mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
remove run evm with signing tracsaction
This commit is contained in:
parent
cafef44074
commit
3fb5566726
10 changed files with 272 additions and 44 deletions
|
|
@ -22,7 +22,8 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
var TIP2019Block = big.NewInt(1050000)
|
var TIP2019Block = big.NewInt(1050000)
|
||||||
var IsTestnet = false
|
var TIPEVMSignerBlock = big.NewInt(2500000)
|
||||||
|
var IsTestnet bool = false
|
||||||
var StoreRewardFolder string
|
var StoreRewardFolder string
|
||||||
var RollbackHash Hash
|
var RollbackHash Hash
|
||||||
var MinGasPrice int64
|
var MinGasPrice int64
|
||||||
|
|
|
||||||
|
|
@ -228,6 +228,7 @@ type Posv struct {
|
||||||
BlockSigners *lru.Cache
|
BlockSigners *lru.Cache
|
||||||
HookReward func(chain consensus.ChainReader, state *state.StateDB, header *types.Header) (error, map[string]interface{})
|
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)
|
HookPenalty func(chain consensus.ChainReader, blockNumberEpoc uint64) ([]common.Address, error)
|
||||||
|
HookPenaltyTIPEVM func(chain consensus.ChainReader, blockNumberEpoc uint64) ([]common.Address, error)
|
||||||
HookValidator func(header *types.Header, signers []common.Address) ([]byte, error)
|
HookValidator func(header *types.Header, signers []common.Address) ([]byte, error)
|
||||||
HookVerifyMNs func(header *types.Header, signers []common.Address) error
|
HookVerifyMNs func(header *types.Header, signers []common.Address) error
|
||||||
}
|
}
|
||||||
|
|
@ -398,8 +399,14 @@ func (c *Posv) verifyCascadingFields(chain consensus.ChainReader, header *types.
|
||||||
// If the block is a checkpoint block, verify the signer list
|
// If the block is a checkpoint block, verify the signer list
|
||||||
if number%c.config.Epoch == 0 {
|
if number%c.config.Epoch == 0 {
|
||||||
penPenalties := []common.Address{}
|
penPenalties := []common.Address{}
|
||||||
if c.HookPenalty != nil {
|
if c.HookPenalty != nil || c.HookPenaltyTIPEVM != nil {
|
||||||
|
var penPenalties []common.Address = nil
|
||||||
|
var err error = nil
|
||||||
|
if chain.Config().IsTIPEVMSigner(header.Number) {
|
||||||
|
penPenalties, err = c.HookPenaltyTIPEVM(chain, number)
|
||||||
|
} else {
|
||||||
penPenalties, err = c.HookPenalty(chain, number)
|
penPenalties, err = c.HookPenalty(chain, number)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -788,8 +795,14 @@ func (c *Posv) Prepare(chain consensus.ChainReader, header *types.Header) error
|
||||||
header.Extra = header.Extra[:extraVanity]
|
header.Extra = header.Extra[:extraVanity]
|
||||||
masternodes := snap.GetSigners()
|
masternodes := snap.GetSigners()
|
||||||
if number >= c.config.Epoch && number%c.config.Epoch == 0 {
|
if number >= c.config.Epoch && number%c.config.Epoch == 0 {
|
||||||
if c.HookPenalty != nil {
|
if c.HookPenalty != nil || c.HookPenaltyTIPEVM != nil {
|
||||||
penMasternodes, err := c.HookPenalty(chain, number)
|
var penMasternodes []common.Address = nil
|
||||||
|
var err error = nil
|
||||||
|
if chain.Config().IsTIPEVMSigner(header.Number) {
|
||||||
|
penMasternodes, err = c.HookPenaltyTIPEVM(chain, number)
|
||||||
|
} else {
|
||||||
|
penMasternodes, err = c.HookPenalty(chain, number)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -1036,8 +1049,8 @@ func (c *Posv) GetMasternodesFromCheckpointHeader(preCheckpointHeader *types.Hea
|
||||||
return masternodes
|
return masternodes
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Posv) CacheData(header *types.Header, txs []*types.Transaction, receipts []*types.Receipt) error {
|
func (c *Posv) CacheData(header *types.Header, txs []*types.Transaction, receipts []*types.Receipt) []*types.Transaction {
|
||||||
var signTxs []*types.Transaction
|
signTxs := []*types.Transaction{}
|
||||||
for _, tx := range txs {
|
for _, tx := range txs {
|
||||||
if tx.IsSigningTransaction() {
|
if tx.IsSigningTransaction() {
|
||||||
var b uint
|
var b uint
|
||||||
|
|
@ -1063,7 +1076,19 @@ func (c *Posv) CacheData(header *types.Header, txs []*types.Transaction, receipt
|
||||||
log.Debug("Save tx signers to cache", "hash", header.Hash().String(), "number", header.Number, "len(txs)", len(signTxs))
|
log.Debug("Save tx signers to cache", "hash", header.Hash().String(), "number", header.Number, "len(txs)", len(signTxs))
|
||||||
c.BlockSigners.Add(header.Hash(), signTxs)
|
c.BlockSigners.Add(header.Hash(), signTxs)
|
||||||
|
|
||||||
return nil
|
return signTxs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Posv) CacheSigner(header *types.Header, 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)
|
||||||
|
return signTxs
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Posv) GetDb() ethdb.Database {
|
func (c *Posv) GetDb() ethdb.Database {
|
||||||
|
|
|
||||||
|
|
@ -373,10 +373,27 @@ func GetRewardForCheckpoint(c *posv.Posv, chain consensus.ChainReader, header *t
|
||||||
mapBlkHash := map[uint64]common.Hash{}
|
mapBlkHash := map[uint64]common.Hash{}
|
||||||
|
|
||||||
data := make(map[common.Hash][]common.Address)
|
data := make(map[common.Hash][]common.Address)
|
||||||
for curNumber := prevCheckpoint + (rCheckpoint * 2) - 1; curNumber >= startBlockNumber; curNumber-- {
|
for i := prevCheckpoint + (rCheckpoint * 2) - 1; i >= startBlockNumber; i-- {
|
||||||
header = chain.GetHeader(header.ParentHash, curNumber)
|
header = chain.GetHeader(header.ParentHash, i)
|
||||||
mapBlkHash[curNumber] = header.Hash()
|
mapBlkHash[i] = header.Hash()
|
||||||
data = GetSignersSignedAtBlockHash(c, chain, data, header, curNumber)
|
signData, ok := c.BlockSigners.Get(header.Hash())
|
||||||
|
if !ok {
|
||||||
|
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) {
|
||||||
|
receipts := core.GetBlockReceipts(c.GetDb(), header.Hash(), i)
|
||||||
|
signData = c.CacheData(header, txs, receipts);
|
||||||
|
} else {
|
||||||
|
signData = c.CacheSigner(header, txs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
header = chain.GetHeader(header.ParentHash, prevCheckpoint)
|
header = chain.GetHeader(header.ParentHash, prevCheckpoint)
|
||||||
masternodes := posv.GetMasternodesFromCheckpointHeader(header)
|
masternodes := posv.GetMasternodesFromCheckpointHeader(header)
|
||||||
|
|
|
||||||
|
|
@ -507,7 +507,7 @@ func (bc *BlockChain) insert(block *types.Block) {
|
||||||
bc.currentBlock.Store(block)
|
bc.currentBlock.Store(block)
|
||||||
|
|
||||||
// save cache BlockSigners
|
// save cache BlockSigners
|
||||||
if bc.chainConfig.Posv != nil {
|
if bc.chainConfig.Posv != nil && !bc.chainConfig.IsTIPEVMSigner(block.Number()) {
|
||||||
engine := bc.Engine().(*posv.Posv)
|
engine := bc.Engine().(*posv.Posv)
|
||||||
engine.CacheData(block.Header(), block.Transactions(), bc.GetReceiptsByHash(block.Hash()))
|
engine.CacheData(block.Header(), block.Transactions(), bc.GetReceiptsByHash(block.Hash()))
|
||||||
}
|
}
|
||||||
|
|
@ -1019,6 +1019,11 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.
|
||||||
if status == CanonStatTy {
|
if status == CanonStatTy {
|
||||||
bc.insert(block)
|
bc.insert(block)
|
||||||
}
|
}
|
||||||
|
// save cache BlockSigners
|
||||||
|
if bc.chainConfig.Posv != nil && bc.chainConfig.IsTIPEVMSigner(block.Number()) {
|
||||||
|
engine := bc.Engine().(*posv.Posv)
|
||||||
|
engine.CacheSigner(block.Header(), block.Transactions())
|
||||||
|
}
|
||||||
bc.futureBlocks.Remove(block.Hash())
|
bc.futureBlocks.Remove(block.Hash())
|
||||||
return status, nil
|
return status, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -357,6 +357,14 @@ func (self *StateDB) deleteStateObject(stateObject *stateObject) {
|
||||||
self.setError(self.trie.TryDelete(addr[:]))
|
self.setError(self.trie.TryDelete(addr[:]))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteAddress removes the address from the state trie.
|
||||||
|
func (self *StateDB) DeleteAddress(addr common.Address) {
|
||||||
|
stateObject := self.getStateObject(addr)
|
||||||
|
if stateObject != nil && !stateObject.deleted {
|
||||||
|
self.deleteStateObject(stateObject)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Retrieve a state object given my the address. Returns nil if not found.
|
// Retrieve a state object given my the address. Returns nil if not found.
|
||||||
func (self *StateDB) getStateObject(addr common.Address) (stateObject *stateObject) {
|
func (self *StateDB) getStateObject(addr common.Address) (stateObject *stateObject) {
|
||||||
// Prefer 'live' objects.
|
// Prefer 'live' objects.
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,9 @@ 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 {
|
if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 {
|
||||||
misc.ApplyDAOHardFork(statedb)
|
misc.ApplyDAOHardFork(statedb)
|
||||||
}
|
}
|
||||||
|
if p.config.IsTIPEVMSigner(header.Number) {
|
||||||
|
statedb.DeleteAddress(common.HexToAddress(common.BlockSigners))
|
||||||
|
}
|
||||||
InitSignerInTransactions(p.config, header, block.Transactions())
|
InitSignerInTransactions(p.config, header, block.Transactions())
|
||||||
for i, tx := range block.Transactions() {
|
for i, tx := range block.Transactions() {
|
||||||
statedb.Prepare(tx.Hash(), block.Hash(), i)
|
statedb.Prepare(tx.Hash(), block.Hash(), i)
|
||||||
|
|
@ -101,6 +104,9 @@ func (p *StateProcessor) ProcessBlockNoValidator(cBlock *CalculatedBlock, stated
|
||||||
if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 {
|
if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 {
|
||||||
misc.ApplyDAOHardFork(statedb)
|
misc.ApplyDAOHardFork(statedb)
|
||||||
}
|
}
|
||||||
|
if p.config.IsTIPEVMSigner(header.Number) {
|
||||||
|
statedb.DeleteAddress(common.HexToAddress(common.BlockSigners))
|
||||||
|
}
|
||||||
if cBlock.stop {
|
if cBlock.stop {
|
||||||
return nil, nil, 0, ErrStopPreparingBlock
|
return nil, nil, 0, ErrStopPreparingBlock
|
||||||
}
|
}
|
||||||
|
|
@ -132,6 +138,9 @@ func (p *StateProcessor) ProcessBlockNoValidator(cBlock *CalculatedBlock, stated
|
||||||
// for the transaction, gas used and an error if the transaction failed,
|
// for the transaction, gas used and an error if the transaction failed,
|
||||||
// indicating the block was invalid.
|
// 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) {
|
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) {
|
||||||
|
return ApplySignTransaction(config, statedb, header, tx, usedGas)
|
||||||
|
}
|
||||||
msg, err := tx.AsMessage(types.MakeSigner(config, header.Number))
|
msg, err := tx.AsMessage(types.MakeSigner(config, header.Number))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
|
|
@ -171,6 +180,41 @@ func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, author *common
|
||||||
return receipt, gas, err
|
return receipt, gas, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ApplySignTransaction(config *params.ChainConfig, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64) (*types.Receipt, uint64, error) {
|
||||||
|
// Update the state with pending changes
|
||||||
|
var root []byte
|
||||||
|
if config.IsByzantium(header.Number) {
|
||||||
|
statedb.Finalise(true)
|
||||||
|
} else {
|
||||||
|
root = statedb.IntermediateRoot(config.IsEIP158(header.Number)).Bytes()
|
||||||
|
}
|
||||||
|
from, err := types.Sender(types.MakeSigner(config, header.Number), tx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
nonce := statedb.GetNonce(from)
|
||||||
|
if nonce < tx.Nonce() {
|
||||||
|
return nil, 0, ErrNonceTooHigh
|
||||||
|
} else if nonce > tx.Nonce() {
|
||||||
|
return nil, 0, ErrNonceTooLow
|
||||||
|
}
|
||||||
|
statedb.SetNonce(from, nonce+1)
|
||||||
|
// Create a new receipt for the transaction, storing the intermediate root and gas used by the tx
|
||||||
|
// based on the eip phase, we're passing wether the root touch-delete accounts.
|
||||||
|
receipt := types.NewReceipt(root, false, *usedGas)
|
||||||
|
receipt.TxHash = tx.Hash()
|
||||||
|
receipt.GasUsed = 0
|
||||||
|
// if the transaction created a contract, store the creation address in the receipt.
|
||||||
|
// Set the receipt logs and create a bloom for filtering
|
||||||
|
log := &types.Log{}
|
||||||
|
log.Address = common.HexToAddress(common.BlockSigners)
|
||||||
|
log.BlockNumber = header.Number.Uint64()
|
||||||
|
statedb.AddLog(log)
|
||||||
|
receipt.Logs = statedb.GetLogs(tx.Hash())
|
||||||
|
receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
|
||||||
|
return receipt, 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
func InitSignerInTransactions(config *params.ChainConfig, header *types.Header, txs types.Transactions) {
|
func InitSignerInTransactions(config *params.ChainConfig, header *types.Header, txs types.Transactions) {
|
||||||
nWorker := runtime.NumCPU()
|
nWorker := runtime.NumCPU()
|
||||||
signer := types.MakeSigner(config, header.Number)
|
signer := types.MakeSigner(config, header.Number)
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ package eth
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"math/big"
|
"math/big"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
@ -36,7 +37,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/contracts"
|
"github.com/ethereum/go-ethereum/contracts"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/bloombits"
|
"github.com/ethereum/go-ethereum/core/bloombits"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
|
||||||
//"github.com/ethereum/go-ethereum/core/state"
|
//"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
|
|
@ -347,6 +347,59 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
|
||||||
return []common.Address{}, nil
|
return []common.Address{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
prevEpoc := blockNumberEpoc - chain.Config().Posv.Epoch
|
||||||
|
if prevEpoc >= 0 {
|
||||||
|
start := time.Now()
|
||||||
|
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
|
||||||
|
}
|
||||||
|
signData, ok := c.BlockSigners.Get(bhash)
|
||||||
|
if !ok {
|
||||||
|
block := chain.GetBlock(bhash, i)
|
||||||
|
txs := block.Transactions()
|
||||||
|
signData = c.CacheSigner(bheader, 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 from == addr {
|
||||||
|
// Remove it from dupSigners.
|
||||||
|
penSigners = append(penSigners[:j], penSigners[j+1:]...)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Debug("Time Calculated HookPenaltyTIPEVM ", "block", blockNumberEpoc, "time", common.PrettyDuration(time.Since(start)))
|
||||||
|
return penSigners, nil
|
||||||
|
}
|
||||||
|
return []common.Address{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Hook calculates reward for masternodes
|
// Hook calculates reward for masternodes
|
||||||
c.HookReward = func(chain consensus.ChainReader, stateBlock *state.StateDB, header *types.Header) (error, map[string]interface{}) {
|
c.HookReward = func(chain consensus.ChainReader, stateBlock *state.StateDB, header *types.Header) (error, map[string]interface{}) {
|
||||||
parentHeader := eth.blockchain.GetHeader(header.ParentHash, header.Number.Uint64()-1)
|
parentHeader := eth.blockchain.GetHeader(header.ParentHash, header.Number.Uint64()-1)
|
||||||
|
|
|
||||||
|
|
@ -950,36 +950,43 @@ func (s *PublicBlockChainAPI) rpcOutputBlockSigners(b *types.Block, ctx context.
|
||||||
var signers []common.Address
|
var signers []common.Address
|
||||||
var filterSigners []common.Address
|
var filterSigners []common.Address
|
||||||
if b.Number().Int64() > 0 {
|
if b.Number().Int64() > 0 {
|
||||||
curBlockNumber := b.Number().Uint64()
|
blockNumber := b.Number().Uint64()
|
||||||
prevBlockNumber := curBlockNumber + (common.MergeSignRange - (curBlockNumber % common.MergeSignRange))
|
signedBlockNumber := blockNumber + (common.MergeSignRange - (blockNumber % common.MergeSignRange))
|
||||||
latestBlockNumber := s.b.CurrentBlock().Number().Uint64()
|
latestBlockNumber := s.b.CurrentBlock().Number()
|
||||||
if prevBlockNumber >= latestBlockNumber || !s.b.ChainConfig().IsTIP2019(b.Number()) {
|
if signedBlockNumber >= latestBlockNumber.Uint64() || !s.b.ChainConfig().IsTIP2019(b.Number()) {
|
||||||
prevBlockNumber = curBlockNumber
|
signedBlockNumber = blockNumber
|
||||||
}
|
}
|
||||||
if engine, ok := s.b.GetEngine().(*posv.Posv); ok {
|
if engine, ok := s.b.GetEngine().(*posv.Posv); ok {
|
||||||
prevBlock, err := s.b.BlockByNumber(ctx, rpc.BlockNumber(prevBlockNumber))
|
// Get block epoc latest.
|
||||||
if err != nil {
|
lastCheckpointNumber := signedBlockNumber - (signedBlockNumber % s.b.ChainConfig().Posv.Epoch)
|
||||||
log.Error("Fail to get previous block", "error", err)
|
prevCheckpointBlock, _ := s.b.BlockByNumber(ctx, rpc.BlockNumber(lastCheckpointNumber))
|
||||||
return []common.Address{}, err
|
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) {
|
||||||
|
signers, err = GetSignersFromBlocks(s.b, signedBlock.NumberU64(), signedBlock.Hash(), masternodes)
|
||||||
|
} else {
|
||||||
|
signers, err = contracts.GetSignersByExecutingEVM(common.HexToAddress(common.BlockSigners), client, signedBlock.Hash())
|
||||||
}
|
}
|
||||||
addrBlockSigner := common.HexToAddress(common.BlockSigners)
|
|
||||||
signers, err = contracts.GetSignersByExecutingEVM(addrBlockSigner, client, prevBlock.Hash())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fail to get signers from block signer SC.", "error", err)
|
log.Error("Fail to get signers from block signer SC.", "error", err)
|
||||||
return []common.Address{}, err
|
return nil, err
|
||||||
}
|
}
|
||||||
validator, _ := engine.RecoverValidator(b.Header())
|
validator, _ := engine.RecoverValidator(b.Header())
|
||||||
creator, _ := engine.RecoverSigner(b.Header())
|
creator, _ := engine.RecoverSigner(b.Header())
|
||||||
signers = append(signers, validator)
|
signers = append(signers, validator)
|
||||||
signers = append(signers, creator)
|
signers = append(signers, creator)
|
||||||
|
countFinality := 0
|
||||||
for _, masternode := range masternodes {
|
for _, masternode := range masternodes {
|
||||||
for _, signer := range signers {
|
for _, signer := range signers {
|
||||||
if signer == masternode {
|
if signer == masternode {
|
||||||
|
countFinality++
|
||||||
filterSigners = append(filterSigners, masternode)
|
filterSigners = append(filterSigners, masternode)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Error("Undefined POSV consensus engine")
|
log.Error("Undefined POSV consensus engine")
|
||||||
}
|
}
|
||||||
|
|
@ -1618,3 +1625,52 @@ func (s *PublicNetAPI) PeerCount() hexutil.Uint {
|
||||||
func (s *PublicNetAPI) Version() string {
|
func (s *PublicNetAPI) Version() string {
|
||||||
return fmt.Sprintf("%d", s.networkVersion)
|
return fmt.Sprintf("%d", s.networkVersion)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetSignersFromBlocks(b Backend, blockNumber uint64, blockHash common.Hash, masternodes []common.Address) ([]common.Address, error) {
|
||||||
|
var addrs []common.Address
|
||||||
|
mapMN := map[common.Address]bool{}
|
||||||
|
for _, node := range masternodes {
|
||||||
|
mapMN[node] = true
|
||||||
|
}
|
||||||
|
if engine, ok := b.GetEngine().(*posv.Posv); ok {
|
||||||
|
limitNumber := blockNumber - blockNumber%b.ChainConfig().Posv.Epoch + 2*b.ChainConfig().Posv.Epoch - 1
|
||||||
|
currentNumber := b.CurrentBlock().NumberU64()
|
||||||
|
if limitNumber > currentNumber {
|
||||||
|
limitNumber = currentNumber
|
||||||
|
}
|
||||||
|
for i := blockNumber + 1; i <= limitNumber; i++ {
|
||||||
|
header, err := b.HeaderByNumber(nil, rpc.BlockNumber(i))
|
||||||
|
if err != nil {
|
||||||
|
return addrs, err
|
||||||
|
}
|
||||||
|
signData, ok := engine.BlockSigners.Get(header.Hash())
|
||||||
|
var signTxs []*types.Transaction = nil
|
||||||
|
if !ok {
|
||||||
|
blockData, err := b.BlockByNumber(nil, rpc.BlockNumber(i))
|
||||||
|
if err != nil {
|
||||||
|
return addrs, err
|
||||||
|
}
|
||||||
|
signTxs = []*types.Transaction{}
|
||||||
|
for _, tx := range blockData.Transactions() {
|
||||||
|
if tx.IsSigningTransaction() {
|
||||||
|
signTxs = append(signTxs, tx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
signTxs = signData.([]*types.Transaction)
|
||||||
|
}
|
||||||
|
for _, signtx := range signTxs {
|
||||||
|
blkHash := common.BytesToHash(signtx.Data()[len(signtx.Data())-32:])
|
||||||
|
from := *signtx.From()
|
||||||
|
if blkHash == blockHash && mapMN[from] == true {
|
||||||
|
addrs = append(addrs, from)
|
||||||
|
delete(mapMN, from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(mapMN) == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return addrs, nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ package miner
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"os"
|
"os"
|
||||||
|
|
@ -583,6 +584,9 @@ func (self *worker) commitNewWork() {
|
||||||
if self.config.DAOForkSupport && self.config.DAOForkBlock != nil && self.config.DAOForkBlock.Cmp(header.Number) == 0 {
|
if self.config.DAOForkSupport && self.config.DAOForkBlock != nil && self.config.DAOForkBlock.Cmp(header.Number) == 0 {
|
||||||
misc.ApplyDAOHardFork(work.state)
|
misc.ApplyDAOHardFork(work.state)
|
||||||
}
|
}
|
||||||
|
if self.config.IsTIPEVMSigner(header.Number) {
|
||||||
|
work.state.DeleteAddress(common.HexToAddress(common.BlockSigners))
|
||||||
|
}
|
||||||
// won't grasp txs at checkpoint
|
// won't grasp txs at checkpoint
|
||||||
var (
|
var (
|
||||||
txs *types.TransactionsByPriceAndNonce
|
txs *types.TransactionsByPriceAndNonce
|
||||||
|
|
@ -671,6 +675,17 @@ func (env *Work) commitTransactions(mux *event.TypeMux, txs *types.TransactionsB
|
||||||
log.Trace("Ignoring reply protected special transaction", "hash", tx.Hash(), "eip155", env.config.EIP155Block)
|
log.Trace("Ignoring reply protected special transaction", "hash", tx.Hash(), "eip155", env.config.EIP155Block)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
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()))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
blkNumber := binary.BigEndian.Uint64(tx.Data()[8:40])
|
||||||
|
if blkNumber >= env.header.Number.Uint64() || blkNumber <= env.header.Number.Uint64()-env.config.Posv.Epoch*2 {
|
||||||
|
log.Trace("Data special transaction invalid number", "hash", tx.Hash(), "blkNumber", blkNumber, "miner", env.header.Number)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
// Start executing the transaction
|
// Start executing the transaction
|
||||||
env.state.Prepare(tx.Hash(), common.Hash{}, env.tcount)
|
env.state.Prepare(tx.Hash(), common.Hash{}, env.tcount)
|
||||||
nonce := env.state.GetNonce(from)
|
nonce := env.state.GetNonce(from)
|
||||||
|
|
|
||||||
|
|
@ -217,6 +217,10 @@ func (c *ChainConfig) IsTIP2019(num *big.Int) bool {
|
||||||
return isForked(common.TIP2019Block, num)
|
return isForked(common.TIP2019Block, num)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *ChainConfig) IsTIPEVMSigner(num *big.Int) bool {
|
||||||
|
return isForked(common.TIPEVMSignerBlock, num)
|
||||||
|
}
|
||||||
|
|
||||||
// GasTable returns the gas table corresponding to the current phase (homestead or homestead reprice).
|
// GasTable returns the gas table corresponding to the current phase (homestead or homestead reprice).
|
||||||
//
|
//
|
||||||
// The returned GasTable's fields shouldn't, under any circumstances, be changed.
|
// The returned GasTable's fields shouldn't, under any circumstances, be changed.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue