remove run evm with signing tracsaction

This commit is contained in:
parmarrushabh 2018-12-28 12:33:35 +05:30
parent 973f9d1271
commit 7833a10c16
7 changed files with 162 additions and 28 deletions

View file

@ -22,7 +22,8 @@ const (
)
var TIP2019Block = big.NewInt(1050000)
var IsTestnet = false
var TIPEVMSignerBlock = big.NewInt(2500000)
var IsTestnet bool = false
var StoreRewardFolder string
var RollbackHash Hash
var MinGasPrice int64

View file

@ -1,3 +1,4 @@
// Copyright 2014 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
@ -507,7 +508,7 @@ func (bc *BlockChain) insert(block *types.Block) {
bc.currentBlock.Store(block)
// save cache BlockSigners
if bc.chainConfig.XDPoS != nil {
if bc.chainConfig.XDPoS != nil && !bc.chainConfig.IsTIPEVMSigner(block.Number()) {
engine := bc.Engine().(*XDPoS.XDPoS)
engine.CacheData(block.Header(), block.Transactions(), bc.GetReceiptsByHash(block.Hash()))
}
@ -1019,6 +1020,11 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.
if status == CanonStatTy {
bc.insert(block)
}
// save cache BlockSigners
if bc.chainConfig.XDPoS != nil && bc.chainConfig.IsTIPEVMSigner(block.Number()) {
engine := bc.Engine().(*XDPoS.XDPoS)
engine.CacheSigner(block.Header(), block.Transactions())
}
bc.futureBlocks.Remove(block.Hash())
return status, nil
}

View file

@ -357,6 +357,14 @@ func (self *StateDB) deleteStateObject(stateObject *stateObject) {
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.
func (self *StateDB) getStateObject(addr common.Address) (stateObject *stateObject) {
// Prefer 'live' objects.

View file

@ -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 {
misc.ApplyDAOHardFork(statedb)
}
if p.config.IsTIPEVMSigner(header.Number) {
statedb.DeleteAddress(common.HexToAddress(common.BlockSigners))
}
InitSignerInTransactions(p.config, header, block.Transactions())
for i, tx := range block.Transactions() {
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 {
misc.ApplyDAOHardFork(statedb)
}
if p.config.IsTIPEVMSigner(header.Number) {
statedb.DeleteAddress(common.HexToAddress(common.BlockSigners))
}
if cBlock.stop {
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,
// 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) {
return ApplySignTransaction(config, statedb, header, tx, usedGas)
}
msg, err := tx.AsMessage(types.MakeSigner(config, header.Number))
if err != nil {
return nil, 0, err
@ -171,6 +180,41 @@ func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, author *common
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) {
nWorker := runtime.NumCPU()
signer := types.MakeSigner(config, header.Number)
@ -195,4 +239,4 @@ func InitSignerInTransactions(config *params.ChainConfig, header *types.Header,
}(from, to)
}
wg.Wait()
}
}

View file

@ -950,33 +950,40 @@ func (s *PublicBlockChainAPI) rpcOutputBlockSigners(b *types.Block, ctx context.
var signers []common.Address
var filterSigners []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
blockNumber := b.Number().Uint64()
signedBlockNumber := blockNumber + (common.MergeSignRange - (blockNumber % common.MergeSignRange))
latestBlockNumber := s.b.CurrentBlock().Number()
if signedBlockNumber >= latestBlockNumber.Uint64() || !s.b.ChainConfig().IsTIP2019(b.Number()) {
signedBlockNumber = blockNumber
}
if engine, ok := s.b.GetEngine().(*XDPoS.XDPoS); ok {
prevBlock, err := s.b.BlockByNumber(ctx, rpc.BlockNumber(prevBlockNumber))
if err != nil {
log.Error("Fail to get previous block", "error", err)
return []common.Address{}, err
}
addrBlockSigner := common.HexToAddress(common.BlockSigners)
signers, err = contracts.GetSignersByExecutingEVM(addrBlockSigner, client, prevBlock.Hash())
if err != nil {
log.Error("Fail to get signers from block signer SC.", "error", err)
return []common.Address{}, err
}
validator, _ := engine.RecoverValidator(b.Header())
creator, _ := engine.RecoverSigner(b.Header())
signers = append(signers, validator)
signers = append(signers, creator)
for _, masternode := range masternodes {
for _, signer := range signers {
if signer == masternode {
filterSigners = append(filterSigners, masternode)
break
// Get block epoc latest.
lastCheckpointNumber := signedBlockNumber - (signedBlockNumber % s.b.ChainConfig().XDPoS.Epoch)
prevCheckpointBlock, _ := s.b.BlockByNumber(ctx, rpc.BlockNumber(lastCheckpointNumber))
if prevCheckpointBlock != nil {
masternodes := engine.GetMasternodesFromCheckpointHeader(prevCheckpointBlock.Header(), blockNumber, s.b.ChainConfig().XDPoS.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())
}
if err != nil {
log.Error("Fail to get signers from block signer SC.", "error", err)
return nil, err
}
validator, _ := engine.RecoverValidator(b.Header())
creator, _ := engine.RecoverSigner(b.Header())
signers = append(signers, validator)
signers = append(signers, creator)
countFinality := 0
for _, masternode := range masternodes {
for _, signer := range signers {
if signer == masternode {
countFinality++
filterSigners = append(filterSigners, masternode)
break
}
}
}
}
@ -1617,4 +1624,53 @@ func (s *PublicNetAPI) PeerCount() hexutil.Uint {
// Version returns the current ethereum protocol version.
func (s *PublicNetAPI) Version() string {
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().(*XDPoS.XDPoS); ok {
limitNumber := blockNumber - blockNumber%b.ChainConfig().XDPoS.Epoch + 2*b.ChainConfig().XDPoS.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
}

View file

@ -18,6 +18,7 @@ package miner
import (
"bytes"
"encoding/binary"
"fmt"
"math/big"
"os"
@ -583,6 +584,9 @@ 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) {
work.state.DeleteAddress(common.HexToAddress(common.BlockSigners))
}
// won't grasp txs at checkpoint
var (
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)
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.XDPoS.Epoch*2 {
log.Trace("Data special transaction invalid number", "hash", tx.Hash(), "blkNumber", blkNumber, "miner", env.header.Number)
continue
}
}
// Start executing the transaction
env.state.Prepare(tx.Hash(), common.Hash{}, env.tcount)
nonce := env.state.GetNonce(from)

View file

@ -217,6 +217,10 @@ 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)
}
// 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.