mirror of https://github.com/poanetwork/quorum.git
Merge pull request #4 from bas-vk/zero-gasprice
cmd,eth enforce gas price of 0
This commit is contained in:
commit
b545f51c3c
|
@ -22,6 +22,8 @@ import (
|
|||
"io"
|
||||
"io/ioutil"
|
||||
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
|
@ -58,5 +60,6 @@ func NewKeyedTransactor(key *ecdsa.PrivateKey) *TransactOpts {
|
|||
}
|
||||
return tx.WithSignature(signature)
|
||||
},
|
||||
GasPrice: new(big.Int),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -207,9 +207,9 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i
|
|||
// Create the transaction, sign it and schedule it for execution
|
||||
var rawTx *types.Transaction
|
||||
if contract == nil {
|
||||
rawTx = types.NewContractCreation(nonce, value, gasLimit, gasPrice, input)
|
||||
rawTx = types.NewContractCreation(nonce, value, gasLimit, nil, input)
|
||||
} else {
|
||||
rawTx = types.NewTransaction(nonce, c.address, value, gasLimit, gasPrice, input)
|
||||
rawTx = types.NewTransaction(nonce, c.address, value, gasLimit, nil, input)
|
||||
}
|
||||
if opts.Signer == nil {
|
||||
return nil, errors.New("no signer to authorize the transaction with")
|
||||
|
|
|
@ -59,7 +59,7 @@ func TestWaitDeployed(t *testing.T) {
|
|||
})
|
||||
|
||||
// Create the transaction.
|
||||
tx := types.NewContractCreation(0, big.NewInt(0), test.gas, big.NewInt(1), common.FromHex(test.code))
|
||||
tx := types.NewContractCreation(0, big.NewInt(0), test.gas, big.NewInt(0), common.FromHex(test.code))
|
||||
tx, _ = tx.SignECDSA(testKey)
|
||||
|
||||
// Wait for it to get mined in the background.
|
||||
|
|
|
@ -116,7 +116,6 @@ participating.
|
|||
utils.MaxPeersFlag,
|
||||
utils.MaxPendingPeersFlag,
|
||||
utils.EtherbaseFlag,
|
||||
utils.GasPriceFlag,
|
||||
utils.AutoDAGFlag,
|
||||
utils.TargetGasLimitFlag,
|
||||
utils.NATFlag,
|
||||
|
@ -149,12 +148,6 @@ participating.
|
|||
utils.MetricsEnabledFlag,
|
||||
utils.FakePoWFlag,
|
||||
utils.SolcPathFlag,
|
||||
utils.GpoMinGasPriceFlag,
|
||||
utils.GpoMaxGasPriceFlag,
|
||||
utils.GpoFullBlockRatioFlag,
|
||||
utils.GpobaseStepDownFlag,
|
||||
utils.GpobaseStepUpFlag,
|
||||
utils.GpobaseCorrectionFactorFlag,
|
||||
utils.ExtraDataFlag,
|
||||
utils.VoteAccountFlag,
|
||||
utils.VoteAccountPasswordFlag,
|
||||
|
|
|
@ -134,17 +134,6 @@ var AppHelpFlagGroups = []flagGroup{
|
|||
utils.NodeKeyHexFlag,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "GAS PRICE ORACLE",
|
||||
Flags: []cli.Flag{
|
||||
utils.GpoMinGasPriceFlag,
|
||||
utils.GpoMaxGasPriceFlag,
|
||||
utils.GpoFullBlockRatioFlag,
|
||||
utils.GpobaseStepDownFlag,
|
||||
utils.GpobaseStepUpFlag,
|
||||
utils.GpobaseCorrectionFactorFlag,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "VIRTUAL MACHINE",
|
||||
Flags: []cli.Flag{
|
||||
|
|
|
@ -169,11 +169,6 @@ var (
|
|||
Usage: "Public address for block mining rewards (default = first account created)",
|
||||
Value: "0",
|
||||
}
|
||||
GasPriceFlag = cli.StringFlag{
|
||||
Name: "gasprice",
|
||||
Usage: "Minimal gas price to accept for mining a transactions",
|
||||
Value: common.Big0.String(),
|
||||
}
|
||||
ExtraDataFlag = cli.StringFlag{
|
||||
Name: "extradata",
|
||||
Usage: "Block extra data set by the miner (default = client version)",
|
||||
|
@ -339,38 +334,6 @@ var (
|
|||
Usage: "Solidity compiler command to be used",
|
||||
Value: "solc",
|
||||
}
|
||||
|
||||
// Gas price oracle settings
|
||||
GpoMinGasPriceFlag = cli.StringFlag{
|
||||
Name: "gpomin",
|
||||
Usage: "Minimum suggested gas price",
|
||||
Value: new(big.Int).Mul(big.NewInt(20), common.Shannon).String(),
|
||||
}
|
||||
GpoMaxGasPriceFlag = cli.StringFlag{
|
||||
Name: "gpomax",
|
||||
Usage: "Maximum suggested gas price",
|
||||
Value: new(big.Int).Mul(big.NewInt(500), common.Shannon).String(),
|
||||
}
|
||||
GpoFullBlockRatioFlag = cli.IntFlag{
|
||||
Name: "gpofull",
|
||||
Usage: "Full block threshold for gas price calculation (%)",
|
||||
Value: 80,
|
||||
}
|
||||
GpobaseStepDownFlag = cli.IntFlag{
|
||||
Name: "gpobasedown",
|
||||
Usage: "Suggested gas price base step down ratio (1/1000)",
|
||||
Value: 10,
|
||||
}
|
||||
GpobaseStepUpFlag = cli.IntFlag{
|
||||
Name: "gpobaseup",
|
||||
Usage: "Suggested gas price base step up ratio (1/1000)",
|
||||
Value: 100,
|
||||
}
|
||||
GpobaseCorrectionFactorFlag = cli.IntFlag{
|
||||
Name: "gpobasecf",
|
||||
Usage: "Suggested gas price base correction factor (%)",
|
||||
Value: 110,
|
||||
}
|
||||
// Quorum flags
|
||||
VoteAccountFlag = cli.StringFlag{
|
||||
Name: "voteaccount",
|
||||
|
@ -699,13 +662,6 @@ func RegisterEthService(ctx *cli.Context, stack *node.Node, extra []byte) {
|
|||
DocRoot: ctx.GlobalString(DocRootFlag.Name),
|
||||
EnableJit: jitEnabled,
|
||||
ForceJit: ctx.GlobalBool(VMForceJitFlag.Name),
|
||||
GasPrice: common.String2Big(ctx.GlobalString(GasPriceFlag.Name)),
|
||||
GpoMinGasPrice: common.String2Big(ctx.GlobalString(GpoMinGasPriceFlag.Name)),
|
||||
GpoMaxGasPrice: common.String2Big(ctx.GlobalString(GpoMaxGasPriceFlag.Name)),
|
||||
GpoFullBlockRatio: ctx.GlobalInt(GpoFullBlockRatioFlag.Name),
|
||||
GpobaseStepDown: ctx.GlobalInt(GpobaseStepDownFlag.Name),
|
||||
GpobaseStepUp: ctx.GlobalInt(GpobaseStepUpFlag.Name),
|
||||
GpobaseCorrectionFactor: ctx.GlobalInt(GpobaseCorrectionFactorFlag.Name),
|
||||
SolcPath: ctx.GlobalString(SolcPathFlag.Name),
|
||||
VoteMinBlockTime: uint(ctx.GlobalInt(VoteMinBlockTimeFlag.Name)),
|
||||
VoteMaxBlockTime: uint(ctx.GlobalInt(VoteMaxBlockTimeFlag.Name)),
|
||||
|
@ -728,9 +684,6 @@ func RegisterEthService(ctx *cli.Context, stack *node.Node, extra []byte) {
|
|||
|
||||
case ctx.GlobalBool(DevModeFlag.Name):
|
||||
ethConf.Genesis = core.OlympicGenesisBlock()
|
||||
if !ctx.GlobalIsSet(GasPriceFlag.Name) {
|
||||
ethConf.GasPrice = new(big.Int)
|
||||
}
|
||||
ethConf.PowTest = true
|
||||
}
|
||||
// Override any global options pertaining to the Ethereum protocol
|
||||
|
|
|
@ -223,7 +223,6 @@ func (be *registryAPIBackend) Transact(fromStr, toStr, nonceStr, valueStr, gasSt
|
|||
to = common.HexToAddress(toStr)
|
||||
value = common.Big(valueStr)
|
||||
gas *big.Int
|
||||
price *big.Int
|
||||
data []byte
|
||||
contractCreation bool
|
||||
)
|
||||
|
@ -234,12 +233,6 @@ func (be *registryAPIBackend) Transact(fromStr, toStr, nonceStr, valueStr, gasSt
|
|||
gas = common.Big(gasStr)
|
||||
}
|
||||
|
||||
if len(gasPriceStr) == 0 {
|
||||
price = big.NewInt(10000000000000)
|
||||
} else {
|
||||
price = common.Big(gasPriceStr)
|
||||
}
|
||||
|
||||
data = common.FromHex(codeStr)
|
||||
if len(toStr) == 0 {
|
||||
contractCreation = true
|
||||
|
@ -252,9 +245,9 @@ func (be *registryAPIBackend) Transact(fromStr, toStr, nonceStr, valueStr, gasSt
|
|||
|
||||
var tx *types.Transaction
|
||||
if contractCreation {
|
||||
tx = types.NewContractCreation(nonce, value, gas, price, data)
|
||||
tx = types.NewContractCreation(nonce, value, gas, nil, data)
|
||||
} else {
|
||||
tx = types.NewTransaction(nonce, to, value, gas, price, data)
|
||||
tx = types.NewTransaction(nonce, to, value, gas, nil, data)
|
||||
}
|
||||
|
||||
signature, err := be.am.SignEthereum(from, tx.SigHash().Bytes())
|
||||
|
|
|
@ -3,8 +3,6 @@ package quorum
|
|||
import (
|
||||
"time"
|
||||
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
|
@ -64,7 +62,6 @@ func (ps *pendingState) applyTransactions(txs *types.TransactionsByPriorityAndNo
|
|||
var (
|
||||
lowGasTxs types.Transactions
|
||||
failedTxs types.Transactions
|
||||
gasPrice = new(big.Int).Mul(big.NewInt(20), common.Shannon)
|
||||
)
|
||||
|
||||
var coalescedLogs vm.Logs
|
||||
|
@ -78,14 +75,6 @@ func (ps *pendingState) applyTransactions(txs *types.TransactionsByPriorityAndNo
|
|||
// during transaction acceptance is the transaction pool.
|
||||
from, _ := tx.From()
|
||||
|
||||
// Ignore any transactions (and accounts subsequently) with low gas limits
|
||||
if tx.GasPrice().Cmp(gasPrice) < 0 && !ps.ownedAccounts.Has(from) {
|
||||
// Pop the current low-priced transaction without shifting in the next from the account
|
||||
glog.V(logger.Info).Infof("Transaction (%x) below gas price (tx=%v ask=%v). All sequential txs from this address(%x) will be ignored\n", tx.Hash().Bytes()[:4], common.CurrencyToString(tx.GasPrice()), common.CurrencyToString(gasPrice), from[:4])
|
||||
lowGasTxs = append(lowGasTxs, tx)
|
||||
txs.Pop()
|
||||
continue
|
||||
}
|
||||
// Start executing the transaction
|
||||
ps.state.StartRecord(tx.Hash(), common.Hash{}, 0)
|
||||
|
||||
|
|
|
@ -92,7 +92,6 @@ func NewBlockVoting(bc *core.BlockChain, chainConfig *core.ChainConfig, txpool *
|
|||
db: db,
|
||||
am: accountMgr,
|
||||
synced: isSynchronised,
|
||||
gasPrice: new(big.Int).Mul(big.NewInt(10), common.Shannon),
|
||||
}
|
||||
|
||||
return bv
|
||||
|
|
|
@ -19,6 +19,7 @@ package core
|
|||
import (
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
|
@ -87,6 +88,11 @@ func ApplyTransaction(config *ChainConfig, bc *BlockChain, gp *GasPool, publicSt
|
|||
if !tx.IsPrivate() {
|
||||
privateState = publicState
|
||||
}
|
||||
|
||||
if tx.GasPrice() != nil && tx.GasPrice().Cmp(common.Big0) > 0 {
|
||||
return nil, nil, nil, ErrInvalidGasPrice
|
||||
}
|
||||
|
||||
_, gas, err := ApplyMessage(NewEnv(publicState, privateState, config, bc, tx, header, cfg), tx, gp)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
|
|
|
@ -33,7 +33,7 @@ func TestStrictTxListAdd(t *testing.T) {
|
|||
|
||||
txs := make(types.Transactions, 1024)
|
||||
for i := 0; i < len(txs); i++ {
|
||||
txs[i] = transaction(uint64(i), new(big.Int), key)
|
||||
txs[i] = transaction(uint64(i), new(big.Int), new(big.Int), key)
|
||||
}
|
||||
// Insert the transactions in a random order
|
||||
list := newTxList(true)
|
||||
|
|
|
@ -37,13 +37,12 @@ var (
|
|||
// Transaction Pool Errors
|
||||
ErrInvalidSender = errors.New("Invalid sender")
|
||||
ErrNonce = errors.New("Nonce too low")
|
||||
ErrCheap = errors.New("Gas price too low for acceptance")
|
||||
ErrBalance = errors.New("Insufficient balance")
|
||||
ErrNonExistentAccount = errors.New("Account does not exist or account balance too low")
|
||||
ErrInvalidGasPrice = errors.New("Gas price not 0")
|
||||
ErrInsufficientFunds = errors.New("Insufficient funds for gas * price + value")
|
||||
ErrIntrinsicGas = errors.New("Intrinsic gas too low")
|
||||
ErrGasLimit = errors.New("Exceeds block gas limit")
|
||||
ErrNegativeValue = errors.New("Negative value")
|
||||
ErrNonExistentAccount = errors.New("Account doesn't exist")
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -69,7 +68,6 @@ type TxPool struct {
|
|||
currentState stateFn // The state function which will allow us to do some pre checks
|
||||
pendingState *state.ManagedState
|
||||
gasLimit func() *big.Int // The current gas limit function callback
|
||||
minGasPrice *big.Int
|
||||
eventMux *event.TypeMux
|
||||
events event.Subscription
|
||||
localTx *txSet
|
||||
|
@ -96,10 +94,9 @@ func NewTxPool(config *ChainConfig, eventMux *event.TypeMux, currentStateFn stat
|
|||
eventMux: eventMux,
|
||||
currentState: currentStateFn,
|
||||
gasLimit: gasLimitFn,
|
||||
minGasPrice: new(big.Int),
|
||||
pendingState: nil,
|
||||
localTx: newTxSet(),
|
||||
events: eventMux.Subscribe(ChainHeadEvent{}, GasPriceChanged{}, RemovedTransactionEvent{}),
|
||||
events: eventMux.Subscribe(ChainHeadEvent{}, RemovedTransactionEvent{}),
|
||||
quit: make(chan struct{}),
|
||||
}
|
||||
|
||||
|
@ -126,10 +123,6 @@ func (pool *TxPool) eventLoop() {
|
|||
|
||||
pool.resetState()
|
||||
pool.mu.Unlock()
|
||||
case GasPriceChanged:
|
||||
pool.mu.Lock()
|
||||
pool.minGasPrice = ev.Price
|
||||
pool.mu.Unlock()
|
||||
case RemovedTransactionEvent:
|
||||
pool.AddBatch(ev.Txs)
|
||||
}
|
||||
|
@ -151,8 +144,7 @@ func (pool *TxPool) resetState() {
|
|||
|
||||
// validate the pool of pending transactions, this will remove
|
||||
// any transactions that have been included in the block or
|
||||
// have been invalidated because of another transaction (e.g.
|
||||
// higher gas price)
|
||||
// have been invalidated because of another transaction.
|
||||
pool.demoteUnexecutables()
|
||||
|
||||
// Update all accounts to the latest known pending nonce
|
||||
|
@ -231,8 +223,7 @@ func (pool *TxPool) Pending() map[common.Address]types.Transactions {
|
|||
return pending
|
||||
}
|
||||
|
||||
// SetLocal marks a transaction as local, skipping gas price
|
||||
// check against local miner minimum in the future
|
||||
// SetLocal marks a transaction as local.
|
||||
func (pool *TxPool) SetLocal(tx *types.Transaction) {
|
||||
pool.mu.Lock()
|
||||
defer pool.mu.Unlock()
|
||||
|
@ -242,10 +233,10 @@ func (pool *TxPool) SetLocal(tx *types.Transaction) {
|
|||
// validateTx checks whether a transaction is valid according
|
||||
// to the consensus rules.
|
||||
func (pool *TxPool) validateTx(tx *types.Transaction) error {
|
||||
local := pool.localTx.contains(tx.Hash())
|
||||
// Drop transactions under our own minimal accepted gas price
|
||||
if !local && pool.minGasPrice.Cmp(tx.GasPrice()) > 0 {
|
||||
return ErrCheap
|
||||
// due to dual state balances of private accounts cannot be determined.
|
||||
// only accept transactions with a gas price of 0
|
||||
if tx.GasPrice().Cmp(common.Big0) != 0 {
|
||||
return ErrInvalidGasPrice
|
||||
}
|
||||
|
||||
currentState, _, err := pool.currentState()
|
||||
|
|
|
@ -31,8 +31,8 @@ import (
|
|||
"github.com/ethereum/go-ethereum/event"
|
||||
)
|
||||
|
||||
func transaction(nonce uint64, gaslimit *big.Int, key *ecdsa.PrivateKey) *types.Transaction {
|
||||
tx, _ := types.NewTransaction(nonce, common.Address{}, big.NewInt(100), gaslimit, big.NewInt(1), nil).SignECDSA(key)
|
||||
func transaction(nonce uint64, gasPrice, gaslimit *big.Int, key *ecdsa.PrivateKey) *types.Transaction {
|
||||
tx, _ := types.NewTransaction(nonce, common.Address{}, big.NewInt(100), gaslimit, gasPrice, nil).SignECDSA(key)
|
||||
return tx
|
||||
}
|
||||
|
||||
|
@ -50,11 +50,7 @@ func setupTxPool() (*TxPool, *ecdsa.PrivateKey) {
|
|||
func TestInvalidTransactions(t *testing.T) {
|
||||
pool, key := setupTxPool()
|
||||
|
||||
tx := transaction(0, big.NewInt(100), key)
|
||||
if err := pool.Add(tx); err != ErrNonExistentAccount {
|
||||
t.Error("expected", ErrNonExistentAccount)
|
||||
}
|
||||
|
||||
tx := transaction(0, big.NewInt(0), big.NewInt(100), key)
|
||||
from, _ := tx.From()
|
||||
currentState, _, _ := pool.currentState()
|
||||
currentState.AddBalance(from, big.NewInt(1))
|
||||
|
@ -70,26 +66,15 @@ func TestInvalidTransactions(t *testing.T) {
|
|||
|
||||
currentState.SetNonce(from, 1)
|
||||
currentState.AddBalance(from, big.NewInt(0xffffffffffffff))
|
||||
tx = transaction(0, big.NewInt(100000), key)
|
||||
tx = transaction(0, big.NewInt(0), big.NewInt(100000), key)
|
||||
if err := pool.Add(tx); err != ErrNonce {
|
||||
t.Error("expected", ErrNonce)
|
||||
}
|
||||
|
||||
tx = transaction(1, big.NewInt(100000), key)
|
||||
pool.minGasPrice = big.NewInt(1000)
|
||||
if err := pool.Add(tx); err != ErrCheap {
|
||||
t.Error("expected", ErrCheap, "got", err)
|
||||
}
|
||||
|
||||
pool.SetLocal(tx)
|
||||
if err := pool.Add(tx); err != nil {
|
||||
t.Error("expected", nil, "got", err)
|
||||
t.Error("expected", ErrNonce, "got", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTransactionQueue(t *testing.T) {
|
||||
pool, key := setupTxPool()
|
||||
tx := transaction(0, big.NewInt(100), key)
|
||||
tx := transaction(0, big.NewInt(0), big.NewInt(100), key)
|
||||
from, _ := tx.From()
|
||||
currentState, _, _ := pool.currentState()
|
||||
currentState.AddBalance(from, big.NewInt(1000))
|
||||
|
@ -100,7 +85,7 @@ func TestTransactionQueue(t *testing.T) {
|
|||
t.Error("expected valid txs to be 1 is", len(pool.pending))
|
||||
}
|
||||
|
||||
tx = transaction(1, big.NewInt(100), key)
|
||||
tx = transaction(1, big.NewInt(0), big.NewInt(100), key)
|
||||
from, _ = tx.From()
|
||||
currentState.SetNonce(from, 2)
|
||||
pool.enqueueTx(tx.Hash(), tx)
|
||||
|
@ -114,9 +99,9 @@ func TestTransactionQueue(t *testing.T) {
|
|||
}
|
||||
|
||||
pool, key = setupTxPool()
|
||||
tx1 := transaction(0, big.NewInt(100), key)
|
||||
tx2 := transaction(10, big.NewInt(100), key)
|
||||
tx3 := transaction(11, big.NewInt(100), key)
|
||||
tx1 := transaction(0, big.NewInt(0), big.NewInt(100), key)
|
||||
tx2 := transaction(10, big.NewInt(0), big.NewInt(100), key)
|
||||
tx3 := transaction(11, big.NewInt(0), big.NewInt(100), key)
|
||||
from, _ = tx1.From()
|
||||
currentState, _, _ = pool.currentState()
|
||||
currentState.AddBalance(from, big.NewInt(1000))
|
||||
|
@ -136,7 +121,7 @@ func TestTransactionQueue(t *testing.T) {
|
|||
|
||||
func TestRemoveTx(t *testing.T) {
|
||||
pool, key := setupTxPool()
|
||||
tx := transaction(0, big.NewInt(100), key)
|
||||
tx := transaction(0, big.NewInt(0), big.NewInt(100), key)
|
||||
from, _ := tx.From()
|
||||
currentState, _, _ := pool.currentState()
|
||||
currentState.AddBalance(from, big.NewInt(1))
|
||||
|
@ -158,18 +143,6 @@ func TestRemoveTx(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestNegativeValue(t *testing.T) {
|
||||
pool, key := setupTxPool()
|
||||
|
||||
tx, _ := types.NewTransaction(0, common.Address{}, big.NewInt(-1), big.NewInt(100), big.NewInt(1), nil).SignECDSA(key)
|
||||
from, _ := tx.From()
|
||||
currentState, _, _ := pool.currentState()
|
||||
currentState.AddBalance(from, big.NewInt(1))
|
||||
if err := pool.Add(tx); err != ErrNegativeValue {
|
||||
t.Error("expected", ErrNegativeValue, "got", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTransactionChainFork(t *testing.T) {
|
||||
pool, key := setupTxPool()
|
||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||
|
@ -183,7 +156,7 @@ func TestTransactionChainFork(t *testing.T) {
|
|||
}
|
||||
resetState()
|
||||
|
||||
tx := transaction(0, big.NewInt(100000), key)
|
||||
tx := transaction(0, new(big.Int), big.NewInt(100000), key)
|
||||
if err := pool.add(tx); err != nil {
|
||||
t.Error("didn't expect error", err)
|
||||
}
|
||||
|
@ -196,60 +169,12 @@ func TestTransactionChainFork(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestTransactionDoubleNonce(t *testing.T) {
|
||||
pool, key := setupTxPool()
|
||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||
resetState := func() {
|
||||
db, _ := ethdb.NewMemDatabase()
|
||||
statedb, _ := state.New(common.Hash{}, db)
|
||||
pool.currentState = func() (*state.StateDB, *state.StateDB, error) { return statedb, statedb, nil }
|
||||
currentState, _, _ := pool.currentState()
|
||||
currentState.AddBalance(addr, big.NewInt(100000000000000))
|
||||
pool.resetState()
|
||||
}
|
||||
resetState()
|
||||
|
||||
tx1, _ := types.NewTransaction(0, common.Address{}, big.NewInt(100), big.NewInt(100000), big.NewInt(1), nil).SignECDSA(key)
|
||||
tx2, _ := types.NewTransaction(0, common.Address{}, big.NewInt(100), big.NewInt(1000000), big.NewInt(2), nil).SignECDSA(key)
|
||||
tx3, _ := types.NewTransaction(0, common.Address{}, big.NewInt(100), big.NewInt(1000000), big.NewInt(1), nil).SignECDSA(key)
|
||||
|
||||
// Add the first two transaction, ensure higher priced stays only
|
||||
if err := pool.add(tx1); err != nil {
|
||||
t.Error("didn't expect error", err)
|
||||
}
|
||||
if err := pool.add(tx2); err != nil {
|
||||
t.Error("didn't expect error", err)
|
||||
}
|
||||
pool.promoteExecutables()
|
||||
if pool.pending[addr].Len() != 1 {
|
||||
t.Error("expected 1 pending transactions, got", pool.pending[addr].Len())
|
||||
}
|
||||
if tx := pool.pending[addr].txs.items[0]; tx.Hash() != tx2.Hash() {
|
||||
t.Errorf("transaction mismatch: have %x, want %x", tx.Hash(), tx2.Hash())
|
||||
}
|
||||
// Add the thid transaction and ensure it's not saved (smaller price)
|
||||
if err := pool.add(tx3); err != nil {
|
||||
t.Error("didn't expect error", err)
|
||||
}
|
||||
pool.promoteExecutables()
|
||||
if pool.pending[addr].Len() != 1 {
|
||||
t.Error("expected 1 pending transactions, got", pool.pending[addr].Len())
|
||||
}
|
||||
if tx := pool.pending[addr].txs.items[0]; tx.Hash() != tx2.Hash() {
|
||||
t.Errorf("transaction mismatch: have %x, want %x", tx.Hash(), tx2.Hash())
|
||||
}
|
||||
// Ensure the total transaction count is correct
|
||||
if len(pool.all) != 1 {
|
||||
t.Error("expected 1 total transactions, got", len(pool.all))
|
||||
}
|
||||
}
|
||||
|
||||
func TestMissingNonce(t *testing.T) {
|
||||
pool, key := setupTxPool()
|
||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||
currentState, _, _ := pool.currentState()
|
||||
currentState.AddBalance(addr, big.NewInt(100000000000000))
|
||||
tx := transaction(1, big.NewInt(100000), key)
|
||||
tx := transaction(1, new(big.Int), big.NewInt(100000), key)
|
||||
if err := pool.add(tx); err != nil {
|
||||
t.Error("didn't expect error", err)
|
||||
}
|
||||
|
@ -272,7 +197,7 @@ func TestNonceRecovery(t *testing.T) {
|
|||
currentState.SetNonce(addr, n)
|
||||
currentState.AddBalance(addr, big.NewInt(100000000000000))
|
||||
pool.resetState()
|
||||
tx := transaction(n, big.NewInt(100000), key)
|
||||
tx := transaction(n, new(big.Int), big.NewInt(100000), key)
|
||||
if err := pool.Add(tx); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
@ -286,7 +211,7 @@ func TestNonceRecovery(t *testing.T) {
|
|||
|
||||
func TestRemovedTxEvent(t *testing.T) {
|
||||
pool, key := setupTxPool()
|
||||
tx := transaction(0, big.NewInt(1000000), key)
|
||||
tx := transaction(0, big.NewInt(0), big.NewInt(1000000), key)
|
||||
from, _ := tx.From()
|
||||
currentState, _, _ := pool.currentState()
|
||||
currentState.AddBalance(from, big.NewInt(1000000000000))
|
||||
|
@ -300,157 +225,19 @@ func TestRemovedTxEvent(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// Tests that if an account runs out of funds, any pending and queued transactions
|
||||
// are dropped.
|
||||
func TestTransactionDropping(t *testing.T) {
|
||||
// Create a test account and fund it
|
||||
pool, key := setupTxPool()
|
||||
account, _ := transaction(0, big.NewInt(0), key).From()
|
||||
|
||||
state, _, _ := pool.currentState()
|
||||
state.AddBalance(account, big.NewInt(1000))
|
||||
|
||||
// Add some pending and some queued transactions
|
||||
var (
|
||||
tx0 = transaction(0, big.NewInt(100), key)
|
||||
tx1 = transaction(1, big.NewInt(200), key)
|
||||
tx10 = transaction(10, big.NewInt(100), key)
|
||||
tx11 = transaction(11, big.NewInt(200), key)
|
||||
)
|
||||
pool.promoteTx(account, tx0.Hash(), tx0)
|
||||
pool.promoteTx(account, tx1.Hash(), tx1)
|
||||
pool.enqueueTx(tx10.Hash(), tx10)
|
||||
pool.enqueueTx(tx11.Hash(), tx11)
|
||||
|
||||
// Check that pre and post validations leave the pool as is
|
||||
if pool.pending[account].Len() != 2 {
|
||||
t.Errorf("pending transaction mismatch: have %d, want %d", pool.pending[account].Len(), 2)
|
||||
}
|
||||
if pool.queue[account].Len() != 2 {
|
||||
t.Errorf("queued transaction mismatch: have %d, want %d", pool.queue[account].Len(), 2)
|
||||
}
|
||||
if len(pool.all) != 4 {
|
||||
t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), 4)
|
||||
}
|
||||
pool.resetState()
|
||||
if pool.pending[account].Len() != 2 {
|
||||
t.Errorf("pending transaction mismatch: have %d, want %d", pool.pending[account].Len(), 2)
|
||||
}
|
||||
if pool.queue[account].Len() != 2 {
|
||||
t.Errorf("queued transaction mismatch: have %d, want %d", pool.queue[account].Len(), 2)
|
||||
}
|
||||
if len(pool.all) != 4 {
|
||||
t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), 4)
|
||||
}
|
||||
// Reduce the balance of the account, and check that invalidated transactions are dropped
|
||||
state.AddBalance(account, big.NewInt(-750))
|
||||
pool.resetState()
|
||||
|
||||
if _, ok := pool.pending[account].txs.items[tx0.Nonce()]; !ok {
|
||||
t.Errorf("funded pending transaction missing: %v", tx0)
|
||||
}
|
||||
if _, ok := pool.pending[account].txs.items[tx1.Nonce()]; ok {
|
||||
t.Errorf("out-of-fund pending transaction present: %v", tx1)
|
||||
}
|
||||
if _, ok := pool.queue[account].txs.items[tx10.Nonce()]; !ok {
|
||||
t.Errorf("funded queued transaction missing: %v", tx10)
|
||||
}
|
||||
if _, ok := pool.queue[account].txs.items[tx11.Nonce()]; ok {
|
||||
t.Errorf("out-of-fund queued transaction present: %v", tx11)
|
||||
}
|
||||
if len(pool.all) != 2 {
|
||||
t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), 2)
|
||||
}
|
||||
}
|
||||
|
||||
// Tests that if a transaction is dropped from the current pending pool (e.g. out
|
||||
// of fund), all consecutive (still valid, but not executable) transactions are
|
||||
// postponed back into the future queue to prevent broadcasting them.
|
||||
func TestTransactionPostponing(t *testing.T) {
|
||||
// Create a test account and fund it
|
||||
pool, key := setupTxPool()
|
||||
account, _ := transaction(0, big.NewInt(0), key).From()
|
||||
|
||||
state, _, _ := pool.currentState()
|
||||
state.AddBalance(account, big.NewInt(1000))
|
||||
|
||||
// Add a batch consecutive pending transactions for validation
|
||||
txns := []*types.Transaction{}
|
||||
for i := 0; i < 100; i++ {
|
||||
var tx *types.Transaction
|
||||
if i%2 == 0 {
|
||||
tx = transaction(uint64(i), big.NewInt(100), key)
|
||||
} else {
|
||||
tx = transaction(uint64(i), big.NewInt(500), key)
|
||||
}
|
||||
pool.promoteTx(account, tx.Hash(), tx)
|
||||
txns = append(txns, tx)
|
||||
}
|
||||
// Check that pre and post validations leave the pool as is
|
||||
if pool.pending[account].Len() != len(txns) {
|
||||
t.Errorf("pending transaction mismatch: have %d, want %d", pool.pending[account].Len(), len(txns))
|
||||
}
|
||||
if len(pool.queue) != 0 {
|
||||
t.Errorf("queued transaction mismatch: have %d, want %d", pool.queue[account].Len(), 0)
|
||||
}
|
||||
if len(pool.all) != len(txns) {
|
||||
t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), len(txns))
|
||||
}
|
||||
pool.resetState()
|
||||
if pool.pending[account].Len() != len(txns) {
|
||||
t.Errorf("pending transaction mismatch: have %d, want %d", pool.pending[account].Len(), len(txns))
|
||||
}
|
||||
if len(pool.queue) != 0 {
|
||||
t.Errorf("queued transaction mismatch: have %d, want %d", pool.queue[account].Len(), 0)
|
||||
}
|
||||
if len(pool.all) != len(txns) {
|
||||
t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), len(txns))
|
||||
}
|
||||
// Reduce the balance of the account, and check that transactions are reorganised
|
||||
state.AddBalance(account, big.NewInt(-750))
|
||||
pool.resetState()
|
||||
|
||||
if _, ok := pool.pending[account].txs.items[txns[0].Nonce()]; !ok {
|
||||
t.Errorf("tx %d: valid and funded transaction missing from pending pool: %v", 0, txns[0])
|
||||
}
|
||||
if _, ok := pool.queue[account].txs.items[txns[0].Nonce()]; ok {
|
||||
t.Errorf("tx %d: valid and funded transaction present in future queue: %v", 0, txns[0])
|
||||
}
|
||||
for i, tx := range txns[1:] {
|
||||
if i%2 == 1 {
|
||||
if _, ok := pool.pending[account].txs.items[tx.Nonce()]; ok {
|
||||
t.Errorf("tx %d: valid but future transaction present in pending pool: %v", i+1, tx)
|
||||
}
|
||||
if _, ok := pool.queue[account].txs.items[tx.Nonce()]; !ok {
|
||||
t.Errorf("tx %d: valid but future transaction missing from future queue: %v", i+1, tx)
|
||||
}
|
||||
} else {
|
||||
if _, ok := pool.pending[account].txs.items[tx.Nonce()]; ok {
|
||||
t.Errorf("tx %d: out-of-fund transaction present in pending pool: %v", i+1, tx)
|
||||
}
|
||||
if _, ok := pool.queue[account].txs.items[tx.Nonce()]; ok {
|
||||
t.Errorf("tx %d: out-of-fund transaction present in future queue: %v", i+1, tx)
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(pool.all) != len(txns)/2 {
|
||||
t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), len(txns)/2)
|
||||
}
|
||||
}
|
||||
|
||||
// Tests that if the transaction count belonging to a single account goes above
|
||||
// some threshold, the higher transactions are dropped to prevent DOS attacks.
|
||||
func TestTransactionQueueAccountLimiting(t *testing.T) {
|
||||
// Create a test account and fund it
|
||||
pool, key := setupTxPool()
|
||||
account, _ := transaction(0, big.NewInt(0), key).From()
|
||||
account, _ := transaction(0, new(big.Int), big.NewInt(0), key).From()
|
||||
|
||||
state, _, _ := pool.currentState()
|
||||
state.AddBalance(account, big.NewInt(1000000))
|
||||
|
||||
// Keep queuing up transactions and make sure all above a limit are dropped
|
||||
for i := uint64(1); i <= maxQueuedPerAccount+5; i++ {
|
||||
if err := pool.Add(transaction(i, big.NewInt(100000), key)); err != nil {
|
||||
if err := pool.Add(transaction(i, new(big.Int), big.NewInt(100000), key)); err != nil {
|
||||
t.Fatalf("tx %d: failed to add transaction: %v", i, err)
|
||||
}
|
||||
if len(pool.pending) != 0 {
|
||||
|
@ -501,7 +288,7 @@ func TestTransactionQueueGlobalLimiting(t *testing.T) {
|
|||
key := keys[rand.Intn(len(keys))]
|
||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||
|
||||
txs = append(txs, transaction(nonces[addr]+1, big.NewInt(100000), key))
|
||||
txs = append(txs, transaction(nonces[addr]+1, new(big.Int), big.NewInt(100000), key))
|
||||
nonces[addr]++
|
||||
}
|
||||
// Import the batch and verify that limits have been enforced
|
||||
|
@ -531,14 +318,14 @@ func TestTransactionQueueTimeLimiting(t *testing.T) {
|
|||
|
||||
// Create a test account and fund it
|
||||
pool, key := setupTxPool()
|
||||
account, _ := transaction(0, big.NewInt(0), key).From()
|
||||
account, _ := transaction(0, new(big.Int), big.NewInt(0), key).From()
|
||||
|
||||
state, _, _ := pool.currentState()
|
||||
state.AddBalance(account, big.NewInt(1000000))
|
||||
|
||||
// Queue up a batch of transactions
|
||||
for i := uint64(1); i <= maxQueuedPerAccount; i++ {
|
||||
if err := pool.Add(transaction(i, big.NewInt(100000), key)); err != nil {
|
||||
if err := pool.Add(transaction(i, new(big.Int), big.NewInt(100000), key)); err != nil {
|
||||
t.Fatalf("tx %d: failed to add transaction: %v", i, err)
|
||||
}
|
||||
}
|
||||
|
@ -555,14 +342,14 @@ func TestTransactionQueueTimeLimiting(t *testing.T) {
|
|||
func TestTransactionPendingLimiting(t *testing.T) {
|
||||
// Create a test account and fund it
|
||||
pool, key := setupTxPool()
|
||||
account, _ := transaction(0, big.NewInt(0), key).From()
|
||||
account, _ := transaction(0, new(big.Int), big.NewInt(0), key).From()
|
||||
|
||||
state, _, _ := pool.currentState()
|
||||
state.AddBalance(account, big.NewInt(1000000))
|
||||
|
||||
// Keep queuing up transactions and make sure all above a limit are dropped
|
||||
for i := uint64(0); i < maxQueuedPerAccount+5; i++ {
|
||||
if err := pool.Add(transaction(i, big.NewInt(100000), key)); err != nil {
|
||||
if err := pool.Add(transaction(i, new(big.Int), big.NewInt(100000), key)); err != nil {
|
||||
t.Fatalf("tx %d: failed to add transaction: %v", i, err)
|
||||
}
|
||||
if pool.pending[account].Len() != int(i)+1 {
|
||||
|
@ -585,24 +372,24 @@ func TestTransactionPendingLimitingEquivalency(t *testing.T) { testTransactionLi
|
|||
func testTransactionLimitingEquivalency(t *testing.T, origin uint64) {
|
||||
// Add a batch of transactions to a pool one by one
|
||||
pool1, key1 := setupTxPool()
|
||||
account1, _ := transaction(0, big.NewInt(0), key1).From()
|
||||
account1, _ := transaction(0, new(big.Int), big.NewInt(0), key1).From()
|
||||
state1, _, _ := pool1.currentState()
|
||||
state1.AddBalance(account1, big.NewInt(1000000))
|
||||
|
||||
for i := uint64(0); i < maxQueuedPerAccount+5; i++ {
|
||||
if err := pool1.Add(transaction(origin+i, big.NewInt(100000), key1)); err != nil {
|
||||
if err := pool1.Add(transaction(origin+i, new(big.Int), big.NewInt(100000), key1)); err != nil {
|
||||
t.Fatalf("tx %d: failed to add transaction: %v", i, err)
|
||||
}
|
||||
}
|
||||
// Add a batch of transactions to a pool in one big batch
|
||||
pool2, key2 := setupTxPool()
|
||||
account2, _ := transaction(0, big.NewInt(0), key2).From()
|
||||
account2, _ := transaction(0, new(big.Int), big.NewInt(0), key2).From()
|
||||
state2, _, _ := pool2.currentState()
|
||||
state2.AddBalance(account2, big.NewInt(1000000))
|
||||
|
||||
txns := []*types.Transaction{}
|
||||
for i := uint64(0); i < maxQueuedPerAccount+5; i++ {
|
||||
txns = append(txns, transaction(origin+i, big.NewInt(100000), key2))
|
||||
txns = append(txns, transaction(origin+i, new(big.Int), big.NewInt(100000), key2))
|
||||
}
|
||||
pool2.AddBatch(txns)
|
||||
|
||||
|
@ -648,7 +435,7 @@ func TestTransactionPendingGlobalLimiting(t *testing.T) {
|
|||
for _, key := range keys {
|
||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||
for j := 0; j < int(maxPendingTotal)/len(keys)*2; j++ {
|
||||
txs = append(txs, transaction(nonces[addr], big.NewInt(100000), key))
|
||||
txs = append(txs, transaction(nonces[addr], new(big.Int), big.NewInt(100000), key))
|
||||
nonces[addr]++
|
||||
}
|
||||
}
|
||||
|
@ -694,7 +481,7 @@ func TestTransactionPendingMinimumAllowance(t *testing.T) {
|
|||
for _, key := range keys {
|
||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||
for j := 0; j < int(minPendingPerAccount)*2; j++ {
|
||||
txs = append(txs, transaction(nonces[addr], big.NewInt(100000), key))
|
||||
txs = append(txs, transaction(nonces[addr], new(big.Int), big.NewInt(100000), key))
|
||||
nonces[addr]++
|
||||
}
|
||||
}
|
||||
|
@ -717,12 +504,12 @@ func BenchmarkPendingDemotion10000(b *testing.B) { benchmarkPendingDemotion(b, 1
|
|||
func benchmarkPendingDemotion(b *testing.B, size int) {
|
||||
// Add a batch of transactions to a pool one by one
|
||||
pool, key := setupTxPool()
|
||||
account, _ := transaction(0, big.NewInt(0), key).From()
|
||||
account, _ := transaction(0, new(big.Int), big.NewInt(0), key).From()
|
||||
state, _, _ := pool.currentState()
|
||||
state.AddBalance(account, big.NewInt(1000000))
|
||||
|
||||
for i := 0; i < size; i++ {
|
||||
tx := transaction(uint64(i), big.NewInt(100000), key)
|
||||
tx := transaction(uint64(i), new(big.Int), big.NewInt(100000), key)
|
||||
pool.promoteTx(account, tx.Hash(), tx)
|
||||
}
|
||||
// Benchmark the speed of pool validation
|
||||
|
@ -741,12 +528,12 @@ func BenchmarkFuturePromotion10000(b *testing.B) { benchmarkFuturePromotion(b, 1
|
|||
func benchmarkFuturePromotion(b *testing.B, size int) {
|
||||
// Add a batch of transactions to a pool one by one
|
||||
pool, key := setupTxPool()
|
||||
account, _ := transaction(0, big.NewInt(0), key).From()
|
||||
account, _ := transaction(0, new(big.Int), big.NewInt(0), key).From()
|
||||
state, _, _ := pool.currentState()
|
||||
state.AddBalance(account, big.NewInt(1000000))
|
||||
|
||||
for i := 0; i < size; i++ {
|
||||
tx := transaction(uint64(1+i), big.NewInt(100000), key)
|
||||
tx := transaction(uint64(1+i), new(big.Int), big.NewInt(100000), key)
|
||||
pool.enqueueTx(tx.Hash(), tx)
|
||||
}
|
||||
// Benchmark the speed of pool validation
|
||||
|
@ -760,13 +547,13 @@ func benchmarkFuturePromotion(b *testing.B, size int) {
|
|||
func BenchmarkPoolInsert(b *testing.B) {
|
||||
// Generate a batch of transactions to enqueue into the pool
|
||||
pool, key := setupTxPool()
|
||||
account, _ := transaction(0, big.NewInt(0), key).From()
|
||||
account, _ := transaction(0, new(big.Int), big.NewInt(0), key).From()
|
||||
state, _, _ := pool.currentState()
|
||||
state.AddBalance(account, big.NewInt(1000000))
|
||||
|
||||
txs := make(types.Transactions, b.N)
|
||||
for i := 0; i < b.N; i++ {
|
||||
txs[i] = transaction(uint64(i), big.NewInt(100000), key)
|
||||
txs[i] = transaction(uint64(i), new(big.Int), big.NewInt(100000), key)
|
||||
}
|
||||
// Benchmark importing the transactions into the queue
|
||||
b.ResetTimer()
|
||||
|
@ -783,7 +570,7 @@ func BenchmarkPoolBatchInsert10000(b *testing.B) { benchmarkPoolBatchInsert(b, 1
|
|||
func benchmarkPoolBatchInsert(b *testing.B, size int) {
|
||||
// Generate a batch of transactions to enqueue into the pool
|
||||
pool, key := setupTxPool()
|
||||
account, _ := transaction(0, big.NewInt(0), key).From()
|
||||
account, _ := transaction(0, new(big.Int), big.NewInt(0), key).From()
|
||||
state, _, _ := pool.currentState()
|
||||
state.AddBalance(account, big.NewInt(1000000))
|
||||
|
||||
|
@ -791,7 +578,7 @@ func benchmarkPoolBatchInsert(b *testing.B, size int) {
|
|||
for i := 0; i < b.N; i++ {
|
||||
batches[i] = make(types.Transactions, size)
|
||||
for j := 0; j < size; j++ {
|
||||
batches[i][j] = transaction(uint64(size*i+j), big.NewInt(100000), key)
|
||||
batches[i][j] = transaction(uint64(size*i+j), new(big.Int), big.NewInt(100000), key)
|
||||
}
|
||||
}
|
||||
// Benchmark importing the transactions into the queue
|
||||
|
|
|
@ -26,9 +26,8 @@ import (
|
|||
"github.com/ethereum/go-ethereum/rlp"
|
||||
)
|
||||
|
||||
// from bcValidBlockTest.json, "SimpleTx"
|
||||
func TestBlockEncoding(t *testing.T) {
|
||||
blockEnc := common.FromHex("f90260f901f9a083cafc574e1f51ba9dc0568fc617a08ea2429fb384059c972f13b19fa1c8dd55a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0ef1552a40b7165c3cd773806b9e0c165b75356e0314bf0706f279c729f51e017a05fe50b260da6308036625b850b5d6ced6d0a9f814c0688bc91ffb7b7a3a54b67a0bc37d79753ad738a6dac4921e57392f145d8887476de3f783dfa7edae9283e52b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefd8825208845506eb0780a0bd4472abb6659ebe3ee06ee4d7b72a00a9f4d001caca51342001075469aff49888a13a5a8c8f2bb1c4f861f85f800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba09bea4c4daac7c7c52e093e6a4c35dbbcf8856f1af7b059ba20253e70848d094fa08a8fae537ce25ed8cb5af9adac3f141af69bd515bd2ba031522df09b97dd72b1c0")
|
||||
blockEnc := common.FromHex("f90260f901f9a083cafc574e1f51ba9dc0568fc617a08ea2429fb384059c972f13b19fa1c8dd55a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0ef1552a40b7165c3cd773806b9e0c165b75356e0314bf0706f279c729f51e017a08bba9707f73a6c9801825706d0814d4ae310e4ff0a16fcd94e72174a176930e4a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefd8825208845506eb0780a0bd4472abb6659ebe3ee06ee4d7b72a00a9f4d001caca51342001075469aff49888a13a5a8c8f2bb1c4f861f85f808082c35094095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba09bea4c4daac7c7c52e093e6a4c35dbbcf8856f1af7b059ba20253e70848d094fa08a8fae537ce25ed8cb5af9adac3f141af69bd515bd2ba031522df09b97dd72b1c0")
|
||||
var block Block
|
||||
if err := rlp.DecodeBytes(blockEnc, &block); err != nil {
|
||||
t.Fatal("decode error: ", err)
|
||||
|
@ -39,18 +38,19 @@ func TestBlockEncoding(t *testing.T) {
|
|||
t.Errorf("%s mismatch: got %v, want %v", f, got, want)
|
||||
}
|
||||
}
|
||||
|
||||
check("Difficulty", block.Difficulty(), big.NewInt(131072))
|
||||
check("GasLimit", block.GasLimit(), big.NewInt(3141592))
|
||||
check("GasUsed", block.GasUsed(), big.NewInt(21000))
|
||||
check("Coinbase", block.Coinbase(), common.HexToAddress("8888f1f195afa192cfee860698584c030f4c9db1"))
|
||||
check("MixDigest", block.MixDigest(), common.HexToHash("bd4472abb6659ebe3ee06ee4d7b72a00a9f4d001caca51342001075469aff498"))
|
||||
check("Root", block.Root(), common.HexToHash("ef1552a40b7165c3cd773806b9e0c165b75356e0314bf0706f279c729f51e017"))
|
||||
check("Hash", block.Hash(), common.HexToHash("0a5843ac1cb04865017cb35a57b50b07084e5fcee39b5acadade33149f4fff9e"))
|
||||
check("Hash", block.Hash(), common.HexToHash("655702f58f3497047c3c3be2ad131b653ac1141a3c1c0045c8fd3946e0d479f2"))
|
||||
check("Nonce", block.Nonce(), uint64(0xa13a5a8c8f2bb1c4))
|
||||
check("Time", block.Time(), big.NewInt(1426516743))
|
||||
check("Size", block.Size(), common.StorageSize(len(blockEnc)))
|
||||
|
||||
tx1 := NewTransaction(0, common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87"), big.NewInt(10), big.NewInt(50000), big.NewInt(10), nil)
|
||||
tx1 := NewTransaction(0, common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87"), big.NewInt(10), big.NewInt(50000), big.NewInt(0), nil)
|
||||
tx1, _ = tx1.WithSignature(common.Hex2Bytes("9bea4c4daac7c7c52e093e6a4c35dbbcf8856f1af7b059ba20253e70848d094f8a8fae537ce25ed8cb5af9adac3f141af69bd515bd2ba031522df09b97dd72b11b"))
|
||||
check("len(Transactions)", len(block.Transactions()), 1)
|
||||
check("Transactions[0].Hash", block.Transactions()[0].Hash(), tx1.Hash())
|
||||
|
|
|
@ -80,7 +80,7 @@ func NewContractCreation(nonce uint64, amount, gasLimit, gasPrice *big.Int, data
|
|||
Recipient: nil,
|
||||
Amount: new(big.Int).Set(amount),
|
||||
GasLimit: new(big.Int).Set(gasLimit),
|
||||
Price: new(big.Int).Set(gasPrice),
|
||||
Price: new(big.Int),
|
||||
Payload: data,
|
||||
R: new(big.Int),
|
||||
S: new(big.Int),
|
||||
|
@ -108,9 +108,6 @@ func NewTransaction(nonce uint64, to common.Address, amount, gasLimit, gasPrice
|
|||
if gasLimit != nil {
|
||||
d.GasLimit.Set(gasLimit)
|
||||
}
|
||||
if gasPrice != nil {
|
||||
d.Price.Set(gasPrice)
|
||||
}
|
||||
return &Transaction{data: d}
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ var (
|
|||
common.HexToAddress("b94f5374fce5edbc8e2a8697c15331677e6ebf0b"),
|
||||
big.NewInt(10),
|
||||
big.NewInt(2000),
|
||||
big.NewInt(1),
|
||||
big.NewInt(0),
|
||||
common.FromHex("5544"),
|
||||
).WithSignature(
|
||||
common.Hex2Bytes("98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a31c"),
|
||||
|
@ -56,8 +56,8 @@ func TestTransactionSigHash(t *testing.T) {
|
|||
if emptyTx.SigHash() != common.HexToHash("c775b99e7ad12f50d819fcd602390467e28141316969f4b57f0626f74fe3b386") {
|
||||
t.Errorf("empty transaction hash mismatch, got %x", emptyTx.Hash())
|
||||
}
|
||||
if rightvrsTx.SigHash() != common.HexToHash("fe7a79529ed5f7c3375d06b26b186a8644e0e16c373d7a12be41c62d6042b77a") {
|
||||
t.Errorf("RightVRS transaction hash mismatch, got %x", rightvrsTx.Hash())
|
||||
if rightvrsTx.SigHash() != common.HexToHash("c75e06c2a1b4e254e869653871436fdfa752fd613152b474e6dd36b73a13dae2") {
|
||||
t.Errorf("RightVRS transaction hash mismatch, got %x", rightvrsTx.SigHash())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ func TestTransactionEncode(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatalf("encode error: %v", err)
|
||||
}
|
||||
should := common.FromHex("f86103018207d094b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a8255441ca098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3")
|
||||
should := common.FromHex("f86103808207d094b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a8255441ca098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3")
|
||||
if !bytes.Equal(txb, should) {
|
||||
t.Errorf("encoded RLP mismatch, got %x", txb)
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/eth/downloader"
|
||||
"github.com/ethereum/go-ethereum/eth/gasprice"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
|
@ -37,7 +36,6 @@ import (
|
|||
// EthApiBackend implements ethapi.Backend for full nodes
|
||||
type EthApiBackend struct {
|
||||
eth *Ethereum
|
||||
gpo *gasprice.GasPriceOracle
|
||||
}
|
||||
|
||||
func (b *EthApiBackend) SetHead(number uint64) {
|
||||
|
@ -177,7 +175,7 @@ func (b *EthApiBackend) ProtocolVersion() int {
|
|||
}
|
||||
|
||||
func (b *EthApiBackend) SuggestPrice(ctx context.Context) (*big.Int, error) {
|
||||
return b.gpo.SuggestPrice(), nil
|
||||
return big.NewInt(0), nil
|
||||
}
|
||||
|
||||
func (b *EthApiBackend) ChainDb() ethdb.Database {
|
||||
|
|
|
@ -20,7 +20,6 @@ package eth
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
|
@ -39,7 +38,6 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/eth/downloader"
|
||||
"github.com/ethereum/go-ethereum/eth/filters"
|
||||
"github.com/ethereum/go-ethereum/eth/gasprice"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
|
@ -82,17 +80,9 @@ type Config struct {
|
|||
ExtraData []byte
|
||||
|
||||
Etherbase common.Address
|
||||
GasPrice *big.Int
|
||||
MinerThreads int
|
||||
SolcPath string
|
||||
|
||||
GpoMinGasPrice *big.Int
|
||||
GpoMaxGasPrice *big.Int
|
||||
GpoFullBlockRatio int
|
||||
GpobaseStepDown int
|
||||
GpobaseStepUp int
|
||||
GpobaseCorrectionFactor int
|
||||
|
||||
EnableJit bool
|
||||
ForceJit bool
|
||||
|
||||
|
@ -227,16 +217,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
gpoParams := &gasprice.GpoParams{
|
||||
GpoMinGasPrice: config.GpoMinGasPrice,
|
||||
GpoMaxGasPrice: config.GpoMaxGasPrice,
|
||||
GpoFullBlockRatio: config.GpoFullBlockRatio,
|
||||
GpobaseStepDown: config.GpobaseStepDown,
|
||||
GpobaseStepUp: config.GpobaseStepUp,
|
||||
GpobaseCorrectionFactor: config.GpobaseCorrectionFactor,
|
||||
}
|
||||
gpo := gasprice.NewGasPriceOracle(eth.blockchain, chainDb, eth.eventMux, gpoParams)
|
||||
eth.apiBackend = &EthApiBackend{eth, gpo}
|
||||
eth.apiBackend = &EthApiBackend{eth}
|
||||
|
||||
eth.blockVoting = quorum.NewBlockVoting(eth.blockchain, eth.chainConfig, eth.txPool, eth.eventMux, eth.chainDb, eth.accountManager, config.SingleBlockMaker)
|
||||
|
||||
|
|
|
@ -1,229 +0,0 @@
|
|||
// Copyright 2015 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package gasprice
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
"math/rand"
|
||||
"sync"
|
||||
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
"github.com/ethereum/go-ethereum/logger"
|
||||
"github.com/ethereum/go-ethereum/logger/glog"
|
||||
)
|
||||
|
||||
const (
|
||||
gpoProcessPastBlocks = 100
|
||||
|
||||
// for testing
|
||||
gpoDefaultBaseCorrectionFactor = 110
|
||||
gpoDefaultMinGasPrice = 10000000000000
|
||||
)
|
||||
|
||||
type blockPriceInfo struct {
|
||||
baseGasPrice *big.Int
|
||||
}
|
||||
|
||||
type GpoParams struct {
|
||||
GpoMinGasPrice *big.Int
|
||||
GpoMaxGasPrice *big.Int
|
||||
GpoFullBlockRatio int
|
||||
GpobaseStepDown int
|
||||
GpobaseStepUp int
|
||||
GpobaseCorrectionFactor int
|
||||
}
|
||||
|
||||
// GasPriceOracle recommends gas prices based on the content of recent
|
||||
// blocks.
|
||||
type GasPriceOracle struct {
|
||||
chain *core.BlockChain
|
||||
db ethdb.Database
|
||||
evmux *event.TypeMux
|
||||
params *GpoParams
|
||||
initOnce sync.Once
|
||||
minPrice *big.Int
|
||||
lastBaseMutex sync.Mutex
|
||||
lastBase *big.Int
|
||||
|
||||
// state of listenLoop
|
||||
blocks map[uint64]*blockPriceInfo
|
||||
firstProcessed, lastProcessed uint64
|
||||
minBase *big.Int
|
||||
}
|
||||
|
||||
// NewGasPriceOracle returns a new oracle.
|
||||
func NewGasPriceOracle(chain *core.BlockChain, db ethdb.Database, evmux *event.TypeMux, params *GpoParams) *GasPriceOracle {
|
||||
minprice := params.GpoMinGasPrice
|
||||
if minprice == nil {
|
||||
minprice = big.NewInt(gpoDefaultMinGasPrice)
|
||||
}
|
||||
minbase := new(big.Int).Mul(minprice, big.NewInt(100))
|
||||
if params.GpobaseCorrectionFactor > 0 {
|
||||
minbase = minbase.Div(minbase, big.NewInt(int64(params.GpobaseCorrectionFactor)))
|
||||
}
|
||||
return &GasPriceOracle{
|
||||
chain: chain,
|
||||
db: db,
|
||||
evmux: evmux,
|
||||
params: params,
|
||||
blocks: make(map[uint64]*blockPriceInfo),
|
||||
minBase: minbase,
|
||||
minPrice: minprice,
|
||||
lastBase: minprice,
|
||||
}
|
||||
}
|
||||
|
||||
func (gpo *GasPriceOracle) init() {
|
||||
gpo.initOnce.Do(func() {
|
||||
gpo.processPastBlocks()
|
||||
go gpo.listenLoop()
|
||||
})
|
||||
}
|
||||
|
||||
func (self *GasPriceOracle) processPastBlocks() {
|
||||
last := int64(-1)
|
||||
cblock := self.chain.CurrentBlock()
|
||||
if cblock != nil {
|
||||
last = int64(cblock.NumberU64())
|
||||
}
|
||||
first := int64(0)
|
||||
if last > gpoProcessPastBlocks {
|
||||
first = last - gpoProcessPastBlocks
|
||||
}
|
||||
self.firstProcessed = uint64(first)
|
||||
for i := first; i <= last; i++ {
|
||||
block := self.chain.GetBlockByNumber(uint64(i))
|
||||
if block != nil {
|
||||
self.processBlock(block)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (self *GasPriceOracle) listenLoop() {
|
||||
events := self.evmux.Subscribe(core.ChainEvent{}, core.ChainSplitEvent{})
|
||||
defer events.Unsubscribe()
|
||||
|
||||
for event := range events.Chan() {
|
||||
switch event := event.Data.(type) {
|
||||
case core.ChainEvent:
|
||||
self.processBlock(event.Block)
|
||||
case core.ChainSplitEvent:
|
||||
self.processBlock(event.Block)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (self *GasPriceOracle) processBlock(block *types.Block) {
|
||||
i := block.NumberU64()
|
||||
if i > self.lastProcessed {
|
||||
self.lastProcessed = i
|
||||
}
|
||||
|
||||
lastBase := self.minPrice
|
||||
bpl := self.blocks[i-1]
|
||||
if bpl != nil {
|
||||
lastBase = bpl.baseGasPrice
|
||||
}
|
||||
if lastBase == nil {
|
||||
return
|
||||
}
|
||||
|
||||
var corr int
|
||||
lp := self.lowestPrice(block)
|
||||
if lp == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if lastBase.Cmp(lp) < 0 {
|
||||
corr = self.params.GpobaseStepUp
|
||||
} else {
|
||||
corr = -self.params.GpobaseStepDown
|
||||
}
|
||||
|
||||
crand := int64(corr * (900 + rand.Intn(201)))
|
||||
newBase := new(big.Int).Mul(lastBase, big.NewInt(1000000+crand))
|
||||
newBase.Div(newBase, big.NewInt(1000000))
|
||||
|
||||
if newBase.Cmp(self.minBase) < 0 {
|
||||
newBase = self.minBase
|
||||
}
|
||||
|
||||
bpi := self.blocks[i]
|
||||
if bpi == nil {
|
||||
bpi = &blockPriceInfo{}
|
||||
self.blocks[i] = bpi
|
||||
}
|
||||
bpi.baseGasPrice = newBase
|
||||
self.lastBaseMutex.Lock()
|
||||
self.lastBase = newBase
|
||||
self.lastBaseMutex.Unlock()
|
||||
|
||||
glog.V(logger.Detail).Infof("Processed block #%v, base price is %v\n", i, newBase.Int64())
|
||||
}
|
||||
|
||||
// returns the lowers possible price with which a tx was or could have been included
|
||||
func (self *GasPriceOracle) lowestPrice(block *types.Block) *big.Int {
|
||||
gasUsed := big.NewInt(0)
|
||||
|
||||
receipts := core.GetBlockReceipts(self.db, block.Hash(), block.NumberU64())
|
||||
if len(receipts) > 0 {
|
||||
if cgu := receipts[len(receipts)-1].CumulativeGasUsed; cgu != nil {
|
||||
gasUsed = receipts[len(receipts)-1].CumulativeGasUsed
|
||||
}
|
||||
}
|
||||
|
||||
if new(big.Int).Mul(gasUsed, big.NewInt(100)).Cmp(new(big.Int).Mul(block.GasLimit(),
|
||||
big.NewInt(int64(self.params.GpoFullBlockRatio)))) < 0 {
|
||||
// block is not full, could have posted a tx with MinGasPrice
|
||||
return big.NewInt(0)
|
||||
}
|
||||
|
||||
txs := block.Transactions()
|
||||
if len(txs) == 0 {
|
||||
return big.NewInt(0)
|
||||
}
|
||||
// block is full, find smallest gasPrice
|
||||
minPrice := txs[0].GasPrice()
|
||||
for i := 1; i < len(txs); i++ {
|
||||
price := txs[i].GasPrice()
|
||||
if price.Cmp(minPrice) < 0 {
|
||||
minPrice = price
|
||||
}
|
||||
}
|
||||
return minPrice
|
||||
}
|
||||
|
||||
// SuggestPrice returns the recommended gas price.
|
||||
func (self *GasPriceOracle) SuggestPrice() *big.Int {
|
||||
self.init()
|
||||
self.lastBaseMutex.Lock()
|
||||
price := new(big.Int).Set(self.lastBase)
|
||||
self.lastBaseMutex.Unlock()
|
||||
|
||||
price.Mul(price, big.NewInt(int64(self.params.GpobaseCorrectionFactor)))
|
||||
price.Div(price, big.NewInt(100))
|
||||
if price.Cmp(self.minPrice) < 0 {
|
||||
price.Set(self.minPrice)
|
||||
} else if self.params.GpoMaxGasPrice != nil && price.Cmp(self.params.GpoMaxGasPrice) > 0 {
|
||||
price.Set(self.params.GpoMaxGasPrice)
|
||||
}
|
||||
return price
|
||||
}
|
|
@ -283,9 +283,9 @@ func (s *PrivateAccountAPI) SendTransaction(ctx context.Context, args SendTxArgs
|
|||
}
|
||||
}
|
||||
if args.To == nil {
|
||||
tx = types.NewContractCreation(args.Nonce.Uint64(), args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), data)
|
||||
tx = types.NewContractCreation(args.Nonce.Uint64(), args.Value.BigInt(), args.Gas.BigInt(), nil, data)
|
||||
} else {
|
||||
tx = types.NewTransaction(args.Nonce.Uint64(), *args.To, args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), data)
|
||||
tx = types.NewTransaction(args.Nonce.Uint64(), *args.To, args.Value.BigInt(), args.Gas.BigInt(), nil, data)
|
||||
}
|
||||
|
||||
signature, err := s.am.SignWithPassphrase(args.From, passwd, tx.SigHash().Bytes())
|
||||
|
@ -558,6 +558,10 @@ func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr
|
|||
msg.gas = big.NewInt(50000000)
|
||||
}
|
||||
|
||||
if msg.gasPrice.Cmp(common.Big0) != 0 {
|
||||
msg.gasPrice = new(big.Int)
|
||||
}
|
||||
|
||||
// Execute the call and return
|
||||
vmenv, vmError, err := s.b.GetVMEnv(ctx, msg, state, header)
|
||||
if err != nil {
|
||||
|
@ -1086,9 +1090,9 @@ func (s *PublicTransactionPoolAPI) SendTransaction(ctx context.Context, args Sen
|
|||
}
|
||||
}
|
||||
if args.To == nil {
|
||||
tx = types.NewContractCreation(args.Nonce.Uint64(), args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), data)
|
||||
tx = types.NewContractCreation(args.Nonce.Uint64(), args.Value.BigInt(), args.Gas.BigInt(), nil, data)
|
||||
} else {
|
||||
tx = types.NewTransaction(args.Nonce.Uint64(), *args.To, args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), data)
|
||||
tx = types.NewTransaction(args.Nonce.Uint64(), *args.To, args.Value.BigInt(), args.Gas.BigInt(), nil, data)
|
||||
}
|
||||
|
||||
signature, err := s.b.AccountManager().SignEthereum(args.From, tx.SigHash().Bytes())
|
||||
|
@ -1206,9 +1210,9 @@ func (tx *Tx) UnmarshalJSON(b []byte) (err error) {
|
|||
}
|
||||
|
||||
if req.To == nil {
|
||||
tx.tx = types.NewContractCreation(tx.Nonce.Uint64(), tx.Value.BigInt(), tx.GasLimit.BigInt(), tx.GasPrice.BigInt(), data)
|
||||
tx.tx = types.NewContractCreation(tx.Nonce.Uint64(), tx.Value.BigInt(), tx.GasLimit.BigInt(), nil, data)
|
||||
} else {
|
||||
tx.tx = types.NewTransaction(tx.Nonce.Uint64(), *tx.To, tx.Value.BigInt(), tx.GasLimit.BigInt(), tx.GasPrice.BigInt(), data)
|
||||
tx.tx = types.NewTransaction(tx.Nonce.Uint64(), *tx.To, tx.Value.BigInt(), tx.GasLimit.BigInt(), nil, data)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -1263,9 +1267,9 @@ func (s *PublicTransactionPoolAPI) SignTransaction(ctx context.Context, args Sig
|
|||
|
||||
var tx *types.Transaction
|
||||
if args.To == nil {
|
||||
tx = types.NewContractCreation(args.Nonce.Uint64(), args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), common.FromHex(args.Data))
|
||||
tx = types.NewContractCreation(args.Nonce.Uint64(), args.Value.BigInt(), args.Gas.BigInt(), nil, common.FromHex(args.Data))
|
||||
} else {
|
||||
tx = types.NewTransaction(args.Nonce.Uint64(), *args.To, args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), common.FromHex(args.Data))
|
||||
tx = types.NewTransaction(args.Nonce.Uint64(), *args.To, args.Value.BigInt(), args.Gas.BigInt(), nil, common.FromHex(args.Data))
|
||||
}
|
||||
|
||||
signedTx, err := s.sign(args.From, tx)
|
||||
|
@ -1310,9 +1314,9 @@ func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, tx Tx, gasPrice,
|
|||
|
||||
var newTx *types.Transaction
|
||||
if tx.tx.To() == nil {
|
||||
newTx = types.NewContractCreation(tx.tx.Nonce(), tx.tx.Value(), gasLimit.BigInt(), gasPrice.BigInt(), tx.tx.Data())
|
||||
newTx = types.NewContractCreation(tx.tx.Nonce(), tx.tx.Value(), gasLimit.BigInt(), nil, tx.tx.Data())
|
||||
} else {
|
||||
newTx = types.NewTransaction(tx.tx.Nonce(), *tx.tx.To(), tx.tx.Value(), gasLimit.BigInt(), gasPrice.BigInt(), tx.tx.Data())
|
||||
newTx = types.NewTransaction(tx.tx.Nonce(), *tx.tx.To(), tx.tx.Value(), gasLimit.BigInt(), nil, tx.tx.Data())
|
||||
}
|
||||
if tx.tx.IsPrivate() {
|
||||
newTx.SetPrivate()
|
||||
|
|
|
@ -22,34 +22,6 @@ import (
|
|||
"testing"
|
||||
)
|
||||
|
||||
func TestBcValidBlockTests(t *testing.T) {
|
||||
err := RunBlockTest(big.NewInt(1000000), nil, nil, filepath.Join(blockTestDir, "bcValidBlockTest.json"), BlockSkipTests)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBcUncleHeaderValidityTests(t *testing.T) {
|
||||
err := RunBlockTest(big.NewInt(1000000), nil, nil, filepath.Join(blockTestDir, "bcUncleHeaderValiditiy.json"), BlockSkipTests)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBcUncleTests(t *testing.T) {
|
||||
err := RunBlockTest(big.NewInt(1000000), nil, nil, filepath.Join(blockTestDir, "bcUncleTest.json"), BlockSkipTests)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBcForkUncleTests(t *testing.T) {
|
||||
err := RunBlockTest(big.NewInt(1000000), nil, nil, filepath.Join(blockTestDir, "bcForkUncle.json"), BlockSkipTests)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBcInvalidHeaderTests(t *testing.T) {
|
||||
err := RunBlockTest(big.NewInt(1000000), nil, nil, filepath.Join(blockTestDir, "bcInvalidHeaderTest.json"), BlockSkipTests)
|
||||
if err != nil {
|
||||
|
@ -78,13 +50,6 @@ func TestBcForkBlockTests(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestBcForkStress(t *testing.T) {
|
||||
err := RunBlockTest(big.NewInt(1000000), nil, nil, filepath.Join(blockTestDir, "bcForkStressTest.json"), BlockSkipTests)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBcTotalDifficulty(t *testing.T) {
|
||||
// skip because these will fail due to selfish mining fix
|
||||
t.Skip()
|
||||
|
@ -95,20 +60,6 @@ func TestBcTotalDifficulty(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestBcWallet(t *testing.T) {
|
||||
err := RunBlockTest(big.NewInt(1000000), nil, nil, filepath.Join(blockTestDir, "bcWalletTest.json"), BlockSkipTests)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBcGasPricer(t *testing.T) {
|
||||
err := RunBlockTest(big.NewInt(1000000), nil, nil, filepath.Join(blockTestDir, "bcGasPricerTest.json"), BlockSkipTests)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: iterate over files once we got more than a few
|
||||
func TestBcRandom(t *testing.T) {
|
||||
err := RunBlockTest(big.NewInt(1000000), nil, big.NewInt(10), filepath.Join(blockTestDir, "RandomTests/bl201507071825GO.json"), BlockSkipTests)
|
||||
|
@ -127,35 +78,6 @@ func TestBcMultiChain(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestBcState(t *testing.T) {
|
||||
err := RunBlockTest(big.NewInt(1000000), nil, big.NewInt(10), filepath.Join(blockTestDir, "bcStateTest.json"), BlockSkipTests)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Homestead tests
|
||||
func TestHomesteadBcValidBlockTests(t *testing.T) {
|
||||
err := RunBlockTest(big.NewInt(0), nil, nil, filepath.Join(blockTestDir, "Homestead", "bcValidBlockTest.json"), BlockSkipTests)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHomesteadBcUncleHeaderValidityTests(t *testing.T) {
|
||||
err := RunBlockTest(big.NewInt(0), nil, nil, filepath.Join(blockTestDir, "Homestead", "bcUncleHeaderValiditiy.json"), BlockSkipTests)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHomesteadBcUncleTests(t *testing.T) {
|
||||
err := RunBlockTest(big.NewInt(0), nil, nil, filepath.Join(blockTestDir, "Homestead", "bcUncleTest.json"), BlockSkipTests)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHomesteadBcInvalidHeaderTests(t *testing.T) {
|
||||
err := RunBlockTest(big.NewInt(0), nil, nil, filepath.Join(blockTestDir, "Homestead", "bcInvalidHeaderTest.json"), BlockSkipTests)
|
||||
if err != nil {
|
||||
|
@ -170,60 +92,6 @@ func TestHomesteadBcRPCAPITests(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestHomesteadBcForkStress(t *testing.T) {
|
||||
err := RunBlockTest(big.NewInt(0), nil, nil, filepath.Join(blockTestDir, "Homestead", "bcForkStressTest.json"), BlockSkipTests)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHomesteadBcTotalDifficulty(t *testing.T) {
|
||||
err := RunBlockTest(big.NewInt(0), nil, nil, filepath.Join(blockTestDir, "Homestead", "bcTotalDifficultyTest.json"), BlockSkipTests)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHomesteadBcWallet(t *testing.T) {
|
||||
err := RunBlockTest(big.NewInt(0), nil, nil, filepath.Join(blockTestDir, "Homestead", "bcWalletTest.json"), BlockSkipTests)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHomesteadBcGasPricer(t *testing.T) {
|
||||
err := RunBlockTest(big.NewInt(0), nil, nil, filepath.Join(blockTestDir, "Homestead", "bcGasPricerTest.json"), BlockSkipTests)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHomesteadBcMultiChain(t *testing.T) {
|
||||
err := RunBlockTest(big.NewInt(0), nil, nil, filepath.Join(blockTestDir, "Homestead", "bcMultiChainTest.json"), BlockSkipTests)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHomesteadBcState(t *testing.T) {
|
||||
err := RunBlockTest(big.NewInt(0), nil, nil, filepath.Join(blockTestDir, "Homestead", "bcStateTest.json"), BlockSkipTests)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHomesteadBcExploit(t *testing.T) {
|
||||
err := RunBlockTest(big.NewInt(0), nil, nil, filepath.Join(blockTestDir, "Homestead", "bcExploitTest.json"), BlockSkipTests)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
func TestHomesteadBcShanghaiLove(t *testing.T) {
|
||||
err := RunBlockTest(big.NewInt(0), nil, nil, filepath.Join(blockTestDir, "Homestead", "bcShanghaiLove.json"), BlockSkipTests)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
func TestHomesteadBcSuicideIssue(t *testing.T) {
|
||||
err := RunBlockTest(big.NewInt(0), nil, nil, filepath.Join(blockTestDir, "Homestead", "bcSuicideIssue.json"), BlockSkipTests)
|
||||
if err != nil {
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
{
|
||||
"data" : "0x",
|
||||
"gasLimit" : "0x44aa20",
|
||||
"gasPrice" : "0x01",
|
||||
"gasPrice" : "0x00",
|
||||
"nonce" : "0x00",
|
||||
"r" : "0x836bdd27c1abba1a55221bc86f6f048c9e364680eebf9f3ab9b6c7ae462b76ee",
|
||||
"s" : "0x0c6fbd2f365de9e87436d2ac7635b709093038befc6ec9933ee936ab0b4a24b6",
|
||||
|
|
Loading…
Reference in New Issue