Skip to content

Commit

Permalink
898 oldaccinputhash for lower forkids (#1161)
Browse files Browse the repository at this point in the history
* parse sequenceBatches calldata

* addec accInputHash calc function

* save l1infoRoot and migration

* correct etrog accInputHash calculation

* save sequences data correctly

* added pre etrog calculation

* fix tests

* fix tests

* add a nil check

* use prev batch accInputHash as old in proverInput endpoint

* add etrog parsing and refactor

* fix naming

* fix test

* fix tests pointer

* fix tests
  • Loading branch information
V-Staykov authored Sep 24, 2024
1 parent edb5799 commit 1ee1ecd
Show file tree
Hide file tree
Showing 15 changed files with 846 additions and 120 deletions.
16 changes: 16 additions & 0 deletions cmd/rpcdaemon/commands/mocks/l1_syncer_mock.go

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

98 changes: 89 additions & 9 deletions cmd/rpcdaemon/commands/zkevm_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
"github.com/gateway-fm/cdk-erigon-lib/kv"
"github.com/gateway-fm/cdk-erigon-lib/kv/memdb"
jsoniter "github.com/json-iterator/go"
zktypes "github.com/ledgerwatch/erigon/zk/types"
"github.com/ledgerwatch/log/v3"

"github.com/holiman/uint256"
"github.com/ledgerwatch/erigon/common/hexutil"
Expand Down Expand Up @@ -43,7 +45,6 @@ import (
"github.com/ledgerwatch/erigon/zk/witness"
"github.com/ledgerwatch/erigon/zkevm/hex"
"github.com/ledgerwatch/erigon/zkevm/jsonrpc/client"
"github.com/ledgerwatch/log/v3"
)

var sha3UncleHash = common.HexToHash("0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347")
Expand Down Expand Up @@ -459,7 +460,6 @@ func (api *ZkEvmAPIImpl) GetBatchByNumber(ctx context.Context, batchNumber rpc.B
}
defer tx.Rollback()
hermezDb := hermez_db.NewHermezDbReader(tx)

// use inbuilt rpc.BlockNumber type to implement the 'latest' behaviour
// the highest block/batch is tied to last block synced
// unless the node is still syncing - in which case 'current block' is used
Expand Down Expand Up @@ -700,13 +700,16 @@ func (api *ZkEvmAPIImpl) GetBatchByNumber(ctx context.Context, batchNumber rpc.B
batch.BatchL2Data = batchL2Data

if api.l1Syncer != nil {
oldAccInputHash, err := api.l1Syncer.GetOldAccInputHash(ctx, &api.config.AddressRollup, api.config.L1RollupId, batchNo)
accInputHash, err := api.getAccInputHash(ctx, hermezDb, batchNo)
if err != nil {
log.Warn("Failed to get old acc input hash", "err", err)
batch.AccInputHash = common.Hash{}
log.Error(fmt.Sprintf("failed to get acc input hash for batch %d: %v", batchNo, err))
}
batch.AccInputHash = oldAccInputHash
if accInputHash == nil {
accInputHash = &common.Hash{}
}
batch.AccInputHash = *accInputHash
}

// forkid exit roots logic
// if forkid < 12 then we should only set the exit roots if they have changed, otherwise 0x00..00
// if forkid >= 12 then we should always set the exit roots
Expand All @@ -732,6 +735,77 @@ func (api *ZkEvmAPIImpl) GetBatchByNumber(ctx context.Context, batchNumber rpc.B
return populateBatchDetails(batch)
}

type SequenceReader interface {
GetRangeSequencesByBatch(batchNo uint64) (*zktypes.L1BatchInfo, *zktypes.L1BatchInfo, error)
GetForkId(batchNo uint64) (uint64, error)
}

func (api *ZkEvmAPIImpl) getAccInputHash(ctx context.Context, db SequenceReader, batchNum uint64) (accInputHash *common.Hash, err error) {
// get batch sequence
prevSequence, batchSequence, err := db.GetRangeSequencesByBatch(batchNum)
if err != nil {
return nil, fmt.Errorf("failed to get sequence range data for batch %d: %w", batchNum, err)
}

// get batch range for sequence
prevSequenceBatch, currentSequenceBatch := prevSequence.BatchNo, batchSequence.BatchNo
// get call data for tx
l1Transaction, _, err := api.l1Syncer.GetTransaction(batchSequence.L1TxHash)
if err != nil {
return nil, fmt.Errorf("failed to get transaction data for tx %s: %w", batchSequence.L1TxHash, err)
}
sequenceBatchesCalldata := l1Transaction.GetData()
if len(sequenceBatchesCalldata) < 10 {
return nil, fmt.Errorf("calldata for tx %s is too short", batchSequence.L1TxHash)
}

currentBatchForkId, err := db.GetForkId(currentSequenceBatch)
if err != nil {
return nil, fmt.Errorf("failed to get fork id for batch %d: %w", currentSequenceBatch, err)
}

prevSequenceAccinputHash, err := api.GetccInputHash(ctx, currentBatchForkId, prevSequenceBatch)
if err != nil {
return nil, fmt.Errorf("failed to get old acc input hash for batch %d: %w", prevSequenceBatch, err)
}

decodedSequenceInteerface, err := syncer.DecodeSequenceBatchesCalldata(sequenceBatchesCalldata)
if err != nil {
return nil, fmt.Errorf("failed to decode calldata for tx %s: %w", batchSequence.L1TxHash, err)
}

accInputHashCalcFn, totalSequenceBatches, err := syncer.GetAccInputDataCalcFunction(batchSequence.L1InfoRoot, decodedSequenceInteerface)
if err != nil {
return nil, fmt.Errorf("failed to get accInputHash calculation func: %w", err)
}

if totalSequenceBatches == 0 || batchNum-prevSequenceBatch > uint64(totalSequenceBatches) {
return nil, fmt.Errorf("batch %d is out of range of sequence calldata", batchNum)
}

accInputHash = &prevSequenceAccinputHash
// calculate acc input hash
for i := 0; i < int(batchNum-prevSequenceBatch); i++ {
accInputHash = accInputHashCalcFn(prevSequenceAccinputHash, i)
}

return
}

func (api *ZkEvmAPIImpl) GetccInputHash(ctx context.Context, currentBatchForkId, lastSequenceBatchNumber uint64) (accInputHash common.Hash, err error) {
if currentBatchForkId < uint64(constants.ForkID8Elderberry) {
accInputHash, err = api.l1Syncer.GetPreElderberryAccInputHash(ctx, &api.config.AddressRollup, lastSequenceBatchNumber)
} else {
accInputHash, err = api.l1Syncer.GetElderberryAccInputHash(ctx, &api.config.AddressRollup, api.config.L1RollupId, lastSequenceBatchNumber)
}

if err != nil {
err = fmt.Errorf("failed to get accInputHash batch %d: %w", lastSequenceBatchNumber, err)
}

return
}

// GetFullBlockByNumber returns a full block from the current canonical chain. If number is nil, the
// latest known block is returned.
func (api *ZkEvmAPIImpl) GetFullBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (types.Block, error) {
Expand Down Expand Up @@ -1072,9 +1146,15 @@ func (api *ZkEvmAPIImpl) GetProverInput(ctx context.Context, batchNumber uint64,
return nil, err
}

oldAccInputHash, err := api.l1Syncer.GetOldAccInputHash(ctx, &api.config.AddressRollup, api.config.L1RollupId, batchNumber)
if err != nil {
return nil, err
var oldAccInputHash common.Hash
if batchNumber > 0 {
oaih, err := api.getAccInputHash(ctx, hDb, batchNumber-1)
if err != nil {
return nil, err
}
oldAccInputHash = *oaih
} else {
oldAccInputHash = common.Hash{}
}

timestampLimit := lastBlock.Time()
Expand Down
67 changes: 42 additions & 25 deletions cmd/rpcdaemon/commands/zkevm_api_test.go

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions migrations/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ var migrations = map[kv.Label][]Migration{
resetBlocks4,
refactorTableLastRoot,
countersToArray,
resetL1Sequences,
},
kv.TxPoolDB: {},
kv.SentryDB: {},
Expand Down
33 changes: 33 additions & 0 deletions migrations/reset_l1sequences.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package migrations

import (
"context"
"fmt"

"github.com/gateway-fm/cdk-erigon-lib/common/datadir"
"github.com/gateway-fm/cdk-erigon-lib/kv"
"github.com/ledgerwatch/erigon/eth/stagedsync/stages"
)

var resetL1Sequences = Migration{
Name: "remove l1 sequences and stage_l1sync progress to download all l1 sequences anew",
Up: func(db kv.RwDB, dirs datadir.Dirs, progress []byte, BeforeCommit Callback) (err error) {
tx, err := db.BeginRw(context.Background())
if err != nil {
return err
}
defer tx.Rollback()
tx.ClearBucket(kv.L1SEQUENCES)

// already checked
if err := stages.SaveStageProgress(tx, stages.L1Syncer, 0); err != nil {
return fmt.Errorf("failed to get highest checked block, %w", err)
}

// This migration is no-op, but it forces the migration mechanism to apply it and thus write the DB schema version info
if err := BeforeCommit(tx, nil, true); err != nil {
return err
}
return tx.Commit()
},
}
4 changes: 4 additions & 0 deletions zk/contracts/l1_abi.go

Large diffs are not rendered by default.

Loading

0 comments on commit 1ee1ecd

Please sign in to comment.