Exemple #1
0
// getOrRequestPublicIdentity retrieves the needed public identity from bmd
// or sends a getpubkey request if it doesn't exist in its database. If both
// return types are nil, it means a getpubkey request has been queued.
func (s *server) getOrRequestPublicIdentity(user uint32, address string) (*identity.Public, error) {
	serverLog.Debug("getOrRequestPublicIdentity called for ", address)
	id, err := s.bmd.GetIdentity(address)
	if err == nil {
		return id, nil
	} else if err != rpc.ErrIdentityNotFound {
		return nil, err
	}

	addr, err := bmutil.DecodeAddress(address)
	if err != nil {
		return nil, fmt.Errorf("Failed to decode address: %v", err)
	}

	serverLog.Debug("getOrRequestPublicIdentity: address not found, send pubkey request.")
	// We don't have the identity so craft a getpubkey request.
	var tag wire.ShaHash
	copy(tag[:], addr.Tag())

	msg := obj.NewGetPubKey(0, time.Now().Add(defaultGetpubkeyExpiry),
		addr.Version, addr.Stream, (*wire.RipeHash)(&addr.Ripe), &tag)

	// Enqueue the request for proof-of-work.
	b := wire.EncodeMessage(msg.MsgObject())[8:] // exclude nonce
	target := pow.CalculateTarget(uint64(len(b)),
		uint64(msg.Header().Expiration().Sub(time.Now()).Seconds()),
		pow.DefaultData)

	s.pow.Run(target, b, func(nonce pow.Nonce) {
		err := s.Send(append(nonce.Bytes(), b...))
		if err != nil {
			serverLog.Error("Could not run pow: ", err)
		}

		// Store a record of the public key request.
		count, _ := s.pk.New(address)
		serverLog.Tracef("getOrRequestPublicIdentity: Requested address %s %d time(s).",
			address, count)
	})

	return nil, nil
}
Exemple #2
0
// newGetpubkey is called when a new getpubkey is received by the RPC client.
// Getpubkey requests are guaranteed to be received in ascending order of
// counter value.
func (s *server) newGetpubkey(counter uint64, object []byte) {
	// Store counter value.
	atomic.StoreUint64(&s.getpubkeyCounter, counter)

	msg := &obj.GetPubKey{}
	err := msg.Decode(bytes.NewReader(object))
	if err != nil {
		serverLog.Errorf("Failed to decode getpubkey #%d from bytes: %v",
			counter, err)
		return // Ignore message.
	}

	var privID *keymgr.PrivateID
	header := msg.Header()

	// Check if the getpubkey request corresponds to any of our identities.
	for _, user := range s.users {
		err = user.Keys.ForEach(func(id *keymgr.PrivateID) error {
			if id.Disabled || id.IsChan { // We don't care about these.
				return nil
			}

			var cond bool // condition to satisfy
			switch header.Version {
			case obj.SimplePubKeyVersion, obj.ExtendedPubKeyVersion:
				cond = bytes.Equal(id.Private.Address.Ripe[:], msg.Ripe[:])
			case obj.TagGetPubKeyVersion:
				cond = bytes.Equal(id.Private.Address.Tag(), msg.Tag[:])
			}
			if cond {
				privID = id
				return errors.New("We have a match.")
			}
			return nil
		})
		if err != nil {
			break
		}
	}
	if err == nil {
		return
	}

	addr := privID.Address()
	serverLog.Infof("Received a getpubkey request for %s, sending out the pubkey.", addr)

	// Generate a pubkey message.
	pkMsg, err := cipher.GeneratePubKey(&privID.Private, defaultPubkeyExpiry)
	if err != nil {
		serverLog.Errorf("Failed to generate pubkey for %s: %v", addr, err)
		return
	}

	// Add it to pow queue.
	pkObj := pkMsg.Object().MsgObject()
	pkHeader := pkObj.Header()
	b := wire.EncodeMessage(pkObj)[8:] // exclude nonce
	target := pow.CalculateTarget(uint64(len(b)),
		uint64(pkHeader.Expiration().Sub(time.Now()).Seconds()),
		pow.DefaultData)

	s.pow.Run(target, b, func(nonce pow.Nonce) {
		s.Send(append(nonce.Bytes(), b...))
	})
}