forked from cerc-io/plugeth
core, miner: added value check on tx validation
* Changed CalcGasLimit to no longer need current block * Added a gas * price + value on tx validation * Transactions in the pool are now re-validated once every X
This commit is contained in:
parent
8d09f95bc7
commit
145e02fc54
@ -64,7 +64,7 @@ func newBlockFromParent(addr common.Address, parent *types.Block) *types.Block {
|
|||||||
header.Difficulty = CalcDifficulty(block.Header(), parent.Header())
|
header.Difficulty = CalcDifficulty(block.Header(), parent.Header())
|
||||||
header.Number = new(big.Int).Add(parent.Header().Number, common.Big1)
|
header.Number = new(big.Int).Add(parent.Header().Number, common.Big1)
|
||||||
header.Time = parent.Header().Time + 10
|
header.Time = parent.Header().Time + 10
|
||||||
header.GasLimit = CalcGasLimit(parent, block)
|
header.GasLimit = CalcGasLimit(parent)
|
||||||
|
|
||||||
block.Td = parent.Td
|
block.Td = parent.Td
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ func makeBlock(bman *BlockProcessor, parent *types.Block, i int, db common.Datab
|
|||||||
block := newBlockFromParent(addr, parent)
|
block := newBlockFromParent(addr, parent)
|
||||||
state := state.New(block.Root(), db)
|
state := state.New(block.Root(), db)
|
||||||
cbase := state.GetOrNewStateObject(addr)
|
cbase := state.GetOrNewStateObject(addr)
|
||||||
cbase.SetGasPool(CalcGasLimit(parent, block))
|
cbase.SetGasPool(CalcGasLimit(parent))
|
||||||
cbase.AddBalance(BlockReward)
|
cbase.AddBalance(BlockReward)
|
||||||
state.Update()
|
state.Update()
|
||||||
block.SetRoot(state.Root())
|
block.SetRoot(state.Root())
|
||||||
|
@ -54,11 +54,7 @@ func CalculateTD(block, parent *types.Block) *big.Int {
|
|||||||
return td
|
return td
|
||||||
}
|
}
|
||||||
|
|
||||||
func CalcGasLimit(parent, block *types.Block) *big.Int {
|
func CalcGasLimit(parent *types.Block) *big.Int {
|
||||||
if block.Number().Cmp(big.NewInt(0)) == 0 {
|
|
||||||
return common.BigPow(10, 6)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ((1024-1) * parent.gasLimit + (gasUsed * 6 / 5)) / 1024
|
// ((1024-1) * parent.gasLimit + (gasUsed * 6 / 5)) / 1024
|
||||||
previous := new(big.Int).Mul(big.NewInt(1024-1), parent.GasLimit())
|
previous := new(big.Int).Mul(big.NewInt(1024-1), parent.GasLimit())
|
||||||
current := new(big.Rat).Mul(new(big.Rat).SetInt(parent.GasUsed()), big.NewRat(6, 5))
|
current := new(big.Rat).Mul(new(big.Rat).SetInt(parent.GasUsed()), big.NewRat(6, 5))
|
||||||
@ -277,7 +273,7 @@ func (bc *ChainManager) NewBlock(coinbase common.Address) *types.Block {
|
|||||||
header := block.Header()
|
header := block.Header()
|
||||||
header.Difficulty = CalcDifficulty(block.Header(), parent.Header())
|
header.Difficulty = CalcDifficulty(block.Header(), parent.Header())
|
||||||
header.Number = new(big.Int).Add(parent.Header().Number, common.Big1)
|
header.Number = new(big.Int).Add(parent.Header().Number, common.Big1)
|
||||||
header.GasLimit = CalcGasLimit(parent, block)
|
header.GasLimit = CalcGasLimit(parent)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -658,7 +654,7 @@ out:
|
|||||||
// We need some control over the mining operation. Acquiring locks and waiting for the miner to create new block takes too long
|
// We need some control over the mining operation. Acquiring locks and waiting for the miner to create new block takes too long
|
||||||
// and in most cases isn't even necessary.
|
// and in most cases isn't even necessary.
|
||||||
if i+1 == ev.canonicalCount {
|
if i+1 == ev.canonicalCount {
|
||||||
self.currentGasLimit = CalcGasLimit(self.GetBlock(event.Block.ParentHash()), event.Block)
|
self.currentGasLimit = CalcGasLimit(event.Block)
|
||||||
self.eventMux.Post(ChainHeadEvent{event.Block})
|
self.eventMux.Post(ChainHeadEvent{event.Block})
|
||||||
}
|
}
|
||||||
case ChainSplitEvent:
|
case ChainSplitEvent:
|
||||||
|
@ -20,8 +20,9 @@ import (
|
|||||||
var (
|
var (
|
||||||
ErrInvalidSender = errors.New("Invalid sender")
|
ErrInvalidSender = errors.New("Invalid sender")
|
||||||
ErrNonce = errors.New("Nonce too low")
|
ErrNonce = errors.New("Nonce too low")
|
||||||
|
ErrBalance = errors.New("Insufficient balance")
|
||||||
ErrNonExistentAccount = errors.New("Account does not exist")
|
ErrNonExistentAccount = errors.New("Account does not exist")
|
||||||
ErrInsufficientFunds = errors.New("Insufficient funds")
|
ErrInsufficientFunds = errors.New("Insufficient funds for gas * price + value")
|
||||||
ErrIntrinsicGas = errors.New("Intrinsic gas too low")
|
ErrIntrinsicGas = errors.New("Intrinsic gas too low")
|
||||||
ErrGasLimit = errors.New("Exceeds block gas limit")
|
ErrGasLimit = errors.New("Exceeds block gas limit")
|
||||||
)
|
)
|
||||||
@ -124,7 +125,9 @@ func (pool *TxPool) ValidateTransaction(tx *types.Transaction) error {
|
|||||||
return ErrGasLimit
|
return ErrGasLimit
|
||||||
}
|
}
|
||||||
|
|
||||||
if pool.currentState().GetBalance(from).Cmp(new(big.Int).Mul(tx.Price, tx.GasLimit)) < 0 {
|
total := new(big.Int).Mul(tx.Price, tx.GasLimit)
|
||||||
|
total.Add(total, tx.Value())
|
||||||
|
if pool.currentState().GetBalance(from).Cmp(total) < 0 {
|
||||||
return ErrInsufficientFunds
|
return ErrInsufficientFunds
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,7 +196,7 @@ func (self *TxPool) AddTransactions(txs []*types.Transaction) {
|
|||||||
|
|
||||||
for _, tx := range txs {
|
for _, tx := range txs {
|
||||||
if err := self.add(tx); err != nil {
|
if err := self.add(tx); err != nil {
|
||||||
glog.V(logger.Debug).Infoln(err)
|
glog.V(logger.Debug).Infoln("tx error:", err)
|
||||||
} else {
|
} else {
|
||||||
h := tx.Hash()
|
h := tx.Hash()
|
||||||
glog.V(logger.Debug).Infof("tx %x\n", h[:4])
|
glog.V(logger.Debug).Infof("tx %x\n", h[:4])
|
||||||
@ -296,7 +299,6 @@ func (pool *TxPool) checkQueue() {
|
|||||||
|
|
||||||
pool.addTx(tx)
|
pool.addTx(tx)
|
||||||
}
|
}
|
||||||
//pool.queue[address] = txs[i:]
|
|
||||||
// delete the entire queue entry if it's empty. There's no need to keep it
|
// delete the entire queue entry if it's empty. There's no need to keep it
|
||||||
if len(pool.queue[address]) == 0 {
|
if len(pool.queue[address]) == 0 {
|
||||||
delete(pool.queue, address)
|
delete(pool.queue, address)
|
||||||
@ -308,12 +310,10 @@ func (pool *TxPool) validatePool() {
|
|||||||
pool.mu.Lock()
|
pool.mu.Lock()
|
||||||
defer pool.mu.Unlock()
|
defer pool.mu.Unlock()
|
||||||
|
|
||||||
statedb := pool.currentState()
|
|
||||||
for hash, tx := range pool.txs {
|
for hash, tx := range pool.txs {
|
||||||
from, _ := tx.From()
|
if err := pool.ValidateTransaction(tx); err != nil {
|
||||||
if nonce := statedb.GetNonce(from); nonce > tx.Nonce() {
|
if glog.V(logger.Info) {
|
||||||
if glog.V(logger.Debug) {
|
glog.Infof("removed tx (%x) from pool: %v\n", hash[:4], err)
|
||||||
glog.Infof("removed tx (%x) from pool due to nonce error. state=%d tx=%d\n", hash[:4], nonce, tx.Nonce())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(pool.txs, hash)
|
delete(pool.txs, hash)
|
||||||
|
@ -43,10 +43,11 @@ func TestInvalidTransactions(t *testing.T) {
|
|||||||
t.Error("expected", ErrInsufficientFunds)
|
t.Error("expected", ErrInsufficientFunds)
|
||||||
}
|
}
|
||||||
|
|
||||||
pool.currentState().AddBalance(from, big.NewInt(100*100))
|
balance := new(big.Int).Add(tx.Value(), new(big.Int).Mul(tx.Gas(), tx.GasPrice()))
|
||||||
|
pool.currentState().AddBalance(from, balance)
|
||||||
err = pool.Add(tx)
|
err = pool.Add(tx)
|
||||||
if err != ErrIntrinsicGas {
|
if err != ErrIntrinsicGas {
|
||||||
t.Error("expected", ErrIntrinsicGas)
|
t.Error("expected", ErrIntrinsicGas, "got", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
pool.currentState().SetNonce(from, 1)
|
pool.currentState().SetNonce(from, 1)
|
||||||
|
@ -236,7 +236,7 @@ func (self *worker) makeCurrent() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
parent := self.chain.GetBlock(self.current.block.ParentHash())
|
parent := self.chain.GetBlock(self.current.block.ParentHash())
|
||||||
self.current.coinbase.SetGasPool(core.CalcGasLimit(parent, self.current.block))
|
self.current.coinbase.SetGasPool(core.CalcGasLimit(parent))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *worker) commitNewWork() {
|
func (self *worker) commitNewWork() {
|
||||||
|
Loading…
Reference in New Issue
Block a user