peer ad test passing correctly with embedded proto

This commit is contained in:
херетик
2023-06-16 11:09:04 +01:00
parent 90a3e15baa
commit 1f7145a43d
5 changed files with 118 additions and 64 deletions

View File

@@ -173,7 +173,7 @@ func (ng *Engine) Shutdown() {
func (ng *Engine) Start() {
log.T.Ln("starting engine")
if ng.sub != nil {
log.I.Ln("starting gossip handling")
log.T.Ln("starting gossip handling")
ng.RunAdHandler(ng.HandleAd)
}
for {

View File

@@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"github.com/libp2p/go-libp2p/core/peer"
"reflect"
"github.com/indra-labs/indra/pkg/ad"
@@ -63,8 +64,8 @@ func (ng *Engine) HandleAd(p *pubsub.Message, ctx context.Context) (e error) {
if e = c.Decode(s); fails(e) {
return
}
switch c.Magic() {
case adaddress.Magic:
switch c.(type) {
case *adaddress.Ad:
log.D.Ln("received", reflect.TypeOf(c), "from gossip network")
if addr, ok := c.(*adaddress.Ad); !ok {
return fmt.Errorf(ErrWrongTypeDecode,
@@ -72,7 +73,7 @@ func (ng *Engine) HandleAd(p *pubsub.Message, ctx context.Context) (e error) {
} else {
_ = addr
}
case adintro.Magic:
case *adintro.Ad:
log.D.Ln("received", reflect.TypeOf(c), "from gossip network")
if intr, ok := c.(*adintro.Ad); !ok {
return fmt.Errorf(ErrWrongTypeDecode,
@@ -81,25 +82,44 @@ func (ng *Engine) HandleAd(p *pubsub.Message, ctx context.Context) (e error) {
_ = intr
}
case adservice.Magic:
case *adservice.Ad:
log.D.Ln("received", reflect.TypeOf(c), "from gossip network")
if serv, ok := c.(*adservice.Ad); !ok {
return fmt.Errorf(ErrWrongTypeDecode,
adservice.Magic, reflect.TypeOf(c).String())
} else {
_ = serv
// If we got to here now we can add to the PeerStore.
log.D.S("new ad for service:", c)
var id peer.ID
if id, e = peer.IDFromPublicKey(serv.Key); fails(e) {
return
}
if e = ng.Listener.Host.
Peerstore().Put(id, "service", s.GetAll().ToBytes()); fails(e) {
return
}
}
case adpeer.Magic:
case *adpeer.Ad:
log.D.Ln("received", reflect.TypeOf(c), "from gossip network")
if peer, ok := c.(*adpeer.Ad); !ok {
var ok bool
var pa *adpeer.Ad
if pa, ok = c.(*adpeer.Ad); !ok {
return fmt.Errorf(ErrWrongTypeDecode,
adpeer.Magic, reflect.TypeOf(c).String())
} else if !peer.Validate() {
} else if !pa.Validate() {
return errors.New("peer ad failed validation")
}
// If we got to here now we can add to the PeerStore.
log.D.S("new ad for peer:", c)
var id peer.ID
if id, e = peer.IDFromPublicKey(pa.Key); fails(e) {
return
}
if e = ng.Listener.Host.
Peerstore().Put(id, "peer", s.GetAll().ToBytes()); fails(e) {
return
}
}
return
}

View File

@@ -38,15 +38,33 @@ func TestEngine_PeerStore(t *testing.T) {
defer os.RemoveAll(dataPath)
go eng.Start()
}
newAd := adpeer.New(nonce.NewID(),
engines[0].Manager.GetLocalNodeIdentityPrv(), 20000)
s := splice.New(newAd.Len())
if e = newAd.Encode(s); fails(e) {
time.Sleep(time.Second)
prvKey := engines[0].Manager.GetLocalNodeIdentityPrv()
newPeerAd := adpeer.New(nonce.NewID(),
prvKey, 20000,
time.Now().Add(time.Hour*24*7))
if e = newPeerAd.Sign(prvKey); fails(e) {
return
}
log.D.S("peer ad", newPeerAd)
s := splice.New(newPeerAd.Len())
if e = newPeerAd.Encode(s); fails(e) {
t.FailNow()
}
if e = engines[0].SendAd(newAd); fails(e) {
if e = engines[0].SendAd(newPeerAd); fails(e) {
t.FailNow()
}
//time.Sleep(time.Second)
//newServiceAd := adservice.NewServiceAd(nonce.NewID(),
// engines[0].Manager.GetLocalNodeIdentityPrv(),
// 20000, 54321, time.Now().Add(time.Hour*24*7))
//ss := splice.New(newServiceAd.Len())
//if e = newServiceAd.Encode(ss); fails(e) {
// t.FailNow()
//}
//if e = engines[0].SendAd(newServiceAd); fails(e) {
// t.FailNow()
//}
time.Sleep(time.Second * 3)
cancel()
for i := range engines {

View File

@@ -1,7 +1,6 @@
package adpeer
import (
"github.com/indra-labs/indra/pkg/ad"
"github.com/indra-labs/indra/pkg/crypto"
"github.com/indra-labs/indra/pkg/crypto/nonce"
"github.com/indra-labs/indra/pkg/crypto/sha256"
@@ -9,12 +8,13 @@ import (
"github.com/indra-labs/indra/pkg/engine/magic"
"github.com/indra-labs/indra/pkg/engine/sess"
"github.com/indra-labs/indra/pkg/onions/adintro"
"github.com/indra-labs/indra/pkg/onions/adproto"
"github.com/indra-labs/indra/pkg/onions/reg"
log2 "github.com/indra-labs/indra/pkg/proc/log"
"github.com/indra-labs/indra/pkg/util/qu"
"github.com/indra-labs/indra/pkg/util/slice"
"github.com/indra-labs/indra/pkg/util/splice"
"reflect"
"time"
)
var (
@@ -24,87 +24,92 @@ var (
const (
Magic = "peer"
Len = magic.Len +
nonce.IDLen +
crypto.PubKeyLen + 1 +
slice.Uint32Len +
crypto.SigLen
Len = adproto.Len +
slice.Uint32Len
)
// Ad stores a specification for the fee rate and the service port, which
// must be a well known port to match with a type of service, eg 80 for web, 53
// for DNS, etc. These are also attached to the PeerAd entry via concatenating
// "/service/N" where N is the index of the entry. A zero value at an index
// signals to stop scanning for more subsequent values.
type Ad struct {
ID nonce.ID // This ensures never a repeated signed message.
Key *crypto.Pub // Identity key.
adproto.Ad
RelayRate uint32
Sig crypto.SigBytes
}
func New(id nonce.ID, key *crypto.Prv,
relayRate uint32) (peerAd *Ad) {
var _ coding.Codec = &Ad{}
pk := crypto.DerivePub(key)
s := splice.New(adintro.Len - magic.Len)
s.ID(id).
Pubkey(pk).
Uint32(relayRate)
// New ...
func New(id nonce.ID, key *crypto.Prv, relayRate uint32,
expiry time.Time) (sv *Ad) {
s := splice.New(adintro.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{
ID: id,
Key: pk,
sv = &Ad{
Ad: adproto.Ad{
ID: id,
Key: k,
Expiry: time.Now().Add(adproto.TTL),
Sig: sign,
},
RelayRate: relayRate,
Sig: sign,
}
return
}
func (x *Ad) Decode(s *splice.Splice) (e error) {
if e = magic.TooShort(s.Remaining(), Len-magic.Len,
Magic); fails(e) {
return
}
s.ReadID(&x.ID).
ReadPubkey(&x.Key).
ReadUint32(&x.RelayRate).
ReadTime(&x.Expiry).
ReadSignature(&x.Sig)
return
}
func (x *Ad) Encode(s *splice.Splice) (e error) {
log.T.S("encoding "+reflect.TypeOf(x).String(), x)
x.Splice(s.Magic(Magic))
x.Splice(s)
return
}
func (x *Ad) GetOnion() interface{} { return x }
func (x *Ad) GetOnion() interface{} { return nil }
func (x *Ad) Gossip(sm *sess.Manager, c qu.C) {
log.D.F("propagating peer info for %s",
x.Key.ToBased32Abbreviated())
ad.Gossip(x, sm, c)
log.T.Ln("finished broadcasting peer info")
}
func (x *Ad) Gossip(sm *sess.Manager, c qu.C) {}
func (x *Ad) Len() int { return Len }
func (x *Ad) Magic() string { return Magic }
func (x *Ad) Magic() string { return "" }
func (x *Ad) Splice(s *splice.Splice) {
s.ID(x.ID).
Pubkey(x.Key).
Uint32(x.RelayRate).
Signature(x.Sig)
func (x *Ad) Sign(prv *crypto.Prv) (e error) {
s := splice.New(x.Len())
x.SpliceNoSig(s)
var b crypto.SigBytes
if b, e = crypto.Sign(prv, sha256.Single(s.GetUntil(s.GetCursor()))); fails(e) {
return
}
copy(x.Sig[:], b[:])
return nil
}
func (x *Ad) Validate() bool {
s := splice.New(Len - magic.Len)
s.ID(x.ID).
Pubkey(x.Key).
Uint32(x.RelayRate)
func (x *Ad) Splice(s *splice.Splice) {
x.SpliceNoSig(s)
s.Signature(x.Sig)
}
func (x *Ad) SpliceNoSig(s *splice.Splice) {
Splice(s, x.ID, x.Key, x.RelayRate, x.Expiry)
}
func (x *Ad) Validate() (valid bool) {
s := splice.New(adintro.Len - magic.Len)
x.SpliceNoSig(s)
hash := sha256.Single(s.GetUntil(s.GetCursor()))
key, e := x.Sig.Recover(hash)
if fails(e) {
@@ -116,6 +121,16 @@ func (x *Ad) Validate() bool {
return false
}
func init() { reg.Register(Magic, peerGen) }
func Splice(s *splice.Splice, id nonce.ID, key *crypto.Pub,
relayRate uint32, expiry time.Time) {
func peerGen() coding.Codec { return &Ad{} }
s.Magic(Magic).
ID(id).
Pubkey(key).
Uint32(relayRate).
Time(expiry)
}
func init() { reg.Register(Magic, serviceAdGen) }
func serviceAdGen() coding.Codec { return &Ad{} }

View File

@@ -2,6 +2,7 @@ package adpeer
import (
"testing"
"time"
"github.com/indra-labs/indra"
"github.com/indra-labs/indra/pkg/crypto"
@@ -28,7 +29,7 @@ func TestPeerAd(t *testing.T) {
for i := range pubs {
pubs[i] = crypto.DerivePub(prvs[i])
}
pa := New(id, pr, 20000)
pa := New(id, pr, 20000, time.Now().Add(time.Hour*24*7))
s := splice.New(pa.Len())
if e = pa.Encode(s); fails(e) {
t.Fatalf("did not encode")