Parcourir la source

node/pkg/common: guardian set state node cleanup

This feature is dedicated to Chorus One, who really like to rotate
node keys! :-)

https://github.com/certusone/wormhole/issues/304

Change-Id: Ic0f1e52095676222970752b1e2ac893d7f0915ec
Leo il y a 4 ans
Parent
commit
621962982a
2 fichiers modifiés avec 34 ajouts et 0 suppressions
  1. 20 0
      node/pkg/common/guardianset.go
  2. 14 0
      node/pkg/p2p/p2p.go

+ 20 - 0
node/pkg/common/guardianset.go

@@ -6,6 +6,7 @@ import (
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/libp2p/go-libp2p-core/peer"
 	"sync"
+	"time"
 )
 
 // MaxGuardianCount specifies the maximum number of guardians supported by on-chain contracts.
@@ -24,6 +25,10 @@ const MaxGuardianCount = 19
 // accidentally reaching the limit due to operational mistakes.
 const MaxNodesPerGuardian = 15
 
+// MaxStateAge specified the maximum age of state entries in seconds. Expired entries are purged
+// from the state by Cleanup().
+const MaxStateAge = 1 * time.Minute
+
 type GuardianSet struct {
 	// Guardian's public key hashes truncated by the ETH standard hashing mechanism (20 bytes).
 	Keys []common.Address
@@ -132,3 +137,18 @@ func (st *GuardianSetState) GetAll() map[common.Address]map[peer.ID]*gossipv1.He
 
 	return ret
 }
+
+// Cleanup removes expired entries from the state.
+func (st *GuardianSetState) Cleanup() {
+	st.mu.Lock()
+	defer st.mu.Unlock()
+
+	for addr, v := range st.lastHeartbeats {
+		for peerId, hb := range v {
+			ts := time.Unix(hb.Timestamp, 0)
+			if time.Since(ts) > MaxStateAge {
+				delete(st.lastHeartbeats[addr], peerId)
+			}
+		}
+	}
+}

+ 14 - 0
node/pkg/p2p/p2p.go

@@ -178,6 +178,20 @@ func Run(obsvC chan *gossipv1.SignedObservation, sendC chan []byte, signedInC ch
 
 		bootTime := time.Now()
 
+		// Periodically run guardian state set cleanup.
+		go func() {
+			ticker := time.NewTicker(15 * time.Second)
+			defer ticker.Stop()
+			for {
+				select {
+				case <-ticker.C:
+					gst.Cleanup()
+				case <-ctx.Done():
+					return
+				}
+			}
+		}()
+
 		go func() {
 			ctr := int64(0)
 			tick := time.NewTicker(15 * time.Second)