Created simple path selector function scheme

This commit is contained in:
David Vennik
2023-01-07 10:48:10 +00:00
parent 48bcd9c2e5
commit 6b6a7151a9
9 changed files with 122 additions and 46 deletions

View File

@@ -83,16 +83,32 @@ out:
}
func (cl *Client) RegisterConfirmation(hook confirm.Hook,
on *confirm.OnionSkin) {
cnf nonce.ID) {
cl.Confirms.Add(&confirm.Callback{
ID: on.ID,
Time: time.Now(),
Hook: hook,
Onion: on,
ID: cnf,
Time: time.Now(),
Hook: hook,
})
}
func (cl *Client) SendKeys(nodeID nonce.ID) (hdr, pld *prv.Key, hdrPub,
pldPub *pub.Key, id nonce.ID, hook func(cf nonce.ID), e error) {
if hdr, e = prv.GenerateKey(); check(e) {
return
}
hdrPub = pub.Derive(hdr)
if pld, e = prv.GenerateKey(); check(e) {
return
}
pldPub = pub.Derive(pld)
n := cl.Nodes.FindByID(nodeID)
_ = n
return
}
func (cl *Client) Cleanup() {
// Do cleanup stuff before shutdown.
}

View File

@@ -8,7 +8,6 @@ import (
"github.com/indra-labs/indra/pkg/key/address"
"github.com/indra-labs/indra/pkg/key/pub"
"github.com/indra-labs/indra/pkg/key/signer"
log2 "github.com/indra-labs/indra/pkg/log"
"github.com/indra-labs/indra/pkg/node"
"github.com/indra-labs/indra/pkg/nonce"
"github.com/indra-labs/indra/pkg/session"
@@ -21,8 +20,6 @@ import (
)
func TestPing(t *testing.T) {
// log2.CodeLoc = true
log2.SetLogLevel(log2.Trace)
const nTotal = 4
clients := make([]*Client, nTotal)
var e error
@@ -45,21 +42,20 @@ func TestPing(t *testing.T) {
hop[i] = clients[0].Nodes[i]
}
os := wire.Ping(pn, clients[0].Node, hop, ks)
// log.I.S(os)
quit := qu.T()
log.I.S("sending ping with ID", os[len(os)-1].(*confirm.OnionSkin))
clients[0].RegisterConfirmation(func(cf *confirm.OnionSkin) {
clients[0].RegisterConfirmation(func(cf nonce.ID) {
log.I.S("received ping confirmation ID", cf)
quit.Q()
}, os[len(os)-1].(*confirm.OnionSkin))
}, os[len(os)-1].(*confirm.OnionSkin).ID)
o := os.Assemble()
b := wire.EncodeOnion(o)
hop[0].Send(b)
go func() {
time.Sleep(time.Second)
quit.Q()
t.Error("ping got stuck")
}()
// go func() {
// time.Sleep(time.Second)
// quit.Q()
// t.Error("ping got stuck")
// }()
<-quit.Wait()
for _, v := range clients {
v.Shutdown()
@@ -67,8 +63,6 @@ func TestPing(t *testing.T) {
}
func TestSendKeys(t *testing.T) {
log2.CodeLoc = true
// log2.SetLogLevel(log2.Trace)
const nTotal = 6
clients := make([]*Client, nTotal)
var e error
@@ -97,12 +91,12 @@ func TestSendKeys(t *testing.T) {
}
os := wire.SendKeys(pn, hdr, pld, clients[0].Node, hop, ks)
log.I.S(os)
quit := qu.T()
log.I.S("sending sendkeys with ID", os[len(os)-1].(*confirm.OnionSkin))
clients[0].RegisterConfirmation(func(cf *confirm.OnionSkin) {
quit := qu.T()
clients[0].RegisterConfirmation(func(cf nonce.ID) {
log.I.S("received sendkeys confirmation ID", cf)
quit.Q()
}, os[len(os)-1].(*confirm.OnionSkin))
}, os[len(os)-1].(*confirm.OnionSkin).ID)
o := os.Assemble()
b := wire.EncodeOnion(o)
hop[0].Send(b)
@@ -118,8 +112,6 @@ func TestSendKeys(t *testing.T) {
}
func TestSendPurchase(t *testing.T) {
// log2.CodeLoc = true
// log2.SetLogLevel(log2.Trace)
const nTotal = 6
clients := make([]*Client, nTotal)
var e error
@@ -159,11 +151,6 @@ func TestSendPurchase(t *testing.T) {
o := os.Assemble()
b := wire.EncodeOnion(o)
hop[0].Send(b)
go func() {
time.Sleep(time.Second * 2)
clients[0].Q()
t.Error("sendpurchase got stuck")
}()
<-clients[0].Wait()
for _, v := range clients {
v.Shutdown()
@@ -171,8 +158,6 @@ func TestSendPurchase(t *testing.T) {
}
func TestSendExit(t *testing.T) {
log2.CodeLoc = true
// log2.SetLogLevel(log2.Trace)
const nTotal = 6
clients := make([]*Client, nTotal)
var e error
@@ -218,13 +203,11 @@ func TestSendExit(t *testing.T) {
t.FailNow()
}
quit := qu.T()
// log.I.S(hash, message.ToBytes())
os := wire.SendExit(message, port, clients[0].Node, hop, sess, ks)
clients[0].ExitHooks = clients[0].ExitHooks.Add(hash, func() {
log.I.S("finished")
quit.Q()
})
// clients[0].PendingSessions = append(clients[0].PendingSessions, id)
o := os.Assemble()
b := wire.EncodeOnion(o)
hop[0].Send(b)

View File

@@ -1,10 +0,0 @@
package client
import (
"testing"
)
func TestPurchaseFlow(t *testing.T) {
// This tests the full process of establishing sessions and mocks
// payment and then runs a test on the bandwidth accounting system.
}

View File

@@ -0,0 +1,33 @@
package client
import (
"testing"
"time"
"github.com/cybriq/qu"
)
func TestPurchaseFlow(t *testing.T) {
// This tests the full process of establishing sessions and mocks
// payment and then runs a test on the bandwidth accounting system.
clients, e := CreateMockCircuitClients(6)
if check(e) {
t.Error(e)
t.FailNow()
}
// Start up the clients.
for _, v := range clients {
go v.Start()
}
quit := qu.T()
go func() {
time.Sleep(time.Second * 3)
quit.Q()
}()
selected := clients[0].Nodes.Select(SimpleSelector, clients[1].Node, 4)
_ = selected
<-quit.Wait()
for _, v := range clients {
v.Shutdown()
}
}

36
pkg/client/selector.go Normal file
View File

@@ -0,0 +1,36 @@
package client
import (
"math/rand"
"github.com/indra-labs/indra/pkg/node"
"github.com/indra-labs/indra/pkg/slice"
)
// SimpleSelector is a pure random shuffle selection algorithm for producing
// a list of nodes for an onion.
//
// This function will return nil if there isn't enough
func SimpleSelector(n node.Nodes, exit *node.Node,
count int) (selected node.Nodes) {
// For the purposes of this simple selector algorithm we require unique
// nodes for each hop.
if len(n) < count+1 {
log.E.F("not enough nodes, have %d, need %d", len(n), count+1)
return
}
// Remove the exit from the list of options.
var nCandidates node.Nodes
for i := range n {
if n[i].ID != exit.ID {
nCandidates = append(nCandidates, n[i])
}
}
// Shuffle the list we made
rand.Seed(slice.GetCryptoRandSeed())
rand.Shuffle(len(nCandidates), func(i, j int) {
nCandidates[i], nCandidates[j] = nCandidates[j], nCandidates[i]
})
return nCandidates[:count]
}

View File

@@ -136,3 +136,13 @@ func (n Nodes) DeleteByAddrPort(ip *netip.AddrPort) (nn Nodes, e error) {
}
return
}
type Selector func(n Nodes, exit *Node, count int) (selected Nodes)
func (n Nodes) Select(selector Selector, exit *Node, count int) (selected Nodes) {
if selector == nil {
log.E.Ln("no selector function given")
return
}
return selector(n, exit, count)
}

View File

@@ -265,3 +265,11 @@ func GenerateRandomAddrPortIPv6() (ap *netip.AddrPort) {
a, e = netip.ParseAddrPort(str)
return &a
}
func GetCryptoRandSeed() int64 {
rBytes := make([]byte, 8)
if n, e := rand.Read(rBytes); n != 8 && check(e) {
return 0
}
return int64(DecodeUint64(rBytes))
}

View File

@@ -7,7 +7,7 @@ import (
"github.com/indra-labs/indra/pkg/nonce"
)
type Hook func(cf *OnionSkin)
type Hook func(cf nonce.ID)
type Callback struct {
nonce.ID
@@ -39,7 +39,7 @@ func (cn *Confirms) Confirm(id nonce.ID) bool {
defer cn.Unlock()
for i := range (*cn).Cnf {
if id == (*cn).Cnf[i].ID {
(*cn).Cnf[i].Hook((*cn).Cnf[i].Onion)
(*cn).Cnf[i].Hook(id)
// delete Callback.
end := i + 1
// if this is the last one, the end is the last one

View File

@@ -10,9 +10,9 @@ var (
// GitRef is the gitref, as in refs/heads/branchname.
GitRef = "refs/heads/protocol"
// ParentGitCommit is the commit hash of the parent HEAD.
ParentGitCommit = "a5efa254ee56c6ccebbabc42ec9e1b931ab2b3db"
ParentGitCommit = "9439d8bc695bba8d6c03c6f1b2c7c46158a8f787"
// BuildTime stores the time when the current binary was built.
BuildTime = "2023-01-06T16:56:57Z"
BuildTime = "2023-01-07T10:48:10Z"
// SemVer lists the (latest) git tag on the release.
SemVer = "v0.1.4"
// PathBase is the path base returned from runtime caller.