@@ -24,10 +24,12 @@ import (
2424)
2525
2626var (
27- defaultNetworkAddr = "0.0.0.0"
28- defaultNetworkPort = 4445
29- defaultRefreshTime = time .Second * 3600
30- defaultPingTime = time .Second * 10
27+ defaultNetworkAddr = "0.0.0.0"
28+ defaultNetworkPort = 4445
29+ defaultRefreshTime = time .Second * 3600
30+ defaultPingTime = time .Second * 10
31+ defaultCleanupInterval = time .Minute * 2
32+ defaultDisabledKeyExpirationInterval = time .Minute * 30
3133)
3234
3335const maxIterations = 5
@@ -38,6 +40,7 @@ type DHT struct {
3840 options * Options // the options of DHT
3941 network * Network // the network of DHT
4042 store Store // the storage of DHT
43+ metaStore MetaStore // the meta storage of DHT
4144 done chan struct {} // distributed hash table is done
4245 cache storage.KeyValue // store bad bootstrap addresses
4346 pastelClient pastel.Client
@@ -73,7 +76,7 @@ type Options struct {
7376}
7477
7578// NewDHT returns a new DHT node
76- func NewDHT (ctx context.Context , store Store , pc pastel.Client , secInfo * alts.SecInfo , options * Options ) (* DHT , error ) {
79+ func NewDHT (ctx context.Context , store Store , metaStore MetaStore , pc pastel.Client , secInfo * alts.SecInfo , options * Options ) (* DHT , error ) {
7780 // validate the options, if it's invalid, set them to default value
7881 if options .IP == "" {
7982 options .IP = defaultNetworkAddr
@@ -92,6 +95,7 @@ func NewDHT(ctx context.Context, store Store, pc pastel.Client, secInfo *alts.Se
9295 }
9396
9497 s := & DHT {
98+ metaStore : metaStore ,
9599 store : store ,
96100 options : options ,
97101 pastelClient : pc ,
@@ -165,6 +169,7 @@ func (s *DHT) Start(ctx context.Context) error {
165169 }
166170
167171 go s .StartReplicationWorker (ctx )
172+ go s .startDisabledKeysCleanupWorker (ctx )
168173
169174 return nil
170175}
@@ -278,6 +283,12 @@ func (s *DHT) Retrieve(ctx context.Context, key string, localOnly ...bool) ([]by
278283 }
279284
280285 dbKey := hex .EncodeToString (decoded )
286+ if s .metaStore != nil {
287+ if err := s .metaStore .Retrieve (ctx , dbKey ); err == nil {
288+ return nil , fmt .Errorf ("key is disabled: %v" , key )
289+ }
290+ }
291+
281292 // retrieve the key/value from local storage
282293 value , err := s .store .Retrieve (ctx , decoded )
283294 if err == nil && len (value ) > 0 {
@@ -871,3 +882,40 @@ func (s *DHT) storeToAlphaNodes(ctx context.Context, nl *NodeList, data []byte,
871882
872883 return fmt .Errorf ("store data to alpha nodes failed, only %d nodes stored" , finalStoreCount )
873884}
885+
886+ func (s * DHT ) startDisabledKeysCleanupWorker (ctx context.Context ) error {
887+ log .P2P ().WithContext (ctx ).Info ("disabled keys cleanup worker started" )
888+
889+ for {
890+ select {
891+ case <- time .After (defaultCleanupInterval ):
892+ s .cleanupDisabledKeys (ctx )
893+ case <- ctx .Done ():
894+ log .P2P ().WithContext (ctx ).Error ("closing disabled keys cleanup worker" )
895+ return nil
896+ }
897+ }
898+ }
899+
900+ func (s * DHT ) cleanupDisabledKeys (ctx context.Context ) error {
901+ if s .metaStore == nil {
902+ return nil
903+ }
904+
905+ from := time .Now ().Add (- 1 * defaultDisabledKeyExpirationInterval )
906+ disabledKeys , err := s .metaStore .GetDisabledKeys (from )
907+ if err != nil {
908+ return errors .Errorf ("get disabled keys: %w" , err )
909+ }
910+
911+ for i := 0 ; i < len (disabledKeys ); i ++ {
912+ dec , err := hex .DecodeString (disabledKeys [i ].Key )
913+ if err != nil {
914+ log .P2P ().WithContext (ctx ).WithError (err ).Error ("decode disabled key failed" )
915+ continue
916+ }
917+ s .metaStore .Delete (ctx , dec )
918+ }
919+
920+ return nil
921+ }
0 commit comments