mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
create new func penalties for hard fork
This commit is contained in:
parent
e90141a3ba
commit
ba55451142
12 changed files with 173 additions and 213 deletions
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
177
eth/backend.go
177
eth/backend.go
|
|
@ -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 }
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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])
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
|
|
|||
Loading…
Reference in a new issue