mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 18:02:24 +00:00
Merge branch 'master' of https://github.com/kielbarry/go-ethereum into commonGolintComments
This commit is contained in:
commit
4d270e9074
97 changed files with 1085 additions and 860 deletions
10
.travis.yml
10
.travis.yml
|
|
@ -126,7 +126,7 @@ matrix:
|
||||||
|
|
||||||
# This builder does the Android Maven and Azure uploads
|
# This builder does the Android Maven and Azure uploads
|
||||||
- os: linux
|
- os: linux
|
||||||
dist: precise # Needed for the android tools
|
dist: trusty
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
packages:
|
packages:
|
||||||
|
|
@ -152,10 +152,10 @@ matrix:
|
||||||
- export GOPATH=$HOME/go
|
- export GOPATH=$HOME/go
|
||||||
script:
|
script:
|
||||||
# Build the Android archive and upload it to Maven Central and Azure
|
# Build the Android archive and upload it to Maven Central and Azure
|
||||||
- curl https://dl.google.com/android/repository/android-ndk-r15c-linux-x86_64.zip -o android-ndk-r15c.zip
|
- curl https://dl.google.com/android/repository/android-ndk-r16b-linux-x86_64.zip -o android-ndk-r16b.zip
|
||||||
- unzip -q android-ndk-r15c.zip && rm android-ndk-r15c.zip
|
- unzip -q android-ndk-r16b.zip && rm android-ndk-r16b.zip
|
||||||
- mv android-ndk-r15c $HOME
|
- mv android-ndk-r16b $HOME
|
||||||
- export ANDROID_NDK=$HOME/android-ndk-r15c
|
- export ANDROID_NDK=$HOME/android-ndk-r16b
|
||||||
|
|
||||||
- mkdir -p $GOPATH/src/github.com/ethereum
|
- mkdir -p $GOPATH/src/github.com/ethereum
|
||||||
- ln -s `pwd` $GOPATH/src/github.com/ethereum
|
- ln -s `pwd` $GOPATH/src/github.com/ethereum
|
||||||
|
|
|
||||||
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
||||||
1.8.8
|
1.8.9
|
||||||
|
|
|
||||||
|
|
@ -111,9 +111,14 @@ func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interfa
|
||||||
if err := requireUnpackKind(value, typ, kind, arguments); err != nil {
|
if err := requireUnpackKind(value, typ, kind, arguments); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// If the output interface is a struct, make sure names don't collide
|
|
||||||
|
// If the interface is a struct, get of abi->struct_field mapping
|
||||||
|
|
||||||
|
var abi2struct map[string]string
|
||||||
if kind == reflect.Struct {
|
if kind == reflect.Struct {
|
||||||
if err := requireUniqueStructFieldNames(arguments); err != nil {
|
var err error
|
||||||
|
abi2struct, err = mapAbiToStructFields(arguments, value)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -123,10 +128,11 @@ func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interfa
|
||||||
|
|
||||||
switch kind {
|
switch kind {
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
err := unpackStruct(value, reflectValue, arg)
|
if structField, ok := abi2struct[arg.Name]; ok {
|
||||||
if err != nil {
|
if err := set(value.FieldByName(structField), reflectValue, arg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
case reflect.Slice, reflect.Array:
|
case reflect.Slice, reflect.Array:
|
||||||
if value.Len() < i {
|
if value.Len() < i {
|
||||||
return fmt.Errorf("abi: insufficient number of arguments for unpack, want %d, got %d", len(arguments), value.Len())
|
return fmt.Errorf("abi: insufficient number of arguments for unpack, want %d, got %d", len(arguments), value.Len())
|
||||||
|
|
@ -151,17 +157,22 @@ func (arguments Arguments) unpackAtomic(v interface{}, marshalledValues []interf
|
||||||
if len(marshalledValues) != 1 {
|
if len(marshalledValues) != 1 {
|
||||||
return fmt.Errorf("abi: wrong length, expected single value, got %d", len(marshalledValues))
|
return fmt.Errorf("abi: wrong length, expected single value, got %d", len(marshalledValues))
|
||||||
}
|
}
|
||||||
|
|
||||||
elem := reflect.ValueOf(v).Elem()
|
elem := reflect.ValueOf(v).Elem()
|
||||||
kind := elem.Kind()
|
kind := elem.Kind()
|
||||||
reflectValue := reflect.ValueOf(marshalledValues[0])
|
reflectValue := reflect.ValueOf(marshalledValues[0])
|
||||||
|
|
||||||
|
var abi2struct map[string]string
|
||||||
if kind == reflect.Struct {
|
if kind == reflect.Struct {
|
||||||
//make sure names don't collide
|
var err error
|
||||||
if err := requireUniqueStructFieldNames(arguments); err != nil {
|
if abi2struct, err = mapAbiToStructFields(arguments, elem); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
arg := arguments.NonIndexed()[0]
|
||||||
return unpackStruct(elem, reflectValue, arguments[0])
|
if structField, ok := abi2struct[arg.Name]; ok {
|
||||||
|
return set(elem.FieldByName(structField), reflectValue, arg)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return set(elem, reflectValue, arguments.NonIndexed()[0])
|
return set(elem, reflectValue, arguments.NonIndexed()[0])
|
||||||
|
|
@ -277,18 +288,3 @@ func capitalise(input string) string {
|
||||||
}
|
}
|
||||||
return strings.ToUpper(input[:1]) + input[1:]
|
return strings.ToUpper(input[:1]) + input[1:]
|
||||||
}
|
}
|
||||||
|
|
||||||
//unpackStruct extracts each argument into its corresponding struct field
|
|
||||||
func unpackStruct(value, reflectValue reflect.Value, arg Argument) error {
|
|
||||||
name := capitalise(arg.Name)
|
|
||||||
typ := value.Type()
|
|
||||||
for j := 0; j < typ.NumField(); j++ {
|
|
||||||
// TODO read tags: `abi:"fieldName"`
|
|
||||||
if typ.Field(j).Name == name {
|
|
||||||
if err := set(value.Field(j), reflectValue, arg); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ type SimulatedBackend struct {
|
||||||
// NewSimulatedBackend creates a new binding backend using a simulated blockchain
|
// NewSimulatedBackend creates a new binding backend using a simulated blockchain
|
||||||
// for testing purposes.
|
// for testing purposes.
|
||||||
func NewSimulatedBackend(alloc core.GenesisAlloc) *SimulatedBackend {
|
func NewSimulatedBackend(alloc core.GenesisAlloc) *SimulatedBackend {
|
||||||
database, _ := ethdb.NewMemDatabase()
|
database := ethdb.NewMemDatabase()
|
||||||
genesis := core.Genesis{Config: params.AllEthashProtocolChanges, Alloc: alloc}
|
genesis := core.Genesis{Config: params.AllEthashProtocolChanges, Alloc: alloc}
|
||||||
genesis.MustCommit(database)
|
genesis.MustCommit(database)
|
||||||
blockchain, _ := core.NewBlockChain(database, nil, genesis.Config, ethash.NewFaker(), vm.Config{})
|
blockchain, _ := core.NewBlockChain(database, nil, genesis.Config, ethash.NewFaker(), vm.Config{})
|
||||||
|
|
|
||||||
|
|
@ -58,12 +58,28 @@ var jsonEventPledge = []byte(`{
|
||||||
"type": "event"
|
"type": "event"
|
||||||
}`)
|
}`)
|
||||||
|
|
||||||
|
var jsonEventMixedCase = []byte(`{
|
||||||
|
"anonymous": false,
|
||||||
|
"inputs": [{
|
||||||
|
"indexed": false, "name": "value", "type": "uint256"
|
||||||
|
}, {
|
||||||
|
"indexed": false, "name": "_value", "type": "uint256"
|
||||||
|
}, {
|
||||||
|
"indexed": false, "name": "Value", "type": "uint256"
|
||||||
|
}],
|
||||||
|
"name": "MixedCase",
|
||||||
|
"type": "event"
|
||||||
|
}`)
|
||||||
|
|
||||||
// 1000000
|
// 1000000
|
||||||
var transferData1 = "00000000000000000000000000000000000000000000000000000000000f4240"
|
var transferData1 = "00000000000000000000000000000000000000000000000000000000000f4240"
|
||||||
|
|
||||||
// "0x00Ce0d46d924CC8437c806721496599FC3FFA268", 2218516807680, "usd"
|
// "0x00Ce0d46d924CC8437c806721496599FC3FFA268", 2218516807680, "usd"
|
||||||
var pledgeData1 = "00000000000000000000000000ce0d46d924cc8437c806721496599fc3ffa2680000000000000000000000000000000000000000000000000000020489e800007573640000000000000000000000000000000000000000000000000000000000"
|
var pledgeData1 = "00000000000000000000000000ce0d46d924cc8437c806721496599fc3ffa2680000000000000000000000000000000000000000000000000000020489e800007573640000000000000000000000000000000000000000000000000000000000"
|
||||||
|
|
||||||
|
// 1000000,2218516807680,1000001
|
||||||
|
var mixedCaseData1 = "00000000000000000000000000000000000000000000000000000000000f42400000000000000000000000000000000000000000000000000000020489e8000000000000000000000000000000000000000000000000000000000000000f4241"
|
||||||
|
|
||||||
func TestEventId(t *testing.T) {
|
func TestEventId(t *testing.T) {
|
||||||
var table = []struct {
|
var table = []struct {
|
||||||
definition string
|
definition string
|
||||||
|
|
@ -121,6 +137,27 @@ func TestEventTupleUnpack(t *testing.T) {
|
||||||
Value *big.Int
|
Value *big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type EventTransferWithTag struct {
|
||||||
|
// this is valid because `value` is not exportable,
|
||||||
|
// so value is only unmarshalled into `Value1`.
|
||||||
|
value *big.Int
|
||||||
|
Value1 *big.Int `abi:"value"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type BadEventTransferWithSameFieldAndTag struct {
|
||||||
|
Value *big.Int
|
||||||
|
Value1 *big.Int `abi:"value"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type BadEventTransferWithDuplicatedTag struct {
|
||||||
|
Value1 *big.Int `abi:"value"`
|
||||||
|
Value2 *big.Int `abi:"value"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type BadEventTransferWithEmptyTag struct {
|
||||||
|
Value *big.Int `abi:""`
|
||||||
|
}
|
||||||
|
|
||||||
type EventPledge struct {
|
type EventPledge struct {
|
||||||
Who common.Address
|
Who common.Address
|
||||||
Wad *big.Int
|
Wad *big.Int
|
||||||
|
|
@ -133,9 +170,16 @@ func TestEventTupleUnpack(t *testing.T) {
|
||||||
Currency [3]byte
|
Currency [3]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type EventMixedCase struct {
|
||||||
|
Value1 *big.Int `abi:"value"`
|
||||||
|
Value2 *big.Int `abi:"_value"`
|
||||||
|
Value3 *big.Int `abi:"Value"`
|
||||||
|
}
|
||||||
|
|
||||||
bigint := new(big.Int)
|
bigint := new(big.Int)
|
||||||
bigintExpected := big.NewInt(1000000)
|
bigintExpected := big.NewInt(1000000)
|
||||||
bigintExpected2 := big.NewInt(2218516807680)
|
bigintExpected2 := big.NewInt(2218516807680)
|
||||||
|
bigintExpected3 := big.NewInt(1000001)
|
||||||
addr := common.HexToAddress("0x00Ce0d46d924CC8437c806721496599FC3FFA268")
|
addr := common.HexToAddress("0x00Ce0d46d924CC8437c806721496599FC3FFA268")
|
||||||
var testCases = []struct {
|
var testCases = []struct {
|
||||||
data string
|
data string
|
||||||
|
|
@ -158,6 +202,34 @@ func TestEventTupleUnpack(t *testing.T) {
|
||||||
jsonEventTransfer,
|
jsonEventTransfer,
|
||||||
"",
|
"",
|
||||||
"Can unpack ERC20 Transfer event into slice",
|
"Can unpack ERC20 Transfer event into slice",
|
||||||
|
}, {
|
||||||
|
transferData1,
|
||||||
|
&EventTransferWithTag{},
|
||||||
|
&EventTransferWithTag{Value1: bigintExpected},
|
||||||
|
jsonEventTransfer,
|
||||||
|
"",
|
||||||
|
"Can unpack ERC20 Transfer event into structure with abi: tag",
|
||||||
|
}, {
|
||||||
|
transferData1,
|
||||||
|
&BadEventTransferWithDuplicatedTag{},
|
||||||
|
&BadEventTransferWithDuplicatedTag{},
|
||||||
|
jsonEventTransfer,
|
||||||
|
"struct: abi tag in 'Value2' already mapped",
|
||||||
|
"Can not unpack ERC20 Transfer event with duplicated abi tag",
|
||||||
|
}, {
|
||||||
|
transferData1,
|
||||||
|
&BadEventTransferWithSameFieldAndTag{},
|
||||||
|
&BadEventTransferWithSameFieldAndTag{},
|
||||||
|
jsonEventTransfer,
|
||||||
|
"abi: multiple variables maps to the same abi field 'value'",
|
||||||
|
"Can not unpack ERC20 Transfer event with a field and a tag mapping to the same abi variable",
|
||||||
|
}, {
|
||||||
|
transferData1,
|
||||||
|
&BadEventTransferWithEmptyTag{},
|
||||||
|
&BadEventTransferWithEmptyTag{},
|
||||||
|
jsonEventTransfer,
|
||||||
|
"struct: abi tag in 'Value' is empty",
|
||||||
|
"Can not unpack ERC20 Transfer event with an empty tag",
|
||||||
}, {
|
}, {
|
||||||
pledgeData1,
|
pledgeData1,
|
||||||
&EventPledge{},
|
&EventPledge{},
|
||||||
|
|
@ -216,6 +288,13 @@ func TestEventTupleUnpack(t *testing.T) {
|
||||||
jsonEventPledge,
|
jsonEventPledge,
|
||||||
"abi: cannot unmarshal tuple into map[string]interface {}",
|
"abi: cannot unmarshal tuple into map[string]interface {}",
|
||||||
"Can not unpack Pledge event into map",
|
"Can not unpack Pledge event into map",
|
||||||
|
}, {
|
||||||
|
mixedCaseData1,
|
||||||
|
&EventMixedCase{},
|
||||||
|
&EventMixedCase{Value1: bigintExpected, Value2: bigintExpected2, Value3: bigintExpected3},
|
||||||
|
jsonEventMixedCase,
|
||||||
|
"",
|
||||||
|
"Can unpack abi variables with mixed case",
|
||||||
}}
|
}}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
|
|
@ -227,7 +306,7 @@ func TestEventTupleUnpack(t *testing.T) {
|
||||||
assert.Nil(err, "Should be able to unpack event data.")
|
assert.Nil(err, "Should be able to unpack event data.")
|
||||||
assert.Equal(tc.expected, tc.dest, tc.name)
|
assert.Equal(tc.expected, tc.dest, tc.name)
|
||||||
} else {
|
} else {
|
||||||
assert.EqualError(err, tc.error)
|
assert.EqualError(err, tc.error, tc.name)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ package abi
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// indirect recursively dereferences the value until it either gets the value
|
// indirect recursively dereferences the value until it either gets the value
|
||||||
|
|
@ -111,18 +112,101 @@ func requireUnpackKind(v reflect.Value, t reflect.Type, k reflect.Kind,
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// requireUniqueStructFieldNames makes sure field names don't collide
|
// mapAbiToStringField maps abi to struct fields.
|
||||||
func requireUniqueStructFieldNames(args Arguments) error {
|
// first round: for each Exportable field that contains a `abi:""` tag
|
||||||
exists := make(map[string]bool)
|
// and this field name exists in the arguments, pair them together.
|
||||||
|
// second round: for each argument field that has not been already linked,
|
||||||
|
// find what variable is expected to be mapped into, if it exists and has not been
|
||||||
|
// used, pair them.
|
||||||
|
func mapAbiToStructFields(args Arguments, value reflect.Value) (map[string]string, error) {
|
||||||
|
|
||||||
|
typ := value.Type()
|
||||||
|
|
||||||
|
abi2struct := make(map[string]string)
|
||||||
|
struct2abi := make(map[string]string)
|
||||||
|
|
||||||
|
// first round ~~~
|
||||||
|
for i := 0; i < typ.NumField(); i++ {
|
||||||
|
structFieldName := typ.Field(i).Name
|
||||||
|
|
||||||
|
// skip private struct fields.
|
||||||
|
if structFieldName[:1] != strings.ToUpper(structFieldName[:1]) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// skip fields that have no abi:"" tag.
|
||||||
|
var ok bool
|
||||||
|
var tagName string
|
||||||
|
if tagName, ok = typ.Field(i).Tag.Lookup("abi"); !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if tag is empty.
|
||||||
|
if tagName == "" {
|
||||||
|
return nil, fmt.Errorf("struct: abi tag in '%s' is empty", structFieldName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// check which argument field matches with the abi tag.
|
||||||
|
found := false
|
||||||
|
for _, abiField := range args.NonIndexed() {
|
||||||
|
if abiField.Name == tagName {
|
||||||
|
if abi2struct[abiField.Name] != "" {
|
||||||
|
return nil, fmt.Errorf("struct: abi tag in '%s' already mapped", structFieldName)
|
||||||
|
}
|
||||||
|
// pair them
|
||||||
|
abi2struct[abiField.Name] = structFieldName
|
||||||
|
struct2abi[structFieldName] = abiField.Name
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if this tag has been mapped.
|
||||||
|
if !found {
|
||||||
|
return nil, fmt.Errorf("struct: abi tag '%s' defined but not found in abi", tagName)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// second round ~~~
|
||||||
for _, arg := range args {
|
for _, arg := range args {
|
||||||
field := capitalise(arg.Name)
|
|
||||||
if field == "" {
|
abiFieldName := arg.Name
|
||||||
return fmt.Errorf("abi: purely underscored output cannot unpack to struct")
|
structFieldName := capitalise(abiFieldName)
|
||||||
|
|
||||||
|
if structFieldName == "" {
|
||||||
|
return nil, fmt.Errorf("abi: purely underscored output cannot unpack to struct")
|
||||||
}
|
}
|
||||||
if exists[field] {
|
|
||||||
return fmt.Errorf("abi: multiple outputs mapping to the same struct field '%s'", field)
|
// this abi has already been paired, skip it... unless there exists another, yet unassigned
|
||||||
|
// struct field with the same field name. If so, raise an error:
|
||||||
|
// abi: [ { "name": "value" } ]
|
||||||
|
// struct { Value *big.Int , Value1 *big.Int `abi:"value"`}
|
||||||
|
if abi2struct[abiFieldName] != "" {
|
||||||
|
if abi2struct[abiFieldName] != structFieldName &&
|
||||||
|
struct2abi[structFieldName] == "" &&
|
||||||
|
value.FieldByName(structFieldName).IsValid() {
|
||||||
|
return nil, fmt.Errorf("abi: multiple variables maps to the same abi field '%s'", abiFieldName)
|
||||||
}
|
}
|
||||||
exists[field] = true
|
continue
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
|
// return an error if this struct field has already been paired.
|
||||||
|
if struct2abi[structFieldName] != "" {
|
||||||
|
return nil, fmt.Errorf("abi: multiple outputs mapping to the same struct field '%s'", structFieldName)
|
||||||
|
}
|
||||||
|
|
||||||
|
if value.FieldByName(structFieldName).IsValid() {
|
||||||
|
// pair them
|
||||||
|
abi2struct[abiFieldName] = structFieldName
|
||||||
|
struct2abi[structFieldName] = abiFieldName
|
||||||
|
} else {
|
||||||
|
// not paired, but annotate as used, to detect cases like
|
||||||
|
// abi : [ { "name": "value" }, { "name": "_value" } ]
|
||||||
|
// struct { Value *big.Int }
|
||||||
|
struct2abi[structFieldName] = abiFieldName
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return abi2struct, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
178
bmt/bmt.go
178
bmt/bmt.go
|
|
@ -150,29 +150,29 @@ func NewTreePool(hasher BaseHasher, segmentCount, capacity int) *TreePool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Drain drains the pool until it has no more than n resources
|
// Drain drains the pool until it has no more than n resources
|
||||||
func (self *TreePool) Drain(n int) {
|
func (p *TreePool) Drain(n int) {
|
||||||
self.lock.Lock()
|
p.lock.Lock()
|
||||||
defer self.lock.Unlock()
|
defer p.lock.Unlock()
|
||||||
for len(self.c) > n {
|
for len(p.c) > n {
|
||||||
<-self.c
|
<-p.c
|
||||||
self.count--
|
p.count--
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reserve is blocking until it returns an available Tree
|
// Reserve is blocking until it returns an available Tree
|
||||||
// it reuses free Trees or creates a new one if size is not reached
|
// it reuses free Trees or creates a new one if size is not reached
|
||||||
func (self *TreePool) Reserve() *Tree {
|
func (p *TreePool) Reserve() *Tree {
|
||||||
self.lock.Lock()
|
p.lock.Lock()
|
||||||
defer self.lock.Unlock()
|
defer p.lock.Unlock()
|
||||||
var t *Tree
|
var t *Tree
|
||||||
if self.count == self.Capacity {
|
if p.count == p.Capacity {
|
||||||
return <-self.c
|
return <-p.c
|
||||||
}
|
}
|
||||||
select {
|
select {
|
||||||
case t = <-self.c:
|
case t = <-p.c:
|
||||||
default:
|
default:
|
||||||
t = NewTree(self.hasher, self.SegmentSize, self.SegmentCount)
|
t = NewTree(p.hasher, p.SegmentSize, p.SegmentCount)
|
||||||
self.count++
|
p.count++
|
||||||
}
|
}
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
@ -180,8 +180,8 @@ func (self *TreePool) Reserve() *Tree {
|
||||||
// Release gives back a Tree to the pool.
|
// Release gives back a Tree to the pool.
|
||||||
// This Tree is guaranteed to be in reusable state
|
// This Tree is guaranteed to be in reusable state
|
||||||
// does not need locking
|
// does not need locking
|
||||||
func (self *TreePool) Release(t *Tree) {
|
func (p *TreePool) Release(t *Tree) {
|
||||||
self.c <- t // can never fail but...
|
p.c <- t // can never fail but...
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tree is a reusable control structure representing a BMT
|
// Tree is a reusable control structure representing a BMT
|
||||||
|
|
@ -193,17 +193,17 @@ type Tree struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw draws the BMT (badly)
|
// Draw draws the BMT (badly)
|
||||||
func (self *Tree) Draw(hash []byte, d int) string {
|
func (t *Tree) Draw(hash []byte, d int) string {
|
||||||
var left, right []string
|
var left, right []string
|
||||||
var anc []*Node
|
var anc []*Node
|
||||||
for i, n := range self.leaves {
|
for i, n := range t.leaves {
|
||||||
left = append(left, fmt.Sprintf("%v", hashstr(n.left)))
|
left = append(left, fmt.Sprintf("%v", hashstr(n.left)))
|
||||||
if i%2 == 0 {
|
if i%2 == 0 {
|
||||||
anc = append(anc, n.parent)
|
anc = append(anc, n.parent)
|
||||||
}
|
}
|
||||||
right = append(right, fmt.Sprintf("%v", hashstr(n.right)))
|
right = append(right, fmt.Sprintf("%v", hashstr(n.right)))
|
||||||
}
|
}
|
||||||
anc = self.leaves
|
anc = t.leaves
|
||||||
var hashes [][]string
|
var hashes [][]string
|
||||||
for l := 0; len(anc) > 0; l++ {
|
for l := 0; len(anc) > 0; l++ {
|
||||||
var nodes []*Node
|
var nodes []*Node
|
||||||
|
|
@ -277,42 +277,42 @@ func NewTree(hasher BaseHasher, segmentSize, segmentCount int) *Tree {
|
||||||
// methods needed by hash.Hash
|
// methods needed by hash.Hash
|
||||||
|
|
||||||
// Size returns the size
|
// Size returns the size
|
||||||
func (self *Hasher) Size() int {
|
func (h *Hasher) Size() int {
|
||||||
return self.size
|
return h.size
|
||||||
}
|
}
|
||||||
|
|
||||||
// BlockSize returns the block size
|
// BlockSize returns the block size
|
||||||
func (self *Hasher) BlockSize() int {
|
func (h *Hasher) BlockSize() int {
|
||||||
return self.blocksize
|
return h.blocksize
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sum returns the hash of the buffer
|
// Sum returns the hash of the buffer
|
||||||
// hash.Hash interface Sum method appends the byte slice to the underlying
|
// hash.Hash interface Sum method appends the byte slice to the underlying
|
||||||
// data before it calculates and returns the hash of the chunk
|
// data before it calculates and returns the hash of the chunk
|
||||||
func (self *Hasher) Sum(b []byte) (r []byte) {
|
func (h *Hasher) Sum(b []byte) (r []byte) {
|
||||||
t := self.bmt
|
t := h.bmt
|
||||||
i := self.cur
|
i := h.cur
|
||||||
n := t.leaves[i]
|
n := t.leaves[i]
|
||||||
j := i
|
j := i
|
||||||
// must run strictly before all nodes calculate
|
// must run strictly before all nodes calculate
|
||||||
// datanodes are guaranteed to have a parent
|
// datanodes are guaranteed to have a parent
|
||||||
if len(self.segment) > self.size && i > 0 && n.parent != nil {
|
if len(h.segment) > h.size && i > 0 && n.parent != nil {
|
||||||
n = n.parent
|
n = n.parent
|
||||||
} else {
|
} else {
|
||||||
i *= 2
|
i *= 2
|
||||||
}
|
}
|
||||||
d := self.finalise(n, i)
|
d := h.finalise(n, i)
|
||||||
self.writeSegment(j, self.segment, d)
|
h.writeSegment(j, h.segment, d)
|
||||||
c := <-self.result
|
c := <-h.result
|
||||||
self.releaseTree()
|
h.releaseTree()
|
||||||
|
|
||||||
// sha3(length + BMT(pure_chunk))
|
// sha3(length + BMT(pure_chunk))
|
||||||
if self.blockLength == nil {
|
if h.blockLength == nil {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
res := self.pool.hasher()
|
res := h.pool.hasher()
|
||||||
res.Reset()
|
res.Reset()
|
||||||
res.Write(self.blockLength)
|
res.Write(h.blockLength)
|
||||||
res.Write(c)
|
res.Write(c)
|
||||||
return res.Sum(nil)
|
return res.Sum(nil)
|
||||||
}
|
}
|
||||||
|
|
@ -321,8 +321,8 @@ func (self *Hasher) Sum(b []byte) (r []byte) {
|
||||||
|
|
||||||
// Hash waits for the hasher result and returns it
|
// Hash waits for the hasher result and returns it
|
||||||
// caller must call this on a BMT Hasher being written to
|
// caller must call this on a BMT Hasher being written to
|
||||||
func (self *Hasher) Hash() []byte {
|
func (h *Hasher) Hash() []byte {
|
||||||
return <-self.result
|
return <-h.result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hasher implements the io.Writer interface
|
// Hasher implements the io.Writer interface
|
||||||
|
|
@ -330,16 +330,16 @@ func (self *Hasher) Hash() []byte {
|
||||||
// Write fills the buffer to hash
|
// Write fills the buffer to hash
|
||||||
// with every full segment complete launches a hasher go routine
|
// with every full segment complete launches a hasher go routine
|
||||||
// that shoots up the BMT
|
// that shoots up the BMT
|
||||||
func (self *Hasher) Write(b []byte) (int, error) {
|
func (h *Hasher) Write(b []byte) (int, error) {
|
||||||
l := len(b)
|
l := len(b)
|
||||||
if l <= 0 {
|
if l <= 0 {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
s := self.segment
|
s := h.segment
|
||||||
i := self.cur
|
i := h.cur
|
||||||
count := (self.count + 1) / 2
|
count := (h.count + 1) / 2
|
||||||
need := self.count*self.size - self.cur*2*self.size
|
need := h.count*h.size - h.cur*2*h.size
|
||||||
size := self.size
|
size := h.size
|
||||||
if need > size {
|
if need > size {
|
||||||
size *= 2
|
size *= 2
|
||||||
}
|
}
|
||||||
|
|
@ -356,7 +356,7 @@ func (self *Hasher) Write(b []byte) (int, error) {
|
||||||
// read full segments and the last possibly partial segment
|
// read full segments and the last possibly partial segment
|
||||||
for need > 0 && i < count-1 {
|
for need > 0 && i < count-1 {
|
||||||
// push all finished chunks we read
|
// push all finished chunks we read
|
||||||
self.writeSegment(i, s, self.depth)
|
h.writeSegment(i, s, h.depth)
|
||||||
need -= size
|
need -= size
|
||||||
if need < 0 {
|
if need < 0 {
|
||||||
size += need
|
size += need
|
||||||
|
|
@ -365,8 +365,8 @@ func (self *Hasher) Write(b []byte) (int, error) {
|
||||||
rest += size
|
rest += size
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
self.segment = s
|
h.segment = s
|
||||||
self.cur = i
|
h.cur = i
|
||||||
// otherwise, we can assume len(s) == 0, so all buffer is read and chunk is not yet full
|
// otherwise, we can assume len(s) == 0, so all buffer is read and chunk is not yet full
|
||||||
return l, nil
|
return l, nil
|
||||||
}
|
}
|
||||||
|
|
@ -376,8 +376,8 @@ func (self *Hasher) Write(b []byte) (int, error) {
|
||||||
// ReadFrom reads from io.Reader and appends to the data to hash using Write
|
// ReadFrom reads from io.Reader and appends to the data to hash using Write
|
||||||
// it reads so that chunk to hash is maximum length or reader reaches EOF
|
// it reads so that chunk to hash is maximum length or reader reaches EOF
|
||||||
// caller must Reset the hasher prior to call
|
// caller must Reset the hasher prior to call
|
||||||
func (self *Hasher) ReadFrom(r io.Reader) (m int64, err error) {
|
func (h *Hasher) ReadFrom(r io.Reader) (m int64, err error) {
|
||||||
bufsize := self.size*self.count - self.size*self.cur - len(self.segment)
|
bufsize := h.size*h.count - h.size*h.cur - len(h.segment)
|
||||||
buf := make([]byte, bufsize)
|
buf := make([]byte, bufsize)
|
||||||
var read int
|
var read int
|
||||||
for {
|
for {
|
||||||
|
|
@ -385,7 +385,7 @@ func (self *Hasher) ReadFrom(r io.Reader) (m int64, err error) {
|
||||||
n, err = r.Read(buf)
|
n, err = r.Read(buf)
|
||||||
read += n
|
read += n
|
||||||
if err == io.EOF || read == len(buf) {
|
if err == io.EOF || read == len(buf) {
|
||||||
hash := self.Sum(buf[:n])
|
hash := h.Sum(buf[:n])
|
||||||
if read == len(buf) {
|
if read == len(buf) {
|
||||||
err = NewEOC(hash)
|
err = NewEOC(hash)
|
||||||
}
|
}
|
||||||
|
|
@ -394,7 +394,7 @@ func (self *Hasher) ReadFrom(r io.Reader) (m int64, err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
n, err = self.Write(buf[:n])
|
n, err = h.Write(buf[:n])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
@ -403,9 +403,9 @@ func (self *Hasher) ReadFrom(r io.Reader) (m int64, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset needs to be called before writing to the hasher
|
// Reset needs to be called before writing to the hasher
|
||||||
func (self *Hasher) Reset() {
|
func (h *Hasher) Reset() {
|
||||||
self.getTree()
|
h.getTree()
|
||||||
self.blockLength = nil
|
h.blockLength = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hasher implements the SwarmHash interface
|
// Hasher implements the SwarmHash interface
|
||||||
|
|
@ -413,52 +413,52 @@ func (self *Hasher) Reset() {
|
||||||
// ResetWithLength needs to be called before writing to the hasher
|
// ResetWithLength needs to be called before writing to the hasher
|
||||||
// the argument is supposed to be the byte slice binary representation of
|
// the argument is supposed to be the byte slice binary representation of
|
||||||
// the length of the data subsumed under the hash
|
// the length of the data subsumed under the hash
|
||||||
func (self *Hasher) ResetWithLength(l []byte) {
|
func (h *Hasher) ResetWithLength(l []byte) {
|
||||||
self.Reset()
|
h.Reset()
|
||||||
self.blockLength = l
|
h.blockLength = l
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release gives back the Tree to the pool whereby it unlocks
|
// Release gives back the Tree to the pool whereby it unlocks
|
||||||
// it resets tree, segment and index
|
// it resets tree, segment and index
|
||||||
func (self *Hasher) releaseTree() {
|
func (h *Hasher) releaseTree() {
|
||||||
if self.bmt != nil {
|
if h.bmt != nil {
|
||||||
n := self.bmt.leaves[self.cur]
|
n := h.bmt.leaves[h.cur]
|
||||||
for ; n != nil; n = n.parent {
|
for ; n != nil; n = n.parent {
|
||||||
n.unbalanced = false
|
n.unbalanced = false
|
||||||
if n.parent != nil {
|
if n.parent != nil {
|
||||||
n.root = false
|
n.root = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.pool.Release(self.bmt)
|
h.pool.Release(h.bmt)
|
||||||
self.bmt = nil
|
h.bmt = nil
|
||||||
|
|
||||||
}
|
}
|
||||||
self.cur = 0
|
h.cur = 0
|
||||||
self.segment = nil
|
h.segment = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Hasher) writeSegment(i int, s []byte, d int) {
|
func (h *Hasher) writeSegment(i int, s []byte, d int) {
|
||||||
h := self.pool.hasher()
|
hash := h.pool.hasher()
|
||||||
n := self.bmt.leaves[i]
|
n := h.bmt.leaves[i]
|
||||||
|
|
||||||
if len(s) > self.size && n.parent != nil {
|
if len(s) > h.size && n.parent != nil {
|
||||||
go func() {
|
go func() {
|
||||||
h.Reset()
|
hash.Reset()
|
||||||
h.Write(s)
|
hash.Write(s)
|
||||||
s = h.Sum(nil)
|
s = hash.Sum(nil)
|
||||||
|
|
||||||
if n.root {
|
if n.root {
|
||||||
self.result <- s
|
h.result <- s
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.run(n.parent, h, d, n.index, s)
|
h.run(n.parent, hash, d, n.index, s)
|
||||||
}()
|
}()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
go self.run(n, h, d, i*2, s)
|
go h.run(n, hash, d, i*2, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Hasher) run(n *Node, h hash.Hash, d int, i int, s []byte) {
|
func (h *Hasher) run(n *Node, hash hash.Hash, d int, i int, s []byte) {
|
||||||
isLeft := i%2 == 0
|
isLeft := i%2 == 0
|
||||||
for {
|
for {
|
||||||
if isLeft {
|
if isLeft {
|
||||||
|
|
@ -470,18 +470,18 @@ func (self *Hasher) run(n *Node, h hash.Hash, d int, i int, s []byte) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !n.unbalanced || !isLeft || i == 0 && d == 0 {
|
if !n.unbalanced || !isLeft || i == 0 && d == 0 {
|
||||||
h.Reset()
|
hash.Reset()
|
||||||
h.Write(n.left)
|
hash.Write(n.left)
|
||||||
h.Write(n.right)
|
hash.Write(n.right)
|
||||||
s = h.Sum(nil)
|
s = hash.Sum(nil)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
s = append(n.left, n.right...)
|
s = append(n.left, n.right...)
|
||||||
}
|
}
|
||||||
|
|
||||||
self.hash = s
|
h.hash = s
|
||||||
if n.root {
|
if n.root {
|
||||||
self.result <- s
|
h.result <- s
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -492,20 +492,20 @@ func (self *Hasher) run(n *Node, h hash.Hash, d int, i int, s []byte) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// getTree obtains a BMT resource by reserving one from the pool
|
// getTree obtains a BMT resource by reserving one from the pool
|
||||||
func (self *Hasher) getTree() *Tree {
|
func (h *Hasher) getTree() *Tree {
|
||||||
if self.bmt != nil {
|
if h.bmt != nil {
|
||||||
return self.bmt
|
return h.bmt
|
||||||
}
|
}
|
||||||
t := self.pool.Reserve()
|
t := h.pool.Reserve()
|
||||||
self.bmt = t
|
h.bmt = t
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
// atomic bool toggle implementing a concurrent reusable 2-state object
|
// atomic bool toggle implementing a concurrent reusable 2-state object
|
||||||
// atomic addint with %2 implements atomic bool toggle
|
// atomic addint with %2 implements atomic bool toggle
|
||||||
// it returns true if the toggler just put it in the active/waiting state
|
// it returns true if the toggler just put it in the active/waiting state
|
||||||
func (self *Node) toggle() bool {
|
func (n *Node) toggle() bool {
|
||||||
return atomic.AddInt32(&self.state, 1)%2 == 1
|
return atomic.AddInt32(&n.state, 1)%2 == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func hashstr(b []byte) string {
|
func hashstr(b []byte) string {
|
||||||
|
|
@ -525,7 +525,7 @@ func depth(n int) (d int) {
|
||||||
|
|
||||||
// finalise is following the zigzags on the tree belonging
|
// finalise is following the zigzags on the tree belonging
|
||||||
// to the final datasegment
|
// to the final datasegment
|
||||||
func (self *Hasher) finalise(n *Node, i int) (d int) {
|
func (h *Hasher) finalise(n *Node, i int) (d int) {
|
||||||
isLeft := i%2 == 0
|
isLeft := i%2 == 0
|
||||||
for {
|
for {
|
||||||
// when the final segment's path is going via left segments
|
// when the final segment's path is going via left segments
|
||||||
|
|
@ -550,8 +550,8 @@ type EOC struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error returns the error string
|
// Error returns the error string
|
||||||
func (self *EOC) Error() string {
|
func (e *EOC) Error() string {
|
||||||
return fmt.Sprintf("hasher limit reached, chunk hash: %x", self.Hash)
|
return fmt.Sprintf("hasher limit reached, chunk hash: %x", e.Hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewEOC creates new end of chunk error with the hash
|
// NewEOC creates new end of chunk error with the hash
|
||||||
|
|
|
||||||
|
|
@ -755,7 +755,7 @@ func doAndroidArchive(cmdline []string) {
|
||||||
os.Rename(archive, meta.Package+".aar")
|
os.Rename(archive, meta.Package+".aar")
|
||||||
if *signer != "" && *deploy != "" {
|
if *signer != "" && *deploy != "" {
|
||||||
// Import the signing key into the local GPG instance
|
// Import the signing key into the local GPG instance
|
||||||
if b64key := os.Getenv(*signer); b64key != "" {
|
b64key := os.Getenv(*signer)
|
||||||
key, err := base64.StdEncoding.DecodeString(b64key)
|
key, err := base64.StdEncoding.DecodeString(b64key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("invalid base64 %s", *signer)
|
log.Fatalf("invalid base64 %s", *signer)
|
||||||
|
|
@ -763,6 +763,10 @@ func doAndroidArchive(cmdline []string) {
|
||||||
gpg := exec.Command("gpg", "--import")
|
gpg := exec.Command("gpg", "--import")
|
||||||
gpg.Stdin = bytes.NewReader(key)
|
gpg.Stdin = bytes.NewReader(key)
|
||||||
build.MustRun(gpg)
|
build.MustRun(gpg)
|
||||||
|
|
||||||
|
keyID, err := build.PGPKeyID(string(key))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
// Upload the artifacts to Sonatype and/or Maven Central
|
// Upload the artifacts to Sonatype and/or Maven Central
|
||||||
repo := *deploy + "/service/local/staging/deploy/maven2"
|
repo := *deploy + "/service/local/staging/deploy/maven2"
|
||||||
|
|
@ -771,6 +775,7 @@ func doAndroidArchive(cmdline []string) {
|
||||||
}
|
}
|
||||||
build.MustRunCommand("mvn", "gpg:sign-and-deploy-file", "-e", "-X",
|
build.MustRunCommand("mvn", "gpg:sign-and-deploy-file", "-e", "-X",
|
||||||
"-settings=build/mvn.settings", "-Durl="+repo, "-DrepositoryId=ossrh",
|
"-settings=build/mvn.settings", "-Durl="+repo, "-DrepositoryId=ossrh",
|
||||||
|
"-Dgpg.keyname="+keyID,
|
||||||
"-DpomFile="+meta.Package+".pom", "-Dfile="+meta.Package+".aar")
|
"-DpomFile="+meta.Package+".pom", "-Dfile="+meta.Package+".aar")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,11 +47,11 @@ import (
|
||||||
"gopkg.in/urfave/cli.v1"
|
"gopkg.in/urfave/cli.v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ExternalApiVersion -- see extapi_changelog.md
|
// ExternalAPIVersion -- see extapi_changelog.md
|
||||||
const ExternalApiVersion = "2.0.0"
|
const ExternalAPIVersion = "2.0.0"
|
||||||
|
|
||||||
// InternalApiVersion -- see intapi_changelog.md
|
// InternalAPIVersion -- see intapi_changelog.md
|
||||||
const InternalApiVersion = "2.0.0"
|
const InternalAPIVersion = "2.0.0"
|
||||||
|
|
||||||
const legalWarning = `
|
const legalWarning = `
|
||||||
WARNING!
|
WARNING!
|
||||||
|
|
@ -398,10 +398,10 @@ func signer(c *cli.Context) error {
|
||||||
}
|
}
|
||||||
// register signer API with server
|
// register signer API with server
|
||||||
var (
|
var (
|
||||||
extapiUrl = "n/a"
|
extapiURL = "n/a"
|
||||||
ipcApiUrl = "n/a"
|
ipcapiURL = "n/a"
|
||||||
)
|
)
|
||||||
rpcApi := []rpc.API{
|
rpcAPI := []rpc.API{
|
||||||
{
|
{
|
||||||
Namespace: "account",
|
Namespace: "account",
|
||||||
Public: true,
|
Public: true,
|
||||||
|
|
@ -415,12 +415,12 @@ func signer(c *cli.Context) error {
|
||||||
|
|
||||||
// start http server
|
// start http server
|
||||||
httpEndpoint := fmt.Sprintf("%s:%d", c.String(utils.RPCListenAddrFlag.Name), c.Int(rpcPortFlag.Name))
|
httpEndpoint := fmt.Sprintf("%s:%d", c.String(utils.RPCListenAddrFlag.Name), c.Int(rpcPortFlag.Name))
|
||||||
listener, _, err := rpc.StartHTTPEndpoint(httpEndpoint, rpcApi, []string{"account"}, cors, vhosts)
|
listener, _, err := rpc.StartHTTPEndpoint(httpEndpoint, rpcAPI, []string{"account"}, cors, vhosts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Fatalf("Could not start RPC api: %v", err)
|
utils.Fatalf("Could not start RPC api: %v", err)
|
||||||
}
|
}
|
||||||
extapiUrl = fmt.Sprintf("http://%s", httpEndpoint)
|
extapiURL = fmt.Sprintf("http://%s", httpEndpoint)
|
||||||
log.Info("HTTP endpoint opened", "url", extapiUrl)
|
log.Info("HTTP endpoint opened", "url", extapiURL)
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
listener.Close()
|
listener.Close()
|
||||||
|
|
@ -430,19 +430,19 @@ func signer(c *cli.Context) error {
|
||||||
}
|
}
|
||||||
if !c.Bool(utils.IPCDisabledFlag.Name) {
|
if !c.Bool(utils.IPCDisabledFlag.Name) {
|
||||||
if c.IsSet(utils.IPCPathFlag.Name) {
|
if c.IsSet(utils.IPCPathFlag.Name) {
|
||||||
ipcApiUrl = c.String(utils.IPCPathFlag.Name)
|
ipcapiURL = c.String(utils.IPCPathFlag.Name)
|
||||||
} else {
|
} else {
|
||||||
ipcApiUrl = filepath.Join(configDir, "clef.ipc")
|
ipcapiURL = filepath.Join(configDir, "clef.ipc")
|
||||||
}
|
}
|
||||||
|
|
||||||
listener, _, err := rpc.StartIPCEndpoint(ipcApiUrl, rpcApi)
|
listener, _, err := rpc.StartIPCEndpoint(ipcapiURL, rpcAPI)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Fatalf("Could not start IPC api: %v", err)
|
utils.Fatalf("Could not start IPC api: %v", err)
|
||||||
}
|
}
|
||||||
log.Info("IPC endpoint opened", "url", ipcApiUrl)
|
log.Info("IPC endpoint opened", "url", ipcapiURL)
|
||||||
defer func() {
|
defer func() {
|
||||||
listener.Close()
|
listener.Close()
|
||||||
log.Info("IPC endpoint closed", "url", ipcApiUrl)
|
log.Info("IPC endpoint closed", "url", ipcapiURL)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -453,10 +453,10 @@ func signer(c *cli.Context) error {
|
||||||
}
|
}
|
||||||
ui.OnSignerStartup(core.StartupInfo{
|
ui.OnSignerStartup(core.StartupInfo{
|
||||||
Info: map[string]interface{}{
|
Info: map[string]interface{}{
|
||||||
"extapi_version": ExternalApiVersion,
|
"extapi_version": ExternalAPIVersion,
|
||||||
"intapi_version": InternalApiVersion,
|
"intapi_version": InternalAPIVersion,
|
||||||
"extapi_http": extapiUrl,
|
"extapi_http": extapiURL,
|
||||||
"extapi_ipc": ipcApiUrl,
|
"extapi_ipc": ipcapiURL,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,8 @@ type JSONLogger struct {
|
||||||
cfg *vm.LogConfig
|
cfg *vm.LogConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewJSONLogger creates a new EVM tracer that prints execution steps as JSON objects
|
||||||
|
// into the provided stream.
|
||||||
func NewJSONLogger(cfg *vm.LogConfig, writer io.Writer) *JSONLogger {
|
func NewJSONLogger(cfg *vm.LogConfig, writer io.Writer) *JSONLogger {
|
||||||
return &JSONLogger{json.NewEncoder(writer), cfg}
|
return &JSONLogger{json.NewEncoder(writer), cfg}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -98,14 +98,13 @@ func runCmd(ctx *cli.Context) error {
|
||||||
}
|
}
|
||||||
if ctx.GlobalString(GenesisFlag.Name) != "" {
|
if ctx.GlobalString(GenesisFlag.Name) != "" {
|
||||||
gen := readGenesis(ctx.GlobalString(GenesisFlag.Name))
|
gen := readGenesis(ctx.GlobalString(GenesisFlag.Name))
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db := ethdb.NewMemDatabase()
|
||||||
genesis := gen.ToBlock(db)
|
genesis := gen.ToBlock(db)
|
||||||
statedb, _ = state.New(genesis.Root(), state.NewDatabase(db))
|
statedb, _ = state.New(genesis.Root(), state.NewDatabase(db))
|
||||||
chainConfig = gen.Config
|
chainConfig = gen.Config
|
||||||
blockNumber = gen.Number
|
blockNumber = gen.Number
|
||||||
} else {
|
} else {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
statedb, _ = state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
|
||||||
statedb, _ = state.New(common.Hash{}, state.NewDatabase(db))
|
|
||||||
}
|
}
|
||||||
if ctx.GlobalString(SenderFlag.Name) != "" {
|
if ctx.GlobalString(SenderFlag.Name) != "" {
|
||||||
sender = common.HexToAddress(ctx.GlobalString(SenderFlag.Name))
|
sender = common.HexToAddress(ctx.GlobalString(SenderFlag.Name))
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,8 @@ var stateTestCommand = cli.Command{
|
||||||
ArgsUsage: "<file>",
|
ArgsUsage: "<file>",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StatetestResult contains the execution status after running a state test, any
|
||||||
|
// error that might have occurred and a dump of the final state if requested.
|
||||||
type StatetestResult struct {
|
type StatetestResult struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Pass bool `json:"pass"`
|
Pass bool `json:"pass"`
|
||||||
|
|
|
||||||
|
|
@ -340,7 +340,7 @@ func importWallet(ctx *cli.Context) error {
|
||||||
if len(keyfile) == 0 {
|
if len(keyfile) == 0 {
|
||||||
utils.Fatalf("keyfile must be given as argument")
|
utils.Fatalf("keyfile must be given as argument")
|
||||||
}
|
}
|
||||||
keyJson, err := ioutil.ReadFile(keyfile)
|
keyJSON, err := ioutil.ReadFile(keyfile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Fatalf("Could not read wallet file: %v", err)
|
utils.Fatalf("Could not read wallet file: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -349,7 +349,7 @@ func importWallet(ctx *cli.Context) error {
|
||||||
passphrase := getPassPhrase("", false, 0, utils.MakePasswordList(ctx))
|
passphrase := getPassPhrase("", false, 0, utils.MakePasswordList(ctx))
|
||||||
|
|
||||||
ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore)
|
ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore)
|
||||||
acct, err := ks.ImportPreSaleKey(keyJson, passphrase)
|
acct, err := ks.ImportPreSaleKey(keyJSON, passphrase)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Fatalf("%v", err)
|
utils.Fatalf("%v", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ var bugCommand = cli.Command{
|
||||||
Category: "MISCELLANEOUS COMMANDS",
|
Category: "MISCELLANEOUS COMMANDS",
|
||||||
}
|
}
|
||||||
|
|
||||||
const issueUrl = "https://github.com/ethereum/go-ethereum/issues/new"
|
const issueURL = "https://github.com/ethereum/go-ethereum/issues/new"
|
||||||
|
|
||||||
// reportBug reports a bug by opening a new URL to the go-ethereum GH issue
|
// reportBug reports a bug by opening a new URL to the go-ethereum GH issue
|
||||||
// tracker and setting default values as the issue body.
|
// tracker and setting default values as the issue body.
|
||||||
|
|
@ -58,8 +58,8 @@ func reportBug(ctx *cli.Context) error {
|
||||||
fmt.Fprintln(&buff, header)
|
fmt.Fprintln(&buff, header)
|
||||||
|
|
||||||
// open a new GH issue
|
// open a new GH issue
|
||||||
if !browser.Open(issueUrl + "?body=" + url.QueryEscape(buff.String())) {
|
if !browser.Open(issueURL + "?body=" + url.QueryEscape(buff.String())) {
|
||||||
fmt.Printf("Please file a new issue at %s using this template:\n\n%s", issueUrl, buff.String())
|
fmt.Printf("Please file a new issue at %s using this template:\n\n%s", issueURL, buff.String())
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -352,7 +352,7 @@ func TestVoting(t *testing.T) {
|
||||||
copy(genesis.ExtraData[extraVanity+j*common.AddressLength:], signer[:])
|
copy(genesis.ExtraData[extraVanity+j*common.AddressLength:], signer[:])
|
||||||
}
|
}
|
||||||
// Create a pristine blockchain with the genesis injected
|
// Create a pristine blockchain with the genesis injected
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db := ethdb.NewMemDatabase()
|
||||||
genesis.Commit(db)
|
genesis.Commit(db)
|
||||||
|
|
||||||
// Assemble a chain of headers from the cast votes
|
// Assemble a chain of headers from the cast votes
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,7 @@ 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 ethdb.Database
|
||||||
if !disk {
|
if !disk {
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db = ethdb.NewMemDatabase()
|
||||||
} else {
|
} else {
|
||||||
dir, err := ioutil.TempDir("", "eth-core-bench")
|
dir, err := ioutil.TempDir("", "eth-core-bench")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ import (
|
||||||
func TestHeaderVerification(t *testing.T) {
|
func TestHeaderVerification(t *testing.T) {
|
||||||
// Create a simple chain to verify
|
// Create a simple chain to verify
|
||||||
var (
|
var (
|
||||||
testdb, _ = ethdb.NewMemDatabase()
|
testdb = ethdb.NewMemDatabase()
|
||||||
gspec = &Genesis{Config: params.TestChainConfig}
|
gspec = &Genesis{Config: params.TestChainConfig}
|
||||||
genesis = gspec.MustCommit(testdb)
|
genesis = gspec.MustCommit(testdb)
|
||||||
blocks, _ = GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), testdb, 8, nil)
|
blocks, _ = GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), testdb, 8, nil)
|
||||||
|
|
@ -84,7 +84,7 @@ func TestHeaderConcurrentVerification32(t *testing.T) { testHeaderConcurrentVeri
|
||||||
func testHeaderConcurrentVerification(t *testing.T, threads int) {
|
func testHeaderConcurrentVerification(t *testing.T, threads int) {
|
||||||
// Create a simple chain to verify
|
// Create a simple chain to verify
|
||||||
var (
|
var (
|
||||||
testdb, _ = ethdb.NewMemDatabase()
|
testdb = ethdb.NewMemDatabase()
|
||||||
gspec = &Genesis{Config: params.TestChainConfig}
|
gspec = &Genesis{Config: params.TestChainConfig}
|
||||||
genesis = gspec.MustCommit(testdb)
|
genesis = gspec.MustCommit(testdb)
|
||||||
blocks, _ = GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), testdb, 8, nil)
|
blocks, _ = GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), testdb, 8, nil)
|
||||||
|
|
@ -156,7 +156,7 @@ func TestHeaderConcurrentAbortion32(t *testing.T) { testHeaderConcurrentAbortion
|
||||||
func testHeaderConcurrentAbortion(t *testing.T, threads int) {
|
func testHeaderConcurrentAbortion(t *testing.T, threads int) {
|
||||||
// Create a simple chain to verify
|
// Create a simple chain to verify
|
||||||
var (
|
var (
|
||||||
testdb, _ = ethdb.NewMemDatabase()
|
testdb = ethdb.NewMemDatabase()
|
||||||
gspec = &Genesis{Config: params.TestChainConfig}
|
gspec = &Genesis{Config: params.TestChainConfig}
|
||||||
genesis = gspec.MustCommit(testdb)
|
genesis = gspec.MustCommit(testdb)
|
||||||
blocks, _ = GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), testdb, 1024, nil)
|
blocks, _ = GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), testdb, 1024, nil)
|
||||||
|
|
|
||||||
|
|
@ -569,7 +569,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 = ethdb.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)
|
||||||
|
|
@ -599,7 +599,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 := ethdb.NewMemDatabase()
|
||||||
gspec.MustCommit(archiveDb)
|
gspec.MustCommit(archiveDb)
|
||||||
archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
|
archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
|
||||||
defer archive.Stop()
|
defer archive.Stop()
|
||||||
|
|
@ -608,7 +608,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 := ethdb.NewMemDatabase()
|
||||||
gspec.MustCommit(fastDb)
|
gspec.MustCommit(fastDb)
|
||||||
fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
|
fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
|
||||||
defer fast.Stop()
|
defer fast.Stop()
|
||||||
|
|
@ -657,7 +657,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 = ethdb.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)
|
||||||
|
|
@ -685,7 +685,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 := ethdb.NewMemDatabase()
|
||||||
gspec.MustCommit(archiveDb)
|
gspec.MustCommit(archiveDb)
|
||||||
|
|
||||||
archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
|
archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
|
||||||
|
|
@ -699,7 +699,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 := ethdb.NewMemDatabase()
|
||||||
gspec.MustCommit(fastDb)
|
gspec.MustCommit(fastDb)
|
||||||
fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
|
fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
|
||||||
defer fast.Stop()
|
defer fast.Stop()
|
||||||
|
|
@ -719,7 +719,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 := ethdb.NewMemDatabase()
|
||||||
gspec.MustCommit(lightDb)
|
gspec.MustCommit(lightDb)
|
||||||
|
|
||||||
light, _ := NewBlockChain(lightDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
|
light, _ := NewBlockChain(lightDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
|
||||||
|
|
@ -742,7 +742,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 = ethdb.NewMemDatabase()
|
||||||
gspec = &Genesis{
|
gspec = &Genesis{
|
||||||
Config: params.TestChainConfig,
|
Config: params.TestChainConfig,
|
||||||
GasLimit: 3141592,
|
GasLimit: 3141592,
|
||||||
|
|
@ -854,7 +854,7 @@ func TestLogReorgs(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||||
addr1 = crypto.PubkeyToAddress(key1.PublicKey)
|
addr1 = crypto.PubkeyToAddress(key1.PublicKey)
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db = ethdb.NewMemDatabase()
|
||||||
// this code generates a log
|
// this code generates a log
|
||||||
code = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
|
code = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
|
||||||
gspec = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}}
|
gspec = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}}
|
||||||
|
|
@ -898,7 +898,7 @@ func TestLogReorgs(t *testing.T) {
|
||||||
|
|
||||||
func TestReorgSideEvent(t *testing.T) {
|
func TestReorgSideEvent(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db = ethdb.NewMemDatabase()
|
||||||
key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||||
addr1 = crypto.PubkeyToAddress(key1.PublicKey)
|
addr1 = crypto.PubkeyToAddress(key1.PublicKey)
|
||||||
gspec = &Genesis{
|
gspec = &Genesis{
|
||||||
|
|
@ -1026,7 +1026,7 @@ func TestCanonicalBlockRetrieval(t *testing.T) {
|
||||||
func TestEIP155Transition(t *testing.T) {
|
func TestEIP155Transition(t *testing.T) {
|
||||||
// Configure and generate a sample block chain
|
// Configure and generate a sample block chain
|
||||||
var (
|
var (
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db = ethdb.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)
|
||||||
|
|
@ -1130,7 +1130,7 @@ func TestEIP155Transition(t *testing.T) {
|
||||||
func TestEIP161AccountRemoval(t *testing.T) {
|
func TestEIP161AccountRemoval(t *testing.T) {
|
||||||
// Configure and generate a sample block chain
|
// Configure and generate a sample block chain
|
||||||
var (
|
var (
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db = ethdb.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)
|
||||||
|
|
@ -1202,7 +1202,7 @@ func TestBlockchainHeaderchainReorgConsistency(t *testing.T) {
|
||||||
// Generate a canonical chain to act as the main dataset
|
// Generate a canonical chain to act as the main dataset
|
||||||
engine := ethash.NewFaker()
|
engine := ethash.NewFaker()
|
||||||
|
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db := ethdb.NewMemDatabase()
|
||||||
genesis := new(Genesis).MustCommit(db)
|
genesis := new(Genesis).MustCommit(db)
|
||||||
blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
|
blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
|
||||||
|
|
||||||
|
|
@ -1218,7 +1218,7 @@ func TestBlockchainHeaderchainReorgConsistency(t *testing.T) {
|
||||||
}
|
}
|
||||||
// Import the canonical and fork chain side by side, verifying the current block
|
// Import the canonical and fork chain side by side, verifying the current block
|
||||||
// and current header consistency
|
// and current header consistency
|
||||||
diskdb, _ := ethdb.NewMemDatabase()
|
diskdb := ethdb.NewMemDatabase()
|
||||||
new(Genesis).MustCommit(diskdb)
|
new(Genesis).MustCommit(diskdb)
|
||||||
|
|
||||||
chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{})
|
chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{})
|
||||||
|
|
@ -1247,7 +1247,7 @@ func TestTrieForkGC(t *testing.T) {
|
||||||
// Generate a canonical chain to act as the main dataset
|
// Generate a canonical chain to act as the main dataset
|
||||||
engine := ethash.NewFaker()
|
engine := ethash.NewFaker()
|
||||||
|
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db := ethdb.NewMemDatabase()
|
||||||
genesis := new(Genesis).MustCommit(db)
|
genesis := new(Genesis).MustCommit(db)
|
||||||
blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*triesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
|
blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*triesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
|
||||||
|
|
||||||
|
|
@ -1262,7 +1262,7 @@ func TestTrieForkGC(t *testing.T) {
|
||||||
forks[i] = fork[0]
|
forks[i] = fork[0]
|
||||||
}
|
}
|
||||||
// Import the canonical and fork chain side by side, forcing the trie cache to cache both
|
// Import the canonical and fork chain side by side, forcing the trie cache to cache both
|
||||||
diskdb, _ := ethdb.NewMemDatabase()
|
diskdb := ethdb.NewMemDatabase()
|
||||||
new(Genesis).MustCommit(diskdb)
|
new(Genesis).MustCommit(diskdb)
|
||||||
|
|
||||||
chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{})
|
chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{})
|
||||||
|
|
@ -1293,7 +1293,7 @@ func TestLargeReorgTrieGC(t *testing.T) {
|
||||||
// Generate the original common chain segment and the two competing forks
|
// Generate the original common chain segment and the two competing forks
|
||||||
engine := ethash.NewFaker()
|
engine := ethash.NewFaker()
|
||||||
|
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db := ethdb.NewMemDatabase()
|
||||||
genesis := new(Genesis).MustCommit(db)
|
genesis := new(Genesis).MustCommit(db)
|
||||||
|
|
||||||
shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
|
shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
|
||||||
|
|
@ -1301,7 +1301,7 @@ func TestLargeReorgTrieGC(t *testing.T) {
|
||||||
competitor, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*triesInMemory+1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{3}) })
|
competitor, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*triesInMemory+1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{3}) })
|
||||||
|
|
||||||
// Import the shared chain and the original canonical one
|
// Import the shared chain and the original canonical one
|
||||||
diskdb, _ := ethdb.NewMemDatabase()
|
diskdb := ethdb.NewMemDatabase()
|
||||||
new(Genesis).MustCommit(diskdb)
|
new(Genesis).MustCommit(diskdb)
|
||||||
|
|
||||||
chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{})
|
chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{})
|
||||||
|
|
@ -1361,7 +1361,7 @@ func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks in
|
||||||
)
|
)
|
||||||
// Generate the original common chain segment and the two competing forks
|
// Generate the original common chain segment and the two competing forks
|
||||||
engine := ethash.NewFaker()
|
engine := ethash.NewFaker()
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db := ethdb.NewMemDatabase()
|
||||||
genesis := gspec.MustCommit(db)
|
genesis := gspec.MustCommit(db)
|
||||||
|
|
||||||
blockGenerator := func(i int, block *BlockGen) {
|
blockGenerator := func(i int, block *BlockGen) {
|
||||||
|
|
@ -1383,7 +1383,7 @@ func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks in
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
// Import the shared chain and the original canonical one
|
// Import the shared chain and the original canonical one
|
||||||
diskdb, _ := ethdb.NewMemDatabase()
|
diskdb := ethdb.NewMemDatabase()
|
||||||
gspec.MustCommit(diskdb)
|
gspec.MustCommit(diskdb)
|
||||||
|
|
||||||
chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{})
|
chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{})
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ func TestChainIndexerWithChildren(t *testing.T) {
|
||||||
// multiple backends. The section size and required confirmation count parameters
|
// multiple backends. The section size and required confirmation count parameters
|
||||||
// are randomized.
|
// are randomized.
|
||||||
func testChainIndexer(t *testing.T, count int) {
|
func testChainIndexer(t *testing.T, count int) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db := ethdb.NewMemDatabase()
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
// Create a chain of indexers and ensure they all report empty
|
// Create a chain of indexers and ensure they all report empty
|
||||||
|
|
|
||||||
|
|
@ -256,11 +256,12 @@ func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.S
|
||||||
// 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(engine consensus.Engine, n int, full bool) (ethdb.Database, *BlockChain, error) {
|
func newCanonical(engine consensus.Engine, n int, full bool) (ethdb.Database, *BlockChain, error) {
|
||||||
// Initialize a fresh chain with only a genesis block
|
var (
|
||||||
gspec := new(Genesis)
|
db = ethdb.NewMemDatabase()
|
||||||
db, _ := ethdb.NewMemDatabase()
|
genesis = new(Genesis).MustCommit(db)
|
||||||
genesis := gspec.MustCommit(db)
|
)
|
||||||
|
|
||||||
|
// Initialize a fresh chain with only a genesis block
|
||||||
blockchain, _ := NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{})
|
blockchain, _ := NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{})
|
||||||
// Create and inject the requested chain
|
// Create and inject the requested chain
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,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 = ethdb.NewMemDatabase()
|
||||||
)
|
)
|
||||||
|
|
||||||
// Ensure that key1 has some funds in the genesis block.
|
// Ensure that key1 has some funds in the genesis block.
|
||||||
|
|
|
||||||
|
|
@ -32,13 +32,13 @@ func TestDAOForkRangeExtradata(t *testing.T) {
|
||||||
forkBlock := big.NewInt(32)
|
forkBlock := big.NewInt(32)
|
||||||
|
|
||||||
// Generate a common prefix for both pro-forkers and non-forkers
|
// Generate a common prefix for both pro-forkers and non-forkers
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db := ethdb.NewMemDatabase()
|
||||||
gspec := new(Genesis)
|
gspec := new(Genesis)
|
||||||
genesis := gspec.MustCommit(db)
|
genesis := gspec.MustCommit(db)
|
||||||
prefix, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, int(forkBlock.Int64()-1), func(i int, gen *BlockGen) {})
|
prefix, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, int(forkBlock.Int64()-1), func(i int, gen *BlockGen) {})
|
||||||
|
|
||||||
// Create the concurrent, conflicting two nodes
|
// Create the concurrent, conflicting two nodes
|
||||||
proDb, _ := ethdb.NewMemDatabase()
|
proDb := ethdb.NewMemDatabase()
|
||||||
gspec.MustCommit(proDb)
|
gspec.MustCommit(proDb)
|
||||||
|
|
||||||
proConf := *params.TestChainConfig
|
proConf := *params.TestChainConfig
|
||||||
|
|
@ -48,7 +48,7 @@ func TestDAOForkRangeExtradata(t *testing.T) {
|
||||||
proBc, _ := NewBlockChain(proDb, nil, &proConf, ethash.NewFaker(), vm.Config{})
|
proBc, _ := NewBlockChain(proDb, nil, &proConf, ethash.NewFaker(), vm.Config{})
|
||||||
defer proBc.Stop()
|
defer proBc.Stop()
|
||||||
|
|
||||||
conDb, _ := ethdb.NewMemDatabase()
|
conDb := ethdb.NewMemDatabase()
|
||||||
gspec.MustCommit(conDb)
|
gspec.MustCommit(conDb)
|
||||||
|
|
||||||
conConf := *params.TestChainConfig
|
conConf := *params.TestChainConfig
|
||||||
|
|
@ -67,7 +67,7 @@ func TestDAOForkRangeExtradata(t *testing.T) {
|
||||||
// Try to expand both pro-fork and non-fork chains iteratively with other camp's blocks
|
// Try to expand both pro-fork and non-fork chains iteratively with other camp's blocks
|
||||||
for i := int64(0); i < params.DAOForkExtraRange.Int64(); i++ {
|
for i := int64(0); i < params.DAOForkExtraRange.Int64(); i++ {
|
||||||
// Create a pro-fork block, and try to feed into the no-fork chain
|
// Create a pro-fork block, and try to feed into the no-fork chain
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db = ethdb.NewMemDatabase()
|
||||||
gspec.MustCommit(db)
|
gspec.MustCommit(db)
|
||||||
bc, _ := NewBlockChain(db, nil, &conConf, ethash.NewFaker(), vm.Config{})
|
bc, _ := NewBlockChain(db, nil, &conConf, ethash.NewFaker(), vm.Config{})
|
||||||
defer bc.Stop()
|
defer bc.Stop()
|
||||||
|
|
@ -92,7 +92,7 @@ func TestDAOForkRangeExtradata(t *testing.T) {
|
||||||
t.Fatalf("contra-fork chain didn't accepted no-fork block: %v", err)
|
t.Fatalf("contra-fork chain didn't accepted no-fork block: %v", err)
|
||||||
}
|
}
|
||||||
// Create a no-fork block, and try to feed into the pro-fork chain
|
// Create a no-fork block, and try to feed into the pro-fork chain
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db = ethdb.NewMemDatabase()
|
||||||
gspec.MustCommit(db)
|
gspec.MustCommit(db)
|
||||||
bc, _ = NewBlockChain(db, nil, &proConf, ethash.NewFaker(), vm.Config{})
|
bc, _ = NewBlockChain(db, nil, &proConf, ethash.NewFaker(), vm.Config{})
|
||||||
defer bc.Stop()
|
defer bc.Stop()
|
||||||
|
|
@ -118,7 +118,7 @@ func TestDAOForkRangeExtradata(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Verify that contra-forkers accept pro-fork extra-datas after forking finishes
|
// Verify that contra-forkers accept pro-fork extra-datas after forking finishes
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db = ethdb.NewMemDatabase()
|
||||||
gspec.MustCommit(db)
|
gspec.MustCommit(db)
|
||||||
bc, _ := NewBlockChain(db, nil, &conConf, ethash.NewFaker(), vm.Config{})
|
bc, _ := NewBlockChain(db, nil, &conConf, ethash.NewFaker(), vm.Config{})
|
||||||
defer bc.Stop()
|
defer bc.Stop()
|
||||||
|
|
@ -138,7 +138,7 @@ func TestDAOForkRangeExtradata(t *testing.T) {
|
||||||
t.Fatalf("contra-fork chain didn't accept pro-fork block post-fork: %v", err)
|
t.Fatalf("contra-fork chain didn't accept pro-fork block post-fork: %v", err)
|
||||||
}
|
}
|
||||||
// Verify that pro-forkers accept contra-fork extra-datas after forking finishes
|
// Verify that pro-forkers accept contra-fork extra-datas after forking finishes
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db = ethdb.NewMemDatabase()
|
||||||
gspec.MustCommit(db)
|
gspec.MustCommit(db)
|
||||||
bc, _ = NewBlockChain(db, nil, &proConf, ethash.NewFaker(), vm.Config{})
|
bc, _ = NewBlockChain(db, nil, &proConf, ethash.NewFaker(), vm.Config{})
|
||||||
defer bc.Stop()
|
defer bc.Stop()
|
||||||
|
|
|
||||||
|
|
@ -222,7 +222,7 @@ func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig {
|
||||||
// to the given database (or discards it if nil).
|
// to the given database (or discards it if nil).
|
||||||
func (g *Genesis) ToBlock(db ethdb.Database) *types.Block {
|
func (g *Genesis) ToBlock(db ethdb.Database) *types.Block {
|
||||||
if db == nil {
|
if db == nil {
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db = ethdb.NewMemDatabase()
|
||||||
}
|
}
|
||||||
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
||||||
for addr, account := range g.Alloc {
|
for addr, account := range g.Alloc {
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,7 @@ func TestSetupGenesis(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db := ethdb.NewMemDatabase()
|
||||||
config, hash, err := test.fn(db)
|
config, hash, err := test.fn(db)
|
||||||
// Check the return values.
|
// Check the return values.
|
||||||
if !reflect.DeepEqual(err, test.wantErr) {
|
if !reflect.DeepEqual(err, test.wantErr) {
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"container/list"
|
"container/list"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
|
|
@ -77,18 +76,11 @@ func (tm *TestManager) Db() ethdb.Database {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTestManager() *TestManager {
|
func NewTestManager() *TestManager {
|
||||||
db, err := ethdb.NewMemDatabase()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Could not create mem-db, failing")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
testManager := &TestManager{}
|
testManager := &TestManager{}
|
||||||
testManager.eventMux = new(event.TypeMux)
|
testManager.eventMux = new(event.TypeMux)
|
||||||
testManager.db = db
|
testManager.db = ethdb.NewMemDatabase()
|
||||||
// testManager.txPool = NewTxPool(testManager)
|
// testManager.txPool = NewTxPool(testManager)
|
||||||
// testManager.blockChain = NewBlockChain(testManager)
|
// testManager.blockChain = NewBlockChain(testManager)
|
||||||
// testManager.stateManager = NewStateManager(testManager)
|
// testManager.stateManager = NewStateManager(testManager)
|
||||||
|
|
||||||
return testManager
|
return testManager
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ import (
|
||||||
|
|
||||||
// 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 := ethdb.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{Number: big.NewInt(42), Extra: []byte("test header")}
|
header := &types.Header{Number: big.NewInt(42), Extra: []byte("test header")}
|
||||||
|
|
@ -63,7 +63,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 := ethdb.NewMemDatabase()
|
||||||
|
|
||||||
// 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
|
||||||
body := &types.Body{Uncles: []*types.Header{{Extra: []byte("test header")}}}
|
body := &types.Body{Uncles: []*types.Header{{Extra: []byte("test header")}}}
|
||||||
|
|
@ -101,7 +101,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 := ethdb.NewMemDatabase()
|
||||||
|
|
||||||
// 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
|
||||||
block := types.NewBlockWithHeader(&types.Header{
|
block := types.NewBlockWithHeader(&types.Header{
|
||||||
|
|
@ -151,7 +151,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 := ethdb.NewMemDatabase()
|
||||||
block := types.NewBlockWithHeader(&types.Header{
|
block := types.NewBlockWithHeader(&types.Header{
|
||||||
Extra: []byte("test block"),
|
Extra: []byte("test block"),
|
||||||
UncleHash: types.EmptyUncleHash,
|
UncleHash: types.EmptyUncleHash,
|
||||||
|
|
@ -185,7 +185,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 := ethdb.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)
|
||||||
|
|
@ -208,7 +208,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 := ethdb.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)
|
||||||
|
|
@ -231,7 +231,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 := ethdb.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")})
|
||||||
|
|
@ -266,7 +266,7 @@ func TestHeadStorage(t *testing.T) {
|
||||||
|
|
||||||
// Tests that receipts associated with a single block can be stored and retrieved.
|
// Tests that receipts associated with a single block can be stored and retrieved.
|
||||||
func TestBlockReceiptStorage(t *testing.T) {
|
func TestBlockReceiptStorage(t *testing.T) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db := ethdb.NewMemDatabase()
|
||||||
|
|
||||||
receipt1 := &types.Receipt{
|
receipt1 := &types.Receipt{
|
||||||
Status: types.ReceiptStatusFailed,
|
Status: types.ReceiptStatusFailed,
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ import (
|
||||||
|
|
||||||
// Tests that positional lookup metadata can be stored and retrieved.
|
// Tests that positional lookup metadata can be stored and retrieved.
|
||||||
func TestLookupStorage(t *testing.T) {
|
func TestLookupStorage(t *testing.T) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db := ethdb.NewMemDatabase()
|
||||||
|
|
||||||
tx1 := types.NewTransaction(1, common.BytesToAddress([]byte{0x11}), big.NewInt(111), 1111, big.NewInt(11111), []byte{0x11, 0x11, 0x11})
|
tx1 := types.NewTransaction(1, common.BytesToAddress([]byte{0x11}), big.NewInt(111), 1111, big.NewInt(11111), []byte{0x11, 0x11, 0x11})
|
||||||
tx2 := types.NewTransaction(2, common.BytesToAddress([]byte{0x22}), big.NewInt(222), 2222, big.NewInt(22222), []byte{0x22, 0x22, 0x22})
|
tx2 := types.NewTransaction(2, common.BytesToAddress([]byte{0x22}), big.NewInt(222), 2222, big.NewInt(22222), []byte{0x22, 0x22, 0x22})
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,7 @@ import (
|
||||||
var addr = common.BytesToAddress([]byte("test"))
|
var addr = common.BytesToAddress([]byte("test"))
|
||||||
|
|
||||||
func create() (*ManagedState, *account) {
|
func create() (*ManagedState, *account) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
statedb, _ := New(common.Hash{}, NewDatabase(ethdb.NewMemDatabase()))
|
||||||
statedb, _ := New(common.Hash{}, NewDatabase(db))
|
|
||||||
ms := ManageState(statedb)
|
ms := ManageState(statedb)
|
||||||
ms.StateDB.SetNonce(addr, 100)
|
ms.StateDB.SetNonce(addr, 100)
|
||||||
ms.accounts[addr] = newAccount(ms.StateDB.getStateObject(addr))
|
ms.accounts[addr] = newAccount(ms.StateDB.getStateObject(addr))
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ func (s *StateSuite) TestDump(c *checker.C) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StateSuite) SetUpTest(c *checker.C) {
|
func (s *StateSuite) SetUpTest(c *checker.C) {
|
||||||
s.db, _ = ethdb.NewMemDatabase()
|
s.db = ethdb.NewMemDatabase()
|
||||||
s.state, _ = New(common.Hash{}, NewDatabase(s.db))
|
s.state, _ = New(common.Hash{}, NewDatabase(s.db))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -133,8 +133,7 @@ func (s *StateSuite) TestSnapshotEmpty(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()
|
state, _ := New(common.Hash{}, NewDatabase(ethdb.NewMemDatabase()))
|
||||||
state, _ := New(common.Hash{}, NewDatabase(db))
|
|
||||||
|
|
||||||
stateobjaddr0 := toAddr([]byte("so0"))
|
stateobjaddr0 := toAddr([]byte("so0"))
|
||||||
stateobjaddr1 := toAddr([]byte("so1"))
|
stateobjaddr1 := toAddr([]byte("so1"))
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ import (
|
||||||
// actually committing the state.
|
// actually committing the state.
|
||||||
func TestUpdateLeaks(t *testing.T) {
|
func TestUpdateLeaks(t *testing.T) {
|
||||||
// Create an empty state database
|
// Create an empty state database
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db := ethdb.NewMemDatabase()
|
||||||
state, _ := New(common.Hash{}, NewDatabase(db))
|
state, _ := New(common.Hash{}, NewDatabase(db))
|
||||||
|
|
||||||
// Update it with some accounts
|
// Update it with some accounts
|
||||||
|
|
@ -66,8 +66,8 @@ func TestUpdateLeaks(t *testing.T) {
|
||||||
// only the one right before the commit.
|
// only the one right before the commit.
|
||||||
func TestIntermediateLeaks(t *testing.T) {
|
func TestIntermediateLeaks(t *testing.T) {
|
||||||
// Create two state databases, one transitioning to the final state, the other final from the beginning
|
// Create two state databases, one transitioning to the final state, the other final from the beginning
|
||||||
transDb, _ := ethdb.NewMemDatabase()
|
transDb := ethdb.NewMemDatabase()
|
||||||
finalDb, _ := ethdb.NewMemDatabase()
|
finalDb := ethdb.NewMemDatabase()
|
||||||
transState, _ := New(common.Hash{}, NewDatabase(transDb))
|
transState, _ := New(common.Hash{}, NewDatabase(transDb))
|
||||||
finalState, _ := New(common.Hash{}, NewDatabase(finalDb))
|
finalState, _ := New(common.Hash{}, NewDatabase(finalDb))
|
||||||
|
|
||||||
|
|
@ -122,8 +122,7 @@ func TestIntermediateLeaks(t *testing.T) {
|
||||||
// https://github.com/ethereum/go-ethereum/pull/15549.
|
// https://github.com/ethereum/go-ethereum/pull/15549.
|
||||||
func TestCopy(t *testing.T) {
|
func TestCopy(t *testing.T) {
|
||||||
// Create a random state test to copy and modify "independently"
|
// Create a random state test to copy and modify "independently"
|
||||||
db, _ := ethdb.NewMemDatabase()
|
orig, _ := New(common.Hash{}, NewDatabase(ethdb.NewMemDatabase()))
|
||||||
orig, _ := New(common.Hash{}, NewDatabase(db))
|
|
||||||
|
|
||||||
for i := byte(0); i < 255; i++ {
|
for i := byte(0); i < 255; i++ {
|
||||||
obj := orig.GetOrNewStateObject(common.BytesToAddress([]byte{i}))
|
obj := orig.GetOrNewStateObject(common.BytesToAddress([]byte{i}))
|
||||||
|
|
@ -334,8 +333,7 @@ func (test *snapshotTest) String() string {
|
||||||
func (test *snapshotTest) run() bool {
|
func (test *snapshotTest) run() bool {
|
||||||
// Run all actions and create snapshots.
|
// Run all actions and create snapshots.
|
||||||
var (
|
var (
|
||||||
db, _ = ethdb.NewMemDatabase()
|
state, _ = New(common.Hash{}, NewDatabase(ethdb.NewMemDatabase()))
|
||||||
state, _ = New(common.Hash{}, NewDatabase(db))
|
|
||||||
snapshotRevs = make([]int, len(test.snapshots))
|
snapshotRevs = make([]int, len(test.snapshots))
|
||||||
sindex = 0
|
sindex = 0
|
||||||
)
|
)
|
||||||
|
|
@ -426,8 +424,7 @@ func (s *StateSuite) TestTouchDelete(c *check.C) {
|
||||||
// TestCopyOfCopy tests that modified objects are carried over to the copy, and the copy of the copy.
|
// TestCopyOfCopy tests that modified objects are carried over to the copy, and the copy of the copy.
|
||||||
// See https://github.com/ethereum/go-ethereum/pull/15225#issuecomment-380191512
|
// See https://github.com/ethereum/go-ethereum/pull/15225#issuecomment-380191512
|
||||||
func TestCopyOfCopy(t *testing.T) {
|
func TestCopyOfCopy(t *testing.T) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
sdb, _ := New(common.Hash{}, NewDatabase(ethdb.NewMemDatabase()))
|
||||||
sdb, _ := New(common.Hash{}, NewDatabase(db))
|
|
||||||
addr := common.HexToAddress("aaaa")
|
addr := common.HexToAddress("aaaa")
|
||||||
sdb.SetBalance(addr, big.NewInt(42))
|
sdb.SetBalance(addr, big.NewInt(42))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,8 +38,7 @@ 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() (Database, common.Hash, []*testAccount) {
|
func makeTestState() (Database, common.Hash, []*testAccount) {
|
||||||
// Create an empty state
|
// Create an empty state
|
||||||
diskdb, _ := ethdb.NewMemDatabase()
|
db := NewDatabase(ethdb.NewMemDatabase())
|
||||||
db := NewDatabase(diskdb)
|
|
||||||
state, _ := New(common.Hash{}, db)
|
state, _ := New(common.Hash{}, db)
|
||||||
|
|
||||||
// Fill it with some arbitrary data
|
// Fill it with some arbitrary data
|
||||||
|
|
@ -125,8 +124,7 @@ func checkStateConsistency(db ethdb.Database, root common.Hash) error {
|
||||||
// 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()
|
if req := NewStateSync(empty, ethdb.NewMemDatabase()).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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -141,7 +139,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 := ethdb.NewMemDatabase()
|
||||||
sched := NewStateSync(srcRoot, dstDb)
|
sched := NewStateSync(srcRoot, dstDb)
|
||||||
|
|
||||||
queue := append([]common.Hash{}, sched.Missing(batch)...)
|
queue := append([]common.Hash{}, sched.Missing(batch)...)
|
||||||
|
|
@ -173,7 +171,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 := ethdb.NewMemDatabase()
|
||||||
sched := NewStateSync(srcRoot, dstDb)
|
sched := NewStateSync(srcRoot, dstDb)
|
||||||
|
|
||||||
queue := append([]common.Hash{}, sched.Missing(0)...)
|
queue := append([]common.Hash{}, sched.Missing(0)...)
|
||||||
|
|
@ -210,7 +208,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 := ethdb.NewMemDatabase()
|
||||||
sched := NewStateSync(srcRoot, dstDb)
|
sched := NewStateSync(srcRoot, dstDb)
|
||||||
|
|
||||||
queue := make(map[common.Hash]struct{})
|
queue := make(map[common.Hash]struct{})
|
||||||
|
|
@ -250,7 +248,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 := ethdb.NewMemDatabase()
|
||||||
sched := NewStateSync(srcRoot, dstDb)
|
sched := NewStateSync(srcRoot, dstDb)
|
||||||
|
|
||||||
queue := make(map[common.Hash]struct{})
|
queue := make(map[common.Hash]struct{})
|
||||||
|
|
@ -297,7 +295,7 @@ func TestIncompleteStateSync(t *testing.T) {
|
||||||
checkTrieConsistency(srcDb.TrieDB().DiskDB().(ethdb.Database), srcRoot)
|
checkTrieConsistency(srcDb.TrieDB().DiskDB().(ethdb.Database), srcRoot)
|
||||||
|
|
||||||
// Create a destination state and sync with the scheduler
|
// Create a destination state and sync with the scheduler
|
||||||
dstDb, _ := ethdb.NewMemDatabase()
|
dstDb := ethdb.NewMemDatabase()
|
||||||
sched := NewStateSync(srcRoot, dstDb)
|
sched := NewStateSync(srcRoot, dstDb)
|
||||||
|
|
||||||
added := []common.Hash{}
|
added := []common.Hash{}
|
||||||
|
|
|
||||||
|
|
@ -78,8 +78,7 @@ func pricedTransaction(nonce uint64, gaslimit uint64, gasprice *big.Int, key *ec
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupTxPool() (*TxPool, *ecdsa.PrivateKey) {
|
func setupTxPool() (*TxPool, *ecdsa.PrivateKey) {
|
||||||
diskdb, _ := ethdb.NewMemDatabase()
|
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
|
||||||
statedb, _ := state.New(common.Hash{}, state.NewDatabase(diskdb))
|
|
||||||
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
|
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
|
||||||
|
|
||||||
key, _ := crypto.GenerateKey()
|
key, _ := crypto.GenerateKey()
|
||||||
|
|
@ -158,8 +157,7 @@ func (c *testChain) State() (*state.StateDB, error) {
|
||||||
// a state change between those fetches.
|
// a state change between those fetches.
|
||||||
stdb := c.statedb
|
stdb := c.statedb
|
||||||
if *c.trigger {
|
if *c.trigger {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
c.statedb, _ = state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
|
||||||
c.statedb, _ = state.New(common.Hash{}, state.NewDatabase(db))
|
|
||||||
// simulate that the new head block included tx0 and tx1
|
// simulate that the new head block included tx0 and tx1
|
||||||
c.statedb.SetNonce(c.address, 2)
|
c.statedb.SetNonce(c.address, 2)
|
||||||
c.statedb.SetBalance(c.address, new(big.Int).SetUint64(params.Ether))
|
c.statedb.SetBalance(c.address, new(big.Int).SetUint64(params.Ether))
|
||||||
|
|
@ -175,10 +173,9 @@ func TestStateChangeDuringTransactionPoolReset(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
db, _ = ethdb.NewMemDatabase()
|
|
||||||
key, _ = crypto.GenerateKey()
|
key, _ = crypto.GenerateKey()
|
||||||
address = crypto.PubkeyToAddress(key.PublicKey)
|
address = crypto.PubkeyToAddress(key.PublicKey)
|
||||||
statedb, _ = state.New(common.Hash{}, state.NewDatabase(db))
|
statedb, _ = state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
|
||||||
trigger = false
|
trigger = false
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -332,8 +329,7 @@ func TestTransactionChainFork(t *testing.T) {
|
||||||
|
|
||||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||||
resetState := func() {
|
resetState := func() {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
|
||||||
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
|
||||||
statedb.AddBalance(addr, big.NewInt(100000000000000))
|
statedb.AddBalance(addr, big.NewInt(100000000000000))
|
||||||
|
|
||||||
pool.chain = &testBlockChain{statedb, 1000000, new(event.Feed)}
|
pool.chain = &testBlockChain{statedb, 1000000, new(event.Feed)}
|
||||||
|
|
@ -362,8 +358,7 @@ func TestTransactionDoubleNonce(t *testing.T) {
|
||||||
|
|
||||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||||
resetState := func() {
|
resetState := func() {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
|
||||||
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
|
||||||
statedb.AddBalance(addr, big.NewInt(100000000000000))
|
statedb.AddBalance(addr, big.NewInt(100000000000000))
|
||||||
|
|
||||||
pool.chain = &testBlockChain{statedb, 1000000, new(event.Feed)}
|
pool.chain = &testBlockChain{statedb, 1000000, new(event.Feed)}
|
||||||
|
|
@ -553,8 +548,7 @@ func TestTransactionPostponing(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the postponing with
|
// Create the pool to test the postponing with
|
||||||
db, _ := ethdb.NewMemDatabase()
|
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
|
||||||
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
|
||||||
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
|
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
|
||||||
|
|
||||||
pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
|
pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
|
||||||
|
|
@ -769,8 +763,7 @@ func testTransactionQueueGlobalLimiting(t *testing.T, nolocals bool) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the limit enforcement with
|
// Create the pool to test the limit enforcement with
|
||||||
db, _ := ethdb.NewMemDatabase()
|
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
|
||||||
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
|
||||||
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
|
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
|
||||||
|
|
||||||
config := testTxPoolConfig
|
config := testTxPoolConfig
|
||||||
|
|
@ -858,8 +851,7 @@ func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) {
|
||||||
evictionInterval = time.Second
|
evictionInterval = time.Second
|
||||||
|
|
||||||
// Create the pool to test the non-expiration enforcement
|
// Create the pool to test the non-expiration enforcement
|
||||||
db, _ := ethdb.NewMemDatabase()
|
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
|
||||||
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
|
||||||
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
|
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
|
||||||
|
|
||||||
config := testTxPoolConfig
|
config := testTxPoolConfig
|
||||||
|
|
@ -1013,8 +1005,7 @@ func TestTransactionPendingGlobalLimiting(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the limit enforcement with
|
// Create the pool to test the limit enforcement with
|
||||||
db, _ := ethdb.NewMemDatabase()
|
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
|
||||||
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
|
||||||
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
|
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
|
||||||
|
|
||||||
config := testTxPoolConfig
|
config := testTxPoolConfig
|
||||||
|
|
@ -1060,8 +1051,7 @@ func TestTransactionCapClearsFromAll(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the limit enforcement with
|
// Create the pool to test the limit enforcement with
|
||||||
db, _ := ethdb.NewMemDatabase()
|
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
|
||||||
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
|
||||||
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
|
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
|
||||||
|
|
||||||
config := testTxPoolConfig
|
config := testTxPoolConfig
|
||||||
|
|
@ -1095,8 +1085,7 @@ func TestTransactionPendingMinimumAllowance(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the limit enforcement with
|
// Create the pool to test the limit enforcement with
|
||||||
db, _ := ethdb.NewMemDatabase()
|
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
|
||||||
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
|
||||||
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
|
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
|
||||||
|
|
||||||
config := testTxPoolConfig
|
config := testTxPoolConfig
|
||||||
|
|
@ -1144,8 +1133,7 @@ func TestTransactionPoolRepricing(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the pricing enforcement with
|
// Create the pool to test the pricing enforcement with
|
||||||
db, _ := ethdb.NewMemDatabase()
|
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
|
||||||
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
|
||||||
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
|
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
|
||||||
|
|
||||||
pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
|
pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
|
||||||
|
|
@ -1266,8 +1254,7 @@ func TestTransactionPoolRepricingKeepsLocals(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the pricing enforcement with
|
// Create the pool to test the pricing enforcement with
|
||||||
db, _ := ethdb.NewMemDatabase()
|
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
|
||||||
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
|
||||||
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
|
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
|
||||||
|
|
||||||
pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
|
pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
|
||||||
|
|
@ -1329,8 +1316,7 @@ func TestTransactionPoolUnderpricing(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the pricing enforcement with
|
// Create the pool to test the pricing enforcement with
|
||||||
db, _ := ethdb.NewMemDatabase()
|
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
|
||||||
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
|
||||||
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
|
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
|
||||||
|
|
||||||
config := testTxPoolConfig
|
config := testTxPoolConfig
|
||||||
|
|
@ -1436,8 +1422,7 @@ func TestTransactionPoolStableUnderpricing(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the pricing enforcement with
|
// Create the pool to test the pricing enforcement with
|
||||||
db, _ := ethdb.NewMemDatabase()
|
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
|
||||||
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
|
||||||
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
|
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
|
||||||
|
|
||||||
config := testTxPoolConfig
|
config := testTxPoolConfig
|
||||||
|
|
@ -1503,8 +1488,7 @@ func TestTransactionReplacement(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the pricing enforcement with
|
// Create the pool to test the pricing enforcement with
|
||||||
db, _ := ethdb.NewMemDatabase()
|
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
|
||||||
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
|
||||||
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
|
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
|
||||||
|
|
||||||
pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
|
pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
|
||||||
|
|
@ -1598,8 +1582,7 @@ func testTransactionJournaling(t *testing.T, nolocals bool) {
|
||||||
os.Remove(journal)
|
os.Remove(journal)
|
||||||
|
|
||||||
// Create the original pool to inject transaction into the journal
|
// Create the original pool to inject transaction into the journal
|
||||||
db, _ := ethdb.NewMemDatabase()
|
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
|
||||||
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
|
||||||
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
|
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
|
||||||
|
|
||||||
config := testTxPoolConfig
|
config := testTxPoolConfig
|
||||||
|
|
@ -1697,8 +1680,7 @@ func TestTransactionStatusCheck(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the status retrievals with
|
// Create the pool to test the status retrievals with
|
||||||
db, _ := ethdb.NewMemDatabase()
|
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
|
||||||
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
|
||||||
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
|
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)}
|
||||||
|
|
||||||
pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
|
pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
|
||||||
|
|
|
||||||
|
|
@ -99,8 +99,7 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
|
||||||
setDefaults(cfg)
|
setDefaults(cfg)
|
||||||
|
|
||||||
if cfg.State == nil {
|
if cfg.State == nil {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
cfg.State, _ = state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
|
||||||
cfg.State, _ = state.New(common.Hash{}, state.NewDatabase(db))
|
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
address = common.BytesToAddress([]byte("contract"))
|
address = common.BytesToAddress([]byte("contract"))
|
||||||
|
|
@ -130,8 +129,7 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) {
|
||||||
setDefaults(cfg)
|
setDefaults(cfg)
|
||||||
|
|
||||||
if cfg.State == nil {
|
if cfg.State == nil {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
cfg.State, _ = state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
|
||||||
cfg.State, _ = state.New(common.Hash{}, state.NewDatabase(db))
|
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
vmenv = NewEnv(cfg)
|
vmenv = NewEnv(cfg)
|
||||||
|
|
|
||||||
|
|
@ -94,8 +94,7 @@ func TestExecute(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCall(t *testing.T) {
|
func TestCall(t *testing.T) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
state, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
|
||||||
state, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
|
||||||
address := common.HexToAddress("0x0a")
|
address := common.HexToAddress("0x0a")
|
||||||
state.SetCode(address, []byte{
|
state.SetCode(address, []byte{
|
||||||
byte(vm.PUSH1), 10,
|
byte(vm.PUSH1), 10,
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
secp256k1_N, _ = new(big.Int).SetString("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", 16)
|
secp256k1N, _ = new(big.Int).SetString("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", 16)
|
||||||
secp256k1_halfN = new(big.Int).Div(secp256k1_N, big.NewInt(2))
|
secp256k1halfN = new(big.Int).Div(secp256k1N, big.NewInt(2))
|
||||||
)
|
)
|
||||||
|
|
||||||
// Keccak256 calculates and returns the Keccak256 hash of the input data.
|
// Keccak256 calculates and returns the Keccak256 hash of the input data.
|
||||||
|
|
@ -68,7 +68,7 @@ func Keccak512(data ...[]byte) []byte {
|
||||||
return d.Sum(nil)
|
return d.Sum(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates an ethereum address given the bytes and the nonce
|
// CreateAddress creates an ethereum address given the bytes and the nonce
|
||||||
func CreateAddress(b common.Address, nonce uint64) common.Address {
|
func CreateAddress(b common.Address, nonce uint64) common.Address {
|
||||||
data, _ := rlp.EncodeToBytes([]interface{}{b, nonce})
|
data, _ := rlp.EncodeToBytes([]interface{}{b, nonce})
|
||||||
return common.BytesToAddress(Keccak256(data)[12:])
|
return common.BytesToAddress(Keccak256(data)[12:])
|
||||||
|
|
@ -99,7 +99,7 @@ func toECDSA(d []byte, strict bool) (*ecdsa.PrivateKey, error) {
|
||||||
priv.D = new(big.Int).SetBytes(d)
|
priv.D = new(big.Int).SetBytes(d)
|
||||||
|
|
||||||
// The priv.D must < N
|
// The priv.D must < N
|
||||||
if priv.D.Cmp(secp256k1_N) >= 0 {
|
if priv.D.Cmp(secp256k1N) >= 0 {
|
||||||
return nil, fmt.Errorf("invalid private key, >=N")
|
return nil, fmt.Errorf("invalid private key, >=N")
|
||||||
}
|
}
|
||||||
// The priv.D must not be zero or negative.
|
// The priv.D must not be zero or negative.
|
||||||
|
|
@ -184,11 +184,11 @@ func ValidateSignatureValues(v byte, r, s *big.Int, homestead bool) bool {
|
||||||
}
|
}
|
||||||
// reject upper range of s values (ECDSA malleability)
|
// reject upper range of s values (ECDSA malleability)
|
||||||
// see discussion in secp256k1/libsecp256k1/include/secp256k1.h
|
// see discussion in secp256k1/libsecp256k1/include/secp256k1.h
|
||||||
if homestead && s.Cmp(secp256k1_halfN) > 0 {
|
if homestead && s.Cmp(secp256k1halfN) > 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// Frontier: allow s to be in full N range
|
// Frontier: allow s to be in full N range
|
||||||
return r.Cmp(secp256k1_N) < 0 && s.Cmp(secp256k1_N) < 0 && (v == 0 || v == 1)
|
return r.Cmp(secp256k1N) < 0 && s.Cmp(secp256k1N) < 0 && (v == 0 || v == 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func PubkeyToAddress(p ecdsa.PublicKey) common.Address {
|
func PubkeyToAddress(p ecdsa.PublicKey) common.Address {
|
||||||
|
|
|
||||||
|
|
@ -154,7 +154,7 @@ func TestValidateSignatureValues(t *testing.T) {
|
||||||
minusOne := big.NewInt(-1)
|
minusOne := big.NewInt(-1)
|
||||||
one := common.Big1
|
one := common.Big1
|
||||||
zero := common.Big0
|
zero := common.Big0
|
||||||
secp256k1nMinus1 := new(big.Int).Sub(secp256k1_N, common.Big1)
|
secp256k1nMinus1 := new(big.Int).Sub(secp256k1N, common.Big1)
|
||||||
|
|
||||||
// correct v,r,s
|
// correct v,r,s
|
||||||
check(true, 0, one, one)
|
check(true, 0, one, one)
|
||||||
|
|
@ -181,9 +181,9 @@ func TestValidateSignatureValues(t *testing.T) {
|
||||||
// correct sig with max r,s
|
// correct sig with max r,s
|
||||||
check(true, 0, secp256k1nMinus1, secp256k1nMinus1)
|
check(true, 0, secp256k1nMinus1, secp256k1nMinus1)
|
||||||
// correct v, combinations of incorrect r,s at upper limit
|
// correct v, combinations of incorrect r,s at upper limit
|
||||||
check(false, 0, secp256k1_N, secp256k1nMinus1)
|
check(false, 0, secp256k1N, secp256k1nMinus1)
|
||||||
check(false, 0, secp256k1nMinus1, secp256k1_N)
|
check(false, 0, secp256k1nMinus1, secp256k1N)
|
||||||
check(false, 0, secp256k1_N, secp256k1_N)
|
check(false, 0, secp256k1N, secp256k1N)
|
||||||
|
|
||||||
// current callers ensures r,s cannot be negative, but let's test for that too
|
// current callers ensures r,s cannot be negative, but let's test for that too
|
||||||
// as crypto package could be used stand-alone
|
// as crypto package could be used stand-alone
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ func (BitCurve *BitCurve) Params() *elliptic.CurveParams {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsOnBitCurve returns true if the given (x,y) lies on the BitCurve.
|
// IsOnCurve returns true if the given (x,y) lies on the BitCurve.
|
||||||
func (BitCurve *BitCurve) IsOnCurve(x, y *big.Int) bool {
|
func (BitCurve *BitCurve) IsOnCurve(x, y *big.Int) bool {
|
||||||
// y² = x³ + b
|
// y² = x³ + b
|
||||||
y2 := new(big.Int).Mul(y, y) //y²
|
y2 := new(big.Int).Mul(y, y) //y²
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ func randSig() []byte {
|
||||||
// tests for malleability
|
// tests for malleability
|
||||||
// highest bit of signature ECDSA s value must be 0, in the 33th byte
|
// highest bit of signature ECDSA s value must be 0, in the 33th byte
|
||||||
func compactSigCheck(t *testing.T, sig []byte) {
|
func compactSigCheck(t *testing.T, sig []byte) {
|
||||||
var b int = int(sig[32])
|
var b = int(sig[32])
|
||||||
if b < 0 {
|
if b < 0 {
|
||||||
t.Errorf("highest bit is negative: %d", b)
|
t.Errorf("highest bit is negative: %d", b)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ func VerifySignature(pubkey, hash, signature []byte) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// Reject malleable signatures. libsecp256k1 does this check but btcec doesn't.
|
// Reject malleable signatures. libsecp256k1 does this check but btcec doesn't.
|
||||||
if sig.S.Cmp(secp256k1_halfN) > 0 {
|
if sig.S.Cmp(secp256k1halfN) > 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return sig.Verify(hash, key)
|
return sig.Verify(hash, key)
|
||||||
|
|
|
||||||
|
|
@ -37,26 +37,26 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
// EthApiBackend implements ethapi.Backend for full nodes
|
// EthAPIBackend implements ethapi.Backend for full nodes
|
||||||
type EthApiBackend struct {
|
type EthAPIBackend struct {
|
||||||
eth *Ethereum
|
eth *Ethereum
|
||||||
gpo *gasprice.Oracle
|
gpo *gasprice.Oracle
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) ChainConfig() *params.ChainConfig {
|
func (b *EthAPIBackend) ChainConfig() *params.ChainConfig {
|
||||||
return b.eth.chainConfig
|
return b.eth.chainConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) CurrentBlock() *types.Block {
|
func (b *EthAPIBackend) CurrentBlock() *types.Block {
|
||||||
return b.eth.blockchain.CurrentBlock()
|
return b.eth.blockchain.CurrentBlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) SetHead(number uint64) {
|
func (b *EthAPIBackend) SetHead(number uint64) {
|
||||||
b.eth.protocolManager.downloader.Cancel()
|
b.eth.protocolManager.downloader.Cancel()
|
||||||
b.eth.blockchain.SetHead(number)
|
b.eth.blockchain.SetHead(number)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) {
|
func (b *EthAPIBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) {
|
||||||
// Pending block is only known by the miner
|
// Pending block is only known by the miner
|
||||||
if blockNr == rpc.PendingBlockNumber {
|
if blockNr == rpc.PendingBlockNumber {
|
||||||
block := b.eth.miner.PendingBlock()
|
block := b.eth.miner.PendingBlock()
|
||||||
|
|
@ -69,7 +69,7 @@ func (b *EthApiBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNum
|
||||||
return b.eth.blockchain.GetHeaderByNumber(uint64(blockNr)), nil
|
return b.eth.blockchain.GetHeaderByNumber(uint64(blockNr)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) BlockByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Block, error) {
|
func (b *EthAPIBackend) BlockByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Block, error) {
|
||||||
// Pending block is only known by the miner
|
// Pending block is only known by the miner
|
||||||
if blockNr == rpc.PendingBlockNumber {
|
if blockNr == rpc.PendingBlockNumber {
|
||||||
block := b.eth.miner.PendingBlock()
|
block := b.eth.miner.PendingBlock()
|
||||||
|
|
@ -82,7 +82,7 @@ func (b *EthApiBackend) BlockByNumber(ctx context.Context, blockNr rpc.BlockNumb
|
||||||
return b.eth.blockchain.GetBlockByNumber(uint64(blockNr)), nil
|
return b.eth.blockchain.GetBlockByNumber(uint64(blockNr)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.StateDB, *types.Header, error) {
|
func (b *EthAPIBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.StateDB, *types.Header, error) {
|
||||||
// Pending state is only known by the miner
|
// Pending state is only known by the miner
|
||||||
if blockNr == rpc.PendingBlockNumber {
|
if blockNr == rpc.PendingBlockNumber {
|
||||||
block, state := b.eth.miner.Pending()
|
block, state := b.eth.miner.Pending()
|
||||||
|
|
@ -97,18 +97,18 @@ func (b *EthApiBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc.
|
||||||
return stateDb, header, err
|
return stateDb, header, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) GetBlock(ctx context.Context, hash common.Hash) (*types.Block, error) {
|
func (b *EthAPIBackend) GetBlock(ctx context.Context, hash common.Hash) (*types.Block, error) {
|
||||||
return b.eth.blockchain.GetBlockByHash(hash), nil
|
return b.eth.blockchain.GetBlockByHash(hash), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) {
|
func (b *EthAPIBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) {
|
||||||
if number := rawdb.ReadHeaderNumber(b.eth.chainDb, hash); number != nil {
|
if number := rawdb.ReadHeaderNumber(b.eth.chainDb, hash); number != nil {
|
||||||
return rawdb.ReadReceipts(b.eth.chainDb, hash, *number), nil
|
return rawdb.ReadReceipts(b.eth.chainDb, hash, *number), nil
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) {
|
func (b *EthAPIBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) {
|
||||||
number := rawdb.ReadHeaderNumber(b.eth.chainDb, hash)
|
number := rawdb.ReadHeaderNumber(b.eth.chainDb, hash)
|
||||||
if number == nil {
|
if number == nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
|
@ -124,11 +124,11 @@ func (b *EthApiBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*typ
|
||||||
return logs, nil
|
return logs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) GetTd(blockHash common.Hash) *big.Int {
|
func (b *EthAPIBackend) GetTd(blockHash common.Hash) *big.Int {
|
||||||
return b.eth.blockchain.GetTdByHash(blockHash)
|
return b.eth.blockchain.GetTdByHash(blockHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header, vmCfg vm.Config) (*vm.EVM, func() error, error) {
|
func (b *EthAPIBackend) GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header, vmCfg vm.Config) (*vm.EVM, func() error, error) {
|
||||||
state.SetBalance(msg.From(), math.MaxBig256)
|
state.SetBalance(msg.From(), math.MaxBig256)
|
||||||
vmError := func() error { return nil }
|
vmError := func() error { return nil }
|
||||||
|
|
||||||
|
|
@ -136,31 +136,31 @@ func (b *EthApiBackend) GetEVM(ctx context.Context, msg core.Message, state *sta
|
||||||
return vm.NewEVM(context, state, b.eth.chainConfig, vmCfg), vmError, nil
|
return vm.NewEVM(context, state, b.eth.chainConfig, vmCfg), vmError, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription {
|
func (b *EthAPIBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription {
|
||||||
return b.eth.BlockChain().SubscribeRemovedLogsEvent(ch)
|
return b.eth.BlockChain().SubscribeRemovedLogsEvent(ch)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription {
|
func (b *EthAPIBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription {
|
||||||
return b.eth.BlockChain().SubscribeChainEvent(ch)
|
return b.eth.BlockChain().SubscribeChainEvent(ch)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription {
|
func (b *EthAPIBackend) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription {
|
||||||
return b.eth.BlockChain().SubscribeChainHeadEvent(ch)
|
return b.eth.BlockChain().SubscribeChainHeadEvent(ch)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription {
|
func (b *EthAPIBackend) SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription {
|
||||||
return b.eth.BlockChain().SubscribeChainSideEvent(ch)
|
return b.eth.BlockChain().SubscribeChainSideEvent(ch)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription {
|
func (b *EthAPIBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription {
|
||||||
return b.eth.BlockChain().SubscribeLogsEvent(ch)
|
return b.eth.BlockChain().SubscribeLogsEvent(ch)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
|
func (b *EthAPIBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
|
||||||
return b.eth.txPool.AddLocal(signedTx)
|
return b.eth.txPool.AddLocal(signedTx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) GetPoolTransactions() (types.Transactions, error) {
|
func (b *EthAPIBackend) GetPoolTransactions() (types.Transactions, error) {
|
||||||
pending, err := b.eth.txPool.Pending()
|
pending, err := b.eth.txPool.Pending()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -172,56 +172,56 @@ func (b *EthApiBackend) GetPoolTransactions() (types.Transactions, error) {
|
||||||
return txs, nil
|
return txs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) GetPoolTransaction(hash common.Hash) *types.Transaction {
|
func (b *EthAPIBackend) GetPoolTransaction(hash common.Hash) *types.Transaction {
|
||||||
return b.eth.txPool.Get(hash)
|
return b.eth.txPool.Get(hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) {
|
func (b *EthAPIBackend) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) {
|
||||||
return b.eth.txPool.State().GetNonce(addr), nil
|
return b.eth.txPool.State().GetNonce(addr), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) Stats() (pending int, queued int) {
|
func (b *EthAPIBackend) Stats() (pending int, queued int) {
|
||||||
return b.eth.txPool.Stats()
|
return b.eth.txPool.Stats()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) TxPoolContent() (map[common.Address]types.Transactions, map[common.Address]types.Transactions) {
|
func (b *EthAPIBackend) TxPoolContent() (map[common.Address]types.Transactions, map[common.Address]types.Transactions) {
|
||||||
return b.eth.TxPool().Content()
|
return b.eth.TxPool().Content()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) SubscribeTxPreEvent(ch chan<- core.TxPreEvent) event.Subscription {
|
func (b *EthAPIBackend) SubscribeTxPreEvent(ch chan<- core.TxPreEvent) event.Subscription {
|
||||||
return b.eth.TxPool().SubscribeTxPreEvent(ch)
|
return b.eth.TxPool().SubscribeTxPreEvent(ch)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) Downloader() *downloader.Downloader {
|
func (b *EthAPIBackend) Downloader() *downloader.Downloader {
|
||||||
return b.eth.Downloader()
|
return b.eth.Downloader()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) ProtocolVersion() int {
|
func (b *EthAPIBackend) ProtocolVersion() int {
|
||||||
return b.eth.EthVersion()
|
return b.eth.EthVersion()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) SuggestPrice(ctx context.Context) (*big.Int, error) {
|
func (b *EthAPIBackend) SuggestPrice(ctx context.Context) (*big.Int, error) {
|
||||||
return b.gpo.SuggestPrice(ctx)
|
return b.gpo.SuggestPrice(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) ChainDb() ethdb.Database {
|
func (b *EthAPIBackend) ChainDb() ethdb.Database {
|
||||||
return b.eth.ChainDb()
|
return b.eth.ChainDb()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) EventMux() *event.TypeMux {
|
func (b *EthAPIBackend) EventMux() *event.TypeMux {
|
||||||
return b.eth.EventMux()
|
return b.eth.EventMux()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) AccountManager() *accounts.Manager {
|
func (b *EthAPIBackend) AccountManager() *accounts.Manager {
|
||||||
return b.eth.AccountManager()
|
return b.eth.AccountManager()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) BloomStatus() (uint64, uint64) {
|
func (b *EthAPIBackend) BloomStatus() (uint64, uint64) {
|
||||||
sections, _, _ := b.eth.bloomIndexer.Sections()
|
sections, _, _ := b.eth.bloomIndexer.Sections()
|
||||||
return params.BloomBitsBlocks, sections
|
return params.BloomBitsBlocks, sections
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) {
|
func (b *EthAPIBackend) ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) {
|
||||||
for i := 0; i < bloomFilterThreads; i++ {
|
for i := 0; i < bloomFilterThreads; i++ {
|
||||||
go session.Multiplex(bloomRetrievalBatch, bloomRetrievalWait, b.eth.bloomRequests)
|
go session.Multiplex(bloomRetrievalBatch, bloomRetrievalWait, b.eth.bloomRequests)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,8 +31,7 @@ var dumper = spew.ConfigState{Indent: " "}
|
||||||
func TestStorageRangeAt(t *testing.T) {
|
func TestStorageRangeAt(t *testing.T) {
|
||||||
// Create a state where account 0x010000... has a few storage entries.
|
// Create a state where account 0x010000... has a few storage entries.
|
||||||
var (
|
var (
|
||||||
db, _ = ethdb.NewMemDatabase()
|
state, _ = state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
|
||||||
state, _ = state.New(common.Hash{}, state.NewDatabase(db))
|
|
||||||
addr = common.Address{0x01}
|
addr = common.Address{0x01}
|
||||||
keys = []common.Hash{ // hashes of Keys of storage
|
keys = []common.Hash{ // hashes of Keys of storage
|
||||||
common.HexToHash("340dd630ad21bf010b4e676dbfa9ba9a02175262d1fa356232cfde6cb5b47ef2"),
|
common.HexToHash("340dd630ad21bf010b4e676dbfa9ba9a02175262d1fa356232cfde6cb5b47ef2"),
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ type Ethereum struct {
|
||||||
bloomRequests chan chan *bloombits.Retrieval // Channel receiving bloom data retrieval requests
|
bloomRequests chan chan *bloombits.Retrieval // Channel receiving bloom data retrieval requests
|
||||||
bloomIndexer *core.ChainIndexer // Bloom indexer operating during block imports
|
bloomIndexer *core.ChainIndexer // Bloom indexer operating during block imports
|
||||||
|
|
||||||
ApiBackend *EthApiBackend
|
APIBackend *EthAPIBackend
|
||||||
|
|
||||||
miner *miner.Miner
|
miner *miner.Miner
|
||||||
gasPrice *big.Int
|
gasPrice *big.Int
|
||||||
|
|
@ -169,12 +169,12 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
|
||||||
eth.miner = miner.New(eth, eth.chainConfig, eth.EventMux(), eth.engine)
|
eth.miner = miner.New(eth, eth.chainConfig, eth.EventMux(), eth.engine)
|
||||||
eth.miner.SetExtra(makeExtraData(config.ExtraData))
|
eth.miner.SetExtra(makeExtraData(config.ExtraData))
|
||||||
|
|
||||||
eth.ApiBackend = &EthApiBackend{eth, nil}
|
eth.APIBackend = &EthAPIBackend{eth, nil}
|
||||||
gpoParams := config.GPO
|
gpoParams := config.GPO
|
||||||
if gpoParams.Default == nil {
|
if gpoParams.Default == nil {
|
||||||
gpoParams.Default = config.GasPrice
|
gpoParams.Default = config.GasPrice
|
||||||
}
|
}
|
||||||
eth.ApiBackend.gpo = gasprice.NewOracle(eth.ApiBackend, gpoParams)
|
eth.APIBackend.gpo = gasprice.NewOracle(eth.APIBackend, gpoParams)
|
||||||
|
|
||||||
return eth, nil
|
return eth, nil
|
||||||
}
|
}
|
||||||
|
|
@ -242,7 +242,7 @@ func CreateConsensusEngine(ctx *node.ServiceContext, config *ethash.Config, chai
|
||||||
// APIs returns the collection of RPC services the ethereum package offers.
|
// APIs returns the collection of RPC services the ethereum package offers.
|
||||||
// NOTE, some of these services probably need to be moved to somewhere else.
|
// NOTE, some of these services probably need to be moved to somewhere else.
|
||||||
func (s *Ethereum) APIs() []rpc.API {
|
func (s *Ethereum) APIs() []rpc.API {
|
||||||
apis := ethapi.GetAPIs(s.ApiBackend)
|
apis := ethapi.GetAPIs(s.APIBackend)
|
||||||
|
|
||||||
// Append any APIs exposed explicitly by the consensus engine
|
// Append any APIs exposed explicitly by the consensus engine
|
||||||
apis = append(apis, s.engine.APIs(s.BlockChain())...)
|
apis = append(apis, s.engine.APIs(s.BlockChain())...)
|
||||||
|
|
@ -272,7 +272,7 @@ func (s *Ethereum) APIs() []rpc.API {
|
||||||
}, {
|
}, {
|
||||||
Namespace: "eth",
|
Namespace: "eth",
|
||||||
Version: "1.0",
|
Version: "1.0",
|
||||||
Service: filters.NewPublicFilterAPI(s.ApiBackend, false),
|
Service: filters.NewPublicFilterAPI(s.APIBackend, false),
|
||||||
Public: true,
|
Public: true,
|
||||||
}, {
|
}, {
|
||||||
Namespace: "admin",
|
Namespace: "admin",
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ type downloadTester struct {
|
||||||
|
|
||||||
// newTester creates a new downloader test mocker.
|
// newTester creates a new downloader test mocker.
|
||||||
func newTester() *downloadTester {
|
func newTester() *downloadTester {
|
||||||
testdb, _ := ethdb.NewMemDatabase()
|
testdb := ethdb.NewMemDatabase()
|
||||||
genesis := core.GenesisBlockForTesting(testdb, testAddress, big.NewInt(1000000000))
|
genesis := core.GenesisBlockForTesting(testdb, testAddress, big.NewInt(1000000000))
|
||||||
|
|
||||||
tester := &downloadTester{
|
tester := &downloadTester{
|
||||||
|
|
@ -93,7 +93,7 @@ func newTester() *downloadTester {
|
||||||
peerChainTds: make(map[string]map[common.Hash]*big.Int),
|
peerChainTds: make(map[string]map[common.Hash]*big.Int),
|
||||||
peerMissingStates: make(map[string]map[common.Hash]bool),
|
peerMissingStates: make(map[string]map[common.Hash]bool),
|
||||||
}
|
}
|
||||||
tester.stateDb, _ = ethdb.NewMemDatabase()
|
tester.stateDb = ethdb.NewMemDatabase()
|
||||||
tester.stateDb.Put(genesis.Root().Bytes(), []byte{0x00})
|
tester.stateDb.Put(genesis.Root().Bytes(), []byte{0x00})
|
||||||
|
|
||||||
tester.downloader = New(FullSync, tester.stateDb, new(event.TypeMux), tester, nil, tester.dropPeer)
|
tester.downloader = New(FullSync, tester.stateDb, new(event.TypeMux), tester, nil, tester.dropPeer)
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
testdb, _ = ethdb.NewMemDatabase()
|
testdb = ethdb.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))
|
||||||
|
|
|
||||||
|
|
@ -268,14 +268,8 @@ func (api *PublicFilterAPI) Logs(ctx context.Context, crit FilterCriteria) (*rpc
|
||||||
}
|
}
|
||||||
|
|
||||||
// FilterCriteria represents a request to create a new filter.
|
// FilterCriteria represents a request to create a new filter.
|
||||||
//
|
// Same as ethereum.FilterQuery but with UnmarshalJSON() method.
|
||||||
// TODO(karalabe): Kill this in favor of ethereum.FilterQuery.
|
type FilterCriteria ethereum.FilterQuery
|
||||||
type FilterCriteria struct {
|
|
||||||
FromBlock *big.Int
|
|
||||||
ToBlock *big.Int
|
|
||||||
Addresses []common.Address
|
|
||||||
Topics [][]common.Hash
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewFilter creates a new filter and returns the filter id. It can be
|
// NewFilter creates a new filter and returns the filter id. It can be
|
||||||
// used to retrieve logs when the state changes. This method cannot be
|
// used to retrieve logs when the state changes. This method cannot be
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -92,8 +93,21 @@ type EventSystem struct {
|
||||||
backend Backend
|
backend Backend
|
||||||
lightMode bool
|
lightMode bool
|
||||||
lastHead *types.Header
|
lastHead *types.Header
|
||||||
|
|
||||||
|
// Subscriptions
|
||||||
|
txSub event.Subscription // Subscription for new transaction event
|
||||||
|
logsSub event.Subscription // Subscription for new log event
|
||||||
|
rmLogsSub event.Subscription // Subscription for removed log event
|
||||||
|
chainSub event.Subscription // Subscription for new chain event
|
||||||
|
pendingLogSub *event.TypeMuxSubscription // Subscription for pending log event
|
||||||
|
|
||||||
|
// Channels
|
||||||
install chan *subscription // install filter for event notification
|
install chan *subscription // install filter for event notification
|
||||||
uninstall chan *subscription // remove filter for event notification
|
uninstall chan *subscription // remove filter for event notification
|
||||||
|
txCh chan core.TxPreEvent // Channel to receive new transaction event
|
||||||
|
logsCh chan []*types.Log // Channel to receive new log event
|
||||||
|
rmLogsCh chan core.RemovedLogsEvent // Channel to receive removed log event
|
||||||
|
chainCh chan core.ChainEvent // Channel to receive new chain event
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewEventSystem creates a new manager that listens for event on the given mux,
|
// NewEventSystem creates a new manager that listens for event on the given mux,
|
||||||
|
|
@ -109,10 +123,27 @@ func NewEventSystem(mux *event.TypeMux, backend Backend, lightMode bool) *EventS
|
||||||
lightMode: lightMode,
|
lightMode: lightMode,
|
||||||
install: make(chan *subscription),
|
install: make(chan *subscription),
|
||||||
uninstall: make(chan *subscription),
|
uninstall: make(chan *subscription),
|
||||||
|
txCh: make(chan core.TxPreEvent, txChanSize),
|
||||||
|
logsCh: make(chan []*types.Log, logsChanSize),
|
||||||
|
rmLogsCh: make(chan core.RemovedLogsEvent, rmLogsChanSize),
|
||||||
|
chainCh: make(chan core.ChainEvent, chainEvChanSize),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Subscribe events
|
||||||
|
m.txSub = m.backend.SubscribeTxPreEvent(m.txCh)
|
||||||
|
m.logsSub = m.backend.SubscribeLogsEvent(m.logsCh)
|
||||||
|
m.rmLogsSub = m.backend.SubscribeRemovedLogsEvent(m.rmLogsCh)
|
||||||
|
m.chainSub = m.backend.SubscribeChainEvent(m.chainCh)
|
||||||
|
// TODO(rjl493456442): use feed to subscribe pending log event
|
||||||
|
m.pendingLogSub = m.mux.Subscribe(core.PendingLogsEvent{})
|
||||||
|
|
||||||
|
// Make sure none of the subscriptions are empty
|
||||||
|
if m.txSub == nil || m.logsSub == nil || m.rmLogsSub == nil || m.chainSub == nil ||
|
||||||
|
m.pendingLogSub.Closed() {
|
||||||
|
log.Crit("Subscribe for event system failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
go m.eventLoop()
|
go m.eventLoop()
|
||||||
|
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -412,52 +443,37 @@ func (es *EventSystem) lightFilterLogs(header *types.Header, addresses []common.
|
||||||
|
|
||||||
// eventLoop (un)installs filters and processes mux events.
|
// eventLoop (un)installs filters and processes mux events.
|
||||||
func (es *EventSystem) eventLoop() {
|
func (es *EventSystem) eventLoop() {
|
||||||
var (
|
// Ensure all subscriptions get cleaned up
|
||||||
index = make(filterIndex)
|
defer func() {
|
||||||
sub = es.mux.Subscribe(core.PendingLogsEvent{})
|
es.pendingLogSub.Unsubscribe()
|
||||||
// Subscribe TxPreEvent form txpool
|
es.txSub.Unsubscribe()
|
||||||
txCh = make(chan core.TxPreEvent, txChanSize)
|
es.logsSub.Unsubscribe()
|
||||||
txSub = es.backend.SubscribeTxPreEvent(txCh)
|
es.rmLogsSub.Unsubscribe()
|
||||||
// Subscribe RemovedLogsEvent
|
es.chainSub.Unsubscribe()
|
||||||
rmLogsCh = make(chan core.RemovedLogsEvent, rmLogsChanSize)
|
}()
|
||||||
rmLogsSub = es.backend.SubscribeRemovedLogsEvent(rmLogsCh)
|
|
||||||
// Subscribe []*types.Log
|
|
||||||
logsCh = make(chan []*types.Log, logsChanSize)
|
|
||||||
logsSub = es.backend.SubscribeLogsEvent(logsCh)
|
|
||||||
// Subscribe ChainEvent
|
|
||||||
chainEvCh = make(chan core.ChainEvent, chainEvChanSize)
|
|
||||||
chainEvSub = es.backend.SubscribeChainEvent(chainEvCh)
|
|
||||||
)
|
|
||||||
|
|
||||||
// Unsubscribe all events
|
|
||||||
defer sub.Unsubscribe()
|
|
||||||
defer txSub.Unsubscribe()
|
|
||||||
defer rmLogsSub.Unsubscribe()
|
|
||||||
defer logsSub.Unsubscribe()
|
|
||||||
defer chainEvSub.Unsubscribe()
|
|
||||||
|
|
||||||
|
index := make(filterIndex)
|
||||||
for i := UnknownSubscription; i < LastIndexSubscription; i++ {
|
for i := UnknownSubscription; i < LastIndexSubscription; i++ {
|
||||||
index[i] = make(map[rpc.ID]*subscription)
|
index[i] = make(map[rpc.ID]*subscription)
|
||||||
}
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case ev, active := <-sub.Chan():
|
// Handle subscribed events
|
||||||
|
case ev := <-es.txCh:
|
||||||
|
es.broadcast(index, ev)
|
||||||
|
case ev := <-es.logsCh:
|
||||||
|
es.broadcast(index, ev)
|
||||||
|
case ev := <-es.rmLogsCh:
|
||||||
|
es.broadcast(index, ev)
|
||||||
|
case ev := <-es.chainCh:
|
||||||
|
es.broadcast(index, ev)
|
||||||
|
case ev, active := <-es.pendingLogSub.Chan():
|
||||||
if !active { // system stopped
|
if !active { // system stopped
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
es.broadcast(index, ev)
|
es.broadcast(index, ev)
|
||||||
|
|
||||||
// Handle subscribed events
|
|
||||||
case ev := <-txCh:
|
|
||||||
es.broadcast(index, ev)
|
|
||||||
case ev := <-rmLogsCh:
|
|
||||||
es.broadcast(index, ev)
|
|
||||||
case ev := <-logsCh:
|
|
||||||
es.broadcast(index, ev)
|
|
||||||
case ev := <-chainEvCh:
|
|
||||||
es.broadcast(index, ev)
|
|
||||||
|
|
||||||
case f := <-es.install:
|
case f := <-es.install:
|
||||||
if f.typ == MinedAndPendingLogsSubscription {
|
if f.typ == MinedAndPendingLogsSubscription {
|
||||||
// the type are logs and pending logs subscriptions
|
// the type are logs and pending logs subscriptions
|
||||||
|
|
@ -467,6 +483,7 @@ func (es *EventSystem) eventLoop() {
|
||||||
index[f.typ][f.id] = f
|
index[f.typ][f.id] = f
|
||||||
}
|
}
|
||||||
close(f.installed)
|
close(f.installed)
|
||||||
|
|
||||||
case f := <-es.uninstall:
|
case f := <-es.uninstall:
|
||||||
if f.typ == MinedAndPendingLogsSubscription {
|
if f.typ == MinedAndPendingLogsSubscription {
|
||||||
// the type are logs and pending logs subscriptions
|
// the type are logs and pending logs subscriptions
|
||||||
|
|
@ -478,13 +495,13 @@ func (es *EventSystem) eventLoop() {
|
||||||
close(f.err)
|
close(f.err)
|
||||||
|
|
||||||
// System stopped
|
// System stopped
|
||||||
case <-txSub.Err():
|
case <-es.txSub.Err():
|
||||||
return
|
return
|
||||||
case <-rmLogsSub.Err():
|
case <-es.logsSub.Err():
|
||||||
return
|
return
|
||||||
case <-logsSub.Err():
|
case <-es.rmLogsSub.Err():
|
||||||
return
|
return
|
||||||
case <-chainEvSub.Err():
|
case <-es.chainSub.Err():
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -153,7 +153,7 @@ func TestBlockSubscription(t *testing.T) {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
mux = new(event.TypeMux)
|
mux = new(event.TypeMux)
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db = ethdb.NewMemDatabase()
|
||||||
txFeed = new(event.Feed)
|
txFeed = new(event.Feed)
|
||||||
rmLogsFeed = new(event.Feed)
|
rmLogsFeed = new(event.Feed)
|
||||||
logsFeed = new(event.Feed)
|
logsFeed = new(event.Feed)
|
||||||
|
|
@ -210,7 +210,7 @@ func TestPendingTxFilter(t *testing.T) {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
mux = new(event.TypeMux)
|
mux = new(event.TypeMux)
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db = ethdb.NewMemDatabase()
|
||||||
txFeed = new(event.Feed)
|
txFeed = new(event.Feed)
|
||||||
rmLogsFeed = new(event.Feed)
|
rmLogsFeed = new(event.Feed)
|
||||||
logsFeed = new(event.Feed)
|
logsFeed = new(event.Feed)
|
||||||
|
|
@ -273,7 +273,7 @@ func TestPendingTxFilter(t *testing.T) {
|
||||||
func TestLogFilterCreation(t *testing.T) {
|
func TestLogFilterCreation(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
mux = new(event.TypeMux)
|
mux = new(event.TypeMux)
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db = ethdb.NewMemDatabase()
|
||||||
txFeed = new(event.Feed)
|
txFeed = new(event.Feed)
|
||||||
rmLogsFeed = new(event.Feed)
|
rmLogsFeed = new(event.Feed)
|
||||||
logsFeed = new(event.Feed)
|
logsFeed = new(event.Feed)
|
||||||
|
|
@ -322,7 +322,7 @@ func TestInvalidLogFilterCreation(t *testing.T) {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
mux = new(event.TypeMux)
|
mux = new(event.TypeMux)
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db = ethdb.NewMemDatabase()
|
||||||
txFeed = new(event.Feed)
|
txFeed = new(event.Feed)
|
||||||
rmLogsFeed = new(event.Feed)
|
rmLogsFeed = new(event.Feed)
|
||||||
logsFeed = new(event.Feed)
|
logsFeed = new(event.Feed)
|
||||||
|
|
@ -352,7 +352,7 @@ func TestLogFilter(t *testing.T) {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
mux = new(event.TypeMux)
|
mux = new(event.TypeMux)
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db = ethdb.NewMemDatabase()
|
||||||
txFeed = new(event.Feed)
|
txFeed = new(event.Feed)
|
||||||
rmLogsFeed = new(event.Feed)
|
rmLogsFeed = new(event.Feed)
|
||||||
logsFeed = new(event.Feed)
|
logsFeed = new(event.Feed)
|
||||||
|
|
@ -471,7 +471,7 @@ func TestPendingLogsSubscription(t *testing.T) {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
mux = new(event.TypeMux)
|
mux = new(event.TypeMux)
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db = ethdb.NewMemDatabase()
|
||||||
txFeed = new(event.Feed)
|
txFeed = new(event.Feed)
|
||||||
rmLogsFeed = new(event.Feed)
|
rmLogsFeed = new(event.Feed)
|
||||||
logsFeed = new(event.Feed)
|
logsFeed = new(event.Feed)
|
||||||
|
|
|
||||||
|
|
@ -366,7 +366,7 @@ func testGetNodeData(t *testing.T, protocol int) {
|
||||||
t.Errorf("data hash mismatch: have %x, want %x", hash, want)
|
t.Errorf("data hash mismatch: have %x, want %x", hash, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
statedb, _ := ethdb.NewMemDatabase()
|
statedb := ethdb.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])
|
||||||
}
|
}
|
||||||
|
|
@ -468,7 +468,7 @@ func testDAOChallenge(t *testing.T, localForked, remoteForked bool, timeout bool
|
||||||
var (
|
var (
|
||||||
evmux = new(event.TypeMux)
|
evmux = new(event.TypeMux)
|
||||||
pow = ethash.NewFaker()
|
pow = ethash.NewFaker()
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db = ethdb.NewMemDatabase()
|
||||||
config = ¶ms.ChainConfig{DAOForkBlock: big.NewInt(1), DAOForkSupport: localForked}
|
config = ¶ms.ChainConfig{DAOForkBlock: big.NewInt(1), DAOForkSupport: localForked}
|
||||||
gspec = &core.Genesis{Config: config}
|
gspec = &core.Genesis{Config: config}
|
||||||
genesis = gspec.MustCommit(db)
|
genesis = gspec.MustCommit(db)
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ func newTestProtocolManager(mode downloader.SyncMode, blocks int, generator func
|
||||||
var (
|
var (
|
||||||
evmux = new(event.TypeMux)
|
evmux = new(event.TypeMux)
|
||||||
engine = ethash.NewFaker()
|
engine = ethash.NewFaker()
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db = ethdb.NewMemDatabase()
|
||||||
gspec = &core.Genesis{
|
gspec = &core.Genesis{
|
||||||
Config: params.TestChainConfig,
|
Config: params.TestChainConfig,
|
||||||
Alloc: core.GenesisAlloc{testBank: {Balance: big.NewInt(1000000)}},
|
Alloc: core.GenesisAlloc{testBank: {Balance: big.NewInt(1000000)}},
|
||||||
|
|
|
||||||
|
|
@ -34,13 +34,13 @@ const (
|
||||||
eth63 = 63
|
eth63 = 63
|
||||||
)
|
)
|
||||||
|
|
||||||
// Official short name of the protocol used during capability negotiation.
|
// ProtocolName is the official short name of the protocol used during capability negotiation.
|
||||||
var ProtocolName = "eth"
|
var ProtocolName = "eth"
|
||||||
|
|
||||||
// Supported versions of the eth protocol (first is primary).
|
// ProtocolVersions are the upported versions of the eth protocol (first is primary).
|
||||||
var ProtocolVersions = []uint{eth63, eth62}
|
var ProtocolVersions = []uint{eth63, eth62}
|
||||||
|
|
||||||
// Number of implemented message corresponding to different protocol versions.
|
// ProtocolLengths are the number of implemented message corresponding to different protocol versions.
|
||||||
var ProtocolLengths = []uint64{17, 8}
|
var ProtocolLengths = []uint64{17, 8}
|
||||||
|
|
||||||
const ProtocolMaxMsgSize = 10 * 1024 * 1024 // Maximum cap on the size of a protocol message
|
const ProtocolMaxMsgSize = 10 * 1024 * 1024 // Maximum cap on the size of a protocol message
|
||||||
|
|
|
||||||
|
|
@ -159,8 +159,7 @@ func TestCallTracer(t *testing.T) {
|
||||||
GasLimit: uint64(test.Context.GasLimit),
|
GasLimit: uint64(test.Context.GasLimit),
|
||||||
GasPrice: tx.GasPrice(),
|
GasPrice: tx.GasPrice(),
|
||||||
}
|
}
|
||||||
db, _ := ethdb.NewMemDatabase()
|
statedb := tests.MakePreState(ethdb.NewMemDatabase(), test.Genesis.Alloc)
|
||||||
statedb := tests.MakePreState(db, test.Genesis.Alloc)
|
|
||||||
|
|
||||||
// Create the tracer, the EVM environment and run it
|
// Create the tracer, the EVM environment and run it
|
||||||
tracer, err := New("callTracer")
|
tracer, err := New("callTracer")
|
||||||
|
|
|
||||||
|
|
@ -53,8 +53,7 @@ func TestLDB_PutGet(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMemoryDB_PutGet(t *testing.T) {
|
func TestMemoryDB_PutGet(t *testing.T) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
testPutGet(ethdb.NewMemDatabase(), t)
|
||||||
testPutGet(db, t)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testPutGet(db ethdb.Database, t *testing.T) {
|
func testPutGet(db ethdb.Database, t *testing.T) {
|
||||||
|
|
@ -131,8 +130,7 @@ func TestLDB_ParallelPutGet(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMemoryDB_ParallelPutGet(t *testing.T) {
|
func TestMemoryDB_ParallelPutGet(t *testing.T) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
testParallelPutGet(ethdb.NewMemDatabase(), t)
|
||||||
testParallelPutGet(db, t)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testParallelPutGet(db ethdb.Database, t *testing.T) {
|
func testParallelPutGet(db ethdb.Database, t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -31,16 +31,16 @@ type MemDatabase struct {
|
||||||
lock sync.RWMutex
|
lock sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMemDatabase() (*MemDatabase, error) {
|
func NewMemDatabase() *MemDatabase {
|
||||||
return &MemDatabase{
|
return &MemDatabase{
|
||||||
db: make(map[string][]byte),
|
db: make(map[string][]byte),
|
||||||
}, nil
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMemDatabaseWithCap(size int) (*MemDatabase, error) {
|
func NewMemDatabaseWithCap(size int) *MemDatabase {
|
||||||
return &MemDatabase{
|
return &MemDatabase{
|
||||||
db: make(map[string][]byte, size),
|
db: make(map[string][]byte, size),
|
||||||
}, nil
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *MemDatabase) Put(key []byte, value []byte) error {
|
func (db *MemDatabase) Put(key []byte, value []byte) error {
|
||||||
|
|
|
||||||
|
|
@ -689,7 +689,7 @@ func (s *Service) reportStats(conn *websocket.Conn) error {
|
||||||
sync := s.eth.Downloader().Progress()
|
sync := s.eth.Downloader().Progress()
|
||||||
syncing = s.eth.BlockChain().CurrentHeader().Number.Uint64() >= sync.HighestBlock
|
syncing = s.eth.BlockChain().CurrentHeader().Number.Uint64() >= sync.HighestBlock
|
||||||
|
|
||||||
price, _ := s.eth.ApiBackend.SuggestPrice(context.Background())
|
price, _ := s.eth.APIBackend.SuggestPrice(context.Background())
|
||||||
gasprice = int(price.Uint64())
|
gasprice = int(price.Uint64())
|
||||||
} else {
|
} else {
|
||||||
sync := s.les.Downloader().Progress()
|
sync := s.les.Downloader().Progress()
|
||||||
|
|
|
||||||
|
|
@ -180,6 +180,12 @@ func (s *TypeMuxSubscription) Unsubscribe() {
|
||||||
s.closewait()
|
s.closewait()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *TypeMuxSubscription) Closed() bool {
|
||||||
|
s.closeMu.Lock()
|
||||||
|
defer s.closeMu.Unlock()
|
||||||
|
return s.closed
|
||||||
|
}
|
||||||
|
|
||||||
func (s *TypeMuxSubscription) closewait() {
|
func (s *TypeMuxSubscription) closewait() {
|
||||||
s.closeMu.Lock()
|
s.closeMu.Lock()
|
||||||
defer s.closeMu.Unlock()
|
defer s.closeMu.Unlock()
|
||||||
|
|
|
||||||
|
|
@ -148,7 +148,9 @@ func (f *Feed) Send(value interface{}) (nsent int) {
|
||||||
f.sendCases[i].Send = rvalue
|
f.sendCases[i].Send = rvalue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send until all channels except removeSub have been chosen.
|
// Send until all channels except removeSub have been chosen. 'cases' tracks a prefix
|
||||||
|
// of sendCases. When a send succeeds, the corresponding case moves to the end of
|
||||||
|
// 'cases' and it shrinks by one element.
|
||||||
cases := f.sendCases
|
cases := f.sendCases
|
||||||
for {
|
for {
|
||||||
// Fast path: try sending without blocking before adding to the select set.
|
// Fast path: try sending without blocking before adding to the select set.
|
||||||
|
|
@ -170,6 +172,7 @@ func (f *Feed) Send(value interface{}) (nsent int) {
|
||||||
index := f.sendCases.find(recv.Interface())
|
index := f.sendCases.find(recv.Interface())
|
||||||
f.sendCases = f.sendCases.delete(index)
|
f.sendCases = f.sendCases.delete(index)
|
||||||
if index >= 0 && index < len(cases) {
|
if index >= 0 && index < len(cases) {
|
||||||
|
// Shrink 'cases' too because the removed case was still active.
|
||||||
cases = f.sendCases[:len(cases)-1]
|
cases = f.sendCases[:len(cases)-1]
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -235,6 +235,45 @@ func TestFeedUnsubscribeBlockedPost(t *testing.T) {
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checks that unsubscribing a channel during Send works even if that
|
||||||
|
// channel has already been sent on.
|
||||||
|
func TestFeedUnsubscribeSentChan(t *testing.T) {
|
||||||
|
var (
|
||||||
|
feed Feed
|
||||||
|
ch1 = make(chan int)
|
||||||
|
ch2 = make(chan int)
|
||||||
|
sub1 = feed.Subscribe(ch1)
|
||||||
|
sub2 = feed.Subscribe(ch2)
|
||||||
|
wg sync.WaitGroup
|
||||||
|
)
|
||||||
|
defer sub2.Unsubscribe()
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
feed.Send(0)
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Wait for the value on ch1.
|
||||||
|
<-ch1
|
||||||
|
// Unsubscribe ch1, removing it from the send cases.
|
||||||
|
sub1.Unsubscribe()
|
||||||
|
|
||||||
|
// Receive ch2, finishing Send.
|
||||||
|
<-ch2
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
// Send again. This should send to ch2 only, so the wait group will unblock
|
||||||
|
// as soon as a value is received on ch2.
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
feed.Send(0)
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
<-ch2
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
func TestFeedUnsubscribeFromInbox(t *testing.T) {
|
func TestFeedUnsubscribeFromInbox(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
feed Feed
|
feed Feed
|
||||||
|
|
|
||||||
|
|
@ -57,3 +57,15 @@ func PGPSignFile(input string, output string, pgpkey string) error {
|
||||||
// Generate the signature and return
|
// Generate the signature and return
|
||||||
return openpgp.ArmoredDetachSign(out, keys[0], in, nil)
|
return openpgp.ArmoredDetachSign(out, keys[0], in, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PGPKeyID parses an armored key and returns the key ID.
|
||||||
|
func PGPKeyID(pgpkey string) (string, error) {
|
||||||
|
keys, err := openpgp.ReadArmoredKeyRing(bytes.NewBufferString(pgpkey))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if len(keys) != 1 {
|
||||||
|
return "", fmt.Errorf("key count mismatch: have %d, want %d", len(keys), 1)
|
||||||
|
}
|
||||||
|
return keys[0].PrimaryKey.KeyIdString(), nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,8 +51,7 @@ func TestGetBlockHeadersLes1(t *testing.T) { testGetBlockHeaders(t, 1) }
|
||||||
func TestGetBlockHeadersLes2(t *testing.T) { testGetBlockHeaders(t, 2) }
|
func TestGetBlockHeadersLes2(t *testing.T) { testGetBlockHeaders(t, 2) }
|
||||||
|
|
||||||
func testGetBlockHeaders(t *testing.T, protocol int) {
|
func testGetBlockHeaders(t *testing.T, protocol int) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
pm := newTestProtocolManagerMust(t, false, downloader.MaxHashFetch+15, nil, nil, nil, ethdb.NewMemDatabase())
|
||||||
pm := newTestProtocolManagerMust(t, false, downloader.MaxHashFetch+15, nil, nil, nil, db)
|
|
||||||
bc := pm.blockchain.(*core.BlockChain)
|
bc := pm.blockchain.(*core.BlockChain)
|
||||||
peer, _ := newTestPeer(t, "peer", protocol, pm, true)
|
peer, _ := newTestPeer(t, "peer", protocol, pm, true)
|
||||||
defer peer.close()
|
defer peer.close()
|
||||||
|
|
@ -181,8 +180,7 @@ func TestGetBlockBodiesLes1(t *testing.T) { testGetBlockBodies(t, 1) }
|
||||||
func TestGetBlockBodiesLes2(t *testing.T) { testGetBlockBodies(t, 2) }
|
func TestGetBlockBodiesLes2(t *testing.T) { testGetBlockBodies(t, 2) }
|
||||||
|
|
||||||
func testGetBlockBodies(t *testing.T, protocol int) {
|
func testGetBlockBodies(t *testing.T, protocol int) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
pm := newTestProtocolManagerMust(t, false, downloader.MaxBlockFetch+15, nil, nil, nil, ethdb.NewMemDatabase())
|
||||||
pm := newTestProtocolManagerMust(t, false, downloader.MaxBlockFetch+15, nil, nil, nil, db)
|
|
||||||
bc := pm.blockchain.(*core.BlockChain)
|
bc := pm.blockchain.(*core.BlockChain)
|
||||||
peer, _ := newTestPeer(t, "peer", protocol, pm, true)
|
peer, _ := newTestPeer(t, "peer", protocol, pm, true)
|
||||||
defer peer.close()
|
defer peer.close()
|
||||||
|
|
@ -259,8 +257,7 @@ func TestGetCodeLes2(t *testing.T) { testGetCode(t, 2) }
|
||||||
|
|
||||||
func testGetCode(t *testing.T, protocol int) {
|
func testGetCode(t *testing.T, protocol int) {
|
||||||
// Assemble the test environment
|
// Assemble the test environment
|
||||||
db, _ := ethdb.NewMemDatabase()
|
pm := newTestProtocolManagerMust(t, false, 4, testChainGen, nil, nil, ethdb.NewMemDatabase())
|
||||||
pm := newTestProtocolManagerMust(t, false, 4, testChainGen, nil, nil, db)
|
|
||||||
bc := pm.blockchain.(*core.BlockChain)
|
bc := pm.blockchain.(*core.BlockChain)
|
||||||
peer, _ := newTestPeer(t, "peer", protocol, pm, true)
|
peer, _ := newTestPeer(t, "peer", protocol, pm, true)
|
||||||
defer peer.close()
|
defer peer.close()
|
||||||
|
|
@ -293,7 +290,7 @@ func TestGetReceiptLes2(t *testing.T) { testGetReceipt(t, 2) }
|
||||||
|
|
||||||
func testGetReceipt(t *testing.T, protocol int) {
|
func testGetReceipt(t *testing.T, protocol int) {
|
||||||
// Assemble the test environment
|
// Assemble the test environment
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db := ethdb.NewMemDatabase()
|
||||||
pm := newTestProtocolManagerMust(t, false, 4, testChainGen, nil, nil, db)
|
pm := newTestProtocolManagerMust(t, false, 4, testChainGen, nil, nil, db)
|
||||||
bc := pm.blockchain.(*core.BlockChain)
|
bc := pm.blockchain.(*core.BlockChain)
|
||||||
peer, _ := newTestPeer(t, "peer", protocol, pm, true)
|
peer, _ := newTestPeer(t, "peer", protocol, pm, true)
|
||||||
|
|
@ -321,7 +318,7 @@ func TestGetProofsLes2(t *testing.T) { testGetProofs(t, 2) }
|
||||||
|
|
||||||
func testGetProofs(t *testing.T, protocol int) {
|
func testGetProofs(t *testing.T, protocol int) {
|
||||||
// Assemble the test environment
|
// Assemble the test environment
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db := ethdb.NewMemDatabase()
|
||||||
pm := newTestProtocolManagerMust(t, false, 4, testChainGen, nil, nil, db)
|
pm := newTestProtocolManagerMust(t, false, 4, testChainGen, nil, nil, db)
|
||||||
bc := pm.blockchain.(*core.BlockChain)
|
bc := pm.blockchain.(*core.BlockChain)
|
||||||
peer, _ := newTestPeer(t, "peer", protocol, pm, true)
|
peer, _ := newTestPeer(t, "peer", protocol, pm, true)
|
||||||
|
|
@ -384,7 +381,7 @@ func testGetCHTProofs(t *testing.T, protocol int) {
|
||||||
frequency = uint64(light.CHTFrequencyServer)
|
frequency = uint64(light.CHTFrequencyServer)
|
||||||
}
|
}
|
||||||
// Assemble the test environment
|
// Assemble the test environment
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db := ethdb.NewMemDatabase()
|
||||||
pm := newTestProtocolManagerMust(t, false, int(frequency)+light.HelperTrieProcessConfirmations, testChainGen, nil, nil, db)
|
pm := newTestProtocolManagerMust(t, false, int(frequency)+light.HelperTrieProcessConfirmations, testChainGen, nil, nil, db)
|
||||||
bc := pm.blockchain.(*core.BlockChain)
|
bc := pm.blockchain.(*core.BlockChain)
|
||||||
peer, _ := newTestPeer(t, "peer", protocol, pm, true)
|
peer, _ := newTestPeer(t, "peer", protocol, pm, true)
|
||||||
|
|
@ -452,7 +449,7 @@ func testGetCHTProofs(t *testing.T, protocol int) {
|
||||||
// Tests that bloombits proofs can be correctly retrieved.
|
// Tests that bloombits proofs can be correctly retrieved.
|
||||||
func TestGetBloombitsProofs(t *testing.T) {
|
func TestGetBloombitsProofs(t *testing.T) {
|
||||||
// Assemble the test environment
|
// Assemble the test environment
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db := ethdb.NewMemDatabase()
|
||||||
pm := newTestProtocolManagerMust(t, false, light.BloomTrieFrequency+256, testChainGen, nil, nil, db)
|
pm := newTestProtocolManagerMust(t, false, light.BloomTrieFrequency+256, testChainGen, nil, nil, db)
|
||||||
bc := pm.blockchain.(*core.BlockChain)
|
bc := pm.blockchain.(*core.BlockChain)
|
||||||
peer, _ := newTestPeer(t, "peer", 2, pm, true)
|
peer, _ := newTestPeer(t, "peer", 2, pm, true)
|
||||||
|
|
@ -491,7 +488,7 @@ func TestGetBloombitsProofs(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTransactionStatusLes2(t *testing.T) {
|
func TestTransactionStatusLes2(t *testing.T) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db := ethdb.NewMemDatabase()
|
||||||
pm := newTestProtocolManagerMust(t, false, 0, nil, nil, nil, db)
|
pm := newTestProtocolManagerMust(t, false, 0, nil, nil, nil, db)
|
||||||
chain := pm.blockchain.(*core.BlockChain)
|
chain := pm.blockchain.(*core.BlockChain)
|
||||||
config := core.DefaultTxPoolConfig
|
config := core.DefaultTxPoolConfig
|
||||||
|
|
|
||||||
|
|
@ -165,8 +165,8 @@ func testOdr(t *testing.T, protocol int, expFail uint64, fn odrTestFn) {
|
||||||
peers := newPeerSet()
|
peers := newPeerSet()
|
||||||
dist := newRequestDistributor(peers, make(chan struct{}))
|
dist := newRequestDistributor(peers, make(chan struct{}))
|
||||||
rm := newRetrieveManager(peers, dist, nil)
|
rm := newRetrieveManager(peers, dist, nil)
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db := ethdb.NewMemDatabase()
|
||||||
ldb, _ := ethdb.NewMemDatabase()
|
ldb := ethdb.NewMemDatabase()
|
||||||
odr := NewLesOdr(ldb, light.NewChtIndexer(db, true), light.NewBloomTrieIndexer(db, true), eth.NewBloomIndexer(db, light.BloomTrieFrequency), rm)
|
odr := NewLesOdr(ldb, light.NewChtIndexer(db, true), light.NewBloomTrieIndexer(db, true), eth.NewBloomIndexer(db, light.BloomTrieFrequency), rm)
|
||||||
pm := newTestProtocolManagerMust(t, false, 4, testChainGen, nil, nil, db)
|
pm := newTestProtocolManagerMust(t, false, 4, testChainGen, nil, nil, db)
|
||||||
lpm := newTestProtocolManagerMust(t, true, 0, nil, peers, odr, ldb)
|
lpm := newTestProtocolManagerMust(t, true, 0, nil, peers, odr, ldb)
|
||||||
|
|
|
||||||
|
|
@ -87,8 +87,8 @@ func testAccess(t *testing.T, protocol int, fn accessTestFn) {
|
||||||
peers := newPeerSet()
|
peers := newPeerSet()
|
||||||
dist := newRequestDistributor(peers, make(chan struct{}))
|
dist := newRequestDistributor(peers, make(chan struct{}))
|
||||||
rm := newRetrieveManager(peers, dist, nil)
|
rm := newRetrieveManager(peers, dist, nil)
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db := ethdb.NewMemDatabase()
|
||||||
ldb, _ := ethdb.NewMemDatabase()
|
ldb := ethdb.NewMemDatabase()
|
||||||
odr := NewLesOdr(ldb, light.NewChtIndexer(db, true), light.NewBloomTrieIndexer(db, true), eth.NewBloomIndexer(db, light.BloomTrieFrequency), rm)
|
odr := NewLesOdr(ldb, light.NewChtIndexer(db, true), light.NewBloomTrieIndexer(db, true), eth.NewBloomIndexer(db, light.BloomTrieFrequency), rm)
|
||||||
|
|
||||||
pm := newTestProtocolManagerMust(t, false, 4, testChainGen, nil, nil, db)
|
pm := newTestProtocolManagerMust(t, false, 4, testChainGen, nil, nil, db)
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ func makeHeaderChain(parent *types.Header, n int, db ethdb.Database, seed int) [
|
||||||
// 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) (ethdb.Database, *LightChain, error) {
|
func newCanonical(n int) (ethdb.Database, *LightChain, error) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db := ethdb.NewMemDatabase()
|
||||||
gspec := core.Genesis{Config: params.TestChainConfig}
|
gspec := core.Genesis{Config: params.TestChainConfig}
|
||||||
genesis := gspec.MustCommit(db)
|
genesis := gspec.MustCommit(db)
|
||||||
blockchain, _ := NewLightChain(&dummyOdr{db: db}, gspec.Config, ethash.NewFaker())
|
blockchain, _ := NewLightChain(&dummyOdr{db: db}, gspec.Config, ethash.NewFaker())
|
||||||
|
|
@ -69,7 +69,7 @@ func newCanonical(n int) (ethdb.Database, *LightChain, error) {
|
||||||
|
|
||||||
// newTestLightChain creates a LightChain that doesn't validate anything.
|
// newTestLightChain creates a LightChain that doesn't validate anything.
|
||||||
func newTestLightChain() *LightChain {
|
func newTestLightChain() *LightChain {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db := ethdb.NewMemDatabase()
|
||||||
gspec := &core.Genesis{
|
gspec := &core.Genesis{
|
||||||
Difficulty: big.NewInt(1),
|
Difficulty: big.NewInt(1),
|
||||||
Config: params.TestChainConfig,
|
Config: params.TestChainConfig,
|
||||||
|
|
|
||||||
|
|
@ -245,8 +245,8 @@ func testChainGen(i int, block *core.BlockGen) {
|
||||||
|
|
||||||
func testChainOdr(t *testing.T, protocol int, fn odrTestFn) {
|
func testChainOdr(t *testing.T, protocol int, fn odrTestFn) {
|
||||||
var (
|
var (
|
||||||
sdb, _ = ethdb.NewMemDatabase()
|
sdb = ethdb.NewMemDatabase()
|
||||||
ldb, _ = ethdb.NewMemDatabase()
|
ldb = ethdb.NewMemDatabase()
|
||||||
gspec = core.Genesis{Alloc: core.GenesisAlloc{testBankAddress: {Balance: testBankFunds}}}
|
gspec = core.Genesis{Alloc: core.GenesisAlloc{testBankAddress: {Balance: testBankFunds}}}
|
||||||
genesis = gspec.MustCommit(sdb)
|
genesis = gspec.MustCommit(sdb)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -59,18 +59,18 @@ type trustedCheckpoint struct {
|
||||||
var (
|
var (
|
||||||
mainnetCheckpoint = trustedCheckpoint{
|
mainnetCheckpoint = trustedCheckpoint{
|
||||||
name: "mainnet",
|
name: "mainnet",
|
||||||
sectionIdx: 165,
|
sectionIdx: 170,
|
||||||
sectionHead: common.HexToHash("21028acf9cd9ce80257221adc437c3c58ce046c4d43c21c3e9b1d1349059ec73"),
|
sectionHead: common.HexToHash("3bb2c28bcce463d57968f14f56cdb3fbf35349ab7a701f44c1afb57349c9a356"),
|
||||||
chtRoot: common.HexToHash("26b2458cb7d0080d3a39311c914be92c368777a65ec074e1893b8bdc79e3910a"),
|
chtRoot: common.HexToHash("d92b6d0853455f8439086292338e87f69781921680dd7aa072fb71547b87415e"),
|
||||||
bloomTrieRoot: common.HexToHash("5d06908769179186165a72db7fc3473b25c28ed27efe78a392a9ff2c3fa67f84"),
|
bloomTrieRoot: common.HexToHash("e4e8250a2fefddead7ae42daecd848cbf9b66d748a8270f8bbd4370b764bb9e9"),
|
||||||
}
|
}
|
||||||
|
|
||||||
ropstenCheckpoint = trustedCheckpoint{
|
ropstenCheckpoint = trustedCheckpoint{
|
||||||
name: "ropsten",
|
name: "ropsten",
|
||||||
sectionIdx: 92,
|
sectionIdx: 97,
|
||||||
sectionHead: common.HexToHash("21a158f9cc643da13a237cafceb37381072649f7278cf98c5820bfbced7cfcec"),
|
sectionHead: common.HexToHash("719448c67c01eb5b9f27833a36a4e34612f66801316d7ff37daf9e77fb4cd095"),
|
||||||
chtRoot: common.HexToHash("1a8ddb8b086d7a33ca90eea90730225948fa504ae0283b15aff3c15c0e089bf9"),
|
chtRoot: common.HexToHash("a7857afc15930ca6e583b6c3d563a025144011655843d52d28e2fdaadd417bea"),
|
||||||
bloomTrieRoot: common.HexToHash("fd192f92afbcdd0020c81ca0625116b5995509659653b10123bd986fe5129cc1"),
|
bloomTrieRoot: common.HexToHash("9c71d4b50cbec86dfeaa8e08992de8a4667b81d13c54d6522b17ce2fc5d36416"),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,8 @@ import (
|
||||||
|
|
||||||
func TestNodeIterator(t *testing.T) {
|
func TestNodeIterator(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
fulldb, _ = ethdb.NewMemDatabase()
|
fulldb = ethdb.NewMemDatabase()
|
||||||
lightdb, _ = ethdb.NewMemDatabase()
|
lightdb = ethdb.NewMemDatabase()
|
||||||
gspec = core.Genesis{Alloc: core.GenesisAlloc{testBankAddress: {Balance: testBankFunds}}}
|
gspec = core.Genesis{Alloc: core.GenesisAlloc{testBankAddress: {Balance: testBankFunds}}}
|
||||||
genesis = gspec.MustCommit(fulldb)
|
genesis = gspec.MustCommit(fulldb)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -81,8 +81,8 @@ func TestTxPool(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
sdb, _ = ethdb.NewMemDatabase()
|
sdb = ethdb.NewMemDatabase()
|
||||||
ldb, _ = ethdb.NewMemDatabase()
|
ldb = ethdb.NewMemDatabase()
|
||||||
gspec = core.Genesis{Alloc: core.GenesisAlloc{testBankAddress: {Balance: testBankFunds}}}
|
gspec = core.Genesis{Alloc: core.GenesisAlloc{testBankAddress: {Balance: testBankFunds}}}
|
||||||
genesis = gspec.MustCommit(sdb)
|
genesis = gspec.MustCommit(sdb)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -568,7 +568,7 @@ func (n *Node) EventMux() *event.TypeMux {
|
||||||
// ephemeral, a memory database is returned.
|
// ephemeral, a memory database is returned.
|
||||||
func (n *Node) OpenDatabase(name string, cache, handles int) (ethdb.Database, error) {
|
func (n *Node) OpenDatabase(name string, cache, handles int) (ethdb.Database, error) {
|
||||||
if n.config.DataDir == "" {
|
if n.config.DataDir == "" {
|
||||||
return ethdb.NewMemDatabase()
|
return ethdb.NewMemDatabase(), nil
|
||||||
}
|
}
|
||||||
return ethdb.NewLDBDatabase(n.config.resolvePath(name), cache, handles)
|
return ethdb.NewLDBDatabase(n.config.resolvePath(name), cache, handles)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ type ServiceContext struct {
|
||||||
// node is an ephemeral one, a memory database is returned.
|
// node is an ephemeral one, a memory database is returned.
|
||||||
func (ctx *ServiceContext) OpenDatabase(name string, cache int, handles int) (ethdb.Database, error) {
|
func (ctx *ServiceContext) OpenDatabase(name string, cache int, handles int) (ethdb.Database, error) {
|
||||||
if ctx.config.DataDir == "" {
|
if ctx.config.DataDir == "" {
|
||||||
return ethdb.NewMemDatabase()
|
return ethdb.NewMemDatabase(), nil
|
||||||
}
|
}
|
||||||
db, err := ethdb.NewLDBDatabase(ctx.config.resolvePath(name), cache, handles)
|
db, err := ethdb.NewLDBDatabase(ctx.config.resolvePath(name), cache, handles)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -582,26 +582,26 @@ func (*preminedTestnet) ping(toid NodeID, toaddr *net.UDPAddr) error { return ni
|
||||||
|
|
||||||
// mine generates a testnet struct literal with nodes at
|
// mine generates a testnet struct literal with nodes at
|
||||||
// various distances to the given target.
|
// various distances to the given target.
|
||||||
func (n *preminedTestnet) mine(target NodeID) {
|
func (tn *preminedTestnet) mine(target NodeID) {
|
||||||
n.target = target
|
tn.target = target
|
||||||
n.targetSha = crypto.Keccak256Hash(n.target[:])
|
tn.targetSha = crypto.Keccak256Hash(tn.target[:])
|
||||||
found := 0
|
found := 0
|
||||||
for found < bucketSize*10 {
|
for found < bucketSize*10 {
|
||||||
k := newkey()
|
k := newkey()
|
||||||
id := PubkeyID(&k.PublicKey)
|
id := PubkeyID(&k.PublicKey)
|
||||||
sha := crypto.Keccak256Hash(id[:])
|
sha := crypto.Keccak256Hash(id[:])
|
||||||
ld := logdist(n.targetSha, sha)
|
ld := logdist(tn.targetSha, sha)
|
||||||
if len(n.dists[ld]) < bucketSize {
|
if len(tn.dists[ld]) < bucketSize {
|
||||||
n.dists[ld] = append(n.dists[ld], id)
|
tn.dists[ld] = append(tn.dists[ld], id)
|
||||||
fmt.Println("found ID with ld", ld)
|
fmt.Println("found ID with ld", ld)
|
||||||
found++
|
found++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Println("&preminedTestnet{")
|
fmt.Println("&preminedTestnet{")
|
||||||
fmt.Printf(" target: %#v,\n", n.target)
|
fmt.Printf(" target: %#v,\n", tn.target)
|
||||||
fmt.Printf(" targetSha: %#v,\n", n.targetSha)
|
fmt.Printf(" targetSha: %#v,\n", tn.targetSha)
|
||||||
fmt.Printf(" dists: [%d][]NodeID{\n", len(n.dists))
|
fmt.Printf(" dists: [%d][]NodeID{\n", len(tn.dists))
|
||||||
for ld, ns := range n.dists {
|
for ld, ns := range tn.dists {
|
||||||
if len(ns) == 0 {
|
if len(ns) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -336,26 +336,26 @@ func (*preminedTestnet) localAddr() *net.UDPAddr {
|
||||||
|
|
||||||
// mine generates a testnet struct literal with nodes at
|
// mine generates a testnet struct literal with nodes at
|
||||||
// various distances to the given target.
|
// various distances to the given target.
|
||||||
func (n *preminedTestnet) mine(target NodeID) {
|
func (tn *preminedTestnet) mine(target NodeID) {
|
||||||
n.target = target
|
tn.target = target
|
||||||
n.targetSha = crypto.Keccak256Hash(n.target[:])
|
tn.targetSha = crypto.Keccak256Hash(tn.target[:])
|
||||||
found := 0
|
found := 0
|
||||||
for found < bucketSize*10 {
|
for found < bucketSize*10 {
|
||||||
k := newkey()
|
k := newkey()
|
||||||
id := PubkeyID(&k.PublicKey)
|
id := PubkeyID(&k.PublicKey)
|
||||||
sha := crypto.Keccak256Hash(id[:])
|
sha := crypto.Keccak256Hash(id[:])
|
||||||
ld := logdist(n.targetSha, sha)
|
ld := logdist(tn.targetSha, sha)
|
||||||
if len(n.dists[ld]) < bucketSize {
|
if len(tn.dists[ld]) < bucketSize {
|
||||||
n.dists[ld] = append(n.dists[ld], id)
|
tn.dists[ld] = append(tn.dists[ld], id)
|
||||||
fmt.Println("found ID with ld", ld)
|
fmt.Println("found ID with ld", ld)
|
||||||
found++
|
found++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Println("&preminedTestnet{")
|
fmt.Println("&preminedTestnet{")
|
||||||
fmt.Printf(" target: %#v,\n", n.target)
|
fmt.Printf(" target: %#v,\n", tn.target)
|
||||||
fmt.Printf(" targetSha: %#v,\n", n.targetSha)
|
fmt.Printf(" targetSha: %#v,\n", tn.targetSha)
|
||||||
fmt.Printf(" dists: [%d][]NodeID{\n", len(n.dists))
|
fmt.Printf(" dists: [%d][]NodeID{\n", len(tn.dists))
|
||||||
for ld, ns := range n.dists {
|
for ld, ns := range tn.dists {
|
||||||
if len(ns) == 0 {
|
if len(ns) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -315,11 +315,11 @@ func PubkeyID(pub *ecdsa.PublicKey) NodeID {
|
||||||
|
|
||||||
// Pubkey returns the public key represented by the node ID.
|
// Pubkey returns the public key represented by the node ID.
|
||||||
// It returns an error if the ID is not a point on the curve.
|
// It returns an error if the ID is not a point on the curve.
|
||||||
func (id NodeID) Pubkey() (*ecdsa.PublicKey, error) {
|
func (n NodeID) Pubkey() (*ecdsa.PublicKey, error) {
|
||||||
p := &ecdsa.PublicKey{Curve: crypto.S256(), X: new(big.Int), Y: new(big.Int)}
|
p := &ecdsa.PublicKey{Curve: crypto.S256(), X: new(big.Int), Y: new(big.Int)}
|
||||||
half := len(id) / 2
|
half := len(n) / 2
|
||||||
p.X.SetBytes(id[:half])
|
p.X.SetBytes(n[:half])
|
||||||
p.Y.SetBytes(id[half:])
|
p.Y.SetBytes(n[half:])
|
||||||
if !p.Curve.IsOnCurve(p.X, p.Y) {
|
if !p.Curve.IsOnCurve(p.X, p.Y) {
|
||||||
return nil, errors.New("id is invalid secp256k1 curve point")
|
return nil, errors.New("id is invalid secp256k1 curve point")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -304,8 +304,8 @@ func (s ticketRefByWaitTime) Len() int {
|
||||||
return len(s)
|
return len(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r ticketRef) waitTime() mclock.AbsTime {
|
func (ref ticketRef) waitTime() mclock.AbsTime {
|
||||||
return r.t.regTime[r.idx] - r.t.issueTime
|
return ref.t.regTime[ref.idx] - ref.t.issueTime
|
||||||
}
|
}
|
||||||
|
|
||||||
// Less reports whether the element with
|
// Less reports whether the element with
|
||||||
|
|
|
||||||
|
|
@ -271,15 +271,15 @@ func (t *topicTable) useTicket(node *Node, serialNo uint32, topics []Topic, idx
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (topictab *topicTable) getTicket(node *Node, topics []Topic) *ticket {
|
func (t *topicTable) getTicket(node *Node, topics []Topic) *ticket {
|
||||||
topictab.collectGarbage()
|
t.collectGarbage()
|
||||||
|
|
||||||
now := mclock.Now()
|
now := mclock.Now()
|
||||||
n := topictab.getOrNewNode(node)
|
n := t.getOrNewNode(node)
|
||||||
n.lastIssuedTicket++
|
n.lastIssuedTicket++
|
||||||
topictab.storeTicketCounters(node)
|
t.storeTicketCounters(node)
|
||||||
|
|
||||||
t := &ticket{
|
tic := &ticket{
|
||||||
issueTime: now,
|
issueTime: now,
|
||||||
topics: topics,
|
topics: topics,
|
||||||
serial: n.lastIssuedTicket,
|
serial: n.lastIssuedTicket,
|
||||||
|
|
@ -287,15 +287,15 @@ func (topictab *topicTable) getTicket(node *Node, topics []Topic) *ticket {
|
||||||
}
|
}
|
||||||
for i, topic := range topics {
|
for i, topic := range topics {
|
||||||
var waitPeriod time.Duration
|
var waitPeriod time.Duration
|
||||||
if topic := topictab.topics[topic]; topic != nil {
|
if topic := t.topics[topic]; topic != nil {
|
||||||
waitPeriod = topic.wcl.waitPeriod
|
waitPeriod = topic.wcl.waitPeriod
|
||||||
} else {
|
} else {
|
||||||
waitPeriod = minWaitPeriod
|
waitPeriod = minWaitPeriod
|
||||||
}
|
}
|
||||||
|
|
||||||
t.regTime[i] = now + mclock.AbsTime(waitPeriod)
|
tic.regTime[i] = now + mclock.AbsTime(waitPeriod)
|
||||||
}
|
}
|
||||||
return t
|
return tic
|
||||||
}
|
}
|
||||||
|
|
||||||
const gcInterval = time.Minute
|
const gcInterval = time.Minute
|
||||||
|
|
|
||||||
|
|
@ -270,15 +270,15 @@ func newMsgEventer(rw MsgReadWriter, feed *event.Feed, peerID discover.NodeID, p
|
||||||
|
|
||||||
// ReadMsg reads a message from the underlying MsgReadWriter and emits a
|
// ReadMsg reads a message from the underlying MsgReadWriter and emits a
|
||||||
// "message received" event
|
// "message received" event
|
||||||
func (self *msgEventer) ReadMsg() (Msg, error) {
|
func (ev *msgEventer) ReadMsg() (Msg, error) {
|
||||||
msg, err := self.MsgReadWriter.ReadMsg()
|
msg, err := ev.MsgReadWriter.ReadMsg()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return msg, err
|
return msg, err
|
||||||
}
|
}
|
||||||
self.feed.Send(&PeerEvent{
|
ev.feed.Send(&PeerEvent{
|
||||||
Type: PeerEventTypeMsgRecv,
|
Type: PeerEventTypeMsgRecv,
|
||||||
Peer: self.peerID,
|
Peer: ev.peerID,
|
||||||
Protocol: self.Protocol,
|
Protocol: ev.Protocol,
|
||||||
MsgCode: &msg.Code,
|
MsgCode: &msg.Code,
|
||||||
MsgSize: &msg.Size,
|
MsgSize: &msg.Size,
|
||||||
})
|
})
|
||||||
|
|
@ -287,15 +287,15 @@ func (self *msgEventer) ReadMsg() (Msg, error) {
|
||||||
|
|
||||||
// WriteMsg writes a message to the underlying MsgReadWriter and emits a
|
// WriteMsg writes a message to the underlying MsgReadWriter and emits a
|
||||||
// "message sent" event
|
// "message sent" event
|
||||||
func (self *msgEventer) WriteMsg(msg Msg) error {
|
func (ev *msgEventer) WriteMsg(msg Msg) error {
|
||||||
err := self.MsgReadWriter.WriteMsg(msg)
|
err := ev.MsgReadWriter.WriteMsg(msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
self.feed.Send(&PeerEvent{
|
ev.feed.Send(&PeerEvent{
|
||||||
Type: PeerEventTypeMsgSend,
|
Type: PeerEventTypeMsgSend,
|
||||||
Peer: self.peerID,
|
Peer: ev.peerID,
|
||||||
Protocol: self.Protocol,
|
Protocol: ev.Protocol,
|
||||||
MsgCode: &msg.Code,
|
MsgCode: &msg.Code,
|
||||||
MsgSize: &msg.Size,
|
MsgSize: &msg.Size,
|
||||||
})
|
})
|
||||||
|
|
@ -304,8 +304,8 @@ func (self *msgEventer) WriteMsg(msg Msg) error {
|
||||||
|
|
||||||
// Close closes the underlying MsgReadWriter if it implements the io.Closer
|
// Close closes the underlying MsgReadWriter if it implements the io.Closer
|
||||||
// interface
|
// interface
|
||||||
func (self *msgEventer) Close() error {
|
func (ev *msgEventer) Close() error {
|
||||||
if v, ok := self.MsgReadWriter.(io.Closer); ok {
|
if v, ok := ev.MsgReadWriter.(io.Closer); ok {
|
||||||
return v.Close()
|
return v.Close()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -220,6 +220,7 @@ loop:
|
||||||
reason = discReasonForError(err)
|
reason = discReasonForError(err)
|
||||||
break loop
|
break loop
|
||||||
case err = <-p.disc:
|
case err = <-p.disc:
|
||||||
|
reason = discReasonForError(err)
|
||||||
break loop
|
break loop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,8 +48,8 @@ func newPeerError(code int, format string, v ...interface{}) *peerError {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *peerError) Error() string {
|
func (pe *peerError) Error() string {
|
||||||
return self.message
|
return pe.message
|
||||||
}
|
}
|
||||||
|
|
||||||
var errProtocolReturned = errors.New("protocol returned")
|
var errProtocolReturned = errors.New("protocol returned")
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@
|
||||||
package adapters
|
package adapters
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"context"
|
"context"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
@ -29,7 +28,6 @@ import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
@ -150,10 +148,6 @@ func (n *ExecNode) Client() (*rpc.Client, error) {
|
||||||
return n.client, nil
|
return n.client, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// wsAddrPattern is a regex used to read the WebSocket address from the node's
|
|
||||||
// log
|
|
||||||
var wsAddrPattern = regexp.MustCompile(`ws://[\d.:]+`)
|
|
||||||
|
|
||||||
// Start exec's the node passing the ID and service as command line arguments
|
// Start exec's the node passing the ID and service as command line arguments
|
||||||
// and the node config encoded as JSON in the _P2P_NODE_CONFIG environment
|
// and the node config encoded as JSON in the _P2P_NODE_CONFIG environment
|
||||||
// variable
|
// variable
|
||||||
|
|
@ -196,23 +190,9 @@ func (n *ExecNode) Start(snapshots map[string][]byte) (err error) {
|
||||||
n.Cmd = cmd
|
n.Cmd = cmd
|
||||||
|
|
||||||
// read the WebSocket address from the stderr logs
|
// read the WebSocket address from the stderr logs
|
||||||
var wsAddr string
|
wsAddr, err := findWSAddr(stderrR, 10*time.Second)
|
||||||
wsAddrC := make(chan string)
|
if err != nil {
|
||||||
go func() {
|
return fmt.Errorf("error getting WebSocket address: %s", err)
|
||||||
s := bufio.NewScanner(stderrR)
|
|
||||||
for s.Scan() {
|
|
||||||
if strings.Contains(s.Text(), "WebSocket endpoint opened:") {
|
|
||||||
wsAddrC <- wsAddrPattern.FindString(s.Text())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
select {
|
|
||||||
case wsAddr = <-wsAddrC:
|
|
||||||
if wsAddr == "" {
|
|
||||||
return errors.New("failed to read WebSocket address from stderr")
|
|
||||||
}
|
|
||||||
case <-time.After(10 * time.Second):
|
|
||||||
return errors.New("timed out waiting for WebSocket address on stderr")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the RPC client and load the node info
|
// create the RPC client and load the node info
|
||||||
|
|
|
||||||
|
|
@ -154,30 +154,30 @@ type SimNode struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Addr returns the node's discovery address
|
// Addr returns the node's discovery address
|
||||||
func (self *SimNode) Addr() []byte {
|
func (sn *SimNode) Addr() []byte {
|
||||||
return []byte(self.Node().String())
|
return []byte(sn.Node().String())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Node returns a discover.Node representing the SimNode
|
// Node returns a discover.Node representing the SimNode
|
||||||
func (self *SimNode) Node() *discover.Node {
|
func (sn *SimNode) Node() *discover.Node {
|
||||||
return discover.NewNode(self.ID, net.IP{127, 0, 0, 1}, 30303, 30303)
|
return discover.NewNode(sn.ID, net.IP{127, 0, 0, 1}, 30303, 30303)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Client returns an rpc.Client which can be used to communicate with the
|
// Client returns an rpc.Client which can be used to communicate with the
|
||||||
// underlying services (it is set once the node has started)
|
// underlying services (it is set once the node has started)
|
||||||
func (self *SimNode) Client() (*rpc.Client, error) {
|
func (sn *SimNode) Client() (*rpc.Client, error) {
|
||||||
self.lock.RLock()
|
sn.lock.RLock()
|
||||||
defer self.lock.RUnlock()
|
defer sn.lock.RUnlock()
|
||||||
if self.client == nil {
|
if sn.client == nil {
|
||||||
return nil, errors.New("node not started")
|
return nil, errors.New("node not started")
|
||||||
}
|
}
|
||||||
return self.client, nil
|
return sn.client, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServeRPC serves RPC requests over the given connection by creating an
|
// ServeRPC serves RPC requests over the given connection by creating an
|
||||||
// in-memory client to the node's RPC server
|
// in-memory client to the node's RPC server
|
||||||
func (self *SimNode) ServeRPC(conn net.Conn) error {
|
func (sn *SimNode) ServeRPC(conn net.Conn) error {
|
||||||
handler, err := self.node.RPCHandler()
|
handler, err := sn.node.RPCHandler()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -187,13 +187,13 @@ func (self *SimNode) ServeRPC(conn net.Conn) error {
|
||||||
|
|
||||||
// Snapshots creates snapshots of the services by calling the
|
// Snapshots creates snapshots of the services by calling the
|
||||||
// simulation_snapshot RPC method
|
// simulation_snapshot RPC method
|
||||||
func (self *SimNode) Snapshots() (map[string][]byte, error) {
|
func (sn *SimNode) Snapshots() (map[string][]byte, error) {
|
||||||
self.lock.RLock()
|
sn.lock.RLock()
|
||||||
services := make(map[string]node.Service, len(self.running))
|
services := make(map[string]node.Service, len(sn.running))
|
||||||
for name, service := range self.running {
|
for name, service := range sn.running {
|
||||||
services[name] = service
|
services[name] = service
|
||||||
}
|
}
|
||||||
self.lock.RUnlock()
|
sn.lock.RUnlock()
|
||||||
if len(services) == 0 {
|
if len(services) == 0 {
|
||||||
return nil, errors.New("no running services")
|
return nil, errors.New("no running services")
|
||||||
}
|
}
|
||||||
|
|
@ -213,23 +213,23 @@ func (self *SimNode) Snapshots() (map[string][]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start registers the services and starts the underlying devp2p node
|
// Start registers the services and starts the underlying devp2p node
|
||||||
func (self *SimNode) Start(snapshots map[string][]byte) error {
|
func (sn *SimNode) Start(snapshots map[string][]byte) error {
|
||||||
newService := func(name string) func(ctx *node.ServiceContext) (node.Service, error) {
|
newService := func(name string) func(ctx *node.ServiceContext) (node.Service, error) {
|
||||||
return func(nodeCtx *node.ServiceContext) (node.Service, error) {
|
return func(nodeCtx *node.ServiceContext) (node.Service, error) {
|
||||||
ctx := &ServiceContext{
|
ctx := &ServiceContext{
|
||||||
RPCDialer: self.adapter,
|
RPCDialer: sn.adapter,
|
||||||
NodeContext: nodeCtx,
|
NodeContext: nodeCtx,
|
||||||
Config: self.config,
|
Config: sn.config,
|
||||||
}
|
}
|
||||||
if snapshots != nil {
|
if snapshots != nil {
|
||||||
ctx.Snapshot = snapshots[name]
|
ctx.Snapshot = snapshots[name]
|
||||||
}
|
}
|
||||||
serviceFunc := self.adapter.services[name]
|
serviceFunc := sn.adapter.services[name]
|
||||||
service, err := serviceFunc(ctx)
|
service, err := serviceFunc(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
self.running[name] = service
|
sn.running[name] = service
|
||||||
return service, nil
|
return service, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -237,9 +237,9 @@ func (self *SimNode) Start(snapshots map[string][]byte) error {
|
||||||
// ensure we only register the services once in the case of the node
|
// ensure we only register the services once in the case of the node
|
||||||
// being stopped and then started again
|
// being stopped and then started again
|
||||||
var regErr error
|
var regErr error
|
||||||
self.registerOnce.Do(func() {
|
sn.registerOnce.Do(func() {
|
||||||
for _, name := range self.config.Services {
|
for _, name := range sn.config.Services {
|
||||||
if err := self.node.Register(newService(name)); err != nil {
|
if err := sn.node.Register(newService(name)); err != nil {
|
||||||
regErr = err
|
regErr = err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -249,54 +249,54 @@ func (self *SimNode) Start(snapshots map[string][]byte) error {
|
||||||
return regErr
|
return regErr
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := self.node.Start(); err != nil {
|
if err := sn.node.Start(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// create an in-process RPC client
|
// create an in-process RPC client
|
||||||
handler, err := self.node.RPCHandler()
|
handler, err := sn.node.RPCHandler()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
self.lock.Lock()
|
sn.lock.Lock()
|
||||||
self.client = rpc.DialInProc(handler)
|
sn.client = rpc.DialInProc(handler)
|
||||||
self.lock.Unlock()
|
sn.lock.Unlock()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop closes the RPC client and stops the underlying devp2p node
|
// Stop closes the RPC client and stops the underlying devp2p node
|
||||||
func (self *SimNode) Stop() error {
|
func (sn *SimNode) Stop() error {
|
||||||
self.lock.Lock()
|
sn.lock.Lock()
|
||||||
if self.client != nil {
|
if sn.client != nil {
|
||||||
self.client.Close()
|
sn.client.Close()
|
||||||
self.client = nil
|
sn.client = nil
|
||||||
}
|
}
|
||||||
self.lock.Unlock()
|
sn.lock.Unlock()
|
||||||
return self.node.Stop()
|
return sn.node.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Services returns a copy of the underlying services
|
// Services returns a copy of the underlying services
|
||||||
func (self *SimNode) Services() []node.Service {
|
func (sn *SimNode) Services() []node.Service {
|
||||||
self.lock.RLock()
|
sn.lock.RLock()
|
||||||
defer self.lock.RUnlock()
|
defer sn.lock.RUnlock()
|
||||||
services := make([]node.Service, 0, len(self.running))
|
services := make([]node.Service, 0, len(sn.running))
|
||||||
for _, service := range self.running {
|
for _, service := range sn.running {
|
||||||
services = append(services, service)
|
services = append(services, service)
|
||||||
}
|
}
|
||||||
return services
|
return services
|
||||||
}
|
}
|
||||||
|
|
||||||
// Server returns the underlying p2p.Server
|
// Server returns the underlying p2p.Server
|
||||||
func (self *SimNode) Server() *p2p.Server {
|
func (sn *SimNode) Server() *p2p.Server {
|
||||||
return self.node.Server()
|
return sn.node.Server()
|
||||||
}
|
}
|
||||||
|
|
||||||
// SubscribeEvents subscribes the given channel to peer events from the
|
// SubscribeEvents subscribes the given channel to peer events from the
|
||||||
// underlying p2p.Server
|
// underlying p2p.Server
|
||||||
func (self *SimNode) SubscribeEvents(ch chan *p2p.PeerEvent) event.Subscription {
|
func (sn *SimNode) SubscribeEvents(ch chan *p2p.PeerEvent) event.Subscription {
|
||||||
srv := self.Server()
|
srv := sn.Server()
|
||||||
if srv == nil {
|
if srv == nil {
|
||||||
panic("node not running")
|
panic("node not running")
|
||||||
}
|
}
|
||||||
|
|
@ -304,12 +304,12 @@ func (self *SimNode) SubscribeEvents(ch chan *p2p.PeerEvent) event.Subscription
|
||||||
}
|
}
|
||||||
|
|
||||||
// NodeInfo returns information about the node
|
// NodeInfo returns information about the node
|
||||||
func (self *SimNode) NodeInfo() *p2p.NodeInfo {
|
func (sn *SimNode) NodeInfo() *p2p.NodeInfo {
|
||||||
server := self.Server()
|
server := sn.Server()
|
||||||
if server == nil {
|
if server == nil {
|
||||||
return &p2p.NodeInfo{
|
return &p2p.NodeInfo{
|
||||||
ID: self.ID.String(),
|
ID: sn.ID.String(),
|
||||||
Enode: self.Node().String(),
|
Enode: sn.Node().String(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return server.NodeInfo()
|
return server.NodeInfo()
|
||||||
|
|
|
||||||
|
|
@ -20,12 +20,12 @@ type SimStateStore struct {
|
||||||
m map[string][]byte
|
m map[string][]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *SimStateStore) Load(s string) ([]byte, error) {
|
func (st *SimStateStore) Load(s string) ([]byte, error) {
|
||||||
return self.m[s], nil
|
return st.m[s], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *SimStateStore) Save(s string, data []byte) error {
|
func (st *SimStateStore) Save(s string, data []byte) error {
|
||||||
self.m[s] = data
|
st.m[s] = data
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
51
p2p/simulations/adapters/ws.go
Normal file
51
p2p/simulations/adapters/ws.go
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
package adapters
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// wsAddrPattern is a regex used to read the WebSocket address from the node's
|
||||||
|
// log
|
||||||
|
var wsAddrPattern = regexp.MustCompile(`ws://[\d.:]+`)
|
||||||
|
|
||||||
|
func matchWSAddr(str string) (string, bool) {
|
||||||
|
if !strings.Contains(str, "WebSocket endpoint opened") {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
|
||||||
|
return wsAddrPattern.FindString(str), true
|
||||||
|
}
|
||||||
|
|
||||||
|
// findWSAddr scans through reader r, looking for the log entry with
|
||||||
|
// WebSocket address information.
|
||||||
|
func findWSAddr(r io.Reader, timeout time.Duration) (string, error) {
|
||||||
|
ch := make(chan string)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
s := bufio.NewScanner(r)
|
||||||
|
for s.Scan() {
|
||||||
|
addr, ok := matchWSAddr(s.Text())
|
||||||
|
if ok {
|
||||||
|
ch <- addr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(ch)
|
||||||
|
}()
|
||||||
|
|
||||||
|
var wsAddr string
|
||||||
|
select {
|
||||||
|
case wsAddr = <-ch:
|
||||||
|
if wsAddr == "" {
|
||||||
|
return "", errors.New("empty result")
|
||||||
|
}
|
||||||
|
case <-time.After(timeout):
|
||||||
|
return "", errors.New("timed out")
|
||||||
|
}
|
||||||
|
|
||||||
|
return wsAddr, nil
|
||||||
|
}
|
||||||
21
p2p/simulations/adapters/ws_test.go
Normal file
21
p2p/simulations/adapters/ws_test.go
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
package adapters
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFindWSAddr(t *testing.T) {
|
||||||
|
line := `t=2018-05-02T19:00:45+0200 lvl=info msg="WebSocket endpoint opened" node.id=26c65a606d1125a44695bc08573190d047152b6b9a776ccbbe593e90f91444d9c1ebdadac6a775ad9fdd0923468a1d698ed3a842c1fb89c1bc0f9d4801f8c39c url=ws://127.0.0.1:59975`
|
||||||
|
buf := bytes.NewBufferString(line)
|
||||||
|
got, err := findWSAddr(buf, 10*time.Second)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to find addr: %v", err)
|
||||||
|
}
|
||||||
|
expected := `ws://127.0.0.1:59975`
|
||||||
|
|
||||||
|
if got != expected {
|
||||||
|
t.Fatalf("Expected to get '%s', but got '%s'", expected, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -74,22 +74,22 @@ func NewNetwork(nodeAdapter adapters.NodeAdapter, conf *NetworkConfig) *Network
|
||||||
}
|
}
|
||||||
|
|
||||||
// Events returns the output event feed of the Network.
|
// Events returns the output event feed of the Network.
|
||||||
func (self *Network) Events() *event.Feed {
|
func (net *Network) Events() *event.Feed {
|
||||||
return &self.events
|
return &net.events
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewNode adds a new node to the network with a random ID
|
// NewNode adds a new node to the network with a random ID
|
||||||
func (self *Network) NewNode() (*Node, error) {
|
func (net *Network) NewNode() (*Node, error) {
|
||||||
conf := adapters.RandomNodeConfig()
|
conf := adapters.RandomNodeConfig()
|
||||||
conf.Services = []string{self.DefaultService}
|
conf.Services = []string{net.DefaultService}
|
||||||
return self.NewNodeWithConfig(conf)
|
return net.NewNodeWithConfig(conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewNodeWithConfig adds a new node to the network with the given config,
|
// NewNodeWithConfig adds a new node to the network with the given config,
|
||||||
// returning an error if a node with the same ID or name already exists
|
// returning an error if a node with the same ID or name already exists
|
||||||
func (self *Network) NewNodeWithConfig(conf *adapters.NodeConfig) (*Node, error) {
|
func (net *Network) NewNodeWithConfig(conf *adapters.NodeConfig) (*Node, error) {
|
||||||
self.lock.Lock()
|
net.lock.Lock()
|
||||||
defer self.lock.Unlock()
|
defer net.lock.Unlock()
|
||||||
|
|
||||||
// create a random ID and PrivateKey if not set
|
// create a random ID and PrivateKey if not set
|
||||||
if conf.ID == (discover.NodeID{}) {
|
if conf.ID == (discover.NodeID{}) {
|
||||||
|
|
@ -100,31 +100,31 @@ func (self *Network) NewNodeWithConfig(conf *adapters.NodeConfig) (*Node, error)
|
||||||
id := conf.ID
|
id := conf.ID
|
||||||
if conf.Reachable == nil {
|
if conf.Reachable == nil {
|
||||||
conf.Reachable = func(otherID discover.NodeID) bool {
|
conf.Reachable = func(otherID discover.NodeID) bool {
|
||||||
_, err := self.InitConn(conf.ID, otherID)
|
_, err := net.InitConn(conf.ID, otherID)
|
||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// assign a name to the node if not set
|
// assign a name to the node if not set
|
||||||
if conf.Name == "" {
|
if conf.Name == "" {
|
||||||
conf.Name = fmt.Sprintf("node%02d", len(self.Nodes)+1)
|
conf.Name = fmt.Sprintf("node%02d", len(net.Nodes)+1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the node doesn't already exist
|
// check the node doesn't already exist
|
||||||
if node := self.getNode(id); node != nil {
|
if node := net.getNode(id); node != nil {
|
||||||
return nil, fmt.Errorf("node with ID %q already exists", id)
|
return nil, fmt.Errorf("node with ID %q already exists", id)
|
||||||
}
|
}
|
||||||
if node := self.getNodeByName(conf.Name); node != nil {
|
if node := net.getNodeByName(conf.Name); node != nil {
|
||||||
return nil, fmt.Errorf("node with name %q already exists", conf.Name)
|
return nil, fmt.Errorf("node with name %q already exists", conf.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if no services are configured, use the default service
|
// if no services are configured, use the default service
|
||||||
if len(conf.Services) == 0 {
|
if len(conf.Services) == 0 {
|
||||||
conf.Services = []string{self.DefaultService}
|
conf.Services = []string{net.DefaultService}
|
||||||
}
|
}
|
||||||
|
|
||||||
// use the NodeAdapter to create the node
|
// use the NodeAdapter to create the node
|
||||||
adapterNode, err := self.nodeAdapter.NewNode(conf)
|
adapterNode, err := net.nodeAdapter.NewNode(conf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -133,27 +133,27 @@ func (self *Network) NewNodeWithConfig(conf *adapters.NodeConfig) (*Node, error)
|
||||||
Config: conf,
|
Config: conf,
|
||||||
}
|
}
|
||||||
log.Trace(fmt.Sprintf("node %v created", id))
|
log.Trace(fmt.Sprintf("node %v created", id))
|
||||||
self.nodeMap[id] = len(self.Nodes)
|
net.nodeMap[id] = len(net.Nodes)
|
||||||
self.Nodes = append(self.Nodes, node)
|
net.Nodes = append(net.Nodes, node)
|
||||||
|
|
||||||
// emit a "control" event
|
// emit a "control" event
|
||||||
self.events.Send(ControlEvent(node))
|
net.events.Send(ControlEvent(node))
|
||||||
|
|
||||||
return node, nil
|
return node, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config returns the network configuration
|
// Config returns the network configuration
|
||||||
func (self *Network) Config() *NetworkConfig {
|
func (net *Network) Config() *NetworkConfig {
|
||||||
return &self.NetworkConfig
|
return &net.NetworkConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
// StartAll starts all nodes in the network
|
// StartAll starts all nodes in the network
|
||||||
func (self *Network) StartAll() error {
|
func (net *Network) StartAll() error {
|
||||||
for _, node := range self.Nodes {
|
for _, node := range net.Nodes {
|
||||||
if node.Up {
|
if node.Up {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err := self.Start(node.ID()); err != nil {
|
if err := net.Start(node.ID()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -161,12 +161,12 @@ func (self *Network) StartAll() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// StopAll stops all nodes in the network
|
// StopAll stops all nodes in the network
|
||||||
func (self *Network) StopAll() error {
|
func (net *Network) StopAll() error {
|
||||||
for _, node := range self.Nodes {
|
for _, node := range net.Nodes {
|
||||||
if !node.Up {
|
if !node.Up {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err := self.Stop(node.ID()); err != nil {
|
if err := net.Stop(node.ID()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -174,21 +174,21 @@ func (self *Network) StopAll() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start starts the node with the given ID
|
// Start starts the node with the given ID
|
||||||
func (self *Network) Start(id discover.NodeID) error {
|
func (net *Network) Start(id discover.NodeID) error {
|
||||||
return self.startWithSnapshots(id, nil)
|
return net.startWithSnapshots(id, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// startWithSnapshots starts the node with the given ID using the give
|
// startWithSnapshots starts the node with the given ID using the give
|
||||||
// snapshots
|
// snapshots
|
||||||
func (self *Network) startWithSnapshots(id discover.NodeID, snapshots map[string][]byte) error {
|
func (net *Network) startWithSnapshots(id discover.NodeID, snapshots map[string][]byte) error {
|
||||||
node := self.GetNode(id)
|
node := net.GetNode(id)
|
||||||
if node == nil {
|
if node == nil {
|
||||||
return fmt.Errorf("node %v does not exist", id)
|
return fmt.Errorf("node %v does not exist", id)
|
||||||
}
|
}
|
||||||
if node.Up {
|
if node.Up {
|
||||||
return fmt.Errorf("node %v already up", id)
|
return fmt.Errorf("node %v already up", id)
|
||||||
}
|
}
|
||||||
log.Trace(fmt.Sprintf("starting node %v: %v using %v", id, node.Up, self.nodeAdapter.Name()))
|
log.Trace(fmt.Sprintf("starting node %v: %v using %v", id, node.Up, net.nodeAdapter.Name()))
|
||||||
if err := node.Start(snapshots); err != nil {
|
if err := node.Start(snapshots); err != nil {
|
||||||
log.Warn(fmt.Sprintf("start up failed: %v", err))
|
log.Warn(fmt.Sprintf("start up failed: %v", err))
|
||||||
return err
|
return err
|
||||||
|
|
@ -196,7 +196,7 @@ func (self *Network) startWithSnapshots(id discover.NodeID, snapshots map[string
|
||||||
node.Up = true
|
node.Up = true
|
||||||
log.Info(fmt.Sprintf("started node %v: %v", id, node.Up))
|
log.Info(fmt.Sprintf("started node %v: %v", id, node.Up))
|
||||||
|
|
||||||
self.events.Send(NewEvent(node))
|
net.events.Send(NewEvent(node))
|
||||||
|
|
||||||
// subscribe to peer events
|
// subscribe to peer events
|
||||||
client, err := node.Client()
|
client, err := node.Client()
|
||||||
|
|
@ -208,22 +208,22 @@ func (self *Network) startWithSnapshots(id discover.NodeID, snapshots map[string
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error getting peer events for node %v: %s", id, err)
|
return fmt.Errorf("error getting peer events for node %v: %s", id, err)
|
||||||
}
|
}
|
||||||
go self.watchPeerEvents(id, events, sub)
|
go net.watchPeerEvents(id, events, sub)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// watchPeerEvents reads peer events from the given channel and emits
|
// watchPeerEvents reads peer events from the given channel and emits
|
||||||
// corresponding network events
|
// corresponding network events
|
||||||
func (self *Network) watchPeerEvents(id discover.NodeID, events chan *p2p.PeerEvent, sub event.Subscription) {
|
func (net *Network) watchPeerEvents(id discover.NodeID, events chan *p2p.PeerEvent, sub event.Subscription) {
|
||||||
defer func() {
|
defer func() {
|
||||||
sub.Unsubscribe()
|
sub.Unsubscribe()
|
||||||
|
|
||||||
// assume the node is now down
|
// assume the node is now down
|
||||||
self.lock.Lock()
|
net.lock.Lock()
|
||||||
node := self.getNode(id)
|
node := net.getNode(id)
|
||||||
node.Up = false
|
node.Up = false
|
||||||
self.lock.Unlock()
|
net.lock.Unlock()
|
||||||
self.events.Send(NewEvent(node))
|
net.events.Send(NewEvent(node))
|
||||||
}()
|
}()
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
|
|
@ -235,16 +235,16 @@ func (self *Network) watchPeerEvents(id discover.NodeID, events chan *p2p.PeerEv
|
||||||
switch event.Type {
|
switch event.Type {
|
||||||
|
|
||||||
case p2p.PeerEventTypeAdd:
|
case p2p.PeerEventTypeAdd:
|
||||||
self.DidConnect(id, peer)
|
net.DidConnect(id, peer)
|
||||||
|
|
||||||
case p2p.PeerEventTypeDrop:
|
case p2p.PeerEventTypeDrop:
|
||||||
self.DidDisconnect(id, peer)
|
net.DidDisconnect(id, peer)
|
||||||
|
|
||||||
case p2p.PeerEventTypeMsgSend:
|
case p2p.PeerEventTypeMsgSend:
|
||||||
self.DidSend(id, peer, event.Protocol, *event.MsgCode)
|
net.DidSend(id, peer, event.Protocol, *event.MsgCode)
|
||||||
|
|
||||||
case p2p.PeerEventTypeMsgRecv:
|
case p2p.PeerEventTypeMsgRecv:
|
||||||
self.DidReceive(peer, id, event.Protocol, *event.MsgCode)
|
net.DidReceive(peer, id, event.Protocol, *event.MsgCode)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -258,8 +258,8 @@ func (self *Network) watchPeerEvents(id discover.NodeID, events chan *p2p.PeerEv
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop stops the node with the given ID
|
// Stop stops the node with the given ID
|
||||||
func (self *Network) Stop(id discover.NodeID) error {
|
func (net *Network) Stop(id discover.NodeID) error {
|
||||||
node := self.GetNode(id)
|
node := net.GetNode(id)
|
||||||
if node == nil {
|
if node == nil {
|
||||||
return fmt.Errorf("node %v does not exist", id)
|
return fmt.Errorf("node %v does not exist", id)
|
||||||
}
|
}
|
||||||
|
|
@ -272,15 +272,15 @@ func (self *Network) Stop(id discover.NodeID) error {
|
||||||
node.Up = false
|
node.Up = false
|
||||||
log.Info(fmt.Sprintf("stop node %v: %v", id, node.Up))
|
log.Info(fmt.Sprintf("stop node %v: %v", id, node.Up))
|
||||||
|
|
||||||
self.events.Send(ControlEvent(node))
|
net.events.Send(ControlEvent(node))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connect connects two nodes together by calling the "admin_addPeer" RPC
|
// Connect connects two nodes together by calling the "admin_addPeer" RPC
|
||||||
// method on the "one" node so that it connects to the "other" node
|
// method on the "one" node so that it connects to the "other" node
|
||||||
func (self *Network) Connect(oneID, otherID discover.NodeID) error {
|
func (net *Network) Connect(oneID, otherID discover.NodeID) error {
|
||||||
log.Debug(fmt.Sprintf("connecting %s to %s", oneID, otherID))
|
log.Debug(fmt.Sprintf("connecting %s to %s", oneID, otherID))
|
||||||
conn, err := self.InitConn(oneID, otherID)
|
conn, err := net.InitConn(oneID, otherID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -288,14 +288,14 @@ func (self *Network) Connect(oneID, otherID discover.NodeID) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
self.events.Send(ControlEvent(conn))
|
net.events.Send(ControlEvent(conn))
|
||||||
return client.Call(nil, "admin_addPeer", string(conn.other.Addr()))
|
return client.Call(nil, "admin_addPeer", string(conn.other.Addr()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disconnect disconnects two nodes by calling the "admin_removePeer" RPC
|
// Disconnect disconnects two nodes by calling the "admin_removePeer" RPC
|
||||||
// method on the "one" node so that it disconnects from the "other" node
|
// method on the "one" node so that it disconnects from the "other" node
|
||||||
func (self *Network) Disconnect(oneID, otherID discover.NodeID) error {
|
func (net *Network) Disconnect(oneID, otherID discover.NodeID) error {
|
||||||
conn := self.GetConn(oneID, otherID)
|
conn := net.GetConn(oneID, otherID)
|
||||||
if conn == nil {
|
if conn == nil {
|
||||||
return fmt.Errorf("connection between %v and %v does not exist", oneID, otherID)
|
return fmt.Errorf("connection between %v and %v does not exist", oneID, otherID)
|
||||||
}
|
}
|
||||||
|
|
@ -306,13 +306,13 @@ func (self *Network) Disconnect(oneID, otherID discover.NodeID) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
self.events.Send(ControlEvent(conn))
|
net.events.Send(ControlEvent(conn))
|
||||||
return client.Call(nil, "admin_removePeer", string(conn.other.Addr()))
|
return client.Call(nil, "admin_removePeer", string(conn.other.Addr()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// DidConnect tracks the fact that the "one" node connected to the "other" node
|
// DidConnect tracks the fact that the "one" node connected to the "other" node
|
||||||
func (self *Network) DidConnect(one, other discover.NodeID) error {
|
func (net *Network) DidConnect(one, other discover.NodeID) error {
|
||||||
conn, err := self.GetOrCreateConn(one, other)
|
conn, err := net.GetOrCreateConn(one, other)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("connection between %v and %v does not exist", one, other)
|
return fmt.Errorf("connection between %v and %v does not exist", one, other)
|
||||||
}
|
}
|
||||||
|
|
@ -320,14 +320,14 @@ func (self *Network) DidConnect(one, other discover.NodeID) error {
|
||||||
return fmt.Errorf("%v and %v already connected", one, other)
|
return fmt.Errorf("%v and %v already connected", one, other)
|
||||||
}
|
}
|
||||||
conn.Up = true
|
conn.Up = true
|
||||||
self.events.Send(NewEvent(conn))
|
net.events.Send(NewEvent(conn))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DidDisconnect tracks the fact that the "one" node disconnected from the
|
// DidDisconnect tracks the fact that the "one" node disconnected from the
|
||||||
// "other" node
|
// "other" node
|
||||||
func (self *Network) DidDisconnect(one, other discover.NodeID) error {
|
func (net *Network) DidDisconnect(one, other discover.NodeID) error {
|
||||||
conn := self.GetConn(one, other)
|
conn := net.GetConn(one, other)
|
||||||
if conn == nil {
|
if conn == nil {
|
||||||
return fmt.Errorf("connection between %v and %v does not exist", one, other)
|
return fmt.Errorf("connection between %v and %v does not exist", one, other)
|
||||||
}
|
}
|
||||||
|
|
@ -336,12 +336,12 @@ func (self *Network) DidDisconnect(one, other discover.NodeID) error {
|
||||||
}
|
}
|
||||||
conn.Up = false
|
conn.Up = false
|
||||||
conn.initiated = time.Now().Add(-dialBanTimeout)
|
conn.initiated = time.Now().Add(-dialBanTimeout)
|
||||||
self.events.Send(NewEvent(conn))
|
net.events.Send(NewEvent(conn))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DidSend tracks the fact that "sender" sent a message to "receiver"
|
// DidSend tracks the fact that "sender" sent a message to "receiver"
|
||||||
func (self *Network) DidSend(sender, receiver discover.NodeID, proto string, code uint64) error {
|
func (net *Network) DidSend(sender, receiver discover.NodeID, proto string, code uint64) error {
|
||||||
msg := &Msg{
|
msg := &Msg{
|
||||||
One: sender,
|
One: sender,
|
||||||
Other: receiver,
|
Other: receiver,
|
||||||
|
|
@ -349,12 +349,12 @@ func (self *Network) DidSend(sender, receiver discover.NodeID, proto string, cod
|
||||||
Code: code,
|
Code: code,
|
||||||
Received: false,
|
Received: false,
|
||||||
}
|
}
|
||||||
self.events.Send(NewEvent(msg))
|
net.events.Send(NewEvent(msg))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DidReceive tracks the fact that "receiver" received a message from "sender"
|
// DidReceive tracks the fact that "receiver" received a message from "sender"
|
||||||
func (self *Network) DidReceive(sender, receiver discover.NodeID, proto string, code uint64) error {
|
func (net *Network) DidReceive(sender, receiver discover.NodeID, proto string, code uint64) error {
|
||||||
msg := &Msg{
|
msg := &Msg{
|
||||||
One: sender,
|
One: sender,
|
||||||
Other: receiver,
|
Other: receiver,
|
||||||
|
|
@ -362,36 +362,36 @@ func (self *Network) DidReceive(sender, receiver discover.NodeID, proto string,
|
||||||
Code: code,
|
Code: code,
|
||||||
Received: true,
|
Received: true,
|
||||||
}
|
}
|
||||||
self.events.Send(NewEvent(msg))
|
net.events.Send(NewEvent(msg))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetNode gets the node with the given ID, returning nil if the node does not
|
// GetNode gets the node with the given ID, returning nil if the node does not
|
||||||
// exist
|
// exist
|
||||||
func (self *Network) GetNode(id discover.NodeID) *Node {
|
func (net *Network) GetNode(id discover.NodeID) *Node {
|
||||||
self.lock.Lock()
|
net.lock.Lock()
|
||||||
defer self.lock.Unlock()
|
defer net.lock.Unlock()
|
||||||
return self.getNode(id)
|
return net.getNode(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetNode gets the node with the given name, returning nil if the node does
|
// GetNode gets the node with the given name, returning nil if the node does
|
||||||
// not exist
|
// not exist
|
||||||
func (self *Network) GetNodeByName(name string) *Node {
|
func (net *Network) GetNodeByName(name string) *Node {
|
||||||
self.lock.Lock()
|
net.lock.Lock()
|
||||||
defer self.lock.Unlock()
|
defer net.lock.Unlock()
|
||||||
return self.getNodeByName(name)
|
return net.getNodeByName(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Network) getNode(id discover.NodeID) *Node {
|
func (net *Network) getNode(id discover.NodeID) *Node {
|
||||||
i, found := self.nodeMap[id]
|
i, found := net.nodeMap[id]
|
||||||
if !found {
|
if !found {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return self.Nodes[i]
|
return net.Nodes[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Network) getNodeByName(name string) *Node {
|
func (net *Network) getNodeByName(name string) *Node {
|
||||||
for _, node := range self.Nodes {
|
for _, node := range net.Nodes {
|
||||||
if node.Config.Name == name {
|
if node.Config.Name == name {
|
||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
|
|
@ -400,40 +400,40 @@ func (self *Network) getNodeByName(name string) *Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetNodes returns the existing nodes
|
// GetNodes returns the existing nodes
|
||||||
func (self *Network) GetNodes() (nodes []*Node) {
|
func (net *Network) GetNodes() (nodes []*Node) {
|
||||||
self.lock.Lock()
|
net.lock.Lock()
|
||||||
defer self.lock.Unlock()
|
defer net.lock.Unlock()
|
||||||
|
|
||||||
nodes = append(nodes, self.Nodes...)
|
nodes = append(nodes, net.Nodes...)
|
||||||
return nodes
|
return nodes
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetConn returns the connection which exists between "one" and "other"
|
// GetConn returns the connection which exists between "one" and "other"
|
||||||
// regardless of which node initiated the connection
|
// regardless of which node initiated the connection
|
||||||
func (self *Network) GetConn(oneID, otherID discover.NodeID) *Conn {
|
func (net *Network) GetConn(oneID, otherID discover.NodeID) *Conn {
|
||||||
self.lock.Lock()
|
net.lock.Lock()
|
||||||
defer self.lock.Unlock()
|
defer net.lock.Unlock()
|
||||||
return self.getConn(oneID, otherID)
|
return net.getConn(oneID, otherID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetOrCreateConn is like GetConn but creates the connection if it doesn't
|
// GetOrCreateConn is like GetConn but creates the connection if it doesn't
|
||||||
// already exist
|
// already exist
|
||||||
func (self *Network) GetOrCreateConn(oneID, otherID discover.NodeID) (*Conn, error) {
|
func (net *Network) GetOrCreateConn(oneID, otherID discover.NodeID) (*Conn, error) {
|
||||||
self.lock.Lock()
|
net.lock.Lock()
|
||||||
defer self.lock.Unlock()
|
defer net.lock.Unlock()
|
||||||
return self.getOrCreateConn(oneID, otherID)
|
return net.getOrCreateConn(oneID, otherID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Network) getOrCreateConn(oneID, otherID discover.NodeID) (*Conn, error) {
|
func (net *Network) getOrCreateConn(oneID, otherID discover.NodeID) (*Conn, error) {
|
||||||
if conn := self.getConn(oneID, otherID); conn != nil {
|
if conn := net.getConn(oneID, otherID); conn != nil {
|
||||||
return conn, nil
|
return conn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
one := self.getNode(oneID)
|
one := net.getNode(oneID)
|
||||||
if one == nil {
|
if one == nil {
|
||||||
return nil, fmt.Errorf("node %v does not exist", oneID)
|
return nil, fmt.Errorf("node %v does not exist", oneID)
|
||||||
}
|
}
|
||||||
other := self.getNode(otherID)
|
other := net.getNode(otherID)
|
||||||
if other == nil {
|
if other == nil {
|
||||||
return nil, fmt.Errorf("node %v does not exist", otherID)
|
return nil, fmt.Errorf("node %v does not exist", otherID)
|
||||||
}
|
}
|
||||||
|
|
@ -444,18 +444,18 @@ func (self *Network) getOrCreateConn(oneID, otherID discover.NodeID) (*Conn, err
|
||||||
other: other,
|
other: other,
|
||||||
}
|
}
|
||||||
label := ConnLabel(oneID, otherID)
|
label := ConnLabel(oneID, otherID)
|
||||||
self.connMap[label] = len(self.Conns)
|
net.connMap[label] = len(net.Conns)
|
||||||
self.Conns = append(self.Conns, conn)
|
net.Conns = append(net.Conns, conn)
|
||||||
return conn, nil
|
return conn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Network) getConn(oneID, otherID discover.NodeID) *Conn {
|
func (net *Network) getConn(oneID, otherID discover.NodeID) *Conn {
|
||||||
label := ConnLabel(oneID, otherID)
|
label := ConnLabel(oneID, otherID)
|
||||||
i, found := self.connMap[label]
|
i, found := net.connMap[label]
|
||||||
if !found {
|
if !found {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return self.Conns[i]
|
return net.Conns[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitConn(one, other) retrieves the connectiton model for the connection between
|
// InitConn(one, other) retrieves the connectiton model for the connection between
|
||||||
|
|
@ -466,13 +466,13 @@ func (self *Network) getConn(oneID, otherID discover.NodeID) *Conn {
|
||||||
// it also checks whether there has been recent attempt to connect the peers
|
// it also checks whether there has been recent attempt to connect the peers
|
||||||
// this is cheating as the simulation is used as an oracle and know about
|
// this is cheating as the simulation is used as an oracle and know about
|
||||||
// remote peers attempt to connect to a node which will then not initiate the connection
|
// remote peers attempt to connect to a node which will then not initiate the connection
|
||||||
func (self *Network) InitConn(oneID, otherID discover.NodeID) (*Conn, error) {
|
func (net *Network) InitConn(oneID, otherID discover.NodeID) (*Conn, error) {
|
||||||
self.lock.Lock()
|
net.lock.Lock()
|
||||||
defer self.lock.Unlock()
|
defer net.lock.Unlock()
|
||||||
if oneID == otherID {
|
if oneID == otherID {
|
||||||
return nil, fmt.Errorf("refusing to connect to self %v", oneID)
|
return nil, fmt.Errorf("refusing to connect to self %v", oneID)
|
||||||
}
|
}
|
||||||
conn, err := self.getOrCreateConn(oneID, otherID)
|
conn, err := net.getOrCreateConn(oneID, otherID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -491,28 +491,28 @@ func (self *Network) InitConn(oneID, otherID discover.NodeID) (*Conn, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shutdown stops all nodes in the network and closes the quit channel
|
// Shutdown stops all nodes in the network and closes the quit channel
|
||||||
func (self *Network) Shutdown() {
|
func (net *Network) Shutdown() {
|
||||||
for _, node := range self.Nodes {
|
for _, node := range net.Nodes {
|
||||||
log.Debug(fmt.Sprintf("stopping node %s", node.ID().TerminalString()))
|
log.Debug(fmt.Sprintf("stopping node %s", node.ID().TerminalString()))
|
||||||
if err := node.Stop(); err != nil {
|
if err := node.Stop(); err != nil {
|
||||||
log.Warn(fmt.Sprintf("error stopping node %s", node.ID().TerminalString()), "err", err)
|
log.Warn(fmt.Sprintf("error stopping node %s", node.ID().TerminalString()), "err", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
close(self.quitc)
|
close(net.quitc)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Reset resets all network properties:
|
//Reset resets all network properties:
|
||||||
//emtpies the nodes and the connection list
|
//emtpies the nodes and the connection list
|
||||||
func (self *Network) Reset() {
|
func (net *Network) Reset() {
|
||||||
self.lock.Lock()
|
net.lock.Lock()
|
||||||
defer self.lock.Unlock()
|
defer net.lock.Unlock()
|
||||||
|
|
||||||
//re-initialize the maps
|
//re-initialize the maps
|
||||||
self.connMap = make(map[string]int)
|
net.connMap = make(map[string]int)
|
||||||
self.nodeMap = make(map[discover.NodeID]int)
|
net.nodeMap = make(map[discover.NodeID]int)
|
||||||
|
|
||||||
self.Nodes = nil
|
net.Nodes = nil
|
||||||
self.Conns = nil
|
net.Conns = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Node is a wrapper around adapters.Node which is used to track the status
|
// Node is a wrapper around adapters.Node which is used to track the status
|
||||||
|
|
@ -528,37 +528,37 @@ type Node struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ID returns the ID of the node
|
// ID returns the ID of the node
|
||||||
func (self *Node) ID() discover.NodeID {
|
func (n *Node) ID() discover.NodeID {
|
||||||
return self.Config.ID
|
return n.Config.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns a log-friendly string
|
// String returns a log-friendly string
|
||||||
func (self *Node) String() string {
|
func (n *Node) String() string {
|
||||||
return fmt.Sprintf("Node %v", self.ID().TerminalString())
|
return fmt.Sprintf("Node %v", n.ID().TerminalString())
|
||||||
}
|
}
|
||||||
|
|
||||||
// NodeInfo returns information about the node
|
// NodeInfo returns information about the node
|
||||||
func (self *Node) NodeInfo() *p2p.NodeInfo {
|
func (n *Node) NodeInfo() *p2p.NodeInfo {
|
||||||
// avoid a panic if the node is not started yet
|
// avoid a panic if the node is not started yet
|
||||||
if self.Node == nil {
|
if n.Node == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
info := self.Node.NodeInfo()
|
info := n.Node.NodeInfo()
|
||||||
info.Name = self.Config.Name
|
info.Name = n.Config.Name
|
||||||
return info
|
return info
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalJSON implements the json.Marshaler interface so that the encoded
|
// MarshalJSON implements the json.Marshaler interface so that the encoded
|
||||||
// JSON includes the NodeInfo
|
// JSON includes the NodeInfo
|
||||||
func (self *Node) MarshalJSON() ([]byte, error) {
|
func (n *Node) MarshalJSON() ([]byte, error) {
|
||||||
return json.Marshal(struct {
|
return json.Marshal(struct {
|
||||||
Info *p2p.NodeInfo `json:"info,omitempty"`
|
Info *p2p.NodeInfo `json:"info,omitempty"`
|
||||||
Config *adapters.NodeConfig `json:"config,omitempty"`
|
Config *adapters.NodeConfig `json:"config,omitempty"`
|
||||||
Up bool `json:"up"`
|
Up bool `json:"up"`
|
||||||
}{
|
}{
|
||||||
Info: self.NodeInfo(),
|
Info: n.NodeInfo(),
|
||||||
Config: self.Config,
|
Config: n.Config,
|
||||||
Up: self.Up,
|
Up: n.Up,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -580,19 +580,19 @@ type Conn struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// nodesUp returns whether both nodes are currently up
|
// nodesUp returns whether both nodes are currently up
|
||||||
func (self *Conn) nodesUp() error {
|
func (c *Conn) nodesUp() error {
|
||||||
if !self.one.Up {
|
if !c.one.Up {
|
||||||
return fmt.Errorf("one %v is not up", self.One)
|
return fmt.Errorf("one %v is not up", c.One)
|
||||||
}
|
}
|
||||||
if !self.other.Up {
|
if !c.other.Up {
|
||||||
return fmt.Errorf("other %v is not up", self.Other)
|
return fmt.Errorf("other %v is not up", c.Other)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns a log-friendly string
|
// String returns a log-friendly string
|
||||||
func (self *Conn) String() string {
|
func (c *Conn) String() string {
|
||||||
return fmt.Sprintf("Conn %v->%v", self.One.TerminalString(), self.Other.TerminalString())
|
return fmt.Sprintf("Conn %v->%v", c.One.TerminalString(), c.Other.TerminalString())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Msg represents a p2p message sent between two nodes in the network
|
// Msg represents a p2p message sent between two nodes in the network
|
||||||
|
|
@ -605,8 +605,8 @@ type Msg struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns a log-friendly string
|
// String returns a log-friendly string
|
||||||
func (self *Msg) String() string {
|
func (m *Msg) String() string {
|
||||||
return fmt.Sprintf("Msg(%d) %v->%v", self.Code, self.One.TerminalString(), self.Other.TerminalString())
|
return fmt.Sprintf("Msg(%d) %v->%v", m.Code, m.One.TerminalString(), m.Other.TerminalString())
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConnLabel generates a deterministic string which represents a connection
|
// ConnLabel generates a deterministic string which represents a connection
|
||||||
|
|
@ -640,14 +640,14 @@ type NodeSnapshot struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Snapshot creates a network snapshot
|
// Snapshot creates a network snapshot
|
||||||
func (self *Network) Snapshot() (*Snapshot, error) {
|
func (net *Network) Snapshot() (*Snapshot, error) {
|
||||||
self.lock.Lock()
|
net.lock.Lock()
|
||||||
defer self.lock.Unlock()
|
defer net.lock.Unlock()
|
||||||
snap := &Snapshot{
|
snap := &Snapshot{
|
||||||
Nodes: make([]NodeSnapshot, len(self.Nodes)),
|
Nodes: make([]NodeSnapshot, len(net.Nodes)),
|
||||||
Conns: make([]Conn, len(self.Conns)),
|
Conns: make([]Conn, len(net.Conns)),
|
||||||
}
|
}
|
||||||
for i, node := range self.Nodes {
|
for i, node := range net.Nodes {
|
||||||
snap.Nodes[i] = NodeSnapshot{Node: *node}
|
snap.Nodes[i] = NodeSnapshot{Node: *node}
|
||||||
if !node.Up {
|
if !node.Up {
|
||||||
continue
|
continue
|
||||||
|
|
@ -658,33 +658,33 @@ func (self *Network) Snapshot() (*Snapshot, error) {
|
||||||
}
|
}
|
||||||
snap.Nodes[i].Snapshots = snapshots
|
snap.Nodes[i].Snapshots = snapshots
|
||||||
}
|
}
|
||||||
for i, conn := range self.Conns {
|
for i, conn := range net.Conns {
|
||||||
snap.Conns[i] = *conn
|
snap.Conns[i] = *conn
|
||||||
}
|
}
|
||||||
return snap, nil
|
return snap, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load loads a network snapshot
|
// Load loads a network snapshot
|
||||||
func (self *Network) Load(snap *Snapshot) error {
|
func (net *Network) Load(snap *Snapshot) error {
|
||||||
for _, n := range snap.Nodes {
|
for _, n := range snap.Nodes {
|
||||||
if _, err := self.NewNodeWithConfig(n.Node.Config); err != nil {
|
if _, err := net.NewNodeWithConfig(n.Node.Config); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !n.Node.Up {
|
if !n.Node.Up {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err := self.startWithSnapshots(n.Node.Config.ID, n.Snapshots); err != nil {
|
if err := net.startWithSnapshots(n.Node.Config.ID, n.Snapshots); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, conn := range snap.Conns {
|
for _, conn := range snap.Conns {
|
||||||
|
|
||||||
if !self.GetNode(conn.One).Up || !self.GetNode(conn.Other).Up {
|
if !net.GetNode(conn.One).Up || !net.GetNode(conn.Other).Up {
|
||||||
//in this case, at least one of the nodes of a connection is not up,
|
//in this case, at least one of the nodes of a connection is not up,
|
||||||
//so it would result in the snapshot `Load` to fail
|
//so it would result in the snapshot `Load` to fail
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err := self.Connect(conn.One, conn.Other); err != nil {
|
if err := net.Connect(conn.One, conn.Other); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -692,7 +692,7 @@ func (self *Network) Load(snap *Snapshot) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Subscribe reads control events from a channel and executes them
|
// Subscribe reads control events from a channel and executes them
|
||||||
func (self *Network) Subscribe(events chan *Event) {
|
func (net *Network) Subscribe(events chan *Event) {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case event, ok := <-events:
|
case event, ok := <-events:
|
||||||
|
|
@ -700,23 +700,23 @@ func (self *Network) Subscribe(events chan *Event) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if event.Control {
|
if event.Control {
|
||||||
self.executeControlEvent(event)
|
net.executeControlEvent(event)
|
||||||
}
|
}
|
||||||
case <-self.quitc:
|
case <-net.quitc:
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Network) executeControlEvent(event *Event) {
|
func (net *Network) executeControlEvent(event *Event) {
|
||||||
log.Trace("execute control event", "type", event.Type, "event", event)
|
log.Trace("execute control event", "type", event.Type, "event", event)
|
||||||
switch event.Type {
|
switch event.Type {
|
||||||
case EventTypeNode:
|
case EventTypeNode:
|
||||||
if err := self.executeNodeEvent(event); err != nil {
|
if err := net.executeNodeEvent(event); err != nil {
|
||||||
log.Error("error executing node event", "event", event, "err", err)
|
log.Error("error executing node event", "event", event, "err", err)
|
||||||
}
|
}
|
||||||
case EventTypeConn:
|
case EventTypeConn:
|
||||||
if err := self.executeConnEvent(event); err != nil {
|
if err := net.executeConnEvent(event); err != nil {
|
||||||
log.Error("error executing conn event", "event", event, "err", err)
|
log.Error("error executing conn event", "event", event, "err", err)
|
||||||
}
|
}
|
||||||
case EventTypeMsg:
|
case EventTypeMsg:
|
||||||
|
|
@ -724,20 +724,21 @@ func (self *Network) executeControlEvent(event *Event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Network) executeNodeEvent(e *Event) error {
|
func (net *Network) executeNodeEvent(e *Event) error {
|
||||||
if !e.Node.Up {
|
if !e.Node.Up {
|
||||||
return self.Stop(e.Node.ID())
|
return net.Stop(e.Node.ID())
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := self.NewNodeWithConfig(e.Node.Config); err != nil {
|
if _, err := net.NewNodeWithConfig(e.Node.Config); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return self.Start(e.Node.ID())
|
return net.Start(e.Node.ID())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Network) executeConnEvent(e *Event) error {
|
func (net *Network) executeConnEvent(e *Event) error {
|
||||||
if e.Conn.Up {
|
if e.Conn.Up {
|
||||||
return self.Connect(e.Conn.One, e.Conn.Other)
|
return net.Connect(e.Conn.One, e.Conn.Other)
|
||||||
|
} else {
|
||||||
|
return net.Disconnect(e.Conn.One, e.Conn.Other)
|
||||||
}
|
}
|
||||||
return self.Disconnect(e.Conn.One, e.Conn.Other)
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,29 +39,29 @@ func NewTestPeerPool() *TestPeerPool {
|
||||||
return &TestPeerPool{peers: make(map[discover.NodeID]TestPeer)}
|
return &TestPeerPool{peers: make(map[discover.NodeID]TestPeer)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *TestPeerPool) Add(p TestPeer) {
|
func (p *TestPeerPool) Add(peer TestPeer) {
|
||||||
self.lock.Lock()
|
p.lock.Lock()
|
||||||
defer self.lock.Unlock()
|
defer p.lock.Unlock()
|
||||||
log.Trace(fmt.Sprintf("pp add peer %v", p.ID()))
|
log.Trace(fmt.Sprintf("pp add peer %v", peer.ID()))
|
||||||
self.peers[p.ID()] = p
|
p.peers[peer.ID()] = peer
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *TestPeerPool) Remove(p TestPeer) {
|
func (p *TestPeerPool) Remove(peer TestPeer) {
|
||||||
self.lock.Lock()
|
p.lock.Lock()
|
||||||
defer self.lock.Unlock()
|
defer p.lock.Unlock()
|
||||||
delete(self.peers, p.ID())
|
delete(p.peers, peer.ID())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *TestPeerPool) Has(id discover.NodeID) bool {
|
func (p *TestPeerPool) Has(id discover.NodeID) bool {
|
||||||
self.lock.Lock()
|
p.lock.Lock()
|
||||||
defer self.lock.Unlock()
|
defer p.lock.Unlock()
|
||||||
_, ok := self.peers[id]
|
_, ok := p.peers[id]
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *TestPeerPool) Get(id discover.NodeID) TestPeer {
|
func (p *TestPeerPool) Get(id discover.NodeID) TestPeer {
|
||||||
self.lock.Lock()
|
p.lock.Lock()
|
||||||
defer self.lock.Unlock()
|
defer p.lock.Unlock()
|
||||||
return self.peers[id]
|
return p.peers[id]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -78,10 +78,10 @@ type Disconnect struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// trigger sends messages from peers
|
// trigger sends messages from peers
|
||||||
func (self *ProtocolSession) trigger(trig Trigger) error {
|
func (s *ProtocolSession) trigger(trig Trigger) error {
|
||||||
simNode, ok := self.adapter.GetNode(trig.Peer)
|
simNode, ok := s.adapter.GetNode(trig.Peer)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("trigger: peer %v does not exist (1- %v)", trig.Peer, len(self.IDs))
|
return fmt.Errorf("trigger: peer %v does not exist (1- %v)", trig.Peer, len(s.IDs))
|
||||||
}
|
}
|
||||||
mockNode, ok := simNode.Services()[0].(*mockNode)
|
mockNode, ok := simNode.Services()[0].(*mockNode)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
@ -107,7 +107,7 @@ func (self *ProtocolSession) trigger(trig Trigger) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// expect checks an expectation of a message sent out by the pivot node
|
// expect checks an expectation of a message sent out by the pivot node
|
||||||
func (self *ProtocolSession) expect(exps []Expect) error {
|
func (s *ProtocolSession) expect(exps []Expect) error {
|
||||||
// construct a map of expectations for each node
|
// construct a map of expectations for each node
|
||||||
peerExpects := make(map[discover.NodeID][]Expect)
|
peerExpects := make(map[discover.NodeID][]Expect)
|
||||||
for _, exp := range exps {
|
for _, exp := range exps {
|
||||||
|
|
@ -120,9 +120,9 @@ func (self *ProtocolSession) expect(exps []Expect) error {
|
||||||
// construct a map of mockNodes for each node
|
// construct a map of mockNodes for each node
|
||||||
mockNodes := make(map[discover.NodeID]*mockNode)
|
mockNodes := make(map[discover.NodeID]*mockNode)
|
||||||
for nodeID := range peerExpects {
|
for nodeID := range peerExpects {
|
||||||
simNode, ok := self.adapter.GetNode(nodeID)
|
simNode, ok := s.adapter.GetNode(nodeID)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("trigger: peer %v does not exist (1- %v)", nodeID, len(self.IDs))
|
return fmt.Errorf("trigger: peer %v does not exist (1- %v)", nodeID, len(s.IDs))
|
||||||
}
|
}
|
||||||
mockNode, ok := simNode.Services()[0].(*mockNode)
|
mockNode, ok := simNode.Services()[0].(*mockNode)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
@ -202,9 +202,9 @@ func (self *ProtocolSession) expect(exps []Expect) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestExchanges tests a series of exchanges against the session
|
// TestExchanges tests a series of exchanges against the session
|
||||||
func (self *ProtocolSession) TestExchanges(exchanges ...Exchange) error {
|
func (s *ProtocolSession) TestExchanges(exchanges ...Exchange) error {
|
||||||
for i, e := range exchanges {
|
for i, e := range exchanges {
|
||||||
if err := self.testExchange(e); err != nil {
|
if err := s.testExchange(e); err != nil {
|
||||||
return fmt.Errorf("exchange #%d %q: %v", i, e.Label, err)
|
return fmt.Errorf("exchange #%d %q: %v", i, e.Label, err)
|
||||||
}
|
}
|
||||||
log.Trace(fmt.Sprintf("exchange #%d %q: run successfully", i, e.Label))
|
log.Trace(fmt.Sprintf("exchange #%d %q: run successfully", i, e.Label))
|
||||||
|
|
@ -214,14 +214,14 @@ func (self *ProtocolSession) TestExchanges(exchanges ...Exchange) error {
|
||||||
|
|
||||||
// testExchange tests a single Exchange.
|
// testExchange tests a single Exchange.
|
||||||
// Default timeout value is 2 seconds.
|
// Default timeout value is 2 seconds.
|
||||||
func (self *ProtocolSession) testExchange(e Exchange) error {
|
func (s *ProtocolSession) testExchange(e Exchange) error {
|
||||||
errc := make(chan error)
|
errc := make(chan error)
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
defer close(done)
|
defer close(done)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for _, trig := range e.Triggers {
|
for _, trig := range e.Triggers {
|
||||||
err := self.trigger(trig)
|
err := s.trigger(trig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errc <- err
|
errc <- err
|
||||||
return
|
return
|
||||||
|
|
@ -229,7 +229,7 @@ func (self *ProtocolSession) testExchange(e Exchange) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case errc <- self.expect(e.Expects):
|
case errc <- s.expect(e.Expects):
|
||||||
case <-done:
|
case <-done:
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
@ -250,7 +250,7 @@ func (self *ProtocolSession) testExchange(e Exchange) error {
|
||||||
|
|
||||||
// TestDisconnected tests the disconnections given as arguments
|
// TestDisconnected tests the disconnections given as arguments
|
||||||
// the disconnect structs describe what disconnect error is expected on which peer
|
// the disconnect structs describe what disconnect error is expected on which peer
|
||||||
func (self *ProtocolSession) TestDisconnected(disconnects ...*Disconnect) error {
|
func (s *ProtocolSession) TestDisconnected(disconnects ...*Disconnect) error {
|
||||||
expects := make(map[discover.NodeID]error)
|
expects := make(map[discover.NodeID]error)
|
||||||
for _, disconnect := range disconnects {
|
for _, disconnect := range disconnects {
|
||||||
expects[disconnect.Peer] = disconnect.Error
|
expects[disconnect.Peer] = disconnect.Error
|
||||||
|
|
@ -259,7 +259,7 @@ func (self *ProtocolSession) TestDisconnected(disconnects ...*Disconnect) error
|
||||||
timeout := time.After(time.Second)
|
timeout := time.After(time.Second)
|
||||||
for len(expects) > 0 {
|
for len(expects) > 0 {
|
||||||
select {
|
select {
|
||||||
case event := <-self.events:
|
case event := <-s.events:
|
||||||
if event.Type != p2p.PeerEventTypeDrop {
|
if event.Type != p2p.PeerEventTypeDrop {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -101,24 +101,24 @@ func NewProtocolTester(t *testing.T, id discover.NodeID, n int, run func(*p2p.Pe
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop stops the p2p server
|
// Stop stops the p2p server
|
||||||
func (self *ProtocolTester) Stop() error {
|
func (t *ProtocolTester) Stop() error {
|
||||||
self.Server.Stop()
|
t.Server.Stop()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connect brings up the remote peer node and connects it using the
|
// Connect brings up the remote peer node and connects it using the
|
||||||
// p2p/simulations network connection with the in memory network adapter
|
// p2p/simulations network connection with the in memory network adapter
|
||||||
func (self *ProtocolTester) Connect(selfID discover.NodeID, peers ...*adapters.NodeConfig) {
|
func (t *ProtocolTester) Connect(selfID discover.NodeID, peers ...*adapters.NodeConfig) {
|
||||||
for _, peer := range peers {
|
for _, peer := range peers {
|
||||||
log.Trace(fmt.Sprintf("start node %v", peer.ID))
|
log.Trace(fmt.Sprintf("start node %v", peer.ID))
|
||||||
if _, err := self.network.NewNodeWithConfig(peer); err != nil {
|
if _, err := t.network.NewNodeWithConfig(peer); err != nil {
|
||||||
panic(fmt.Sprintf("error starting peer %v: %v", peer.ID, err))
|
panic(fmt.Sprintf("error starting peer %v: %v", peer.ID, err))
|
||||||
}
|
}
|
||||||
if err := self.network.Start(peer.ID); err != nil {
|
if err := t.network.Start(peer.ID); err != nil {
|
||||||
panic(fmt.Sprintf("error starting peer %v: %v", peer.ID, err))
|
panic(fmt.Sprintf("error starting peer %v: %v", peer.ID, err))
|
||||||
}
|
}
|
||||||
log.Trace(fmt.Sprintf("connect to %v", peer.ID))
|
log.Trace(fmt.Sprintf("connect to %v", peer.ID))
|
||||||
if err := self.network.Connect(selfID, peer.ID); err != nil {
|
if err := t.network.Connect(selfID, peer.ID); err != nil {
|
||||||
panic(fmt.Sprintf("error connecting to peer %v: %v", peer.ID, err))
|
panic(fmt.Sprintf("error connecting to peer %v: %v", peer.ID, err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ import (
|
||||||
const (
|
const (
|
||||||
VersionMajor = 1 // Major version component of the current release
|
VersionMajor = 1 // Major version component of the current release
|
||||||
VersionMinor = 8 // Minor version component of the current release
|
VersionMinor = 8 // Minor version component of the current release
|
||||||
VersionPatch = 8 // Patch version component of the current release
|
VersionPatch = 9 // Patch version component of the current release
|
||||||
VersionMeta = "unstable" // Version metadata to append to the version string
|
VersionMeta = "unstable" // Version metadata to append to the version string
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,23 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
// EOL is returned when the end of the current list
|
||||||
|
// has been reached during streaming.
|
||||||
|
EOL = errors.New("rlp: end of list")
|
||||||
|
|
||||||
|
// Actual Errors
|
||||||
|
ErrExpectedString = errors.New("rlp: expected String or Byte")
|
||||||
|
ErrExpectedList = errors.New("rlp: expected List")
|
||||||
|
ErrCanonInt = errors.New("rlp: non-canonical integer format")
|
||||||
|
ErrCanonSize = errors.New("rlp: non-canonical size information")
|
||||||
|
ErrElemTooLarge = errors.New("rlp: element is larger than containing list")
|
||||||
|
ErrValueTooLarge = errors.New("rlp: value size exceeds available input length")
|
||||||
|
ErrMoreThanOneValue = errors.New("rlp: input contains more than one value")
|
||||||
|
|
||||||
|
// internal errors
|
||||||
|
errNotInList = errors.New("rlp: call of ListEnd outside of any list")
|
||||||
|
errNotAtEOL = errors.New("rlp: call of ListEnd not positioned at EOL")
|
||||||
|
errUintOverflow = errors.New("rlp: uint overflow")
|
||||||
errNoPointer = errors.New("rlp: interface given to Decode must be a pointer")
|
errNoPointer = errors.New("rlp: interface given to Decode must be a pointer")
|
||||||
errDecodeIntoNil = errors.New("rlp: pointer given to Decode must not be nil")
|
errDecodeIntoNil = errors.New("rlp: pointer given to Decode must not be nil")
|
||||||
)
|
)
|
||||||
|
|
@ -274,9 +291,8 @@ func makeListDecoder(typ reflect.Type, tag tags) (decoder, error) {
|
||||||
if etype.Kind() == reflect.Uint8 && !reflect.PtrTo(etype).Implements(decoderInterface) {
|
if etype.Kind() == reflect.Uint8 && !reflect.PtrTo(etype).Implements(decoderInterface) {
|
||||||
if typ.Kind() == reflect.Array {
|
if typ.Kind() == reflect.Array {
|
||||||
return decodeByteArray, nil
|
return decodeByteArray, nil
|
||||||
} else {
|
|
||||||
return decodeByteSlice, nil
|
|
||||||
}
|
}
|
||||||
|
return decodeByteSlice, nil
|
||||||
}
|
}
|
||||||
etypeinfo, err := cachedTypeInfo1(etype, tags{})
|
etypeinfo, err := cachedTypeInfo1(etype, tags{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -555,29 +571,6 @@ func (k Kind) String() string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
// EOL is returned when the end of the current list
|
|
||||||
// has been reached during streaming.
|
|
||||||
EOL = errors.New("rlp: end of list")
|
|
||||||
|
|
||||||
// Actual Errors
|
|
||||||
ErrExpectedString = errors.New("rlp: expected String or Byte")
|
|
||||||
ErrExpectedList = errors.New("rlp: expected List")
|
|
||||||
ErrCanonInt = errors.New("rlp: non-canonical integer format")
|
|
||||||
ErrCanonSize = errors.New("rlp: non-canonical size information")
|
|
||||||
ErrElemTooLarge = errors.New("rlp: element is larger than containing list")
|
|
||||||
ErrValueTooLarge = errors.New("rlp: value size exceeds available input length")
|
|
||||||
|
|
||||||
// This error is reported by DecodeBytes if the slice contains
|
|
||||||
// additional data after the first RLP value.
|
|
||||||
ErrMoreThanOneValue = errors.New("rlp: input contains more than one value")
|
|
||||||
|
|
||||||
// internal errors
|
|
||||||
errNotInList = errors.New("rlp: call of ListEnd outside of any list")
|
|
||||||
errNotAtEOL = errors.New("rlp: call of ListEnd not positioned at EOL")
|
|
||||||
errUintOverflow = errors.New("rlp: uint overflow")
|
|
||||||
)
|
|
||||||
|
|
||||||
// ByteReader must be implemented by any input reader for a Stream. It
|
// ByteReader must be implemented by any input reader for a Stream. It
|
||||||
// is implemented by e.g. bufio.Reader and bytes.Reader.
|
// is implemented by e.g. bufio.Reader and bytes.Reader.
|
||||||
type ByteReader interface {
|
type ByteReader interface {
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ func Encode(w io.Writer, val interface{}) error {
|
||||||
return eb.toWriter(w)
|
return eb.toWriter(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EncodeBytes returns the RLP encoding of val.
|
// EncodeToBytes returns the RLP encoding of val.
|
||||||
// Please see the documentation of Encode for the encoding rules.
|
// Please see the documentation of Encode for the encoding rules.
|
||||||
func EncodeToBytes(val interface{}) ([]byte, error) {
|
func EncodeToBytes(val interface{}) ([]byte, error) {
|
||||||
eb := encbufPool.Get().(*encbuf)
|
eb := encbufPool.Get().(*encbuf)
|
||||||
|
|
@ -104,7 +104,7 @@ func EncodeToBytes(val interface{}) ([]byte, error) {
|
||||||
return eb.toBytes(), nil
|
return eb.toBytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// EncodeReader returns a reader from which the RLP encoding of val
|
// EncodeToReader returns a reader from which the RLP encoding of val
|
||||||
// can be read. The returned size is the total size of the encoded
|
// can be read. The returned size is the total size of the encoded
|
||||||
// data.
|
// data.
|
||||||
//
|
//
|
||||||
|
|
@ -151,11 +151,10 @@ func puthead(buf []byte, smalltag, largetag byte, size uint64) int {
|
||||||
if size < 56 {
|
if size < 56 {
|
||||||
buf[0] = smalltag + byte(size)
|
buf[0] = smalltag + byte(size)
|
||||||
return 1
|
return 1
|
||||||
} else {
|
}
|
||||||
sizesize := putint(buf[1:], size)
|
sizesize := putint(buf[1:], size)
|
||||||
buf[0] = largetag + byte(sizesize)
|
buf[0] = largetag + byte(sizesize)
|
||||||
return sizesize + 1
|
return sizesize + 1
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// encbufs are pooled.
|
// encbufs are pooled.
|
||||||
|
|
@ -218,7 +217,7 @@ func (w *encbuf) list() *listhead {
|
||||||
func (w *encbuf) listEnd(lh *listhead) {
|
func (w *encbuf) listEnd(lh *listhead) {
|
||||||
lh.size = w.size() - lh.offset - lh.size
|
lh.size = w.size() - lh.offset - lh.size
|
||||||
if lh.size < 56 {
|
if lh.size < 56 {
|
||||||
w.lhsize += 1 // length encoded into kind tag
|
w.lhsize++ // length encoded into kind tag
|
||||||
} else {
|
} else {
|
||||||
w.lhsize += 1 + intsize(uint64(lh.size))
|
w.lhsize += 1 + intsize(uint64(lh.size))
|
||||||
}
|
}
|
||||||
|
|
@ -322,10 +321,9 @@ func (r *encReader) next() []byte {
|
||||||
p := r.buf.str[r.strpos:head.offset]
|
p := r.buf.str[r.strpos:head.offset]
|
||||||
r.strpos += sizebefore
|
r.strpos += sizebefore
|
||||||
return p
|
return p
|
||||||
} else {
|
}
|
||||||
r.lhpos++
|
r.lhpos++
|
||||||
return head.encode(r.buf.sizebuf)
|
return head.encode(r.buf.sizebuf)
|
||||||
}
|
|
||||||
|
|
||||||
case r.strpos < len(r.buf.str):
|
case r.strpos < len(r.buf.str):
|
||||||
// String data at the end, after all list headers.
|
// String data at the end, after all list headers.
|
||||||
|
|
@ -576,9 +574,8 @@ func makePtrWriter(typ reflect.Type) (writer, error) {
|
||||||
writer := func(val reflect.Value, w *encbuf) error {
|
writer := func(val reflect.Value, w *encbuf) error {
|
||||||
if val.IsNil() {
|
if val.IsNil() {
|
||||||
return nilfunc(w)
|
return nilfunc(w)
|
||||||
} else {
|
|
||||||
return etypeinfo.writer(val.Elem(), w)
|
|
||||||
}
|
}
|
||||||
|
return etypeinfo.writer(val.Elem(), w)
|
||||||
}
|
}
|
||||||
return writer, err
|
return writer, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ func (t *BlockTest) Run() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// import pre accounts & construct test genesis block & state root
|
// import pre accounts & construct test genesis block & state root
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db := ethdb.NewMemDatabase()
|
||||||
gblock, err := t.genesis(config).Commit(db)
|
gblock, err := t.genesis(config).Commit(db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
|
|
@ -126,8 +126,7 @@ func (t *StateTest) Run(subtest StateSubtest, vmconfig vm.Config) (*state.StateD
|
||||||
return nil, UnsupportedForkError{subtest.Fork}
|
return nil, UnsupportedForkError{subtest.Fork}
|
||||||
}
|
}
|
||||||
block := t.genesis(config).ToBlock(nil)
|
block := t.genesis(config).ToBlock(nil)
|
||||||
db, _ := ethdb.NewMemDatabase()
|
statedb := MakePreState(ethdb.NewMemDatabase(), t.json.Pre)
|
||||||
statedb := MakePreState(db, t.json.Pre)
|
|
||||||
|
|
||||||
post := t.json.Post[subtest.Fork][subtest.Index]
|
post := t.json.Post[subtest.Fork][subtest.Index]
|
||||||
msg, err := t.json.Tx.toMessage(post)
|
msg, err := t.json.Tx.toMessage(post)
|
||||||
|
|
|
||||||
|
|
@ -79,8 +79,7 @@ type vmExecMarshaling struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *VMTest) Run(vmconfig vm.Config) error {
|
func (t *VMTest) Run(vmconfig vm.Config) error {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
statedb := MakePreState(ethdb.NewMemDatabase(), t.json.Pre)
|
||||||
statedb := MakePreState(db, t.json.Pre)
|
|
||||||
ret, gasRemaining, err := t.exec(statedb, vmconfig)
|
ret, gasRemaining, err := t.exec(statedb, vmconfig)
|
||||||
|
|
||||||
if t.json.GasRemaining == nil {
|
if t.json.GasRemaining == nil {
|
||||||
|
|
|
||||||
|
|
@ -289,7 +289,7 @@ func TestIteratorContinueAfterErrorDisk(t *testing.T) { testIteratorContinueA
|
||||||
func TestIteratorContinueAfterErrorMemonly(t *testing.T) { testIteratorContinueAfterError(t, true) }
|
func TestIteratorContinueAfterErrorMemonly(t *testing.T) { testIteratorContinueAfterError(t, true) }
|
||||||
|
|
||||||
func testIteratorContinueAfterError(t *testing.T, memonly bool) {
|
func testIteratorContinueAfterError(t *testing.T, memonly bool) {
|
||||||
diskdb, _ := ethdb.NewMemDatabase()
|
diskdb := ethdb.NewMemDatabase()
|
||||||
triedb := NewDatabase(diskdb)
|
triedb := NewDatabase(diskdb)
|
||||||
|
|
||||||
tr, _ := New(common.Hash{}, triedb)
|
tr, _ := New(common.Hash{}, triedb)
|
||||||
|
|
@ -376,7 +376,7 @@ func TestIteratorContinueAfterSeekErrorMemonly(t *testing.T) {
|
||||||
|
|
||||||
func testIteratorContinueAfterSeekError(t *testing.T, memonly bool) {
|
func testIteratorContinueAfterSeekError(t *testing.T, memonly bool) {
|
||||||
// Commit test trie to db, then remove the node containing "bars".
|
// Commit test trie to db, then remove the node containing "bars".
|
||||||
diskdb, _ := ethdb.NewMemDatabase()
|
diskdb := ethdb.NewMemDatabase()
|
||||||
triedb := NewDatabase(diskdb)
|
triedb := NewDatabase(diskdb)
|
||||||
|
|
||||||
ctr, _ := New(common.Hash{}, triedb)
|
ctr, _ := New(common.Hash{}, triedb)
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ func TestProof(t *testing.T) {
|
||||||
trie, vals := randomTrie(500)
|
trie, vals := randomTrie(500)
|
||||||
root := trie.Hash()
|
root := trie.Hash()
|
||||||
for _, kv := range vals {
|
for _, kv := range vals {
|
||||||
proofs, _ := ethdb.NewMemDatabase()
|
proofs := ethdb.NewMemDatabase()
|
||||||
if trie.Prove(kv.k, 0, proofs) != nil {
|
if trie.Prove(kv.k, 0, proofs) != nil {
|
||||||
t.Fatalf("missing key %x while constructing proof", kv.k)
|
t.Fatalf("missing key %x while constructing proof", kv.k)
|
||||||
}
|
}
|
||||||
|
|
@ -53,7 +53,7 @@ func TestProof(t *testing.T) {
|
||||||
func TestOneElementProof(t *testing.T) {
|
func TestOneElementProof(t *testing.T) {
|
||||||
trie := new(Trie)
|
trie := new(Trie)
|
||||||
updateString(trie, "k", "v")
|
updateString(trie, "k", "v")
|
||||||
proofs, _ := ethdb.NewMemDatabase()
|
proofs := ethdb.NewMemDatabase()
|
||||||
trie.Prove([]byte("k"), 0, proofs)
|
trie.Prove([]byte("k"), 0, proofs)
|
||||||
if len(proofs.Keys()) != 1 {
|
if len(proofs.Keys()) != 1 {
|
||||||
t.Error("proof should have one element")
|
t.Error("proof should have one element")
|
||||||
|
|
@ -71,7 +71,7 @@ func TestVerifyBadProof(t *testing.T) {
|
||||||
trie, vals := randomTrie(800)
|
trie, vals := randomTrie(800)
|
||||||
root := trie.Hash()
|
root := trie.Hash()
|
||||||
for _, kv := range vals {
|
for _, kv := range vals {
|
||||||
proofs, _ := ethdb.NewMemDatabase()
|
proofs := ethdb.NewMemDatabase()
|
||||||
trie.Prove(kv.k, 0, proofs)
|
trie.Prove(kv.k, 0, proofs)
|
||||||
if len(proofs.Keys()) == 0 {
|
if len(proofs.Keys()) == 0 {
|
||||||
t.Fatal("zero length proof")
|
t.Fatal("zero length proof")
|
||||||
|
|
@ -109,7 +109,7 @@ func BenchmarkProve(b *testing.B) {
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
kv := vals[keys[i%len(keys)]]
|
kv := vals[keys[i%len(keys)]]
|
||||||
proofs, _ := ethdb.NewMemDatabase()
|
proofs := ethdb.NewMemDatabase()
|
||||||
if trie.Prove(kv.k, 0, proofs); len(proofs.Keys()) == 0 {
|
if trie.Prove(kv.k, 0, proofs); len(proofs.Keys()) == 0 {
|
||||||
b.Fatalf("zero length proof for %x", kv.k)
|
b.Fatalf("zero length proof for %x", kv.k)
|
||||||
}
|
}
|
||||||
|
|
@ -123,7 +123,7 @@ func BenchmarkVerifyProof(b *testing.B) {
|
||||||
var proofs []*ethdb.MemDatabase
|
var proofs []*ethdb.MemDatabase
|
||||||
for k := range vals {
|
for k := range vals {
|
||||||
keys = append(keys, k)
|
keys = append(keys, k)
|
||||||
proof, _ := ethdb.NewMemDatabase()
|
proof := ethdb.NewMemDatabase()
|
||||||
trie.Prove([]byte(k), 0, proof)
|
trie.Prove([]byte(k), 0, proof)
|
||||||
proofs = append(proofs, proof)
|
proofs = append(proofs, proof)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,18 +28,14 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func newEmptySecure() *SecureTrie {
|
func newEmptySecure() *SecureTrie {
|
||||||
diskdb, _ := ethdb.NewMemDatabase()
|
trie, _ := NewSecure(common.Hash{}, NewDatabase(ethdb.NewMemDatabase()), 0)
|
||||||
triedb := NewDatabase(diskdb)
|
|
||||||
|
|
||||||
trie, _ := NewSecure(common.Hash{}, triedb, 0)
|
|
||||||
return trie
|
return trie
|
||||||
}
|
}
|
||||||
|
|
||||||
// makeTestSecureTrie creates a large enough secure trie for testing.
|
// makeTestSecureTrie creates a large enough secure trie for testing.
|
||||||
func makeTestSecureTrie() (*Database, *SecureTrie, map[string][]byte) {
|
func makeTestSecureTrie() (*Database, *SecureTrie, map[string][]byte) {
|
||||||
// Create an empty trie
|
// Create an empty trie
|
||||||
diskdb, _ := ethdb.NewMemDatabase()
|
triedb := NewDatabase(ethdb.NewMemDatabase())
|
||||||
triedb := NewDatabase(diskdb)
|
|
||||||
|
|
||||||
trie, _ := NewSecure(common.Hash{}, triedb, 0)
|
trie, _ := NewSecure(common.Hash{}, triedb, 0)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,7 @@ import (
|
||||||
// makeTestTrie create a sample test trie to test node-wise reconstruction.
|
// makeTestTrie create a sample test trie to test node-wise reconstruction.
|
||||||
func makeTestTrie() (*Database, *Trie, map[string][]byte) {
|
func makeTestTrie() (*Database, *Trie, map[string][]byte) {
|
||||||
// Create an empty trie
|
// Create an empty trie
|
||||||
diskdb, _ := ethdb.NewMemDatabase()
|
triedb := NewDatabase(ethdb.NewMemDatabase())
|
||||||
triedb := NewDatabase(diskdb)
|
|
||||||
trie, _ := New(common.Hash{}, triedb)
|
trie, _ := New(common.Hash{}, triedb)
|
||||||
|
|
||||||
// Fill it with some arbitrary data
|
// Fill it with some arbitrary data
|
||||||
|
|
@ -89,18 +88,13 @@ func checkTrieConsistency(db *Database, root common.Hash) error {
|
||||||
|
|
||||||
// Tests that an empty trie is not scheduled for syncing.
|
// Tests that an empty trie is not scheduled for syncing.
|
||||||
func TestEmptyTrieSync(t *testing.T) {
|
func TestEmptyTrieSync(t *testing.T) {
|
||||||
diskdbA, _ := ethdb.NewMemDatabase()
|
dbA := NewDatabase(ethdb.NewMemDatabase())
|
||||||
triedbA := NewDatabase(diskdbA)
|
dbB := NewDatabase(ethdb.NewMemDatabase())
|
||||||
|
emptyA, _ := New(common.Hash{}, dbA)
|
||||||
diskdbB, _ := ethdb.NewMemDatabase()
|
emptyB, _ := New(emptyRoot, dbB)
|
||||||
triedbB := NewDatabase(diskdbB)
|
|
||||||
|
|
||||||
emptyA, _ := New(common.Hash{}, triedbA)
|
|
||||||
emptyB, _ := New(emptyRoot, triedbB)
|
|
||||||
|
|
||||||
for i, trie := range []*Trie{emptyA, emptyB} {
|
for i, trie := range []*Trie{emptyA, emptyB} {
|
||||||
diskdb, _ := ethdb.NewMemDatabase()
|
if req := NewTrieSync(trie.Hash(), ethdb.NewMemDatabase(), nil).Missing(1); len(req) != 0 {
|
||||||
if req := NewTrieSync(trie.Hash(), diskdb, 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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -116,7 +110,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
|
||||||
diskdb, _ := ethdb.NewMemDatabase()
|
diskdb := ethdb.NewMemDatabase()
|
||||||
triedb := NewDatabase(diskdb)
|
triedb := NewDatabase(diskdb)
|
||||||
sched := NewTrieSync(srcTrie.Hash(), diskdb, nil)
|
sched := NewTrieSync(srcTrie.Hash(), diskdb, nil)
|
||||||
|
|
||||||
|
|
@ -149,7 +143,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
|
||||||
diskdb, _ := ethdb.NewMemDatabase()
|
diskdb := ethdb.NewMemDatabase()
|
||||||
triedb := NewDatabase(diskdb)
|
triedb := NewDatabase(diskdb)
|
||||||
sched := NewTrieSync(srcTrie.Hash(), diskdb, nil)
|
sched := NewTrieSync(srcTrie.Hash(), diskdb, nil)
|
||||||
|
|
||||||
|
|
@ -187,7 +181,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
|
||||||
diskdb, _ := ethdb.NewMemDatabase()
|
diskdb := ethdb.NewMemDatabase()
|
||||||
triedb := NewDatabase(diskdb)
|
triedb := NewDatabase(diskdb)
|
||||||
sched := NewTrieSync(srcTrie.Hash(), diskdb, nil)
|
sched := NewTrieSync(srcTrie.Hash(), diskdb, nil)
|
||||||
|
|
||||||
|
|
@ -228,7 +222,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
|
||||||
diskdb, _ := ethdb.NewMemDatabase()
|
diskdb := ethdb.NewMemDatabase()
|
||||||
triedb := NewDatabase(diskdb)
|
triedb := NewDatabase(diskdb)
|
||||||
sched := NewTrieSync(srcTrie.Hash(), diskdb, nil)
|
sched := NewTrieSync(srcTrie.Hash(), diskdb, nil)
|
||||||
|
|
||||||
|
|
@ -275,7 +269,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
|
||||||
diskdb, _ := ethdb.NewMemDatabase()
|
diskdb := ethdb.NewMemDatabase()
|
||||||
triedb := NewDatabase(diskdb)
|
triedb := NewDatabase(diskdb)
|
||||||
sched := NewTrieSync(srcTrie.Hash(), diskdb, nil)
|
sched := NewTrieSync(srcTrie.Hash(), diskdb, nil)
|
||||||
|
|
||||||
|
|
@ -315,7 +309,7 @@ func TestIncompleteTrieSync(t *testing.T) {
|
||||||
srcDb, srcTrie, _ := makeTestTrie()
|
srcDb, srcTrie, _ := makeTestTrie()
|
||||||
|
|
||||||
// Create a destination trie and sync with the scheduler
|
// Create a destination trie and sync with the scheduler
|
||||||
diskdb, _ := ethdb.NewMemDatabase()
|
diskdb := ethdb.NewMemDatabase()
|
||||||
triedb := NewDatabase(diskdb)
|
triedb := NewDatabase(diskdb)
|
||||||
sched := NewTrieSync(srcTrie.Hash(), diskdb, nil)
|
sched := NewTrieSync(srcTrie.Hash(), diskdb, nil)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,8 +43,7 @@ func init() {
|
||||||
|
|
||||||
// Used for testing
|
// Used for testing
|
||||||
func newEmpty() *Trie {
|
func newEmpty() *Trie {
|
||||||
diskdb, _ := ethdb.NewMemDatabase()
|
trie, _ := New(common.Hash{}, NewDatabase(ethdb.NewMemDatabase()))
|
||||||
trie, _ := New(common.Hash{}, NewDatabase(diskdb))
|
|
||||||
return trie
|
return trie
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -68,8 +67,7 @@ func TestNull(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMissingRoot(t *testing.T) {
|
func TestMissingRoot(t *testing.T) {
|
||||||
diskdb, _ := ethdb.NewMemDatabase()
|
trie, err := New(common.HexToHash("0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"), NewDatabase(ethdb.NewMemDatabase()))
|
||||||
trie, err := New(common.HexToHash("0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"), NewDatabase(diskdb))
|
|
||||||
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")
|
||||||
}
|
}
|
||||||
|
|
@ -82,7 +80,7 @@ func TestMissingNodeDisk(t *testing.T) { testMissingNode(t, false) }
|
||||||
func TestMissingNodeMemonly(t *testing.T) { testMissingNode(t, true) }
|
func TestMissingNodeMemonly(t *testing.T) { testMissingNode(t, true) }
|
||||||
|
|
||||||
func testMissingNode(t *testing.T, memonly bool) {
|
func testMissingNode(t *testing.T, memonly bool) {
|
||||||
diskdb, _ := ethdb.NewMemDatabase()
|
diskdb := ethdb.NewMemDatabase()
|
||||||
triedb := NewDatabase(diskdb)
|
triedb := NewDatabase(diskdb)
|
||||||
|
|
||||||
trie, _ := New(common.Hash{}, triedb)
|
trie, _ := New(common.Hash{}, triedb)
|
||||||
|
|
@ -413,8 +411,7 @@ func (randTest) Generate(r *rand.Rand, size int) reflect.Value {
|
||||||
}
|
}
|
||||||
|
|
||||||
func runRandTest(rt randTest) bool {
|
func runRandTest(rt randTest) bool {
|
||||||
diskdb, _ := ethdb.NewMemDatabase()
|
triedb := NewDatabase(ethdb.NewMemDatabase())
|
||||||
triedb := NewDatabase(diskdb)
|
|
||||||
|
|
||||||
tr, _ := New(common.Hash{}, triedb)
|
tr, _ := New(common.Hash{}, triedb)
|
||||||
values := make(map[string]string) // tracks content of the trie
|
values := make(map[string]string) // tracks content of the trie
|
||||||
|
|
|
||||||
|
|
@ -135,9 +135,9 @@ func (sc *Client) AddSymmetricKey(ctx context.Context, key []byte) (string, erro
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenerateSymmetricKeyFromPassword generates the key from password, stores it, and returns its identifier.
|
// GenerateSymmetricKeyFromPassword generates the key from password, stores it, and returns its identifier.
|
||||||
func (sc *Client) GenerateSymmetricKeyFromPassword(ctx context.Context, passwd []byte) (string, error) {
|
func (sc *Client) GenerateSymmetricKeyFromPassword(ctx context.Context, passwd string) (string, error) {
|
||||||
var id string
|
var id string
|
||||||
return id, sc.c.CallContext(ctx, &id, "shh_generateSymKeyFromPassword", hexutil.Bytes(passwd))
|
return id, sc.c.CallContext(ctx, &id, "shh_generateSymKeyFromPassword", passwd)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasSymmetricKey returns an indication if the key associated with the given id is stored in the node.
|
// HasSymmetricKey returns an indication if the key associated with the given id is stored in the node.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue