diff --git a/arbitrum/apibackend.go b/arbitrum/apibackend.go index a31fcd30a..d00346d48 100644 --- a/arbitrum/apibackend.go +++ b/arbitrum/apibackend.go @@ -96,6 +96,7 @@ type SyncProgressBackend interface { SyncProgressMap() map[string]interface{} SafeBlockNumber(ctx context.Context) (uint64, error) FinalizedBlockNumber(ctx context.Context) (uint64, error) + BlockMetadataByNumber(blockNum uint64) (common.BlockMetadata, error) } func createRegisterAPIBackend(backend *Backend, filterConfig filters.Config, fallbackClientUrl string, fallbackClientTimeout time.Duration) (*filters.FilterSystem, error) { @@ -460,6 +461,10 @@ func (a *APIBackend) BlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc. return nil, errors.New("invalid arguments; neither block nor hash specified") } +func (a *APIBackend) BlockMetadataByNumber(blockNum uint64) (common.BlockMetadata, error) { + return a.sync.BlockMetadataByNumber(blockNum) +} + func StateAndHeaderFromHeader(ctx context.Context, chainDb ethdb.Database, bc *core.BlockChain, maxRecreateStateDepth int64, header *types.Header, err error) (*state.StateDB, *types.Header, error) { if err != nil { return nil, header, err diff --git a/common/types.go b/common/types.go index b914787d1..e2fe42e13 100644 --- a/common/types.go +++ b/common/types.go @@ -486,3 +486,20 @@ func (b PrettyBytes) TerminalString() string { } return fmt.Sprintf("%#x...%x (%dB)", b[:3], b[len(b)-3:], len(b)) } + +type BlockMetadata []byte + +// IsTxTimeboosted given a tx's index in the block returns whether the tx was timeboosted or not +func (b BlockMetadata) IsTxTimeboosted(txIndex int) (bool, error) { + if len(b) == 0 { + return false, errors.New("blockMetadata is not set") + } + if txIndex < 0 { + return false, fmt.Errorf("invalid transaction index- %d, should be positive", txIndex) + } + maxTxCount := (len(b) - 1) * 8 + if txIndex >= maxTxCount { + return false, nil + } + return b[1+(txIndex/8)]&(1<<(txIndex%8)) != 0, nil +} diff --git a/eth/api_backend.go b/eth/api_backend.go index dadbfa312..f9b59945d 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -182,6 +182,10 @@ func (b *EthAPIBackend) BlockByNumberOrHash(ctx context.Context, blockNrOrHash r return nil, errors.New("invalid arguments; neither block nor hash specified") } +func (b *EthAPIBackend) BlockMetadataByNumber(blockNum uint64) (common.BlockMetadata, error) { + return nil, nil +} + func (b *EthAPIBackend) Pending() (*types.Block, types.Receipts, *state.StateDB) { return b.eth.miner.Pending() } diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index cd5f1300e..7bcdcf57e 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1983,6 +1983,17 @@ func marshalReceipt(ctx context.Context, receipt *types.Receipt, blockHash commo fields["l1BlockNumber"] = hexutil.Uint64(arbTx.L1BlockNumber) } } + + blockMetadata, err := backend.BlockMetadataByNumber(blockNumber) + if err != nil { + return nil, err + } + if blockMetadata != nil { + fields["timeboosted"], err = blockMetadata.IsTxTimeboosted(txIndex) + if err != nil { + log.Error("Error checking if a tx was timeboosted", "txIndex", txIndex, "txHash", tx.Hash(), "err", err) + } + } } return fields, nil } diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index 49d50658f..f737ce781 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -527,6 +527,9 @@ func (b testBackend) BlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc. } panic("unknown type rpc.BlockNumberOrHash") } +func (b testBackend) BlockMetadataByNumber(blockNum uint64) (common.BlockMetadata, error) { + return nil, nil +} func (b testBackend) GetBody(ctx context.Context, hash common.Hash, number rpc.BlockNumber) (*types.Body, error) { return b.chain.GetBlock(hash, uint64(number.Int64())).Body(), nil } diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go index 246dd8a8d..0e9832cd9 100644 --- a/internal/ethapi/backend.go +++ b/internal/ethapi/backend.go @@ -67,6 +67,7 @@ type Backend interface { BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) BlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Block, error) + BlockMetadataByNumber(blockNum uint64) (common.BlockMetadata, error) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*state.StateDB, *types.Header, error) Pending() (*types.Block, types.Receipts, *state.StateDB) diff --git a/internal/ethapi/transaction_args_test.go b/internal/ethapi/transaction_args_test.go index 0986a2074..64dd6e835 100644 --- a/internal/ethapi/transaction_args_test.go +++ b/internal/ethapi/transaction_args_test.go @@ -351,6 +351,9 @@ func (b *backendMock) BlockByHash(ctx context.Context, hash common.Hash) (*types func (b *backendMock) BlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Block, error) { return nil, nil } +func (b *backendMock) BlockMetadataByNumber(blockNum uint64) (common.BlockMetadata, error) { + return nil, nil +} func (b *backendMock) GetBody(ctx context.Context, hash common.Hash, number rpc.BlockNumber) (*types.Body, error) { return nil, nil }