From dc2e34ddf37cc46e32959a50f03e1d7fe1445630 Mon Sep 17 00:00:00 2001 From: Jeffrey Wilcke Date: Thu, 20 Oct 2016 13:36:29 +0200 Subject: core, core/state, trie: Hardfork EIP155, EIP161, EIP170 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 --- eth/api.go | 24 +++++++++++++++++++----- eth/backend.go | 11 +++-------- eth/backend_test.go | 3 ++- eth/downloader/downloader_test.go | 2 +- eth/fetcher/fetcher_test.go | 2 +- eth/filters/filter_test.go | 5 +++-- eth/handler.go | 5 +++-- eth/handler_test.go | 4 ++-- eth/helper_test.go | 5 +++-- 9 files changed, 37 insertions(+), 24 deletions(-) (limited to 'eth') diff --git a/eth/api.go b/eth/api.go index ed885805a..79a1521d8 100644 --- a/eth/api.go +++ b/eth/api.go @@ -46,6 +46,7 @@ import ( "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/miner" "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" "github.com/syndtr/goleveldb/leveldb" @@ -408,6 +409,7 @@ func (s *PublicAccountAPI) Accounts() []accounts.Account { // It offers methods to create, (un)lock en list accounts. Some methods accept // passwords and are therefore considered private by default. type PrivateAccountAPI struct { + bc *core.BlockChain am *accounts.Manager txPool *core.TxPool txMu *sync.Mutex @@ -417,6 +419,7 @@ type PrivateAccountAPI struct { // NewPrivateAccountAPI create a new PrivateAccountAPI. func NewPrivateAccountAPI(e *Ethereum) *PrivateAccountAPI { return &PrivateAccountAPI{ + bc: e.blockchain, am: e.accountManager, txPool: e.txPool, txMu: &e.txMu, @@ -495,6 +498,10 @@ func (s *PrivateAccountAPI) SignAndSendTransaction(args SendTxArgs, passwd strin tx = types.NewTransaction(args.Nonce.Uint64(), *args.To, args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), common.FromHex(args.Data)) } + if s.bc.Config().IsEIP155(s.bc.CurrentBlock().Number()) { + tx.SetSigner(types.NewEIP155Signer(s.bc.Config().ChainId)) + } + signature, err := s.am.SignWithPassphrase(args.From, passwd, tx.SigHash().Bytes()) if err != nil { return common.Hash{}, err @@ -506,7 +513,7 @@ func (s *PrivateAccountAPI) SignAndSendTransaction(args SendTxArgs, passwd strin // PublicBlockChainAPI provides an API to access the Ethereum blockchain. // It offers only methods that operate on public data that is freely available to anyone. type PublicBlockChainAPI struct { - config *core.ChainConfig + config *params.ChainConfig bc *core.BlockChain chainDb ethdb.Database eventMux *event.TypeMux @@ -518,7 +525,7 @@ type PublicBlockChainAPI struct { } // NewPublicBlockChainAPI creates a new Etheruem blockchain API. -func NewPublicBlockChainAPI(config *core.ChainConfig, bc *core.BlockChain, m *miner.Miner, chainDb ethdb.Database, gpo *GasPriceOracle, eventMux *event.TypeMux, am *accounts.Manager) *PublicBlockChainAPI { +func NewPublicBlockChainAPI(config *params.ChainConfig, bc *core.BlockChain, m *miner.Miner, chainDb ethdb.Database, gpo *GasPriceOracle, eventMux *event.TypeMux, am *accounts.Manager) *PublicBlockChainAPI { api := &PublicBlockChainAPI{ config: config, bc: bc, @@ -769,7 +776,7 @@ func (s *PublicBlockChainAPI) doCall(args CallArgs, blockNr rpc.BlockNumber) (st } // Execute the call and return - vmenv := core.NewEnv(stateDb, s.config, s.bc, msg, block.Header(), s.config.VmConfig) + vmenv := core.NewEnv(stateDb, s.config, s.bc, msg, block.Header(), vm.Config{}) gp := new(core.GasPool).AddGas(common.MaxBig) res, requiredGas, _, err := core.NewStateTransition(vmenv, msg, gp).TransitionDb() @@ -823,6 +830,9 @@ func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx if fullTx { formatTx = func(tx *types.Transaction) (interface{}, error) { + if tx.Protected() { + tx.SetSigner(types.NewEIP155Signer(s.bc.Config().ChainId)) + } return newRPCTransaction(b, tx.Hash()) } } @@ -1207,6 +1217,10 @@ func (s *PublicTransactionPoolAPI) SendTransaction(args SendTxArgs) (common.Hash tx = types.NewTransaction(args.Nonce.Uint64(), *args.To, args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), common.FromHex(args.Data)) } + if s.bc.Config().IsEIP155(s.bc.CurrentBlock().Number()) { + tx.SetSigner(types.NewEIP155Signer(s.bc.Config().ChainId)) + } + signature, err := s.am.Sign(args.From, tx.SigHash().Bytes()) if err != nil { return common.Hash{}, err @@ -1619,13 +1633,13 @@ func (api *PublicDebugAPI) SeedHash(number uint64) (string, error) { // PrivateDebugAPI is the collection of Etheruem APIs exposed over the private // debugging endpoint. type PrivateDebugAPI struct { - config *core.ChainConfig + config *params.ChainConfig eth *Ethereum } // NewPrivateDebugAPI creates a new API definition for the 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} } diff --git a/eth/backend.go b/eth/backend.go index 7176c2887..b967ba301 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -37,7 +37,6 @@ import ( "github.com/ethereum/go-ethereum/common/registrar/ethreg" "github.com/ethereum/go-ethereum/core" "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/filters" "github.com/ethereum/go-ethereum/ethdb" @@ -47,6 +46,7 @@ import ( "github.com/ethereum/go-ethereum/miner" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" ) @@ -65,7 +65,7 @@ var ( ) 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 Genesis string // Genesis JSON to seed the chain database with @@ -104,14 +104,13 @@ type Config struct { } type Ethereum struct { - chainConfig *core.ChainConfig + chainConfig *params.ChainConfig // Channel for shutting down the ethereum shutdownChan chan bool // DB interfaces chainDb ethdb.Database // Block chain database dappDb ethdb.Database // Dapp database - // Handlers txPool *core.TxPool txMu sync.Mutex @@ -253,10 +252,6 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { core.WriteChainConfig(chainDb, genesis.Hash(), 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()) if err != nil { diff --git a/eth/backend_test.go b/eth/backend_test.go index f5889dee9..4fe269047 100644 --- a/eth/backend_test.go +++ b/eth/backend_test.go @@ -25,6 +25,7 @@ import ( "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/params" ) func TestMipmapUpgrade(t *testing.T) { @@ -32,7 +33,7 @@ func TestMipmapUpgrade(t *testing.T) { addr := common.BytesToAddress([]byte("jeff")) 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 switch i { case 1: diff --git a/eth/downloader/downloader_test.go b/eth/downloader/downloader_test.go index 4f921f353..f3a9cb80c 100644 --- a/eth/downloader/downloader_test.go +++ b/eth/downloader/downloader_test.go @@ -55,7 +55,7 @@ func init() { // reassembly. func 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 - blocks, receipts := core.GenerateChain(nil, parent, testdb, n, func(i int, block *core.BlockGen) { + blocks, receipts := core.GenerateChain(params.TestChainConfig, parent, testdb, n, func(i int, block *core.BlockGen) { block.SetCoinbase(common.Address{seed}) // If a heavy chain is requested, delay blocks to raise difficulty diff --git a/eth/fetcher/fetcher_test.go b/eth/fetcher/fetcher_test.go index ad955a577..5d46c62fd 100644 --- a/eth/fetcher/fetcher_test.go +++ b/eth/fetcher/fetcher_test.go @@ -45,7 +45,7 @@ var ( // contains a transaction and every 5th an uncle to allow testing correct block // reassembly. 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}) // If the block number is multiple of 3, send a bonus transaction to the miner diff --git a/eth/filters/filter_test.go b/eth/filters/filter_test.go index 1afe78525..4be0d693d 100644 --- a/eth/filters/filter_test.go +++ b/eth/filters/filter_test.go @@ -28,6 +28,7 @@ import ( "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/params" ) func makeReceipt(addr common.Address) *types.Receipt { @@ -57,7 +58,7 @@ func BenchmarkMipmaps(b *testing.B) { defer db.Close() 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 switch i { case 2403: @@ -133,7 +134,7 @@ func TestFilters(t *testing.T) { defer db.Close() 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 switch i { case 1: diff --git a/eth/handler.go b/eth/handler.go index 187291655..343bcc684 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -37,6 +37,7 @@ import ( "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p/discover" + "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/pow" "github.com/ethereum/go-ethereum/rlp" ) @@ -67,7 +68,7 @@ type ProtocolManager struct { txpool txPool blockchain *core.BlockChain chaindb ethdb.Database - chainconfig *core.ChainConfig + chainconfig *params.ChainConfig downloader *downloader.Downloader fetcher *fetcher.Fetcher @@ -94,7 +95,7 @@ type ProtocolManager struct { // NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable // with the ethereum network. -func NewProtocolManager(config *core.ChainConfig, fastSync bool, networkId 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, mux *event.TypeMux, txpool txPool, pow pow.PoW, blockchain *core.BlockChain, chaindb ethdb.Database) (*ProtocolManager, error) { // Create the protocol manager with the base fields manager := &ProtocolManager{ networkId: networkId, diff --git a/eth/handler_test.go b/eth/handler_test.go index 571defd81..36e8cfe75 100644 --- a/eth/handler_test.go +++ b/eth/handler_test.go @@ -466,7 +466,7 @@ func testDAOChallenge(t *testing.T, localForked, remoteForked bool, timeout bool pow = new(core.FakePow) db, _ = ethdb.NewMemDatabase() 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) ) pm, err := NewProtocolManager(config, false, NetworkId, 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 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 { block.SetExtra(params.DAOForkBlockExtra) } diff --git a/eth/helper_test.go b/eth/helper_test.go index 732fe89ee..ec57902f2 100644 --- a/eth/helper_test.go +++ b/eth/helper_test.go @@ -35,6 +35,7 @@ import ( "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p/discover" + "github.com/ethereum/go-ethereum/params" ) var ( @@ -54,10 +55,10 @@ func newTestProtocolManager(fastSync bool, blocks int, generator func(int, *core pow = new(core.FakePow) db, _ = ethdb.NewMemDatabase() 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) ) - chain, _ := core.GenerateChain(nil, genesis, db, blocks, generator) + chain, _ := core.GenerateChain(chainConfig, genesis, db, blocks, generator) if _, err := blockchain.InsertChain(chain); err != nil { panic(err) } -- cgit v1.2.3