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,22 +259,22 @@ 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() } | ||||||
| func (self *VMEnv) RevertToSnapshot(snap int) { self.state.RevertToSnapshot(snap) } | func (self *VMEnv) RevertToSnapshot(snap int)        { self.state.RevertToSnapshot(snap) } | ||||||
| func (self *VMEnv) Origin() common.Address    { return *self.transactor } | func (self *VMEnv) Origin() common.Address           { return *self.transactor } | ||||||
| func (self *VMEnv) BlockNumber() *big.Int     { return common.Big0 } | func (self *VMEnv) BlockNumber() *big.Int            { return common.Big0 } | ||||||
| func (self *VMEnv) Coinbase() common.Address  { return *self.transactor } | func (self *VMEnv) Coinbase() common.Address         { return *self.transactor } | ||||||
| func (self *VMEnv) Time() *big.Int            { return self.time } | func (self *VMEnv) Time() *big.Int                   { return self.time } | ||||||
| func (self *VMEnv) Difficulty() *big.Int      { return common.Big1 } | func (self *VMEnv) Difficulty() *big.Int             { return common.Big1 } | ||||||
| func (self *VMEnv) BlockHash() []byte         { return make([]byte, 32) } | func (self *VMEnv) BlockHash() []byte                { return make([]byte, 32) } | ||||||
| func (self *VMEnv) Value() *big.Int           { return self.value } | func (self *VMEnv) Value() *big.Int                  { return self.value } | ||||||
| func (self *VMEnv) GasLimit() *big.Int        { return big.NewInt(1000000000) } | func (self *VMEnv) GasLimit() *big.Int               { return big.NewInt(1000000000) } | ||||||
| func (self *VMEnv) VmType() vm.Type           { return vm.StdVmTy } | func (self *VMEnv) VmType() vm.Type                  { return vm.StdVmTy } | ||||||
| func (self *VMEnv) Depth() int                { return 0 } | func (self *VMEnv) Depth() int                       { return 0 } | ||||||
| func (self *VMEnv) SetDepth(i int)            { self.depth = i } | func (self *VMEnv) SetDepth(i int)                   { self.depth = i } | ||||||
| func (self *VMEnv) GetHash(n uint64) common.Hash { | func (self *VMEnv) GetHash(n uint64) common.Hash { | ||||||
| 	if self.block.Number().Cmp(big.NewInt(int64(n))) == 0 { | 	if self.block.Number().Cmp(big.NewInt(int64(n))) == 0 { | ||||||
| 		return self.block.Hash() | 		return self.block.Hash() | ||||||
|  | |||||||
| @ -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 ctx.GlobalBool(TestNetFlag.Name) { | 	} | ||||||
| 				config.HomesteadGasRepriceBlock = params.TestNetHomesteadGasRepriceBlock | 	if config.EIP150Block == nil { | ||||||
| 			} else { | 		if ctx.GlobalBool(TestNetFlag.Name) { | ||||||
| 				config.HomesteadGasRepriceBlock = params.MainNetHomesteadGasRepriceBlock | 			config.EIP150Block = params.TestNetHomesteadGasRepriceBlock | ||||||
| 			} | 		} else { | ||||||
|  | 			config.EIP150Block = params.MainNetHomesteadGasRepriceBlock | ||||||
| 		} | 		} | ||||||
| 		if config.HomesteadGasRepriceHash == (common.Hash{}) { | 	} | ||||||
| 			if ctx.GlobalBool(TestNetFlag.Name) { | 	if config.EIP150Hash == (common.Hash{}) { | ||||||
| 				config.HomesteadGasRepriceHash = params.TestNetHomesteadGasRepriceHash | 		if ctx.GlobalBool(TestNetFlag.Name) { | ||||||
| 			} else { | 			config.EIP150Hash = params.TestNetHomesteadGasRepriceHash | ||||||
| 				config.HomesteadGasRepriceHash = params.MainNetHomesteadGasRepriceHash | 		} else { | ||||||
| 			} | 			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,13 +23,14 @@ 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 | ||||||
| 
 | 
 | ||||||
| 	origin   common.Address | 	origin   common.Address | ||||||
| 	coinbase common.Address | 	coinbase common.Address | ||||||
| @ -47,14 +48,14 @@ 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, | ||||||
| 		number:     cfg.BlockNumber, | 		number:      cfg.BlockNumber, | ||||||
| 		time:       cfg.Time, | 		time:        cfg.Time, | ||||||
| 		difficulty: cfg.Difficulty, | 		difficulty:  cfg.Difficulty, | ||||||
| 		gasLimit:   cfg.GasLimit, | 		gasLimit:    cfg.GasLimit, | ||||||
| 	} | 	} | ||||||
| 	env.evm = vm.New(env, vm.Config{ | 	env.evm = vm.New(env, vm.Config{ | ||||||
| 		Debug:     cfg.Debug, | 		Debug:     cfg.Debug, | ||||||
| @ -65,16 +66,16 @@ 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 } | ||||||
| func (self *Env) Coinbase() common.Address { return self.coinbase } | func (self *Env) Coinbase() common.Address         { return self.coinbase } | ||||||
| func (self *Env) Time() *big.Int           { return self.time } | func (self *Env) Time() *big.Int                   { return self.time } | ||||||
| func (self *Env) Difficulty() *big.Int     { return self.difficulty } | func (self *Env) Difficulty() *big.Int             { return self.difficulty } | ||||||
| func (self *Env) Db() vm.Database          { return self.state } | func (self *Env) Db() vm.Database                  { return self.state } | ||||||
| func (self *Env) GasLimit() *big.Int       { return self.gasLimit } | func (self *Env) GasLimit() *big.Int               { return self.gasLimit } | ||||||
| func (self *Env) VmType() vm.Type          { return vm.StdVmTy } | func (self *Env) VmType() vm.Type                  { return vm.StdVmTy } | ||||||
| func (self *Env) GetHash(n uint64) common.Hash { | func (self *Env) GetHash(n uint64) common.Hash { | ||||||
| 	return self.getHashFn(n) | 	return self.getHashFn(n) | ||||||
| } | } | ||||||
|  | |||||||
| @ -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,18 +42,18 @@ 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
 | ||||||
| 	msg         Message        // Message appliod
 | 	msg         Message             // Message appliod
 | ||||||
| 
 | 
 | ||||||
| 	header    *types.Header            // Header information
 | 	header    *types.Header            // Header information
 | ||||||
| 	chain     *BlockChain              // Blockchain handle
 | 	chain     *BlockChain              // Blockchain handle
 | ||||||
| 	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,18 +67,18 @@ 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 } | ||||||
| func (self *VMEnv) Coinbase() common.Address { return self.header.Coinbase } | func (self *VMEnv) Coinbase() common.Address         { return self.header.Coinbase } | ||||||
| func (self *VMEnv) Time() *big.Int           { return self.header.Time } | func (self *VMEnv) Time() *big.Int                   { return self.header.Time } | ||||||
| func (self *VMEnv) Difficulty() *big.Int     { return self.header.Difficulty } | func (self *VMEnv) Difficulty() *big.Int             { return self.header.Difficulty } | ||||||
| func (self *VMEnv) GasLimit() *big.Int       { return self.header.GasLimit } | func (self *VMEnv) GasLimit() *big.Int               { return self.header.GasLimit } | ||||||
| func (self *VMEnv) Value() *big.Int          { return self.msg.Value() } | func (self *VMEnv) Value() *big.Int                  { return self.msg.Value() } | ||||||
| func (self *VMEnv) Db() vm.Database          { return self.state } | func (self *VMEnv) Db() vm.Database                  { return self.state } | ||||||
| func (self *VMEnv) Depth() int               { return self.depth } | func (self *VMEnv) Depth() int                       { return self.depth } | ||||||
| func (self *VMEnv) SetDepth(i int)           { self.depth = i } | func (self *VMEnv) SetDepth(i int)                   { self.depth = i } | ||||||
| func (self *VMEnv) GetHash(n uint64) common.Hash { | func (self *VMEnv) GetHash(n uint64) common.Hash { | ||||||
| 	return self.getHashFn(n) | 	return self.getHashFn(n) | ||||||
| } | } | ||||||
|  | |||||||
| @ -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,17 +59,17 @@ 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 } | ||||||
| func (self *VMEnv) Coinbase() common.Address { return self.header.Coinbase } | func (self *VMEnv) Coinbase() common.Address         { return self.header.Coinbase } | ||||||
| func (self *VMEnv) Time() *big.Int           { return self.header.Time } | func (self *VMEnv) Time() *big.Int                   { return self.header.Time } | ||||||
| func (self *VMEnv) Difficulty() *big.Int     { return self.header.Difficulty } | func (self *VMEnv) Difficulty() *big.Int             { return self.header.Difficulty } | ||||||
| func (self *VMEnv) GasLimit() *big.Int       { return self.header.GasLimit } | func (self *VMEnv) GasLimit() *big.Int               { return self.header.GasLimit } | ||||||
| func (self *VMEnv) Db() vm.Database          { return self.state } | func (self *VMEnv) Db() vm.Database                  { return self.state } | ||||||
| func (self *VMEnv) Depth() int               { return self.depth } | func (self *VMEnv) Depth() int                       { return self.depth } | ||||||
| func (self *VMEnv) SetDepth(i int)           { self.depth = i } | func (self *VMEnv) SetDepth(i int)                   { self.depth = i } | ||||||
| func (self *VMEnv) GetHash(n uint64) common.Hash { | func (self *VMEnv) GetHash(n uint64) common.Hash { | ||||||
| 	for header := self.chain.GetHeader(self.header.ParentHash, self.header.Number.Uint64()-1); header != nil; header = self.chain.GetHeader(header.ParentHash, header.Number.Uint64()-1) { | 	for header := self.chain.GetHeader(self.header.ParentHash, self.header.Number.Uint64()-1); header != nil; header = self.chain.GetHeader(header.ParentHash, header.Number.Uint64()-1) { | ||||||
| 		if header.Number.Uint64() == n { | 		if header.Number.Uint64() == n { | ||||||
|  | |||||||
| @ -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,16 +198,16 @@ 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 } | ||||||
| func (self *Env) Coinbase() common.Address { return self.coinbase } | func (self *Env) Coinbase() common.Address         { return self.coinbase } | ||||||
| func (self *Env) Time() *big.Int           { return self.time } | func (self *Env) Time() *big.Int                   { return self.time } | ||||||
| func (self *Env) Difficulty() *big.Int     { return self.difficulty } | func (self *Env) Difficulty() *big.Int             { return self.difficulty } | ||||||
| func (self *Env) Db() vm.Database          { return self.state } | func (self *Env) Db() vm.Database                  { return self.state } | ||||||
| func (self *Env) GasLimit() *big.Int       { return self.gasLimit } | func (self *Env) GasLimit() *big.Int               { return self.gasLimit } | ||||||
| func (self *Env) VmType() vm.Type          { return vm.StdVmTy } | func (self *Env) VmType() vm.Type                  { return vm.StdVmTy } | ||||||
| func (self *Env) GetHash(n uint64) common.Hash { | func (self *Env) GetHash(n uint64) common.Hash { | ||||||
| 	return common.BytesToHash(crypto.Keccak256([]byte(big.NewInt(int64(n)).String()))) | 	return common.BytesToHash(crypto.Keccak256([]byte(big.NewInt(int64(n)).String()))) | ||||||
| } | } | ||||||
|  | |||||||
| @ -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