create new func penalties for hard fork

This commit is contained in:
Nguyen Ba Tam 2019-02-22 17:05:03 +07:00
parent e90141a3ba
commit ba55451142
12 changed files with 173 additions and 213 deletions

View file

@ -25,9 +25,12 @@ import (
var (
dir = flag.String("dir", "", "dir to mainet chain data")
cacheSize = flag.Int("size", 1000000, "dir to mainet chain data")
file = flag.String("file", "", "dir to mainet chain data")
)
type TrieRoot struct {
trie *trie.SecureTrie
number uint64
}
type StateNode struct {
node trie.Node
path []byte
@ -45,7 +48,7 @@ var cleanAddress = []common.Address{common.HexToAddress(common.BlockSigners)}
var cache *lru.Cache
var finish = int32(0)
var running = true
var stateRoots = make(chan *trie.SecureTrie)
var stateRoots = make(chan TrieRoot)
func main() {
flag.Parse()
@ -63,10 +66,9 @@ func main() {
if err != nil {
continue
}
fmt.Println(time.Now().Format(time.RFC3339), "Found a trie state root at block ", i, "state root ", root.Hex())
if running {
stateRoots <- trieRoot
}else {
stateRoots <- TrieRoot{trieRoot, i}
} else {
break
}
}
@ -78,29 +80,31 @@ func main() {
atomic.StoreInt32(&finish, 1)
if running {
for _, address := range cleanAddress {
enc := trieRoot.Get(address.Bytes())
enc := trieRoot.trie.Get(address.Bytes())
var data state.Account
rlp.DecodeBytes(enc, &data)
fmt.Println(time.Now().Format(time.RFC3339), "Start clean state address ", address.Hex(), " at state root ", common.Bytes2Hex(trieRoot.Root()), "state address root", data.Root.Hex())
fmt.Println(time.Now().Format(time.RFC3339), "Start clean state address ", address.Hex(), " at block ", trieRoot.number)
signerRoot, err := resolveHash(data.Root[:], lddb.LDB())
if err != nil {
fmt.Println(time.Now().Format(time.RFC3339), "Not found clean state address ", address.Hex(), " at state root ", common.Bytes2Hex(trieRoot.Root()), "state address root", data.Root.Hex())
fmt.Println(time.Now().Format(time.RFC3339), "Not found clean state address ", address.Hex(), " at block ", trieRoot.number)
continue
}
batch := new(leveldb.Batch)
list := []*StateNode{&StateNode{node: signerRoot}}
count := 1
list := []*StateNode{{node: signerRoot}}
for len(list) > 0 {
newList, total := findNewNodes(list, lddb.LDB(), batch)
count = count + 17*len(newList)
list = removeNodesNil(newList, total)
}
fmt.Println(time.Now().Format(time.RFC3339), "Finish clean state address ", address.Hex(), " at state root ", common.Bytes2Hex(trieRoot.Root()), "state address root", data.Root.Hex())
fmt.Println(time.Now().Format(time.RFC3339), "Finish clean state address ", address.Hex(), " at block ", trieRoot.number, " keys ", count)
err = lddb.LDB().Write(batch, nil)
if err != nil {
fmt.Println(time.Now().Format(time.RFC3339), "Write batch leveldb error", err)
os.Exit(1)
}
}
}else {
} else {
break
}
atomic.StoreInt32(&finish, 0)
@ -133,10 +137,7 @@ func catchEventInterupt(db *leveldb.DB) {
running = false
if atomic.LoadInt32(&finish) == 0 {
close(stateRoots)
fmt.Println(time.Now(), "interrupt compact")
db.CompactRange(util.Range{})
db.Close()
fmt.Println(time.Now(), "interrupt end")
os.Exit(1)
}
}
@ -169,7 +170,7 @@ func getAllChilds(n StateNode, db *leveldb.DB) ([17]*StateNode, error) {
if err == nil {
childs[i] = &StateNode{node: childNode, path: append(n.path, byte(i))}
} else if err != nil {
_, ok := err.(*trie.MissingNodeError);
_, ok := err.(*trie.MissingNodeError)
if !ok {
return childs, err
}
@ -186,7 +187,7 @@ func getAllChilds(n StateNode, db *leveldb.DB) ([17]*StateNode, error) {
if err == nil {
childs[0] = &StateNode{node: childNode, path: append(n.path, node.Key...)}
} else if err != nil {
_, ok := err.(*trie.MissingNodeError);
_, ok := err.(*trie.MissingNodeError)
if !ok {
return childs, err
}
@ -234,8 +235,7 @@ func findNewNodes(nodes []*StateNode, db *leveldb.DB, batchlvdb *leveldb.Batch)
childNodes := make([][17]*StateNode, length)
results := make(chan ResultProcessNode)
wg := sync.WaitGroup{}
wgResults := sync.WaitGroup{}
wg.Add(nWorker)
wg.Add(length)
for i := 0; i < nWorker; i++ {
from := i * chunkSize
to := from + chunkSize
@ -245,15 +245,12 @@ func findNewNodes(nodes []*StateNode, db *leveldb.DB, batchlvdb *leveldb.Batch)
go func(from int, to int) {
for j := from; j < to; j++ {
childs, keys, number := processNodes(*nodes[j], db)
wgResults.Add(1)
go func(result ResultProcessNode) {
results <- result
}(ResultProcessNode{j, number, childs, keys})
}
wg.Done()
}(from, to)
}
wg.Wait()
total := 0
go func() {
for result := range results {
@ -264,10 +261,10 @@ func findNewNodes(nodes []*StateNode, db *leveldb.DB, batchlvdb *leveldb.Batch)
batchlvdb.Delete(*key)
}
}
wgResults.Done()
wg.Done()
}
}()
wgResults.Wait()
wg.Wait()
close(results)
return childNodes, total
}

View file

@ -18,11 +18,12 @@ const (
LimitThresholdNonceInQueue = 10
DefaultMinGasPrice = 2500
MergeSignRange = 15
RangeReturnSigner = 90
RangeReturnSigner = 150
MinimunMinerBlockPerEpoch = 1
)
var TIP2019Block = big.NewInt(1050000)
var TIPEVMSignerBlock = big.NewInt(2500000)
var TIPSigning = big.NewInt(3000000)
var IsTestnet bool = false
var StoreRewardFolder string
var RollbackHash Hash

View file

@ -228,7 +228,7 @@ type Posv struct {
BlockSigners *lru.Cache
HookReward func(chain consensus.ChainReader, state *state.StateDB, header *types.Header) (error, map[string]interface{})
HookPenalty func(chain consensus.ChainReader, blockNumberEpoc uint64) ([]common.Address, error)
HookPenaltyTIPEVM func(chain consensus.ChainReader, blockNumberEpoc uint64) ([]common.Address, error)
HookPenaltyTIPSigning func(chain consensus.ChainReader, header *types.Header, candidate []common.Address) ([]common.Address, error)
HookValidator func(header *types.Header, signers []common.Address) ([]byte, error)
HookVerifyMNs func(header *types.Header, signers []common.Address) error
}
@ -398,12 +398,12 @@ func (c *Posv) verifyCascadingFields(chain consensus.ChainReader, header *types.
}
// If the block is a checkpoint block, verify the signer list
if number%c.config.Epoch == 0 {
signers := snap.GetSigners()
penPenalties := []common.Address{}
if c.HookPenalty != nil || c.HookPenaltyTIPEVM != nil {
var penPenalties []common.Address = nil
if c.HookPenalty != nil || c.HookPenaltyTIPSigning != nil {
var err error = nil
if chain.Config().IsTIPEVMSigner(header.Number) {
penPenalties, err = c.HookPenaltyTIPEVM(chain, number)
if chain.Config().IsTIPSigning(header.Number) {
penPenalties, err = c.HookPenaltyTIPSigning(chain, header, signers)
} else {
penPenalties, err = c.HookPenalty(chain, number)
}
@ -418,7 +418,6 @@ func (c *Posv) verifyCascadingFields(chain consensus.ChainReader, header *types.
return errInvalidCheckpointPenalties
}
}
signers := snap.GetSigners()
signers = common.RemoveItemFromArray(signers, penPenalties)
for i := 1; i <= common.LimitPenaltyEpoch; i++ {
if number > uint64(i)*c.config.Epoch {
@ -795,11 +794,11 @@ func (c *Posv) Prepare(chain consensus.ChainReader, header *types.Header) error
header.Extra = header.Extra[:extraVanity]
masternodes := snap.GetSigners()
if number >= c.config.Epoch && number%c.config.Epoch == 0 {
if c.HookPenalty != nil || c.HookPenaltyTIPEVM != nil {
if c.HookPenalty != nil || c.HookPenaltyTIPSigning != nil {
var penMasternodes []common.Address = nil
var err error = nil
if chain.Config().IsTIPEVMSigner(header.Number) {
penMasternodes, err = c.HookPenaltyTIPEVM(chain, number)
if chain.Config().IsTIPSigning(header.Number) {
penMasternodes, err = c.HookPenaltyTIPSigning(chain, header, masternodes)
} else {
penMasternodes, err = c.HookPenalty(chain, number)
}
@ -810,7 +809,7 @@ func (c *Posv) Prepare(chain consensus.ChainReader, header *types.Header) error
// penalize bad masternode(s)
masternodes = common.RemoveItemFromArray(masternodes, penMasternodes)
for _, address := range penMasternodes {
log.Debug("Penalty status", "address", address, "block number", number)
log.Debug("Penalty status", "address", address, "number", number)
}
header.Penalties = common.ExtractAddressToBytes(penMasternodes)
}
@ -1079,15 +1078,15 @@ func (c *Posv) CacheData(header *types.Header, txs []*types.Transaction, receipt
return signTxs
}
func (c *Posv) CacheSigner(header *types.Header, txs []*types.Transaction) []*types.Transaction {
func (c *Posv) CacheSigner(hash common.Hash, txs []*types.Transaction) []*types.Transaction {
signTxs := []*types.Transaction{}
for _, tx := range txs {
if tx.IsSigningTransaction() {
signTxs = append(signTxs, tx)
}
}
log.Debug("Save tx signers to cache", "hash", header.Hash().String(), "number", header.Number, "len(txs)", len(signTxs))
c.BlockSigners.Add(header.Hash(), signTxs)
log.Debug("Save tx signers to cache", "hash", hash.String(), "len(txs)", len(signTxs))
c.BlockSigners.Add(hash, signTxs)
return signTxs
}

View file

@ -306,62 +306,6 @@ func DecryptRandomizeFromSecretsAndOpening(secrets [][32]byte, opening [32]byte)
return random, nil
}
// Get txw signed for block using cache or block body inside.
func GetSignersSignedAtBlockHash(c *posv.Posv, chain consensus.ChainReader, data map[common.Hash][]common.Address, header *types.Header, curNumber uint64) map[common.Hash][]common.Address {
if signData, ok := c.BlockSigners.Get(header.Hash()); ok {
txs := signData.([]*types.Transaction)
for _, tx := range txs {
blkHash := common.BytesToHash(tx.Data()[len(tx.Data())-32:])
from := *tx.From()
data[blkHash] = append(data[blkHash], from)
}
} else {
log.Debug("Failed get from cached", "hash", header.Hash().String(), "number", curNumber)
block := chain.GetBlock(header.Hash(), curNumber)
txs := block.Transactions()
receipts := core.GetBlockReceipts(c.GetDb(), header.Hash(), curNumber)
var signTxs []*types.Transaction
for _, tx := range txs {
if tx.IsSigningTransaction() {
var b uint
for _, r := range receipts {
if r.TxHash == tx.Hash() {
if len(r.PostState) > 0 {
b = types.ReceiptStatusSuccessful
} else {
b = r.Status
}
break
}
}
if b == types.ReceiptStatusFailed {
continue
}
signTxs = append(signTxs, tx)
blkHash := common.BytesToHash(tx.Data()[len(tx.Data())-32:])
from := *tx.From()
data[blkHash] = append(data[blkHash], from)
}
}
c.BlockSigners.Add(header.Hash(), signTxs)
}
return data
}
// Get signers list from bytes.
func GetSignersFromBytes(byteHeader []byte) []common.Address {
signers := make([]common.Address, len(byteHeader)/common.AddressLength)
for i := 0; i < len(signers); i++ {
copy(signers[i][:], byteHeader[i*common.AddressLength:])
}
return signers
}
// Calculate reward for reward checkpoint.
func GetRewardForCheckpoint(c *posv.Posv, chain consensus.ChainReader, header *types.Header, rCheckpoint uint64, totalSigner *uint64) (map[common.Address]*rewardLog, error) {
// Not reward for singer of genesis block and only calculate reward at checkpoint block.
@ -381,11 +325,11 @@ func GetRewardForCheckpoint(c *posv.Posv, chain consensus.ChainReader, header *t
log.Debug("Failed get from cached", "hash", header.Hash().String(), "number", i)
block := chain.GetBlock(header.Hash(), i)
txs := block.Transactions()
if !chain.Config().IsTIPEVMSigner(header.Number) {
if !chain.Config().IsTIPSigning(header.Number) {
receipts := core.GetBlockReceipts(c.GetDb(), header.Hash(), i)
signData = c.CacheData(header, txs, receipts);
signData = c.CacheData(header, txs, receipts)
} else {
signData = c.CacheSigner(header, txs);
signData = c.CacheSigner(header.Hash(), txs)
}
}
txs := signData.([]*types.Transaction)

View file

@ -507,7 +507,7 @@ func (bc *BlockChain) insert(block *types.Block) {
bc.currentBlock.Store(block)
// save cache BlockSigners
if bc.chainConfig.Posv != nil && !bc.chainConfig.IsTIPEVMSigner(block.Number()) {
if bc.chainConfig.Posv != nil && !bc.chainConfig.IsTIPSigning(block.Number()) {
engine := bc.Engine().(*posv.Posv)
engine.CacheData(block.Header(), block.Transactions(), bc.GetReceiptsByHash(block.Hash()))
}
@ -1020,9 +1020,9 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.
bc.insert(block)
}
// save cache BlockSigners
if bc.chainConfig.Posv != nil && bc.chainConfig.IsTIPEVMSigner(block.Number()) {
if bc.chainConfig.Posv != nil && bc.chainConfig.IsTIPSigning(block.Number()) {
engine := bc.Engine().(*posv.Posv)
engine.CacheSigner(block.Header(), block.Transactions())
engine.CacheSigner(block.Header().Hash(), block.Transactions())
}
bc.futureBlocks.Remove(block.Hash())
return status, nil

View file

@ -73,7 +73,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 {
misc.ApplyDAOHardFork(statedb)
}
if p.config.IsTIPEVMSigner(header.Number) {
if common.TIPSigning.Cmp(header.Number) == 0 {
statedb.DeleteAddress(common.HexToAddress(common.BlockSigners))
}
InitSignerInTransactions(p.config, header, block.Transactions())
@ -104,7 +104,7 @@ func (p *StateProcessor) ProcessBlockNoValidator(cBlock *CalculatedBlock, stated
if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 {
misc.ApplyDAOHardFork(statedb)
}
if p.config.IsTIPEVMSigner(header.Number) {
if common.TIPSigning.Cmp(header.Number) == 0 {
statedb.DeleteAddress(common.HexToAddress(common.BlockSigners))
}
if cBlock.stop {
@ -138,7 +138,7 @@ func (p *StateProcessor) ProcessBlockNoValidator(cBlock *CalculatedBlock, stated
// for the transaction, gas used and an error if the transaction failed,
// indicating the block was invalid.
func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, uint64, error) {
if tx.To() != nil && tx.To().String() == common.BlockSigners && config.IsTIPEVMSigner(header.Number) {
if tx.To() != nil && tx.To().String() == common.BlockSigners && config.IsTIPSigning(header.Number) {
return ApplySignTransaction(config, statedb, header, tx, usedGas)
}
msg, err := tx.AsMessage(types.MakeSigner(config, header.Number))

View file

@ -219,7 +219,7 @@ type TxPool struct {
wg sync.WaitGroup // for shutdown sync
homestead bool
IsMasterNode func(address common.Address) bool
IsSigner func(address common.Address) bool
}
// NewTxPool creates a new transaction pool to gather, sort and filter inbound
@ -592,7 +592,7 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error {
// Drop non-local transactions under our own minimal accepted gas price
local = local || pool.locals.contains(from) // account may be local even if the transaction arrived from the network
if !local && pool.gasPrice.Cmp(tx.GasPrice()) > 0 {
if !tx.IsSpecialTransaction() || (pool.IsMasterNode != nil && !pool.IsMasterNode(from)) {
if !tx.IsSpecialTransaction() || (pool.IsSigner != nil && !pool.IsSigner(from)) {
return ErrUnderpriced
}
}
@ -661,7 +661,7 @@ func (pool *TxPool) add(tx *types.Transaction, local bool) (bool, error) {
return false, err
}
from, _ := types.Sender(pool.signer, tx) // already validated
if tx.IsSpecialTransaction() && pool.IsMasterNode != nil && pool.IsMasterNode(from) && pool.pendingState.GetNonce(from) == tx.Nonce() {
if tx.IsSpecialTransaction() && pool.IsSigner != nil && pool.IsSigner(from) && pool.pendingState.GetNonce(from) == tx.Nonce() {
return pool.promoteSpecialTx(from, tx)
}
// If the transaction pool is full, discard underpriced transactions

View file

@ -20,7 +20,10 @@ package eth
import (
"errors"
"fmt"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/eth/filters"
"github.com/ethereum/go-ethereum/rlp"
"math/big"
"runtime"
"sync"
@ -30,7 +33,6 @@ import (
"bytes"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/consensus/posv"
@ -41,7 +43,6 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/eth/downloader"
"github.com/ethereum/go-ethereum/eth/filters"
"github.com/ethereum/go-ethereum/eth/gasprice"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
@ -51,7 +52,6 @@ import (
"github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc"
)
@ -208,12 +208,13 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
if eth.chainConfig.Posv != nil {
c := eth.engine.(*posv.Posv)
signHook := func(block *types.Block) error {
ok, err := eth.ValidateMasternode()
eb, err := eth.Etherbase()
if err != nil {
return fmt.Errorf("Can't verify masternode permission: %v", err)
log.Error("Cannot get etherbase for append m2 header", "err", err)
return fmt.Errorf("etherbase missing: %v", err)
}
ok := eth.txPool.IsSigner != nil && eth.txPool.IsSigner(eb)
if !ok {
// silently return as this node doesn't have masternode permission to sign block
return nil
}
if block.NumberU64()%common.MergeSignRange == 0 || !eth.chainConfig.IsTIP2019(block.Number()) {
@ -274,7 +275,6 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
start := time.Now()
prevHeader := chain.GetHeaderByNumber(prevEpoc)
penSigners := c.GetMasternodes(chain, prevHeader)
signedSigners := make(map[common.Address]*big.Int)
if len(penSigners) > 0 {
// Loop for each block to check missing sign.
for i := prevEpoc; i < blockNumberEpoc; i++ {
@ -283,64 +283,27 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
bhash := bheader.Hash()
block := chain.GetBlock(bhash, i)
if len(penSigners) > 0 {
signer, err := c.RecoverSigner(block.Header())
signedMasternodes, err := contracts.GetSignersFromContract(canonicalState, block)
if err != nil {
return nil, err
}
for _, addr := range penSigners {
if signer == addr {
signedSigners[signer] = signedSigners[signer].Add(signedSigners[signer], big.NewInt(1))
if len(signedMasternodes) > 0 {
// Check signer signed?
for _, signed := range signedMasternodes {
for j, addr := range penSigners {
if signed == addr {
// Remove it from dupSigners.
penSigners = append(penSigners[:j], penSigners[j+1:]...)
}
}
}
}
} else {
break
}
}
if len(signedSigners) > 0 {
for signer, totalSign := range signedSigners {
if totalSign.Cmp(big.NewInt(4)) >= 0 {
for j, addr := range penSigners {
if signer == addr {
// If create block above 4 times then remove it from penSigners.
penSigners = append(penSigners[:j], penSigners[j+1:]...)
}
}
}
}
}
}
}
// Check penalty signer return chain.
prevSigners := contracts.GetSignersFromBytes(prevHeader.Penalties)
if len(prevSigners) > 0 {
startCheck := blockNumberEpoc - common.RangeReturnSigner
data := make(map[common.Hash][]common.Address)
mapBlkHash := map[uint64]common.Hash{}
for curNumber := startCheck; curNumber < blockNumberEpoc; curNumber++ {
signers := make(map[common.Hash][]common.Address)
header := chain.GetHeaderByNumber(curNumber)
mapBlkHash[curNumber] = header.Hash()
data = contracts.GetSignersSignedAtBlockHash(c, chain, signers, header, curNumber)
}
for _, blkHash := range mapBlkHash {
signers := data[blkHash]
for j, addr := range prevSigners {
for _, signer := range signers {
if signer == addr {
// If create block above 4 times then remove it from penSigners.
prevSigners = append(prevSigners[:j], prevSigners[j+1:]...)
}
}
}
}
if len(prevSigners) > 0 {
penSigners = append(penSigners, prevSigners...)
}
}
log.Debug("Time Calculated HookPenalty ", "block", blockNumberEpoc, "time", common.PrettyDuration(time.Since(start)))
return penSigners, nil
}
@ -348,42 +311,94 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
}
// Hook scans for bad masternodes and decide to penalty them
c.HookPenaltyTIPEVM = func(chain consensus.ChainReader, blockNumberEpoc uint64) ([]common.Address, error) {
canonicalState, err := eth.blockchain.State()
if canonicalState == nil || err != nil {
log.Crit("Can't get state at head of canonical chain", "head number", eth.blockchain.CurrentHeader().Number.Uint64(), "err", err)
c.HookPenaltyTIPSigning = func(chain consensus.ChainReader, header *types.Header, candidates []common.Address) ([]common.Address, error) {
prevEpoc := header.Number.Uint64() - chain.Config().Posv.Epoch
combackEpoch := uint64(0)
comebackLength := uint64((common.LimitPenaltyEpoch + 1) * chain.Config().Posv.Epoch)
if header.Number.Uint64() > comebackLength {
combackEpoch = header.Number.Uint64() - comebackLength
}
prevEpoc := blockNumberEpoc - chain.Config().Posv.Epoch
if prevEpoc >= 0 {
start := time.Now()
listBlockHash := make([]common.Hash, chain.Config().Posv.Epoch)
// get list block hash & stats total created block
statMiners := make(map[common.Address]int)
listBlockHash[0] = header.ParentHash
parentnumber := header.Number.Uint64() - 1
parentHash := header.ParentHash
for i := uint64(1); i < chain.Config().Posv.Epoch; i++ {
parentHeader := chain.GetHeader(parentHash, parentnumber)
miner, _ := c.RecoverSigner(parentHeader)
value, exist := statMiners[miner]
if exist {
value = value + 1
} else {
value = 1
}
statMiners[miner] = value
parentHash = parentHeader.ParentHash
parentnumber--
listBlockHash[i] = parentHash
}
// add list not miner to penalties
prevHeader := chain.GetHeaderByNumber(prevEpoc)
penSigners := c.GetMasternodes(chain, prevHeader)
if len(penSigners) > 0 {
// Loop for each block to check missing sign.
blockHash := map[common.Hash]bool{}
for i := prevEpoc; i < blockNumberEpoc; i++ {
if len(penSigners) > 0 {
bheader := chain.GetHeaderByNumber(i)
bhash := bheader.Hash()
if i%common.MergeSignRange == 0 {
blockHash[bhash] = true
preMasternodes := c.GetMasternodes(chain, prevHeader)
penalties := []common.Address{}
for miner, total := range statMiners {
if total < common.MinimunMinerBlockPerEpoch {
log.Debug("Find a node not enough requirement create block", "addr", miner.Hex(), "total", total)
penalties = append(penalties, miner)
}
}
for _, addr := range preMasternodes {
if _, exist := statMiners[addr]; !exist {
log.Debug("Find a node don't create block", "addr", addr.Hex())
penalties = append(penalties, addr)
}
}
// get list check penalties signing block & list master nodes wil comeback
penComebacks := []common.Address{}
if combackEpoch > 0 {
combackHeader := chain.GetHeaderByNumber(combackEpoch)
penalties := common.ExtractAddressFromBytes(combackHeader.Penalties)
for _, penaltie := range penalties {
for _, addr := range candidates {
if penaltie == addr {
penComebacks = append(penComebacks, penaltie)
}
}
}
}
// Loop for each block to check missing sign. with comeback nodes
mapBlockHash := map[common.Hash]bool{}
for i := common.RangeReturnSigner - 1; i >= 0; i-- {
if len(penComebacks) > 0 {
blockNumber := header.Number.Uint64() - uint64(i) - 1
bhash := listBlockHash[i]
if blockNumber%common.MergeSignRange == 0 {
mapBlockHash[bhash] = true
}
signData, ok := c.BlockSigners.Get(bhash)
if !ok {
block := chain.GetBlock(bhash, i)
block := chain.GetBlock(bhash, blockNumber)
txs := block.Transactions()
signData = c.CacheSigner(bheader, txs);
signData = c.CacheSigner(bhash, txs)
}
txs := signData.([]*types.Transaction)
// Check signer signed?
for _, tx := range txs {
blkHash := common.BytesToHash(tx.Data()[len(tx.Data())-32:])
from := *tx.From()
if blockHash[blkHash] == true {
for j, addr := range penSigners {
if mapBlockHash[blkHash] {
for j, addr := range penComebacks {
if from == addr {
// Remove it from dupSigners.
penSigners = append(penSigners[:j], penSigners[j+1:]...)
penComebacks = append(penComebacks[:j], penComebacks[j+1:]...)
break
}
}
@ -393,9 +408,11 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
break
}
}
}
log.Debug("Time Calculated HookPenaltyTIPEVM ", "block", blockNumberEpoc, "time", common.PrettyDuration(time.Since(start)))
return penSigners, nil
log.Debug("Time Calculated HookPenaltyTIPSigning ", "block", header.Number, "hash", header.Hash().Hex(), "pen comeback nodes", len(penComebacks), "not enough miner", len(penalties), "time", common.PrettyDuration(time.Since(start)))
penalties = append(penalties, penComebacks...)
return penComebacks, nil
}
return []common.Address{}, nil
}
@ -473,7 +490,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
return nil
}
eth.txPool.IsMasterNode = func(address common.Address) bool {
eth.txPool.IsSigner = func(address common.Address) bool {
currentHeader := eth.blockchain.CurrentHeader()
header := currentHeader
// Sometimes, the latest block hasn't been inserted to chain yet
@ -721,7 +738,9 @@ func (s *Ethereum) StartStaking(local bool) error {
return nil
}
func (s *Ethereum) StopStaking() { s.miner.Stop() }
func (s *Ethereum) StopStaking() {
s.miner.Stop()
}
func (s *Ethereum) IsStaking() bool { return s.miner.Mining() }
func (s *Ethereum) Miner() *miner.Miner { return s.miner }

View file

@ -963,7 +963,7 @@ func (s *PublicBlockChainAPI) rpcOutputBlockSigners(b *types.Block, ctx context.
if prevCheckpointBlock != nil {
masternodes := engine.GetMasternodesFromCheckpointHeader(prevCheckpointBlock.Header(), blockNumber, s.b.ChainConfig().Posv.Epoch)
signedBlock, _ := s.b.BlockByNumber(ctx, rpc.BlockNumber(signedBlockNumber))
if s.b.ChainConfig().IsTIPEVMSigner(latestBlockNumber) {
if s.b.ChainConfig().IsTIPSigning(latestBlockNumber) {
signers, err = GetSignersFromBlocks(s.b, signedBlock.NumberU64(), signedBlock.Hash(), masternodes)
} else {
signers, err = contracts.GetSignersByExecutingEVM(common.HexToAddress(common.BlockSigners), client, signedBlock.Hash())
@ -1662,7 +1662,7 @@ func GetSignersFromBlocks(b Backend, blockNumber uint64, blockHash common.Hash,
for _, signtx := range signTxs {
blkHash := common.BytesToHash(signtx.Data()[len(signtx.Data())-32:])
from := *signtx.From()
if blkHash == blockHash && mapMN[from] == true {
if blkHash == blockHash && mapMN[from] {
addrs = append(addrs, from)
delete(mapMN, from)
}

View file

@ -584,7 +584,7 @@ func (self *worker) commitNewWork() {
if self.config.DAOForkSupport && self.config.DAOForkBlock != nil && self.config.DAOForkBlock.Cmp(header.Number) == 0 {
misc.ApplyDAOHardFork(work.state)
}
if self.config.IsTIPEVMSigner(header.Number) {
if common.TIPSigning.Cmp(header.Number) == 0 {
work.state.DeleteAddress(common.HexToAddress(common.BlockSigners))
}
// won't grasp txs at checkpoint
@ -677,7 +677,7 @@ func (env *Work) commitTransactions(mux *event.TypeMux, txs *types.TransactionsB
}
if tx.To().Hex() == common.BlockSigners {
if len(tx.Data()) < 68 {
log.Trace("Data special transaction invalid lenght", "hash", tx.Hash(), "data", len(tx.Data()))
log.Trace("Data special transaction invalid length", "hash", tx.Hash(), "data", len(tx.Data()))
continue
}
blkNumber := binary.BigEndian.Uint64(tx.Data()[8:40])

View file

@ -217,8 +217,8 @@ func (c *ChainConfig) IsTIP2019(num *big.Int) bool {
return isForked(common.TIP2019Block, num)
}
func (c *ChainConfig) IsTIPEVMSigner(num *big.Int) bool {
return isForked(common.TIPEVMSignerBlock, num)
func (c *ChainConfig) IsTIPSigning(num *big.Int) bool {
return isForked(common.TIPSigning, num)
}
// GasTable returns the gas table corresponding to the current phase (homestead or homestead reprice).