Don't throw ErrRequestedBlockTooHigh for Ethereum RPC:s

pull/3543/head
Sebastian Johnsson 4 years ago
parent 0512846a8b
commit fe20992664
  1. 131
      rpc/blockchain.go

@ -137,51 +137,56 @@ func (s *PublicBlockchainService) GetBlockByNumber(
} }
blockArgs.InclTx = true blockArgs.InclTx = true
// Fetch the block // Some Ethereum tools (such as Truffle) rely on being able to query for future blocks without the chain returning errors.
if isBlockGreaterThanLatest(s.hmy, blockNum) { // These tools implement retry mechanisms that will query & retry for a given block until it has been finalized.
// Throwing an error like "requested block number greater than current block number" breaks this retry functionality.
// Disable isBlockGreaterThanLatest checks for Ethereum RPC:s, but keep them in place for legacy hmy_ RPC:s for now to ensure backwards compatibility
if s.version != Eth && isBlockGreaterThanLatest(s.hmy, blockNum) {
return nil, ErrRequestedBlockTooHigh return nil, ErrRequestedBlockTooHigh
} }
blk, err := s.hmy.BlockByNumber(ctx, blockNum) blk, err := s.hmy.BlockByNumber(ctx, blockNum)
if err != nil { if blk != nil && err == nil {
return nil, err if blockArgs.WithSigners {
} blockArgs.Signers, err = s.GetBlockSigners(ctx, blockNumber)
if blockArgs.WithSigners { if err != nil {
blockArgs.Signers, err = s.GetBlockSigners(ctx, blockNumber) return nil, err
}
}
// Format the response according to version
leader := s.hmy.GetLeaderAddress(blk.Header().Coinbase(), blk.Header().Epoch())
var rpcBlock interface{}
switch s.version {
case V1:
rpcBlock, err = v1.NewBlock(blk, blockArgs, leader)
case V2:
rpcBlock, err = v2.NewBlock(blk, blockArgs, leader)
case Eth:
rpcBlock, err = eth.NewBlock(blk, blockArgs, leader)
default:
return nil, ErrUnknownRPCVersion
}
if err != nil { if err != nil {
return nil, err return nil, err
} }
}
// Format the response according to version response, err = NewStructuredResponse(rpcBlock)
leader := s.hmy.GetLeaderAddress(blk.Header().Coinbase(), blk.Header().Epoch()) if err != nil {
var rpcBlock interface{} return nil, err
switch s.version { }
case V1:
rpcBlock, err = v1.NewBlock(blk, blockArgs, leader)
case V2:
rpcBlock, err = v2.NewBlock(blk, blockArgs, leader)
case Eth:
rpcBlock, err = eth.NewBlock(blk, blockArgs, leader)
default:
return nil, ErrUnknownRPCVersion
}
if err != nil {
return nil, err
}
response, err = NewStructuredResponse(rpcBlock)
if err != nil {
return nil, err
}
// Pending blocks need to nil out a few fields // Pending blocks need to nil out a few fields
if blockNum == rpc.PendingBlockNumber { if blockNum == rpc.PendingBlockNumber {
for _, field := range []string{"hash", "nonce", "miner"} { for _, field := range []string{"hash", "nonce", "miner"} {
response[field] = nil response[field] = nil
}
} }
return response, err
} }
return response, err return nil, err
} }
// GetBlockByHash returns the requested block. When fullTx is true all transactions in the block are returned in full // GetBlockByHash returns the requested block. When fullTx is true all transactions in the block are returned in full
@ -203,33 +208,34 @@ func (s *PublicBlockchainService) GetBlockByHash(
// Fetch the block // Fetch the block
blk, err := s.hmy.GetBlock(ctx, blockHash) blk, err := s.hmy.GetBlock(ctx, blockHash)
if err != nil { if blk != nil && err == nil {
return nil, err if blockArgs.WithSigners {
} blockArgs.Signers, err = s.GetBlockSigners(ctx, BlockNumber(blk.NumberU64()))
if blockArgs.WithSigners { if err != nil {
blockArgs.Signers, err = s.GetBlockSigners(ctx, BlockNumber(blk.NumberU64())) return nil, err
}
}
// Format the response according to version
leader := s.hmy.GetLeaderAddress(blk.Header().Coinbase(), blk.Header().Epoch())
var rpcBlock interface{}
switch s.version {
case V1:
rpcBlock, err = v1.NewBlock(blk, blockArgs, leader)
case V2:
rpcBlock, err = v2.NewBlock(blk, blockArgs, leader)
case Eth:
rpcBlock, err = eth.NewBlock(blk, blockArgs, leader)
default:
return nil, ErrUnknownRPCVersion
}
if err != nil { if err != nil {
return nil, err return nil, err
} }
return NewStructuredResponse(rpcBlock)
} }
// Format the response according to version return nil, err
leader := s.hmy.GetLeaderAddress(blk.Header().Coinbase(), blk.Header().Epoch())
var rpcBlock interface{}
switch s.version {
case V1:
rpcBlock, err = v1.NewBlock(blk, blockArgs, leader)
case V2:
rpcBlock, err = v2.NewBlock(blk, blockArgs, leader)
case Eth:
rpcBlock, err = eth.NewBlock(blk, blockArgs, leader)
default:
return nil, ErrUnknownRPCVersion
}
if err != nil {
return nil, err
}
return NewStructuredResponse(rpcBlock)
} }
// GetBlockByNumberNew is an alias for GetBlockByNumber using rpc_common.BlockArgs // GetBlockByNumberNew is an alias for GetBlockByNumber using rpc_common.BlockArgs
@ -556,19 +562,18 @@ func (s *PublicBlockchainService) GetHeaderByNumber(
blockNum := blockNumber.EthBlockNumber() blockNum := blockNumber.EthBlockNumber()
// Ensure valid block number // Ensure valid block number
if isBlockGreaterThanLatest(s.hmy, blockNum) { if s.version != Eth && isBlockGreaterThanLatest(s.hmy, blockNum) {
return nil, ErrRequestedBlockTooHigh return nil, ErrRequestedBlockTooHigh
} }
// Fetch Header // Fetch Header
header, err := s.hmy.HeaderByNumber(ctx, blockNum) header, err := s.hmy.HeaderByNumber(ctx, blockNum)
if err != nil { if header != nil && err == nil {
return nil, err // Response output is the same for all versions
leader := s.hmy.GetLeaderAddress(header.Coinbase(), header.Epoch())
return NewStructuredResponse(NewHeaderInformation(header, leader))
} }
return nil, err
// Response output is the same for all versions
leader := s.hmy.GetLeaderAddress(header.Coinbase(), header.Epoch())
return NewStructuredResponse(NewHeaderInformation(header, leader))
} }
// GetCurrentUtilityMetrics .. // GetCurrentUtilityMetrics ..

Loading…
Cancel
Save