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

synchronizer accepts empty closed batches from trusted #3370

Merged
Merged
Show file tree
Hide file tree
Changes from 4 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: 1 addition & 1 deletion cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ func runSynchronizer(cfg config.Config, etherman *etherman.Client, ethTxManagerS
log.Fatal("error getting trusted sequencer URI. Error: %v", err)
}
}
log.Debug("trustedSequencerURL ", trustedSequencerURL)
log.Info("trustedSequencerURL ", trustedSequencerURL)
}
zkEVMClient := client.NewClient(trustedSequencerURL)

Expand Down
4 changes: 4 additions & 0 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ func Test_Defaults(t *testing.T) {
path: "Synchronizer.L1ParallelSynchronization.MaxPendingNoProcessedBlocks",
expectedValue: uint64(25),
},
{
path: "Synchronizer.L2Synchronization.AcceptEmptyClosedBatches",
expectedValue: false,
},
{
path: "Sequencer.DeletePoolTxsL1BlockConfirmations",
expectedValue: uint64(100),
Expand Down
2 changes: 2 additions & 0 deletions config/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ L1SynchronizationMode = "sequential"
[Synchronizer.L1ParallelSynchronization.PerformanceWarning]
AceptableInacctivityTime = "5s"
ApplyAfterNumRollupReceived = 10
[Synchronizer.L2Synchronization]
AcceptEmptyClosedBatches = false

[Sequencer]
DeletePoolTxsL1BlockConfirmations = 100
Expand Down
2 changes: 1 addition & 1 deletion docs/config-file/node-config-doc.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
</pre></div> </div><div id=Synchronizer_L1ParallelSynchronization_TimeOutMainLoop_ex2 class="jumbotron examples"><div class=highlight><pre><span></span><span class=s2>&quot;300ms&quot;</span>
</pre></div> </div> <hr> <div class=breadcrumbs> <!-- None --><!-- None --><!-- None --><a href=#Synchronizer.L1ParallelSynchronization.RollupInfoRetriesSpacing onclick="anchorLink('Synchronizer.L1ParallelSynchronization.RollupInfoRetriesSpacing')">Synchronizer.L1ParallelSynchronization.RollupInfoRetriesSpacing=</a> </div> <span class="badge badge-success default-value">Default: "5s"</span><span class="badge badge-dark value-type">Type: string</span><br> <span class=description><p>RollupInfoRetriesSpacing is the minimum time between retries to request rollup info (it will sleep for fulfill this time) to avoid spamming L1</p> </span> <br> <div class="badge badge-secondary">Examples:</div> <br><div id=Synchronizer_L1ParallelSynchronization_RollupInfoRetriesSpacing_ex1 class="jumbotron examples"><div class=highlight><pre><span></span><span class=s2>&quot;1m&quot;</span>
</pre></div> </div><div id=Synchronizer_L1ParallelSynchronization_RollupInfoRetriesSpacing_ex2 class="jumbotron examples"><div class=highlight><pre><span></span><span class=s2>&quot;300ms&quot;</span>
</pre></div> </div> <hr> <div class=breadcrumbs> <!-- None --><!-- None --><!-- None --><a href=#Synchronizer.L1ParallelSynchronization.FallbackToSequentialModeOnSynchronized onclick="anchorLink('Synchronizer.L1ParallelSynchronization.FallbackToSequentialModeOnSynchronized')">Synchronizer.L1ParallelSynchronization.FallbackToSequentialModeOnSynchronized=</a> </div> <span class="badge badge-success default-value">Default: false</span><span class="badge badge-dark value-type">Type: boolean</span><br> <span class=description><p>FallbackToSequentialModeOnSynchronized if true switch to sequential mode if the system is synchronized</p> </span> <hr> </div> </div> </div> </div> </div> </div> </div> </div> <div class=accordion id=accordionSequencer> <div class=card> <div class=card-header id=headingSequencer> <h2 class=mb-0> <button class="btn btn-link property-name-button" type=button data-toggle=collapse data-target=#Sequencer aria-expanded aria-controls=Sequencer onclick="setAnchor('#Sequencer')"><span class=property-name> <div class=breadcrumbs>[<a href=#Sequencer onclick="anchorLink('Sequencer')">Sequencer</a>] </div></span></button> </h2> Configuration of the sequencer service </div> <div id=Sequencer class="collapse property-definition-div" aria-labelledby=headingSequencer data-parent=#accordionSequencer> <div class="card-body pl-5"> <div class=breadcrumbs> <!-- None --><!-- None --><a href=#Sequencer.DeletePoolTxsL1BlockConfirmations onclick="anchorLink('Sequencer.DeletePoolTxsL1BlockConfirmations')">Sequencer.DeletePoolTxsL1BlockConfirmations=</a> </div> <span class="badge badge-success default-value">Default: 100</span><span class="badge badge-dark value-type">Type: integer</span><br> <span class=description><p>DeletePoolTxsL1BlockConfirmations is blocks amount after which txs will be deleted from the pool</p> </span> <hr> <div class=breadcrumbs> <!-- None --><!-- None --><a href=#Sequencer.DeletePoolTxsCheckInterval onclick="anchorLink('Sequencer.DeletePoolTxsCheckInterval')">Sequencer.DeletePoolTxsCheckInterval=</a> </div> <span class="badge badge-success default-value">Default: "12h0m0s"</span><span class="badge badge-dark value-type">Type: string</span><br> <span class=description><p>DeletePoolTxsCheckInterval is frequency with which txs will be checked for deleting</p> </span> <br> <div class="badge badge-secondary">Examples:</div> <br><div id=Sequencer_DeletePoolTxsCheckInterval_ex1 class="jumbotron examples"><div class=highlight><pre><span></span><span class=s2>&quot;1m&quot;</span>
</pre></div> </div> <hr> <div class=breadcrumbs> <!-- None --><!-- None --><!-- None --><a href=#Synchronizer.L1ParallelSynchronization.FallbackToSequentialModeOnSynchronized onclick="anchorLink('Synchronizer.L1ParallelSynchronization.FallbackToSequentialModeOnSynchronized')">Synchronizer.L1ParallelSynchronization.FallbackToSequentialModeOnSynchronized=</a> </div> <span class="badge badge-success default-value">Default: false</span><span class="badge badge-dark value-type">Type: boolean</span><br> <span class=description><p>FallbackToSequentialModeOnSynchronized if true switch to sequential mode if the system is synchronized</p> </span> <hr> </div> </div> </div> </div> <div class=accordion id=accordionSynchronizer_L2Synchronization> <div class=card> <div class=card-header id=headingSynchronizer_L2Synchronization> <h2 class=mb-0> <button class="btn btn-link property-name-button" type=button data-toggle=collapse data-target=#Synchronizer_L2Synchronization aria-expanded aria-controls=Synchronizer_L2Synchronization onclick="setAnchor('#Synchronizer_L2Synchronization')"><span class=property-name> <div class=breadcrumbs>[<a href=#Synchronizer onclick="anchorLink('Synchronizer')">Synchronizer</a> . <a href=#Synchronizer_L2Synchronization onclick="anchorLink('Synchronizer_L2Synchronization')">L2Synchronization</a>] </div></span></button> </h2> L2Synchronization Configuration for L2 synchronization </div> <div id=Synchronizer_L2Synchronization class="collapse property-definition-div" aria-labelledby=headingSynchronizer_L2Synchronization data-parent=#accordionSynchronizer_L2Synchronization> <div class="card-body pl-5"> <div class=breadcrumbs> <!-- None --><!-- None --><!-- None --><a href=#Synchronizer.L2Synchronization.AcceptEmptyClosedBatches onclick="anchorLink('Synchronizer.L2Synchronization.AcceptEmptyClosedBatches')">Synchronizer.L2Synchronization.AcceptEmptyClosedBatches=</a> </div> <span class="badge badge-success default-value">Default: false</span><span class="badge badge-dark value-type">Type: boolean</span><br> <span class=description><p>AcceptEmptyClosedBatches is a flag to enable or disable the acceptance of empty batches.<br> if true, the synchronizer will accept empty batches and process them.</p> </span> <hr> </div> </div> </div> </div> </div> </div> </div> </div> <div class=accordion id=accordionSequencer> <div class=card> <div class=card-header id=headingSequencer> <h2 class=mb-0> <button class="btn btn-link property-name-button" type=button data-toggle=collapse data-target=#Sequencer aria-expanded aria-controls=Sequencer onclick="setAnchor('#Sequencer')"><span class=property-name> <div class=breadcrumbs>[<a href=#Sequencer onclick="anchorLink('Sequencer')">Sequencer</a>] </div></span></button> </h2> Configuration of the sequencer service </div> <div id=Sequencer class="collapse property-definition-div" aria-labelledby=headingSequencer data-parent=#accordionSequencer> <div class="card-body pl-5"> <div class=breadcrumbs> <!-- None --><!-- None --><a href=#Sequencer.DeletePoolTxsL1BlockConfirmations onclick="anchorLink('Sequencer.DeletePoolTxsL1BlockConfirmations')">Sequencer.DeletePoolTxsL1BlockConfirmations=</a> </div> <span class="badge badge-success default-value">Default: 100</span><span class="badge badge-dark value-type">Type: integer</span><br> <span class=description><p>DeletePoolTxsL1BlockConfirmations is blocks amount after which txs will be deleted from the pool</p> </span> <hr> <div class=breadcrumbs> <!-- None --><!-- None --><a href=#Sequencer.DeletePoolTxsCheckInterval onclick="anchorLink('Sequencer.DeletePoolTxsCheckInterval')">Sequencer.DeletePoolTxsCheckInterval=</a> </div> <span class="badge badge-success default-value">Default: "12h0m0s"</span><span class="badge badge-dark value-type">Type: string</span><br> <span class=description><p>DeletePoolTxsCheckInterval is frequency with which txs will be checked for deleting</p> </span> <br> <div class="badge badge-secondary">Examples:</div> <br><div id=Sequencer_DeletePoolTxsCheckInterval_ex1 class="jumbotron examples"><div class=highlight><pre><span></span><span class=s2>&quot;1m&quot;</span>
</pre></div> </div><div id=Sequencer_DeletePoolTxsCheckInterval_ex2 class="jumbotron examples"><div class=highlight><pre><span></span><span class=s2>&quot;300ms&quot;</span>
</pre></div> </div> <hr> <div class=breadcrumbs> <!-- None --><!-- None --><a href=#Sequencer.TxLifetimeCheckInterval onclick="anchorLink('Sequencer.TxLifetimeCheckInterval')">Sequencer.TxLifetimeCheckInterval=</a> </div> <span class="badge badge-success default-value">Default: "10m0s"</span><span class="badge badge-dark value-type">Type: string</span><br> <span class=description><p>TxLifetimeCheckInterval is the time the sequencer waits to check txs lifetime</p> </span> <br> <div class="badge badge-secondary">Examples:</div> <br><div id=Sequencer_TxLifetimeCheckInterval_ex1 class="jumbotron examples"><div class=highlight><pre><span></span><span class=s2>&quot;1m&quot;</span>
</pre></div> </div><div id=Sequencer_TxLifetimeCheckInterval_ex2 class="jumbotron examples"><div class=highlight><pre><span></span><span class=s2>&quot;300ms&quot;</span>
Expand Down
25 changes: 25 additions & 0 deletions docs/config-file/node-config-doc.md
Original file line number Diff line number Diff line change
Expand Up @@ -1341,6 +1341,7 @@ because depending of this values is going to ask to a trusted node for trusted t
| - [TrustedSequencerURL](#Synchronizer_TrustedSequencerURL ) | No | string | No | - | TrustedSequencerURL is the rpc url to connect and sync the trusted state |
| - [L1SynchronizationMode](#Synchronizer_L1SynchronizationMode ) | No | enum (of string) | No | - | L1SynchronizationMode define how to synchronize with L1:<br />- parallel: Request data to L1 in parallel, and process sequentially. The advantage is that executor is not blocked waiting for L1 data<br />- sequential: Request data to L1 and execute |
| - [L1ParallelSynchronization](#Synchronizer_L1ParallelSynchronization ) | No | object | No | - | L1ParallelSynchronization Configuration for parallel mode (if L1SynchronizationMode equal to 'parallel') |
| - [L2Synchronization](#Synchronizer_L2Synchronization ) | No | object | No | - | L2Synchronization Configuration for L2 synchronization |

### <a name="Synchronizer_SyncInterval"></a>9.1. `Synchronizer.SyncInterval`

Expand Down Expand Up @@ -1677,6 +1678,30 @@ RollupInfoRetriesSpacing="5s"
FallbackToSequentialModeOnSynchronized=false
```

### <a name="Synchronizer_L2Synchronization"></a>9.6. `[Synchronizer.L2Synchronization]`

**Type:** : `object`
**Description:** L2Synchronization Configuration for L2 synchronization

| Property | Pattern | Type | Deprecated | Definition | Title/Description |
| --------------------------------------------------------------------------------------- | ------- | ------- | ---------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| - [AcceptEmptyClosedBatches](#Synchronizer_L2Synchronization_AcceptEmptyClosedBatches ) | No | boolean | No | - | AcceptEmptyClosedBatches is a flag to enable or disable the acceptance of empty batches.<br />if true, the synchronizer will accept empty batches and process them. |

#### <a name="Synchronizer_L2Synchronization_AcceptEmptyClosedBatches"></a>9.6.1. `Synchronizer.L2Synchronization.AcceptEmptyClosedBatches`

**Type:** : `boolean`

**Default:** `false`

**Description:** AcceptEmptyClosedBatches is a flag to enable or disable the acceptance of empty batches.
if true, the synchronizer will accept empty batches and process them.

**Example setting the default value** (false):
```
[Synchronizer.L2Synchronization]
AcceptEmptyClosedBatches=false
```

## <a name="Sequencer"></a>10. `[Sequencer]`

**Type:** : `object`
Expand Down
12 changes: 12 additions & 0 deletions docs/config-file/node-config-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,18 @@
"additionalProperties": false,
"type": "object",
"description": "L1ParallelSynchronization Configuration for parallel mode (if L1SynchronizationMode equal to 'parallel')"
},
"L2Synchronization": {
"properties": {
"AcceptEmptyClosedBatches": {
"type": "boolean",
"description": "AcceptEmptyClosedBatches is a flag to enable or disable the acceptance of empty batches.\nif true, the synchronizer will accept empty batches and process them.",
"default": false
}
},
"additionalProperties": false,
"type": "object",
"description": "L2Synchronization Configuration for L2 synchronization"
}
},
"additionalProperties": false,
Expand Down
25 changes: 25 additions & 0 deletions jsonrpc/client/zkevm_test.go
joanestebanr marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package client

import (
"context"
"fmt"
"math/big"
"testing"

"github.com/0xPolygonHermez/zkevm-node/log"
"github.com/stretchr/testify/require"
)

func TestZkevmGetBatch(t *testing.T) {
t.Skip("This test is exploratory")
// Create a new client
client := NewClient("https://zkevm-rpc.com/")
lastTrustedStateBatchNumberSeen, err := client.BatchNumber(context.Background())
require.NoError(t, err)
log.Info("lastTrustedStateBatchNumberSeen: ", lastTrustedStateBatchNumberSeen)
batch, err := client.BatchByNumber(context.Background(), big.NewInt(int64(lastTrustedStateBatchNumberSeen)))
require.NoError(t, err)

// Print the batch
fmt.Println(batch)
}
3 changes: 3 additions & 0 deletions synchronizer/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package synchronizer

import (
"github.com/0xPolygonHermez/zkevm-node/config/types"
"github.com/0xPolygonHermez/zkevm-node/synchronizer/l2_sync"
)

// Config represents the configuration of the synchronizer
Expand All @@ -19,6 +20,8 @@ type Config struct {
L1SynchronizationMode string `jsonschema:"enum=sequential,enum=parallel"`
// L1ParallelSynchronization Configuration for parallel mode (if L1SynchronizationMode equal to 'parallel')
L1ParallelSynchronization L1ParallelSynchronizationConfig
// L2Synchronization Configuration for L2 synchronization
L2Synchronization l2_sync.Config `mapstructure:"L2Synchronization"`
}

// L1ParallelSynchronizationConfig Configuration for parallel mode (if UL1SynchronizationMode equal to 'parallel')
Expand Down
8 changes: 8 additions & 0 deletions synchronizer/l2_sync/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package l2_sync

// Config configuration of L2 sync process
type Config struct {
// AcceptEmptyClosedBatches is a flag to enable or disable the acceptance of empty batches.
// if true, the synchronizer will accept empty batches and process them.
AcceptEmptyClosedBatches bool `mapstructure:"AcceptEmptyClosedBatches"`
}
32 changes: 27 additions & 5 deletions synchronizer/l2_sync/l2_shared/processor_trusted_batch_sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/0xPolygonHermez/zkevm-node/log"
"github.com/0xPolygonHermez/zkevm-node/state"
syncCommon "github.com/0xPolygonHermez/zkevm-node/synchronizer/common"
"github.com/0xPolygonHermez/zkevm-node/synchronizer/l2_sync"
"github.com/ethereum/go-ethereum/common"
"github.com/jackc/pgx/v4"
)
Expand Down Expand Up @@ -124,8 +125,6 @@ type SyncTrustedBatchExecutor interface {
ReProcess(ctx context.Context, data *ProcessData, dbTx pgx.Tx) (*ProcessResponse, error)
// NothingProcess process a batch that is already synchronized, so we don't need to process it
NothingProcess(ctx context.Context, data *ProcessData, dbTx pgx.Tx) (*ProcessResponse, error)
// CloseBatch close a batch
//CloseBatch(ctx context.Context, trustedBatch *types.Batch, dbTx pgx.Tx) error
}

// ProcessorTrustedBatchSync is a template to sync trusted state. It classify what kind of update is needed and call to SyncTrustedStateBatchExecutorSteps
Expand All @@ -136,14 +135,16 @@ type SyncTrustedBatchExecutor interface {
type ProcessorTrustedBatchSync struct {
Steps SyncTrustedBatchExecutor
timeProvider syncCommon.TimeProvider
Cfg l2_sync.Config
}

// NewProcessorTrustedBatchSync creates a new SyncTrustedStateBatchExecutorTemplate
func NewProcessorTrustedBatchSync(steps SyncTrustedBatchExecutor,
timeProvider syncCommon.TimeProvider) *ProcessorTrustedBatchSync {
timeProvider syncCommon.TimeProvider, cfg l2_sync.Config) *ProcessorTrustedBatchSync {
return &ProcessorTrustedBatchSync{
Steps: steps,
timeProvider: timeProvider,
Cfg: cfg,
}
}

Expand Down Expand Up @@ -308,23 +309,39 @@ func (s *ProcessorTrustedBatchSync) GetModeForProcessBatch(trustedNodeBatch *typ
}
}
}

if result.Mode == "" {
return result, fmt.Errorf("failed to get mode for process batch %v", trustedNodeBatch.Number)
return result, fmt.Errorf("batch %v: failed to get mode for process ", trustedNodeBatch.Number)
}

result.BatchNumber = uint64(trustedNodeBatch.Number)
result.StateBatch = stateBatch
result.TrustedBatch = trustedNodeBatch
result.PreviousStateBatch = statePreviousBatch
result.OldAccInputHash = statePreviousBatch.AccInputHash
result.Now = s.timeProvider.Now()
result.DebugPrefix = fmt.Sprintf("%s mode %s:", debugPrefix, result.Mode)

if isTrustedBatchEmptyAndClosed(trustedNodeBatch) {
if s.Cfg.AcceptEmptyClosedBatches {
log.Infof("%s Batch %v: TrustedBatch Empty and closed, accepted due configuration", result.DebugPrefix, trustedNodeBatch.Number)
} else {
log.Infof("%s Batch %v: TrustedBatch Empty and closed, rejected due configuration", result.DebugPrefix, trustedNodeBatch.Number)
return result, fmt.Errorf("%s Batch %v: TrustedBatch Empty and closed, rejected due configuration", result.DebugPrefix, trustedNodeBatch.Number)
joanestebanr marked this conversation as resolved.
Show resolved Hide resolved
}
}

return result, nil
}

func isTrustedBatchClosed(batch *types.Batch) bool {
return batch.Closed
}

func isTrustedBatchEmptyAndClosed(batch *types.Batch) bool {
return len(batch.BatchL2Data) == 0 && isTrustedBatchClosed(batch)
}

func checkStateRootAndLER(batchNumber uint64, expectedStateRoot common.Hash, expectedLER common.Hash, calculatedStateRoot common.Hash, calculatedLER common.Hash) error {
if calculatedStateRoot != expectedStateRoot {
return fmt.Errorf("batch %v: stareRoot calculated [%s] is different from the one in the batch [%s] err:%w", batchNumber, calculatedStateRoot, expectedStateRoot, ErrFatalBatchDesynchronized)
Expand All @@ -339,7 +356,12 @@ func checkProcessBatchResultMatchExpected(data *ProcessData, processBatchResp *s
var err error = nil
var trustedBatch = data.TrustedBatch
if trustedBatch == nil {
panic("trustedBatch is nil")
log.Error("trustedBatch is nil, it never should be nil")
return fmt.Errorf("trustedBatch is nil, it never should be nil")
joanestebanr marked this conversation as resolved.
Show resolved Hide resolved
}
if len(trustedBatch.BatchL2Data) == 0 {
log.Warnf("Batch %v: BatchL2Data is empty, no checking", trustedBatch.Number)
return nil
}
if processBatchResp == nil {
log.Warnf("Batch %v: Can't check processBatchResp because is nil, then check store batch in DB", trustedBatch.Number)
Expand Down
Loading
Loading