@cryptotaxi247 / kubo / commits / d674dd7e1

repub: iterate through all keys in keystore

Iterate through all keys in the keystore so keys added with "ipfs key gen" behave the same as the <self> key. Don't maintain a separate repub list as it does not really serve a purpose at this point in time. See #3808. License: MIT Signed-off-by: Kevin Atkinson <k@kevina.org>

Kevin Atkinson committed Jun 7, 2017 at 14:23 UTC d674dd7e1fe3c72080b8ba0c18de2a63da498640
4 files changed +79 -31
core/core.go
+1 -2
@@ -366,8 +366,7 @@ func (n *IpfsNode) setupIpnsRepublisher() error {
366 return err
367 }
368
369 - n.IpnsRepub = ipnsrp.NewRepublisher(n.Routing, n.Repo.Datastore(), n.Peerstore)
370 - n.IpnsRepub.AddName(n.Identity)
369 + n.IpnsRepub = ipnsrp.NewRepublisher(n.Routing, n.Repo.Datastore(), n.PrivateKey, n.Repo.Keystore())
370
371 if cfg.Ipns.RepublishPeriod != "" {
372 d, err := time.ParseDuration(cfg.Ipns.RepublishPeriod)
namesys/republisher/repub.go
+54 -27
@@ -6,18 +6,19 @@ import (
6 "sync"
7 "time"
8
9 + keystore "github.com/ipfs/go-ipfs/keystore"
10 namesys "github.com/ipfs/go-ipfs/namesys"
11 pb "github.com/ipfs/go-ipfs/namesys/pb"
12 path "github.com/ipfs/go-ipfs/path"
13 dshelp "github.com/ipfs/go-ipfs/thirdparty/ds-help"
14
15 routing "gx/ipfs/QmNdaQ8itUU9jEZUwTsG4gHMaPmRfi6FEe89QjQAFbep3M/go-libp2p-routing"
16 + ic "gx/ipfs/QmP1DfoUjiWH2ZBo1PBH6FupdBucbDepx3HpWmEY6JMUpY/go-libp2p-crypto"
17 ds "gx/ipfs/QmRWDav6mzWseLWeYfVd5fvUKiVe9xNH29YfMF438fG364/go-datastore"
18 goprocess "gx/ipfs/QmSF8fPo3jgVBAy8fpdjjYqgG87dkJgUprRBHRd2tmfgpP/goprocess"
19 gpctx "gx/ipfs/QmSF8fPo3jgVBAy8fpdjjYqgG87dkJgUprRBHRd2tmfgpP/goprocess/context"
20 logging "gx/ipfs/QmSpJByNKFX1sCsHBEp3R73FL4NF6FnQTEGyNAXHm2GS52/go-log"
21 recpb "gx/ipfs/QmWYCqr6UDqqD1bfRybaAPtbAqcN3TSJpveaBXMwbQ3ePZ/go-libp2p-record/pb"
20 - pstore "gx/ipfs/QmXZSd1qR5BxZkPyuwfT5jpqQFScZccoZvDneXsKzCNHWX/go-libp2p-peerstore"
22 proto "gx/ipfs/QmZ4Qi3GaRbjcx28Sme5eMH7RQjGkt8wHxt2a65oLaeFEV/gogo-protobuf/proto"
23 peer "gx/ipfs/QmdS9KpbDyPrieswibZhkod1oXqRwZJrUPzxCofAMWpFGq/go-libp2p-peer"
24 )
@@ -31,9 +32,10 @@ var DefaultRebroadcastInterval = time.Hour * 4
32 const DefaultRecordLifetime = time.Hour * 24
33
34 type Republisher struct {
34 - r routing.ValueStore
35 - ds ds.Datastore
36 - ps pstore.Peerstore
35 + r routing.ValueStore
36 + ds ds.Datastore
37 + self ic.PrivKey
38 + ks keystore.Keystore
39
40 Interval time.Duration
41
@@ -44,23 +46,18 @@ type Republisher struct {
46 entries map[peer.ID]struct{}
47 }
48
47 -func NewRepublisher(r routing.ValueStore, ds ds.Datastore, ps pstore.Peerstore) *Republisher {
49 +// NewRepublisher creates a new Republisher
50 +func NewRepublisher(r routing.ValueStore, ds ds.Datastore, self ic.PrivKey, ks keystore.Keystore) *Republisher {
51 return &Republisher{
52 r: r,
50 - ps: ps,
53 ds: ds,
52 - entries: make(map[peer.ID]struct{}),
54 + self: self,
55 + ks: ks,
56 Interval: DefaultRebroadcastInterval,
57 RecordLifetime: DefaultRecordLifetime,
58 }
59 }
60
58 -func (rp *Republisher) AddName(id peer.ID) {
59 - rp.entrylock.Lock()
60 - defer rp.entrylock.Unlock()
61 - rp.entries[id] = struct{}{}
62 -}
63 -
61 func (rp *Republisher) Run(proc goprocess.Process) {
62 tick := time.NewTicker(rp.Interval)
63 defer tick.Stop()
@@ -82,31 +79,61 @@ func (rp *Republisher) republishEntries(p goprocess.Process) error {
79 ctx, cancel := context.WithCancel(gpctx.OnClosingContext(p))
80 defer cancel()
81
85 - for id, _ := range rp.entries {
86 - log.Debugf("republishing ipns entry for %s", id)
87 - priv := rp.ps.PrivKey(id)
82 + err := rp.republishEntry(ctx, rp.self)
83 + if err != nil {
84 + return err
85 + }
86
89 - // Look for it locally only
90 - _, ipnskey := namesys.IpnsKeysForID(id)
91 - p, seq, err := rp.getLastVal(ipnskey)
87 + if rp.ks != nil {
88 + keyNames, err := rp.ks.List()
89 if err != nil {
93 - if err == errNoEntry {
94 - continue
95 - }
90 return err
91 }
92 + for _, name := range keyNames {
93 + priv, err := rp.ks.Get(name)
94 + if err != nil {
95 + return err
96 + }
97 + err = rp.republishEntry(ctx, priv)
98 + if err != nil {
99 + return err
100 + }
101
99 - // update record with same sequence number
100 - eol := time.Now().Add(rp.RecordLifetime)
101 - err = namesys.PutRecordToRouting(ctx, priv, p, seq, eol, rp.r, id)
102 - if err != nil {
103 - return err
102 }
103 }
104
105 return nil
106 }
107
108 +func (rp *Republisher) republishEntry(ctx context.Context, priv ic.PrivKey) error {
109 + id, err := peer.IDFromPrivateKey(priv)
110 + if err != nil {
111 + return err
112 + }
113 +
114 + log.Debugf("republishing ipns entry for %s", id)
115 +
116 + // Look for it locally only
117 + _, ipnskey := namesys.IpnsKeysForID(id)
118 + p, seq, err := rp.getLastVal(ipnskey)
119 + if err != nil {
120 + if err == errNoEntry {
121 + return nil
122 + }
123 + return err
124 + }
125 +
126 + // update record with same sequence number
127 + eol := time.Now().Add(rp.RecordLifetime)
128 + err = namesys.PutRecordToRouting(ctx, priv, p, seq, eol, rp.r, id)
129 + if err != nil {
130 + println("put record to routing error: " + err.Error())
131 + return err
132 + }
133 +
134 + return nil
135 +}
136 +
137 func (rp *Republisher) getLastVal(k string) (path.Path, uint64, error) {
138 ival, err := rp.ds.Get(dshelp.NewKeyFromBinary([]byte(k)))
139 if err != nil {
namesys/republisher/repub_test.go
+1 -2
@@ -78,10 +78,9 @@ func TestRepublish(t *testing.T) {
78 // The republishers that are contained within the nodes have their timeout set
79 // to 12 hours. Instead of trying to tweak those, we're just going to pretend
80 // they dont exist and make our own.
81 - repub := NewRepublisher(publisher.Routing, publisher.Repo.Datastore(), publisher.Peerstore)
81 + repub := NewRepublisher(publisher.Routing, publisher.Repo.Datastore(), publisher.PrivateKey, publisher.Repo.Keystore())
82 repub.Interval = time.Second
83 repub.RecordLifetime = time.Second * 5
84 - repub.AddName(publisher.Identity)
84
85 proc := goprocess.Go(repub.Run)
86 defer proc.Close()
test/sharness/t0240-republisher.sh
+23
@@ -94,6 +94,29 @@ go-sleep 15s
94
95 verify_can_resolve "$num_test_nodes" "$id" "$HASH" "republisher fires after twenty seconds"
96
97 +#
98 +
99 +test_expect_success "generate new key" '
100 +KEY2=`ipfsi 1 key gen beepboop --type ed25519`
101 +'
102 +
103 +test_expect_success "publish with new key succeeds" '
104 + HASH=$(echo "barfoo" | ipfsi 1 add -q) &&
105 + ipfsi 1 name publish -t 5s -k "$KEY2" $HASH
106 +'
107 +
108 +verify_can_resolve "$num_test_nodes" "$KEY2" "$HASH" "new key just after publishing"
109 +
110 +go-sleep 5s
111 +
112 +verify_cannot_resolve "$num_test_nodes" "$KEY2" "new key cannot resolve after 5 seconds"
113 +
114 +go-sleep 15s
115 +
116 +verify_can_resolve "$num_test_nodes" "$KEY2" "$HASH" "new key can resolve again after republish"
117 +
118 +#
119 +
120 teardown_iptb
121
122 test_done