// Determines which algorithm to use. Note: f(a, b) = f(b, a) func SelectBest(myPrefs, theirPrefs string) (string, error) { // Person with greatest hash gets first choice. myHash := u.Hash([]byte(myPrefs)) theirHash := u.Hash([]byte(theirPrefs)) cmp := bytes.Compare(myHash, theirHash) var firstChoiceArr, secChoiceArr []string if cmp == -1 { firstChoiceArr = strings.Split(theirPrefs, ",") secChoiceArr = strings.Split(myPrefs, ",") } else if cmp == 1 { firstChoiceArr = strings.Split(myPrefs, ",") secChoiceArr = strings.Split(theirPrefs, ",") } else { // Exact same preferences. myPrefsArr := strings.Split(myPrefs, ",") return myPrefsArr[0], nil } for _, secChoice := range secChoiceArr { for _, firstChoice := range firstChoiceArr { if firstChoice == secChoice { return firstChoice, nil } } } return "", errors.New("No algorithms in common!") }
// ID returns the ID of a given Conn. func ID(c Conn) string { l := fmt.Sprintf("%s/%s", c.LocalMultiaddr(), c.LocalPeer().ID()) r := fmt.Sprintf("%s/%s", c.RemoteMultiaddr(), c.RemotePeer().ID()) lh := u.Hash([]byte(l)) rh := u.Hash([]byte(r)) ch := u.XOR(lh, rh) return u.Key(ch).Pretty() }
// KeyHash hashes a key. func KeyHash(k Key) ([]byte, error) { kb, err := k.Bytes() if err != nil { return nil, err } return u.Hash(kb), nil }
// IDFromPubKey retrieves a Public Key from the peer given by pk func IDFromPubKey(pk ic.PubKey) (ID, error) { b, err := pk.Bytes() if err != nil { return nil, err } hash := u.Hash(b) return ID(hash), nil }
// NewBlockWithHash creates a new block when the hash of the data // is already known, this is used to save time in situations where // we are able to be confident that the data is correct func NewBlockWithHash(data []byte, h mh.Multihash) (*Block, error) { if u.Debug { chk := u.Hash(data) if string(chk) != string(h) { return nil, errors.New("Data did not match given hash!") } } return &Block{Data: data, Multihash: h}, nil }
// Encoded returns the encoded raw data version of a Node instance. // It may use a cached encoded version, unless the force flag is given. func (n *Node) Encoded(force bool) ([]byte, error) { if n.encoded == nil || force { var err error n.encoded, err = n.Marshal() if err != nil { return []byte{}, err } n.cached = u.Hash(n.encoded) } return n.encoded, nil }
// ValidatePublicKeyRecord implements ValidatorFunc and // verifies that the passed in record value is the PublicKey // that matches the passed in key. func ValidatePublicKeyRecord(k u.Key, val []byte) error { keyparts := bytes.Split([]byte(k), []byte("/")) if len(keyparts) < 3 { return errors.New("invalid key") } pkh := u.Hash(val) if !bytes.Equal(keyparts[2], pkh) { return errors.New("public key does not match storage key") } return nil }
func TestRoutingResolve(t *testing.T) { local := peer.WithIDString("testID") lds := ds.NewMapDatastore() d := mock.NewMockRouter(local, lds) resolver := NewRoutingResolver(d) publisher := NewRoutingPublisher(d) privk, pubk, err := ci.GenerateKeyPair(ci.RSA, 512) if err != nil { t.Fatal(err) } err = publisher.Publish(privk, "Hello") if err == nil { t.Fatal("should have errored out when publishing a non-multihash val") } h := u.Key(u.Hash([]byte("Hello"))).Pretty() err = publisher.Publish(privk, h) if err != nil { t.Fatal(err) } pubkb, err := pubk.Bytes() if err != nil { t.Fatal(err) } pkhash := u.Hash(pubkb) res, err := resolver.Resolve(u.Key(pkhash).Pretty()) if err != nil { t.Fatal(err) } if res != h { t.Fatal("Got back incorrect value.") } }
// Publish implements Publisher. Accepts a keypair and a value, // and publishes it out to the routing system func (p *ipnsPublisher) Publish(k ci.PrivKey, value string) error { log.Debugf("namesys: Publish %s", value) // validate `value` is a ref (multihash) _, err := mh.FromB58String(value) if err != nil { log.Errorf("hash cast failed: %s", value) return fmt.Errorf("publish value must be str multihash. %v", err) } ctx := context.TODO() data, err := createRoutingEntryData(k, value) if err != nil { log.Error("entry creation failed.") return err } pubkey := k.GetPublic() pkbytes, err := pubkey.Bytes() if err != nil { log.Error("pubkey getbytes failed.") return err } nameb := u.Hash(pkbytes) namekey := u.Key("/pk/" + string(nameb)) log.Debugf("Storing pubkey at: %s", namekey) // Store associated public key timectx, _ := context.WithDeadline(ctx, time.Now().Add(time.Second*4)) err = p.routing.PutValue(timectx, namekey, pkbytes) if err != nil { return err } ipnskey := u.Key("/ipns/" + string(nameb)) log.Debugf("Storing ipns entry at: %s", ipnskey) // Store ipns entry at "/ipns/"+b58(h(pubkey)) timectx, _ = context.WithDeadline(ctx, time.Now().Add(time.Second*4)) err = p.routing.PutValue(timectx, ipnskey, data) if err != nil { return err } return nil }
func TestBlocks(t *testing.T) { d := ds.NewMapDatastore() bs, err := NewBlockService(d, nil) if err != nil { t.Error("failed to construct block service", err) return } b := blocks.NewBlock([]byte("beep boop")) h := u.Hash([]byte("beep boop")) if !bytes.Equal(b.Multihash, h) { t.Error("Block Multihash and data multihash not equal") } if b.Key() != u.Key(h) { t.Error("Block key and data multihash key not equal") } k, err := bs.AddBlock(b) if err != nil { t.Error("failed to add block to BlockService", err) return } if k != b.Key() { t.Error("returned key is not equal to block key", err) } ctx, _ := context.WithTimeout(context.TODO(), time.Second*5) b2, err := bs.GetBlock(ctx, b.Key()) if err != nil { t.Error("failed to retrieve block from BlockService", err) return } if b.Key() != b2.Key() { t.Error("Block keys not equal.") } if !bytes.Equal(b.Data, b2.Data) { t.Error("Block data is not equal.") } }
func newPeerTime(t time.Time) peer.Peer { s := fmt.Sprintf("hmmm time: %v", t) h := u.Hash([]byte(s)) return peer.WithID(peer.ID(h)) }
func RandPeer() peer.Peer { id := make([]byte, 16) crand.Read(id) mhid := u.Hash(id) return peer.WithID(peer.ID(mhid)) }
// NewBlock creates a Block object from opaque data. It will hash the data. func NewBlock(data []byte) *Block { return &Block{Data: data, Multihash: u.Hash(data)} }