Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions simulators/ethereum/engine/client/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type Eth interface {
BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error)
HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error)
SendTransaction(ctx context.Context, tx *types.Transaction) error
SendTransactions(ctx context.Context, txs []*types.Transaction) []error
StorageAt(ctx context.Context, account common.Address, key common.Hash, blockNumber *big.Int) ([]byte, error)
TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error)
NonceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (uint64, error)
Expand Down Expand Up @@ -55,6 +56,7 @@ type EngineClient interface {

// Local Test Account Management
GetNextAccountNonce(testCtx context.Context, account common.Address) (uint64, error)
UpdateNonce(testCtx context.Context, account common.Address, newNonce uint64) error

// TTD Methods
TerminalTotalDifficulty() *big.Int
Expand Down
43 changes: 43 additions & 0 deletions simulators/ethereum/engine/client/hive_rpc/hive_rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,49 @@ func (ec *HiveRPCEngineClient) GetNextAccountNonce(testCtx context.Context, acco
return nonce, nil
}

func (ec *HiveRPCEngineClient) UpdateNonce(testCtx context.Context, account common.Address, newNonce uint64) error {
// First get the current head of the client where we will send the tx
ctx, cancel := context.WithTimeout(testCtx, globals.RPCTimeout)
defer cancel()
head, err := ec.HeaderByNumber(ctx, nil)
if err != nil {
return err
}
ec.accTxInfoMap[account] = &AccountTransactionInfo{
PreviousBlock: head.Hash(),
PreviousNonce: newNonce,
}
return nil
}

func (ec *HiveRPCEngineClient) SendTransactions(ctx context.Context, txs []*types.Transaction) []error {
reqs := make([]rpc.BatchElem, len(txs))
hashes := make([]common.Hash, len(txs))
for i := range reqs {
data, err := txs[i].MarshalBinary()
if err != nil {
return []error{err}
}
reqs[i] = rpc.BatchElem{
Method: "eth_sendRawTransaction",
Args: []interface{}{hexutil.Encode(data)},
Result: &hashes[i],
}
}
if err := ec.PrepareDefaultAuthCallToken(); err != nil {
return []error{err}
}
if err := ec.c.BatchCallContext(ctx, reqs); err != nil {
return []error{err}
}

errs := make([]error, len(txs))
for i := range reqs {
errs[i] = reqs[i].Error
}
return nil
}

func (ec *HiveRPCEngineClient) PostRunVerifications() error {
// There are no post run verifications for RPC clients yet
return nil
Expand Down
23 changes: 23 additions & 0 deletions simulators/ethereum/engine/client/node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,16 @@ func (n *GethNode) SendTransaction(ctx context.Context, tx *types.Transaction) e
return n.eth.APIBackend.SendTx(ctx, tx)
}

func (n *GethNode) SendTransactions(ctx context.Context, txs []*types.Transaction) []error {
for _, tx := range txs {
err := n.eth.APIBackend.SendTx(ctx, tx)
if err != nil {
return []error{err}
}
}
return nil
}

func (n *GethNode) getStateDB(ctx context.Context, blockNumber *big.Int) (*state.StateDB, error) {
b, err := n.eth.APIBackend.BlockByNumber(ctx, parseBlockNumber(blockNumber))
if err != nil {
Expand Down Expand Up @@ -899,6 +909,19 @@ func (n *GethNode) GetNextAccountNonce(testCtx context.Context, account common.A
return nonce, nil
}

func (n *GethNode) UpdateNonce(testCtx context.Context, account common.Address, newNonce uint64) error {
// First get the current head of the client where we will send the tx
head, err := n.eth.APIBackend.BlockByNumber(testCtx, LatestBlockNumber)
if err != nil {
return err
}
n.accTxInfoMap[account] = &AccountTransactionInfo{
PreviousBlock: head.Hash(),
PreviousNonce: newNonce,
}
return nil
}

func (n *GethNode) PostRunVerifications() error {
// Check that the node did not receive more gossiped blocks than expected
if n.config.ExpectedGossipNewBlocksCount != nil {
Expand Down
29 changes: 28 additions & 1 deletion simulators/ethereum/engine/helper/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,8 @@ func (tc *BigInitcodeTransactionCreator) MakeTransaction(nonce uint64) (*types.T
// already knew the tx (might happen if we produced a re-org where the tx was
// unwind back into the txpool)
func SentTxAlreadyKnown(err error) bool {
return strings.Contains(err.Error(), "already known")
return strings.Contains(err.Error(), "already known") || strings.Contains(err.Error(), "already in the TxPool") ||
strings.Contains(err.Error(), "AlreadyKnown")
}

func SendNextTransaction(testCtx context.Context, node client.EngineClient, txCreator TransactionCreator) (*types.Transaction, error) {
Expand Down Expand Up @@ -504,3 +505,29 @@ func SendNextTransaction(testCtx context.Context, node client.EngineClient, txCr
}
}
}

func SendNextTransactions(testCtx context.Context, node client.EngineClient, txCreator TransactionCreator, txCount uint64) ([]*types.Transaction, error) {
var err error
nonce, err := node.GetNextAccountNonce(testCtx, globals.VaultAccountAddress)
if err != nil {
return nil, err
}
txs := make([]*types.Transaction, txCount)
for i := range txs {
txs[i], err = txCreator.MakeTransaction(nonce)
if err != nil {
return nil, err
}
nonce++
}
ctx, cancel := context.WithTimeout(testCtx, globals.RPCTimeout)
defer cancel()
errs := node.SendTransactions(ctx, txs)
for _, err := range errs {
if err != nil && !SentTxAlreadyKnown(err) {
return txs, err
}
}
node.UpdateNonce(testCtx, globals.VaultAccountAddress, nonce+txCount)
return txs, nil
}
43 changes: 26 additions & 17 deletions simulators/ethereum/engine/suites/withdrawals/tests.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@ var Tests = []test.SpecInterface{
`,
SlotsToSafe: big.NewInt(32),
SlotsToFinalized: big.NewInt(64),
TimeoutSeconds: 300,
},
WithdrawalsForkHeight: 1, // Genesis is Pre-Withdrawals
WithdrawalsBlockCount: 16,
Expand All @@ -345,6 +346,7 @@ var Tests = []test.SpecInterface{
`,
SlotsToSafe: big.NewInt(32),
SlotsToFinalized: big.NewInt(64),
TimeoutSeconds: 300,
},
WithdrawalsForkHeight: 1, // Genesis is Pre-Withdrawals
WithdrawalsBlockCount: 16,
Expand All @@ -363,6 +365,7 @@ var Tests = []test.SpecInterface{
`,
SlotsToSafe: big.NewInt(32),
SlotsToFinalized: big.NewInt(64),
TimeoutSeconds: 300,
},
WithdrawalsForkHeight: 1, // Genesis is Pre-Withdrawals
WithdrawalsBlockCount: 16,
Expand All @@ -382,6 +385,7 @@ var Tests = []test.SpecInterface{
`,
SlotsToSafe: big.NewInt(32),
SlotsToFinalized: big.NewInt(64),
TimeoutSeconds: 300,
},
WithdrawalsForkHeight: 8, // Genesis is Pre-Withdrawals
WithdrawalsBlockCount: 8,
Expand All @@ -401,6 +405,7 @@ var Tests = []test.SpecInterface{
`,
SlotsToSafe: big.NewInt(32),
SlotsToFinalized: big.NewInt(64),
TimeoutSeconds: 300,
},
WithdrawalsForkHeight: 8, // Genesis is Pre-Withdrawals
WithdrawalsBlockCount: 8,
Expand All @@ -420,6 +425,7 @@ var Tests = []test.SpecInterface{
`,
SlotsToSafe: big.NewInt(32),
SlotsToFinalized: big.NewInt(64),
TimeoutSeconds: 300,
},
WithdrawalsForkHeight: 8, // Genesis is Pre-Withdrawals
WithdrawalsBlockCount: 8,
Expand All @@ -440,6 +446,7 @@ var Tests = []test.SpecInterface{
`,
SlotsToSafe: big.NewInt(32),
SlotsToFinalized: big.NewInt(64),
TimeoutSeconds: 300,
},
WithdrawalsForkHeight: 8, // Genesis is Pre-Withdrawals
WithdrawalsBlockCount: 8,
Expand All @@ -460,6 +467,7 @@ var Tests = []test.SpecInterface{
`,
SlotsToSafe: big.NewInt(32),
SlotsToFinalized: big.NewInt(64),
TimeoutSeconds: 300,
},
WithdrawalsForkHeight: 8, // Genesis is Pre-Withdrawals
WithdrawalsBlockCount: 8,
Expand All @@ -481,6 +489,7 @@ var Tests = []test.SpecInterface{
`,
SlotsToSafe: big.NewInt(32),
SlotsToFinalized: big.NewInt(64),
TimeoutSeconds: 300,
},
WithdrawalsForkHeight: 8, // Genesis is Pre-Withdrawals
WithdrawalsBlockCount: 8,
Expand Down Expand Up @@ -1553,25 +1562,25 @@ func (ws *WithdrawalsReorgSpec) Execute(t *test.Env) {
},
OnRequestNextPayload: func() {
// Send transactions to be included in the payload
for i := uint64(0); i < ws.GetTransactionCountPerPayload(); i++ {
tx, err := helper.SendNextTransaction(
t.TestContext,
t.CLMock.NextBlockProducer,
&helper.BaseTransactionCreator{
Recipient: &globals.PrevRandaoContractAddr,
Amount: common.Big1,
Payload: nil,
TxType: t.TestTransactionType,
GasLimit: 75000,
},
)
if err != nil {
t.Fatalf("FAIL (%s): Error trying to send transaction: %v", t.TestName, err)
}
// Error will be ignored here since the tx could have been already relayed
secondaryEngine.SendTransaction(t.TestContext, tx)
txs, err := helper.SendNextTransactions(
t.TestContext,
t.CLMock.NextBlockProducer,
&helper.BaseTransactionCreator{
Recipient: &globals.PrevRandaoContractAddr,
Amount: common.Big1,
Payload: nil,
TxType: t.TestTransactionType,
GasLimit: 75000,
},
ws.GetTransactionCountPerPayload(),
)
if err != nil {
t.Fatalf("FAIL (%s): Error trying to send transactions: %v", t.TestName, err)
}

// Error will be ignored here since the tx could have been already relayed
secondaryEngine.SendTransactions(t.TestContext, txs)

if t.CLMock.CurrentPayloadNumber >= ws.GetSidechainSplitHeight() {
// Also request a payload from the sidechain
fcU := beacon.ForkchoiceStateV1{
Expand Down