1
1
import { type AztecNodeService } from '@aztec/aztec-node' ;
2
2
import { sleep } from '@aztec/aztec.js' ;
3
+ import { RollupAbi } from '@aztec/l1-artifacts' ;
3
4
4
5
import { jest } from '@jest/globals' ;
5
6
import fs from 'fs' ;
7
+ import { getContract } from 'viem' ;
6
8
7
9
import { type NodeContext , createNodes } from '../fixtures/setup_p2p_test.js' ;
8
10
import { P2PNetworkTest , WAIT_FOR_TX_TIMEOUT } from './p2p_network.js' ;
9
11
import { createPXEServiceAndSubmitTransactions } from './shared.js' ;
10
12
11
13
// Don't set this to a higher value than 9 because each node will use a different L1 publisher account and anvil seeds
12
- const NUM_NODES = 4 ;
14
+ const NUM_NODES = 6 ;
13
15
const NUM_TXS_PER_NODE = 2 ;
14
16
const BOOT_NODE_UDP_PORT = 40800 ;
15
17
@@ -27,6 +29,7 @@ describe('e2e_p2p_reqresp_tx', () => {
27
29
} ) ;
28
30
await t . applyBaseSnapshots ( ) ;
29
31
await t . setup ( ) ;
32
+ await t . removeInitialNode ( ) ;
30
33
} ) ;
31
34
32
35
afterEach ( async ( ) => {
@@ -37,10 +40,6 @@ describe('e2e_p2p_reqresp_tx', () => {
37
40
}
38
41
} ) ;
39
42
40
- // NOTE: If this test fails in a PR where the shuffling algorithm is changed, then it is failing as the node with
41
- // the mocked p2p layer is being picked as the sequencer, and it does not have any transactions in it's mempool.
42
- // If this is the case, then we should update the test to switch off the mempool of a different node.
43
- // adjust `nodeToTurnOffTxGossip` in the test below.
44
43
it ( 'should produce an attestation by requesting tx data over the p2p network' , async ( ) => {
45
44
/**
46
45
* Birds eye overview of the test
@@ -73,12 +72,15 @@ describe('e2e_p2p_reqresp_tx', () => {
73
72
// wait a bit for peers to discover each other
74
73
await sleep ( 4000 ) ;
75
74
76
- t . logger . info ( 'Turning off tx gossip' ) ;
75
+ const { proposerIndexes, nodesToTurnOffTxGossip } = await getProposerIndexes ( ) ;
76
+
77
+ t . logger . info ( `Turning off tx gossip for nodes: ${ nodesToTurnOffTxGossip } ` ) ;
78
+ t . logger . info ( `Sending txs to proposer nodes: ${ proposerIndexes } ` ) ;
79
+
77
80
// Replace the p2p node implementation of some of the nodes with a spy such that it does not store transactions that are gossiped to it
78
81
// Original implementation of `processTxFromPeer` will store received transactions in the tx pool.
79
- // We have chosen nodes 0,3 as they do not get chosen to be the sequencer in this test.
80
- const nodeToTurnOffTxGossip = [ 0 , 3 ] ;
81
- for ( const nodeIndex of nodeToTurnOffTxGossip ) {
82
+ // We chose the first 2 nodes that will be the proposers for the next few slots
83
+ for ( const nodeIndex of nodesToTurnOffTxGossip ) {
82
84
jest
83
85
. spyOn ( ( nodes [ nodeIndex ] as any ) . p2pClient . p2pService , 'processTxFromPeer' )
84
86
. mockImplementation ( ( ) : Promise < void > => {
@@ -87,10 +89,9 @@ describe('e2e_p2p_reqresp_tx', () => {
87
89
}
88
90
89
91
t . logger . info ( 'Submitting transactions' ) ;
90
- // Only submit transactions to the first two nodes, so that we avoid our sequencer with a mocked p2p layer being picked to produce a block.
91
- // If the shuffling algorithm changes, then this will need to be updated.
92
- for ( let i = 1 ; i < 3 ; i ++ ) {
93
- const context = await createPXEServiceAndSubmitTransactions ( t . logger , nodes [ i ] , NUM_TXS_PER_NODE ) ;
92
+
93
+ for ( const nodeIndex of proposerIndexes . slice ( 0 , 2 ) ) {
94
+ const context = await createPXEServiceAndSubmitTransactions ( t . logger , nodes [ nodeIndex ] , NUM_TXS_PER_NODE ) ;
94
95
contexts . push ( context ) ;
95
96
}
96
97
@@ -107,4 +108,34 @@ describe('e2e_p2p_reqresp_tx', () => {
107
108
) ;
108
109
t . logger . info ( 'All transactions mined' ) ;
109
110
} ) ;
111
+
112
+ /**
113
+ * Get the indexes in the nodes array that will produce the next few blocks
114
+ */
115
+ async function getProposerIndexes ( ) {
116
+ // Get the nodes for the next set of slots
117
+ const rollupContract = getContract ( {
118
+ address : t . ctx . deployL1ContractsValues . l1ContractAddresses . rollupAddress . toString ( ) ,
119
+ abi : RollupAbi ,
120
+ client : t . ctx . deployL1ContractsValues . publicClient ,
121
+ } ) ;
122
+
123
+ const currentTime = await t . ctx . cheatCodes . eth . timestamp ( ) ;
124
+ const slotDuration = await rollupContract . read . SLOT_DURATION ( ) ;
125
+
126
+ const proposers = [ ] ;
127
+
128
+ for ( let i = 0 ; i < 3 ; i ++ ) {
129
+ const nextSlot = BigInt ( currentTime ) + BigInt ( i ) * BigInt ( slotDuration ) ;
130
+ const proposer = await rollupContract . read . getProposerAt ( [ nextSlot ] ) ;
131
+ proposers . push ( proposer ) ;
132
+ }
133
+
134
+ // Get the indexes of the nodes that are responsible for the next two slots
135
+ const proposerIndexes = proposers . map ( proposer => t . nodePublicKeys . indexOf ( proposer ) ) ;
136
+ const nodesToTurnOffTxGossip = Array . from ( { length : NUM_NODES } , ( _ , i ) => i ) . filter (
137
+ i => ! proposerIndexes . includes ( i ) ,
138
+ ) ;
139
+ return { proposerIndexes, nodesToTurnOffTxGossip } ;
140
+ }
110
141
} ) ;
0 commit comments