@@ -81,7 +81,8 @@ type Table struct {
8181 closeReq chan struct {}
8282 closed chan struct {}
8383
84- nodeAddedHook func (* node ) // for testing
84+ nodeAddedHook func (* bucket , * node )
85+ nodeRemovedHook func (* bucket , * node )
8586}
8687
8788// transport is implemented by the UDP transports.
@@ -131,6 +132,22 @@ func newTable(t transport, db *enode.DB, cfg Config) (*Table, error) {
131132 return tab , nil
132133}
133134
135+ func newMeteredTable (t transport , db * enode.DB , cfg Config ) (* Table , error ) {
136+ tab , err := newTable (t , db , cfg )
137+ if err != nil {
138+ return nil , err
139+ }
140+ if metrics .Enabled {
141+ tab .nodeAddedHook = func (b * bucket , n * node ) {
142+ bucketsCounter [b .index ].Inc (1 )
143+ }
144+ tab .nodeRemovedHook = func (b * bucket , n * node ) {
145+ bucketsCounter [b .index ].Dec (1 )
146+ }
147+ }
148+ return tab , nil
149+ }
150+
134151// Nodes returns all nodes contained in the table.
135152func (tab * Table ) Nodes () []* enode.Node {
136153 if ! tab .isInitDone () {
@@ -498,10 +515,7 @@ func (tab *Table) addSeenNode(n *node) {
498515 n .addedAt = time .Now ()
499516
500517 if tab .nodeAddedHook != nil {
501- tab .nodeAddedHook (n )
502- }
503- if metrics .Enabled {
504- bucketsCounter [b .index ].Inc (1 )
518+ tab .nodeAddedHook (b , n )
505519 }
506520}
507521
@@ -545,10 +559,7 @@ func (tab *Table) addVerifiedNode(n *node) {
545559 n .addedAt = time .Now ()
546560
547561 if tab .nodeAddedHook != nil {
548- tab .nodeAddedHook (n )
549- }
550- if metrics .Enabled {
551- bucketsCounter [b .index ].Inc (1 )
562+ tab .nodeAddedHook (b , n )
552563 }
553564}
554565
@@ -647,11 +658,16 @@ func (tab *Table) bumpInBucket(b *bucket, n *node) bool {
647658}
648659
649660func (tab * Table ) deleteInBucket (b * bucket , n * node ) {
650- if metrics .Enabled && contains (b .entries , n .ID ()) {
651- bucketsCounter [b .index ].Dec (1 )
661+ // Check if the node is actually in the bucket so the removed hook
662+ // isn't called multiple times for the same node.
663+ if ! contains (b .entries , n .ID ()) {
664+ return
652665 }
653666 b .entries = deleteNode (b .entries , n )
654667 tab .removeIP (b , n .IP ())
668+ if tab .nodeRemovedHook != nil {
669+ tab .nodeRemovedHook (b , n )
670+ }
655671}
656672
657673func contains (ns []* node , id enode.ID ) bool {
0 commit comments