Skip to content

Commit

Permalink
add: eth67 protocol
Browse files Browse the repository at this point in the history
  • Loading branch information
anshalshukla committed Sep 12, 2024
1 parent a291fa7 commit a323609
Show file tree
Hide file tree
Showing 15 changed files with 435 additions and 233 deletions.
2 changes: 1 addition & 1 deletion cmd/devp2p/internal/ethtest/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ func (c *Conn) ReadEth() (any, error) {
case eth.TransactionsMsg:
msg = new(eth.TransactionsPacket)
case eth.NewPooledTransactionHashesMsg:
msg = new(eth.NewPooledTransactionHashesPacket)
msg = new(eth.NewPooledTransactionHashesPacket68)
case eth.GetPooledTransactionsMsg:
msg = new(eth.GetPooledTransactionsPacket)
case eth.PooledTransactionsMsg:
Expand Down
10 changes: 5 additions & 5 deletions cmd/devp2p/internal/ethtest/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,7 @@ the transactions using a GetPooledTransactions request.`)
}

// Send announcement.
ann := eth.NewPooledTransactionHashesPacket{Types: txTypes, Sizes: sizes, Hashes: hashes}
ann := eth.NewPooledTransactionHashesPacket68{Types: txTypes, Sizes: sizes, Hashes: hashes}
err = conn.Write(ethProto, eth.NewPooledTransactionHashesMsg, ann)
if err != nil {
t.Fatalf("failed to write to connection: %v", err)
Expand All @@ -753,7 +753,7 @@ the transactions using a GetPooledTransactions request.`)
}

return
case *eth.NewPooledTransactionHashesPacket:
case *eth.NewPooledTransactionHashesPacket68:
continue
case *eth.TransactionsPacket:
continue
Expand Down Expand Up @@ -823,12 +823,12 @@ func (s *Suite) TestBlobViolations(t *utesting.T) {
t2 = s.makeBlobTxs(2, 3, 0x2)
)
for _, test := range []struct {
ann eth.NewPooledTransactionHashesPacket
ann eth.NewPooledTransactionHashesPacket68
resp eth.PooledTransactionsResponse
}{
// Invalid tx size.
{
ann: eth.NewPooledTransactionHashesPacket{
ann: eth.NewPooledTransactionHashesPacket68{
Types: []byte{types.BlobTxType, types.BlobTxType},
Sizes: []uint32{uint32(t1[0].Size()), uint32(t1[1].Size() + 10)},
Hashes: []common.Hash{t1[0].Hash(), t1[1].Hash()},
Expand All @@ -837,7 +837,7 @@ func (s *Suite) TestBlobViolations(t *utesting.T) {
},
// Wrong tx type.
{
ann: eth.NewPooledTransactionHashesPacket{
ann: eth.NewPooledTransactionHashesPacket68{
Types: []byte{types.DynamicFeeTxType, types.BlobTxType},
Sizes: []uint32{uint32(t2[0].Size()), uint32(t2[1].Size())},
Hashes: []common.Hash{t2[0].Hash(), t2[1].Hash()},
Expand Down
4 changes: 2 additions & 2 deletions cmd/devp2p/internal/ethtest/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func (s *Suite) sendTxs(t *utesting.T, txs []*types.Transaction) error {
for _, tx := range *msg {
got[tx.Hash()] = true
}
case *eth.NewPooledTransactionHashesPacket:
case *eth.NewPooledTransactionHashesPacket68:
for _, hash := range msg.Hashes {
got[hash] = true
}
Expand Down Expand Up @@ -157,7 +157,7 @@ func (s *Suite) sendInvalidTxs(t *utesting.T, txs []*types.Transaction) error {
return fmt.Errorf("received bad tx: %s", tx.Hash())
}
}
case *eth.NewPooledTransactionHashesPacket:
case *eth.NewPooledTransactionHashesPacket68:
for _, hash := range msg.Hashes {
if _, ok := invalids[hash]; ok {
return fmt.Errorf("received bad tx: %s", hash)
Expand Down
94 changes: 86 additions & 8 deletions eth/downloader/bor_downloader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import (
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie"

"github.com/stretchr/testify/assert"
)

Expand Down Expand Up @@ -480,6 +481,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 TestCanonicalSynchronisation67Full(t *testing.T) { testCanonSync(t, eth.ETH67, FullSync) }
func TestCanonicalSynchronisation67Snap(t *testing.T) { testCanonSync(t, eth.ETH67, SnapSync) }

func testCanonSync(t *testing.T, protocol uint, mode SyncMode) {
tester := newTester(t)
Expand All @@ -501,6 +504,8 @@ func testCanonSync(t *testing.T, protocol uint, mode SyncMode) {
// 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 TestThrottling67Full(t *testing.T) { testThrottling(t, eth.ETH67, FullSync) }
func TestThrottling67Snap(t *testing.T) { testThrottling(t, eth.ETH67, SnapSync) }

func testThrottling(t *testing.T, protocol uint, mode SyncMode) {
tester := newTester(t)
Expand Down Expand Up @@ -586,6 +591,8 @@ func testThrottling(t *testing.T, protocol uint, mode SyncMode) {
// binary search should be executed.
func TestForkedSync68Full(t *testing.T) { testForkedSync(t, eth.ETH68, FullSync) }
func TestForkedSync68Snap(t *testing.T) { testForkedSync(t, eth.ETH68, SnapSync) }
func TestForkedSync67Full(t *testing.T) { testForkedSync(t, eth.ETH67, FullSync) }
func TestForkedSync67Snap(t *testing.T) { testForkedSync(t, eth.ETH67, SnapSync) }

func testForkedSync(t *testing.T, protocol uint, mode SyncMode) {
tester := newTester(t)
Expand Down Expand Up @@ -614,6 +621,8 @@ func testForkedSync(t *testing.T, protocol uint, mode SyncMode) {
// currently and is not dropped.
func TestHeavyForkedSync68Full(t *testing.T) { testHeavyForkedSync(t, eth.ETH68, FullSync) }
func TestHeavyForkedSync68Snap(t *testing.T) { testHeavyForkedSync(t, eth.ETH68, SnapSync) }
func TestHeavyForkedSync67Full(t *testing.T) { testHeavyForkedSync(t, eth.ETH67, FullSync) }
func TestHeavyForkedSync67Snap(t *testing.T) { testHeavyForkedSync(t, eth.ETH67, SnapSync) }

func testHeavyForkedSync(t *testing.T, protocol uint, mode SyncMode) {
tester := newTester(t)
Expand Down Expand Up @@ -644,6 +653,8 @@ func testHeavyForkedSync(t *testing.T, protocol uint, mode SyncMode) {
// long dead chains.
func TestBoundedForkedSync68Full(t *testing.T) { testBoundedForkedSync(t, eth.ETH68, FullSync) }
func TestBoundedForkedSync68Snap(t *testing.T) { testBoundedForkedSync(t, eth.ETH68, SnapSync) }
func TestBoundedForkedSync67Full(t *testing.T) { testBoundedForkedSync(t, eth.ETH67, FullSync) }
func TestBoundedForkedSync67Snap(t *testing.T) { testBoundedForkedSync(t, eth.ETH67, SnapSync) }

func testBoundedForkedSync(t *testing.T, protocol uint, mode SyncMode) {
tester := newTester(t)
Expand Down Expand Up @@ -678,6 +689,15 @@ func TestBoundedHeavyForkedSync68Snap(t *testing.T) {
testBoundedHeavyForkedSync(t, eth.ETH68, SnapSync)
}

func TestBoundedHeavyForkedSync67Full(t *testing.T) {
t.Parallel()
testBoundedHeavyForkedSync(t, eth.ETH67, FullSync)
}
func TestBoundedHeavyForkedSync67Snap(t *testing.T) {
t.Parallel()
testBoundedHeavyForkedSync(t, eth.ETH67, SnapSync)
}

func testBoundedHeavyForkedSync(t *testing.T, protocol uint, mode SyncMode) {
tester := newTester(t)
defer tester.terminate()
Expand Down Expand Up @@ -705,6 +725,8 @@ func testBoundedHeavyForkedSync(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 TestCancel67Full(t *testing.T) { testCancel(t, eth.ETH67, FullSync) }
func TestCancel67Snap(t *testing.T) { testCancel(t, eth.ETH67, SnapSync) }

func testCancel(t *testing.T, protocol uint, mode SyncMode) {
tester := newTester(t)
Expand Down Expand Up @@ -734,6 +756,8 @@ func testCancel(t *testing.T, protocol uint, mode SyncMode) {
// Tests that synchronisation from multiple peers works as intended (multi thread sanity test).
func TestMultiSynchronisation68Full(t *testing.T) { testMultiSynchronisation(t, eth.ETH68, FullSync) }
func TestMultiSynchronisation68Snap(t *testing.T) { testMultiSynchronisation(t, eth.ETH68, SnapSync) }
func TestMultiSynchronisation67Full(t *testing.T) { testMultiSynchronisation(t, eth.ETH67, FullSync) }
func TestMultiSynchronisation67Snap(t *testing.T) { testMultiSynchronisation(t, eth.ETH67, SnapSync) }

func testMultiSynchronisation(t *testing.T, protocol uint, mode SyncMode) {
tester := newTester(t)
Expand All @@ -759,6 +783,8 @@ func testMultiSynchronisation(t *testing.T, protocol uint, mode SyncMode) {
// 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 TestMultiProtoSynchronisation67Full(t *testing.T) { testMultiProtoSync(t, eth.ETH67, FullSync) }
func TestMultiProtoSynchronisation67Snap(t *testing.T) { testMultiProtoSync(t, eth.ETH67, SnapSync) }

func testMultiProtoSync(t *testing.T, protocol uint, mode SyncMode) {
tester := newTester(t)
Expand All @@ -769,6 +795,7 @@ func testMultiProtoSync(t *testing.T, protocol uint, mode SyncMode) {

// Create peers of every type
tester.newPeer("peer 68", eth.ETH68, chain.blocks[1:])
tester.newPeer("peer 67", eth.ETH67, chain.blocks[1:])

// Synchronise with the requested peer and make sure all blocks were retrieved
if err := tester.sync(fmt.Sprintf("peer %d", protocol), nil, mode); err != nil {
Expand All @@ -778,7 +805,7 @@ func testMultiProtoSync(t *testing.T, protocol uint, mode SyncMode) {
assertOwnChain(t, tester, len(chain.blocks))

// Check that no peers have been dropped off
for _, version := range []int{68} {
for _, version := range []int{68, 67} {
peer := fmt.Sprintf("peer %d", version)
if _, ok := tester.peers[peer]; !ok {
t.Errorf("%s dropped", peer)
Expand All @@ -790,6 +817,8 @@ func testMultiProtoSync(t *testing.T, protocol uint, mode SyncMode) {
// 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 TestEmptyShortCircuit67Full(t *testing.T) { testEmptyShortCircuit(t, eth.ETH67, FullSync) }
func TestEmptyShortCircuit67Snap(t *testing.T) { testEmptyShortCircuit(t, eth.ETH67, SnapSync) }

func testEmptyShortCircuit(t *testing.T, protocol uint, mode SyncMode) {
tester := newTester(t)
Expand Down Expand Up @@ -819,7 +848,7 @@ func testEmptyShortCircuit(t *testing.T, protocol uint, mode SyncMode) {
bodiesNeeded, receiptsNeeded := 0, 0

for _, block := range chain.blocks[1:] {
if (mode == SnapSync || mode == FullSync) && (len(block.Transactions()) > 0 || len(block.Uncles()) > 0) {
if len(block.Transactions()) > 0 || len(block.Uncles()) > 0 {
bodiesNeeded++
}
}
Expand All @@ -843,6 +872,8 @@ func testEmptyShortCircuit(t *testing.T, protocol uint, mode SyncMode) {
// stalling the downloader by feeding gapped header chains.
func TestMissingHeaderAttack68Full(t *testing.T) { testMissingHeaderAttack(t, eth.ETH68, FullSync) }
func TestMissingHeaderAttack68Snap(t *testing.T) { testMissingHeaderAttack(t, eth.ETH68, SnapSync) }
func TestMissingHeaderAttack67Full(t *testing.T) { testMissingHeaderAttack(t, eth.ETH67, FullSync) }
func TestMissingHeaderAttack67Snap(t *testing.T) { testMissingHeaderAttack(t, eth.ETH67, SnapSync) }

func testMissingHeaderAttack(t *testing.T, protocol uint, mode SyncMode) {
tester := newTester(t)
Expand Down Expand Up @@ -870,6 +901,8 @@ func testMissingHeaderAttack(t *testing.T, protocol uint, mode SyncMode) {
// detects the invalid numbering.
func TestShiftedHeaderAttack68Full(t *testing.T) { testShiftedHeaderAttack(t, eth.ETH68, FullSync) }
func TestShiftedHeaderAttack68Snap(t *testing.T) { testShiftedHeaderAttack(t, eth.ETH68, SnapSync) }
func TestShiftedHeaderAttack67Full(t *testing.T) { testShiftedHeaderAttack(t, eth.ETH67, FullSync) }
func TestShiftedHeaderAttack67Snap(t *testing.T) { testShiftedHeaderAttack(t, eth.ETH67, SnapSync) }

func testShiftedHeaderAttack(t *testing.T, protocol uint, mode SyncMode) {
tester := newTester(t)
Expand Down Expand Up @@ -903,6 +936,15 @@ func TestHighTDStarvationAttack68Snap(t *testing.T) {
testHighTDStarvationAttack(t, eth.ETH68, SnapSync)
}

func TestHighTDStarvationAttack67Full(t *testing.T) {
t.Parallel()
testHighTDStarvationAttack(t, eth.ETH67, FullSync)
}
func TestHighTDStarvationAttack67Snap(t *testing.T) {
t.Parallel()
testHighTDStarvationAttack(t, eth.ETH67, SnapSync)
}

func testHighTDStarvationAttack(t *testing.T, protocol uint, mode SyncMode) {
tester := newTester(t)
defer tester.terminate()
Expand All @@ -917,6 +959,7 @@ func testHighTDStarvationAttack(t *testing.T, protocol uint, mode SyncMode) {

// Tests that misbehaving peers are disconnected, whilst behaving ones are not.
func TestBlockHeaderAttackerDropping68(t *testing.T) { testBlockHeaderAttackerDropping(t, eth.ETH68) }
func TestBlockHeaderAttackerDropping67(t *testing.T) { testBlockHeaderAttackerDropping(t, eth.ETH67) }

func testBlockHeaderAttackerDropping(t *testing.T, protocol uint) {
// Define the disconnection requirement for individual hash fetch errors
Expand Down Expand Up @@ -969,6 +1012,8 @@ func testBlockHeaderAttackerDropping(t *testing.T, protocol uint) {
// 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 TestSyncProgress67Full(t *testing.T) { testSyncProgress(t, eth.ETH67, FullSync) }
func TestSyncProgress67Snap(t *testing.T) { testSyncProgress(t, eth.ETH67, SnapSync) }

func testSyncProgress(t *testing.T, protocol uint, mode SyncMode) {
tester := newTester(t)
Expand Down Expand Up @@ -1052,6 +1097,8 @@ func checkProgress(t *testing.T, d *Downloader, stage string, want ethereum.Sync
// revertal).
func TestForkedSyncProgress68Full(t *testing.T) { testForkedSyncProgress(t, eth.ETH68, FullSync) }
func TestForkedSyncProgress68Snap(t *testing.T) { testForkedSyncProgress(t, eth.ETH68, SnapSync) }
func TestForkedSyncProgress67Full(t *testing.T) { testForkedSyncProgress(t, eth.ETH67, FullSync) }
func TestForkedSyncProgress67Snap(t *testing.T) { testForkedSyncProgress(t, eth.ETH67, SnapSync) }

func testForkedSyncProgress(t *testing.T, protocol uint, mode SyncMode) {
tester := newTester(t)
Expand Down Expand Up @@ -1130,6 +1177,8 @@ func testForkedSyncProgress(t *testing.T, protocol uint, mode SyncMode) {
// continuation of the previous sync and not a new instance.
func TestFailedSyncProgress68Full(t *testing.T) { testFailedSyncProgress(t, eth.ETH68, FullSync) }
func TestFailedSyncProgress68Snap(t *testing.T) { testFailedSyncProgress(t, eth.ETH68, SnapSync) }
func TestFailedSyncProgress67Full(t *testing.T) { testFailedSyncProgress(t, eth.ETH67, FullSync) }
func TestFailedSyncProgress67Snap(t *testing.T) { testFailedSyncProgress(t, eth.ETH67, SnapSync) }

func testFailedSyncProgress(t *testing.T, protocol uint, mode SyncMode) {
tester := newTester(t)
Expand Down Expand Up @@ -1203,6 +1252,8 @@ func testFailedSyncProgress(t *testing.T, protocol uint, mode SyncMode) {
// the progress height is successfully reduced at the next sync invocation.
func TestFakedSyncProgress68Full(t *testing.T) { testFakedSyncProgress(t, eth.ETH68, FullSync) }
func TestFakedSyncProgress68Snap(t *testing.T) { testFakedSyncProgress(t, eth.ETH68, SnapSync) }
func TestFakedSyncProgress67Full(t *testing.T) { testFakedSyncProgress(t, eth.ETH67, FullSync) }
func TestFakedSyncProgress67Snap(t *testing.T) { testFakedSyncProgress(t, eth.ETH67, SnapSync) }

func testFakedSyncProgress(t *testing.T, protocol uint, mode SyncMode) {
tester := newTester(t)
Expand Down Expand Up @@ -1367,6 +1418,8 @@ func TestRemoteHeaderRequestSpan(t *testing.T) {
// 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 TestBeaconSync67Full(t *testing.T) { testBeaconSync(t, eth.ETH67, FullSync) }
func TestBeaconSync67Snap(t *testing.T) { testBeaconSync(t, eth.ETH67, SnapSync) }

func testBeaconSync(t *testing.T, protocol uint, mode SyncMode) {
t.Helper()
Expand Down Expand Up @@ -1477,12 +1530,37 @@ func (w *whitelistFake) GetMilestoneIDsList() []string {
return nil
}

// TestFakedSyncProgress67WhitelistMismatch tests if in case of whitelisted
// checkpoint mismatch with opposite peer, the sync should fail.
func TestFakedSyncProgress67WhitelistMismatch(t *testing.T) {
t.Parallel()

protocol := uint(eth.ETH67)
mode := FullSync

tester := newTester(t)
validate := func(count int) (bool, error) {
return false, whitelist.ErrMismatch
}
tester.downloader.ChainValidator = newWhitelistFake(validate)

defer tester.terminate()

chainA := testChainForkLightA.blocks
tester.newPeer("light", protocol, chainA[1:])

// Synchronise with the peer and make sure all blocks were retrieved
if err := tester.sync("light", nil, mode); err == nil {
t.Fatal("succeeded attacker synchronisation")
}
}

// TestFakedSyncProgress67WhitelistMatch tests if in case of whitelisted
// checkpoint match with opposite peer, the sync should succeed.
func TestFakedSyncProgress68WhitelistMatch(t *testing.T) {
func TestFakedSyncProgress67WhitelistMatch(t *testing.T) {
t.Parallel()

protocol := uint(eth.ETH68)
protocol := uint(eth.ETH67)
mode := FullSync

tester := newTester(t)
Expand All @@ -1505,10 +1583,10 @@ func TestFakedSyncProgress68WhitelistMatch(t *testing.T) {
// TestFakedSyncProgress67NoRemoteCheckpoint tests if in case of missing/invalid
// checkpointed blocks with opposite peer, the sync should fail initially but
// with the retry mechanism, it should succeed eventually.
func TestFakedSyncProgress68NoRemoteCheckpoint(t *testing.T) {
func TestFakedSyncProgress67NoRemoteCheckpoint(t *testing.T) {
t.Parallel()

protocol := uint(eth.ETH68)
protocol := uint(eth.ETH67)
mode := FullSync

tester := newTester(t)
Expand Down Expand Up @@ -1544,8 +1622,8 @@ func TestFakedSyncProgress68NoRemoteCheckpoint(t *testing.T) {

// TestFakedSyncProgress67BypassWhitelistValidation tests if peer validation
// via whitelist is bypassed when remote peer is far away or not
func TestFakedSyncProgress68BypassWhitelistValidation(t *testing.T) {
protocol := uint(eth.ETH68)
func TestFakedSyncProgress67BypassWhitelistValidation(t *testing.T) {
protocol := uint(eth.ETH67)
mode := FullSync

tester := newTester(t)
Expand Down
Loading

0 comments on commit a323609

Please sign in to comment.