diff options
-rw-r--r-- | eth/api.go | 46 | ||||
-rw-r--r-- | eth/api_backend.go | 37 | ||||
-rw-r--r-- | eth/api_tracer.go | 32 | ||||
-rw-r--r-- | eth/filters/api.go | 5 | ||||
-rw-r--r-- | eth/filters/filter.go | 2 | ||||
-rw-r--r-- | internal/ethapi/api.go | 65 | ||||
-rw-r--r-- | plugin/evm/config.go | 39 | ||||
-rw-r--r-- | plugin/evm/service.go | 67 | ||||
-rw-r--r-- | plugin/evm/vm.go | 23 | ||||
-rw-r--r-- | plugin/main.go | 7 | ||||
-rw-r--r-- | plugin/params.go | 41 | ||||
-rw-r--r-- | rpc/types.go | 9 |
12 files changed, 185 insertions, 188 deletions
@@ -278,21 +278,13 @@ func NewPublicDebugAPI(eth *Ethereum) *PublicDebugAPI { // DumpBlock retrieves the entire state of the database at a given block. func (api *PublicDebugAPI) DumpBlock(blockNr rpc.BlockNumber) (state.Dump, error) { - if blockNr == rpc.PendingBlockNumber { - // If we're dumping the pending state, we need to request - // both the pending block as well as the pending state from - // the miner and operate on those - _, stateDb := api.eth.miner.Pending() - return stateDb.RawDump(false, false, true), nil - } var block *types.Block - if blockNr == rpc.LatestBlockNumber { - block = api.eth.blockchain.CurrentBlock() - } else if blockNr == rpc.AcceptedBlockNumber { + if blockNr.IsAccepted() { block = api.eth.AcceptedBlock() } else { block = api.eth.blockchain.GetBlockByNumber(uint64(blockNr)) } + if block == nil { return state.Dump{}, fmt.Errorf("block #%d not found", blockNr) } @@ -362,27 +354,19 @@ func (api *PublicDebugAPI) AccountRange(blockNrOrHash rpc.BlockNumberOrHash, sta var err error if number, ok := blockNrOrHash.Number(); ok { - if number == rpc.PendingBlockNumber { - // If we're dumping the pending state, we need to request - // both the pending block as well as the pending state from - // the miner and operate on those - _, stateDb = api.eth.miner.Pending() + var block *types.Block + if number.IsAccepted() { + block = api.eth.AcceptedBlock() } else { - var block *types.Block - if number == rpc.LatestBlockNumber { - block = api.eth.blockchain.CurrentBlock() - } else if number == rpc.AcceptedBlockNumber { - block = api.eth.AcceptedBlock() - } else { - block = api.eth.blockchain.GetBlockByNumber(uint64(number)) - } - if block == nil { - return state.IteratorDump{}, fmt.Errorf("block #%d not found", number) - } - stateDb, err = api.eth.BlockChain().StateAt(block.Root()) - if err != nil { - return state.IteratorDump{}, err - } + block = api.eth.blockchain.GetBlockByNumber(uint64(number)) + } + + if block == nil { + return state.IteratorDump{}, fmt.Errorf("block #%d not found", number) + } + stateDb, err = api.eth.BlockChain().StateAt(block.Root()) + if err != nil { + return state.IteratorDump{}, err } } else if hash, ok := blockNrOrHash.Hash(); ok { block := api.eth.blockchain.GetBlockByHash(hash) @@ -393,6 +377,8 @@ func (api *PublicDebugAPI) AccountRange(blockNrOrHash rpc.BlockNumberOrHash, sta if err != nil { return state.IteratorDump{}, err } + } else { + return state.IteratorDump{}, errors.New("either block number or block hash must be specified") } if maxResults > AccountRangeMaxResults || maxResults <= 0 { diff --git a/eth/api_backend.go b/eth/api_backend.go index 6c5ebd8..f1b5f74 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -65,20 +65,12 @@ func (b *EthAPIBackend) SetHead(number uint64) { } func (b *EthAPIBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) { - // Pending block is only known by the miner in - // Ethereum, but Coreth does not have the same notion. - // So we treat requests for the pending block identically - // to the latest accepted block instead - if number == rpc.PendingBlockNumber { - return b.eth.AcceptedBlock().Header(), nil - } - // Otherwise resolve and return the block - if number == rpc.LatestBlockNumber { - return b.eth.blockchain.CurrentBlock().Header(), nil - } - if number == rpc.AcceptedBlockNumber { + // Treat requests for the pending, latest, or accepted block + // identically. + if number.IsAccepted() { return b.eth.AcceptedBlock().Header(), nil } + return b.eth.blockchain.GetHeaderByNumber(uint64(number)), nil } @@ -104,20 +96,12 @@ func (b *EthAPIBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*ty } func (b *EthAPIBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) { - // Pending block is only known by the miner in - // Ethereum, but Coreth does not have the same notion. - // So we treat requests for the pending block identically - // to the latest accepted block instead - if number == rpc.PendingBlockNumber { - return b.eth.AcceptedBlock(), nil - } - // Otherwise resolve and return the block - if number == rpc.LatestBlockNumber { - return b.eth.blockchain.CurrentBlock(), nil - } - if number == rpc.AcceptedBlockNumber { + // Treat requests for the pending, latest, or accepted block + // identically. + if number.IsAccepted() { return b.eth.AcceptedBlock(), nil } + return b.eth.blockchain.GetBlockByNumber(uint64(number)), nil } @@ -147,11 +131,6 @@ func (b *EthAPIBackend) BlockByNumberOrHash(ctx context.Context, blockNrOrHash r } func (b *EthAPIBackend) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error) { - // Note: Ethereum typically first checks if the request is for - // the pending block (by rpc.PendingBlockNumber), but Coreth - // does not have the same notion of the miner having a pending - // block, so this is skipped here - // Request the block by its number and retrieve its state header, err := b.HeaderByNumber(ctx, number) if err != nil { diff --git a/eth/api_tracer.go b/eth/api_tracer.go index c044dcc..23209de 100644 --- a/eth/api_tracer.go +++ b/eth/api_tracer.go @@ -105,26 +105,18 @@ func (api *PrivateDebugAPI) TraceChain(ctx context.Context, start, end rpc.Block // Fetch the block interval that we want to trace var from, to *types.Block - switch start { - case rpc.PendingBlockNumber: - from = api.eth.miner.PendingBlock() - case rpc.LatestBlockNumber: - from = api.eth.blockchain.CurrentBlock() - case rpc.AcceptedBlockNumber: + if start.IsAccepted() { from = api.eth.AcceptedBlock() - default: + } else { from = api.eth.blockchain.GetBlockByNumber(uint64(start)) } - switch end { - case rpc.PendingBlockNumber: - to = api.eth.miner.PendingBlock() - case rpc.LatestBlockNumber: - to = api.eth.blockchain.CurrentBlock() - case rpc.AcceptedBlockNumber: - from = api.eth.AcceptedBlock() - default: + + if end.IsAccepted() { + to = api.eth.AcceptedBlock() + } else { to = api.eth.blockchain.GetBlockByNumber(uint64(end)) } + // Trace the chain if we've found all our blocks if from == nil { return nil, fmt.Errorf("starting block #%d not found", start) @@ -360,16 +352,12 @@ func (api *PrivateDebugAPI) TraceBlockByNumber(ctx context.Context, number rpc.B // Fetch the block that we want to trace var block *types.Block - switch number { - case rpc.PendingBlockNumber: - block = api.eth.miner.PendingBlock() - case rpc.LatestBlockNumber: - block = api.eth.blockchain.CurrentBlock() - case rpc.AcceptedBlockNumber: + if number.IsAccepted() { block = api.eth.AcceptedBlock() - default: + } else { block = api.eth.blockchain.GetBlockByNumber(uint64(number)) } + // Trace the block if it was found if block == nil { return nil, fmt.Errorf("block #%d not found", number) diff --git a/eth/filters/api.go b/eth/filters/api.go index 71e6454..9ee96af 100644 --- a/eth/filters/api.go +++ b/eth/filters/api.go @@ -330,6 +330,8 @@ func (api *PublicFilterAPI) GetLogs(ctx context.Context, crit FilterCriteria) ([ filter = NewBlockFilter(api.backend, *crit.BlockHash, crit.Addresses, crit.Topics) } else { // Convert the RPC block numbers into internal representations + // LatestBlockNumber is left in place here to be handled + // correctly within NewRangeFilter begin := rpc.LatestBlockNumber.Int64() if crit.FromBlock != nil { begin = crit.FromBlock.Int64() @@ -385,6 +387,9 @@ func (api *PublicFilterAPI) GetFilterLogs(ctx context.Context, id rpc.ID) ([]*ty filter = NewBlockFilter(api.backend, *f.crit.BlockHash, f.crit.Addresses, f.crit.Topics) } else { // Convert the RPC block numbers into internal representations + // Leave LatestBlockNumber in place here as the defaults + // Should be handled correctly as request for the last + // accepted block instead throughout all APIs. begin := rpc.LatestBlockNumber.Int64() if f.crit.FromBlock != nil { begin = f.crit.FromBlock.Int64() diff --git a/eth/filters/filter.go b/eth/filters/filter.go index 48a76c7..3c18e6e 100644 --- a/eth/filters/filter.go +++ b/eth/filters/filter.go @@ -129,6 +129,8 @@ func (f *Filter) Logs(ctx context.Context) ([]*types.Log, error) { return f.blockLogs(ctx, header) } // Figure out the limits of the filter range + // LatestBlockNumber is handled appropriately in HeaderByNumber + // so it is left in place here. header, _ := f.backend.HeaderByNumber(ctx, rpc.LatestBlockNumber) if header == nil { return nil, nil diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 825f8fc..728fb07 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -77,20 +77,21 @@ func (s *PublicEthereumAPI) ProtocolVersion() hexutil.Uint { // - pulledStates: number of state entries processed until now // - knownStates: number of known state entries that still need to be pulled func (s *PublicEthereumAPI) Syncing() (interface{}, error) { - progress := s.b.Downloader().Progress() - - // Return not syncing if the synchronisation already completed - if progress.CurrentBlock >= progress.HighestBlock { - return false, nil - } - // Otherwise gather the block sync stats - return map[string]interface{}{ - "startingBlock": hexutil.Uint64(progress.StartingBlock), - "currentBlock": hexutil.Uint64(progress.CurrentBlock), - "highestBlock": hexutil.Uint64(progress.HighestBlock), - "pulledStates": hexutil.Uint64(progress.PulledStates), - "knownStates": hexutil.Uint64(progress.KnownStates), - }, nil + return nil, errors.New("not implemented in coreth") // Info or Health API should be used instead + // progress := s.b.Downloader().Progress() + + // // Return not syncing if the synchronisation already completed + // if progress.CurrentBlock >= progress.HighestBlock { + // return false, nil + // } + // // Otherwise gather the block sync stats + // return map[string]interface{}{ + // "startingBlock": hexutil.Uint64(progress.StartingBlock), + // "currentBlock": hexutil.Uint64(progress.CurrentBlock), + // "highestBlock": hexutil.Uint64(progress.HighestBlock), + // "pulledStates": hexutil.Uint64(progress.PulledStates), + // "knownStates": hexutil.Uint64(progress.KnownStates), + // }, nil } // PublicTxPoolAPI offers and API for the transaction pool. It only operates on data that is non confidential. @@ -546,8 +547,8 @@ func (s *PublicBlockChainAPI) BlockNumber() hexutil.Uint64 { } // GetBalance returns the amount of wei for the given address in the state of the -// given block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta -// block numbers are also allowed. +// given block number. The rpc.LatestBlockNumber, rpc.PendingBlockNumber, and +// rpc.AcceptedBlockNumber meta block numbers are also allowed. func (s *PublicBlockChainAPI) GetBalance(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Big, error) { state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) if state == nil || err != nil { @@ -556,9 +557,9 @@ func (s *PublicBlockChainAPI) GetBalance(ctx context.Context, address common.Add return (*hexutil.Big)(state.GetBalance(address)), state.Error() } -// GetBalanceMultiCoin returns the amount of wei for the given address in the state of the -// given block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta -// block numbers are also allowed. +// GetAssetBalance returns the amount of wei for the given address in the state of the +// given block number. The rpc.LatestBlockNumber, rpc.PendingBlockNumber, and +// rpc.AcceptedBlockNumber meta block numbers are also allowed. func (s *PublicBlockChainAPI) GetAssetBalance(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash, assetID ids.ID) (*hexutil.Big, error) { state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) if state == nil || err != nil { @@ -640,12 +641,13 @@ func (s *PublicBlockChainAPI) GetHeaderByNumber(ctx context.Context, number rpc. header, err := s.b.HeaderByNumber(ctx, number) if header != nil && err == nil { response := s.rpcMarshalHeader(ctx, header) - if number == rpc.PendingBlockNumber { - // Pending header need to nil out a few fields - for _, field := range []string{"hash", "nonce", "miner"} { - response[field] = nil - } - } + // coreth has no notion of a pending block + // if number == rpc.PendingBlockNumber { + // // Pending header need to nil out a few fields + // for _, field := range []string{"hash", "nonce", "miner"} { + // response[field] = nil + // } + // } return response, err } return nil, err @@ -669,12 +671,13 @@ func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, number rpc.B block, err := s.b.BlockByNumber(ctx, number) if block != nil && err == nil { response, err := s.rpcMarshalBlock(ctx, block, true, fullTx) - if err == nil && number == rpc.PendingBlockNumber { - // Pending blocks need to nil out a few fields - for _, field := range []string{"hash", "nonce", "miner"} { - response[field] = nil - } - } + // coreth has no notion of a pending block + // if err == nil && number == rpc.PendingBlockNumber { + // // Pending blocks need to nil out a few fields + // for _, field := range []string{"hash", "nonce", "miner"} { + // response[field] = nil + // } + // } return response, err } return nil, err diff --git a/plugin/evm/config.go b/plugin/evm/config.go new file mode 100644 index 0000000..4669807 --- /dev/null +++ b/plugin/evm/config.go @@ -0,0 +1,39 @@ +package evm + +// CommandLineConfig ... +type CommandLineConfig struct { + // Coreth APIs + SnowmanAPIEnabled bool `json:"snowmanAPIEnabled"` + Web3APIEnabled bool `json:"web3APIEnabled"` + CorethAdminAPIEnabled bool `json:"corethAdminAPIEnabled"` + + // Coreth API Gas/Price Caps + RPCGasCap uint64 `json:"rpcGasCap"` + RPCTxFeeCap float64 `json:"rpcTxFeeCap"` + + // Eth APIs + EthAPIEnabled bool `json:"ethAPIEnabled"` + PersonalAPIEnabled bool `json:"personalAPIEnabled"` + TxPoolAPIEnabled bool `json:"txPoolAPIEnabled"` + DebugAPIEnabled bool `json:"debugAPIEnabled"` +} + +// EthAPIs returns an array of strings representing the Eth APIs that should be enabled +func (c CommandLineConfig) EthAPIs() []string { + ethAPIs := make([]string, 0) + + if c.EthAPIEnabled { + ethAPIs = append(ethAPIs, "eth") + } + if c.PersonalAPIEnabled { + ethAPIs = append(ethAPIs, "personal") + } + if c.TxPoolAPIEnabled { + ethAPIs = append(ethAPIs, "txpool") + } + if c.DebugAPIEnabled { + ethAPIs = append(ethAPIs, "debug") + } + + return ethAPIs +} diff --git a/plugin/evm/service.go b/plugin/evm/service.go index a844f10..128b98e 100644 --- a/plugin/evm/service.go +++ b/plugin/evm/service.go @@ -5,22 +5,18 @@ package evm import ( "context" - "crypto/rand" "errors" "fmt" "math/big" "net/http" "strings" - "github.com/ava-labs/coreth" - "github.com/ava-labs/avalanchego/api" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto" "github.com/ava-labs/avalanchego/utils/formatting" "github.com/ava-labs/avalanchego/utils/json" - "github.com/ava-labs/coreth/core/types" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" ethcrypto "github.com/ethereum/go-ethereum/crypto" @@ -28,7 +24,7 @@ import ( ) const ( - version = "Athereum 1.0" + version = "coreth-v0.3.7" ) // test constants @@ -37,30 +33,12 @@ const ( GenesisTestKey = "0xabd71b35d559563fea757f0f5edbde286fb8c043105b15abb7cd57189306d7d1" ) -// DebugAPI introduces helper functions for debuging -type DebugAPI struct{ vm *VM } - // SnowmanAPI introduces snowman specific functionality to the evm type SnowmanAPI struct{ vm *VM } -// NetAPI offers network related API methods -type NetAPI struct{ vm *VM } - // AvaxAPI offers Avalanche network related API methods type AvaxAPI struct{ vm *VM } -// NewNetAPI creates a new net API instance. -func NewNetAPI(vm *VM) *NetAPI { return &NetAPI{vm} } - -// Listening returns an indication if the node is listening for network connections. -func (s *NetAPI) Listening() bool { return true } // always listening - -// PeerCount returns the number of connected peers -func (s *NetAPI) PeerCount() hexutil.Uint { return hexutil.Uint(0) } // TODO: report number of connected peers - -// Version returns the current ethereum protocol version. -func (s *NetAPI) Version() string { return fmt.Sprintf("%d", s.vm.networkID) } - // Web3API offers helper API methods type Web3API struct{} @@ -86,49 +64,8 @@ func (api *SnowmanAPI) GetAcceptedFront(ctx context.Context) (*GetAcceptedFrontR }, nil } -// GetGenesisBalance returns the current funds in the genesis -func (api *DebugAPI) GetGenesisBalance(ctx context.Context) (*hexutil.Big, error) { - lastAccepted := api.vm.getLastAccepted() - log.Trace(fmt.Sprintf("Currently accepted block front: %s", lastAccepted.ethBlock.Hash().Hex())) - state, err := api.vm.chain.BlockState(lastAccepted.ethBlock) - if err != nil { - return nil, err - } - return (*hexutil.Big)(state.GetBalance(common.HexToAddress(GenesisTestAddr))), nil -} - -// SpendGenesis funds -func (api *DebugAPI) SpendGenesis(ctx context.Context, nonce uint64) error { - log.Info("Spending the genesis") - - value := big.NewInt(1000000000000) - gasLimit := 21000 - gasPrice := big.NewInt(1000000000) - - genPrivateKey, err := ethcrypto.HexToECDSA(GenesisTestKey[2:]) - if err != nil { - return err - } - bob, err := coreth.NewKey(rand.Reader) - if err != nil { - return err - } - - tx := types.NewTransaction(nonce, bob.Address, value, uint64(gasLimit), gasPrice, nil) - signedTx, err := types.SignTx(tx, types.NewEIP155Signer(api.vm.chainID), genPrivateKey) - if err != nil { - return err - } - - if err := api.vm.issueRemoteTxs([]*types.Transaction{signedTx}); err != nil { - return err - } - - return nil -} - // IssueBlock to the chain -func (api *DebugAPI) IssueBlock(ctx context.Context) error { +func (api *SnowmanAPI) IssueBlock(ctx context.Context) error { log.Info("Issuing a new block") return api.vm.tryBlockGen() diff --git a/plugin/evm/vm.go b/plugin/evm/vm.go index f19c105..c429bca 100644 --- a/plugin/evm/vm.go +++ b/plugin/evm/vm.go @@ -154,6 +154,8 @@ func init() { type VM struct { ctx *snow.Context + CLIConfig CommandLineConfig + chainID *big.Int networkID uint64 genesisHash common.Hash @@ -259,8 +261,8 @@ func (vm *VM) Initialize( // Set minimum price for mining and default gas price oracle value to the min // gas price to prevent so transactions and blocks all use the correct fees config.Miner.GasPrice = params.MinGasPrice - config.RPCGasCap = 2500000000 // 25000000 x 100 - config.RPCTxFeeCap = 100 // 100 AVAX + config.RPCGasCap = vm.CLIConfig.RPCGasCap + config.RPCTxFeeCap = vm.CLIConfig.RPCTxFeeCap config.GPO.Default = params.MinGasPrice config.TxPool.PriceLimit = params.MinGasPrice.Uint64() config.TxPool.NoLocals = true @@ -512,12 +514,17 @@ func newHandler(name string, service interface{}, lockOption ...commonEng.LockOp // CreateHandlers makes new http handlers that can handle API calls func (vm *VM) CreateHandlers() map[string]*commonEng.HTTPHandler { handler := vm.chain.NewRPCHandler() - vm.chain.AttachEthService(handler, []string{"eth", "personal", "txpool"}) - handler.RegisterName("net", &NetAPI{vm}) - handler.RegisterName("snowman", &SnowmanAPI{vm}) - handler.RegisterName("web3", &Web3API{}) - handler.RegisterName("debug", &DebugAPI{vm}) - handler.RegisterName("admin", &admin.Performance{}) + vm.chain.AttachEthService(handler, vm.CLIConfig.EthAPIs()) + + if vm.CLIConfig.SnowmanAPIEnabled { + handler.RegisterName("snowman", &SnowmanAPI{vm}) + } + if vm.CLIConfig.Web3APIEnabled { + handler.RegisterName("web3", &Web3API{}) + } + if vm.CLIConfig.CorethAdminAPIEnabled { + handler.RegisterName("admin", &admin.Performance{}) + } return map[string]*commonEng.HTTPHandler{ "/rpc": {LockOptions: commonEng.NoLock, Handler: handler}, diff --git a/plugin/main.go b/plugin/main.go index c79a305..b42ba14 100644 --- a/plugin/main.go +++ b/plugin/main.go @@ -1,6 +1,8 @@ package main import ( + "fmt" + "github.com/hashicorp/go-plugin" "github.com/ava-labs/avalanchego/vms/rpcchainvm" @@ -9,10 +11,13 @@ import ( ) func main() { + if errs.Errored() { + panic(fmt.Sprintf("Errored while parsing Coreth CLI Config: %w", errs.Err)) + } plugin.Serve(&plugin.ServeConfig{ HandshakeConfig: rpcchainvm.Handshake, Plugins: map[string]plugin.Plugin{ - "vm": rpcchainvm.New(&evm.VM{}), + "vm": rpcchainvm.New(&evm.VM{CLIConfig: cliConfig}), }, // A non-nil value here enables gRPC serving for this plugin... diff --git a/plugin/params.go b/plugin/params.go new file mode 100644 index 0000000..1810295 --- /dev/null +++ b/plugin/params.go @@ -0,0 +1,41 @@ +package main + +import ( + "encoding/json" + "flag" + "os" + + "github.com/ava-labs/avalanchego/utils/wrappers" + "github.com/ava-labs/coreth/plugin/evm" +) + +const ( + name = "coreth" +) + +var ( + cliConfig evm.CommandLineConfig + errs wrappers.Errs +) + +func init() { + errs := wrappers.Errs{} + fs := flag.NewFlagSet(name, flag.ContinueOnError) + + config := fs.String("coreth-config", "default", "Pass in CLI Config to set runtime attributes for Coreth") + + if err := fs.Parse(os.Args[1:]); err != nil { + errs.Add(err) + return + } + + if *config == "default" { + cliConfig.EthAPIEnabled = true + cliConfig.TxPoolAPIEnabled = true + cliConfig.RPCGasCap = 2500000000 // 25000000 x 100 + cliConfig.RPCTxFeeCap = 100 // 100 AVAX + } else { + // TODO only overwrite values that were explicitly set + errs.Add(json.Unmarshal([]byte(*config), &cliConfig)) + } +} diff --git a/rpc/types.go b/rpc/types.go index 99e29fc..4e62a53 100644 --- a/rpc/types.go +++ b/rpc/types.go @@ -92,7 +92,7 @@ func (bn *BlockNumber) UnmarshalJSON(data []byte) error { *bn = EarliestBlockNumber return nil case "latest": - *bn = AcceptedBlockNumber + *bn = LatestBlockNumber return nil case "pending": *bn = PendingBlockNumber @@ -117,6 +117,11 @@ func (bn BlockNumber) Int64() int64 { return (int64)(bn) } +// IsAccepted returns true if this blockNumber should be treated as a request for the last accepted block +func (bn BlockNumber) IsAccepted() bool { + return bn < EarliestBlockNumber && bn >= AcceptedBlockNumber +} + type BlockNumberOrHash struct { BlockNumber *BlockNumber `json:"blockNumber,omitempty"` BlockHash *common.Hash `json:"blockHash,omitempty"` @@ -147,7 +152,7 @@ func (bnh *BlockNumberOrHash) UnmarshalJSON(data []byte) error { bnh.BlockNumber = &bn return nil case "latest": - bn := AcceptedBlockNumber + bn := LatestBlockNumber bnh.BlockNumber = &bn return nil case "pending": |