@@ -25,6 +25,11 @@ import (
2525 "encoding/binary"
2626 "encoding/hex"
2727 "fmt"
28+ "math/rand"
29+ "strings"
30+ "sync"
31+ "time"
32+
2833 "github.com/perlin-network/noise"
2934 "github.com/perlin-network/noise/skademlia"
3035 "github.com/perlin-network/wavelet/avl"
@@ -36,10 +41,6 @@ import (
3641 "google.golang.org/grpc"
3742 "google.golang.org/grpc/connectivity"
3843 "google.golang.org/grpc/peer"
39- "math/rand"
40- "strings"
41- "sync"
42- "time"
4344)
4445
4546type Ledger struct {
@@ -57,9 +58,10 @@ type Ledger struct {
5758
5859 consensus sync.WaitGroup
5960
60- broadcastNops bool
61- broadcastNopsDelay time.Time
62- broadcastNopsLock sync.Mutex
61+ broadcastNops bool
62+ broadcastNopsMaxDepth uint64
63+ broadcastNopsDelay time.Time
64+ broadcastNopsLock sync.Mutex
6365
6466 sync chan struct {}
6567 syncVotes chan vote
@@ -70,21 +72,49 @@ type Ledger struct {
7072 sendQuota chan struct {}
7173}
7274
73- func NewLedger (kv store.KV , client * skademlia.Client , genesis * string ) * Ledger {
75+ type config struct {
76+ GCDisabled bool
77+ Genesis * string
78+ }
79+
80+ type Option func (cfg * config )
81+
82+ // WithoutGC disables GC. Used for testing purposes.
83+ func WithoutGC () Option {
84+ return func (cfg * config ) {
85+ cfg .GCDisabled = true
86+ }
87+ }
88+
89+ func WithGenesis (genesis * string ) Option {
90+ return func (cfg * config ) {
91+ cfg .Genesis = genesis
92+ }
93+ }
94+
95+ func NewLedger (kv store.KV , client * skademlia.Client , opts ... Option ) * Ledger {
96+ var cfg config
97+ for _ , opt := range opts {
98+ opt (& cfg )
99+ }
100+
74101 logger := log .Node ()
75102
76103 metrics := NewMetrics (context .TODO ())
77104 indexer := NewIndexer ()
78105
79106 accounts := NewAccounts (kv )
80- go accounts .GC (context .Background ())
107+
108+ if ! cfg .GCDisabled {
109+ go accounts .GC (context .Background ())
110+ }
81111
82112 rounds , err := NewRounds (kv , sys .PruningLimit )
83113
84114 var round * Round
85115
86116 if rounds != nil && err != nil {
87- genesis := performInception (accounts .tree , genesis )
117+ genesis := performInception (accounts .tree , cfg . Genesis )
88118 if err := accounts .Commit (nil ); err != nil {
89119 logger .Fatal ().Err (err ).Msg ("BUG: accounts.Commit" )
90120 }
@@ -162,12 +192,13 @@ func (l *Ledger) AddTransaction(tx Transaction) error {
162192 l .gossiper .Push (tx )
163193
164194 l .broadcastNopsLock .Lock ()
165- if tx .Tag != sys .TagNop {
195+ if tx .Tag != sys .TagNop && tx .Sender == l .client .Keys ().PublicKey () {
196+ l .broadcastNops = true
166197 l .broadcastNopsDelay = time .Now ()
167- }
168198
169- if tx .Sender == l .client .Keys ().PublicKey () && l .finalizer .Preferred () == nil {
170- l .broadcastNops = true
199+ if tx .Depth > l .broadcastNopsMaxDepth {
200+ l .broadcastNopsMaxDepth = tx .Depth
201+ }
171202 }
172203 l .broadcastNopsLock .Unlock ()
173204 }
@@ -271,6 +302,16 @@ func (l *Ledger) Snapshot() *avl.Tree {
271302 return l .accounts .Snapshot ()
272303}
273304
305+ // BroadcastingNop returns true if the node is
306+ // supposed to broadcast nop transaction.
307+ func (l * Ledger ) BroadcastingNop () bool {
308+ l .broadcastNopsLock .Lock ()
309+ broadcastNops := l .broadcastNops
310+ l .broadcastNopsLock .Unlock ()
311+
312+ return broadcastNops
313+ }
314+
274315// BroadcastNop has the node send a nop transaction should they have sufficient
275316// balance available. They are broadcasted if no other transaction that is not a nop transaction
276317// is not broadcasted by the node after 500 milliseconds. These conditions only apply so long as
@@ -387,7 +428,7 @@ func (l *Ledger) PullMissingTransactions() {
387428 for _ , buf := range batch .Transactions {
388429 tx , err := UnmarshalTransaction (bytes .NewReader (buf ))
389430 if err != nil {
390- fmt .Printf ("error unmarshaling downloaded tx [%v]: %+v" , err , tx )
431+ fmt .Printf ("error unmarshaling downloaded tx [%v]: %+v\n " , err , tx )
391432 continue
392433 }
393434
@@ -474,8 +515,12 @@ FINALIZE_ROUNDS:
474515 continue FINALIZE_ROUNDS
475516 }
476517
518+ // Only stop broadcasting nops if the most recently added transaction
519+ // has been applied
477520 l .broadcastNopsLock .Lock ()
478- l .broadcastNops = false
521+ if l .broadcastNops && l .broadcastNopsMaxDepth <= l .finalizer .Preferred ().End .Depth {
522+ l .broadcastNops = false
523+ }
479524 l .broadcastNopsLock .Unlock ()
480525
481526 workerChan := make (chan * grpc.ClientConn , 16 )
0 commit comments