forked from cerc-io/plugeth
Merge branch 'develop' into interop
Conflicts: peer.go
This commit is contained in:
commit
8a2e50ab2a
@ -154,6 +154,36 @@ func (block *Block) PayFee(addr []byte, fee *big.Int) bool {
|
|||||||
return true
|
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 {
|
func (block *Block) BlockInfo() BlockInfo {
|
||||||
bi := BlockInfo{}
|
bi := BlockInfo{}
|
||||||
data, _ := ethutil.Config.Db.Get(append(block.Hash(), []byte("Info")...))
|
data, _ := ethutil.Config.Db.Get(append(block.Hash(), []byte("Info")...))
|
||||||
|
@ -72,19 +72,7 @@ func (bc *BlockChain) NewBlock(coinbase []byte) *Block {
|
|||||||
|
|
||||||
block.Number = new(big.Int).Add(bc.CurrentBlock.Number, ethutil.Big1)
|
block.Number = new(big.Int).Add(bc.CurrentBlock.Number, ethutil.Big1)
|
||||||
|
|
||||||
// max(10000, (parent gas limit * (1024 - 1) + (parent gas used * 6 / 5)) / 1024)
|
block.GasLimit = block.CalcGasLimit(bc.CurrentBlock)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return block
|
return block
|
||||||
|
@ -2,6 +2,7 @@ package ethchain
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/big"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Parent error. In case a parent is unknown this error will be thrown
|
// Parent error. In case a parent is unknown this error will be thrown
|
||||||
@ -43,6 +44,23 @@ func IsValidationErr(err error) bool {
|
|||||||
return ok
|
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 {
|
type NonceErr struct {
|
||||||
Message string
|
Message string
|
||||||
Is, Exp uint64
|
Is, Exp uint64
|
||||||
|
@ -188,6 +188,8 @@ func (sm *StateManager) ApplyTransactions(coinbase []byte, state *State, block *
|
|||||||
// Process each transaction/contract
|
// Process each transaction/contract
|
||||||
var receipts []*Receipt
|
var receipts []*Receipt
|
||||||
var validTxs []*Transaction
|
var validTxs []*Transaction
|
||||||
|
var ignoredTxs []*Transaction // Transactions which go over the gasLimit
|
||||||
|
|
||||||
totalUsedGas := big.NewInt(0)
|
totalUsedGas := big.NewInt(0)
|
||||||
|
|
||||||
for _, tx := range txs {
|
for _, tx := range txs {
|
||||||
@ -196,6 +198,12 @@ func (sm *StateManager) ApplyTransactions(coinbase []byte, state *State, block *
|
|||||||
if IsNonceErr(err) {
|
if IsNonceErr(err) {
|
||||||
continue
|
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)
|
ethutil.Config.Log.Infoln(err)
|
||||||
}
|
}
|
||||||
@ -207,6 +215,9 @@ func (sm *StateManager) ApplyTransactions(coinbase []byte, state *State, block *
|
|||||||
validTxs = append(validTxs, tx)
|
validTxs = append(validTxs, tx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the total gas used for the block (to be mined)
|
||||||
|
block.GasUsed = totalUsedGas
|
||||||
|
|
||||||
return receipts, validTxs
|
return receipts, validTxs
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,6 +237,7 @@ func (sm *StateManager) ApplyTransaction(coinbase []byte, state *State, block *B
|
|||||||
script []byte
|
script []byte
|
||||||
)
|
)
|
||||||
totalGasUsed = big.NewInt(0)
|
totalGasUsed = big.NewInt(0)
|
||||||
|
snapshot := state.Snapshot()
|
||||||
|
|
||||||
ca := state.GetAccount(coinbase)
|
ca := state.GetAccount(coinbase)
|
||||||
// Apply the transaction to the current state
|
// 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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ type TxMsgTy byte
|
|||||||
const (
|
const (
|
||||||
TxPre = iota
|
TxPre = iota
|
||||||
TxPost
|
TxPost
|
||||||
|
minGasPrice = 1000000
|
||||||
)
|
)
|
||||||
|
|
||||||
type TxMsg struct {
|
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())
|
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
|
// Increment the nonce making each tx valid only once to prevent replay
|
||||||
// attacks
|
// attacks
|
||||||
|
|
||||||
|
@ -46,6 +46,8 @@ type PBlock struct {
|
|||||||
Transactions string `json:"transactions"`
|
Transactions string `json:"transactions"`
|
||||||
Time int64 `json:"time"`
|
Time int64 `json:"time"`
|
||||||
Coinbase string `json:"coinbase"`
|
Coinbase string `json:"coinbase"`
|
||||||
|
GasLimit string `json:"gasLimit"`
|
||||||
|
GasUsed string `json:"gasUsed"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a new QML Block from a chain block
|
// Creates a new QML Block from a chain block
|
||||||
@ -64,7 +66,7 @@ func NewPBlock(block *ethchain.Block) *PBlock {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return &PBlock{ref: block, Number: int(block.Number.Uint64()), Hash: ethutil.Hex(block.Hash()), Transactions: string(txJson), Time: block.Time, Coinbase: ethutil.Hex(block.Coinbase)}
|
return &PBlock{ref: block, Number: int(block.Number.Uint64()), GasUsed: block.GasUsed.String(), GasLimit: block.GasLimit.String(), Hash: ethutil.Hex(block.Hash()), Transactions: string(txJson), Time: block.Time, Coinbase: ethutil.Hex(block.Coinbase)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *PBlock) ToString() string {
|
func (self *PBlock) ToString() string {
|
||||||
|
@ -68,8 +68,8 @@ func BigCopy(src *big.Int) *big.Int {
|
|||||||
// Returns the maximum size big integer
|
// Returns the maximum size big integer
|
||||||
func BigMax(x, y *big.Int) *big.Int {
|
func BigMax(x, y *big.Int) *big.Int {
|
||||||
if x.Cmp(y) <= 0 {
|
if x.Cmp(y) <= 0 {
|
||||||
return x
|
|
||||||
}
|
|
||||||
|
|
||||||
return y
|
return y
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
@ -18,8 +18,8 @@ var (
|
|||||||
Wei = big.NewInt(1)
|
Wei = big.NewInt(1)
|
||||||
)
|
)
|
||||||
|
|
||||||
// Currency to string
|
|
||||||
//
|
//
|
||||||
|
// Currency to string
|
||||||
// Returns a string representing a human readable format
|
// Returns a string representing a human readable format
|
||||||
func CurrencyToString(num *big.Int) string {
|
func CurrencyToString(num *big.Int) string {
|
||||||
switch {
|
switch {
|
||||||
|
14
peer.go
14
peer.go
@ -18,6 +18,8 @@ const (
|
|||||||
outputBufferSize = 50
|
outputBufferSize = 50
|
||||||
// Current protocol version
|
// Current protocol version
|
||||||
ProtocolVersion = 20
|
ProtocolVersion = 20
|
||||||
|
// Interval for ping/pong message
|
||||||
|
pingPongTimer = 30 * time.Second
|
||||||
)
|
)
|
||||||
|
|
||||||
type DiscReason byte
|
type DiscReason byte
|
||||||
@ -243,7 +245,7 @@ func (p *Peer) writeMessage(msg *ethwire.Msg) {
|
|||||||
|
|
||||||
err := ethwire.WriteMessage(p.conn, msg)
|
err := ethwire.WriteMessage(p.conn, msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ethutil.Config.Log.Debugln("Can't send message:", err)
|
ethutil.Config.Log.Debugln("[PEER] Can't send message:", err)
|
||||||
// Stop the client if there was an error writing to it
|
// Stop the client if there was an error writing to it
|
||||||
p.Stop()
|
p.Stop()
|
||||||
return
|
return
|
||||||
@ -253,7 +255,7 @@ func (p *Peer) writeMessage(msg *ethwire.Msg) {
|
|||||||
// Outbound message handler. Outbound messages are handled here
|
// Outbound message handler. Outbound messages are handled here
|
||||||
func (p *Peer) HandleOutbound() {
|
func (p *Peer) HandleOutbound() {
|
||||||
// The ping timer. Makes sure that every 2 minutes a ping is send to the peer
|
// The ping timer. Makes sure that every 2 minutes a ping is send to the peer
|
||||||
pingTimer := time.NewTicker(30 * time.Second)
|
pingTimer := time.NewTicker(pingPongTimer)
|
||||||
serviceTimer := time.NewTicker(5 * time.Minute)
|
serviceTimer := time.NewTicker(5 * time.Minute)
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@ -264,8 +266,14 @@ out:
|
|||||||
p.writeMessage(msg)
|
p.writeMessage(msg)
|
||||||
p.lastSend = time.Now()
|
p.lastSend = time.Now()
|
||||||
|
|
||||||
// Ping timer sends a ping to the peer each 2 minutes
|
// Ping timer
|
||||||
case <-pingTimer.C:
|
case <-pingTimer.C:
|
||||||
|
timeSince := time.Since(time.Unix(p.lastPong, 0))
|
||||||
|
if p.pingStartTime.IsZero() == false && timeSince > (pingPongTimer+10*time.Second) {
|
||||||
|
ethutil.Config.Log.Infof("[PEER] Peer did not respond to latest pong fast enough, it took %s, disconnecting.\n", timeSince)
|
||||||
|
p.Stop()
|
||||||
|
return
|
||||||
|
}
|
||||||
p.writeMessage(ethwire.NewMessage(ethwire.MsgPingTy, ""))
|
p.writeMessage(ethwire.NewMessage(ethwire.MsgPingTy, ""))
|
||||||
p.pingStartTime = time.Now()
|
p.pingStartTime = time.Now()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user