Skip to content

Commit

Permalink
Use Eth block hash for l2 blocks in data stream (#3661)
Browse files Browse the repository at this point in the history
* Use Eth block hash for l2 blocks in data stream

* handle minTimestamp
  • Loading branch information
ToniRamirezM authored May 30, 2024
1 parent d9a1a10 commit cea67d1
Show file tree
Hide file tree
Showing 14 changed files with 92 additions and 44 deletions.
10 changes: 7 additions & 3 deletions sequencer/datastreamer.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"github.com/ethereum/go-ethereum/common"
)

func (f *finalizer) DSSendL2Block(ctx context.Context, batchNumber uint64, blockResponse *state.ProcessBlockResponse, l1InfoTreeIndex uint32, minTimestamp uint64) error {
func (f *finalizer) DSSendL2Block(ctx context.Context, batchNumber uint64, blockResponse *state.ProcessBlockResponse, l1InfoTreeIndex uint32, minTimestamp uint64, blockHash common.Hash) error {
forkID := f.stateIntf.GetForkIDByBatchNumber(batchNumber)

// Send data to streamer
Expand All @@ -18,17 +18,21 @@ func (f *finalizer) DSSendL2Block(ctx context.Context, batchNumber uint64, block
BatchNumber: batchNumber,
L2BlockNumber: blockResponse.BlockNumber,
Timestamp: blockResponse.Timestamp,
Min_timestamp: minTimestamp,
MinTimestamp: minTimestamp,
L1InfoTreeIndex: l1InfoTreeIndex,
L1BlockHash: blockResponse.BlockHashL1,
GlobalExitRoot: blockResponse.GlobalExitRoot,
Coinbase: f.l2Coinbase,
ForkID: forkID,
BlockHash: blockResponse.BlockHash,
BlockHash: blockHash,
StateRoot: blockResponse.BlockHash, //From etrog, the blockhash is the block root
BlockInfoRoot: blockResponse.BlockInfoRoot,
}

if l2Block.ForkID >= state.FORKID_ETROG && l2Block.L1InfoTreeIndex == 0 {
l2Block.MinTimestamp = 0
}

l2Transactions := []state.DSL2Transaction{}

for i, txResponse := range blockResponse.TransactionResponses {
Expand Down
4 changes: 2 additions & 2 deletions sequencer/forcedbatch.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ func (f *finalizer) handleProcessForcedBatchResponse(ctx context.Context, newBat
// process L2 blocks responses for the forced batch
for _, forcedL2BlockResponse := range batchResponse.BlockResponses {
// Store forced L2 blocks in the state
err := f.stateIntf.StoreL2Block(ctx, newBatchNumber, forcedL2BlockResponse, nil, dbTx)
blockHash, err := f.stateIntf.StoreL2Block(ctx, newBatchNumber, forcedL2BlockResponse, nil, dbTx)
if err != nil {
return fmt.Errorf("database error on storing L2 block %d, error: %v", forcedL2BlockResponse.BlockNumber, err)
}
Expand All @@ -198,7 +198,7 @@ func (f *finalizer) handleProcessForcedBatchResponse(ctx context.Context, newBat
}

// Send L2 block to data streamer
err = f.DSSendL2Block(ctx, newBatchNumber, forcedL2BlockResponse, 0, forcedL2BlockResponse.Timestamp)
err = f.DSSendL2Block(ctx, newBatchNumber, forcedL2BlockResponse, 0, forcedL2BlockResponse.Timestamp, blockHash)
if err != nil {
//TODO: we need to halt/rollback the L2 block if we had an error sending to the data streamer?
log.Errorf("error sending L2 block %d to data streamer, error: %v", forcedL2BlockResponse.BlockNumber, err)
Expand Down
2 changes: 1 addition & 1 deletion sequencer/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ type stateInterface interface {
GetDSL2Blocks(ctx context.Context, firstBatchNumber, lastBatchNumber uint64, dbTx pgx.Tx) ([]*state.DSL2Block, error)
GetDSL2Transactions(ctx context.Context, firstL2Block, lastL2Block uint64, dbTx pgx.Tx) ([]*state.DSL2Transaction, error)
GetStorageAt(ctx context.Context, address common.Address, position *big.Int, root common.Hash) (*big.Int, error)
StoreL2Block(ctx context.Context, batchNumber uint64, l2Block *state.ProcessBlockResponse, txsEGPLog []*state.EffectiveGasPriceLog, dbTx pgx.Tx) error
StoreL2Block(ctx context.Context, batchNumber uint64, l2Block *state.ProcessBlockResponse, txsEGPLog []*state.EffectiveGasPriceLog, dbTx pgx.Tx) (common.Hash, error)
BuildChangeL2Block(deltaTimestamp uint32, l1InfoTreeIndex uint32) []byte
GetL1InfoTreeDataFromBatchL2Data(ctx context.Context, batchL2Data []byte, dbTx pgx.Tx) (map[uint32]state.L1DataV2, common.Hash, common.Hash, error)
GetBlockByNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) (*state.Block, error)
Expand Down
4 changes: 2 additions & 2 deletions sequencer/l2block.go
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ func (f *finalizer) storeL2Block(ctx context.Context, l2Block *L2Block) error {
}

// Store L2 block in the state
err = f.stateIntf.StoreL2Block(ctx, l2Block.batch.batchNumber, blockResponse, txsEGPLog, dbTx)
blockHash, err := f.stateIntf.StoreL2Block(ctx, l2Block.batch.batchNumber, blockResponse, txsEGPLog, dbTx)
if err != nil {
return rollbackOnError(fmt.Errorf("database error on storing L2 block %d [%d], error: %v", blockResponse.BlockNumber, l2Block.trackingNum, err))
}
Expand Down Expand Up @@ -490,7 +490,7 @@ func (f *finalizer) storeL2Block(ctx context.Context, l2Block *L2Block) error {
}

// Send L2 block to data streamer
err = f.DSSendL2Block(ctx, l2Block.batch.batchNumber, blockResponse, l2Block.getL1InfoTreeIndex(), l2Block.timestamp)
err = f.DSSendL2Block(ctx, l2Block.batch.batchNumber, blockResponse, l2Block.getL1InfoTreeIndex(), l2Block.timestamp, blockHash)
if err != nil {
//TODO: we need to halt/rollback the L2 block if we had an error sending to the data streamer?
log.Errorf("error sending L2 block %d [%d] to data streamer, error: %v", blockResponse.BlockNumber, l2Block.trackingNum, err)
Expand Down
22 changes: 17 additions & 5 deletions sequencer/mock_state.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion sequencer/sequencer.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ func (s *Sequencer) sendDataToStreamer(chainID uint64) {
BatchNumber: l2Block.BatchNumber,
Timestamp: l2Block.Timestamp,
DeltaTimestamp: uint32(l2Block.Timestamp - previousL2Block.Timestamp),
MinTimestamp: l2Block.Min_timestamp,
MinTimestamp: l2Block.MinTimestamp,
L1Blockhash: l2Block.L1BlockHash.Bytes(),
L1InfotreeIndex: l2Block.L1InfoTreeIndex,
Hash: l2Block.BlockHash.Bytes(),
Expand Down
2 changes: 1 addition & 1 deletion state/batchV2.go
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ func (s *State) ProcessAndStoreClosedBatchV2(ctx context.Context, processingCtx

if len(processedBatch.BlockResponses) > 0 && !processedBatch.IsRomOOCError && processedBatch.RomError_V2 == nil {
for _, blockResponse := range processedBatch.BlockResponses {
err = s.StoreL2Block(ctx, processingCtx.BatchNumber, blockResponse, nil, dbTx)
_, err = s.StoreL2Block(ctx, processingCtx.BatchNumber, blockResponse, nil, dbTx)
if err != nil {
log.Errorf("%s error StoreL2Block: %v", debugPrefix, err)
return common.Hash{}, noFlushID, noProverID, err
Expand Down
16 changes: 12 additions & 4 deletions state/datastream.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ type DSL2Block struct {
BatchNumber uint64
L2BlockNumber uint64
Timestamp uint64
Min_timestamp uint64
MinTimestamp uint64
L1InfoTreeIndex uint32
L1BlockHash common.Hash
GlobalExitRoot common.Hash
Expand Down Expand Up @@ -512,14 +512,22 @@ func GenerateDataStreamFile(ctx context.Context, streamServer *datastreamer.Stre
BlockGasLimit: l2Block.BlockGasLimit,
}

if l2Block.ForkID >= FORKID_ETROG {
streamL2Block.Hash = l2Block.StateRoot.Bytes()
}
// Keep the l2 block hash as it is, as the state root can be found in the StateRoot field
// So disable this
/*
if l2Block.ForkID >= FORKID_ETROG {
streamL2Block.Hash = l2Block.StateRoot.Bytes()
}
*/

if l2Block.ForkID == FORKID_ETROG && batch.EtrogTimestamp != nil {
streamL2Block.MinTimestamp = uint64(batch.EtrogTimestamp.Unix())
}

if l2Block.ForkID >= FORKID_ETROG && l2Block.L1InfoTreeIndex == 0 {
streamL2Block.MinTimestamp = 0
}

previousTimestamp = l2Block.Timestamp

bookMark := &datastream.BookMark{
Expand Down
10 changes: 5 additions & 5 deletions state/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,17 +208,17 @@ func (s *State) StoreTransactions(ctx context.Context, batchNumber uint64, proce
}

// StoreL2Block stores a l2 block into the state
func (s *State) StoreL2Block(ctx context.Context, batchNumber uint64, l2Block *ProcessBlockResponse, txsEGPLog []*EffectiveGasPriceLog, dbTx pgx.Tx) error {
func (s *State) StoreL2Block(ctx context.Context, batchNumber uint64, l2Block *ProcessBlockResponse, txsEGPLog []*EffectiveGasPriceLog, dbTx pgx.Tx) (common.Hash, error) {
if dbTx == nil {
return ErrDBTxNil
return common.Hash{}, ErrDBTxNil
}

log.Debugf("storing l2 block %d, txs %d, hash %s", l2Block.BlockNumber, len(l2Block.TransactionResponses), l2Block.BlockHash.String())
start := time.Now()

prevL2BlockHash, err := s.GetL2BlockHashByNumber(ctx, l2Block.BlockNumber-1, dbTx)
if err != nil {
return err
return common.Hash{}, err
}

forkID := s.GetForkIDByBatchNumber(batchNumber)
Expand Down Expand Up @@ -289,12 +289,12 @@ func (s *State) StoreL2Block(ctx context.Context, batchNumber uint64, l2Block *P

// Store L2 block and its transactions
if err := s.AddL2Block(ctx, batchNumber, block, receipts, txsL2Hash, storeTxsEGPData, imStateRoots, dbTx); err != nil {
return err
return common.Hash{}, err
}

log.Debugf("stored L2 block %d for batch %d, storing time %v", header.Number, batchNumber, time.Since(start))

return nil
return block.Hash(), nil
}

// PreProcessUnsignedTransaction processes the unsigned transaction in order to calculate its zkCounters
Expand Down
28 changes: 20 additions & 8 deletions synchronizer/common/syncinterfaces/mocks/state_full_interface.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion synchronizer/common/syncinterfaces/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ type StateFullInterface interface {
GetForkIDByBlockNumber(blockNumber uint64) uint64
GetStoredFlushID(ctx context.Context) (uint64, string, error)
AddL1InfoTreeLeaf(ctx context.Context, L1InfoTreeLeaf *state.L1InfoTreeLeaf, dbTx pgx.Tx) (*state.L1InfoTreeExitRootStorageEntry, error)
StoreL2Block(ctx context.Context, batchNumber uint64, l2Block *state.ProcessBlockResponse, txsEGPLog []*state.EffectiveGasPriceLog, dbTx pgx.Tx) error
StoreL2Block(ctx context.Context, batchNumber uint64, l2Block *state.ProcessBlockResponse, txsEGPLog []*state.EffectiveGasPriceLog, dbTx pgx.Tx) (common.Hash, error)
GetL1InfoRootLeafByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) (state.L1InfoTreeExitRootStorageEntry, error)
UpdateWIPBatch(ctx context.Context, receipt state.ProcessingReceipt, dbTx pgx.Tx) error
GetL1InfoTreeDataFromBatchL2Data(ctx context.Context, batchL2Data []byte, dbTx pgx.Tx) (map[uint32]state.L1DataV2, common.Hash, common.Hash, error)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ type StateInterface interface {
ResetTrustedState(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) error
OpenBatch(ctx context.Context, processingContext state.ProcessingContext, dbTx pgx.Tx) error
ProcessBatchV2(ctx context.Context, request state.ProcessRequest, updateMerkleTree bool) (*state.ProcessBatchResponse, string, error)
StoreL2Block(ctx context.Context, batchNumber uint64, l2Block *state.ProcessBlockResponse, txsEGPLog []*state.EffectiveGasPriceLog, dbTx pgx.Tx) error
StoreL2Block(ctx context.Context, batchNumber uint64, l2Block *state.ProcessBlockResponse, txsEGPLog []*state.EffectiveGasPriceLog, dbTx pgx.Tx) (common.Hash, error)
GetL1InfoTreeDataFromBatchL2Data(ctx context.Context, batchL2Data []byte, dbTx pgx.Tx) (map[uint32]state.L1DataV2, common.Hash, common.Hash, error)
GetLastVirtualBatchNum(ctx context.Context, dbTx pgx.Tx) (uint64, error)
}
Expand Down Expand Up @@ -392,7 +392,7 @@ func (b *SyncTrustedBatchExecutorForEtrog) processAndStoreTxs(ctx context.Contex
}
for _, block := range processBatchResp.BlockResponses {
log.Debugf("%s Storing trusted tx %d", debugPrefix, block.BlockNumber)
if err = b.state.StoreL2Block(ctx, request.BatchNumber, block, nil, dbTx); err != nil {
if _, err = b.state.StoreL2Block(ctx, request.BatchNumber, block, nil, dbTx); err != nil {
newErr := fmt.Errorf("%s failed to store l2block: %v err:%w", debugPrefix, block.BlockNumber, err)
log.Error(newErr.Error())
return nil, newErr
Expand Down
28 changes: 20 additions & 8 deletions synchronizer/l2_sync/l2_sync_etrog/mocks/state_interface.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion synchronizer/synchronizer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -901,7 +901,7 @@ func expectedCallsForsyncTrustedState(t *testing.T, m *mocks, sync *ClientSynchr
m.State.EXPECT().ProcessBatchV2(mock.Anything, mock.Anything, mock.Anything).
Return(&processedBatch, "", nil).Times(1)
m.State.EXPECT().StoreL2Block(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).
Return(nil).Times(1)
Return(common.Hash{}, nil).Times(1)
m.State.EXPECT().UpdateWIPBatch(mock.Anything, mock.Anything, mock.Anything).
Return(nil).Times(1)
m.State.EXPECT().GetBatchByNumber(mock.Anything, mock.Anything, mock.Anything).
Expand Down

0 comments on commit cea67d1

Please sign in to comment.