mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-19 21:31:37 +00:00
Core Updated
This commit is contained in:
parent
7de9cee4fb
commit
bf626ddc95
6 changed files with 95 additions and 21 deletions
|
|
@ -48,7 +48,6 @@ func TestHeaderVerification(t *testing.T) {
|
|||
for i := 0; i < len(blocks); i++ {
|
||||
for j, valid := range []bool{true, false} {
|
||||
var results <-chan error
|
||||
|
||||
if valid {
|
||||
engine := ethash.NewFaker()
|
||||
_, results = engine.VerifyHeaders(chain, []*types.Header{headers[i]}, []bool{true})
|
||||
|
|
@ -104,7 +103,6 @@ func testHeaderConcurrentVerification(t *testing.T, threads int) {
|
|||
// also an invalid chain (enough if one arbitrary block is invalid).
|
||||
for i, valid := range []bool{true, false} {
|
||||
var results <-chan error
|
||||
|
||||
if valid {
|
||||
chain, _ := NewBlockChain(testdb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{})
|
||||
_, results = chain.engine.VerifyHeaders(chain, headers, seals)
|
||||
|
|
@ -175,7 +173,6 @@ func testHeaderConcurrentAbortion(t *testing.T, threads int) {
|
|||
// Start the verifications and immediately abort
|
||||
chain, _ := NewBlockChain(testdb, nil, params.TestChainConfig, ethash.NewFakeDelayer(time.Millisecond), vm.Config{})
|
||||
defer chain.Stop()
|
||||
|
||||
abort, results := chain.engine.VerifyHeaders(chain, headers, seals)
|
||||
close(abort)
|
||||
|
||||
|
|
|
|||
|
|
@ -141,10 +141,9 @@ type BlockChain struct {
|
|||
validator Validator // block and state validator interface
|
||||
vmConfig vm.Config
|
||||
|
||||
badBlocks *lru.Cache // Bad block cache
|
||||
IPCEndpoint string
|
||||
Client *ethclient.Client // Global ipc client instance.
|
||||
HookWriteRewards func(header *types.Header)
|
||||
badBlocks *lru.Cache // Bad block cache
|
||||
IPCEndpoint string
|
||||
Client *ethclient.Client // Global ipc client instance.
|
||||
}
|
||||
|
||||
// NewBlockChain returns a fully initialised block chain using information
|
||||
|
|
@ -507,6 +506,12 @@ func (bc *BlockChain) insert(block *types.Block) {
|
|||
}
|
||||
bc.currentBlock.Store(block)
|
||||
|
||||
// save cache BlockSigners
|
||||
if bc.chainConfig.XDPoS != nil && !bc.chainConfig.IsTIPSigning(block.Number()) {
|
||||
engine := bc.Engine().(*XDPoS.XDPoS)
|
||||
engine.CacheData(block.Header(), block.Transactions(), bc.GetReceiptsByHash(block.Hash()))
|
||||
}
|
||||
|
||||
// If the block is better than our head or is on a different chain, force update heads
|
||||
if updateHeads {
|
||||
bc.hc.SetCurrentHeader(block.Header())
|
||||
|
|
@ -1014,6 +1019,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.IsTIPSigning(block.Number()) {
|
||||
engine := bc.Engine().(*XDPoS.XDPoS)
|
||||
engine.CacheSigner(block.Header().Hash(), block.Transactions())
|
||||
}
|
||||
bc.futureBlocks.Remove(block.Hash())
|
||||
return status, nil
|
||||
}
|
||||
|
|
@ -1067,7 +1077,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty
|
|||
|
||||
for i, block := range chain {
|
||||
headers[i] = block.Header()
|
||||
seals[i] = true
|
||||
seals[i] = false
|
||||
bc.downloadingBlock.Add(block.Hash(), true)
|
||||
}
|
||||
abort, results := bc.engine.VerifyHeaders(bc, headers, seals)
|
||||
|
|
@ -1222,9 +1232,6 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty
|
|||
}
|
||||
}
|
||||
}
|
||||
if bc.HookWriteRewards != nil {
|
||||
bc.HookWriteRewards(block.Header())
|
||||
}
|
||||
}
|
||||
// Append a single chain head event if we've progressed the chain
|
||||
if lastCanon != nil && bc.CurrentBlock().Hash() == lastCanon.Hash() {
|
||||
|
|
@ -1431,9 +1438,6 @@ func (bc *BlockChain) insertBlock(block *types.Block) ([]interface{}, []*types.L
|
|||
events = append(events, ChainHeadEvent{block})
|
||||
log.Debug("New ChainHeadEvent from fetcher ", "number", block.NumberU64(), "hash", block.Hash())
|
||||
}
|
||||
if bc.HookWriteRewards != nil {
|
||||
bc.HookWriteRewards(block.Header())
|
||||
}
|
||||
return events, coalescedLogs, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 common.TIPSigning.Cmp(header.Number) == 0 {
|
||||
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 common.TIPSigning.Cmp(header.Number) == 0 {
|
||||
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.IsTIPSigning(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)
|
||||
|
|
|
|||
|
|
@ -229,15 +229,22 @@ func (st *StateTransition) TransitionDb() (ret []byte, usedGas uint64, failed bo
|
|||
// error.
|
||||
vmerr error
|
||||
)
|
||||
// for debugging purpose
|
||||
// TODO: clean it after fixing the issue https://github.com/XDCchain/XDCchain/issues/401
|
||||
var contractAction string
|
||||
nonce := uint64(1)
|
||||
if contractCreation {
|
||||
ret, _, st.gas, vmerr = evm.Create(sender, st.data, st.gas, st.value)
|
||||
contractAction = "contract creation"
|
||||
} else {
|
||||
// Increment the nonce for the next transaction
|
||||
st.state.SetNonce(sender.Address(), st.state.GetNonce(sender.Address())+1)
|
||||
nonce = st.state.GetNonce(sender.Address()) + 1
|
||||
st.state.SetNonce(sender.Address(), nonce)
|
||||
ret, st.gas, vmerr = evm.Call(sender, st.to().Address(), st.data, st.gas, st.value)
|
||||
contractAction = "contract call"
|
||||
}
|
||||
if vmerr != nil {
|
||||
log.Debug("VM returned with error", "err", vmerr)
|
||||
log.Debug("VM returned with error", "action", contractAction, "contract address", st.to().Address(), "gas", st.gas, "gasPrice", st.gasPrice, "nonce", nonce, "err", vmerr)
|
||||
// The only possible consensus-error would be if there wasn't
|
||||
// sufficient balance to make the transfer happen. The first
|
||||
// balance transfer may never fail.
|
||||
|
|
|
|||
|
|
@ -81,7 +81,11 @@ var (
|
|||
|
||||
ErrZeroGasPrice = errors.New("zero gas price")
|
||||
|
||||
ErrUnderMinGasPrice = errors.New("under min gas price")
|
||||
|
||||
ErrDuplicateSpecialTransaction = errors.New("duplicate a special transaction")
|
||||
|
||||
ErrMinDeploySMC = errors.New("smart contract creation cost is under allowance")
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -214,8 +218,8 @@ type TxPool struct {
|
|||
|
||||
wg sync.WaitGroup // for shutdown sync
|
||||
|
||||
homestead bool
|
||||
IsMasterNode func(address common.Address) bool
|
||||
homestead bool
|
||||
IsSigner func(address common.Address) bool
|
||||
}
|
||||
|
||||
// NewTxPool creates a new transaction pool to gather, sort and filter inbound
|
||||
|
|
@ -587,8 +591,8 @@ 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 && tx.To() != nil && pool.gasPrice.Cmp(tx.GasPrice()) > 0 {
|
||||
if !tx.IsSpecialTransaction() || (pool.IsMasterNode != nil && !pool.IsMasterNode(from)) {
|
||||
if !local && pool.gasPrice.Cmp(tx.GasPrice()) > 0 {
|
||||
if !tx.IsSpecialTransaction() || (pool.IsSigner != nil && !pool.IsSigner(from)) {
|
||||
return ErrUnderpriced
|
||||
}
|
||||
}
|
||||
|
|
@ -619,6 +623,16 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error {
|
|||
if tx.GasPrice().Cmp(new(big.Int).SetInt64(0)) == 0 {
|
||||
return ErrZeroGasPrice
|
||||
}
|
||||
|
||||
// under min gas price
|
||||
if tx.GasPrice().Cmp(new(big.Int).SetInt64(common.MinGasPrice)) < 0 {
|
||||
return ErrUnderMinGasPrice
|
||||
}
|
||||
}
|
||||
|
||||
minGasDeploySMC := new(big.Int).Mul(new(big.Int).SetUint64(10), new(big.Int).SetUint64(params.Ether))
|
||||
if tx.To() == nil && (tx.Cost().Cmp(minGasDeploySMC) < 0 || tx.GasPrice().Cmp(new(big.Int).SetUint64(10000*params.Shannon)) < 0) {
|
||||
return ErrMinDeploySMC
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
@ -647,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
|
||||
|
|
|
|||
Loading…
Reference in a new issue