mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-17 17:33:47 +00:00
Merge 861a38398b into 221486a291
This commit is contained in:
commit
3a26b0dcb4
5 changed files with 36 additions and 23 deletions
|
|
@ -140,20 +140,20 @@ func (r *ReceiptsRequest) GetCost(peer *peer) uint64 {
|
|||
|
||||
// CanSend tells if a certain peer is suitable for serving the given request
|
||||
func (r *ReceiptsRequest) CanSend(peer *peer) bool {
|
||||
return peer.HasBlock(r.Hash, r.Number)
|
||||
return peer.HasBlock(r.Block.Hash(), r.Block.NumberU64())
|
||||
}
|
||||
|
||||
// Request sends an ODR request to the LES network (implementation of LesOdrRequest)
|
||||
func (r *ReceiptsRequest) Request(reqID uint64, peer *peer) error {
|
||||
peer.Log().Debug("Requesting block receipts", "hash", r.Hash)
|
||||
return peer.RequestReceipts(reqID, r.GetCost(peer), []common.Hash{r.Hash})
|
||||
peer.Log().Debug("Requesting block receipts", "hash", r.Block.Hash())
|
||||
return peer.RequestReceipts(reqID, r.GetCost(peer), []common.Hash{r.Block.Hash()})
|
||||
}
|
||||
|
||||
// Valid processes an ODR request reply message from the LES network
|
||||
// returns true and stores results in memory if the message was a valid reply
|
||||
// to the request (implementation of LesOdrRequest)
|
||||
func (r *ReceiptsRequest) Validate(db ethdb.Database, msg *Msg) error {
|
||||
log.Debug("Validating block receipts", "hash", r.Hash)
|
||||
log.Debug("Validating block receipts", "hash", r.Block.Hash())
|
||||
|
||||
// Ensure we have a correct message with a single block receipt
|
||||
if msg.MsgType != MsgReceipts {
|
||||
|
|
@ -166,14 +166,12 @@ func (r *ReceiptsRequest) Validate(db ethdb.Database, msg *Msg) error {
|
|||
receipt := receipts[0]
|
||||
|
||||
// Retrieve our stored header and validate receipt content against it
|
||||
header := core.GetHeader(db, r.Hash, r.Number)
|
||||
if header == nil {
|
||||
return errHeaderUnavailable
|
||||
}
|
||||
if header.ReceiptHash != types.DeriveSha(receipt) {
|
||||
if r.Block.ReceiptHash() != types.DeriveSha(receipt) {
|
||||
return errReceiptHashMismatch
|
||||
}
|
||||
// Validations passed, store and return
|
||||
core.SetReceiptsData(r.Config, r.Block, receipt)
|
||||
|
||||
r.Receipts = receipt
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,13 +35,13 @@ func secAddr(addr common.Address) []byte {
|
|||
return crypto.Keccak256(addr[:])
|
||||
}
|
||||
|
||||
type accessTestFn func(db ethdb.Database, bhash common.Hash, number uint64) light.OdrRequest
|
||||
type accessTestFn func(odr *LesOdr, bhash common.Hash, number uint64) light.OdrRequest
|
||||
|
||||
func TestBlockAccessLes1(t *testing.T) { testAccess(t, 1, tfBlockAccess) }
|
||||
|
||||
func TestBlockAccessLes2(t *testing.T) { testAccess(t, 2, tfBlockAccess) }
|
||||
|
||||
func tfBlockAccess(db ethdb.Database, bhash common.Hash, number uint64) light.OdrRequest {
|
||||
func tfBlockAccess(odr *LesOdr, bhash common.Hash, number uint64) light.OdrRequest {
|
||||
return &light.BlockRequest{Hash: bhash, Number: number}
|
||||
}
|
||||
|
||||
|
|
@ -49,24 +49,30 @@ func TestReceiptsAccessLes1(t *testing.T) { testAccess(t, 1, tfReceiptsAccess) }
|
|||
|
||||
func TestReceiptsAccessLes2(t *testing.T) { testAccess(t, 2, tfReceiptsAccess) }
|
||||
|
||||
func tfReceiptsAccess(db ethdb.Database, bhash common.Hash, number uint64) light.OdrRequest {
|
||||
return &light.ReceiptsRequest{Hash: bhash, Number: number}
|
||||
func tfReceiptsAccess(odr *LesOdr, bhash common.Hash, number uint64) light.OdrRequest {
|
||||
odr.Retrieve(context.TODO(), &light.BlockRequest{Hash: bhash, Number: number})
|
||||
|
||||
block := core.GetBlock(odr.Database(), bhash, number)
|
||||
genesis := core.GetCanonicalHash(odr.Database(), 0)
|
||||
config, _ := core.GetChainConfig(odr.Database(), genesis)
|
||||
|
||||
return &light.ReceiptsRequest{Config: config, Block: block}
|
||||
}
|
||||
|
||||
func TestTrieEntryAccessLes1(t *testing.T) { testAccess(t, 1, tfTrieEntryAccess) }
|
||||
|
||||
func TestTrieEntryAccessLes2(t *testing.T) { testAccess(t, 2, tfTrieEntryAccess) }
|
||||
|
||||
func tfTrieEntryAccess(db ethdb.Database, bhash common.Hash, number uint64) light.OdrRequest {
|
||||
return &light.TrieRequest{Id: light.StateTrieID(core.GetHeader(db, bhash, core.GetBlockNumber(db, bhash))), Key: testBankSecureTrieKey}
|
||||
func tfTrieEntryAccess(odr *LesOdr, bhash common.Hash, number uint64) light.OdrRequest {
|
||||
return &light.TrieRequest{Id: light.StateTrieID(core.GetHeader(odr.Database(), bhash, core.GetBlockNumber(odr.Database(), bhash))), Key: testBankSecureTrieKey}
|
||||
}
|
||||
|
||||
func TestCodeAccessLes1(t *testing.T) { testAccess(t, 1, tfCodeAccess) }
|
||||
|
||||
func TestCodeAccessLes2(t *testing.T) { testAccess(t, 2, tfCodeAccess) }
|
||||
|
||||
func tfCodeAccess(db ethdb.Database, bhash common.Hash, number uint64) light.OdrRequest {
|
||||
header := core.GetHeader(db, bhash, core.GetBlockNumber(db, bhash))
|
||||
func tfCodeAccess(odr *LesOdr, bhash common.Hash, number uint64) light.OdrRequest {
|
||||
header := core.GetHeader(odr.Database(), bhash, core.GetBlockNumber(odr.Database(), bhash))
|
||||
if header.Number.Uint64() < testContractDeployed {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -100,7 +106,7 @@ func testAccess(t *testing.T, protocol int, fn accessTestFn) {
|
|||
test := func(expFail uint64) {
|
||||
for i := uint64(0); i <= pm.blockchain.CurrentHeader().Number.Uint64(); i++ {
|
||||
bhash := core.GetCanonicalHash(db, i)
|
||||
if req := fn(ldb, bhash, i); req != nil {
|
||||
if req := fn(odr, bhash, i); req != nil {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
|
||||
defer cancel()
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
)
|
||||
|
||||
// NoOdr is the default context passed to an ODR capable function when the ODR
|
||||
|
|
@ -118,14 +119,14 @@ func (req *BlockRequest) StoreResult(db ethdb.Database) {
|
|||
// ReceiptsRequest is the ODR request type for retrieving block bodies
|
||||
type ReceiptsRequest struct {
|
||||
OdrRequest
|
||||
Hash common.Hash
|
||||
Number uint64
|
||||
Config *params.ChainConfig
|
||||
Block *types.Block
|
||||
Receipts types.Receipts
|
||||
}
|
||||
|
||||
// StoreResult stores the retrieved data in local database
|
||||
func (req *ReceiptsRequest) StoreResult(db ethdb.Database) {
|
||||
core.WriteBlockReceipts(db, req.Hash, req.Number, req.Receipts)
|
||||
core.WriteBlockReceipts(db, req.Block.Hash(), req.Block.NumberU64(), req.Receipts)
|
||||
}
|
||||
|
||||
// ChtRequest is the ODR request type for state/storage trie entries
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ func (odr *testOdr) Retrieve(ctx context.Context, req OdrRequest) error {
|
|||
case *BlockRequest:
|
||||
req.Rlp = core.GetBodyRLP(odr.sdb, req.Hash, core.GetBlockNumber(odr.sdb, req.Hash))
|
||||
case *ReceiptsRequest:
|
||||
req.Receipts = core.GetBlockReceipts(odr.sdb, req.Hash, core.GetBlockNumber(odr.sdb, req.Hash))
|
||||
req.Receipts = core.GetBlockReceipts(odr.sdb, req.Block.Hash(), req.Block.NumberU64())
|
||||
case *TrieRequest:
|
||||
t, _ := trie.New(req.Id.Root, trie.NewDatabase(odr.sdb))
|
||||
nodes := NewNodeSet()
|
||||
|
|
|
|||
|
|
@ -130,7 +130,15 @@ func GetBlockReceipts(ctx context.Context, odr OdrBackend, hash common.Hash, num
|
|||
if receipts != nil {
|
||||
return receipts, nil
|
||||
}
|
||||
r := &ReceiptsRequest{Hash: hash, Number: number}
|
||||
// Receipts unavailable locally, we need the full block to reconstruct
|
||||
block, err := GetBlock(ctx, odr, hash, number)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
genesis := core.GetCanonicalHash(odr.Database(), 0)
|
||||
config, _ := core.GetChainConfig(odr.Database(), genesis)
|
||||
|
||||
r := &ReceiptsRequest{Config: config, Block: block}
|
||||
if err := odr.Retrieve(ctx, r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue