swarm/pss: WIP whisper keys handling

This commit is contained in:
lash 2017-07-13 17:44:16 +02:00
parent d9a883910e
commit 78d0a9d1d5
4 changed files with 445 additions and 414 deletions

View file

@ -41,6 +41,10 @@ func NewAddressFromBytes(b []byte) Address {
return Address(h) return Address(h)
} }
func (a Address) IsZero() bool {
return a.Bin() == zerosBin
}
func (a Address) String() string { func (a Address) String() string {
return fmt.Sprintf("%x", a[:]) return fmt.Sprintf("%x", a[:])
} }

View file

@ -9,7 +9,6 @@ import (
"time" "time"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/p2p/discover" "github.com/ethereum/go-ethereum/p2p/discover"
@ -65,11 +64,11 @@ type Pss struct {
network.Overlay // we can get the overlayaddress from this network.Overlay // we can get the overlayaddress from this
peerPool map[pot.Address]map[whisper.TopicType]p2p.MsgReadWriter // keep track of all virtual p2p.Peers we are currently speaking to peerPool map[pot.Address]map[whisper.TopicType]p2p.MsgReadWriter // keep track of all virtual p2p.Peers we are currently speaking to
fwdPool map[discover.NodeID]*protocols.Peer // keep track of all peers sitting on the pssmsg routing layer fwdPool map[discover.NodeID]*protocols.Peer // keep track of all peers sitting on the pssmsg routing layer
keyPool map[pot.Address]ecdsa.PublicKey // keep track of all public keys so we can encrypt for our peers keyPool map[pot.Address]map[whisper.TopicType]ecdsa.PublicKey // keep track of all public keys so we can encrypt for our peers
reverseKeyPool map[string]pot.Address // as above but reverse lookup reverseKeyPool map[ecdsa.PublicKey]map[whisper.TopicType]pot.Address
handlers map[whisper.TopicType]map[*Handler]bool // topic and version based pss payload handlers handlers map[whisper.TopicType]map[*Handler]bool // topic and version based pss payload handlers
fwdcache map[pssDigest]pssCacheEntry // checksum of unique fields from pssmsg mapped to expiry, cache to determine whether to drop msg fwdcache map[pssDigest]pssCacheEntry // checksum of unique fields from pssmsg mapped to expiry, cache to determine whether to drop msg
cachettl time.Duration // how long to keep messages in fwdcache cachettl time.Duration // how long to keep messages in fwdcache
lock sync.Mutex lock sync.Mutex
dpa *storage.DPA dpa *storage.DPA
privatekey *ecdsa.PrivateKey privatekey *ecdsa.PrivateKey
@ -98,8 +97,8 @@ func NewPss(k network.Overlay, dpa *storage.DPA, params *PssParams) *Pss {
Overlay: k, Overlay: k,
peerPool: make(map[pot.Address]map[whisper.TopicType]p2p.MsgReadWriter, PssPeerCapacity), peerPool: make(map[pot.Address]map[whisper.TopicType]p2p.MsgReadWriter, PssPeerCapacity),
fwdPool: make(map[discover.NodeID]*protocols.Peer), fwdPool: make(map[discover.NodeID]*protocols.Peer),
keyPool: make(map[pot.Address]ecdsa.PublicKey), keyPool: make(map[pot.Address]map[whisper.TopicType]ecdsa.PublicKey),
reverseKeyPool: make(map[string]pot.Address), reverseKeyPool: make(map[ecdsa.PublicKey]map[whisper.TopicType]pot.Address),
handlers: make(map[whisper.TopicType]map[*Handler]bool), handlers: make(map[whisper.TopicType]map[*Handler]bool),
fwdcache: make(map[pssDigest]pssCacheEntry), fwdcache: make(map[pssDigest]pssCacheEntry),
cachettl: params.Cachettl, cachettl: params.Cachettl,
@ -176,25 +175,45 @@ func (self *Pss) Register(topic *whisper.TopicType, handler Handler) func() {
return func() { self.deregister(topic, &handler) } return func() { self.deregister(topic, &handler) }
} }
func (self *Pss) AddAddressKeyPair(addr pot.Address, pubkey ecdsa.PublicKey) { // Add a Public key address mapping
// returns false if identical mapping already exists
func (self *Pss) AddPublicKey(addr pot.Address, topic whisper.TopicType, pubkey ecdsa.PublicKey) bool {
self.lock.Lock() self.lock.Lock()
defer self.lock.Unlock() defer self.lock.Unlock()
self.keyPool[addr] = pubkey if len(self.keyPool[addr]) == 0 {
self.reverseKeyPool[common.ToHex(crypto.FromECDSAPub(&pubkey))] = addr self.keyPool[addr] = make(map[whisper.TopicType]ecdsa.PublicKey)
self.reverseKeyPool[pubkey] = make(map[whisper.TopicType]pot.Address)
}
self.keyPool[addr][topic] = pubkey
self.reverseKeyPool[pubkey][topic] = addr
return true
} }
// may need these later, please let them be func (self *Pss) RemovePublicKey(addr pot.Address, topic whisper.TopicType, pubkey ecdsa.PublicKey) bool {
////func (self *Pss) RemoveAddressKeyPair(addr pot.Address, pubkey ecdsa.PublicKey) { if len(self.keyPool[addr]) == 0 {
// delete(self.reverseKeyPool, &self.keyPool[addr]) return false
// delete(self.keyPool, addr) }
//} zeroKey := ecdsa.PublicKey{}
// if self.keyPool[addr][topic] == zeroKey {
//func (self *Pss) hasAddressKeyPair(addr pot.Address, pubkey ecdsa.PublicKey) bool { return false
// if self.keyPool[addr] != nil { }
// return *self.keyPool[addr] == pubkey delete(self.reverseKeyPool, pubkey)
// } self.keyPool[addr][topic] = zeroKey
// return false return true
//} }
func (self *Pss) GetKeys(addr pot.Address) (keys []ecdsa.PublicKey) {
outer:
for _, key := range self.keyPool[addr] {
for _, havekey := range keys {
if havekey == key {
continue outer
}
}
keys = append(keys, key)
}
return
}
func (self *Pss) deregister(topic *whisper.TopicType, h *Handler) { func (self *Pss) deregister(topic *whisper.TopicType, h *Handler) {
self.lock.Lock() self.lock.Lock()
@ -300,9 +319,10 @@ func (self *Pss) Process(pssmsg *PssMsg) error {
nid, _ := discover.HexID("0x00") nid, _ := discover.HexID("0x00")
p := p2p.NewPeer(nid, fmt.Sprintf("%x", recvmsg.Src), []p2p.Cap{}) p := p2p.NewPeer(nid, fmt.Sprintf("%x", recvmsg.Src), []p2p.Cap{})
addr := self.reverseKeyPool[common.ToHex(crypto.FromECDSAPub(recvmsg.Src))] //addr := self.reverseKeyPool[common.ToHex(crypto.FromECDSAPub(recvmsg.Src))]
addr := self.reverseKeyPool[*recvmsg.Src][recvmsg.Topic]
log.Warn("recvkey", "key", *recvmsg.Src, "addr", addr) log.Warn("recvkey", "key", *recvmsg.Src, "addr", addr)
if bytes.Equal([]byte{}, addr[:]) { if addr.IsZero() {
return fmt.Errorf("unknown key", "addr", addr) return fmt.Errorf("unknown key", "addr", addr)
} }
@ -323,7 +343,7 @@ func (self *Pss) Process(pssmsg *PssMsg) error {
func (self *Pss) SendAsym(to []byte, topic whisper.TopicType, msg []byte) error { func (self *Pss) SendAsym(to []byte, topic whisper.TopicType, msg []byte) error {
var potaddr pot.Address var potaddr pot.Address
copy(potaddr[:], to) copy(potaddr[:], to)
topubkey := self.keyPool[potaddr] topubkey := self.keyPool[potaddr][topic]
log.Debug("using pubkey", "pubkey", topubkey) log.Debug("using pubkey", "pubkey", topubkey)
wparams := &whisper.MessageParams{ wparams := &whisper.MessageParams{
TTL: DefaultTTL, TTL: DefaultTTL,

View file

@ -2,29 +2,31 @@ package pss
import ( import (
"bytes" "bytes"
"context" // "context"
// "crypto/ecdsa"
"encoding/hex" "encoding/hex"
"encoding/json" // "encoding/json"
"flag"
"fmt" "fmt"
"io/ioutil" // "io/ioutil"
"math/rand" "math/rand"
"os" "os"
"sync" // "sync"
"testing" "testing"
"time" "time"
"flag"
// "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/node" // "github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/p2p/discover" // "github.com/ethereum/go-ethereum/p2p/discover"
"github.com/ethereum/go-ethereum/p2p/protocols" // "github.com/ethereum/go-ethereum/p2p/protocols"
"github.com/ethereum/go-ethereum/p2p/simulations" // "github.com/ethereum/go-ethereum/p2p/simulations"
"github.com/ethereum/go-ethereum/p2p/simulations/adapters" // "github.com/ethereum/go-ethereum/p2p/simulations/adapters"
p2ptest "github.com/ethereum/go-ethereum/p2p/testing" // p2ptest "github.com/ethereum/go-ethereum/p2p/testing"
"github.com/ethereum/go-ethereum/swarm/network" "github.com/ethereum/go-ethereum/swarm/network"
"github.com/ethereum/go-ethereum/swarm/storage" // "github.com/ethereum/go-ethereum/swarm/storage"
whisper "github.com/ethereum/go-ethereum/whisper/whisperv5"
) )
const ( const (
@ -34,11 +36,10 @@ const (
var ( var (
snapshotfile string snapshotfile string
debugflag = flag.Bool("v", false, "verbose") debugflag = flag.Bool("v", false, "verbose")
// custom logging // custom logging
psslogmain log.Logger psslogmain log.Logger
) )
var services = newServices() var services = newServices()
@ -63,6 +64,12 @@ func init() {
} }
func TestKeys(t *testing.T) {
key, err := crypto.GenerateKey()
addr := network.RandomAddress.Over()
topic := whisper.NewTopic("foo", 42)
}
func TestCache(t *testing.T) { func TestCache(t *testing.T) {
var err error var err error
to, _ := hex.DecodeString("08090a0b0c0d0e0f1011121314150001020304050607161718191a1b1c1d1e1f") to, _ := hex.DecodeString("08090a0b0c0d0e0f1011121314150001020304050607161718191a1b1c1d1e1f")
@ -199,374 +206,374 @@ func TestRegisterHandler(t *testing.T) {
} }
} }
func TestSimpleLinear(t *testing.T) { //func TestSimpleLinear(t *testing.T) {
var err error // var err error
nodeconfig := adapters.RandomNodeConfig() // nodeconfig := adapters.RandomNodeConfig()
addr := network.NewAddrFromNodeID(nodeconfig.ID) // addr := network.NewAddrFromNodeID(nodeconfig.ID)
_ = p2ptest.NewTestPeerPool() // _ = p2ptest.NewTestPeerPool()
ps := NewTestPss(addr.Over()) // ps := NewTestPss(addr.Over())
//
ping := &Ping{ // ping := &Ping{
C: make(chan struct{}), // C: make(chan struct{}),
} // }
//
ps.Register(&PingTopic, RegisterPssProtocol(ps, &PingTopic, PingProtocol, NewPingProtocol(ping.PingHandler)).Handle) // ps.Register(&PingTopic, RegisterPssProtocol(ps, &PingTopic, PingProtocol, NewPingProtocol(ping.PingHandler)).Handle)
//
if err != nil { // if err != nil {
t.Fatalf("Failed to register virtual protocol in pss: %v", err) // t.Fatalf("Failed to register virtual protocol in pss: %v", err)
} // }
run := func(p *p2p.Peer, rw p2p.MsgReadWriter) error { // run := func(p *p2p.Peer, rw p2p.MsgReadWriter) error {
id := p.ID() // id := p.ID()
pp := protocols.NewPeer(p, rw, pssSpec) // pp := protocols.NewPeer(p, rw, pssSpec)
bp := &testOverlayConn{ // bp := &testOverlayConn{
Peer: pp, // Peer: pp,
addr: network.ToOverlayAddr(id[:]), // addr: network.ToOverlayAddr(id[:]),
} // }
//a := pot.NewAddressFromBytes(bp.addr) // //a := pot.NewAddressFromBytes(bp.addr)
//ps.fwdPool[a] = pp // //ps.fwdPool[a] = pp
ps.fwdPool[id] = pp // ps.fwdPool[id] = pp
ps.Overlay.On(bp) // ps.Overlay.On(bp)
defer ps.Overlay.Off(bp) // defer ps.Overlay.Off(bp)
log.Debug(fmt.Sprintf("%v", ps.Overlay)) // log.Debug(fmt.Sprintf("%v", ps.Overlay))
return bp.Run(ps.handlePssMsg) // return bp.Run(ps.handlePssMsg)
} // }
//
pt := p2ptest.NewProtocolTester(t, nodeconfig.ID, 2, run) // pt := p2ptest.NewProtocolTester(t, nodeconfig.ID, 2, run)
//
msg := NewPingMsg(network.ToOverlayAddr(pt.IDs[0].Bytes()), PingProtocol, PingTopic, []byte{1, 2, 3}) // msg := NewPingMsg(network.ToOverlayAddr(pt.IDs[0].Bytes()), PingProtocol, PingTopic, []byte{1, 2, 3})
//
exchange := p2ptest.Exchange{ // exchange := p2ptest.Exchange{
Expects: []p2ptest.Expect{ // Expects: []p2ptest.Expect{
p2ptest.Expect{ // p2ptest.Expect{
Code: 0, // Code: 0,
Msg: msg, // Msg: msg,
Peer: pt.IDs[0], // Peer: pt.IDs[0],
}, // },
}, // },
Triggers: []p2ptest.Trigger{ // Triggers: []p2ptest.Trigger{
p2ptest.Trigger{ // p2ptest.Trigger{
Code: 0, // Code: 0,
Msg: msg, // Msg: msg,
Peer: pt.IDs[1], // Peer: pt.IDs[1],
}, // },
}, // },
} // }
//
err = pt.TestExchanges(exchange) // err = pt.TestExchanges(exchange)
if err != nil { // if err != nil {
t.Fatalf("exchange failed %v", err) // t.Fatalf("exchange failed %v", err)
} // }
} //}
//
func TestSnapshot_50_5(t *testing.T) { //func TestSnapshot_50_5(t *testing.T) {
testSnapshot(t, "testdata/snapshot_50.json", 5, true) // testSnapshot(t, "testdata/snapshot_50.json", 5, true)
} //}
//
func TestSnapshot_5_50(t *testing.T) { //func TestSnapshot_5_50(t *testing.T) {
testSnapshot(t, "testdata/snapshot_5.json", 50, true) // testSnapshot(t, "testdata/snapshot_5.json", 50, true)
} //}
//
func TestSnapshot_5_5(t *testing.T) { //func TestSnapshot_5_5(t *testing.T) {
testSnapshot(t, "testdata/snapshot_5.json", 5, true) // testSnapshot(t, "testdata/snapshot_5.json", 5, true)
} //}
//
func testSnapshot(t *testing.T, snapshotfile string, msgcount int, sim bool) { //func testSnapshot(t *testing.T, snapshotfile string, msgcount int, sim bool) {
//
//
// choose the adapter to use // // choose the adapter to use
var adapter adapters.NodeAdapter // var adapter adapters.NodeAdapter
if sim { // if sim {
adapter = adapters.NewSimAdapter(services) // adapter = adapters.NewSimAdapter(services)
} else { // } else {
baseDir, err := ioutil.TempDir("", "swarm-test") // baseDir, err := ioutil.TempDir("", "swarm-test")
if err != nil { // if err != nil {
t.Fatal(err) // t.Fatal(err)
} // }
defer os.RemoveAll(baseDir) // defer os.RemoveAll(baseDir)
adapter = adapters.NewExecAdapter(baseDir) // adapter = adapters.NewExecAdapter(baseDir)
} // }
//
// process shapshot // // process shapshot
jsonsnapshot, err := ioutil.ReadFile(snapshotfile) // jsonsnapshot, err := ioutil.ReadFile(snapshotfile)
if err != nil { // if err != nil {
t.Fatalf("cant read snapshot: %s", snapshotfile) // t.Fatalf("cant read snapshot: %s", snapshotfile)
} // }
snapshot := &simulations.Snapshot{} // snapshot := &simulations.Snapshot{}
err = json.Unmarshal(jsonsnapshot, snapshot) // err = json.Unmarshal(jsonsnapshot, snapshot)
if err != nil { // if err != nil {
t.Fatalf("snapshot file unreadable: %v", err) // t.Fatalf("snapshot file unreadable: %v", err)
} // }
for _, node := range snapshot.Nodes { // for _, node := range snapshot.Nodes {
node.Config.Services = []string{"bzz", "pss"} // node.Config.Services = []string{"bzz", "pss"}
} // }
//
// setup network with snapshot // // setup network with snapshot
net := simulations.NewNetwork(adapter, &simulations.NetworkConfig{ // net := simulations.NewNetwork(adapter, &simulations.NetworkConfig{
ID: "0", // ID: "0",
}) // })
defer net.Shutdown() // defer net.Shutdown()
//
err = net.Load(snapshot) // err = net.Load(snapshot)
if err != nil { // if err != nil {
t.Fatalf("invalid snapshot: %v", err) // t.Fatalf("invalid snapshot: %v", err)
} // }
//
timeout := 15 * time.Second // timeout := 15 * time.Second
ctx, cancelmain := context.WithTimeout(context.Background(), timeout) // ctx, cancelmain := context.WithTimeout(context.Background(), timeout)
defer cancelmain() // defer cancelmain()
//
// nodes expecting messages // // nodes expecting messages
recvids := make([]discover.NodeID, msgcount) // recvids := make([]discover.NodeID, msgcount)
//
// the overlay address map to recvids // // the overlay address map to recvids
recvaddrs := make(map[discover.NodeID][]byte) // recvaddrs := make(map[discover.NodeID][]byte)
//
// messages actually received (registered through trigger and test check) // // messages actually received (registered through trigger and test check)
var msgreceived []discover.NodeID // var msgreceived []discover.NodeID
//
// trigger for expect in test // // trigger for expect in test
trigger := make(chan discover.NodeID) // trigger := make(chan discover.NodeID)
//
// one wait for every message // // one wait for every message
wg := sync.WaitGroup{} // wg := sync.WaitGroup{}
wg.Add(msgcount) // wg.Add(msgcount)
//
action := func(ctx context.Context) error { // action := func(ctx context.Context) error {
var rpcerr error // var rpcerr error
var rpcbyte []byte // var rpcbyte []byte
for _, simnode := range net.Nodes { // for _, simnode := range net.Nodes {
if simnode == nil { // if simnode == nil {
return fmt.Errorf("unknown node: %s", simnode.ID()) // return fmt.Errorf("unknown node: %s", simnode.ID())
} // }
client, err := simnode.Client() // client, err := simnode.Client()
if err != nil { // if err != nil {
return fmt.Errorf("error getting recp node client: %s", err) // return fmt.Errorf("error getting recp node client: %s", err)
} // }
//
err = client.Call(&rpcbyte, "pss_baseAddr") // err = client.Call(&rpcbyte, "pss_baseAddr")
if err != nil { // if err != nil {
t.Fatalf("cant get overlayaddr: %v", err) // t.Fatalf("cant get overlayaddr: %v", err)
} // }
//
recvaddrs[simnode.ID()] = rpcbyte // recvaddrs[simnode.ID()] = rpcbyte
err = client.Call(&rpcbyte, "pss_baseAddr") // err = client.Call(&rpcbyte, "pss_baseAddr")
if err != nil { // if err != nil {
t.Fatalf("cant get overlayaddr: %v", err) // t.Fatalf("cant get overlayaddr: %v", err)
} // }
//
err = triggerChecks(ctx, &wg, &trigger, net, simnode.ID()) // err = triggerChecks(ctx, &wg, &trigger, net, simnode.ID())
if err != nil { // if err != nil {
t.Fatalf("trigger setup failed: %v", err) // t.Fatalf("trigger setup failed: %v", err)
} // }
} // }
for i := 0; i < msgcount; i++ { // for i := 0; i < msgcount; i++ {
//
idx := rand.Intn(len(net.Nodes)) // idx := rand.Intn(len(net.Nodes))
sendernode := net.Nodes[idx] // sendernode := net.Nodes[idx]
toidx := rand.Intn(len(net.Nodes)-1) // toidx := rand.Intn(len(net.Nodes)-1)
if toidx >= idx { // if toidx >= idx {
toidx++ // toidx++
} // }
recvnode := net.Nodes[toidx] // recvnode := net.Nodes[toidx]
recvids[i] = recvnode.ID() // recvids[i] = recvnode.ID()
msg := PingMsg{Created: time.Now()} // msg := PingMsg{Created: time.Now()}
code, _ := PingProtocol.GetCode(&PingMsg{}) // code, _ := PingProtocol.GetCode(&PingMsg{})
pmsg, _ := NewProtocolMsg(code, msg) // pmsg, _ := NewProtocolMsg(code, msg)
//
client, err := sendernode.Client() // client, err := sendernode.Client()
if err != nil { // if err != nil {
return fmt.Errorf("error getting sendernode client: %s", err) // return fmt.Errorf("error getting sendernode client: %s", err)
} // }
client.CallContext(ctx, &rpcerr, "pss_send", PingTopic, APIMsg{ // client.CallContext(ctx, &rpcerr, "pss_send", PingTopic, APIMsg{
Addr: recvaddrs[recvnode.ID()], // Addr: recvaddrs[recvnode.ID()],
Msg: pmsg, // Msg: pmsg,
}) // })
if rpcerr != nil { // if rpcerr != nil {
return fmt.Errorf("error rpc send id %x: %v", sendernode.ID(), rpcerr) // return fmt.Errorf("error rpc send id %x: %v", sendernode.ID(), rpcerr)
} // }
} // }
return nil // return nil
} // }
check := func(ctx context.Context, id discover.NodeID) (bool, error) { // check := func(ctx context.Context, id discover.NodeID) (bool, error) {
select { // select {
case <-ctx.Done(): // case <-ctx.Done():
wg.Done() // wg.Done()
return false, ctx.Err() // return false, ctx.Err()
default: // default:
} // }
msgreceived = append(msgreceived, id) // msgreceived = append(msgreceived, id)
psslogmain.Info("trigger received", "id", id, "len", len(msgreceived)) // psslogmain.Info("trigger received", "id", id, "len", len(msgreceived))
wg.Done() // wg.Done()
return true, nil // return true, nil
} // }
//
result := simulations.NewSimulation(net).Run(ctx, &simulations.Step{ // result := simulations.NewSimulation(net).Run(ctx, &simulations.Step{
Action: action, // Action: action,
Trigger: trigger, // Trigger: trigger,
Expect: &simulations.Expectation{ // Expect: &simulations.Expectation{
Nodes: recvids, // Nodes: recvids,
Check: check, // Check: check,
}, // },
}) // })
if result.Error != nil { // if result.Error != nil {
psslogmain.Error("msg failed!", "err", result.Error) // psslogmain.Error("msg failed!", "err", result.Error)
cancelmain() // cancelmain()
t.Fatalf("simulation failed: %s", result.Error) // t.Fatalf("simulation failed: %s", result.Error)
} // }
//
wg.Wait() // wg.Wait()
//
if len(msgreceived) != msgcount { // if len(msgreceived) != msgcount {
t.Fatalf("Simulation Failed, got %d of %d msgs", len(msgreceived), msgcount) // t.Fatalf("Simulation Failed, got %d of %d msgs", len(msgreceived), msgcount)
} // }
//
psslogmain.Info("done!") // psslogmain.Info("done!")
t.Logf("Simulation Passed, got %d of %d msgs", len(msgreceived), msgcount) // t.Logf("Simulation Passed, got %d of %d msgs", len(msgreceived), msgcount)
//t.Logf("Duration: %s", result.FinishedAt.Sub(result.StartedAt)) // //t.Logf("Duration: %s", result.FinishedAt.Sub(result.StartedAt))
} //}
//
// triggerChecks triggers a simulation step check whenever a peer is added or //// triggerChecks triggers a simulation step check whenever a peer is added or
// removed from the given node //// removed from the given node
// connections and connectionstarget are temporary kademlia check workarounds //// connections and connectionstarget are temporary kademlia check workarounds
func triggerChecks(ctx context.Context, wg *sync.WaitGroup, trigger *chan discover.NodeID, net *simulations.Network, id discover.NodeID) error { //func triggerChecks(ctx context.Context, wg *sync.WaitGroup, trigger *chan discover.NodeID, net *simulations.Network, id discover.NodeID) error {
//
quitC := make(chan struct{}) // quitC := make(chan struct{})
//
node := net.GetNode(id) // node := net.GetNode(id)
if node == nil { // if node == nil {
return fmt.Errorf("unknown node: %s", id) // return fmt.Errorf("unknown node: %s", id)
} // }
client, err := node.Client() // client, err := node.Client()
if err != nil { // if err != nil {
return err // return err
} // }
//
peerevents := make(chan *p2p.PeerEvent) // peerevents := make(chan *p2p.PeerEvent)
peersub, err := client.Subscribe(context.Background(), "admin", peerevents, "peerEvents") // peersub, err := client.Subscribe(context.Background(), "admin", peerevents, "peerEvents")
if err != nil { // if err != nil {
return fmt.Errorf("error getting peer events for node %v: %s", id, err) // return fmt.Errorf("error getting peer events for node %v: %s", id, err)
} // }
//
msgevents := make(chan APIMsg) // msgevents := make(chan APIMsg)
msgsub, err := client.Subscribe(context.Background(), "pss", msgevents, "receive", PingTopic) // msgsub, err := client.Subscribe(context.Background(), "pss", msgevents, "receive", PingTopic)
if err != nil { // if err != nil {
return fmt.Errorf("error getting msg events for node %v: %s", id, err) // return fmt.Errorf("error getting msg events for node %v: %s", id, err)
} // }
//
go func() { // go func() {
defer msgsub.Unsubscribe() // defer msgsub.Unsubscribe()
defer peersub.Unsubscribe() // defer peersub.Unsubscribe()
for { // for {
select { // select {
case <-msgevents: // case <-msgevents:
psslogmain.Debug("incoming msg", "node", id) // psslogmain.Debug("incoming msg", "node", id)
*trigger <- id // *trigger <- id
case err := <-peersub.Err(): // case err := <-peersub.Err():
if err != nil { // if err != nil {
log.Error(fmt.Sprintf("error getting peer events for node %v", id), "err", err) // log.Error(fmt.Sprintf("error getting peer events for node %v", id), "err", err)
} // }
return // return
//
case err := <-msgsub.Err(): // case err := <-msgsub.Err():
if err != nil { // if err != nil {
log.Error(fmt.Sprintf("error getting msg for node %v", id), "err", err) // log.Error(fmt.Sprintf("error getting msg for node %v", id), "err", err)
} // }
return // return
case <-quitC: // case <-quitC:
return // return
} // }
} // }
}() // }()
//
go func() { // go func() {
wg.Wait() // wg.Wait()
quitC <- struct{}{} // quitC <- struct{}{}
}() // }()
//
return nil // return nil
} //}
//
func newServices() adapters.Services { //func newServices() adapters.Services {
stateStore := adapters.NewSimStateStore() // stateStore := adapters.NewSimStateStore()
kademlias := make(map[discover.NodeID]*network.Kademlia) // kademlias := make(map[discover.NodeID]*network.Kademlia)
kademlia := func(id discover.NodeID) *network.Kademlia { // kademlia := func(id discover.NodeID) *network.Kademlia {
if k, ok := kademlias[id]; ok { // if k, ok := kademlias[id]; ok {
return k // return k
} // }
addr := network.NewAddrFromNodeID(id) // addr := network.NewAddrFromNodeID(id)
params := network.NewKadParams() // params := network.NewKadParams()
params.MinProxBinSize = 2 // params.MinProxBinSize = 2
params.MaxBinSize = 3 // params.MaxBinSize = 3
params.MinBinSize = 1 // params.MinBinSize = 1
params.MaxRetries = 1000 // params.MaxRetries = 1000
params.RetryExponent = 2 // params.RetryExponent = 2
params.RetryInterval = 1000000 // params.RetryInterval = 1000000
kademlias[id] = network.NewKademlia(addr.Over(), params) // kademlias[id] = network.NewKademlia(addr.Over(), params)
return kademlias[id] // return kademlias[id]
} // }
return adapters.Services{ // return adapters.Services{
//"pss": func(id discover.NodeID, snapshot []byte) node.Service { // //"pss": func(id discover.NodeID, snapshot []byte) node.Service {
"pss": func(ctx *adapters.ServiceContext) (node.Service, error) { // "pss": func(ctx *adapters.ServiceContext) (node.Service, error) {
cachedir, err := ioutil.TempDir("", "pss-cache") // cachedir, err := ioutil.TempDir("", "pss-cache")
if err != nil { // if err != nil {
return nil, fmt.Errorf("create pss cache tmpdir failed", "error", err) // return nil, fmt.Errorf("create pss cache tmpdir failed", "error", err)
} // }
dpa, err := storage.NewLocalDPA(cachedir) // dpa, err := storage.NewLocalDPA(cachedir)
if err != nil { // if err != nil {
return nil, fmt.Errorf("local dpa creation failed", "error", err) // return nil, fmt.Errorf("local dpa creation failed", "error", err)
} // }
//
pssp := NewPssParams(true) // pssp := NewPssParams(true)
ps := NewPss(kademlia(ctx.Config.ID), dpa, pssp) // ps := NewPss(kademlia(ctx.Config.ID), dpa, pssp)
//
ping := &Ping{ // ping := &Ping{
C: make(chan struct{}), // C: make(chan struct{}),
} // }
ps.Register(&PingTopic, RegisterPssProtocol(ps, &PingTopic, PingProtocol, NewPingProtocol(ping.PingHandler)).Handle) // ps.Register(&PingTopic, RegisterPssProtocol(ps, &PingTopic, PingProtocol, NewPingProtocol(ping.PingHandler)).Handle)
if err != nil { // if err != nil {
log.Error("Couldnt register pss protocol", "err", err) // log.Error("Couldnt register pss protocol", "err", err)
os.Exit(1) // os.Exit(1)
} // }
//
return ps, nil // return ps, nil
}, // },
//"bzz": func(id discover.NodeID, snapshot []byte) node.Service { // //"bzz": func(id discover.NodeID, snapshot []byte) node.Service {
"bzz": func(ctx *adapters.ServiceContext) (node.Service, error) { // "bzz": func(ctx *adapters.ServiceContext) (node.Service, error) {
addr := network.NewAddrFromNodeID(ctx.Config.ID) // addr := network.NewAddrFromNodeID(ctx.Config.ID)
hp := network.NewHiveParams() // hp := network.NewHiveParams()
hp.Discovery = false // hp.Discovery = false
config := &network.BzzConfig{ // config := &network.BzzConfig{
OverlayAddr: addr.Over(), // OverlayAddr: addr.Over(),
UnderlayAddr: addr.Under(), // UnderlayAddr: addr.Under(),
HiveParams: hp, // HiveParams: hp,
} // }
return network.NewBzz(config, kademlia(ctx.Config.ID), stateStore), nil // return network.NewBzz(config, kademlia(ctx.Config.ID), stateStore), nil
}, // },
} // }
} //}
//
type connmap struct { //type connmap struct {
conns map[discover.NodeID][]discover.NodeID // conns map[discover.NodeID][]discover.NodeID
healthy map[discover.NodeID]bool // healthy map[discover.NodeID]bool
lock sync.Mutex // lock sync.Mutex
} //}
//
type testOverlayConn struct { //type testOverlayConn struct {
*protocols.Peer // *protocols.Peer
addr []byte // addr []byte
} //}
//
func (self *testOverlayConn) Address() []byte { //func (self *testOverlayConn) Address() []byte {
return self.addr // return self.addr
} //}
//
func (self *testOverlayConn) Off() network.OverlayAddr { //func (self *testOverlayConn) Off() network.OverlayAddr {
return self // return self
} //}
//
func (self *testOverlayConn) Drop(err error) { //func (self *testOverlayConn) Drop(err error) {
} //}
//
func (self *testOverlayConn) Update(o network.OverlayAddr) network.OverlayAddr { //func (self *testOverlayConn) Update(o network.OverlayAddr) network.OverlayAddr {
return self // return self
} //}

View file

@ -74,10 +74,10 @@ func (pssapi *API) BaseAddr() ([]byte, error) {
return pssapi.Pss.BaseAddr(), nil return pssapi.Pss.BaseAddr(), nil
} }
func (pssapi *API) AddAddressKeyPair(addr []byte, pubkey ecdsa.PublicKey) error { func (pssapi *API) AddPublicKey(addr []byte, topic whisper.TopicType, pubkey ecdsa.PublicKey) error {
var potaddr pot.Address var potaddr pot.Address
copy(potaddr[:], addr) copy(potaddr[:], addr)
pssapi.Pss.AddAddressKeyPair(potaddr, pubkey) pssapi.Pss.AddPublicKey(potaddr, topic, pubkey)
return nil return nil
} }