Merge remote-tracking branch 'harmony/main' into traceDB

pull/3799/head
peekpi 3 years ago
commit acc5a8a749
  1. 2
      block/interface/header.go
  2. 7
      consensus/validator.go
  3. 6
      node/node.go
  4. 143
      rpc/blockchain.go
  5. 2
      rpc/metrics.go

@ -223,7 +223,7 @@ type Header interface {
Logger(logger *zerolog.Logger) *zerolog.Logger
// GetShardState returns the deserialized shard state object.
// Note that header encoded shard state only exists in the first block of the epoch
// Note that header encoded shard state only exists in the last block of the previous epoch
GetShardState() (shard.State, error)
// Copy returns a copy of the header.

@ -84,7 +84,7 @@ func (consensus *Consensus) validateNewBlock(recvMsg *FBFTMessage) (*types.Block
blockObj = consensus.FBFTLog.GetBlockByHash(recvMsg.BlockHash)
if blockObj == nil {
if err := rlp.DecodeBytes(recvMsg.Block, &blockObj); err != nil {
if err := rlp.DecodeBytes(recvMsg.Block, blockObj); err != nil {
consensus.getLogger().Warn().
Err(err).
Uint64("MsgBlockNum", recvMsg.BlockNum).
@ -157,7 +157,7 @@ func (consensus *Consensus) prepare() {
// sendCommitMessages send out commit messages to leader
func (consensus *Consensus) sendCommitMessages(blockObj *types.Block) {
if consensus.IsBackup() {
if consensus.IsBackup() || blockObj == nil {
return
}
@ -269,6 +269,9 @@ func (consensus *Consensus) onPrepared(recvMsg *FBFTMessage) {
go func() {
// Try process future committed messages and process them in case of receiving committed before prepared
if blockObj == nil {
return
}
curBlockNum := consensus.blockNum
for _, committedMsg := range consensus.FBFTLog.GetNotVerifiedCommittedMessages(blockObj.NumberU64(), blockObj.Header().ViewID().Uint64(), blockObj.Hash()) {
if committedMsg != nil {

@ -195,6 +195,12 @@ func (node *Node) tryBroadcastStaking(stakingTx *staking.StakingTransaction) {
// Add new transactions to the pending transaction list.
func (node *Node) addPendingTransactions(newTxs types.Transactions) []error {
if inSync, _, _ := node.SyncStatus(node.Blockchain().ShardID()); !inSync && node.NodeConfig.GetNetworkType() == nodeconfig.Mainnet {
utils.Logger().Debug().
Int("length of newTxs", len(newTxs)).
Msg("[addPendingTransactions] Node out of sync, ignoring transactions")
return nil
}
poolTxs := types.PoolTransactions{}
errs := []error{}
acceptCx := node.Blockchain().Config().AcceptsCrossTx(node.Blockchain().CurrentHeader().Epoch())

@ -6,8 +6,12 @@ import (
"math/big"
"time"
"encoding/hex"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc"
lru "github.com/hashicorp/golang-lru"
"github.com/pkg/errors"
@ -663,6 +667,145 @@ func (s *PublicBlockchainService) GetHeaderByNumber(
return nil, err
}
// Result structs for GetProof
type AccountResult struct {
Address common.Address `json:"address"`
AccountProof []string `json:"accountProof"`
Balance *hexutil.Big `json:"balance"`
CodeHash common.Hash `json:"codeHash"`
Nonce hexutil.Uint64 `json:"nonce"`
StorageHash common.Hash `json:"storageHash"`
StorageProof []StorageResult `json:"storageProof"`
}
type StorageResult struct {
Key string `json:"key"`
Value *hexutil.Big `json:"value"`
Proof []string `json:"proof"`
}
// GetHeaderByNumberRLPHex returns block header at given number by `hex(rlp(header))`
func (s *PublicBlockchainService) GetProof(
ctx context.Context, address common.Address, storageKeys []string, blockNumber BlockNumber) (ret *AccountResult, err error) {
timer := DoMetricRPCRequest(GetProof)
defer DoRPCRequestDuration(GetProof, timer)
defer func() {
if ret == nil || err != nil {
DoMetricRPCQueryInfo(GetProof, FailedNumber)
}
}()
err = s.wait(ctx)
if err != nil {
return
}
// Process number based on version
blockNum := blockNumber.EthBlockNumber()
// Ensure valid block number
if s.version != Eth && isBlockGreaterThanLatest(s.hmy, blockNum) {
err = ErrRequestedBlockTooHigh
return
}
// Fetch Header
header, err := s.hmy.HeaderByNumber(ctx, blockNum)
if header == nil && err != nil {
return
}
state, err := s.hmy.BeaconChain.StateAt(header.Root())
if state == nil || err != nil {
return
}
storageTrie := state.StorageTrie(address)
storageHash := types.EmptyRootHash
codeHash := state.GetCodeHash(address)
storageProof := make([]StorageResult, len(storageKeys))
// if we have a storageTrie, (which means the account exists), we can update the storagehash
if storageTrie != nil {
storageHash = storageTrie.Hash()
} else {
// no storageTrie means the account does not exist, so the codeHash is the hash of an empty bytearray.
codeHash = crypto.Keccak256Hash(nil)
}
// create the proof for the storageKeys
for i, key := range storageKeys {
if storageTrie != nil {
proof, storageError := state.GetStorageProof(address, common.HexToHash(key))
if storageError != nil {
err = storageError
return
}
storageProof[i] = StorageResult{key, (*hexutil.Big)(state.GetState(address, common.HexToHash(key)).Big()), toHexSlice(proof)}
} else {
storageProof[i] = StorageResult{key, &hexutil.Big{}, []string{}}
}
}
// create the accountProof
accountProof, err := state.GetProof(address)
if err != nil {
return
}
ret, err = &AccountResult{
Address: address,
AccountProof: toHexSlice(accountProof),
Balance: (*hexutil.Big)(state.GetBalance(address)),
CodeHash: codeHash,
Nonce: hexutil.Uint64(state.GetNonce(address)),
StorageHash: storageHash,
StorageProof: storageProof,
}, state.Error()
return
}
// toHexSlice creates a slice of hex-strings based on []byte.
func toHexSlice(b [][]byte) []string {
r := make([]string, len(b))
for i := range b {
r[i] = hexutil.Encode(b[i])
}
return r
}
// GetHeaderByNumberRLPHex returns block header at given number by `hex(rlp(header))`
func (s *PublicBlockchainService) GetHeaderByNumberRLPHex(
ctx context.Context, blockNumber BlockNumber,
) (string, error) {
timer := DoMetricRPCRequest(GetHeaderByNumberRLPHex)
defer DoRPCRequestDuration(GetHeaderByNumberRLPHex, timer)
err := s.wait(ctx)
if err != nil {
DoMetricRPCQueryInfo(GetHeaderByNumberRLPHex, FailedNumber)
return "", err
}
// Process number based on version
blockNum := blockNumber.EthBlockNumber()
// Ensure valid block number
if s.version != Eth && isBlockGreaterThanLatest(s.hmy, blockNum) {
DoMetricRPCQueryInfo(GetHeaderByNumberRLPHex, FailedNumber)
return "", ErrRequestedBlockTooHigh
}
// Fetch Header
header, err := s.hmy.HeaderByNumber(ctx, blockNum)
if header != nil && err == nil {
// Response output is the same for all versions
val, _ := rlp.EncodeToBytes(header)
return hex.EncodeToString(val), nil
}
return "", err
}
// GetCurrentUtilityMetrics ..
func (s *PublicBlockchainService) GetCurrentUtilityMetrics(
ctx context.Context,

@ -19,6 +19,8 @@ const (
GetLatestChainHeaders = "GetLatestChainHeaders"
GetLastCrossLinks = "GetLastCrossLinks"
GetHeaderByNumber = "GetHeaderByNumber"
GetHeaderByNumberRLPHex = "GetHeaderByNumberRLPHex"
GetProof = "GetProof"
GetCurrentUtilityMetrics = "GetCurrentUtilityMetrics"
GetSuperCommittees = "GetSuperCommittees"
GetCurrentBadBlocks = "GetCurrentBadBlocks"

Loading…
Cancel
Save