aboutsummaryrefslogtreecommitdiffstats
path: root/lds
diff options
context:
space:
mode:
authorSonic <sonic@dexon.org>2019-05-09 14:57:06 +0800
committerSonic <sonic@dexon.org>2019-05-09 14:57:06 +0800
commit5709a57dcf41cc3cb1c09575dd02081e3f4ad496 (patch)
tree01b3303381d9594d660f55e0036aee1f77544bcc /lds
parent2555cb4549e55566131f4ef3d4e06e736f4bdffb (diff)
downloaddexon-5709a57dcf41cc3cb1c09575dd02081e3f4ad496.tar
dexon-5709a57dcf41cc3cb1c09575dd02081e3f4ad496.tar.gz
dexon-5709a57dcf41cc3cb1c09575dd02081e3f4ad496.tar.bz2
dexon-5709a57dcf41cc3cb1c09575dd02081e3f4ad496.tar.lz
dexon-5709a57dcf41cc3cb1c09575dd02081e3f4ad496.tar.xz
dexon-5709a57dcf41cc3cb1c09575dd02081e3f4ad496.tar.zst
dexon-5709a57dcf41cc3cb1c09575dd02081e3f4ad496.zip
lds: implement request/send gov state msg
Diffstat (limited to 'lds')
-rw-r--r--lds/handler.go64
-rw-r--r--lds/peer.go9
-rw-r--r--lds/protocol.go6
3 files changed, 76 insertions, 3 deletions
diff --git a/lds/handler.go b/lds/handler.go
index 6464cb45b..ea8aa40f6 100644
--- a/lds/handler.go
+++ b/lds/handler.go
@@ -83,6 +83,7 @@ type BlockChain interface {
dexcon.GovernanceStateFetcher, *dexCore.TSigVerifierCache) (int, error)
Rollback(chain []common.Hash)
GetHeaderByNumber(number uint64) *types.Header
+ GetGovStateByHash(hash common.Hash) (*types.GovState, error)
GetGovStateByNumber(number uint64) (*types.GovState, error)
GetAncestor(hash common.Hash, number, ancestor uint64, maxNonCanonical *uint64) (common.Hash, uint64)
Genesis() *types.Block
@@ -330,7 +331,7 @@ func (pm *ProtocolManager) handle(p *peer) error {
}
}
-var reqList = []uint64{GetBlockHeadersMsg, GetBlockBodiesMsg, GetCodeMsg, GetReceiptsMsg, SendTxV2Msg, GetTxStatusMsg, GetProofsV2Msg, GetHelperTrieProofsMsg}
+var reqList = []uint64{GetBlockHeadersMsg, GetBlockBodiesMsg, GetCodeMsg, GetReceiptsMsg, SendTxV2Msg, GetTxStatusMsg, GetProofsV2Msg, GetHelperTrieProofsMsg, GetGovStateMsg}
// handleMsg is invoked whenever an inbound message is received from a remote
// peer. The remote connection is torn down upon returning any error.
@@ -949,6 +950,45 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
p.fcServer.GotReply(resp.ReqID, resp.BV)
+ case GetGovStateMsg:
+ p.Log().Trace("Received gov state request")
+ var req struct {
+ ReqID uint64
+ Hash common.Hash
+ }
+ if err := msg.Decode(&req); err != nil {
+ return errResp(ErrDecode, "%v: %v", msg, err)
+ }
+
+ govState, err := pm.blockchain.GetGovStateByHash(req.Hash)
+ if err != nil {
+ p.Log().Debug("Invalid gov state msg", "hash", req.Hash.String(), "err", err)
+ return errResp(ErrInvalidGovStateMsg, "hash=%v", req.Hash.String())
+ }
+
+ bv, rcost := p.fcClient.RequestProcessed(costs.baseCost + costs.reqCost)
+ pm.server.fcCostStats.update(msg.Code, 1, rcost)
+ return p.SendGovState(req.ReqID, bv, govState)
+
+ case GovStateMsg:
+ if pm.downloader == nil {
+ return errResp(ErrUnexpectedResponse, "")
+ }
+
+ p.Log().Trace("Received block header response message")
+ // A batch of headers arrived to one of our previous requests
+ var resp struct {
+ ReqID, BV uint64
+ GovState types.GovState
+ }
+ if err := msg.Decode(&resp); err != nil {
+ return errResp(ErrDecode, "msg %v: %v", msg, err)
+ }
+ p.fcServer.GotReply(resp.ReqID, resp.BV)
+ if err := pm.downloader.DeliverGovState(p.id, &resp.GovState); err != nil {
+ log.Debug(fmt.Sprint(err))
+ }
+
default:
p.Log().Trace("Received unknown message", "code", msg.Code)
return errResp(ErrInvalidMsgCode, "%v", msg.Code)
@@ -1085,7 +1125,27 @@ func (pc *peerConnection) RequestHeadersByNumber(origin uint64, amount int, skip
}
func (pc *peerConnection) RequestGovStateByHash(hash common.Hash) error {
- return fmt.Errorf("Not implemented yet")
+ reqID := genReqID()
+ rq := &distReq{
+ getCost: func(dp distPeer) uint64 {
+ peer := dp.(*peer)
+ return peer.GetRequestCost(GetGovStateMsg, 1)
+ },
+ canSend: func(dp distPeer) bool {
+ return dp.(*peer) == pc.peer
+ },
+ request: func(dp distPeer) func() {
+ peer := dp.(*peer)
+ cost := peer.GetRequestCost(GetGovStateMsg, 1)
+ peer.fcServer.QueueRequest(reqID, cost)
+ return func() { peer.RequestGovStateByHash(reqID, cost, hash) }
+ },
+ }
+ _, ok := <-pc.manager.reqDist.queue(rq)
+ if !ok {
+ return light.ErrNoPeers
+ }
+ return nil
}
func (d *downloaderPeerNotify) registerPeer(p *peer) {
diff --git a/lds/peer.go b/lds/peer.go
index b41824ad7..a5dcf0421 100644
--- a/lds/peer.go
+++ b/lds/peer.go
@@ -195,6 +195,10 @@ func (p *peer) SendBlockBodiesRLP(reqID, bv uint64, bodies []rlp.RawValue) error
return sendResponse(p.rw, BlockBodiesMsg, reqID, bv, bodies)
}
+func (p *peer) SendGovState(reqID, bv uint64, govState *types.GovState) error {
+ return sendResponse(p.rw, GovStateMsg, reqID, bv, govState)
+}
+
// SendCodeRLP sends a batch of arbitrary internal data, corresponding to the
// hashes requested.
func (p *peer) SendCode(reqID, bv uint64, data [][]byte) error {
@@ -243,6 +247,11 @@ func (p *peer) RequestBodies(reqID, cost uint64, hashes []common.Hash) error {
return sendRequest(p.rw, GetBlockBodiesMsg, reqID, cost, hashes)
}
+func (p *peer) RequestGovStateByHash(reqID, cost uint64, hash common.Hash) error {
+ p.Log().Debug("Fetching one gov state", "hash", hash)
+ return sendRequest(p.rw, GetGovStateMsg, reqID, cost, hash)
+}
+
// RequestCode fetches a batch of arbitrary data from a node's known state
// data, corresponding to the specified hashes.
func (p *peer) RequestCode(reqID, cost uint64, reqs []CodeReq) error {
diff --git a/lds/protocol.go b/lds/protocol.go
index 4c7f574e0..2aa03466c 100644
--- a/lds/protocol.go
+++ b/lds/protocol.go
@@ -45,7 +45,7 @@ var (
)
// Number of implemented message corresponding to different protocol versions.
-var ProtocolLengths = map[uint]uint64{lpv2: 22}
+var ProtocolLengths = map[uint]uint64{lpv2: 24}
const (
NetworkId = 1
@@ -73,6 +73,9 @@ const (
SendTxV2Msg = 0x13
GetTxStatusMsg = 0x14
TxStatusMsg = 0x15
+
+ GetGovStateMsg = 0x16
+ GovStateMsg = 0x17
)
type errCode int
@@ -93,6 +96,7 @@ const (
ErrInvalidResponse
ErrTooManyTimeouts
ErrMissingKey
+ ErrInvalidGovStateMsg
)
func (e errCode) String() string {