Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/zkevm' into banana
Browse files Browse the repository at this point in the history
  • Loading branch information
cffls committed Aug 29, 2024
2 parents 497ec51 + 31dc6f6 commit d5d0490
Show file tree
Hide file tree
Showing 9 changed files with 688 additions and 1 deletion.
191 changes: 191 additions & 0 deletions cmd/rpcdaemon/commands/zkevm_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,34 @@ import (
libcommon "github.com/gateway-fm/cdk-erigon-lib/common"
"github.com/gateway-fm/cdk-erigon-lib/common/hexutility"
"github.com/gateway-fm/cdk-erigon-lib/kv"
"github.com/gateway-fm/cdk-erigon-lib/kv/memdb"
jsoniter "github.com/json-iterator/go"

"github.com/holiman/uint256"
"github.com/ledgerwatch/erigon/common/hexutil"
"github.com/ledgerwatch/erigon/core"
"github.com/ledgerwatch/erigon/core/rawdb"
"github.com/ledgerwatch/erigon/core/state"
eritypes "github.com/ledgerwatch/erigon/core/types"
"github.com/ledgerwatch/erigon/core/types/accounts"
"github.com/ledgerwatch/erigon/eth/ethconfig"
"github.com/ledgerwatch/erigon/eth/stagedsync"
"github.com/ledgerwatch/erigon/eth/stagedsync/stages"
"github.com/ledgerwatch/erigon/eth/tracers"
"github.com/ledgerwatch/erigon/rpc"
smtDb "github.com/ledgerwatch/erigon/smt/pkg/db"
smt "github.com/ledgerwatch/erigon/smt/pkg/smt"
smtUtils "github.com/ledgerwatch/erigon/smt/pkg/utils"
"github.com/ledgerwatch/erigon/turbo/rpchelper"
"github.com/ledgerwatch/erigon/zk/hermez_db"
"github.com/ledgerwatch/erigon/zk/legacy_executor_verifier"
types "github.com/ledgerwatch/erigon/zk/rpcdaemon"
"github.com/ledgerwatch/erigon/zk/sequencer"
zkStages "github.com/ledgerwatch/erigon/zk/stages"
"github.com/ledgerwatch/erigon/zk/syncer"
zktx "github.com/ledgerwatch/erigon/zk/tx"
"github.com/ledgerwatch/erigon/zk/utils"
zkUtils "github.com/ledgerwatch/erigon/zk/utils"
"github.com/ledgerwatch/erigon/zk/witness"
"github.com/ledgerwatch/erigon/zkevm/hex"
"github.com/ledgerwatch/erigon/zkevm/jsonrpc/client"
Expand Down Expand Up @@ -1444,3 +1453,185 @@ func populateBatchDataSlimDetails(batches []*types.BatchDataSlim) (json.RawMessa

return json.Marshal(jBatches)
}

// GetProof
func (zkapi *ZkEvmAPIImpl) GetProof(ctx context.Context, address common.Address, storageKeys []common.Hash, blockNrOrHash rpc.BlockNumberOrHash) (*accounts.SMTAccProofResult, error) {
api := zkapi.ethApi

tx, err := api.db.BeginRo(ctx)
if err != nil {
return nil, err
}
defer tx.Rollback()
if api.historyV3(tx) {
return nil, fmt.Errorf("not supported by Erigon3")
}

blockNr, _, _, err := rpchelper.GetBlockNumber(blockNrOrHash, tx, api.filters)
if err != nil {
return nil, err
}

latestBlock, err := rpchelper.GetLatestBlockNumber(tx)
if err != nil {
return nil, err
}

if latestBlock < blockNr {
// shouldn't happen, but check anyway
return nil, fmt.Errorf("block number is in the future latest=%d requested=%d", latestBlock, blockNr)
}

batch := memdb.NewMemoryBatch(tx, api.dirs.Tmp)
defer batch.Rollback()
if err = zkUtils.PopulateMemoryMutationTables(batch); err != nil {
return nil, err
}

if blockNr < latestBlock {
if latestBlock-blockNr > maxGetProofRewindBlockCount {
return nil, fmt.Errorf("requested block is too old, block must be within %d blocks of the head block number (currently %d)", maxGetProofRewindBlockCount, latestBlock)
}
unwindState := &stagedsync.UnwindState{UnwindPoint: blockNr}
stageState := &stagedsync.StageState{BlockNumber: latestBlock}

interHashStageCfg := zkStages.StageZkInterHashesCfg(nil, true, true, false, api.dirs.Tmp, api._blockReader, nil, api.historyV3(tx), api._agg, nil)

if err = zkStages.UnwindZkIntermediateHashesStage(unwindState, stageState, batch, interHashStageCfg, ctx, true); err != nil {
return nil, fmt.Errorf("unwind intermediate hashes: %w", err)
}

if err != nil {
return nil, err
}
tx = batch
}

reader, err := rpchelper.CreateStateReader(ctx, tx, blockNrOrHash, 0, api.filters, api.stateCache, api.historyV3(tx), "")
if err != nil {
return nil, err
}

header, err := api._blockReader.HeaderByNumber(ctx, tx, blockNr)
if err != nil {
return nil, err
}

tds := state.NewTrieDbState(header.Root, tx, blockNr, nil)
tds.SetResolveReads(true)
tds.StartNewBuffer()
tds.SetStateReader(reader)

ibs := state.New(tds)

ibs.GetBalance(address)

for _, key := range storageKeys {
value := new(uint256.Int)
ibs.GetState(address, &key, value)
}

rl, err := tds.ResolveSMTRetainList()
if err != nil {
return nil, err
}

smtTrie := smt.NewRoSMT(smtDb.NewRoEriDb(tx))

proofs, err := smt.BuildProofs(smtTrie, rl, ctx)
if err != nil {
return nil, err
}

stateRootNode := smtUtils.ScalarToRoot(new(big.Int).SetBytes(header.Root.Bytes()))

if err != nil {
return nil, err
}

balanceKey, err := smtUtils.KeyEthAddrBalance(address.String())
if err != nil {
return nil, err
}

nonceKey, err := smtUtils.KeyEthAddrNonce(address.String())
if err != nil {
return nil, err
}

codeHashKey, err := smtUtils.KeyContractCode(address.String())
if err != nil {
return nil, err
}

codeLengthKey, err := smtUtils.KeyContractLength(address.String())
if err != nil {
return nil, err
}

balanceProofs := smt.FilterProofs(proofs, balanceKey)
balanceBytes, err := smt.VerifyAndGetVal(stateRootNode, balanceProofs, balanceKey)
if err != nil {
return nil, fmt.Errorf("balance proof verification failed: %w", err)
}

balance := new(big.Int).SetBytes(balanceBytes)

nonceProofs := smt.FilterProofs(proofs, nonceKey)
nonceBytes, err := smt.VerifyAndGetVal(stateRootNode, nonceProofs, nonceKey)
if err != nil {
return nil, fmt.Errorf("nonce proof verification failed: %w", err)
}
nonce := new(big.Int).SetBytes(nonceBytes).Uint64()

codeHashProofs := smt.FilterProofs(proofs, codeHashKey)
codeHashBytes, err := smt.VerifyAndGetVal(stateRootNode, codeHashProofs, codeHashKey)
if err != nil {
return nil, fmt.Errorf("code hash proof verification failed: %w", err)
}
codeHash := codeHashBytes

codeLengthProofs := smt.FilterProofs(proofs, codeLengthKey)
codeLengthBytes, err := smt.VerifyAndGetVal(stateRootNode, codeLengthProofs, codeLengthKey)
if err != nil {
return nil, fmt.Errorf("code length proof verification failed: %w", err)
}
codeLength := new(big.Int).SetBytes(codeLengthBytes).Uint64()

accProof := &accounts.SMTAccProofResult{
Address: address,
Balance: (*hexutil.Big)(balance),
CodeHash: libcommon.BytesToHash(codeHash),
CodeLength: hexutil.Uint64(codeLength),
Nonce: hexutil.Uint64(nonce),
BalanceProof: balanceProofs,
NonceProof: nonceProofs,
CodeHashProof: codeHashProofs,
CodeLengthProof: codeLengthProofs,
StorageProof: make([]accounts.SMTStorageProofResult, 0),
}

addressArrayBig := smtUtils.ScalarToArrayBig(smtUtils.ConvertHexToBigInt(address.String()))
for _, k := range storageKeys {
storageKey, err := smtUtils.KeyContractStorage(addressArrayBig, k.String())
if err != nil {
return nil, err
}
storageProofs := smt.FilterProofs(proofs, storageKey)

valueBytes, err := smt.VerifyAndGetVal(stateRootNode, storageProofs, storageKey)
if err != nil {
return nil, fmt.Errorf("storage proof verification failed: %w", err)
}

value := new(big.Int).SetBytes(valueBytes)

accProof.StorageProof = append(accProof.StorageProof, accounts.SMTStorageProofResult{
Key: k,
Value: (*hexutil.Big)(value),
Proof: storageProofs,
})
}

return accProof, nil
}
19 changes: 19 additions & 0 deletions core/types/accounts/account_proof.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,22 @@ type StorProofResult struct {
Value *hexutil.Big `json:"value"`
Proof []hexutility.Bytes `json:"proof"`
}

type SMTAccProofResult struct {
Address libcommon.Address `json:"address"`
Balance *hexutil.Big `json:"balance"`
CodeHash libcommon.Hash `json:"codeHash"`
CodeLength hexutil.Uint64 `json:"codeLength"`
Nonce hexutil.Uint64 `json:"nonce"`
BalanceProof []hexutility.Bytes `json:"balanceProof"`
NonceProof []hexutility.Bytes `json:"nonceProof"`
CodeHashProof []hexutility.Bytes `json:"codeHashProof"`
CodeLengthProof []hexutility.Bytes `json:"codeLengthProof"`
StorageProof []SMTStorageProofResult `json:"storageProof"`
}

type SMTStorageProofResult struct {
Key libcommon.Hash `json:"key"`
Value *hexutil.Big `json:"value"`
Proof []hexutility.Bytes `json:"proof"`
}
1 change: 1 addition & 0 deletions eth/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
seqAndVerifTopics := [][]libcommon.Hash{{
contracts.SequencedBatchTopicPreEtrog,
contracts.SequencedBatchTopicEtrog,
contracts.RollbackBatchesTopic,
contracts.VerificationTopicPreEtrog,
contracts.VerificationTopicEtrog,
contracts.VerificationValidiumTopicEtrog,
Expand Down
Loading

0 comments on commit d5d0490

Please sign in to comment.