diff options
author | Sonic <sonic@dexon.org> | 2019-05-09 14:57:06 +0800 |
---|---|---|
committer | Sonic <sonic@dexon.org> | 2019-05-09 14:57:06 +0800 |
commit | 5709a57dcf41cc3cb1c09575dd02081e3f4ad496 (patch) | |
tree | 01b3303381d9594d660f55e0036aee1f77544bcc /lds | |
parent | 2555cb4549e55566131f4ef3d4e06e736f4bdffb (diff) | |
download | dexon-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.go | 64 | ||||
-rw-r--r-- | lds/peer.go | 9 | ||||
-rw-r--r-- | lds/protocol.go | 6 |
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 { |