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

AccInputHash Post Etrog Rework #1510

Draft
wants to merge 6 commits into
base: zkevm
Choose a base branch
from
Draft
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion cmd/integration/commands/stages_zkevm.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,7 @@
nil,
nil,
nil,
nil,

Check failure on line 142 in cmd/integration/commands/stages_zkevm.go

View workflow job for this annotation

GitHub Actions / tests (ubuntu-22.04)

too many arguments in call to stages2.NewSequencerZkStages

Check failure on line 142 in cmd/integration/commands/stages_zkevm.go

View workflow job for this annotation

GitHub Actions / tests (macos-14-xlarge)

too many arguments in call to stages2.NewSequencerZkStages
nil,
)
} else {
stages = stages2.NewDefaultZkStages(
Expand All @@ -157,6 +156,7 @@
nil,
nil,
nil,
nil,
nil)
}

Expand Down
8 changes: 4 additions & 4 deletions core/state/intra_block_state_zkevm.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ type ReadOnlyHermezDb interface {
GetBlockL1BlockHash(l2BlockNo uint64) (libcommon.Hash, error)
GetIntermediateTxStateRoot(blockNum uint64, txhash libcommon.Hash) (libcommon.Hash, error)
GetReusedL1InfoTreeIndex(blockNum uint64) (bool, error)
GetSequenceByBatchNo(batchNo uint64) (*zktypes.L1BatchInfo, error)
GetSequenceByBatchNo(batchNo uint64) (*zktypes.BatchSequenceInfo, error)
GetHighestBlockInBatch(batchNo uint64) (uint64, bool, error)
GetSequenceByBatchNoOrHighest(batchNo uint64) (*zktypes.L1BatchInfo, error)
GetSequenceByBatchNoOrHighest(batchNo uint64) (*zktypes.BatchSequenceInfo, error)
GetLowestBlockInBatch(batchNo uint64) (uint64, bool, error)
GetL2BlockNosByBatch(batchNo uint64) ([]uint64, error)
GetBatchGlobalExitRoot(batchNum uint64) (*dstypes.GerUpdate, error)
GetVerificationByBatchNo(batchNo uint64) (*zktypes.L1BatchInfo, error)
GetVerificationByBatchNoOrHighest(batchNo uint64) (*zktypes.L1BatchInfo, error)
GetVerificationByBatchNo(batchNo uint64) (*zktypes.BatchVerificationInfo, error)
GetVerificationByBatchNoOrHighest(batchNo uint64) (*zktypes.BatchVerificationInfo, error)
GetL1BatchData(batchNumber uint64) ([]byte, error)
GetL1InfoTreeUpdateByGer(ger libcommon.Hash) (*zktypes.L1InfoTreeUpdate, error)
GetBlockL1InfoTreeIndex(blockNumber uint64) (uint64, error)
Expand Down
65 changes: 19 additions & 46 deletions eth/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -1035,53 +1035,39 @@ func New(ctx context.Context, stack *node.Node, config *ethconfig.Config, logger
log.Info("Starting sequencer in L1 recovery mode", "startBlock", cfg.L1SyncStartBlock)
}

seqAndVerifTopics := [][]libcommon.Hash{{
contracts.SequencedBatchTopicPreEtrog,
contracts.SequencedBatchTopicEtrog,
contracts.RollbackBatchesTopic,
contracts.VerificationTopicPreEtrog,
contracts.VerificationTopicEtrog,
contracts.VerificationValidiumTopicEtrog,
}}

seqAndVerifL1Contracts := []libcommon.Address{cfg.AddressRollup, cfg.AddressAdmin, cfg.AddressZkevm}

var l1Topics [][]libcommon.Hash
var l1Contracts []libcommon.Address
if isSequencer {
l1Topics = [][]libcommon.Hash{{
combinedL1Topics := [][]libcommon.Hash{
{
contracts.SequencedBatchTopicPreEtrog,
contracts.SequencedBatchTopicEtrog,
contracts.RollbackBatchesTopic,
contracts.VerificationTopicPreEtrog,
contracts.VerificationTopicEtrog,
contracts.VerificationValidiumTopicEtrog,
contracts.InitialSequenceBatchesTopic,
contracts.AddNewRollupTypeTopic,
contracts.AddNewRollupTypeTopicBanana,
contracts.CreateNewRollupTopic,
contracts.UpdateRollupTopic,
}}
l1Contracts = []libcommon.Address{cfg.AddressZkevm, cfg.AddressRollup}
} else {
l1Topics = seqAndVerifTopics
l1Contracts = seqAndVerifL1Contracts
contracts.SequenceBatchesTopic,
},
}

combinedL1Contracts := []libcommon.Address{
cfg.AddressRollup,
cfg.AddressAdmin,
cfg.AddressZkevm,
}

ethermanClients := make([]syncer.IEtherman, len(backend.etherManClients))
for i, c := range backend.etherManClients {
ethermanClients[i] = c.EthClient
}

seqVerSyncer := syncer.NewL1Syncer(
ctx,
ethermanClients,
seqAndVerifL1Contracts,
seqAndVerifTopics,
cfg.L1BlockRange,
cfg.L1QueryDelay,
cfg.L1HighestBlockType,
)

backend.l1Syncer = syncer.NewL1Syncer(
ctx,
ethermanClients,
l1Contracts,
l1Topics,
combinedL1Contracts,
combinedL1Topics,
cfg.L1BlockRange,
cfg.L1QueryDelay,
cfg.L1HighestBlockType,
Expand Down Expand Up @@ -1153,18 +1139,6 @@ func New(ctx context.Context, stack *node.Node, config *ethconfig.Config, logger
// we switch context from being an RPC node to a sequencer
backend.txPool2.ForceUpdateLatestBlock(executionProgress)

l1BlockSyncer := syncer.NewL1Syncer(
ctx,
ethermanClients,
[]libcommon.Address{cfg.AddressZkevm, cfg.AddressRollup},
[][]libcommon.Hash{{
contracts.SequenceBatchesTopic,
}},
cfg.L1BlockRange,
cfg.L1QueryDelay,
cfg.L1HighestBlockType,
)

backend.syncStages = stages2.NewSequencerZkStages(
backend.sentryCtx,
backend.chainDB,
Expand All @@ -1178,8 +1152,6 @@ func New(ctx context.Context, stack *node.Node, config *ethconfig.Config, logger
backend.engine,
dataStreamServer,
backend.l1Syncer,
seqVerSyncer,
l1BlockSyncer,
backend.txPool2,
backend.txPool2DB,
verifier,
Expand Down Expand Up @@ -1217,6 +1189,7 @@ func New(ctx context.Context, stack *node.Node, config *ethconfig.Config, logger
backend.forkValidator,
backend.engine,
backend.l1Syncer,
l1InfoTreeUpdater,
streamClient,
dataStreamServer,
l1InfoTreeUpdater,
Expand Down
128 changes: 29 additions & 99 deletions turbo/jsonrpc/zkevm_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ import (
"github.com/ledgerwatch/erigon-lib/kv"
"github.com/ledgerwatch/log/v3"

zktypes "github.com/ledgerwatch/erigon/zk/types"

"math"

"github.com/holiman/uint256"
Expand All @@ -35,6 +33,7 @@ import (
smtUtils "github.com/ledgerwatch/erigon/smt/pkg/utils"
"github.com/ledgerwatch/erigon/turbo/rpchelper"
"github.com/ledgerwatch/erigon/turbo/trie"
"github.com/ledgerwatch/erigon/zk/acc_input_hash"
"github.com/ledgerwatch/erigon/zk/datastream/server"
"github.com/ledgerwatch/erigon/zk/hermez_db"
"github.com/ledgerwatch/erigon/zk/legacy_executor_verifier"
Expand Down Expand Up @@ -389,7 +388,18 @@ func (api *ZkEvmAPIImpl) getOrCalcBatchData(ctx context.Context, tx kv.Tx, dbRea
return nil, err
}

return utils.GenerateBatchDataFromDb(tx, dbReader, batchBlocks, forkId)
lastBlockNoInPreviousBatch := uint64(0)
firstBlockInBatch := batchBlocks[0]
if firstBlockInBatch.NumberU64() != 0 {
lastBlockNoInPreviousBatch = firstBlockInBatch.NumberU64() - 1
}

lastBlockInPreviousBatch, err := rawdb.ReadBlockByNumber(tx, lastBlockNoInPreviousBatch)
if err != nil {
return nil, err
}

return utils.GenerateBatchDataFromDb(tx, dbReader, batchBlocks, lastBlockInPreviousBatch, forkId)
}

type blockGetter interface {
Expand Down Expand Up @@ -626,14 +636,15 @@ func (api *ZkEvmAPIImpl) GetBatchByNumber(ctx context.Context, rpcBatchNumber rp
batch.BatchL2Data = batchL2Data

if api.l1Syncer != nil {
accInputHash, err := api.getAccInputHash(ctx, hermezDb, batchNo)
calc, err := acc_input_hash.NewCalculator(ctx, tx, hermezDb, forkId)
if err != nil {
log.Error(fmt.Sprintf("failed to get acc input hash for batch %d: %v", batchNo, err))
return nil, err
}
if accInputHash == nil {
accInputHash = &common.Hash{}
accInputHash, err := calc.Calculate(batchNo)
if err != nil {
log.Error(fmt.Sprintf("failed to get acc input hash for batch %d: %v", batchNo, err))
}
batch.AccInputHash = *accInputHash
batch.AccInputHash = accInputHash
}

// forkid exit roots logic
Expand Down Expand Up @@ -720,95 +731,6 @@ func (api *ZkEvmAPIImpl) fullTxBlockData(ctx context.Context, tx kv.Tx, hermezDb
return batchBlocksJson, batchTransactionsJson, nil
}

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)
}

// if we are asking for genesis return 0x0..0
if batchNum == 0 && prevSequence.BatchNo == 0 {
return &common.Hash{}, nil
}

if prevSequence == nil || batchSequence == nil {
var missing string
if prevSequence == nil && batchSequence == nil {
missing = "previous and current batch sequences"
} else if prevSequence == nil {
missing = "previous batch sequence"
} else {
missing = "current batch sequence"
}
return nil, fmt.Errorf("failed to get %s for batch %d", missing, batchNum)
}

// 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)
}

decodedSequenceInterface, 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, decodedSequenceInterface)
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)
}

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

return
}

func (api *ZkEvmAPIImpl) GetccInputHash(ctx context.Context, currentBatchForkId, lastSequenceBatchNumber uint64) (accInputHash common.Hash, err error) {
if currentBatchForkId < uint64(chain.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 @@ -1224,11 +1146,19 @@ func (api *ZkEvmAPIImpl) GetProverInput(ctx context.Context, batchNumber uint64,

var oldAccInputHash common.Hash
if batchNumber > 0 {
oaih, err := api.getAccInputHash(ctx, hDb, batchNumber-1)
forkId, err := hDb.GetForkId(batchNumber - 1)
if err != nil {
return nil, err
}
calc, err := acc_input_hash.NewCalculator(ctx, tx, hDb, forkId)
if err != nil {
return nil, err
}
oaih, err := calc.Calculate(batchNumber - 1)
if err != nil {
return nil, err
}
oldAccInputHash = *oaih
oldAccInputHash = oaih
} else {
oldAccInputHash = common.Hash{}
}
Expand Down
13 changes: 9 additions & 4 deletions turbo/jsonrpc/zkevm_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ func TestGetBatchByNumber(t *testing.T) {
assert.NoError(err)
err = hDB.WriteBlockGlobalExitRoot(uint64(i+1), gers[i])
assert.NoError(err)
l1InforTree := &zktypes.L1InfoTreeUpdate{
l1InfoTree := &zktypes.L1InfoTreeUpdate{
Index: uint64(i),
GER: gers[i],
MainnetExitRoot: mainnetExitRoots[i],
Expand All @@ -413,7 +413,11 @@ func TestGetBatchByNumber(t *testing.T) {
Timestamp: times[i],
BlockNumber: uint64(i + 1),
}
err = hDB.WriteL1InfoTreeUpdateToGer(l1InforTree)
err = hDB.WriteL1InfoTreeUpdateToGer(l1InfoTree)
assert.NoError(err)
err = hDB.WriteL1InfoTreeUpdate(l1InfoTree)
assert.NoError(err)
err = hDB.WriteL1InfoTreeRoot(hashes[i], uint64(i))
assert.NoError(err)
}

Expand All @@ -435,6 +439,8 @@ func TestGetBatchByNumber(t *testing.T) {
assert.NoError(err)
}

accInputHash := common.HexToHash("0xd24388f39169a9187e66711e42c8da0dfd9f9089ec46c9a95d29a1f25a58234a")

for i := 0; i < 4; i++ {
_, err := erigonDB.WriteHeader(big.NewInt(int64(i+1)), hashes[i], stateRoots[i], txsRoot[i], parentHashes[i], coinBase, times[i], gasLimits[i], params.TestChainConfig)
assert.NoError(err)
Expand All @@ -443,7 +449,6 @@ func TestGetBatchByNumber(t *testing.T) {
}
tx.Commit()
var response []byte
accInputHash := common.HexToHash("0xd24388f39169a9187e66711e42c8da0dfd9f9089ec46c9a95d29a1f25a58234a")
response = append(response, accInputHash.Bytes()...)
response = append(response, common.Hash{}.Bytes()...)
response = append(response, common.FromHex(fmt.Sprintf("0x%064x", 1))...)
Expand Down Expand Up @@ -480,7 +485,7 @@ func TestGetBatchByNumber(t *testing.T) {
assert.Equal(gers[len(gers)-1], batch.GlobalExitRoot)
assert.Equal(mainnetExitRoots[len(mainnetExitRoots)-1], batch.MainnetExitRoot)
assert.Equal(rollupExitRoots[len(rollupExitRoots)-1], batch.RollupExitRoot)
assert.Equal(common.HexToHash("0x97d1524156ccb46723e5c3c87951da9a390499ba288161d879df1dbc03d49afc"), batch.AccInputHash)
assert.Equal(common.HexToHash("0x4ada34202c254799e2abc9f832764692c2fc6f654fa98a1f9c19391deff623bd"), batch.AccInputHash)
assert.Equal(common.HexToHash("0x22ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba97"), *batch.SendSequencesTxHash)
assert.Equal(rpctypes.ArgUint64(1714427009), batch.Timestamp)
assert.Equal(true, batch.Closed)
Expand Down
Loading
Loading