diff --git a/aggregator/aggregator.go b/aggregator/aggregator.go index 74aed60c3b..1b23c11202 100644 --- a/aggregator/aggregator.go +++ b/aggregator/aggregator.go @@ -756,8 +756,23 @@ func (a *Aggregator) getAndLockBatchToProve(ctx context.Context, prover proverIn return nil, nil, err } + // Get header of the last L1 block + lastL1BlockHeader, err := a.Ethman.GetLatestBlockHeader(ctx) + if err != nil { + log.Errorf("Failed to get last L1 block header, err: %v", err) + return nil, nil, err + } + lastL1BlockNumber := lastL1BlockHeader.Number.Uint64() + + // Calculate max L1 block number for getting next virtual batch to prove + maxL1BlockNumber := uint64(0) + if a.cfg.BatchProofL1BlockConfirmations <= lastL1BlockNumber { + maxL1BlockNumber = lastL1BlockNumber - a.cfg.BatchProofL1BlockConfirmations + } + log.Debugf("Max L1 block number for getting next virtual batch to prove: %d", maxL1BlockNumber) + // Get virtual batch pending to generate proof - batchToVerify, err := a.State.GetVirtualBatchToProve(ctx, lastVerifiedBatch.BatchNumber, nil) + batchToVerify, err := a.State.GetVirtualBatchToProve(ctx, lastVerifiedBatch.BatchNumber, maxL1BlockNumber, nil) if err != nil { return nil, nil, err } diff --git a/aggregator/aggregator_test.go b/aggregator/aggregator_test.go index eb51a09381..a071828a16 100644 --- a/aggregator/aggregator_test.go +++ b/aggregator/aggregator_test.go @@ -17,6 +17,7 @@ import ( "github.com/0xPolygonHermez/zkevm-node/state" "github.com/0xPolygonHermez/zkevm-node/test/testutils" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -775,7 +776,7 @@ func TestTryGenerateBatchProof(t *testing.T) { m.proverMock.On("ID").Return(proverID).Twice() m.proverMock.On("Addr").Return("addr") m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(&lastVerifiedBatch, nil).Once() - m.stateMock.On("GetVirtualBatchToProve", mock.MatchedBy(matchProverCtxFn), lastVerifiedBatchNum, nil).Return(&batchToProve, nil).Once() + m.stateMock.On("GetVirtualBatchToProve", mock.MatchedBy(matchProverCtxFn), lastVerifiedBatchNum, mock.Anything, nil).Return(&batchToProve, nil).Once() m.stateMock.On("AddGeneratedProof", mock.MatchedBy(matchProverCtxFn), mock.Anything, nil).Run( func(args mock.Arguments) { proof := args[1].(*state.Proof) @@ -798,6 +799,7 @@ func TestTryGenerateBatchProof(t *testing.T) { L1InfoRoot: &l1InfoRoot, TimestampBatchEtrog: &t, } + m.etherman.On("GetLatestBlockHeader", mock.Anything).Return(&types.Header{Number: new(big.Int).SetUint64(1)}, nil).Once() m.stateMock.On("GetVirtualBatch", mock.Anything, lastVerifiedBatchNum+1, nil).Return(&vb, nil).Twice() m.stateMock.On("GetLeafsByL1InfoRoot", mock.Anything, *vb.L1InfoRoot, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil).Twice() expectedInputProver, err := a.buildInputProver(context.Background(), &batchToProve) @@ -817,7 +819,7 @@ func TestTryGenerateBatchProof(t *testing.T) { m.proverMock.On("ID").Return(proverID).Twice() m.proverMock.On("Addr").Return("addr") m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(&lastVerifiedBatch, nil).Once() - m.stateMock.On("GetVirtualBatchToProve", mock.MatchedBy(matchProverCtxFn), lastVerifiedBatchNum, nil).Return(&batchToProve, nil).Once() + m.stateMock.On("GetVirtualBatchToProve", mock.MatchedBy(matchProverCtxFn), lastVerifiedBatchNum, mock.Anything, nil).Return(&batchToProve, nil).Once() m.stateMock.On("AddGeneratedProof", mock.MatchedBy(matchProverCtxFn), mock.Anything, nil).Run( func(args mock.Arguments) { proof := args[1].(*state.Proof) @@ -840,6 +842,7 @@ func TestTryGenerateBatchProof(t *testing.T) { L1InfoRoot: &l1InfoRoot, TimestampBatchEtrog: &t, } + m.etherman.On("GetLatestBlockHeader", mock.Anything).Return(&types.Header{Number: new(big.Int).SetUint64(1)}, nil).Once() m.stateMock.On("GetVirtualBatch", mock.Anything, lastVerifiedBatchNum+1, nil).Return(&vb, nil).Twice() m.stateMock.On("GetLeafsByL1InfoRoot", mock.Anything, *vb.L1InfoRoot, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil).Twice() expectedInputProver, err := a.buildInputProver(context.Background(), &batchToProve) @@ -860,7 +863,7 @@ func TestTryGenerateBatchProof(t *testing.T) { m.proverMock.On("ID").Return(proverID).Twice() m.proverMock.On("Addr").Return(proverID) m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(&lastVerifiedBatch, nil).Once() - m.stateMock.On("GetVirtualBatchToProve", mock.MatchedBy(matchProverCtxFn), lastVerifiedBatchNum, nil).Return(&batchToProve, nil).Once() + m.stateMock.On("GetVirtualBatchToProve", mock.MatchedBy(matchProverCtxFn), lastVerifiedBatchNum, mock.Anything, nil).Return(&batchToProve, nil).Once() m.stateMock.On("AddGeneratedProof", mock.MatchedBy(matchProverCtxFn), mock.Anything, nil).Run( func(args mock.Arguments) { proof := args[1].(*state.Proof) @@ -883,6 +886,7 @@ func TestTryGenerateBatchProof(t *testing.T) { L1InfoRoot: &l1InfoRoot, TimestampBatchEtrog: &t, } + m.etherman.On("GetLatestBlockHeader", mock.Anything).Return(&types.Header{Number: new(big.Int).SetUint64(1)}, nil).Once() m.stateMock.On("GetVirtualBatch", mock.Anything, lastVerifiedBatchNum+1, nil).Return(&vb, nil).Twice() m.stateMock.On("GetLeafsByL1InfoRoot", mock.Anything, *vb.L1InfoRoot, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil).Twice() expectedInputProver, err := a.buildInputProver(context.Background(), &batchToProve) @@ -903,7 +907,7 @@ func TestTryGenerateBatchProof(t *testing.T) { m.proverMock.On("ID").Return(proverID).Times(3) m.proverMock.On("Addr").Return("addr") m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(&lastVerifiedBatch, nil).Once() - m.stateMock.On("GetVirtualBatchToProve", mock.MatchedBy(matchProverCtxFn), lastVerifiedBatchNum, nil).Return(&batchToProve, nil).Once() + m.stateMock.On("GetVirtualBatchToProve", mock.MatchedBy(matchProverCtxFn), lastVerifiedBatchNum, mock.Anything, nil).Return(&batchToProve, nil).Once() m.stateMock.On("AddGeneratedProof", mock.MatchedBy(matchProverCtxFn), mock.Anything, nil).Run( func(args mock.Arguments) { proof := args[1].(*state.Proof) @@ -926,6 +930,7 @@ func TestTryGenerateBatchProof(t *testing.T) { L1InfoRoot: &l1InfoRoot, TimestampBatchEtrog: &t, } + m.etherman.On("GetLatestBlockHeader", mock.Anything).Return(&types.Header{Number: new(big.Int).SetUint64(1)}, nil).Once() m.stateMock.On("GetVirtualBatch", mock.Anything, lastVerifiedBatchNum+1, nil).Return(&vb, nil).Twice() m.stateMock.On("GetLeafsByL1InfoRoot", mock.Anything, *vb.L1InfoRoot, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil).Twice() expectedInputProver, err := a.buildInputProver(context.Background(), &batchToProve) @@ -960,7 +965,7 @@ func TestTryGenerateBatchProof(t *testing.T) { m.proverMock.On("ID").Return(proverID).Times(3) m.proverMock.On("Addr").Return("addr") m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(&lastVerifiedBatch, nil).Once() - m.stateMock.On("GetVirtualBatchToProve", mock.MatchedBy(matchProverCtxFn), lastVerifiedBatchNum, nil).Return(&batchToProve, nil).Once() + m.stateMock.On("GetVirtualBatchToProve", mock.MatchedBy(matchProverCtxFn), lastVerifiedBatchNum, mock.Anything, nil).Return(&batchToProve, nil).Once() m.stateMock.On("AddGeneratedProof", mock.MatchedBy(matchProverCtxFn), mock.Anything, nil).Run( func(args mock.Arguments) { proof := args[1].(*state.Proof) @@ -995,6 +1000,7 @@ func TestTryGenerateBatchProof(t *testing.T) { On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil). Return(&state.VerifiedBatch{BatchNumber: uint64(42)}, nil).Once() m.etherman.On("GetLatestVerifiedBatchNum").Return(uint64(42), nil).Once() + m.etherman.On("GetLatestBlockHeader", mock.Anything).Return(&types.Header{Number: new(big.Int).SetUint64(1)}, nil).Once() // make tryBuildFinalProof fail ASAP m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(nil, errBanana).Once().NotBefore(isSyncedCall) m.stateMock.On("UpdateGeneratedProof", mock.MatchedBy(matchAggregatorCtxFn), mock.Anything, nil).Run( diff --git a/aggregator/config.go b/aggregator/config.go index 9099df1931..420d6dcd2a 100644 --- a/aggregator/config.go +++ b/aggregator/config.go @@ -88,4 +88,7 @@ type Config struct { // UpgradeEtrogBatchNumber is the number of the first batch after upgrading to etrog UpgradeEtrogBatchNumber uint64 `mapstructure:"UpgradeEtrogBatchNumber"` + + // BatchProofL1BlockConfirmations is number of L1 blocks to consider we can generate the proof for a virtual batch + BatchProofL1BlockConfirmations uint64 `mapstructure:"BatchProofL1BlockConfirmations"` } diff --git a/aggregator/interfaces.go b/aggregator/interfaces.go index 3bc9c2fe8a..0d6b11b7ed 100644 --- a/aggregator/interfaces.go +++ b/aggregator/interfaces.go @@ -9,6 +9,7 @@ import ( "github.com/0xPolygonHermez/zkevm-node/ethtxmanager" "github.com/0xPolygonHermez/zkevm-node/state" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" "github.com/jackc/pgx/v4" ) @@ -39,6 +40,7 @@ type ethTxManager interface { type etherman interface { GetLatestVerifiedBatchNum() (uint64, error) BuildTrustedVerifyBatchesTxData(lastVerifiedBatch, newVerifiedBatch uint64, inputs *ethmanTypes.FinalProofInputs, beneficiary common.Address) (to *common.Address, data []byte, err error) + GetLatestBlockHeader(ctx context.Context) (*types.Header, error) } // aggregatorTxProfitabilityChecker interface for different profitability @@ -53,7 +55,7 @@ type stateInterface interface { CheckProofContainsCompleteSequences(ctx context.Context, proof *state.Proof, dbTx pgx.Tx) (bool, error) GetLastVerifiedBatch(ctx context.Context, dbTx pgx.Tx) (*state.VerifiedBatch, error) GetProofReadyToVerify(ctx context.Context, lastVerfiedBatchNumber uint64, dbTx pgx.Tx) (*state.Proof, error) - GetVirtualBatchToProve(ctx context.Context, lastVerfiedBatchNumber uint64, dbTx pgx.Tx) (*state.Batch, error) + GetVirtualBatchToProve(ctx context.Context, lastVerfiedBatchNumber uint64, maxL1Block uint64, dbTx pgx.Tx) (*state.Batch, error) GetProofsToAggregate(ctx context.Context, dbTx pgx.Tx) (*state.Proof, *state.Proof, error) GetBatchByNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.Batch, error) AddGeneratedProof(ctx context.Context, proof *state.Proof, dbTx pgx.Tx) error diff --git a/aggregator/mocks/mock_etherman.go b/aggregator/mocks/mock_etherman.go index 4f0f97c61e..077771c339 100644 --- a/aggregator/mocks/mock_etherman.go +++ b/aggregator/mocks/mock_etherman.go @@ -3,7 +3,12 @@ package mocks import ( + context "context" + common "github.com/ethereum/go-ethereum/common" + + coretypes "github.com/ethereum/go-ethereum/core/types" + mock "github.com/stretchr/testify/mock" types "github.com/0xPolygonHermez/zkevm-node/etherman/types" @@ -53,6 +58,36 @@ func (_m *Etherman) BuildTrustedVerifyBatchesTxData(lastVerifiedBatch uint64, ne return r0, r1, r2 } +// GetLatestBlockHeader provides a mock function with given fields: ctx +func (_m *Etherman) GetLatestBlockHeader(ctx context.Context) (*coretypes.Header, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for GetLatestBlockHeader") + } + + var r0 *coretypes.Header + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (*coretypes.Header, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) *coretypes.Header); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*coretypes.Header) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // GetLatestVerifiedBatchNum provides a mock function with given fields: func (_m *Etherman) GetLatestVerifiedBatchNum() (uint64, error) { ret := _m.Called() diff --git a/aggregator/mocks/mock_state.go b/aggregator/mocks/mock_state.go index 24b2ffd61e..cfc5b66e7d 100644 --- a/aggregator/mocks/mock_state.go +++ b/aggregator/mocks/mock_state.go @@ -454,9 +454,9 @@ func (_m *StateMock) GetVirtualBatchParentHash(ctx context.Context, batchNumber return r0, r1 } -// GetVirtualBatchToProve provides a mock function with given fields: ctx, lastVerfiedBatchNumber, dbTx -func (_m *StateMock) GetVirtualBatchToProve(ctx context.Context, lastVerfiedBatchNumber uint64, dbTx pgx.Tx) (*state.Batch, error) { - ret := _m.Called(ctx, lastVerfiedBatchNumber, dbTx) +// GetVirtualBatchToProve provides a mock function with given fields: ctx, lastVerfiedBatchNumber, maxL1Block, dbTx +func (_m *StateMock) GetVirtualBatchToProve(ctx context.Context, lastVerfiedBatchNumber uint64, maxL1Block uint64, dbTx pgx.Tx) (*state.Batch, error) { + ret := _m.Called(ctx, lastVerfiedBatchNumber, maxL1Block, dbTx) if len(ret) == 0 { panic("no return value specified for GetVirtualBatchToProve") @@ -464,19 +464,19 @@ func (_m *StateMock) GetVirtualBatchToProve(ctx context.Context, lastVerfiedBatc var r0 *state.Batch var r1 error - if rf, ok := ret.Get(0).(func(context.Context, uint64, pgx.Tx) (*state.Batch, error)); ok { - return rf(ctx, lastVerfiedBatchNumber, dbTx) + if rf, ok := ret.Get(0).(func(context.Context, uint64, uint64, pgx.Tx) (*state.Batch, error)); ok { + return rf(ctx, lastVerfiedBatchNumber, maxL1Block, dbTx) } - if rf, ok := ret.Get(0).(func(context.Context, uint64, pgx.Tx) *state.Batch); ok { - r0 = rf(ctx, lastVerfiedBatchNumber, dbTx) + if rf, ok := ret.Get(0).(func(context.Context, uint64, uint64, pgx.Tx) *state.Batch); ok { + r0 = rf(ctx, lastVerfiedBatchNumber, maxL1Block, dbTx) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*state.Batch) } } - if rf, ok := ret.Get(1).(func(context.Context, uint64, pgx.Tx) error); ok { - r1 = rf(ctx, lastVerfiedBatchNumber, dbTx) + if rf, ok := ret.Get(1).(func(context.Context, uint64, uint64, pgx.Tx) error); ok { + r1 = rf(ctx, lastVerfiedBatchNumber, maxL1Block, dbTx) } else { r1 = ret.Error(1) } diff --git a/config/config_test.go b/config/config_test.go index a031f88a68..2efaaf0616 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -477,6 +477,10 @@ func Test_Defaults(t *testing.T) { path: "Aggregator.UpgradeEtrogBatchNumber", expectedValue: uint64(0), }, + { + path: "Aggregator.BatchProofL1BlockConfirmations", + expectedValue: uint64(2), + }, { path: "State.Batch.Constraints.MaxTxsPerBatch", expectedValue: uint64(300), diff --git a/config/default.go b/config/default.go index a18586be4e..4bca8b1c9a 100644 --- a/config/default.go +++ b/config/default.go @@ -164,6 +164,7 @@ CleanupLockedProofsInterval = "2m" GeneratingProofCleanupThreshold = "10m" GasOffset = 0 UpgradeEtrogBatchNumber = 0 +BatchProofL1BlockConfirmations = 2 [L2GasPriceSuggester] Type = "follower" diff --git a/config/environments/local/local.node.config.toml b/config/environments/local/local.node.config.toml index ebf5b2544d..9fefe6362b 100644 --- a/config/environments/local/local.node.config.toml +++ b/config/environments/local/local.node.config.toml @@ -128,6 +128,7 @@ SenderAddress = "0x70997970c51812dc3a010c7d01b50e0d17dc79c8" CleanupLockedProofsInterval = "2m" GeneratingProofCleanupThreshold = "10m" UpgradeEtrogBatchNumber = 0 +BatchProofL1BlockConfirmations = 2 [EthTxManager] ForcedGas = 0 diff --git a/docs/config-file/node-config-doc.html b/docs/config-file/node-config-doc.html index 8f9e04279a..f578dbcd6a 100644 --- a/docs/config-file/node-config-doc.html +++ b/docs/config-file/node-config-doc.html @@ -66,7 +66,7 @@
"300ms"
ChainID is the L2 ChainID provided by the Network Config
ForkID is the L2 ForkID provided by the Network Config
SenderAddress defines which private key the eth tx manager needs to use
to sign the L1 txs
CleanupLockedProofsInterval is the interval of time to clean up locked proofs.
"1m"
"300ms"
-
GeneratingProofCleanupThreshold represents the time interval after
which a proof in generating state is considered to be stuck and
allowed to be cleared.
GasOffset is the amount of gas to be added to the gas estimation in order
to provide an amount that is higher than the estimated one. This is used
to avoid the TX getting reverted in case something has changed in the network
state after the estimation which can cause the TX to require more gas to be
executed.
ex:
gas estimation: 1000
gas offset: 100
final gas: 1100
UpgradeEtrogBatchNumber is the number of the first batch after upgrading to etrog
Chain ID of the L1 network
ZkEVMAddr Address of the L1 contract polygonZkEVMAddress
Must contain a minimum of 20
items
Must contain a maximum of 20
items
RollupManagerAddr Address of the L1 contract
Must contain a minimum of 20
items
Must contain a maximum of 20
items
PolAddr Address of the L1 Pol token Contract
Must contain a minimum of 20
items
Must contain a maximum of 20
items
GlobalExitRootManagerAddr Address of the L1 GlobalExitRootManager contract
Must contain a minimum of 20
items
Must contain a maximum of 20
items
BlockNumber is the block number where the polygonZKEVM smc was deployed on L1
Root hash of the genesis block
Must contain a minimum of 32
items
Must contain a maximum of 32
items
Actions is the data to populate into the state trie
DefaultGasPriceWei is used to set the gas price to be used by the default gas pricer or as minimim gas price by the follower gas pricer.
MaxGasPriceWei is used to limit the gas price returned by the follower gas pricer to a maximum value. It is ignored if 0.
"1m"
+
GeneratingProofCleanupThreshold represents the time interval after
which a proof in generating state is considered to be stuck and
allowed to be cleared.
GasOffset is the amount of gas to be added to the gas estimation in order
to provide an amount that is higher than the estimated one. This is used
to avoid the TX getting reverted in case something has changed in the network
state after the estimation which can cause the TX to require more gas to be
executed.
ex:
gas estimation: 1000
gas offset: 100
final gas: 1100
UpgradeEtrogBatchNumber is the number of the first batch after upgrading to etrog
BatchProofL1BlockConfirmations is number of L1 blocks to consider we can generate the proof for a virtual batch
Chain ID of the L1 network
ZkEVMAddr Address of the L1 contract polygonZkEVMAddress
Must contain a minimum of 20
items
Must contain a maximum of 20
items
RollupManagerAddr Address of the L1 contract
Must contain a minimum of 20
items
Must contain a maximum of 20
items
PolAddr Address of the L1 Pol token Contract
Must contain a minimum of 20
items
Must contain a maximum of 20
items
GlobalExitRootManagerAddr Address of the L1 GlobalExitRootManager contract
Must contain a minimum of 20
items
Must contain a maximum of 20
items
BlockNumber is the block number where the polygonZKEVM smc was deployed on L1
Root hash of the genesis block
Must contain a minimum of 32
items
Must contain a maximum of 32
items
Actions is the data to populate into the state trie
DefaultGasPriceWei is used to set the gas price to be used by the default gas pricer or as minimim gas price by the follower gas pricer.
MaxGasPriceWei is used to limit the gas price returned by the follower gas pricer to a maximum value. It is ignored if 0.
"1m"
"300ms"
"1m"
"300ms"
diff --git a/docs/config-file/node-config-doc.md b/docs/config-file/node-config-doc.md
index 37a3d6563a..249daf8660 100644
--- a/docs/config-file/node-config-doc.md
+++ b/docs/config-file/node-config-doc.md
@@ -2370,6 +2370,7 @@ GasOffset=80000
| - [GeneratingProofCleanupThreshold](#Aggregator_GeneratingProofCleanupThreshold ) | No | string | No | - | GeneratingProofCleanupThreshold represents the time interval after
which a proof in generating state is considered to be stuck and
allowed to be cleared. |
| - [GasOffset](#Aggregator_GasOffset ) | No | integer | No | - | GasOffset is the amount of gas to be added to the gas estimation in order
to provide an amount that is higher than the estimated one. This is used
to avoid the TX getting reverted in case something has changed in the network
state after the estimation which can cause the TX to require more gas to be
executed.
ex:
gas estimation: 1000
gas offset: 100
final gas: 1100 |
| - [UpgradeEtrogBatchNumber](#Aggregator_UpgradeEtrogBatchNumber ) | No | integer | No | - | UpgradeEtrogBatchNumber is the number of the first batch after upgrading to etrog |
+| - [BatchProofL1BlockConfirmations](#Aggregator_BatchProofL1BlockConfirmations ) | No | integer | No | - | BatchProofL1BlockConfirmations is number of L1 blocks to consider we can generate the proof for a virtual batch |
### 12.1. `Aggregator.Host`
@@ -2647,6 +2648,20 @@ GasOffset=0
UpgradeEtrogBatchNumber=0
```
+### 12.16. `Aggregator.BatchProofL1BlockConfirmations`
+
+**Type:** : `integer`
+
+**Default:** `2`
+
+**Description:** BatchProofL1BlockConfirmations is number of L1 blocks to consider we can generate the proof for a virtual batch
+
+**Example setting the default value** (2):
+```
+[Aggregator]
+BatchProofL1BlockConfirmations=2
+```
+
## 13. `[NetworkConfig]`
**Type:** : `object`
diff --git a/docs/config-file/node-config-schema.json b/docs/config-file/node-config-schema.json
index b28e8ea462..95e2e2b248 100644
--- a/docs/config-file/node-config-schema.json
+++ b/docs/config-file/node-config-schema.json
@@ -1011,6 +1011,11 @@
"type": "integer",
"description": "UpgradeEtrogBatchNumber is the number of the first batch after upgrading to etrog",
"default": 0
+ },
+ "BatchProofL1BlockConfirmations": {
+ "type": "integer",
+ "description": "BatchProofL1BlockConfirmations is number of L1 blocks to consider we can generate the proof for a virtual batch",
+ "default": 2
}
},
"additionalProperties": false,
diff --git a/state/interfaces.go b/state/interfaces.go
index 17636f5ce1..f6b5859a80 100644
--- a/state/interfaces.go
+++ b/state/interfaces.go
@@ -98,7 +98,7 @@ type storage interface {
GetExitRootByGlobalExitRoot(ctx context.Context, ger common.Hash, dbTx pgx.Tx) (*GlobalExitRoot, error)
AddSequence(ctx context.Context, sequence Sequence, dbTx pgx.Tx) error
GetSequences(ctx context.Context, lastVerifiedBatchNumber uint64, dbTx pgx.Tx) ([]Sequence, error)
- GetVirtualBatchToProve(ctx context.Context, lastVerfiedBatchNumber uint64, dbTx pgx.Tx) (*Batch, error)
+ GetVirtualBatchToProve(ctx context.Context, lastVerfiedBatchNumber uint64, maxL1Block uint64, dbTx pgx.Tx) (*Batch, error)
CheckProofContainsCompleteSequences(ctx context.Context, proof *Proof, dbTx pgx.Tx) (bool, error)
GetProofReadyToVerify(ctx context.Context, lastVerfiedBatchNumber uint64, dbTx pgx.Tx) (*Proof, error)
GetProofsToAggregate(ctx context.Context, dbTx pgx.Tx) (*Proof, *Proof, error)
diff --git a/state/mocks/mock_storage.go b/state/mocks/mock_storage.go
index 559e73a930..4856aa7e41 100644
--- a/state/mocks/mock_storage.go
+++ b/state/mocks/mock_storage.go
@@ -6950,9 +6950,9 @@ func (_c *StorageMock_GetVirtualBatchParentHash_Call) RunAndReturn(run func(cont
return _c
}
-// GetVirtualBatchToProve provides a mock function with given fields: ctx, lastVerfiedBatchNumber, dbTx
-func (_m *StorageMock) GetVirtualBatchToProve(ctx context.Context, lastVerfiedBatchNumber uint64, dbTx pgx.Tx) (*state.Batch, error) {
- ret := _m.Called(ctx, lastVerfiedBatchNumber, dbTx)
+// GetVirtualBatchToProve provides a mock function with given fields: ctx, lastVerfiedBatchNumber, maxL1Block, dbTx
+func (_m *StorageMock) GetVirtualBatchToProve(ctx context.Context, lastVerfiedBatchNumber uint64, maxL1Block uint64, dbTx pgx.Tx) (*state.Batch, error) {
+ ret := _m.Called(ctx, lastVerfiedBatchNumber, maxL1Block, dbTx)
if len(ret) == 0 {
panic("no return value specified for GetVirtualBatchToProve")
@@ -6960,19 +6960,19 @@ func (_m *StorageMock) GetVirtualBatchToProve(ctx context.Context, lastVerfiedBa
var r0 *state.Batch
var r1 error
- if rf, ok := ret.Get(0).(func(context.Context, uint64, pgx.Tx) (*state.Batch, error)); ok {
- return rf(ctx, lastVerfiedBatchNumber, dbTx)
+ if rf, ok := ret.Get(0).(func(context.Context, uint64, uint64, pgx.Tx) (*state.Batch, error)); ok {
+ return rf(ctx, lastVerfiedBatchNumber, maxL1Block, dbTx)
}
- if rf, ok := ret.Get(0).(func(context.Context, uint64, pgx.Tx) *state.Batch); ok {
- r0 = rf(ctx, lastVerfiedBatchNumber, dbTx)
+ if rf, ok := ret.Get(0).(func(context.Context, uint64, uint64, pgx.Tx) *state.Batch); ok {
+ r0 = rf(ctx, lastVerfiedBatchNumber, maxL1Block, dbTx)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*state.Batch)
}
}
- if rf, ok := ret.Get(1).(func(context.Context, uint64, pgx.Tx) error); ok {
- r1 = rf(ctx, lastVerfiedBatchNumber, dbTx)
+ if rf, ok := ret.Get(1).(func(context.Context, uint64, uint64, pgx.Tx) error); ok {
+ r1 = rf(ctx, lastVerfiedBatchNumber, maxL1Block, dbTx)
} else {
r1 = ret.Error(1)
}
@@ -6988,14 +6988,15 @@ type StorageMock_GetVirtualBatchToProve_Call struct {
// GetVirtualBatchToProve is a helper method to define mock.On call
// - ctx context.Context
// - lastVerfiedBatchNumber uint64
+// - maxL1Block uint64
// - dbTx pgx.Tx
-func (_e *StorageMock_Expecter) GetVirtualBatchToProve(ctx interface{}, lastVerfiedBatchNumber interface{}, dbTx interface{}) *StorageMock_GetVirtualBatchToProve_Call {
- return &StorageMock_GetVirtualBatchToProve_Call{Call: _e.mock.On("GetVirtualBatchToProve", ctx, lastVerfiedBatchNumber, dbTx)}
+func (_e *StorageMock_Expecter) GetVirtualBatchToProve(ctx interface{}, lastVerfiedBatchNumber interface{}, maxL1Block interface{}, dbTx interface{}) *StorageMock_GetVirtualBatchToProve_Call {
+ return &StorageMock_GetVirtualBatchToProve_Call{Call: _e.mock.On("GetVirtualBatchToProve", ctx, lastVerfiedBatchNumber, maxL1Block, dbTx)}
}
-func (_c *StorageMock_GetVirtualBatchToProve_Call) Run(run func(ctx context.Context, lastVerfiedBatchNumber uint64, dbTx pgx.Tx)) *StorageMock_GetVirtualBatchToProve_Call {
+func (_c *StorageMock_GetVirtualBatchToProve_Call) Run(run func(ctx context.Context, lastVerfiedBatchNumber uint64, maxL1Block uint64, dbTx pgx.Tx)) *StorageMock_GetVirtualBatchToProve_Call {
_c.Call.Run(func(args mock.Arguments) {
- run(args[0].(context.Context), args[1].(uint64), args[2].(pgx.Tx))
+ run(args[0].(context.Context), args[1].(uint64), args[2].(uint64), args[3].(pgx.Tx))
})
return _c
}
@@ -7005,7 +7006,7 @@ func (_c *StorageMock_GetVirtualBatchToProve_Call) Return(_a0 *state.Batch, _a1
return _c
}
-func (_c *StorageMock_GetVirtualBatchToProve_Call) RunAndReturn(run func(context.Context, uint64, pgx.Tx) (*state.Batch, error)) *StorageMock_GetVirtualBatchToProve_Call {
+func (_c *StorageMock_GetVirtualBatchToProve_Call) RunAndReturn(run func(context.Context, uint64, uint64, pgx.Tx) (*state.Batch, error)) *StorageMock_GetVirtualBatchToProve_Call {
_c.Call.Return(run)
return _c
}
diff --git a/state/pgstatestorage/batch.go b/state/pgstatestorage/batch.go
index 214be8a685..83bfad3cdb 100644
--- a/state/pgstatestorage/batch.go
+++ b/state/pgstatestorage/batch.go
@@ -764,7 +764,7 @@ func (p *PostgresStorage) GetLastVerifiedBatch(ctx context.Context, dbTx pgx.Tx)
// GetVirtualBatchToProve return the next batch that is not proved, neither in
// proved process.
-func (p *PostgresStorage) GetVirtualBatchToProve(ctx context.Context, lastVerfiedBatchNumber uint64, dbTx pgx.Tx) (*state.Batch, error) {
+func (p *PostgresStorage) GetVirtualBatchToProve(ctx context.Context, lastVerfiedBatchNumber uint64, maxL1Block uint64, dbTx pgx.Tx) (*state.Batch, error) {
const query = `
SELECT
b.batch_num,
@@ -783,6 +783,7 @@ func (p *PostgresStorage) GetVirtualBatchToProve(ctx context.Context, lastVerfie
state.virtual_batch v
WHERE
b.batch_num > $1 AND b.batch_num = v.batch_num AND
+ v.block_num <= $2 AND
NOT EXISTS (
SELECT p.batch_num FROM state.proof p
WHERE v.batch_num >= p.batch_num AND v.batch_num <= p.batch_num_final
@@ -790,7 +791,7 @@ func (p *PostgresStorage) GetVirtualBatchToProve(ctx context.Context, lastVerfie
ORDER BY b.batch_num ASC LIMIT 1
`
e := p.getExecQuerier(dbTx)
- row := e.QueryRow(ctx, query, lastVerfiedBatchNumber)
+ row := e.QueryRow(ctx, query, lastVerfiedBatchNumber, maxL1Block)
batch, err := scanBatch(row)
if errors.Is(err, pgx.ErrNoRows) {
return nil, state.ErrNotFound
diff --git a/test/config/debug.node.config.toml b/test/config/debug.node.config.toml
index aa1a5f5ee0..32bbdd7f56 100644
--- a/test/config/debug.node.config.toml
+++ b/test/config/debug.node.config.toml
@@ -129,6 +129,7 @@ SenderAddress = "0x70997970c51812dc3a010c7d01b50e0d17dc79c8"
CleanupLockedProofsInterval = "2m"
GeneratingProofCleanupThreshold = "10m"
UpgradeEtrogBatchNumber = 0
+BatchProofL1BlockConfirmations = 2
[EthTxManager]
ForcedGas = 0
diff --git a/test/config/test.node.config.toml b/test/config/test.node.config.toml
index 76c6e53aee..8d6a0d215d 100644
--- a/test/config/test.node.config.toml
+++ b/test/config/test.node.config.toml
@@ -146,6 +146,7 @@ SenderAddress = "0x70997970c51812dc3a010c7d01b50e0d17dc79c8"
CleanupLockedProofsInterval = "2m"
GeneratingProofCleanupThreshold = "10m"
UpgradeEtrogBatchNumber = 0
+BatchProofL1BlockConfirmations = 2
[EthTxManager]
ForcedGas = 0