aboutsummaryrefslogtreecommitdiffstats
path: root/ethchain
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2014-06-12 03:56:59 +0800
committerobscuren <geffobscura@gmail.com>2014-06-12 03:56:59 +0800
commit8a2e50ab2a6c903a6ab3ab10a74c37e1f3b8f3f1 (patch)
tree3cf67a559ef450500ddfd7df9d457f3e1a994caf /ethchain
parent9ee6295c752a518603de01e4feaec787c61a5dcf (diff)
parent1938bfcddfd2722880a692c59cad344b611711c8 (diff)
downloaddexon-8a2e50ab2a6c903a6ab3ab10a74c37e1f3b8f3f1.tar.gz
dexon-8a2e50ab2a6c903a6ab3ab10a74c37e1f3b8f3f1.tar.zst
dexon-8a2e50ab2a6c903a6ab3ab10a74c37e1f3b8f3f1.zip
Merge branch 'develop' into interop
Conflicts: peer.go
Diffstat (limited to 'ethchain')
-rw-r--r--ethchain/block.go30
-rw-r--r--ethchain/block_chain.go14
-rw-r--r--ethchain/error.go18
-rw-r--r--ethchain/state_manager.go20
-rw-r--r--ethchain/transaction_pool.go7
5 files changed, 76 insertions, 13 deletions
diff --git a/ethchain/block.go b/ethchain/block.go
index 73e29f878..fee4a2d59 100644
--- a/ethchain/block.go
+++ b/ethchain/block.go
@@ -154,6 +154,36 @@ func (block *Block) PayFee(addr []byte, fee *big.Int) bool {
return true
}
+func (block *Block) CalcGasLimit(parent *Block) *big.Int {
+ if block.Number.Cmp(big.NewInt(0)) == 0 {
+ return ethutil.BigPow(10, 6)
+ }
+
+ previous := new(big.Int).Mul(big.NewInt(1023), parent.GasLimit)
+ current := new(big.Rat).Mul(new(big.Rat).SetInt(block.GasUsed), big.NewRat(6, 5))
+ curInt := new(big.Int).Div(current.Num(), current.Denom())
+
+ result := new(big.Int).Add(previous, curInt)
+ result.Div(result, big.NewInt(1024))
+
+ min := ethutil.BigPow(10, 4)
+
+ return ethutil.BigMax(min, result)
+ /*
+ base := new(big.Int)
+ base2 := new(big.Int)
+ parentGL := bc.CurrentBlock.GasLimit
+ parentUsed := bc.CurrentBlock.GasUsed
+
+ base.Mul(parentGL, big.NewInt(1024-1))
+ base2.Mul(parentUsed, big.NewInt(6))
+ base2.Div(base2, big.NewInt(5))
+ base.Add(base, base2)
+ base.Div(base, big.NewInt(1024))
+ */
+
+}
+
func (block *Block) BlockInfo() BlockInfo {
bi := BlockInfo{}
data, _ := ethutil.Config.Db.Get(append(block.Hash(), []byte("Info")...))
diff --git a/ethchain/block_chain.go b/ethchain/block_chain.go
index 68ef9d47e..8cede2403 100644
--- a/ethchain/block_chain.go
+++ b/ethchain/block_chain.go
@@ -72,19 +72,7 @@ func (bc *BlockChain) NewBlock(coinbase []byte) *Block {
block.Number = new(big.Int).Add(bc.CurrentBlock.Number, ethutil.Big1)
- // max(10000, (parent gas limit * (1024 - 1) + (parent gas used * 6 / 5)) / 1024)
- base := new(big.Int)
- base2 := new(big.Int)
- parentGL := bc.CurrentBlock.GasLimit
- parentUsed := bc.CurrentBlock.GasUsed
-
- base.Mul(parentGL, big.NewInt(1024-1))
- base2.Mul(parentUsed, big.NewInt(6))
- base2.Div(base2, big.NewInt(5))
- base.Add(base, base2)
- base.Div(base, big.NewInt(1024))
-
- block.GasLimit = ethutil.BigMax(big.NewInt(10000), base)
+ block.GasLimit = block.CalcGasLimit(bc.CurrentBlock)
}
return block
diff --git a/ethchain/error.go b/ethchain/error.go
index 8d37b0208..29896bc59 100644
--- a/ethchain/error.go
+++ b/ethchain/error.go
@@ -2,6 +2,7 @@ package ethchain
import (
"fmt"
+ "math/big"
)
// Parent error. In case a parent is unknown this error will be thrown
@@ -43,6 +44,23 @@ func IsValidationErr(err error) bool {
return ok
}
+type GasLimitErr struct {
+ Message string
+ Is, Max *big.Int
+}
+
+func IsGasLimitErr(err error) bool {
+ _, ok := err.(*GasLimitErr)
+
+ return ok
+}
+func (err *GasLimitErr) Error() string {
+ return err.Message
+}
+func GasLimitError(is, max *big.Int) *GasLimitErr {
+ return &GasLimitErr{Message: fmt.Sprintf("GasLimit error. Max %s, transaction would take it to %s", max, is), Is: is, Max: max}
+}
+
type NonceErr struct {
Message string
Is, Exp uint64
diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go
index e783ffdd8..9631b55fe 100644
--- a/ethchain/state_manager.go
+++ b/ethchain/state_manager.go
@@ -188,6 +188,8 @@ func (sm *StateManager) ApplyTransactions(coinbase []byte, state *State, block *
// Process each transaction/contract
var receipts []*Receipt
var validTxs []*Transaction
+ var ignoredTxs []*Transaction // Transactions which go over the gasLimit
+
totalUsedGas := big.NewInt(0)
for _, tx := range txs {
@@ -196,6 +198,12 @@ func (sm *StateManager) ApplyTransactions(coinbase []byte, state *State, block *
if IsNonceErr(err) {
continue
}
+ if IsGasLimitErr(err) {
+ ignoredTxs = append(ignoredTxs, tx)
+ // We need to figure out if we want to do something with thse txes
+ ethutil.Config.Log.Debugln("Gastlimit:", err)
+ continue
+ }
ethutil.Config.Log.Infoln(err)
}
@@ -207,6 +215,9 @@ func (sm *StateManager) ApplyTransactions(coinbase []byte, state *State, block *
validTxs = append(validTxs, tx)
}
+ // Update the total gas used for the block (to be mined)
+ block.GasUsed = totalUsedGas
+
return receipts, validTxs
}
@@ -226,6 +237,7 @@ func (sm *StateManager) ApplyTransaction(coinbase []byte, state *State, block *B
script []byte
)
totalGasUsed = big.NewInt(0)
+ snapshot := state.Snapshot()
ca := state.GetAccount(coinbase)
// Apply the transaction to the current state
@@ -266,6 +278,14 @@ func (sm *StateManager) ApplyTransaction(coinbase []byte, state *State, block *B
}
}
+ parent := sm.bc.GetBlock(block.PrevHash)
+ total := new(big.Int).Add(block.GasUsed, totalGasUsed)
+ limit := block.CalcGasLimit(parent)
+ if total.Cmp(limit) > 0 {
+ state.Revert(snapshot)
+ err = GasLimitError(total, limit)
+ }
+
return
}
diff --git a/ethchain/transaction_pool.go b/ethchain/transaction_pool.go
index bc7bde797..6220f29a3 100644
--- a/ethchain/transaction_pool.go
+++ b/ethchain/transaction_pool.go
@@ -22,6 +22,7 @@ type TxMsgTy byte
const (
TxPre = iota
TxPost
+ minGasPrice = 1000000
)
type TxMsg struct {
@@ -181,6 +182,12 @@ func (pool *TxPool) ValidateTransaction(tx *Transaction) error {
return fmt.Errorf("[TXPL] Insufficient amount in sender's (%x) account", tx.Sender())
}
+ if tx.IsContract() {
+ if tx.GasPrice.Cmp(big.NewInt(minGasPrice)) < 0 {
+ return fmt.Errorf("[TXPL] Gasprice to low, %s given should be at least %d.", tx.GasPrice, minGasPrice)
+ }
+ }
+
// Increment the nonce making each tx valid only once to prevent replay
// attacks