swarm/pss: Remove go1.7 test workaround

This commit is contained in:
lash 2018-03-28 12:35:18 +02:00
parent 2acb592647
commit bdef57fd32
3 changed files with 123 additions and 845 deletions

View file

@ -1,130 +0,0 @@
// +build go1.8
package pss
import (
"context"
"fmt"
"strconv"
"strings"
"testing"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/p2p/discover"
)
// simple ping pong protocol test for the pss devp2p emulation
func TestProtocol(t *testing.T) {
t.Run("32", testProtocol)
t.Run("8", testProtocol)
t.Run("0", testProtocol)
}
func testProtocol(t *testing.T) {
// address hint size
var addrsize int64
paramstring := strings.Split(t.Name(), "/")
addrsize, _ = strconv.ParseInt(paramstring[1], 10, 0)
log.Info("protocol test", "addrsize", addrsize)
topic := PingTopic.String()
clients, err := setupNetwork(2)
if err != nil {
t.Fatal(err)
}
var loaddrhex string
err = clients[0].Call(&loaddrhex, "pss_baseAddr")
if err != nil {
t.Fatalf("rpc get node 1 baseaddr fail: %v", err)
}
loaddrhex = loaddrhex[:2+(addrsize*2)]
var roaddrhex string
err = clients[1].Call(&roaddrhex, "pss_baseAddr")
if err != nil {
t.Fatalf("rpc get node 2 baseaddr fail: %v", err)
}
roaddrhex = roaddrhex[:2+(addrsize*2)]
lnodeinfo := &p2p.NodeInfo{}
err = clients[0].Call(&lnodeinfo, "admin_nodeInfo")
if err != nil {
t.Fatalf("rpc nodeinfo node 11 fail: %v", err)
}
var lpubkey string
err = clients[0].Call(&lpubkey, "pss_getPublicKey")
if err != nil {
t.Fatalf("rpc get node 1 pubkey fail: %v", err)
}
var rpubkey string
err = clients[1].Call(&rpubkey, "pss_getPublicKey")
if err != nil {
t.Fatalf("rpc get node 2 pubkey fail: %v", err)
}
time.Sleep(time.Millisecond * 1000) // replace with hive healthy code
lmsgC := make(chan APIMsg)
lctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()
lsub, err := clients[0].Subscribe(lctx, "pss", lmsgC, "receive", topic)
defer lsub.Unsubscribe()
rmsgC := make(chan APIMsg)
rctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()
rsub, err := clients[1].Subscribe(rctx, "pss", rmsgC, "receive", topic)
defer rsub.Unsubscribe()
// set reciprocal public keys
err = clients[0].Call(nil, "pss_setPeerPublicKey", rpubkey, topic, roaddrhex)
if err != nil {
t.Fatal(err)
}
err = clients[1].Call(nil, "pss_setPeerPublicKey", lpubkey, topic, loaddrhex)
if err != nil {
t.Fatal(err)
}
// add right peer's public key as protocol peer on left
nid, _ := discover.HexID("0x00") // this hack is needed to satisfy the p2p method
p := p2p.NewPeer(nid, fmt.Sprintf("%x", common.FromHex(loaddrhex)), []p2p.Cap{})
_, err = pssprotocols[lnodeinfo.ID].protocol.AddPeer(p, pssprotocols[lnodeinfo.ID].run, PingTopic, true, rpubkey)
if err != nil {
t.Fatal(err)
}
// sends ping asym, checks delivery
pssprotocols[lnodeinfo.ID].C <- false
select {
case <-lmsgC:
log.Debug("lnode ok")
case cerr := <-lctx.Done():
t.Fatalf("test message timed out: %v", cerr)
}
select {
case <-rmsgC:
log.Debug("rnode ok")
case cerr := <-lctx.Done():
t.Fatalf("test message timed out: %v", cerr)
}
// sends ping asym, checks delivery
pssprotocols[lnodeinfo.ID].C <- false
select {
case <-lmsgC:
log.Debug("lnode ok")
case cerr := <-lctx.Done():
t.Fatalf("test message timed out: %v", cerr)
}
select {
case <-rmsgC:
log.Debug("rnode ok")
case cerr := <-lctx.Done():
t.Fatalf("test message timed out: %v", cerr)
}
}

View file

@ -1,7 +1,17 @@
package pss package pss
import ( import (
"context"
"fmt"
"strconv"
"strings"
"testing"
"time"
"github.com/ethereum/go-ethereum/common"
"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"
) )
type protoCtrl struct { type protoCtrl struct {
@ -9,3 +19,116 @@ type protoCtrl struct {
protocol *Protocol protocol *Protocol
run func(*p2p.Peer, p2p.MsgReadWriter) error run func(*p2p.Peer, p2p.MsgReadWriter) error
} }
// simple ping pong protocol test for the pss devp2p emulation
func TestProtocol(t *testing.T) {
t.Run("32", testProtocol)
t.Run("8", testProtocol)
t.Run("0", testProtocol)
}
func testProtocol(t *testing.T) {
// address hint size
var addrsize int64
paramstring := strings.Split(t.Name(), "/")
addrsize, _ = strconv.ParseInt(paramstring[1], 10, 0)
log.Info("protocol test", "addrsize", addrsize)
topic := PingTopic.String()
clients, err := setupNetwork(2)
if err != nil {
t.Fatal(err)
}
var loaddrhex string
err = clients[0].Call(&loaddrhex, "pss_baseAddr")
if err != nil {
t.Fatalf("rpc get node 1 baseaddr fail: %v", err)
}
loaddrhex = loaddrhex[:2+(addrsize*2)]
var roaddrhex string
err = clients[1].Call(&roaddrhex, "pss_baseAddr")
if err != nil {
t.Fatalf("rpc get node 2 baseaddr fail: %v", err)
}
roaddrhex = roaddrhex[:2+(addrsize*2)]
lnodeinfo := &p2p.NodeInfo{}
err = clients[0].Call(&lnodeinfo, "admin_nodeInfo")
if err != nil {
t.Fatalf("rpc nodeinfo node 11 fail: %v", err)
}
var lpubkey string
err = clients[0].Call(&lpubkey, "pss_getPublicKey")
if err != nil {
t.Fatalf("rpc get node 1 pubkey fail: %v", err)
}
var rpubkey string
err = clients[1].Call(&rpubkey, "pss_getPublicKey")
if err != nil {
t.Fatalf("rpc get node 2 pubkey fail: %v", err)
}
time.Sleep(time.Millisecond * 1000) // replace with hive healthy code
lmsgC := make(chan APIMsg)
lctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()
lsub, err := clients[0].Subscribe(lctx, "pss", lmsgC, "receive", topic)
defer lsub.Unsubscribe()
rmsgC := make(chan APIMsg)
rctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()
rsub, err := clients[1].Subscribe(rctx, "pss", rmsgC, "receive", topic)
defer rsub.Unsubscribe()
// set reciprocal public keys
err = clients[0].Call(nil, "pss_setPeerPublicKey", rpubkey, topic, roaddrhex)
if err != nil {
t.Fatal(err)
}
err = clients[1].Call(nil, "pss_setPeerPublicKey", lpubkey, topic, loaddrhex)
if err != nil {
t.Fatal(err)
}
// add right peer's public key as protocol peer on left
nid, _ := discover.HexID("0x00") // this hack is needed to satisfy the p2p method
p := p2p.NewPeer(nid, fmt.Sprintf("%x", common.FromHex(loaddrhex)), []p2p.Cap{})
_, err = pssprotocols[lnodeinfo.ID].protocol.AddPeer(p, pssprotocols[lnodeinfo.ID].run, PingTopic, true, rpubkey)
if err != nil {
t.Fatal(err)
}
// sends ping asym, checks delivery
pssprotocols[lnodeinfo.ID].C <- false
select {
case <-lmsgC:
log.Debug("lnode ok")
case cerr := <-lctx.Done():
t.Fatalf("test message timed out: %v", cerr)
}
select {
case <-rmsgC:
log.Debug("rnode ok")
case cerr := <-lctx.Done():
t.Fatalf("test message timed out: %v", cerr)
}
// sends ping asym, checks delivery
pssprotocols[lnodeinfo.ID].C <- false
select {
case <-lmsgC:
log.Debug("lnode ok")
case cerr := <-lctx.Done():
t.Fatalf("test message timed out: %v", cerr)
}
select {
case <-rmsgC:
log.Debug("rnode ok")
case cerr := <-lctx.Done():
t.Fatalf("test message timed out: %v", cerr)
}
}

View file

@ -1,715 +0,0 @@
// +build foo
package pss
import (
"bytes"
"context"
"encoding/binary"
"encoding/json"
"fmt"
"io/ioutil"
"math/rand"
"os"
"strconv"
"strings"
"testing"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/p2p/discover"
"github.com/ethereum/go-ethereum/p2p/simulations"
"github.com/ethereum/go-ethereum/p2p/simulations/adapters"
"github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum/go-ethereum/swarm/network"
whisper "github.com/ethereum/go-ethereum/whisper/whisperv5"
)
// send symmetrically encrypted message between two directly connected peers
func TestSymSend(t *testing.T) {
t.Run("32", testSymSend)
t.Run("8", testSymSend)
t.Run("0", testSymSend)
}
func testSymSend(t *testing.T) {
// address hint size
var addrsize int64
var err error
paramstring := strings.Split(t.Name(), "/")
addrsize, _ = strconv.ParseInt(paramstring[1], 10, 0)
log.Info("sym send test", "addrsize", addrsize)
clients, err := setupNetwork(2)
if err != nil {
t.Fatal(err)
}
var topic string
err = clients[0].Call(&topic, "pss_stringToTopic", "foo:42")
if err != nil {
t.Fatal(err)
}
var loaddrhex string
err = clients[0].Call(&loaddrhex, "pss_baseAddr")
if err != nil {
t.Fatalf("rpc get node 1 baseaddr fail: %v", err)
}
loaddrhex = loaddrhex[:2+(addrsize*2)]
var roaddrhex string
err = clients[1].Call(&roaddrhex, "pss_baseAddr")
if err != nil {
t.Fatalf("rpc get node 2 baseaddr fail: %v", err)
}
roaddrhex = roaddrhex[:2+(addrsize*2)]
// retrieve public key from pss instance
// set this public key reciprocally
var lpubkeyhex string
err = clients[0].Call(&lpubkeyhex, "pss_getPublicKey")
if err != nil {
t.Fatalf("rpc get node 1 pubkey fail: %v", err)
}
var rpubkeyhex string
err = clients[1].Call(&rpubkeyhex, "pss_getPublicKey")
if err != nil {
t.Fatalf("rpc get node 2 pubkey fail: %v", err)
}
time.Sleep(time.Millisecond * 500)
// at this point we've verified that symkeys are saved and match on each peer
// now try sending symmetrically encrypted message, both directions
lmsgC := make(chan APIMsg)
lctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()
lsub, err := clients[0].Subscribe(lctx, "pss", lmsgC, "receive", topic)
log.Trace("lsub", "id", lsub)
defer lsub.Unsubscribe()
rmsgC := make(chan APIMsg)
rctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()
rsub, err := clients[1].Subscribe(rctx, "pss", rmsgC, "receive", topic)
log.Trace("rsub", "id", rsub)
defer rsub.Unsubscribe()
lrecvkey := network.RandomAddr().Over()
rrecvkey := network.RandomAddr().Over()
var lkeyids [2]string
var rkeyids [2]string
// manually set reciprocal symkeys
err = clients[0].Call(&lkeyids, "psstest_setSymKeys", rpubkeyhex, lrecvkey, rrecvkey, defaultSymKeySendLimit, topic, roaddrhex)
if err != nil {
t.Fatal(err)
}
err = clients[1].Call(&rkeyids, "psstest_setSymKeys", rpubkeyhex, rrecvkey, lrecvkey, defaultSymKeySendLimit, topic, loaddrhex)
if err != nil {
t.Fatal(err)
}
// send and verify delivery
lmsg := []byte("plugh")
err = clients[1].Call(nil, "pss_sendSym", rkeyids[1], topic, hexutil.Encode(lmsg))
if err != nil {
t.Fatal(err)
}
select {
case recvmsg := <-lmsgC:
if !bytes.Equal(recvmsg.Msg, lmsg) {
t.Fatalf("node 1 received payload mismatch: expected %v, got %v", lmsg, recvmsg)
}
case cerr := <-lctx.Done():
t.Fatalf("test message timed out: %v", cerr)
}
rmsg := []byte("xyzzy")
err = clients[0].Call(nil, "pss_sendSym", lkeyids[1], topic, hexutil.Encode(rmsg))
if err != nil {
t.Fatal(err)
}
select {
case recvmsg := <-rmsgC:
if !bytes.Equal(recvmsg.Msg, rmsg) {
t.Fatalf("node 2 received payload mismatch: expected %v, got %v", rmsg, recvmsg.Msg)
}
case cerr := <-rctx.Done():
t.Fatalf("test message timed out: %v", cerr)
}
}
// send asymmetrically encrypted message between two directly connected peers
func TestAsymSend(t *testing.T) {
t.Run("32", testAsymSend)
t.Run("8", testAsymSend)
t.Run("0", testAsymSend)
}
func testAsymSend(t *testing.T) {
// address hint size
var addrsize int64
var err error
paramstring := strings.Split(t.Name(), "/")
addrsize, _ = strconv.ParseInt(paramstring[1], 10, 0)
log.Info("asym send test", "addrsize", addrsize)
clients, err := setupNetwork(2)
if err != nil {
t.Fatal(err)
}
var topic string
err = clients[0].Call(&topic, "pss_stringToTopic", "foo:42")
if err != nil {
t.Fatal(err)
}
time.Sleep(time.Millisecond * 250)
var loaddrhex string
err = clients[0].Call(&loaddrhex, "pss_baseAddr")
if err != nil {
t.Fatalf("rpc get node 1 baseaddr fail: %v", err)
}
loaddrhex = loaddrhex[:2+(addrsize*2)]
var roaddrhex string
err = clients[1].Call(&roaddrhex, "pss_baseAddr")
if err != nil {
t.Fatalf("rpc get node 2 baseaddr fail: %v", err)
}
roaddrhex = roaddrhex[:2+(addrsize*2)]
// retrieve public key from pss instance
// set this public key reciprocally
var lpubkey string
err = clients[0].Call(&lpubkey, "pss_getPublicKey")
if err != nil {
t.Fatalf("rpc get node 1 pubkey fail: %v", err)
}
var rpubkey string
err = clients[1].Call(&rpubkey, "pss_getPublicKey")
if err != nil {
t.Fatalf("rpc get node 2 pubkey fail: %v", err)
}
time.Sleep(time.Millisecond * 500) // replace with hive healthy code
lmsgC := make(chan APIMsg)
lctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()
lsub, err := clients[0].Subscribe(lctx, "pss", lmsgC, "receive", topic)
log.Trace("lsub", "id", lsub)
defer lsub.Unsubscribe()
rmsgC := make(chan APIMsg)
rctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()
rsub, err := clients[1].Subscribe(rctx, "pss", rmsgC, "receive", topic)
log.Trace("rsub", "id", rsub)
defer rsub.Unsubscribe()
// store reciprocal public keys
err = clients[0].Call(nil, "pss_setPeerPublicKey", rpubkey, topic, roaddrhex)
if err != nil {
t.Fatal(err)
}
err = clients[1].Call(nil, "pss_setPeerPublicKey", lpubkey, topic, loaddrhex)
if err != nil {
t.Fatal(err)
}
// send and verify delivery
rmsg := []byte("xyzzy")
err = clients[0].Call(nil, "pss_sendAsym", rpubkey, topic, hexutil.Encode(rmsg))
if err != nil {
t.Fatal(err)
}
select {
case recvmsg := <-rmsgC:
if !bytes.Equal(recvmsg.Msg, rmsg) {
t.Fatalf("node 2 received payload mismatch: expected %v, got %v", rmsg, recvmsg.Msg)
}
case cerr := <-rctx.Done():
t.Fatalf("test message timed out: %v", cerr)
}
lmsg := []byte("plugh")
err = clients[1].Call(nil, "pss_sendAsym", lpubkey, topic, hexutil.Encode(lmsg))
if err != nil {
t.Fatal(err)
}
select {
case recvmsg := <-lmsgC:
if !bytes.Equal(recvmsg.Msg, lmsg) {
t.Fatalf("node 1 received payload mismatch: expected %v, got %v", lmsg, recvmsg.Msg)
}
case cerr := <-lctx.Done():
t.Fatalf("test message timed out: %v", cerr)
}
}
type Job struct {
Msg []byte
SendNode discover.NodeID
RecvNode discover.NodeID
}
func worker(id int, jobs <-chan Job, rpcs map[discover.NodeID]*rpc.Client, pubkeys map[discover.NodeID]string, topic string) {
for j := range jobs {
rpcs[j.SendNode].Call(nil, "pss_sendAsym", pubkeys[j.RecvNode], topic, hexutil.Encode(j.Msg))
}
}
// params in run name:
// nodes/msgs/addrbytes/adaptertype
// if adaptertype is exec uses execadapter, simadapter otherwise
//
// ( some tests are commented out because of resource limitations on Travis)
func TestNetwork(t *testing.T) {
t.Skip("Temporarily deactivated because not all messages can be delivered")
//t.Run("3/2000/4/sock", testNetwork)
//t.Run("4/2000/4/sock", testNetwork)
t.Run("8/2000/4/sock", testNetwork)
t.Run("16/2000/4/sock", testNetwork)
t.Run("8/3000/4/sock", testNetwork)
t.Run("16/3000/4/sock", testNetwork)
//t.Run("32/2000/4/sock", testNetwork)
t.Run("8/2000/4/sim", testNetwork)
t.Run("16/2000/4/sim", testNetwork)
t.Run("8/3000/4/sim", testNetwork)
t.Run("16/3000/4/sim", testNetwork)
//t.Run("32/2000/4/sim", testNetwork)
// t.Run("64/2000/4/sim", testNetwork)
}
func testNetwork(t *testing.T) {
type msgnotifyC struct {
id discover.NodeID
msgIdx int
}
paramstring := strings.Split(t.Name(), "/")
nodecount, _ := strconv.ParseInt(paramstring[1], 10, 0)
msgcount, _ := strconv.ParseInt(paramstring[2], 10, 0)
addrsize, _ := strconv.ParseInt(paramstring[3], 10, 0)
adapter := paramstring[4]
log.Info("network test", "nodecount", nodecount, "msgcount", msgcount, "addrhintsize", addrsize)
nodes := make([]discover.NodeID, nodecount)
bzzaddrs := make(map[discover.NodeID]string, nodecount)
rpcs := make(map[discover.NodeID]*rpc.Client, nodecount)
pubkeys := make(map[discover.NodeID]string, nodecount)
sentmsgs := make([][]byte, msgcount)
recvmsgs := make([]bool, msgcount)
nodemsgcount := make(map[discover.NodeID]int, nodecount)
trigger := make(chan discover.NodeID)
var a adapters.NodeAdapter
if adapter == "exec" {
dirname, err := ioutil.TempDir(".", "")
if err != nil {
t.Fatal(err)
}
a = adapters.NewExecAdapter(dirname)
} else if adapter == "sock" {
a = adapters.NewSocketAdapter(services)
} else if adapter == "tcp" {
a = adapters.NewTCPAdapter(services)
} else if adapter == "sim" {
a = adapters.NewSimAdapter(services)
}
net := simulations.NewNetwork(a, &simulations.NetworkConfig{
ID: "0",
})
defer net.Shutdown()
f, err := os.Open(fmt.Sprintf("testdata/snapshot_%d.json", nodecount))
if err != nil {
t.Fatal(err)
}
jsonbyte, err := ioutil.ReadAll(f)
if err != nil {
t.Fatal(err)
}
var snap simulations.Snapshot
err = json.Unmarshal(jsonbyte, &snap)
if err != nil {
t.Fatal(err)
}
err = net.Load(&snap)
if err != nil {
t.Fatal(err)
}
triggerChecks := func(trigger chan discover.NodeID, id discover.NodeID, rpcclient *rpc.Client, topic string) error {
msgC := make(chan APIMsg)
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
sub, err := rpcclient.Subscribe(ctx, "pss", msgC, "receive", topic)
if err != nil {
t.Fatal(err)
}
go func() {
defer sub.Unsubscribe()
for {
select {
case recvmsg := <-msgC:
idx, _ := binary.Uvarint(recvmsg.Msg)
if !recvmsgs[idx] {
log.Debug("msg recv", "idx", idx, "id", id)
recvmsgs[idx] = true
trigger <- id
}
case <-sub.Err():
return
}
}
}()
return nil
}
var topic string
for i, nod := range net.GetNodes() {
nodes[i] = nod.ID()
rpcs[nodes[i]], err = nod.Client()
if err != nil {
t.Fatal(err)
}
if topic == "" {
err = rpcs[nodes[i]].Call(&topic, "pss_stringToTopic", "foo:42")
if err != nil {
t.Fatal(err)
}
}
var pubkey string
err = rpcs[nodes[i]].Call(&pubkey, "pss_getPublicKey")
if err != nil {
t.Fatal(err)
}
pubkeys[nod.ID()] = pubkey
var addrhex string
err = rpcs[nodes[i]].Call(&addrhex, "pss_baseAddr")
if err != nil {
t.Fatal(err)
}
bzzaddrs[nodes[i]] = addrhex
err = triggerChecks(trigger, nodes[i], rpcs[nodes[i]], topic)
if err != nil {
t.Fatal(err)
}
}
// setup workers
jobs := make(chan Job, 10)
for w := 1; w <= 10; w++ {
go worker(w, jobs, rpcs, pubkeys, topic)
}
for i := 0; i < int(msgcount); i++ {
sendnodeidx := rand.Intn(int(nodecount))
recvnodeidx := rand.Intn(int(nodecount - 1))
if recvnodeidx >= sendnodeidx {
recvnodeidx++
}
nodemsgcount[nodes[recvnodeidx]]++
sentmsgs[i] = make([]byte, 8)
c := binary.PutUvarint(sentmsgs[i], uint64(i))
if c == 0 {
t.Fatal("0 byte message")
}
if err != nil {
t.Fatal(err)
}
err = rpcs[nodes[sendnodeidx]].Call(nil, "pss_setPeerPublicKey", pubkeys[nodes[recvnodeidx]], topic, bzzaddrs[nodes[recvnodeidx]])
if err != nil {
t.Fatal(err)
}
jobs <- Job{
Msg: sentmsgs[i],
SendNode: nodes[sendnodeidx],
RecvNode: nodes[recvnodeidx],
}
}
finalmsgcount := 0
ctx, cancel := context.WithTimeout(context.Background(), 180*time.Second)
defer cancel()
outer:
for i := 0; i < int(msgcount); i++ {
select {
case id := <-trigger:
nodemsgcount[id]--
finalmsgcount++
case <-ctx.Done():
log.Warn("timeout")
break outer
}
}
for i, msg := range recvmsgs {
if !msg {
log.Debug("missing message", "idx", i)
}
}
t.Logf("%d of %d messages received", finalmsgcount, msgcount)
if finalmsgcount != int(msgcount) {
t.Fatalf("%d messages were not received", int(msgcount)-finalmsgcount)
}
}
// symmetric send performance with varying message sizes
func BenchmarkSymkeySend(b *testing.B) {
b.Run(fmt.Sprintf("%d", 256), benchmarkSymKeySend)
b.Run(fmt.Sprintf("%d", 1024), benchmarkSymKeySend)
b.Run(fmt.Sprintf("%d", 1024*1024), benchmarkSymKeySend)
b.Run(fmt.Sprintf("%d", 1024*1024*10), benchmarkSymKeySend)
b.Run(fmt.Sprintf("%d", 1024*1024*100), benchmarkSymKeySend)
}
func benchmarkSymKeySend(b *testing.B) {
msgsizestring := strings.Split(b.Name(), "/")
if len(msgsizestring) != 2 {
b.Fatalf("benchmark called without msgsize param")
}
msgsize, err := strconv.ParseInt(msgsizestring[1], 10, 0)
if err != nil {
b.Fatalf("benchmark called with invalid msgsize param '%s': %v", msgsizestring[1], err)
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
keys, err := wapi.NewKeyPair(ctx)
privkey, err := w.GetPrivateKey(keys)
ps := newTestPss(privkey, nil, nil)
msg := make([]byte, msgsize)
rand.Read(msg)
topic := BytesToTopic([]byte("foo"))
to := make(PssAddress, 32)
copy(to[:], network.RandomAddr().Over())
symkeyid, err := ps.generateSymmetricKey(topic, &to, true)
if err != nil {
b.Fatalf("could not generate symkey: %v", err)
}
symkey, err := ps.w.GetSymKey(symkeyid)
if err != nil {
b.Fatalf("could not retrieve symkey: %v", err)
}
ps.SetSymmetricKey(symkey, topic, &to, false)
b.ResetTimer()
for i := 0; i < b.N; i++ {
ps.SendSym(symkeyid, topic, msg)
}
}
// asymmetric send performance with varying message sizes
func BenchmarkAsymkeySend(b *testing.B) {
b.Run(fmt.Sprintf("%d", 256), benchmarkAsymKeySend)
b.Run(fmt.Sprintf("%d", 1024), benchmarkAsymKeySend)
b.Run(fmt.Sprintf("%d", 1024*1024), benchmarkAsymKeySend)
b.Run(fmt.Sprintf("%d", 1024*1024*10), benchmarkAsymKeySend)
b.Run(fmt.Sprintf("%d", 1024*1024*100), benchmarkAsymKeySend)
}
func benchmarkAsymKeySend(b *testing.B) {
msgsizestring := strings.Split(b.Name(), "/")
if len(msgsizestring) != 2 {
b.Fatalf("benchmark called without msgsize param")
}
msgsize, err := strconv.ParseInt(msgsizestring[1], 10, 0)
if err != nil {
b.Fatalf("benchmark called with invalid msgsize param '%s': %v", msgsizestring[1], err)
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
keys, err := wapi.NewKeyPair(ctx)
privkey, err := w.GetPrivateKey(keys)
ps := newTestPss(privkey, nil, nil)
msg := make([]byte, msgsize)
rand.Read(msg)
topic := BytesToTopic([]byte("foo"))
to := make(PssAddress, 32)
copy(to[:], network.RandomAddr().Over())
ps.SetPeerPublicKey(&privkey.PublicKey, topic, &to)
b.ResetTimer()
for i := 0; i < b.N; i++ {
ps.SendAsym(common.ToHex(crypto.FromECDSAPub(&privkey.PublicKey)), topic, msg)
}
}
func BenchmarkSymkeyBruteforceChangeaddr(b *testing.B) {
for i := 100; i < 100000; i = i * 10 {
for j := 32; j < 10000; j = j * 8 {
b.Run(fmt.Sprintf("%d/%d", i, j), benchmarkSymkeyBruteforceChangeaddr)
}
//b.Run(fmt.Sprintf("%d", i), benchmarkSymkeyBruteforceChangeaddr)
}
}
// decrypt performance using symkey cache, worst case
// (decrypt key always last in cache)
func benchmarkSymkeyBruteforceChangeaddr(b *testing.B) {
keycountstring := strings.Split(b.Name(), "/")
cachesize := int64(0)
var ps *Pss
if len(keycountstring) < 2 {
b.Fatalf("benchmark called without count param")
}
keycount, err := strconv.ParseInt(keycountstring[1], 10, 0)
if err != nil {
b.Fatalf("benchmark called with invalid count param '%s': %v", keycountstring[1], err)
}
if len(keycountstring) == 3 {
cachesize, err = strconv.ParseInt(keycountstring[2], 10, 0)
if err != nil {
b.Fatalf("benchmark called with invalid cachesize '%s': %v", keycountstring[2], err)
}
}
pssmsgs := make([]*PssMsg, 0, keycount)
var keyid string
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
keys, err := wapi.NewKeyPair(ctx)
privkey, err := w.GetPrivateKey(keys)
if cachesize > 0 {
ps = newTestPss(privkey, nil, &PssParams{SymKeyCacheCapacity: int(cachesize)})
} else {
ps = newTestPss(privkey, nil, nil)
}
topic := BytesToTopic([]byte("foo"))
for i := 0; i < int(keycount); i++ {
to := make(PssAddress, 32)
copy(to[:], network.RandomAddr().Over())
keyid, err = ps.generateSymmetricKey(topic, &to, true)
if err != nil {
b.Fatalf("cant generate symkey #%d: %v", i, err)
}
symkey, err := ps.w.GetSymKey(keyid)
if err != nil {
b.Fatalf("could not retrieve symkey %s: %v", keyid, err)
}
wparams := &whisper.MessageParams{
TTL: defaultWhisperTTL,
KeySym: symkey,
Topic: whisper.TopicType(topic),
WorkTime: defaultWhisperWorkTime,
PoW: defaultWhisperPoW,
Payload: []byte("xyzzy"),
Padding: []byte("1234567890abcdef"),
}
woutmsg, err := whisper.NewSentMessage(wparams)
if err != nil {
b.Fatalf("could not create whisper message: %v", err)
}
env, err := woutmsg.Wrap(wparams)
if err != nil {
b.Fatalf("could not generate whisper envelope: %v", err)
}
ps.Register(&topic, func(msg []byte, p *p2p.Peer, asymmetric bool, keyid string) error {
return nil
})
pssmsgs = append(pssmsgs, &PssMsg{
To: to,
Payload: env,
})
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
if !ps.process(pssmsgs[len(pssmsgs)-(i%len(pssmsgs))-1]) {
b.Fatalf("pss processing failed: %v", err)
}
}
}
func BenchmarkSymkeyBruteforceSameaddr(b *testing.B) {
for i := 100; i < 100000; i = i * 10 {
for j := 32; j < 10000; j = j * 8 {
b.Run(fmt.Sprintf("%d/%d", i, j), benchmarkSymkeyBruteforceSameaddr)
}
}
}
// decrypt performance using symkey cache, best case
// (decrypt key always first in cache)
func benchmarkSymkeyBruteforceSameaddr(b *testing.B) {
var keyid string
var ps *Pss
cachesize := int64(0)
keycountstring := strings.Split(b.Name(), "/")
if len(keycountstring) < 2 {
b.Fatalf("benchmark called without count param")
}
keycount, err := strconv.ParseInt(keycountstring[1], 10, 0)
if err != nil {
b.Fatalf("benchmark called with invalid count param '%s': %v", keycountstring[1], err)
}
if len(keycountstring) == 3 {
cachesize, err = strconv.ParseInt(keycountstring[2], 10, 0)
if err != nil {
b.Fatalf("benchmark called with invalid cachesize '%s': %v", keycountstring[2], err)
}
}
addr := make([]PssAddress, keycount)
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
keys, err := wapi.NewKeyPair(ctx)
privkey, err := w.GetPrivateKey(keys)
if cachesize > 0 {
ps = newTestPss(privkey, nil, &PssParams{SymKeyCacheCapacity: int(cachesize)})
} else {
ps = newTestPss(privkey, nil, nil)
}
topic := BytesToTopic([]byte("foo"))
for i := 0; i < int(keycount); i++ {
copy(addr[i], network.RandomAddr().Over())
keyid, err = ps.generateSymmetricKey(topic, &addr[i], true)
if err != nil {
b.Fatalf("cant generate symkey #%d: %v", i, err)
}
}
symkey, err := ps.w.GetSymKey(keyid)
if err != nil {
b.Fatalf("could not retrieve symkey %s: %v", keyid, err)
}
wparams := &whisper.MessageParams{
TTL: defaultWhisperTTL,
KeySym: symkey,
Topic: whisper.TopicType(topic),
WorkTime: defaultWhisperWorkTime,
PoW: defaultWhisperPoW,
Payload: []byte("xyzzy"),
Padding: []byte("1234567890abcdef"),
}
woutmsg, err := whisper.NewSentMessage(wparams)
if err != nil {
b.Fatalf("could not create whisper message: %v", err)
}
env, err := woutmsg.Wrap(wparams)
if err != nil {
b.Fatalf("could not generate whisper envelope: %v", err)
}
ps.Register(&topic, func(msg []byte, p *p2p.Peer, asymmetric bool, keyid string) error {
return nil
})
pssmsg := &PssMsg{
To: addr[len(addr)-1][:],
Payload: env,
}
for i := 0; i < b.N; i++ {
if !ps.process(pssmsg) {
b.Fatalf("pss processing failed: %v", err)
}
}
}