diff --git a/.github/workflows/go_integration_tests.yml b/.github/workflows/go_integration_tests.yml
index dac6070f5..791619e25 100644
--- a/.github/workflows/go_integration_tests.yml
+++ b/.github/workflows/go_integration_tests.yml
@@ -16,31 +16,9 @@ jobs:
uses: actions/setup-go@v2
with:
go-version: ^1.17
-
- - name: Install crypto util from Dela
- run: |
- git clone https://github.com/dedis/dela.git
- cd dela
- go install ./cli/crypto
- name: Check out code into the Go module directory
uses: actions/checkout@v2
-
- - name: Create a private key
- run: crypto bls signer new --save private.key
-
- - name: Install memcoin
- run: make build
-
- - name: Start 3 nodes
- run: |
- ./memcoin --config /tmp/node1 start --postinstall --promaddr :9100 --proxyaddr :9080 --proxykey adbacd10fdb9822c71025d6d00092b8a4abb5ebcb673d28d863f7c7c5adaddf3 --listen tcp://0.0.0.0:2001 --public //localhost:2001 &
- ./memcoin --config /tmp/node2 start --postinstall --promaddr :9101 --proxyaddr :9081 --proxykey adbacd10fdb9822c71025d6d00092b8a4abb5ebcb673d28d863f7c7c5adaddf3 --listen tcp://0.0.0.0:2002 --public //localhost:2002 &
- ./memcoin --config /tmp/node3 start --postinstall --promaddr :9102 --proxyaddr :9082 --proxykey adbacd10fdb9822c71025d6d00092b8a4abb5ebcb673d28d863f7c7c5adaddf3 --listen tcp://0.0.0.0:2003 --public //localhost:2003 &
-
- - name: Run the setup
- run: ./setupnNode.sh -n 3 -d false
-
- - name: Test integration & benchmark with coverage
- run: go test -bench -cover -tags=integration ./integration/...
+ - name: Run the integration test
+ run: go test -timeout 7m -run TestIntegration ./integration/...
\ No newline at end of file
diff --git a/.github/workflows/go_scenario_test.yml b/.github/workflows/go_scenario_test.yml
new file mode 100644
index 000000000..5d763271a
--- /dev/null
+++ b/.github/workflows/go_scenario_test.yml
@@ -0,0 +1,45 @@
+name: Go Scenario Test (with proxy)
+
+on:
+ push:
+ branches: [ main ]
+ pull_request:
+ branches: [ main ]
+
+jobs:
+
+ test:
+ name: Tests
+ runs-on: ubuntu-latest
+ steps:
+ - name: Set up Go ^1.17
+ uses: actions/setup-go@v2
+ with:
+ go-version: ^1.17
+
+ - name: Install crypto util from Dela
+ run: |
+ git clone https://github.com/dedis/dela.git
+ cd dela
+ go install ./cli/crypto
+
+ - name: Check out code into the Go module directory
+ uses: actions/checkout@v2
+
+ - name: Create a private key
+ run: crypto bls signer new --save private.key
+
+ - name: Install memcoin
+ run: make build
+
+ - name: Start 3 nodes
+ run: |
+ ./memcoin --config /tmp/node1 start --postinstall --promaddr :9100 --proxyaddr :9080 --proxykey adbacd10fdb9822c71025d6d00092b8a4abb5ebcb673d28d863f7c7c5adaddf3 --listen tcp://0.0.0.0:2001 --public //localhost:2001 --routing tree &
+ ./memcoin --config /tmp/node2 start --postinstall --promaddr :9101 --proxyaddr :9081 --proxykey adbacd10fdb9822c71025d6d00092b8a4abb5ebcb673d28d863f7c7c5adaddf3 --listen tcp://0.0.0.0:2002 --public //localhost:2002 --routing tree &
+ ./memcoin --config /tmp/node3 start --postinstall --promaddr :9102 --proxyaddr :9082 --proxykey adbacd10fdb9822c71025d6d00092b8a4abb5ebcb673d28d863f7c7c5adaddf3 --listen tcp://0.0.0.0:2003 --public //localhost:2003 --routing tree &
+
+ - name: Run the setup
+ run: ./setupnNode.sh -n 3 -d false
+
+ - name: Run the scenario Test
+ run: go test -timeout 7m -run TestScenario ./integration/...
diff --git a/.github/workflows/go_test.yml b/.github/workflows/go_test.yml
index 934a2c51a..bd7ff1429 100644
--- a/.github/workflows/go_test.yml
+++ b/.github/workflows/go_test.yml
@@ -1,4 +1,4 @@
-name: Go Test
+name: Go Unit Tests
on:
push:
@@ -10,14 +10,14 @@ jobs:
name: Tests
runs-on: ubuntu-latest
steps:
- - name: Set up Go ^1.17
- uses: actions/setup-go@v2
+ - name: Use Go >= 1.19
+ uses: actions/setup-go@v3
with:
- go-version: ^1.17
+ go-version: '>=1.19'
id: go
- name: Check out code into the Go module directory
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- name: Run lint
run: make lint
diff --git a/README.md b/README.md
index 88dad8ce3..e6e6c2617 100644
--- a/README.md
+++ b/README.md
@@ -12,6 +12,9 @@
+
+
+
@@ -29,6 +32,9 @@
+
+
+
@@ -354,7 +360,7 @@ results.
# ⚙️ Setup
-First be sure to have Go installed (at least 1.17).
+First be sure to have Go installed (at least 1.19).
Be sure to have the `crypto` utility from Dela:
diff --git a/cli/cosipbftcontroller/action_test.go b/cli/cosipbftcontroller/action_test.go
index 479dd0352..322b89863 100644
--- a/cli/cosipbftcontroller/action_test.go
+++ b/cli/cosipbftcontroller/action_test.go
@@ -3,7 +3,7 @@ package controller
import (
"bytes"
"context"
- "io/ioutil"
+ "io"
"testing"
"time"
@@ -172,7 +172,7 @@ func prepContext(calls *fake.Call) node.Context {
ctx := node.Context{
Injector: node.NewInjector(),
Flags: make(node.FlagSet),
- Out: ioutil.Discard,
+ Out: io.Discard,
}
events := []ordering.Event{
diff --git a/cli/cosipbftcontroller/mod_test.go b/cli/cosipbftcontroller/mod_test.go
index 0a9237641..ac9e3525e 100644
--- a/cli/cosipbftcontroller/mod_test.go
+++ b/cli/cosipbftcontroller/mod_test.go
@@ -2,7 +2,6 @@ package controller
import (
"encoding"
- "io/ioutil"
"os"
"path/filepath"
"testing"
@@ -105,7 +104,7 @@ func TestMinimal_MalformedKey_OnStart(t *testing.T) {
}
func TestMinimal_OnStop(t *testing.T) {
- dir, err := ioutil.TempDir(os.TempDir(), "dela-test-")
+ dir, err := os.MkdirTemp(os.TempDir(), "dela-test-")
require.NoError(t, err)
db, err := kv.New(filepath.Join(dir, "test.db"))
@@ -152,7 +151,7 @@ func TestMinimal_OnStop(t *testing.T) {
// Utility functions
func makeFlags(t *testing.T) (cli.Flags, string, func()) {
- dir, err := ioutil.TempDir(os.TempDir(), "dela-")
+ dir, err := os.MkdirTemp(os.TempDir(), "dela-")
require.NoError(t, err)
fset := make(node.FlagSet)
diff --git a/cli/memcoin/mod_test.go b/cli/memcoin/mod_test.go
index df4ec489a..876bbed15 100644
--- a/cli/memcoin/mod_test.go
+++ b/cli/memcoin/mod_test.go
@@ -3,7 +3,7 @@ package main
import (
"bytes"
"fmt"
- "io/ioutil"
+ "io"
"net"
"os"
"path/filepath"
@@ -25,7 +25,7 @@ func TestMemcoin_Main(t *testing.T) {
// be able to communicate, but the chain should proceed because of the
// threshold.
func TestMemcoin_Scenario_SetupAndTransactions(t *testing.T) {
- dir, err := ioutil.TempDir(os.TempDir(), "memcoin1")
+ dir, err := os.MkdirTemp(os.TempDir(), "memcoin1")
require.NoError(t, err)
defer os.RemoveAll(dir)
@@ -40,7 +40,7 @@ func TestMemcoin_Scenario_SetupAndTransactions(t *testing.T) {
node4 := filepath.Join(dir, "node4")
node5 := filepath.Join(dir, "node5")
- cfg := config{Channel: sigs, Writer: ioutil.Discard}
+ cfg := config{Channel: sigs, Writer: io.Discard}
runNode(t, node1, cfg, 2111, &wg)
runNode(t, node2, cfg, 2112, &wg)
@@ -117,7 +117,7 @@ func TestMemcoin_Scenario_SetupAndTransactions(t *testing.T) {
// restart. It basically tests if the components are correctly loaded from the
// persisten storage.
func TestMemcoin_Scenario_RestartNode(t *testing.T) {
- dir, err := ioutil.TempDir(os.TempDir(), "memcoin2")
+ dir, err := os.MkdirTemp(os.TempDir(), "memcoin2")
require.NoError(t, err)
defer os.RemoveAll(dir)
@@ -132,7 +132,7 @@ func TestMemcoin_Scenario_RestartNode(t *testing.T) {
wg := sync.WaitGroup{}
wg.Add(2)
- cfg := config{Channel: sigs, Writer: ioutil.Discard}
+ cfg := config{Channel: sigs, Writer: io.Discard}
// Now the node are restarted. It should correctly follow the existing chain
// and then participate to new blocks.
@@ -177,7 +177,7 @@ func setupChain(t *testing.T, nodes []string, ports []uint16) {
wg := sync.WaitGroup{}
wg.Add(len(nodes))
- cfg := config{Channel: sigs, Writer: ioutil.Discard}
+ cfg := config{Channel: sigs, Writer: io.Discard}
for i, node := range nodes {
runNode(t, node, cfg, ports[i], &wg)
diff --git a/contracts/evoting/controller/action.go b/contracts/evoting/controller/action.go
index a030613be..b6134f6a8 100644
--- a/contracts/evoting/controller/action.go
+++ b/contracts/evoting/controller/action.go
@@ -8,7 +8,6 @@ import (
"encoding/json"
"fmt"
"io"
- "io/ioutil"
"net/http"
"strconv"
"strings"
@@ -267,7 +266,7 @@ func (a *scenarioTestAction) Execute(ctx node.Context) error {
}
if resp.StatusCode != http.StatusOK {
- buf, _ := ioutil.ReadAll(resp.Body)
+ buf, _ := io.ReadAll(resp.Body)
return xerrors.Errorf("unexpected status: %s - %s", resp.Status, buf)
}
@@ -525,7 +524,7 @@ func (a *scenarioTestAction) Execute(ctx node.Context) error {
}
if resp.StatusCode != http.StatusOK {
- buf, _ := ioutil.ReadAll(resp.Body)
+ buf, _ := io.ReadAll(resp.Body)
return xerrors.Errorf("unexpected shuffle status: %s - %s", resp.Status, buf)
}
@@ -686,7 +685,7 @@ func castVote(electionID string, signed []byte, proxyAddr string) (string, error
}
if resp.StatusCode != http.StatusOK {
- buf, _ := ioutil.ReadAll(resp.Body)
+ buf, _ := io.ReadAll(resp.Body)
return "", xerrors.Errorf("unexpected status: %s - %s", resp.Status, buf)
}
@@ -721,7 +720,7 @@ func updateElection(secret kyber.Scalar, proxyAddr, electionIDHex, action string
}
if resp.StatusCode != http.StatusOK {
- buf, _ := ioutil.ReadAll(resp.Body)
+ buf, _ := io.ReadAll(resp.Body)
return resp.StatusCode, xerrors.Errorf("unexpected status: %s - %s", resp.Status, buf)
}
@@ -744,7 +743,7 @@ func initDKG(secret kyber.Scalar, proxyAddr, electionIDHex string) error {
}
if resp.StatusCode != http.StatusOK {
- buf, _ := ioutil.ReadAll(resp.Body)
+ buf, _ := io.ReadAll(resp.Body)
return xerrors.Errorf("unexpected status: %s - %s", resp.Status, buf)
}
@@ -772,7 +771,7 @@ func updateDKG(secret kyber.Scalar, proxyAddr, electionIDHex, action string) (in
}
if resp.StatusCode != http.StatusOK {
- buf, _ := ioutil.ReadAll(resp.Body)
+ buf, _ := io.ReadAll(resp.Body)
return resp.StatusCode, xerrors.Errorf("unexpected status: %s - %s", resp.Status, buf)
}
diff --git a/contracts/evoting/types/ballots.go b/contracts/evoting/types/ballots.go
index bb95a160e..9cdeaea8c 100644
--- a/contracts/evoting/types/ballots.go
+++ b/contracts/evoting/types/ballots.go
@@ -171,8 +171,6 @@ func (b *Ballot) invalidate() {
// Equal performs a loose comparison of a ballot.
func (b *Ballot) Equal(other Ballot) bool {
- fmt.Printf("b: %v\n", b)
- fmt.Printf("other: %v\n", other)
if len(b.SelectResultIDs) != len(other.SelectResultIDs) {
return false
}
diff --git a/contracts/evoting/types/ballots_test.go b/contracts/evoting/types/ballots_test.go
index 0dec0b364..c4e28ed73 100644
--- a/contracts/evoting/types/ballots_test.go
+++ b/contracts/evoting/types/ballots_test.go
@@ -158,7 +158,7 @@ func TestBallot_Unmarshal(t *testing.T) {
err = b.Unmarshal(ballotWrongSelect, election)
require.EqualError(t, err, "could not unmarshal select answers: "+
- "question Q1 has too many selected answers")
+ "failed to check number of answers: question Q1 has too many selected answers")
// with not enough selected answers in select question
ballotWrongSelect = string("select:" + encodedQuestionID(1) + ":1,0,0\n" +
@@ -170,7 +170,7 @@ func TestBallot_Unmarshal(t *testing.T) {
err = b.Unmarshal(ballotWrongSelect, election)
require.EqualError(t, err, "could not unmarshal select answers: "+
- "question Q1 has not enough selected answers")
+ "failed to check number of answers: question Q1 has not enough selected answers")
// with not enough answers in rank question
ballotWrongRank := string("select:" + encodedQuestionID(1) + ":1,0,1\n" +
@@ -192,7 +192,7 @@ func TestBallot_Unmarshal(t *testing.T) {
err = b.Unmarshal(ballotWrongRank, election)
require.EqualError(t, err, "could not unmarshal rank answers: "+
- "could not parse rank value for Q.Q2 : strconv.ParseInt: parsing \"x\": invalid syntax")
+ "could not parse rank value for Q.Q2: strconv.ParseInt: parsing \"x\": invalid syntax")
// with too many selected answers in rank question
ballotWrongRank = string("select:" + encodedQuestionID(1) + ":1,0,1\n" +
@@ -204,7 +204,7 @@ func TestBallot_Unmarshal(t *testing.T) {
err = b.Unmarshal(ballotWrongRank, election)
require.EqualError(t, err, "could not unmarshal rank answers: "+
- "invalid rank not in range [0, MaxN[")
+ "invalid rank not in range [0, MaxN[: 3")
// with valid ranks but one is selected twice
ballotWrongRank = string("select:" + encodedQuestionID(1) + ":1,0,1\n" +
@@ -216,7 +216,7 @@ func TestBallot_Unmarshal(t *testing.T) {
err = b.Unmarshal(ballotWrongRank, election)
require.EqualError(t, err, "could not unmarshal rank answers: "+
- "question Q2 has too many selected answers")
+ "failed to check number of answers: question Q2 has too many selected answers")
// with not enough selected answers in rank question
ballotWrongRank = string("select:" + encodedQuestionID(1) + ":1,0,1\n" +
@@ -227,7 +227,8 @@ func TestBallot_Unmarshal(t *testing.T) {
election.BallotSize = len(ballotWrongRank)
err = b.Unmarshal(ballotWrongRank, election)
- require.EqualError(t, err, "could not unmarshal rank answers: question"+
+ require.EqualError(t, err, "could not unmarshal rank answers: "+
+ "failed to check number of answers: question"+
" Q2 has not enough selected answers")
// with not enough answers in text question
@@ -252,7 +253,7 @@ func TestBallot_Unmarshal(t *testing.T) {
err = b.Unmarshal(ballotWrongText, election)
require.EqualError(t, err, "could not unmarshal text answers: "+
- "could not decode text for Q. Q4: illegal base64 data at input byte 12")
+ "could not decode text for Q.Q4: illegal base64 data at input byte 12")
// with too many selected answers in text question
election.Configuration.Scaffold[0].Texts[0].MaxN = 1
@@ -266,7 +267,7 @@ func TestBallot_Unmarshal(t *testing.T) {
err = b.Unmarshal(ballotWrongText, election)
require.EqualError(t, err, "could not unmarshal text answers: "+
- "question Q4 has too many selected answers")
+ "failed to check number of answers: question Q4 has too many selected answers")
election.Configuration.Scaffold[0].Texts[0].MaxN = 2
@@ -280,7 +281,7 @@ func TestBallot_Unmarshal(t *testing.T) {
err = b.Unmarshal(ballotWrongText, election)
require.EqualError(t, err, "could not unmarshal text answers: "+
- "question Q4 has not enough selected answers")
+ "failed to check number of answers: question Q4 has not enough selected answers")
// with unknown question type
ballotWrongType := string("wrong:" + encodedQuestionID(1) + ":")
@@ -382,14 +383,6 @@ func TestSubject_IsValid(t *testing.T) {
valid := configuration.IsValid()
require.True(t, valid)
- // with wrongly ID not in base64
- mainSubject.ID = "zzz"
-
- configuration.Scaffold = []Subject{*mainSubject}
-
- valid = configuration.IsValid()
- require.False(t, valid)
-
// with double IDs
mainSubject.ID = ID(base64.StdEncoding.EncodeToString([]byte("S1")))
diff --git a/go.mod b/go.mod
index d4523fb84..708aa7ec3 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
module github.com/dedis/d-voting
-go 1.16
+go 1.19
require (
github.com/gorilla/mux v1.8.0
@@ -9,10 +9,42 @@ require (
github.com/rs/zerolog v1.19.0
github.com/stretchr/testify v1.7.0
github.com/uber/jaeger-client-go v2.25.0+incompatible
- go.dedis.ch/dela v0.0.0-20220705073643-0b58fb2e471f
+ go.dedis.ch/dela v0.0.0-20220727144418-4a9466c2c294
go.dedis.ch/dela-apps v0.0.0-20211019120455-a0db752a0ba0
go.dedis.ch/kyber/v3 v3.1.0-alpha
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f
golang.org/x/tools v0.1.11-0.20220316014157-77aa08bb151a
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1
)
+
+require (
+ github.com/beorn7/perks v1.0.1 // indirect
+ github.com/cespare/xxhash/v2 v2.1.2 // indirect
+ github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
+ github.com/davecgh/go-spew v1.1.1 // indirect
+ github.com/golang/protobuf v1.5.2 // indirect
+ github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
+ github.com/opentracing-contrib/go-grpc v0.0.0-20200813121455-4a6760c71486 // indirect
+ github.com/pkg/errors v0.9.1 // indirect
+ github.com/pmezard/go-difflib v1.0.0 // indirect
+ github.com/prometheus/client_model v0.2.0 // indirect
+ github.com/prometheus/common v0.32.1 // indirect
+ github.com/prometheus/procfs v0.7.3 // indirect
+ github.com/rs/xid v1.2.1 // indirect
+ github.com/russross/blackfriday/v2 v2.0.1 // indirect
+ github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
+ github.com/uber/jaeger-lib v2.4.0+incompatible // indirect
+ github.com/urfave/cli/v2 v2.2.0 // indirect
+ go.dedis.ch/fixbuf v1.0.3 // indirect
+ go.dedis.ch/protobuf v1.0.11 // indirect
+ go.etcd.io/bbolt v1.3.5 // indirect
+ go.uber.org/atomic v1.7.0 // indirect
+ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
+ golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect
+ golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect
+ golang.org/x/text v0.3.7 // indirect
+ google.golang.org/genproto v0.0.0-20200825200019-8632dd797987 // indirect
+ google.golang.org/grpc v1.49.0 // indirect
+ google.golang.org/protobuf v1.27.1 // indirect
+ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
+)
diff --git a/go.sum b/go.sum
index 5984bf2bf..6539bccd6 100644
--- a/go.sum
+++ b/go.sum
@@ -124,8 +124,8 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
@@ -244,10 +244,8 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.dedis.ch/dela v0.0.0-20211018150429-1fdbe35cd189/go.mod h1:GVQ2MumgCcAkor2MmfRCoqTBsFjaaqt7HfJpQLhMGok=
-go.dedis.ch/dela v0.0.0-20220428080424-2348afb6228a h1:Ahci1dtYYj9MIVOUjsA2kavD6oAEmnLZrwBctzHOYYA=
-go.dedis.ch/dela v0.0.0-20220428080424-2348afb6228a/go.mod h1:IIIV0aR0f1c9z4jRB2HVYYeLK7XbQ6pfqv6RufaXmUg=
-go.dedis.ch/dela v0.0.0-20220705073643-0b58fb2e471f h1:BbrlaRV3rFMTlKUQ+o2PJJQUlmyINIqB4FPmMlsSLjU=
-go.dedis.ch/dela v0.0.0-20220705073643-0b58fb2e471f/go.mod h1:IIIV0aR0f1c9z4jRB2HVYYeLK7XbQ6pfqv6RufaXmUg=
+go.dedis.ch/dela v0.0.0-20220727144418-4a9466c2c294 h1:q+kgJ4Cso4daxyR1owhz5jmFNxTG/O0xI4O/ppHaPdQ=
+go.dedis.ch/dela v0.0.0-20220727144418-4a9466c2c294/go.mod h1:IIIV0aR0f1c9z4jRB2HVYYeLK7XbQ6pfqv6RufaXmUg=
go.dedis.ch/dela-apps v0.0.0-20211019120455-a0db752a0ba0 h1:gPrJd+7QUuADpfToMKr80maGnjGPeB7ft7iNrkAtwGY=
go.dedis.ch/dela-apps v0.0.0-20211019120455-a0db752a0ba0/go.mod h1:MoJSdm3LXkNtiKEK3eiBKgqFhory4v8sBr7ldFP/vFc=
go.dedis.ch/fixbuf v1.0.3 h1:hGcV9Cd/znUxlusJ64eAlExS+5cJDIyTyEG+otu5wQs=
@@ -536,8 +534,9 @@ google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
-google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M=
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
+google.golang.org/grpc v1.49.0 h1:WTLtQzmQori5FUH25Pq4WT22oCsv8USpQ+F6rqtsmxw=
+google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@@ -549,8 +548,9 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
-google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
+google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
diff --git a/integration/dvotingdela.go b/integration/dvotingdela.go
index 8abb41b93..02ec67771 100644
--- a/integration/dvotingdela.go
+++ b/integration/dvotingdela.go
@@ -315,7 +315,7 @@ func (c dVotingNode) Setup(nodes ...dela) {
token := joinable.GenerateToken(time.Hour)
- certHash, err := joinable.GetCertificateStore().Hash(joinable.GetCertificate())
+ certHash, err := joinable.GetCertificateStore().Hash(joinable.GetCertificateChain())
require.NoError(c.t, err)
for _, n := range nodes {
diff --git a/integration/integration_test.go b/integration/integration_test.go
index 852819270..60985c858 100644
--- a/integration/integration_test.go
+++ b/integration/integration_test.go
@@ -8,7 +8,6 @@ import (
"encoding/hex"
"fmt"
"io"
- "io/ioutil"
"math/rand"
"os"
"strconv"
@@ -60,7 +59,7 @@ func getIntegrationTest(numNodes, numVotes int) func(*testing.T) {
delaPkg.Logger = delaPkg.Logger.Level(zerolog.WarnLevel)
- dirPath, err := ioutil.TempDir(os.TempDir(), "d-voting-three-votes")
+ dirPath, err := os.MkdirTemp(os.TempDir(), "d-voting-three-votes")
require.NoError(t, err)
defer os.RemoveAll(dirPath)
@@ -72,7 +71,7 @@ func getIntegrationTest(numNodes, numVotes int) func(*testing.T) {
signer := createDVotingAccess(t, nodes, dirPath)
- m := newTxManager(signer, nodes[0], time.Second*time.Duration(numNodes/2+1), numNodes*2)
+ m := newTxManager(signer, nodes[0], time.Second*time.Duration(numNodes/2+1), numNodes*4)
err = grantAccess(m, signer)
require.NoError(t, err)
@@ -111,8 +110,9 @@ func getIntegrationTest(numNodes, numVotes int) func(*testing.T) {
err = closeElection(m, electionID, adminID)
require.NoError(t, err)
- waitForStatus(t, types.Closed, electionFac, electionID, nodes, numNodes,
+ err = waitForStatus(types.Closed, electionFac, electionID, nodes, numNodes,
5*time.Second)
+ require.NoError(t, err)
// ##### SHUFFLE BALLOTS #####
t.Logf("initializing shuffle")
@@ -125,8 +125,9 @@ func getIntegrationTest(numNodes, numVotes int) func(*testing.T) {
err = sActor.Shuffle(electionID)
require.NoError(t, err)
- waitForStatus(t, types.ShuffledBallots, electionFac, electionID, nodes,
+ err = waitForStatus(types.ShuffledBallots, electionFac, electionID, nodes,
numNodes, 2*time.Second*time.Duration(numNodes))
+ require.NoError(t, err)
// ##### SUBMIT PUBLIC SHARES #####
t.Logf("submitting public shares")
@@ -136,8 +137,9 @@ func getIntegrationTest(numNodes, numVotes int) func(*testing.T) {
err = actor.ComputePubshares()
require.NoError(t, err)
- waitForStatus(t, types.PubSharesSubmitted, electionFac, electionID, nodes,
+ err = waitForStatus(types.PubSharesSubmitted, electionFac, electionID, nodes,
numNodes, 6*time.Second*time.Duration(numNodes))
+ require.NoError(t, err)
// ##### DECRYPT BALLOTS #####
t.Logf("decrypting")
@@ -148,8 +150,9 @@ func getIntegrationTest(numNodes, numVotes int) func(*testing.T) {
err = decryptBallots(m, actor, election)
require.NoError(t, err)
- waitForStatus(t, types.ResultAvailable, electionFac, electionID, nodes,
+ err = waitForStatus(types.ResultAvailable, electionFac, electionID, nodes,
numNodes, 1500*time.Millisecond*time.Duration(numVotes))
+ require.NoError(t, err)
t.Logf("get vote proof")
election, err = getElection(electionFac, electionID, nodes[0].GetOrdering())
@@ -173,7 +176,12 @@ func getIntegrationTest(numNodes, numVotes int) func(*testing.T) {
require.True(t, ok)
}
- closeNodes(t, nodes)
+ fmt.Println("closing nodes")
+
+ err = closeNodes(nodes)
+ require.NoError(t, err)
+
+ fmt.Println("test done")
}
}
@@ -544,7 +552,7 @@ func decryptBallots(m txManager, actor dkg.Actor, election types.Election) error
return nil
}
-func closeNodes(t *testing.T, nodes []dVotingCosiDela) {
+func closeNodes(nodes []dVotingCosiDela) error {
wait := sync.WaitGroup{}
wait.Add(len(nodes))
@@ -555,20 +563,19 @@ func closeNodes(t *testing.T, nodes []dVotingCosiDela) {
}(n.(dVotingNode))
}
- t.Log("stopping nodes...")
-
done := make(chan struct{})
go func() {
- select {
- case <-done:
- case <-time.After(time.Second * 30):
- t.Error("timeout while closing nodes")
- }
+ wait.Wait()
+ close(done)
}()
- wait.Wait()
- close(done)
+ select {
+ case <-done:
+ return nil
+ case <-time.After(time.Second * 30):
+ return xerrors.New("failed to close: timeout")
+ }
}
func encodeID(ID string) types.ID {
@@ -577,31 +584,40 @@ func encodeID(ID string) types.ID {
// waitForStatus polls the nodes until they all updated to the expected status
// for the given election. An error is raised if the timeout expires.
-func waitForStatus(t *testing.T, status types.Status, electionFac types.ElectionFactory,
- electionID []byte, nodes []dVotingCosiDela, numNodes int, timeOut time.Duration) {
- // set up a timer to fail the test in case we never reach the status
- timer := time.NewTimer(timeOut)
- go func() {
- <-timer.C
- t.Errorf("timed out while waiting for status %d", status)
- }()
+func waitForStatus(status types.Status, electionFac types.ElectionFactory,
+ electionID []byte, nodes []dVotingCosiDela, numNodes int, timeOut time.Duration) error {
- isOK := func() bool {
+ expiration := time.Now().Add(timeOut)
+
+ isOK := func() (bool, error) {
for _, node := range nodes {
election, err := getElection(electionFac, electionID, node.GetOrdering())
- require.NoError(t, err)
+ if err != nil {
+ return false, xerrors.Errorf("failed to get election: %v", err)
+ }
if election.Status != status {
- return false
+ return false, nil
}
}
- return true
+ return true, nil
}
- for !isOK() {
+ for {
+ if time.Now().After(expiration) {
+ return xerrors.New("status check expired")
+ }
+
+ ok, err := isOK()
+ if err != nil {
+ return xerrors.Errorf("failed to check status: %v", err)
+ }
+
+ if ok {
+ return nil
+ }
+
time.Sleep(time.Millisecond * 100)
}
-
- timer.Stop()
}
diff --git a/integration/performance_test.go b/integration/performance_test.go
index e23e4321f..3e442a542 100644
--- a/integration/performance_test.go
+++ b/integration/performance_test.go
@@ -4,7 +4,6 @@ import (
"crypto/sha256"
"encoding/base64"
"fmt"
- "io/ioutil"
"math/rand"
"os"
"strconv"
@@ -39,7 +38,7 @@ func BenchmarkIntegration_CustomVotesScenario(b *testing.B) {
delaPkg.Logger = delaPkg.Logger.Level(zerolog.WarnLevel)
- dirPath, err := ioutil.TempDir(os.TempDir(), "d-voting-three-votes")
+ dirPath, err := os.MkdirTemp(os.TempDir(), "d-voting-three-votes")
require.NoError(b, err)
defer os.RemoveAll(dirPath)
diff --git a/integration/scenario_test.go b/integration/scenario_test.go
index fe9a6e691..d2a9e258f 100644
--- a/integration/scenario_test.go
+++ b/integration/scenario_test.go
@@ -150,7 +150,10 @@ func startElectionProcess(wg *sync.WaitGroup, numNodes int, numVotes int, proxyA
// Wait for DKG setup
timeTable := make([]float64, 5)
oldTime := time.Now()
- waitForDKG(proxyArray[0], electionID, time.Second*100, t)
+
+ err = waitForDKG(proxyArray[0], electionID, time.Second*100, t)
+ require.NoError(t, err)
+
currentTime := time.Now()
diff := currentTime.Sub(oldTime)
timeTable[0] = diff.Seconds()
@@ -312,7 +315,9 @@ func startElectionProcess(wg *sync.WaitGroup, numNodes int, numVotes int, proxyA
getElectionResponse = getElectionInfo(proxyAddr1, electionID, t)
electionStatus = getElectionResponse.Status
- waitForElectionStatus(proxyAddr1, electionID, uint16(3), time.Second*100, t)
+ err = waitForElectionStatus(proxyAddr1, electionID, uint16(3), time.Second*100, t)
+ require.NoError(t, err)
+
t.Logf("Status of the election : %v", electionStatus)
require.Equal(t, uint16(3), electionStatus)
@@ -339,7 +344,9 @@ func startElectionProcess(wg *sync.WaitGroup, numNodes int, numVotes int, proxyA
electionStatus = getElectionResponse.Status
oldTime = time.Now()
- waitForElectionStatus(proxyAddr1, electionID, uint16(4), time.Second*300, t)
+ err = waitForElectionStatus(proxyAddr1, electionID, uint16(4), time.Second*300, t)
+ require.NoError(t, err)
+
currentTime = time.Now()
diff = currentTime.Sub(oldTime)
timeTable[4] = diff.Seconds()
@@ -370,7 +377,9 @@ func startElectionProcess(wg *sync.WaitGroup, numNodes int, numVotes int, proxyA
getElectionResponse = getElectionInfo(proxyAddr1, electionID, t)
electionStatus = getElectionResponse.Status
- waitForElectionStatus(proxyAddr1, electionID, uint16(5), time.Second*100, t)
+ err = waitForElectionStatus(proxyAddr1, electionID, uint16(5), time.Second*100, t)
+ require.NoError(t, err)
+
t.Logf("Status of the election : %v", electionStatus)
require.Equal(t, uint16(5), electionStatus)
@@ -631,52 +640,40 @@ func getDKGInfo(proxyAddr, electionID string, t *testing.T) ptypes.GetActorInfo
}
-func waitForDKG(proxyAddr, electionID string, timeOut time.Duration, t *testing.T) {
- // set up a timer to fail the test in case we never reach the status
- timer := time.NewTimer(timeOut)
- go func() {
- <-timer.C
- t.Error("timed out while waiting for DKG setup")
- }()
+func waitForDKG(proxyAddr, electionID string, timeOut time.Duration, t *testing.T) error {
+ expired := time.Now().Add(timeOut)
isOK := func() bool {
infoDKG := getDKGInfo(proxyAddr, electionID, t)
- // t.Logf("status is %v", infoDKG.Status)
- if infoDKG.Status != 1 {
- t.Logf("Node %v status is %v", proxyAddr, infoDKG.Status)
- return false
- }
- return true
+ return infoDKG.Status == 1
}
for !isOK() {
- time.Sleep(time.Millisecond * 100)
+ if time.Now().After(expired) {
+ return xerrors.New("expired")
+ }
+
+ time.Sleep(time.Millisecond * 1000)
}
- timer.Stop()
+ return nil
}
-func waitForElectionStatus(proxyAddr, electionID string, status uint16, timeOut time.Duration, t *testing.T) {
- // set up a timer to fail the test in case we never reach the status
- timer := time.NewTimer(timeOut)
- go func() {
- <-timer.C
- t.Errorf("timed out while waiting for enter status %v", status)
- }()
+func waitForElectionStatus(proxyAddr, electionID string, status uint16, timeOut time.Duration, t *testing.T) error {
+ expired := time.Now().Add(timeOut)
isOK := func() bool {
infoElection := getElectionInfo(proxyAddr, electionID, t)
- // t.Logf("status is %v", infoDKG.Status)
- if infoElection.Status != status {
- t.Logf("Node %v status is %v", proxyAddr, infoElection.Status)
- return false
- }
- return true
+ return infoElection.Status == status
}
for !isOK() {
- time.Sleep(time.Millisecond * 100)
+ if time.Now().After(expired) {
+ return xerrors.New("expired")
+ }
+
+ time.Sleep(time.Millisecond * 1000)
}
- timer.Stop()
+ return nil
}
diff --git a/internal/testing/fake/ordering.go b/internal/testing/fake/ordering.go
index f3c6cabd7..1c9e8da2e 100644
--- a/internal/testing/fake/ordering.go
+++ b/internal/testing/fake/ordering.go
@@ -3,7 +3,6 @@ package fake
import (
"context"
"encoding/hex"
- "fmt"
electionTypes "github.com/dedis/d-voting/contracts/evoting/types"
"go.dedis.ch/dela/core/ordering"
@@ -112,7 +111,6 @@ func (f *Service) AddTx(tx Transaction) {
f.Status = true
- fmt.Println("watch", results[0])
f.Channel <- ordering.Event{
Index: 0,
Transactions: results,
diff --git a/services/dkg/pedersen/controller/action_test.go b/services/dkg/pedersen/controller/action_test.go
index ab3156dbd..8634ef6a3 100644
--- a/services/dkg/pedersen/controller/action_test.go
+++ b/services/dkg/pedersen/controller/action_test.go
@@ -2,10 +2,11 @@ package controller
import (
"encoding/hex"
- "golang.org/x/xerrors"
- "io/ioutil"
+ "io"
"testing"
+ "golang.org/x/xerrors"
+
"github.com/dedis/d-voting/internal/testing/fake"
"github.com/dedis/d-voting/services/dkg"
"github.com/stretchr/testify/require"
@@ -21,7 +22,7 @@ func TestInitAction_Execute(t *testing.T) {
ctx := node.Context{
Injector: node.NewInjector(),
Flags: flags,
- Out: ioutil.Discard,
+ Out: io.Discard,
}
action := initAction{}
@@ -89,7 +90,7 @@ func TestSetupAction_Execute(t *testing.T) {
ctx := node.Context{
Injector: inj,
- Out: ioutil.Discard,
+ Out: io.Discard,
}
electionID := "deadbeef"
@@ -151,7 +152,7 @@ func TestExportInfoAction_Execute(t *testing.T) {
ctx := node.Context{
Injector: node.NewInjector(),
Flags: make(node.FlagSet),
- Out: ioutil.Discard,
+ Out: io.Discard,
}
action := exportInfoAction{}
diff --git a/services/dkg/pedersen/controller/mod_test.go b/services/dkg/pedersen/controller/mod_test.go
index 1f1af6f4d..adc148f72 100644
--- a/services/dkg/pedersen/controller/mod_test.go
+++ b/services/dkg/pedersen/controller/mod_test.go
@@ -1,14 +1,15 @@
package controller
import (
- "go.dedis.ch/dela/core/txn/signed"
- "go.dedis.ch/dela/core/validation/simple"
- "go.dedis.ch/dela/crypto/bls"
- "io/ioutil"
+ "io"
"os"
"path/filepath"
"testing"
+ "go.dedis.ch/dela/core/txn/signed"
+ "go.dedis.ch/dela/core/validation/simple"
+ "go.dedis.ch/dela/crypto/bls"
+
"github.com/dedis/d-voting/internal/testing/fake"
"github.com/stretchr/testify/require"
"go.dedis.ch/dela/cli/node"
@@ -26,7 +27,7 @@ func TestMinimal_OnStart(t *testing.T) {
ctx := node.Context{
Injector: node.NewInjector(),
Flags: flags,
- Out: ioutil.Discard,
+ Out: io.Discard,
}
// Should miss mino.Mino
@@ -82,7 +83,7 @@ func TestMinimal_OnStart(t *testing.T) {
err = c.OnStart(nil, ctx.Injector)
require.EqualError(t, err, "no flags")
- dir, err := ioutil.TempDir(os.TempDir(), "memcoin1")
+ dir, err := os.MkdirTemp(os.TempDir(), "memcoin1")
require.NoError(t, err)
flags.strings["config"] = dir
diff --git a/services/dkg/pedersen/handler.go b/services/dkg/pedersen/handler.go
index 33a9f004e..70135bf72 100644
--- a/services/dkg/pedersen/handler.go
+++ b/services/dkg/pedersen/handler.go
@@ -2,15 +2,19 @@ package pedersen
import (
"bytes"
+ "container/list"
"context"
"crypto/sha256"
"encoding/hex"
"encoding/json"
+ "errors"
+ "io"
"math/rand"
"sync"
"time"
"github.com/dedis/d-voting/contracts/evoting"
+ "github.com/rs/zerolog"
"go.dedis.ch/dela/core/execution/native"
"go.dedis.ch/dela/core/txn"
"go.dedis.ch/dela/core/txn/pool"
@@ -33,8 +37,13 @@ import (
"golang.org/x/xerrors"
)
-// recvResponseTimeout is the maximum time a node will wait for a response
-const recvResponseTimeout = time.Second * 10
+// the receiving time out, after which we check if the DKG setup is done or not.
+// Allows to exit the loop.
+const recvTimeout = time.Second * 2
+
+// the time after which we expect new messages (deals or responses) to be
+// received.
+const retryTimeout = time.Second * 1
// Handler represents the RPC executed on each node
//
@@ -58,6 +67,9 @@ type Handler struct {
context serde.Context
electionFac serde.Factory
+
+ log zerolog.Logger
+ running bool
}
// NewHandler creates a new handler
@@ -70,6 +82,8 @@ func NewHandler(me mino.Address, service ordering.Service, pool pool.Pool,
startRes := handlerData.StartRes
privShare := handlerData.PrivShare
+ log := dela.Logger.With().Str("role", "DKG").Str("address", me.String()).Logger()
+
return &Handler{
me: me,
service: service,
@@ -84,6 +98,9 @@ func NewHandler(me mino.Address, service ordering.Service, pool pool.Pool,
context: context,
electionFac: electionFac,
+
+ log: log,
+ running: false,
}
}
@@ -97,86 +114,118 @@ func (h *Handler) Stream(out mino.Sender, in mino.Receiver) error {
// messages to the other nodes, and then we might get their messages before
// the start message.
- deals := []types.Deal{}
- responses := []*pedersen.Response{}
-
-mainSwitch:
- from, msg, err := in.Recv(context.Background())
- if err != nil {
- return xerrors.Errorf("failed to receive: %v", err)
+ // We make sure not additional request is accepted if a setup is in
+ // progress.
+ h.Lock()
+ if !h.startRes.Done() && h.running {
+ h.Unlock()
+ return xerrors.Errorf("DKG is running")
}
+ if !h.startRes.Done() {
+ // This is the first setup
+ h.running = true
+ }
+ h.Unlock()
- // We expect a Start message or a decrypt request at first, but we might
- // receive other messages in the meantime, like a Deal.
- switch msg := msg.(type) {
-
- case types.Start:
- err := h.start(msg, deals, responses, from, out, in)
- if err != nil {
- return xerrors.Errorf("failed to start: %v", err)
- }
+ deals := list.New()
+ responses := list.New()
- case types.Deal:
- // This is a special case where a DKG started, some nodes received the
- // start signal and started sending their deals but we have not yet
- // received our start signal. In this case we collect the Deals while
- // waiting for the start signal.
- deals = append(deals, msg)
- goto mainSwitch
-
- case types.Response:
- // This is a special case where a DKG started, some nodes received the
- // start signal and started sending their deals but we have not yet
- // received our start signal. In this case we collect the Response while
- // waiting for the start signal.
- response := &pedersen.Response{
- Index: msg.GetIndex(),
- Response: &vss.Response{
- SessionID: msg.GetResponse().GetSessionID(),
- Index: msg.GetResponse().GetIndex(),
- Status: msg.GetResponse().GetStatus(),
- Signature: msg.GetResponse().GetSignature(),
- },
- }
- responses = append(responses, response)
- goto mainSwitch
+ for {
+ ctx, cancel := context.WithTimeout(context.Background(), recvTimeout)
+ from, msg, err := in.Recv(ctx)
+ cancel()
- case types.DecryptRequest:
+ if errors.Is(err, context.DeadlineExceeded) {
+ if h.startRes.Done() {
+ return nil
+ }
- if !h.startRes.Done() {
- return xerrors.Errorf("you must first initialize DKG. Did you " +
- "call setup() first?")
+ continue
}
- err = h.handleDecryptRequest(msg.GetElectionId())
- if err != nil {
- return xerrors.Errorf("could not send pubShares: %v", err)
+ if errors.Is(err, io.EOF) {
+ return nil
}
- case types.GetPeerPubKey:
- response := types.NewGetPeerPubKeyResp(h.pubKey)
- errs := out.Send(response, from)
- err = <-errs
if err != nil {
- return xerrors.Errorf("got an error while sending the get peer pubkey resp "+
- "reply: %v", err)
+ return xerrors.Errorf("failed to receive: %v", err)
}
- goto mainSwitch
- default:
- return xerrors.Errorf("expected Start message, decrypt request or "+
- "Deal as first message, got: %T", msg)
- }
+ h.log.Info().Msgf("received message from %s: %T\n", from, msg)
- return nil
+ // We expect a Start message or a decrypt request at first, but we might
+ // receive other messages in the meantime, like a Deal.
+ switch msg := msg.(type) {
+
+ case types.Start:
+ err := h.start(msg, deals, responses, from, out)
+ if err != nil {
+ return xerrors.Errorf("failed to start: %v", err)
+ }
+
+ case types.Deal:
+ // This is a special case where a DKG started, some nodes received the
+ // start signal and started sending their deals but we have not yet
+ // received our start signal. In this case we collect the Deals while
+ // waiting for the start signal.
+ h.Lock()
+ deals.PushBack(msg)
+ h.Unlock()
+
+ case types.Response:
+ // This is a special case where a DKG started, some nodes received the
+ // start signal and started sending their deals but we have not yet
+ // received our start signal. In this case we collect the Response while
+ // waiting for the start signal.
+ response := &pedersen.Response{
+ Index: msg.GetIndex(),
+ Response: &vss.Response{
+ SessionID: msg.GetResponse().GetSessionID(),
+ Index: msg.GetResponse().GetIndex(),
+ Status: msg.GetResponse().GetStatus(),
+ Signature: msg.GetResponse().GetSignature(),
+ },
+ }
+
+ h.Lock()
+ responses.PushBack(response)
+ h.Unlock()
+
+ case types.DecryptRequest:
+
+ if !h.startRes.Done() {
+ return xerrors.Errorf("you must first initialize DKG. Did you " +
+ "call setup() first?")
+ }
+
+ err = h.handleDecryptRequest(msg.GetElectionId())
+ if err != nil {
+ return xerrors.Errorf("could not send pubShares: %v", err)
+ }
+
+ return nil
+
+ case types.GetPeerPubKey:
+ response := types.NewGetPeerPubKeyResp(h.pubKey)
+ errs := out.Send(response, from)
+ err = <-errs
+ if err != nil {
+ return xerrors.Errorf("got an error while sending the get peer pubkey resp "+
+ "reply: %v", err)
+ }
+
+ default:
+ return xerrors.Errorf("expected Start message, decrypt request or "+
+ "Deal as first message, got: %T", msg)
+ }
+ }
}
// start is called when the node has received its start message. Note that we
// might have already received some deals from other nodes in the meantime. The
// function handles the DKG creation protocol.
-func (h *Handler) start(start types.Start, receivedDeals []types.Deal,
- receivedResps []*pedersen.Response, from mino.Address, out mino.Sender,
- in mino.Receiver) error {
+func (h *Handler) start(start types.Start, deals, resps *list.List, from mino.Address,
+ out mino.Sender) error {
if len(start.GetAddresses()) != len(start.GetPublicKeys()) {
return xerrors.Errorf("there should be as many players as "+
@@ -184,23 +233,73 @@ func (h *Handler) start(start types.Start, receivedDeals []types.Deal,
}
// create the DKG
- thrshold := threshold.ByzantineThreshold(len(start.GetPublicKeys()))
- d, err := pedersen.NewDistKeyGenerator(suite, h.privKey, start.GetPublicKeys(), thrshold)
+ t := threshold.ByzantineThreshold(len(start.GetPublicKeys()))
+ d, err := pedersen.NewDistKeyGenerator(suite, h.privKey, start.GetPublicKeys(), t)
if err != nil {
return xerrors.Errorf("failed to create new DKG: %v", err)
}
+
h.dkg = d
+ h.startRes.SetParticipants(start.GetAddresses())
+
+ // asynchronously start the procedure. This allows for receiving messages
+ // in the main for loop in the meantime.
+ go h.doDKG(deals, resps, out, from)
+
+ return nil
+}
+
+// doDKG calls the subsequent DKG steps
+func (h *Handler) doDKG(deals, resps *list.List, out mino.Sender, from mino.Address) {
+ h.log.Info().Str("action", "deal").Msg("new state")
+ h.deal(out)
+
+ h.log.Info().Str("action", "respond").Msg("new state")
+ h.respond(deals, out)
+
+ h.log.Info().Str("action", "certify").Msg("new state")
+ err := h.certify(resps, out)
+ if err != nil {
+ dela.Logger.Error().Msgf("failed to certify: %v", err)
+ return
+ }
+
+ h.log.Info().Str("action", "finalize").Msg("new state")
+
+ // Send back the public DKG key
+ distKey, err := h.dkg.DistKeyShare()
+ if err != nil {
+ dela.Logger.Error().Msgf("failed to get distr key: %v", err)
+ return
+ }
+
+ // Update the state before sending to acknowledgement to the
+ // orchestrator, so that it can process decrypt requests right away.
+ h.startRes.SetDistKey(distKey.Public())
+
+ h.Lock()
+ h.privShare = distKey.PriShare()
+ h.Unlock()
+
+ done := types.NewStartDone(distKey.Public())
+ err = <-out.Send(done, from)
+ if err != nil {
+ dela.Logger.Error().Msgf("got an error while sending pub key: %v", err)
+ return
+ }
+}
+
+func (h *Handler) deal(out mino.Sender) error {
+ // Send my Deals to the other nodes. Note that we take an optimistic
+ // approach and don't check if the deals are correctly sent to the node. The
+ // DKG setup needs a full connectivity anyway, and for the moment everything
+ // fails if this assumption breaks.
- // send my Deals to the other nodes
deals, err := h.dkg.Deals()
if err != nil {
return xerrors.Errorf("failed to compute the deals: %v", err)
}
- // use a waitgroup to send all the deals asynchronously and wait
- var wg sync.WaitGroup
- wg.Add(len(deals))
-
for i, deal := range deals {
dealMsg := types.NewDeal(
deal.Index,
@@ -213,158 +312,67 @@ func (h *Handler) start(start types.Start, receivedDeals []types.Deal,
),
)
- errs := out.Send(dealMsg, start.GetAddresses()[i])
- go func(errs <-chan error) {
- err, more := <-errs
- if more {
- dela.Logger.Warn().Msgf("got an error while sending deal: %v", err)
- }
- wg.Done()
- }(errs)
- }
+ to := h.startRes.participants[i]
- wg.Wait()
+ h.log.Info().Str("to", to.String()).Msg("send deal")
- dela.Logger.Trace().Msgf("%s sent all its deals", h.me)
+ out.Send(dealMsg, to)
+ }
+ return nil
+}
+
+func (h *Handler) respond(deals *list.List, out mino.Sender) {
numReceivedDeals := 0
- // Process the deals we received before the start message
- for _, deal := range receivedDeals {
- err = h.handleDeal(deal, from, start.GetAddresses(), out)
- if err != nil {
- dela.Logger.Warn().Msgf("%s failed to handle received deal "+
- "from %s: %v", h.me, from, err)
+ for numReceivedDeals < len(h.startRes.participants)-1 {
+ h.Lock()
+ deal := deals.Front()
+ if deal != nil {
+ deals.Remove(deal)
}
- numReceivedDeals++
- }
+ h.Unlock()
- // If there are N nodes, then N nodes first send (N-1) Deals. Then each node
- // send a response to every other nodes. So the number of responses a node
- // get is (N-1) * (N-1), where (N-1) should equal len(deals).
- for numReceivedDeals < len(deals) {
- from, msg, err := in.Recv(context.Background())
- if err != nil {
- return xerrors.Errorf("failed to receive after sending deals: %v", err)
+ if deal == nil {
+ time.Sleep(retryTimeout)
+ continue
}
- switch msg := msg.(type) {
-
- case types.Deal:
- // Process the Deal and Send the response to all the other nodes
- err = h.handleDeal(msg, from, start.GetAddresses(), out)
- if err != nil {
- dela.Logger.Warn().Msgf("%s failed to handle received deal "+
- "from %s: %v", h.me, from, err)
- return xerrors.Errorf("failed to handle deal from '%s': %v", from, err)
- }
- numReceivedDeals++
-
- case types.Response:
- // Process responses
- dela.Logger.Trace().Msgf("%s received response from %s", h.me, from)
- response := &pedersen.Response{
- Index: msg.GetIndex(),
- Response: &vss.Response{
- SessionID: msg.GetResponse().GetSessionID(),
- Index: msg.GetResponse().GetIndex(),
- Status: msg.GetResponse().GetStatus(),
- Signature: msg.GetResponse().GetSignature(),
- },
- }
- receivedResps = append(receivedResps, response)
-
- default:
- return xerrors.Errorf("unexpected message: %T", msg)
+ err := h.handleDeal(deal.Value.(types.Deal), out)
+ if err != nil {
+ h.log.Warn().Msgf("failed to handle received deal: %v", err)
}
- }
-
- h.startRes.SetParticipants(start.GetAddresses())
- err = h.certify(receivedResps, out, in, from)
- if err != nil {
- return xerrors.Errorf("failed to certify: %v", err)
+ numReceivedDeals++
}
-
- return nil
}
-func (h *Handler) certify(resps []*pedersen.Response, out mino.Sender,
- in mino.Receiver, from mino.Address) error {
-
- for _, response := range resps {
- _, err := h.dkg.ProcessResponse(response)
- if err != nil {
- dela.Logger.Warn().Msgf("%s failed to process response: %v", h.me, err)
- }
- }
+func (h *Handler) certify(resps *list.List, out mino.Sender) error {
for !h.dkg.Certified() {
- ctx, cancel := context.WithTimeout(context.Background(),
- recvResponseTimeout)
- defer cancel()
-
- from, msg, err := in.Recv(ctx)
- if err != nil {
- return xerrors.Errorf("failed to receive after sending deals: %v", err)
+ h.Lock()
+ resp := resps.Front()
+ if resp != nil {
+ resps.Remove(resp)
}
+ h.Unlock()
- switch msg := msg.(type) {
-
- case types.Response:
- // Processing responses
- dela.Logger.Trace().Msgf("%s received response from %s", h.me, from)
- response := &pedersen.Response{
- Index: msg.GetIndex(),
- Response: &vss.Response{
- SessionID: msg.GetResponse().GetSessionID(),
- Index: msg.GetResponse().GetIndex(),
- Status: msg.GetResponse().GetStatus(),
- Signature: msg.GetResponse().GetSignature(),
- },
- }
-
- _, err = h.dkg.ProcessResponse(response)
- if err != nil {
- dela.Logger.Warn().Msgf("%s, failed to process response "+
- "from '%s': %v", h.me, from, err)
- }
-
- default:
- return xerrors.Errorf("expected a response, got: %T", msg)
+ if resp == nil {
+ time.Sleep(retryTimeout)
+ continue
}
- }
-
- dela.Logger.Trace().Msgf("%s is certified", h.me)
- // Send back the public DKG key
- distKey, err := h.dkg.DistKeyShare()
- if err != nil {
- return xerrors.Errorf("failed to get distr key: %v", err)
- }
-
- // Update the state before sending to acknowledgement to the
- // orchestrator, so that it can process decrypt requests right away.
- h.startRes.SetDistKey(distKey.Public())
-
- h.Lock()
- h.privShare = distKey.PriShare()
- h.Unlock()
-
- done := types.NewStartDone(distKey.Public())
- err = <-out.Send(done, from)
- if err != nil {
- return xerrors.Errorf("got an error while sending pub key: %v", err)
+ _, err := h.dkg.ProcessResponse(resp.Value.(*pedersen.Response))
+ if err != nil {
+ h.log.Warn().Msgf("%s failed to process response: %v", h.me, err)
+ }
}
return nil
}
// handleDeal process the Deal and send the responses to the other nodes.
-func (h *Handler) handleDeal(msg types.Deal, from mino.Address, addrs []mino.Address,
- out mino.Sender) error {
-
- dela.Logger.Trace().Msgf("%s received deal from %s", h.me, from)
+func (h *Handler) handleDeal(msg types.Deal, out mino.Sender) error {
deal := &pedersen.Deal{
Index: msg.GetIndex(),
@@ -379,8 +387,7 @@ func (h *Handler) handleDeal(msg types.Deal, from mino.Address, addrs []mino.Add
response, err := h.dkg.ProcessDeal(deal)
if err != nil {
- return xerrors.Errorf("failed to process deal from %s: %v",
- h.me, err)
+ return xerrors.Errorf("failed to process deal: %v", err)
}
resp := types.NewResponse(
@@ -393,19 +400,17 @@ func (h *Handler) handleDeal(msg types.Deal, from mino.Address, addrs []mino.Add
),
)
- for _, addr := range addrs {
+ for _, addr := range h.startRes.participants {
if addr.Equal(h.me) {
continue
}
errs := out.Send(resp, addr)
+
err = <-errs
if err != nil {
- dela.Logger.Warn().Msgf("got an error while sending "+
- "response: %v", err)
return xerrors.Errorf("failed to send response to '%s': %v", addr, err)
}
-
}
return nil
@@ -471,7 +476,7 @@ func (h *Handler) handleDecryptRequest(electionID string) error {
return xerrors.Errorf("failed to make tx: %v", err)
}
- //TODO: Define in term of size of election ? (same in shuffle)
+ // TODO: Define in term of size of election ? (same in shuffle)
watchTimeout := 4 + rand.Intn(election.ShuffleThreshold)
watchCtx, cancel := context.WithTimeout(context.Background(), time.Duration(watchTimeout)*time.Second)
defer cancel()
diff --git a/services/dkg/pedersen/handler_test.go b/services/dkg/pedersen/handler_test.go
index ccf21f9bf..a60d789d0 100644
--- a/services/dkg/pedersen/handler_test.go
+++ b/services/dkg/pedersen/handler_test.go
@@ -1,8 +1,10 @@
package pedersen
import (
+ "container/list"
"encoding/hex"
"strconv"
+ "strings"
"testing"
electionTypes "github.com/dedis/d-voting/contracts/evoting/types"
@@ -17,7 +19,6 @@ import (
"go.dedis.ch/kyber/v3"
"go.dedis.ch/kyber/v3/share"
pedersen "go.dedis.ch/kyber/v3/share/dkg/pedersen"
- vss "go.dedis.ch/kyber/v3/share/vss/pedersen"
)
func TestHandler_Stream(t *testing.T) {
@@ -111,30 +112,16 @@ func TestHandler_Start(t *testing.T) {
[]mino.Address{fake.NewAddress(0)},
[]kyber.Point{},
)
- err := h.start(start, []types.Deal{}, []*pedersen.Response{}, nil, nil, nil)
+ err := h.start(start, list.New(), list.New(), nil, nil)
require.EqualError(t, err, "there should be as many players as pubKey: 1 := 0")
start = types.NewStart(
[]mino.Address{fake.NewAddress(0), fake.NewAddress(1)},
[]kyber.Point{pubKey, suite.Point()},
)
- receiver := fake.NewBadReceiver()
- err = h.start(start, []types.Deal{}, []*pedersen.Response{}, nil, fake.Sender{}, receiver)
- require.EqualError(t, err, fake.Err("failed to receive after sending deals"))
-
- receiver = fake.NewReceiver(
- fake.NewRecvMsg(fake.NewAddress(0), types.Deal{}),
- fake.NewRecvMsg(fake.NewAddress(0), nil),
- )
- err = h.start(start, []types.Deal{}, []*pedersen.Response{}, nil, fake.Sender{}, receiver)
- require.EqualError(t, err, "failed to handle deal from 'fake.Address[0]': failed to process deal from %!s(): schnorr: signature of invalid length 0 instead of 64")
-
- err = h.start(start, []types.Deal{}, []*pedersen.Response{}, nil, fake.Sender{}, &fake.Receiver{})
- require.EqualError(t, err, "unexpected message: ")
- // We check when there is already something in the slice if Deals
- err = h.start(start, []types.Deal{{}}, []*pedersen.Response{}, nil, fake.NewBadSender(), &fake.Receiver{})
- require.EqualError(t, err, "failed to certify: expected a response, got: ")
+ err = h.start(start, list.New(), list.New(), nil, fake.Sender{})
+ require.NoError(t, err)
}
func TestHandler_Certify(t *testing.T) {
@@ -148,19 +135,16 @@ func TestHandler_Certify(t *testing.T) {
startRes: &state{},
dkg: dkg,
}
- receiver := fake.NewBadReceiver()
- responses := []*pedersen.Response{{Response: &vss.Response{}}}
- err = h.certify(responses, fake.Sender{}, receiver, nil)
- require.EqualError(t, err, fake.Err("failed to receive after sending deals"))
+ responses := list.New()
dkg = getCertified(t)
h.dkg = dkg
- err = h.certify(responses, fake.NewBadSender(), &fake.Receiver{}, nil)
- require.EqualError(t, err, fake.Err("got an error while sending pub key"))
+ err = h.certify(responses, fake.NewBadSender())
+ require.NoError(t, err)
}
-func TestHandler_HandleDeal(t *testing.T) {
+func TestHandler_HandleDeal_Fail(t *testing.T) {
privKey1 := suite.Scalar().Pick(suite.RandomStream())
pubKey1 := suite.Point().Mul(privKey1, nil)
privKey2 := suite.Scalar().Pick(suite.RandomStream())
@@ -194,9 +178,58 @@ func TestHandler_HandleDeal(t *testing.T) {
h := Handler{
dkg: dkg1,
+ startRes: &state{
+ participants: []mino.Address{fake.NewAddress(0)},
+ },
}
- err = h.handleDeal(dealMsg, nil, []mino.Address{fake.NewAddress(0)}, fake.NewBadSender())
+ err = h.handleDeal(dealMsg, fake.NewBadSender())
require.EqualError(t, err, fake.Err("failed to send response to 'fake.Address[0]'"))
+
+ err = h.handleDeal(dealMsg, fake.Sender{})
+ require.True(t, strings.Contains(err.Error(), "failed to process deal"))
+}
+
+func TestHandler_HandleDeal_Ok(t *testing.T) {
+ privKey1 := suite.Scalar().Pick(suite.RandomStream())
+ pubKey1 := suite.Point().Mul(privKey1, nil)
+ privKey2 := suite.Scalar().Pick(suite.RandomStream())
+ pubKey2 := suite.Point().Mul(privKey2, nil)
+
+ dkg1, err := pedersen.NewDistKeyGenerator(suite, privKey1, []kyber.Point{pubKey1, pubKey2}, 2)
+ require.NoError(t, err)
+
+ dkg2, err := pedersen.NewDistKeyGenerator(suite, privKey2, []kyber.Point{pubKey1, pubKey2}, 2)
+ require.NoError(t, err)
+
+ deals, err := dkg2.Deals()
+ require.Len(t, deals, 1)
+ require.NoError(t, err)
+
+ var deal *pedersen.Deal
+ for _, d := range deals {
+ deal = d
+ }
+
+ dealMsg := types.NewDeal(
+ deal.Index,
+ deal.Signature,
+ types.NewEncryptedDeal(
+ deal.Deal.DHKey,
+ deal.Deal.Signature,
+ deal.Deal.Nonce,
+ deal.Deal.Cipher,
+ ),
+ )
+
+ h := Handler{
+ dkg: dkg1,
+ startRes: &state{
+ participants: []mino.Address{fake.NewAddress(0)},
+ },
+ }
+
+ err = h.handleDeal(dealMsg, fake.Sender{})
+ require.NoError(t, err)
}
func TestHandlerData_MarshalJSON(t *testing.T) {
@@ -340,6 +373,7 @@ func TestHandler_HandlerDecryptRequest(t *testing.T) {
}
+// -----------------------------------------------------------------------------
// Utility functions
func getCertified(t *testing.T) *pedersen.DistKeyGenerator {
diff --git a/services/dkg/pedersen/mod.go b/services/dkg/pedersen/mod.go
index 3e9645135..a69366d4e 100644
--- a/services/dkg/pedersen/mod.go
+++ b/services/dkg/pedersen/mod.go
@@ -14,6 +14,7 @@ import (
"github.com/dedis/d-voting/contracts/evoting"
etypes "github.com/dedis/d-voting/contracts/evoting/types"
+ "github.com/rs/zerolog"
"github.com/dedis/d-voting/internal/tracing"
"github.com/dedis/d-voting/services/dkg"
@@ -124,6 +125,8 @@ func (s *Pedersen) NewActor(electionIDBuf []byte, pool pool.Pool, txmngr txn.Man
no := s.mino.WithSegment(electionID)
rpc := mino.MustCreateRPC(no, RPC, h, s.factory)
+ log := dela.Logger.With().Str("role", "DKG actor").Logger()
+
a := &Actor{
rpc: rpc,
factory: s.factory,
@@ -133,6 +136,7 @@ func (s *Pedersen) NewActor(electionIDBuf []byte, pool pool.Pool, txmngr txn.Man
handler: h,
electionID: electionID,
status: dkg.Status{Status: dkg.Initialized},
+ log: log,
}
evoting.PromElectionDkgStatus.WithLabelValues(electionID).Set(float64(dkg.Initialized))
@@ -164,6 +168,7 @@ type Actor struct {
handler *Handler
electionID string
status dkg.Status
+ log zerolog.Logger
}
func (a *Actor) setErr(err error, args map[string]interface{}) {
@@ -180,6 +185,7 @@ func (a *Actor) setErr(err error, args map[string]interface{}) {
// participating nodes. This function updates the actor's status in case of
// error to allow asynchronous call of this function.
func (a *Actor) Setup() (kyber.Point, error) {
+ a.log.Info().Msg("setup")
if a.handler.startRes.Done() {
err := xerrors.New("setup() was already called, only one call is allowed")
@@ -211,6 +217,8 @@ func (a *Actor) Setup() (kyber.Point, error) {
addrs = append(addrs, addrIter.GetNext())
}
+ a.log.Info().Msgf("sending getkey request to %v", addrs)
+
// get the peer DKG pub keys
getPeerKey := types.NewGetPeerPubKey()
errs := sender.Send(getPeerKey, addrs...)
@@ -260,6 +268,8 @@ func (a *Actor) Setup() (kyber.Point, error) {
message := types.NewStart(associatedAddrs, dkgPeerPubkeys)
+ a.log.Info().Msgf("sending start to %s", addrs)
+
errs = sender.Send(message, addrs...)
err = <-errs
if err != nil {
@@ -272,7 +282,7 @@ func (a *Actor) Setup() (kyber.Point, error) {
for i := 0; i < lenAddrs; i++ {
- ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
+ ctx, cancel := context.WithTimeout(context.Background(), time.Second*200)
defer cancel()
addr, msg, err := receiver.Recv(ctx)
@@ -299,6 +309,8 @@ func (a *Actor) Setup() (kyber.Point, error) {
a.setErr(err, nil)
return nil, err
}
+
+ a.log.Info().Msgf("ok for %s", addr.String())
}
a.status = dkg.Status{Status: dkg.Setup}
diff --git a/services/dkg/pedersen/mod_test.go b/services/dkg/pedersen/mod_test.go
index 7a44821d9..542bc92ac 100644
--- a/services/dkg/pedersen/mod_test.go
+++ b/services/dkg/pedersen/mod_test.go
@@ -1,13 +1,16 @@
package pedersen
import (
+ "bytes"
"encoding/hex"
"encoding/json"
"net/url"
"strconv"
+ "strings"
"testing"
"time"
+ "go.dedis.ch/dela"
"go.dedis.ch/dela/core/access"
"go.dedis.ch/dela/core/ordering"
"go.dedis.ch/dela/core/txn/signed"
@@ -20,6 +23,7 @@ import (
"github.com/dedis/d-voting/services/dkg"
"github.com/dedis/d-voting/services/dkg/pedersen/types"
"github.com/prometheus/client_golang/prometheus/testutil"
+ "github.com/rs/zerolog"
"github.com/stretchr/testify/require"
"go.dedis.ch/dela/core/ordering/cosipbft/authority"
"go.dedis.ch/dela/core/store/kv"
@@ -468,7 +472,7 @@ func TestPedersen_Scenario(t *testing.T) {
token := joinable.GenerateToken(time.Hour)
- certHash, err := joinable.GetCertificateStore().Hash(joinable.GetCertificate())
+ certHash, err := joinable.GetCertificateStore().Hash(joinable.GetCertificateChain())
require.NoError(t, err)
for _, n := range minos {
@@ -623,8 +627,19 @@ func TestPedersen_ComputePubshares_SenderFailed(t *testing.T) {
rpc: fake.NewStreamRPC(nil, fake.NewBadSender()),
}
+ oldLog := dela.Logger
+ defer func() {
+ dela.Logger = oldLog
+ }()
+
+ out := new(bytes.Buffer)
+ dela.Logger = zerolog.New(out)
+
+ // should only output a warning
err := a.ComputePubshares()
- require.EqualError(t, err, fake.Err("failed to send decrypt request"))
+ require.NoError(t, err)
+
+ require.True(t, strings.Contains(out.String(), "failed to send decrypt request"), out.String())
}
func TestPedersen_ComputePubshares_OK(t *testing.T) {
diff --git a/services/shuffle/neff/controller/action_test.go b/services/shuffle/neff/controller/action_test.go
index 18a3665ac..3dcb56d8e 100644
--- a/services/shuffle/neff/controller/action_test.go
+++ b/services/shuffle/neff/controller/action_test.go
@@ -1,7 +1,7 @@
package controller
import (
- "io/ioutil"
+ "io"
"testing"
"github.com/stretchr/testify/require"
@@ -12,7 +12,7 @@ func TestInitAction_Execute(t *testing.T) {
ctx := node.Context{
Injector: node.NewInjector(),
Flags: make(node.FlagSet),
- Out: ioutil.Discard,
+ Out: io.Discard,
}
action := InitAction{}
diff --git a/services/shuffle/neff/mod_test.go b/services/shuffle/neff/mod_test.go
index c6125f84d..c310e15dd 100644
--- a/services/shuffle/neff/mod_test.go
+++ b/services/shuffle/neff/mod_test.go
@@ -1,9 +1,12 @@
package neff
import (
+ "bytes"
"encoding/hex"
+ "strings"
"testing"
+ "go.dedis.ch/dela"
"go.dedis.ch/dela/core/ordering/cosipbft/authority"
"go.dedis.ch/dela/crypto"
"go.dedis.ch/dela/mino"
@@ -13,6 +16,7 @@ import (
etypes "github.com/dedis/d-voting/contracts/evoting/types"
"github.com/dedis/d-voting/internal/testing/fake"
"github.com/dedis/d-voting/services/shuffle/neff/types"
+ "github.com/rs/zerolog"
"github.com/stretchr/testify/require"
)
@@ -72,8 +76,18 @@ func TestNeffShuffle_Shuffle(t *testing.T) {
rpc := fake.NewStreamRPC(fake.NewReceiver(), fake.NewBadSender())
actor.rpc = rpc
+ oldLog := dela.Logger
+ defer func() {
+ dela.Logger = oldLog
+ }()
+
+ out := new(bytes.Buffer)
+ dela.Logger = zerolog.New(out)
+
+ // should only output a warning
err = actor.Shuffle(electionIDBuf)
- require.EqualError(t, err, fake.Err("failed to start shuffle"))
+ require.NoError(t, err)
+ require.True(t, strings.Contains(out.String(), "failed to start shuffle"), out.String())
rpc = fake.NewStreamRPC(fake.NewBadReceiver(), fake.Sender{})
actor.rpc = rpc