cache public keys and use better method for fetching
Jeromy committed
Mar 30, 2015 at 10:48 UTC
97aeda9ae8ee9287ca27072b1216149260385baa
3 files changed
+35
-16
namesys/routing.go
+28
-13
@@ -8,6 +8,7 @@ import (
8
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
9
pb "github.com/ipfs/go-ipfs/namesys/internal/pb"
10
ci "github.com/ipfs/go-ipfs/p2p/crypto"
11
+ peer "github.com/ipfs/go-ipfs/p2p/peer"
12
routing "github.com/ipfs/go-ipfs/routing"
13
u "github.com/ipfs/go-ipfs/util"
14
)
@@ -65,24 +66,38 @@ func (r *routingResolver) Resolve(ctx context.Context, name string) (u.Key, erro
66
67
// name should be a public key retrievable from ipfs
68
// /ipfs/<name>
68
- key := u.Key("/pk/" + string(hash))
69
- pkval, err := r.routing.GetValue(ctx, key)
70
- if err != nil {
71
- log.Warning("RoutingResolve PubKey Get failed.")
72
- return "", err
73
- }
69
+ var pubkey ci.PubKey
70
+ if dht, ok := r.routing.(routing.PubKeyFetcher); ok {
71
+ // If we have a DHT as our routing system, use optimized fetcher
72
+ pk, err := dht.GetPublicKey(ctx, peer.ID(hash))
73
+ if err != nil {
74
+ log.Warning("RoutingResolve PubKey Get failed.")
75
+ return "", err
76
+ }
77
+ pubkey = pk
78
+ } else {
79
+ key := u.Key("/pk/" + string(hash))
80
+ pkval, err := r.routing.GetValue(ctx, key)
81
+ if err != nil {
82
+ log.Warning("RoutingResolve PubKey Get failed.")
83
+ return "", err
84
+ }
85
75
- // get PublicKey from node.Data
76
- pk, err := ci.UnmarshalPublicKey(pkval)
77
- if err != nil {
78
- return "", err
86
+ // get PublicKey from node.Data
87
+ pk, err := ci.UnmarshalPublicKey(pkval)
88
+ if err != nil {
89
+ return "", err
90
+ }
91
+
92
+ pubkey = pk
93
}
80
- hsh, _ := pk.Hash()
94
+
95
+ hsh, _ := pubkey.Hash()
96
log.Debugf("pk hash = %s", u.Key(hsh))
97
98
// check sig with pk
84
- if ok, err := pk.Verify(ipnsEntryDataForSig(entry), entry.GetSignature()); err != nil || !ok {
85
- return "", fmt.Errorf("Invalid value. Not signed by PrivateKey corresponding to %v", pk)
99
+ if ok, err := pubkey.Verify(ipnsEntryDataForSig(entry), entry.GetSignature()); err != nil || !ok {
100
+ return "", fmt.Errorf("Invalid value. Not signed by PrivateKey corresponding to %v", pubkey)
101
}
102
103
// ok sig checks out. this is a valid name.
routing/dht/records.go
+2
-3
@@ -18,7 +18,7 @@ func KeyForPublicKey(id peer.ID) u.Key {
18
return u.Key("/pk/" + string(id))
19
}
20
21
-func (dht *IpfsDHT) getPublicKeyOnline(ctx context.Context, p peer.ID) (ci.PubKey, error) {
21
+func (dht *IpfsDHT) GetPublicKey(ctx context.Context, p peer.ID) (ci.PubKey, error) {
22
log.Debugf("getPublicKey for: %s", p)
23
24
// check locally.
@@ -42,7 +42,6 @@ func (dht *IpfsDHT) getPublicKeyOnline(ctx context.Context, p peer.ID) (ci.PubKe
42
log.Debugf("pk for %s not in peerstore, and peer failed. trying dht.", p)
43
pkkey := KeyForPublicKey(p)
44
45
- // ok, now try the dht. Anyone who has previously fetched the key should have it
45
val, err := dht.GetValue(ctxT, pkkey)
46
if err != nil {
47
log.Warning("Failed to find requested public key.")
@@ -132,7 +131,7 @@ func (dht *IpfsDHT) verifyRecordOnline(ctx context.Context, r *pb.Record) error
131
if len(r.Signature) > 0 {
132
// get the public key, search for it if necessary.
133
p := peer.ID(r.GetAuthor())
135
- pk, err := dht.getPublicKeyOnline(ctx, p)
134
+ pk, err := dht.GetPublicKey(ctx, p)
135
if err != nil {
136
return err
137
}
routing/routing.go
+5
@@ -6,6 +6,7 @@ import (
6
"time"
7
8
context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
9
+ ci "github.com/ipfs/go-ipfs/p2p/crypto"
10
peer "github.com/ipfs/go-ipfs/p2p/peer"
11
u "github.com/ipfs/go-ipfs/util"
12
)
@@ -46,3 +47,7 @@ type IpfsRouting interface {
47
48
// TODO expose io.Closer or plain-old Close error
49
}
50
+
51
+type PubKeyFetcher interface {
52
+ GetPublicKey(context.Context, peer.ID) (ci.PubKey, error)
53
+}