Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

les, les/lespay: implement new server pool #20758

Merged
merged 57 commits into from
May 22, 2020
Merged
Changes from 1 commit
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
d6d27cd
les: new server pool
zsfelfoldi Feb 26, 2020
ce4930c
les/utils: NodeStateMachine simplifications
zsfelfoldi Apr 24, 2020
71d1497
les/utils: handle enode.Node inside NodeStateMachine
zsfelfoldi Apr 24, 2020
c73cac6
les/utils: fixed NodeStateMachine tests
zsfelfoldi Apr 24, 2020
aef76b6
les/lespay/client: fixed tests
zsfelfoldi Apr 24, 2020
e769402
les: fixed serverpool test
zsfelfoldi Apr 24, 2020
07bc71a
les/utils: add comments
zsfelfoldi Apr 25, 2020
a5bec6c
les/utils: fix linter warnings
zsfelfoldi Apr 25, 2020
136b341
les: add node state logger, fix bug
zsfelfoldi Apr 25, 2020
0065fe1
les: add persistent redialWait timeouts
zsfelfoldi Apr 26, 2020
1d37de2
les: fixed test and removed debug prints
zsfelfoldi Apr 26, 2020
3604369
les: add metrics
zsfelfoldi Apr 26, 2020
185f59f
p2p/nodestate: moved NodeStateMachine to its own package
zsfelfoldi Apr 28, 2020
1fa4919
p2p/nodestate, les: changed flag/field definition
zsfelfoldi Apr 28, 2020
b032eab
les, p2p/nodestate: fixed tests
zsfelfoldi Apr 28, 2020
44942ee
p2p/nodestate: removed unnecessary errors and added comments
zsfelfoldi Apr 28, 2020
6948793
p2p/nodestate: fix after rebase
zsfelfoldi Apr 28, 2020
8028528
cmd/utils: use les DNS list for --syncmode=light
fjl Apr 29, 2020
e7d7a4f
les: remove redundant ENR filter on DNS output
fjl Apr 29, 2020
095bc6e
les/lespay/client: use sync.Cond in QueueIterator
fjl Apr 29, 2020
52fbd74
les/lespay/client: use sync.Cond in WrsIterator
fjl Apr 29, 2020
a543d42
cmd/utils: revert default DNS setup condition
fjl Apr 29, 2020
c0a1ca3
les/lespay/client: use enode.SignNull in test
fjl Apr 29, 2020
df77440
les/lespay/client: fix wrs iterator panic
fjl Apr 29, 2020
c65ba19
les: remove goroutine in weight callback
fjl Apr 29, 2020
2eb1018
les/lespay/client: fixed race condition in WrsIterator test
zsfelfoldi Apr 29, 2020
3452414
les: move NodeStateMachine construction inside serverPool
zsfelfoldi Apr 29, 2020
12320a5
les/lespay/client: add PreNegFilter
zsfelfoldi May 1, 2020
2d4e7e5
les: nodeWeights field
zsfelfoldi May 2, 2020
4f94866
les: sp test
zsfelfoldi May 4, 2020
477b5cd
les: sp test fix
zsfelfoldi May 4, 2020
95fdee9
les: fixed sp test
zsfelfoldi May 4, 2020
e37b225
les/lespay/client: fixed tests
zsfelfoldi May 4, 2020
2fba0ce
p2p/nodestate: fixed minor issues
zsfelfoldi May 4, 2020
a5c13c5
les: removed dummyQuery
zsfelfoldi May 4, 2020
1562211
les/lespay/client: TestPreNegFilter
zsfelfoldi May 4, 2020
92e5552
les: avoid persisting clock
rjl493456442 May 6, 2020
904b835
les: polish
rjl493456442 May 7, 2020
9a1f898
les: use real-time clock for redialWait
zsfelfoldi May 8, 2020
d1ffbf8
les: refactored node stats, weights and wait time calculation
zsfelfoldi May 8, 2020
8810945
p2p/nodestate: use uint operands for bit shift
zsfelfoldi May 8, 2020
bc628b9
les: remove unnecessary connectedStats flag reset
zsfelfoldi May 10, 2020
b4aed55
les, les/lespay/client: more elegant pre-neg filter
zsfelfoldi May 14, 2020
94315f7
les: add recovery mechanism for UDP not working
zsfelfoldi May 14, 2020
0d34da1
les: removed mclock rtc
zsfelfoldi May 15, 2020
1cc3502
p2p/nodestate: removed mapping conversion, added simple version checking
zsfelfoldi May 15, 2020
478f506
les: drop known node if redialWait becomes extremely long
zsfelfoldi May 15, 2020
33928fe
eth: switched ethEntry back to lower case
zsfelfoldi May 15, 2020
ee8eb42
les: start serverPool first
zsfelfoldi May 15, 2020
816b90b
les: fixed redialWait calculation
zsfelfoldi May 15, 2020
4da949e
les: add mixer timeout
zsfelfoldi May 18, 2020
6041177
p2p/nodestate: fix duplicated flags
rjl493456442 May 20, 2020
0106fae
les/utils: fixed ExpirationFactor.Value overflow error
zsfelfoldi May 21, 2020
5749d01
les: made serverpool test safer
zsfelfoldi May 21, 2020
ab6c8bc
les: make dial timeout safe
zsfelfoldi May 21, 2020
85a22fb
les: more readable redialWait logic
zsfelfoldi May 21, 2020
d038392
les: changed flag names
zsfelfoldi May 22, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
p2p/nodestate: removed unnecessary errors and added comments
  • Loading branch information
zsfelfoldi committed May 15, 2020
commit 44942ee5a1985e1d189150c4e66e906f4a12e9e7
69 changes: 41 additions & 28 deletions p2p/nodestate/nodestate.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,13 @@ type (
saveNodeHook func(*nodeInfo)
}

// Flags represents a set of flags from a certain setup
Flags struct {
mask bitMask
setup *Setup
}

// Field represents a field from a certain setup
Field struct {
index int
setup *Setup
Expand Down Expand Up @@ -172,12 +174,7 @@ type (
}
)

var (
errAlreadyStarted = errors.New("state machine already started")
errNotStarted = errors.New("state machine not started yet")
errOutOfBound = errors.New("field index out of bound")
errInvalidField = errors.New("invalid field type")
)
var errInvalidField = errors.New("invalid field type")

// offlineState is a special state that is assumed to be set before a node is loaded from
// the database and after it is shut down.
Expand All @@ -203,6 +200,7 @@ func (s *Setup) NewPersistentFlag(name string) Flags {
return f
}

// OfflineFlag returns the system-defined offline flag belonging to the given setup
func (s *Setup) OfflineFlag() Flags {
return Flags{mask: offlineState, setup: s}
}
Expand All @@ -229,6 +227,7 @@ func (s *Setup) NewPersistentField(name string, ftype reflect.Type, encode func(
return f
}

// flagOp implements binary flag operations and also checks whether the operands belong to the same setup
func flagOp(a, b Flags, trueIfA, trueIfB, trueIfBoth bool) Flags {
if a.setup == nil {
if a.mask != 0 {
Expand Down Expand Up @@ -258,17 +257,31 @@ func flagOp(a, b Flags, trueIfA, trueIfB, trueIfBoth bool) Flags {
return res
}

func (a Flags) And(b Flags) Flags { return flagOp(a, b, false, false, true) }
// And returns the set of flags present in both a and b
func (a Flags) And(b Flags) Flags { return flagOp(a, b, false, false, true) }

// AndNot returns the set of flags present in a but not in b
func (a Flags) AndNot(b Flags) Flags { return flagOp(a, b, true, false, false) }
func (a Flags) Or(b Flags) Flags { return flagOp(a, b, true, true, true) }
func (a Flags) Xor(b Flags) Flags { return flagOp(a, b, true, true, false) }

func (a Flags) HasAll(b Flags) bool { return flagOp(a, b, false, true, false).mask == 0 }
// Or returns the set of flags present in either a or b
func (a Flags) Or(b Flags) Flags { return flagOp(a, b, true, true, true) }

// Xor returns the set of flags present in either a or b but not both
func (a Flags) Xor(b Flags) Flags { return flagOp(a, b, true, true, false) }

// HasAll returns true if b is a subset of a
func (a Flags) HasAll(b Flags) bool { return flagOp(a, b, false, true, false).mask == 0 }

// HasNone returns true if a and b have no shared flags
func (a Flags) HasNone(b Flags) bool { return flagOp(a, b, false, false, true).mask == 0 }
func (a Flags) Equals(b Flags) bool { return flagOp(a, b, true, true, false).mask == 0 }

// Equals returns true if a and b have the same flags set
func (a Flags) Equals(b Flags) bool { return flagOp(a, b, true, true, false).mask == 0 }

// IsEmpty returns true if a has no flags set
func (a Flags) IsEmpty() bool { return a.mask == 0 }

// MergeFlags merges multiple sets of state flags
func MergeFlags(list ...Flags) Flags {
if len(list) == 0 {
return Flags{}
Expand Down Expand Up @@ -340,14 +353,16 @@ func NewNodeStateMachine(db ethdb.KeyValueStore, dbKey []byte, clock mclock.Cloc
return ns
}

func (ns *NodeStateMachine) mask(flags Flags) bitMask {
// stateMask checks whether the set of flags belongs to the same setup and returns its internal bit mask
func (ns *NodeStateMachine) stateMask(flags Flags) bitMask {
if flags.setup != ns.setup && flags.mask != 0 {
rjl493456442 marked this conversation as resolved.
Show resolved Hide resolved
panic("Node state flags belong to a different setup")
}
return flags.mask
}

func (ns *NodeStateMachine) index(field Field) int {
// fieldIndex checks whether the field belongs to the same setup and returns its internal index
func (ns *NodeStateMachine) fieldIndex(field Field) int {
if field.setup != ns.setup {
panic("Node field belongs to a different setup")
}
Expand All @@ -361,28 +376,26 @@ func (ns *NodeStateMachine) index(field Field) int {
// infinite toggling of flags or hazardous/non-deterministic state changes.
// State subscriptions should be installed before loading the node database or making the
// first state update.
func (ns *NodeStateMachine) SubscribeState(flags Flags, callback StateCallback) error {
func (ns *NodeStateMachine) SubscribeState(flags Flags, callback StateCallback) {
ns.lock.Lock()
defer ns.lock.Unlock()

if ns.started {
return errAlreadyStarted
panic("state machine already started")
}
ns.stateSubs = append(ns.stateSubs, stateSub{ns.mask(flags), callback})
return nil
ns.stateSubs = append(ns.stateSubs, stateSub{ns.stateMask(flags), callback})
}

// SubscribeField adds a node field subscription. Same rules apply as for SubscribeState.
func (ns *NodeStateMachine) SubscribeField(field Field, callback FieldCallback) error {
func (ns *NodeStateMachine) SubscribeField(field Field, callback FieldCallback) {
ns.lock.Lock()
defer ns.lock.Unlock()

if ns.started {
return errAlreadyStarted
panic("state machine already started")
}
f := ns.fields[ns.index(field)]
f := ns.fields[ns.fieldIndex(field)]
f.subs = append(f.subs, callback)
return nil
}

// newNode creates a new nodeInfo
Expand All @@ -393,7 +406,7 @@ func (ns *NodeStateMachine) newNode(n *enode.Node) *nodeInfo {
// checkStarted checks whether the state machine has already been started and panics otherwise.
func (ns *NodeStateMachine) checkStarted() {
if !ns.started {
panic(errNotStarted)
panic("state machine not started yet")
}
}

Expand All @@ -402,7 +415,7 @@ func (ns *NodeStateMachine) checkStarted() {
func (ns *NodeStateMachine) Start() {
ns.lock.Lock()
if ns.started {
panic(errAlreadyStarted)
panic("state machine already started")
}
ns.started = true
if ns.db != nil {
Expand Down Expand Up @@ -689,7 +702,7 @@ func (ns *NodeStateMachine) SetState(n *enode.Node, setFlags, resetFlags Flags,
return
}

set, reset := ns.mask(setFlags), ns.mask(resetFlags)
set, reset := ns.stateMask(setFlags), ns.stateMask(resetFlags)
id, node := ns.updateEnode(n)
if node == nil {
if set == 0 {
Expand Down Expand Up @@ -782,7 +795,7 @@ func (ns *NodeStateMachine) AddTimeout(n *enode.Node, flags Flags, timeout time.
if ns.stopped {
return
}
ns.addTimeout(n, ns.mask(flags), timeout)
ns.addTimeout(n, ns.stateMask(flags), timeout)
}

// addTimeout adds a node state timeout associated to the given state flag(s).
Expand Down Expand Up @@ -841,7 +854,7 @@ func (ns *NodeStateMachine) GetField(n *enode.Node, field Field) interface{} {
return nil
}
if _, node := ns.updateEnode(n); node != nil {
return node.fields[ns.index(field)]
return node.fields[ns.fieldIndex(field)]
}
return nil
}
Expand All @@ -859,7 +872,7 @@ func (ns *NodeStateMachine) SetField(n *enode.Node, field Field, value interface
ns.lock.Unlock()
return nil
}
fieldIndex := ns.index(field)
fieldIndex := ns.fieldIndex(field)
f := ns.fields[fieldIndex]
if value != nil && reflect.TypeOf(value) != f.ftype {
log.Error("Invalid field type", "type", reflect.TypeOf(value), "required", f.ftype)
Expand Down Expand Up @@ -894,7 +907,7 @@ func (ns *NodeStateMachine) ForEach(requireFlags, disableFlags Flags, cb func(n
node *enode.Node
state bitMask
}
require, disable := ns.mask(requireFlags), ns.mask(disableFlags)
require, disable := ns.stateMask(requireFlags), ns.stateMask(disableFlags)
var callbacks []callback
for _, node := range ns.nodes {
if node.state&require == require && node.state&disable == 0 {
Expand Down