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