mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-17 09:23:48 +00:00
les: implement ProofsV2Msg
This commit is contained in:
parent
6016610f7d
commit
c76e52132f
8 changed files with 168 additions and 51 deletions
108
les/handler.go
108
les/handler.go
|
|
@ -18,6 +18,7 @@
|
||||||
package les
|
package les
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
@ -51,13 +52,13 @@ const (
|
||||||
|
|
||||||
ethVersion = 63 // equivalent eth version for the downloader
|
ethVersion = 63 // equivalent eth version for the downloader
|
||||||
|
|
||||||
MaxHeaderFetch = 192 // Amount of block headers to be fetched per retrieval request
|
MaxHeaderFetch = 192 // Amount of block headers to be fetched per retrieval request
|
||||||
MaxBodyFetch = 32 // Amount of block bodies to be fetched per retrieval request
|
MaxBodyFetch = 32 // Amount of block bodies to be fetched per retrieval request
|
||||||
MaxReceiptFetch = 128 // Amount of transaction receipts to allow fetching per request
|
MaxReceiptFetch = 128 // Amount of transaction receipts to allow fetching per request
|
||||||
MaxCodeFetch = 64 // Amount of contract codes to allow fetching per request
|
MaxCodeFetch = 64 // Amount of contract codes to allow fetching per request
|
||||||
MaxProofsFetch = 64 // Amount of merkle proofs to be fetched per retrieval request
|
MaxProofsFetch = 64 // Amount of merkle proofs to be fetched per retrieval request
|
||||||
MaxHeaderProofsFetch = 64 // Amount of merkle proofs to be fetched per retrieval request
|
MaxPPTProofsFetch = 64 // Amount of merkle proofs to be fetched per retrieval request
|
||||||
MaxTxSend = 64 // Amount of transactions to be send per request
|
MaxTxSend = 64 // Amount of transactions to be send per request
|
||||||
|
|
||||||
disableClientRemovePeer = false
|
disableClientRemovePeer = false
|
||||||
)
|
)
|
||||||
|
|
@ -316,7 +317,7 @@ func (pm *ProtocolManager) handle(p *peer) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var reqList = []uint64{GetBlockHeadersMsg, GetBlockBodiesMsg, GetCodeMsg, GetReceiptsMsg, GetProofsMsg, SendTxMsg, GetHeaderProofsMsg}
|
var reqList = []uint64{GetBlockHeadersMsg, GetBlockBodiesMsg, GetCodeMsg, GetReceiptsMsg, GetProofsV1Msg, SendTxMsg, GetHeaderProofsMsg, GetProofsV2Msg, GetPPTProofsMsg}
|
||||||
|
|
||||||
// handleMsg is invoked whenever an inbound message is received from a remote
|
// handleMsg is invoked whenever an inbound message is received from a remote
|
||||||
// peer. The remote connection is torn down upon returning any error.
|
// peer. The remote connection is torn down upon returning any error.
|
||||||
|
|
@ -656,7 +657,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
|
||||||
Obj: resp.Receipts,
|
Obj: resp.Receipts,
|
||||||
}
|
}
|
||||||
|
|
||||||
case GetProofsMsg:
|
case GetProofsV1Msg:
|
||||||
p.Log().Trace("Received proofs request")
|
p.Log().Trace("Received proofs request")
|
||||||
// Decode the retrieval message
|
// Decode the retrieval message
|
||||||
var req struct {
|
var req struct {
|
||||||
|
|
@ -703,7 +704,67 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
|
||||||
pm.server.fcCostStats.update(msg.Code, uint64(reqCnt), rcost)
|
pm.server.fcCostStats.update(msg.Code, uint64(reqCnt), rcost)
|
||||||
return p.SendProofs(req.ReqID, bv, proofs)
|
return p.SendProofs(req.ReqID, bv, proofs)
|
||||||
|
|
||||||
case ProofsMsg:
|
case GetProofsV2Msg:
|
||||||
|
p.Log().Trace("Received les/2 proofs request")
|
||||||
|
// Decode the retrieval message
|
||||||
|
var req struct {
|
||||||
|
ReqID uint64
|
||||||
|
Reqs []ProofReq
|
||||||
|
}
|
||||||
|
if err := msg.Decode(&req); err != nil {
|
||||||
|
return errResp(ErrDecode, "msg %v: %v", msg, err)
|
||||||
|
}
|
||||||
|
// Gather state data until the fetch or network limits is reached
|
||||||
|
var (
|
||||||
|
lastBHash common.Hash
|
||||||
|
lastAccKey []byte
|
||||||
|
tr, str *trie.Trie
|
||||||
|
)
|
||||||
|
reqCnt := len(req.Reqs)
|
||||||
|
if reject(uint64(reqCnt), MaxProofsFetch) {
|
||||||
|
return errResp(ErrRequestRejected, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
nodes := light.NewNodeSet()
|
||||||
|
|
||||||
|
for _, req := range req.Reqs {
|
||||||
|
if nodes.DataSize() >= softResponseLimit {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if tr == nil || req.BHash != lastBHash {
|
||||||
|
if header := core.GetHeader(pm.chainDb, req.BHash, core.GetBlockNumber(pm.chainDb, req.BHash)); header != nil {
|
||||||
|
tr, _ = trie.New(header.Root, pm.chainDb)
|
||||||
|
} else {
|
||||||
|
tr = nil
|
||||||
|
}
|
||||||
|
lastBHash = req.BHash
|
||||||
|
str = nil
|
||||||
|
}
|
||||||
|
if tr != nil {
|
||||||
|
if len(req.AccKey) > 0 {
|
||||||
|
if str == nil || !bytes.Equal(req.AccKey, lastAccKey) {
|
||||||
|
sdata := tr.Get(req.AccKey)
|
||||||
|
str = nil
|
||||||
|
var acc state.Account
|
||||||
|
if err := rlp.DecodeBytes(sdata, &acc); err == nil {
|
||||||
|
str, _ = trie.New(acc.Root, pm.chainDb)
|
||||||
|
}
|
||||||
|
lastAccKey = common.CopyBytes(req.AccKey)
|
||||||
|
}
|
||||||
|
if str != nil {
|
||||||
|
str.Prove(req.Key, req.FromLevel, nodes)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tr.Prove(req.Key, req.FromLevel, nodes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
proofs := nodes.NodeList()
|
||||||
|
bv, rcost := p.fcClient.RequestProcessed(costs.baseCost + uint64(reqCnt)*costs.reqCost)
|
||||||
|
pm.server.fcCostStats.update(msg.Code, uint64(reqCnt), rcost)
|
||||||
|
return p.SendProofsV2(req.ReqID, bv, proofs)
|
||||||
|
|
||||||
|
case ProofsV1Msg:
|
||||||
if pm.odr == nil {
|
if pm.odr == nil {
|
||||||
return errResp(ErrUnexpectedResponse, "")
|
return errResp(ErrUnexpectedResponse, "")
|
||||||
}
|
}
|
||||||
|
|
@ -712,14 +773,35 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
|
||||||
// A batch of merkle proofs arrived to one of our previous requests
|
// A batch of merkle proofs arrived to one of our previous requests
|
||||||
var resp struct {
|
var resp struct {
|
||||||
ReqID, BV uint64
|
ReqID, BV uint64
|
||||||
Data [][]rlp.RawValue
|
Data []light.NodeList
|
||||||
}
|
}
|
||||||
if err := msg.Decode(&resp); err != nil {
|
if err := msg.Decode(&resp); err != nil {
|
||||||
return errResp(ErrDecode, "msg %v: %v", msg, err)
|
return errResp(ErrDecode, "msg %v: %v", msg, err)
|
||||||
}
|
}
|
||||||
p.fcServer.GotReply(resp.ReqID, resp.BV)
|
p.fcServer.GotReply(resp.ReqID, resp.BV)
|
||||||
deliverMsg = &Msg{
|
deliverMsg = &Msg{
|
||||||
MsgType: MsgProofs,
|
MsgType: MsgProofsV1,
|
||||||
|
ReqID: resp.ReqID,
|
||||||
|
Obj: resp.Data,
|
||||||
|
}
|
||||||
|
|
||||||
|
case ProofsV2Msg:
|
||||||
|
if pm.odr == nil {
|
||||||
|
return errResp(ErrUnexpectedResponse, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
p.Log().Trace("Received les/2 proofs response")
|
||||||
|
// A batch of merkle proofs arrived to one of our previous requests
|
||||||
|
var resp struct {
|
||||||
|
ReqID, BV uint64
|
||||||
|
Data light.NodeList
|
||||||
|
}
|
||||||
|
if err := msg.Decode(&resp); err != nil {
|
||||||
|
return errResp(ErrDecode, "msg %v: %v", msg, err)
|
||||||
|
}
|
||||||
|
p.fcServer.GotReply(resp.ReqID, resp.BV)
|
||||||
|
deliverMsg = &Msg{
|
||||||
|
MsgType: MsgProofsV2,
|
||||||
ReqID: resp.ReqID,
|
ReqID: resp.ReqID,
|
||||||
Obj: resp.Data,
|
Obj: resp.Data,
|
||||||
}
|
}
|
||||||
|
|
@ -740,7 +822,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
|
||||||
proofs []ChtResp
|
proofs []ChtResp
|
||||||
)
|
)
|
||||||
reqCnt := len(req.Reqs)
|
reqCnt := len(req.Reqs)
|
||||||
if reject(uint64(reqCnt), MaxHeaderProofsFetch) {
|
if reject(uint64(reqCnt), MaxPPTProofsFetch) {
|
||||||
return errResp(ErrRequestRejected, "")
|
return errResp(ErrRequestRejected, "")
|
||||||
}
|
}
|
||||||
for _, req := range req.Reqs {
|
for _, req := range req.Reqs {
|
||||||
|
|
|
||||||
|
|
@ -338,9 +338,9 @@ func testGetProofs(t *testing.T, protocol int) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Send the proof request and verify the response
|
// Send the proof request and verify the response
|
||||||
cost := peer.GetRequestCost(GetProofsMsg, len(proofreqs))
|
cost := peer.GetRequestCost(GetProofsV1Msg, len(proofreqs))
|
||||||
sendRequest(peer.app, GetProofsMsg, 42, cost, proofreqs)
|
sendRequest(peer.app, GetProofsV1Msg, 42, cost, proofreqs)
|
||||||
if err := expectResponse(peer.app, ProofsMsg, 42, testBufLimit, proofs); err != nil {
|
if err := expectResponse(peer.app, ProofsV1Msg, 42, testBufLimit, proofs); err != nil {
|
||||||
t.Errorf("proofs mismatch: %v", err)
|
t.Errorf("proofs mismatch: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,8 @@ const (
|
||||||
MsgBlockBodies = iota
|
MsgBlockBodies = iota
|
||||||
MsgCode
|
MsgCode
|
||||||
MsgReceipts
|
MsgReceipts
|
||||||
MsgProofs
|
MsgProofsV1
|
||||||
|
MsgProofsV2
|
||||||
MsgHeaderProofs
|
MsgHeaderProofs
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ var (
|
||||||
errReceiptHashMismatch = errors.New("receipt hash mismatch")
|
errReceiptHashMismatch = errors.New("receipt hash mismatch")
|
||||||
errDataHashMismatch = errors.New("data hash mismatch")
|
errDataHashMismatch = errors.New("data hash mismatch")
|
||||||
errCHTHashMismatch = errors.New("cht hash mismatch")
|
errCHTHashMismatch = errors.New("cht hash mismatch")
|
||||||
|
errUselessNodes = errors.New("useless nodes in merkle proof nodeset")
|
||||||
)
|
)
|
||||||
|
|
||||||
type LesOdrRequest interface {
|
type LesOdrRequest interface {
|
||||||
|
|
@ -186,7 +187,14 @@ type TrieRequest light.TrieRequest
|
||||||
// GetCost returns the cost of the given ODR request according to the serving
|
// GetCost returns the cost of the given ODR request according to the serving
|
||||||
// peer's cost table (implementation of LesOdrRequest)
|
// peer's cost table (implementation of LesOdrRequest)
|
||||||
func (r *TrieRequest) GetCost(peer *peer) uint64 {
|
func (r *TrieRequest) GetCost(peer *peer) uint64 {
|
||||||
return peer.GetRequestCost(GetProofsMsg, 1)
|
switch peer.version {
|
||||||
|
case lpv1:
|
||||||
|
return peer.GetRequestCost(GetProofsV1Msg, 1)
|
||||||
|
case lpv2:
|
||||||
|
return peer.GetRequestCost(GetProofsV2Msg, 1)
|
||||||
|
default:
|
||||||
|
panic(nil)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CanSend tells if a certain peer is suitable for serving the given request
|
// CanSend tells if a certain peer is suitable for serving the given request
|
||||||
|
|
@ -211,20 +219,38 @@ func (r *TrieRequest) Request(reqID uint64, peer *peer) error {
|
||||||
func (r *TrieRequest) Validate(db ethdb.Database, msg *Msg) error {
|
func (r *TrieRequest) Validate(db ethdb.Database, msg *Msg) error {
|
||||||
log.Debug("Validating trie proof", "root", r.Id.Root, "key", r.Key)
|
log.Debug("Validating trie proof", "root", r.Id.Root, "key", r.Key)
|
||||||
|
|
||||||
// Ensure we have a correct message with a single proof
|
switch msg.MsgType {
|
||||||
if msg.MsgType != MsgProofs {
|
case MsgProofsV1:
|
||||||
|
proofs := msg.Obj.([]light.NodeList)
|
||||||
|
if len(proofs) != 1 {
|
||||||
|
return errInvalidEntryCount
|
||||||
|
}
|
||||||
|
nodeSet := proofs[0].NodeSet()
|
||||||
|
// Verify the proof and store if checks out
|
||||||
|
if _, err, _ := trie.VerifyProof(r.Id.Root, r.Key, nodeSet); err != nil {
|
||||||
|
return fmt.Errorf("merkle proof verification failed: %v", err)
|
||||||
|
}
|
||||||
|
r.Proof = nodeSet
|
||||||
|
return nil
|
||||||
|
|
||||||
|
case MsgProofsV2:
|
||||||
|
proofs := msg.Obj.(light.NodeList)
|
||||||
|
// Verify the proof and store if checks out
|
||||||
|
pdb := proofs.NodeSet()
|
||||||
|
cdb := pdb.ReadCache()
|
||||||
|
if _, err, _ := trie.VerifyProof(r.Id.Root, r.Key, cdb); err != nil {
|
||||||
|
return fmt.Errorf("merkle proof verification failed: %v", err)
|
||||||
|
}
|
||||||
|
// check if all nodes have been read by VerifyProof
|
||||||
|
if pdb.KeyCount() != cdb.KeyCount() {
|
||||||
|
return errUselessNodes
|
||||||
|
}
|
||||||
|
r.Proof = pdb
|
||||||
|
return nil
|
||||||
|
|
||||||
|
default:
|
||||||
return errInvalidMessageType
|
return errInvalidMessageType
|
||||||
}
|
}
|
||||||
proofs := msg.Obj.([][]rlp.RawValue)
|
|
||||||
if len(proofs) != 1 {
|
|
||||||
return errMultipleEntries
|
|
||||||
}
|
|
||||||
// Verify the proof and store if checks out
|
|
||||||
if _, err, _ := trie.VerifyProof(r.Id.Root, r.Key, light.NodeList(proofs[0]).NodeSet()); err != nil {
|
|
||||||
return fmt.Errorf("merkle proof verification failed: %v", err)
|
|
||||||
}
|
|
||||||
r.Proof = proofs[0]
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type CodeReq struct {
|
type CodeReq struct {
|
||||||
|
|
|
||||||
18
les/peer.go
18
les/peer.go
|
|
@ -28,6 +28,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/eth"
|
"github.com/ethereum/go-ethereum/eth"
|
||||||
"github.com/ethereum/go-ethereum/les/flowcontrol"
|
"github.com/ethereum/go-ethereum/les/flowcontrol"
|
||||||
|
"github.com/ethereum/go-ethereum/light"
|
||||||
"github.com/ethereum/go-ethereum/p2p"
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
)
|
)
|
||||||
|
|
@ -199,7 +200,12 @@ func (p *peer) SendReceiptsRLP(reqID, bv uint64, receipts []rlp.RawValue) error
|
||||||
|
|
||||||
// SendProofs sends a batch of merkle proofs, corresponding to the ones requested.
|
// SendProofs sends a batch of merkle proofs, corresponding to the ones requested.
|
||||||
func (p *peer) SendProofs(reqID, bv uint64, proofs proofsData) error {
|
func (p *peer) SendProofs(reqID, bv uint64, proofs proofsData) error {
|
||||||
return sendResponse(p.rw, ProofsMsg, reqID, bv, proofs)
|
return sendResponse(p.rw, ProofsV1Msg, reqID, bv, proofs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendProofsV2 sends a batch of merkle proofs, corresponding to the ones requested.
|
||||||
|
func (p *peer) SendProofsV2(reqID, bv uint64, proofs light.NodeList) error {
|
||||||
|
return sendResponse(p.rw, ProofsV2Msg, reqID, bv, proofs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendHeaderProofs sends a batch of header proofs, corresponding to the ones requested.
|
// SendHeaderProofs sends a batch of header proofs, corresponding to the ones requested.
|
||||||
|
|
@ -244,7 +250,15 @@ func (p *peer) RequestReceipts(reqID, cost uint64, hashes []common.Hash) error {
|
||||||
// RequestProofs fetches a batch of merkle proofs from a remote node.
|
// RequestProofs fetches a batch of merkle proofs from a remote node.
|
||||||
func (p *peer) RequestProofs(reqID, cost uint64, reqs []*ProofReq) error {
|
func (p *peer) RequestProofs(reqID, cost uint64, reqs []*ProofReq) error {
|
||||||
p.Log().Debug("Fetching batch of proofs", "count", len(reqs))
|
p.Log().Debug("Fetching batch of proofs", "count", len(reqs))
|
||||||
return sendRequest(p.rw, GetProofsMsg, reqID, cost, reqs)
|
switch p.version {
|
||||||
|
case lpv1:
|
||||||
|
return sendRequest(p.rw, GetProofsV1Msg, reqID, cost, reqs)
|
||||||
|
case lpv2:
|
||||||
|
return sendRequest(p.rw, GetProofsV2Msg, reqID, cost, reqs)
|
||||||
|
default:
|
||||||
|
panic(nil)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RequestHeaderProofs fetches a batch of header merkle proofs from a remote node.
|
// RequestHeaderProofs fetches a batch of header merkle proofs from a remote node.
|
||||||
|
|
|
||||||
|
|
@ -29,13 +29,14 @@ import (
|
||||||
// Constants to match up protocol versions and messages
|
// Constants to match up protocol versions and messages
|
||||||
const (
|
const (
|
||||||
lpv1 = 1
|
lpv1 = 1
|
||||||
|
lpv2 = 2
|
||||||
)
|
)
|
||||||
|
|
||||||
// Supported versions of the les protocol (first is primary).
|
// Supported versions of the les protocol (first is primary).
|
||||||
var ProtocolVersions = []uint{lpv1}
|
var ProtocolVersions = []uint{lpv1, lpv2}
|
||||||
|
|
||||||
// Number of implemented message corresponding to different protocol versions.
|
// Number of implemented message corresponding to different protocol versions.
|
||||||
var ProtocolLengths = []uint64{15}
|
var ProtocolLengths = []uint64{15, 19}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
NetworkId = 1
|
NetworkId = 1
|
||||||
|
|
@ -53,13 +54,18 @@ const (
|
||||||
BlockBodiesMsg = 0x05
|
BlockBodiesMsg = 0x05
|
||||||
GetReceiptsMsg = 0x06
|
GetReceiptsMsg = 0x06
|
||||||
ReceiptsMsg = 0x07
|
ReceiptsMsg = 0x07
|
||||||
GetProofsMsg = 0x08
|
GetProofsV1Msg = 0x08
|
||||||
ProofsMsg = 0x09
|
ProofsV1Msg = 0x09
|
||||||
GetCodeMsg = 0x0a
|
GetCodeMsg = 0x0a
|
||||||
CodeMsg = 0x0b
|
CodeMsg = 0x0b
|
||||||
SendTxMsg = 0x0c
|
SendTxMsg = 0x0c
|
||||||
GetHeaderProofsMsg = 0x0d
|
GetHeaderProofsMsg = 0x0d
|
||||||
HeaderProofsMsg = 0x0e
|
HeaderProofsMsg = 0x0e
|
||||||
|
// Protocol messages belonging to LPV2
|
||||||
|
GetProofsV2Msg = 0x0f
|
||||||
|
ProofsV2Msg = 0x10
|
||||||
|
GetPPTProofsMsg = 0x11
|
||||||
|
PPTProofsMsg = 0x12
|
||||||
)
|
)
|
||||||
|
|
||||||
type errCode int
|
type errCode int
|
||||||
|
|
|
||||||
16
light/odr.go
16
light/odr.go
|
|
@ -25,7 +25,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
)
|
)
|
||||||
|
|
@ -80,23 +79,12 @@ type TrieRequest struct {
|
||||||
OdrRequest
|
OdrRequest
|
||||||
Id *TrieID
|
Id *TrieID
|
||||||
Key []byte
|
Key []byte
|
||||||
Proof []rlp.RawValue
|
Proof *NodeSet
|
||||||
}
|
}
|
||||||
|
|
||||||
// StoreResult stores the retrieved data in local database
|
// StoreResult stores the retrieved data in local database
|
||||||
func (req *TrieRequest) StoreResult(db ethdb.Database) {
|
func (req *TrieRequest) StoreResult(db ethdb.Database) {
|
||||||
storeProof(db, req.Proof)
|
req.Proof.Store(db)
|
||||||
}
|
|
||||||
|
|
||||||
// storeProof stores the new trie nodes obtained from a merkle proof in the database
|
|
||||||
func storeProof(db ethdb.Database, proof []rlp.RawValue) {
|
|
||||||
for _, buf := range proof {
|
|
||||||
hash := crypto.Keccak256(buf)
|
|
||||||
val, _ := db.Get(hash)
|
|
||||||
if val == nil {
|
|
||||||
db.Put(hash, buf)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CodeRequest is the ODR request type for retrieving contract code
|
// CodeRequest is the ODR request type for retrieving contract code
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ func (odr *testOdr) Retrieve(ctx context.Context, req OdrRequest) error {
|
||||||
t, _ := trie.New(req.Id.Root, odr.sdb)
|
t, _ := trie.New(req.Id.Root, odr.sdb)
|
||||||
nodes := NewNodeSet()
|
nodes := NewNodeSet()
|
||||||
t.Prove(req.Key, 0, nodes)
|
t.Prove(req.Key, 0, nodes)
|
||||||
req.Proof = nodes.NodeList()
|
req.Proof = nodes
|
||||||
case *CodeRequest:
|
case *CodeRequest:
|
||||||
req.Data, _ = odr.sdb.Get(req.Hash[:])
|
req.Data, _ = odr.sdb.Get(req.Hash[:])
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue