Commit d674dd7e authored by Kevin Atkinson's avatar Kevin Atkinson

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: default avatarKevin Atkinson <k@kevina.org>
parent eef022cd
......@@ -366,8 +366,7 @@ func (n *IpfsNode) setupIpnsRepublisher() error {
return err
}
n.IpnsRepub = ipnsrp.NewRepublisher(n.Routing, n.Repo.Datastore(), n.Peerstore)
n.IpnsRepub.AddName(n.Identity)
n.IpnsRepub = ipnsrp.NewRepublisher(n.Routing, n.Repo.Datastore(), n.PrivateKey, n.Repo.Keystore())
if cfg.Ipns.RepublishPeriod != "" {
d, err := time.ParseDuration(cfg.Ipns.RepublishPeriod)
......
......@@ -6,18 +6,19 @@ import (
"sync"
"time"
keystore "github.com/ipfs/go-ipfs/keystore"
namesys "github.com/ipfs/go-ipfs/namesys"
pb "github.com/ipfs/go-ipfs/namesys/pb"
path "github.com/ipfs/go-ipfs/path"
dshelp "github.com/ipfs/go-ipfs/thirdparty/ds-help"
routing "gx/ipfs/QmNdaQ8itUU9jEZUwTsG4gHMaPmRfi6FEe89QjQAFbep3M/go-libp2p-routing"
ic "gx/ipfs/QmP1DfoUjiWH2ZBo1PBH6FupdBucbDepx3HpWmEY6JMUpY/go-libp2p-crypto"
ds "gx/ipfs/QmRWDav6mzWseLWeYfVd5fvUKiVe9xNH29YfMF438fG364/go-datastore"
goprocess "gx/ipfs/QmSF8fPo3jgVBAy8fpdjjYqgG87dkJgUprRBHRd2tmfgpP/goprocess"
gpctx "gx/ipfs/QmSF8fPo3jgVBAy8fpdjjYqgG87dkJgUprRBHRd2tmfgpP/goprocess/context"
logging "gx/ipfs/QmSpJByNKFX1sCsHBEp3R73FL4NF6FnQTEGyNAXHm2GS52/go-log"
recpb "gx/ipfs/QmWYCqr6UDqqD1bfRybaAPtbAqcN3TSJpveaBXMwbQ3ePZ/go-libp2p-record/pb"
pstore "gx/ipfs/QmXZSd1qR5BxZkPyuwfT5jpqQFScZccoZvDneXsKzCNHWX/go-libp2p-peerstore"
proto "gx/ipfs/QmZ4Qi3GaRbjcx28Sme5eMH7RQjGkt8wHxt2a65oLaeFEV/gogo-protobuf/proto"
peer "gx/ipfs/QmdS9KpbDyPrieswibZhkod1oXqRwZJrUPzxCofAMWpFGq/go-libp2p-peer"
)
......@@ -31,9 +32,10 @@ var DefaultRebroadcastInterval = time.Hour * 4
const DefaultRecordLifetime = time.Hour * 24
type Republisher struct {
r routing.ValueStore
ds ds.Datastore
ps pstore.Peerstore
r routing.ValueStore
ds ds.Datastore
self ic.PrivKey
ks keystore.Keystore
Interval time.Duration
......@@ -44,23 +46,18 @@ type Republisher struct {
entries map[peer.ID]struct{}
}
func NewRepublisher(r routing.ValueStore, ds ds.Datastore, ps pstore.Peerstore) *Republisher {
// NewRepublisher creates a new Republisher
func NewRepublisher(r routing.ValueStore, ds ds.Datastore, self ic.PrivKey, ks keystore.Keystore) *Republisher {
return &Republisher{
r: r,
ps: ps,
ds: ds,
entries: make(map[peer.ID]struct{}),
self: self,
ks: ks,
Interval: DefaultRebroadcastInterval,
RecordLifetime: DefaultRecordLifetime,
}
}
func (rp *Republisher) AddName(id peer.ID) {
rp.entrylock.Lock()
defer rp.entrylock.Unlock()
rp.entries[id] = struct{}{}
}
func (rp *Republisher) Run(proc goprocess.Process) {
tick := time.NewTicker(rp.Interval)
defer tick.Stop()
......@@ -82,31 +79,61 @@ func (rp *Republisher) republishEntries(p goprocess.Process) error {
ctx, cancel := context.WithCancel(gpctx.OnClosingContext(p))
defer cancel()
for id, _ := range rp.entries {
log.Debugf("republishing ipns entry for %s", id)
priv := rp.ps.PrivKey(id)
err := rp.republishEntry(ctx, rp.self)
if err != nil {
return err
}
// Look for it locally only
_, ipnskey := namesys.IpnsKeysForID(id)
p, seq, err := rp.getLastVal(ipnskey)
if rp.ks != nil {
keyNames, err := rp.ks.List()
if err != nil {
if err == errNoEntry {
continue
}
return err
}
for _, name := range keyNames {
priv, err := rp.ks.Get(name)
if err != nil {
return err
}
err = rp.republishEntry(ctx, priv)
if err != nil {
return err
}
// update record with same sequence number
eol := time.Now().Add(rp.RecordLifetime)
err = namesys.PutRecordToRouting(ctx, priv, p, seq, eol, rp.r, id)
if err != nil {
return err
}
}
return nil
}
func (rp *Republisher) republishEntry(ctx context.Context, priv ic.PrivKey) error {
id, err := peer.IDFromPrivateKey(priv)
if err != nil {
return err
}
log.Debugf("republishing ipns entry for %s", id)
// Look for it locally only
_, ipnskey := namesys.IpnsKeysForID(id)
p, seq, err := rp.getLastVal(ipnskey)
if err != nil {
if err == errNoEntry {
return nil
}
return err
}
// update record with same sequence number
eol := time.Now().Add(rp.RecordLifetime)
err = namesys.PutRecordToRouting(ctx, priv, p, seq, eol, rp.r, id)
if err != nil {
println("put record to routing error: " + err.Error())
return err
}
return nil
}
func (rp *Republisher) getLastVal(k string) (path.Path, uint64, error) {
ival, err := rp.ds.Get(dshelp.NewKeyFromBinary([]byte(k)))
if err != nil {
......
......@@ -78,10 +78,9 @@ func TestRepublish(t *testing.T) {
// The republishers that are contained within the nodes have their timeout set
// to 12 hours. Instead of trying to tweak those, we're just going to pretend
// they dont exist and make our own.
repub := NewRepublisher(publisher.Routing, publisher.Repo.Datastore(), publisher.Peerstore)
repub := NewRepublisher(publisher.Routing, publisher.Repo.Datastore(), publisher.PrivateKey, publisher.Repo.Keystore())
repub.Interval = time.Second
repub.RecordLifetime = time.Second * 5
repub.AddName(publisher.Identity)
proc := goprocess.Go(repub.Run)
defer proc.Close()
......
......@@ -94,6 +94,29 @@ go-sleep 15s
verify_can_resolve "$num_test_nodes" "$id" "$HASH" "republisher fires after twenty seconds"
#
test_expect_success "generate new key" '
KEY2=`ipfsi 1 key gen beepboop --type ed25519`
'
test_expect_success "publish with new key succeeds" '
HASH=$(echo "barfoo" | ipfsi 1 add -q) &&
ipfsi 1 name publish -t 5s -k "$KEY2" $HASH
'
verify_can_resolve "$num_test_nodes" "$KEY2" "$HASH" "new key just after publishing"
go-sleep 5s
verify_cannot_resolve "$num_test_nodes" "$KEY2" "new key cannot resolve after 5 seconds"
go-sleep 15s
verify_can_resolve "$num_test_nodes" "$KEY2" "$HASH" "new key can resolve again after republish"
#
teardown_iptb
test_done
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment