mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-02-26 15:47:21 +00:00
Merge ef7258ed99 into 406a852ec8
This commit is contained in:
commit
21be332503
15 changed files with 167 additions and 635 deletions
|
|
@ -155,7 +155,7 @@ func (c *Conn) ReadEth() (any, error) {
|
|||
var msg any
|
||||
switch int(code) {
|
||||
case eth.StatusMsg:
|
||||
msg = new(eth.StatusPacket69)
|
||||
msg = new(eth.StatusPacket)
|
||||
case eth.GetBlockHeadersMsg:
|
||||
msg = new(eth.GetBlockHeadersPacket)
|
||||
case eth.BlockHeadersMsg:
|
||||
|
|
@ -164,10 +164,6 @@ func (c *Conn) ReadEth() (any, error) {
|
|||
msg = new(eth.GetBlockBodiesPacket)
|
||||
case eth.BlockBodiesMsg:
|
||||
msg = new(eth.BlockBodiesPacket)
|
||||
case eth.NewBlockMsg:
|
||||
msg = new(eth.NewBlockPacket)
|
||||
case eth.NewBlockHashesMsg:
|
||||
msg = new(eth.NewBlockHashesPacket)
|
||||
case eth.TransactionsMsg:
|
||||
msg = new(eth.TransactionsPacket)
|
||||
case eth.NewPooledTransactionHashesMsg:
|
||||
|
|
@ -229,7 +225,7 @@ func (c *Conn) ReadSnap() (any, error) {
|
|||
}
|
||||
|
||||
// dialAndPeer creates a peer connection and runs the handshake.
|
||||
func (s *Suite) dialAndPeer(status *eth.StatusPacket69) (*Conn, error) {
|
||||
func (s *Suite) dialAndPeer(status *eth.StatusPacket) (*Conn, error) {
|
||||
c, err := s.dial()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -242,7 +238,7 @@ func (s *Suite) dialAndPeer(status *eth.StatusPacket69) (*Conn, error) {
|
|||
|
||||
// peer performs both the protocol handshake and the status message
|
||||
// exchange with the node in order to peer with it.
|
||||
func (c *Conn) peer(chain *Chain, status *eth.StatusPacket69) error {
|
||||
func (c *Conn) peer(chain *Chain, status *eth.StatusPacket) error {
|
||||
if err := c.handshake(); err != nil {
|
||||
return fmt.Errorf("handshake failed: %v", err)
|
||||
}
|
||||
|
|
@ -315,7 +311,7 @@ func (c *Conn) negotiateEthProtocol(caps []p2p.Cap) {
|
|||
}
|
||||
|
||||
// statusExchange performs a `Status` message exchange with the given node.
|
||||
func (c *Conn) statusExchange(chain *Chain, status *eth.StatusPacket69) error {
|
||||
func (c *Conn) statusExchange(chain *Chain, status *eth.StatusPacket) error {
|
||||
loop:
|
||||
for {
|
||||
code, data, err := c.Read()
|
||||
|
|
@ -324,7 +320,7 @@ loop:
|
|||
}
|
||||
switch code {
|
||||
case eth.StatusMsg + protoOffset(ethProto):
|
||||
msg := new(eth.StatusPacket69)
|
||||
msg := new(eth.StatusPacket)
|
||||
if err := rlp.DecodeBytes(data, &msg); err != nil {
|
||||
return fmt.Errorf("error decoding status packet: %w", err)
|
||||
}
|
||||
|
|
@ -363,7 +359,7 @@ loop:
|
|||
}
|
||||
if status == nil {
|
||||
// default status message
|
||||
status = ð.StatusPacket69{
|
||||
status = ð.StatusPacket{
|
||||
ProtocolVersion: uint32(c.negotiatedProtoVersion),
|
||||
NetworkID: chain.config.ChainID.Uint64(),
|
||||
Genesis: chain.blocks[0].Hash(),
|
||||
|
|
|
|||
|
|
@ -447,7 +447,7 @@ func (s *Suite) TestGetReceipts(t *utesting.T) {
|
|||
t.Fatalf("could not write to connection: %v", err)
|
||||
}
|
||||
// Wait for response.
|
||||
resp := new(eth.ReceiptsPacket[*eth.ReceiptList69])
|
||||
resp := new(eth.ReceiptsPacket)
|
||||
if err := conn.ReadMsg(ethProto, eth.ReceiptsMsg, &resp); err != nil {
|
||||
t.Fatalf("error reading block bodies msg: %v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package downloader
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"sync"
|
||||
|
|
@ -40,6 +41,16 @@ import (
|
|||
"github.com/ethereum/go-ethereum/trie"
|
||||
)
|
||||
|
||||
type receiptHashList struct {
|
||||
items []eth.Receipt
|
||||
bloomBuf [6]byte
|
||||
}
|
||||
|
||||
func (l *receiptHashList) Len() int { return len(l.items) }
|
||||
func (l *receiptHashList) EncodeIndex(i int, buf *bytes.Buffer) {
|
||||
l.items[i].EncodeForHash(&l.bloomBuf, buf)
|
||||
}
|
||||
|
||||
// downloadTester is a test simulator for mocking out local block chain.
|
||||
type downloadTester struct {
|
||||
chain *core.BlockChain
|
||||
|
|
@ -261,16 +272,18 @@ func (dlp *downloadTesterPeer) RequestBodies(hashes []common.Hash, sink chan *et
|
|||
// peer in the download tester. The returned function can be used to retrieve
|
||||
// batches of block receipts from the particularly requested peer.
|
||||
func (dlp *downloadTesterPeer) RequestReceipts(hashes []common.Hash, sink chan *eth.Response) (*eth.Request, error) {
|
||||
blobs := eth.ServiceGetReceiptsQuery68(dlp.chain, hashes)
|
||||
blobs := eth.ServiceGetReceiptsQuery(dlp.chain, hashes)
|
||||
|
||||
receipts := make([]types.Receipts, len(blobs))
|
||||
|
||||
hashes = make([]common.Hash, len(blobs))
|
||||
hasher := trie.NewStackTrie(nil)
|
||||
for i, blob := range blobs {
|
||||
rlp.DecodeBytes(blob, &receipts[i])
|
||||
}
|
||||
hasher := trie.NewStackTrie(nil)
|
||||
hashes = make([]common.Hash, len(receipts))
|
||||
for i, receipt := range receipts {
|
||||
hashes[i] = types.DeriveSha(receipt, hasher)
|
||||
|
||||
var items []eth.Receipt
|
||||
rlp.DecodeBytes(blob, &items)
|
||||
hashes[i] = types.DeriveSha(&receiptHashList{items: items}, hasher)
|
||||
}
|
||||
req := ð.Request{
|
||||
Peer: dlp.id,
|
||||
|
|
@ -398,8 +411,8 @@ func assertOwnChain(t *testing.T, tester *downloadTester, length int) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestCanonicalSynchronisation68Full(t *testing.T) { testCanonSync(t, eth.ETH68, FullSync) }
|
||||
func TestCanonicalSynchronisation68Snap(t *testing.T) { testCanonSync(t, eth.ETH68, SnapSync) }
|
||||
func TestCanonicalSynchronisation68Full(t *testing.T) { testCanonSync(t, eth.ETH69, FullSync) }
|
||||
func TestCanonicalSynchronisation68Snap(t *testing.T) { testCanonSync(t, eth.ETH69, SnapSync) }
|
||||
|
||||
func testCanonSync(t *testing.T, protocol uint, mode SyncMode) {
|
||||
success := make(chan struct{})
|
||||
|
|
@ -426,8 +439,8 @@ func testCanonSync(t *testing.T, protocol uint, mode SyncMode) {
|
|||
|
||||
// Tests that if a large batch of blocks are being downloaded, it is throttled
|
||||
// until the cached blocks are retrieved.
|
||||
func TestThrottling68Full(t *testing.T) { testThrottling(t, eth.ETH68, FullSync) }
|
||||
func TestThrottling68Snap(t *testing.T) { testThrottling(t, eth.ETH68, SnapSync) }
|
||||
func TestThrottling68Full(t *testing.T) { testThrottling(t, eth.ETH69, FullSync) }
|
||||
func TestThrottling68Snap(t *testing.T) { testThrottling(t, eth.ETH69, SnapSync) }
|
||||
|
||||
func testThrottling(t *testing.T, protocol uint, mode SyncMode) {
|
||||
tester := newTester(t, mode)
|
||||
|
|
@ -504,8 +517,8 @@ func testThrottling(t *testing.T, protocol uint, mode SyncMode) {
|
|||
}
|
||||
|
||||
// Tests that a canceled download wipes all previously accumulated state.
|
||||
func TestCancel68Full(t *testing.T) { testCancel(t, eth.ETH68, FullSync) }
|
||||
func TestCancel68Snap(t *testing.T) { testCancel(t, eth.ETH68, SnapSync) }
|
||||
func TestCancel68Full(t *testing.T) { testCancel(t, eth.ETH69, FullSync) }
|
||||
func TestCancel68Snap(t *testing.T) { testCancel(t, eth.ETH69, SnapSync) }
|
||||
|
||||
func testCancel(t *testing.T, protocol uint, mode SyncMode) {
|
||||
complete := make(chan struct{})
|
||||
|
|
@ -536,8 +549,8 @@ func testCancel(t *testing.T, protocol uint, mode SyncMode) {
|
|||
|
||||
// Tests that synchronisations behave well in multi-version protocol environments
|
||||
// and not wreak havoc on other nodes in the network.
|
||||
func TestMultiProtoSynchronisation68Full(t *testing.T) { testMultiProtoSync(t, eth.ETH68, FullSync) }
|
||||
func TestMultiProtoSynchronisation68Snap(t *testing.T) { testMultiProtoSync(t, eth.ETH68, SnapSync) }
|
||||
func TestMultiProtoSynchronisation68Full(t *testing.T) { testMultiProtoSync(t, eth.ETH69, FullSync) }
|
||||
func TestMultiProtoSynchronisation68Snap(t *testing.T) { testMultiProtoSync(t, eth.ETH69, SnapSync) }
|
||||
|
||||
func testMultiProtoSync(t *testing.T, protocol uint, mode SyncMode) {
|
||||
complete := make(chan struct{})
|
||||
|
|
@ -551,7 +564,7 @@ func testMultiProtoSync(t *testing.T, protocol uint, mode SyncMode) {
|
|||
chain := testChainBase.shorten(blockCacheMaxItems - 15)
|
||||
|
||||
// Create peers of every type
|
||||
tester.newPeer("peer 68", eth.ETH68, chain.blocks[1:])
|
||||
tester.newPeer("peer 68", eth.ETH69, chain.blocks[1:])
|
||||
|
||||
if err := tester.downloader.BeaconSync(chain.blocks[len(chain.blocks)-1].Header(), nil); err != nil {
|
||||
t.Fatalf("failed to start beacon sync: %v", err)
|
||||
|
|
@ -575,8 +588,8 @@ func testMultiProtoSync(t *testing.T, protocol uint, mode SyncMode) {
|
|||
|
||||
// Tests that if a block is empty (e.g. header only), no body request should be
|
||||
// made, and instead the header should be assembled into a whole block in itself.
|
||||
func TestEmptyShortCircuit68Full(t *testing.T) { testEmptyShortCircuit(t, eth.ETH68, FullSync) }
|
||||
func TestEmptyShortCircuit68Snap(t *testing.T) { testEmptyShortCircuit(t, eth.ETH68, SnapSync) }
|
||||
func TestEmptyShortCircuit68Full(t *testing.T) { testEmptyShortCircuit(t, eth.ETH69, FullSync) }
|
||||
func TestEmptyShortCircuit68Snap(t *testing.T) { testEmptyShortCircuit(t, eth.ETH69, SnapSync) }
|
||||
|
||||
func testEmptyShortCircuit(t *testing.T, protocol uint, mode SyncMode) {
|
||||
success := make(chan struct{})
|
||||
|
|
@ -644,8 +657,8 @@ func checkProgress(t *testing.T, d *Downloader, stage string, want ethereum.Sync
|
|||
|
||||
// Tests that peers below a pre-configured checkpoint block are prevented from
|
||||
// being fast-synced from, avoiding potential cheap eclipse attacks.
|
||||
func TestBeaconSync68Full(t *testing.T) { testBeaconSync(t, eth.ETH68, FullSync) }
|
||||
func TestBeaconSync68Snap(t *testing.T) { testBeaconSync(t, eth.ETH68, SnapSync) }
|
||||
func TestBeaconSync68Full(t *testing.T) { testBeaconSync(t, eth.ETH69, FullSync) }
|
||||
func TestBeaconSync68Snap(t *testing.T) { testBeaconSync(t, eth.ETH69, SnapSync) }
|
||||
|
||||
func testBeaconSync(t *testing.T, protocol uint, mode SyncMode) {
|
||||
var cases = []struct {
|
||||
|
|
@ -690,8 +703,8 @@ func testBeaconSync(t *testing.T, protocol uint, mode SyncMode) {
|
|||
|
||||
// Tests that synchronisation progress (origin block number, current block number
|
||||
// and highest block number) is tracked and updated correctly.
|
||||
func TestSyncProgress68Full(t *testing.T) { testSyncProgress(t, eth.ETH68, FullSync) }
|
||||
func TestSyncProgress68Snap(t *testing.T) { testSyncProgress(t, eth.ETH68, SnapSync) }
|
||||
func TestSyncProgress68Full(t *testing.T) { testSyncProgress(t, eth.ETH69, FullSync) }
|
||||
func TestSyncProgress68Snap(t *testing.T) { testSyncProgress(t, eth.ETH69, SnapSync) }
|
||||
|
||||
func testSyncProgress(t *testing.T, protocol uint, mode SyncMode) {
|
||||
success := make(chan struct{})
|
||||
|
|
|
|||
|
|
@ -845,7 +845,7 @@ func TestSkeletonSyncRetrievals(t *testing.T) {
|
|||
// Create a peer set to feed headers through
|
||||
peerset := newPeerSet()
|
||||
for _, peer := range tt.peers {
|
||||
peerset.Register(newPeerConnection(peer.id, eth.ETH68, peer, log.New("id", peer.id)))
|
||||
peerset.Register(newPeerConnection(peer.id, eth.ETH69, peer, log.New("id", peer.id)))
|
||||
}
|
||||
// Create a peer dropper to track malicious peers
|
||||
dropped := make(map[string]int)
|
||||
|
|
@ -912,7 +912,7 @@ func TestSkeletonSyncRetrievals(t *testing.T) {
|
|||
// Apply the post-init events if there's any
|
||||
endpeers := tt.peers
|
||||
if tt.newPeer != nil {
|
||||
if err := peerset.Register(newPeerConnection(tt.newPeer.id, eth.ETH68, tt.newPeer, log.New("id", tt.newPeer.id))); err != nil {
|
||||
if err := peerset.Register(newPeerConnection(tt.newPeer.id, eth.ETH69, tt.newPeer, log.New("id", tt.newPeer.id))); err != nil {
|
||||
t.Errorf("test %d: failed to register new peer: %v", i, err)
|
||||
}
|
||||
time.Sleep(time.Millisecond * 50) // given time for peer registration
|
||||
|
|
|
|||
|
|
@ -38,9 +38,8 @@ import (
|
|||
// testEthHandler is a mock event handler to listen for inbound network requests
|
||||
// on the `eth` protocol and convert them into a more easily testable form.
|
||||
type testEthHandler struct {
|
||||
blockBroadcasts event.Feed
|
||||
txAnnounces event.Feed
|
||||
txBroadcasts event.Feed
|
||||
txAnnounces event.Feed
|
||||
txBroadcasts event.Feed
|
||||
}
|
||||
|
||||
func (h *testEthHandler) Chain() *core.BlockChain { panic("no backing chain") }
|
||||
|
|
@ -51,10 +50,6 @@ func (h *testEthHandler) PeerInfo(enode.ID) interface{} { panic("not used
|
|||
|
||||
func (h *testEthHandler) Handle(peer *eth.Peer, packet eth.Packet) error {
|
||||
switch packet := packet.(type) {
|
||||
case *eth.NewBlockPacket:
|
||||
h.blockBroadcasts.Send(packet.Block)
|
||||
return nil
|
||||
|
||||
case *eth.NewPooledTransactionHashesPacket:
|
||||
h.txAnnounces.Send(packet.Hashes)
|
||||
return nil
|
||||
|
|
@ -82,7 +77,7 @@ func (h *testEthHandler) Handle(peer *eth.Peer, packet eth.Packet) error {
|
|||
|
||||
// Tests that peers are correctly accepted (or rejected) based on the advertised
|
||||
// fork IDs in the protocol handshake.
|
||||
func TestForkIDSplit68(t *testing.T) { testForkIDSplit(t, eth.ETH68) }
|
||||
func TestForkIDSplit69(t *testing.T) { testForkIDSplit(t, eth.ETH69) }
|
||||
|
||||
func testForkIDSplit(t *testing.T, protocol uint) {
|
||||
t.Parallel()
|
||||
|
|
@ -234,7 +229,7 @@ func testForkIDSplit(t *testing.T, protocol uint) {
|
|||
}
|
||||
|
||||
// Tests that received transactions are added to the local pool.
|
||||
func TestRecvTransactions68(t *testing.T) { testRecvTransactions(t, eth.ETH68) }
|
||||
func TestRecvTransactions69(t *testing.T) { testRecvTransactions(t, eth.ETH69) }
|
||||
|
||||
func testRecvTransactions(t *testing.T, protocol uint) {
|
||||
t.Parallel()
|
||||
|
|
@ -263,7 +258,8 @@ func testRecvTransactions(t *testing.T, protocol uint) {
|
|||
return eth.Handle((*ethHandler)(handler.handler), peer)
|
||||
})
|
||||
// Run the handshake locally to avoid spinning up a source handler
|
||||
if err := src.Handshake(1, handler.chain, eth.BlockRangeUpdatePacket{}); err != nil {
|
||||
head := handler.chain.CurrentBlock()
|
||||
if err := src.Handshake(1, handler.chain, eth.BlockRangeUpdatePacket{EarliestBlock: 0, LatestBlock: head.Number.Uint64(), LatestBlockHash: head.Hash()}); err != nil {
|
||||
t.Fatalf("failed to run protocol handshake")
|
||||
}
|
||||
// Send the transaction to the sink and verify that it's added to the tx pool
|
||||
|
|
@ -286,7 +282,7 @@ func testRecvTransactions(t *testing.T, protocol uint) {
|
|||
}
|
||||
|
||||
// This test checks that pending transactions are sent.
|
||||
func TestSendTransactions68(t *testing.T) { testSendTransactions(t, eth.ETH68) }
|
||||
func TestSendTransactions69(t *testing.T) { testSendTransactions(t, eth.ETH69) }
|
||||
|
||||
func testSendTransactions(t *testing.T, protocol uint) {
|
||||
t.Parallel()
|
||||
|
|
@ -318,7 +314,8 @@ func testSendTransactions(t *testing.T, protocol uint) {
|
|||
return eth.Handle((*ethHandler)(handler.handler), peer)
|
||||
})
|
||||
// Run the handshake locally to avoid spinning up a source handler
|
||||
if err := sink.Handshake(1, handler.chain, eth.BlockRangeUpdatePacket{}); err != nil {
|
||||
head := handler.chain.CurrentBlock()
|
||||
if err := sink.Handshake(1, handler.chain, eth.BlockRangeUpdatePacket{EarliestBlock: 0, LatestBlock: head.Number.Uint64(), LatestBlockHash: head.Hash()}); err != nil {
|
||||
t.Fatalf("failed to run protocol handshake")
|
||||
}
|
||||
// After the handshake completes, the source handler should stream the sink
|
||||
|
|
@ -338,22 +335,16 @@ func testSendTransactions(t *testing.T, protocol uint) {
|
|||
// Make sure we get all the transactions on the correct channels
|
||||
seen := make(map[common.Hash]struct{})
|
||||
for len(seen) < len(insert) {
|
||||
switch protocol {
|
||||
case 68:
|
||||
select {
|
||||
case hashes := <-anns:
|
||||
for _, hash := range hashes {
|
||||
if _, ok := seen[hash]; ok {
|
||||
t.Errorf("duplicate transaction announced: %x", hash)
|
||||
}
|
||||
seen[hash] = struct{}{}
|
||||
select {
|
||||
case hashes := <-anns:
|
||||
for _, hash := range hashes {
|
||||
if _, ok := seen[hash]; ok {
|
||||
t.Errorf("duplicate transaction announced: %x", hash)
|
||||
}
|
||||
case <-bcasts:
|
||||
t.Errorf("initial tx broadcast received on post eth/66")
|
||||
seen[hash] = struct{}{}
|
||||
}
|
||||
|
||||
default:
|
||||
panic("unsupported protocol, please extend test")
|
||||
case <-bcasts:
|
||||
t.Errorf("initial tx broadcast received on post eth/66")
|
||||
}
|
||||
}
|
||||
for _, tx := range insert {
|
||||
|
|
@ -365,7 +356,7 @@ func testSendTransactions(t *testing.T, protocol uint) {
|
|||
|
||||
// Tests that transactions get propagated to all attached peers, either via direct
|
||||
// broadcasts or via announcements/retrievals.
|
||||
func TestTransactionPropagation68(t *testing.T) { testTransactionPropagation(t, eth.ETH68) }
|
||||
func TestTransactionPropagation69(t *testing.T) { testTransactionPropagation(t, eth.ETH69) }
|
||||
|
||||
func testTransactionPropagation(t *testing.T, protocol uint) {
|
||||
t.Parallel()
|
||||
|
|
|
|||
|
|
@ -166,21 +166,6 @@ type Decoder interface {
|
|||
Time() time.Time
|
||||
}
|
||||
|
||||
var eth68 = map[uint64]msgHandler{
|
||||
NewBlockHashesMsg: handleNewBlockhashes,
|
||||
NewBlockMsg: handleNewBlock,
|
||||
TransactionsMsg: handleTransactions,
|
||||
NewPooledTransactionHashesMsg: handleNewPooledTransactionHashes,
|
||||
GetBlockHeadersMsg: handleGetBlockHeaders,
|
||||
BlockHeadersMsg: handleBlockHeaders,
|
||||
GetBlockBodiesMsg: handleGetBlockBodies,
|
||||
BlockBodiesMsg: handleBlockBodies,
|
||||
GetReceiptsMsg: handleGetReceipts68,
|
||||
ReceiptsMsg: handleReceipts[*ReceiptList68],
|
||||
GetPooledTransactionsMsg: handleGetPooledTransactions,
|
||||
PooledTransactionsMsg: handlePooledTransactions,
|
||||
}
|
||||
|
||||
var eth69 = map[uint64]msgHandler{
|
||||
TransactionsMsg: handleTransactions,
|
||||
NewPooledTransactionHashesMsg: handleNewPooledTransactionHashes,
|
||||
|
|
@ -188,8 +173,8 @@ var eth69 = map[uint64]msgHandler{
|
|||
BlockHeadersMsg: handleBlockHeaders,
|
||||
GetBlockBodiesMsg: handleGetBlockBodies,
|
||||
BlockBodiesMsg: handleBlockBodies,
|
||||
GetReceiptsMsg: handleGetReceipts69,
|
||||
ReceiptsMsg: handleReceipts[*ReceiptList69],
|
||||
GetReceiptsMsg: handleGetReceipts,
|
||||
ReceiptsMsg: handleReceipts,
|
||||
GetPooledTransactionsMsg: handleGetPooledTransactions,
|
||||
PooledTransactionsMsg: handlePooledTransactions,
|
||||
BlockRangeUpdateMsg: handleBlockRangeUpdate,
|
||||
|
|
@ -209,9 +194,7 @@ func handleMessage(backend Backend, peer *Peer) error {
|
|||
defer msg.Discard()
|
||||
|
||||
var handlers map[uint64]msgHandler
|
||||
if peer.version == ETH68 {
|
||||
handlers = eth68
|
||||
} else if peer.version == ETH69 {
|
||||
if peer.version == ETH69 {
|
||||
handlers = eth69
|
||||
} else {
|
||||
return fmt.Errorf("unknown eth protocol version: %v", peer.version)
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ func (b *testBackend) Handle(*Peer, Packet) error {
|
|||
}
|
||||
|
||||
// Tests that block headers can be retrieved from a remote chain based on user queries.
|
||||
func TestGetBlockHeaders68(t *testing.T) { testGetBlockHeaders(t, ETH68) }
|
||||
func TestGetBlockHeaders69(t *testing.T) { testGetBlockHeaders(t, ETH69) }
|
||||
|
||||
func testGetBlockHeaders(t *testing.T, protocol uint) {
|
||||
t.Parallel()
|
||||
|
|
@ -387,7 +387,7 @@ func testGetBlockHeaders(t *testing.T, protocol uint) {
|
|||
}
|
||||
|
||||
// Tests that block contents can be retrieved from a remote chain based on their hashes.
|
||||
func TestGetBlockBodies68(t *testing.T) { testGetBlockBodies(t, ETH68) }
|
||||
func TestGetBlockBodies69(t *testing.T) { testGetBlockBodies(t, ETH69) }
|
||||
|
||||
func testGetBlockBodies(t *testing.T, protocol uint) {
|
||||
t.Parallel()
|
||||
|
|
@ -536,7 +536,7 @@ func TestHashBody(t *testing.T) {
|
|||
}
|
||||
|
||||
// Tests that the transaction receipts can be retrieved based on hashes.
|
||||
func TestGetBlockReceipts68(t *testing.T) { testGetBlockReceipts(t, ETH68) }
|
||||
func TestGetBlockReceipts69(t *testing.T) { testGetBlockReceipts(t, ETH69) }
|
||||
|
||||
func testGetBlockReceipts(t *testing.T, protocol uint) {
|
||||
t.Parallel()
|
||||
|
|
@ -586,13 +586,16 @@ func testGetBlockReceipts(t *testing.T, protocol uint) {
|
|||
// Collect the hashes to request, and the response to expect
|
||||
var (
|
||||
hashes []common.Hash
|
||||
receipts rlp.RawList[*ReceiptList68]
|
||||
receipts []rlp.RawValue
|
||||
)
|
||||
for i := uint64(0); i <= backend.chain.CurrentBlock().Number.Uint64(); i++ {
|
||||
block := backend.chain.GetBlockByNumber(i)
|
||||
hashes = append(hashes, block.Hash())
|
||||
trs := backend.chain.GetReceiptsByHash(block.Hash())
|
||||
receipts.Append(NewReceiptList68(trs))
|
||||
|
||||
receiptsRLP := backend.chain.GetReceiptsRLP(block.Hash())
|
||||
bodyRLP := backend.chain.GetBodyRLP(block.Hash())
|
||||
tr, _ := encodeTypes(receiptsRLP, bodyRLP)
|
||||
receipts = append(receipts, tr)
|
||||
}
|
||||
|
||||
// Send the hash request and verify the response
|
||||
|
|
@ -600,9 +603,9 @@ func testGetBlockReceipts(t *testing.T, protocol uint) {
|
|||
RequestId: 123,
|
||||
GetReceiptsRequest: hashes,
|
||||
})
|
||||
if err := p2p.ExpectMsg(peer.app, ReceiptsMsg, &ReceiptsPacket[*ReceiptList68]{
|
||||
RequestId: 123,
|
||||
List: receipts,
|
||||
if err := p2p.ExpectMsg(peer.app, ReceiptsMsg, &ReceiptsRLPPacket{
|
||||
RequestId: 123,
|
||||
ReceiptsRLPResponse: receipts,
|
||||
}); err != nil {
|
||||
t.Errorf("receipts mismatch: %v", err)
|
||||
}
|
||||
|
|
@ -656,7 +659,7 @@ func setup() (*testBackend, *testPeer) {
|
|||
}
|
||||
}
|
||||
backend := newTestBackendWithGenerator(maxBodiesServe+15, true, false, gen)
|
||||
peer, _ := newTestPeer("peer", ETH68, backend)
|
||||
peer, _ := newTestPeer("peer", ETH69, backend)
|
||||
// Discard all messages
|
||||
go func() {
|
||||
for {
|
||||
|
|
@ -701,7 +704,7 @@ func testGetPooledTransaction(t *testing.T, blobTx bool) {
|
|||
backend := newTestBackendWithGenerator(0, true, true, nil)
|
||||
defer backend.close()
|
||||
|
||||
peer, _ := newTestPeer("peer", ETH68, backend)
|
||||
peer, _ := newTestPeer("peer", ETH69, backend)
|
||||
defer peer.close()
|
||||
|
||||
var (
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ package eth
|
|||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
|
|
@ -247,29 +246,20 @@ func ServiceGetBlockBodiesQuery(chain *core.BlockChain, query GetBlockBodiesRequ
|
|||
return bodies
|
||||
}
|
||||
|
||||
func handleGetReceipts68(backend Backend, msg Decoder, peer *Peer) error {
|
||||
func handleGetReceipts(backend Backend, msg Decoder, peer *Peer) error {
|
||||
// Decode the block receipts retrieval message
|
||||
var query GetReceiptsPacket
|
||||
if err := msg.Decode(&query); err != nil {
|
||||
return err
|
||||
}
|
||||
response := ServiceGetReceiptsQuery68(backend.Chain(), query.GetReceiptsRequest)
|
||||
response := ServiceGetReceiptsQuery(backend.Chain(), query.GetReceiptsRequest)
|
||||
return peer.ReplyReceiptsRLP(query.RequestId, response)
|
||||
}
|
||||
|
||||
func handleGetReceipts69(backend Backend, msg Decoder, peer *Peer) error {
|
||||
// Decode the block receipts retrieval message
|
||||
var query GetReceiptsPacket
|
||||
if err := msg.Decode(&query); err != nil {
|
||||
return err
|
||||
}
|
||||
response := serviceGetReceiptsQuery69(backend.Chain(), query.GetReceiptsRequest)
|
||||
return peer.ReplyReceiptsRLP(query.RequestId, response)
|
||||
}
|
||||
|
||||
// ServiceGetReceiptsQuery68 assembles the response to a receipt query. It is
|
||||
// exposed to allow external packages to test protocol behavior.
|
||||
func ServiceGetReceiptsQuery68(chain *core.BlockChain, query GetReceiptsRequest) []rlp.RawValue {
|
||||
// ServiceGetReceiptsQuery assembles the response to a receipt query.
|
||||
// It does not send the bloom filters for the receipts. It is exposed
|
||||
// to allow external packages to test protocol behavior.
|
||||
func ServiceGetReceiptsQuery(chain *core.BlockChain, query GetReceiptsRequest) []rlp.RawValue {
|
||||
// Gather state data until the fetch or network limits is reached
|
||||
var (
|
||||
bytes int
|
||||
|
|
@ -292,7 +282,7 @@ func ServiceGetReceiptsQuery68(chain *core.BlockChain, query GetReceiptsRequest)
|
|||
continue
|
||||
}
|
||||
var err error
|
||||
results, err = blockReceiptsToNetwork68(results, body)
|
||||
results, err = encodeTypes(results, body)
|
||||
if err != nil {
|
||||
log.Error("Error in block receipts conversion", "hash", hash, "err", err)
|
||||
continue
|
||||
|
|
@ -304,51 +294,6 @@ func ServiceGetReceiptsQuery68(chain *core.BlockChain, query GetReceiptsRequest)
|
|||
return receipts
|
||||
}
|
||||
|
||||
// serviceGetReceiptsQuery69 assembles the response to a receipt query.
|
||||
// It does not send the bloom filters for the receipts
|
||||
func serviceGetReceiptsQuery69(chain *core.BlockChain, query GetReceiptsRequest) []rlp.RawValue {
|
||||
// Gather state data until the fetch or network limits is reached
|
||||
var (
|
||||
bytes int
|
||||
receipts []rlp.RawValue
|
||||
)
|
||||
for lookups, hash := range query {
|
||||
if bytes >= softResponseLimit || len(receipts) >= maxReceiptsServe ||
|
||||
lookups >= 2*maxReceiptsServe {
|
||||
break
|
||||
}
|
||||
// Retrieve the requested block's receipts
|
||||
results := chain.GetReceiptsRLP(hash)
|
||||
if results == nil {
|
||||
if header := chain.GetHeaderByHash(hash); header == nil || header.ReceiptHash != types.EmptyRootHash {
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
body := chain.GetBodyRLP(hash)
|
||||
if body == nil {
|
||||
continue
|
||||
}
|
||||
var err error
|
||||
results, err = blockReceiptsToNetwork69(results, body)
|
||||
if err != nil {
|
||||
log.Error("Error in block receipts conversion", "hash", hash, "err", err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
receipts = append(receipts, results)
|
||||
bytes += len(results)
|
||||
}
|
||||
return receipts
|
||||
}
|
||||
|
||||
func handleNewBlockhashes(backend Backend, msg Decoder, peer *Peer) error {
|
||||
return errors.New("block announcements disallowed") // We dropped support for non-merge networks
|
||||
}
|
||||
|
||||
func handleNewBlock(backend Backend, msg Decoder, peer *Peer) error {
|
||||
return errors.New("block broadcasts disallowed") // We dropped support for non-merge networks
|
||||
}
|
||||
|
||||
func handleBlockHeaders(backend Backend, msg Decoder, peer *Peer) error {
|
||||
// A batch of headers arrived to one of our previous requests
|
||||
res := new(BlockHeadersPacket)
|
||||
|
|
@ -490,9 +435,19 @@ func writeTxForHash(tx []byte, buf *bytes.Buffer) {
|
|||
}
|
||||
}
|
||||
|
||||
func handleReceipts[L ReceiptsList](backend Backend, msg Decoder, peer *Peer) error {
|
||||
// writeReceiptForHash returns a write function that encode receipts for hash derivation.
|
||||
func writeReceiptForHash(bloomBuf *[6]byte) func([]byte, *bytes.Buffer) {
|
||||
return func(data []byte, outbuf *bytes.Buffer) {
|
||||
var r Receipt
|
||||
if rlp.DecodeBytes(data, &r) == nil {
|
||||
r.EncodeForHash(bloomBuf, outbuf)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func handleReceipts(backend Backend, msg Decoder, peer *Peer) error {
|
||||
// A batch of receipts arrived to one of our previous requests
|
||||
res := new(ReceiptsPacket[L])
|
||||
res := new(ReceiptsPacket)
|
||||
if err := msg.Decode(res); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -502,25 +457,23 @@ func handleReceipts[L ReceiptsList](backend Backend, msg Decoder, peer *Peer) er
|
|||
return fmt.Errorf("Receipts: %w", err)
|
||||
}
|
||||
|
||||
// Assign temporary hashing buffer to each list item, the same buffer is shared
|
||||
// between all receipt list instances.
|
||||
receiptLists, err := res.List.Items()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Receipts: %w", err)
|
||||
}
|
||||
buffers := new(receiptListBuffers)
|
||||
for i := range receiptLists {
|
||||
receiptLists[i].setBuffers(buffers)
|
||||
}
|
||||
|
||||
var bloomBuf [6]byte
|
||||
writeReceipt := writeReceiptForHash(&bloomBuf)
|
||||
metadata := func() interface{} {
|
||||
hasher := trie.NewStackTrie(nil)
|
||||
hashes := make([]common.Hash, len(receiptLists))
|
||||
for i := range receiptLists {
|
||||
hashes[i] = types.DeriveSha(receiptLists[i].Derivable(), hasher)
|
||||
receipts := newDerivableRawList(&receiptLists[i].items, writeReceipt)
|
||||
hashes[i] = types.DeriveSha(receipts, hasher)
|
||||
}
|
||||
return hashes
|
||||
}
|
||||
|
||||
var enc ReceiptsRLPResponse
|
||||
for i := range receiptLists {
|
||||
encReceipts, err := receiptLists[i].EncodeForStorage()
|
||||
|
|
|
|||
|
|
@ -36,62 +36,6 @@ const (
|
|||
// Handshake executes the eth protocol handshake, negotiating version number,
|
||||
// network IDs, difficulties, head and genesis blocks.
|
||||
func (p *Peer) Handshake(networkID uint64, chain forkid.Blockchain, rangeMsg BlockRangeUpdatePacket) error {
|
||||
switch p.version {
|
||||
case ETH69:
|
||||
return p.handshake69(networkID, chain, rangeMsg)
|
||||
case ETH68:
|
||||
return p.handshake68(networkID, chain)
|
||||
default:
|
||||
return errors.New("unsupported protocol version")
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Peer) handshake68(networkID uint64, chain forkid.Blockchain) error {
|
||||
var (
|
||||
genesis = chain.Genesis()
|
||||
latest = chain.CurrentHeader()
|
||||
forkID = forkid.NewID(chain.Config(), genesis, latest.Number.Uint64(), latest.Time)
|
||||
forkFilter = forkid.NewFilter(chain)
|
||||
)
|
||||
errc := make(chan error, 2)
|
||||
go func() {
|
||||
pkt := &StatusPacket68{
|
||||
ProtocolVersion: uint32(p.version),
|
||||
NetworkID: networkID,
|
||||
Head: latest.Hash(),
|
||||
Genesis: genesis.Hash(),
|
||||
ForkID: forkID,
|
||||
}
|
||||
errc <- p2p.Send(p.rw, StatusMsg, pkt)
|
||||
}()
|
||||
var status StatusPacket68 // safe to read after two values have been received from errc
|
||||
go func() {
|
||||
errc <- p.readStatus68(networkID, &status, genesis.Hash(), forkFilter)
|
||||
}()
|
||||
|
||||
return waitForHandshake(errc, p)
|
||||
}
|
||||
|
||||
func (p *Peer) readStatus68(networkID uint64, status *StatusPacket68, genesis common.Hash, forkFilter forkid.Filter) error {
|
||||
if err := p.readStatusMsg(status); err != nil {
|
||||
return err
|
||||
}
|
||||
if status.NetworkID != networkID {
|
||||
return fmt.Errorf("%w: %d (!= %d)", errNetworkIDMismatch, status.NetworkID, networkID)
|
||||
}
|
||||
if uint(status.ProtocolVersion) != p.version {
|
||||
return fmt.Errorf("%w: %d (!= %d)", errProtocolVersionMismatch, status.ProtocolVersion, p.version)
|
||||
}
|
||||
if status.Genesis != genesis {
|
||||
return fmt.Errorf("%w: %x (!= %x)", errGenesisMismatch, status.Genesis, genesis)
|
||||
}
|
||||
if err := forkFilter(status.ForkID); err != nil {
|
||||
return fmt.Errorf("%w: %v", errForkIDRejected, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Peer) handshake69(networkID uint64, chain forkid.Blockchain, rangeMsg BlockRangeUpdatePacket) error {
|
||||
var (
|
||||
genesis = chain.Genesis()
|
||||
latest = chain.CurrentHeader()
|
||||
|
|
@ -101,7 +45,7 @@ func (p *Peer) handshake69(networkID uint64, chain forkid.Blockchain, rangeMsg B
|
|||
|
||||
errc := make(chan error, 2)
|
||||
go func() {
|
||||
pkt := &StatusPacket69{
|
||||
pkt := &StatusPacket{
|
||||
ProtocolVersion: uint32(p.version),
|
||||
NetworkID: networkID,
|
||||
Genesis: genesis.Hash(),
|
||||
|
|
@ -112,15 +56,15 @@ func (p *Peer) handshake69(networkID uint64, chain forkid.Blockchain, rangeMsg B
|
|||
}
|
||||
errc <- p2p.Send(p.rw, StatusMsg, pkt)
|
||||
}()
|
||||
var status StatusPacket69 // safe to read after two values have been received from errc
|
||||
var status StatusPacket // safe to read after two values have been received from errc
|
||||
go func() {
|
||||
errc <- p.readStatus69(networkID, &status, genesis.Hash(), forkFilter)
|
||||
errc <- p.readStatus(networkID, &status, genesis.Hash(), forkFilter)
|
||||
}()
|
||||
|
||||
return waitForHandshake(errc, p)
|
||||
}
|
||||
|
||||
func (p *Peer) readStatus69(networkID uint64, status *StatusPacket69, genesis common.Hash, forkFilter forkid.Filter) error {
|
||||
func (p *Peer) readStatus(networkID uint64, status *StatusPacket, genesis common.Hash, forkFilter forkid.Filter) error {
|
||||
if err := p.readStatusMsg(status); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ package eth
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
|
@ -28,7 +27,7 @@ import (
|
|||
)
|
||||
|
||||
// Tests that handshake failures are detected and reported correctly.
|
||||
func TestHandshake68(t *testing.T) { testHandshake(t, ETH68) }
|
||||
func TestHandshake69(t *testing.T) { testHandshake(t, ETH69) }
|
||||
|
||||
func testHandshake(t *testing.T, protocol uint) {
|
||||
t.Parallel()
|
||||
|
|
@ -52,21 +51,25 @@ func testHandshake(t *testing.T, protocol uint) {
|
|||
want: errNoStatusMsg,
|
||||
},
|
||||
{
|
||||
code: StatusMsg, data: StatusPacket68{10, 1, new(big.Int), head.Hash(), genesis.Hash(), forkID},
|
||||
code: StatusMsg, data: StatusPacket{10, 1, genesis.Hash(), forkID, 0, head.Number.Uint64(), head.Hash()},
|
||||
want: errProtocolVersionMismatch,
|
||||
},
|
||||
{
|
||||
code: StatusMsg, data: StatusPacket68{uint32(protocol), 999, new(big.Int), head.Hash(), genesis.Hash(), forkID},
|
||||
code: StatusMsg, data: StatusPacket{uint32(protocol), 999, genesis.Hash(), forkID, 0, head.Number.Uint64(), head.Hash()},
|
||||
want: errNetworkIDMismatch,
|
||||
},
|
||||
{
|
||||
code: StatusMsg, data: StatusPacket68{uint32(protocol), 1, new(big.Int), head.Hash(), common.Hash{3}, forkID},
|
||||
code: StatusMsg, data: StatusPacket{uint32(protocol), 1, common.Hash{3}, forkID, 0, head.Number.Uint64(), head.Hash()},
|
||||
want: errGenesisMismatch,
|
||||
},
|
||||
{
|
||||
code: StatusMsg, data: StatusPacket68{uint32(protocol), 1, new(big.Int), head.Hash(), genesis.Hash(), forkid.ID{Hash: [4]byte{0x00, 0x01, 0x02, 0x03}}},
|
||||
code: StatusMsg, data: StatusPacket{uint32(protocol), 1, genesis.Hash(), forkid.ID{Hash: [4]byte{0x00, 0x01, 0x02, 0x03}}, 0, head.Number.Uint64(), head.Hash()},
|
||||
want: errForkIDRejected,
|
||||
},
|
||||
{
|
||||
code: StatusMsg, data: StatusPacket{uint32(protocol), 1, genesis.Hash(), forkID, head.Number.Uint64() + 1, head.Number.Uint64(), head.Hash()},
|
||||
want: errInvalidBlockRange,
|
||||
},
|
||||
}
|
||||
for i, test := range tests {
|
||||
// Create the two peers to shake with each other
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/forkid"
|
||||
|
|
@ -30,7 +29,6 @@ import (
|
|||
|
||||
// Constants to match up protocol versions and messages
|
||||
const (
|
||||
ETH68 = 68
|
||||
ETH69 = 69
|
||||
)
|
||||
|
||||
|
|
@ -40,11 +38,11 @@ const ProtocolName = "eth"
|
|||
|
||||
// ProtocolVersions are the supported versions of the `eth` protocol (first
|
||||
// is primary).
|
||||
var ProtocolVersions = []uint{ETH69, ETH68}
|
||||
var ProtocolVersions = []uint{ETH69}
|
||||
|
||||
// protocolLengths are the number of implemented message corresponding to
|
||||
// different protocol versions.
|
||||
var protocolLengths = map[uint]uint64{ETH68: 17, ETH69: 18}
|
||||
var protocolLengths = map[uint]uint64{ETH69: 18}
|
||||
|
||||
// maxMessageSize is the maximum cap on the size of a protocol message.
|
||||
const maxMessageSize = 10 * 1024 * 1024
|
||||
|
|
@ -88,17 +86,7 @@ type Packet interface {
|
|||
}
|
||||
|
||||
// StatusPacket is the network packet for the status message.
|
||||
type StatusPacket68 struct {
|
||||
ProtocolVersion uint32
|
||||
NetworkID uint64
|
||||
TD *big.Int
|
||||
Head common.Hash
|
||||
Genesis common.Hash
|
||||
ForkID forkid.ID
|
||||
}
|
||||
|
||||
// StatusPacket69 is the network packet for the status message.
|
||||
type StatusPacket69 struct {
|
||||
type StatusPacket struct {
|
||||
ProtocolVersion uint32
|
||||
NetworkID uint64
|
||||
Genesis common.Hash
|
||||
|
|
@ -109,26 +97,6 @@ type StatusPacket69 struct {
|
|||
LatestBlockHash common.Hash
|
||||
}
|
||||
|
||||
// NewBlockHashesPacket is the network packet for the block announcements.
|
||||
type NewBlockHashesPacket []struct {
|
||||
Hash common.Hash // Hash of one particular block being announced
|
||||
Number uint64 // Number of one particular block being announced
|
||||
}
|
||||
|
||||
// Unpack retrieves the block hashes and numbers from the announcement packet
|
||||
// and returns them in a split flat format that's more consistent with the
|
||||
// internal data structures.
|
||||
func (p *NewBlockHashesPacket) Unpack() ([]common.Hash, []uint64) {
|
||||
var (
|
||||
hashes = make([]common.Hash, len(*p))
|
||||
numbers = make([]uint64, len(*p))
|
||||
)
|
||||
for i, body := range *p {
|
||||
hashes[i], numbers[i] = body.Hash, body.Number
|
||||
}
|
||||
return hashes, numbers
|
||||
}
|
||||
|
||||
// TransactionsPacket is the network packet for broadcasting new transactions.
|
||||
type TransactionsPacket struct {
|
||||
rlp.RawList[*types.Transaction]
|
||||
|
|
@ -203,12 +171,6 @@ type BlockHeadersRLPPacket struct {
|
|||
BlockHeadersRLPResponse
|
||||
}
|
||||
|
||||
// NewBlockPacket is the network packet for the block propagation message.
|
||||
type NewBlockPacket struct {
|
||||
Block *types.Block
|
||||
TD *big.Int
|
||||
}
|
||||
|
||||
// GetBlockBodiesRequest represents a block body query.
|
||||
type GetBlockBodiesRequest []common.Hash
|
||||
|
||||
|
|
@ -258,19 +220,11 @@ type GetReceiptsPacket struct {
|
|||
// ReceiptsResponse is the network packet for block receipts distribution.
|
||||
type ReceiptsResponse []types.Receipts
|
||||
|
||||
// ReceiptsList is a type constraint for block receceipt list types.
|
||||
type ReceiptsList interface {
|
||||
*ReceiptList68 | *ReceiptList69
|
||||
setBuffers(*receiptListBuffers)
|
||||
EncodeForStorage() (rlp.RawValue, error)
|
||||
Derivable() types.DerivableList
|
||||
}
|
||||
|
||||
// ReceiptsPacket is the network packet for block receipts distribution with
|
||||
// request ID wrapping.
|
||||
type ReceiptsPacket[L ReceiptsList] struct {
|
||||
type ReceiptsPacket struct {
|
||||
RequestId uint64
|
||||
List rlp.RawList[L]
|
||||
List rlp.RawList[*ReceiptList]
|
||||
}
|
||||
|
||||
// ReceiptsRLPResponse is used for receipts, when we already have it encoded
|
||||
|
|
@ -325,14 +279,8 @@ type BlockRangeUpdatePacket struct {
|
|||
LatestBlockHash common.Hash
|
||||
}
|
||||
|
||||
func (*StatusPacket68) Name() string { return "Status" }
|
||||
func (*StatusPacket68) Kind() byte { return StatusMsg }
|
||||
|
||||
func (*StatusPacket69) Name() string { return "Status" }
|
||||
func (*StatusPacket69) Kind() byte { return StatusMsg }
|
||||
|
||||
func (*NewBlockHashesPacket) Name() string { return "NewBlockHashes" }
|
||||
func (*NewBlockHashesPacket) Kind() byte { return NewBlockHashesMsg }
|
||||
func (*StatusPacket) Name() string { return "Status" }
|
||||
func (*StatusPacket) Kind() byte { return StatusMsg }
|
||||
|
||||
func (*TransactionsPacket) Name() string { return "Transactions" }
|
||||
func (*TransactionsPacket) Kind() byte { return TransactionsMsg }
|
||||
|
|
@ -349,9 +297,6 @@ func (*GetBlockBodiesRequest) Kind() byte { return GetBlockBodiesMsg }
|
|||
func (*BlockBodiesResponse) Name() string { return "BlockBodies" }
|
||||
func (*BlockBodiesResponse) Kind() byte { return BlockBodiesMsg }
|
||||
|
||||
func (*NewBlockPacket) Name() string { return "NewBlock" }
|
||||
func (*NewBlockPacket) Kind() byte { return NewBlockMsg }
|
||||
|
||||
func (*NewPooledTransactionHashesPacket) Name() string { return "NewPooledTransactionHashes" }
|
||||
func (*NewPooledTransactionHashesPacket) Kind() byte { return NewPooledTransactionHashesMsg }
|
||||
|
||||
|
|
|
|||
|
|
@ -95,8 +95,7 @@ func TestEmptyMessages(t *testing.T) {
|
|||
BlockBodiesRLPPacket{1111, BlockBodiesRLPResponse([]rlp.RawValue{})},
|
||||
// Receipts
|
||||
GetReceiptsPacket{1111, GetReceiptsRequest([]common.Hash{})},
|
||||
ReceiptsPacket[*ReceiptList68]{1111, encodeRL([]*ReceiptList68{})},
|
||||
ReceiptsPacket[*ReceiptList69]{1111, encodeRL([]*ReceiptList69{})},
|
||||
ReceiptsPacket{1111, encodeRL([]*ReceiptList{})},
|
||||
// Transactions
|
||||
GetPooledTransactionsPacket{1111, GetPooledTransactionsRequest([]common.Hash{})},
|
||||
PooledTransactionsPacket{1111, encodeRL([]*types.Transaction{})},
|
||||
|
|
@ -231,16 +230,11 @@ func TestMessages(t *testing.T) {
|
|||
common.FromHex("f847820457f842a000000000000000000000000000000000000000000000000000000000deadc0dea000000000000000000000000000000000000000000000000000000000feedbeef"),
|
||||
},
|
||||
{
|
||||
ReceiptsPacket[*ReceiptList68]{1111, encodeRL([]*ReceiptList68{NewReceiptList68(receipts)})},
|
||||
common.FromHex("f902e6820457f902e0f902ddf901688082014db9010000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000004000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000f85ff85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100ffb9016f01f9016b018201bcb9010000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000001000000000000000000000000000000000000000000000000040000000000000000000000000004000000000000000000000000000000000000000000000000000000008000400000000000000000000000000000000000000000000000000000000000000000000000000000040f862f860940000000000000000000000000000000000000022f842a00000000000000000000000000000000000000000000000000000000000005668a0000000000000000000000000000000000000000000000000000000000000977386020f0f0f0608"),
|
||||
},
|
||||
{
|
||||
// Identical to the eth/68 encoding above.
|
||||
ReceiptsRLPPacket{1111, ReceiptsRLPResponse([]rlp.RawValue{receiptsRlp})},
|
||||
common.FromHex("f902e6820457f902e0f902ddf901688082014db9010000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000004000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000f85ff85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100ffb9016f01f9016b018201bcb9010000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000001000000000000000000000000000000000000000000000000040000000000000000000000000004000000000000000000000000000000000000000000000000000000008000400000000000000000000000000000000000000000000000000000000000000000000000000000040f862f860940000000000000000000000000000000000000022f842a00000000000000000000000000000000000000000000000000000000000005668a0000000000000000000000000000000000000000000000000000000000000977386020f0f0f0608"),
|
||||
},
|
||||
{
|
||||
ReceiptsPacket[*ReceiptList69]{1111, encodeRL([]*ReceiptList69{NewReceiptList69(receipts)})},
|
||||
ReceiptsPacket{1111, encodeRL([]*ReceiptList{NewReceiptList(receipts)})},
|
||||
common.FromHex("f8da820457f8d5f8d3f866808082014df85ff85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100fff86901018201bcf862f860940000000000000000000000000000000000000022f842a00000000000000000000000000000000000000000000000000000000000005668a0000000000000000000000000000000000000000000000000000000000000977386020f0f0f0608"),
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -27,9 +27,6 @@ import (
|
|||
"github.com/ethereum/go-ethereum/rlp"
|
||||
)
|
||||
|
||||
// This is just a sanity limit for the size of a single receipt.
|
||||
const maxReceiptSize = 16 * 1024 * 1024
|
||||
|
||||
// Receipt is the representation of receipts for networking purposes.
|
||||
type Receipt struct {
|
||||
TxType byte
|
||||
|
|
@ -49,154 +46,18 @@ func newReceipt(tr *types.Receipt) Receipt {
|
|||
return r
|
||||
}
|
||||
|
||||
// decode68 parses a receipt in the eth/68 network encoding.
|
||||
func (r *Receipt) decode68(b []byte) error {
|
||||
k, content, _, err := rlp.Split(b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*r = Receipt{}
|
||||
if k == rlp.List {
|
||||
// Legacy receipt.
|
||||
return r.decodeInnerList(b, false, true)
|
||||
}
|
||||
// Typed receipt.
|
||||
if len(content) < 2 || len(content) > maxReceiptSize {
|
||||
return fmt.Errorf("invalid receipt size %d", len(content))
|
||||
}
|
||||
r.TxType = content[0]
|
||||
return r.decodeInnerList(content[1:], false, true)
|
||||
}
|
||||
|
||||
// decode69 parses a receipt in the eth/69 network encoding.
|
||||
func (r *Receipt) decode69(b []byte) error {
|
||||
*r = Receipt{}
|
||||
return r.decodeInnerList(b, true, false)
|
||||
}
|
||||
|
||||
// decodeDatabase parses a receipt in the basic database encoding.
|
||||
func (r *Receipt) decodeDatabase(txType byte, b []byte) error {
|
||||
*r = Receipt{TxType: txType}
|
||||
return r.decodeInnerList(b, false, false)
|
||||
}
|
||||
|
||||
func (r *Receipt) decodeInnerList(input []byte, readTxType, readBloom bool) error {
|
||||
input, _, err := rlp.SplitList(input)
|
||||
if err != nil {
|
||||
return fmt.Errorf("inner list: %v", err)
|
||||
}
|
||||
|
||||
// txType
|
||||
if readTxType {
|
||||
var txType uint64
|
||||
txType, input, err = rlp.SplitUint64(input)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid txType: %w", err)
|
||||
}
|
||||
if txType > 0x7f {
|
||||
return fmt.Errorf("invalid txType: too large")
|
||||
}
|
||||
r.TxType = byte(txType)
|
||||
}
|
||||
|
||||
// status
|
||||
r.PostStateOrStatus, input, err = rlp.SplitString(input)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid postStateOrStatus: %w", err)
|
||||
}
|
||||
if len(r.PostStateOrStatus) > 1 && len(r.PostStateOrStatus) != 32 {
|
||||
return fmt.Errorf("invalid postStateOrStatus length %d", len(r.PostStateOrStatus))
|
||||
}
|
||||
|
||||
// gas
|
||||
r.GasUsed, input, err = rlp.SplitUint64(input)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid gasUsed: %w", err)
|
||||
}
|
||||
|
||||
// bloom
|
||||
if readBloom {
|
||||
var bloomBytes []byte
|
||||
bloomBytes, input, err = rlp.SplitString(input)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid bloom: %v", err)
|
||||
}
|
||||
if len(bloomBytes) != types.BloomByteLength {
|
||||
return fmt.Errorf("invalid bloom length %d", len(bloomBytes))
|
||||
}
|
||||
}
|
||||
|
||||
// logs
|
||||
_, rest, err := rlp.SplitList(input)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid logs: %w", err)
|
||||
}
|
||||
if len(rest) != 0 {
|
||||
return fmt.Errorf("junk at end of receipt")
|
||||
}
|
||||
r.Logs = input
|
||||
return nil
|
||||
}
|
||||
|
||||
// encodeForStorage produces the the storage encoding, i.e. the result matches
|
||||
// the RLP encoding of types.ReceiptForStorage.
|
||||
func (r *Receipt) encodeForStorage(w *rlp.EncoderBuffer) {
|
||||
list := w.List()
|
||||
w.WriteBytes(r.PostStateOrStatus)
|
||||
w.WriteUint64(r.GasUsed)
|
||||
w.Write(r.Logs)
|
||||
w.ListEnd(list)
|
||||
}
|
||||
|
||||
// encodeForNetwork68 produces the eth/68 network protocol encoding of a receipt.
|
||||
// Note this recomputes the bloom filter of the receipt.
|
||||
func (r *Receipt) encodeForNetwork68(buf *receiptListBuffers, w *rlp.EncoderBuffer) {
|
||||
writeInner := func(w *rlp.EncoderBuffer) {
|
||||
list := w.List()
|
||||
w.WriteBytes(r.PostStateOrStatus)
|
||||
w.WriteUint64(r.GasUsed)
|
||||
bloom := r.bloom(&buf.bloom)
|
||||
w.WriteBytes(bloom[:])
|
||||
w.Write(r.Logs)
|
||||
w.ListEnd(list)
|
||||
}
|
||||
|
||||
if r.TxType == 0 {
|
||||
writeInner(w)
|
||||
} else {
|
||||
buf.tmp.Reset()
|
||||
buf.tmp.WriteByte(r.TxType)
|
||||
buf.enc.Reset(&buf.tmp)
|
||||
writeInner(&buf.enc)
|
||||
buf.enc.Flush()
|
||||
w.WriteBytes(buf.tmp.Bytes())
|
||||
}
|
||||
}
|
||||
|
||||
// encodeForNetwork69 produces the eth/69 network protocol encoding of a receipt.
|
||||
func (r *Receipt) encodeForNetwork69(w *rlp.EncoderBuffer) {
|
||||
list := w.List()
|
||||
w.WriteUint64(uint64(r.TxType))
|
||||
w.WriteBytes(r.PostStateOrStatus)
|
||||
w.WriteUint64(r.GasUsed)
|
||||
w.Write(r.Logs)
|
||||
w.ListEnd(list)
|
||||
}
|
||||
|
||||
// encodeForHash encodes a receipt for the block receiptsRoot derivation.
|
||||
func (r *Receipt) encodeForHash(buf *receiptListBuffers, out *bytes.Buffer) {
|
||||
// EncodeForHash encodes a receipt for the block receiptsRoot derivation.
|
||||
func (r *Receipt) EncodeForHash(bloomBuf *[6]byte, out *bytes.Buffer) {
|
||||
// For typed receipts, add the tx type.
|
||||
if r.TxType != 0 {
|
||||
out.WriteByte(r.TxType)
|
||||
}
|
||||
// Encode list = [postStateOrStatus, gasUsed, bloom, logs].
|
||||
w := &buf.enc
|
||||
w.Reset(out)
|
||||
w := rlp.NewEncoderBuffer(out)
|
||||
l := w.List()
|
||||
w.WriteBytes(r.PostStateOrStatus)
|
||||
w.WriteUint64(r.GasUsed)
|
||||
bloom := r.bloom(&buf.bloom)
|
||||
bloom := r.bloom(bloomBuf)
|
||||
w.WriteBytes(bloom[:])
|
||||
w.Write(r.Logs)
|
||||
w.ListEnd(l)
|
||||
|
|
@ -229,31 +90,31 @@ func (r *Receipt) bloom(buffer *[6]byte) types.Bloom {
|
|||
return b
|
||||
}
|
||||
|
||||
type receiptListBuffers struct {
|
||||
enc rlp.EncoderBuffer
|
||||
bloom [6]byte
|
||||
tmp bytes.Buffer
|
||||
// ReceiptList is the block receipt list as downloaded by eth/69.
|
||||
type ReceiptList struct {
|
||||
items rlp.RawList[Receipt]
|
||||
}
|
||||
|
||||
func initBuffers(buf **receiptListBuffers) {
|
||||
if *buf == nil {
|
||||
*buf = new(receiptListBuffers)
|
||||
}
|
||||
}
|
||||
|
||||
// encodeForStorage encodes a list of receipts for the database.
|
||||
func (buf *receiptListBuffers) encodeForStorage(rs rlp.RawList[Receipt], decode func([]byte, *Receipt) error) (rlp.RawValue, error) {
|
||||
// EncodeForStorage encodes a list of receipts for the database.
|
||||
// It only strips the first element (TxType) from each receipt's
|
||||
// raw RLP without the actual decoding and re-encoding.
|
||||
func (rl *ReceiptList) EncodeForStorage() (rlp.RawValue, error) {
|
||||
var out bytes.Buffer
|
||||
w := &buf.enc
|
||||
w.Reset(&out)
|
||||
w := rlp.NewEncoderBuffer(&out)
|
||||
outer := w.List()
|
||||
it := rs.ContentIterator()
|
||||
it := rl.items.ContentIterator()
|
||||
for it.Next() {
|
||||
var receipt Receipt
|
||||
if err := decode(it.Value(), &receipt); err != nil {
|
||||
return nil, err
|
||||
content, _, err := rlp.SplitList(it.Value())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("bad receipt: %v", err)
|
||||
}
|
||||
receipt.encodeForStorage(w)
|
||||
_, _, rest, err := rlp.Split(content)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("bad receipt: %v", err)
|
||||
}
|
||||
inner := w.List()
|
||||
w.Write(rest)
|
||||
w.ListEnd(inner)
|
||||
}
|
||||
if it.Err() != nil {
|
||||
return nil, fmt.Errorf("bad list: %v", it.Err())
|
||||
|
|
@ -263,149 +124,32 @@ func (buf *receiptListBuffers) encodeForStorage(rs rlp.RawList[Receipt], decode
|
|||
return out.Bytes(), nil
|
||||
}
|
||||
|
||||
// ReceiptList68 is a block receipt list as downloaded by eth/68.
|
||||
// This also implements types.DerivableList for validation purposes.
|
||||
type ReceiptList68 struct {
|
||||
buf *receiptListBuffers
|
||||
items rlp.RawList[Receipt]
|
||||
}
|
||||
|
||||
// NewReceiptList68 creates a receipt list.
|
||||
// NewReceiptList creates a receipt list.
|
||||
// This is slow, and exists for testing purposes.
|
||||
func NewReceiptList68(trs []*types.Receipt) *ReceiptList68 {
|
||||
rl := new(ReceiptList68)
|
||||
initBuffers(&rl.buf)
|
||||
enc := rlp.NewEncoderBuffer(nil)
|
||||
func NewReceiptList(trs []*types.Receipt) *ReceiptList {
|
||||
rl := new(ReceiptList)
|
||||
for _, tr := range trs {
|
||||
r := newReceipt(tr)
|
||||
r.encodeForNetwork68(rl.buf, &enc)
|
||||
rl.items.AppendRaw(enc.ToBytes())
|
||||
enc.Reset(nil)
|
||||
encoded, _ := rlp.EncodeToBytes(&r)
|
||||
rl.items.AppendRaw(encoded)
|
||||
}
|
||||
return rl
|
||||
}
|
||||
|
||||
func blockReceiptsToNetwork68(blockReceipts, blockBody rlp.RawValue) ([]byte, error) {
|
||||
txTypesIter, err := txTypesInBody(blockBody)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid block body: %v", err)
|
||||
}
|
||||
nextTxType, stopTxTypes := iter.Pull(txTypesIter)
|
||||
defer stopTxTypes()
|
||||
|
||||
var (
|
||||
out bytes.Buffer
|
||||
buf receiptListBuffers
|
||||
)
|
||||
blockReceiptIter, _ := rlp.NewListIterator(blockReceipts)
|
||||
w := rlp.NewEncoderBuffer(&out)
|
||||
outer := w.List()
|
||||
for i := 0; blockReceiptIter.Next(); i++ {
|
||||
txType, _ := nextTxType()
|
||||
var r Receipt
|
||||
if err := r.decodeDatabase(txType, blockReceiptIter.Value()); err != nil {
|
||||
return nil, fmt.Errorf("invalid database receipt %d: %v", i, err)
|
||||
}
|
||||
r.encodeForNetwork68(&buf, &w)
|
||||
}
|
||||
w.ListEnd(outer)
|
||||
w.Flush()
|
||||
return out.Bytes(), nil
|
||||
}
|
||||
|
||||
// setBuffers implements ReceiptsList.
|
||||
func (rl *ReceiptList68) setBuffers(buf *receiptListBuffers) {
|
||||
rl.buf = buf
|
||||
}
|
||||
|
||||
// EncodeForStorage encodes the receipts for storage into the database.
|
||||
func (rl *ReceiptList68) EncodeForStorage() (rlp.RawValue, error) {
|
||||
initBuffers(&rl.buf)
|
||||
return rl.buf.encodeForStorage(rl.items, func(data []byte, r *Receipt) error {
|
||||
return r.decode68(data)
|
||||
})
|
||||
}
|
||||
|
||||
// Derivable turns the receipts into a list that can derive the root hash.
|
||||
func (rl *ReceiptList68) Derivable() types.DerivableList {
|
||||
initBuffers(&rl.buf)
|
||||
return newDerivableRawList(&rl.items, func(data []byte, outbuf *bytes.Buffer) {
|
||||
var r Receipt
|
||||
if r.decode68(data) == nil {
|
||||
r.encodeForHash(rl.buf, outbuf)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// DecodeRLP decodes a list of receipts from the network format.
|
||||
func (rl *ReceiptList68) DecodeRLP(s *rlp.Stream) error {
|
||||
return rl.items.DecodeRLP(s)
|
||||
}
|
||||
|
||||
// EncodeRLP encodes the list into the network format of eth/68.
|
||||
func (rl *ReceiptList68) EncodeRLP(w io.Writer) error {
|
||||
return rl.items.EncodeRLP(w)
|
||||
}
|
||||
|
||||
// ReceiptList69 is the block receipt list as downloaded by eth/69.
|
||||
// This implements types.DerivableList for validation purposes.
|
||||
type ReceiptList69 struct {
|
||||
buf *receiptListBuffers
|
||||
items rlp.RawList[Receipt]
|
||||
}
|
||||
|
||||
// NewReceiptList69 creates a receipt list.
|
||||
// This is slow, and exists for testing purposes.
|
||||
func NewReceiptList69(trs []*types.Receipt) *ReceiptList69 {
|
||||
rl := new(ReceiptList69)
|
||||
enc := rlp.NewEncoderBuffer(nil)
|
||||
for _, tr := range trs {
|
||||
r := newReceipt(tr)
|
||||
r.encodeForNetwork69(&enc)
|
||||
rl.items.AppendRaw(enc.ToBytes())
|
||||
enc.Reset(nil)
|
||||
}
|
||||
return rl
|
||||
}
|
||||
|
||||
// setBuffers implements ReceiptsList.
|
||||
func (rl *ReceiptList69) setBuffers(buf *receiptListBuffers) {
|
||||
rl.buf = buf
|
||||
}
|
||||
|
||||
// EncodeForStorage encodes the receipts for storage into the database.
|
||||
func (rl *ReceiptList69) EncodeForStorage() (rlp.RawValue, error) {
|
||||
initBuffers(&rl.buf)
|
||||
return rl.buf.encodeForStorage(rl.items, func(data []byte, r *Receipt) error {
|
||||
return r.decode69(data)
|
||||
})
|
||||
}
|
||||
|
||||
// Derivable turns the receipts into a list that can derive the root hash.
|
||||
func (rl *ReceiptList69) Derivable() types.DerivableList {
|
||||
initBuffers(&rl.buf)
|
||||
return newDerivableRawList(&rl.items, func(data []byte, outbuf *bytes.Buffer) {
|
||||
var r Receipt
|
||||
if r.decode69(data) == nil {
|
||||
r.encodeForHash(rl.buf, outbuf)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// DecodeRLP decodes a list receipts from the network format.
|
||||
func (rl *ReceiptList69) DecodeRLP(s *rlp.Stream) error {
|
||||
func (rl *ReceiptList) DecodeRLP(s *rlp.Stream) error {
|
||||
return rl.items.DecodeRLP(s)
|
||||
}
|
||||
|
||||
// EncodeRLP encodes the list into the network format of eth/69.
|
||||
func (rl *ReceiptList69) EncodeRLP(w io.Writer) error {
|
||||
func (rl *ReceiptList) EncodeRLP(w io.Writer) error {
|
||||
return rl.items.EncodeRLP(w)
|
||||
}
|
||||
|
||||
// blockReceiptsToNetwork69 takes a slice of rlp-encoded receipts, and transactions,
|
||||
// encodeTypes takes a slice of rlp-encoded receipts, and transactions,
|
||||
// and applies the type-encoding on the receipts (for non-legacy receipts).
|
||||
// e.g. for non-legacy receipts: receipt-data -> {tx-type || receipt-data}
|
||||
func blockReceiptsToNetwork69(blockReceipts, blockBody rlp.RawValue) ([]byte, error) {
|
||||
func encodeTypes(blockReceipts, blockBody rlp.RawValue) ([]byte, error) {
|
||||
txTypesIter, err := txTypesInBody(blockBody)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid block body: %v", err)
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ func init() {
|
|||
}
|
||||
}
|
||||
|
||||
func TestReceiptList69(t *testing.T) {
|
||||
func TestReceiptList(t *testing.T) {
|
||||
for i, test := range receiptsTests {
|
||||
// encode receipts from types.ReceiptForStorage object.
|
||||
canonDB, _ := rlp.EncodeToBytes(test.input)
|
||||
|
|
@ -105,13 +105,13 @@ func TestReceiptList69(t *testing.T) {
|
|||
canonBody, _ := rlp.EncodeToBytes(blockBody)
|
||||
|
||||
// convert from storage encoding to network encoding
|
||||
network, err := blockReceiptsToNetwork69(canonDB, canonBody)
|
||||
network, err := encodeTypes(canonDB, canonBody)
|
||||
if err != nil {
|
||||
t.Fatalf("test[%d]: blockReceiptsToNetwork69 error: %v", i, err)
|
||||
t.Fatalf("test[%d]: encodeTypes error: %v", i, err)
|
||||
}
|
||||
|
||||
// parse as Receipts response list from network encoding
|
||||
var rl ReceiptList69
|
||||
var rl ReceiptList
|
||||
if err := rlp.DecodeBytes(network, &rl); err != nil {
|
||||
t.Fatalf("test[%d]: can't decode network receipts: %v", i, err)
|
||||
}
|
||||
|
|
@ -127,50 +127,13 @@ func TestReceiptList69(t *testing.T) {
|
|||
t.Fatalf("test[%d]: re-encoded network receipt list not equal\nhave: %x\nwant: %x", i, rlNetworkEnc, network)
|
||||
}
|
||||
|
||||
// compute root hash from ReceiptList69 and compare.
|
||||
responseHash := types.DeriveSha(rl.Derivable(), trie.NewStackTrie(nil))
|
||||
// compute root hash from ReceiptList and compare.
|
||||
var bloomBuf [6]byte
|
||||
writeReceipt := writeReceiptForHash(&bloomBuf)
|
||||
receipts := newDerivableRawList(&rl.items, writeReceipt)
|
||||
responseHash := types.DeriveSha(receipts, trie.NewStackTrie(nil))
|
||||
if responseHash != test.root {
|
||||
t.Fatalf("test[%d]: wrong root hash from ReceiptList69\nhave: %v\nwant: %v", i, responseHash, test.root)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestReceiptList68(t *testing.T) {
|
||||
for i, test := range receiptsTests {
|
||||
// encode receipts from types.ReceiptForStorage object.
|
||||
canonDB, _ := rlp.EncodeToBytes(test.input)
|
||||
|
||||
// encode block body from types object.
|
||||
blockBody := types.Body{Transactions: test.txs}
|
||||
canonBody, _ := rlp.EncodeToBytes(blockBody)
|
||||
|
||||
// convert from storage encoding to network encoding
|
||||
network, err := blockReceiptsToNetwork68(canonDB, canonBody)
|
||||
if err != nil {
|
||||
t.Fatalf("test[%d]: blockReceiptsToNetwork68 error: %v", i, err)
|
||||
}
|
||||
|
||||
// parse as Receipts response list from network encoding
|
||||
var rl ReceiptList68
|
||||
if err := rlp.DecodeBytes(network, &rl); err != nil {
|
||||
t.Fatalf("test[%d]: can't decode network receipts: %v", i, err)
|
||||
}
|
||||
rlStorageEnc, err := rl.EncodeForStorage()
|
||||
if err != nil {
|
||||
t.Fatalf("test[%d]: error from EncodeForStorage: %v", i, err)
|
||||
}
|
||||
if !bytes.Equal(rlStorageEnc, canonDB) {
|
||||
t.Fatalf("test[%d]: re-encoded receipts not equal\nhave: %x\nwant: %x", i, rlStorageEnc, canonDB)
|
||||
}
|
||||
rlNetworkEnc, _ := rlp.EncodeToBytes(&rl)
|
||||
if !bytes.Equal(rlNetworkEnc, network) {
|
||||
t.Fatalf("test[%d]: re-encoded network receipt list not equal\nhave: %x\nwant: %x", i, rlNetworkEnc, network)
|
||||
}
|
||||
|
||||
// compute root hash from ReceiptList68 and compare.
|
||||
responseHash := types.DeriveSha(rl.Derivable(), trie.NewStackTrie(nil))
|
||||
if responseHash != test.root {
|
||||
t.Fatalf("test[%d]: wrong root hash from ReceiptList68\nhave: %v\nwant: %v", i, responseHash, test.root)
|
||||
t.Fatalf("test[%d]: wrong root hash from ReceiptList\nhave: %v\nwant: %v", i, responseHash, test.root)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ import (
|
|||
)
|
||||
|
||||
// Tests that snap sync is disabled after a successful sync cycle.
|
||||
func TestSnapSyncDisabling68(t *testing.T) { testSnapSyncDisabling(t, eth.ETH68, snap.SNAP1) }
|
||||
func TestSnapSyncDisabling69(t *testing.T) { testSnapSyncDisabling(t, eth.ETH69, snap.SNAP1) }
|
||||
|
||||
// Tests that snap sync gets disabled as soon as a real block is successfully
|
||||
// imported into the blockchain.
|
||||
|
|
|
|||
Loading…
Reference in a new issue