Skip to content

Commit

Permalink
add support to safe and finalized blocks for jRPC block parameters (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
tclemos authored May 2, 2023
1 parent fe36528 commit d61db6d
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 6 deletions.
2 changes: 1 addition & 1 deletion jsonrpc/endpoints_zkevm.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type ZKEVMEndpoints struct {
txMan dbTxManager
}

// ConsolidatedBlockNumber returns current block number for consolidated blocks
// ConsolidatedBlockNumber returns last block number related to the last verified batch
func (z *ZKEVMEndpoints) ConsolidatedBlockNumber() (interface{}, types.Error) {
return z.txMan.NewDbTxScope(z.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) {
lastBlockNumber, err := z.state.GetLastConsolidatedL2BlockNumber(ctx, dbTx)
Expand Down
24 changes: 24 additions & 0 deletions jsonrpc/mocks/mock_state.go

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

34 changes: 33 additions & 1 deletion jsonrpc/types/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ const (
LatestBlockNumber = BlockNumber(-2)
// EarliestBlockNumber represents the earliest block number
EarliestBlockNumber = BlockNumber(-1)
// SafeBlockNumber represents the last virtualized block number
SafeBlockNumber = BlockNumber(-4)
// FinalizedBlockNumber represents the last verified block number
FinalizedBlockNumber = BlockNumber(-5)

// LatestBatchNumber represents the latest batch number
LatestBatchNumber = BatchNumber(-2)
Expand All @@ -28,8 +32,12 @@ const (
Earliest = "earliest"
// Latest contains the string to represent the latest block known.
Latest = "latest"
// Pending contains the string to represent pending blocks.
// Pending contains the string to represent the pending block known.
Pending = "pending"
// Safe contains the string to represent the last virtualized block known.
Safe = "safe"
// Finalized contains the string to represent the last verified block known.
Finalized = "finalized"

// EIP-1898: https://eips.ethereum.org/EIPS/eip-1898 //

Expand Down Expand Up @@ -171,6 +179,22 @@ func (b *BlockNumber) GetNumericBlockNumber(ctx context.Context, s StateInterfac
case EarliestBlockNumber:
return 0, nil

case SafeBlockNumber:
lastBlockNumber, err := s.GetLastVirtualizedL2BlockNumber(ctx, dbTx)
if err != nil {
return 0, NewRPCError(DefaultErrorCode, "failed to get the last virtualized block number from state")
}

return lastBlockNumber, nil

case FinalizedBlockNumber:
lastBlockNumber, err := s.GetLastConsolidatedL2BlockNumber(ctx, dbTx)
if err != nil {
return 0, NewRPCError(DefaultErrorCode, "failed to get the last verified block number from state")
}

return lastBlockNumber, nil

default:
if bValue < 0 {
return 0, NewRPCError(InvalidParamsErrorCode, "invalid block number: %v", bValue)
Expand All @@ -192,6 +216,10 @@ func (b *BlockNumber) StringOrHex() string {
return Pending
case LatestBlockNumber:
return Latest
case SafeBlockNumber:
return Safe
case FinalizedBlockNumber:
return Finalized
default:
return hex.EncodeUint64(uint64(*b))
}
Expand All @@ -207,6 +235,10 @@ func StringToBlockNumber(str string) (BlockNumber, error) {
return PendingBlockNumber, nil
case Latest, "":
return LatestBlockNumber, nil
case Safe:
return SafeBlockNumber, nil
case Finalized:
return FinalizedBlockNumber, nil
}

n, err := encoding.DecodeUint64orHex(&str)
Expand Down
32 changes: 29 additions & 3 deletions jsonrpc/types/codec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ func TestBlockNumberMarshalJSON(t *testing.T) {
{"latest", int64(LatestBlockNumber), nil},
{"pending", int64(PendingBlockNumber), nil},
{"earliest", int64(EarliestBlockNumber), nil},
{"safe", int64(SafeBlockNumber), nil},
{"finalized", int64(FinalizedBlockNumber), nil},
{"", int64(LatestBlockNumber), nil},
{"0", int64(0), nil},
{"10", int64(10), nil},
Expand Down Expand Up @@ -95,6 +97,30 @@ func TestGetNumericBlockNumber(t *testing.T) {
expectedError: nil,
setupMocks: func(s *mocks.StateMock, d *mocks.DBTxMock, t *testCase) {},
},
{
name: "BlockNumber SafeBlockNumber",
bn: bnPtr(SafeBlockNumber),
expectedBlockNumber: 40,
expectedError: nil,
setupMocks: func(s *mocks.StateMock, d *mocks.DBTxMock, t *testCase) {
s.
On("GetLastVirtualizedL2BlockNumber", context.Background(), d).
Return(uint64(40), nil).
Once()
},
},
{
name: "BlockNumber FinalizedBlockNumber",
bn: bnPtr(FinalizedBlockNumber),
expectedBlockNumber: 50,
expectedError: nil,
setupMocks: func(s *mocks.StateMock, d *mocks.DBTxMock, t *testCase) {
s.
On("GetLastConsolidatedL2BlockNumber", context.Background(), d).
Return(uint64(50), nil).
Once()
},
},
{
name: "BlockNumber Positive Number",
bn: bnPtr(BlockNumber(int64(10))),
Expand All @@ -103,10 +129,10 @@ func TestGetNumericBlockNumber(t *testing.T) {
setupMocks: func(s *mocks.StateMock, d *mocks.DBTxMock, t *testCase) {},
},
{
name: "BlockNumber Negative Number <= -4",
bn: bnPtr(BlockNumber(int64(-4))),
name: "BlockNumber Negative Number <= -6",
bn: bnPtr(BlockNumber(int64(-6))),
expectedBlockNumber: 0,
expectedError: NewRPCError(InvalidParamsErrorCode, "invalid block number: -4"),
expectedError: NewRPCError(InvalidParamsErrorCode, "invalid block number: -6"),
setupMocks: func(s *mocks.StateMock, d *mocks.DBTxMock, t *testCase) {},
},
}
Expand Down
1 change: 1 addition & 0 deletions jsonrpc/types/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type StateInterface interface {
GetL2BlockHeaderByNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) (*types.Header, error)
GetL2BlockTransactionCountByHash(ctx context.Context, hash common.Hash, dbTx pgx.Tx) (uint64, error)
GetL2BlockTransactionCountByNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) (uint64, error)
GetLastVirtualizedL2BlockNumber(ctx context.Context, dbTx pgx.Tx) (uint64, error)
GetLastConsolidatedL2BlockNumber(ctx context.Context, dbTx pgx.Tx) (uint64, error)
GetLastL2Block(ctx context.Context, dbTx pgx.Tx) (*types.Block, error)
GetLastL2BlockNumber(ctx context.Context, dbTx pgx.Tx) (uint64, error)
Expand Down
29 changes: 28 additions & 1 deletion state/pgstatestorage.go
Original file line number Diff line number Diff line change
Expand Up @@ -1457,10 +1457,37 @@ func (p *PostgresStorage) AddL2Block(ctx context.Context, batchNumber uint64, l2
return nil
}

// GetLastVirtualizedL2BlockNumber gets the last l2 block verified
func (p *PostgresStorage) GetLastVirtualizedL2BlockNumber(ctx context.Context, dbTx pgx.Tx) (uint64, error) {
var lastVirtualizedBlockNumber uint64
const getLastVirtualizedBlockNumberSQL = `
SELECT b.block_num
FROM state.l2block b
INNER JOIN state.virtual_batch vb
ON vb.batch_num = b.batch_num
ORDER BY b.block_num DESC LIMIT 1`

q := p.getExecQuerier(dbTx)
err := q.QueryRow(ctx, getLastVirtualizedBlockNumberSQL).Scan(&lastVirtualizedBlockNumber)

if errors.Is(err, pgx.ErrNoRows) {
return 0, ErrNotFound
} else if err != nil {
return 0, err
}

return lastVirtualizedBlockNumber, nil
}

// GetLastConsolidatedL2BlockNumber gets the last l2 block verified
func (p *PostgresStorage) GetLastConsolidatedL2BlockNumber(ctx context.Context, dbTx pgx.Tx) (uint64, error) {
var lastConsolidatedBlockNumber uint64
const getLastConsolidatedBlockNumberSQL = "SELECT b.block_num FROM state.l2block b INNER JOIN state.verified_batch vb ON vb.batch_num = b.batch_num ORDER BY b.block_num DESC LIMIT 1"
const getLastConsolidatedBlockNumberSQL = `
SELECT b.block_num
FROM state.l2block b
INNER JOIN state.verified_batch vb
ON vb.batch_num = b.batch_num
ORDER BY b.block_num DESC LIMIT 1`

q := p.getExecQuerier(dbTx)
err := q.QueryRow(ctx, getLastConsolidatedBlockNumberSQL).Scan(&lastConsolidatedBlockNumber)
Expand Down
4 changes: 4 additions & 0 deletions test/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,10 @@ deploy-uniswap: ## deploy the uniswap environment to the network
run-db-scripts: ## Executes scripts on the db after it has been initialized, potentially using info from the environment
./scripts/postgres/run.sh

.PHONY: install-mockery
install-mockery: ## Installs mockery with the correct version to generate the mocks
go install github.com/vektra/mockery/[email protected]

.PHONY: generate-mocks
generate-mocks: ## Generates mocks for the tests, using mockery tool
mockery --name=storageInterface --dir=../jsonrpc --output=../jsonrpc --outpkg=jsonrpc --inpackage --structname=storageMock --filename=mock_storage.go
Expand Down

0 comments on commit d61db6d

Please sign in to comment.