mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-24 13:46:43 +00:00
light core refactoring
This commit is contained in:
parent
0ceb181030
commit
e5e1e6ffaf
82 changed files with 660 additions and 1219 deletions
2
Godeps/_workspace/src/github.com/rcrowley/go-metrics/ewma.go
generated
vendored
2
Godeps/_workspace/src/github.com/rcrowley/go-metrics/ewma.go
generated
vendored
|
|
@ -77,7 +77,7 @@ func (NilEWMA) Update(n int64) {}
|
||||||
// of uncounted events and processes them on each tick. It uses the
|
// of uncounted events and processes them on each tick. It uses the
|
||||||
// sync/atomic package to manage uncounted events.
|
// sync/atomic package to manage uncounted events.
|
||||||
type StandardEWMA struct {
|
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
|
alpha float64
|
||||||
rate float64
|
rate float64
|
||||||
init bool
|
init bool
|
||||||
|
|
|
||||||
2
Godeps/_workspace/src/github.com/rcrowley/go-metrics/graphite_test.go
generated
vendored
2
Godeps/_workspace/src/github.com/rcrowley/go-metrics/graphite_test.go
generated
vendored
|
|
@ -17,6 +17,6 @@ func ExampleGraphiteWithConfig() {
|
||||||
Registry: DefaultRegistry,
|
Registry: DefaultRegistry,
|
||||||
FlushInterval: 1 * time.Second,
|
FlushInterval: 1 * time.Second,
|
||||||
DurationUnit: time.Millisecond,
|
DurationUnit: time.Millisecond,
|
||||||
Percentiles: []float64{ 0.5, 0.75, 0.99, 0.999 },
|
Percentiles: []float64{0.5, 0.75, 0.99, 0.999},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
1
Godeps/_workspace/src/github.com/rcrowley/go-metrics/opentsdb_test.go
generated
vendored
1
Godeps/_workspace/src/github.com/rcrowley/go-metrics/opentsdb_test.go
generated
vendored
|
|
@ -19,4 +19,3 @@ func ExampleOpenTSDBWithConfig() {
|
||||||
DurationUnit: time.Millisecond,
|
DurationUnit: time.Millisecond,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
2
Godeps/_workspace/src/github.com/robertkrimen/otto/dbg/dbg.go
generated
vendored
2
Godeps/_workspace/src/github.com/robertkrimen/otto/dbg/dbg.go
generated
vendored
|
|
@ -282,7 +282,7 @@ func (self *Dbgr) getEmit() _emit {
|
||||||
// SetOutput will accept the following as a destination for output:
|
// SetOutput will accept the following as a destination for output:
|
||||||
//
|
//
|
||||||
// *log.Logger Print*/Panic*/Fatal* of the logger
|
// *log.Logger Print*/Panic*/Fatal* of the logger
|
||||||
// io.Writer -
|
// io.Writer -
|
||||||
// nil Reset to the default output (os.Stderr)
|
// nil Reset to the default output (os.Stderr)
|
||||||
// "log" Print*/Panic*/Fatal* via the "log" package
|
// "log" Print*/Panic*/Fatal* via the "log" package
|
||||||
//
|
//
|
||||||
|
|
|
||||||
1
Godeps/_workspace/src/github.com/robertkrimen/otto/underscore/source.go
generated
vendored
1
Godeps/_workspace/src/github.com/robertkrimen/otto/underscore/source.go
generated
vendored
|
|
@ -3456,6 +3456,7 @@ func underscore() []byte {
|
||||||
0x69, 0x73, 0x29, 0x3b, 0x0a,
|
0x69, 0x73, 0x29, 0x3b, 0x0a,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Underscore.js 1.4.4
|
// Underscore.js 1.4.4
|
||||||
// http://underscorejs.org
|
// http://underscorejs.org
|
||||||
// (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
|
// (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
|
||||||
|
|
|
||||||
2
Godeps/_workspace/src/gopkg.in/check.v1/benchmark_test.go
generated
vendored
2
Godeps/_workspace/src/gopkg.in/check.v1/benchmark_test.go
generated
vendored
|
|
@ -3,8 +3,8 @@
|
||||||
package check_test
|
package check_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
|
||||||
. "gopkg.in/check.v1"
|
. "gopkg.in/check.v1"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var benchmarkS = Suite(&BenchmarkS{})
|
var benchmarkS = Suite(&BenchmarkS{})
|
||||||
|
|
|
||||||
145
Godeps/_workspace/src/gopkg.in/check.v1/printer_test.go
generated
vendored
145
Godeps/_workspace/src/gopkg.in/check.v1/printer_test.go
generated
vendored
|
|
@ -1,7 +1,7 @@
|
||||||
package check_test
|
package check_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
. "gopkg.in/check.v1"
|
. "gopkg.in/check.v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = Suite(&PrinterS{})
|
var _ = Suite(&PrinterS{})
|
||||||
|
|
@ -9,96 +9,101 @@ var _ = Suite(&PrinterS{})
|
||||||
type PrinterS struct{}
|
type PrinterS struct{}
|
||||||
|
|
||||||
func (s *PrinterS) TestCountSuite(c *C) {
|
func (s *PrinterS) TestCountSuite(c *C) {
|
||||||
suitesRun += 1
|
suitesRun += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
var printTestFuncLine int
|
var printTestFuncLine int
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
printTestFuncLine = getMyLine() + 3
|
printTestFuncLine = getMyLine() + 3
|
||||||
}
|
}
|
||||||
|
|
||||||
func printTestFunc() {
|
func printTestFunc() {
|
||||||
println(1) // Comment1
|
println(1) // Comment1
|
||||||
if 2 == 2 { // Comment2
|
if 2 == 2 { // Comment2
|
||||||
println(3) // Comment3
|
println(3) // Comment3
|
||||||
}
|
}
|
||||||
switch 5 {
|
switch 5 {
|
||||||
case 6: println(6) // Comment6
|
case 6:
|
||||||
println(7)
|
println(6) // Comment6
|
||||||
}
|
println(7)
|
||||||
switch interface{}(9).(type) {// Comment9
|
}
|
||||||
case int: println(10)
|
switch interface{}(9).(type) { // Comment9
|
||||||
println(11)
|
case int:
|
||||||
}
|
println(10)
|
||||||
select {
|
println(11)
|
||||||
case <-(chan bool)(nil): println(14)
|
}
|
||||||
println(15)
|
select {
|
||||||
default: println(16)
|
case <-(chan bool)(nil):
|
||||||
println(17)
|
println(14)
|
||||||
}
|
println(15)
|
||||||
println(19,
|
default:
|
||||||
20)
|
println(16)
|
||||||
_ = func() { println(21)
|
println(17)
|
||||||
println(22)
|
}
|
||||||
}
|
println(19,
|
||||||
println(24, func() {
|
20)
|
||||||
println(25)
|
_ = func() {
|
||||||
})
|
println(21)
|
||||||
// Leading comment
|
println(22)
|
||||||
// with multiple lines.
|
}
|
||||||
println(29) // Comment29
|
println(24, func() {
|
||||||
|
println(25)
|
||||||
|
})
|
||||||
|
// Leading comment
|
||||||
|
// with multiple lines.
|
||||||
|
println(29) // Comment29
|
||||||
}
|
}
|
||||||
|
|
||||||
var printLineTests = []struct {
|
var printLineTests = []struct {
|
||||||
line int
|
line int
|
||||||
output string
|
output string
|
||||||
}{
|
}{
|
||||||
{1, "println(1) // Comment1"},
|
{1, "println(1) // Comment1"},
|
||||||
{2, "if 2 == 2 { // Comment2\n ...\n}"},
|
{2, "if 2 == 2 { // Comment2\n ...\n}"},
|
||||||
{3, "println(3) // Comment3"},
|
{3, "println(3) // Comment3"},
|
||||||
{5, "switch 5 {\n...\n}"},
|
{5, "switch 5 {\n...\n}"},
|
||||||
{6, "case 6:\n println(6) // Comment6\n ..."},
|
{6, "case 6:\n println(6) // Comment6\n ..."},
|
||||||
{7, "println(7)"},
|
{7, "println(7)"},
|
||||||
{9, "switch interface{}(9).(type) { // Comment9\n...\n}"},
|
{9, "switch interface{}(9).(type) { // Comment9\n...\n}"},
|
||||||
{10, "case int:\n println(10)\n ..."},
|
{10, "case int:\n println(10)\n ..."},
|
||||||
{14, "case <-(chan bool)(nil):\n println(14)\n ..."},
|
{14, "case <-(chan bool)(nil):\n println(14)\n ..."},
|
||||||
{15, "println(15)"},
|
{15, "println(15)"},
|
||||||
{16, "default:\n println(16)\n ..."},
|
{16, "default:\n println(16)\n ..."},
|
||||||
{17, "println(17)"},
|
{17, "println(17)"},
|
||||||
{19, "println(19,\n 20)"},
|
{19, "println(19,\n 20)"},
|
||||||
{20, "println(19,\n 20)"},
|
{20, "println(19,\n 20)"},
|
||||||
{21, "_ = func() {\n println(21)\n println(22)\n}"},
|
{21, "_ = func() {\n println(21)\n println(22)\n}"},
|
||||||
{22, "println(22)"},
|
{22, "println(22)"},
|
||||||
{24, "println(24, func() {\n println(25)\n})"},
|
{24, "println(24, func() {\n println(25)\n})"},
|
||||||
{25, "println(25)"},
|
{25, "println(25)"},
|
||||||
{26, "println(24, func() {\n println(25)\n})"},
|
{26, "println(24, func() {\n println(25)\n})"},
|
||||||
{29, "// Leading comment\n// with multiple lines.\nprintln(29) // Comment29"},
|
{29, "// Leading comment\n// with multiple lines.\nprintln(29) // Comment29"},
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *PrinterS) TestPrintLine(c *C) {
|
func (s *PrinterS) TestPrintLine(c *C) {
|
||||||
for _, test := range printLineTests {
|
for _, test := range printLineTests {
|
||||||
output, err := PrintLine("printer_test.go", printTestFuncLine+test.line)
|
output, err := PrintLine("printer_test.go", printTestFuncLine+test.line)
|
||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
c.Assert(output, Equals, test.output)
|
c.Assert(output, Equals, test.output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var indentTests = []struct {
|
var indentTests = []struct {
|
||||||
in, out string
|
in, out string
|
||||||
}{
|
}{
|
||||||
{"", ""},
|
{"", ""},
|
||||||
{"\n", "\n"},
|
{"\n", "\n"},
|
||||||
{"a", ">>>a"},
|
{"a", ">>>a"},
|
||||||
{"a\n", ">>>a\n"},
|
{"a\n", ">>>a\n"},
|
||||||
{"a\nb", ">>>a\n>>>b"},
|
{"a\nb", ">>>a\n>>>b"},
|
||||||
{" ", ">>> "},
|
{" ", ">>> "},
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *PrinterS) TestIndent(c *C) {
|
func (s *PrinterS) TestIndent(c *C) {
|
||||||
for _, test := range indentTests {
|
for _, test := range indentTests {
|
||||||
out := Indent(test.in, ">>>")
|
out := Indent(test.in, ">>>")
|
||||||
c.Assert(out, Equals, test.out)
|
c.Assert(out, Equals, test.out)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
4
Godeps/_workspace/src/gopkg.in/check.v1/run_test.go
generated
vendored
4
Godeps/_workspace/src/gopkg.in/check.v1/run_test.go
generated
vendored
|
|
@ -400,7 +400,7 @@ func (s *RunS) TestStreamModeWithMiss(c *C) {
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
// Verify that that the keep work dir request indeed does so.
|
// Verify that that the keep work dir request indeed does so.
|
||||||
|
|
||||||
type WorkDirSuite struct {}
|
type WorkDirSuite struct{}
|
||||||
|
|
||||||
func (s *WorkDirSuite) Test(c *C) {
|
func (s *WorkDirSuite) Test(c *C) {
|
||||||
c.MkDir()
|
c.MkDir()
|
||||||
|
|
@ -411,7 +411,7 @@ func (s *RunS) TestKeepWorkDir(c *C) {
|
||||||
runConf := RunConf{Output: &output, Verbose: true, KeepWorkDir: true}
|
runConf := RunConf{Output: &output, Verbose: true, KeepWorkDir: true}
|
||||||
result := Run(&WorkDirSuite{}, &runConf)
|
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)
|
stat, err := os.Stat(result.WorkDir)
|
||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
|
|
|
||||||
0
ethdb/.gitignore → access/.gitignore
vendored
0
ethdb/.gitignore → access/.gitignore
vendored
|
|
@ -14,7 +14,7 @@
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
package ethdb
|
package access
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
package ethdb
|
package access
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
package ethdb
|
package access
|
||||||
|
|
||||||
type Database interface {
|
type Database interface {
|
||||||
Put(key []byte, value []byte) error
|
Put(key []byte, value []byte) error
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
package ethdb
|
package access
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
84
access/odr.go
Normal file
84
access/odr.go
Normal file
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
@ -25,14 +25,13 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/codegangsta/cli"
|
"github.com/codegangsta/cli"
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"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/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -113,7 +112,7 @@ func run(ctx *cli.Context) {
|
||||||
glog.SetToStderr(true)
|
glog.SetToStderr(true)
|
||||||
glog.SetV(ctx.GlobalInt(VerbosityFlag.Name))
|
glog.SetV(ctx.GlobalInt(VerbosityFlag.Name))
|
||||||
|
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
statedb, _ := state.New(common.Hash{}, access.NewDbChainAccess(db))
|
statedb, _ := state.New(common.Hash{}, access.NewDbChainAccess(db))
|
||||||
sender := statedb.CreateAccount(common.StringToAddress("sender"))
|
sender := statedb.CreateAccount(common.StringToAddress("sender"))
|
||||||
receiver := statedb.CreateAccount(common.StringToAddress("receiver"))
|
receiver := statedb.CreateAccount(common.StringToAddress("receiver"))
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,9 @@ import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/codegangsta/cli"
|
"github.com/codegangsta/cli"
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||||
"github.com/ethereum/go-ethereum/eth"
|
"github.com/ethereum/go-ethereum/eth"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/tests"
|
"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) {
|
func runOneBlockTest(ctx *cli.Context, test *tests.BlockTest) (*eth.Ethereum, error) {
|
||||||
cfg := utils.MakeEthConfig(ClientIdentifier, Version, ctx)
|
cfg := utils.MakeEthConfig(ClientIdentifier, Version, ctx)
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
cfg.NewDB = func(path string) (ethdb.Database, error) { return db, nil }
|
cfg.NewDB = func(path string) (access.Database, error) { return db, nil }
|
||||||
cfg.MaxPeers = 0 // disable network
|
cfg.MaxPeers = 0 // disable network
|
||||||
cfg.Shh = false // disable whisper
|
cfg.Shh = false // disable whisper
|
||||||
cfg.NAT = nil // disable port mapping
|
cfg.NAT = nil // disable port mapping
|
||||||
|
|
|
||||||
|
|
@ -24,13 +24,12 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/codegangsta/cli"
|
"github.com/codegangsta/cli"
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"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/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -197,7 +196,7 @@ func hashish(x string) bool {
|
||||||
return err != nil
|
return err != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func closeAll(dbs ...ethdb.Database) {
|
func closeAll(dbs ...access.Database) {
|
||||||
for _, db := range dbs {
|
for _, db := range dbs {
|
||||||
db.Close()
|
db.Close()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/compiler"
|
"github.com/ethereum/go-ethereum/common/compiler"
|
||||||
|
|
@ -37,7 +38,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/eth"
|
"github.com/ethereum/go-ethereum/eth"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/rpc/codec"
|
"github.com/ethereum/go-ethereum/rpc/codec"
|
||||||
"github.com/ethereum/go-ethereum/rpc/comms"
|
"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)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
|
|
||||||
core.WriteGenesisBlockForTesting(db, core.GenesisAccount{common.HexToAddress(testAddress), common.String2Big(testBalance)})
|
core.WriteGenesisBlockForTesting(db, core.GenesisAccount{common.HexToAddress(testAddress), common.String2Big(testBalance)})
|
||||||
ks := crypto.NewKeyStorePlain(filepath.Join(tmp, "keystore"))
|
ks := crypto.NewKeyStorePlain(filepath.Join(tmp, "keystore"))
|
||||||
|
|
@ -104,7 +104,7 @@ func testREPL(t *testing.T, config func(*eth.Config)) (string, *testjethre, *eth
|
||||||
DocRoot: "/",
|
DocRoot: "/",
|
||||||
SolcPath: testSolcPath,
|
SolcPath: testSolcPath,
|
||||||
PowTest: true,
|
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 {
|
if config != nil {
|
||||||
config(conf)
|
config(conf)
|
||||||
|
|
|
||||||
|
|
@ -30,14 +30,13 @@ import (
|
||||||
|
|
||||||
"github.com/codegangsta/cli"
|
"github.com/codegangsta/cli"
|
||||||
"github.com/ethereum/ethash"
|
"github.com/ethereum/ethash"
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"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/types"
|
||||||
"github.com/ethereum/go-ethereum/eth"
|
"github.com/ethereum/go-ethereum/eth"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
"github.com/ethereum/go-ethereum/metrics"
|
"github.com/ethereum/go-ethereum/metrics"
|
||||||
|
|
@ -552,7 +551,7 @@ func blockRecovery(ctx *cli.Context) {
|
||||||
cfg := utils.MakeEthConfig(ClientIdentifier, nodeNameVersion, ctx)
|
cfg := utils.MakeEthConfig(ClientIdentifier, nodeNameVersion, ctx)
|
||||||
utils.CheckLegalese(cfg.DataDir)
|
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 {
|
if err != nil {
|
||||||
glog.Fatalln("could not open db:", err)
|
glog.Fatalln("could not open db:", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,14 +31,13 @@ import (
|
||||||
|
|
||||||
"github.com/codegangsta/cli"
|
"github.com/codegangsta/cli"
|
||||||
"github.com/ethereum/ethash"
|
"github.com/ethereum/ethash"
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"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/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/eth"
|
"github.com/ethereum/go-ethereum/eth"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
|
|
@ -535,12 +534,12 @@ func SetupVM(ctx *cli.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// MakeChain creates a chain manager from set command line flags.
|
// 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)
|
datadir := MustDataDir(ctx)
|
||||||
cache := ctx.GlobalInt(CacheFlag.Name)
|
cache := ctx.GlobalInt(CacheFlag.Name)
|
||||||
|
|
||||||
var err error
|
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)
|
Fatalf("Could not open database: %v", err)
|
||||||
}
|
}
|
||||||
if ctx.GlobalBool(OlympicFlag.Name) {
|
if ctx.GlobalBool(OlympicFlag.Name) {
|
||||||
|
|
@ -666,4 +665,4 @@ func ParamToAddress(addr string, am *accounts.Manager) (addrHex string, err erro
|
||||||
addrHex = addr
|
addrHex = addr
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/httpclient"
|
"github.com/ethereum/go-ethereum/common/httpclient"
|
||||||
|
|
@ -33,7 +34,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/eth"
|
"github.com/ethereum/go-ethereum/eth"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
xe "github.com/ethereum/go-ethereum/xeth"
|
xe "github.com/ethereum/go-ethereum/xeth"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -125,7 +125,7 @@ func testEth(t *testing.T) (ethereum *eth.Ethereum, err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
addr := common.HexToAddress(testAddress)
|
addr := common.HexToAddress(testAddress)
|
||||||
core.WriteGenesisBlockForTesting(db, core.GenesisAccount{addr, common.String2Big(testBalance)})
|
core.WriteGenesisBlockForTesting(db, core.GenesisAccount{addr, common.String2Big(testBalance)})
|
||||||
ks := crypto.NewKeyStorePassphrase(filepath.Join(tmp, "keystore"), crypto.LightScryptN, crypto.LightScryptP)
|
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),
|
Etherbase: common.HexToAddress(testAddress),
|
||||||
MaxPeers: 0,
|
MaxPeers: 0,
|
||||||
PowTest: true,
|
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,
|
GpoMinGasPrice: common.Big1,
|
||||||
GpobaseCorrectionFactor: 1,
|
GpobaseCorrectionFactor: 1,
|
||||||
GpoMaxGasPrice: common.Big1,
|
GpoMaxGasPrice: common.Big1,
|
||||||
|
|
|
||||||
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
|
|
@ -23,11 +23,10 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"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/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
@ -145,16 +144,16 @@ func genUncles(i int, gen *BlockGen) {
|
||||||
|
|
||||||
func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) {
|
func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) {
|
||||||
// Create the database in memory or in a temporary directory.
|
// Create the database in memory or in a temporary directory.
|
||||||
var db ethdb.Database
|
var db access.Database
|
||||||
if !disk {
|
if !disk {
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db, _ = access.NewMemDatabase()
|
||||||
} else {
|
} else {
|
||||||
dir, err := ioutil.TempDir("", "eth-core-bench")
|
dir, err := ioutil.TempDir("", "eth-core-bench")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatalf("cannot create temporary directory: %v", err)
|
b.Fatalf("cannot create temporary directory: %v", err)
|
||||||
}
|
}
|
||||||
defer os.RemoveAll(dir)
|
defer os.RemoveAll(dir)
|
||||||
db, err = ethdb.NewLDBDatabase(dir, 0)
|
db, err = access.NewLDBDatabase(dir, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatalf("cannot create temporary database: %v", err)
|
b.Fatalf("cannot create temporary database: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,8 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"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/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
|
|
@ -88,10 +88,10 @@ func (gp *GasPool) String() string {
|
||||||
func NewBlockProcessor(ca *access.ChainAccess, pow pow.PoW, blockchain *BlockChain, eventMux *event.TypeMux) *BlockProcessor {
|
func NewBlockProcessor(ca *access.ChainAccess, pow pow.PoW, blockchain *BlockChain, eventMux *event.TypeMux) *BlockProcessor {
|
||||||
sm := &BlockProcessor{
|
sm := &BlockProcessor{
|
||||||
chainAccess: ca,
|
chainAccess: ca,
|
||||||
mem: make(map[string]*big.Int),
|
mem: make(map[string]*big.Int),
|
||||||
Pow: pow,
|
Pow: pow,
|
||||||
bc: blockchain,
|
bc: blockchain,
|
||||||
eventMux: eventMux,
|
eventMux: eventMux,
|
||||||
}
|
}
|
||||||
return sm
|
return sm
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,18 +21,17 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"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/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/pow/ezp"
|
"github.com/ethereum/go-ethereum/pow/ezp"
|
||||||
)
|
)
|
||||||
|
|
||||||
func proc() (*BlockProcessor, *BlockChain) {
|
func proc() (*BlockProcessor, *BlockChain) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
ca := access.NewDbChainAccess(db)
|
ca := access.NewDbChainAccess(db)
|
||||||
var mux event.TypeMux
|
var mux event.TypeMux
|
||||||
|
|
||||||
|
|
@ -64,7 +63,7 @@ func TestNumber(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPutReceipt(t *testing.T) {
|
func TestPutReceipt(t *testing.T) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
|
|
||||||
var addr common.Address
|
var addr common.Address
|
||||||
addr[0] = 1
|
addr[0] = 1
|
||||||
|
|
|
||||||
|
|
@ -30,12 +30,11 @@ import (
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"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/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
|
|
@ -67,7 +66,7 @@ const (
|
||||||
|
|
||||||
type BlockChain struct {
|
type BlockChain struct {
|
||||||
chainAccess *access.ChainAccess
|
chainAccess *access.ChainAccess
|
||||||
chainDb ethdb.Database
|
chainDb access.Database
|
||||||
processor types.BlockProcessor
|
processor types.BlockProcessor
|
||||||
eventMux *event.TypeMux
|
eventMux *event.TypeMux
|
||||||
genesisBlock *types.Block
|
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("Bad block #%v (%s)\n", block.Number(), block.Hash().Hex())
|
||||||
glog.Errorf(" %v", err)
|
glog.Errorf(" %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,12 +27,11 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/ethereum/ethash"
|
"github.com/ethereum/ethash"
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"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/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/pow"
|
"github.com/ethereum/go-ethereum/pow"
|
||||||
|
|
@ -49,7 +48,7 @@ func thePow() pow.PoW {
|
||||||
return 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
|
var eventMux event.TypeMux
|
||||||
WriteTestNetGenesisBlock(db, 0)
|
WriteTestNetGenesisBlock(db, 0)
|
||||||
ca := access.NewDbChainAccess(db)
|
ca := access.NewDbChainAccess(db)
|
||||||
|
|
@ -189,7 +188,7 @@ func insertChain(done chan bool, blockchain *BlockChain, chain types.Blocks, t *
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLastBlock(t *testing.T) {
|
func TestLastBlock(t *testing.T) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
|
|
||||||
bchain := theBlockChain(db, t)
|
bchain := theBlockChain(db, t)
|
||||||
block := makeBlockChain(bchain.CurrentBlock(), 1, db, 0)[0]
|
block := makeBlockChain(bchain.CurrentBlock(), 1, db, 0)[0]
|
||||||
|
|
@ -336,7 +335,7 @@ func testBrokenChain(t *testing.T, full bool) {
|
||||||
func TestChainInsertions(t *testing.T) {
|
func TestChainInsertions(t *testing.T) {
|
||||||
t.Skip("Skipped: outdated test files")
|
t.Skip("Skipped: outdated test files")
|
||||||
|
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
|
|
||||||
chain1, err := loadChain("valid1", t)
|
chain1, err := loadChain("valid1", t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -374,7 +373,7 @@ func TestChainInsertions(t *testing.T) {
|
||||||
func TestChainMultipleInsertions(t *testing.T) {
|
func TestChainMultipleInsertions(t *testing.T) {
|
||||||
t.Skip("Skipped: outdated test files")
|
t.Skip("Skipped: outdated test files")
|
||||||
|
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
|
|
||||||
const max = 4
|
const max = 4
|
||||||
chains := make([]types.Blocks, max)
|
chains := make([]types.Blocks, max)
|
||||||
|
|
@ -452,7 +451,7 @@ func makeBlockChainWithDiff(genesis *types.Block, d []int, seed byte) []*types.B
|
||||||
return chain
|
return chain
|
||||||
}
|
}
|
||||||
|
|
||||||
func chm(genesis *types.Block, db ethdb.Database) *BlockChain {
|
func chm(genesis *types.Block, db access.Database) *BlockChain {
|
||||||
var eventMux event.TypeMux
|
var eventMux event.TypeMux
|
||||||
ca := access.NewDbChainAccess(db)
|
ca := access.NewDbChainAccess(db)
|
||||||
bc := &BlockChain{chainAccess: ca, chainDb: db, genesisBlock: genesis, eventMux: &eventMux, pow: FakePow{}, rand: rand.New(rand.NewSource(0))}
|
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) {
|
func testReorg(t *testing.T, first, second []int, td int64, full bool) {
|
||||||
// Create a pristine block chain
|
// Create a pristine block chain
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
genesis, _ := WriteTestNetGenesisBlock(db, 0)
|
genesis, _ := WriteTestNetGenesisBlock(db, 0)
|
||||||
bc := chm(genesis, db)
|
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
|
// Check that the chain is valid number and link wise
|
||||||
if full {
|
if full {
|
||||||
prev := bc.CurrentBlock()
|
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() {
|
if prev.ParentHash() != block.Hash() {
|
||||||
t.Errorf("parent block hash mismatch: have %x, want %x", 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) {
|
func testBadHashes(t *testing.T, full bool) {
|
||||||
// Create a pristine block chain
|
// Create a pristine block chain
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
genesis, _ := WriteTestNetGenesisBlock(db, 0)
|
genesis, _ := WriteTestNetGenesisBlock(db, 0)
|
||||||
bc := chm(genesis, db)
|
bc := chm(genesis, db)
|
||||||
|
|
||||||
|
|
@ -562,7 +561,7 @@ func TestReorgBadBlockHashes(t *testing.T) { testReorgBadHashes(t, true) }
|
||||||
|
|
||||||
func testReorgBadHashes(t *testing.T, full bool) {
|
func testReorgBadHashes(t *testing.T, full bool) {
|
||||||
// Create a pristine block chain
|
// Create a pristine block chain
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
genesis, _ := WriteTestNetGenesisBlock(db, 0)
|
genesis, _ := WriteTestNetGenesisBlock(db, 0)
|
||||||
bc := chm(genesis, db)
|
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.
|
// Check that all no blocks after the failing block have been inserted.
|
||||||
for j := 0; j < i-failAt; j++ {
|
for j := 0; j < i-failAt; j++ {
|
||||||
if full {
|
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)
|
t.Errorf("test %d: invalid block in chain: %v", i, block)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -685,7 +684,7 @@ func testInsertNonceError(t *testing.T, full bool) {
|
||||||
func TestFastVsFullChains(t *testing.T) {
|
func TestFastVsFullChains(t *testing.T) {
|
||||||
// Configure and generate a sample block chain
|
// Configure and generate a sample block chain
|
||||||
var (
|
var (
|
||||||
gendb, _ = ethdb.NewMemDatabase()
|
gendb, _ = access.NewMemDatabase()
|
||||||
key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||||
address = crypto.PubkeyToAddress(key.PublicKey)
|
address = crypto.PubkeyToAddress(key.PublicKey)
|
||||||
funds = big.NewInt(1000000000)
|
funds = big.NewInt(1000000000)
|
||||||
|
|
@ -710,7 +709,7 @@ func TestFastVsFullChains(t *testing.T) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
// Import the chain as an archive node for the comparison baseline
|
// Import the chain as an archive node for the comparison baseline
|
||||||
archiveDb, _ := ethdb.NewMemDatabase()
|
archiveDb, _ := access.NewMemDatabase()
|
||||||
archiveCa := access.NewDbChainAccess(archiveDb)
|
archiveCa := access.NewDbChainAccess(archiveDb)
|
||||||
WriteGenesisBlockForTesting(archiveDb, GenesisAccount{address, funds})
|
WriteGenesisBlockForTesting(archiveDb, GenesisAccount{address, funds})
|
||||||
|
|
||||||
|
|
@ -721,7 +720,7 @@ func TestFastVsFullChains(t *testing.T) {
|
||||||
t.Fatalf("failed to process block %d: %v", n, err)
|
t.Fatalf("failed to process block %d: %v", n, err)
|
||||||
}
|
}
|
||||||
// Fast import the chain as a non-archive node to test
|
// Fast import the chain as a non-archive node to test
|
||||||
fastDb, _ := ethdb.NewMemDatabase()
|
fastDb, _ := access.NewMemDatabase()
|
||||||
fastCa := access.NewDbChainAccess(fastDb)
|
fastCa := access.NewDbChainAccess(fastDb)
|
||||||
WriteGenesisBlockForTesting(fastDb, GenesisAccount{address, funds})
|
WriteGenesisBlockForTesting(fastDb, GenesisAccount{address, funds})
|
||||||
fast, _ := NewBlockChain(fastCa, FakePow{}, new(event.TypeMux))
|
fast, _ := NewBlockChain(fastCa, FakePow{}, new(event.TypeMux))
|
||||||
|
|
@ -771,7 +770,7 @@ func TestFastVsFullChains(t *testing.T) {
|
||||||
func TestLightVsFastVsFullChainHeads(t *testing.T) {
|
func TestLightVsFastVsFullChainHeads(t *testing.T) {
|
||||||
// Configure and generate a sample block chain
|
// Configure and generate a sample block chain
|
||||||
var (
|
var (
|
||||||
gendb, _ = ethdb.NewMemDatabase()
|
gendb, _ = access.NewMemDatabase()
|
||||||
key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||||
address = crypto.PubkeyToAddress(key.PublicKey)
|
address = crypto.PubkeyToAddress(key.PublicKey)
|
||||||
funds = big.NewInt(1000000000)
|
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
|
// Import the chain as an archive node and ensure all pointers are updated
|
||||||
archiveDb, _ := ethdb.NewMemDatabase()
|
archiveDb, _ := access.NewMemDatabase()
|
||||||
archiveCa := access.NewDbChainAccess(archiveDb)
|
archiveCa := access.NewDbChainAccess(archiveDb)
|
||||||
WriteGenesisBlockForTesting(archiveDb, GenesisAccount{address, funds})
|
WriteGenesisBlockForTesting(archiveDb, GenesisAccount{address, funds})
|
||||||
archive, _ := NewBlockChain(archiveCa, FakePow{}, new(event.TypeMux))
|
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)
|
assert(t, "archive", archive, height/2, height/2, height/2)
|
||||||
|
|
||||||
// Import the chain as a non-archive node and ensure all pointers are updated
|
// Import the chain as a non-archive node and ensure all pointers are updated
|
||||||
fastDb, _ := ethdb.NewMemDatabase()
|
fastDb, _ := access.NewMemDatabase()
|
||||||
fastCa := access.NewDbChainAccess(fastDb)
|
fastCa := access.NewDbChainAccess(fastDb)
|
||||||
WriteGenesisBlockForTesting(fastDb, GenesisAccount{address, funds})
|
WriteGenesisBlockForTesting(fastDb, GenesisAccount{address, funds})
|
||||||
fast, _ := NewBlockChain(fastCa, FakePow{}, new(event.TypeMux))
|
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)
|
assert(t, "fast", fast, height/2, height/2, 0)
|
||||||
|
|
||||||
// Import the chain as a light node and ensure all pointers are updated
|
// Import the chain as a light node and ensure all pointers are updated
|
||||||
lightDb, _ := ethdb.NewMemDatabase()
|
lightDb, _ := access.NewMemDatabase()
|
||||||
lightCa := access.NewDbChainAccess(lightDb)
|
lightCa := access.NewDbChainAccess(lightDb)
|
||||||
WriteGenesisBlockForTesting(lightDb, GenesisAccount{address, funds})
|
WriteGenesisBlockForTesting(lightDb, GenesisAccount{address, funds})
|
||||||
light, _ := NewBlockChain(lightCa, FakePow{}, new(event.TypeMux))
|
light, _ := NewBlockChain(lightCa, FakePow{}, new(event.TypeMux))
|
||||||
|
|
@ -859,7 +858,7 @@ func TestChainTxReorgs(t *testing.T) {
|
||||||
addr1 = crypto.PubkeyToAddress(key1.PublicKey)
|
addr1 = crypto.PubkeyToAddress(key1.PublicKey)
|
||||||
addr2 = crypto.PubkeyToAddress(key2.PublicKey)
|
addr2 = crypto.PubkeyToAddress(key2.PublicKey)
|
||||||
addr3 = crypto.PubkeyToAddress(key3.PublicKey)
|
addr3 = crypto.PubkeyToAddress(key3.PublicKey)
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db, _ = access.NewMemDatabase()
|
||||||
)
|
)
|
||||||
genesis := WriteGenesisBlockForTesting(db,
|
genesis := WriteGenesisBlockForTesting(db,
|
||||||
GenesisAccount{addr1, big.NewInt(1000000)},
|
GenesisAccount{addr1, big.NewInt(1000000)},
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,10 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"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/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/pow"
|
"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
|
// Blocks created by GenerateChain do not contain valid proof of work
|
||||||
// values. Inserting them into BlockChain requires use of FakePow or
|
// values. Inserting them into BlockChain requires use of FakePow or
|
||||||
// a similar non-validating proof of work implementation.
|
// a similar non-validating proof of work implementation.
|
||||||
func GenerateChain(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))
|
statedb, err := state.New(parent.Root(), access.NewDbChainAccess(db))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
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
|
// 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
|
// chain. Depending on the full flag, if creates either a full block chain or a
|
||||||
// header only chain.
|
// 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
|
// Create te new chain database
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
evmux := &event.TypeMux{}
|
evmux := &event.TypeMux{}
|
||||||
|
|
||||||
// Initialize a fresh chain with only a genesis block
|
// 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.
|
// 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)
|
blocks := makeBlockChain(types.NewBlockWithHeader(parent), n, db, seed)
|
||||||
headers := make([]*types.Header, len(blocks))
|
headers := make([]*types.Header, len(blocks))
|
||||||
for i, block := range 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.
|
// 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) {
|
blocks, _ := GenerateChain(parent, db, n, func(i int, b *BlockGen) {
|
||||||
b.SetCoinbase(common.Address{0: byte(seed), 19: byte(i)})
|
b.SetCoinbase(common.Address{0: byte(seed), 19: byte(i)})
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,9 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"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/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
@ -39,7 +38,7 @@ func ExampleGenerateChain() {
|
||||||
addr1 = crypto.PubkeyToAddress(key1.PublicKey)
|
addr1 = crypto.PubkeyToAddress(key1.PublicKey)
|
||||||
addr2 = crypto.PubkeyToAddress(key2.PublicKey)
|
addr2 = crypto.PubkeyToAddress(key2.PublicKey)
|
||||||
addr3 = crypto.PubkeyToAddress(key3.PublicKey)
|
addr3 = crypto.PubkeyToAddress(key3.PublicKey)
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db, _ = access.NewMemDatabase()
|
||||||
)
|
)
|
||||||
|
|
||||||
// Ensure that key1 has some funds in the genesis block.
|
// Ensure that key1 has some funds in the genesis block.
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,9 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/pow"
|
"github.com/ethereum/go-ethereum/pow"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -58,7 +58,7 @@ func (pow delayedPow) Turbo(bool) {}
|
||||||
func TestPowVerification(t *testing.T) {
|
func TestPowVerification(t *testing.T) {
|
||||||
// Create a simple chain to verify
|
// Create a simple chain to verify
|
||||||
var (
|
var (
|
||||||
testdb, _ = ethdb.NewMemDatabase()
|
testdb, _ = access.NewMemDatabase()
|
||||||
genesis = GenesisBlockForTesting(testdb, common.Address{}, new(big.Int))
|
genesis = GenesisBlockForTesting(testdb, common.Address{}, new(big.Int))
|
||||||
blocks, _ = GenerateChain(genesis, testdb, 8, nil)
|
blocks, _ = GenerateChain(genesis, testdb, 8, nil)
|
||||||
)
|
)
|
||||||
|
|
@ -113,7 +113,7 @@ func TestPowConcurrentVerification32(t *testing.T) { testPowConcurrentVerificati
|
||||||
func testPowConcurrentVerification(t *testing.T, threads int) {
|
func testPowConcurrentVerification(t *testing.T, threads int) {
|
||||||
// Create a simple chain to verify
|
// Create a simple chain to verify
|
||||||
var (
|
var (
|
||||||
testdb, _ = ethdb.NewMemDatabase()
|
testdb, _ = access.NewMemDatabase()
|
||||||
genesis = GenesisBlockForTesting(testdb, common.Address{}, new(big.Int))
|
genesis = GenesisBlockForTesting(testdb, common.Address{}, new(big.Int))
|
||||||
blocks, _ = GenerateChain(genesis, testdb, 8, nil)
|
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) {
|
func testPowConcurrentAbortion(t *testing.T, threads int) {
|
||||||
// Create a simple chain to verify
|
// Create a simple chain to verify
|
||||||
var (
|
var (
|
||||||
testdb, _ = ethdb.NewMemDatabase()
|
testdb, _ = access.NewMemDatabase()
|
||||||
genesis = GenesisBlockForTesting(testdb, common.Address{}, new(big.Int))
|
genesis = GenesisBlockForTesting(testdb, common.Address{}, new(big.Int))
|
||||||
blocks, _ = GenerateChain(genesis, testdb, 1024, nil)
|
blocks, _ = GenerateChain(genesis, testdb, 1024, nil)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -22,11 +22,9 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"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/core/types"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
|
@ -121,7 +119,7 @@ func CalcGasLimit(parent *types.Block) *big.Int {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCanonicalHash retrieves a hash assigned to a canonical block number.
|
// 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()...))
|
data, _ := db.Get(append(blockNumPrefix, big.NewInt(int64(number)).Bytes()...))
|
||||||
if len(data) == 0 {
|
if len(data) == 0 {
|
||||||
return common.Hash{}
|
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
|
// 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
|
// hash is updated already at header import, allowing head tracking for the
|
||||||
// light synchronization mechanism.
|
// light synchronization mechanism.
|
||||||
func GetHeadHeaderHash(db ethdb.Database) common.Hash {
|
func GetHeadHeaderHash(db access.Database) common.Hash {
|
||||||
data, _ := db.Get(headHeaderKey)
|
data, _ := db.Get(headHeaderKey)
|
||||||
if len(data) == 0 {
|
if len(data) == 0 {
|
||||||
return common.Hash{}
|
return common.Hash{}
|
||||||
|
|
@ -143,7 +141,7 @@ func GetHeadHeaderHash(db ethdb.Database) common.Hash {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetHeadBlockHash retrieves the hash of the current canonical head block.
|
// 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)
|
data, _ := db.Get(headBlockKey)
|
||||||
if len(data) == 0 {
|
if len(data) == 0 {
|
||||||
return common.Hash{}
|
return common.Hash{}
|
||||||
|
|
@ -155,7 +153,7 @@ func GetHeadBlockHash(db ethdb.Database) common.Hash {
|
||||||
// fast synchronization. The difference between this and GetHeadBlockHash is that
|
// 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
|
// whereas the last block hash is only updated upon a full block import, the last
|
||||||
// fast hash is updated when importing pre-processed blocks.
|
// 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)
|
data, _ := db.Get(headFastKey)
|
||||||
if len(data) == 0 {
|
if len(data) == 0 {
|
||||||
return common.Hash{}
|
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
|
// GetHeaderRLP retrieves a block header in its raw RLP database encoding, or nil
|
||||||
// if the header's not found.
|
// 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...))
|
data, _ := db.Get(append(append(blockPrefix, hash[:]...), headerSuffix...))
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetHeader retrieves the block header corresponding to the hash, nil if none
|
// GetHeader retrieves the block header corresponding to the hash, nil if none
|
||||||
// found.
|
// 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)
|
data := GetHeaderRLP(db, hash)
|
||||||
if len(data) == 0 {
|
if len(data) == 0 {
|
||||||
return nil
|
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
|
// GetBodyRLP retrieves the block body (transactions and uncles) from the
|
||||||
// database in RLP encoding.
|
// database in RLP encoding.
|
||||||
func GetBodyRLP(ca *access.ChainAccess, hash common.Hash) rlp.RawValue {
|
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
|
// GetBodyRLPOdr retrieves the block body (transactions and uncles) from the
|
||||||
// database or network in RLP encoding.
|
// database or network in RLP encoding.
|
||||||
func GetBodyRLPOdr(ctx context.Context, ca *access.ChainAccess, hash common.Hash) rlp.RawValue {
|
func GetBodyRLPOdr(ctx context.Context, ca *access.ChainAccess, hash common.Hash) rlp.RawValue {
|
||||||
//fmt.Println("request block %v", hash)
|
res := GetBodyRLP(ca, hash)
|
||||||
r := requests.NewBlockAccess(ca.Db(), hash, GetHeader)
|
if res != nil || !access.IsOdrContext(ctx) {
|
||||||
ca.Retrieve(ctx, r)
|
return res
|
||||||
|
}
|
||||||
|
r := &BlockRequest{ctx: ctx, blockHash: hash}
|
||||||
|
ca.Retrieve(r)
|
||||||
return r.GetRlp()
|
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
|
// GetTd retrieves a block's total difficulty corresponding to the hash, nil if
|
||||||
// none found.
|
// 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...))
|
data, _ := db.Get(append(append(blockPrefix, hash.Bytes()...), tdSuffix...))
|
||||||
if len(data) == 0 {
|
if len(data) == 0 {
|
||||||
return nil
|
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.
|
// 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()...)
|
key := append(blockNumPrefix, big.NewInt(int64(number)).Bytes()...)
|
||||||
if err := db.Put(key, hash.Bytes()); err != nil {
|
if err := db.Put(key, hash.Bytes()); err != nil {
|
||||||
glog.Fatalf("failed to store number to hash mapping into database: %v", err)
|
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.
|
// 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 {
|
if err := db.Put(headHeaderKey, hash.Bytes()); err != nil {
|
||||||
glog.Fatalf("failed to store last header's hash into database: %v", err)
|
glog.Fatalf("failed to store last header's hash into database: %v", err)
|
||||||
return err
|
return err
|
||||||
|
|
@ -278,7 +280,7 @@ func WriteHeadHeaderHash(db ethdb.Database, hash common.Hash) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteHeadBlockHash stores the head block's hash.
|
// 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 {
|
if err := db.Put(headBlockKey, hash.Bytes()); err != nil {
|
||||||
glog.Fatalf("failed to store last block's hash into database: %v", err)
|
glog.Fatalf("failed to store last block's hash into database: %v", err)
|
||||||
return err
|
return err
|
||||||
|
|
@ -287,7 +289,7 @@ func WriteHeadBlockHash(db ethdb.Database, hash common.Hash) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteHeadFastBlockHash stores the fast head block's hash.
|
// 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 {
|
if err := db.Put(headFastKey, hash.Bytes()); err != nil {
|
||||||
glog.Fatalf("failed to store last fast block's hash into database: %v", err)
|
glog.Fatalf("failed to store last fast block's hash into database: %v", err)
|
||||||
return err
|
return err
|
||||||
|
|
@ -296,7 +298,7 @@ func WriteHeadFastBlockHash(db ethdb.Database, hash common.Hash) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteHeader serializes a block header into the database.
|
// 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)
|
data, err := rlp.EncodeToBytes(header)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -310,12 +312,8 @@ func WriteHeader(db ethdb.Database, header *types.Header) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteBody serializes the body of a block into the database.
|
// WriteBodyRlp stores the serialized body of a block into the database.
|
||||||
func WriteBody(db ethdb.Database, hash common.Hash, body *types.Body) error {
|
func WriteBodyRlp(db access.Database, hash common.Hash, data []byte) error {
|
||||||
data, err := rlp.EncodeToBytes(body)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
key := append(append(blockPrefix, hash.Bytes()...), bodySuffix...)
|
key := append(append(blockPrefix, hash.Bytes()...), bodySuffix...)
|
||||||
if err := db.Put(key, data); err != nil {
|
if err := db.Put(key, data); err != nil {
|
||||||
glog.Fatalf("failed to store block body into database: %v", err)
|
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
|
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.
|
// 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)
|
data, err := rlp.EncodeToBytes(td)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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.
|
// 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
|
// Store the body first to retain database consistency
|
||||||
if err := WriteBody(db, block.Hash(), &types.Body{block.Transactions(), block.Uncles()}); err != nil {
|
if err := WriteBody(db, block.Hash(), &types.Body{block.Transactions(), block.Uncles()}); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -354,27 +361,27 @@ func WriteBlock(db ethdb.Database, block *types.Block) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteCanonicalHash removes the number to hash canonical mapping.
|
// 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()...))
|
db.Delete(append(blockNumPrefix, big.NewInt(int64(number)).Bytes()...))
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteHeader removes all block header data associated with a hash.
|
// 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...))
|
db.Delete(append(append(blockPrefix, hash.Bytes()...), headerSuffix...))
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteBody removes all block body data associated with a hash.
|
// 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...))
|
db.Delete(append(append(blockPrefix, hash.Bytes()...), bodySuffix...))
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteTd removes all block total difficulty data associated with a hash.
|
// 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...))
|
db.Delete(append(append(blockPrefix, hash.Bytes()...), tdSuffix...))
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteBlock removes all block data associated with a hash.
|
// 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)
|
DeleteHeader(db, hash)
|
||||||
DeleteBody(db, hash)
|
DeleteBody(db, hash)
|
||||||
DeleteTd(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
|
// 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
|
// access the old combined block representation. It will be dropped after the
|
||||||
// network transitions to eth/63.
|
// 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[:]...))
|
data, _ := db.Get(append(blockHashPre, hash[:]...))
|
||||||
if len(data) == 0 {
|
if len(data) == 0 {
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -411,7 +418,7 @@ func mipmapKey(num, level uint64) []byte {
|
||||||
|
|
||||||
// WriteMapmapBloom writes each address included in the receipts' logs to the
|
// WriteMapmapBloom writes each address included in the receipts' logs to the
|
||||||
// MIP bloom bin.
|
// 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()
|
batch := db.NewBatch()
|
||||||
for _, level := range MIPMapLevels {
|
for _, level := range MIPMapLevels {
|
||||||
key := mipmapKey(number, level)
|
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
|
// GetMipmapBloom returns a bloom filter using the number and level as input
|
||||||
// parameters. For available levels see MIPMapLevels.
|
// 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))
|
bloomDat, _ := db.Get(mipmapKey(number, level))
|
||||||
return types.BytesToBloom(bloomDat)
|
return types.BytesToBloom(bloomDat)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,13 +23,12 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"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/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/crypto/sha3"
|
"github.com/ethereum/go-ethereum/crypto/sha3"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -86,7 +85,7 @@ func TestDifficulty(t *testing.T) {
|
||||||
|
|
||||||
// Tests block header storage and retrieval operations.
|
// Tests block header storage and retrieval operations.
|
||||||
func TestHeaderStorage(t *testing.T) {
|
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
|
// Create a test header to move around the database and make sure it's really new
|
||||||
header := &types.Header{Extra: []byte("test header")}
|
header := &types.Header{Extra: []byte("test header")}
|
||||||
|
|
@ -121,7 +120,7 @@ func TestHeaderStorage(t *testing.T) {
|
||||||
|
|
||||||
// Tests block body storage and retrieval operations.
|
// Tests block body storage and retrieval operations.
|
||||||
func TestBodyStorage(t *testing.T) {
|
func TestBodyStorage(t *testing.T) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
ca := access.NewDbChainAccess(db)
|
ca := access.NewDbChainAccess(db)
|
||||||
|
|
||||||
// Create a test body to move around the database and make sure it's really new
|
// 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.
|
// Tests block storage and retrieval operations.
|
||||||
func TestBlockStorage(t *testing.T) {
|
func TestBlockStorage(t *testing.T) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
ca := access.NewDbChainAccess(db)
|
ca := access.NewDbChainAccess(db)
|
||||||
|
|
||||||
// Create a test block to move around the database and make sure it's really new
|
// 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.
|
// Tests that partial block contents don't get reassembled into full blocks.
|
||||||
func TestPartialBlockStorage(t *testing.T) {
|
func TestPartialBlockStorage(t *testing.T) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
ca := access.NewDbChainAccess(db)
|
ca := access.NewDbChainAccess(db)
|
||||||
block := types.NewBlockWithHeader(&types.Header{
|
block := types.NewBlockWithHeader(&types.Header{
|
||||||
Extra: []byte("test block"),
|
Extra: []byte("test block"),
|
||||||
|
|
@ -257,7 +256,7 @@ func TestPartialBlockStorage(t *testing.T) {
|
||||||
|
|
||||||
// Tests block total difficulty storage and retrieval operations.
|
// Tests block total difficulty storage and retrieval operations.
|
||||||
func TestTdStorage(t *testing.T) {
|
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
|
// Create a test TD to move around the database and make sure it's really new
|
||||||
hash, td := common.Hash{}, big.NewInt(314)
|
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.
|
// Tests that canonical numbers can be mapped to hashes and retrieved.
|
||||||
func TestCanonicalMappingStorage(t *testing.T) {
|
func TestCanonicalMappingStorage(t *testing.T) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
|
|
||||||
// Create a test canonical number and assinged hash to move around
|
// Create a test canonical number and assinged hash to move around
|
||||||
hash, number := common.Hash{0: 0xff}, uint64(314)
|
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.
|
// Tests that head headers and head blocks can be assigned, individually.
|
||||||
func TestHeadStorage(t *testing.T) {
|
func TestHeadStorage(t *testing.T) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
|
|
||||||
blockHead := types.NewBlockWithHeader(&types.Header{Extra: []byte("test block header")})
|
blockHead := types.NewBlockWithHeader(&types.Header{Extra: []byte("test block header")})
|
||||||
blockFull := types.NewBlockWithHeader(&types.Header{Extra: []byte("test block full")})
|
blockFull := types.NewBlockWithHeader(&types.Header{Extra: []byte("test block full")})
|
||||||
|
|
@ -346,7 +345,7 @@ func TestHeadStorage(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMipmapBloom(t *testing.T) {
|
func TestMipmapBloom(t *testing.T) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
|
|
||||||
receipt1 := new(types.Receipt)
|
receipt1 := new(types.Receipt)
|
||||||
receipt1.Logs = vm.Logs{
|
receipt1.Logs = vm.Logs{
|
||||||
|
|
@ -370,7 +369,7 @@ func TestMipmapBloom(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset
|
// reset
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db, _ = access.NewMemDatabase()
|
||||||
receipt := new(types.Receipt)
|
receipt := new(types.Receipt)
|
||||||
receipt.Logs = vm.Logs{
|
receipt.Logs = vm.Logs{
|
||||||
&vm.Log{Address: common.BytesToAddress([]byte("test"))},
|
&vm.Log{Address: common.BytesToAddress([]byte("test"))},
|
||||||
|
|
@ -397,7 +396,7 @@ func TestMipmapChain(t *testing.T) {
|
||||||
defer os.RemoveAll(dir)
|
defer os.RemoveAll(dir)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
db, _ = ethdb.NewLDBDatabase(dir, 16)
|
db, _ = access.NewLDBDatabase(dir, 16)
|
||||||
key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||||
addr = crypto.PubkeyToAddress(key1.PublicKey)
|
addr = crypto.PubkeyToAddress(key1.PublicKey)
|
||||||
addr2 = common.BytesToAddress([]byte("jeff"))
|
addr2 = common.BytesToAddress([]byte("jeff"))
|
||||||
|
|
|
||||||
|
|
@ -24,18 +24,17 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"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/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
// WriteGenesisBlock writes the genesis block to the database as block number 0
|
// 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)
|
contents, err := ioutil.ReadAll(reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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.
|
// 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
|
// 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))
|
statedb, _ := state.New(common.Hash{}, access.NewDbChainAccess(db))
|
||||||
obj := statedb.GetOrNewStateObject(addr)
|
obj := statedb.GetOrNewStateObject(addr)
|
||||||
obj.SetBalance(balance)
|
obj.SetBalance(balance)
|
||||||
|
|
@ -140,7 +139,7 @@ type GenesisAccount struct {
|
||||||
Balance *big.Int
|
Balance *big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
func WriteGenesisBlockForTesting(db ethdb.Database, accounts ...GenesisAccount) *types.Block {
|
func WriteGenesisBlockForTesting(db access.Database, accounts ...GenesisAccount) *types.Block {
|
||||||
accountJson := "{"
|
accountJson := "{"
|
||||||
for i, account := range accounts {
|
for i, account := range accounts {
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
|
|
@ -160,7 +159,7 @@ func WriteGenesisBlockForTesting(db ethdb.Database, accounts ...GenesisAccount)
|
||||||
return block
|
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(`{
|
testGenesis := fmt.Sprintf(`{
|
||||||
"nonce": "0x%x",
|
"nonce": "0x%x",
|
||||||
"difficulty": "0x20000",
|
"difficulty": "0x20000",
|
||||||
|
|
@ -181,7 +180,7 @@ func WriteTestNetGenesisBlock(chainDb ethdb.Database, nonce uint64) (*types.Bloc
|
||||||
return WriteGenesisBlock(chainDb, strings.NewReader(testGenesis))
|
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(`{
|
testGenesis := fmt.Sprintf(`{
|
||||||
"nonce":"0x%x",
|
"nonce":"0x%x",
|
||||||
"gasLimit":"0x%x",
|
"gasLimit":"0x%x",
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
// "github.com/ethereum/go-ethereum/crypto"
|
// "github.com/ethereum/go-ethereum/crypto"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -32,7 +32,7 @@ type TestManager struct {
|
||||||
// stateManager *StateManager
|
// stateManager *StateManager
|
||||||
eventMux *event.TypeMux
|
eventMux *event.TypeMux
|
||||||
|
|
||||||
db ethdb.Database
|
db access.Database
|
||||||
txPool *TxPool
|
txPool *TxPool
|
||||||
blockChain *BlockChain
|
blockChain *BlockChain
|
||||||
Blocks []*types.Block
|
Blocks []*types.Block
|
||||||
|
|
@ -74,12 +74,12 @@ func (tm *TestManager) EventMux() *event.TypeMux {
|
||||||
// return nil
|
// return nil
|
||||||
// }
|
// }
|
||||||
|
|
||||||
func (tm *TestManager) Db() ethdb.Database {
|
func (tm *TestManager) Db() access.Database {
|
||||||
return tm.db
|
return tm.db
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTestManager() *TestManager {
|
func NewTestManager() *TestManager {
|
||||||
db, err := ethdb.NewMemDatabase()
|
db, err := access.NewMemDatabase()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Could not create mem-db, failing")
|
fmt.Println("Could not create mem-db, failing")
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,8 @@
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
"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"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -29,8 +28,8 @@ type Backend interface {
|
||||||
BlockProcessor() *BlockProcessor
|
BlockProcessor() *BlockProcessor
|
||||||
BlockChain() *BlockChain
|
BlockChain() *BlockChain
|
||||||
TxPool() *TxPool
|
TxPool() *TxPool
|
||||||
ChainDb() ethdb.Database
|
ChainDb() access.Database
|
||||||
ChainAccess() *access.ChainAccess
|
ChainAccess() *access.ChainAccess
|
||||||
DappDb() ethdb.Database
|
DappDb() access.Database
|
||||||
EventMux() *event.TypeMux
|
EventMux() *event.TypeMux
|
||||||
}
|
}
|
||||||
|
|
|
||||||
60
core/requests.go
Normal file
60
core/requests.go
Normal file
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
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())
|
||||||
|
}
|
||||||
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
|
|
@ -20,8 +20,8 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/access"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Account struct {
|
type Account struct {
|
||||||
|
|
|
||||||
|
|
@ -19,15 +19,14 @@ package state
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"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"))
|
var addr = common.BytesToAddress([]byte("test"))
|
||||||
|
|
||||||
func create() (*ManagedState, *account) {
|
func create() (*ManagedState, *account) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
statedb, _ := New(common.Hash{}, access.NewDbChainAccess(db))
|
statedb, _ := New(common.Hash{}, access.NewDbChainAccess(db))
|
||||||
ms := ManageState(statedb)
|
ms := ManageState(statedb)
|
||||||
so := &StateObject{address: addr, nonce: 100}
|
so := &StateObject{address: addr, nonce: 100}
|
||||||
|
|
|
||||||
105
core/state/requests.go
Normal file
105
core/state/requests.go
Normal file
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
|
@ -21,9 +21,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"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/crypto"
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
|
|
@ -60,7 +59,7 @@ func (self Storage) Copy() Storage {
|
||||||
type StateObject struct {
|
type StateObject struct {
|
||||||
// State database for storing state changes
|
// State database for storing state changes
|
||||||
ca *access.ChainAccess
|
ca *access.ChainAccess
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
trie *trie.SecureTrie
|
trie *trie.SecureTrie
|
||||||
|
|
||||||
// Address belonging to this account
|
// 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)
|
glog.Errorf("can't decode state object %x: %v", address, err)
|
||||||
return nil
|
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 {
|
if err != nil {
|
||||||
// TODO: bubble this up or panic
|
// TODO: bubble this up or panic
|
||||||
glog.Errorf("can't create account trie with root %x: %v", extobject.Root[:], err)
|
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.codeHash = extobject.CodeHash
|
||||||
object.trie = trie
|
object.trie = trie
|
||||||
object.storage = make(map[string]common.Hash)
|
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
|
return object
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -221,7 +220,7 @@ func (self *StateObject) CopyOdr(ctx context.Context) *StateObject {
|
||||||
stateObject.codeHash = common.CopyBytes(self.codeHash)
|
stateObject.codeHash = common.CopyBytes(self.codeHash)
|
||||||
stateObject.nonce = self.nonce
|
stateObject.nonce = self.nonce
|
||||||
if access.IsOdrContext(ctx) {
|
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 {
|
} else {
|
||||||
stateObject.trie = self.trie
|
stateObject.trie = self.trie
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,8 @@ import (
|
||||||
|
|
||||||
checker "gopkg.in/check.v1"
|
checker "gopkg.in/check.v1"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/access"
|
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type StateSuite struct {
|
type StateSuite struct {
|
||||||
|
|
@ -77,12 +76,12 @@ func (s *StateSuite) TestDump(c *checker.C) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StateSuite) SetUpTest(c *checker.C) {
|
func (s *StateSuite) SetUpTest(c *checker.C) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
s.state, _ = New(common.Hash{}, access.NewDbChainAccess(db))
|
s.state, _ = New(common.Hash{}, access.NewDbChainAccess(db))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNull(t *testing.T) {
|
func TestNull(t *testing.T) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
state, _ := New(common.Hash{}, access.NewDbChainAccess(db))
|
state, _ := New(common.Hash{}, access.NewDbChainAccess(db))
|
||||||
|
|
||||||
address := common.HexToAddress("0x823140710bf13990e4500136726d8b55")
|
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
|
// use testing instead of checker because checker does not support
|
||||||
// printing/logging in tests (-check.vv does not work)
|
// printing/logging in tests (-check.vv does not work)
|
||||||
func TestSnapshot2(t *testing.T) {
|
func TestSnapshot2(t *testing.T) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
state, _ := New(common.Hash{}, access.NewDbChainAccess(db))
|
state, _ := New(common.Hash{}, access.NewDbChainAccess(db))
|
||||||
|
|
||||||
stateobjaddr0 := toAddr([]byte("so0"))
|
stateobjaddr0 := toAddr([]byte("so0"))
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,9 @@ package state
|
||||||
import (
|
import (
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"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"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
"github.com/ethereum/go-ethereum/trie"
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
|
|
@ -43,7 +41,7 @@ var StartingNonce uint64
|
||||||
type StateDB struct {
|
type StateDB struct {
|
||||||
ca *access.ChainAccess
|
ca *access.ChainAccess
|
||||||
trie *trie.SecureTrie
|
trie *trie.SecureTrie
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
|
|
||||||
stateObjects map[string]*StateObject
|
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
|
// 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) {
|
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 {
|
if err != nil {
|
||||||
glog.Errorf("can't create state trie with root %x: %v", root[:], err)
|
glog.Errorf("can't create state trie with root %x: %v", root[:], err)
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -70,7 +68,7 @@ func NewOdr(ctx context.Context, root common.Hash, ca *access.ChainAccess) (*Sta
|
||||||
return &StateDB{
|
return &StateDB{
|
||||||
ca: ca,
|
ca: ca,
|
||||||
trie: tr,
|
trie: tr,
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
stateObjects: make(map[string]*StateObject),
|
stateObjects: make(map[string]*StateObject),
|
||||||
refund: new(big.Int),
|
refund: new(big.Int),
|
||||||
logs: make(map[common.Hash]vm.Logs),
|
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
|
// ignore error - we assume state-to-be-copied always exists
|
||||||
state, _ := NewOdr(ctx, common.Hash{}, self.ca)
|
state, _ := NewOdr(ctx, common.Hash{}, self.ca)
|
||||||
if access.IsOdrContext(ctx) {
|
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 {
|
} else {
|
||||||
state.trie = self.trie
|
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
|
// CommitBatch commits all state changes to a write batch but does not
|
||||||
// execute the batch. It is used to validate state changes against
|
// execute the batch. It is used to validate state changes against
|
||||||
// the root hash stored in a block.
|
// the root hash stored in a block.
|
||||||
func (s *StateDB) CommitBatch() (root common.Hash, batch ethdb.Batch) {
|
func (s *StateDB) CommitBatch() (root common.Hash, batch access.Batch) {
|
||||||
batch = s.ca.Db().NewBatch()
|
batch = s.ca.Db().NewBatch()
|
||||||
root, _ = s.commit(batch)
|
root, _ = s.commit(batch)
|
||||||
return root, batch
|
return root, batch
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,8 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/trie"
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
)
|
)
|
||||||
|
|
@ -32,7 +32,7 @@ import (
|
||||||
type StateSync trie.TrieSync
|
type StateSync trie.TrieSync
|
||||||
|
|
||||||
// NewStateSync create a new state trie download scheduler.
|
// 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
|
var syncer *trie.TrieSync
|
||||||
|
|
||||||
callback := func(leaf []byte, parent common.Hash) error {
|
callback := func(leaf []byte, parent common.Hash) error {
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,8 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"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"
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -36,9 +35,9 @@ type testAccount struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// makeTestState create a sample test state to test node-wise reconstruction.
|
// 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
|
// Create an empty state
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
state, _ := New(common.Hash{}, access.NewDbChainAccess(db))
|
state, _ := New(common.Hash{}, access.NewDbChainAccess(db))
|
||||||
|
|
||||||
// Fill it with some arbitrary data
|
// 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
|
// checkStateAccounts cross references a reconstructed state with an expected
|
||||||
// account array.
|
// 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))
|
state, _ := New(root, access.NewDbChainAccess(db))
|
||||||
for i, acc := range accounts {
|
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.
|
// Tests that an empty state is not scheduled for syncing.
|
||||||
func TestEmptyStateSync(t *testing.T) {
|
func TestEmptyStateSync(t *testing.T) {
|
||||||
empty := common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
empty := common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
if req := NewStateSync(empty, db).Missing(1); len(req) != 0 {
|
if req := NewStateSync(empty, db).Missing(1); len(req) != 0 {
|
||||||
t.Errorf("content requested for empty state: %v", req)
|
t.Errorf("content requested for empty state: %v", req)
|
||||||
}
|
}
|
||||||
|
|
@ -103,7 +102,7 @@ func testIterativeStateSync(t *testing.T, batch int) {
|
||||||
srcDb, srcRoot, srcAccounts := makeTestState()
|
srcDb, srcRoot, srcAccounts := makeTestState()
|
||||||
|
|
||||||
// Create a destination state and sync with the scheduler
|
// Create a destination state and sync with the scheduler
|
||||||
dstDb, _ := ethdb.NewMemDatabase()
|
dstDb, _ := access.NewMemDatabase()
|
||||||
sched := NewStateSync(srcRoot, dstDb)
|
sched := NewStateSync(srcRoot, dstDb)
|
||||||
|
|
||||||
queue := append([]common.Hash{}, sched.Missing(batch)...)
|
queue := append([]common.Hash{}, sched.Missing(batch)...)
|
||||||
|
|
@ -132,7 +131,7 @@ func TestIterativeDelayedStateSync(t *testing.T) {
|
||||||
srcDb, srcRoot, srcAccounts := makeTestState()
|
srcDb, srcRoot, srcAccounts := makeTestState()
|
||||||
|
|
||||||
// Create a destination state and sync with the scheduler
|
// Create a destination state and sync with the scheduler
|
||||||
dstDb, _ := ethdb.NewMemDatabase()
|
dstDb, _ := access.NewMemDatabase()
|
||||||
sched := NewStateSync(srcRoot, dstDb)
|
sched := NewStateSync(srcRoot, dstDb)
|
||||||
|
|
||||||
queue := append([]common.Hash{}, sched.Missing(0)...)
|
queue := append([]common.Hash{}, sched.Missing(0)...)
|
||||||
|
|
@ -166,7 +165,7 @@ func testIterativeRandomStateSync(t *testing.T, batch int) {
|
||||||
srcDb, srcRoot, srcAccounts := makeTestState()
|
srcDb, srcRoot, srcAccounts := makeTestState()
|
||||||
|
|
||||||
// Create a destination state and sync with the scheduler
|
// Create a destination state and sync with the scheduler
|
||||||
dstDb, _ := ethdb.NewMemDatabase()
|
dstDb, _ := access.NewMemDatabase()
|
||||||
sched := NewStateSync(srcRoot, dstDb)
|
sched := NewStateSync(srcRoot, dstDb)
|
||||||
|
|
||||||
queue := make(map[common.Hash]struct{})
|
queue := make(map[common.Hash]struct{})
|
||||||
|
|
@ -203,7 +202,7 @@ func TestIterativeRandomDelayedStateSync(t *testing.T) {
|
||||||
srcDb, srcRoot, srcAccounts := makeTestState()
|
srcDb, srcRoot, srcAccounts := makeTestState()
|
||||||
|
|
||||||
// Create a destination state and sync with the scheduler
|
// Create a destination state and sync with the scheduler
|
||||||
dstDb, _ := ethdb.NewMemDatabase()
|
dstDb, _ := access.NewMemDatabase()
|
||||||
sched := NewStateSync(srcRoot, dstDb)
|
sched := NewStateSync(srcRoot, dstDb)
|
||||||
|
|
||||||
queue := make(map[common.Hash]struct{})
|
queue := make(map[common.Hash]struct{})
|
||||||
|
|
|
||||||
|
|
@ -21,12 +21,11 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"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/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"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) {
|
func setupTxPool() (*TxPool, *ecdsa.PrivateKey) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
statedb, _ := state.New(common.Hash{}, access.NewDbChainAccess(db))
|
statedb, _ := state.New(common.Hash{}, access.NewDbChainAccess(db))
|
||||||
|
|
||||||
var m event.TypeMux
|
var m event.TypeMux
|
||||||
|
|
@ -163,7 +162,7 @@ func TestTransactionChainFork(t *testing.T) {
|
||||||
pool, key := setupTxPool()
|
pool, key := setupTxPool()
|
||||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||||
resetState := func() {
|
resetState := func() {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
statedb, _ := state.New(common.Hash{}, access.NewDbChainAccess(db))
|
statedb, _ := state.New(common.Hash{}, access.NewDbChainAccess(db))
|
||||||
pool.currentState = func() (*state.StateDB, error) { return statedb, nil }
|
pool.currentState = func() (*state.StateDB, error) { return statedb, nil }
|
||||||
currentState, _ := pool.currentState()
|
currentState, _ := pool.currentState()
|
||||||
|
|
@ -189,7 +188,7 @@ func TestTransactionDoubleNonce(t *testing.T) {
|
||||||
pool, key := setupTxPool()
|
pool, key := setupTxPool()
|
||||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||||
resetState := func() {
|
resetState := func() {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
statedb, _ := state.New(common.Hash{}, access.NewDbChainAccess(db))
|
statedb, _ := state.New(common.Hash{}, access.NewDbChainAccess(db))
|
||||||
pool.currentState = func() (*state.StateDB, error) { return statedb, nil }
|
pool.currentState = func() (*state.StateDB, error) { return statedb, nil }
|
||||||
currentState, _ := pool.currentState()
|
currentState, _ := pool.currentState()
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,9 @@ package core
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"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/core/types"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
|
|
@ -32,12 +30,12 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
blockReceiptsPre = []byte("receipts-block-")
|
|
||||||
receiptsPre = []byte("receipts-")
|
receiptsPre = []byte("receipts-")
|
||||||
|
blockReceiptsPre = []byte("receipts-block-")
|
||||||
)
|
)
|
||||||
|
|
||||||
// PutTransactions stores the transactions in the given database
|
// 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()
|
batch := db.NewBatch()
|
||||||
|
|
||||||
for i, tx := range block.Transactions() {
|
for i, tx := range block.Transactions() {
|
||||||
|
|
@ -70,11 +68,11 @@ func PutTransactions(db ethdb.Database, block *types.Block, txs types.Transactio
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeleteTransaction(db ethdb.Database, txHash common.Hash) {
|
func DeleteTransaction(db access.Database, txHash common.Hash) {
|
||||||
db.Delete(txHash[:])
|
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[:])
|
data, _ := db.Get(txhash[:])
|
||||||
if len(data) != 0 {
|
if len(data) != 0 {
|
||||||
var tx types.Transaction
|
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
|
// 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)
|
batch := new(leveldb.Batch)
|
||||||
_, batchWrite := db.(*ethdb.LDBDatabase)
|
_, batchWrite := db.(*access.LDBDatabase)
|
||||||
|
|
||||||
for _, receipt := range receipts {
|
for _, receipt := range receipts {
|
||||||
storageReceipt := (*types.ReceiptForStorage)(receipt)
|
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 {
|
if err := db.LDB().Write(batch, nil); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -117,7 +115,7 @@ func PutReceipts(db ethdb.Database, receipts types.Receipts) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete a receipts from the database
|
// 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[:]...))
|
db.Delete(append(receiptsPre, txHash[:]...))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -135,24 +133,41 @@ func GetReceipt(ca *access.ChainAccess, txHash common.Hash) *types.Receipt {
|
||||||
return (*types.Receipt)(&receipt)
|
return (*types.Receipt)(&receipt)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBlockReceipts returns the receipts generated by the transactions
|
// GetBlockReceipts retrieves the receipts generated by the transactions included
|
||||||
// included in block's given hash.
|
// in a block given by its hash.
|
||||||
func GetBlockReceipts(ca *access.ChainAccess, hash common.Hash) types.Receipts {
|
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
|
// GetBlockReceiptsOdr returns the receipts generated by the transactions
|
||||||
// included in block's given hash from the database or network.
|
// included in block's given hash from the database or network.
|
||||||
func GetBlockReceiptsOdr(ctx context.Context, ca *access.ChainAccess, hash common.Hash) types.Receipts {
|
func GetBlockReceiptsOdr(ctx context.Context, ca *access.ChainAccess, hash common.Hash) types.Receipts {
|
||||||
r := requests.NewReceiptsAccess(ca.Db(), hash, GetHeader, PutReceipts, PutBlockReceipts)
|
res := GetBlockReceipts(ca, hash)
|
||||||
ca.Retrieve(ctx, r)
|
if res != nil || !access.IsOdrContext(ctx) {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
r := &ReceiptsRequest{ctx: ctx, blockHash: hash}
|
||||||
|
ca.Retrieve(r)
|
||||||
return r.GetReceipts()
|
return r.GetReceipts()
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutBlockReceipts stores the block's transactions associated receipts
|
// PutBlockReceipts stores the block's transactions associated receipts
|
||||||
// and stores them by block hash in a single slice. This is required for
|
// and stores them by block hash in a single slice. This is required for
|
||||||
// forks and chain reorgs
|
// 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))
|
rs := make([]*types.ReceiptForStorage, len(receipts))
|
||||||
for i, receipt := range receipts {
|
for i, receipt := range receipts {
|
||||||
rs[i] = (*types.ReceiptForStorage)(receipt)
|
rs[i] = (*types.ReceiptForStorage)(receipt)
|
||||||
|
|
|
||||||
|
|
@ -20,12 +20,11 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"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/state"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Config is a basic type specifing certain configuration flags for running
|
// 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
|
vm.Debug = cfg.Debug
|
||||||
|
|
||||||
var (
|
var (
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db, _ = access.NewMemDatabase()
|
||||||
statedb, _ = state.New(common.Hash{}, access.NewDbChainAccess(db))
|
statedb, _ = state.New(common.Hash{}, access.NewDbChainAccess(db))
|
||||||
vmenv = NewEnv(cfg, statedb)
|
vmenv = NewEnv(cfg, statedb)
|
||||||
sender = statedb.CreateAccount(cfg.Origin)
|
sender = statedb.CreateAccount(cfg.Origin)
|
||||||
|
|
|
||||||
|
|
@ -32,18 +32,17 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/ethash"
|
"github.com/ethereum/ethash"
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/compiler"
|
"github.com/ethereum/go-ethereum/common/compiler"
|
||||||
"github.com/ethereum/go-ethereum/common/httpclient"
|
"github.com/ethereum/go-ethereum/common/httpclient"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/access"
|
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/eth/downloader"
|
"github.com/ethereum/go-ethereum/eth/downloader"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
|
|
@ -143,7 +142,7 @@ type Config struct {
|
||||||
|
|
||||||
// NewDB is used to create databases.
|
// NewDB is used to create databases.
|
||||||
// If nil, the default is to create leveldb databases on disk.
|
// 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 {
|
func (cfg *Config) parseBootNodes() []*discover.Node {
|
||||||
|
|
@ -229,8 +228,8 @@ type Ethereum struct {
|
||||||
shutdownChan chan bool
|
shutdownChan chan bool
|
||||||
|
|
||||||
// DB interfaces
|
// DB interfaces
|
||||||
chainDb ethdb.Database // Block chain database
|
chainDb access.Database // Block chain database
|
||||||
dappDb ethdb.Database // Dapp database
|
dappDb access.Database // Dapp database
|
||||||
|
|
||||||
chainAccess *access.ChainAccess // blockchain access layer
|
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)
|
// 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
|
const dbCount = 3
|
||||||
ethdb.OpenFileLimit = 128 / (dbCount + 1)
|
access.OpenFileLimit = 128 / (dbCount + 1)
|
||||||
|
|
||||||
newdb := config.NewDB
|
newdb := config.NewDB
|
||||||
if newdb == nil {
|
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
|
// 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)
|
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/")
|
db.Meter("eth/db/chaindata/")
|
||||||
}
|
}
|
||||||
if err := upgradeChainDatabase(chainDb); err != nil {
|
if err := upgradeChainDatabase(chainDb); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
chainAccess := access.NewChainAccess(chainDb, false)
|
chainAccess := access.NewChainAccess(chainDb, nil)
|
||||||
if err := addMipmapBloomBins(chainAccess); err != nil {
|
if err := addMipmapBloomBins(chainAccess); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -311,7 +310,7 @@ func New(config *Config) (*Ethereum, error) {
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("dapp db err: %v", err)
|
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/")
|
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) TxPool() *core.TxPool { return s.txPool }
|
||||||
func (s *Ethereum) Whisper() *whisper.Whisper { return s.whisper }
|
func (s *Ethereum) Whisper() *whisper.Whisper { return s.whisper }
|
||||||
func (s *Ethereum) EventMux() *event.TypeMux { return s.eventMux }
|
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) 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) IsListening() bool { return true } // Always listening
|
||||||
func (s *Ethereum) PeerCount() int { return s.net.PeerCount() }
|
func (s *Ethereum) PeerCount() int { return s.net.PeerCount() }
|
||||||
func (s *Ethereum) Peers() []*p2p.Peer { return s.net.Peers() }
|
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
|
return dag, "full-R" + dag
|
||||||
}
|
}
|
||||||
|
|
||||||
func saveBlockchainVersion(db ethdb.Database, bcVersion int) {
|
func saveBlockchainVersion(db access.Database, bcVersion int) {
|
||||||
d, _ := db.Get([]byte("BlockchainVersion"))
|
d, _ := db.Get([]byte("BlockchainVersion"))
|
||||||
blockchainVersion := common.NewValue(d).Uint()
|
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
|
// upgradeChainDatabase ensures that the chain database stores block split into
|
||||||
// separate header and body entries.
|
// 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
|
// Short circuit if the head block is stored already as separate header and body
|
||||||
data, err := db.Get([]byte("LastBlock"))
|
data, err := db.Get([]byte("LastBlock"))
|
||||||
if err != nil {
|
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!)
|
// 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...")
|
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-")
|
blockPrefix := []byte("block-hash-")
|
||||||
for it := db.NewIterator(); it.Next(); {
|
for it := db.NewIterator(); it.Next(); {
|
||||||
// Skip anything other than a combined block
|
// Skip anything other than a combined block
|
||||||
|
|
|
||||||
|
|
@ -4,16 +4,15 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"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/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMipmapUpgrade(t *testing.T) {
|
func TestMipmapUpgrade(t *testing.T) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
addr := common.BytesToAddress([]byte("jeff"))
|
addr := common.BytesToAddress([]byte("jeff"))
|
||||||
genesis := core.WriteGenesisBlockForTesting(db)
|
genesis := core.WriteGenesisBlockForTesting(db)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,9 @@ import (
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
|
|
@ -156,7 +156,7 @@ type Downloader struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new downloader to fetch hashes and blocks from remote peers.
|
// 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,
|
getBlock blockRetrievalFn, headHeader headHeaderRetrievalFn, headBlock headBlockRetrievalFn, headFastBlock headFastBlockRetrievalFn,
|
||||||
commitHeadBlock headBlockCommitterFn, getTd tdRetrievalFn, insertHeaders headerChainInsertFn, insertBlocks blockChainInsertFn,
|
commitHeadBlock headBlockCommitterFn, getTd tdRetrievalFn, insertHeaders headerChainInsertFn, insertBlocks blockChainInsertFn,
|
||||||
insertReceipts receiptChainInsertFn, rollback chainRollbackFn, dropPeer peerDropFn) *Downloader {
|
insertReceipts receiptChainInsertFn, rollback chainRollbackFn, dropPeer peerDropFn) *Downloader {
|
||||||
|
|
|
||||||
|
|
@ -25,20 +25,19 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"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/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/trie"
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
testdb, _ = ethdb.NewMemDatabase()
|
testdb, _ = access.NewMemDatabase()
|
||||||
testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||||
testAddress = crypto.PubkeyToAddress(testKey.PublicKey)
|
testAddress = crypto.PubkeyToAddress(testKey.PublicKey)
|
||||||
genesis = core.GenesisBlockForTesting(testdb, testAddress, big.NewInt(1000000000))
|
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.
|
// downloadTester is a test simulator for mocking out local block chain.
|
||||||
type downloadTester struct {
|
type downloadTester struct {
|
||||||
stateDb ethdb.Database
|
stateDb access.Database
|
||||||
downloader *Downloader
|
downloader *Downloader
|
||||||
|
|
||||||
ownHashes []common.Hash // Hash chain belonging to the tester
|
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),
|
peerReceipts: make(map[string]map[common.Hash]types.Receipts),
|
||||||
peerChainTds: make(map[string]map[common.Hash]*big.Int),
|
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.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.getBlock, tester.headHeader, tester.headBlock, tester.headFastBlock, tester.commitHeadBlock, tester.getTd,
|
||||||
tester.insertHeaders, tester.insertBlocks, tester.insertReceipts, tester.rollback, tester.dropPeer)
|
tester.insertHeaders, tester.insertBlocks, tester.insertReceipts, tester.rollback, tester.dropPeer)
|
||||||
|
|
|
||||||
|
|
@ -26,11 +26,11 @@ import (
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
"github.com/ethereum/go-ethereum/trie"
|
"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
|
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
|
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
|
stateScheduler *state.StateSync // [eth/63] State trie synchronisation scheduler and integrator
|
||||||
stateProcessors int32 // [eth/63] Number of currently running state processors
|
stateProcessors int32 // [eth/63] Number of currently running state processors
|
||||||
stateSchedLock sync.RWMutex // [eth/63] Lock serialising access to the state scheduler
|
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.
|
// newQueue creates a new download queue for scheduling block retrieval.
|
||||||
func newQueue(stateDb ethdb.Database) *queue {
|
func newQueue(stateDb access.Database) *queue {
|
||||||
return &queue{
|
return &queue{
|
||||||
hashPool: make(map[common.Hash]int),
|
hashPool: make(map[common.Hash]int),
|
||||||
hashQueue: prque.New(),
|
hashQueue: prque.New(),
|
||||||
|
|
|
||||||
|
|
@ -24,16 +24,16 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
testdb, _ = ethdb.NewMemDatabase()
|
testdb, _ = access.NewMemDatabase()
|
||||||
testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||||
testAddress = crypto.PubkeyToAddress(testKey.PublicKey)
|
testAddress = crypto.PubkeyToAddress(testKey.PublicKey)
|
||||||
genesis = core.GenesisBlockForTesting(testdb, testAddress, big.NewInt(1000000000))
|
genesis = core.GenesisBlockForTesting(testdb, testAddress, big.NewInt(1000000000))
|
||||||
|
|
|
||||||
|
|
@ -19,12 +19,11 @@ package filters
|
||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"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/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type AccountChange struct {
|
type AccountChange struct {
|
||||||
|
|
@ -34,7 +33,7 @@ type AccountChange struct {
|
||||||
// Filtering interface
|
// Filtering interface
|
||||||
type Filter struct {
|
type Filter struct {
|
||||||
ca *access.ChainAccess
|
ca *access.ChainAccess
|
||||||
db ethdb.Database
|
db access.Database
|
||||||
begin, end int64
|
begin, end int64
|
||||||
addresses []common.Address
|
addresses []common.Address
|
||||||
topics [][]common.Hash
|
topics [][]common.Hash
|
||||||
|
|
@ -51,7 +50,7 @@ func New(ca *access.ChainAccess) *Filter {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewWithDb creates a filter with no ODR option
|
// 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}
|
return &Filter{ca: access.NewDbChainAccess(db), db: db}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,12 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func makeReceipt(addr common.Address) *types.Receipt {
|
func makeReceipt(addr common.Address) *types.Receipt {
|
||||||
|
|
@ -31,7 +31,7 @@ func BenchmarkMipmaps(b *testing.B) {
|
||||||
defer os.RemoveAll(dir)
|
defer os.RemoveAll(dir)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
db, _ = ethdb.NewLDBDatabase(dir, 16)
|
db, _ = access.NewLDBDatabase(dir, 16)
|
||||||
key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||||
addr1 = crypto.PubkeyToAddress(key1.PublicKey)
|
addr1 = crypto.PubkeyToAddress(key1.PublicKey)
|
||||||
addr2 = common.BytesToAddress([]byte("jeff"))
|
addr2 = common.BytesToAddress([]byte("jeff"))
|
||||||
|
|
@ -105,7 +105,7 @@ func TestFilters(t *testing.T) {
|
||||||
defer os.RemoveAll(dir)
|
defer os.RemoveAll(dir)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
db, _ = ethdb.NewLDBDatabase(dir, 16)
|
db, _ = access.NewLDBDatabase(dir, 16)
|
||||||
key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||||
addr = crypto.PubkeyToAddress(key1.PublicKey)
|
addr = crypto.PubkeyToAddress(key1.PublicKey)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,9 +24,9 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"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/types"
|
||||||
"github.com/ethereum/go-ethereum/eth/downloader"
|
"github.com/ethereum/go-ethereum/eth/downloader"
|
||||||
"github.com/ethereum/go-ethereum/eth/fetcher"
|
"github.com/ethereum/go-ethereum/eth/fetcher"
|
||||||
|
|
@ -292,7 +292,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
|
||||||
request.Amount = uint64(downloader.MaxHashFetch)
|
request.Amount = uint64(downloader.MaxHashFetch)
|
||||||
}
|
}
|
||||||
// Calculate the last block that should be retrieved, and short circuit if unavailable
|
// 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 {
|
if last == nil {
|
||||||
last = pm.blockchain.CurrentBlock()
|
last = pm.blockchain.CurrentBlock()
|
||||||
request.Amount = last.NumberU64() - request.Number + 1
|
request.Amount = last.NumberU64() - request.Number + 1
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,13 @@ import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"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/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/eth/downloader"
|
"github.com/ethereum/go-ethereum/eth/downloader"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/p2p"
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
@ -62,14 +61,14 @@ func testGetBlockHashes(t *testing.T, protocol int) {
|
||||||
number int
|
number int
|
||||||
result int
|
result int
|
||||||
}{
|
}{
|
||||||
{common.Hash{}, 1, 0}, // Make sure non existent hashes don't return results
|
{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.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(), 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(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.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(), 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, limit}, // Request the maximum allowed hash count
|
||||||
{pm.blockchain.CurrentBlock().Hash(), limit + 1, limit}, // Request more than 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
|
// Run each of the tests and verify the results against the chain
|
||||||
for i, tt := range tests {
|
for i, tt := range tests {
|
||||||
|
|
@ -78,7 +77,7 @@ func testGetBlockHashes(t *testing.T, protocol int) {
|
||||||
if len(resp) > 0 {
|
if len(resp) > 0 {
|
||||||
from := pm.blockchain.GetBlock(tt.origin).NumberU64() - 1
|
from := pm.blockchain.GetBlock(tt.origin).NumberU64() - 1
|
||||||
for j := 0; j < len(resp); j++ {
|
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
|
// 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
|
// Assemble the hash response we would like to receive
|
||||||
resp := make([]common.Hash, tt.result)
|
resp := make([]common.Hash, tt.result)
|
||||||
for j := 0; j < len(resp); j++ {
|
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
|
// Send the hash request and verify the response
|
||||||
p2p.Send(peer.app, 0x08, getBlockHashesFromNumberData{tt.origin, uint64(tt.number)})
|
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
|
// A single random block should be retrievable by hash and number too
|
||||||
{
|
{
|
||||||
&getBlockHeadersData{Origin: hashOrNumber{Hash: pm.blockchain.GetBlockByNumber(limit/2).Hash()}, Amount: 1},
|
&getBlockHeadersData{Origin: hashOrNumber{Hash: pm.blockchain.GetBlockByNumber(limit / 2).Hash()}, Amount: 1},
|
||||||
[]common.Hash{pm.blockchain.GetBlockByNumber(limit/2).Hash()},
|
[]common.Hash{pm.blockchain.GetBlockByNumber(limit / 2).Hash()},
|
||||||
}, {
|
}, {
|
||||||
&getBlockHeadersData{Origin: hashOrNumber{Number: limit / 2}, Amount: 1},
|
&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
|
// Multiple headers should be retrievable in both directions
|
||||||
{
|
{
|
||||||
&getBlockHeadersData{Origin: hashOrNumber{Number: limit / 2}, Amount: 3},
|
&getBlockHeadersData{Origin: hashOrNumber{Number: limit / 2}, Amount: 3},
|
||||||
[]common.Hash{
|
[]common.Hash{
|
||||||
pm.blockchain.GetBlockByNumber(limit/2).Hash(),
|
pm.blockchain.GetBlockByNumber(limit / 2).Hash(),
|
||||||
pm.blockchain.GetBlockByNumber(limit/2+1).Hash(),
|
pm.blockchain.GetBlockByNumber(limit/2 + 1).Hash(),
|
||||||
pm.blockchain.GetBlockByNumber(limit/2+2).Hash(),
|
pm.blockchain.GetBlockByNumber(limit/2 + 2).Hash(),
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
&getBlockHeadersData{Origin: hashOrNumber{Number: limit / 2}, Amount: 3, Reverse: true},
|
&getBlockHeadersData{Origin: hashOrNumber{Number: limit / 2}, Amount: 3, Reverse: true},
|
||||||
[]common.Hash{
|
[]common.Hash{
|
||||||
pm.blockchain.GetBlockByNumber(limit/2).Hash(),
|
pm.blockchain.GetBlockByNumber(limit / 2).Hash(),
|
||||||
pm.blockchain.GetBlockByNumber(limit/2-1).Hash(),
|
pm.blockchain.GetBlockByNumber(limit/2 - 1).Hash(),
|
||||||
pm.blockchain.GetBlockByNumber(limit/2-2).Hash(),
|
pm.blockchain.GetBlockByNumber(limit/2 - 2).Hash(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// Multiple headers with skip lists should be retrievable
|
// Multiple headers with skip lists should be retrievable
|
||||||
{
|
{
|
||||||
&getBlockHeadersData{Origin: hashOrNumber{Number: limit / 2}, Skip: 3, Amount: 3},
|
&getBlockHeadersData{Origin: hashOrNumber{Number: limit / 2}, Skip: 3, Amount: 3},
|
||||||
[]common.Hash{
|
[]common.Hash{
|
||||||
pm.blockchain.GetBlockByNumber(limit/2).Hash(),
|
pm.blockchain.GetBlockByNumber(limit / 2).Hash(),
|
||||||
pm.blockchain.GetBlockByNumber(limit/2+4).Hash(),
|
pm.blockchain.GetBlockByNumber(limit/2 + 4).Hash(),
|
||||||
pm.blockchain.GetBlockByNumber(limit/2+8).Hash(),
|
pm.blockchain.GetBlockByNumber(limit/2 + 8).Hash(),
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
&getBlockHeadersData{Origin: hashOrNumber{Number: limit / 2}, Skip: 3, Amount: 3, Reverse: true},
|
&getBlockHeadersData{Origin: hashOrNumber{Number: limit / 2}, Skip: 3, Amount: 3, Reverse: true},
|
||||||
[]common.Hash{
|
[]common.Hash{
|
||||||
pm.blockchain.GetBlockByNumber(limit/2).Hash(),
|
pm.blockchain.GetBlockByNumber(limit / 2).Hash(),
|
||||||
pm.blockchain.GetBlockByNumber(limit/2-4).Hash(),
|
pm.blockchain.GetBlockByNumber(limit/2 - 4).Hash(),
|
||||||
pm.blockchain.GetBlockByNumber(limit/2-8).Hash(),
|
pm.blockchain.GetBlockByNumber(limit/2 - 8).Hash(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// The chain endpoints should be retrievable
|
// 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},
|
&getBlockHeadersData{Origin: hashOrNumber{Number: pm.blockchain.CurrentBlock().NumberU64() - 4}, Skip: 3, Amount: 3},
|
||||||
[]common.Hash{
|
[]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(),
|
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},
|
&getBlockHeadersData{Origin: hashOrNumber{Number: pm.blockchain.CurrentBlock().NumberU64() - 4}, Skip: 2, Amount: 3},
|
||||||
[]common.Hash{
|
[]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()-1).Hash(),
|
pm.blockchain.GetBlockByNumber(pm.blockchain.CurrentBlock().NumberU64() - 1).Hash(),
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
&getBlockHeadersData{Origin: hashOrNumber{Number: 4}, Skip: 2, Amount: 3, Reverse: true},
|
&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
|
// Fetch for now the entire chain db
|
||||||
hashes := []common.Hash{}
|
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{}) {
|
if len(key) == len(common.Hash{}) {
|
||||||
hashes = append(hashes, common.BytesToHash(key))
|
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)
|
fmt.Errorf("data hash mismatch: have %x, want %x", hash, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
statedb, _ := ethdb.NewMemDatabase()
|
statedb, _ := access.NewMemDatabase()
|
||||||
for i := 0; i < len(data); i++ {
|
for i := 0; i < len(data); i++ {
|
||||||
statedb.Put(hashes[i].Bytes(), data[i])
|
statedb.Put(hashes[i].Bytes(), data[i])
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,12 +9,11 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"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/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/p2p"
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||||
|
|
@ -33,7 +32,7 @@ func newTestProtocolManager(fastSync bool, blocks int, generator func(int, *core
|
||||||
var (
|
var (
|
||||||
evmux = new(event.TypeMux)
|
evmux = new(event.TypeMux)
|
||||||
pow = new(core.FakePow)
|
pow = new(core.FakePow)
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db, _ = access.NewMemDatabase()
|
||||||
ca = access.NewDbChainAccess(db)
|
ca = access.NewDbChainAccess(db)
|
||||||
genesis = core.WriteGenesisBlockForTesting(db, core.GenesisAccount{testBankAddress, testBankFunds})
|
genesis = core.WriteGenesisBlockForTesting(db, core.GenesisAccount{testBankAddress, testBankFunds})
|
||||||
blockchain, _ = core.NewBlockChain(ca, pow, evmux)
|
blockchain, _ = core.NewBlockChain(ca, pow, evmux)
|
||||||
|
|
|
||||||
|
|
@ -154,7 +154,7 @@ loop:
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("js error:", err, arguments)
|
fmt.Println("js error:", err, arguments)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, inreg := registry[timer] // when clearInterval is called from within the callback don't reset it
|
_, inreg := registry[timer] // when clearInterval is called from within the callback don't reset it
|
||||||
if timer.interval && inreg {
|
if timer.interval && inreg {
|
||||||
timer.timer.Reset(timer.duration)
|
timer.timer.Reset(timer.duration)
|
||||||
|
|
|
||||||
|
|
@ -24,13 +24,13 @@ import (
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
|
|
@ -101,7 +101,7 @@ type worker struct {
|
||||||
eth core.Backend
|
eth core.Backend
|
||||||
chain *core.BlockChain
|
chain *core.BlockChain
|
||||||
proc *core.BlockProcessor
|
proc *core.BlockProcessor
|
||||||
chainDb ethdb.Database
|
chainDb access.Database
|
||||||
|
|
||||||
coinbase common.Address
|
coinbase common.Address
|
||||||
gasPrice *big.Int
|
gasPrice *big.Int
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,8 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"time"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/rpc/shared"
|
"github.com/ethereum/go-ethereum/rpc/shared"
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -17,14 +17,14 @@
|
||||||
package comms
|
package comms
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"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"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
"github.com/ethereum/go-ethereum/rpc/codec"
|
"github.com/ethereum/go-ethereum/rpc/codec"
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"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"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
"github.com/ethereum/go-ethereum/rpc/codec"
|
"github.com/ethereum/go-ethereum/rpc/codec"
|
||||||
|
|
@ -66,16 +66,16 @@ type stopServer struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type handler struct {
|
type handler struct {
|
||||||
codec codec.Codec
|
codec codec.Codec
|
||||||
api shared.EthereumApi
|
api shared.EthereumApi
|
||||||
channelID *access.OdrChannelID
|
channelID *access.OdrChannelID
|
||||||
}
|
}
|
||||||
|
|
||||||
// StartHTTP starts listening for RPC requests sent via HTTP.
|
// StartHTTP starts listening for RPC requests sent via HTTP.
|
||||||
func StartHttp(cfg HttpConfig, codec codec.Codec, api shared.EthereumApi) error {
|
func StartHttp(cfg HttpConfig, codec codec.Codec, api shared.EthereumApi) error {
|
||||||
httpServerMu.Lock()
|
httpServerMu.Lock()
|
||||||
defer httpServerMu.Unlock()
|
defer httpServerMu.Unlock()
|
||||||
|
|
||||||
addr := fmt.Sprintf("%s:%d", cfg.ListenAddress, cfg.ListenPort)
|
addr := fmt.Sprintf("%s:%d", cfg.ListenAddress, cfg.ListenPort)
|
||||||
if httpServer != nil {
|
if httpServer != nil {
|
||||||
if addr != httpServer.Addr {
|
if addr != httpServer.Addr {
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"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/codec"
|
||||||
"github.com/ethereum/go-ethereum/rpc/shared"
|
"github.com/ethereum/go-ethereum/rpc/shared"
|
||||||
)
|
)
|
||||||
|
|
@ -32,13 +32,13 @@ type InProcClient struct {
|
||||||
lastJsonrpc string
|
lastJsonrpc string
|
||||||
lastErr error
|
lastErr error
|
||||||
lastRes interface{}
|
lastRes interface{}
|
||||||
channelID *access.OdrChannelID
|
channelID *access.OdrChannelID
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new in process client
|
// Create a new in process client
|
||||||
func NewInProcClient(codec codec.Codec) *InProcClient {
|
func NewInProcClient(codec codec.Codec) *InProcClient {
|
||||||
return &InProcClient{
|
return &InProcClient{
|
||||||
codec: codec,
|
codec: codec,
|
||||||
channelID: access.NewChannelID(time.Second),
|
channelID: access.NewChannelID(time.Second),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ type Request struct {
|
||||||
Jsonrpc string `json:"jsonrpc"`
|
Jsonrpc string `json:"jsonrpc"`
|
||||||
Method string `json:"method"`
|
Method string `json:"method"`
|
||||||
Params json.RawMessage `json:"params"`
|
Params json.RawMessage `json:"params"`
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
// RPC response
|
// RPC response
|
||||||
|
|
|
||||||
|
|
@ -28,15 +28,14 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"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/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/eth"
|
"github.com/ethereum/go-ethereum/eth"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
)
|
)
|
||||||
|
|
@ -165,13 +164,13 @@ func runBlockTests(bt map[string]*BlockTest, skipTests []string) error {
|
||||||
func runBlockTest(test *BlockTest) error {
|
func runBlockTest(test *BlockTest) error {
|
||||||
ks := crypto.NewKeyStorePassphrase(filepath.Join(common.DefaultDataDir(), "keystore"), crypto.StandardScryptN, crypto.StandardScryptP)
|
ks := crypto.NewKeyStorePassphrase(filepath.Join(common.DefaultDataDir(), "keystore"), crypto.StandardScryptN, crypto.StandardScryptP)
|
||||||
am := accounts.NewManager(ks)
|
am := accounts.NewManager(ks)
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
cfg := ð.Config{
|
cfg := ð.Config{
|
||||||
DataDir: common.DefaultDataDir(),
|
DataDir: common.DefaultDataDir(),
|
||||||
Verbosity: 5,
|
Verbosity: 5,
|
||||||
Etherbase: common.Address{},
|
Etherbase: common.Address{},
|
||||||
AccountManager: am,
|
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
|
cfg.GenesisBlock = test.Genesis
|
||||||
|
|
@ -217,7 +216,7 @@ func runBlockTest(test *BlockTest) error {
|
||||||
|
|
||||||
// InsertPreState populates the given database with the genesis
|
// InsertPreState populates the given database with the genesis
|
||||||
// accounts defined by the test.
|
// 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))
|
statedb, err := state.New(common.Hash{}, access.NewDbChainAccess(db))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
||||||
|
|
@ -25,13 +25,12 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"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/state"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"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) {
|
func benchStateTest(test VmTest, env map[string]string, b *testing.B) {
|
||||||
b.StopTimer()
|
b.StopTimer()
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
statedb, _ := state.New(common.Hash{}, access.NewDbChainAccess(db))
|
statedb, _ := state.New(common.Hash{}, access.NewDbChainAccess(db))
|
||||||
for addr, account := range test.Pre {
|
for addr, account := range test.Pre {
|
||||||
obj := StateObjectFromAccount(db, addr, account)
|
obj := StateObjectFromAccount(db, addr, account)
|
||||||
|
|
@ -142,7 +141,7 @@ func runStateTests(tests map[string]VmTest, skipTests []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func runStateTest(test VmTest) error {
|
func runStateTest(test VmTest) error {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
statedb, _ := state.New(common.Hash{}, access.NewDbChainAccess(db))
|
statedb, _ := state.New(common.Hash{}, access.NewDbChainAccess(db))
|
||||||
for addr, account := range test.Pre {
|
for addr, account := range test.Pre {
|
||||||
obj := StateObjectFromAccount(db, addr, account)
|
obj := StateObjectFromAccount(db, addr, account)
|
||||||
|
|
|
||||||
|
|
@ -21,14 +21,13 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"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/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func checkLogs(tlog []Log, logs vm.Logs) error {
|
func checkLogs(tlog []Log, logs vm.Logs) error {
|
||||||
|
|
@ -89,7 +88,7 @@ func (self Log) Topics() [][]byte {
|
||||||
return t
|
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 := state.NewStateObject(access.NoOdr, common.HexToAddress(addr), access.NewDbChainAccess(db))
|
||||||
obj.SetBalance(common.Big(account.Balance))
|
obj.SetBalance(common.Big(account.Balance))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,11 +24,10 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"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/state"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"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) {
|
func benchVmTest(test VmTest, env map[string]string, b *testing.B) {
|
||||||
b.StopTimer()
|
b.StopTimer()
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
statedb, _ := state.New(common.Hash{}, access.NewDbChainAccess(db))
|
statedb, _ := state.New(common.Hash{}, access.NewDbChainAccess(db))
|
||||||
for addr, account := range test.Pre {
|
for addr, account := range test.Pre {
|
||||||
obj := StateObjectFromAccount(db, addr, account)
|
obj := StateObjectFromAccount(db, addr, account)
|
||||||
|
|
@ -159,7 +158,7 @@ func runVmTests(tests map[string]VmTest, skipTests []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func runVmTest(test VmTest) error {
|
func runVmTest(test VmTest) error {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
statedb, _ := state.New(common.Hash{}, access.NewDbChainAccess(db))
|
statedb, _ := state.New(common.Hash{}, access.NewDbChainAccess(db))
|
||||||
for addr, account := range test.Pre {
|
for addr, account := range test.Pre {
|
||||||
obj := StateObjectFromAccount(db, addr, account)
|
obj := StateObjectFromAccount(db, addr, account)
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -37,7 +37,7 @@ func TestProof(t *testing.T) {
|
||||||
func TestStoreProof(t *testing.T) {
|
func TestStoreProof(t *testing.T) {
|
||||||
trie, vals := randomTrie(500)
|
trie, vals := randomTrie(500)
|
||||||
root := trie.Hash()
|
root := trie.Hash()
|
||||||
mdb, _ := ethdb.NewMemDatabase()
|
mdb, _ := access.NewMemDatabase()
|
||||||
for _, kv := range vals {
|
for _, kv := range vals {
|
||||||
proof := trie.Prove(kv.k)
|
proof := trie.Prove(kv.k)
|
||||||
if proof == nil {
|
if proof == nil {
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,8 @@ package trie
|
||||||
import (
|
import (
|
||||||
"hash"
|
"hash"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/access"
|
|
||||||
"github.com/ethereum/go-ethereum/crypto/sha3"
|
"github.com/ethereum/go-ethereum/crypto/sha3"
|
||||||
"golang.org/x/net/context"
|
"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
|
// CopySecureWithOdr creates a copy of a trie with additional ODR capability
|
||||||
func (t *SecureTrie) CopySecureWithOdr(ctx context.Context, access OdrAccess) *SecureTrie {
|
func (t *SecureTrie) CopySecureWithOdr(ctx context.Context, access OdrAccess) *SecureTrie {
|
||||||
return &SecureTrie{
|
return &SecureTrie{
|
||||||
Trie: t.Trie.CopyWithOdr(ctx, access),
|
Trie: t.Trie.CopyWithOdr(ctx, access),
|
||||||
hash: t.hash,
|
hash: t.hash,
|
||||||
secKeyBuf: t.secKeyBuf,
|
secKeyBuf: t.secKeyBuf,
|
||||||
hashKeyBuf: t.hashKeyBuf,
|
hashKeyBuf: t.hashKeyBuf,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,13 +20,13 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func newEmptySecure() *SecureTrie {
|
func newEmptySecure() *SecureTrie {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
trie, _ := NewSecure(common.Hash{}, db)
|
trie, _ := NewSecure(common.Hash{}, db)
|
||||||
return trie
|
return trie
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,8 @@ package trie
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"gopkg.in/karalabe/cookiejar.v2/collections/prque"
|
"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
|
// unknown trie hashes to retrieve, accepts node data associated with said hashes
|
||||||
// and reconstructs the trie step by step until all is done.
|
// and reconstructs the trie step by step until all is done.
|
||||||
type TrieSync struct {
|
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
|
requests map[common.Hash]*request // Pending requests pertaining to a key hash
|
||||||
queue *prque.Prque // Priority queue with the pending requests
|
queue *prque.Prque // Priority queue with the pending requests
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTrieSync creates a new trie data download scheduler.
|
// 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{
|
ts := &TrieSync{
|
||||||
database: database,
|
database: database,
|
||||||
requests: make(map[common.Hash]*request),
|
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
|
// 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
|
// of the referencing parent requests complete due to this commit, they are also
|
||||||
// committed themselves.
|
// 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
|
// Create a new batch if none was specified
|
||||||
if batch == nil {
|
if batch == nil {
|
||||||
batch = s.database.NewBatch()
|
batch = s.database.NewBatch()
|
||||||
|
|
|
||||||
|
|
@ -20,14 +20,14 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// makeTestTrie create a sample test trie to test node-wise reconstruction.
|
// 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
|
// Create an empty trie
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
trie, _ := New(common.Hash{}, db)
|
trie, _ := New(common.Hash{}, db)
|
||||||
|
|
||||||
// Fill it with some arbitrary data
|
// Fill it with some arbitrary data
|
||||||
|
|
@ -67,7 +67,7 @@ func TestEmptyTrieSync(t *testing.T) {
|
||||||
emptyB, _ := New(emptyRoot, nil)
|
emptyB, _ := New(emptyRoot, nil)
|
||||||
|
|
||||||
for i, trie := range []*Trie{emptyA, emptyB} {
|
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 {
|
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)
|
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()
|
srcDb, srcTrie, srcData := makeTestTrie()
|
||||||
|
|
||||||
// Create a destination trie and sync with the scheduler
|
// Create a destination trie and sync with the scheduler
|
||||||
dstDb, _ := ethdb.NewMemDatabase()
|
dstDb, _ := access.NewMemDatabase()
|
||||||
sched := NewTrieSync(common.BytesToHash(srcTrie.Root()), dstDb, nil)
|
sched := NewTrieSync(common.BytesToHash(srcTrie.Root()), dstDb, nil)
|
||||||
|
|
||||||
queue := append([]common.Hash{}, sched.Missing(batch)...)
|
queue := append([]common.Hash{}, sched.Missing(batch)...)
|
||||||
|
|
@ -113,7 +113,7 @@ func TestIterativeDelayedTrieSync(t *testing.T) {
|
||||||
srcDb, srcTrie, srcData := makeTestTrie()
|
srcDb, srcTrie, srcData := makeTestTrie()
|
||||||
|
|
||||||
// Create a destination trie and sync with the scheduler
|
// Create a destination trie and sync with the scheduler
|
||||||
dstDb, _ := ethdb.NewMemDatabase()
|
dstDb, _ := access.NewMemDatabase()
|
||||||
sched := NewTrieSync(common.BytesToHash(srcTrie.Root()), dstDb, nil)
|
sched := NewTrieSync(common.BytesToHash(srcTrie.Root()), dstDb, nil)
|
||||||
|
|
||||||
queue := append([]common.Hash{}, sched.Missing(10000)...)
|
queue := append([]common.Hash{}, sched.Missing(10000)...)
|
||||||
|
|
@ -147,7 +147,7 @@ func testIterativeRandomTrieSync(t *testing.T, batch int) {
|
||||||
srcDb, srcTrie, srcData := makeTestTrie()
|
srcDb, srcTrie, srcData := makeTestTrie()
|
||||||
|
|
||||||
// Create a destination trie and sync with the scheduler
|
// Create a destination trie and sync with the scheduler
|
||||||
dstDb, _ := ethdb.NewMemDatabase()
|
dstDb, _ := access.NewMemDatabase()
|
||||||
sched := NewTrieSync(common.BytesToHash(srcTrie.Root()), dstDb, nil)
|
sched := NewTrieSync(common.BytesToHash(srcTrie.Root()), dstDb, nil)
|
||||||
|
|
||||||
queue := make(map[common.Hash]struct{})
|
queue := make(map[common.Hash]struct{})
|
||||||
|
|
@ -184,7 +184,7 @@ func TestIterativeRandomDelayedTrieSync(t *testing.T) {
|
||||||
srcDb, srcTrie, srcData := makeTestTrie()
|
srcDb, srcTrie, srcData := makeTestTrie()
|
||||||
|
|
||||||
// Create a destination trie and sync with the scheduler
|
// Create a destination trie and sync with the scheduler
|
||||||
dstDb, _ := ethdb.NewMemDatabase()
|
dstDb, _ := access.NewMemDatabase()
|
||||||
sched := NewTrieSync(common.BytesToHash(srcTrie.Root()), dstDb, nil)
|
sched := NewTrieSync(common.BytesToHash(srcTrie.Root()), dstDb, nil)
|
||||||
|
|
||||||
queue := make(map[common.Hash]struct{})
|
queue := make(map[common.Hash]struct{})
|
||||||
|
|
@ -227,7 +227,7 @@ func TestDuplicateAvoidanceTrieSync(t *testing.T) {
|
||||||
srcDb, srcTrie, srcData := makeTestTrie()
|
srcDb, srcTrie, srcData := makeTestTrie()
|
||||||
|
|
||||||
// Create a destination trie and sync with the scheduler
|
// Create a destination trie and sync with the scheduler
|
||||||
dstDb, _ := ethdb.NewMemDatabase()
|
dstDb, _ := access.NewMemDatabase()
|
||||||
sched := NewTrieSync(common.BytesToHash(srcTrie.Root()), dstDb, nil)
|
sched := NewTrieSync(common.BytesToHash(srcTrie.Root()), dstDb, nil)
|
||||||
|
|
||||||
queue := append([]common.Hash{}, sched.Missing(0)...)
|
queue := append([]common.Hash{}, sched.Missing(0)...)
|
||||||
|
|
|
||||||
10
trie/trie.go
10
trie/trie.go
|
|
@ -23,8 +23,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"hash"
|
"hash"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"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"
|
||||||
"github.com/ethereum/go-ethereum/crypto/sha3"
|
"github.com/ethereum/go-ethereum/crypto/sha3"
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"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
|
// OdrAccess is an interface to on-demand network access layer
|
||||||
type OdrAccess interface {
|
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
|
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
|
root node
|
||||||
db Database
|
db Database
|
||||||
access OdrAccess
|
access OdrAccess
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
*hasher
|
*hasher
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -388,8 +388,8 @@ func (t *Trie) CommitTo(db DatabaseWriter) (root common.Hash, err error) {
|
||||||
if access.Terminated(t.ctx) {
|
if access.Terminated(t.ctx) {
|
||||||
// we should never commit potentially corrupt trie nodes to the db
|
// we should never commit potentially corrupt trie nodes to the db
|
||||||
return common.Hash{}, t.ctx.Err()
|
return common.Hash{}, t.ctx.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
n, err := t.hashRoot(db)
|
n, err := t.hashRoot(db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return (common.Hash{}), err
|
return (common.Hash{}), err
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,8 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
|
"github.com/ethereum/go-ethereum/access"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
@ -36,7 +36,7 @@ func init() {
|
||||||
|
|
||||||
// Used for testing
|
// Used for testing
|
||||||
func newEmpty() *Trie {
|
func newEmpty() *Trie {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
trie, _ := New(common.Hash{}, db)
|
trie, _ := New(common.Hash{}, db)
|
||||||
return trie
|
return trie
|
||||||
}
|
}
|
||||||
|
|
@ -59,7 +59,7 @@ func TestNull(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMissingRoot(t *testing.T) {
|
func TestMissingRoot(t *testing.T) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := access.NewMemDatabase()
|
||||||
trie, err := New(common.HexToHash("0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"), db)
|
trie, err := New(common.HexToHash("0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"), db)
|
||||||
if trie != nil {
|
if trie != nil {
|
||||||
t.Error("New returned non-nil trie for invalid root")
|
t.Error("New returned non-nil trie for invalid root")
|
||||||
|
|
@ -388,7 +388,7 @@ func tempDB() (string, Database) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Sprintf("can't create temporary directory: %v", err))
|
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 {
|
if err != nil {
|
||||||
panic(fmt.Sprintf("can't create temporary database: %v", err))
|
panic(fmt.Sprintf("can't create temporary database: %v", err))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ type XEth struct {
|
||||||
state *State
|
state *State
|
||||||
whisper *Whisper
|
whisper *Whisper
|
||||||
filterManager *filters.FilterSystem
|
filterManager *filters.FilterSystem
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTest(eth *eth.Ethereum, frontend Frontend) *XEth {
|
func NewTest(eth *eth.Ethereum, frontend Frontend) *XEth {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue