mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-16 01:40:44 +00:00
create new func penalties for hard fork
This commit is contained in:
parent
a479343cc7
commit
147e1f0baf
7 changed files with 95 additions and 264 deletions
|
|
@ -1,5 +1,7 @@
|
||||||
package common
|
package common
|
||||||
|
|
||||||
|
import "math/big"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
RewardMasterPercent = 40
|
RewardMasterPercent = 40
|
||||||
RewardVoterPercent = 50
|
RewardVoterPercent = 50
|
||||||
|
|
@ -14,7 +16,15 @@ const (
|
||||||
LimitPenaltyEpoch = 4
|
LimitPenaltyEpoch = 4
|
||||||
BlocksPerYear = uint64(15768000)
|
BlocksPerYear = uint64(15768000)
|
||||||
LimitThresholdNonceInQueue = 10
|
LimitThresholdNonceInQueue = 10
|
||||||
MinGasPrice = 2500
|
DefaultMinGasPrice = 2500
|
||||||
|
MergeSignRange = 15
|
||||||
|
RangeReturnSigner = 150
|
||||||
|
MinimunMinerBlockPerEpoch = 1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var TIP2019Block = big.NewInt(1050000)
|
||||||
|
var TIPSigning = big.NewInt(3000000)
|
||||||
var IsTestnet bool = false
|
var IsTestnet bool = false
|
||||||
|
var StoreRewardFolder string
|
||||||
|
var RollbackHash Hash
|
||||||
|
var MinGasPrice int64
|
||||||
|
|
@ -42,6 +42,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
"github.com/hashicorp/golang-lru"
|
"github.com/hashicorp/golang-lru"
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -209,7 +210,7 @@ func ecrecover(header *types.Header, sigcache *lru.ARCCache) (common.Address, er
|
||||||
// Ethereum testnet following the Ropsten attacks.
|
// Ethereum testnet following the Ropsten attacks.
|
||||||
type XDPoS struct {
|
type XDPoS struct {
|
||||||
config *params.XDPoSConfig // Consensus engine configuration parameters
|
config *params.XDPoSConfig // Consensus engine configuration parameters
|
||||||
db ethdb.Database // Database to store and retrieve snapshot checkpoints
|
db ethdb.Database // Database to store and retrieve snapshot checkpoints
|
||||||
|
|
||||||
recents *lru.ARCCache // Snapshots for recent block to speed up reorgs
|
recents *lru.ARCCache // Snapshots for recent block to speed up reorgs
|
||||||
signatures *lru.ARCCache // Signatures of recent blocks to speed up mining
|
signatures *lru.ARCCache // Signatures of recent blocks to speed up mining
|
||||||
|
|
@ -922,7 +923,7 @@ func (c *XDPoS) Seal(chain consensus.ChainReader, block *types.Block, stop <-cha
|
||||||
if limit := uint64(2); number < limit || seen > number-limit {
|
if limit := uint64(2); number < limit || seen > number-limit {
|
||||||
// Only take into account the non-epoch blocks
|
// Only take into account the non-epoch blocks
|
||||||
if number%c.config.Epoch != 0 {
|
if number%c.config.Epoch != 0 {
|
||||||
log.Info("len(masternodes)", len(masternodes), "number", number, "limit", limit, "seen", seen, "recent", recent.String(), "snap.Recents", snap.Recents)
|
log.Info("Length of MasterNodes", "len(masternodes)", len(masternodes), "number", number, "limit", limit, "seen", seen, "recent", recent.String(), "snap.Recents", snap.Recents)
|
||||||
log.Info("Signed recently, must wait for others")
|
log.Info("Signed recently, must wait for others")
|
||||||
<-stop
|
<-stop
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
|
|
||||||
|
|
@ -374,7 +374,7 @@ func CalculateRewardForSigner(chainReward *big.Int, signers map[common.Address]*
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get candidate owner by address.
|
// Get candidate owner by address.
|
||||||
func GetCandidatesOwnerBySigner(validator *contractValidator.Kyc, signerAddr common.Address) common.Address {
|
func GetCandidatesOwnerBySigner(validator *contractValidator.XDCValidator, signerAddr common.Address) common.Address {
|
||||||
owner := signerAddr
|
owner := signerAddr
|
||||||
opts := new(bind.CallOpts)
|
opts := new(bind.CallOpts)
|
||||||
owner, err := validator.GetCandidateOwner(opts, signerAddr)
|
owner, err := validator.GetCandidateOwner(opts, signerAddr)
|
||||||
|
|
@ -387,7 +387,7 @@ func GetCandidatesOwnerBySigner(validator *contractValidator.Kyc, signerAddr com
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate reward for holders.
|
// Calculate reward for holders.
|
||||||
func CalculateRewardForHolders(foudationWalletAddr common.Address, validator *contractValidator.Kyc, state *state.StateDB, signer common.Address, calcReward *big.Int) (error, map[common.Address]*big.Int) {
|
func CalculateRewardForHolders(foudationWalletAddr common.Address, validator *contractValidator.XDCValidator, state *state.StateDB, signer common.Address, calcReward *big.Int) (error, map[common.Address]*big.Int) {
|
||||||
rewards, err := GetRewardBalancesRate(foudationWalletAddr, signer, calcReward, validator)
|
rewards, err := GetRewardBalancesRate(foudationWalletAddr, signer, calcReward, validator)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err, nil
|
return err, nil
|
||||||
|
|
@ -401,7 +401,7 @@ func CalculateRewardForHolders(foudationWalletAddr common.Address, validator *co
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get reward balance rates for master node, founder and holders.
|
// Get reward balance rates for master node, founder and holders.
|
||||||
func GetRewardBalancesRate(foudationWalletAddr common.Address, masterAddr common.Address, totalReward *big.Int, validator *contractValidator.Kyc) (map[common.Address]*big.Int, error) {
|
func GetRewardBalancesRate(foudationWalletAddr common.Address, masterAddr common.Address, totalReward *big.Int, validator *contractValidator.XDCValidator) (map[common.Address]*big.Int, error) {
|
||||||
owner := GetCandidatesOwnerBySigner(validator, masterAddr)
|
owner := GetCandidatesOwnerBySigner(validator, masterAddr)
|
||||||
balances := make(map[common.Address]*big.Int)
|
balances := make(map[common.Address]*big.Int)
|
||||||
rewardMaster := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(common.RewardMasterPercent))
|
rewardMaster := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(common.RewardMasterPercent))
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/trie"
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
lru "github.com/hashicorp/golang-lru"
|
"github.com/hashicorp/golang-lru"
|
||||||
"gopkg.in/karalabe/cookiejar.v2/collections/prque"
|
"gopkg.in/karalabe/cookiejar.v2/collections/prque"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -1833,7 +1833,7 @@ func (bc *BlockChain) UpdateM1() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
addr := common.HexToAddress(common.MasternodeVotingSMC)
|
addr := common.HexToAddress(common.MasternodeVotingSMC)
|
||||||
validator, err := contractValidator.NewKyc(addr, client)
|
validator, err := contractValidator.NewXDCValidator(addr, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,13 +30,12 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"bytes"
|
"bytes"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
"github.com/ethereum/go-ethereum/consensus"
|
"github.com/ethereum/go-ethereum/consensus"
|
||||||
"github.com/ethereum/go-ethereum/consensus/XDPoS"
|
|
||||||
"github.com/ethereum/go-ethereum/consensus/ethash"
|
"github.com/ethereum/go-ethereum/consensus/ethash"
|
||||||
|
"github.com/ethereum/go-ethereum/consensus/XDPoS"
|
||||||
"github.com/ethereum/go-ethereum/contracts"
|
"github.com/ethereum/go-ethereum/contracts"
|
||||||
"github.com/ethereum/go-ethereum/contracts/validator/contract"
|
"github.com/ethereum/go-ethereum/contracts/validator/contract"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
|
|
@ -324,7 +323,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
|
||||||
return err, nil
|
return err, nil
|
||||||
}
|
}
|
||||||
// Get validator.
|
// Get validator.
|
||||||
validator, err := contract.NewKyc(common.HexToAddress(common.MasternodeVotingSMC), client)
|
validator, err := contract.NewXDCValidator(common.HexToAddress(common.MasternodeVotingSMC), client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fail get instance of XDC Validator", "error", err)
|
log.Error("Fail get instance of XDC Validator", "error", err)
|
||||||
return err, nil
|
return err, nil
|
||||||
|
|
|
||||||
|
|
@ -44,17 +44,10 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
"github.com/syndtr/goleveldb/leveldb"
|
"github.com/syndtr/goleveldb/leveldb"
|
||||||
"github.com/syndtr/goleveldb/leveldb/util"
|
"github.com/syndtr/goleveldb/leveldb/util"
|
||||||
contractValidator "github.com/ethereum/go-ethereum/contracts/validator/contract"
|
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
defaultGasPrice = 50 * params.Shannon
|
defaultGasPrice = 50 * params.Shannon
|
||||||
// statuses of candidates
|
|
||||||
statusMasternode = "MASTERNODE"
|
|
||||||
statusSlashed = "SLASHED"
|
|
||||||
statusProposed = "PROPOSED"
|
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// PublicEthereumAPI provides an API to access Ethereum related information.
|
// PublicEthereumAPI provides an API to access Ethereum related information.
|
||||||
|
|
@ -501,7 +494,13 @@ func (s *PublicBlockChainAPI) BlockNumber() *big.Int {
|
||||||
|
|
||||||
// BlockNumber returns the block number of the chain head.
|
// BlockNumber returns the block number of the chain head.
|
||||||
func (s *PublicBlockChainAPI) GetRewardByHash(hash common.Hash) map[string]interface{} {
|
func (s *PublicBlockChainAPI) GetRewardByHash(hash common.Hash) map[string]interface{} {
|
||||||
return s.b.GetRewardByHash(hash)
|
if c, ok := s.b.GetEngine().(*XDPoS.XDPoS); ok {
|
||||||
|
rewards := c.GetRewards(hash)
|
||||||
|
if rewards != nil {
|
||||||
|
return rewards
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return make(map[string]interface{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBalance returns the amount of wei for the given address in the state of the
|
// GetBalance returns the amount of wei for the given address in the state of the
|
||||||
|
|
@ -615,175 +614,6 @@ func (s *PublicBlockChainAPI) GetStorageAt(ctx context.Context, address common.A
|
||||||
return res[:], state.Error()
|
return res[:], state.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *PublicBlockChainAPI) GetBlockSignersByHash(ctx context.Context, blockHash common.Hash) ([]common.Address, error) {
|
|
||||||
block, err := s.b.GetBlock(ctx, blockHash)
|
|
||||||
if err != nil || block == nil {
|
|
||||||
return []common.Address{}, err
|
|
||||||
}
|
|
||||||
masternodes, err := s.GetMasternodes(ctx, block)
|
|
||||||
if err != nil || len(masternodes) == 0 {
|
|
||||||
log.Error("Failed to get masternodes", "err", err, "len(masternodes)", len(masternodes))
|
|
||||||
return []common.Address{}, err
|
|
||||||
}
|
|
||||||
return s.rpcOutputBlockSigners(block, ctx, masternodes)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *PublicBlockChainAPI) GetBlockSignersByNumber(ctx context.Context, blockNumber rpc.BlockNumber) ([]common.Address, error) {
|
|
||||||
block, err := s.b.BlockByNumber(ctx, blockNumber)
|
|
||||||
if err != nil || block == nil {
|
|
||||||
return []common.Address{}, err
|
|
||||||
}
|
|
||||||
masternodes, err := s.GetMasternodes(ctx, block)
|
|
||||||
if err != nil || len(masternodes) == 0 {
|
|
||||||
log.Error("Failed to get masternodes", "err", err, "len(masternodes)", len(masternodes))
|
|
||||||
return []common.Address{}, err
|
|
||||||
}
|
|
||||||
return s.rpcOutputBlockSigners(block, ctx, masternodes)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *PublicBlockChainAPI) GetBlockFinalityByHash(ctx context.Context, blockHash common.Hash) (int32, error) {
|
|
||||||
block, err := s.b.GetBlock(ctx, blockHash)
|
|
||||||
if err != nil || block == nil {
|
|
||||||
return int32(0), err
|
|
||||||
}
|
|
||||||
masternodes, err := s.GetMasternodes(ctx, block)
|
|
||||||
if err != nil || len(masternodes) == 0 {
|
|
||||||
log.Error("Failed to get masternodes", "err", err, "len(masternodes)", len(masternodes))
|
|
||||||
return int32(0), err
|
|
||||||
}
|
|
||||||
blockSigners, err := s.rpcOutputBlockSigners(block, ctx, masternodes)
|
|
||||||
if err != nil {
|
|
||||||
return int32(0), err
|
|
||||||
}
|
|
||||||
return int32(100 * len(blockSigners) / len(masternodes)), err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *PublicBlockChainAPI) GetBlockFinalityByNumber(ctx context.Context, blockNumber rpc.BlockNumber) (int32, error) {
|
|
||||||
block, err := s.b.BlockByNumber(ctx, blockNumber)
|
|
||||||
if err != nil || block == nil {
|
|
||||||
return int32(0), err
|
|
||||||
}
|
|
||||||
masternodes, err := s.GetMasternodes(ctx, block)
|
|
||||||
if err != nil || len(masternodes) == 0 {
|
|
||||||
log.Error("Failed to get masternodes", "err", err, "len(masternodes)", len(masternodes))
|
|
||||||
return int32(0), err
|
|
||||||
}
|
|
||||||
blockSigners, err := s.rpcOutputBlockSigners(block, ctx, masternodes)
|
|
||||||
if err != nil {
|
|
||||||
return int32(0), err
|
|
||||||
}
|
|
||||||
return int32(100 * len(blockSigners) / len(masternodes)), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetMasternodes returns masternodes set at the starting block of epoch of the given block
|
|
||||||
func (s *PublicBlockChainAPI) GetMasternodes(ctx context.Context, b *types.Block) ([]common.Address, error) {
|
|
||||||
var masternodes []common.Address
|
|
||||||
if b.Number().Int64() >= 0 {
|
|
||||||
curBlockNumber := b.Number().Uint64()
|
|
||||||
prevBlockNumber := curBlockNumber + (common.MergeSignRange - (curBlockNumber % common.MergeSignRange))
|
|
||||||
latestBlockNumber := s.b.CurrentBlock().Number().Uint64()
|
|
||||||
if prevBlockNumber >= latestBlockNumber || !s.b.ChainConfig().IsTIP2019(b.Number()) {
|
|
||||||
prevBlockNumber = curBlockNumber
|
|
||||||
}
|
|
||||||
if engine, ok := s.b.GetEngine().(*XDPoS.XDPoS); ok {
|
|
||||||
// Get block epoc latest.
|
|
||||||
lastCheckpointNumber := prevBlockNumber - (prevBlockNumber % s.b.ChainConfig().XDPoS.Epoch)
|
|
||||||
prevCheckpointBlock, _ := s.b.BlockByNumber(ctx, rpc.BlockNumber(lastCheckpointNumber))
|
|
||||||
if prevCheckpointBlock != nil {
|
|
||||||
masternodes = engine.GetMasternodesFromCheckpointHeader(prevCheckpointBlock.Header(), curBlockNumber, s.b.ChainConfig().XDPoS.Epoch)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.Error("Undefined XDPoS consensus engine")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return masternodes, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// GetCandidateStatus returns status of the given candidate at a specified epochNumber
|
|
||||||
func (s *PublicBlockChainAPI) GetCandidateStatus(ctx context.Context, coinbaseAddress common.Address, epochNumber rpc.EpochNumber) (string, error) {
|
|
||||||
var (
|
|
||||||
block *types.Block
|
|
||||||
masternodes, penaltyList, candidates, proposedList []common.Address
|
|
||||||
penalties []byte
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
block = s.b.CurrentBlock()
|
|
||||||
epoch := s.b.ChainConfig().XDPoS.Epoch
|
|
||||||
// TODO: we currently support the latest epoch only
|
|
||||||
//if epochNumber == rpc.LatestEpochNumber {
|
|
||||||
// block = s.b.CurrentBlock()
|
|
||||||
//} else {
|
|
||||||
// checkpointNumber := rpc.BlockNumber((uint64(epochNumber) - 1) * epoch)
|
|
||||||
// if checkpointNumber < 0 {
|
|
||||||
// checkpointNumber = 0
|
|
||||||
// }
|
|
||||||
// block, err = s.b.BlockByNumber(ctx, checkpointNumber)
|
|
||||||
// if err != nil || block == nil {
|
|
||||||
// return "", err
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
blockNum := block.Number().Uint64()
|
|
||||||
masternodes, err = s.GetMasternodes(ctx, block)
|
|
||||||
if err != nil || len(masternodes) == 0 {
|
|
||||||
log.Error("Failed to get masternodes", "err", err, "len(masternodes)", len(masternodes))
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
for _, masternode := range masternodes {
|
|
||||||
if coinbaseAddress == masternode {
|
|
||||||
return statusMasternode, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// look up recent checkpoint headers to get penalty list
|
|
||||||
for i := 0; i <= common.LimitPenaltyEpoch; i++ {
|
|
||||||
if blockNum > uint64(i) * epoch {
|
|
||||||
blockCheckpointNumber := rpc.BlockNumber(blockNum - (blockNum % epoch) - (uint64(i) * epoch))
|
|
||||||
blockCheckpoint, err := s.b.BlockByNumber(ctx, blockCheckpointNumber)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Failed to get block by number", "num", blockCheckpointNumber, "err", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
penalties = append(penalties, blockCheckpoint.Penalties()...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(penalties) > 0 {
|
|
||||||
penaltyList = common.ExtractAddressFromBytes(penalties)
|
|
||||||
for _, pen := range penaltyList {
|
|
||||||
if coinbaseAddress == pen {
|
|
||||||
return statusSlashed, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// read smart contract to get candidate list
|
|
||||||
client, err := s.b.GetIPCClient()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
addr := common.HexToAddress(common.MasternodeVotingSMC)
|
|
||||||
validator, err := contractValidator.NewXDCValidator(addr, client)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
opts := new(bind.CallOpts)
|
|
||||||
candidates, err = validator.GetCandidates(opts)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
// exclude masternodes
|
|
||||||
proposedList = common.RemoveItemFromArray(candidates, masternodes)
|
|
||||||
// exclude penalties
|
|
||||||
proposedList = common.RemoveItemFromArray(proposedList, penaltyList)
|
|
||||||
|
|
||||||
for _, proposed := range proposedList {
|
|
||||||
if coinbaseAddress == proposed {
|
|
||||||
return statusProposed, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CallArgs represents the arguments for a call.
|
// CallArgs represents the arguments for a call.
|
||||||
type CallArgs struct {
|
type CallArgs struct {
|
||||||
From common.Address `json:"from"`
|
From common.Address `json:"from"`
|
||||||
|
|
@ -1030,55 +860,46 @@ func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx
|
||||||
uncleHashes[i] = uncle.Hash()
|
uncleHashes[i] = uncle.Hash()
|
||||||
}
|
}
|
||||||
fields["uncles"] = uncleHashes
|
fields["uncles"] = uncleHashes
|
||||||
return fields, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *PublicBlockChainAPI) rpcOutputBlockSigners(b *types.Block, ctx context.Context, masternodes []common.Address) ([]common.Address, error) {
|
|
||||||
// Get signers for block.
|
// Get signers for block.
|
||||||
client, err := s.b.GetIPCClient()
|
client, err := s.b.GetIPCClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fail to connect IPC client for block status", "error", err)
|
log.Error("Fail to connect IPC client for block status", "error", err)
|
||||||
return []common.Address{}, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var signers []common.Address
|
var signers []common.Address
|
||||||
var filterSigners []common.Address
|
var filterSigners []common.Address
|
||||||
|
finality := int32(0)
|
||||||
if b.Number().Int64() > 0 {
|
if b.Number().Int64() > 0 {
|
||||||
curBlockNumber := b.Number().Uint64()
|
addrBlockSigner := common.HexToAddress(common.BlockSigners)
|
||||||
prevBlockNumber := curBlockNumber + (common.MergeSignRange - (curBlockNumber % common.MergeSignRange))
|
signers, err = contracts.GetSignersFromContract(addrBlockSigner, client, b.Hash())
|
||||||
latestBlockNumber := s.b.CurrentBlock().Number().Uint64()
|
if err != nil {
|
||||||
if prevBlockNumber >= latestBlockNumber || !s.b.ChainConfig().IsTIP2019(b.Number()) {
|
log.Error("Fail to get signers from block signer SC.", "error", err)
|
||||||
prevBlockNumber = curBlockNumber
|
|
||||||
}
|
}
|
||||||
if engine, ok := s.b.GetEngine().(*XDPoS.XDPoS); ok {
|
// Get block epoc latest.
|
||||||
prevBlock, err := s.b.BlockByNumber(ctx, rpc.BlockNumber(prevBlockNumber))
|
if s.b.ChainConfig().XDPoS != nil {
|
||||||
if err != nil {
|
engine := s.b.GetEngine()
|
||||||
log.Error("Fail to get previous block", "error", err)
|
lastCheckpointNumber := rpc.BlockNumber(b.Number().Uint64() - (b.Number().Uint64() % s.b.ChainConfig().XDPoS.Epoch))
|
||||||
return []common.Address{}, err
|
prevCheckpointBlock, _ := s.b.BlockByNumber(ctx, lastCheckpointNumber)
|
||||||
}
|
if prevCheckpointBlock != nil {
|
||||||
addrBlockSigner := common.HexToAddress(common.BlockSigners)
|
masternodes := engine.(*XDPoS.XDPoS).GetMasternodesFromCheckpointHeader(prevCheckpointBlock.Header(), b.Number().Uint64(), s.b.ChainConfig().XDPoS.Epoch)
|
||||||
signers, err = contracts.GetSignersByExecutingEVM(addrBlockSigner, client, prevBlock.Hash())
|
countFinality := 0
|
||||||
if err != nil {
|
for _, masternode := range masternodes {
|
||||||
log.Error("Fail to get signers from block signer SC.", "error", err)
|
for _, signer := range signers {
|
||||||
return []common.Address{}, err
|
if signer == masternode {
|
||||||
}
|
countFinality++
|
||||||
validator, _ := engine.RecoverValidator(b.Header())
|
filterSigners = append(filterSigners, masternode)
|
||||||
creator, _ := engine.RecoverSigner(b.Header())
|
break
|
||||||
signers = append(signers, validator)
|
}
|
||||||
signers = append(signers, creator)
|
|
||||||
for _, masternode := range masternodes {
|
|
||||||
for _, signer := range signers {
|
|
||||||
if signer == masternode {
|
|
||||||
filterSigners = append(filterSigners, masternode)
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
finality = int32(countFinality * 100 / len(masternodes))
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
log.Error("Undefined XDPoS consensus engine")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return filterSigners, nil
|
fields["signers"] = filterSigners
|
||||||
|
fields["finality"] = finality
|
||||||
|
|
||||||
|
return fields, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction
|
// RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction
|
||||||
|
|
|
||||||
78
trie/node.go
78
trie/node.go
|
|
@ -27,63 +27,63 @@ import (
|
||||||
|
|
||||||
var indices = []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "[17]"}
|
var indices = []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "[17]"}
|
||||||
|
|
||||||
type Node interface {
|
type node interface {
|
||||||
fstring(string) string
|
fstring(string) string
|
||||||
Cache() (HashNode, bool)
|
cache() (hashNode, bool)
|
||||||
canUnload(cachegen, cachelimit uint16) bool
|
canUnload(cachegen, cachelimit uint16) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type (
|
type (
|
||||||
FullNode struct {
|
fullNode struct {
|
||||||
Children [17]Node // Actual trie node data to encode/decode (needs custom encoder)
|
Children [17]node // Actual trie node data to encode/decode (needs custom encoder)
|
||||||
flags nodeFlag
|
flags nodeFlag
|
||||||
}
|
}
|
||||||
ShortNode struct {
|
shortNode struct {
|
||||||
Key []byte
|
Key []byte
|
||||||
Val Node
|
Val node
|
||||||
flags nodeFlag
|
flags nodeFlag
|
||||||
}
|
}
|
||||||
HashNode []byte
|
hashNode []byte
|
||||||
ValueNode []byte
|
valueNode []byte
|
||||||
)
|
)
|
||||||
|
|
||||||
// EncodeRLP encodes a full node into the consensus RLP format.
|
// EncodeRLP encodes a full node into the consensus RLP format.
|
||||||
func (n *FullNode) EncodeRLP(w io.Writer) error {
|
func (n *fullNode) EncodeRLP(w io.Writer) error {
|
||||||
return rlp.Encode(w, n.Children)
|
return rlp.Encode(w, n.Children)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *FullNode) copy() *FullNode { copy := *n; return © }
|
func (n *fullNode) copy() *fullNode { copy := *n; return © }
|
||||||
func (n *ShortNode) copy() *ShortNode { copy := *n; return © }
|
func (n *shortNode) copy() *shortNode { copy := *n; return © }
|
||||||
|
|
||||||
// nodeFlag contains caching-related metadata about a node.
|
// nodeFlag contains caching-related metadata about a node.
|
||||||
type nodeFlag struct {
|
type nodeFlag struct {
|
||||||
hash HashNode // cached hash of the node (may be nil)
|
hash hashNode // cached hash of the node (may be nil)
|
||||||
gen uint16 // cache generation counter
|
gen uint16 // cache generation counter
|
||||||
dirty bool // whether the node has changes that must be written to the database
|
dirty bool // whether the node has changes that must be written to the database
|
||||||
}
|
}
|
||||||
|
|
||||||
// canUnload tells whether a Node can be unloaded.
|
// canUnload tells whether a node can be unloaded.
|
||||||
func (n *nodeFlag) canUnload(cachegen, cachelimit uint16) bool {
|
func (n *nodeFlag) canUnload(cachegen, cachelimit uint16) bool {
|
||||||
return !n.dirty && cachegen-n.gen >= cachelimit
|
return !n.dirty && cachegen-n.gen >= cachelimit
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *FullNode) canUnload(gen, limit uint16) bool { return n.flags.canUnload(gen, limit) }
|
func (n *fullNode) canUnload(gen, limit uint16) bool { return n.flags.canUnload(gen, limit) }
|
||||||
func (n *ShortNode) canUnload(gen, limit uint16) bool { return n.flags.canUnload(gen, limit) }
|
func (n *shortNode) canUnload(gen, limit uint16) bool { return n.flags.canUnload(gen, limit) }
|
||||||
func (n HashNode) canUnload(uint16, uint16) bool { return false }
|
func (n hashNode) canUnload(uint16, uint16) bool { return false }
|
||||||
func (n ValueNode) canUnload(uint16, uint16) bool { return false }
|
func (n valueNode) canUnload(uint16, uint16) bool { return false }
|
||||||
|
|
||||||
func (n *FullNode) Cache() (HashNode, bool) { return n.flags.hash, n.flags.dirty }
|
func (n *fullNode) cache() (hashNode, bool) { return n.flags.hash, n.flags.dirty }
|
||||||
func (n *ShortNode) Cache() (HashNode, bool) { return n.flags.hash, n.flags.dirty }
|
func (n *shortNode) cache() (hashNode, bool) { return n.flags.hash, n.flags.dirty }
|
||||||
func (n HashNode) Cache() (HashNode, bool) { return nil, true }
|
func (n hashNode) cache() (hashNode, bool) { return nil, true }
|
||||||
func (n ValueNode) Cache() (HashNode, bool) { return nil, true }
|
func (n valueNode) cache() (hashNode, bool) { return nil, true }
|
||||||
|
|
||||||
// Pretty printing.
|
// Pretty printing.
|
||||||
func (n *FullNode) String() string { return n.fstring("") }
|
func (n *fullNode) String() string { return n.fstring("") }
|
||||||
func (n *ShortNode) String() string { return n.fstring("") }
|
func (n *shortNode) String() string { return n.fstring("") }
|
||||||
func (n HashNode) String() string { return n.fstring("") }
|
func (n hashNode) String() string { return n.fstring("") }
|
||||||
func (n ValueNode) String() string { return n.fstring("") }
|
func (n valueNode) String() string { return n.fstring("") }
|
||||||
|
|
||||||
func (n *FullNode) fstring(ind string) string {
|
func (n *fullNode) fstring(ind string) string {
|
||||||
resp := fmt.Sprintf("[\n%s ", ind)
|
resp := fmt.Sprintf("[\n%s ", ind)
|
||||||
for i, node := range n.Children {
|
for i, node := range n.Children {
|
||||||
if node == nil {
|
if node == nil {
|
||||||
|
|
@ -94,17 +94,17 @@ func (n *FullNode) fstring(ind string) string {
|
||||||
}
|
}
|
||||||
return resp + fmt.Sprintf("\n%s] ", ind)
|
return resp + fmt.Sprintf("\n%s] ", ind)
|
||||||
}
|
}
|
||||||
func (n *ShortNode) fstring(ind string) string {
|
func (n *shortNode) fstring(ind string) string {
|
||||||
return fmt.Sprintf("{%x: %v} ", n.Key, n.Val.fstring(ind+" "))
|
return fmt.Sprintf("{%x: %v} ", n.Key, n.Val.fstring(ind+" "))
|
||||||
}
|
}
|
||||||
func (n HashNode) fstring(ind string) string {
|
func (n hashNode) fstring(ind string) string {
|
||||||
return fmt.Sprintf("<%x> ", []byte(n))
|
return fmt.Sprintf("<%x> ", []byte(n))
|
||||||
}
|
}
|
||||||
func (n ValueNode) fstring(ind string) string {
|
func (n valueNode) fstring(ind string) string {
|
||||||
return fmt.Sprintf("%x ", []byte(n))
|
return fmt.Sprintf("%x ", []byte(n))
|
||||||
}
|
}
|
||||||
|
|
||||||
func MustDecodeNode(hash, buf []byte, cachegen uint16) Node {
|
func mustDecodeNode(hash, buf []byte, cachegen uint16) node {
|
||||||
n, err := decodeNode(hash, buf, cachegen)
|
n, err := decodeNode(hash, buf, cachegen)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Sprintf("node %x: %v", hash, err))
|
panic(fmt.Sprintf("node %x: %v", hash, err))
|
||||||
|
|
@ -113,7 +113,7 @@ func MustDecodeNode(hash, buf []byte, cachegen uint16) Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
// decodeNode parses the RLP encoding of a trie node.
|
// decodeNode parses the RLP encoding of a trie node.
|
||||||
func decodeNode(hash, buf []byte, cachegen uint16) (Node, error) {
|
func decodeNode(hash, buf []byte, cachegen uint16) (node, error) {
|
||||||
if len(buf) == 0 {
|
if len(buf) == 0 {
|
||||||
return nil, io.ErrUnexpectedEOF
|
return nil, io.ErrUnexpectedEOF
|
||||||
}
|
}
|
||||||
|
|
@ -133,7 +133,7 @@ func decodeNode(hash, buf []byte, cachegen uint16) (Node, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeShort(hash, buf, elems []byte, cachegen uint16) (Node, error) {
|
func decodeShort(hash, buf, elems []byte, cachegen uint16) (node, error) {
|
||||||
kbuf, rest, err := rlp.SplitString(elems)
|
kbuf, rest, err := rlp.SplitString(elems)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -146,17 +146,17 @@ func decodeShort(hash, buf, elems []byte, cachegen uint16) (Node, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("invalid value node: %v", err)
|
return nil, fmt.Errorf("invalid value node: %v", err)
|
||||||
}
|
}
|
||||||
return &ShortNode{key, append(ValueNode{}, val...), flag}, nil
|
return &shortNode{key, append(valueNode{}, val...), flag}, nil
|
||||||
}
|
}
|
||||||
r, _, err := decodeRef(rest, cachegen)
|
r, _, err := decodeRef(rest, cachegen)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, wrapError(err, "val")
|
return nil, wrapError(err, "val")
|
||||||
}
|
}
|
||||||
return &ShortNode{key, r, flag}, nil
|
return &shortNode{key, r, flag}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeFull(hash, buf, elems []byte, cachegen uint16) (*FullNode, error) {
|
func decodeFull(hash, buf, elems []byte, cachegen uint16) (*fullNode, error) {
|
||||||
n := &FullNode{flags: nodeFlag{hash: hash, gen: cachegen}}
|
n := &fullNode{flags: nodeFlag{hash: hash, gen: cachegen}}
|
||||||
for i := 0; i < 16; i++ {
|
for i := 0; i < 16; i++ {
|
||||||
cld, rest, err := decodeRef(elems, cachegen)
|
cld, rest, err := decodeRef(elems, cachegen)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -169,14 +169,14 @@ func decodeFull(hash, buf, elems []byte, cachegen uint16) (*FullNode, error) {
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
if len(val) > 0 {
|
if len(val) > 0 {
|
||||||
n.Children[16] = append(ValueNode{}, val...)
|
n.Children[16] = append(valueNode{}, val...)
|
||||||
}
|
}
|
||||||
return n, nil
|
return n, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
const hashLen = len(common.Hash{})
|
const hashLen = len(common.Hash{})
|
||||||
|
|
||||||
func decodeRef(buf []byte, cachegen uint16) (Node, []byte, error) {
|
func decodeRef(buf []byte, cachegen uint16) (node, []byte, error) {
|
||||||
kind, val, rest, err := rlp.Split(buf)
|
kind, val, rest, err := rlp.Split(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, buf, err
|
return nil, buf, err
|
||||||
|
|
@ -195,7 +195,7 @@ func decodeRef(buf []byte, cachegen uint16) (Node, []byte, error) {
|
||||||
// empty node
|
// empty node
|
||||||
return nil, rest, nil
|
return nil, rest, nil
|
||||||
case kind == rlp.String && len(val) == 32:
|
case kind == rlp.String && len(val) == 32:
|
||||||
return append(HashNode{}, val...), rest, nil
|
return append(hashNode{}, val...), rest, nil
|
||||||
default:
|
default:
|
||||||
return nil, nil, fmt.Errorf("invalid RLP string size %d (want 0 or 32)", len(val))
|
return nil, nil, fmt.Errorf("invalid RLP string size %d (want 0 or 32)", len(val))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue