mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-17 09:23:48 +00:00
api: Fetch pending state from txpool
This commit changes the source of the state when asking for the *pending* state. Instead of consulting the miner of the node, it uses teh pending state of the transaction pool. Two reasons for this change: 1. Introduction of the consensus package + BFT algorithms With the introduction of the consensus package and the potential BFT algorithms being built with it, the concept of the "pending block/state" changes its definition. In some of these algorithms, pending block can mean a block that is in the process of validation, but that can no longer be updated. This conflicts with the traditional meaning of "pending state", being the latest block plus all known pending transactions. Most notably, the Istanbul implementation has this problem. This also results in the values for the pending state being different for a node that has the miner enabled and the miner disabled. 2. General principle that the miner package should be disabled for non-mining nodes So considering the previous point, the use of the miner package for something else than mining should be evaluated. I think it makes sense to try working towards not using it at all when a node does not participate in the mining/validating process. Currently, the miner's pending state is used (a.o.) for executing new incoming transactions (because the EVM needs a "current block" for the global getters). I think this should be fairly easy to work around and this is a first step.
This commit is contained in:
parent
302c17c36a
commit
cff5803b27
6 changed files with 33 additions and 18 deletions
|
|
@ -1348,6 +1348,11 @@ func (bc *BlockChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []com
|
|||
return bc.hc.GetBlockHashesFromHash(hash, max)
|
||||
}
|
||||
|
||||
// GetBlockHashByNumber retrieves the block hash from the database by number.
|
||||
func (bc *BlockChain) GetBlockHashByNumber(number uint64) common.Hash {
|
||||
return bc.hc.GetBlockHashByNumber(number)
|
||||
}
|
||||
|
||||
// GetHeaderByNumber retrieves a block header from the database by number,
|
||||
// caching it (associated with its hash) if found.
|
||||
func (bc *BlockChain) GetHeaderByNumber(number uint64) *types.Header {
|
||||
|
|
|
|||
|
|
@ -370,10 +370,15 @@ func (hc *HeaderChain) HasHeader(hash common.Hash, number uint64) bool {
|
|||
return ok
|
||||
}
|
||||
|
||||
// GetBlockHashByNumber retrieves the block hash from the database by number.
|
||||
func (hc *HeaderChain) GetBlockHashByNumber(number uint64) common.Hash {
|
||||
return GetCanonicalHash(hc.chainDb, number)
|
||||
}
|
||||
|
||||
// GetHeaderByNumber retrieves a block header from the database by number,
|
||||
// caching it (associated with its hash) if found.
|
||||
func (hc *HeaderChain) GetHeaderByNumber(number uint64) *types.Header {
|
||||
hash := GetCanonicalHash(hc.chainDb, number)
|
||||
hash := hc.GetBlockHashByNumber(number)
|
||||
if hash == (common.Hash{}) {
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,19 +81,19 @@ func (b *EthApiBackend) BlockByNumber(ctx context.Context, blockNr rpc.BlockNumb
|
|||
return b.eth.blockchain.GetBlockByNumber(uint64(blockNr)), nil
|
||||
}
|
||||
|
||||
func (b *EthApiBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.StateDB, *types.Header, error) {
|
||||
func (b *EthApiBackend) StateByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.StateDB, error) {
|
||||
// Pending state is only known by the miner
|
||||
if blockNr == rpc.PendingBlockNumber {
|
||||
block, state := b.eth.miner.Pending()
|
||||
return state, block.Header(), nil
|
||||
return b.eth.TxPool().State().StateDB, nil
|
||||
}
|
||||
|
||||
// Otherwise resolve the block number and return its state
|
||||
header, err := b.HeaderByNumber(ctx, blockNr)
|
||||
if header == nil || err != nil {
|
||||
return nil, nil, err
|
||||
if blockNr == rpc.LatestBlockNumber {
|
||||
return b.eth.BlockChain().State()
|
||||
}
|
||||
stateDb, err := b.eth.BlockChain().StateAt(header.Root)
|
||||
return stateDb, header, err
|
||||
|
||||
blockHash := b.eth.BlockChain().GetBlockHashByNumber(uint64(blockNr))
|
||||
return b.eth.BlockChain().StateAt(blockHash)
|
||||
}
|
||||
|
||||
func (b *EthApiBackend) GetBlock(ctx context.Context, blockHash common.Hash) (*types.Block, error) {
|
||||
|
|
|
|||
|
|
@ -463,7 +463,7 @@ func (s *PublicBlockChainAPI) BlockNumber() *big.Int {
|
|||
// given block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta
|
||||
// block numbers are also allowed.
|
||||
func (s *PublicBlockChainAPI) GetBalance(ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (*big.Int, error) {
|
||||
state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr)
|
||||
state, err := s.b.StateByNumber(ctx, blockNr)
|
||||
if state == nil || err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -550,7 +550,7 @@ func (s *PublicBlockChainAPI) GetUncleCountByBlockHash(ctx context.Context, bloc
|
|||
|
||||
// GetCode returns the code stored at the given address in the state for the given block number.
|
||||
func (s *PublicBlockChainAPI) GetCode(ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (hexutil.Bytes, error) {
|
||||
state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr)
|
||||
state, err := s.b.StateByNumber(ctx, blockNr)
|
||||
if state == nil || err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -562,7 +562,7 @@ func (s *PublicBlockChainAPI) GetCode(ctx context.Context, address common.Addres
|
|||
// block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta block
|
||||
// numbers are also allowed.
|
||||
func (s *PublicBlockChainAPI) GetStorageAt(ctx context.Context, address common.Address, key string, blockNr rpc.BlockNumber) (hexutil.Bytes, error) {
|
||||
state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr)
|
||||
state, err := s.b.StateByNumber(ctx, blockNr)
|
||||
if state == nil || err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -583,10 +583,15 @@ type CallArgs struct {
|
|||
func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr rpc.BlockNumber, vmCfg vm.Config) ([]byte, uint64, bool, error) {
|
||||
defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now())
|
||||
|
||||
state, header, err := s.b.StateAndHeaderByNumber(ctx, blockNr)
|
||||
state, err := s.b.StateByNumber(ctx, blockNr)
|
||||
if state == nil || err != nil {
|
||||
return nil, 0, false, err
|
||||
}
|
||||
header, err := s.b.HeaderByNumber(ctx, blockNr)
|
||||
if header == nil || err != nil {
|
||||
return nil, 0, false, err
|
||||
}
|
||||
|
||||
// Set sender address or use a default if none specified
|
||||
addr := args.From
|
||||
if addr == (common.Address{}) {
|
||||
|
|
@ -963,7 +968,7 @@ func (s *PublicTransactionPoolAPI) GetRawTransactionByBlockHashAndIndex(ctx cont
|
|||
|
||||
// GetTransactionCount returns the number of transactions the given address has sent for the given block number
|
||||
func (s *PublicTransactionPoolAPI) GetTransactionCount(ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (*hexutil.Uint64, error) {
|
||||
state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr)
|
||||
state, err := s.b.StateByNumber(ctx, blockNr)
|
||||
if state == nil || err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ type Backend interface {
|
|||
SetHead(number uint64)
|
||||
HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error)
|
||||
BlockByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Block, error)
|
||||
StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.StateDB, *types.Header, error)
|
||||
StateByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.StateDB, error)
|
||||
GetBlock(ctx context.Context, blockHash common.Hash) (*types.Block, error)
|
||||
GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error)
|
||||
GetTd(blockHash common.Hash) *big.Int
|
||||
|
|
|
|||
|
|
@ -71,12 +71,12 @@ func (b *LesApiBackend) BlockByNumber(ctx context.Context, blockNr rpc.BlockNumb
|
|||
return b.GetBlock(ctx, header.Hash())
|
||||
}
|
||||
|
||||
func (b *LesApiBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.StateDB, *types.Header, error) {
|
||||
func (b *LesApiBackend) StateByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.StateDB, error) {
|
||||
header, err := b.HeaderByNumber(ctx, blockNr)
|
||||
if header == nil || err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
return light.NewState(ctx, header, b.eth.odr), header, nil
|
||||
return light.NewState(ctx, header, b.eth.odr), nil
|
||||
}
|
||||
|
||||
func (b *LesApiBackend) GetBlock(ctx context.Context, blockHash common.Hash) (*types.Block, error) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue