Files
indra/pkg/codec/ad/peer/peer.go
l0k18 a2bac60a30 encryption added to tests that didn't refactor correctly
note about encryption and why it must be

test datastore now using same settings as seed

badger options extracted from storage for test and other uses

one place it was missing

all using badger/v3 now

peer database entry count implemented

fixed stray incorrect refactorings

added expiry to interface, now propagates correctly

eliminated type switch with extending of interface

Access to badger View and Update now in Engine

Datastore now available via Listener
2023-08-01 10:50:29 +01:00

145 lines
3.6 KiB
Go

// Package peer provides a message type that provides the base information, identity key and relay rate for an Indra relay.
package peer
import (
"github.com/indra-labs/indra/pkg/codec"
"github.com/indra-labs/indra/pkg/codec/ad"
"github.com/indra-labs/indra/pkg/codec/ad/intro"
"github.com/indra-labs/indra/pkg/codec/reg"
"github.com/indra-labs/indra/pkg/crypto"
"github.com/indra-labs/indra/pkg/crypto/nonce"
"github.com/indra-labs/indra/pkg/crypto/sha256"
log2 "github.com/indra-labs/indra/pkg/proc/log"
"github.com/indra-labs/indra/pkg/util/slice"
"github.com/indra-labs/indra/pkg/util/splice"
"github.com/libp2p/go-libp2p/core/peer"
"time"
)
var (
log = log2.GetLogger()
fails = log.E.Chk
)
const (
Magic = "pead"
Len = ad.Len +
slice.Uint32Len
)
// Ad stores a specification for the relaying fee rate and existence of a peer.
type Ad struct {
// Embed ad.Ad for the common fields
ad.Ad
// RelayRate is the fee for forwarding packets, mSAT/Mb (1024^3 bytes).
RelayRate uint32
}
var _ codec.Codec = &Ad{}
func (x *Ad) PubKey() (key *crypto.Pub) { return x.Key }
func (x *Ad) Fingerprint() (pf string) { return x.Key.Fingerprint() }
func (x *Ad) Expired() (is bool) { return x.Expiry.Before(time.Now()) }
func (x *Ad) GetID() (id peer.ID, e error) {
return peer.IDFromPublicKey(x.Key)
}
// New creates a new Ad and signs it with the provided private key.
func New(id nonce.ID, key *crypto.Prv, relayRate uint32,
expiry time.Time) (peerAd *Ad) {
s := splice.New(intro.Len)
k := crypto.DerivePub(key)
Splice(s, id, k, relayRate, expiry)
hash := sha256.Single(s.GetUntil(s.GetCursor()))
var e error
var sign crypto.SigBytes
if sign, e = crypto.Sign(key, hash); fails(e) {
return nil
}
peerAd = &Ad{
Ad: ad.Ad{
ID: id,
Key: k,
Expiry: time.Now().Add(time.Hour * 3),
Sig: sign,
},
RelayRate: relayRate,
}
log.T.S("peer ad", peerAd)
if e = peerAd.Sign(key); fails(e) {
return nil
}
log.T.S("signed", peerAd)
return
}
// Decode an Ad out of the next bytes of a splice.Splice.
func (x *Ad) Decode(s *splice.Splice) (e error) {
s.ReadID(&x.ID).
ReadPubkey(&x.Key).
ReadUint32(&x.RelayRate).
ReadTime(&x.Expiry).
ReadSignature(&x.Sig)
return
}
// Encode an Ad into a splice.Splice's next bytes. It is assumed the
// signature has been generated, or it would be an invalid Ad.
func (x *Ad) Encode(s *splice.Splice) (e error) {
x.SpliceNoSig(s)
s.Signature(x.Sig)
return
}
// Unwrap returns nil because there is no onion inside.
func (x *Ad) Unwrap() interface{} { return nil }
// Len returns the length of the binary encoded Ad.
func (x *Ad) Len() int { return Len }
// Magic is the identifier indicating an Ad is encoded in the following bytes.
func (x *Ad) Magic() string { return "" }
func (x *Ad) Sign(prv *crypto.Prv) (e error) {
s := splice.New(x.Len())
x.SpliceNoSig(s)
var b []byte
if b, e = prv.Sign(s.GetUntilCursor()); fails(e) {
return
}
copy(x.Sig[:], b[:])
return
}
// Validate checks the signature matches the public key of the Ad.
func (x *Ad) Validate() (valid bool) {
s := splice.New(x.Len())
x.SpliceNoSig(s)
return x.Sig.MatchesPubkey(s.GetUntilCursor(), x.Key) &&
x.Expiry.After(time.Now())
}
// SpliceNoSig serializes the Ad but stops at the signature.
func (x *Ad) SpliceNoSig(s *splice.Splice) {
Splice(s, x.ID, x.Key, x.RelayRate, x.Expiry)
}
// Splice serializes an Ad into a splice.Splice.
func Splice(s *splice.Splice, id nonce.ID, key *crypto.Pub,
relayRate uint32, expiry time.Time) {
s.Magic(Magic).
ID(id).
Pubkey(key).
Uint32(relayRate).
Time(expiry)
}
func init() { reg.Register(Magic, Gen) }
func Gen() codec.Codec { return &Ad{} }