diff --git a/Godeps/_workspace/src/github.com/rcrowley/go-metrics/ewma.go b/Godeps/_workspace/src/github.com/rcrowley/go-metrics/ewma.go index 7c152a174a..694a1d0330 100644 --- a/Godeps/_workspace/src/github.com/rcrowley/go-metrics/ewma.go +++ b/Godeps/_workspace/src/github.com/rcrowley/go-metrics/ewma.go @@ -77,7 +77,7 @@ func (NilEWMA) Update(n int64) {} // of uncounted events and processes them on each tick. It uses the // sync/atomic package to manage uncounted events. type StandardEWMA struct { - uncounted int64 // /!\ this should be the first member to ensure 64-bit alignment + uncounted int64 // /!\ this should be the first member to ensure 64-bit alignment alpha float64 rate float64 init bool diff --git a/Godeps/_workspace/src/github.com/rcrowley/go-metrics/graphite_test.go b/Godeps/_workspace/src/github.com/rcrowley/go-metrics/graphite_test.go index b49dc4bb56..c797c781df 100644 --- a/Godeps/_workspace/src/github.com/rcrowley/go-metrics/graphite_test.go +++ b/Godeps/_workspace/src/github.com/rcrowley/go-metrics/graphite_test.go @@ -17,6 +17,6 @@ func ExampleGraphiteWithConfig() { Registry: DefaultRegistry, FlushInterval: 1 * time.Second, DurationUnit: time.Millisecond, - Percentiles: []float64{ 0.5, 0.75, 0.99, 0.999 }, + Percentiles: []float64{0.5, 0.75, 0.99, 0.999}, }) } diff --git a/Godeps/_workspace/src/github.com/rcrowley/go-metrics/opentsdb_test.go b/Godeps/_workspace/src/github.com/rcrowley/go-metrics/opentsdb_test.go index 6173d61ab7..c43728960e 100644 --- a/Godeps/_workspace/src/github.com/rcrowley/go-metrics/opentsdb_test.go +++ b/Godeps/_workspace/src/github.com/rcrowley/go-metrics/opentsdb_test.go @@ -19,4 +19,3 @@ func ExampleOpenTSDBWithConfig() { DurationUnit: time.Millisecond, }) } - diff --git a/Godeps/_workspace/src/github.com/robertkrimen/otto/dbg/dbg.go b/Godeps/_workspace/src/github.com/robertkrimen/otto/dbg/dbg.go index 83bf6c5734..8c27fa293e 100644 --- a/Godeps/_workspace/src/github.com/robertkrimen/otto/dbg/dbg.go +++ b/Godeps/_workspace/src/github.com/robertkrimen/otto/dbg/dbg.go @@ -282,7 +282,7 @@ func (self *Dbgr) getEmit() _emit { // SetOutput will accept the following as a destination for output: // // *log.Logger Print*/Panic*/Fatal* of the logger -// io.Writer - +// io.Writer - // nil Reset to the default output (os.Stderr) // "log" Print*/Panic*/Fatal* via the "log" package // diff --git a/Godeps/_workspace/src/github.com/robertkrimen/otto/underscore/source.go b/Godeps/_workspace/src/github.com/robertkrimen/otto/underscore/source.go index 65754ab715..7c5df97145 100644 --- a/Godeps/_workspace/src/github.com/robertkrimen/otto/underscore/source.go +++ b/Godeps/_workspace/src/github.com/robertkrimen/otto/underscore/source.go @@ -3456,6 +3456,7 @@ func underscore() []byte { 0x69, 0x73, 0x29, 0x3b, 0x0a, } } + // Underscore.js 1.4.4 // http://underscorejs.org // (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc. diff --git a/Godeps/_workspace/src/gopkg.in/check.v1/benchmark_test.go b/Godeps/_workspace/src/gopkg.in/check.v1/benchmark_test.go index 4dd827c160..0114c5b1ab 100644 --- a/Godeps/_workspace/src/gopkg.in/check.v1/benchmark_test.go +++ b/Godeps/_workspace/src/gopkg.in/check.v1/benchmark_test.go @@ -3,8 +3,8 @@ package check_test import ( - "time" . "gopkg.in/check.v1" + "time" ) var benchmarkS = Suite(&BenchmarkS{}) diff --git a/Godeps/_workspace/src/gopkg.in/check.v1/printer_test.go b/Godeps/_workspace/src/gopkg.in/check.v1/printer_test.go index 538b2d52e3..daa6a737ae 100644 --- a/Godeps/_workspace/src/gopkg.in/check.v1/printer_test.go +++ b/Godeps/_workspace/src/gopkg.in/check.v1/printer_test.go @@ -1,7 +1,7 @@ package check_test import ( - . "gopkg.in/check.v1" + . "gopkg.in/check.v1" ) var _ = Suite(&PrinterS{}) @@ -9,96 +9,101 @@ var _ = Suite(&PrinterS{}) type PrinterS struct{} func (s *PrinterS) TestCountSuite(c *C) { - suitesRun += 1 + suitesRun += 1 } var printTestFuncLine int func init() { - printTestFuncLine = getMyLine() + 3 + printTestFuncLine = getMyLine() + 3 } func printTestFunc() { - println(1) // Comment1 - if 2 == 2 { // Comment2 - println(3) // Comment3 - } - switch 5 { - case 6: println(6) // Comment6 - println(7) - } - switch interface{}(9).(type) {// Comment9 - case int: println(10) - println(11) - } - select { - case <-(chan bool)(nil): println(14) - println(15) - default: println(16) - println(17) - } - println(19, - 20) - _ = func() { println(21) - println(22) - } - println(24, func() { - println(25) - }) - // Leading comment - // with multiple lines. - println(29) // Comment29 + println(1) // Comment1 + if 2 == 2 { // Comment2 + println(3) // Comment3 + } + switch 5 { + case 6: + println(6) // Comment6 + println(7) + } + switch interface{}(9).(type) { // Comment9 + case int: + println(10) + println(11) + } + select { + case <-(chan bool)(nil): + println(14) + println(15) + default: + println(16) + println(17) + } + println(19, + 20) + _ = func() { + println(21) + println(22) + } + println(24, func() { + println(25) + }) + // Leading comment + // with multiple lines. + println(29) // Comment29 } var printLineTests = []struct { - line int - output string + line int + output string }{ - {1, "println(1) // Comment1"}, - {2, "if 2 == 2 { // Comment2\n ...\n}"}, - {3, "println(3) // Comment3"}, - {5, "switch 5 {\n...\n}"}, - {6, "case 6:\n println(6) // Comment6\n ..."}, - {7, "println(7)"}, - {9, "switch interface{}(9).(type) { // Comment9\n...\n}"}, - {10, "case int:\n println(10)\n ..."}, - {14, "case <-(chan bool)(nil):\n println(14)\n ..."}, - {15, "println(15)"}, - {16, "default:\n println(16)\n ..."}, - {17, "println(17)"}, - {19, "println(19,\n 20)"}, - {20, "println(19,\n 20)"}, - {21, "_ = func() {\n println(21)\n println(22)\n}"}, - {22, "println(22)"}, - {24, "println(24, func() {\n println(25)\n})"}, - {25, "println(25)"}, - {26, "println(24, func() {\n println(25)\n})"}, - {29, "// Leading comment\n// with multiple lines.\nprintln(29) // Comment29"}, + {1, "println(1) // Comment1"}, + {2, "if 2 == 2 { // Comment2\n ...\n}"}, + {3, "println(3) // Comment3"}, + {5, "switch 5 {\n...\n}"}, + {6, "case 6:\n println(6) // Comment6\n ..."}, + {7, "println(7)"}, + {9, "switch interface{}(9).(type) { // Comment9\n...\n}"}, + {10, "case int:\n println(10)\n ..."}, + {14, "case <-(chan bool)(nil):\n println(14)\n ..."}, + {15, "println(15)"}, + {16, "default:\n println(16)\n ..."}, + {17, "println(17)"}, + {19, "println(19,\n 20)"}, + {20, "println(19,\n 20)"}, + {21, "_ = func() {\n println(21)\n println(22)\n}"}, + {22, "println(22)"}, + {24, "println(24, func() {\n println(25)\n})"}, + {25, "println(25)"}, + {26, "println(24, func() {\n println(25)\n})"}, + {29, "// Leading comment\n// with multiple lines.\nprintln(29) // Comment29"}, } func (s *PrinterS) TestPrintLine(c *C) { - for _, test := range printLineTests { - output, err := PrintLine("printer_test.go", printTestFuncLine+test.line) - c.Assert(err, IsNil) - c.Assert(output, Equals, test.output) - } + for _, test := range printLineTests { + output, err := PrintLine("printer_test.go", printTestFuncLine+test.line) + c.Assert(err, IsNil) + c.Assert(output, Equals, test.output) + } } var indentTests = []struct { - in, out string + in, out string }{ - {"", ""}, - {"\n", "\n"}, - {"a", ">>>a"}, - {"a\n", ">>>a\n"}, - {"a\nb", ">>>a\n>>>b"}, - {" ", ">>> "}, + {"", ""}, + {"\n", "\n"}, + {"a", ">>>a"}, + {"a\n", ">>>a\n"}, + {"a\nb", ">>>a\n>>>b"}, + {" ", ">>> "}, } func (s *PrinterS) TestIndent(c *C) { - for _, test := range indentTests { - out := Indent(test.in, ">>>") - c.Assert(out, Equals, test.out) - } + for _, test := range indentTests { + out := Indent(test.in, ">>>") + c.Assert(out, Equals, test.out) + } } diff --git a/Godeps/_workspace/src/gopkg.in/check.v1/run_test.go b/Godeps/_workspace/src/gopkg.in/check.v1/run_test.go index f41fffc3f5..3ccb0eed75 100644 --- a/Godeps/_workspace/src/gopkg.in/check.v1/run_test.go +++ b/Godeps/_workspace/src/gopkg.in/check.v1/run_test.go @@ -400,7 +400,7 @@ func (s *RunS) TestStreamModeWithMiss(c *C) { // ----------------------------------------------------------------------- // Verify that that the keep work dir request indeed does so. -type WorkDirSuite struct {} +type WorkDirSuite struct{} func (s *WorkDirSuite) Test(c *C) { c.MkDir() @@ -411,7 +411,7 @@ func (s *RunS) TestKeepWorkDir(c *C) { runConf := RunConf{Output: &output, Verbose: true, KeepWorkDir: true} result := Run(&WorkDirSuite{}, &runConf) - c.Assert(result.String(), Matches, ".*\nWORK=" + result.WorkDir) + c.Assert(result.String(), Matches, ".*\nWORK="+result.WorkDir) stat, err := os.Stat(result.WorkDir) c.Assert(err, IsNil) diff --git a/ethdb/.gitignore b/access/.gitignore similarity index 100% rename from ethdb/.gitignore rename to access/.gitignore diff --git a/ethdb/README.md b/access/README.md similarity index 100% rename from ethdb/README.md rename to access/README.md diff --git a/core/access/context.go b/access/context.go similarity index 100% rename from core/access/context.go rename to access/context.go diff --git a/ethdb/database.go b/access/database.go similarity index 99% rename from ethdb/database.go rename to access/database.go index 047821c303..2d2b7d0e8a 100644 --- a/ethdb/database.go +++ b/access/database.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package ethdb +package access import ( "path/filepath" diff --git a/ethdb/database_test.go b/access/database_test.go similarity index 98% rename from ethdb/database_test.go rename to access/database_test.go index ae49061660..02c9425937 100644 --- a/ethdb/database_test.go +++ b/access/database_test.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package ethdb +package access import ( "os" diff --git a/ethdb/interface.go b/access/interface.go similarity index 98% rename from ethdb/interface.go rename to access/interface.go index f4b787a52a..069912cfc6 100644 --- a/ethdb/interface.go +++ b/access/interface.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package ethdb +package access type Database interface { Put(key []byte, value []byte) error diff --git a/ethdb/memory_database.go b/access/memory_database.go similarity index 99% rename from ethdb/memory_database.go rename to access/memory_database.go index 01273b9db3..b49bb6ad51 100644 --- a/ethdb/memory_database.go +++ b/access/memory_database.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package ethdb +package access import ( "errors" diff --git a/access/odr.go b/access/odr.go new file mode 100644 index 0000000000..cadc7c732f --- /dev/null +++ b/access/odr.go @@ -0,0 +1,84 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package access provides a layer to handle local blockchain database and +// on-demand network retrieval +package access + +import ( + "errors" + + "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/logger/glog" + "golang.org/x/net/context" +) + +var ( + errNoOdr = errors.New("ODR request is not possible") +) + +type OdrFunction func(req Request) error + +// ChainAccess provides access to blockchain and state data through local +// database and optionally also on-demand network retrieval +type ChainAccess struct { + db Database + odrFn OdrFunction +} + +// NewDbChainAccess creates a ChainAccess with ODR disabled +func NewDbChainAccess(db Database) *ChainAccess { + return NewChainAccess(db, nil) +} + +// NewChainAccess create a ChainAccess with optional ODR +func NewChainAccess(db Database, odr OdrFunction) *ChainAccess { + return &ChainAccess{ + db: db, + odrFn: odr, + } +} + +// Db returns the local database assigned to the ChainAccess object +func (self *ChainAccess) Db() Database { + return self.db +} + +// OdrEnabled returns true if this ChainAccess is capable of doing ODR requests +func (self *ChainAccess) OdrEnabled() bool { + return self.odrFn != nil +} + +type Request interface { + Ctx() context.Context + StoreResult(db Database) +} + +// Retrieve tries to fetch an object from the local db, then from the LES network. +// If the network retrieval was successful, it stores the object in local db. +func (self *ChainAccess) Retrieve(req Request) (err error) { + if !self.OdrEnabled() || !IsOdrContext(req.Ctx()) { + return errNoOdr + } + err = self.odrFn(req) + if err == nil { + // retrieved from network, store in db + req.StoreResult(self.Db()) + } else { + glog.V(logger.Info).Infof("ODR retrieve err = %v", err) + } + return +} diff --git a/cmd/evm/main.go b/cmd/evm/main.go index 2df3a4e8da..546b1144d6 100644 --- a/cmd/evm/main.go +++ b/cmd/evm/main.go @@ -25,14 +25,13 @@ import ( "time" "github.com/codegangsta/cli" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/access" "github.com/ethereum/go-ethereum/core/state" "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/logger/glog" ) @@ -113,7 +112,7 @@ func run(ctx *cli.Context) { glog.SetToStderr(true) glog.SetV(ctx.GlobalInt(VerbosityFlag.Name)) - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() statedb, _ := state.New(common.Hash{}, access.NewDbChainAccess(db)) sender := statedb.CreateAccount(common.StringToAddress("sender")) receiver := statedb.CreateAccount(common.StringToAddress("receiver")) diff --git a/cmd/geth/blocktestcmd.go b/cmd/geth/blocktestcmd.go index e4d97aa531..66770e30d9 100644 --- a/cmd/geth/blocktestcmd.go +++ b/cmd/geth/blocktestcmd.go @@ -21,9 +21,9 @@ import ( "os" "github.com/codegangsta/cli" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/eth" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/tests" ) @@ -101,8 +101,8 @@ func runBlockTest(ctx *cli.Context) { func runOneBlockTest(ctx *cli.Context, test *tests.BlockTest) (*eth.Ethereum, error) { cfg := utils.MakeEthConfig(ClientIdentifier, Version, ctx) - db, _ := ethdb.NewMemDatabase() - cfg.NewDB = func(path string) (ethdb.Database, error) { return db, nil } + db, _ := access.NewMemDatabase() + cfg.NewDB = func(path string) (access.Database, error) { return db, nil } cfg.MaxPeers = 0 // disable network cfg.Shh = false // disable whisper cfg.NAT = nil // disable port mapping diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go index ef5680960f..3757a6be37 100644 --- a/cmd/geth/chaincmd.go +++ b/cmd/geth/chaincmd.go @@ -24,13 +24,12 @@ import ( "time" "github.com/codegangsta/cli" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/access" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/logger/glog" ) @@ -197,7 +196,7 @@ func hashish(x string) bool { return err != nil } -func closeAll(dbs ...ethdb.Database) { +func closeAll(dbs ...access.Database) { for _, db := range dbs { db.Close() } diff --git a/cmd/geth/js_test.go b/cmd/geth/js_test.go index 4770797062..ad81051836 100644 --- a/cmd/geth/js_test.go +++ b/cmd/geth/js_test.go @@ -28,6 +28,7 @@ import ( "testing" "time" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/compiler" @@ -37,7 +38,6 @@ import ( "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/rpc/codec" "github.com/ethereum/go-ethereum/rpc/comms" ) @@ -90,7 +90,7 @@ func testREPL(t *testing.T, config func(*eth.Config)) (string, *testjethre, *eth t.Fatal(err) } - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() core.WriteGenesisBlockForTesting(db, core.GenesisAccount{common.HexToAddress(testAddress), common.String2Big(testBalance)}) ks := crypto.NewKeyStorePlain(filepath.Join(tmp, "keystore")) @@ -104,7 +104,7 @@ func testREPL(t *testing.T, config func(*eth.Config)) (string, *testjethre, *eth DocRoot: "/", SolcPath: testSolcPath, PowTest: true, - NewDB: func(path string) (ethdb.Database, error) { return db, nil }, + NewDB: func(path string) (access.Database, error) { return db, nil }, } if config != nil { config(conf) diff --git a/cmd/geth/main.go b/cmd/geth/main.go index a8434626f8..41954c12cd 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -30,14 +30,13 @@ import ( "github.com/codegangsta/cli" "github.com/ethereum/ethash" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/access" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/metrics" @@ -552,7 +551,7 @@ func blockRecovery(ctx *cli.Context) { cfg := utils.MakeEthConfig(ClientIdentifier, nodeNameVersion, ctx) utils.CheckLegalese(cfg.DataDir) - blockDb, err := ethdb.NewLDBDatabase(filepath.Join(cfg.DataDir, "blockchain"), cfg.DatabaseCache) + blockDb, err := access.NewLDBDatabase(filepath.Join(cfg.DataDir, "blockchain"), cfg.DatabaseCache) if err != nil { glog.Fatalln("could not open db:", err) } diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 22212df466..a3ca0c67fe 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -31,14 +31,13 @@ import ( "github.com/codegangsta/cli" "github.com/ethereum/ethash" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/access" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" @@ -535,12 +534,12 @@ func SetupVM(ctx *cli.Context) { } // MakeChain creates a chain manager from set command line flags. -func MakeChain(ctx *cli.Context) (chain *core.BlockChain, chainDb ethdb.Database) { +func MakeChain(ctx *cli.Context) (chain *core.BlockChain, chainDb access.Database) { datadir := MustDataDir(ctx) cache := ctx.GlobalInt(CacheFlag.Name) var err error - if chainDb, err = ethdb.NewLDBDatabase(filepath.Join(datadir, "chaindata"), cache); err != nil { + if chainDb, err = access.NewLDBDatabase(filepath.Join(datadir, "chaindata"), cache); err != nil { Fatalf("Could not open database: %v", err) } if ctx.GlobalBool(OlympicFlag.Name) { @@ -666,4 +665,4 @@ func ParamToAddress(addr string, am *accounts.Manager) (addrHex string, err erro addrHex = addr } return -} \ No newline at end of file +} diff --git a/common/natspec/natspec_e2e_test.go b/common/natspec/natspec_e2e_test.go index 5c0d43091c..e049e52cea 100644 --- a/common/natspec/natspec_e2e_test.go +++ b/common/natspec/natspec_e2e_test.go @@ -26,6 +26,7 @@ import ( "testing" "time" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/httpclient" @@ -33,7 +34,6 @@ import ( "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth" - "github.com/ethereum/go-ethereum/ethdb" xe "github.com/ethereum/go-ethereum/xeth" ) @@ -125,7 +125,7 @@ func testEth(t *testing.T) (ethereum *eth.Ethereum, err error) { if err != nil { t.Fatal(err) } - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() addr := common.HexToAddress(testAddress) core.WriteGenesisBlockForTesting(db, core.GenesisAccount{addr, common.String2Big(testBalance)}) ks := crypto.NewKeyStorePassphrase(filepath.Join(tmp, "keystore"), crypto.LightScryptN, crypto.LightScryptP) @@ -152,7 +152,7 @@ func testEth(t *testing.T) (ethereum *eth.Ethereum, err error) { Etherbase: common.HexToAddress(testAddress), MaxPeers: 0, PowTest: true, - NewDB: func(path string) (ethdb.Database, error) { return db, nil }, + NewDB: func(path string) (access.Database, error) { return db, nil }, GpoMinGasPrice: common.Big1, GpobaseCorrectionFactor: 1, GpoMaxGasPrice: common.Big1, diff --git a/core/access/chain_access.go b/core/access/chain_access.go deleted file mode 100644 index 515fc6f85b..0000000000 --- a/core/access/chain_access.go +++ /dev/null @@ -1,219 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// Package access provides a layer to handle local blockchain database and -// on-demand network retrieval -package access - -import ( - "errors" - "sync" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/logger" - "github.com/ethereum/go-ethereum/logger/glog" - "golang.org/x/net/context" -) - -var ( - errNotInDb = errors.New("object not found in database") -) - -const LogLevel = logger.Debug - -var ( - requestTimeout = time.Millisecond * 300 - retryPeers = time.Second * 1 -) - -// ChainAccess provides access to blockchain and state data through local -// database and optionally also on-demand network retrieval -type ChainAccess struct { - db ethdb.Database - odr bool // light client mode, odr enabled - lock sync.Mutex - sentReqs map[uint64]*sentReq - sentReqCnt uint64 - peers *peerSet -} - -// requestFunc is a function that requests some data from a peer -type requestFunc func(*Peer) error - -// validatorFunc is a function that processes a message and returns true if -// it was a meaningful answer to a given request -type validatorFunc func(*Msg) bool - -// sentReq is a request waiting for an answer that satisfies its valFunc -type sentReq struct { - valFunc validatorFunc - deliverChan chan *Msg -} - -// NewDbChainAccess creates a ChainAccess with ODR disabled -func NewDbChainAccess(db ethdb.Database) *ChainAccess { - return NewChainAccess(db, false) -} - -// NewChainAccess create a ChainAccess with optional ODR -func NewChainAccess(db ethdb.Database, odr bool) *ChainAccess { - return &ChainAccess{ - db: db, - peers: newPeerSet(), - sentReqs: make(map[uint64]*sentReq), - odr: odr, - } -} - -// Db returns the local database assigned to the ChainAccess object -func (self *ChainAccess) Db() ethdb.Database { - return self.db -} - -// OdrEnabled returns true if this ChainAccess is capable of doing ODR requests -func (self *ChainAccess) OdrEnabled() bool { - return self.odr -} - -// RegisterPeer registers a new LES peer to the ODR capable peer set -func (self *ChainAccess) RegisterPeer(id string, version int, head common.Hash, getBlockBodies getBlockBodiesFn, getNodeData getNodeDataFn, getReceipts getReceiptsFn, getProofs getProofsFn) error { - glog.V(logger.Detail).Infoln("Registering peer", id) - if err := self.peers.Register(newPeer(id, version, head, getBlockBodies, getNodeData, getReceipts, getProofs)); err != nil { - glog.V(logger.Error).Infoln("Register failed:", err) - return err - } - return nil -} - -// UnregisterPeer removes a peer from the ODR capable peer set -func (self *ChainAccess) UnregisterPeer(id string) { - self.peers.Unregister(id) -} - -const ( - MsgBlockBodies = iota - MsgNodeData - MsgReceipts - MsgProofs -) - -// Msg encodes a LES message that delivers reply data for a request -type Msg struct { - MsgType int - Obj interface{} -} - -// ObjectAccess is the ODR request interface (passed to Retrieve, functions called by Retrieve and Deliver) -// DbGet() tries to retrieve the object from the local database (object is stored by the request struct in memory if retrieved) -// DbPut() stores it in the local database -// Request(*Peer) requests it from a LES peer -// Valid(*Msg) checks if a message is a valid answer to this request and stores the retrieved object in memory -type ObjectAccess interface { - // database storage - DbGet() bool - DbPut() - // network retrieval - Request(*Peer) error - Valid(*Msg) bool // if true, keeps the retrieved object -} - -// Deliver is called by the LES protocol manager to deliver ODR reply messages to waiting requests -func (self *ChainAccess) Deliver(id string, msg *Msg) (processed bool) { - self.lock.Lock() - defer self.lock.Unlock() - - for i, req := range self.sentReqs { - if req.valFunc(msg) { - req.deliverChan <- msg - delete(self.sentReqs, i) - return true - } - } - return false -} - -// networkRequest sends a request to known peers until an answer is received -// or the context is cancelled -func (self *ChainAccess) networkRequest(ctx context.Context, rqFunc requestFunc, valFunc validatorFunc) (*Msg, error) { - req := &sentReq{ - deliverChan: make(chan *Msg), - valFunc: valFunc, - } - self.lock.Lock() - reqCnt := self.sentReqCnt - self.sentReqCnt++ - self.sentReqs[reqCnt] = req - self.lock.Unlock() - - defer func() { - self.lock.Lock() - delete(self.sentReqs, reqCnt) - self.lock.Unlock() - }() - - var msg *Msg - - for { - peers := self.peers.BestPeers() - if len(peers) == 0 { - select { - case <-ctx.Done(): - setTerminated(ctx) - return nil, ctx.Err() - case <-time.After(retryPeers): - } - } - for _, peer := range peers { - rqFunc(peer) - select { - case <-ctx.Done(): - setTerminated(ctx) - return nil, ctx.Err() - case msg = <-req.deliverChan: - peer.Promote() - glog.V(LogLevel).Infof("networkRequest success") - return msg, nil - case <-time.After(requestTimeout): - peer.Demote() - glog.V(LogLevel).Infof("networkRequest timeout") - } - } - } -} - -// Retrieve tries to fetch an object from the local db, then from the LES network. -// If the network retrieval was successful, it stores the object in local db. -func (self *ChainAccess) Retrieve(ctx context.Context, obj ObjectAccess) (err error) { - // look in db - if obj.DbGet() { - return nil - } - if IsOdrContext(ctx) { - // not found in db, trying the network - _, err = self.networkRequest(ctx, obj.Request, obj.Valid) - if err == nil { - // retrieved from network, store in db - obj.DbPut() - } else { - glog.V(LogLevel).Infof("networkRequest err = %v", err) - } - return - } else { - return errNotInDb - } -} diff --git a/core/access/peer.go b/core/access/peer.go deleted file mode 100644 index 2d6e979291..0000000000 --- a/core/access/peer.go +++ /dev/null @@ -1,181 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// Package access provides a layer to handle local blockchain database and -// on-demand network retrieval -package access - -import ( - "errors" - "sync" - "sync/atomic" - - "github.com/ethereum/go-ethereum/common" -) - -var ( - errAlreadyRegistered = errors.New("peer is already registered") - errNotRegistered = errors.New("peer is not registered") - errNoOdr = errors.New("peer cannot serve on-demand requests") -) - -type ProofReq struct { - Root common.Hash - Key []byte -} - -type getBlockBodiesFn func([]common.Hash) error -type getNodeDataFn func([]common.Hash) error -type getReceiptsFn func([]common.Hash) error -type getProofsFn func([]*ProofReq) error - -// Peer stores ODR-specific information about LES peers that are able to serve requests -type Peer struct { - id string // Unique identifier of the peer - head common.Hash // Hash of the peers latest known block - - rep int32 // Simple peer reputation - - GetBlockBodies getBlockBodiesFn - GetNodeData getNodeDataFn - GetReceipts getReceiptsFn - GetProofs getProofsFn - - version int // LES protocol version number -} - -// newPeer creates a new ODR peer -func newPeer(id string, version int, head common.Hash, getBlockBodies getBlockBodiesFn, getNodeData getNodeDataFn, getReceipts getReceiptsFn, getProofs getProofsFn) *Peer { - return &Peer{ - id: id, - head: head, - GetBlockBodies: getBlockBodies, - GetNodeData: getNodeData, - GetReceipts: getReceipts, - GetProofs: getProofs, - version: version, - } -} - -// Id returns a peer's ID string -func (p *Peer) Id() string { - return p.id -} - - -// Promote increases the peer's reputation -func (p *Peer) Promote() { - atomic.AddInt32(&p.rep, 1) -} - -// Demote decreases the peer's reputation or leaves it at 0. -func (p *Peer) Demote() { - for { - // Calculate the new reputation value - prev := atomic.LoadInt32(&p.rep) - next := prev / 2 - - // Try to update the old value - if atomic.CompareAndSwapInt32(&p.rep, prev, next) { - return - } - } -} - -// peerSet represents the collection of active peer participating in the block -// download procedure. -type peerSet struct { - peers map[string]*Peer - lock sync.RWMutex -} - -// newPeerSet creates a new peer set top track the active download sources. -func newPeerSet() *peerSet { - return &peerSet{ - peers: make(map[string]*Peer), - } -} - -// Register injects a new peer into the working set, or returns an error if the -// peer is already known. -func (ps *peerSet) Register(p *Peer) error { - ps.lock.Lock() - defer ps.lock.Unlock() - - if _, ok := ps.peers[p.id]; ok { - return errAlreadyRegistered - } - ps.peers[p.id] = p - return nil -} - -// Unregister removes a remote peer from the active set, disabling any further -// actions to/from that particular entity. -func (ps *peerSet) Unregister(id string) error { - ps.lock.Lock() - defer ps.lock.Unlock() - - if _, ok := ps.peers[id]; !ok { - return errNotRegistered - } - delete(ps.peers, id) - return nil -} - -// Peer retrieves the registered peer with the given id. -func (ps *peerSet) Peer(id string) *Peer { - ps.lock.RLock() - defer ps.lock.RUnlock() - - return ps.peers[id] -} - -// Len returns if the current number of peers in the set. -func (ps *peerSet) Len() int { - ps.lock.RLock() - defer ps.lock.RUnlock() - - return len(ps.peers) -} - -// AllPeers retrieves a flat list of all the peers within the set. -func (ps *peerSet) AllPeers() []*Peer { - ps.lock.RLock() - defer ps.lock.RUnlock() - - list := make([]*Peer, 0, len(ps.peers)) - for _, p := range ps.peers { - list = append(list, p) - } - return list -} - -// BestPeers returns an ordered list of available peers, starting with the -// highest reputation -func (ps *peerSet) BestPeers() []*Peer { - list := ps.AllPeers() - ps.lock.RLock() - defer ps.lock.RUnlock() - - for i := 0; i < len(list); i++ { - for j := i + 1; j < len(list); j++ { - if atomic.LoadInt32(&list[i].rep) < atomic.LoadInt32(&list[j].rep) { - list[i], list[j] = list[j], list[i] - } - } - } - return list -} diff --git a/core/bench_test.go b/core/bench_test.go index 704e6a0ad4..1964d3571a 100644 --- a/core/bench_test.go +++ b/core/bench_test.go @@ -23,11 +23,10 @@ import ( "os" "testing" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/access" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/params" ) @@ -145,16 +144,16 @@ func genUncles(i int, gen *BlockGen) { func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) { // Create the database in memory or in a temporary directory. - var db ethdb.Database + var db access.Database if !disk { - db, _ = ethdb.NewMemDatabase() + db, _ = access.NewMemDatabase() } else { dir, err := ioutil.TempDir("", "eth-core-bench") if err != nil { b.Fatalf("cannot create temporary directory: %v", err) } defer os.RemoveAll(dir) - db, err = ethdb.NewLDBDatabase(dir, 0) + db, err = access.NewLDBDatabase(dir, 0) if err != nil { b.Fatalf("cannot create temporary database: %v", err) } diff --git a/core/block_processor.go b/core/block_processor.go index 1511eaf89b..f42064f297 100644 --- a/core/block_processor.go +++ b/core/block_processor.go @@ -22,8 +22,8 @@ import ( "sync" "time" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/access" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" @@ -88,10 +88,10 @@ func (gp *GasPool) String() string { func NewBlockProcessor(ca *access.ChainAccess, pow pow.PoW, blockchain *BlockChain, eventMux *event.TypeMux) *BlockProcessor { sm := &BlockProcessor{ chainAccess: ca, - mem: make(map[string]*big.Int), - Pow: pow, - bc: blockchain, - eventMux: eventMux, + mem: make(map[string]*big.Int), + Pow: pow, + bc: blockchain, + eventMux: eventMux, } return sm } diff --git a/core/block_processor_test.go b/core/block_processor_test.go index a5f6527785..4d18c81a42 100644 --- a/core/block_processor_test.go +++ b/core/block_processor_test.go @@ -21,18 +21,17 @@ import ( "math/big" "testing" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/access" "github.com/ethereum/go-ethereum/core/state" "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/event" "github.com/ethereum/go-ethereum/pow/ezp" ) func proc() (*BlockProcessor, *BlockChain) { - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() ca := access.NewDbChainAccess(db) var mux event.TypeMux @@ -64,7 +63,7 @@ func TestNumber(t *testing.T) { } func TestPutReceipt(t *testing.T) { - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() var addr common.Address addr[0] = 1 diff --git a/core/blockchain.go b/core/blockchain.go index 4484a6d73b..a23e4f41be 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -30,12 +30,11 @@ import ( "sync/atomic" "time" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/access" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" @@ -67,7 +66,7 @@ const ( type BlockChain struct { chainAccess *access.ChainAccess - chainDb ethdb.Database + chainDb access.Database processor types.BlockProcessor eventMux *event.TypeMux genesisBlock *types.Block @@ -1303,4 +1302,4 @@ func blockErr(block *types.Block, err error) { glog.Errorf("Bad block #%v (%s)\n", block.Number(), block.Hash().Hex()) glog.Errorf(" %v", err) } -} \ No newline at end of file +} diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 523b7bcd28..e68a946ac3 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -27,12 +27,11 @@ import ( "testing" "github.com/ethereum/ethash" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/access" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/pow" @@ -49,7 +48,7 @@ func thePow() pow.PoW { return pow } -func theBlockChain(db ethdb.Database, t *testing.T) *BlockChain { +func theBlockChain(db access.Database, t *testing.T) *BlockChain { var eventMux event.TypeMux WriteTestNetGenesisBlock(db, 0) ca := access.NewDbChainAccess(db) @@ -189,7 +188,7 @@ func insertChain(done chan bool, blockchain *BlockChain, chain types.Blocks, t * } func TestLastBlock(t *testing.T) { - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() bchain := theBlockChain(db, t) block := makeBlockChain(bchain.CurrentBlock(), 1, db, 0)[0] @@ -336,7 +335,7 @@ func testBrokenChain(t *testing.T, full bool) { func TestChainInsertions(t *testing.T) { t.Skip("Skipped: outdated test files") - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() chain1, err := loadChain("valid1", t) if err != nil { @@ -374,7 +373,7 @@ func TestChainInsertions(t *testing.T) { func TestChainMultipleInsertions(t *testing.T) { t.Skip("Skipped: outdated test files") - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() const max = 4 chains := make([]types.Blocks, max) @@ -452,7 +451,7 @@ func makeBlockChainWithDiff(genesis *types.Block, d []int, seed byte) []*types.B return chain } -func chm(genesis *types.Block, db ethdb.Database) *BlockChain { +func chm(genesis *types.Block, db access.Database) *BlockChain { var eventMux event.TypeMux ca := access.NewDbChainAccess(db) bc := &BlockChain{chainAccess: ca, chainDb: db, genesisBlock: genesis, eventMux: &eventMux, pow: FakePow{}, rand: rand.New(rand.NewSource(0))} @@ -488,7 +487,7 @@ func testReorgShort(t *testing.T, full bool) { func testReorg(t *testing.T, first, second []int, td int64, full bool) { // Create a pristine block chain - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() genesis, _ := WriteTestNetGenesisBlock(db, 0) bc := chm(genesis, db) @@ -503,7 +502,7 @@ func testReorg(t *testing.T, first, second []int, td int64, full bool) { // Check that the chain is valid number and link wise if full { prev := bc.CurrentBlock() - for block := bc.GetBlockByNumber(bc.CurrentBlock().NumberU64()-1); block.NumberU64() != 0; prev, block = block, bc.GetBlockByNumber(block.NumberU64()-1) { + for block := bc.GetBlockByNumber(bc.CurrentBlock().NumberU64() - 1); block.NumberU64() != 0; prev, block = block, bc.GetBlockByNumber(block.NumberU64()-1) { if prev.ParentHash() != block.Hash() { t.Errorf("parent block hash mismatch: have %x, want %x", prev.ParentHash(), block.Hash()) } @@ -535,7 +534,7 @@ func TestBadBlockHashes(t *testing.T) { testBadHashes(t, true) } func testBadHashes(t *testing.T, full bool) { // Create a pristine block chain - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() genesis, _ := WriteTestNetGenesisBlock(db, 0) bc := chm(genesis, db) @@ -562,7 +561,7 @@ func TestReorgBadBlockHashes(t *testing.T) { testReorgBadHashes(t, true) } func testReorgBadHashes(t *testing.T, full bool) { // Create a pristine block chain - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() genesis, _ := WriteTestNetGenesisBlock(db, 0) bc := chm(genesis, db) @@ -668,7 +667,7 @@ func testInsertNonceError(t *testing.T, full bool) { // Check that all no blocks after the failing block have been inserted. for j := 0; j < i-failAt; j++ { if full { - if block := bc.GetBlockByNumber(failNum+uint64(j)); block != nil { + if block := bc.GetBlockByNumber(failNum + uint64(j)); block != nil { t.Errorf("test %d: invalid block in chain: %v", i, block) } } else { @@ -685,7 +684,7 @@ func testInsertNonceError(t *testing.T, full bool) { func TestFastVsFullChains(t *testing.T) { // Configure and generate a sample block chain var ( - gendb, _ = ethdb.NewMemDatabase() + gendb, _ = access.NewMemDatabase() key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") address = crypto.PubkeyToAddress(key.PublicKey) funds = big.NewInt(1000000000) @@ -710,7 +709,7 @@ func TestFastVsFullChains(t *testing.T) { } }) // Import the chain as an archive node for the comparison baseline - archiveDb, _ := ethdb.NewMemDatabase() + archiveDb, _ := access.NewMemDatabase() archiveCa := access.NewDbChainAccess(archiveDb) WriteGenesisBlockForTesting(archiveDb, GenesisAccount{address, funds}) @@ -721,7 +720,7 @@ func TestFastVsFullChains(t *testing.T) { t.Fatalf("failed to process block %d: %v", n, err) } // Fast import the chain as a non-archive node to test - fastDb, _ := ethdb.NewMemDatabase() + fastDb, _ := access.NewMemDatabase() fastCa := access.NewDbChainAccess(fastDb) WriteGenesisBlockForTesting(fastDb, GenesisAccount{address, funds}) fast, _ := NewBlockChain(fastCa, FakePow{}, new(event.TypeMux)) @@ -771,7 +770,7 @@ func TestFastVsFullChains(t *testing.T) { func TestLightVsFastVsFullChainHeads(t *testing.T) { // Configure and generate a sample block chain var ( - gendb, _ = ethdb.NewMemDatabase() + gendb, _ = access.NewMemDatabase() key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") address = crypto.PubkeyToAddress(key.PublicKey) funds = big.NewInt(1000000000) @@ -798,7 +797,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) { } } // Import the chain as an archive node and ensure all pointers are updated - archiveDb, _ := ethdb.NewMemDatabase() + archiveDb, _ := access.NewMemDatabase() archiveCa := access.NewDbChainAccess(archiveDb) WriteGenesisBlockForTesting(archiveDb, GenesisAccount{address, funds}) archive, _ := NewBlockChain(archiveCa, FakePow{}, new(event.TypeMux)) @@ -812,7 +811,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) { assert(t, "archive", archive, height/2, height/2, height/2) // Import the chain as a non-archive node and ensure all pointers are updated - fastDb, _ := ethdb.NewMemDatabase() + fastDb, _ := access.NewMemDatabase() fastCa := access.NewDbChainAccess(fastDb) WriteGenesisBlockForTesting(fastDb, GenesisAccount{address, funds}) fast, _ := NewBlockChain(fastCa, FakePow{}, new(event.TypeMux)) @@ -833,7 +832,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) { assert(t, "fast", fast, height/2, height/2, 0) // Import the chain as a light node and ensure all pointers are updated - lightDb, _ := ethdb.NewMemDatabase() + lightDb, _ := access.NewMemDatabase() lightCa := access.NewDbChainAccess(lightDb) WriteGenesisBlockForTesting(lightDb, GenesisAccount{address, funds}) light, _ := NewBlockChain(lightCa, FakePow{}, new(event.TypeMux)) @@ -859,7 +858,7 @@ func TestChainTxReorgs(t *testing.T) { addr1 = crypto.PubkeyToAddress(key1.PublicKey) addr2 = crypto.PubkeyToAddress(key2.PublicKey) addr3 = crypto.PubkeyToAddress(key3.PublicKey) - db, _ = ethdb.NewMemDatabase() + db, _ = access.NewMemDatabase() ) genesis := WriteGenesisBlockForTesting(db, GenesisAccount{addr1, big.NewInt(1000000)}, diff --git a/core/chain_makers.go b/core/chain_makers.go index e6f69541f9..104ab1a584 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -20,11 +20,10 @@ import ( "fmt" "math/big" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/access" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/pow" ) @@ -164,7 +163,7 @@ func (b *BlockGen) OffsetTime(seconds int64) { // Blocks created by GenerateChain do not contain valid proof of work // values. Inserting them into BlockChain requires use of FakePow or // a similar non-validating proof of work implementation. -func GenerateChain(parent *types.Block, db ethdb.Database, n int, gen func(int, *BlockGen)) ([]*types.Block, []types.Receipts) { +func GenerateChain(parent *types.Block, db access.Database, n int, gen func(int, *BlockGen)) ([]*types.Block, []types.Receipts) { statedb, err := state.New(parent.Root(), access.NewDbChainAccess(db)) if err != nil { panic(err) @@ -215,9 +214,9 @@ func makeHeader(parent *types.Block, state *state.StateDB) *types.Header { // newCanonical creates a chain database, and injects a deterministic canonical // chain. Depending on the full flag, if creates either a full block chain or a // header only chain. -func newCanonical(n int, full bool) (ethdb.Database, *BlockProcessor, error) { +func newCanonical(n int, full bool) (access.Database, *BlockProcessor, error) { // Create te new chain database - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() evmux := &event.TypeMux{} // Initialize a fresh chain with only a genesis block @@ -245,7 +244,7 @@ func newCanonical(n int, full bool) (ethdb.Database, *BlockProcessor, error) { } // 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 access.Database, seed int) []*types.Header { blocks := makeBlockChain(types.NewBlockWithHeader(parent), n, db, seed) headers := make([]*types.Header, len(blocks)) for i, block := range blocks { @@ -255,7 +254,7 @@ func makeHeaderChain(parent *types.Header, n int, db ethdb.Database, seed int) [ } // 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 access.Database, seed int) []*types.Block { blocks, _ := GenerateChain(parent, db, n, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{0: byte(seed), 19: byte(i)}) }) diff --git a/core/chain_makers_test.go b/core/chain_makers_test.go index 6e87dd0ff0..868e0502ba 100644 --- a/core/chain_makers_test.go +++ b/core/chain_makers_test.go @@ -20,10 +20,9 @@ import ( "fmt" "math/big" - "github.com/ethereum/go-ethereum/core/access" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/params" ) @@ -39,7 +38,7 @@ func ExampleGenerateChain() { addr1 = crypto.PubkeyToAddress(key1.PublicKey) addr2 = crypto.PubkeyToAddress(key2.PublicKey) addr3 = crypto.PubkeyToAddress(key3.PublicKey) - db, _ = ethdb.NewMemDatabase() + db, _ = access.NewMemDatabase() ) // Ensure that key1 has some funds in the genesis block. diff --git a/core/chain_pow_test.go b/core/chain_pow_test.go index d2b0bd1443..1d5c786719 100644 --- a/core/chain_pow_test.go +++ b/core/chain_pow_test.go @@ -22,9 +22,9 @@ import ( "testing" "time" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/pow" ) @@ -58,7 +58,7 @@ func (pow delayedPow) Turbo(bool) {} func TestPowVerification(t *testing.T) { // Create a simple chain to verify var ( - testdb, _ = ethdb.NewMemDatabase() + testdb, _ = access.NewMemDatabase() genesis = GenesisBlockForTesting(testdb, common.Address{}, new(big.Int)) blocks, _ = GenerateChain(genesis, testdb, 8, nil) ) @@ -113,7 +113,7 @@ func TestPowConcurrentVerification32(t *testing.T) { testPowConcurrentVerificati func testPowConcurrentVerification(t *testing.T, threads int) { // Create a simple chain to verify var ( - testdb, _ = ethdb.NewMemDatabase() + testdb, _ = access.NewMemDatabase() genesis = GenesisBlockForTesting(testdb, common.Address{}, new(big.Int)) blocks, _ = GenerateChain(genesis, testdb, 8, nil) ) @@ -184,7 +184,7 @@ func TestPowConcurrentAbortion32(t *testing.T) { testPowConcurrentAbortion(t, 32 func testPowConcurrentAbortion(t *testing.T, threads int) { // Create a simple chain to verify var ( - testdb, _ = ethdb.NewMemDatabase() + testdb, _ = access.NewMemDatabase() genesis = GenesisBlockForTesting(testdb, common.Address{}, new(big.Int)) blocks, _ = GenerateChain(genesis, testdb, 1024, nil) ) diff --git a/core/chain_util.go b/core/chain_util.go index 439d882e5f..d477e19046 100644 --- a/core/chain_util.go +++ b/core/chain_util.go @@ -22,11 +22,9 @@ import ( "fmt" "math/big" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/access" - "github.com/ethereum/go-ethereum/core/requests" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/params" @@ -121,7 +119,7 @@ func CalcGasLimit(parent *types.Block) *big.Int { } // GetCanonicalHash retrieves a hash assigned to a canonical block number. -func GetCanonicalHash(db ethdb.Database, number uint64) common.Hash { +func GetCanonicalHash(db access.Database, number uint64) common.Hash { data, _ := db.Get(append(blockNumPrefix, big.NewInt(int64(number)).Bytes()...)) if len(data) == 0 { return common.Hash{} @@ -134,7 +132,7 @@ func GetCanonicalHash(db ethdb.Database, number uint64) common.Hash { // last block hash is only updated upon a full block import, the last header // hash is updated already at header import, allowing head tracking for the // light synchronization mechanism. -func GetHeadHeaderHash(db ethdb.Database) common.Hash { +func GetHeadHeaderHash(db access.Database) common.Hash { data, _ := db.Get(headHeaderKey) if len(data) == 0 { return common.Hash{} @@ -143,7 +141,7 @@ func GetHeadHeaderHash(db ethdb.Database) common.Hash { } // GetHeadBlockHash retrieves the hash of the current canonical head block. -func GetHeadBlockHash(db ethdb.Database) common.Hash { +func GetHeadBlockHash(db access.Database) common.Hash { data, _ := db.Get(headBlockKey) if len(data) == 0 { return common.Hash{} @@ -155,7 +153,7 @@ func GetHeadBlockHash(db ethdb.Database) common.Hash { // fast synchronization. The difference between this and GetHeadBlockHash is that // whereas the last block hash is only updated upon a full block import, the last // fast hash is updated when importing pre-processed blocks. -func GetHeadFastBlockHash(db ethdb.Database) common.Hash { +func GetHeadFastBlockHash(db access.Database) common.Hash { data, _ := db.Get(headFastKey) if len(data) == 0 { return common.Hash{} @@ -165,14 +163,14 @@ func GetHeadFastBlockHash(db ethdb.Database) common.Hash { // GetHeaderRLP retrieves a block header in its raw RLP database encoding, or nil // if the header's not found. -func GetHeaderRLP(db ethdb.Database, hash common.Hash) rlp.RawValue { +func GetHeaderRLP(db access.Database, hash common.Hash) rlp.RawValue { data, _ := db.Get(append(append(blockPrefix, hash[:]...), headerSuffix...)) return data } // GetHeader retrieves the block header corresponding to the hash, nil if none // found. -func GetHeader(db ethdb.Database, hash common.Hash) *types.Header { +func GetHeader(db access.Database, hash common.Hash) *types.Header { data := GetHeaderRLP(db, hash) if len(data) == 0 { return nil @@ -188,15 +186,19 @@ func GetHeader(db ethdb.Database, hash common.Hash) *types.Header { // GetBodyRLP retrieves the block body (transactions and uncles) from the // database in RLP encoding. func GetBodyRLP(ca *access.ChainAccess, hash common.Hash) rlp.RawValue { - return GetBodyRLPOdr(access.NoOdr, ca, hash) + data, _ := ca.Db().Get(append(append(blockPrefix, hash[:]...), bodySuffix...)) + return data } // GetBodyRLPOdr retrieves the block body (transactions and uncles) from the // database or network in RLP encoding. func GetBodyRLPOdr(ctx context.Context, ca *access.ChainAccess, hash common.Hash) rlp.RawValue { - //fmt.Println("request block %v", hash) - r := requests.NewBlockAccess(ca.Db(), hash, GetHeader) - ca.Retrieve(ctx, r) + res := GetBodyRLP(ca, hash) + if res != nil || !access.IsOdrContext(ctx) { + return res + } + r := &BlockRequest{ctx: ctx, blockHash: hash} + ca.Retrieve(r) return r.GetRlp() } @@ -223,7 +225,7 @@ func GetBodyOdr(ctx context.Context, ca *access.ChainAccess, hash common.Hash) * // GetTd retrieves a block's total difficulty corresponding to the hash, nil if // none found. -func GetTd(db ethdb.Database, hash common.Hash) *big.Int { +func GetTd(db access.Database, hash common.Hash) *big.Int { data, _ := db.Get(append(append(blockPrefix, hash.Bytes()...), tdSuffix...)) if len(data) == 0 { return nil @@ -259,7 +261,7 @@ func GetBlockOdr(ctx context.Context, ca *access.ChainAccess, hash common.Hash) } // WriteCanonicalHash stores the canonical hash for the given block number. -func WriteCanonicalHash(db ethdb.Database, hash common.Hash, number uint64) error { +func WriteCanonicalHash(db access.Database, hash common.Hash, number uint64) error { key := append(blockNumPrefix, big.NewInt(int64(number)).Bytes()...) if err := db.Put(key, hash.Bytes()); err != nil { glog.Fatalf("failed to store number to hash mapping into database: %v", err) @@ -269,7 +271,7 @@ func WriteCanonicalHash(db ethdb.Database, hash common.Hash, number uint64) erro } // WriteHeadHeaderHash stores the head header's hash. -func WriteHeadHeaderHash(db ethdb.Database, hash common.Hash) error { +func WriteHeadHeaderHash(db access.Database, hash common.Hash) error { if err := db.Put(headHeaderKey, hash.Bytes()); err != nil { glog.Fatalf("failed to store last header's hash into database: %v", err) return err @@ -278,7 +280,7 @@ func WriteHeadHeaderHash(db ethdb.Database, hash common.Hash) error { } // WriteHeadBlockHash stores the head block's hash. -func WriteHeadBlockHash(db ethdb.Database, hash common.Hash) error { +func WriteHeadBlockHash(db access.Database, hash common.Hash) error { if err := db.Put(headBlockKey, hash.Bytes()); err != nil { glog.Fatalf("failed to store last block's hash into database: %v", err) return err @@ -287,7 +289,7 @@ func WriteHeadBlockHash(db ethdb.Database, hash common.Hash) error { } // WriteHeadFastBlockHash stores the fast head block's hash. -func WriteHeadFastBlockHash(db ethdb.Database, hash common.Hash) error { +func WriteHeadFastBlockHash(db access.Database, hash common.Hash) error { if err := db.Put(headFastKey, hash.Bytes()); err != nil { glog.Fatalf("failed to store last fast block's hash into database: %v", err) return err @@ -296,7 +298,7 @@ func WriteHeadFastBlockHash(db ethdb.Database, hash common.Hash) error { } // WriteHeader serializes a block header into the database. -func WriteHeader(db ethdb.Database, header *types.Header) error { +func WriteHeader(db access.Database, header *types.Header) error { data, err := rlp.EncodeToBytes(header) if err != nil { return err @@ -310,12 +312,8 @@ func WriteHeader(db ethdb.Database, header *types.Header) error { return nil } -// WriteBody serializes the body of a block into the database. -func WriteBody(db ethdb.Database, hash common.Hash, body *types.Body) error { - data, err := rlp.EncodeToBytes(body) - if err != nil { - return err - } +// WriteBodyRlp stores the serialized body of a block into the database. +func WriteBodyRlp(db access.Database, hash common.Hash, data []byte) error { key := append(append(blockPrefix, hash.Bytes()...), bodySuffix...) if err := db.Put(key, data); err != nil { glog.Fatalf("failed to store block body into database: %v", err) @@ -325,8 +323,17 @@ func WriteBody(db ethdb.Database, hash common.Hash, body *types.Body) error { return nil } +// WriteBody serializes the body of a block into the database. +func WriteBody(db access.Database, hash common.Hash, body *types.Body) error { + data, err := rlp.EncodeToBytes(body) + if err != nil { + return err + } + return WriteBodyRlp(db, hash, data) +} + // WriteTd serializes the total difficulty of a block into the database. -func WriteTd(db ethdb.Database, hash common.Hash, td *big.Int) error { +func WriteTd(db access.Database, hash common.Hash, td *big.Int) error { data, err := rlp.EncodeToBytes(td) if err != nil { return err @@ -341,7 +348,7 @@ func WriteTd(db ethdb.Database, hash common.Hash, td *big.Int) error { } // WriteBlock serializes a block into the database, header and body separately. -func WriteBlock(db ethdb.Database, block *types.Block) error { +func WriteBlock(db access.Database, block *types.Block) error { // Store the body first to retain database consistency if err := WriteBody(db, block.Hash(), &types.Body{block.Transactions(), block.Uncles()}); err != nil { return err @@ -354,27 +361,27 @@ func WriteBlock(db ethdb.Database, block *types.Block) error { } // DeleteCanonicalHash removes the number to hash canonical mapping. -func DeleteCanonicalHash(db ethdb.Database, number uint64) { +func DeleteCanonicalHash(db access.Database, number uint64) { db.Delete(append(blockNumPrefix, big.NewInt(int64(number)).Bytes()...)) } // DeleteHeader removes all block header data associated with a hash. -func DeleteHeader(db ethdb.Database, hash common.Hash) { +func DeleteHeader(db access.Database, hash common.Hash) { db.Delete(append(append(blockPrefix, hash.Bytes()...), headerSuffix...)) } // DeleteBody removes all block body data associated with a hash. -func DeleteBody(db ethdb.Database, hash common.Hash) { +func DeleteBody(db access.Database, hash common.Hash) { db.Delete(append(append(blockPrefix, hash.Bytes()...), bodySuffix...)) } // DeleteTd removes all block total difficulty data associated with a hash. -func DeleteTd(db ethdb.Database, hash common.Hash) { +func DeleteTd(db access.Database, hash common.Hash) { db.Delete(append(append(blockPrefix, hash.Bytes()...), tdSuffix...)) } // DeleteBlock removes all block data associated with a hash. -func DeleteBlock(db ethdb.Database, hash common.Hash) { +func DeleteBlock(db access.Database, hash common.Hash) { DeleteHeader(db, hash) DeleteBody(db, hash) DeleteTd(db, hash) @@ -385,7 +392,7 @@ func DeleteBlock(db ethdb.Database, hash common.Hash) { // or nil if not found. This method is only used by the upgrade mechanism to // access the old combined block representation. It will be dropped after the // network transitions to eth/63. -func GetBlockByHashOld(db ethdb.Database, hash common.Hash) *types.Block { +func GetBlockByHashOld(db access.Database, hash common.Hash) *types.Block { data, _ := db.Get(append(blockHashPre, hash[:]...)) if len(data) == 0 { return nil @@ -411,7 +418,7 @@ func mipmapKey(num, level uint64) []byte { // WriteMapmapBloom writes each address included in the receipts' logs to the // MIP bloom bin. -func WriteMipmapBloom(db ethdb.Database, number uint64, receipts types.Receipts) error { +func WriteMipmapBloom(db access.Database, number uint64, receipts types.Receipts) error { batch := db.NewBatch() for _, level := range MIPMapLevels { key := mipmapKey(number, level) @@ -432,7 +439,7 @@ func WriteMipmapBloom(db ethdb.Database, number uint64, receipts types.Receipts) // GetMipmapBloom returns a bloom filter using the number and level as input // parameters. For available levels see MIPMapLevels. -func GetMipmapBloom(db ethdb.Database, number, level uint64) types.Bloom { +func GetMipmapBloom(db access.Database, number, level uint64) types.Bloom { bloomDat, _ := db.Get(mipmapKey(number, level)) return types.BytesToBloom(bloomDat) } diff --git a/core/chain_util_test.go b/core/chain_util_test.go index 53bcfaf8f2..5810ab3efa 100644 --- a/core/chain_util_test.go +++ b/core/chain_util_test.go @@ -23,13 +23,12 @@ import ( "os" "testing" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/access" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto/sha3" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/rlp" ) @@ -86,7 +85,7 @@ func TestDifficulty(t *testing.T) { // Tests block header storage and retrieval operations. func TestHeaderStorage(t *testing.T) { - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() // Create a test header to move around the database and make sure it's really new header := &types.Header{Extra: []byte("test header")} @@ -121,7 +120,7 @@ func TestHeaderStorage(t *testing.T) { // Tests block body storage and retrieval operations. func TestBodyStorage(t *testing.T) { - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() ca := access.NewDbChainAccess(db) // Create a test body to move around the database and make sure it's really new @@ -162,7 +161,7 @@ func TestBodyStorage(t *testing.T) { // Tests block storage and retrieval operations. func TestBlockStorage(t *testing.T) { - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() ca := access.NewDbChainAccess(db) // Create a test block to move around the database and make sure it's really new @@ -215,7 +214,7 @@ func TestBlockStorage(t *testing.T) { // Tests that partial block contents don't get reassembled into full blocks. func TestPartialBlockStorage(t *testing.T) { - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() ca := access.NewDbChainAccess(db) block := types.NewBlockWithHeader(&types.Header{ Extra: []byte("test block"), @@ -257,7 +256,7 @@ func TestPartialBlockStorage(t *testing.T) { // Tests block total difficulty storage and retrieval operations. func TestTdStorage(t *testing.T) { - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() // Create a test TD to move around the database and make sure it's really new hash, td := common.Hash{}, big.NewInt(314) @@ -282,7 +281,7 @@ func TestTdStorage(t *testing.T) { // Tests that canonical numbers can be mapped to hashes and retrieved. func TestCanonicalMappingStorage(t *testing.T) { - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() // Create a test canonical number and assinged hash to move around hash, number := common.Hash{0: 0xff}, uint64(314) @@ -307,7 +306,7 @@ func TestCanonicalMappingStorage(t *testing.T) { // Tests that head headers and head blocks can be assigned, individually. func TestHeadStorage(t *testing.T) { - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() blockHead := types.NewBlockWithHeader(&types.Header{Extra: []byte("test block header")}) blockFull := types.NewBlockWithHeader(&types.Header{Extra: []byte("test block full")}) @@ -346,7 +345,7 @@ func TestHeadStorage(t *testing.T) { } func TestMipmapBloom(t *testing.T) { - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() receipt1 := new(types.Receipt) receipt1.Logs = vm.Logs{ @@ -370,7 +369,7 @@ func TestMipmapBloom(t *testing.T) { } // reset - db, _ = ethdb.NewMemDatabase() + db, _ = access.NewMemDatabase() receipt := new(types.Receipt) receipt.Logs = vm.Logs{ &vm.Log{Address: common.BytesToAddress([]byte("test"))}, @@ -397,7 +396,7 @@ func TestMipmapChain(t *testing.T) { defer os.RemoveAll(dir) var ( - db, _ = ethdb.NewLDBDatabase(dir, 16) + db, _ = access.NewLDBDatabase(dir, 16) key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") addr = crypto.PubkeyToAddress(key1.PublicKey) addr2 = common.BytesToAddress([]byte("jeff")) diff --git a/core/genesis.go b/core/genesis.go index c5a355f0c0..9edae819ca 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -24,18 +24,17 @@ import ( "math/big" "strings" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/access" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/params" ) // WriteGenesisBlock writes the genesis block to the database as block number 0 -func WriteGenesisBlock(chainDb ethdb.Database, reader io.Reader) (*types.Block, error) { +func WriteGenesisBlock(chainDb access.Database, reader io.Reader) (*types.Block, error) { contents, err := ioutil.ReadAll(reader) if err != nil { return nil, err @@ -119,7 +118,7 @@ func WriteGenesisBlock(chainDb ethdb.Database, reader io.Reader) (*types.Block, // GenesisBlockForTesting creates a block in which addr has the given wei balance. // The state trie of the block is written to db. the passed db needs to contain a state root -func GenesisBlockForTesting(db ethdb.Database, addr common.Address, balance *big.Int) *types.Block { +func GenesisBlockForTesting(db access.Database, addr common.Address, balance *big.Int) *types.Block { statedb, _ := state.New(common.Hash{}, access.NewDbChainAccess(db)) obj := statedb.GetOrNewStateObject(addr) obj.SetBalance(balance) @@ -140,7 +139,7 @@ type GenesisAccount struct { Balance *big.Int } -func WriteGenesisBlockForTesting(db ethdb.Database, accounts ...GenesisAccount) *types.Block { +func WriteGenesisBlockForTesting(db access.Database, accounts ...GenesisAccount) *types.Block { accountJson := "{" for i, account := range accounts { if i != 0 { @@ -160,7 +159,7 @@ func WriteGenesisBlockForTesting(db ethdb.Database, accounts ...GenesisAccount) return block } -func WriteTestNetGenesisBlock(chainDb ethdb.Database, nonce uint64) (*types.Block, error) { +func WriteTestNetGenesisBlock(chainDb access.Database, nonce uint64) (*types.Block, error) { testGenesis := fmt.Sprintf(`{ "nonce": "0x%x", "difficulty": "0x20000", @@ -181,7 +180,7 @@ func WriteTestNetGenesisBlock(chainDb ethdb.Database, nonce uint64) (*types.Bloc return WriteGenesisBlock(chainDb, strings.NewReader(testGenesis)) } -func WriteOlympicGenesisBlock(chainDb ethdb.Database, nonce uint64) (*types.Block, error) { +func WriteOlympicGenesisBlock(chainDb access.Database, nonce uint64) (*types.Block, error) { testGenesis := fmt.Sprintf(`{ "nonce":"0x%x", "gasLimit":"0x%x", diff --git a/core/helper_test.go b/core/helper_test.go index fd6a5491c5..41e06c7e48 100644 --- a/core/helper_test.go +++ b/core/helper_test.go @@ -23,7 +23,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" // "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/event" ) @@ -32,7 +32,7 @@ type TestManager struct { // stateManager *StateManager eventMux *event.TypeMux - db ethdb.Database + db access.Database txPool *TxPool blockChain *BlockChain Blocks []*types.Block @@ -74,12 +74,12 @@ func (tm *TestManager) EventMux() *event.TypeMux { // return nil // } -func (tm *TestManager) Db() ethdb.Database { +func (tm *TestManager) Db() access.Database { return tm.db } func NewTestManager() *TestManager { - db, err := ethdb.NewMemDatabase() + db, err := access.NewMemDatabase() if err != nil { fmt.Println("Could not create mem-db, failing") return nil diff --git a/core/manager.go b/core/manager.go index c2dbe8bfef..536a7a9ac6 100644 --- a/core/manager.go +++ b/core/manager.go @@ -17,9 +17,8 @@ package core import ( + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/accounts" - "github.com/ethereum/go-ethereum/core/access" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" ) @@ -29,8 +28,8 @@ type Backend interface { BlockProcessor() *BlockProcessor BlockChain() *BlockChain TxPool() *TxPool - ChainDb() ethdb.Database + ChainDb() access.Database ChainAccess() *access.ChainAccess - DappDb() ethdb.Database + DappDb() access.Database EventMux() *event.TypeMux } diff --git a/core/requests.go b/core/requests.go new file mode 100644 index 0000000000..102b722808 --- /dev/null +++ b/core/requests.go @@ -0,0 +1,60 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "github.com/ethereum/go-ethereum/access" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "golang.org/x/net/context" +) + +// BlockRequest is the ODR request type for block bodies +type BlockRequest struct { + access.Request + ctx context.Context + blockHash common.Hash + data []byte +} + +func (req *BlockRequest) Ctx() context.Context { return req.ctx } + +func (req *BlockRequest) GetRlp() []byte { + return req.data +} + +func (req *BlockRequest) StoreResult(db access.Database) { + WriteBodyRlp(db, req.blockHash, req.GetRlp()) +} + +// ReceiptsRequest is the ODR request type for block receipts by block hash +type ReceiptsRequest struct { + access.Request + ctx context.Context + blockHash common.Hash + data types.Receipts +} + +func (req *ReceiptsRequest) Ctx() context.Context { return req.ctx } + +func (req *ReceiptsRequest) GetReceipts() types.Receipts { + return req.data +} + +func (req *ReceiptsRequest) StoreResult(db access.Database) { + PutBlockReceipts(db, req.blockHash, req.GetReceipts()) +} diff --git a/core/requests/block_access.go b/core/requests/block_access.go deleted file mode 100644 index 50faabe335..0000000000 --- a/core/requests/block_access.go +++ /dev/null @@ -1,204 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package requests - -import ( - "bytes" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/core/access" - "github.com/ethereum/go-ethereum/logger" - "github.com/ethereum/go-ethereum/logger/glog" - "github.com/ethereum/go-ethereum/rlp" -) - -var ( - blockReceiptsPre = []byte("receipts-block-") - blockPrefix = []byte("block-") - bodySuffix = []byte("-body") -) - -// BlockAccess is the ODR request type for block bodies -type BlockAccess struct { - access.ObjectAccess - db ethdb.Database - blockHash common.Hash - rlp []byte - getHeader getHeaderFn -} - -type getHeaderFn func(db ethdb.Database, hash common.Hash) *types.Header - -// NewBlockAccess creates a new BlockAccess request -func NewBlockAccess(db ethdb.Database, blockHash common.Hash, getHeader getHeaderFn) *BlockAccess { - return &BlockAccess{db: db, blockHash: blockHash, getHeader: getHeader} -} - -// GetRlp returns the block body rlp data stored in memory after a successful request -func (self *BlockAccess) GetRlp() []byte { - return self.rlp -} - -// Request sends an ODR request to the LES network (implementation of access.ObjectAccess) -func (self *BlockAccess) Request(peer *access.Peer) error { - glog.V(access.LogLevel).Infof("ODR: requesting body of block %08x from peer %v", self.blockHash[:4], peer.Id()) - return peer.GetBlockBodies([]common.Hash{self.blockHash}) -} - -// Valid processes an ODR request reply message from the LES network -// returns true and stores results in memory if the message was a valid reply -// to the request (implementation of access.ObjectAccess) -func (self *BlockAccess) Valid(msg *access.Msg) bool { - glog.V(access.LogLevel).Infof("ODR: validating body of block %08x", self.blockHash[:4]) - if msg.MsgType != access.MsgBlockBodies { - glog.V(access.LogLevel).Infof("ODR: invalid message type") - return false - } - bodies := msg.Obj.([]*types.Body) - if len(bodies) != 1 { - glog.V(access.LogLevel).Infof("ODR: invalid number of entries: %d", len(bodies)) - return false - } - body := bodies[0] - header := self.getHeader(self.db, self.blockHash) - if header == nil { - glog.V(access.LogLevel).Infof("ODR: header not found for block %08x", self.blockHash[:4]) - return false - } - txHash := types.DeriveSha(types.Transactions(body.Transactions)) - if header.TxHash != txHash { - glog.V(access.LogLevel).Infof("ODR: header.TxHash %08x does not match received txHash %08x", header.TxHash[:4], txHash[:4]) - return false - } - uncleHash := types.CalcUncleHash(body.Uncles) - if header.UncleHash != uncleHash { - glog.V(access.LogLevel).Infof("ODR: header.UncleHash %08x does not match received uncleHash %08x", header.UncleHash[:4], uncleHash[:4]) - return false - } - data, err := rlp.EncodeToBytes(body) - if err != nil { - glog.V(access.LogLevel).Infof("ODR: body RLP encode error: %v", err) - return false - } - self.rlp = data - glog.V(access.LogLevel).Infof("ODR: validation successful") - return true -} - -// DbGet tries to retrieve requested data from the local database, returns -// true and stores results in memory if successful -// (implementation of access.ObjectAccess) -func (self *BlockAccess) DbGet() bool { - self.rlp, _ = self.db.Get(append(append(blockPrefix, self.blockHash[:]...), bodySuffix...)) - glog.V(access.LogLevel).Infof("ODR: get body %08x len = %d", self.blockHash[:4], len(self.rlp)) - return len(self.rlp) != 0 -} - -// DbPut stores the results of a successful request in the local database -// (implementation of access.ObjectAccess) -func (self *BlockAccess) DbPut() { - self.db.Put(append(append(blockPrefix, self.blockHash[:]...), bodySuffix...), self.rlp) - glog.V(access.LogLevel).Infof("ODR: put body %08x len = %d", self.blockHash[:4], len(self.rlp)) -} - -// ReceiptsAccess is the ODR request type for block receipts by block hash -type ReceiptsAccess struct { - access.ObjectAccess - db ethdb.Database - blockHash common.Hash - receipts types.Receipts - getHeader getHeaderFn - putReceipts putReceiptsFn - putBlockReceipts putBlockReceiptsFn -} - -type putReceiptsFn func(db ethdb.Database, receipts types.Receipts) error -type putBlockReceiptsFn func(db ethdb.Database, hash common.Hash, receipts types.Receipts) error - -// NewReceiptsAccess creates a new ReceiptsAccess request -func NewReceiptsAccess(db ethdb.Database, blockHash common.Hash, getHeader getHeaderFn, putReceipts putReceiptsFn, putBlockReceipts putBlockReceiptsFn) *ReceiptsAccess { - return &ReceiptsAccess{db: db, blockHash: blockHash, getHeader: getHeader, putReceipts: putReceipts, putBlockReceipts: putBlockReceipts} -} - -// GetReceipts returns the block receipts stored in memory after a successful request -func (self *ReceiptsAccess) GetReceipts() types.Receipts { - return self.receipts -} - -// Request sends an ODR request to the LES network (implementation of access.ObjectAccess) -func (self *ReceiptsAccess) Request(peer *access.Peer) error { - glog.V(access.LogLevel).Infof("ODR: requesting receipts for block %08x from peer %v", self.blockHash[:4], peer.Id()) - return peer.GetReceipts([]common.Hash{self.blockHash}) -} - -// Valid processes an ODR request reply message from the LES network -// returns true and stores results in memory if the message was a valid reply -// to the request (implementation of access.ObjectAccess) -func (self *ReceiptsAccess) Valid(msg *access.Msg) bool { - glog.V(access.LogLevel).Infof("ODR: validating receipts for block %08x", self.blockHash[:4]) - if msg.MsgType != access.MsgReceipts { - glog.V(access.LogLevel).Infof("ODR: invalid message type") - return false - } - receipts := msg.Obj.([]types.Receipts) - if len(receipts) != 1 { - glog.V(access.LogLevel).Infof("ODR: invalid number of entries: %d", len(receipts)) - return false - } - hash := types.DeriveSha(receipts[0]) - header := self.getHeader(self.db, self.blockHash) - if header == nil { - glog.V(access.LogLevel).Infof("ODR: header not found for block %08x", self.blockHash[:4]) - return false - } - if !bytes.Equal(header.ReceiptHash[:], hash[:]) { - glog.V(access.LogLevel).Infof("ODR: header receipts hash %08x does not match calculated RLP hash %08x", header.ReceiptHash[:4], hash[:4]) - return false - } - self.receipts = receipts[0] - glog.V(access.LogLevel).Infof("ODR: validation successful") - return true -} - -// DbGet tries to retrieve requested data from the local database, returns -// true and stores results in memory if successful -// (implementation of access.ObjectAccess) -func (self *ReceiptsAccess) DbGet() bool { - data, _ := self.db.Get(append(blockReceiptsPre, self.blockHash[:]...)) - if len(data) == 0 { - return false - } - rs := []*types.ReceiptForStorage{} - if err := rlp.DecodeBytes(data, &rs); err != nil { - glog.V(logger.Error).Infof("invalid receipt array RLP for hash %x: %v", self.blockHash, err) - return false - } - self.receipts = make(types.Receipts, len(rs)) - for i, receipt := range rs { - self.receipts[i] = (*types.Receipt)(receipt) - } - return true -} - -// DbPut stores the results of a successful request in the local database -// (implementation of access.ObjectAccess) -func (self *ReceiptsAccess) DbPut() { - self.putBlockReceipts(self.db, self.blockHash, self.receipts) - self.putReceipts(self.db, self.receipts) -} diff --git a/core/requests/trie_access.go b/core/requests/trie_access.go deleted file mode 100644 index fd49994bac..0000000000 --- a/core/requests/trie_access.go +++ /dev/null @@ -1,200 +0,0 @@ -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// Package state provides a caching layer atop the Ethereum state trie. -package requests - -import ( - "bytes" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/crypto/sha3" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/core/access" - "github.com/ethereum/go-ethereum/logger/glog" - "github.com/ethereum/go-ethereum/trie" - "golang.org/x/net/context" -) - -// TrieAccess implements trie.OdrAccess, providing database/network access for -// a trie identified by root hash -type TrieAccess struct { - trie.OdrAccess - ca *access.ChainAccess - root common.Hash - trieDb trie.Database -} - -// NewTrieAccess creates a new TrieAccess -func NewTrieAccess(ca *access.ChainAccess, root common.Hash, trieDb trie.Database) *TrieAccess { - return &TrieAccess{ - ca: ca, - root: root, - trieDb: trieDb, - } -} - -// RetrieveKey retrieves a single key, returns true and stores nodes in local -// database if successful -func (self *TrieAccess) RetrieveKey(ctx context.Context, key []byte) bool { - //fmt.Println("request trie %v key %v", self.root, key) - r := NewTrieEntryAccess(self.root, self.trieDb, key) - return self.ca.Retrieve(ctx, r) == nil -} - -// OdrEnabled returns true if this TrieAccess is capable of doing network requests -func (self *TrieAccess) OdrEnabled() bool { - return self.ca.OdrEnabled() -} - -// TrieEntryAccess is the ODR request type for state/storage trie entries -type TrieEntryAccess struct { - access.ObjectAccess - root common.Hash - trieDb trie.Database - key, value []byte - proof trie.MerkleProof - skipLevels int // set by DbGet() if unsuccessful -} - -// NewTrieEntryAccess creates a new TrieEntryAccess request -func NewTrieEntryAccess(root common.Hash, trieDb trie.Database, key []byte) *TrieEntryAccess { - return &TrieEntryAccess{root: root, trieDb: trieDb, key: key} -} - -// Request sends an ODR request to the LES network (implementation of access.ObjectAccess) -func (self *TrieEntryAccess) Request(peer *access.Peer) error { - glog.V(access.LogLevel).Infof("ODR: requesting trie root %08x key %08x from peer %v", self.root[:4], self.key[:4], peer.Id()) - req := &access.ProofReq{ - Root: self.root, - Key: self.key, - } - return peer.GetProofs([]*access.ProofReq{req}) -} - -// Valid processes an ODR request reply message from the LES network -// returns true and stores results in memory if the message was a valid reply -// to the request (implementation of access.ObjectAccess) -func (self *TrieEntryAccess) Valid(msg *access.Msg) bool { - glog.V(access.LogLevel).Infof("ODR: validating trie root %08x key %08x", self.root[:4], self.key[:4]) - - if msg.MsgType != access.MsgProofs { - glog.V(access.LogLevel).Infof("ODR: invalid message type") - return false - } - proofs := msg.Obj.([]trie.MerkleProof) - if len(proofs) != 1 { - glog.V(access.LogLevel).Infof("ODR: invalid number of entries: %d", len(proofs)) - return false - } - value, err := trie.VerifyProof(self.root, self.key, proofs[0]) - if err != nil { - glog.V(access.LogLevel).Infof("ODR: merkle proof verification error: %v", err) - return false - } - self.proof = proofs[0] - self.value = value - glog.V(access.LogLevel).Infof("ODR: validation successful") - return true -} - -// DbGet tries to retrieve requested data from the local database, returns -// true and stores results in memory if successful -// (implementation of access.ObjectAccess) -func (self *TrieEntryAccess) DbGet() bool { - return false // not used -} - -// DbPut stores the results of a successful request in the local database -// (implementation of access.ObjectAccess) -func (self *TrieEntryAccess) DbPut() { - trie.StoreProof(self.trieDb, self.proof) -} - -// NodeDataBlockAccess is the ODR request type for node data (used for retrieving contract code) -type NodeDataAccess struct { - access.ObjectAccess - db ethdb.Database - hash common.Hash - data []byte -} - -// NewNodeDataAccess creates a new NodeDataAccess request -func NewNodeDataAccess(db ethdb.Database, hash common.Hash) *NodeDataAccess { - return &NodeDataAccess{db: db, hash: hash} -} - -// Request sends an ODR request to the LES network (implementation of access.ObjectAccess) -func (self *NodeDataAccess) Request(peer *access.Peer) error { - glog.V(access.LogLevel).Infof("ODR: requesting node data for hash %08x from peer %v", self.hash[:4], peer.Id()) - return peer.GetNodeData([]common.Hash{self.hash}) -} - -// Valid processes an ODR request reply message from the LES network -// returns true and stores results in memory if the message was a valid reply -// to the request (implementation of access.ObjectAccess) -func (self *NodeDataAccess) Valid(msg *access.Msg) bool { - glog.V(access.LogLevel).Infof("ODR: validating node data for hash %08x", self.hash[:4]) - if msg.MsgType != access.MsgNodeData { - glog.V(access.LogLevel).Infof("ODR: invalid message type") - return false - } - reply := msg.Obj.([][]byte) - if len(reply) != 1 { - glog.V(access.LogLevel).Infof("ODR: invalid number of entries: %d", len(reply)) - return false - } - data := reply[0] - hash := crypto.Sha3Hash(data) - if bytes.Compare(self.hash[:], hash[:]) != 0 { - glog.V(access.LogLevel).Infof("ODR: requested hash %08x does not match received data hash %08x", self.hash[:4], hash[:4]) - return false - } - self.data = data - glog.V(access.LogLevel).Infof("ODR: validation successful") - return true -} - -// DbGet tries to retrieve requested data from the local database, returns -// true and stores results in memory if successful -// (implementation of access.ObjectAccess) -func (self *NodeDataAccess) DbGet() bool { - data, _ := self.db.Get(self.hash[:]) - if len(data) == 0 { - return false - } - self.data = data - return true -} - -// DbPut stores the results of a successful request in the local database -// (implementation of access.ObjectAccess) -func (self *NodeDataAccess) DbPut() { - self.db.Put(self.hash[:], self.data) -} - -var sha3_nil = sha3.NewKeccak256().Sum(nil) - -func RetrieveNodeData(ctx context.Context, ca *access.ChainAccess, hash common.Hash) []byte { - //fmt.Println("request node data %v", hash) - if bytes.Compare(hash[:], sha3_nil) == 0 { - return nil - } - r := NewNodeDataAccess(ca.Db(), hash) - ca.Retrieve(ctx, r) - return r.data -} diff --git a/core/state/dump.go b/core/state/dump.go index 14e7e6ee42..83a45a800c 100644 --- a/core/state/dump.go +++ b/core/state/dump.go @@ -20,8 +20,8 @@ import ( "encoding/json" "fmt" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/access" ) type Account struct { diff --git a/core/state/managed_state_test.go b/core/state/managed_state_test.go index 5356b0533c..f548a59574 100644 --- a/core/state/managed_state_test.go +++ b/core/state/managed_state_test.go @@ -19,15 +19,14 @@ package state import ( "testing" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/access" - "github.com/ethereum/go-ethereum/ethdb" ) var addr = common.BytesToAddress([]byte("test")) func create() (*ManagedState, *account) { - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() statedb, _ := New(common.Hash{}, access.NewDbChainAccess(db)) ms := ManageState(statedb) so := &StateObject{address: addr, nonce: 100} diff --git a/core/state/requests.go b/core/state/requests.go new file mode 100644 index 0000000000..0de9b03a91 --- /dev/null +++ b/core/state/requests.go @@ -0,0 +1,105 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package state + +import ( + "bytes" + + "github.com/ethereum/go-ethereum/access" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto/sha3" + "github.com/ethereum/go-ethereum/trie" + "golang.org/x/net/context" +) + +// TrieAccess implements trie.OdrAccess, providing database/network access for +// a trie identified by root hash +type TrieAccess struct { + trie.OdrAccess + ca *access.ChainAccess + root common.Hash + trieDb trie.Database +} + +// NewTrieAccess creates a new TrieAccess +func NewTrieAccess(ca *access.ChainAccess, root common.Hash, trieDb trie.Database) *TrieAccess { + return &TrieAccess{ + ca: ca, + root: root, + trieDb: trieDb, + } +} + +// RetrieveKey retrieves a single key, returns true and stores nodes in local +// database if successful +func (self *TrieAccess) RetrieveKey(ctx context.Context, key []byte) bool { + r := &TrieRequest{ctx: ctx, root: self.root, key: key} + return self.ca.Retrieve(r) == nil +} + +// OdrEnabled returns true if this TrieAccess is capable of doing network requests +func (self *TrieAccess) OdrEnabled() bool { + return self.ca.OdrEnabled() +} + +// TrieRequest is the ODR request type for state/storage trie entries +type TrieRequest struct { + access.Request + ctx context.Context + root common.Hash + key []byte + proof trie.MerkleProof +} + +func (req *TrieRequest) Ctx() context.Context { return req.ctx } + +func (req *TrieRequest) StoreResult(db access.Database) { + trie.StoreProof(db, req.proof) +} + +// NodeDataRequest is the ODR request type for node data (used for retrieving contract code) +type NodeDataRequest struct { + access.Request + ctx context.Context + hash common.Hash + data []byte +} + +func (req *NodeDataRequest) Ctx() context.Context { return req.ctx } + +func (req *NodeDataRequest) GetData() []byte { + return req.data +} + +func (req *NodeDataRequest) StoreResult(db access.Database) { + db.Put(req.hash[:], req.GetData()) +} + +var sha3_nil = sha3.NewKeccak256().Sum(nil) + +func RetrieveNodeData(ctx context.Context, ca *access.ChainAccess, hash common.Hash) []byte { + if bytes.Compare(hash[:], sha3_nil) == 0 { + return nil + } + res, _ := ca.Db().Get(hash[:]) + if res != nil || !access.IsOdrContext(ctx) { + return res + } + r := &NodeDataRequest{ctx: ctx, hash: hash} + ca.Retrieve(r) + return r.GetData() +} diff --git a/core/state/state_object.go b/core/state/state_object.go index 7fffa071d8..ccf5244290 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -21,9 +21,8 @@ import ( "fmt" "math/big" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/access" - "github.com/ethereum/go-ethereum/core/requests" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" @@ -60,7 +59,7 @@ func (self Storage) Copy() Storage { type StateObject struct { // State database for storing state changes ca *access.ChainAccess - ctx context.Context + ctx context.Context trie *trie.SecureTrie // Address belonging to this account @@ -105,7 +104,7 @@ func NewStateObjectFromBytes(ctx context.Context, address common.Address, data [ glog.Errorf("can't decode state object %x: %v", address, err) return nil } - trie, err := trie.NewSecureOdr(ctx, extobject.Root, ca.Db(), requests.NewTrieAccess(ca, extobject.Root, ca.Db())) + trie, err := trie.NewSecureOdr(ctx, extobject.Root, ca.Db(), NewTrieAccess(ca, extobject.Root, ca.Db())) if err != nil { // TODO: bubble this up or panic glog.Errorf("can't create account trie with root %x: %v", extobject.Root[:], err) @@ -118,7 +117,7 @@ func NewStateObjectFromBytes(ctx context.Context, address common.Address, data [ object.codeHash = extobject.CodeHash object.trie = trie object.storage = make(map[string]common.Hash) - object.code = requests.RetrieveNodeData(ctx, ca, common.BytesToHash(extobject.CodeHash)) + object.code = RetrieveNodeData(ctx, ca, common.BytesToHash(extobject.CodeHash)) return object } @@ -221,7 +220,7 @@ func (self *StateObject) CopyOdr(ctx context.Context) *StateObject { stateObject.codeHash = common.CopyBytes(self.codeHash) stateObject.nonce = self.nonce if access.IsOdrContext(ctx) { - stateObject.trie = self.trie.CopySecureWithOdr(ctx, requests.NewTrieAccess(self.ca, common.BytesToHash(self.trie.Root()), self.ca.Db())) + stateObject.trie = self.trie.CopySecureWithOdr(ctx, NewTrieAccess(self.ca, common.BytesToHash(self.trie.Root()), self.ca.Db())) } else { stateObject.trie = self.trie } diff --git a/core/state/state_test.go b/core/state/state_test.go index 02e422fa89..30654814e5 100644 --- a/core/state/state_test.go +++ b/core/state/state_test.go @@ -23,9 +23,8 @@ import ( checker "gopkg.in/check.v1" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/access" - "github.com/ethereum/go-ethereum/ethdb" ) type StateSuite struct { @@ -77,12 +76,12 @@ func (s *StateSuite) TestDump(c *checker.C) { } func (s *StateSuite) SetUpTest(c *checker.C) { - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() s.state, _ = New(common.Hash{}, access.NewDbChainAccess(db)) } func TestNull(t *testing.T) { - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() state, _ := New(common.Hash{}, access.NewDbChainAccess(db)) address := common.HexToAddress("0x823140710bf13990e4500136726d8b55") @@ -122,7 +121,7 @@ func (s *StateSuite) TestSnapshot(c *checker.C) { // use testing instead of checker because checker does not support // printing/logging in tests (-check.vv does not work) func TestSnapshot2(t *testing.T) { - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() state, _ := New(common.Hash{}, access.NewDbChainAccess(db)) stateobjaddr0 := toAddr([]byte("so0")) diff --git a/core/state/statedb.go b/core/state/statedb.go index 7e2242fec3..c7ddec4412 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -20,11 +20,9 @@ package state import ( "math/big" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/core/access" - "github.com/ethereum/go-ethereum/core/requests" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/trie" @@ -43,7 +41,7 @@ var StartingNonce uint64 type StateDB struct { ca *access.ChainAccess trie *trie.SecureTrie - ctx context.Context + ctx context.Context stateObjects map[string]*StateObject @@ -62,7 +60,7 @@ func New(root common.Hash, ca *access.ChainAccess) (*StateDB, error) { // NewOdr creates a new state from a given trie with ODR option func NewOdr(ctx context.Context, root common.Hash, ca *access.ChainAccess) (*StateDB, error) { - tr, err := trie.NewSecureOdr(ctx, root, ca.Db(), requests.NewTrieAccess(ca, root, ca.Db())) + tr, err := trie.NewSecureOdr(ctx, root, ca.Db(), NewTrieAccess(ca, root, ca.Db())) if err != nil { glog.Errorf("can't create state trie with root %x: %v", root[:], err) return nil, err @@ -70,7 +68,7 @@ func NewOdr(ctx context.Context, root common.Hash, ca *access.ChainAccess) (*Sta return &StateDB{ ca: ca, trie: tr, - ctx: ctx, + ctx: ctx, stateObjects: make(map[string]*StateObject), refund: new(big.Int), logs: make(map[common.Hash]vm.Logs), @@ -324,7 +322,7 @@ func (self *StateDB) CopyOdr(ctx context.Context) *StateDB { // ignore error - we assume state-to-be-copied always exists state, _ := NewOdr(ctx, common.Hash{}, self.ca) if access.IsOdrContext(ctx) { - state.trie = self.trie.CopySecureWithOdr(ctx, requests.NewTrieAccess(self.ca, common.BytesToHash(self.trie.Root()), self.ca.Db())) + state.trie = self.trie.CopySecureWithOdr(ctx, NewTrieAccess(self.ca, common.BytesToHash(self.trie.Root()), self.ca.Db())) } else { state.trie = self.trie } @@ -383,7 +381,7 @@ func (s *StateDB) Commit() (root common.Hash, err error) { // CommitBatch commits all state changes to a write batch but does not // execute the batch. It is used to validate state changes against // the root hash stored in a block. -func (s *StateDB) CommitBatch() (root common.Hash, batch ethdb.Batch) { +func (s *StateDB) CommitBatch() (root common.Hash, batch access.Batch) { batch = s.ca.Db().NewBatch() root, _ = s.commit(batch) return root, batch diff --git a/core/state/sync.go b/core/state/sync.go index ef2b4b84c5..86526d3eac 100644 --- a/core/state/sync.go +++ b/core/state/sync.go @@ -20,8 +20,8 @@ import ( "bytes" "math/big" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie" ) @@ -32,7 +32,7 @@ import ( type StateSync trie.TrieSync // NewStateSync create a new state trie download scheduler. -func NewStateSync(root common.Hash, database ethdb.Database) *StateSync { +func NewStateSync(root common.Hash, database access.Database) *StateSync { var syncer *trie.TrieSync callback := func(leaf []byte, parent common.Hash) error { diff --git a/core/state/sync_test.go b/core/state/sync_test.go index 1a175bf3a3..9d027a48b4 100644 --- a/core/state/sync_test.go +++ b/core/state/sync_test.go @@ -21,9 +21,8 @@ import ( "math/big" "testing" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/access" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/trie" ) @@ -36,9 +35,9 @@ type testAccount struct { } // makeTestState create a sample test state to test node-wise reconstruction. -func makeTestState() (ethdb.Database, common.Hash, []*testAccount) { +func makeTestState() (access.Database, common.Hash, []*testAccount) { // Create an empty state - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() state, _ := New(common.Hash{}, access.NewDbChainAccess(db)) // Fill it with some arbitrary data @@ -68,7 +67,7 @@ func makeTestState() (ethdb.Database, common.Hash, []*testAccount) { // checkStateAccounts cross references a reconstructed state with an expected // account array. -func checkStateAccounts(t *testing.T, db ethdb.Database, root common.Hash, accounts []*testAccount) { +func checkStateAccounts(t *testing.T, db access.Database, root common.Hash, accounts []*testAccount) { state, _ := New(root, access.NewDbChainAccess(db)) for i, acc := range accounts { @@ -87,7 +86,7 @@ func checkStateAccounts(t *testing.T, db ethdb.Database, root common.Hash, accou // Tests that an empty state is not scheduled for syncing. func TestEmptyStateSync(t *testing.T) { empty := common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421") - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() if req := NewStateSync(empty, db).Missing(1); len(req) != 0 { t.Errorf("content requested for empty state: %v", req) } @@ -103,7 +102,7 @@ func testIterativeStateSync(t *testing.T, batch int) { srcDb, srcRoot, srcAccounts := makeTestState() // Create a destination state and sync with the scheduler - dstDb, _ := ethdb.NewMemDatabase() + dstDb, _ := access.NewMemDatabase() sched := NewStateSync(srcRoot, dstDb) queue := append([]common.Hash{}, sched.Missing(batch)...) @@ -132,7 +131,7 @@ func TestIterativeDelayedStateSync(t *testing.T) { srcDb, srcRoot, srcAccounts := makeTestState() // Create a destination state and sync with the scheduler - dstDb, _ := ethdb.NewMemDatabase() + dstDb, _ := access.NewMemDatabase() sched := NewStateSync(srcRoot, dstDb) queue := append([]common.Hash{}, sched.Missing(0)...) @@ -166,7 +165,7 @@ func testIterativeRandomStateSync(t *testing.T, batch int) { srcDb, srcRoot, srcAccounts := makeTestState() // Create a destination state and sync with the scheduler - dstDb, _ := ethdb.NewMemDatabase() + dstDb, _ := access.NewMemDatabase() sched := NewStateSync(srcRoot, dstDb) queue := make(map[common.Hash]struct{}) @@ -203,7 +202,7 @@ func TestIterativeRandomDelayedStateSync(t *testing.T) { srcDb, srcRoot, srcAccounts := makeTestState() // Create a destination state and sync with the scheduler - dstDb, _ := ethdb.NewMemDatabase() + dstDb, _ := access.NewMemDatabase() sched := NewStateSync(srcRoot, dstDb) queue := make(map[common.Hash]struct{}) diff --git a/core/transaction_pool_test.go b/core/transaction_pool_test.go index ccf030e3e7..3b2f6aefcf 100644 --- a/core/transaction_pool_test.go +++ b/core/transaction_pool_test.go @@ -21,12 +21,11 @@ import ( "math/big" "testing" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/access" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" ) @@ -36,7 +35,7 @@ func transaction(nonce uint64, gaslimit *big.Int, key *ecdsa.PrivateKey) *types. } func setupTxPool() (*TxPool, *ecdsa.PrivateKey) { - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() statedb, _ := state.New(common.Hash{}, access.NewDbChainAccess(db)) var m event.TypeMux @@ -163,7 +162,7 @@ func TestTransactionChainFork(t *testing.T) { pool, key := setupTxPool() addr := crypto.PubkeyToAddress(key.PublicKey) resetState := func() { - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() statedb, _ := state.New(common.Hash{}, access.NewDbChainAccess(db)) pool.currentState = func() (*state.StateDB, error) { return statedb, nil } currentState, _ := pool.currentState() @@ -189,7 +188,7 @@ func TestTransactionDoubleNonce(t *testing.T) { pool, key := setupTxPool() addr := crypto.PubkeyToAddress(key.PublicKey) resetState := func() { - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() statedb, _ := state.New(common.Hash{}, access.NewDbChainAccess(db)) pool.currentState = func() (*state.StateDB, error) { return statedb, nil } currentState, _ := pool.currentState() diff --git a/core/transaction_util.go b/core/transaction_util.go index fcb9407fcd..acbe18c419 100644 --- a/core/transaction_util.go +++ b/core/transaction_util.go @@ -19,11 +19,9 @@ package core import ( "fmt" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/access" - "github.com/ethereum/go-ethereum/core/requests" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/rlp" @@ -32,12 +30,12 @@ import ( ) var ( - blockReceiptsPre = []byte("receipts-block-") receiptsPre = []byte("receipts-") + blockReceiptsPre = []byte("receipts-block-") ) // PutTransactions stores the transactions in the given database -func PutTransactions(db ethdb.Database, block *types.Block, txs types.Transactions) error { +func PutTransactions(db access.Database, block *types.Block, txs types.Transactions) error { batch := db.NewBatch() for i, tx := range block.Transactions() { @@ -70,11 +68,11 @@ func PutTransactions(db ethdb.Database, block *types.Block, txs types.Transactio return nil } -func DeleteTransaction(db ethdb.Database, txHash common.Hash) { +func DeleteTransaction(db access.Database, txHash common.Hash) { db.Delete(txHash[:]) } -func GetTransaction(db ethdb.Database, txhash common.Hash) *types.Transaction { +func GetTransaction(db access.Database, txhash common.Hash) *types.Transaction { data, _ := db.Get(txhash[:]) if len(data) != 0 { var tx types.Transaction @@ -87,9 +85,9 @@ func GetTransaction(db ethdb.Database, txhash common.Hash) *types.Transaction { } // PutReceipts stores the receipts in the current database -func PutReceipts(db ethdb.Database, receipts types.Receipts) error { +func PutReceipts(db access.Database, receipts types.Receipts) error { batch := new(leveldb.Batch) - _, batchWrite := db.(*ethdb.LDBDatabase) + _, batchWrite := db.(*access.LDBDatabase) for _, receipt := range receipts { storageReceipt := (*types.ReceiptForStorage)(receipt) @@ -107,7 +105,7 @@ func PutReceipts(db ethdb.Database, receipts types.Receipts) error { } } } - if db, ok := db.(*ethdb.LDBDatabase); ok { + if db, ok := db.(*access.LDBDatabase); ok { if err := db.LDB().Write(batch, nil); err != nil { return err } @@ -117,7 +115,7 @@ func PutReceipts(db ethdb.Database, receipts types.Receipts) error { } // Delete a receipts from the database -func DeleteReceipt(db ethdb.Database, txHash common.Hash) { +func DeleteReceipt(db access.Database, txHash common.Hash) { db.Delete(append(receiptsPre, txHash[:]...)) } @@ -135,24 +133,41 @@ func GetReceipt(ca *access.ChainAccess, txHash common.Hash) *types.Receipt { return (*types.Receipt)(&receipt) } -// GetBlockReceipts returns the receipts generated by the transactions -// included in block's given hash. +// GetBlockReceipts retrieves the receipts generated by the transactions included +// in a block given by its hash. func GetBlockReceipts(ca *access.ChainAccess, hash common.Hash) types.Receipts { - return GetBlockReceiptsOdr(access.NoOdr, ca, hash) + data, _ := ca.Db().Get(append(blockReceiptsPre, hash[:]...)) + if len(data) == 0 { + return nil + } + storageReceipts := []*types.ReceiptForStorage{} + if err := rlp.DecodeBytes(data, &storageReceipts); err != nil { + glog.V(logger.Error).Infof("invalid receipt array RLP for hash %x: %v", hash, err) + return nil + } + receipts := make(types.Receipts, len(storageReceipts)) + for i, receipt := range storageReceipts { + receipts[i] = (*types.Receipt)(receipt) + } + return receipts } // GetBlockReceiptsOdr returns the receipts generated by the transactions // included in block's given hash from the database or network. func GetBlockReceiptsOdr(ctx context.Context, ca *access.ChainAccess, hash common.Hash) types.Receipts { - r := requests.NewReceiptsAccess(ca.Db(), hash, GetHeader, PutReceipts, PutBlockReceipts) - ca.Retrieve(ctx, r) + res := GetBlockReceipts(ca, hash) + if res != nil || !access.IsOdrContext(ctx) { + return res + } + r := &ReceiptsRequest{ctx: ctx, blockHash: hash} + ca.Retrieve(r) return r.GetReceipts() } // PutBlockReceipts stores the block's transactions associated receipts // and stores them by block hash in a single slice. This is required for // forks and chain reorgs -func PutBlockReceipts(db ethdb.Database, hash common.Hash, receipts types.Receipts) error { +func PutBlockReceipts(db access.Database, hash common.Hash, receipts types.Receipts) error { rs := make([]*types.ReceiptForStorage, len(receipts)) for i, receipt := range receipts { rs[i] = (*types.ReceiptForStorage)(receipt) diff --git a/core/vm/runtime/runtime.go b/core/vm/runtime/runtime.go index 3b11a8d1ea..900670263f 100644 --- a/core/vm/runtime/runtime.go +++ b/core/vm/runtime/runtime.go @@ -20,12 +20,11 @@ import ( "math/big" "time" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/access" "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/ethdb" ) // Config is a basic type specifing certain configuration flags for running @@ -96,7 +95,7 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) { vm.Debug = cfg.Debug var ( - db, _ = ethdb.NewMemDatabase() + db, _ = access.NewMemDatabase() statedb, _ = state.New(common.Hash{}, access.NewDbChainAccess(db)) vmenv = NewEnv(cfg, statedb) sender = statedb.CreateAccount(cfg.Origin) diff --git a/eth/backend.go b/eth/backend.go index 387eb2712d..58621fcfbe 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -32,18 +32,17 @@ import ( "time" "github.com/ethereum/ethash" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/compiler" "github.com/ethereum/go-ethereum/common/httpclient" "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/access" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth/downloader" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" @@ -143,7 +142,7 @@ type Config struct { // NewDB is used to create databases. // If nil, the default is to create leveldb databases on disk. - NewDB func(path string) (ethdb.Database, error) + NewDB func(path string) (access.Database, error) } func (cfg *Config) parseBootNodes() []*discover.Node { @@ -229,8 +228,8 @@ type Ethereum struct { shutdownChan chan bool // DB interfaces - chainDb ethdb.Database // Block chain database - dappDb ethdb.Database // Dapp database + chainDb access.Database // Block chain database + dappDb access.Database // Dapp database chainAccess *access.ChainAccess // blockchain access layer @@ -279,11 +278,11 @@ func New(config *Config) (*Ethereum, error) { // Let the database take 3/4 of the max open files (TODO figure out a way to get the actual limit of the open files) const dbCount = 3 - ethdb.OpenFileLimit = 128 / (dbCount + 1) + access.OpenFileLimit = 128 / (dbCount + 1) newdb := config.NewDB if newdb == nil { - newdb = func(path string) (ethdb.Database, error) { return ethdb.NewLDBDatabase(path, config.DatabaseCache) } + newdb = func(path string) (access.Database, error) { return access.NewLDBDatabase(path, config.DatabaseCache) } } // Open the chain database and perform any upgrades needed @@ -294,13 +293,13 @@ func New(config *Config) (*Ethereum, error) { } return nil, fmt.Errorf("blockchain db err: %v", err) } - if db, ok := chainDb.(*ethdb.LDBDatabase); ok { + if db, ok := chainDb.(*access.LDBDatabase); ok { db.Meter("eth/db/chaindata/") } if err := upgradeChainDatabase(chainDb); err != nil { return nil, err } - chainAccess := access.NewChainAccess(chainDb, false) + chainAccess := access.NewChainAccess(chainDb, nil) if err := addMipmapBloomBins(chainAccess); err != nil { return nil, err } @@ -311,7 +310,7 @@ func New(config *Config) (*Ethereum, error) { } return nil, fmt.Errorf("dapp db err: %v", err) } - if db, ok := dappDb.(*ethdb.LDBDatabase); ok { + if db, ok := dappDb.(*access.LDBDatabase); ok { db.Meter("eth/db/dapp/") } @@ -498,9 +497,9 @@ func (s *Ethereum) BlockProcessor() *core.BlockProcessor { return s.blockProcess func (s *Ethereum) TxPool() *core.TxPool { return s.txPool } func (s *Ethereum) Whisper() *whisper.Whisper { return s.whisper } func (s *Ethereum) EventMux() *event.TypeMux { return s.eventMux } -func (s *Ethereum) ChainDb() ethdb.Database { return s.chainDb } +func (s *Ethereum) ChainDb() access.Database { return s.chainDb } func (s *Ethereum) ChainAccess() *access.ChainAccess { return s.chainAccess } -func (s *Ethereum) DappDb() ethdb.Database { return s.dappDb } +func (s *Ethereum) DappDb() access.Database { return s.dappDb } func (s *Ethereum) IsListening() bool { return true } // Always listening func (s *Ethereum) PeerCount() int { return s.net.PeerCount() } func (s *Ethereum) Peers() []*p2p.Peer { return s.net.Peers() } @@ -671,7 +670,7 @@ func dagFiles(epoch uint64) (string, string) { return dag, "full-R" + dag } -func saveBlockchainVersion(db ethdb.Database, bcVersion int) { +func saveBlockchainVersion(db access.Database, bcVersion int) { d, _ := db.Get([]byte("BlockchainVersion")) blockchainVersion := common.NewValue(d).Uint() @@ -682,7 +681,7 @@ func saveBlockchainVersion(db ethdb.Database, bcVersion int) { // upgradeChainDatabase ensures that the chain database stores block split into // separate header and body entries. -func upgradeChainDatabase(db ethdb.Database) error { +func upgradeChainDatabase(db access.Database) error { // Short circuit if the head block is stored already as separate header and body data, err := db.Get([]byte("LastBlock")) if err != nil { @@ -696,7 +695,7 @@ func upgradeChainDatabase(db ethdb.Database) error { // At least some of the database is still the old format, upgrade (skip the head block!) glog.V(logger.Info).Info("Old database detected, upgrading...") - if db, ok := db.(*ethdb.LDBDatabase); ok { + if db, ok := db.(*access.LDBDatabase); ok { blockPrefix := []byte("block-hash-") for it := db.NewIterator(); it.Next(); { // Skip anything other than a combined block diff --git a/eth/backend_test.go b/eth/backend_test.go index fdabf4d64e..4151364b5b 100644 --- a/eth/backend_test.go +++ b/eth/backend_test.go @@ -4,16 +4,15 @@ import ( "math/big" "testing" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/access" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/ethdb" ) func TestMipmapUpgrade(t *testing.T) { - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() addr := common.BytesToAddress([]byte("jeff")) genesis := core.WriteGenesisBlockForTesting(db) diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index 153427ee48..839b296a27 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -28,9 +28,9 @@ import ( "sync/atomic" "time" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" @@ -156,7 +156,7 @@ type Downloader struct { } // New creates a new downloader to fetch hashes and blocks from remote peers. -func New(stateDb ethdb.Database, mux *event.TypeMux, hasHeader headerCheckFn, hasBlock blockCheckFn, getHeader headerRetrievalFn, +func New(stateDb access.Database, mux *event.TypeMux, hasHeader headerCheckFn, hasBlock blockCheckFn, getHeader headerRetrievalFn, getBlock blockRetrievalFn, headHeader headHeaderRetrievalFn, headBlock headBlockRetrievalFn, headFastBlock headFastBlockRetrievalFn, commitHeadBlock headBlockCommitterFn, getTd tdRetrievalFn, insertHeaders headerChainInsertFn, insertBlocks blockChainInsertFn, insertReceipts receiptChainInsertFn, rollback chainRollbackFn, dropPeer peerDropFn) *Downloader { diff --git a/eth/downloader/downloader_test.go b/eth/downloader/downloader_test.go index b8dd075477..a693bec7f9 100644 --- a/eth/downloader/downloader_test.go +++ b/eth/downloader/downloader_test.go @@ -25,20 +25,19 @@ import ( "testing" "time" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/access" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/trie" ) var ( - testdb, _ = ethdb.NewMemDatabase() + testdb, _ = access.NewMemDatabase() testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") testAddress = crypto.PubkeyToAddress(testKey.PublicKey) genesis = core.GenesisBlockForTesting(testdb, testAddress, big.NewInt(1000000000)) @@ -118,7 +117,7 @@ func makeChainFork(n, f int, parent *types.Block, parentReceipts types.Receipts) // downloadTester is a test simulator for mocking out local block chain. type downloadTester struct { - stateDb ethdb.Database + stateDb access.Database downloader *Downloader ownHashes []common.Hash // Hash chain belonging to the tester @@ -150,7 +149,7 @@ func newTester() *downloadTester { peerReceipts: make(map[string]map[common.Hash]types.Receipts), peerChainTds: make(map[string]map[common.Hash]*big.Int), } - tester.stateDb, _ = ethdb.NewMemDatabase() + tester.stateDb, _ = access.NewMemDatabase() tester.downloader = New(tester.stateDb, new(event.TypeMux), tester.hasHeader, tester.hasBlock, tester.getHeader, tester.getBlock, tester.headHeader, tester.headBlock, tester.headFastBlock, tester.commitHeadBlock, tester.getTd, tester.insertHeaders, tester.insertBlocks, tester.insertReceipts, tester.rollback, tester.dropPeer) diff --git a/eth/downloader/queue.go b/eth/downloader/queue.go index 1fb5b6e12f..931bfd59c0 100644 --- a/eth/downloader/queue.go +++ b/eth/downloader/queue.go @@ -26,11 +26,11 @@ import ( "sync/atomic" "time" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/trie" @@ -93,7 +93,7 @@ type queue struct { stateTaskQueue *prque.Prque // [eth/63] Priority queue of the hashes to fetch the node data for statePendPool map[string]*fetchRequest // [eth/63] Currently pending node data retrieval operations - stateDatabase ethdb.Database // [eth/63] Trie database to populate during state reassembly + stateDatabase access.Database // [eth/63] Trie database to populate during state reassembly stateScheduler *state.StateSync // [eth/63] State trie synchronisation scheduler and integrator stateProcessors int32 // [eth/63] Number of currently running state processors stateSchedLock sync.RWMutex // [eth/63] Lock serialising access to the state scheduler @@ -105,7 +105,7 @@ type queue struct { } // newQueue creates a new download queue for scheduling block retrieval. -func newQueue(stateDb ethdb.Database) *queue { +func newQueue(stateDb access.Database) *queue { return &queue{ hashPool: make(map[common.Hash]int), hashQueue: prque.New(), diff --git a/eth/fetcher/fetcher_test.go b/eth/fetcher/fetcher_test.go index 2404c8cfa7..56409d9073 100644 --- a/eth/fetcher/fetcher_test.go +++ b/eth/fetcher/fetcher_test.go @@ -24,16 +24,16 @@ import ( "testing" "time" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/params" ) var ( - testdb, _ = ethdb.NewMemDatabase() + testdb, _ = access.NewMemDatabase() testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") testAddress = crypto.PubkeyToAddress(testKey.PublicKey) genesis = core.GenesisBlockForTesting(testdb, testAddress, big.NewInt(1000000000)) diff --git a/eth/filters/filter.go b/eth/filters/filter.go index 5bfd1beec2..fc745a49b4 100644 --- a/eth/filters/filter.go +++ b/eth/filters/filter.go @@ -19,12 +19,11 @@ package filters import ( "math" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/access" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/ethdb" ) type AccountChange struct { @@ -34,7 +33,7 @@ type AccountChange struct { // Filtering interface type Filter struct { ca *access.ChainAccess - db ethdb.Database + db access.Database begin, end int64 addresses []common.Address topics [][]common.Hash @@ -51,7 +50,7 @@ func New(ca *access.ChainAccess) *Filter { } // NewWithDb creates a filter with no ODR option -func NewWithDb(db ethdb.Database) *Filter { +func NewWithDb(db access.Database) *Filter { return &Filter{ca: access.NewDbChainAccess(db), db: db} } diff --git a/eth/filters/filter_test.go b/eth/filters/filter_test.go index 22e515aa87..713648b93f 100644 --- a/eth/filters/filter_test.go +++ b/eth/filters/filter_test.go @@ -6,12 +6,12 @@ import ( "os" "testing" + "github.com/ethereum/go-ethereum/access" "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/vm" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" ) func makeReceipt(addr common.Address) *types.Receipt { @@ -31,7 +31,7 @@ func BenchmarkMipmaps(b *testing.B) { defer os.RemoveAll(dir) var ( - db, _ = ethdb.NewLDBDatabase(dir, 16) + db, _ = access.NewLDBDatabase(dir, 16) key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") addr1 = crypto.PubkeyToAddress(key1.PublicKey) addr2 = common.BytesToAddress([]byte("jeff")) @@ -105,7 +105,7 @@ func TestFilters(t *testing.T) { defer os.RemoveAll(dir) var ( - db, _ = ethdb.NewLDBDatabase(dir, 16) + db, _ = access.NewLDBDatabase(dir, 16) key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") addr = crypto.PubkeyToAddress(key1.PublicKey) diff --git a/eth/handler.go b/eth/handler.go index c2e4ae17ab..3f5eb7755c 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -24,9 +24,9 @@ import ( "sync" "time" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/access" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/fetcher" @@ -292,7 +292,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { request.Amount = uint64(downloader.MaxHashFetch) } // Calculate the last block that should be retrieved, and short circuit if unavailable - last := pm.blockchain.GetBlockByNumber(request.Number+request.Amount-1) + last := pm.blockchain.GetBlockByNumber(request.Number + request.Amount - 1) if last == nil { last = pm.blockchain.CurrentBlock() request.Amount = last.NumberU64() - request.Number + 1 diff --git a/eth/handler_test.go b/eth/handler_test.go index a9a4a22a74..370c6541d1 100644 --- a/eth/handler_test.go +++ b/eth/handler_test.go @@ -6,14 +6,13 @@ import ( "math/rand" "testing" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/access" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth/downloader" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/params" ) @@ -62,14 +61,14 @@ func testGetBlockHashes(t *testing.T, protocol int) { number int result int }{ - {common.Hash{}, 1, 0}, // Make sure non existent hashes don't return results - {pm.blockchain.Genesis().Hash(), 1, 0}, // There are no hashes to retrieve up from the genesis - {pm.blockchain.GetBlockByNumber(5).Hash(), 5, 5}, // All the hashes including the genesis requested - {pm.blockchain.GetBlockByNumber(5).Hash(), 10, 5}, // More hashes than available till the genesis requested - {pm.blockchain.GetBlockByNumber(100).Hash(), 10, 10}, // All hashes available from the middle of the chain - {pm.blockchain.CurrentBlock().Hash(), 10, 10}, // All hashes available from the head of the chain - {pm.blockchain.CurrentBlock().Hash(), limit, limit}, // Request the maximum allowed hash count - {pm.blockchain.CurrentBlock().Hash(), limit + 1, limit}, // Request more than the maximum allowed hash count + {common.Hash{}, 1, 0}, // Make sure non existent hashes don't return results + {pm.blockchain.Genesis().Hash(), 1, 0}, // There are no hashes to retrieve up from the genesis + {pm.blockchain.GetBlockByNumber(5).Hash(), 5, 5}, // All the hashes including the genesis requested + {pm.blockchain.GetBlockByNumber(5).Hash(), 10, 5}, // More hashes than available till the genesis requested + {pm.blockchain.GetBlockByNumber(100).Hash(), 10, 10}, // All hashes available from the middle of the chain + {pm.blockchain.CurrentBlock().Hash(), 10, 10}, // All hashes available from the head of the chain + {pm.blockchain.CurrentBlock().Hash(), limit, limit}, // Request the maximum allowed hash count + {pm.blockchain.CurrentBlock().Hash(), limit + 1, limit}, // Request more than the maximum allowed hash count } // Run each of the tests and verify the results against the chain for i, tt := range tests { @@ -78,7 +77,7 @@ func testGetBlockHashes(t *testing.T, protocol int) { if len(resp) > 0 { from := pm.blockchain.GetBlock(tt.origin).NumberU64() - 1 for j := 0; j < len(resp); j++ { - resp[j] = pm.blockchain.GetBlockByNumber(uint64(int(from)-j)).Hash() + resp[j] = pm.blockchain.GetBlockByNumber(uint64(int(from) - j)).Hash() } } // Send the hash request and verify the response @@ -120,7 +119,7 @@ func testGetBlockHashesFromNumber(t *testing.T, protocol int) { // Assemble the hash response we would like to receive resp := make([]common.Hash, tt.result) for j := 0; j < len(resp); j++ { - resp[j] = pm.blockchain.GetBlockByNumber(tt.origin+uint64(j)).Hash() + resp[j] = pm.blockchain.GetBlockByNumber(tt.origin + uint64(j)).Hash() } // Send the hash request and verify the response p2p.Send(peer.app, 0x08, getBlockHashesFromNumberData{tt.origin, uint64(tt.number)}) @@ -222,42 +221,42 @@ func testGetBlockHeaders(t *testing.T, protocol int) { }{ // A single random block should be retrievable by hash and number too { - &getBlockHeadersData{Origin: hashOrNumber{Hash: pm.blockchain.GetBlockByNumber(limit/2).Hash()}, Amount: 1}, - []common.Hash{pm.blockchain.GetBlockByNumber(limit/2).Hash()}, + &getBlockHeadersData{Origin: hashOrNumber{Hash: pm.blockchain.GetBlockByNumber(limit / 2).Hash()}, Amount: 1}, + []common.Hash{pm.blockchain.GetBlockByNumber(limit / 2).Hash()}, }, { &getBlockHeadersData{Origin: hashOrNumber{Number: limit / 2}, Amount: 1}, - []common.Hash{pm.blockchain.GetBlockByNumber(limit/2).Hash()}, + []common.Hash{pm.blockchain.GetBlockByNumber(limit / 2).Hash()}, }, // Multiple headers should be retrievable in both directions { &getBlockHeadersData{Origin: hashOrNumber{Number: limit / 2}, Amount: 3}, []common.Hash{ - pm.blockchain.GetBlockByNumber(limit/2).Hash(), - pm.blockchain.GetBlockByNumber(limit/2+1).Hash(), - pm.blockchain.GetBlockByNumber(limit/2+2).Hash(), + pm.blockchain.GetBlockByNumber(limit / 2).Hash(), + pm.blockchain.GetBlockByNumber(limit/2 + 1).Hash(), + pm.blockchain.GetBlockByNumber(limit/2 + 2).Hash(), }, }, { &getBlockHeadersData{Origin: hashOrNumber{Number: limit / 2}, Amount: 3, Reverse: true}, []common.Hash{ - pm.blockchain.GetBlockByNumber(limit/2).Hash(), - pm.blockchain.GetBlockByNumber(limit/2-1).Hash(), - pm.blockchain.GetBlockByNumber(limit/2-2).Hash(), + pm.blockchain.GetBlockByNumber(limit / 2).Hash(), + pm.blockchain.GetBlockByNumber(limit/2 - 1).Hash(), + pm.blockchain.GetBlockByNumber(limit/2 - 2).Hash(), }, }, // Multiple headers with skip lists should be retrievable { &getBlockHeadersData{Origin: hashOrNumber{Number: limit / 2}, Skip: 3, Amount: 3}, []common.Hash{ - pm.blockchain.GetBlockByNumber(limit/2).Hash(), - pm.blockchain.GetBlockByNumber(limit/2+4).Hash(), - pm.blockchain.GetBlockByNumber(limit/2+8).Hash(), + pm.blockchain.GetBlockByNumber(limit / 2).Hash(), + pm.blockchain.GetBlockByNumber(limit/2 + 4).Hash(), + pm.blockchain.GetBlockByNumber(limit/2 + 8).Hash(), }, }, { &getBlockHeadersData{Origin: hashOrNumber{Number: limit / 2}, Skip: 3, Amount: 3, Reverse: true}, []common.Hash{ - pm.blockchain.GetBlockByNumber(limit/2).Hash(), - pm.blockchain.GetBlockByNumber(limit/2-4).Hash(), - pm.blockchain.GetBlockByNumber(limit/2-8).Hash(), + pm.blockchain.GetBlockByNumber(limit / 2).Hash(), + pm.blockchain.GetBlockByNumber(limit/2 - 4).Hash(), + pm.blockchain.GetBlockByNumber(limit/2 - 8).Hash(), }, }, // The chain endpoints should be retrievable @@ -277,7 +276,7 @@ func testGetBlockHeaders(t *testing.T, protocol int) { { &getBlockHeadersData{Origin: hashOrNumber{Number: pm.blockchain.CurrentBlock().NumberU64() - 4}, Skip: 3, Amount: 3}, []common.Hash{ - pm.blockchain.GetBlockByNumber(pm.blockchain.CurrentBlock().NumberU64()-4).Hash(), + pm.blockchain.GetBlockByNumber(pm.blockchain.CurrentBlock().NumberU64() - 4).Hash(), pm.blockchain.GetBlockByNumber(pm.blockchain.CurrentBlock().NumberU64()).Hash(), }, }, { @@ -291,8 +290,8 @@ func testGetBlockHeaders(t *testing.T, protocol int) { { &getBlockHeadersData{Origin: hashOrNumber{Number: pm.blockchain.CurrentBlock().NumberU64() - 4}, Skip: 2, Amount: 3}, []common.Hash{ - pm.blockchain.GetBlockByNumber(pm.blockchain.CurrentBlock().NumberU64()-4).Hash(), - pm.blockchain.GetBlockByNumber(pm.blockchain.CurrentBlock().NumberU64()-1).Hash(), + pm.blockchain.GetBlockByNumber(pm.blockchain.CurrentBlock().NumberU64() - 4).Hash(), + pm.blockchain.GetBlockByNumber(pm.blockchain.CurrentBlock().NumberU64() - 1).Hash(), }, }, { &getBlockHeadersData{Origin: hashOrNumber{Number: 4}, Skip: 2, Amount: 3, Reverse: true}, @@ -442,7 +441,7 @@ func testGetNodeData(t *testing.T, protocol int) { // Fetch for now the entire chain db hashes := []common.Hash{} - for _, key := range pm.chainAccess.Db().(*ethdb.MemDatabase).Keys() { + for _, key := range pm.chainAccess.Db().(*access.MemDatabase).Keys() { if len(key) == len(common.Hash{}) { hashes = append(hashes, common.BytesToHash(key)) } @@ -465,7 +464,7 @@ func testGetNodeData(t *testing.T, protocol int) { fmt.Errorf("data hash mismatch: have %x, want %x", hash, want) } } - statedb, _ := ethdb.NewMemDatabase() + statedb, _ := access.NewMemDatabase() for i := 0; i < len(data); i++ { statedb.Put(hashes[i].Bytes(), data[i]) } diff --git a/eth/helper_test.go b/eth/helper_test.go index 875cc50217..a48afcc834 100644 --- a/eth/helper_test.go +++ b/eth/helper_test.go @@ -9,12 +9,11 @@ import ( "sync" "testing" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/access" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p/discover" @@ -33,7 +32,7 @@ func newTestProtocolManager(fastSync bool, blocks int, generator func(int, *core var ( evmux = new(event.TypeMux) pow = new(core.FakePow) - db, _ = ethdb.NewMemDatabase() + db, _ = access.NewMemDatabase() ca = access.NewDbChainAccess(db) genesis = core.WriteGenesisBlockForTesting(db, core.GenesisAccount{testBankAddress, testBankFunds}) blockchain, _ = core.NewBlockChain(ca, pow, evmux) diff --git a/jsre/jsre.go b/jsre/jsre.go index af7d507c6d..7d8b028ed6 100644 --- a/jsre/jsre.go +++ b/jsre/jsre.go @@ -154,7 +154,7 @@ loop: if err != nil { fmt.Println("js error:", err, arguments) } - + _, inreg := registry[timer] // when clearInterval is called from within the callback don't reset it if timer.interval && inreg { timer.timer.Reset(timer.duration) diff --git a/miner/worker.go b/miner/worker.go index 99ba7719f5..a37ba5414b 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -24,13 +24,13 @@ import ( "sync/atomic" "time" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" "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/event" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" @@ -101,7 +101,7 @@ type worker struct { eth core.Backend chain *core.BlockChain proc *core.BlockProcessor - chainDb ethdb.Database + chainDb access.Database coinbase common.Address gasPrice *big.Int diff --git a/rpc/codec/json.go b/rpc/codec/json.go index cfc449143b..f5d1b1c814 100644 --- a/rpc/codec/json.go +++ b/rpc/codec/json.go @@ -20,8 +20,8 @@ import ( "encoding/json" "fmt" "net" - "time" "strings" + "time" "github.com/ethereum/go-ethereum/rpc/shared" ) diff --git a/rpc/comms/comms.go b/rpc/comms/comms.go index b21be624cc..492a65d727 100644 --- a/rpc/comms/comms.go +++ b/rpc/comms/comms.go @@ -17,14 +17,14 @@ package comms import ( + "fmt" "io" "net" - "fmt" - "strings" "strconv" + "strings" "time" - "github.com/ethereum/go-ethereum/core/access" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/rpc/codec" diff --git a/rpc/comms/http.go b/rpc/comms/http.go index 67b3653c11..82d2d31b86 100644 --- a/rpc/comms/http.go +++ b/rpc/comms/http.go @@ -29,7 +29,7 @@ import ( "io" "io/ioutil" - "github.com/ethereum/go-ethereum/core/access" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/rpc/codec" @@ -66,16 +66,16 @@ type stopServer struct { } type handler struct { - codec codec.Codec - api shared.EthereumApi - channelID *access.OdrChannelID + codec codec.Codec + api shared.EthereumApi + channelID *access.OdrChannelID } // StartHTTP starts listening for RPC requests sent via HTTP. func StartHttp(cfg HttpConfig, codec codec.Codec, api shared.EthereumApi) error { httpServerMu.Lock() defer httpServerMu.Unlock() - + addr := fmt.Sprintf("%s:%d", cfg.ListenAddress, cfg.ListenPort) if httpServer != nil { if addr != httpServer.Addr { diff --git a/rpc/comms/inproc.go b/rpc/comms/inproc.go index aa2b9074d0..d6725b045f 100644 --- a/rpc/comms/inproc.go +++ b/rpc/comms/inproc.go @@ -20,7 +20,7 @@ import ( "fmt" "time" - "github.com/ethereum/go-ethereum/core/access" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/rpc/codec" "github.com/ethereum/go-ethereum/rpc/shared" ) @@ -32,13 +32,13 @@ type InProcClient struct { lastJsonrpc string lastErr error lastRes interface{} - channelID *access.OdrChannelID + channelID *access.OdrChannelID } // Create a new in process client func NewInProcClient(codec codec.Codec) *InProcClient { return &InProcClient{ - codec: codec, + codec: codec, channelID: access.NewChannelID(time.Second), } } diff --git a/rpc/shared/types.go b/rpc/shared/types.go index 64eae1a846..1e5db461ef 100644 --- a/rpc/shared/types.go +++ b/rpc/shared/types.go @@ -47,7 +47,7 @@ type Request struct { Jsonrpc string `json:"jsonrpc"` Method string `json:"method"` Params json.RawMessage `json:"params"` - ctx context.Context + ctx context.Context } // RPC response diff --git a/tests/block_test_util.go b/tests/block_test_util.go index 8017eea082..1ae940699c 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -28,15 +28,14 @@ import ( "strings" "time" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/access" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/rlp" ) @@ -165,13 +164,13 @@ func runBlockTests(bt map[string]*BlockTest, skipTests []string) error { func runBlockTest(test *BlockTest) error { ks := crypto.NewKeyStorePassphrase(filepath.Join(common.DefaultDataDir(), "keystore"), crypto.StandardScryptN, crypto.StandardScryptP) am := accounts.NewManager(ks) - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() cfg := ð.Config{ DataDir: common.DefaultDataDir(), Verbosity: 5, Etherbase: common.Address{}, AccountManager: am, - NewDB: func(path string) (ethdb.Database, error) { return db, nil }, + NewDB: func(path string) (access.Database, error) { return db, nil }, } cfg.GenesisBlock = test.Genesis @@ -217,7 +216,7 @@ func runBlockTest(test *BlockTest) error { // InsertPreState populates the given database with the genesis // accounts defined by the test. -func (t *BlockTest) InsertPreState(db ethdb.Database, am *accounts.Manager) (*state.StateDB, error) { +func (t *BlockTest) InsertPreState(db access.Database, am *accounts.Manager) (*state.StateDB, error) { statedb, err := state.New(common.Hash{}, access.NewDbChainAccess(db)) if err != nil { return nil, err diff --git a/tests/state_test_util.go b/tests/state_test_util.go index d2016f3e37..cbdaa849b6 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -25,13 +25,12 @@ import ( "strconv" "testing" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/access" "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/ethdb" "github.com/ethereum/go-ethereum/logger/glog" ) @@ -103,7 +102,7 @@ func BenchStateTest(p string, conf bconf, b *testing.B) error { func benchStateTest(test VmTest, env map[string]string, b *testing.B) { b.StopTimer() - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() statedb, _ := state.New(common.Hash{}, access.NewDbChainAccess(db)) for addr, account := range test.Pre { obj := StateObjectFromAccount(db, addr, account) @@ -142,7 +141,7 @@ func runStateTests(tests map[string]VmTest, skipTests []string) error { } func runStateTest(test VmTest) error { - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() statedb, _ := state.New(common.Hash{}, access.NewDbChainAccess(db)) for addr, account := range test.Pre { obj := StateObjectFromAccount(db, addr, account) diff --git a/tests/util.go b/tests/util.go index 8a2f6f9630..81afc32e25 100644 --- a/tests/util.go +++ b/tests/util.go @@ -21,14 +21,13 @@ import ( "fmt" "math/big" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/access" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" ) func checkLogs(tlog []Log, logs vm.Logs) error { @@ -89,7 +88,7 @@ func (self Log) Topics() [][]byte { return t } -func StateObjectFromAccount(db ethdb.Database, addr string, account Account) *state.StateObject { +func StateObjectFromAccount(db access.Database, addr string, account Account) *state.StateObject { obj := state.NewStateObject(access.NoOdr, common.HexToAddress(addr), access.NewDbChainAccess(db)) obj.SetBalance(common.Big(account.Balance)) diff --git a/tests/vm_test_util.go b/tests/vm_test_util.go index f6c6c4996d..4a2a2fc350 100644 --- a/tests/vm_test_util.go +++ b/tests/vm_test_util.go @@ -24,11 +24,10 @@ import ( "strconv" "testing" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/access" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/logger/glog" ) @@ -108,7 +107,7 @@ func BenchVmTest(p string, conf bconf, b *testing.B) error { func benchVmTest(test VmTest, env map[string]string, b *testing.B) { b.StopTimer() - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() statedb, _ := state.New(common.Hash{}, access.NewDbChainAccess(db)) for addr, account := range test.Pre { obj := StateObjectFromAccount(db, addr, account) @@ -159,7 +158,7 @@ func runVmTests(tests map[string]VmTest, skipTests []string) error { } func runVmTest(test VmTest) error { - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() statedb, _ := state.New(common.Hash{}, access.NewDbChainAccess(db)) for addr, account := range test.Pre { obj := StateObjectFromAccount(db, addr, account) diff --git a/trie/proof_test.go b/trie/proof_test.go index 6738a50bcf..ecb53826bc 100644 --- a/trie/proof_test.go +++ b/trie/proof_test.go @@ -7,8 +7,8 @@ import ( "testing" "time" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/rlp" ) @@ -37,7 +37,7 @@ func TestProof(t *testing.T) { func TestStoreProof(t *testing.T) { trie, vals := randomTrie(500) root := trie.Hash() - mdb, _ := ethdb.NewMemDatabase() + mdb, _ := access.NewMemDatabase() for _, kv := range vals { proof := trie.Prove(kv.k) if proof == nil { diff --git a/trie/secure_trie.go b/trie/secure_trie.go index 3d944ed772..b20637b48f 100644 --- a/trie/secure_trie.go +++ b/trie/secure_trie.go @@ -19,8 +19,8 @@ package trie import ( "hash" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/access" "github.com/ethereum/go-ethereum/crypto/sha3" "golang.org/x/net/context" ) @@ -71,9 +71,9 @@ func NewSecureOdr(ctx context.Context, root common.Hash, db Database, access Odr // CopySecureWithOdr creates a copy of a trie with additional ODR capability func (t *SecureTrie) CopySecureWithOdr(ctx context.Context, access OdrAccess) *SecureTrie { return &SecureTrie{ - Trie: t.Trie.CopyWithOdr(ctx, access), - hash: t.hash, - secKeyBuf: t.secKeyBuf, + Trie: t.Trie.CopyWithOdr(ctx, access), + hash: t.hash, + secKeyBuf: t.secKeyBuf, hashKeyBuf: t.hashKeyBuf, } } diff --git a/trie/secure_trie_test.go b/trie/secure_trie_test.go index 13c6cd02e9..c070363cdc 100644 --- a/trie/secure_trie_test.go +++ b/trie/secure_trie_test.go @@ -20,13 +20,13 @@ import ( "bytes" "testing" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" ) func newEmptySecure() *SecureTrie { - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() trie, _ := NewSecure(common.Hash{}, db) return trie } diff --git a/trie/sync.go b/trie/sync.go index d55399d06b..9854466a40 100644 --- a/trie/sync.go +++ b/trie/sync.go @@ -19,8 +19,8 @@ package trie import ( "fmt" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" "gopkg.in/karalabe/cookiejar.v2/collections/prque" ) @@ -53,13 +53,13 @@ type TrieSyncLeafCallback func(leaf []byte, parent common.Hash) error // unknown trie hashes to retrieve, accepts node data associated with said hashes // and reconstructs the trie step by step until all is done. type TrieSync struct { - database ethdb.Database // State database for storing all the assembled node data + database access.Database // State database for storing all the assembled node data requests map[common.Hash]*request // Pending requests pertaining to a key hash queue *prque.Prque // Priority queue with the pending requests } // NewTrieSync creates a new trie data download scheduler. -func NewTrieSync(root common.Hash, database ethdb.Database, callback TrieSyncLeafCallback) *TrieSync { +func NewTrieSync(root common.Hash, database access.Database, callback TrieSyncLeafCallback) *TrieSync { ts := &TrieSync{ database: database, requests: make(map[common.Hash]*request), @@ -258,7 +258,7 @@ func (s *TrieSync) children(req *request) ([]*request, error) { // commit finalizes a retrieval request and stores it into the database. If any // of the referencing parent requests complete due to this commit, they are also // committed themselves. -func (s *TrieSync) commit(req *request, batch ethdb.Batch) (err error) { +func (s *TrieSync) commit(req *request, batch access.Batch) (err error) { // Create a new batch if none was specified if batch == nil { batch = s.database.NewBatch() diff --git a/trie/sync_test.go b/trie/sync_test.go index 9c036a3a92..0ba2a5d26b 100644 --- a/trie/sync_test.go +++ b/trie/sync_test.go @@ -20,14 +20,14 @@ import ( "bytes" "testing" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" ) // makeTestTrie create a sample test trie to test node-wise reconstruction. -func makeTestTrie() (ethdb.Database, *Trie, map[string][]byte) { +func makeTestTrie() (access.Database, *Trie, map[string][]byte) { // Create an empty trie - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() trie, _ := New(common.Hash{}, db) // Fill it with some arbitrary data @@ -67,7 +67,7 @@ func TestEmptyTrieSync(t *testing.T) { emptyB, _ := New(emptyRoot, nil) for i, trie := range []*Trie{emptyA, emptyB} { - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() if req := NewTrieSync(common.BytesToHash(trie.Root()), db, nil).Missing(1); len(req) != 0 { t.Errorf("test %d: content requested for empty trie: %v", i, req) } @@ -84,7 +84,7 @@ func testIterativeTrieSync(t *testing.T, batch int) { srcDb, srcTrie, srcData := makeTestTrie() // Create a destination trie and sync with the scheduler - dstDb, _ := ethdb.NewMemDatabase() + dstDb, _ := access.NewMemDatabase() sched := NewTrieSync(common.BytesToHash(srcTrie.Root()), dstDb, nil) queue := append([]common.Hash{}, sched.Missing(batch)...) @@ -113,7 +113,7 @@ func TestIterativeDelayedTrieSync(t *testing.T) { srcDb, srcTrie, srcData := makeTestTrie() // Create a destination trie and sync with the scheduler - dstDb, _ := ethdb.NewMemDatabase() + dstDb, _ := access.NewMemDatabase() sched := NewTrieSync(common.BytesToHash(srcTrie.Root()), dstDb, nil) queue := append([]common.Hash{}, sched.Missing(10000)...) @@ -147,7 +147,7 @@ func testIterativeRandomTrieSync(t *testing.T, batch int) { srcDb, srcTrie, srcData := makeTestTrie() // Create a destination trie and sync with the scheduler - dstDb, _ := ethdb.NewMemDatabase() + dstDb, _ := access.NewMemDatabase() sched := NewTrieSync(common.BytesToHash(srcTrie.Root()), dstDb, nil) queue := make(map[common.Hash]struct{}) @@ -184,7 +184,7 @@ func TestIterativeRandomDelayedTrieSync(t *testing.T) { srcDb, srcTrie, srcData := makeTestTrie() // Create a destination trie and sync with the scheduler - dstDb, _ := ethdb.NewMemDatabase() + dstDb, _ := access.NewMemDatabase() sched := NewTrieSync(common.BytesToHash(srcTrie.Root()), dstDb, nil) queue := make(map[common.Hash]struct{}) @@ -227,7 +227,7 @@ func TestDuplicateAvoidanceTrieSync(t *testing.T) { srcDb, srcTrie, srcData := makeTestTrie() // Create a destination trie and sync with the scheduler - dstDb, _ := ethdb.NewMemDatabase() + dstDb, _ := access.NewMemDatabase() sched := NewTrieSync(common.BytesToHash(srcTrie.Root()), dstDb, nil) queue := append([]common.Hash{}, sched.Missing(0)...) diff --git a/trie/trie.go b/trie/trie.go index fabb7468b3..e9d4fc29ae 100644 --- a/trie/trie.go +++ b/trie/trie.go @@ -23,8 +23,8 @@ import ( "fmt" "hash" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/access" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto/sha3" "github.com/ethereum/go-ethereum/logger" @@ -54,7 +54,7 @@ var ErrMissingRoot = errors.New("missing root node") // OdrAccess is an interface to on-demand network access layer type OdrAccess interface { - OdrEnabled() bool // is network access actually enabled + OdrEnabled() bool // is network access actually enabled RetrieveKey(ctx context.Context, key []byte) bool // retrieve key from network and store it in local db } @@ -82,7 +82,7 @@ type Trie struct { root node db Database access OdrAccess - ctx context.Context + ctx context.Context *hasher } @@ -388,8 +388,8 @@ func (t *Trie) CommitTo(db DatabaseWriter) (root common.Hash, err error) { if access.Terminated(t.ctx) { // we should never commit potentially corrupt trie nodes to the db return common.Hash{}, t.ctx.Err() - } - + } + n, err := t.hashRoot(db) if err != nil { return (common.Hash{}), err diff --git a/trie/trie_test.go b/trie/trie_test.go index c96861bedb..61e457e998 100644 --- a/trie/trie_test.go +++ b/trie/trie_test.go @@ -25,8 +25,8 @@ import ( "testing" "github.com/davecgh/go-spew/spew" + "github.com/ethereum/go-ethereum/access" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" ) func init() { @@ -36,7 +36,7 @@ func init() { // Used for testing func newEmpty() *Trie { - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() trie, _ := New(common.Hash{}, db) return trie } @@ -59,7 +59,7 @@ func TestNull(t *testing.T) { } func TestMissingRoot(t *testing.T) { - db, _ := ethdb.NewMemDatabase() + db, _ := access.NewMemDatabase() trie, err := New(common.HexToHash("0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"), db) if trie != nil { t.Error("New returned non-nil trie for invalid root") @@ -388,7 +388,7 @@ func tempDB() (string, Database) { if err != nil { panic(fmt.Sprintf("can't create temporary directory: %v", err)) } - db, err := ethdb.NewLDBDatabase(dir, 300*1024) + db, err := access.NewLDBDatabase(dir, 300*1024) if err != nil { panic(fmt.Sprintf("can't create temporary database: %v", err)) } diff --git a/xeth/xeth.go b/xeth/xeth.go index 6b1ac15a76..75ca91838e 100644 --- a/xeth/xeth.go +++ b/xeth/xeth.go @@ -85,7 +85,7 @@ type XEth struct { state *State whisper *Whisper filterManager *filters.FilterSystem - ctx context.Context + ctx context.Context } func NewTest(eth *eth.Ethereum, frontend Frontend) *XEth {