mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 06:36:43 +00:00
feat(rpc): add scroll_* rollup APIs (#548)
* feat(rpc): add scroll_* rollup APIs * address comments * address comments * address comments * support finalized tag in eth_feeHistory * Update internal/web3ext/web3ext.go Co-authored-by: Péter Garamvölgyi <peter@scroll.io> * tweak --------- Co-authored-by: Péter Garamvölgyi <peter@scroll.io>
This commit is contained in:
parent
a8a9dc83cb
commit
1bf26286db
5 changed files with 89 additions and 1 deletions
54
eth/api.go
54
eth/api.go
|
|
@ -715,6 +715,60 @@ func (api *ScrollAPI) GetNumSkippedTransactions(ctx context.Context) (uint64, er
|
||||||
return rawdb.ReadNumSkippedTransactions(api.eth.ChainDb()), nil
|
return rawdb.ReadNumSkippedTransactions(api.eth.ChainDb()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SyncStatus includes L2 block sync height, L1 rollup sync height,
|
||||||
|
// L1 message sync height, and L2 finalized block height.
|
||||||
|
type SyncStatus struct {
|
||||||
|
L2BlockSyncHeight uint64 `json:"l2BlockSyncHeight,omitempty"`
|
||||||
|
L1RollupSyncHeight uint64 `json:"l1RollupSyncHeight,omitempty"`
|
||||||
|
L1MessageSyncHeight uint64 `json:"l1MessageSyncHeight,omitempty"`
|
||||||
|
L2FinalizedBlockHeight uint64 `json:"l2FinalizedBlockHeight,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SyncStatus returns the overall rollup status including L2 block sync height, L1 rollup sync height,
|
||||||
|
// L1 message sync height, and L2 finalized block height.
|
||||||
|
func (api *ScrollAPI) SyncStatus(_ context.Context) *SyncStatus {
|
||||||
|
status := &SyncStatus{}
|
||||||
|
|
||||||
|
l2BlockHeader := api.eth.blockchain.CurrentHeader()
|
||||||
|
if l2BlockHeader != nil {
|
||||||
|
status.L2BlockSyncHeight = l2BlockHeader.Number.Uint64()
|
||||||
|
}
|
||||||
|
|
||||||
|
l1RollupSyncHeightPtr := rawdb.ReadRollupEventSyncedL1BlockNumber(api.eth.ChainDb())
|
||||||
|
if l1RollupSyncHeightPtr != nil {
|
||||||
|
status.L1RollupSyncHeight = *l1RollupSyncHeightPtr
|
||||||
|
}
|
||||||
|
|
||||||
|
l1MessageSyncHeightPtr := rawdb.ReadSyncedL1BlockNumber(api.eth.ChainDb())
|
||||||
|
if l1MessageSyncHeightPtr != nil {
|
||||||
|
status.L1MessageSyncHeight = *l1MessageSyncHeightPtr
|
||||||
|
}
|
||||||
|
|
||||||
|
l2FinalizedBlockHeightPtr := rawdb.ReadFinalizedL2BlockNumber(api.eth.ChainDb())
|
||||||
|
if l2FinalizedBlockHeightPtr != nil {
|
||||||
|
status.L2FinalizedBlockHeight = *l2FinalizedBlockHeightPtr
|
||||||
|
}
|
||||||
|
|
||||||
|
return status
|
||||||
|
}
|
||||||
|
|
||||||
|
// EstimateL1DataFee returns an estimate of the L1 data fee required to
|
||||||
|
// process the given transaction against the current pending block.
|
||||||
|
func (api *ScrollAPI) EstimateL1DataFee(ctx context.Context, args ethapi.TransactionArgs, blockNrOrHash *rpc.BlockNumberOrHash) (*hexutil.Uint64, error) {
|
||||||
|
bNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber)
|
||||||
|
if blockNrOrHash != nil {
|
||||||
|
bNrOrHash = *blockNrOrHash
|
||||||
|
}
|
||||||
|
|
||||||
|
l1DataFee, err := ethapi.EstimateL1MsgFee(ctx, api.eth.APIBackend, args, bNrOrHash, nil, 0, api.eth.APIBackend.RPCGasCap(), api.eth.APIBackend.ChainConfig())
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to estimate L1 data fee: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
result := hexutil.Uint64(l1DataFee.Uint64())
|
||||||
|
return &result, nil
|
||||||
|
}
|
||||||
|
|
||||||
// RPCTransaction is the standard RPC transaction return type with some additional skip-related fields.
|
// RPCTransaction is the standard RPC transaction return type with some additional skip-related fields.
|
||||||
type RPCTransaction struct {
|
type RPCTransaction struct {
|
||||||
ethapi.RPCTransaction
|
ethapi.RPCTransaction
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,14 @@ func (b *EthAPIBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumb
|
||||||
if number == rpc.LatestBlockNumber {
|
if number == rpc.LatestBlockNumber {
|
||||||
return b.eth.blockchain.CurrentBlock().Header(), nil
|
return b.eth.blockchain.CurrentBlock().Header(), nil
|
||||||
}
|
}
|
||||||
|
if number == rpc.FinalizedBlockNumber {
|
||||||
|
finalizedBlockHeightPtr := rawdb.ReadFinalizedL2BlockNumber(b.eth.ChainDb())
|
||||||
|
if finalizedBlockHeightPtr == nil {
|
||||||
|
return nil, errors.New("L2 finalized block height not found in database")
|
||||||
|
}
|
||||||
|
number = rpc.BlockNumber(*finalizedBlockHeightPtr)
|
||||||
|
return b.eth.blockchain.GetHeaderByNumber(uint64(number)), nil
|
||||||
|
}
|
||||||
return b.eth.blockchain.GetHeaderByNumber(uint64(number)), nil
|
return b.eth.blockchain.GetHeaderByNumber(uint64(number)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -110,6 +118,14 @@ func (b *EthAPIBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumbe
|
||||||
if number == rpc.LatestBlockNumber {
|
if number == rpc.LatestBlockNumber {
|
||||||
return b.eth.blockchain.CurrentBlock(), nil
|
return b.eth.blockchain.CurrentBlock(), nil
|
||||||
}
|
}
|
||||||
|
if number == rpc.FinalizedBlockNumber {
|
||||||
|
finalizedBlockHeightPtr := rawdb.ReadFinalizedL2BlockNumber(b.eth.ChainDb())
|
||||||
|
if finalizedBlockHeightPtr == nil {
|
||||||
|
return nil, errors.New("L2 finalized block height not found in database")
|
||||||
|
}
|
||||||
|
number = rpc.BlockNumber(*finalizedBlockHeightPtr)
|
||||||
|
return b.eth.blockchain.GetBlockByNumber(uint64(number)), nil
|
||||||
|
}
|
||||||
return b.eth.blockchain.GetBlockByNumber(uint64(number)), nil
|
return b.eth.blockchain.GetBlockByNumber(uint64(number)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -170,6 +170,13 @@ func (oracle *Oracle) resolveBlockRange(ctx context.Context, lastBlock rpc.Block
|
||||||
} else if pendingBlock == nil && lastBlock > headBlock {
|
} else if pendingBlock == nil && lastBlock > headBlock {
|
||||||
return nil, nil, 0, 0, fmt.Errorf("%w: requested %d, head %d", errRequestBeyondHead, lastBlock, headBlock)
|
return nil, nil, 0, 0, fmt.Errorf("%w: requested %d, head %d", errRequestBeyondHead, lastBlock, headBlock)
|
||||||
}
|
}
|
||||||
|
if lastBlock == rpc.FinalizedBlockNumber {
|
||||||
|
if latestFinalizedHeader, err := oracle.backend.HeaderByNumber(ctx, rpc.FinalizedBlockNumber); err == nil {
|
||||||
|
lastBlock = rpc.BlockNumber(latestFinalizedHeader.Number.Uint64())
|
||||||
|
} else {
|
||||||
|
return nil, nil, 0, 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
// ensure not trying to retrieve before genesis
|
// ensure not trying to retrieve before genesis
|
||||||
if rpc.BlockNumber(blocks) > lastBlock+1 {
|
if rpc.BlockNumber(blocks) > lastBlock+1 {
|
||||||
blocks = int(lastBlock + 1)
|
blocks = int(lastBlock + 1)
|
||||||
|
|
|
||||||
|
|
@ -897,6 +897,13 @@ web3._extend({
|
||||||
call: 'scroll_getSkippedTransactionHashes',
|
call: 'scroll_getSkippedTransactionHashes',
|
||||||
params: 2
|
params: 2
|
||||||
}),
|
}),
|
||||||
|
new web3._extend.Method({
|
||||||
|
name: 'estimateL1DataFee',
|
||||||
|
call: 'scroll_estimateL1DataFee',
|
||||||
|
params: 2,
|
||||||
|
inputFormatter: [web3._extend.formatters.inputCallFormatter, web3._extend.formatters.inputBlockNumberFormatter],
|
||||||
|
outputFormatter: web3._extend.utils.toDecimal
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
properties:
|
properties:
|
||||||
[
|
[
|
||||||
|
|
@ -912,6 +919,10 @@ web3._extend({
|
||||||
name: 'numSkippedTransactions',
|
name: 'numSkippedTransactions',
|
||||||
getter: 'scroll_getNumSkippedTransactions'
|
getter: 'scroll_getNumSkippedTransactions'
|
||||||
}),
|
}),
|
||||||
|
new web3._extend.Property({
|
||||||
|
name: 'syncStatus',
|
||||||
|
getter: 'scroll_syncStatus',
|
||||||
|
}),
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
`
|
`
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ import (
|
||||||
const (
|
const (
|
||||||
VersionMajor = 5 // Major version component of the current release
|
VersionMajor = 5 // Major version component of the current release
|
||||||
VersionMinor = 1 // Minor version component of the current release
|
VersionMinor = 1 // Minor version component of the current release
|
||||||
VersionPatch = 0 // Patch version component of the current release
|
VersionPatch = 1 // Patch version component of the current release
|
||||||
VersionMeta = "mainnet" // Version metadata to append to the version string
|
VersionMeta = "mainnet" // Version metadata to append to the version string
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue