Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix estimate gas nonce computation to deal with sequencer concurrency #2204

Merged
merged 2 commits into from
Jul 27, 2023
Merged
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
57 changes: 34 additions & 23 deletions state/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -758,21 +758,6 @@ func (s *State) internalProcessUnsignedTransaction(ctx context.Context, tx *type
return nil, err
}

stateRoot := l2BlockStateRoot
if l2BlockNumber != nil {
l2Block, err := s.GetL2BlockByNumber(ctx, *l2BlockNumber, dbTx)
if err != nil {
return nil, err
}
stateRoot = l2Block.Root()
}

loadedNonce, err := s.tree.GetNonce(ctx, senderAddress, stateRoot.Bytes())
if err != nil {
return nil, err
}
nonce := loadedNonce.Uint64()

// Get latest batch from the database to get globalExitRoot and Timestamp
lastBatch := lastBatches[0]

Expand All @@ -782,9 +767,15 @@ func (s *State) internalProcessUnsignedTransaction(ctx context.Context, tx *type
previousBatch = lastBatches[1]
}

stateRoot := l2BlockStateRoot
timestamp := uint64(lastBatch.Timestamp.Unix())

if l2BlockNumber != nil {
l2Block, err := s.GetL2BlockByNumber(ctx, *l2BlockNumber, dbTx)
if err != nil {
return nil, err
}
stateRoot = l2Block.Root()

latestL2BlockNumber, err := s.PostgresStorage.GetLastL2BlockNumber(ctx, dbTx)
if err != nil {
return nil, err
Expand All @@ -796,6 +787,11 @@ func (s *State) internalProcessUnsignedTransaction(ctx context.Context, tx *type
}

forkID := s.GetForkIDByBatchNumber(lastBatch.BatchNumber)
loadedNonce, err := s.tree.GetNonce(ctx, senderAddress, stateRoot.Bytes())
if err != nil {
return nil, err
}
nonce := loadedNonce.Uint64()

batchL2Data, err := EncodeUnsignedTransaction(*tx, s.cfg.ChainID, &nonce, forkID)
if err != nil {
Expand Down Expand Up @@ -963,6 +959,21 @@ func (s *State) EstimateGas(transaction *types.Transaction, senderAddress common
return 0, nil, err
}

stateRoot := l2BlockStateRoot
if l2BlockNumber != nil {
l2Block, err := s.GetL2BlockByNumber(ctx, *l2BlockNumber, dbTx)
if err != nil {
return 0, nil, err
}
stateRoot = l2Block.Root()
}

loadedNonce, err := s.tree.GetNonce(ctx, senderAddress, stateRoot.Bytes())
if err != nil {
return 0, nil, err
}
nonce := loadedNonce.Uint64()

// Get latest batch from the database to get globalExitRoot and Timestamp
lastBatch := lastBatches[0]

Expand All @@ -978,7 +989,7 @@ func (s *State) EstimateGas(transaction *types.Transaction, senderAddress common
}

if lowEnd == ethTransferGas && transaction.To() != nil {
code, err := s.tree.GetCode(ctx, *transaction.To(), l2BlockStateRoot.Bytes())
code, err := s.tree.GetCode(ctx, *transaction.To(), stateRoot.Bytes())
if err != nil {
log.Warnf("error while getting transaction.to() code %v", err)
} else if len(code) == 0 {
Expand All @@ -995,7 +1006,7 @@ func (s *State) EstimateGas(transaction *types.Transaction, senderAddress common
var availableBalance *big.Int

if senderAddress != ZeroAddress {
senderBalance, err := s.tree.GetBalance(ctx, senderAddress, l2BlockStateRoot.Bytes())
senderBalance, err := s.tree.GetBalance(ctx, senderAddress, stateRoot.Bytes())
if err != nil {
if errors.Is(err, ErrNotFound) {
senderBalance = big.NewInt(0)
Expand Down Expand Up @@ -1029,9 +1040,9 @@ func (s *State) EstimateGas(transaction *types.Transaction, senderAddress common

// Run the transaction with the specified gas value.
// Returns a status indicating if the transaction failed, if it was reverted and the accompanying error
testTransaction := func(gas uint64, shouldOmitErr bool) (failed, reverted bool, gasUsed uint64, returnValue []byte, err error) {
testTransaction := func(gas uint64, nonce uint64, shouldOmitErr bool) (failed, reverted bool, gasUsed uint64, returnValue []byte, err error) {
tx := types.NewTx(&types.LegacyTx{
Nonce: transaction.Nonce(),
Nonce: nonce,
To: transaction.To(),
Value: transaction.Value(),
Gas: gas,
Expand All @@ -1052,7 +1063,7 @@ func (s *State) EstimateGas(transaction *types.Transaction, senderAddress common
OldBatchNum: lastBatch.BatchNumber,
BatchL2Data: batchL2Data,
From: senderAddress.String(),
OldStateRoot: l2BlockStateRoot.Bytes(),
OldStateRoot: stateRoot.Bytes(),
GlobalExitRoot: lastBatch.GlobalExitRoot.Bytes(),
OldAccInputHash: previousBatch.AccInputHash.Bytes(),
EthTimestamp: uint64(lastBatch.Timestamp.Unix()),
Expand Down Expand Up @@ -1116,7 +1127,7 @@ func (s *State) EstimateGas(transaction *types.Transaction, senderAddress common
var totalExecutionTime time.Duration

// Check if the highEnd is a good value to make the transaction pass
failed, reverted, gasUsed, returnValue, err := testTransaction(highEnd, false)
failed, reverted, gasUsed, returnValue, err := testTransaction(highEnd, nonce, false)
log.Debugf("Estimate gas. Trying to execute TX with %v gas", highEnd)
if failed {
if reverted {
Expand All @@ -1142,7 +1153,7 @@ func (s *State) EstimateGas(transaction *types.Transaction, senderAddress common

log.Debugf("Estimate gas. Trying to execute TX with %v gas", mid)

failed, reverted, _, _, testErr := testTransaction(mid, true)
failed, reverted, _, _, testErr := testTransaction(mid, nonce, true)
executionTime := time.Since(txExecutionStart)
totalExecutionTime += executionTime
txExecutions = append(txExecutions, executionTime)
Expand Down