core, core/state, trie: EIP158, reprice & skip empty account write
This commit implements EIP158 part 1, 2, 3 & 4 1. If an account is empty it's no longer written to the trie. An empty account is defined as (balance=0, nonce=0, storage=0, code=0). 2. Delete an empty account if it's touched 3. An empty account is redefined as either non-existent or empty. 4. Zero value calls and zero value suicides no longer consume the 25k reation costs. params: moved core/config to params Signed-off-by: Jeffrey Wilcke <jeffrey@ethereum.org>
This commit is contained in:
parent
932d973e36
commit
445feaeef5
@ -31,11 +31,12 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Default chain configuration which sets homestead phase at block 0 (i.e. no frontier)
|
// Default chain configuration which sets homestead phase at block 0 (i.e. no frontier)
|
||||||
var chainConfig = &core.ChainConfig{HomesteadBlock: big.NewInt(0)}
|
var chainConfig = ¶ms.ChainConfig{HomesteadBlock: big.NewInt(0), EIP150Block: new(big.Int), EIP158Block: new(big.Int)}
|
||||||
|
|
||||||
// This nil assignment ensures compile time that SimulatedBackend implements bind.ContractBackend.
|
// This nil assignment ensures compile time that SimulatedBackend implements bind.ContractBackend.
|
||||||
var _ bind.ContractBackend = (*SimulatedBackend)(nil)
|
var _ bind.ContractBackend = (*SimulatedBackend)(nil)
|
||||||
@ -51,6 +52,8 @@ type SimulatedBackend struct {
|
|||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
pendingBlock *types.Block // Currently pending block that will be imported on request
|
pendingBlock *types.Block // Currently pending block that will be imported on request
|
||||||
pendingState *state.StateDB // Currently pending state that will be the active on on request
|
pendingState *state.StateDB // Currently pending state that will be the active on on request
|
||||||
|
|
||||||
|
config *params.ChainConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSimulatedBackend creates a new binding backend using a simulated blockchain
|
// NewSimulatedBackend creates a new binding backend using a simulated blockchain
|
||||||
@ -85,7 +88,7 @@ func (b *SimulatedBackend) Rollback() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *SimulatedBackend) rollback() {
|
func (b *SimulatedBackend) rollback() {
|
||||||
blocks, _ := core.GenerateChain(nil, b.blockchain.CurrentBlock(), b.database, 1, func(int, *core.BlockGen) {})
|
blocks, _ := core.GenerateChain(chainConfig, b.blockchain.CurrentBlock(), b.database, 1, func(int, *core.BlockGen) {})
|
||||||
b.pendingBlock = blocks[0]
|
b.pendingBlock = blocks[0]
|
||||||
b.pendingState, _ = state.New(b.pendingBlock.Root(), b.database)
|
b.pendingState, _ = state.New(b.pendingBlock.Root(), b.database)
|
||||||
}
|
}
|
||||||
@ -243,7 +246,7 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transa
|
|||||||
panic(fmt.Errorf("invalid transaction nonce: got %d, want %d", tx.Nonce(), nonce))
|
panic(fmt.Errorf("invalid transaction nonce: got %d, want %d", tx.Nonce(), nonce))
|
||||||
}
|
}
|
||||||
|
|
||||||
blocks, _ := core.GenerateChain(nil, b.blockchain.CurrentBlock(), b.database, 1, func(number int, block *core.BlockGen) {
|
blocks, _ := core.GenerateChain(chainConfig, b.blockchain.CurrentBlock(), b.database, 1, func(number int, block *core.BlockGen) {
|
||||||
for _, tx := range b.pendingBlock.Transactions() {
|
for _, tx := range b.pendingBlock.Transactions() {
|
||||||
block.AddTx(tx)
|
block.AddTx(tx)
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ func runTestWithReader(test string, r io.Reader) error {
|
|||||||
case "bk", "block", "blocktest", "blockchaintest", "blocktests", "blockchaintests":
|
case "bk", "block", "blocktest", "blockchaintest", "blocktests", "blockchaintests":
|
||||||
err = tests.RunBlockTestWithReader(params.MainNetHomesteadBlock, params.MainNetDAOForkBlock, params.MainNetHomesteadGasRepriceBlock, r, skipTests)
|
err = tests.RunBlockTestWithReader(params.MainNetHomesteadBlock, params.MainNetDAOForkBlock, params.MainNetHomesteadGasRepriceBlock, r, skipTests)
|
||||||
case "st", "state", "statetest", "statetests":
|
case "st", "state", "statetest", "statetests":
|
||||||
rs := tests.RuleSet{HomesteadBlock: params.MainNetHomesteadBlock, DAOForkBlock: params.MainNetDAOForkBlock, DAOForkSupport: true}
|
rs := ¶ms.ChainConfig{HomesteadBlock: params.MainNetHomesteadBlock, DAOForkBlock: params.MainNetDAOForkBlock, DAOForkSupport: true, EIP150Block: params.MainNetHomesteadGasRepriceBlock}
|
||||||
err = tests.RunStateTestWithReader(rs, r, skipTests)
|
err = tests.RunStateTestWithReader(rs, r, skipTests)
|
||||||
case "tx", "transactiontest", "transactiontests":
|
case "tx", "transactiontest", "transactiontests":
|
||||||
err = tests.RunTransactionTestsWithReader(r, skipTests)
|
err = tests.RunTransactionTestsWithReader(r, skipTests)
|
||||||
|
@ -191,7 +191,7 @@ func run(ctx *cli.Context) error {
|
|||||||
vmdone := time.Since(tstart)
|
vmdone := time.Since(tstart)
|
||||||
|
|
||||||
if ctx.GlobalBool(DumpFlag.Name) {
|
if ctx.GlobalBool(DumpFlag.Name) {
|
||||||
statedb.Commit()
|
statedb.Commit(true)
|
||||||
fmt.Println(string(statedb.Dump()))
|
fmt.Println(string(statedb.Dump()))
|
||||||
}
|
}
|
||||||
vm.StdErrFormat(logger.StructLogs())
|
vm.StdErrFormat(logger.StructLogs())
|
||||||
@ -251,7 +251,7 @@ func NewEnv(state *state.StateDB, transactor common.Address, value *big.Int, cfg
|
|||||||
return env
|
return env
|
||||||
}
|
}
|
||||||
|
|
||||||
// ruleSet implements vm.RuleSet and will always default to the homestead rule set.
|
// ruleSet implements vm.ChainConfig and will always default to the homestead rule set.
|
||||||
type ruleSet struct{}
|
type ruleSet struct{}
|
||||||
|
|
||||||
func (ruleSet) IsHomestead(*big.Int) bool { return true }
|
func (ruleSet) IsHomestead(*big.Int) bool { return true }
|
||||||
@ -259,7 +259,7 @@ func (ruleSet) GasTable(*big.Int) params.GasTable {
|
|||||||
return params.GasTableHomesteadGasRepriceFork
|
return params.GasTableHomesteadGasRepriceFork
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *VMEnv) RuleSet() vm.RuleSet { return ruleSet{} }
|
func (self *VMEnv) ChainConfig() *params.ChainConfig { return params.TestChainConfig }
|
||||||
func (self *VMEnv) Vm() vm.Vm { return self.evm }
|
func (self *VMEnv) Vm() vm.Vm { return self.evm }
|
||||||
func (self *VMEnv) Db() vm.Database { return self.state }
|
func (self *VMEnv) Db() vm.Database { return self.state }
|
||||||
func (self *VMEnv) SnapshotDatabase() int { return self.state.Snapshot() }
|
func (self *VMEnv) SnapshotDatabase() int { return self.state.Snapshot() }
|
||||||
|
@ -23,7 +23,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/core"
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/eth"
|
"github.com/ethereum/go-ethereum/eth"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
@ -122,7 +121,7 @@ func MakeSystemNode(privkey string, test *tests.BlockTest) (*node.Node, error) {
|
|||||||
ethConf := ð.Config{
|
ethConf := ð.Config{
|
||||||
TestGenesisState: db,
|
TestGenesisState: db,
|
||||||
TestGenesisBlock: test.Genesis,
|
TestGenesisBlock: test.Genesis,
|
||||||
ChainConfig: &core.ChainConfig{HomesteadBlock: params.MainNetHomesteadBlock},
|
ChainConfig: ¶ms.ChainConfig{HomesteadBlock: params.MainNetHomesteadBlock},
|
||||||
}
|
}
|
||||||
if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { return eth.New(ctx, ethConf) }); err != nil {
|
if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { return eth.New(ctx, ethConf) }); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -801,7 +801,7 @@ func SetupNetwork(ctx *cli.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MakeChainConfig reads the chain configuration from the database in ctx.Datadir.
|
// MakeChainConfig reads the chain configuration from the database in ctx.Datadir.
|
||||||
func MakeChainConfig(ctx *cli.Context, stack *node.Node) *core.ChainConfig {
|
func MakeChainConfig(ctx *cli.Context, stack *node.Node) *params.ChainConfig {
|
||||||
db := MakeChainDatabase(ctx, stack)
|
db := MakeChainDatabase(ctx, stack)
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
@ -809,9 +809,9 @@ func MakeChainConfig(ctx *cli.Context, stack *node.Node) *core.ChainConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MakeChainConfigFromDb reads the chain configuration from the given database.
|
// MakeChainConfigFromDb reads the chain configuration from the given database.
|
||||||
func MakeChainConfigFromDb(ctx *cli.Context, db ethdb.Database) *core.ChainConfig {
|
func MakeChainConfigFromDb(ctx *cli.Context, db ethdb.Database) *params.ChainConfig {
|
||||||
// If the chain is already initialized, use any existing chain configs
|
// If the chain is already initialized, use any existing chain configs
|
||||||
config := new(core.ChainConfig)
|
config := new(params.ChainConfig)
|
||||||
|
|
||||||
genesis := core.GetBlock(db, core.GetCanonicalHash(db, 0), 0)
|
genesis := core.GetBlock(db, core.GetCanonicalHash(db, 0), 0)
|
||||||
if genesis != nil {
|
if genesis != nil {
|
||||||
@ -849,19 +849,20 @@ func MakeChainConfigFromDb(ctx *cli.Context, db ethdb.Database) *core.ChainConfi
|
|||||||
}
|
}
|
||||||
config.DAOForkSupport = true
|
config.DAOForkSupport = true
|
||||||
}
|
}
|
||||||
if config.HomesteadGasRepriceBlock == nil {
|
config.DAOForkSupport = true
|
||||||
|
}
|
||||||
|
if config.EIP150Block == nil {
|
||||||
if ctx.GlobalBool(TestNetFlag.Name) {
|
if ctx.GlobalBool(TestNetFlag.Name) {
|
||||||
config.HomesteadGasRepriceBlock = params.TestNetHomesteadGasRepriceBlock
|
config.EIP150Block = params.TestNetHomesteadGasRepriceBlock
|
||||||
} else {
|
} else {
|
||||||
config.HomesteadGasRepriceBlock = params.MainNetHomesteadGasRepriceBlock
|
config.EIP150Block = params.MainNetHomesteadGasRepriceBlock
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if config.HomesteadGasRepriceHash == (common.Hash{}) {
|
if config.EIP150Hash == (common.Hash{}) {
|
||||||
if ctx.GlobalBool(TestNetFlag.Name) {
|
if ctx.GlobalBool(TestNetFlag.Name) {
|
||||||
config.HomesteadGasRepriceHash = params.TestNetHomesteadGasRepriceHash
|
config.EIP150Hash = params.TestNetHomesteadGasRepriceHash
|
||||||
} else {
|
} else {
|
||||||
config.HomesteadGasRepriceHash = params.MainNetHomesteadGasRepriceHash
|
config.EIP150Hash = params.MainNetHomesteadGasRepriceHash
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Force override any existing configs if explicitly requested
|
// Force override any existing configs if explicitly requested
|
||||||
|
@ -32,11 +32,12 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
// registryAPIBackend is a backend for an Ethereum Registry.
|
// registryAPIBackend is a backend for an Ethereum Registry.
|
||||||
type registryAPIBackend struct {
|
type registryAPIBackend struct {
|
||||||
config *core.ChainConfig
|
config *params.ChainConfig
|
||||||
bc *core.BlockChain
|
bc *core.BlockChain
|
||||||
chainDb ethdb.Database
|
chainDb ethdb.Database
|
||||||
txPool *core.TxPool
|
txPool *core.TxPool
|
||||||
@ -45,12 +46,12 @@ type registryAPIBackend struct {
|
|||||||
|
|
||||||
// PrivateRegistarAPI offers various functions to access the Ethereum registry.
|
// PrivateRegistarAPI offers various functions to access the Ethereum registry.
|
||||||
type PrivateRegistarAPI struct {
|
type PrivateRegistarAPI struct {
|
||||||
config *core.ChainConfig
|
config *params.ChainConfig
|
||||||
be *registryAPIBackend
|
be *registryAPIBackend
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPrivateRegistarAPI creates a new PrivateRegistarAPI instance.
|
// NewPrivateRegistarAPI creates a new PrivateRegistarAPI instance.
|
||||||
func NewPrivateRegistarAPI(config *core.ChainConfig, bc *core.BlockChain, chainDb ethdb.Database, txPool *core.TxPool, am *accounts.Manager) *PrivateRegistarAPI {
|
func NewPrivateRegistarAPI(config *params.ChainConfig, bc *core.BlockChain, chainDb ethdb.Database, txPool *core.TxPool, am *accounts.Manager) *PrivateRegistarAPI {
|
||||||
return &PrivateRegistarAPI{
|
return &PrivateRegistarAPI{
|
||||||
config: config,
|
config: config,
|
||||||
be: ®istryAPIBackend{
|
be: ®istryAPIBackend{
|
||||||
|
@ -28,10 +28,10 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
|
||||||
"github.com/ethereum/go-ethereum/eth"
|
"github.com/ethereum/go-ethereum/eth"
|
||||||
"github.com/ethereum/go-ethereum/internal/jsre"
|
"github.com/ethereum/go-ethereum/internal/jsre"
|
||||||
"github.com/ethereum/go-ethereum/node"
|
"github.com/ethereum/go-ethereum/node"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -97,7 +97,7 @@ func newTester(t *testing.T, confOverride func(*eth.Config)) *tester {
|
|||||||
t.Fatalf("failed to create node: %v", err)
|
t.Fatalf("failed to create node: %v", err)
|
||||||
}
|
}
|
||||||
ethConf := ð.Config{
|
ethConf := ð.Config{
|
||||||
ChainConfig: &core.ChainConfig{HomesteadBlock: new(big.Int)},
|
ChainConfig: ¶ms.ChainConfig{HomesteadBlock: new(big.Int)},
|
||||||
Etherbase: common.HexToAddress(testAddress),
|
Etherbase: common.HexToAddress(testAddress),
|
||||||
PowTest: true,
|
PowTest: true,
|
||||||
}
|
}
|
||||||
|
@ -163,12 +163,12 @@ func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) {
|
|||||||
// Generate a chain of b.N blocks using the supplied block
|
// Generate a chain of b.N blocks using the supplied block
|
||||||
// generator function.
|
// generator function.
|
||||||
genesis := WriteGenesisBlockForTesting(db, GenesisAccount{benchRootAddr, benchRootFunds})
|
genesis := WriteGenesisBlockForTesting(db, GenesisAccount{benchRootAddr, benchRootFunds})
|
||||||
chain, _ := GenerateChain(nil, genesis, db, b.N, gen)
|
chain, _ := GenerateChain(params.TestChainConfig, genesis, db, b.N, gen)
|
||||||
|
|
||||||
// Time the insertion of the new chain.
|
// Time the insertion of the new chain.
|
||||||
// State and blocks are stored in the same DB.
|
// State and blocks are stored in the same DB.
|
||||||
evmux := new(event.TypeMux)
|
evmux := new(event.TypeMux)
|
||||||
chainman, _ := NewBlockChain(db, &ChainConfig{HomesteadBlock: new(big.Int)}, FakePow{}, evmux)
|
chainman, _ := NewBlockChain(db, ¶ms.ChainConfig{HomesteadBlock: new(big.Int)}, FakePow{}, evmux)
|
||||||
defer chainman.Stop()
|
defer chainman.Stop()
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
|
@ -41,13 +41,13 @@ var (
|
|||||||
//
|
//
|
||||||
// BlockValidator implements Validator.
|
// BlockValidator implements Validator.
|
||||||
type BlockValidator struct {
|
type BlockValidator struct {
|
||||||
config *ChainConfig // Chain configuration options
|
config *params.ChainConfig // Chain configuration options
|
||||||
bc *BlockChain // Canonical block chain
|
bc *BlockChain // Canonical block chain
|
||||||
Pow pow.PoW // Proof of work used for validating
|
Pow pow.PoW // Proof of work used for validating
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBlockValidator returns a new block validator which is safe for re-use
|
// NewBlockValidator returns a new block validator which is safe for re-use
|
||||||
func NewBlockValidator(config *ChainConfig, blockchain *BlockChain, pow pow.PoW) *BlockValidator {
|
func NewBlockValidator(config *params.ChainConfig, blockchain *BlockChain, pow pow.PoW) *BlockValidator {
|
||||||
validator := &BlockValidator{
|
validator := &BlockValidator{
|
||||||
config: config,
|
config: config,
|
||||||
Pow: pow,
|
Pow: pow,
|
||||||
@ -128,7 +128,7 @@ func (v *BlockValidator) ValidateState(block, parent *types.Block, statedb *stat
|
|||||||
}
|
}
|
||||||
// Validate the state root against the received state root and throw
|
// Validate the state root against the received state root and throw
|
||||||
// an error if they don't match.
|
// an error if they don't match.
|
||||||
if root := statedb.IntermediateRoot(); header.Root != root {
|
if root := statedb.IntermediateRoot(v.config.IsEIP158(header.Number)); header.Root != root {
|
||||||
return fmt.Errorf("invalid merkle root: header=%x computed=%x", header.Root, root)
|
return fmt.Errorf("invalid merkle root: header=%x computed=%x", header.Root, root)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -203,7 +203,7 @@ func (v *BlockValidator) ValidateHeader(header, parent *types.Header, checkPow b
|
|||||||
// Validates a header. Returns an error if the header is invalid.
|
// Validates a header. Returns an error if the header is invalid.
|
||||||
//
|
//
|
||||||
// See YP section 4.3.4. "Block Header Validity"
|
// See YP section 4.3.4. "Block Header Validity"
|
||||||
func ValidateHeader(config *ChainConfig, pow pow.PoW, header *types.Header, parent *types.Header, checkPow, uncle bool) error {
|
func ValidateHeader(config *params.ChainConfig, pow pow.PoW, header *types.Header, parent *types.Header, checkPow, uncle bool) error {
|
||||||
if big.NewInt(int64(len(header.Extra))).Cmp(params.MaximumExtraDataSize) == 1 {
|
if big.NewInt(int64(len(header.Extra))).Cmp(params.MaximumExtraDataSize) == 1 {
|
||||||
return fmt.Errorf("Header extra data too long (%d)", len(header.Extra))
|
return fmt.Errorf("Header extra data too long (%d)", len(header.Extra))
|
||||||
}
|
}
|
||||||
@ -251,9 +251,9 @@ func ValidateHeader(config *ChainConfig, pow pow.PoW, header *types.Header, pare
|
|||||||
if err := ValidateDAOHeaderExtraData(config, header); err != nil {
|
if err := ValidateDAOHeaderExtraData(config, header); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if config.HomesteadGasRepriceBlock != nil && config.HomesteadGasRepriceBlock.Cmp(header.Number) == 0 {
|
if config.EIP150Block != nil && config.EIP150Block.Cmp(header.Number) == 0 {
|
||||||
if config.HomesteadGasRepriceHash != (common.Hash{}) && config.HomesteadGasRepriceHash != header.Hash() {
|
if config.EIP150Hash != (common.Hash{}) && config.EIP150Hash != header.Hash() {
|
||||||
return ValidationError("Homestead gas reprice fork hash mismatch: have 0x%x, want 0x%x", header.Hash(), config.HomesteadGasRepriceHash)
|
return ValidationError("Homestead gas reprice fork hash mismatch: have 0x%x, want 0x%x", header.Hash(), config.EIP150Hash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -262,7 +262,7 @@ func ValidateHeader(config *ChainConfig, pow pow.PoW, header *types.Header, pare
|
|||||||
// CalcDifficulty is the difficulty adjustment algorithm. It returns
|
// CalcDifficulty is the difficulty adjustment algorithm. It returns
|
||||||
// the difficulty that a new block should have when created at time
|
// the difficulty that a new block should have when created at time
|
||||||
// given the parent block's time and difficulty.
|
// given the parent block's time and difficulty.
|
||||||
func CalcDifficulty(config *ChainConfig, time, parentTime uint64, parentNumber, parentDiff *big.Int) *big.Int {
|
func CalcDifficulty(config *params.ChainConfig, time, parentTime uint64, parentNumber, parentDiff *big.Int) *big.Int {
|
||||||
if config.IsHomestead(new(big.Int).Add(parentNumber, common.Big1)) {
|
if config.IsHomestead(new(big.Int).Add(parentNumber, common.Big1)) {
|
||||||
return calcDifficultyHomestead(time, parentTime, parentNumber, parentDiff)
|
return calcDifficultyHomestead(time, parentTime, parentNumber, parentDiff)
|
||||||
} else {
|
} else {
|
||||||
|
@ -27,11 +27,13 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/pow/ezp"
|
"github.com/ethereum/go-ethereum/pow/ezp"
|
||||||
)
|
)
|
||||||
|
|
||||||
func testChainConfig() *ChainConfig {
|
func testChainConfig() *params.ChainConfig {
|
||||||
return &ChainConfig{HomesteadBlock: big.NewInt(0)}
|
return params.TestChainConfig
|
||||||
|
//return ¶ms.ChainConfig{HomesteadBlock: big.NewInt(0)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func proc() (Validator, *BlockChain) {
|
func proc() (Validator, *BlockChain) {
|
||||||
@ -51,15 +53,15 @@ func TestNumber(t *testing.T) {
|
|||||||
_, chain := proc()
|
_, chain := proc()
|
||||||
|
|
||||||
statedb, _ := state.New(chain.Genesis().Root(), chain.chainDb)
|
statedb, _ := state.New(chain.Genesis().Root(), chain.chainDb)
|
||||||
header := makeHeader(chain.Genesis(), statedb)
|
|
||||||
header.Number = big.NewInt(3)
|
|
||||||
cfg := testChainConfig()
|
cfg := testChainConfig()
|
||||||
|
header := makeHeader(cfg, chain.Genesis(), statedb)
|
||||||
|
header.Number = big.NewInt(3)
|
||||||
err := ValidateHeader(cfg, pow, header, chain.Genesis().Header(), false, false)
|
err := ValidateHeader(cfg, pow, header, chain.Genesis().Header(), false, false)
|
||||||
if err != BlockNumberErr {
|
if err != BlockNumberErr {
|
||||||
t.Errorf("expected block number error, got %q", err)
|
t.Errorf("expected block number error, got %q", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
header = makeHeader(chain.Genesis(), statedb)
|
header = makeHeader(cfg, chain.Genesis(), statedb)
|
||||||
err = ValidateHeader(cfg, pow, header, chain.Genesis().Header(), false, false)
|
err = ValidateHeader(cfg, pow, header, chain.Genesis().Header(), false, false)
|
||||||
if err == BlockNumberErr {
|
if err == BlockNumberErr {
|
||||||
t.Errorf("didn't expect block number error")
|
t.Errorf("didn't expect block number error")
|
||||||
|
@ -38,6 +38,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
"github.com/ethereum/go-ethereum/metrics"
|
"github.com/ethereum/go-ethereum/metrics"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/pow"
|
"github.com/ethereum/go-ethereum/pow"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/trie"
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
@ -78,7 +79,7 @@ const (
|
|||||||
// included in the canonical one where as GetBlockByNumber always represents the
|
// included in the canonical one where as GetBlockByNumber always represents the
|
||||||
// canonical chain.
|
// canonical chain.
|
||||||
type BlockChain struct {
|
type BlockChain struct {
|
||||||
config *ChainConfig // chain & network configuration
|
config *params.ChainConfig // chain & network configuration
|
||||||
|
|
||||||
hc *HeaderChain
|
hc *HeaderChain
|
||||||
chainDb ethdb.Database
|
chainDb ethdb.Database
|
||||||
@ -113,7 +114,7 @@ type BlockChain struct {
|
|||||||
// NewBlockChain returns a fully initialised block chain using information
|
// NewBlockChain returns a fully initialised block chain using information
|
||||||
// available in the database. It initialiser the default Ethereum Validator and
|
// available in the database. It initialiser the default Ethereum Validator and
|
||||||
// Processor.
|
// Processor.
|
||||||
func NewBlockChain(chainDb ethdb.Database, config *ChainConfig, pow pow.PoW, mux *event.TypeMux) (*BlockChain, error) {
|
func NewBlockChain(chainDb ethdb.Database, config *params.ChainConfig, pow pow.PoW, mux *event.TypeMux) (*BlockChain, error) {
|
||||||
bodyCache, _ := lru.New(bodyCacheLimit)
|
bodyCache, _ := lru.New(bodyCacheLimit)
|
||||||
bodyRLPCache, _ := lru.New(bodyCacheLimit)
|
bodyRLPCache, _ := lru.New(bodyCacheLimit)
|
||||||
blockCache, _ := lru.New(blockCacheLimit)
|
blockCache, _ := lru.New(blockCacheLimit)
|
||||||
@ -924,7 +925,7 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) {
|
|||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
// Process block using the parent state as reference point.
|
// Process block using the parent state as reference point.
|
||||||
receipts, logs, usedGas, err := self.processor.Process(block, self.stateCache, self.config.VmConfig)
|
receipts, logs, usedGas, err := self.processor.Process(block, self.stateCache, vm.Config{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
reportBlock(block, err)
|
reportBlock(block, err)
|
||||||
return i, err
|
return i, err
|
||||||
@ -936,7 +937,7 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) {
|
|||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
// Write state changes to database
|
// Write state changes to database
|
||||||
_, err = self.stateCache.Commit()
|
_, err = self.stateCache.Commit(self.config.IsEIP158(block.Number()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
@ -1309,4 +1310,4 @@ func (self *BlockChain) GetHeaderByNumber(number uint64) *types.Header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Config retrieves the blockchain's chain configuration.
|
// Config retrieves the blockchain's chain configuration.
|
||||||
func (self *BlockChain) Config() *ChainConfig { return self.config }
|
func (self *BlockChain) Config() *params.ChainConfig { return self.config }
|
||||||
|
@ -154,7 +154,7 @@ func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error {
|
|||||||
blockchain.mu.Lock()
|
blockchain.mu.Lock()
|
||||||
WriteTd(blockchain.chainDb, block.Hash(), block.NumberU64(), new(big.Int).Add(block.Difficulty(), blockchain.GetTdByHash(block.ParentHash())))
|
WriteTd(blockchain.chainDb, block.Hash(), block.NumberU64(), new(big.Int).Add(block.Difficulty(), blockchain.GetTdByHash(block.ParentHash())))
|
||||||
WriteBlock(blockchain.chainDb, block)
|
WriteBlock(blockchain.chainDb, block)
|
||||||
statedb.Commit()
|
statedb.Commit(false)
|
||||||
blockchain.mu.Unlock()
|
blockchain.mu.Unlock()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -712,7 +712,7 @@ func TestFastVsFullChains(t *testing.T) {
|
|||||||
funds = big.NewInt(1000000000)
|
funds = big.NewInt(1000000000)
|
||||||
genesis = GenesisBlockForTesting(gendb, address, funds)
|
genesis = GenesisBlockForTesting(gendb, address, funds)
|
||||||
)
|
)
|
||||||
blocks, receipts := GenerateChain(nil, genesis, gendb, 1024, func(i int, block *BlockGen) {
|
blocks, receipts := GenerateChain(params.TestChainConfig, genesis, gendb, 1024, func(i int, block *BlockGen) {
|
||||||
block.SetCoinbase(common.Address{0x00})
|
block.SetCoinbase(common.Address{0x00})
|
||||||
|
|
||||||
// If the block number is multiple of 3, send a few bonus transactions to the miner
|
// If the block number is multiple of 3, send a few bonus transactions to the miner
|
||||||
@ -795,7 +795,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) {
|
|||||||
genesis = GenesisBlockForTesting(gendb, address, funds)
|
genesis = GenesisBlockForTesting(gendb, address, funds)
|
||||||
)
|
)
|
||||||
height := uint64(1024)
|
height := uint64(1024)
|
||||||
blocks, receipts := GenerateChain(nil, genesis, gendb, int(height), nil)
|
blocks, receipts := GenerateChain(params.TestChainConfig, genesis, gendb, int(height), nil)
|
||||||
|
|
||||||
// Configure a subchain to roll back
|
// Configure a subchain to roll back
|
||||||
remove := []common.Hash{}
|
remove := []common.Hash{}
|
||||||
@ -895,7 +895,7 @@ func TestChainTxReorgs(t *testing.T) {
|
|||||||
// - futureAdd: transaction added after the reorg has already finished
|
// - futureAdd: transaction added after the reorg has already finished
|
||||||
var pastAdd, freshAdd, futureAdd *types.Transaction
|
var pastAdd, freshAdd, futureAdd *types.Transaction
|
||||||
|
|
||||||
chain, _ := GenerateChain(nil, genesis, db, 3, func(i int, gen *BlockGen) {
|
chain, _ := GenerateChain(params.TestChainConfig, genesis, db, 3, func(i int, gen *BlockGen) {
|
||||||
switch i {
|
switch i {
|
||||||
case 0:
|
case 0:
|
||||||
pastDrop, _ = types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil).SignECDSA(key2)
|
pastDrop, _ = types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil).SignECDSA(key2)
|
||||||
@ -920,7 +920,7 @@ func TestChainTxReorgs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// overwrite the old chain
|
// overwrite the old chain
|
||||||
chain, _ = GenerateChain(nil, genesis, db, 5, func(i int, gen *BlockGen) {
|
chain, _ = GenerateChain(params.TestChainConfig, genesis, db, 5, func(i int, gen *BlockGen) {
|
||||||
switch i {
|
switch i {
|
||||||
case 0:
|
case 0:
|
||||||
pastAdd, _ = types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil).SignECDSA(key3)
|
pastAdd, _ = types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil).SignECDSA(key3)
|
||||||
@ -990,7 +990,7 @@ func TestLogReorgs(t *testing.T) {
|
|||||||
blockchain, _ := NewBlockChain(db, testChainConfig(), FakePow{}, evmux)
|
blockchain, _ := NewBlockChain(db, testChainConfig(), FakePow{}, evmux)
|
||||||
|
|
||||||
subs := evmux.Subscribe(RemovedLogsEvent{})
|
subs := evmux.Subscribe(RemovedLogsEvent{})
|
||||||
chain, _ := GenerateChain(nil, genesis, db, 2, func(i int, gen *BlockGen) {
|
chain, _ := GenerateChain(params.TestChainConfig, genesis, db, 2, func(i int, gen *BlockGen) {
|
||||||
if i == 1 {
|
if i == 1 {
|
||||||
tx, err := types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), big.NewInt(1000000), new(big.Int), code).SignECDSA(key1)
|
tx, err := types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), big.NewInt(1000000), new(big.Int), code).SignECDSA(key1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1003,7 +1003,7 @@ func TestLogReorgs(t *testing.T) {
|
|||||||
t.Fatalf("failed to insert chain: %v", err)
|
t.Fatalf("failed to insert chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
chain, _ = GenerateChain(nil, genesis, db, 3, func(i int, gen *BlockGen) {})
|
chain, _ = GenerateChain(params.TestChainConfig, genesis, db, 3, func(i int, gen *BlockGen) {})
|
||||||
if _, err := blockchain.InsertChain(chain); err != nil {
|
if _, err := blockchain.InsertChain(chain); err != nil {
|
||||||
t.Fatalf("failed to insert forked chain: %v", err)
|
t.Fatalf("failed to insert forked chain: %v", err)
|
||||||
}
|
}
|
||||||
@ -1025,12 +1025,12 @@ func TestReorgSideEvent(t *testing.T) {
|
|||||||
evmux := &event.TypeMux{}
|
evmux := &event.TypeMux{}
|
||||||
blockchain, _ := NewBlockChain(db, testChainConfig(), FakePow{}, evmux)
|
blockchain, _ := NewBlockChain(db, testChainConfig(), FakePow{}, evmux)
|
||||||
|
|
||||||
chain, _ := GenerateChain(nil, genesis, db, 3, func(i int, gen *BlockGen) {})
|
chain, _ := GenerateChain(params.TestChainConfig, genesis, db, 3, func(i int, gen *BlockGen) {})
|
||||||
if _, err := blockchain.InsertChain(chain); err != nil {
|
if _, err := blockchain.InsertChain(chain); err != nil {
|
||||||
t.Fatalf("failed to insert chain: %v", err)
|
t.Fatalf("failed to insert chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
replacementBlocks, _ := GenerateChain(nil, genesis, db, 4, func(i int, gen *BlockGen) {
|
replacementBlocks, _ := GenerateChain(params.TestChainConfig, genesis, db, 4, func(i int, gen *BlockGen) {
|
||||||
tx, err := types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), big.NewInt(1000000), new(big.Int), nil).SignECDSA(key1)
|
tx, err := types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), big.NewInt(1000000), new(big.Int), nil).SignECDSA(key1)
|
||||||
if i == 2 {
|
if i == 2 {
|
||||||
gen.OffsetTime(-1)
|
gen.OffsetTime(-1)
|
||||||
@ -1101,7 +1101,7 @@ func TestCanonicalBlockRetrieval(t *testing.T) {
|
|||||||
evmux := &event.TypeMux{}
|
evmux := &event.TypeMux{}
|
||||||
blockchain, _ := NewBlockChain(db, testChainConfig(), FakePow{}, evmux)
|
blockchain, _ := NewBlockChain(db, testChainConfig(), FakePow{}, evmux)
|
||||||
|
|
||||||
chain, _ := GenerateChain(nil, genesis, db, 10, func(i int, gen *BlockGen) {})
|
chain, _ := GenerateChain(params.TestChainConfig, genesis, db, 10, func(i int, gen *BlockGen) {})
|
||||||
|
|
||||||
for i, _ := range chain {
|
for i, _ := range chain {
|
||||||
go func(block *types.Block) {
|
go func(block *types.Block) {
|
||||||
|
@ -35,8 +35,8 @@ import (
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// MakeChainConfig returns a new ChainConfig with the ethereum default chain settings.
|
// MakeChainConfig returns a new ChainConfig with the ethereum default chain settings.
|
||||||
func MakeChainConfig() *ChainConfig {
|
func MakeChainConfig() *params.ChainConfig {
|
||||||
return &ChainConfig{
|
return ¶ms.ChainConfig{
|
||||||
HomesteadBlock: big.NewInt(0),
|
HomesteadBlock: big.NewInt(0),
|
||||||
DAOForkBlock: nil,
|
DAOForkBlock: nil,
|
||||||
DAOForkSupport: true,
|
DAOForkSupport: true,
|
||||||
@ -73,6 +73,8 @@ type BlockGen struct {
|
|||||||
txs []*types.Transaction
|
txs []*types.Transaction
|
||||||
receipts []*types.Receipt
|
receipts []*types.Receipt
|
||||||
uncles []*types.Header
|
uncles []*types.Header
|
||||||
|
|
||||||
|
config *params.ChainConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetCoinbase sets the coinbase of the generated block.
|
// SetCoinbase sets the coinbase of the generated block.
|
||||||
@ -106,7 +108,7 @@ func (b *BlockGen) AddTx(tx *types.Transaction) {
|
|||||||
b.SetCoinbase(common.Address{})
|
b.SetCoinbase(common.Address{})
|
||||||
}
|
}
|
||||||
b.statedb.StartRecord(tx.Hash(), common.Hash{}, len(b.txs))
|
b.statedb.StartRecord(tx.Hash(), common.Hash{}, len(b.txs))
|
||||||
receipt, _, _, err := ApplyTransaction(MakeChainConfig(), nil, b.gasPool, b.statedb, b.header, tx, b.header.GasUsed, vm.Config{})
|
receipt, _, _, err := ApplyTransaction(b.config, nil, b.gasPool, b.statedb, b.header, tx, b.header.GasUsed, vm.Config{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@ -178,10 +180,10 @@ func (b *BlockGen) OffsetTime(seconds int64) {
|
|||||||
// Blocks created by GenerateChain do not contain valid proof of work
|
// Blocks created by GenerateChain do not contain valid proof of work
|
||||||
// values. Inserting them into BlockChain requires use of FakePow or
|
// values. Inserting them into BlockChain requires use of FakePow or
|
||||||
// a similar non-validating proof of work implementation.
|
// a similar non-validating proof of work implementation.
|
||||||
func GenerateChain(config *ChainConfig, parent *types.Block, db ethdb.Database, n int, gen func(int, *BlockGen)) ([]*types.Block, []types.Receipts) {
|
func GenerateChain(config *params.ChainConfig, parent *types.Block, db ethdb.Database, n int, gen func(int, *BlockGen)) ([]*types.Block, []types.Receipts) {
|
||||||
blocks, receipts := make(types.Blocks, n), make([]types.Receipts, n)
|
blocks, receipts := make(types.Blocks, n), make([]types.Receipts, n)
|
||||||
genblock := func(i int, h *types.Header, statedb *state.StateDB) (*types.Block, types.Receipts) {
|
genblock := func(i int, h *types.Header, statedb *state.StateDB) (*types.Block, types.Receipts) {
|
||||||
b := &BlockGen{parent: parent, i: i, chain: blocks, header: h, statedb: statedb}
|
b := &BlockGen{parent: parent, i: i, chain: blocks, header: h, statedb: statedb, config: config}
|
||||||
|
|
||||||
// Mutate the state and block according to any hard-fork specs
|
// Mutate the state and block according to any hard-fork specs
|
||||||
if config == nil {
|
if config == nil {
|
||||||
@ -203,7 +205,7 @@ func GenerateChain(config *ChainConfig, parent *types.Block, db ethdb.Database,
|
|||||||
gen(i, b)
|
gen(i, b)
|
||||||
}
|
}
|
||||||
AccumulateRewards(statedb, h, b.uncles)
|
AccumulateRewards(statedb, h, b.uncles)
|
||||||
root, err := statedb.Commit()
|
root, err := statedb.Commit(config.IsEIP158(h.Number))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Sprintf("state write error: %v", err))
|
panic(fmt.Sprintf("state write error: %v", err))
|
||||||
}
|
}
|
||||||
@ -215,7 +217,7 @@ func GenerateChain(config *ChainConfig, parent *types.Block, db ethdb.Database,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
header := makeHeader(parent, statedb)
|
header := makeHeader(config, parent, statedb)
|
||||||
block, receipt := genblock(i, header, statedb)
|
block, receipt := genblock(i, header, statedb)
|
||||||
blocks[i] = block
|
blocks[i] = block
|
||||||
receipts[i] = receipt
|
receipts[i] = receipt
|
||||||
@ -224,7 +226,7 @@ func GenerateChain(config *ChainConfig, parent *types.Block, db ethdb.Database,
|
|||||||
return blocks, receipts
|
return blocks, receipts
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeHeader(parent *types.Block, state *state.StateDB) *types.Header {
|
func makeHeader(config *params.ChainConfig, parent *types.Block, state *state.StateDB) *types.Header {
|
||||||
var time *big.Int
|
var time *big.Int
|
||||||
if parent.Time() == nil {
|
if parent.Time() == nil {
|
||||||
time = big.NewInt(10)
|
time = big.NewInt(10)
|
||||||
@ -232,7 +234,7 @@ func makeHeader(parent *types.Block, state *state.StateDB) *types.Header {
|
|||||||
time = new(big.Int).Add(parent.Time(), big.NewInt(10)) // block time is fixed at 10 seconds
|
time = new(big.Int).Add(parent.Time(), big.NewInt(10)) // block time is fixed at 10 seconds
|
||||||
}
|
}
|
||||||
return &types.Header{
|
return &types.Header{
|
||||||
Root: state.IntermediateRoot(),
|
Root: state.IntermediateRoot(config.IsEIP158(parent.Number())),
|
||||||
ParentHash: parent.Hash(),
|
ParentHash: parent.Hash(),
|
||||||
Coinbase: parent.Coinbase(),
|
Coinbase: parent.Coinbase(),
|
||||||
Difficulty: CalcDifficulty(MakeChainConfig(), time.Uint64(), new(big.Int).Sub(time, big.NewInt(10)).Uint64(), parent.Number(), parent.Difficulty()),
|
Difficulty: CalcDifficulty(MakeChainConfig(), time.Uint64(), new(big.Int).Sub(time, big.NewInt(10)).Uint64(), parent.Number(), parent.Difficulty()),
|
||||||
@ -283,7 +285,7 @@ func makeHeaderChain(parent *types.Header, n int, db ethdb.Database, seed int) [
|
|||||||
|
|
||||||
// makeBlockChain creates a deterministic chain of blocks rooted at parent.
|
// makeBlockChain creates a deterministic chain of blocks rooted at parent.
|
||||||
func makeBlockChain(parent *types.Block, n int, db ethdb.Database, seed int) []*types.Block {
|
func makeBlockChain(parent *types.Block, n int, db ethdb.Database, seed int) []*types.Block {
|
||||||
blocks, _ := GenerateChain(nil, parent, db, n, func(i int, b *BlockGen) {
|
blocks, _ := GenerateChain(params.TestChainConfig, parent, db, n, func(i int, b *BlockGen) {
|
||||||
b.SetCoinbase(common.Address{0: byte(seed), 19: byte(i)})
|
b.SetCoinbase(common.Address{0: byte(seed), 19: byte(i)})
|
||||||
})
|
})
|
||||||
return blocks
|
return blocks
|
||||||
|
@ -41,13 +41,16 @@ func ExampleGenerateChain() {
|
|||||||
db, _ = ethdb.NewMemDatabase()
|
db, _ = ethdb.NewMemDatabase()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
chainConfig := ¶ms.ChainConfig{
|
||||||
|
HomesteadBlock: new(big.Int),
|
||||||
|
}
|
||||||
// Ensure that key1 has some funds in the genesis block.
|
// Ensure that key1 has some funds in the genesis block.
|
||||||
genesis := WriteGenesisBlockForTesting(db, GenesisAccount{addr1, big.NewInt(1000000)})
|
genesis := WriteGenesisBlockForTesting(db, GenesisAccount{addr1, big.NewInt(1000000)})
|
||||||
|
|
||||||
// This call generates a chain of 5 blocks. The function runs for
|
// This call generates a chain of 5 blocks. The function runs for
|
||||||
// each block and adds different features to gen based on the
|
// each block and adds different features to gen based on the
|
||||||
// block index.
|
// block index.
|
||||||
chain, _ := GenerateChain(nil, genesis, db, 5, func(i int, gen *BlockGen) {
|
chain, _ := GenerateChain(chainConfig, genesis, db, 5, func(i int, gen *BlockGen) {
|
||||||
switch i {
|
switch i {
|
||||||
case 0:
|
case 0:
|
||||||
// In block 1, addr1 sends addr2 some ether.
|
// In block 1, addr1 sends addr2 some ether.
|
||||||
@ -77,7 +80,7 @@ func ExampleGenerateChain() {
|
|||||||
|
|
||||||
// Import the chain. This runs all block validation rules.
|
// Import the chain. This runs all block validation rules.
|
||||||
evmux := &event.TypeMux{}
|
evmux := &event.TypeMux{}
|
||||||
blockchain, _ := NewBlockChain(db, MakeChainConfig(), FakePow{}, evmux)
|
blockchain, _ := NewBlockChain(db, chainConfig, FakePow{}, evmux)
|
||||||
if i, err := blockchain.InsertChain(chain); err != nil {
|
if i, err := blockchain.InsertChain(chain); err != nil {
|
||||||
fmt.Printf("insert error (block %d): %v\n", chain[i].NumberU64(), err)
|
fmt.Printf("insert error (block %d): %v\n", chain[i].NumberU64(), err)
|
||||||
return
|
return
|
||||||
|
@ -25,6 +25,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/pow"
|
"github.com/ethereum/go-ethereum/pow"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -60,7 +61,7 @@ func TestPowVerification(t *testing.T) {
|
|||||||
var (
|
var (
|
||||||
testdb, _ = ethdb.NewMemDatabase()
|
testdb, _ = ethdb.NewMemDatabase()
|
||||||
genesis = GenesisBlockForTesting(testdb, common.Address{}, new(big.Int))
|
genesis = GenesisBlockForTesting(testdb, common.Address{}, new(big.Int))
|
||||||
blocks, _ = GenerateChain(nil, genesis, testdb, 8, nil)
|
blocks, _ = GenerateChain(params.TestChainConfig, genesis, testdb, 8, nil)
|
||||||
)
|
)
|
||||||
headers := make([]*types.Header, len(blocks))
|
headers := make([]*types.Header, len(blocks))
|
||||||
for i, block := range blocks {
|
for i, block := range blocks {
|
||||||
@ -115,7 +116,7 @@ func testPowConcurrentVerification(t *testing.T, threads int) {
|
|||||||
var (
|
var (
|
||||||
testdb, _ = ethdb.NewMemDatabase()
|
testdb, _ = ethdb.NewMemDatabase()
|
||||||
genesis = GenesisBlockForTesting(testdb, common.Address{}, new(big.Int))
|
genesis = GenesisBlockForTesting(testdb, common.Address{}, new(big.Int))
|
||||||
blocks, _ = GenerateChain(nil, genesis, testdb, 8, nil)
|
blocks, _ = GenerateChain(params.TestChainConfig, genesis, testdb, 8, nil)
|
||||||
)
|
)
|
||||||
headers := make([]*types.Header, len(blocks))
|
headers := make([]*types.Header, len(blocks))
|
||||||
for i, block := range blocks {
|
for i, block := range blocks {
|
||||||
@ -186,7 +187,7 @@ func testPowConcurrentAbortion(t *testing.T, threads int) {
|
|||||||
var (
|
var (
|
||||||
testdb, _ = ethdb.NewMemDatabase()
|
testdb, _ = ethdb.NewMemDatabase()
|
||||||
genesis = GenesisBlockForTesting(testdb, common.Address{}, new(big.Int))
|
genesis = GenesisBlockForTesting(testdb, common.Address{}, new(big.Int))
|
||||||
blocks, _ = GenerateChain(nil, genesis, testdb, 1024, nil)
|
blocks, _ = GenerateChain(params.TestChainConfig, genesis, testdb, 1024, nil)
|
||||||
)
|
)
|
||||||
headers := make([]*types.Header, len(blocks))
|
headers := make([]*types.Header, len(blocks))
|
||||||
for i, block := range blocks {
|
for i, block := range blocks {
|
||||||
|
@ -33,7 +33,7 @@ import (
|
|||||||
// with the fork specific extra-data set
|
// with the fork specific extra-data set
|
||||||
// b) if the node is pro-fork, require blocks in the specific range to have the
|
// b) if the node is pro-fork, require blocks in the specific range to have the
|
||||||
// unique extra-data set.
|
// unique extra-data set.
|
||||||
func ValidateDAOHeaderExtraData(config *ChainConfig, header *types.Header) error {
|
func ValidateDAOHeaderExtraData(config *params.ChainConfig, header *types.Header) error {
|
||||||
// Short circuit validation if the node doesn't care about the DAO fork
|
// Short circuit validation if the node doesn't care about the DAO fork
|
||||||
if config.DAOForkBlock == nil {
|
if config.DAOForkBlock == nil {
|
||||||
return nil
|
return nil
|
||||||
|
@ -33,17 +33,17 @@ func TestDAOForkRangeExtradata(t *testing.T) {
|
|||||||
// Generate a common prefix for both pro-forkers and non-forkers
|
// Generate a common prefix for both pro-forkers and non-forkers
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
genesis := WriteGenesisBlockForTesting(db)
|
genesis := WriteGenesisBlockForTesting(db)
|
||||||
prefix, _ := GenerateChain(nil, genesis, db, int(forkBlock.Int64()-1), func(i int, gen *BlockGen) {})
|
prefix, _ := GenerateChain(params.TestChainConfig, genesis, db, int(forkBlock.Int64()-1), func(i int, gen *BlockGen) {})
|
||||||
|
|
||||||
// Create the concurrent, conflicting two nodes
|
// Create the concurrent, conflicting two nodes
|
||||||
proDb, _ := ethdb.NewMemDatabase()
|
proDb, _ := ethdb.NewMemDatabase()
|
||||||
WriteGenesisBlockForTesting(proDb)
|
WriteGenesisBlockForTesting(proDb)
|
||||||
proConf := &ChainConfig{HomesteadBlock: big.NewInt(0), DAOForkBlock: forkBlock, DAOForkSupport: true}
|
proConf := ¶ms.ChainConfig{HomesteadBlock: big.NewInt(0), DAOForkBlock: forkBlock, DAOForkSupport: true}
|
||||||
proBc, _ := NewBlockChain(proDb, proConf, new(FakePow), new(event.TypeMux))
|
proBc, _ := NewBlockChain(proDb, proConf, new(FakePow), new(event.TypeMux))
|
||||||
|
|
||||||
conDb, _ := ethdb.NewMemDatabase()
|
conDb, _ := ethdb.NewMemDatabase()
|
||||||
WriteGenesisBlockForTesting(conDb)
|
WriteGenesisBlockForTesting(conDb)
|
||||||
conConf := &ChainConfig{HomesteadBlock: big.NewInt(0), DAOForkBlock: forkBlock, DAOForkSupport: false}
|
conConf := ¶ms.ChainConfig{HomesteadBlock: big.NewInt(0), DAOForkBlock: forkBlock, DAOForkSupport: false}
|
||||||
conBc, _ := NewBlockChain(conDb, conConf, new(FakePow), new(event.TypeMux))
|
conBc, _ := NewBlockChain(conDb, conConf, new(FakePow), new(event.TypeMux))
|
||||||
|
|
||||||
if _, err := proBc.InsertChain(prefix); err != nil {
|
if _, err := proBc.InsertChain(prefix); err != nil {
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
@ -28,6 +29,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -59,6 +61,8 @@ var (
|
|||||||
oldBlockNumPrefix = []byte("block-num-")
|
oldBlockNumPrefix = []byte("block-num-")
|
||||||
oldBlockReceiptsPrefix = []byte("receipts-block-")
|
oldBlockReceiptsPrefix = []byte("receipts-block-")
|
||||||
oldBlockHashPrefix = []byte("block-hash-") // [deprecated by the header/block split, remove eventually]
|
oldBlockHashPrefix = []byte("block-hash-") // [deprecated by the header/block split, remove eventually]
|
||||||
|
|
||||||
|
ChainConfigNotFoundErr = errors.New("ChainConfig not found") // general config not found error
|
||||||
)
|
)
|
||||||
|
|
||||||
// encodeBlockNumber encodes a block number as big endian uint64
|
// encodeBlockNumber encodes a block number as big endian uint64
|
||||||
@ -600,7 +604,7 @@ func WriteBlockChainVersion(db ethdb.Database, vsn int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WriteChainConfig writes the chain config settings to the database.
|
// WriteChainConfig writes the chain config settings to the database.
|
||||||
func WriteChainConfig(db ethdb.Database, hash common.Hash, cfg *ChainConfig) error {
|
func WriteChainConfig(db ethdb.Database, hash common.Hash, cfg *params.ChainConfig) error {
|
||||||
// short circuit and ignore if nil config. GetChainConfig
|
// short circuit and ignore if nil config. GetChainConfig
|
||||||
// will return a default.
|
// will return a default.
|
||||||
if cfg == nil {
|
if cfg == nil {
|
||||||
@ -616,13 +620,13 @@ func WriteChainConfig(db ethdb.Database, hash common.Hash, cfg *ChainConfig) err
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetChainConfig will fetch the network settings based on the given hash.
|
// GetChainConfig will fetch the network settings based on the given hash.
|
||||||
func GetChainConfig(db ethdb.Database, hash common.Hash) (*ChainConfig, error) {
|
func GetChainConfig(db ethdb.Database, hash common.Hash) (*params.ChainConfig, error) {
|
||||||
jsonChainConfig, _ := db.Get(append(configPrefix, hash[:]...))
|
jsonChainConfig, _ := db.Get(append(configPrefix, hash[:]...))
|
||||||
if len(jsonChainConfig) == 0 {
|
if len(jsonChainConfig) == 0 {
|
||||||
return nil, ChainConfigNotFoundErr
|
return nil, ChainConfigNotFoundErr
|
||||||
}
|
}
|
||||||
|
|
||||||
var config ChainConfig
|
var config params.ChainConfig
|
||||||
if err := json.Unmarshal(jsonChainConfig, &config); err != nil {
|
if err := json.Unmarshal(jsonChainConfig, &config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/crypto/sha3"
|
"github.com/ethereum/go-ethereum/crypto/sha3"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -75,7 +76,7 @@ func TestCalcDifficulty(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
config := &ChainConfig{HomesteadBlock: big.NewInt(1150000)}
|
config := ¶ms.ChainConfig{HomesteadBlock: big.NewInt(1150000)}
|
||||||
for name, test := range tests {
|
for name, test := range tests {
|
||||||
number := new(big.Int).Sub(test.CurrentBlocknumber, big.NewInt(1))
|
number := new(big.Int).Sub(test.CurrentBlocknumber, big.NewInt(1))
|
||||||
diff := CalcDifficulty(config, test.CurrentTimestamp, test.ParentTimestamp, number, test.ParentDifficulty)
|
diff := CalcDifficulty(config, test.CurrentTimestamp, test.ParentTimestamp, number, test.ParentDifficulty)
|
||||||
@ -562,7 +563,7 @@ func TestMipmapChain(t *testing.T) {
|
|||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
genesis := WriteGenesisBlockForTesting(db, GenesisAccount{addr, big.NewInt(1000000)})
|
genesis := WriteGenesisBlockForTesting(db, GenesisAccount{addr, big.NewInt(1000000)})
|
||||||
chain, receipts := GenerateChain(nil, genesis, db, 1010, func(i int, gen *BlockGen) {
|
chain, receipts := GenerateChain(params.TestChainConfig, genesis, db, 1010, func(i int, gen *BlockGen) {
|
||||||
var receipts types.Receipts
|
var receipts types.Receipts
|
||||||
switch i {
|
switch i {
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -27,62 +27,17 @@ import (
|
|||||||
|
|
||||||
// Call executes within the given contract
|
// Call executes within the given contract
|
||||||
func Call(env vm.Environment, caller vm.ContractRef, addr common.Address, input []byte, gas, gasPrice, value *big.Int) (ret []byte, err error) {
|
func Call(env vm.Environment, caller vm.ContractRef, addr common.Address, input []byte, gas, gasPrice, value *big.Int) (ret []byte, err error) {
|
||||||
ret, _, err = exec(env, caller, &addr, &addr, env.Db().GetCodeHash(addr), input, env.Db().GetCode(addr), gas, gasPrice, value)
|
|
||||||
return ret, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// CallCode executes the given address' code as the given contract address
|
|
||||||
func CallCode(env vm.Environment, caller vm.ContractRef, addr common.Address, input []byte, gas, gasPrice, value *big.Int) (ret []byte, err error) {
|
|
||||||
callerAddr := caller.Address()
|
|
||||||
ret, _, err = exec(env, caller, &callerAddr, &addr, env.Db().GetCodeHash(addr), input, env.Db().GetCode(addr), gas, gasPrice, value)
|
|
||||||
return ret, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// DelegateCall is equivalent to CallCode except that sender and value propagates from parent scope to child scope
|
|
||||||
func DelegateCall(env vm.Environment, caller vm.ContractRef, addr common.Address, input []byte, gas, gasPrice *big.Int) (ret []byte, err error) {
|
|
||||||
callerAddr := caller.Address()
|
|
||||||
originAddr := env.Origin()
|
|
||||||
callerValue := caller.Value()
|
|
||||||
ret, _, err = execDelegateCall(env, caller, &originAddr, &callerAddr, &addr, env.Db().GetCodeHash(addr), input, env.Db().GetCode(addr), gas, gasPrice, callerValue)
|
|
||||||
return ret, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create creates a new contract with the given code
|
|
||||||
func Create(env vm.Environment, caller vm.ContractRef, code []byte, gas, gasPrice, value *big.Int) (ret []byte, address common.Address, err error) {
|
|
||||||
ret, address, err = exec(env, caller, nil, nil, crypto.Keccak256Hash(code), nil, code, gas, gasPrice, value)
|
|
||||||
// Here we get an error if we run into maximum stack depth,
|
|
||||||
// See: https://github.com/ethereum/yellowpaper/pull/131
|
|
||||||
// and YP definitions for CREATE instruction
|
|
||||||
if err != nil {
|
|
||||||
return nil, address, err
|
|
||||||
}
|
|
||||||
return ret, address, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func exec(env vm.Environment, caller vm.ContractRef, address, codeAddr *common.Address, codeHash common.Hash, input, code []byte, gas, gasPrice, value *big.Int) (ret []byte, addr common.Address, err error) {
|
|
||||||
evm := env.Vm()
|
|
||||||
// Depth check execution. Fail if we're trying to execute above the
|
// Depth check execution. Fail if we're trying to execute above the
|
||||||
// limit.
|
// limit.
|
||||||
if env.Depth() > int(params.CallCreateDepth.Int64()) {
|
if env.Depth() > int(params.CallCreateDepth.Int64()) {
|
||||||
caller.ReturnGas(gas, gasPrice)
|
caller.ReturnGas(gas, gasPrice)
|
||||||
|
|
||||||
return nil, common.Address{}, vm.DepthError
|
return nil, vm.DepthError
|
||||||
}
|
}
|
||||||
|
|
||||||
if !env.CanTransfer(caller.Address(), value) {
|
if !env.CanTransfer(caller.Address(), value) {
|
||||||
caller.ReturnGas(gas, gasPrice)
|
caller.ReturnGas(gas, gasPrice)
|
||||||
|
|
||||||
return nil, common.Address{}, ValueTransferErr("insufficient funds to transfer value. Req %v, has %v", value, env.Db().GetBalance(caller.Address()))
|
return nil, ValueTransferErr("insufficient funds to transfer value. Req %v, has %v", value, env.Db().GetBalance(caller.Address()))
|
||||||
}
|
|
||||||
|
|
||||||
var createAccount bool
|
|
||||||
if address == nil {
|
|
||||||
// Create a new account on the state
|
|
||||||
nonce := env.Db().GetNonce(caller.Address())
|
|
||||||
env.Db().SetNonce(caller.Address(), nonce+1)
|
|
||||||
addr = crypto.CreateAddress(caller.Address(), nonce)
|
|
||||||
address = &addr
|
|
||||||
createAccount = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
snapshotPreTransfer := env.SnapshotDatabase()
|
snapshotPreTransfer := env.SnapshotDatabase()
|
||||||
@ -90,14 +45,15 @@ func exec(env vm.Environment, caller vm.ContractRef, address, codeAddr *common.A
|
|||||||
from = env.Db().GetAccount(caller.Address())
|
from = env.Db().GetAccount(caller.Address())
|
||||||
to vm.Account
|
to vm.Account
|
||||||
)
|
)
|
||||||
if createAccount {
|
if !env.Db().Exist(addr) {
|
||||||
to = env.Db().CreateAccount(*address)
|
if vm.Precompiled[addr.Str()] == nil && env.ChainConfig().IsEIP158(env.BlockNumber()) && value.BitLen() == 0 {
|
||||||
} else {
|
caller.ReturnGas(gas, gasPrice)
|
||||||
if !env.Db().Exist(*address) {
|
return nil, nil
|
||||||
to = env.Db().CreateAccount(*address)
|
|
||||||
} else {
|
|
||||||
to = env.Db().GetAccount(*address)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
to = env.Db().CreateAccount(addr)
|
||||||
|
} else {
|
||||||
|
to = env.Db().GetAccount(addr)
|
||||||
}
|
}
|
||||||
env.Transfer(from, to, value)
|
env.Transfer(from, to, value)
|
||||||
|
|
||||||
@ -105,19 +61,104 @@ func exec(env vm.Environment, caller vm.ContractRef, address, codeAddr *common.A
|
|||||||
// EVM. The contract is a scoped environment for this execution context
|
// EVM. The contract is a scoped environment for this execution context
|
||||||
// only.
|
// only.
|
||||||
contract := vm.NewContract(caller, to, value, gas, gasPrice)
|
contract := vm.NewContract(caller, to, value, gas, gasPrice)
|
||||||
contract.SetCallCode(codeAddr, codeHash, code)
|
contract.SetCallCode(&addr, env.Db().GetCodeHash(addr), env.Db().GetCode(addr))
|
||||||
defer contract.Finalise()
|
defer contract.Finalise()
|
||||||
|
|
||||||
ret, err = evm.Run(contract, input)
|
ret, err = env.Vm().Run(contract, input)
|
||||||
|
// When an error was returned by the EVM or when setting the creation code
|
||||||
|
// above we revert to the snapshot and consume any gas remaining. Additionally
|
||||||
|
// when we're in homestead this also counts for code storage gas errors.
|
||||||
|
if err != nil {
|
||||||
|
contract.UseGas(contract.Gas)
|
||||||
|
|
||||||
|
env.RevertToSnapshot(snapshotPreTransfer)
|
||||||
|
}
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CallCode executes the given address' code as the given contract address
|
||||||
|
func CallCode(env vm.Environment, caller vm.ContractRef, addr common.Address, input []byte, gas, gasPrice, value *big.Int) (ret []byte, err error) {
|
||||||
|
// Depth check execution. Fail if we're trying to execute above the
|
||||||
|
// limit.
|
||||||
|
if env.Depth() > int(params.CallCreateDepth.Int64()) {
|
||||||
|
caller.ReturnGas(gas, gasPrice)
|
||||||
|
|
||||||
|
return nil, vm.DepthError
|
||||||
|
}
|
||||||
|
if !env.CanTransfer(caller.Address(), value) {
|
||||||
|
caller.ReturnGas(gas, gasPrice)
|
||||||
|
|
||||||
|
return nil, ValueTransferErr("insufficient funds to transfer value. Req %v, has %v", value, env.Db().GetBalance(caller.Address()))
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
snapshotPreTransfer = env.SnapshotDatabase()
|
||||||
|
to = env.Db().GetAccount(caller.Address())
|
||||||
|
)
|
||||||
|
// initialise a new contract and set the code that is to be used by the
|
||||||
|
// EVM. The contract is a scoped environment for this execution context
|
||||||
|
// only.
|
||||||
|
contract := vm.NewContract(caller, to, value, gas, gasPrice)
|
||||||
|
contract.SetCallCode(&addr, env.Db().GetCodeHash(addr), env.Db().GetCode(addr))
|
||||||
|
defer contract.Finalise()
|
||||||
|
|
||||||
|
ret, err = env.Vm().Run(contract, input)
|
||||||
|
if err != nil {
|
||||||
|
contract.UseGas(contract.Gas)
|
||||||
|
|
||||||
|
env.RevertToSnapshot(snapshotPreTransfer)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create creates a new contract with the given code
|
||||||
|
func Create(env vm.Environment, caller vm.ContractRef, code []byte, gas, gasPrice, value *big.Int) (ret []byte, address common.Address, err error) {
|
||||||
|
// Depth check execution. Fail if we're trying to execute above the
|
||||||
|
// limit.
|
||||||
|
if env.Depth() > int(params.CallCreateDepth.Int64()) {
|
||||||
|
caller.ReturnGas(gas, gasPrice)
|
||||||
|
|
||||||
|
return nil, common.Address{}, vm.DepthError
|
||||||
|
}
|
||||||
|
if !env.CanTransfer(caller.Address(), value) {
|
||||||
|
caller.ReturnGas(gas, gasPrice)
|
||||||
|
|
||||||
|
return nil, common.Address{}, ValueTransferErr("insufficient funds to transfer value. Req %v, has %v", value, env.Db().GetBalance(caller.Address()))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new account on the state
|
||||||
|
nonce := env.Db().GetNonce(caller.Address())
|
||||||
|
env.Db().SetNonce(caller.Address(), nonce+1)
|
||||||
|
|
||||||
|
snapshotPreTransfer := env.SnapshotDatabase()
|
||||||
|
var (
|
||||||
|
addr = crypto.CreateAddress(caller.Address(), nonce)
|
||||||
|
from = env.Db().GetAccount(caller.Address())
|
||||||
|
to = env.Db().CreateAccount(addr)
|
||||||
|
)
|
||||||
|
if env.ChainConfig().IsEIP158(env.BlockNumber()) {
|
||||||
|
env.Db().SetNonce(addr, 1)
|
||||||
|
}
|
||||||
|
env.Transfer(from, to, value)
|
||||||
|
|
||||||
|
// initialise a new contract and set the code that is to be used by the
|
||||||
|
// EVM. The contract is a scoped environment for this execution context
|
||||||
|
// only.
|
||||||
|
contract := vm.NewContract(caller, to, value, gas, gasPrice)
|
||||||
|
contract.SetCallCode(&addr, crypto.Keccak256Hash(code), code)
|
||||||
|
defer contract.Finalise()
|
||||||
|
|
||||||
|
ret, err = env.Vm().Run(contract, nil)
|
||||||
// if the contract creation ran successfully and no errors were returned
|
// if the contract creation ran successfully and no errors were returned
|
||||||
// calculate the gas required to store the code. If the code could not
|
// calculate the gas required to store the code. If the code could not
|
||||||
// be stored due to not enough gas set an error and let it be handled
|
// be stored due to not enough gas set an error and let it be handled
|
||||||
// by the error checking condition below.
|
// by the error checking condition below.
|
||||||
if err == nil && createAccount {
|
if err == nil {
|
||||||
dataGas := big.NewInt(int64(len(ret)))
|
dataGas := big.NewInt(int64(len(ret)))
|
||||||
dataGas.Mul(dataGas, params.CreateDataGas)
|
dataGas.Mul(dataGas, params.CreateDataGas)
|
||||||
if contract.UseGas(dataGas) {
|
if contract.UseGas(dataGas) {
|
||||||
env.Db().SetCode(*address, ret)
|
env.Db().SetCode(addr, ret)
|
||||||
} else {
|
} else {
|
||||||
err = vm.CodeStoreOutOfGasError
|
err = vm.CodeStoreOutOfGasError
|
||||||
}
|
}
|
||||||
@ -126,46 +167,45 @@ func exec(env vm.Environment, caller vm.ContractRef, address, codeAddr *common.A
|
|||||||
// When an error was returned by the EVM or when setting the creation code
|
// When an error was returned by the EVM or when setting the creation code
|
||||||
// above we revert to the snapshot and consume any gas remaining. Additionally
|
// above we revert to the snapshot and consume any gas remaining. Additionally
|
||||||
// when we're in homestead this also counts for code storage gas errors.
|
// when we're in homestead this also counts for code storage gas errors.
|
||||||
if err != nil && (env.RuleSet().IsHomestead(env.BlockNumber()) || err != vm.CodeStoreOutOfGasError) {
|
if err != nil && (env.ChainConfig().IsHomestead(env.BlockNumber()) || err != vm.CodeStoreOutOfGasError) {
|
||||||
contract.UseGas(contract.Gas)
|
contract.UseGas(contract.Gas)
|
||||||
|
|
||||||
env.RevertToSnapshot(snapshotPreTransfer)
|
env.RevertToSnapshot(snapshotPreTransfer)
|
||||||
|
|
||||||
|
// Nothing should be returned when an error is thrown.
|
||||||
|
return nil, addr, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret, addr, err
|
return ret, addr, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func execDelegateCall(env vm.Environment, caller vm.ContractRef, originAddr, toAddr, codeAddr *common.Address, codeHash common.Hash, input, code []byte, gas, gasPrice, value *big.Int) (ret []byte, addr common.Address, err error) {
|
// DelegateCall is equivalent to CallCode except that sender and value propagates from parent scope to child scope
|
||||||
evm := env.Vm()
|
func DelegateCall(env vm.Environment, caller vm.ContractRef, addr common.Address, input []byte, gas, gasPrice *big.Int) (ret []byte, err error) {
|
||||||
// Depth check execution. Fail if we're trying to execute above the
|
// Depth check execution. Fail if we're trying to execute above the
|
||||||
// limit.
|
// limit.
|
||||||
if env.Depth() > int(params.CallCreateDepth.Int64()) {
|
if env.Depth() > int(params.CallCreateDepth.Int64()) {
|
||||||
caller.ReturnGas(gas, gasPrice)
|
caller.ReturnGas(gas, gasPrice)
|
||||||
return nil, common.Address{}, vm.DepthError
|
return nil, vm.DepthError
|
||||||
}
|
}
|
||||||
|
|
||||||
snapshot := env.SnapshotDatabase()
|
var (
|
||||||
|
snapshot = env.SnapshotDatabase()
|
||||||
var to vm.Account
|
to = env.Db().GetAccount(caller.Address())
|
||||||
if !env.Db().Exist(*toAddr) {
|
)
|
||||||
to = env.Db().CreateAccount(*toAddr)
|
|
||||||
} else {
|
|
||||||
to = env.Db().GetAccount(*toAddr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Iinitialise a new contract and make initialise the delegate values
|
// Iinitialise a new contract and make initialise the delegate values
|
||||||
contract := vm.NewContract(caller, to, value, gas, gasPrice).AsDelegate()
|
contract := vm.NewContract(caller, to, caller.Value(), gas, gasPrice).AsDelegate()
|
||||||
contract.SetCallCode(codeAddr, codeHash, code)
|
contract.SetCallCode(&addr, env.Db().GetCodeHash(addr), env.Db().GetCode(addr))
|
||||||
defer contract.Finalise()
|
defer contract.Finalise()
|
||||||
|
|
||||||
ret, err = evm.Run(contract, input)
|
ret, err = env.Vm().Run(contract, input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
contract.UseGas(contract.Gas)
|
contract.UseGas(contract.Gas)
|
||||||
|
|
||||||
env.RevertToSnapshot(snapshot)
|
env.RevertToSnapshot(snapshot)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret, addr, err
|
return ret, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// generic transfer method
|
// generic transfer method
|
||||||
|
@ -43,7 +43,7 @@ func WriteGenesisBlock(chainDb ethdb.Database, reader io.Reader) (*types.Block,
|
|||||||
}
|
}
|
||||||
|
|
||||||
var genesis struct {
|
var genesis struct {
|
||||||
ChainConfig *ChainConfig `json:"config"`
|
ChainConfig *params.ChainConfig `json:"config"`
|
||||||
Nonce string
|
Nonce string
|
||||||
Timestamp string
|
Timestamp string
|
||||||
ParentHash string
|
ParentHash string
|
||||||
@ -73,7 +73,7 @@ func WriteGenesisBlock(chainDb ethdb.Database, reader io.Reader) (*types.Block,
|
|||||||
statedb.SetState(address, common.HexToHash(key), common.HexToHash(value))
|
statedb.SetState(address, common.HexToHash(key), common.HexToHash(value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
root, stateBatch := statedb.CommitBatch()
|
root, stateBatch := statedb.CommitBatch(false)
|
||||||
|
|
||||||
difficulty := common.String2Big(genesis.Difficulty)
|
difficulty := common.String2Big(genesis.Difficulty)
|
||||||
block := types.NewBlock(&types.Header{
|
block := types.NewBlock(&types.Header{
|
||||||
@ -128,7 +128,7 @@ func GenesisBlockForTesting(db ethdb.Database, addr common.Address, balance *big
|
|||||||
statedb, _ := state.New(common.Hash{}, db)
|
statedb, _ := state.New(common.Hash{}, db)
|
||||||
obj := statedb.GetOrNewStateObject(addr)
|
obj := statedb.GetOrNewStateObject(addr)
|
||||||
obj.SetBalance(balance)
|
obj.SetBalance(balance)
|
||||||
root, err := statedb.Commit()
|
root, err := statedb.Commit(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Sprintf("cannot write state: %v", err))
|
panic(fmt.Sprintf("cannot write state: %v", err))
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/pow"
|
"github.com/ethereum/go-ethereum/pow"
|
||||||
"github.com/hashicorp/golang-lru"
|
"github.com/hashicorp/golang-lru"
|
||||||
)
|
)
|
||||||
@ -48,7 +49,7 @@ const (
|
|||||||
// It is not thread safe either, the encapsulating chain structures should do
|
// It is not thread safe either, the encapsulating chain structures should do
|
||||||
// the necessary mutex locking/unlocking.
|
// the necessary mutex locking/unlocking.
|
||||||
type HeaderChain struct {
|
type HeaderChain struct {
|
||||||
config *ChainConfig
|
config *params.ChainConfig
|
||||||
|
|
||||||
chainDb ethdb.Database
|
chainDb ethdb.Database
|
||||||
genesisHeader *types.Header
|
genesisHeader *types.Header
|
||||||
@ -73,7 +74,7 @@ type getHeaderValidatorFn func() HeaderValidator
|
|||||||
// getValidator should return the parent's validator
|
// getValidator should return the parent's validator
|
||||||
// procInterrupt points to the parent's interrupt semaphore
|
// procInterrupt points to the parent's interrupt semaphore
|
||||||
// wg points to the parent's shutdown wait group
|
// wg points to the parent's shutdown wait group
|
||||||
func NewHeaderChain(chainDb ethdb.Database, config *ChainConfig, getValidator getHeaderValidatorFn, procInterrupt func() bool) (*HeaderChain, error) {
|
func NewHeaderChain(chainDb ethdb.Database, config *params.ChainConfig, getValidator getHeaderValidatorFn, procInterrupt func() bool) (*HeaderChain, error) {
|
||||||
headerCache, _ := lru.New(headerCacheLimit)
|
headerCache, _ := lru.New(headerCacheLimit)
|
||||||
tdCache, _ := lru.New(tdCacheLimit)
|
tdCache, _ := lru.New(tdCacheLimit)
|
||||||
numberCache, _ := lru.New(numberCacheLimit)
|
numberCache, _ := lru.New(numberCacheLimit)
|
||||||
@ -490,13 +491,13 @@ func (hc *HeaderChain) SetGenesis(head *types.Header) {
|
|||||||
//
|
//
|
||||||
// headerValidator implements HeaderValidator.
|
// headerValidator implements HeaderValidator.
|
||||||
type headerValidator struct {
|
type headerValidator struct {
|
||||||
config *ChainConfig
|
config *params.ChainConfig
|
||||||
hc *HeaderChain // Canonical header chain
|
hc *HeaderChain // Canonical header chain
|
||||||
Pow pow.PoW // Proof of work used for validating
|
Pow pow.PoW // Proof of work used for validating
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBlockValidator returns a new block validator which is safe for re-use
|
// NewBlockValidator returns a new block validator which is safe for re-use
|
||||||
func NewHeaderValidator(config *ChainConfig, chain *HeaderChain, pow pow.PoW) HeaderValidator {
|
func NewHeaderValidator(config *params.ChainConfig, chain *HeaderChain, pow pow.PoW) HeaderValidator {
|
||||||
return &headerValidator{
|
return &headerValidator{
|
||||||
config: config,
|
config: config,
|
||||||
Pow: pow,
|
Pow: pow,
|
||||||
|
@ -91,6 +91,11 @@ type StateObject struct {
|
|||||||
onDirty func(addr common.Address) // Callback method to mark a state object newly dirty
|
onDirty func(addr common.Address) // Callback method to mark a state object newly dirty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// empty returns whether the account is considered empty.
|
||||||
|
func (s *StateObject) empty() bool {
|
||||||
|
return s.data.Nonce == 0 && s.data.Balance.BitLen() == 0 && bytes.Equal(s.data.CodeHash, emptyCodeHash)
|
||||||
|
}
|
||||||
|
|
||||||
// Account is the Ethereum consensus representation of accounts.
|
// Account is the Ethereum consensus representation of accounts.
|
||||||
// These objects are stored in the main account trie.
|
// These objects are stored in the main account trie.
|
||||||
type Account struct {
|
type Account struct {
|
||||||
@ -221,8 +226,12 @@ func (self *StateObject) CommitTrie(db trie.Database, dbw trie.DatabaseWriter) e
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddBalance removes amount from c's balance.
|
||||||
|
// It is used to add funds to the destination account of a transfer.
|
||||||
func (c *StateObject) AddBalance(amount *big.Int) {
|
func (c *StateObject) AddBalance(amount *big.Int) {
|
||||||
if amount.Cmp(common.Big0) == 0 {
|
// EIP158: We must check emptiness for the objects such that the account
|
||||||
|
// clearing (0,0,0 objects) can take effect.
|
||||||
|
if amount.Cmp(common.Big0) == 0 && !c.empty() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.SetBalance(new(big.Int).Add(c.Balance(), amount))
|
c.SetBalance(new(big.Int).Add(c.Balance(), amount))
|
||||||
@ -232,6 +241,8 @@ func (c *StateObject) AddBalance(amount *big.Int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SubBalance removes amount from c's balance.
|
||||||
|
// It is used to remove funds from the origin account of a transfer.
|
||||||
func (c *StateObject) SubBalance(amount *big.Int) {
|
func (c *StateObject) SubBalance(amount *big.Int) {
|
||||||
if amount.Cmp(common.Big0) == 0 {
|
if amount.Cmp(common.Big0) == 0 {
|
||||||
return
|
return
|
||||||
|
@ -48,7 +48,7 @@ func (s *StateSuite) TestDump(c *checker.C) {
|
|||||||
// write some of them to the trie
|
// write some of them to the trie
|
||||||
s.state.updateStateObject(obj1)
|
s.state.updateStateObject(obj1)
|
||||||
s.state.updateStateObject(obj2)
|
s.state.updateStateObject(obj2)
|
||||||
s.state.Commit()
|
s.state.Commit(false)
|
||||||
|
|
||||||
// check that dump contains the state objects that are in trie
|
// check that dump contains the state objects that are in trie
|
||||||
got := string(s.state.Dump())
|
got := string(s.state.Dump())
|
||||||
@ -100,7 +100,7 @@ func TestNull(t *testing.T) {
|
|||||||
//value := common.FromHex("0x823140710bf13990e4500136726d8b55")
|
//value := common.FromHex("0x823140710bf13990e4500136726d8b55")
|
||||||
var value common.Hash
|
var value common.Hash
|
||||||
state.SetState(address, common.Hash{}, value)
|
state.SetState(address, common.Hash{}, value)
|
||||||
state.Commit()
|
state.Commit(false)
|
||||||
value = state.GetState(address, common.Hash{})
|
value = state.GetState(address, common.Hash{})
|
||||||
if !common.EmptyHash(value) {
|
if !common.EmptyHash(value) {
|
||||||
t.Errorf("expected empty hash. got %x", value)
|
t.Errorf("expected empty hash. got %x", value)
|
||||||
@ -160,7 +160,7 @@ func TestSnapshot2(t *testing.T) {
|
|||||||
so0.deleted = false
|
so0.deleted = false
|
||||||
state.setStateObject(so0)
|
state.setStateObject(so0)
|
||||||
|
|
||||||
root, _ := state.Commit()
|
root, _ := state.Commit(false)
|
||||||
state.Reset(root)
|
state.Reset(root)
|
||||||
|
|
||||||
// and one with deleted == true
|
// and one with deleted == true
|
||||||
|
@ -213,6 +213,13 @@ func (self *StateDB) Exist(addr common.Address) bool {
|
|||||||
return self.GetStateObject(addr) != nil
|
return self.GetStateObject(addr) != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Empty returns whether the state object is either non-existant
|
||||||
|
// or empty according to the EIP161 specification (balance = nonce = code = 0)
|
||||||
|
func (self *StateDB) Empty(addr common.Address) bool {
|
||||||
|
so := self.GetStateObject(addr)
|
||||||
|
return so == nil || so.empty()
|
||||||
|
}
|
||||||
|
|
||||||
func (self *StateDB) GetAccount(addr common.Address) vm.Account {
|
func (self *StateDB) GetAccount(addr common.Address) vm.Account {
|
||||||
return self.GetStateObject(addr)
|
return self.GetStateObject(addr)
|
||||||
}
|
}
|
||||||
@ -516,10 +523,10 @@ func (self *StateDB) GetRefund() *big.Int {
|
|||||||
// IntermediateRoot computes the current root hash of the state trie.
|
// IntermediateRoot computes the current root hash of the state trie.
|
||||||
// It is called in between transactions to get the root hash that
|
// It is called in between transactions to get the root hash that
|
||||||
// goes into transaction receipts.
|
// goes into transaction receipts.
|
||||||
func (s *StateDB) IntermediateRoot() common.Hash {
|
func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
|
||||||
for addr, _ := range s.stateObjectsDirty {
|
for addr, _ := range s.stateObjectsDirty {
|
||||||
stateObject := s.stateObjects[addr]
|
stateObject := s.stateObjects[addr]
|
||||||
if stateObject.suicided {
|
if stateObject.suicided || (deleteEmptyObjects && stateObject.empty()) {
|
||||||
s.deleteStateObject(stateObject)
|
s.deleteStateObject(stateObject)
|
||||||
} else {
|
} else {
|
||||||
stateObject.updateRoot(s.db)
|
stateObject.updateRoot(s.db)
|
||||||
@ -553,17 +560,17 @@ func (s *StateDB) DeleteSuicides() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Commit commits all state changes to the database.
|
// Commit commits all state changes to the database.
|
||||||
func (s *StateDB) Commit() (root common.Hash, err error) {
|
func (s *StateDB) Commit(deleteEmptyObjects bool) (root common.Hash, err error) {
|
||||||
root, batch := s.CommitBatch()
|
root, batch := s.CommitBatch(deleteEmptyObjects)
|
||||||
return root, batch.Write()
|
return root, batch.Write()
|
||||||
}
|
}
|
||||||
|
|
||||||
// CommitBatch commits all state changes to a write batch but does not
|
// CommitBatch commits all state changes to a write batch but does not
|
||||||
// execute the batch. It is used to validate state changes against
|
// execute the batch. It is used to validate state changes against
|
||||||
// the root hash stored in a block.
|
// the root hash stored in a block.
|
||||||
func (s *StateDB) CommitBatch() (root common.Hash, batch ethdb.Batch) {
|
func (s *StateDB) CommitBatch(deleteEmptyObjects bool) (root common.Hash, batch ethdb.Batch) {
|
||||||
batch = s.db.NewBatch()
|
batch = s.db.NewBatch()
|
||||||
root, _ = s.commit(batch)
|
root, _ = s.commit(batch, deleteEmptyObjects)
|
||||||
|
|
||||||
glog.V(logger.Debug).Infof("Trie cache stats: %d misses, %d unloads", trie.CacheMisses(), trie.CacheUnloads())
|
glog.V(logger.Debug).Infof("Trie cache stats: %d misses, %d unloads", trie.CacheMisses(), trie.CacheUnloads())
|
||||||
return root, batch
|
return root, batch
|
||||||
@ -575,16 +582,18 @@ func (s *StateDB) clearJournalAndRefund() {
|
|||||||
s.refund = new(big.Int)
|
s.refund = new(big.Int)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StateDB) commit(dbw trie.DatabaseWriter) (root common.Hash, err error) {
|
func (s *StateDB) commit(dbw trie.DatabaseWriter, deleteEmptyObjects bool) (root common.Hash, err error) {
|
||||||
defer s.clearJournalAndRefund()
|
defer s.clearJournalAndRefund()
|
||||||
|
|
||||||
// Commit objects to the trie.
|
// Commit objects to the trie.
|
||||||
for addr, stateObject := range s.stateObjects {
|
for addr, stateObject := range s.stateObjects {
|
||||||
if stateObject.suicided {
|
_, isDirty := s.stateObjectsDirty[addr]
|
||||||
|
switch {
|
||||||
|
case stateObject.suicided || (isDirty && deleteEmptyObjects && stateObject.empty()):
|
||||||
// If the object has been removed, don't bother syncing it
|
// If the object has been removed, don't bother syncing it
|
||||||
// and just mark it for deletion in the trie.
|
// and just mark it for deletion in the trie.
|
||||||
s.deleteStateObject(stateObject)
|
s.deleteStateObject(stateObject)
|
||||||
} else if _, ok := s.stateObjectsDirty[addr]; ok {
|
case isDirty:
|
||||||
// Write any contract code associated with the state object
|
// Write any contract code associated with the state object
|
||||||
if stateObject.code != nil && stateObject.dirtyCode {
|
if stateObject.code != nil && stateObject.dirtyCode {
|
||||||
if err := dbw.Put(stateObject.CodeHash(), stateObject.code); err != nil {
|
if err := dbw.Put(stateObject.CodeHash(), stateObject.code); err != nil {
|
||||||
|
@ -51,7 +51,7 @@ func TestUpdateLeaks(t *testing.T) {
|
|||||||
if i%3 == 0 {
|
if i%3 == 0 {
|
||||||
state.SetCode(addr, []byte{i, i, i, i, i})
|
state.SetCode(addr, []byte{i, i, i, i, i})
|
||||||
}
|
}
|
||||||
state.IntermediateRoot()
|
state.IntermediateRoot(false)
|
||||||
}
|
}
|
||||||
// Ensure that no data was leaked into the database
|
// Ensure that no data was leaked into the database
|
||||||
for _, key := range db.Keys() {
|
for _, key := range db.Keys() {
|
||||||
@ -86,7 +86,7 @@ func TestIntermediateLeaks(t *testing.T) {
|
|||||||
modify(transState, common.Address{byte(i)}, i, 0)
|
modify(transState, common.Address{byte(i)}, i, 0)
|
||||||
}
|
}
|
||||||
// Write modifications to trie.
|
// Write modifications to trie.
|
||||||
transState.IntermediateRoot()
|
transState.IntermediateRoot(false)
|
||||||
|
|
||||||
// Overwrite all the data with new values in the transient database.
|
// Overwrite all the data with new values in the transient database.
|
||||||
for i := byte(0); i < 255; i++ {
|
for i := byte(0); i < 255; i++ {
|
||||||
@ -95,10 +95,10 @@ func TestIntermediateLeaks(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Commit and cross check the databases.
|
// Commit and cross check the databases.
|
||||||
if _, err := transState.Commit(); err != nil {
|
if _, err := transState.Commit(false); err != nil {
|
||||||
t.Fatalf("failed to commit transition state: %v", err)
|
t.Fatalf("failed to commit transition state: %v", err)
|
||||||
}
|
}
|
||||||
if _, err := finalState.Commit(); err != nil {
|
if _, err := finalState.Commit(false); err != nil {
|
||||||
t.Fatalf("failed to commit final state: %v", err)
|
t.Fatalf("failed to commit final state: %v", err)
|
||||||
}
|
}
|
||||||
for _, key := range finalDb.Keys() {
|
for _, key := range finalDb.Keys() {
|
||||||
|
@ -60,7 +60,7 @@ func makeTestState() (ethdb.Database, common.Hash, []*testAccount) {
|
|||||||
state.updateStateObject(obj)
|
state.updateStateObject(obj)
|
||||||
accounts = append(accounts, acc)
|
accounts = append(accounts, acc)
|
||||||
}
|
}
|
||||||
root, _ := state.Commit()
|
root, _ := state.Commit(false)
|
||||||
|
|
||||||
// Return the generated state
|
// Return the generated state
|
||||||
return db, root, accounts
|
return db, root, accounts
|
||||||
|
@ -25,6 +25,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -37,12 +38,12 @@ var (
|
|||||||
//
|
//
|
||||||
// StateProcessor implements Processor.
|
// StateProcessor implements Processor.
|
||||||
type StateProcessor struct {
|
type StateProcessor struct {
|
||||||
config *ChainConfig
|
config *params.ChainConfig
|
||||||
bc *BlockChain
|
bc *BlockChain
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewStateProcessor initialises a new StateProcessor.
|
// NewStateProcessor initialises a new StateProcessor.
|
||||||
func NewStateProcessor(config *ChainConfig, bc *BlockChain) *StateProcessor {
|
func NewStateProcessor(config *params.ChainConfig, bc *BlockChain) *StateProcessor {
|
||||||
return &StateProcessor{
|
return &StateProcessor{
|
||||||
config: config,
|
config: config,
|
||||||
bc: bc,
|
bc: bc,
|
||||||
@ -89,7 +90,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
|
|||||||
//
|
//
|
||||||
// ApplyTransactions returns the generated receipts and vm logs during the
|
// ApplyTransactions returns the generated receipts and vm logs during the
|
||||||
// execution of the state transition phase.
|
// execution of the state transition phase.
|
||||||
func ApplyTransaction(config *ChainConfig, bc *BlockChain, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *big.Int, cfg vm.Config) (*types.Receipt, vm.Logs, *big.Int, error) {
|
func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *big.Int, cfg vm.Config) (*types.Receipt, vm.Logs, *big.Int, error) {
|
||||||
_, gas, err := ApplyMessage(NewEnv(statedb, config, bc, tx, header, cfg), tx, gp)
|
_, gas, err := ApplyMessage(NewEnv(statedb, config, bc, tx, header, cfg), tx, gp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
@ -97,7 +98,7 @@ func ApplyTransaction(config *ChainConfig, bc *BlockChain, gp *GasPool, statedb
|
|||||||
|
|
||||||
// Update the state with pending changes
|
// Update the state with pending changes
|
||||||
usedGas.Add(usedGas, gas)
|
usedGas.Add(usedGas, gas)
|
||||||
receipt := types.NewReceipt(statedb.IntermediateRoot().Bytes(), usedGas)
|
receipt := types.NewReceipt(statedb.IntermediateRoot(config.IsEIP158(header.Number)).Bytes(), usedGas)
|
||||||
receipt.TxHash = tx.Hash()
|
receipt.TxHash = tx.Hash()
|
||||||
receipt.GasUsed = new(big.Int).Set(gas)
|
receipt.GasUsed = new(big.Int).Set(gas)
|
||||||
if MessageCreatesContract(tx) {
|
if MessageCreatesContract(tx) {
|
||||||
|
@ -139,7 +139,7 @@ func (self *StateTransition) from() (vm.Account, error) {
|
|||||||
f common.Address
|
f common.Address
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
if self.env.RuleSet().IsHomestead(self.env.BlockNumber()) {
|
if self.env.ChainConfig().IsHomestead(self.env.BlockNumber()) {
|
||||||
f, err = self.msg.From()
|
f, err = self.msg.From()
|
||||||
} else {
|
} else {
|
||||||
f, err = self.msg.FromFrontier()
|
f, err = self.msg.FromFrontier()
|
||||||
@ -234,7 +234,7 @@ func (self *StateTransition) TransitionDb() (ret []byte, requiredGas, usedGas *b
|
|||||||
msg := self.msg
|
msg := self.msg
|
||||||
sender, _ := self.from() // err checked in preCheck
|
sender, _ := self.from() // err checked in preCheck
|
||||||
|
|
||||||
homestead := self.env.RuleSet().IsHomestead(self.env.BlockNumber())
|
homestead := self.env.ChainConfig().IsHomestead(self.env.BlockNumber())
|
||||||
contractCreation := MessageCreatesContract(msg)
|
contractCreation := MessageCreatesContract(msg)
|
||||||
// Pay intrinsic gas
|
// Pay intrinsic gas
|
||||||
if err = self.useGas(IntrinsicGas(self.data, contractCreation, homestead)); err != nil {
|
if err = self.useGas(IntrinsicGas(self.data, contractCreation, homestead)); err != nil {
|
||||||
|
@ -31,6 +31,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
"github.com/ethereum/go-ethereum/metrics"
|
"github.com/ethereum/go-ethereum/metrics"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"gopkg.in/karalabe/cookiejar.v2/collections/prque"
|
"gopkg.in/karalabe/cookiejar.v2/collections/prque"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -83,7 +84,7 @@ type stateFn func() (*state.StateDB, error)
|
|||||||
// current state) and future transactions. Transactions move between those
|
// current state) and future transactions. Transactions move between those
|
||||||
// two states over time as they are received and processed.
|
// two states over time as they are received and processed.
|
||||||
type TxPool struct {
|
type TxPool struct {
|
||||||
config *ChainConfig
|
config *params.ChainConfig
|
||||||
currentState stateFn // The state function which will allow us to do some pre checks
|
currentState stateFn // The state function which will allow us to do some pre checks
|
||||||
pendingState *state.ManagedState
|
pendingState *state.ManagedState
|
||||||
gasLimit func() *big.Int // The current gas limit function callback
|
gasLimit func() *big.Int // The current gas limit function callback
|
||||||
@ -104,7 +105,7 @@ type TxPool struct {
|
|||||||
homestead bool
|
homestead bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTxPool(config *ChainConfig, eventMux *event.TypeMux, currentStateFn stateFn, gasLimitFn func() *big.Int) *TxPool {
|
func NewTxPool(config *params.ChainConfig, eventMux *event.TypeMux, currentStateFn stateFn, gasLimitFn func() *big.Int) *TxPool {
|
||||||
pool := &TxPool{
|
pool := &TxPool{
|
||||||
config: config,
|
config: config,
|
||||||
pending: make(map[common.Address]*txList),
|
pending: make(map[common.Address]*txList),
|
||||||
|
@ -23,20 +23,11 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RuleSet is an interface that defines the current rule set during the
|
|
||||||
// execution of the EVM instructions (e.g. whether it's homestead)
|
|
||||||
type RuleSet interface {
|
|
||||||
IsHomestead(*big.Int) bool
|
|
||||||
// GasTable returns the gas prices for this phase, which is based on
|
|
||||||
// block number passed in.
|
|
||||||
GasTable(*big.Int) params.GasTable
|
|
||||||
}
|
|
||||||
|
|
||||||
// Environment is an EVM requirement and helper which allows access to outside
|
// Environment is an EVM requirement and helper which allows access to outside
|
||||||
// information such as states.
|
// information such as states.
|
||||||
type Environment interface {
|
type Environment interface {
|
||||||
// The current ruleset
|
// The current ruleset
|
||||||
RuleSet() RuleSet
|
ChainConfig() *params.ChainConfig
|
||||||
// The state database
|
// The state database
|
||||||
Db() Database
|
Db() Database
|
||||||
// Creates a restorable snapshot
|
// Creates a restorable snapshot
|
||||||
@ -115,6 +106,9 @@ type Database interface {
|
|||||||
// Exist reports whether the given account exists in state.
|
// Exist reports whether the given account exists in state.
|
||||||
// Notably this should also return true for suicided accounts.
|
// Notably this should also return true for suicided accounts.
|
||||||
Exist(common.Address) bool
|
Exist(common.Address) bool
|
||||||
|
// Empty returns whether the given account is empty. Empty
|
||||||
|
// is defined according to EIP161 (balance = nonce = code = 0).
|
||||||
|
Empty(common.Address) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Account represents a contract or basic ethereum account.
|
// Account represents a contract or basic ethereum account.
|
||||||
|
@ -515,7 +515,7 @@ func opCreate(instr instruction, pc *uint64, env Environment, contract *Contract
|
|||||||
input = memory.Get(offset.Int64(), size.Int64())
|
input = memory.Get(offset.Int64(), size.Int64())
|
||||||
gas = new(big.Int).Set(contract.Gas)
|
gas = new(big.Int).Set(contract.Gas)
|
||||||
)
|
)
|
||||||
if env.RuleSet().GasTable(env.BlockNumber()).CreateBySuicide != nil {
|
if env.ChainConfig().IsEIP150(env.BlockNumber()) {
|
||||||
gas.Div(gas, n64)
|
gas.Div(gas, n64)
|
||||||
gas = gas.Sub(contract.Gas, gas)
|
gas = gas.Sub(contract.Gas, gas)
|
||||||
}
|
}
|
||||||
@ -526,7 +526,7 @@ func opCreate(instr instruction, pc *uint64, env Environment, contract *Contract
|
|||||||
// homestead we must check for CodeStoreOutOfGasError (homestead only
|
// homestead we must check for CodeStoreOutOfGasError (homestead only
|
||||||
// rule) and treat as an error, if the ruleset is frontier we must
|
// rule) and treat as an error, if the ruleset is frontier we must
|
||||||
// ignore this error and pretend the operation was successful.
|
// ignore this error and pretend the operation was successful.
|
||||||
if env.RuleSet().IsHomestead(env.BlockNumber()) && suberr == CodeStoreOutOfGasError {
|
if env.ChainConfig().IsHomestead(env.BlockNumber()) && suberr == CodeStoreOutOfGasError {
|
||||||
stack.push(new(big.Int))
|
stack.push(new(big.Int))
|
||||||
} else if suberr != nil && suberr != CodeStoreOutOfGasError {
|
} else if suberr != nil && suberr != CodeStoreOutOfGasError {
|
||||||
stack.push(new(big.Int))
|
stack.push(new(big.Int))
|
||||||
|
@ -319,7 +319,7 @@ func runProgram(program *Program, pcstart uint64, mem *Memory, stack *Stack, env
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
homestead := env.RuleSet().IsHomestead(env.BlockNumber())
|
homestead := env.ChainConfig().IsHomestead(env.BlockNumber())
|
||||||
for pc < uint64(len(program.instructions)) {
|
for pc < uint64(len(program.instructions)) {
|
||||||
instrCount++
|
instrCount++
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ import (
|
|||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
const maxRun = 1000
|
const maxRun = 1000
|
||||||
@ -172,7 +173,9 @@ func NewEnv(config *Config) *Env {
|
|||||||
return env
|
return env
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Env) RuleSet() RuleSet { return ruleSet{new(big.Int)} }
|
func (self *Env) ChainConfig() *params.ChainConfig {
|
||||||
|
return ¶ms.ChainConfig{new(big.Int), new(big.Int), true, new(big.Int), common.Hash{}, new(big.Int)}
|
||||||
|
}
|
||||||
func (self *Env) Vm() Vm { return self.evm }
|
func (self *Env) Vm() Vm { return self.evm }
|
||||||
func (self *Env) Origin() common.Address { return common.Address{} }
|
func (self *Env) Origin() common.Address { return common.Address{} }
|
||||||
func (self *Env) BlockNumber() *big.Int { return big.NewInt(0) }
|
func (self *Env) BlockNumber() *big.Int { return big.NewInt(0) }
|
||||||
|
@ -16,7 +16,11 @@
|
|||||||
|
|
||||||
package vm
|
package vm
|
||||||
|
|
||||||
import "math/big"
|
import (
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
)
|
||||||
|
|
||||||
type jumpPtr struct {
|
type jumpPtr struct {
|
||||||
fn instrFn
|
fn instrFn
|
||||||
@ -25,7 +29,7 @@ type jumpPtr struct {
|
|||||||
|
|
||||||
type vmJumpTable [256]jumpPtr
|
type vmJumpTable [256]jumpPtr
|
||||||
|
|
||||||
func newJumpTable(ruleset RuleSet, blockNumber *big.Int) vmJumpTable {
|
func newJumpTable(ruleset *params.ChainConfig, blockNumber *big.Int) vmJumpTable {
|
||||||
var jumpTable vmJumpTable
|
var jumpTable vmJumpTable
|
||||||
|
|
||||||
// when initialising a new VM execution we must first check the homestead
|
// when initialising a new VM execution we must first check the homestead
|
||||||
|
@ -19,16 +19,18 @@ package vm
|
|||||||
import (
|
import (
|
||||||
"math/big"
|
"math/big"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestInit(t *testing.T) {
|
func TestInit(t *testing.T) {
|
||||||
jumpTable := newJumpTable(ruleSet{big.NewInt(1)}, big.NewInt(0))
|
jumpTable := newJumpTable(¶ms.ChainConfig{HomesteadBlock: big.NewInt(1)}, big.NewInt(0))
|
||||||
if jumpTable[DELEGATECALL].valid {
|
if jumpTable[DELEGATECALL].valid {
|
||||||
t.Error("Expected DELEGATECALL not to be present")
|
t.Error("Expected DELEGATECALL not to be present")
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, n := range []int64{1, 2, 100} {
|
for _, n := range []int64{1, 2, 100} {
|
||||||
jumpTable := newJumpTable(ruleSet{big.NewInt(1)}, big.NewInt(n))
|
jumpTable := newJumpTable(¶ms.ChainConfig{HomesteadBlock: big.NewInt(1)}, big.NewInt(n))
|
||||||
if !jumpTable[DELEGATECALL].valid {
|
if !jumpTable[DELEGATECALL].valid {
|
||||||
t.Error("Expected DELEGATECALL to be present for block", n)
|
t.Error("Expected DELEGATECALL to be present for block", n)
|
||||||
}
|
}
|
||||||
|
@ -23,11 +23,12 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Env is a basic runtime environment required for running the EVM.
|
// Env is a basic runtime environment required for running the EVM.
|
||||||
type Env struct {
|
type Env struct {
|
||||||
ruleSet vm.RuleSet
|
chainConfig *params.ChainConfig
|
||||||
depth int
|
depth int
|
||||||
state *state.StateDB
|
state *state.StateDB
|
||||||
|
|
||||||
@ -47,7 +48,7 @@ type Env struct {
|
|||||||
// NewEnv returns a new vm.Environment
|
// NewEnv returns a new vm.Environment
|
||||||
func NewEnv(cfg *Config, state *state.StateDB) vm.Environment {
|
func NewEnv(cfg *Config, state *state.StateDB) vm.Environment {
|
||||||
env := &Env{
|
env := &Env{
|
||||||
ruleSet: cfg.RuleSet,
|
chainConfig: cfg.ChainConfig,
|
||||||
state: state,
|
state: state,
|
||||||
origin: cfg.Origin,
|
origin: cfg.Origin,
|
||||||
coinbase: cfg.Coinbase,
|
coinbase: cfg.Coinbase,
|
||||||
@ -65,7 +66,7 @@ func NewEnv(cfg *Config, state *state.StateDB) vm.Environment {
|
|||||||
return env
|
return env
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Env) RuleSet() vm.RuleSet { return self.ruleSet }
|
func (self *Env) ChainConfig() *params.ChainConfig { return self.chainConfig }
|
||||||
func (self *Env) Vm() vm.Vm { return self.evm }
|
func (self *Env) Vm() vm.Vm { return self.evm }
|
||||||
func (self *Env) Origin() common.Address { return self.origin }
|
func (self *Env) Origin() common.Address { return self.origin }
|
||||||
func (self *Env) BlockNumber() *big.Int { return self.number }
|
func (self *Env) BlockNumber() *big.Int { return self.number }
|
||||||
|
@ -22,7 +22,6 @@ import (
|
|||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
@ -39,7 +38,7 @@ func (ruleSet) GasTable(*big.Int) params.GasTable {
|
|||||||
// Config is a basic type specifying certain configuration flags for running
|
// Config is a basic type specifying certain configuration flags for running
|
||||||
// the EVM.
|
// the EVM.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
RuleSet vm.RuleSet
|
ChainConfig *params.ChainConfig
|
||||||
Difficulty *big.Int
|
Difficulty *big.Int
|
||||||
Origin common.Address
|
Origin common.Address
|
||||||
Coinbase common.Address
|
Coinbase common.Address
|
||||||
@ -57,8 +56,8 @@ type Config struct {
|
|||||||
|
|
||||||
// sets defaults on the config
|
// sets defaults on the config
|
||||||
func setDefaults(cfg *Config) {
|
func setDefaults(cfg *Config) {
|
||||||
if cfg.RuleSet == nil {
|
if cfg.ChainConfig == nil {
|
||||||
cfg.RuleSet = ruleSet{}
|
cfg.ChainConfig = ¶ms.ChainConfig{new(big.Int), new(big.Int), false, new(big.Int), common.Hash{}, new(big.Int)}
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg.Difficulty == nil {
|
if cfg.Difficulty == nil {
|
||||||
|
@ -51,9 +51,9 @@ type EVM struct {
|
|||||||
func New(env Environment, cfg Config) *EVM {
|
func New(env Environment, cfg Config) *EVM {
|
||||||
return &EVM{
|
return &EVM{
|
||||||
env: env,
|
env: env,
|
||||||
jumpTable: newJumpTable(env.RuleSet(), env.BlockNumber()),
|
jumpTable: newJumpTable(env.ChainConfig(), env.BlockNumber()),
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
gasTable: env.RuleSet().GasTable(env.BlockNumber()),
|
gasTable: env.ChainConfig().GasTable(env.BlockNumber()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,6 +172,7 @@ func (evm *EVM) Run(contract *Contract, input []byte) (ret []byte, err error) {
|
|||||||
|
|
||||||
// Get the memory location of pc
|
// Get the memory location of pc
|
||||||
op = contract.GetOp(pc)
|
op = contract.GetOp(pc)
|
||||||
|
//fmt.Printf("OP %d %v\n", op, op)
|
||||||
// calculate the new memory size and gas price for the current executing opcode
|
// calculate the new memory size and gas price for the current executing opcode
|
||||||
newMemSize, cost, err = calculateGasAndSize(evm.gasTable, evm.env, contract, caller, op, statedb, mem, stack)
|
newMemSize, cost, err = calculateGasAndSize(evm.gasTable, evm.env, contract, caller, op, statedb, mem, stack)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -254,10 +255,20 @@ func calculateGasAndSize(gasTable params.GasTable, env Environment, contract *Co
|
|||||||
// stack Check, memory resize & gas phase
|
// stack Check, memory resize & gas phase
|
||||||
switch op {
|
switch op {
|
||||||
case SUICIDE:
|
case SUICIDE:
|
||||||
// if suicide is not nil: homestead gas fork
|
// EIP150 homestead gas reprice fork:
|
||||||
if gasTable.CreateBySuicide != nil {
|
if gasTable.CreateBySuicide != nil {
|
||||||
gas.Set(gasTable.Suicide)
|
gas.Set(gasTable.Suicide)
|
||||||
if !env.Db().Exist(common.BigToAddress(stack.data[len(stack.data)-1])) {
|
var (
|
||||||
|
address = common.BigToAddress(stack.data[len(stack.data)-1])
|
||||||
|
eip158 = env.ChainConfig().IsEIP158(env.BlockNumber())
|
||||||
|
)
|
||||||
|
|
||||||
|
if eip158 {
|
||||||
|
// if empty and transfers value
|
||||||
|
if env.Db().Empty(address) && statedb.GetBalance(contract.Address()).BitLen() > 0 {
|
||||||
|
gas.Add(gas, gasTable.CreateBySuicide)
|
||||||
|
}
|
||||||
|
} else if !env.Db().Exist(address) {
|
||||||
gas.Add(gas, gasTable.CreateBySuicide)
|
gas.Add(gas, gasTable.CreateBySuicide)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -378,12 +389,21 @@ func calculateGasAndSize(gasTable params.GasTable, env Environment, contract *Co
|
|||||||
case CALL, CALLCODE:
|
case CALL, CALLCODE:
|
||||||
gas.Set(gasTable.Calls)
|
gas.Set(gasTable.Calls)
|
||||||
|
|
||||||
|
transfersValue := stack.data[len(stack.data)-3].BitLen() > 0
|
||||||
if op == CALL {
|
if op == CALL {
|
||||||
if !env.Db().Exist(common.BigToAddress(stack.data[stack.len()-2])) {
|
var (
|
||||||
|
address = common.BigToAddress(stack.data[len(stack.data)-2])
|
||||||
|
eip158 = env.ChainConfig().IsEIP158(env.BlockNumber())
|
||||||
|
)
|
||||||
|
if eip158 {
|
||||||
|
if env.Db().Empty(address) && transfersValue {
|
||||||
|
gas.Add(gas, params.CallNewAccountGas)
|
||||||
|
}
|
||||||
|
} else if !env.Db().Exist(address) {
|
||||||
gas.Add(gas, params.CallNewAccountGas)
|
gas.Add(gas, params.CallNewAccountGas)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(stack.data[stack.len()-3].Bytes()) > 0 {
|
if transfersValue {
|
||||||
gas.Add(gas, params.CallValueTransferGas)
|
gas.Add(gas, params.CallValueTransferGas)
|
||||||
}
|
}
|
||||||
x := calcMemSize(stack.data[stack.len()-6], stack.data[stack.len()-7])
|
x := calcMemSize(stack.data[stack.len()-6], stack.data[stack.len()-7])
|
||||||
|
@ -23,6 +23,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetHashFn returns a function for which the VM env can query block hashes through
|
// GetHashFn returns a function for which the VM env can query block hashes through
|
||||||
@ -41,7 +42,7 @@ func GetHashFn(ref common.Hash, chain *BlockChain) func(n uint64) common.Hash {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type VMEnv struct {
|
type VMEnv struct {
|
||||||
chainConfig *ChainConfig // Chain configuration
|
chainConfig *params.ChainConfig // Chain configuration
|
||||||
state *state.StateDB // State to use for executing
|
state *state.StateDB // State to use for executing
|
||||||
evm *vm.EVM // The Ethereum Virtual Machine
|
evm *vm.EVM // The Ethereum Virtual Machine
|
||||||
depth int // Current execution depth
|
depth int // Current execution depth
|
||||||
@ -52,7 +53,7 @@ type VMEnv struct {
|
|||||||
getHashFn func(uint64) common.Hash // getHashFn callback is used to retrieve block hashes
|
getHashFn func(uint64) common.Hash // getHashFn callback is used to retrieve block hashes
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEnv(state *state.StateDB, chainConfig *ChainConfig, chain *BlockChain, msg Message, header *types.Header, cfg vm.Config) *VMEnv {
|
func NewEnv(state *state.StateDB, chainConfig *params.ChainConfig, chain *BlockChain, msg Message, header *types.Header, cfg vm.Config) *VMEnv {
|
||||||
env := &VMEnv{
|
env := &VMEnv{
|
||||||
chainConfig: chainConfig,
|
chainConfig: chainConfig,
|
||||||
chain: chain,
|
chain: chain,
|
||||||
@ -66,7 +67,7 @@ func NewEnv(state *state.StateDB, chainConfig *ChainConfig, chain *BlockChain, m
|
|||||||
return env
|
return env
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *VMEnv) RuleSet() vm.RuleSet { return self.chainConfig }
|
func (self *VMEnv) ChainConfig() *params.ChainConfig { return self.chainConfig }
|
||||||
func (self *VMEnv) Vm() vm.Vm { return self.evm }
|
func (self *VMEnv) Vm() vm.Vm { return self.evm }
|
||||||
func (self *VMEnv) Origin() common.Address { f, _ := self.msg.From(); return f }
|
func (self *VMEnv) Origin() common.Address { f, _ := self.msg.From(); return f }
|
||||||
func (self *VMEnv) BlockNumber() *big.Int { return self.header.Number }
|
func (self *VMEnv) BlockNumber() *big.Int { return self.header.Number }
|
||||||
|
@ -37,6 +37,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
"github.com/ethereum/go-ethereum/miner"
|
"github.com/ethereum/go-ethereum/miner"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
@ -303,13 +304,13 @@ func (api *PublicDebugAPI) DumpBlock(number uint64) (state.Dump, error) {
|
|||||||
// PrivateDebugAPI is the collection of Etheruem full node APIs exposed over
|
// PrivateDebugAPI is the collection of Etheruem full node APIs exposed over
|
||||||
// the private debugging endpoint.
|
// the private debugging endpoint.
|
||||||
type PrivateDebugAPI struct {
|
type PrivateDebugAPI struct {
|
||||||
config *core.ChainConfig
|
config *params.ChainConfig
|
||||||
eth *Ethereum
|
eth *Ethereum
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPrivateDebugAPI creates a new API definition for the full node-related
|
// NewPrivateDebugAPI creates a new API definition for the full node-related
|
||||||
// private debug methods of the Ethereum service.
|
// private debug methods of the Ethereum service.
|
||||||
func NewPrivateDebugAPI(config *core.ChainConfig, eth *Ethereum) *PrivateDebugAPI {
|
func NewPrivateDebugAPI(config *params.ChainConfig, eth *Ethereum) *PrivateDebugAPI {
|
||||||
return &PrivateDebugAPI{config: config, eth: eth}
|
return &PrivateDebugAPI{config: config, eth: eth}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ func (b *EthApiBackend) GetVMEnv(ctx context.Context, msg core.Message, state et
|
|||||||
from := statedb.GetOrNewStateObject(addr)
|
from := statedb.GetOrNewStateObject(addr)
|
||||||
from.SetBalance(common.MaxBig)
|
from.SetBalance(common.MaxBig)
|
||||||
vmError := func() error { return nil }
|
vmError := func() error { return nil }
|
||||||
return core.NewEnv(statedb, b.eth.chainConfig, b.eth.blockchain, msg, header, b.eth.chainConfig.VmConfig), vmError, nil
|
return core.NewEnv(statedb, b.eth.chainConfig, b.eth.blockchain, msg, header, vm.Config{}), vmError, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
|
func (b *EthApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
|
||||||
|
@ -35,7 +35,6 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/common/registrar/ethreg"
|
"github.com/ethereum/go-ethereum/common/registrar/ethreg"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"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/downloader"
|
||||||
"github.com/ethereum/go-ethereum/eth/filters"
|
"github.com/ethereum/go-ethereum/eth/filters"
|
||||||
"github.com/ethereum/go-ethereum/eth/gasprice"
|
"github.com/ethereum/go-ethereum/eth/gasprice"
|
||||||
@ -47,6 +46,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/miner"
|
"github.com/ethereum/go-ethereum/miner"
|
||||||
"github.com/ethereum/go-ethereum/node"
|
"github.com/ethereum/go-ethereum/node"
|
||||||
"github.com/ethereum/go-ethereum/p2p"
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
ChainConfig *core.ChainConfig // chain configuration
|
ChainConfig *params.ChainConfig // chain configuration
|
||||||
|
|
||||||
NetworkId int // Network ID to use for selecting peers to connect to
|
NetworkId int // Network ID to use for selecting peers to connect to
|
||||||
Genesis string // Genesis JSON to seed the chain database with
|
Genesis string // Genesis JSON to seed the chain database with
|
||||||
@ -112,7 +112,7 @@ type LesServer interface {
|
|||||||
|
|
||||||
// Ethereum implements the Ethereum full node service.
|
// Ethereum implements the Ethereum full node service.
|
||||||
type Ethereum struct {
|
type Ethereum struct {
|
||||||
chainConfig *core.ChainConfig
|
chainConfig *params.ChainConfig
|
||||||
// Channel for shutting down the service
|
// Channel for shutting down the service
|
||||||
shutdownChan chan bool // Channel for shutting down the ethereum
|
shutdownChan chan bool // Channel for shutting down the ethereum
|
||||||
stopDbUpgrade func() // stop chain db sequential key upgrade
|
stopDbUpgrade func() // stop chain db sequential key upgrade
|
||||||
@ -217,10 +217,6 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
|
|||||||
core.WriteChainConfig(chainDb, genesis.Hash(), config.ChainConfig)
|
core.WriteChainConfig(chainDb, genesis.Hash(), config.ChainConfig)
|
||||||
|
|
||||||
eth.chainConfig = config.ChainConfig
|
eth.chainConfig = config.ChainConfig
|
||||||
eth.chainConfig.VmConfig = vm.Config{
|
|
||||||
EnableJit: config.EnableJit,
|
|
||||||
ForceJit: config.ForceJit,
|
|
||||||
}
|
|
||||||
|
|
||||||
eth.blockchain, err = core.NewBlockChain(chainDb, eth.chainConfig, eth.pow, eth.EventMux())
|
eth.blockchain, err = core.NewBlockChain(chainDb, eth.chainConfig, eth.pow, eth.EventMux())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -25,6 +25,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMipmapUpgrade(t *testing.T) {
|
func TestMipmapUpgrade(t *testing.T) {
|
||||||
@ -32,7 +33,7 @@ func TestMipmapUpgrade(t *testing.T) {
|
|||||||
addr := common.BytesToAddress([]byte("jeff"))
|
addr := common.BytesToAddress([]byte("jeff"))
|
||||||
genesis := core.WriteGenesisBlockForTesting(db)
|
genesis := core.WriteGenesisBlockForTesting(db)
|
||||||
|
|
||||||
chain, receipts := core.GenerateChain(nil, genesis, db, 10, func(i int, gen *core.BlockGen) {
|
chain, receipts := core.GenerateChain(params.TestChainConfig, genesis, db, 10, func(i int, gen *core.BlockGen) {
|
||||||
var receipts types.Receipts
|
var receipts types.Receipts
|
||||||
switch i {
|
switch i {
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -109,7 +109,7 @@ func newTester() *downloadTester {
|
|||||||
// reassembly.
|
// reassembly.
|
||||||
func (dl *downloadTester) makeChain(n int, seed byte, parent *types.Block, parentReceipts types.Receipts, heavy bool) ([]common.Hash, map[common.Hash]*types.Header, map[common.Hash]*types.Block, map[common.Hash]types.Receipts) {
|
func (dl *downloadTester) makeChain(n int, seed byte, parent *types.Block, parentReceipts types.Receipts, heavy bool) ([]common.Hash, map[common.Hash]*types.Header, map[common.Hash]*types.Block, map[common.Hash]types.Receipts) {
|
||||||
// Generate the block chain
|
// Generate the block chain
|
||||||
blocks, receipts := core.GenerateChain(nil, parent, dl.peerDb, n, func(i int, block *core.BlockGen) {
|
blocks, receipts := core.GenerateChain(params.TestChainConfig, parent, dl.peerDb, n, func(i int, block *core.BlockGen) {
|
||||||
block.SetCoinbase(common.Address{seed})
|
block.SetCoinbase(common.Address{seed})
|
||||||
|
|
||||||
// If a heavy chain is requested, delay blocks to raise difficulty
|
// If a heavy chain is requested, delay blocks to raise difficulty
|
||||||
|
@ -45,7 +45,7 @@ var (
|
|||||||
// contains a transaction and every 5th an uncle to allow testing correct block
|
// contains a transaction and every 5th an uncle to allow testing correct block
|
||||||
// reassembly.
|
// reassembly.
|
||||||
func makeChain(n int, seed byte, parent *types.Block) ([]common.Hash, map[common.Hash]*types.Block) {
|
func makeChain(n int, seed byte, parent *types.Block) ([]common.Hash, map[common.Hash]*types.Block) {
|
||||||
blocks, _ := core.GenerateChain(nil, parent, testdb, n, func(i int, block *core.BlockGen) {
|
blocks, _ := core.GenerateChain(params.TestChainConfig, parent, testdb, n, func(i int, block *core.BlockGen) {
|
||||||
block.SetCoinbase(common.Address{seed})
|
block.SetCoinbase(common.Address{seed})
|
||||||
|
|
||||||
// If the block number is multiple of 3, send a bonus transaction to the miner
|
// If the block number is multiple of 3, send a bonus transaction to the miner
|
||||||
|
@ -30,6 +30,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -81,7 +82,7 @@ func TestBlockSubscription(t *testing.T) {
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
genesis = core.WriteGenesisBlockForTesting(db)
|
genesis = core.WriteGenesisBlockForTesting(db)
|
||||||
chain, _ = core.GenerateChain(nil, genesis, db, 10, func(i int, gen *core.BlockGen) {})
|
chain, _ = core.GenerateChain(params.TestChainConfig, genesis, db, 10, func(i int, gen *core.BlockGen) {})
|
||||||
chainEvents = []core.ChainEvent{}
|
chainEvents = []core.ChainEvent{}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
func makeReceipt(addr common.Address) *types.Receipt {
|
func makeReceipt(addr common.Address) *types.Receipt {
|
||||||
@ -60,7 +61,7 @@ func BenchmarkMipmaps(b *testing.B) {
|
|||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
genesis := core.WriteGenesisBlockForTesting(db, core.GenesisAccount{Address: addr1, Balance: big.NewInt(1000000)})
|
genesis := core.WriteGenesisBlockForTesting(db, core.GenesisAccount{Address: addr1, Balance: big.NewInt(1000000)})
|
||||||
chain, receipts := core.GenerateChain(nil, genesis, db, 100010, func(i int, gen *core.BlockGen) {
|
chain, receipts := core.GenerateChain(params.TestChainConfig, genesis, db, 100010, func(i int, gen *core.BlockGen) {
|
||||||
var receipts types.Receipts
|
var receipts types.Receipts
|
||||||
switch i {
|
switch i {
|
||||||
case 2403:
|
case 2403:
|
||||||
@ -137,7 +138,7 @@ func TestFilters(t *testing.T) {
|
|||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
genesis := core.WriteGenesisBlockForTesting(db, core.GenesisAccount{Address: addr, Balance: big.NewInt(1000000)})
|
genesis := core.WriteGenesisBlockForTesting(db, core.GenesisAccount{Address: addr, Balance: big.NewInt(1000000)})
|
||||||
chain, receipts := core.GenerateChain(nil, genesis, db, 1000, func(i int, gen *core.BlockGen) {
|
chain, receipts := core.GenerateChain(params.TestChainConfig, genesis, db, 1000, func(i int, gen *core.BlockGen) {
|
||||||
var receipts types.Receipts
|
var receipts types.Receipts
|
||||||
switch i {
|
switch i {
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -37,6 +37,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
"github.com/ethereum/go-ethereum/p2p"
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/pow"
|
"github.com/ethereum/go-ethereum/pow"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
)
|
)
|
||||||
@ -67,7 +68,7 @@ type ProtocolManager struct {
|
|||||||
txpool txPool
|
txpool txPool
|
||||||
blockchain *core.BlockChain
|
blockchain *core.BlockChain
|
||||||
chaindb ethdb.Database
|
chaindb ethdb.Database
|
||||||
chainconfig *core.ChainConfig
|
chainconfig *params.ChainConfig
|
||||||
maxPeers int
|
maxPeers int
|
||||||
|
|
||||||
downloader *downloader.Downloader
|
downloader *downloader.Downloader
|
||||||
@ -95,7 +96,7 @@ type ProtocolManager struct {
|
|||||||
|
|
||||||
// NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable
|
// NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable
|
||||||
// with the ethereum network.
|
// with the ethereum network.
|
||||||
func NewProtocolManager(config *core.ChainConfig, fastSync bool, networkId int, maxPeers int, mux *event.TypeMux, txpool txPool, pow pow.PoW, blockchain *core.BlockChain, chaindb ethdb.Database) (*ProtocolManager, error) {
|
func NewProtocolManager(config *params.ChainConfig, fastSync bool, networkId int, maxPeers int, mux *event.TypeMux, txpool txPool, pow pow.PoW, blockchain *core.BlockChain, chaindb ethdb.Database) (*ProtocolManager, error) {
|
||||||
// Create the protocol manager with the base fields
|
// Create the protocol manager with the base fields
|
||||||
manager := &ProtocolManager{
|
manager := &ProtocolManager{
|
||||||
networkId: networkId,
|
networkId: networkId,
|
||||||
|
@ -466,7 +466,7 @@ func testDAOChallenge(t *testing.T, localForked, remoteForked bool, timeout bool
|
|||||||
pow = new(core.FakePow)
|
pow = new(core.FakePow)
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db, _ = ethdb.NewMemDatabase()
|
||||||
genesis = core.WriteGenesisBlockForTesting(db)
|
genesis = core.WriteGenesisBlockForTesting(db)
|
||||||
config = &core.ChainConfig{DAOForkBlock: big.NewInt(1), DAOForkSupport: localForked}
|
config = ¶ms.ChainConfig{DAOForkBlock: big.NewInt(1), DAOForkSupport: localForked}
|
||||||
blockchain, _ = core.NewBlockChain(db, config, pow, evmux)
|
blockchain, _ = core.NewBlockChain(db, config, pow, evmux)
|
||||||
)
|
)
|
||||||
pm, err := NewProtocolManager(config, false, NetworkId, 1000, evmux, new(testTxPool), pow, blockchain, db)
|
pm, err := NewProtocolManager(config, false, NetworkId, 1000, evmux, new(testTxPool), pow, blockchain, db)
|
||||||
@ -491,7 +491,7 @@ func testDAOChallenge(t *testing.T, localForked, remoteForked bool, timeout bool
|
|||||||
}
|
}
|
||||||
// Create a block to reply to the challenge if no timeout is simualted
|
// Create a block to reply to the challenge if no timeout is simualted
|
||||||
if !timeout {
|
if !timeout {
|
||||||
blocks, _ := core.GenerateChain(nil, genesis, db, 1, func(i int, block *core.BlockGen) {
|
blocks, _ := core.GenerateChain(¶ms.ChainConfig{}, genesis, db, 1, func(i int, block *core.BlockGen) {
|
||||||
if remoteForked {
|
if remoteForked {
|
||||||
block.SetExtra(params.DAOForkBlockExtra)
|
block.SetExtra(params.DAOForkBlockExtra)
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/p2p"
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -54,10 +55,10 @@ func newTestProtocolManager(fastSync bool, blocks int, generator func(int, *core
|
|||||||
pow = new(core.FakePow)
|
pow = new(core.FakePow)
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db, _ = ethdb.NewMemDatabase()
|
||||||
genesis = core.WriteGenesisBlockForTesting(db, testBank)
|
genesis = core.WriteGenesisBlockForTesting(db, testBank)
|
||||||
chainConfig = &core.ChainConfig{HomesteadBlock: big.NewInt(0)} // homestead set to 0 because of chain maker
|
chainConfig = ¶ms.ChainConfig{HomesteadBlock: big.NewInt(0)} // homestead set to 0 because of chain maker
|
||||||
blockchain, _ = core.NewBlockChain(db, chainConfig, pow, evmux)
|
blockchain, _ = core.NewBlockChain(db, chainConfig, pow, evmux)
|
||||||
)
|
)
|
||||||
chain, _ := core.GenerateChain(nil, genesis, db, blocks, generator)
|
chain, _ := core.GenerateChain(chainConfig, genesis, db, blocks, generator)
|
||||||
if _, err := blockchain.InsertChain(chain); err != nil {
|
if _, err := blockchain.InsertChain(chain); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -29,11 +29,6 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ruleSet struct{}
|
|
||||||
|
|
||||||
func (self *ruleSet) IsHomestead(*big.Int) bool { return true }
|
|
||||||
func (*ruleSet) GasTable(*big.Int) params.GasTable { return params.GasTableHomesteadGasRepriceFork }
|
|
||||||
|
|
||||||
type Env struct {
|
type Env struct {
|
||||||
gasLimit *big.Int
|
gasLimit *big.Int
|
||||||
depth int
|
depth int
|
||||||
@ -46,7 +41,9 @@ func NewEnv(config *vm.Config) *Env {
|
|||||||
return env
|
return env
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Env) RuleSet() vm.RuleSet { return &ruleSet{} }
|
func (self *Env) ChainConfig() *params.ChainConfig {
|
||||||
|
return params.TestChainConfig
|
||||||
|
}
|
||||||
func (self *Env) Vm() vm.Vm { return self.evm }
|
func (self *Env) Vm() vm.Vm { return self.evm }
|
||||||
func (self *Env) Origin() common.Address { return common.Address{} }
|
func (self *Env) Origin() common.Address { return common.Address{} }
|
||||||
func (self *Env) BlockNumber() *big.Int { return big.NewInt(0) }
|
func (self *Env) BlockNumber() *big.Int { return big.NewInt(0) }
|
||||||
|
@ -87,7 +87,7 @@ func (b *LesApiBackend) GetVMEnv(ctx context.Context, msg core.Message, state et
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
from.SetBalance(common.MaxBig)
|
from.SetBalance(common.MaxBig)
|
||||||
env := light.NewEnv(ctx, stateDb, b.eth.chainConfig, b.eth.blockchain, msg, header, b.eth.chainConfig.VmConfig)
|
env := light.NewEnv(ctx, stateDb, b.eth.chainConfig, b.eth.blockchain, msg, header, vm.Config{})
|
||||||
return env, env.Error, nil
|
return env, env.Error, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,6 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/common/httpclient"
|
"github.com/ethereum/go-ethereum/common/httpclient"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
|
||||||
"github.com/ethereum/go-ethereum/eth"
|
"github.com/ethereum/go-ethereum/eth"
|
||||||
"github.com/ethereum/go-ethereum/eth/downloader"
|
"github.com/ethereum/go-ethereum/eth/downloader"
|
||||||
"github.com/ethereum/go-ethereum/eth/filters"
|
"github.com/ethereum/go-ethereum/eth/filters"
|
||||||
@ -42,13 +41,14 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
"github.com/ethereum/go-ethereum/node"
|
"github.com/ethereum/go-ethereum/node"
|
||||||
"github.com/ethereum/go-ethereum/p2p"
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
rpc "github.com/ethereum/go-ethereum/rpc"
|
rpc "github.com/ethereum/go-ethereum/rpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
type LightEthereum struct {
|
type LightEthereum struct {
|
||||||
odr *LesOdr
|
odr *LesOdr
|
||||||
relay *LesTxRelay
|
relay *LesTxRelay
|
||||||
chainConfig *core.ChainConfig
|
chainConfig *params.ChainConfig
|
||||||
// Channel for shutting down the service
|
// Channel for shutting down the service
|
||||||
shutdownChan chan bool
|
shutdownChan chan bool
|
||||||
// Handlers
|
// Handlers
|
||||||
@ -107,10 +107,6 @@ func New(ctx *node.ServiceContext, config *eth.Config) (*LightEthereum, error) {
|
|||||||
return nil, errors.New("missing chain config")
|
return nil, errors.New("missing chain config")
|
||||||
}
|
}
|
||||||
eth.chainConfig = config.ChainConfig
|
eth.chainConfig = config.ChainConfig
|
||||||
eth.chainConfig.VmConfig = vm.Config{
|
|
||||||
EnableJit: config.EnableJit,
|
|
||||||
ForceJit: config.ForceJit,
|
|
||||||
}
|
|
||||||
eth.blockchain, err = light.NewLightChain(odr, eth.chainConfig, eth.pow, eth.eventMux)
|
eth.blockchain, err = light.NewLightChain(odr, eth.chainConfig, eth.pow, eth.eventMux)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == core.ErrNoGenesis {
|
if err == core.ErrNoGenesis {
|
||||||
|
@ -38,6 +38,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/p2p"
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||||
"github.com/ethereum/go-ethereum/p2p/discv5"
|
"github.com/ethereum/go-ethereum/p2p/discv5"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/pow"
|
"github.com/ethereum/go-ethereum/pow"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/trie"
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
@ -95,7 +96,7 @@ type ProtocolManager struct {
|
|||||||
txpool txPool
|
txpool txPool
|
||||||
txrelay *LesTxRelay
|
txrelay *LesTxRelay
|
||||||
networkId int
|
networkId int
|
||||||
chainConfig *core.ChainConfig
|
chainConfig *params.ChainConfig
|
||||||
blockchain BlockChain
|
blockchain BlockChain
|
||||||
chainDb ethdb.Database
|
chainDb ethdb.Database
|
||||||
odr *LesOdr
|
odr *LesOdr
|
||||||
@ -129,7 +130,7 @@ type ProtocolManager struct {
|
|||||||
|
|
||||||
// NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable
|
// NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable
|
||||||
// with the ethereum network.
|
// with the ethereum network.
|
||||||
func NewProtocolManager(chainConfig *core.ChainConfig, lightSync bool, networkId int, mux *event.TypeMux, pow pow.PoW, blockchain BlockChain, txpool txPool, chainDb ethdb.Database, odr *LesOdr, txrelay *LesTxRelay) (*ProtocolManager, error) {
|
func NewProtocolManager(chainConfig *params.ChainConfig, lightSync bool, networkId int, mux *event.TypeMux, pow pow.PoW, blockchain BlockChain, txpool txPool, chainDb ethdb.Database, odr *LesOdr, txrelay *LesTxRelay) (*ProtocolManager, error) {
|
||||||
// Create the protocol manager with the base fields
|
// Create the protocol manager with the base fields
|
||||||
manager := &ProtocolManager{
|
manager := &ProtocolManager{
|
||||||
lightSync: lightSync,
|
lightSync: lightSync,
|
||||||
|
@ -131,7 +131,7 @@ func newTestProtocolManager(lightSync bool, blocks int, generator func(int, *cor
|
|||||||
pow = new(core.FakePow)
|
pow = new(core.FakePow)
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db, _ = ethdb.NewMemDatabase()
|
||||||
genesis = core.WriteGenesisBlockForTesting(db, core.GenesisAccount{Address: testBankAddress, Balance: testBankFunds})
|
genesis = core.WriteGenesisBlockForTesting(db, core.GenesisAccount{Address: testBankAddress, Balance: testBankFunds})
|
||||||
chainConfig = &core.ChainConfig{HomesteadBlock: big.NewInt(0)} // homestead set to 0 because of chain maker
|
chainConfig = ¶ms.ChainConfig{HomesteadBlock: big.NewInt(0)} // homestead set to 0 because of chain maker
|
||||||
odr *LesOdr
|
odr *LesOdr
|
||||||
chain BlockChain
|
chain BlockChain
|
||||||
)
|
)
|
||||||
@ -141,7 +141,7 @@ func newTestProtocolManager(lightSync bool, blocks int, generator func(int, *cor
|
|||||||
chain, _ = light.NewLightChain(odr, chainConfig, pow, evmux)
|
chain, _ = light.NewLightChain(odr, chainConfig, pow, evmux)
|
||||||
} else {
|
} else {
|
||||||
blockchain, _ := core.NewBlockChain(db, chainConfig, pow, evmux)
|
blockchain, _ := core.NewBlockChain(db, chainConfig, pow, evmux)
|
||||||
gchain, _ := core.GenerateChain(nil, genesis, db, blocks, generator)
|
gchain, _ := core.GenerateChain(chainConfig, genesis, db, blocks, generator)
|
||||||
if _, err := blockchain.InsertChain(gchain); err != nil {
|
if _, err := blockchain.InsertChain(gchain); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -26,17 +26,19 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/light"
|
"github.com/ethereum/go-ethereum/light"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
type odrTestFn func(ctx context.Context, db ethdb.Database, config *core.ChainConfig, bc *core.BlockChain, lc *light.LightChain, bhash common.Hash) []byte
|
type odrTestFn func(ctx context.Context, db ethdb.Database, config *params.ChainConfig, bc *core.BlockChain, lc *light.LightChain, bhash common.Hash) []byte
|
||||||
|
|
||||||
func TestOdrGetBlockLes1(t *testing.T) { testOdr(t, 1, 1, odrGetBlock) }
|
func TestOdrGetBlockLes1(t *testing.T) { testOdr(t, 1, 1, odrGetBlock) }
|
||||||
|
|
||||||
func odrGetBlock(ctx context.Context, db ethdb.Database, config *core.ChainConfig, bc *core.BlockChain, lc *light.LightChain, bhash common.Hash) []byte {
|
func odrGetBlock(ctx context.Context, db ethdb.Database, config *params.ChainConfig, bc *core.BlockChain, lc *light.LightChain, bhash common.Hash) []byte {
|
||||||
var block *types.Block
|
var block *types.Block
|
||||||
if bc != nil {
|
if bc != nil {
|
||||||
block = bc.GetBlockByHash(bhash)
|
block = bc.GetBlockByHash(bhash)
|
||||||
@ -52,7 +54,7 @@ func odrGetBlock(ctx context.Context, db ethdb.Database, config *core.ChainConfi
|
|||||||
|
|
||||||
func TestOdrGetReceiptsLes1(t *testing.T) { testOdr(t, 1, 1, odrGetReceipts) }
|
func TestOdrGetReceiptsLes1(t *testing.T) { testOdr(t, 1, 1, odrGetReceipts) }
|
||||||
|
|
||||||
func odrGetReceipts(ctx context.Context, db ethdb.Database, config *core.ChainConfig, bc *core.BlockChain, lc *light.LightChain, bhash common.Hash) []byte {
|
func odrGetReceipts(ctx context.Context, db ethdb.Database, config *params.ChainConfig, bc *core.BlockChain, lc *light.LightChain, bhash common.Hash) []byte {
|
||||||
var receipts types.Receipts
|
var receipts types.Receipts
|
||||||
if bc != nil {
|
if bc != nil {
|
||||||
receipts = core.GetBlockReceipts(db, bhash, core.GetBlockNumber(db, bhash))
|
receipts = core.GetBlockReceipts(db, bhash, core.GetBlockNumber(db, bhash))
|
||||||
@ -68,7 +70,7 @@ func odrGetReceipts(ctx context.Context, db ethdb.Database, config *core.ChainCo
|
|||||||
|
|
||||||
func TestOdrAccountsLes1(t *testing.T) { testOdr(t, 1, 1, odrAccounts) }
|
func TestOdrAccountsLes1(t *testing.T) { testOdr(t, 1, 1, odrAccounts) }
|
||||||
|
|
||||||
func odrAccounts(ctx context.Context, db ethdb.Database, config *core.ChainConfig, bc *core.BlockChain, lc *light.LightChain, bhash common.Hash) []byte {
|
func odrAccounts(ctx context.Context, db ethdb.Database, config *params.ChainConfig, bc *core.BlockChain, lc *light.LightChain, bhash common.Hash) []byte {
|
||||||
dummyAddr := common.HexToAddress("1234567812345678123456781234567812345678")
|
dummyAddr := common.HexToAddress("1234567812345678123456781234567812345678")
|
||||||
acc := []common.Address{testBankAddress, acc1Addr, acc2Addr, dummyAddr}
|
acc := []common.Address{testBankAddress, acc1Addr, acc2Addr, dummyAddr}
|
||||||
|
|
||||||
@ -138,7 +140,7 @@ func (m lightcallmsg) Gas() *big.Int { return m.gas }
|
|||||||
func (m lightcallmsg) Value() *big.Int { return m.value }
|
func (m lightcallmsg) Value() *big.Int { return m.value }
|
||||||
func (m lightcallmsg) Data() []byte { return m.data }
|
func (m lightcallmsg) Data() []byte { return m.data }
|
||||||
|
|
||||||
func odrContractCall(ctx context.Context, db ethdb.Database, config *core.ChainConfig, bc *core.BlockChain, lc *light.LightChain, bhash common.Hash) []byte {
|
func odrContractCall(ctx context.Context, db ethdb.Database, config *params.ChainConfig, bc *core.BlockChain, lc *light.LightChain, bhash common.Hash) []byte {
|
||||||
data := common.Hex2Bytes("60CD26850000000000000000000000000000000000000000000000000000000000000000")
|
data := common.Hex2Bytes("60CD26850000000000000000000000000000000000000000000000000000000000000000")
|
||||||
|
|
||||||
var res []byte
|
var res []byte
|
||||||
@ -160,7 +162,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *core.ChainC
|
|||||||
to: &testContractAddr,
|
to: &testContractAddr,
|
||||||
}
|
}
|
||||||
|
|
||||||
vmenv := core.NewEnv(statedb, config, bc, msg, header, config.VmConfig)
|
vmenv := core.NewEnv(statedb, config, bc, msg, header, vm.Config{})
|
||||||
gp := new(core.GasPool).AddGas(common.MaxBig)
|
gp := new(core.GasPool).AddGas(common.MaxBig)
|
||||||
ret, _, _ := core.ApplyMessage(vmenv, msg, gp)
|
ret, _, _ := core.ApplyMessage(vmenv, msg, gp)
|
||||||
res = append(res, ret...)
|
res = append(res, ret...)
|
||||||
@ -181,7 +183,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *core.ChainC
|
|||||||
to: &testContractAddr,
|
to: &testContractAddr,
|
||||||
}
|
}
|
||||||
|
|
||||||
vmenv := light.NewEnv(ctx, state, config, lc, msg, header, config.VmConfig)
|
vmenv := light.NewEnv(ctx, state, config, lc, msg, header, vm.Config{})
|
||||||
gp := new(core.GasPool).AddGas(common.MaxBig)
|
gp := new(core.GasPool).AddGas(common.MaxBig)
|
||||||
ret, _, _ := core.ApplyMessage(vmenv, msg, gp)
|
ret, _, _ := core.ApplyMessage(vmenv, msg, gp)
|
||||||
if vmenv.Error() == nil {
|
if vmenv.Error() == nil {
|
||||||
|
@ -29,6 +29,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/pow"
|
"github.com/ethereum/go-ethereum/pow"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/hashicorp/golang-lru"
|
"github.com/hashicorp/golang-lru"
|
||||||
@ -71,7 +72,7 @@ type LightChain struct {
|
|||||||
// NewLightChain returns a fully initialised light chain using information
|
// NewLightChain returns a fully initialised light chain using information
|
||||||
// available in the database. It initialises the default Ethereum header
|
// available in the database. It initialises the default Ethereum header
|
||||||
// validator.
|
// validator.
|
||||||
func NewLightChain(odr OdrBackend, config *core.ChainConfig, pow pow.PoW, mux *event.TypeMux) (*LightChain, error) {
|
func NewLightChain(odr OdrBackend, config *params.ChainConfig, pow pow.PoW, mux *event.TypeMux) (*LightChain, error) {
|
||||||
bodyCache, _ := lru.New(bodyCacheLimit)
|
bodyCache, _ := lru.New(bodyCacheLimit)
|
||||||
bodyRLPCache, _ := lru.New(bodyCacheLimit)
|
bodyRLPCache, _ := lru.New(bodyCacheLimit)
|
||||||
blockCache, _ := lru.New(blockCacheLimit)
|
blockCache, _ := lru.New(blockCacheLimit)
|
||||||
|
@ -28,6 +28,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/pow"
|
"github.com/ethereum/go-ethereum/pow"
|
||||||
"github.com/hashicorp/golang-lru"
|
"github.com/hashicorp/golang-lru"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
@ -41,7 +42,7 @@ var (
|
|||||||
|
|
||||||
// makeHeaderChain creates a deterministic chain of headers rooted at parent.
|
// makeHeaderChain creates a deterministic chain of headers rooted at parent.
|
||||||
func makeHeaderChain(parent *types.Header, n int, db ethdb.Database, seed int) []*types.Header {
|
func makeHeaderChain(parent *types.Header, n int, db ethdb.Database, seed int) []*types.Header {
|
||||||
blocks, _ := core.GenerateChain(nil, types.NewBlockWithHeader(parent), db, n, func(i int, b *core.BlockGen) {
|
blocks, _ := core.GenerateChain(params.TestChainConfig, types.NewBlockWithHeader(parent), db, n, func(i int, b *core.BlockGen) {
|
||||||
b.SetCoinbase(common.Address{0: byte(seed), 19: byte(i)})
|
b.SetCoinbase(common.Address{0: byte(seed), 19: byte(i)})
|
||||||
})
|
})
|
||||||
headers := make([]*types.Header, len(blocks))
|
headers := make([]*types.Header, len(blocks))
|
||||||
@ -51,8 +52,8 @@ func makeHeaderChain(parent *types.Header, n int, db ethdb.Database, seed int) [
|
|||||||
return headers
|
return headers
|
||||||
}
|
}
|
||||||
|
|
||||||
func testChainConfig() *core.ChainConfig {
|
func testChainConfig() *params.ChainConfig {
|
||||||
return &core.ChainConfig{HomesteadBlock: big.NewInt(0)}
|
return ¶ms.ChainConfig{HomesteadBlock: big.NewInt(0)}
|
||||||
}
|
}
|
||||||
|
|
||||||
// newCanonical creates a chain database, and injects a deterministic canonical
|
// newCanonical creates a chain database, and injects a deterministic canonical
|
||||||
|
@ -294,7 +294,8 @@ func testChainOdr(t *testing.T, protocol int, expFail uint64, fn odrTestFn) {
|
|||||||
core.WriteGenesisBlockForTesting(ldb, core.GenesisAccount{Address: testBankAddress, Balance: testBankFunds})
|
core.WriteGenesisBlockForTesting(ldb, core.GenesisAccount{Address: testBankAddress, Balance: testBankFunds})
|
||||||
// Assemble the test environment
|
// Assemble the test environment
|
||||||
blockchain, _ := core.NewBlockChain(sdb, testChainConfig(), pow, evmux)
|
blockchain, _ := core.NewBlockChain(sdb, testChainConfig(), pow, evmux)
|
||||||
gchain, _ := core.GenerateChain(nil, genesis, sdb, 4, testChainGen)
|
chainConfig := ¶ms.ChainConfig{HomesteadBlock: new(big.Int)}
|
||||||
|
gchain, _ := core.GenerateChain(chainConfig, genesis, sdb, 4, testChainGen)
|
||||||
if _, err := blockchain.InsertChain(gchain); err != nil {
|
if _, err := blockchain.InsertChain(gchain); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ func makeTestState() (common.Hash, ethdb.Database) {
|
|||||||
st.AddBalance(addr, big.NewInt(int64(i)))
|
st.AddBalance(addr, big.NewInt(int64(i)))
|
||||||
st.SetCode(addr, []byte{i, i, i})
|
st.SetCode(addr, []byte{i, i, i})
|
||||||
}
|
}
|
||||||
root, _ := st.Commit()
|
root, _ := st.Commit(false)
|
||||||
return root, sdb
|
return root, sdb
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
@ -42,7 +43,7 @@ var txPermanent = uint64(500)
|
|||||||
// always receive all locally signed transactions in the same order as they are
|
// always receive all locally signed transactions in the same order as they are
|
||||||
// created.
|
// created.
|
||||||
type TxPool struct {
|
type TxPool struct {
|
||||||
config *core.ChainConfig
|
config *params.ChainConfig
|
||||||
quit chan bool
|
quit chan bool
|
||||||
eventMux *event.TypeMux
|
eventMux *event.TypeMux
|
||||||
events event.Subscription
|
events event.Subscription
|
||||||
@ -76,7 +77,7 @@ type TxRelayBackend interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewTxPool creates a new light transaction pool
|
// NewTxPool creates a new light transaction pool
|
||||||
func NewTxPool(config *core.ChainConfig, eventMux *event.TypeMux, chain *LightChain, relay TxRelayBackend) *TxPool {
|
func NewTxPool(config *params.ChainConfig, eventMux *event.TypeMux, chain *LightChain, relay TxRelayBackend) *TxPool {
|
||||||
pool := &TxPool{
|
pool := &TxPool{
|
||||||
config: config,
|
config: config,
|
||||||
nonce: make(map[common.Address]uint64),
|
nonce: make(map[common.Address]uint64),
|
||||||
|
@ -87,7 +87,8 @@ func TestTxPool(t *testing.T) {
|
|||||||
core.WriteGenesisBlockForTesting(ldb, core.GenesisAccount{Address: testBankAddress, Balance: testBankFunds})
|
core.WriteGenesisBlockForTesting(ldb, core.GenesisAccount{Address: testBankAddress, Balance: testBankFunds})
|
||||||
// Assemble the test environment
|
// Assemble the test environment
|
||||||
blockchain, _ := core.NewBlockChain(sdb, testChainConfig(), pow, evmux)
|
blockchain, _ := core.NewBlockChain(sdb, testChainConfig(), pow, evmux)
|
||||||
gchain, _ := core.GenerateChain(nil, genesis, sdb, poolTestBlocks, txPoolTestChainGen)
|
chainConfig := ¶ms.ChainConfig{HomesteadBlock: new(big.Int)}
|
||||||
|
gchain, _ := core.GenerateChain(chainConfig, genesis, sdb, poolTestBlocks, txPoolTestChainGen)
|
||||||
if _, err := blockchain.InsertChain(gchain); err != nil {
|
if _, err := blockchain.InsertChain(gchain); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -34,7 +35,7 @@ import (
|
|||||||
type VMEnv struct {
|
type VMEnv struct {
|
||||||
vm.Environment
|
vm.Environment
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
chainConfig *core.ChainConfig
|
chainConfig *params.ChainConfig
|
||||||
evm *vm.EVM
|
evm *vm.EVM
|
||||||
state *VMState
|
state *VMState
|
||||||
header *types.Header
|
header *types.Header
|
||||||
@ -45,7 +46,7 @@ type VMEnv struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewEnv creates a new execution environment based on an ODR capable light state
|
// NewEnv creates a new execution environment based on an ODR capable light state
|
||||||
func NewEnv(ctx context.Context, state *LightState, chainConfig *core.ChainConfig, chain *LightChain, msg core.Message, header *types.Header, cfg vm.Config) *VMEnv {
|
func NewEnv(ctx context.Context, state *LightState, chainConfig *params.ChainConfig, chain *LightChain, msg core.Message, header *types.Header, cfg vm.Config) *VMEnv {
|
||||||
env := &VMEnv{
|
env := &VMEnv{
|
||||||
chainConfig: chainConfig,
|
chainConfig: chainConfig,
|
||||||
chain: chain,
|
chain: chain,
|
||||||
@ -58,7 +59,7 @@ func NewEnv(ctx context.Context, state *LightState, chainConfig *core.ChainConfi
|
|||||||
return env
|
return env
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *VMEnv) RuleSet() vm.RuleSet { return self.chainConfig }
|
func (self *VMEnv) ChainConfig() *params.ChainConfig { return self.chainConfig }
|
||||||
func (self *VMEnv) Vm() vm.Vm { return self.evm }
|
func (self *VMEnv) Vm() vm.Vm { return self.evm }
|
||||||
func (self *VMEnv) Origin() common.Address { f, _ := self.msg.From(); return f }
|
func (self *VMEnv) Origin() common.Address { f, _ := self.msg.From(); return f }
|
||||||
func (self *VMEnv) BlockNumber() *big.Int { return self.header.Number }
|
func (self *VMEnv) BlockNumber() *big.Int { return self.header.Number }
|
||||||
|
@ -62,7 +62,7 @@ type Miner struct {
|
|||||||
shouldStart int32 // should start indicates whether we should start after sync
|
shouldStart int32 // should start indicates whether we should start after sync
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(eth Backend, config *core.ChainConfig, mux *event.TypeMux, pow pow.PoW) *Miner {
|
func New(eth Backend, config *params.ChainConfig, mux *event.TypeMux, pow pow.PoW) *Miner {
|
||||||
miner := &Miner{
|
miner := &Miner{
|
||||||
eth: eth,
|
eth: eth,
|
||||||
mux: mux,
|
mux: mux,
|
||||||
|
@ -63,7 +63,7 @@ type uint64RingBuffer struct {
|
|||||||
// Work is the workers current environment and holds
|
// Work is the workers current environment and holds
|
||||||
// all of the current state information
|
// all of the current state information
|
||||||
type Work struct {
|
type Work struct {
|
||||||
config *core.ChainConfig
|
config *params.ChainConfig
|
||||||
state *state.StateDB // apply state changes here
|
state *state.StateDB // apply state changes here
|
||||||
ancestors *set.Set // ancestor set (used for checking uncle parent validity)
|
ancestors *set.Set // ancestor set (used for checking uncle parent validity)
|
||||||
family *set.Set // family set (used for checking uncle invalidity)
|
family *set.Set // family set (used for checking uncle invalidity)
|
||||||
@ -90,7 +90,7 @@ type Result struct {
|
|||||||
|
|
||||||
// worker is the main object which takes care of applying messages to the new state
|
// worker is the main object which takes care of applying messages to the new state
|
||||||
type worker struct {
|
type worker struct {
|
||||||
config *core.ChainConfig
|
config *params.ChainConfig
|
||||||
|
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
|
|
||||||
@ -128,7 +128,7 @@ type worker struct {
|
|||||||
fullValidation bool
|
fullValidation bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func newWorker(config *core.ChainConfig, coinbase common.Address, eth Backend, mux *event.TypeMux) *worker {
|
func newWorker(config *params.ChainConfig, coinbase common.Address, eth Backend, mux *event.TypeMux) *worker {
|
||||||
worker := &worker{
|
worker := &worker{
|
||||||
config: config,
|
config: config,
|
||||||
eth: eth,
|
eth: eth,
|
||||||
@ -276,7 +276,7 @@ func (self *worker) wait() {
|
|||||||
}
|
}
|
||||||
go self.mux.Post(core.NewMinedBlockEvent{Block: block})
|
go self.mux.Post(core.NewMinedBlockEvent{Block: block})
|
||||||
} else {
|
} else {
|
||||||
work.state.Commit()
|
work.state.Commit(self.config.IsEIP158(block.Number()))
|
||||||
parent := self.chain.GetBlock(block.ParentHash(), block.NumberU64()-1)
|
parent := self.chain.GetBlock(block.ParentHash(), block.NumberU64()-1)
|
||||||
if parent == nil {
|
if parent == nil {
|
||||||
glog.V(logger.Error).Infoln("Invalid block found during mining")
|
glog.V(logger.Error).Infoln("Invalid block found during mining")
|
||||||
@ -528,7 +528,7 @@ func (self *worker) commitNewWork() {
|
|||||||
if atomic.LoadInt32(&self.mining) == 1 {
|
if atomic.LoadInt32(&self.mining) == 1 {
|
||||||
// commit state root after all state transitions.
|
// commit state root after all state transitions.
|
||||||
core.AccumulateRewards(work.state, header, uncles)
|
core.AccumulateRewards(work.state, header, uncles)
|
||||||
header.Root = work.state.IntermediateRoot()
|
header.Root = work.state.IntermediateRoot(self.config.IsEIP158(header.Number))
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the new block whose nonce will be mined.
|
// create the new block whose nonce will be mined.
|
||||||
@ -620,14 +620,7 @@ func (env *Work) commitTransactions(mux *event.TypeMux, txs *types.TransactionsB
|
|||||||
func (env *Work) commitTransaction(tx *types.Transaction, bc *core.BlockChain, gp *core.GasPool) (error, vm.Logs) {
|
func (env *Work) commitTransaction(tx *types.Transaction, bc *core.BlockChain, gp *core.GasPool) (error, vm.Logs) {
|
||||||
snap := env.state.Snapshot()
|
snap := env.state.Snapshot()
|
||||||
|
|
||||||
// this is a bit of a hack to force jit for the miners
|
receipt, logs, _, err := core.ApplyTransaction(env.config, bc, gp, env.state, env.header, tx, env.header.GasUsed, vm.Config{})
|
||||||
config := env.config.VmConfig
|
|
||||||
if !(config.EnableJit && config.ForceJit) {
|
|
||||||
config.EnableJit = false
|
|
||||||
}
|
|
||||||
config.ForceJit = false // disable forcing jit
|
|
||||||
|
|
||||||
receipt, logs, _, err := core.ApplyTransaction(env.config, bc, gp, env.state, env.header, tx, env.header.GasUsed, config)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
env.state.RevertToSnapshot(snap)
|
env.state.RevertToSnapshot(snap)
|
||||||
return err, nil
|
return err, nil
|
||||||
|
@ -14,19 +14,14 @@
|
|||||||
// You should have received a copy of the GNU Lesser General Public License
|
// 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/>.
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
package core
|
package params
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
|
||||||
"github.com/ethereum/go-ethereum/params"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var ChainConfigNotFoundErr = errors.New("ChainConfig not found") // general config not found error
|
|
||||||
|
|
||||||
// ChainConfig is the core config which determines the blockchain settings.
|
// ChainConfig is the core config which determines the blockchain settings.
|
||||||
//
|
//
|
||||||
// ChainConfig is stored in the database on a per block basis. This means
|
// ChainConfig is stored in the database on a per block basis. This means
|
||||||
@ -37,12 +32,15 @@ type ChainConfig struct {
|
|||||||
DAOForkBlock *big.Int `json:"daoForkBlock"` // TheDAO hard-fork switch block (nil = no fork)
|
DAOForkBlock *big.Int `json:"daoForkBlock"` // TheDAO hard-fork switch block (nil = no fork)
|
||||||
DAOForkSupport bool `json:"daoForkSupport"` // Whether the nodes supports or opposes the DAO hard-fork
|
DAOForkSupport bool `json:"daoForkSupport"` // Whether the nodes supports or opposes the DAO hard-fork
|
||||||
|
|
||||||
HomesteadGasRepriceBlock *big.Int `json:"homesteadGasRepriceBlock"` // Homestead gas reprice switch block (nil = no fork)
|
// EIP150 implements the Gas price changes (https://github.com/ethereum/EIPs/issues/150)
|
||||||
HomesteadGasRepriceHash common.Hash `json:"homesteadGasRepriceHash"` // Homestead gas reprice switch block hash (fast sync aid)
|
EIP150Block *big.Int `json:"EIP150Block"` // EIP150 HF block (nil = no fork)
|
||||||
|
EIP150Hash common.Hash `json:"EIP150Hash"` // EIP150 HF hash (fast sync aid)
|
||||||
|
|
||||||
VmConfig vm.Config `json:"-"`
|
EIP158Block *big.Int `json:"EIP158Block"` // EIP158 HF block
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var TestChainConfig = &ChainConfig{new(big.Int), new(big.Int), true, new(big.Int), common.Hash{}, new(big.Int)}
|
||||||
|
|
||||||
// IsHomestead returns whether num is either equal to the homestead block or greater.
|
// IsHomestead returns whether num is either equal to the homestead block or greater.
|
||||||
func (c *ChainConfig) IsHomestead(num *big.Int) bool {
|
func (c *ChainConfig) IsHomestead(num *big.Int) bool {
|
||||||
if c.HomesteadBlock == nil || num == nil {
|
if c.HomesteadBlock == nil || num == nil {
|
||||||
@ -54,10 +52,33 @@ func (c *ChainConfig) IsHomestead(num *big.Int) bool {
|
|||||||
// GasTable returns the gas table corresponding to the current phase (homestead or homestead reprice).
|
// GasTable returns the gas table corresponding to the current phase (homestead or homestead reprice).
|
||||||
//
|
//
|
||||||
// The returned GasTable's fields shouldn't, under any circumstances, be changed.
|
// The returned GasTable's fields shouldn't, under any circumstances, be changed.
|
||||||
func (c *ChainConfig) GasTable(num *big.Int) params.GasTable {
|
func (c *ChainConfig) GasTable(num *big.Int) GasTable {
|
||||||
if c.HomesteadGasRepriceBlock == nil || num == nil || num.Cmp(c.HomesteadGasRepriceBlock) < 0 {
|
if num == nil {
|
||||||
return params.GasTableHomestead
|
return GasTableHomestead
|
||||||
}
|
}
|
||||||
|
|
||||||
return params.GasTableHomesteadGasRepriceFork
|
switch {
|
||||||
|
case c.EIP158Block != nil && num.Cmp(c.EIP158Block) >= 0:
|
||||||
|
return GasTableEIP158
|
||||||
|
case c.EIP150Block != nil && num.Cmp(c.EIP150Block) >= 0:
|
||||||
|
return GasTableHomesteadGasRepriceFork
|
||||||
|
default:
|
||||||
|
return GasTableHomestead
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ChainConfig) IsEIP150(num *big.Int) bool {
|
||||||
|
if c.EIP150Block == nil || num == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return num.Cmp(c.EIP150Block) >= 0
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ChainConfig) IsEIP158(num *big.Int) bool {
|
||||||
|
if c.EIP158Block == nil || num == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return num.Cmp(c.EIP158Block) >= 0
|
||||||
|
|
||||||
}
|
}
|
@ -26,6 +26,10 @@ type GasTable struct {
|
|||||||
Calls *big.Int
|
Calls *big.Int
|
||||||
Suicide *big.Int
|
Suicide *big.Int
|
||||||
|
|
||||||
|
Exp *big.Int
|
||||||
|
ExpOneByte *big.Int
|
||||||
|
Exp256 *big.Int
|
||||||
|
|
||||||
// CreateBySuicide occurs when the
|
// CreateBySuicide occurs when the
|
||||||
// refunded account is one that does
|
// refunded account is one that does
|
||||||
// not exist. This logic is similar
|
// not exist. This logic is similar
|
||||||
@ -44,6 +48,7 @@ var (
|
|||||||
SLoad: big.NewInt(50),
|
SLoad: big.NewInt(50),
|
||||||
Calls: big.NewInt(40),
|
Calls: big.NewInt(40),
|
||||||
Suicide: big.NewInt(0),
|
Suicide: big.NewInt(0),
|
||||||
|
Exp: big.NewInt(20),
|
||||||
|
|
||||||
// explicitly set to nil to indicate
|
// explicitly set to nil to indicate
|
||||||
// this rule does not apply to homestead.
|
// this rule does not apply to homestead.
|
||||||
@ -52,6 +57,8 @@ var (
|
|||||||
|
|
||||||
// GasTableHomestead contain the gas re-prices for
|
// GasTableHomestead contain the gas re-prices for
|
||||||
// the homestead phase.
|
// the homestead phase.
|
||||||
|
//
|
||||||
|
// TODO rename to GasTableEIP150
|
||||||
GasTableHomesteadGasRepriceFork = GasTable{
|
GasTableHomesteadGasRepriceFork = GasTable{
|
||||||
ExtcodeSize: big.NewInt(700),
|
ExtcodeSize: big.NewInt(700),
|
||||||
ExtcodeCopy: big.NewInt(700),
|
ExtcodeCopy: big.NewInt(700),
|
||||||
@ -59,6 +66,21 @@ var (
|
|||||||
SLoad: big.NewInt(200),
|
SLoad: big.NewInt(200),
|
||||||
Calls: big.NewInt(700),
|
Calls: big.NewInt(700),
|
||||||
Suicide: big.NewInt(5000),
|
Suicide: big.NewInt(5000),
|
||||||
|
Exp: big.NewInt(20),
|
||||||
|
|
||||||
|
CreateBySuicide: big.NewInt(25000),
|
||||||
|
}
|
||||||
|
|
||||||
|
GasTableEIP158 = GasTable{
|
||||||
|
ExtcodeSize: big.NewInt(700),
|
||||||
|
ExtcodeCopy: big.NewInt(700),
|
||||||
|
Balance: big.NewInt(400),
|
||||||
|
SLoad: big.NewInt(200),
|
||||||
|
Calls: big.NewInt(700),
|
||||||
|
Suicide: big.NewInt(5000),
|
||||||
|
Exp: big.NewInt(80),
|
||||||
|
ExpOneByte: big.NewInt(160),
|
||||||
|
Exp256: big.NewInt(2640),
|
||||||
|
|
||||||
CreateBySuicide: big.NewInt(25000),
|
CreateBySuicide: big.NewInt(25000),
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -170,7 +171,7 @@ func runBlockTest(homesteadBlock, daoForkBlock, gasPriceFork *big.Int, test *Blo
|
|||||||
core.WriteCanonicalHash(db, test.Genesis.Hash(), test.Genesis.NumberU64())
|
core.WriteCanonicalHash(db, test.Genesis.Hash(), test.Genesis.NumberU64())
|
||||||
core.WriteHeadBlockHash(db, test.Genesis.Hash())
|
core.WriteHeadBlockHash(db, test.Genesis.Hash())
|
||||||
evmux := new(event.TypeMux)
|
evmux := new(event.TypeMux)
|
||||||
config := &core.ChainConfig{HomesteadBlock: homesteadBlock, DAOForkBlock: daoForkBlock, DAOForkSupport: true, HomesteadGasRepriceBlock: gasPriceFork}
|
config := ¶ms.ChainConfig{HomesteadBlock: homesteadBlock, DAOForkBlock: daoForkBlock, DAOForkSupport: true, EIP150Block: gasPriceFork}
|
||||||
chain, err := core.NewBlockChain(db, config, ethash.NewShared(), evmux)
|
chain, err := core.NewBlockChain(db, config, ethash.NewShared(), evmux)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -228,7 +229,7 @@ func (t *BlockTest) InsertPreState(db ethdb.Database) (*state.StateDB, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
root, err := statedb.Commit()
|
root, err := statedb.Commit(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error writing state: %v", err)
|
return nil, fmt.Errorf("error writing state: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
func BenchmarkStateCall1024(b *testing.B) {
|
func BenchmarkStateCall1024(b *testing.B) {
|
||||||
@ -31,172 +33,172 @@ func BenchmarkStateCall1024(b *testing.B) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestStateSystemOperations(t *testing.T) {
|
func TestStateSystemOperations(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: big.NewInt(1150000),
|
HomesteadBlock: big.NewInt(1150000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "stSystemOperationsTest.json")
|
fn := filepath.Join(stateTestDir, "stSystemOperationsTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStateExample(t *testing.T) {
|
func TestStateExample(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: big.NewInt(1150000),
|
HomesteadBlock: big.NewInt(1150000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "stExample.json")
|
fn := filepath.Join(stateTestDir, "stExample.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStatePreCompiledContracts(t *testing.T) {
|
func TestStatePreCompiledContracts(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: big.NewInt(1150000),
|
HomesteadBlock: big.NewInt(1150000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "stPreCompiledContracts.json")
|
fn := filepath.Join(stateTestDir, "stPreCompiledContracts.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStateRecursiveCreate(t *testing.T) {
|
func TestStateRecursiveCreate(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: big.NewInt(1150000),
|
HomesteadBlock: big.NewInt(1150000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "stRecursiveCreate.json")
|
fn := filepath.Join(stateTestDir, "stRecursiveCreate.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStateSpecial(t *testing.T) {
|
func TestStateSpecial(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: big.NewInt(1150000),
|
HomesteadBlock: big.NewInt(1150000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "stSpecialTest.json")
|
fn := filepath.Join(stateTestDir, "stSpecialTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStateRefund(t *testing.T) {
|
func TestStateRefund(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: big.NewInt(1150000),
|
HomesteadBlock: big.NewInt(1150000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "stRefundTest.json")
|
fn := filepath.Join(stateTestDir, "stRefundTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStateBlockHash(t *testing.T) {
|
func TestStateBlockHash(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: big.NewInt(1150000),
|
HomesteadBlock: big.NewInt(1150000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "stBlockHashTest.json")
|
fn := filepath.Join(stateTestDir, "stBlockHashTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStateInitCode(t *testing.T) {
|
func TestStateInitCode(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: big.NewInt(1150000),
|
HomesteadBlock: big.NewInt(1150000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "stInitCodeTest.json")
|
fn := filepath.Join(stateTestDir, "stInitCodeTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStateLog(t *testing.T) {
|
func TestStateLog(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: big.NewInt(1150000),
|
HomesteadBlock: big.NewInt(1150000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "stLogTests.json")
|
fn := filepath.Join(stateTestDir, "stLogTests.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStateTransaction(t *testing.T) {
|
func TestStateTransaction(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: big.NewInt(1150000),
|
HomesteadBlock: big.NewInt(1150000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "stTransactionTest.json")
|
fn := filepath.Join(stateTestDir, "stTransactionTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStateTransition(t *testing.T) {
|
func TestStateTransition(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: big.NewInt(1150000),
|
HomesteadBlock: big.NewInt(1150000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "stTransitionTest.json")
|
fn := filepath.Join(stateTestDir, "stTransitionTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCallCreateCallCode(t *testing.T) {
|
func TestCallCreateCallCode(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: big.NewInt(1150000),
|
HomesteadBlock: big.NewInt(1150000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "stCallCreateCallCodeTest.json")
|
fn := filepath.Join(stateTestDir, "stCallCreateCallCodeTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCallCodes(t *testing.T) {
|
func TestCallCodes(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: big.NewInt(1150000),
|
HomesteadBlock: big.NewInt(1150000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "stCallCodes.json")
|
fn := filepath.Join(stateTestDir, "stCallCodes.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDelegateCall(t *testing.T) {
|
func TestDelegateCall(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: big.NewInt(1150000),
|
HomesteadBlock: big.NewInt(1150000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "stDelegatecallTest.json")
|
fn := filepath.Join(stateTestDir, "stDelegatecallTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMemory(t *testing.T) {
|
func TestMemory(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: big.NewInt(1150000),
|
HomesteadBlock: big.NewInt(1150000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "stMemoryTest.json")
|
fn := filepath.Join(stateTestDir, "stMemoryTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMemoryStress(t *testing.T) {
|
func TestMemoryStress(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: big.NewInt(1150000),
|
HomesteadBlock: big.NewInt(1150000),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,13 +206,13 @@ func TestMemoryStress(t *testing.T) {
|
|||||||
t.Skip()
|
t.Skip()
|
||||||
}
|
}
|
||||||
fn := filepath.Join(stateTestDir, "stMemoryStressTest.json")
|
fn := filepath.Join(stateTestDir, "stMemoryStressTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestQuadraticComplexity(t *testing.T) {
|
func TestQuadraticComplexity(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: big.NewInt(1150000),
|
HomesteadBlock: big.NewInt(1150000),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,41 +220,41 @@ func TestQuadraticComplexity(t *testing.T) {
|
|||||||
t.Skip()
|
t.Skip()
|
||||||
}
|
}
|
||||||
fn := filepath.Join(stateTestDir, "stQuadraticComplexityTest.json")
|
fn := filepath.Join(stateTestDir, "stQuadraticComplexityTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSolidity(t *testing.T) {
|
func TestSolidity(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: big.NewInt(1150000),
|
HomesteadBlock: big.NewInt(1150000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "stSolidityTest.json")
|
fn := filepath.Join(stateTestDir, "stSolidityTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestWallet(t *testing.T) {
|
func TestWallet(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: big.NewInt(1150000),
|
HomesteadBlock: big.NewInt(1150000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "stWalletTest.json")
|
fn := filepath.Join(stateTestDir, "stWalletTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStateTestsRandom(t *testing.T) {
|
func TestStateTestsRandom(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: big.NewInt(1150000),
|
HomesteadBlock: big.NewInt(1150000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fns, _ := filepath.Glob("./files/StateTests/RandomTests/*")
|
fns, _ := filepath.Glob("./files/StateTests/RandomTests/*")
|
||||||
for _, fn := range fns {
|
for _, fn := range fns {
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(fn, err)
|
t.Error(fn, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -260,117 +262,117 @@ func TestStateTestsRandom(t *testing.T) {
|
|||||||
|
|
||||||
// homestead tests
|
// homestead tests
|
||||||
func TestHomesteadStateSystemOperations(t *testing.T) {
|
func TestHomesteadStateSystemOperations(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "Homestead", "stSystemOperationsTest.json")
|
fn := filepath.Join(stateTestDir, "Homestead", "stSystemOperationsTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHomesteadStatePreCompiledContracts(t *testing.T) {
|
func TestHomesteadStatePreCompiledContracts(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "Homestead", "stPreCompiledContracts.json")
|
fn := filepath.Join(stateTestDir, "Homestead", "stPreCompiledContracts.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHomesteadStateRecursiveCreate(t *testing.T) {
|
func TestHomesteadStateRecursiveCreate(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "Homestead", "stSpecialTest.json")
|
fn := filepath.Join(stateTestDir, "Homestead", "stSpecialTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHomesteadStateRefund(t *testing.T) {
|
func TestHomesteadStateRefund(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "Homestead", "stRefundTest.json")
|
fn := filepath.Join(stateTestDir, "Homestead", "stRefundTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHomesteadStateInitCode(t *testing.T) {
|
func TestHomesteadStateInitCode(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "Homestead", "stInitCodeTest.json")
|
fn := filepath.Join(stateTestDir, "Homestead", "stInitCodeTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHomesteadStateLog(t *testing.T) {
|
func TestHomesteadStateLog(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "Homestead", "stLogTests.json")
|
fn := filepath.Join(stateTestDir, "Homestead", "stLogTests.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHomesteadStateTransaction(t *testing.T) {
|
func TestHomesteadStateTransaction(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "Homestead", "stTransactionTest.json")
|
fn := filepath.Join(stateTestDir, "Homestead", "stTransactionTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHomesteadCallCreateCallCode(t *testing.T) {
|
func TestHomesteadCallCreateCallCode(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "Homestead", "stCallCreateCallCodeTest.json")
|
fn := filepath.Join(stateTestDir, "Homestead", "stCallCreateCallCodeTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHomesteadCallCodes(t *testing.T) {
|
func TestHomesteadCallCodes(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "Homestead", "stCallCodes.json")
|
fn := filepath.Join(stateTestDir, "Homestead", "stCallCodes.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHomesteadMemory(t *testing.T) {
|
func TestHomesteadMemory(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "Homestead", "stMemoryTest.json")
|
fn := filepath.Join(stateTestDir, "Homestead", "stMemoryTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHomesteadMemoryStress(t *testing.T) {
|
func TestHomesteadMemoryStress(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -378,13 +380,13 @@ func TestHomesteadMemoryStress(t *testing.T) {
|
|||||||
t.Skip()
|
t.Skip()
|
||||||
}
|
}
|
||||||
fn := filepath.Join(stateTestDir, "Homestead", "stMemoryStressTest.json")
|
fn := filepath.Join(stateTestDir, "Homestead", "stMemoryStressTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHomesteadQuadraticComplexity(t *testing.T) {
|
func TestHomesteadQuadraticComplexity(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -392,286 +394,313 @@ func TestHomesteadQuadraticComplexity(t *testing.T) {
|
|||||||
t.Skip()
|
t.Skip()
|
||||||
}
|
}
|
||||||
fn := filepath.Join(stateTestDir, "Homestead", "stQuadraticComplexityTest.json")
|
fn := filepath.Join(stateTestDir, "Homestead", "stQuadraticComplexityTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHomesteadWallet(t *testing.T) {
|
func TestHomesteadWallet(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "Homestead", "stWalletTest.json")
|
fn := filepath.Join(stateTestDir, "Homestead", "stWalletTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHomesteadDelegateCodes(t *testing.T) {
|
func TestHomesteadDelegateCodes(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "Homestead", "stCallDelegateCodes.json")
|
fn := filepath.Join(stateTestDir, "Homestead", "stCallDelegateCodes.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHomesteadDelegateCodesCallCode(t *testing.T) {
|
func TestHomesteadDelegateCodesCallCode(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "Homestead", "stCallDelegateCodesCallCode.json")
|
fn := filepath.Join(stateTestDir, "Homestead", "stCallDelegateCodesCallCode.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHomesteadBounds(t *testing.T) {
|
func TestHomesteadBounds(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "Homestead", "stBoundsTest.json")
|
fn := filepath.Join(stateTestDir, "Homestead", "stBoundsTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// EIP150 tests
|
// EIP150 tests
|
||||||
func TestEIP150Specific(t *testing.T) {
|
func TestEIP150Specific(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
HomesteadGasRepriceBlock: big.NewInt(2457000),
|
EIP150Block: big.NewInt(2457000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "EIP150", "stEIPSpecificTest.json")
|
fn := filepath.Join(stateTestDir, "EIP150", "stEIPSpecificTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEIP150SingleCodeGasPrice(t *testing.T) {
|
func TestEIP150SingleCodeGasPrice(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
HomesteadGasRepriceBlock: big.NewInt(2457000),
|
EIP150Block: big.NewInt(2457000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "EIP150", "stEIPSingleCodeGasPrices.json")
|
fn := filepath.Join(stateTestDir, "EIP150", "stEIPSingleCodeGasPrices.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEIP150MemExpandingCalls(t *testing.T) {
|
func TestEIP150MemExpandingCalls(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
HomesteadGasRepriceBlock: big.NewInt(2457000),
|
EIP150Block: big.NewInt(2457000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "EIP150", "stMemExpandingEIPCalls.json")
|
fn := filepath.Join(stateTestDir, "EIP150", "stMemExpandingEIPCalls.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEIP150HomesteadStateSystemOperations(t *testing.T) {
|
func TestEIP150HomesteadStateSystemOperations(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
HomesteadGasRepriceBlock: big.NewInt(2457000),
|
EIP150Block: big.NewInt(2457000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "EIP150", "Homestead", "stSystemOperationsTest.json")
|
fn := filepath.Join(stateTestDir, "EIP150", "Homestead", "stSystemOperationsTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEIP150HomesteadStatePreCompiledContracts(t *testing.T) {
|
func TestEIP150HomesteadStatePreCompiledContracts(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
HomesteadGasRepriceBlock: big.NewInt(2457000),
|
EIP150Block: big.NewInt(2457000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "EIP150", "Homestead", "stPreCompiledContracts.json")
|
fn := filepath.Join(stateTestDir, "EIP150", "Homestead", "stPreCompiledContracts.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEIP150HomesteadStateRecursiveCreate(t *testing.T) {
|
func TestEIP150HomesteadStateRecursiveCreate(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
HomesteadGasRepriceBlock: big.NewInt(2457000),
|
EIP150Block: big.NewInt(2457000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "EIP150", "Homestead", "stSpecialTest.json")
|
fn := filepath.Join(stateTestDir, "EIP150", "Homestead", "stSpecialTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEIP150HomesteadStateRefund(t *testing.T) {
|
func TestEIP150HomesteadStateRefund(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
HomesteadGasRepriceBlock: big.NewInt(2457000),
|
EIP150Block: big.NewInt(2457000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "EIP150", "Homestead", "stRefundTest.json")
|
fn := filepath.Join(stateTestDir, "EIP150", "Homestead", "stRefundTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEIP150HomesteadStateInitCode(t *testing.T) {
|
func TestEIP150HomesteadStateInitCode(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
HomesteadGasRepriceBlock: big.NewInt(2457000),
|
EIP150Block: big.NewInt(2457000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "EIP150", "Homestead", "stInitCodeTest.json")
|
fn := filepath.Join(stateTestDir, "EIP150", "Homestead", "stInitCodeTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEIP150HomesteadStateLog(t *testing.T) {
|
func TestEIP150HomesteadStateLog(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
HomesteadGasRepriceBlock: big.NewInt(2457000),
|
EIP150Block: big.NewInt(2457000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "EIP150", "Homestead", "stLogTests.json")
|
fn := filepath.Join(stateTestDir, "EIP150", "Homestead", "stLogTests.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEIP150HomesteadStateTransaction(t *testing.T) {
|
func TestEIP150HomesteadStateTransaction(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
HomesteadGasRepriceBlock: big.NewInt(2457000),
|
EIP150Block: big.NewInt(2457000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "EIP150", "Homestead", "stTransactionTest.json")
|
fn := filepath.Join(stateTestDir, "EIP150", "Homestead", "stTransactionTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEIP150HomesteadCallCreateCallCode(t *testing.T) {
|
func TestEIP150HomesteadCallCreateCallCode(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
HomesteadGasRepriceBlock: big.NewInt(2457000),
|
EIP150Block: big.NewInt(2457000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "EIP150", "Homestead", "stCallCreateCallCodeTest.json")
|
fn := filepath.Join(stateTestDir, "EIP150", "Homestead", "stCallCreateCallCodeTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEIP150HomesteadCallCodes(t *testing.T) {
|
func TestEIP150HomesteadCallCodes(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
HomesteadGasRepriceBlock: big.NewInt(2457000),
|
EIP150Block: big.NewInt(2457000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "EIP150", "Homestead", "stCallCodes.json")
|
fn := filepath.Join(stateTestDir, "EIP150", "Homestead", "stCallCodes.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEIP150HomesteadMemory(t *testing.T) {
|
func TestEIP150HomesteadMemory(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
HomesteadGasRepriceBlock: big.NewInt(2457000),
|
EIP150Block: big.NewInt(2457000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "EIP150", "Homestead", "stMemoryTest.json")
|
fn := filepath.Join(stateTestDir, "EIP150", "Homestead", "stMemoryTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEIP150HomesteadMemoryStress(t *testing.T) {
|
func TestEIP150HomesteadMemoryStress(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
HomesteadGasRepriceBlock: big.NewInt(2457000),
|
EIP150Block: big.NewInt(2457000),
|
||||||
}
|
}
|
||||||
|
|
||||||
if os.Getenv("TEST_VM_COMPLEX") == "" {
|
if os.Getenv("TEST_VM_COMPLEX") == "" {
|
||||||
t.Skip()
|
t.Skip()
|
||||||
}
|
}
|
||||||
fn := filepath.Join(stateTestDir, "EIP150", "Homestead", "stMemoryStressTest.json")
|
fn := filepath.Join(stateTestDir, "EIP150", "Homestead", "stMemoryStressTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEIP150HomesteadQuadraticComplexity(t *testing.T) {
|
func TestEIP150HomesteadQuadraticComplexity(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
HomesteadGasRepriceBlock: big.NewInt(2457000),
|
EIP150Block: big.NewInt(2457000),
|
||||||
}
|
}
|
||||||
|
|
||||||
if os.Getenv("TEST_VM_COMPLEX") == "" {
|
if os.Getenv("TEST_VM_COMPLEX") == "" {
|
||||||
t.Skip()
|
t.Skip()
|
||||||
}
|
}
|
||||||
fn := filepath.Join(stateTestDir, "EIP150", "Homestead", "stQuadraticComplexityTest.json")
|
fn := filepath.Join(stateTestDir, "EIP150", "Homestead", "stQuadraticComplexityTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEIP150HomesteadWallet(t *testing.T) {
|
func TestEIP150HomesteadWallet(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
HomesteadGasRepriceBlock: big.NewInt(2457000),
|
EIP150Block: big.NewInt(2457000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "EIP150", "Homestead", "stWalletTest.json")
|
fn := filepath.Join(stateTestDir, "EIP150", "Homestead", "stWalletTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEIP150HomesteadDelegateCodes(t *testing.T) {
|
func TestEIP150HomesteadDelegateCodes(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
HomesteadGasRepriceBlock: big.NewInt(2457000),
|
EIP150Block: big.NewInt(2457000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "EIP150", "Homestead", "stCallDelegateCodes.json")
|
fn := filepath.Join(stateTestDir, "EIP150", "Homestead", "stCallDelegateCodes.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEIP150HomesteadDelegateCodesCallCode(t *testing.T) {
|
func TestEIP150HomesteadDelegateCodesCallCode(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
HomesteadGasRepriceBlock: big.NewInt(2457000),
|
EIP150Block: big.NewInt(2457000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "EIP150", "Homestead", "stCallDelegateCodesCallCode.json")
|
fn := filepath.Join(stateTestDir, "EIP150", "Homestead", "stCallDelegateCodesCallCode.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEIP150HomesteadBounds(t *testing.T) {
|
func TestEIP150HomesteadBounds(t *testing.T) {
|
||||||
ruleSet := RuleSet{
|
chainConfig := ¶ms.ChainConfig{
|
||||||
HomesteadBlock: new(big.Int),
|
HomesteadBlock: new(big.Int),
|
||||||
HomesteadGasRepriceBlock: big.NewInt(2457000),
|
EIP150Block: big.NewInt(2457000),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := filepath.Join(stateTestDir, "EIP150", "Homestead", "stBoundsTest.json")
|
fn := filepath.Join(stateTestDir, "EIP150", "Homestead", "stBoundsTest.json")
|
||||||
if err := RunStateTest(ruleSet, fn, StateSkipTests); err != nil {
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// EIP158 tests
|
||||||
|
func TestEIP158Create(t *testing.T) {
|
||||||
|
chainConfig := ¶ms.ChainConfig{
|
||||||
|
HomesteadBlock: new(big.Int),
|
||||||
|
EIP150Block: big.NewInt(2457000),
|
||||||
|
EIP158Block: big.NewInt(3500000),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn := filepath.Join(stateTestDir, "EIP158", "stCreateTest.json")
|
||||||
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEIP158Specific(t *testing.T) {
|
||||||
|
chainConfig := ¶ms.ChainConfig{
|
||||||
|
HomesteadBlock: new(big.Int),
|
||||||
|
EIP150Block: big.NewInt(2457000),
|
||||||
|
EIP158Block: big.NewInt(3500000),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn := filepath.Join(stateTestDir, "EIP158", "stEIP158SpecificTest.json")
|
||||||
|
if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,28 +33,29 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
func RunStateTestWithReader(ruleSet RuleSet, r io.Reader, skipTests []string) error {
|
func RunStateTestWithReader(chainConfig *params.ChainConfig, r io.Reader, skipTests []string) error {
|
||||||
tests := make(map[string]VmTest)
|
tests := make(map[string]VmTest)
|
||||||
if err := readJson(r, &tests); err != nil {
|
if err := readJson(r, &tests); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := runStateTests(ruleSet, tests, skipTests); err != nil {
|
if err := runStateTests(chainConfig, tests, skipTests); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func RunStateTest(ruleSet RuleSet, p string, skipTests []string) error {
|
func RunStateTest(chainConfig *params.ChainConfig, p string, skipTests []string) error {
|
||||||
tests := make(map[string]VmTest)
|
tests := make(map[string]VmTest)
|
||||||
if err := readJsonFile(p, &tests); err != nil {
|
if err := readJsonFile(p, &tests); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := runStateTests(ruleSet, tests, skipTests); err != nil {
|
if err := runStateTests(chainConfig, tests, skipTests); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +63,7 @@ func RunStateTest(ruleSet RuleSet, p string, skipTests []string) error {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchStateTest(ruleSet RuleSet, p string, conf bconf, b *testing.B) error {
|
func BenchStateTest(chainConfig *params.ChainConfig, p string, conf bconf, b *testing.B) error {
|
||||||
tests := make(map[string]VmTest)
|
tests := make(map[string]VmTest)
|
||||||
if err := readJsonFile(p, &tests); err != nil {
|
if err := readJsonFile(p, &tests); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -87,22 +88,22 @@ func BenchStateTest(ruleSet RuleSet, p string, conf bconf, b *testing.B) error {
|
|||||||
|
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
benchStateTest(ruleSet, test, env, b)
|
benchStateTest(chainConfig, test, env, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func benchStateTest(ruleSet RuleSet, test VmTest, env map[string]string, b *testing.B) {
|
func benchStateTest(chainConfig *params.ChainConfig, test VmTest, env map[string]string, b *testing.B) {
|
||||||
b.StopTimer()
|
b.StopTimer()
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
statedb := makePreState(db, test.Pre)
|
statedb := makePreState(db, test.Pre)
|
||||||
b.StartTimer()
|
b.StartTimer()
|
||||||
|
|
||||||
RunState(ruleSet, statedb, env, test.Exec)
|
RunState(chainConfig, statedb, env, test.Exec)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runStateTests(ruleSet RuleSet, tests map[string]VmTest, skipTests []string) error {
|
func runStateTests(chainConfig *params.ChainConfig, tests map[string]VmTest, skipTests []string) error {
|
||||||
skipTest := make(map[string]bool, len(skipTests))
|
skipTest := make(map[string]bool, len(skipTests))
|
||||||
for _, name := range skipTests {
|
for _, name := range skipTests {
|
||||||
skipTest[name] = true
|
skipTest[name] = true
|
||||||
@ -115,7 +116,7 @@ func runStateTests(ruleSet RuleSet, tests map[string]VmTest, skipTests []string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//fmt.Println("StateTest:", name)
|
//fmt.Println("StateTest:", name)
|
||||||
if err := runStateTest(ruleSet, test); err != nil {
|
if err := runStateTest(chainConfig, test); err != nil {
|
||||||
return fmt.Errorf("%s: %s\n", name, err.Error())
|
return fmt.Errorf("%s: %s\n", name, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,7 +127,7 @@ func runStateTests(ruleSet RuleSet, tests map[string]VmTest, skipTests []string)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func runStateTest(ruleSet RuleSet, test VmTest) error {
|
func runStateTest(chainConfig *params.ChainConfig, test VmTest) error {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
statedb := makePreState(db, test.Pre)
|
statedb := makePreState(db, test.Pre)
|
||||||
|
|
||||||
@ -150,7 +151,7 @@ func runStateTest(ruleSet RuleSet, test VmTest) error {
|
|||||||
logs vm.Logs
|
logs vm.Logs
|
||||||
)
|
)
|
||||||
|
|
||||||
ret, logs, _, _ = RunState(ruleSet, statedb, env, test.Transaction)
|
ret, logs, _, _ = RunState(chainConfig, statedb, env, test.Transaction)
|
||||||
|
|
||||||
// Compare expected and actual return
|
// Compare expected and actual return
|
||||||
var rexp []byte
|
var rexp []byte
|
||||||
@ -189,7 +190,7 @@ func runStateTest(ruleSet RuleSet, test VmTest) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
root, _ := statedb.Commit()
|
root, _ := statedb.Commit(false)
|
||||||
if common.HexToHash(test.PostStateRoot) != root {
|
if common.HexToHash(test.PostStateRoot) != root {
|
||||||
return fmt.Errorf("Post state root error. Expected: %s have: %x", test.PostStateRoot, root)
|
return fmt.Errorf("Post state root error. Expected: %s have: %x", test.PostStateRoot, root)
|
||||||
}
|
}
|
||||||
@ -204,7 +205,7 @@ func runStateTest(ruleSet RuleSet, test VmTest) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func RunState(ruleSet RuleSet, statedb *state.StateDB, env, tx map[string]string) ([]byte, vm.Logs, *big.Int, error) {
|
func RunState(chainConfig *params.ChainConfig, statedb *state.StateDB, env, tx map[string]string) ([]byte, vm.Logs, *big.Int, error) {
|
||||||
var (
|
var (
|
||||||
data = common.FromHex(tx["data"])
|
data = common.FromHex(tx["data"])
|
||||||
gas = common.Big(tx["gasLimit"])
|
gas = common.Big(tx["gasLimit"])
|
||||||
@ -226,13 +227,13 @@ func RunState(ruleSet RuleSet, statedb *state.StateDB, env, tx map[string]string
|
|||||||
key, _ := hex.DecodeString(tx["secretKey"])
|
key, _ := hex.DecodeString(tx["secretKey"])
|
||||||
addr := crypto.PubkeyToAddress(crypto.ToECDSA(key).PublicKey)
|
addr := crypto.PubkeyToAddress(crypto.ToECDSA(key).PublicKey)
|
||||||
message := NewMessage(addr, to, data, value, gas, price, nonce)
|
message := NewMessage(addr, to, data, value, gas, price, nonce)
|
||||||
vmenv := NewEnvFromMap(ruleSet, statedb, env, tx)
|
vmenv := NewEnvFromMap(chainConfig, statedb, env, tx)
|
||||||
vmenv.origin = addr
|
vmenv.origin = addr
|
||||||
ret, _, err := core.ApplyMessage(vmenv, message, gaspool)
|
ret, _, err := core.ApplyMessage(vmenv, message, gaspool)
|
||||||
if core.IsNonceErr(err) || core.IsInvalidTxErr(err) || core.IsGasLimitErr(err) {
|
if core.IsNonceErr(err) || core.IsInvalidTxErr(err) || core.IsGasLimitErr(err) {
|
||||||
statedb.RevertToSnapshot(snapshot)
|
statedb.RevertToSnapshot(snapshot)
|
||||||
}
|
}
|
||||||
statedb.Commit()
|
statedb.Commit(chainConfig.IsEIP158(vmenv.BlockNumber()))
|
||||||
|
|
||||||
return ret, vmenv.state.Logs(), vmenv.Gas, err
|
return ret, vmenv.state.Logs(), vmenv.Gas, err
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,6 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
@ -164,7 +163,7 @@ func verifyTxFields(txTest TransactionTest, decodedTx *types.Transaction) (err e
|
|||||||
decodedSender common.Address
|
decodedSender common.Address
|
||||||
)
|
)
|
||||||
|
|
||||||
chainConfig := &core.ChainConfig{HomesteadBlock: params.MainNetHomesteadBlock}
|
chainConfig := ¶ms.ChainConfig{HomesteadBlock: params.MainNetHomesteadBlock}
|
||||||
if chainConfig.IsHomestead(common.String2Big(txTest.Blocknumber)) {
|
if chainConfig.IsHomestead(common.String2Big(txTest.Blocknumber)) {
|
||||||
decodedSender, err = decodedTx.From()
|
decodedSender, err = decodedTx.From()
|
||||||
} else {
|
} else {
|
||||||
|
@ -148,27 +148,8 @@ type VmTest struct {
|
|||||||
PostStateRoot string
|
PostStateRoot string
|
||||||
}
|
}
|
||||||
|
|
||||||
type RuleSet struct {
|
|
||||||
HomesteadBlock *big.Int
|
|
||||||
DAOForkBlock *big.Int
|
|
||||||
DAOForkSupport bool
|
|
||||||
HomesteadGasRepriceBlock *big.Int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r RuleSet) IsHomestead(n *big.Int) bool {
|
|
||||||
return n.Cmp(r.HomesteadBlock) >= 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r RuleSet) GasTable(num *big.Int) params.GasTable {
|
|
||||||
if r.HomesteadGasRepriceBlock == nil || num == nil || num.Cmp(r.HomesteadGasRepriceBlock) < 0 {
|
|
||||||
return params.GasTableHomestead
|
|
||||||
}
|
|
||||||
|
|
||||||
return params.GasTableHomesteadGasRepriceFork
|
|
||||||
}
|
|
||||||
|
|
||||||
type Env struct {
|
type Env struct {
|
||||||
ruleSet RuleSet
|
chainConfig *params.ChainConfig
|
||||||
depth int
|
depth int
|
||||||
state *state.StateDB
|
state *state.StateDB
|
||||||
skipTransfer bool
|
skipTransfer bool
|
||||||
@ -189,16 +170,16 @@ type Env struct {
|
|||||||
evm *vm.EVM
|
evm *vm.EVM
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEnv(ruleSet RuleSet, state *state.StateDB) *Env {
|
func NewEnv(chainConfig *params.ChainConfig, state *state.StateDB) *Env {
|
||||||
env := &Env{
|
env := &Env{
|
||||||
ruleSet: ruleSet,
|
chainConfig: chainConfig,
|
||||||
state: state,
|
state: state,
|
||||||
}
|
}
|
||||||
return env
|
return env
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEnvFromMap(ruleSet RuleSet, state *state.StateDB, envValues map[string]string, exeValues map[string]string) *Env {
|
func NewEnvFromMap(chainConfig *params.ChainConfig, state *state.StateDB, envValues map[string]string, exeValues map[string]string) *Env {
|
||||||
env := NewEnv(ruleSet, state)
|
env := NewEnv(chainConfig, state)
|
||||||
|
|
||||||
env.origin = common.HexToAddress(exeValues["caller"])
|
env.origin = common.HexToAddress(exeValues["caller"])
|
||||||
env.parent = common.HexToHash(envValues["previousHash"])
|
env.parent = common.HexToHash(envValues["previousHash"])
|
||||||
@ -217,7 +198,7 @@ func NewEnvFromMap(ruleSet RuleSet, state *state.StateDB, envValues map[string]s
|
|||||||
return env
|
return env
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Env) RuleSet() vm.RuleSet { return self.ruleSet }
|
func (self *Env) ChainConfig() *params.ChainConfig { return self.chainConfig }
|
||||||
func (self *Env) Vm() vm.Vm { return self.evm }
|
func (self *Env) Vm() vm.Vm { return self.evm }
|
||||||
func (self *Env) Origin() common.Address { return self.origin }
|
func (self *Env) Origin() common.Address { return self.origin }
|
||||||
func (self *Env) BlockNumber() *big.Int { return self.number }
|
func (self *Env) BlockNumber() *big.Int { return self.number }
|
||||||
|
@ -225,7 +225,7 @@ func RunVm(state *state.StateDB, env, exec map[string]string) ([]byte, vm.Logs,
|
|||||||
|
|
||||||
caller := state.GetOrNewStateObject(from)
|
caller := state.GetOrNewStateObject(from)
|
||||||
|
|
||||||
vmenv := NewEnvFromMap(RuleSet{params.MainNetHomesteadBlock, params.MainNetDAOForkBlock, true, nil}, state, env, exec)
|
vmenv := NewEnvFromMap(¶ms.ChainConfig{params.MainNetHomesteadBlock, params.MainNetDAOForkBlock, true, nil, common.Hash{}, nil}, state, env, exec)
|
||||||
vmenv.vmTest = true
|
vmenv.vmTest = true
|
||||||
vmenv.skipTransfer = true
|
vmenv.skipTransfer = true
|
||||||
vmenv.initial = true
|
vmenv.initial = true
|
||||||
|
Loading…
Reference in New Issue
Block a user