Skip to content

Commit

Permalink
Merge pull request #1305 from 0xPolygonHermez/add-rpcs-return-finishe…
Browse files Browse the repository at this point in the history
…d-block

feat: change RPCs to use latest finished block
  • Loading branch information
MorettiGeorgiev authored Oct 21, 2024
2 parents 17167c0 + 435460c commit 9257579
Show file tree
Hide file tree
Showing 16 changed files with 76 additions and 84 deletions.
11 changes: 5 additions & 6 deletions rpc/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,10 @@ type jsonWriter interface {
remoteAddr() string
}

type BlockNumber int64
type Timestamp uint64
type (
BlockNumber int64
Timestamp uint64
)

const (
LatestExecutedBlockNumber = BlockNumber(-5)
Expand Down Expand Up @@ -159,7 +161,7 @@ func (bn *BlockNumber) MarshallJson() string {
case -5:
return "latestExecuted"
default:
return fmt.Sprintf("0x%x", *bn)
return fmt.Sprintf("0x%x", bn.Int64())
}
}

Expand Down Expand Up @@ -468,17 +470,14 @@ func (ts *Timestamp) UnmarshalJSON(data []byte) error {
// parse string to uint64
timestamp, err := strconv.ParseUint(input, 10, 64)
if err != nil {

// try hex number
if timestamp, err = hexutil.DecodeUint64(input); err != nil {
return err
}

}

*ts = Timestamp(timestamp)
return nil

}

type ForkInterval struct {
Expand Down
2 changes: 1 addition & 1 deletion turbo/jsonrpc/debug_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ func (api *PrivateDebugAPIImpl) AccountRange(ctx context.Context, blockNrOrHash
if number == rpc.LatestBlockNumber {
var err error

blockNumber, err = stages.GetStageProgress(tx, stages.Execution)
blockNumber, err = stages.GetStageProgress(tx, stages.Finish)
if err != nil {
return state.IteratorDump{}, fmt.Errorf("last block has not found: %w", err)
}
Expand Down
4 changes: 2 additions & 2 deletions turbo/jsonrpc/erigon_receipts.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func (api *ErigonImpl) GetLogs(ctx context.Context, crit filters.FilterCriteria)

} else {
// Convert the RPC block numbers into internal representations
latest, err := rpchelper.GetLatestBlockNumber(tx)
latest, err := rpchelper.GetLatestFinishedBlockNumber(tx)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -234,7 +234,7 @@ func (api *ErigonImpl) GetLatestLogs(ctx context.Context, crit filters.FilterCri
end = header.Number.Uint64()
} else {
// Convert the RPC block numbers into internal representations
latest, err := rpchelper.GetLatestBlockNumber(tx)
latest, err := rpchelper.GetLatestFinishedBlockNumber(tx)
if err != nil {
return nil, err
}
Expand Down
9 changes: 2 additions & 7 deletions turbo/jsonrpc/erigon_system.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,13 @@ func (api *ErigonImpl) BlockNumber(ctx context.Context, rpcBlockNumPtr *rpc.Bloc

var rpcBlockNum rpc.BlockNumber
if rpcBlockNumPtr == nil {
rpcBlockNum = rpc.LatestExecutedBlockNumber
rpcBlockNum = rpc.LatestBlockNumber
} else {
rpcBlockNum = *rpcBlockNumPtr
}

var blockNum uint64
switch rpcBlockNum {
case rpc.LatestBlockNumber:
blockNum, err = rpchelper.GetLatestBlockNumber(tx)
if err != nil {
return 0, err
}
case rpc.EarliestBlockNumber:
blockNum = 0
case rpc.SafeBlockNumber:
Expand All @@ -85,7 +80,7 @@ func (api *ErigonImpl) BlockNumber(ctx context.Context, rpcBlockNumPtr *rpc.Bloc
return 0, err
}
default:
blockNum, err = rpchelper.GetLatestExecutedBlockNumber(tx)
blockNum, err = rpchelper.GetLatestFinishedBlockNumber(tx)
if err != nil {
return 0, err
}
Expand Down
11 changes: 11 additions & 0 deletions turbo/jsonrpc/eth_accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,17 @@ func (api *APIImpl) GetTransactionCount(ctx context.Context, address libcommon.A
return nil, fmt.Errorf("getTransactionCount cannot open tx: %w", err1)
}
defer tx.Rollback()

latestExecutedBlockNumber, err := rpchelper.GetLatestExecutedBlockNumber(tx)
if err != nil {
return nil, fmt.Errorf("getTransactionCount cannot get latest executed block number: %w", err)
}

if blockNrOrHash.BlockNumber != nil && *blockNrOrHash.BlockNumber == rpc.BlockNumber(latestExecutedBlockNumber) {
blockNumber := rpc.BlockNumber(rpc.LatestExecutedBlockNumber)
blockNrOrHash.BlockNumber = &blockNumber
}

reader, err := rpchelper.CreateStateReader(ctx, tx, *blockNrOrHash, 0, api.filters, api.stateCache, api.historyV3(tx), "")
if err != nil {
return nil, err
Expand Down
2 changes: 1 addition & 1 deletion turbo/jsonrpc/eth_accounts_zk.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func (api *APIImpl) sendGetTransactionCountToSequencer(rpcUrl string, address li
return nil, fmt.Errorf("RPC error response: %s", res.Error.Message)
}

//hash comes in escaped quotes, so we trim them here
// hash comes in escaped quotes, so we trim them here
// \"0x1234\" -> 0x1234
hashHex := strings.Trim(string(res.Result), "\"")

Expand Down
2 changes: 1 addition & 1 deletion turbo/jsonrpc/eth_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ func (api *APIImpl) GetBlockTransactionCountByNumber(ctx context.Context, blockN
if err != nil {
return nil, err
}
latestBlockNumber, err := rpchelper.GetLatestBlockNumber(tx)
latestBlockNumber, err := rpchelper.GetLatestFinishedBlockNumber(tx)
if err != nil {
return nil, err
}
Expand Down
8 changes: 4 additions & 4 deletions turbo/jsonrpc/eth_block_zkevm.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,15 +216,15 @@ func (api *APIImpl) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber
}
defer tx.Rollback()

// get latest executed block
executedBlock, err := stages.GetStageProgress(tx, stages.Execution)
// get latest finished block
finishedBlock, err := stages.GetStageProgress(tx, stages.Finish)
if err != nil {
return nil, err
}

// return null if requested block is higher than executed
// return null if requested block is higher than finished
// made for consistency with zkevm
if number > 0 && executedBlock < uint64(number.Int64()) {
if number > 0 && finishedBlock < uint64(number.Int64()) {
return nil, nil
}

Expand Down
4 changes: 2 additions & 2 deletions turbo/jsonrpc/eth_receipts.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ func (api *APIImpl) GetLogs(ctx context.Context, crit filters.FilterCriteria) (t
end = header.Number.Uint64()
} else {
// Convert the RPC block numbers into internal representations
latest, _, _, err := rpchelper.GetBlockNumber(rpc.BlockNumberOrHashWithNumber(rpc.LatestExecutedBlockNumber), tx, nil)
latest, _, _, err := rpchelper.GetBlockNumber(rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber), tx, nil)
if err != nil {
return nil, err
}
Expand All @@ -144,7 +144,7 @@ func (api *APIImpl) GetLogs(ctx context.Context, crit filters.FilterCriteria) (t
return nil, fmt.Errorf("end (%d) < begin (%d)", end, begin)
}
if end > roaring.MaxUint32 {
latest, err := rpchelper.GetLatestBlockNumber(tx)
latest, err := rpchelper.GetLatestFinishedBlockNumber(tx)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion turbo/jsonrpc/eth_system.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func (api *APIImpl) BlockNumber(ctx context.Context) (hexutil.Uint64, error) {
return 0, err
}
defer tx.Rollback()
blockNum, err := rpchelper.GetLatestBlockNumber(tx)
blockNum, err := rpchelper.GetLatestFinishedBlockNumber(tx)
if err != nil {
return 0, err
}
Expand Down
4 changes: 2 additions & 2 deletions turbo/jsonrpc/overlay_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,7 @@ func (api *OverlayAPIImpl) replayBlock(ctx context.Context, blockNum uint64, sta
log.Debug("[replayBlock] res result for transaction", "transactionHash", txn.Hash(), "failed", res.Failed(), "revert", res.Revert(), "error", res.Err)
log.Debug("[replayBlock] discarding txLogs because tx has status=failed", "transactionHash", txn.Hash())
} else {
//append logs only if tx has not reverted
// append logs only if tx has not reverted
txLogs := statedb.GetLogs(txn.Hash())
log.Debug("[replayBlock]", "len(txLogs)", len(txLogs), "transactionHash", txn.Hash())
blockLogs = append(blockLogs, txLogs...)
Expand Down Expand Up @@ -618,7 +618,7 @@ func getBeginEnd(ctx context.Context, tx kv.Tx, api *OverlayAPIImpl, crit filter
return 0, 0, fmt.Errorf("end (%d) < begin (%d)", end, begin)
}
if end > roaring.MaxUint32 {
latest, err := rpchelper.GetLatestBlockNumber(tx)
latest, err := rpchelper.GetLatestFinishedBlockNumber(tx)
if err != nil {
return 0, 0, err
}
Expand Down
2 changes: 1 addition & 1 deletion turbo/jsonrpc/zkevm_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -1597,7 +1597,7 @@ func (zkapi *ZkEvmAPIImpl) GetProof(ctx context.Context, address common.Address,
return nil, err
}

latestBlock, err := rpchelper.GetLatestBlockNumber(tx)
latestBlock, err := rpchelper.GetLatestFinishedBlockNumber(tx)
if err != nil {
return nil, err
}
Expand Down
5 changes: 5 additions & 0 deletions turbo/jsonrpc/zkevm_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -983,6 +983,11 @@ func TestGetFullBlockByNumber(t *testing.T) {
err = erigonDB.WriteBody(big.NewInt(9), common.HexToHash("0x27ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a84b7ba81"), []types.Transaction{})
assert.NoError(err)

for i := 1; i <= 4; i++ {
err = stages.SaveStageProgress(tx, stages.Finish, uint64(i))
assert.NoError(err)
}

tx.Commit()

// Block 1
Expand Down
31 changes: 18 additions & 13 deletions turbo/rpchelper/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,18 @@ func GetCanonicalBlockNumber(blockNrOrHash rpc.BlockNumberOrHash, tx kv.Tx, filt
}

func _GetBlockNumber(requireCanonical bool, blockNrOrHash rpc.BlockNumberOrHash, tx kv.Tx, filters *Filters) (blockNumber uint64, hash libcommon.Hash, latest bool, err error) {
// Due to changed semantics of `lastest` block in RPC request, it is now distinct
// from the block number corresponding to the plain state
var plainStateBlockNumber uint64
if plainStateBlockNumber, err = stages.GetStageProgress(tx, stages.Execution); err != nil {
return 0, libcommon.Hash{}, false, fmt.Errorf("getting plain state block number: %w", err)
finishedBlockNumber, err := stages.GetStageProgress(tx, stages.Finish)
if err != nil {
return 0, libcommon.Hash{}, false, fmt.Errorf("getting finished block number: %w", err)
}

var ok bool
hash, ok = blockNrOrHash.Hash()
if !ok {
number := *blockNrOrHash.BlockNumber
switch number {
case rpc.LatestBlockNumber:
if blockNumber, err = GetLatestBlockNumber(tx); err != nil {
if blockNumber, err = GetLatestFinishedBlockNumber(tx); err != nil {
return 0, libcommon.Hash{}, false, err
}
case rpc.EarliestBlockNumber:
Expand All @@ -74,21 +73,26 @@ func _GetBlockNumber(requireCanonical bool, blockNrOrHash rpc.BlockNumberOrHash,
// [zkevm] safe not available, returns finilized instead
// blockNumber, err = GetSafeBlockNumber(tx)
blockNumber, err = GetFinalizedBlockNumber(tx)

if err != nil {
return 0, libcommon.Hash{}, false, err
}
case rpc.PendingBlockNumber:
pendingBlock := filters.LastPendingBlock()
if pendingBlock == nil {
blockNumber = plainStateBlockNumber
blockNumber = finishedBlockNumber
} else {
return pendingBlock.NumberU64(), pendingBlock.Hash(), false, nil
}
case rpc.LatestExecutedBlockNumber:
blockNumber = plainStateBlockNumber
blockNumber, err = stages.GetStageProgress(tx, stages.Execution)
if err != nil {
return 0, libcommon.Hash{}, false, fmt.Errorf("getting latest executed block number: %w", err)
}
default:
blockNumber = uint64(number.Int64())
if blockNumber > finishedBlockNumber {
return 0, libcommon.Hash{}, false, fmt.Errorf("block with number %d not found", blockNumber)
}
}
hash, err = rawdb.ReadCanonicalHash(tx, blockNumber)
if err != nil {
Expand All @@ -109,7 +113,7 @@ func _GetBlockNumber(requireCanonical bool, blockNrOrHash rpc.BlockNumberOrHash,
return 0, libcommon.Hash{}, false, nonCanonocalHashError{hash}
}
}
return blockNumber, hash, blockNumber == plainStateBlockNumber, nil
return blockNumber, hash, blockNumber == finishedBlockNumber, nil
}

func CreateStateReader(ctx context.Context, tx kv.Tx, blockNrOrHash rpc.BlockNumberOrHash, txnIndex int, filters *Filters, stateCache kvcache.Cache, historyV3 bool, chainName string) (state.StateReader, error) {
Expand All @@ -134,12 +138,12 @@ func CreateStateReaderFromBlockNumber(ctx context.Context, tx kv.Tx, blockNumber
func CreateHistoryStateReader(tx kv.Tx, blockNumber uint64, txnIndex int, historyV3 bool, chainName string) (state.StateReader, error) {
if !historyV3 {
r := state.NewPlainState(tx, blockNumber, systemcontracts.SystemContractCodeLookup[chainName])
//r.SetTrace(true)
// r.SetTrace(true)
return r, nil
}
r := state.NewHistoryReaderV3()
r.SetTx(tx)
//r.SetTrace(true)
// r.SetTrace(true)
minTxNum, err := rawdbv3.TxNums.Min(tx, blockNumber)
if err != nil {
return nil, err
Expand All @@ -151,10 +155,11 @@ func CreateHistoryStateReader(tx kv.Tx, blockNumber uint64, txnIndex int, histor
func NewLatestStateReader(tx kv.Getter) state.StateReader {
if config3.EnableHistoryV4InTest {
panic("implement me")
//b.pendingReader = state.NewReaderV4(b.pendingReaderTx.(kv.TemporalTx))
// b.pendingReader = state.NewReaderV4(b.pendingReaderTx.(kv.TemporalTx))
}
return state.NewPlainStateReader(tx)
}

func NewLatestStateWriter(tx kv.RwTx, blockNum uint64) state.StateWriter {
if config3.EnableHistoryV4InTest {
panic("implement me")
Expand Down
34 changes: 14 additions & 20 deletions turbo/rpchelper/helper_zkevm.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,38 +12,32 @@ import (
func GetBatchNumber(rpcBatchNumber rpc.BlockNumber, tx kv.Tx, filters *Filters) (batchNumber uint64, latest bool, err error) {
// Due to changed semantics of `lastest` block in RPC request, it is now distinct
// from the block block number corresponding to the plain state
var (
executedBlock uint64
plainStateBatchNumber uint64
)
hermezDb := hermez_db.NewHermezDbReader(tx)

// get highest executed batch
if executedBlock, err = stages.GetStageProgress(tx, stages.Execution); err != nil {
return 0, false, fmt.Errorf("getting plain state block number: %w", err)
}

if plainStateBatchNumber, err = hermezDb.GetBatchNoByL2Block(executedBlock); err != nil {
return 0, false, fmt.Errorf("getting plain state batch number: %w", err)
}

switch rpcBatchNumber {
case rpc.EarliestBlockNumber:
batchNumber = 0
case rpc.FinalizedBlockNumber:
case rpc.SafeBlockNumber:
case rpc.SafeBlockNumber, rpc.FinalizedBlockNumber:
// [zkevm] safe not available, returns finilized instead
// get highest verified batch
if batchNumber, err = stages.GetStageProgress(tx, stages.L1VerificationsBatchNo); err != nil {
return 0, false, fmt.Errorf("getting verified batch number: %w", err)
}
case rpc.PendingBlockNumber:
case rpc.LatestBlockNumber:
case rpc.LatestExecutedBlockNumber:
batchNumber = plainStateBatchNumber
case rpc.LatestBlockNumber, rpc.LatestExecutedBlockNumber, rpc.PendingBlockNumber:
// get highest finished batch
latestFinishedBlock, err := stages.GetStageProgress(tx, stages.Finish)
if err != nil {
return 0, false, fmt.Errorf("getting latest finished state block number: %w", err)
}

if batchNumber, err = hermezDb.GetBatchNoByL2Block(latestFinishedBlock); err != nil {
return 0, false, fmt.Errorf("getting latest finished state batch number: %w", err)
}

latest = true
default:
batchNumber = uint64(rpcBatchNumber.Int64())
}

return batchNumber, batchNumber == plainStateBatchNumber, nil
return batchNumber, latest, nil
}
Loading

0 comments on commit 9257579

Please sign in to comment.