From a8d38b4ffb58468648403102075c7c93e62f4e0c Mon Sep 17 00:00:00 2001 From: Linus Gasser Date: Fri, 2 Oct 2020 08:54:55 +0200 Subject: [PATCH] wip --- Makefile | 3 +- blscosi/protocol/sub_protocol.go | 2 + byzcoin/api_test.go | 93 +++--------- byzcoin/byzcoin_test.go | 238 ------------------------------- byzcoin/service_test.go | 97 +++++++------ 5 files changed, 79 insertions(+), 354 deletions(-) delete mode 100644 byzcoin/byzcoin_test.go diff --git a/Makefile b/Makefile index f3ad73edda..26d00d4c98 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,8 @@ EXCLUDE_LINT := should be.*UI #TESTS := TestViewChange_Basic3\$$ -TESTS := SecureDarc|TestDeferred_WrongSignature|TestViewChange_Basic|TestDeferred_DefaultExpireBlockIdx +#TESTS := SecureDarc|TestDeferred_WrongSignature|TestViewChange_Basic|TestDeferred_DefaultExpireBlockIdx +TESTS := Coding/bin/Makefile.base: git clone https://github.com/dedis/Coding diff --git a/blscosi/protocol/sub_protocol.go b/blscosi/protocol/sub_protocol.go index 64195fae14..3f0b349ed4 100644 --- a/blscosi/protocol/sub_protocol.go +++ b/blscosi/protocol/sub_protocol.go @@ -101,6 +101,8 @@ func NewSubBlsCosi(n *onet.TreeNodeInstance, vf VerificationFn, suite *pairing.S func (p *SubBlsCosi) Dispatch() error { defer p.Done() + log.Printf("%s: has %s", p.ServerIdentity(), p.Tree().Dump()) + // Send announcement to start sending signatures if p.IsRoot() { return p.dispatchRoot() diff --git a/byzcoin/api_test.go b/byzcoin/api_test.go index eca9d64090..7fac4966b8 100644 --- a/byzcoin/api_test.go +++ b/byzcoin/api_test.go @@ -118,41 +118,21 @@ func TestClient_CreateTransaction(t *testing.T) { } func TestClient_GetProof(t *testing.T) { - l := onet.NewTCPTest(cothority.Suite) - servers, roster, _ := l.GenTree(3, true) - registerContracts(servers) - defer l.CloseAll() - - // Initialise the genesis message and send it to the service. - signer := darc.NewSignerEd25519(nil, nil) - msg, err := DefaultGenesisMsg(CurrentVersion, roster, []string{"spawn:dummy"}, signer.Identity()) - msg.BlockInterval = 100 * time.Millisecond - require.NoError(t, err) - - // The darc inside it should be valid. - d := msg.GenesisDarc - require.Nil(t, d.Verify(true)) - - c, csr, err := NewLedger(msg, false) - require.NoError(t, err) - - gac, err := c.GetAllByzCoinIDs(roster.List[1]) - require.NoError(t, err) - require.Equal(t, 1, len(gac.IDs)) + b := newBCTRun(t, nil) + defer b.CloseAll() // Create a new transaction. value := []byte{5, 6, 7, 8} - kind := "dummy" - tx, err := createOneClientTx(d.GetBaseID(), kind, value, signer) + tx, err := createOneClientTx(b.GenesisDarc.GetBaseID(), DummyContractName, value, b.Signer) require.NoError(t, err) - atr, err := c.AddTransactionAndWait(tx, 10) + atr, err := b.Client.AddTransactionAndWait(tx, 10) require.NoError(t, err) // We should have a proof of our transaction in the skipchain. newID := tx.Instructions[0].Hash() - p, err := c.GetProofAfter(newID, true, &atr.Proof.Latest) + p, err := b.Client.GetProofAfter(newID, true, &atr.Proof.Latest) require.NoError(t, err) - require.Nil(t, p.Proof.Verify(csr.Skipblock.SkipChainID())) + require.Nil(t, p.Proof.Verify(b.Genesis.SkipChainID())) require.Equal(t, 2, len(p.Proof.Links)) k, v0, _, _, err := p.Proof.KeyValue() require.NoError(t, err) @@ -160,7 +140,7 @@ func TestClient_GetProof(t *testing.T) { require.Equal(t, value, v0) // The proof should now be smaller as we learnt about the block - p, err = c.GetProofAfter(newID, false, &atr.Proof.Latest) + p, err = b.Client.GetProofAfter(newID, false, &atr.Proof.Latest) require.NoError(t, err) require.Equal(t, 1, len(p.Proof.Links)) } @@ -198,41 +178,25 @@ func TestClient_GetProofCorrupted(t *testing.T) { // Create a streaming client and add blocks in the background. The client // should receive valid blocks. func TestClient_Streaming(t *testing.T) { - l := onet.NewTCPTest(cothority.Suite) - servers, roster, _ := l.GenTree(3, true) - registerContracts(servers) - defer l.CloseAll() - - // Initialise the genesis message and send it to the service. - signer := darc.NewSignerEd25519(nil, nil) - msg, err := DefaultGenesisMsg(CurrentVersion, roster, []string{"spawn:dummy"}, signer.Identity()) - msg.BlockInterval = time.Second - require.NoError(t, err) - - // The darc inside it should be valid. - d := msg.GenesisDarc - require.Nil(t, d.Verify(true)) - - c, csr, err := NewLedger(msg, false) - require.NoError(t, err) + b := newBCTRun(t, nil) + defer b.CloseAll() n := 2 go func() { time.Sleep(100 * time.Millisecond) for i := 0; i < n; i++ { value := []byte{5, 6, 7, 8} - kind := "dummy" - tx, err := createOneClientTxWithCounter(d.GetBaseID(), kind, value, signer, uint64(i)+1) + tx, err := createOneClientTxWithCounter(b.GenesisDarc.GetBaseID(), DummyContractName, value, b.Signer, uint64(i)+1) // Need log.ErrFatal here, else it races with the rest of the code that // uses 't'. require.NoError(t, err) - _, err = c.AddTransaction(tx) + _, err = b.Client.AddTransaction(tx) require.NoError(t, err) } }() // Start collecting transactions - c1 := NewClientKeep(csr.Skipblock.Hash, *roster) + c1 := NewClientKeep(b.Genesis.Hash, *b.Roster) var xMut sync.Mutex var x int done := make(chan bool) @@ -263,48 +227,31 @@ func TestClient_Streaming(t *testing.T) { } go func() { - err = c1.StreamTransactions(cb) + err := c1.StreamTransactions(cb) require.NoError(t, err) }() select { case <-done: - case <-time.After(time.Duration(10) * msg.BlockInterval): + case <-time.After(time.Duration(10) * b.GenesisMessage.BlockInterval): require.Fail(t, "should have got n transactions") } require.NoError(t, c1.Close()) } func TestClient_NoPhantomSkipchain(t *testing.T) { - l := onet.NewTCPTest(cothority.Suite) - servers, roster, _ := l.GenTree(3, true) - registerContracts(servers) - defer l.CloseAll() - - // Initialise the genesis message and send it to the service. - signer := darc.NewSignerEd25519(nil, nil) - msg, err := DefaultGenesisMsg(CurrentVersion, roster, []string{"spawn:dummy"}, signer.Identity()) - msg.BlockInterval = 100 * time.Millisecond - require.NoError(t, err) - - d := msg.GenesisDarc - - c, _, err := NewLedger(msg, false) - require.NoError(t, err) - - gac, err := c.GetAllByzCoinIDs(roster.List[0]) - require.NoError(t, err) - require.Equal(t, 1, len(gac.IDs)) + b := newBCTRun(t, nil) + defer b.CloseAll() // Create a new transaction. - tx, err := createOneClientTx(d.GetBaseID(), "dummy", []byte{}, signer) + tx, err := createOneClientTx(b.GenesisDarc.GetBaseID(), DummyContractName, + []byte{}, b.Signer) require.NoError(t, err) - _, err = c.AddTransactionAndWait(tx, 10) + _, err = b.Client.AddTransactionAndWait(tx, 10) require.NoError(t, err) - gac, err = c.GetAllByzCoinIDs(roster.List[0]) + gac, err := b.Client.GetAllByzCoinIDs(b.Roster.List[0]) require.NoError(t, err) require.Equal(t, 1, len(gac.IDs)) - require.NoError(t, l.WaitDone(time.Second)) } // Insure that the decoder will return an error if the reply diff --git a/byzcoin/byzcoin_test.go b/byzcoin/byzcoin_test.go deleted file mode 100644 index c33718881d..0000000000 --- a/byzcoin/byzcoin_test.go +++ /dev/null @@ -1,238 +0,0 @@ -package byzcoin - -import ( - "encoding/hex" - "github.com/stretchr/testify/require" - "go.dedis.ch/cothority/v3/darc" - "go.dedis.ch/cothority/v3/darc/expression" - "go.dedis.ch/cothority/v3/skipchain" - "go.dedis.ch/onet/v3" - "go.dedis.ch/onet/v3/log" - "go.etcd.io/bbolt" - "testing" - "time" -) - -type BCTest struct { - Local *onet.LocalTest - Servers []*onet.Server - Roster *onet.Roster - Services []*Service - Genesis *skipchain.SkipBlock - Value []byte - GenesisDarc *darc.Darc - Signer darc.Signer - SignerCounter uint64 - PropagationInterval time.Duration - Client *Client - GenesisMessage *CreateGenesisBlock - T *testing.T -} - -type BCTestArgs struct { - PropagationInterval time.Duration - Nodes int -} - -type TxArgs struct { - Node int - Wait int - WaitPropagation bool - RequireSuccess bool -} - -var TxArgsDefault = TxArgs{ - Node: 0, - Wait: 10, - WaitPropagation: true, - RequireSuccess: true, -} - -var defaultBCTestArgs = BCTestArgs{ - PropagationInterval: 500 * time.Millisecond, - Nodes: 3, -} - -// NewBCTestWithArgs takes a BCTestArgs to override the default values. -func NewBCTest(t *testing.T, ba *BCTestArgs) *BCTest { - if ba == nil { - ba = &defaultBCTestArgs - } - b := &BCTest{ - T: t, - Local: onet.NewLocalTestT(tSuite, t), - Value: []byte("anyvalue"), - Signer: darc.NewSignerEd25519(nil, nil), - SignerCounter: 1, - } - - require.NoError(t, RegisterGlobalContract(DummyContractName, - DummyContractFromBytes)) - b.Servers, b.Roster, _ = b.Local.GenTree(ba.Nodes, true) - for _, sv := range b.Local.GetServices(b.Servers, ByzCoinID) { - service := sv.(*Service) - b.Services = append(b.Services, service) - } - - var err error - b.GenesisMessage, err = DefaultGenesisMsg(CurrentVersion, b.Roster, nil, - b.Signer.Identity()) - require.NoError(t, err) - b.GenesisDarc = &b.GenesisMessage.GenesisDarc - - b.GenesisMessage.BlockInterval = ba.PropagationInterval - b.PropagationInterval = b.GenesisMessage.BlockInterval - - return b -} - -func (b *BCTest) AddGenesisRules(rules ...string) { - ownerExpr := expression.Expr(b.Signer.Identity().String()) - for _, r := range rules { - require.NoError(b.T, b.GenesisMessage.GenesisDarc.Rules.AddRule( - darc.Action(r), ownerExpr)) - } -} - -func (b *BCTest) CreateByzCoin() { - resp, err := b.Services[0].CreateGenesisBlock(b.GenesisMessage) - require.NoError(b.T, err) - b.Genesis = resp.Skipblock - b.Client = NewClient(b.Genesis.SkipChainID(), *b.Roster) - require.NoError(b.T, b.Client.WaitPropagation(0)) -} - -func (b *BCTest) NodeStop(index int) { - b.Services[index].TestClose() - b.Servers[index].Pause() -} - -func (b *BCTest) NodeRestart(index int) { - b.Servers[index].Unpause() - require.NoError(b.T, b.Services[index].TestRestart()) -} - -func (b *BCTest) CloseAll() { - if b.Client != nil { - require.NoError(b.T, b.Client.WaitPropagation(-1)) - } - b.Local.CloseAll() -} - -func (b *BCTest) SendInst(args *TxArgs, - inst ...Instruction) (ClientTransaction, AddTxResponse) { - - for i := range inst { - inst[i].SignerCounter = []uint64{b.SignerCounter} - b.SignerCounter++ - } - ctx, err := combineInstrsAndSign(b.Signer, inst...) - require.NoError(b.T, err) - - return ctx, b.SendTx(args, ctx) -} - -func (b *BCTest) SendTx(args *TxArgs, ctx ClientTransaction) AddTxResponse { - if args == nil { - args = &TxArgsDefault - } - - resp, err := b.Services[args.Node].AddTransaction(&AddTxRequest{ - Version: CurrentVersion, - SkipchainID: b.Genesis.SkipChainID(), - Transaction: ctx, - InclusionWait: args.Wait, - }) - require.NoError(b.T, err) - require.NotNil(b.T, resp) - if args.RequireSuccess { - require.Empty(b.T, resp.Error) - } - if args.WaitPropagation { - require.NoError(b.T, b.Client.WaitPropagation(-1)) - } - return *resp -} - -func (b *BCTest) SpawnDummy(args *TxArgs) (ClientTransaction, AddTxResponse) { - return b.SendInst(args, Instruction{ - InstanceID: NewInstanceID(b.GenesisDarc.GetBaseID()), - Spawn: &Spawn{ - ContractID: DummyContractName, - Args: Arguments{{Name: "data", Value: []byte("anyvalue")}}, - }, - }) -} - -func (b *BCTest) DeleteDBs(index int) { - bc := b.Services[index] - log.Lvlf1("%s: Deleting DB of node %d", bc.ServerIdentity(), index) - bc.TestClose() - for scid := range bc.stateTries { - require.NoError(b.T, deleteDB(bc.ServiceProcessor, []byte(scid))) - idStr := hex.EncodeToString([]byte(scid)) - require.NoError(b.T, deleteDB(bc.ServiceProcessor, []byte(idStr))) - } - require.NoError(b.T, deleteDB(bc.ServiceProcessor, storageID)) - sc := bc.Service(skipchain.ServiceName).(*skipchain.Service) - require.NoError(b.T, deleteDB(sc.ServiceProcessor, []byte("skipblocks"))) - require.NoError(b.T, deleteDB(sc.ServiceProcessor, []byte("skipchainconfig"))) - require.NoError(b.T, bc.TestRestart()) -} - -func deleteDB(s *onet.ServiceProcessor, key []byte) error { - db, stBucket := s.GetAdditionalBucket(key) - return db.Update(func(tx *bbolt.Tx) error { - return tx.DeleteBucket(stBucket) - }) -} - -const DummyContractName = "dummy" - -type DummyContract struct { - BasicContract - Data []byte -} - -func DummyContractFromBytes(in []byte) (Contract, error) { - return &DummyContract{Data: in}, nil -} - -func (dc *DummyContract) Spawn(cdb ReadOnlyStateTrie, inst Instruction, c []Coin) ([]StateChange, []Coin, error) { - _, _, _, darcID, err := cdb.GetValues(inst.InstanceID.Slice()) - if err != nil { - return nil, nil, err - } - - if len(inst.Spawn.Args.Search("data")) == 32 { - return []StateChange{ - NewStateChange(Create, NewInstanceID(inst.Spawn.Args.Search("data")), inst.Spawn.ContractID, - []byte{}, darcID), - }, nil, nil - } - return []StateChange{ - NewStateChange(Create, NewInstanceID(inst.Hash()), inst.Spawn.ContractID, inst.Spawn.Args[0].Value, darcID), - }, nil, nil -} - -func (dc *DummyContract) Invoke(cdb ReadOnlyStateTrie, inst Instruction, c []Coin) ([]StateChange, []Coin, error) { - _, _, _, darcID, err := cdb.GetValues(inst.InstanceID.Slice()) - if err != nil { - return nil, nil, err - } - - return []StateChange{ - NewStateChange(Update, inst.InstanceID, DummyContractName, inst.Invoke.Args[0].Value, darcID), - }, nil, nil -} - -func (dc *DummyContract) Delete(cdb ReadOnlyStateTrie, inst Instruction, c []Coin) ([]StateChange, []Coin, error) { - _, _, _, darcID, err := cdb.GetValues(inst.InstanceID.Slice()) - if err != nil { - return nil, nil, err - } - - return []StateChange{ - NewStateChange(Remove, inst.InstanceID, "", nil, darcID), - }, nil, nil -} diff --git a/byzcoin/service_test.go b/byzcoin/service_test.go index fa7e300cd5..0b367da0f9 100644 --- a/byzcoin/service_test.go +++ b/byzcoin/service_test.go @@ -4,7 +4,9 @@ import ( "bytes" "crypto/sha256" "encoding/binary" + "encoding/hex" "fmt" + "go.etcd.io/bbolt" "strings" "sync" "testing" @@ -28,6 +30,11 @@ import ( "go.dedis.ch/protobuf" ) +func init() { + log.ErrFatal(RegisterGlobalContract(DummyContractName, + dummyContractFromBytes)) +} + var tSuite = suites.MustFind("Ed25519") const slowContract = "slow" @@ -267,7 +274,7 @@ func TestService_AddTransaction_WrongNode(t *testing.T) { outsideServer := b.Local.GenServers(1)[0] outside := outsideServer.Service(ServiceName).(*Service) - registerContracts([]*onet.Server{outsideServer}) + registerContracts(outside) // add the first tx to outside server log.Lvl1("adding the first tx - this should fail") @@ -1019,21 +1026,6 @@ func sendTransactionWithCounter(t *testing.T, s *BCTest, client int, kind string return proof, key, resp, err, err2 } -func (b *BCTest) sendInstructions(t *testing.T, wait int, - instr ...Instruction) (resp *AddTxResponse, ctx ClientTransaction) { - var err error - ctx, err = combineInstrsAndSign(b.Signer, instr...) - require.NoError(t, err) - resp, err = b.Services[0].AddTransaction(&AddTxRequest{ - Version: CurrentVersion, - SkipchainID: b.Genesis.SkipChainID(), - Transaction: ctx, - InclusionWait: wait, - }) - require.NoError(t, err) - return -} - func TestService_InvalidVerification(t *testing.T) { b := newBCTRun(t, nil) defer b.CloseAll() @@ -1361,8 +1353,11 @@ func TestService_DarcEvolutionFail(t *testing.T) { Invoke: &invoke, SignerCounter: []uint64{counterResponse.Counters[0] + 1}, } - resp, _ := b.sendInstructions(t, 10, instr) + bcArgs := TxArgsDefault + bcArgs.RequireSuccess = false + _, resp := b.SendInst(&bcArgs, instr) require.Contains(t, resp.Error, "instruction verification failed") + b.SignerCounter-- } // then we create a bad request, i.e., with an invalid version number @@ -1649,8 +1644,7 @@ func TestService_SetConfigRosterNewNodes(t *testing.T) { testDarcBuf, err := testDarc.ToProto() require.NoError(t, err) instr := createSpawnInstr(b.GenesisDarc.GetBaseID(), ContractDarcID, "darc", testDarcBuf) - require.NoError(t, err) - b.sendInstructions(t, 10, instr) + b.SendInst(nil, instr) log.Lvl1("Creating blocks to check rotation of the leader") leanClient := onet.NewClient(cothority.Suite, ServiceName) @@ -1908,8 +1902,7 @@ func addDummyTxsTo(t *testing.T, s *BCTest, nbr int, perCTx int, counter int, id counter++ instrs = append(instrs, instr) } - s.sendInstructions(t, 10, instrs...) - s.Local.WaitDone(time.Second) + s.SendInst(nil, instrs...) } return counter } @@ -1929,8 +1922,7 @@ func TestService_SetConfigRosterDownload(t *testing.T) { testDarcBuf, err := testDarc.ToProto() require.NoError(t, err) instr := createSpawnInstr(b.GenesisDarc.GetBaseID(), ContractDarcID, "darc", testDarcBuf) - require.NoError(t, err) - b.sendInstructions(t, 10, instr) + b.SendInst(nil, instr) // Add other transaction so we're on a new border between forward links ct := addDummyTxs(t, b, 4, 1, 2) @@ -2145,7 +2137,7 @@ func TestService_DownloadStateRunning(t *testing.T) { continue } log.Lvl1("Deleting node", i, "and adding new transaction") - b.DeleteDBs(i) + deleteDBs(b, i) addDummyTxsTo(t, b, 1, 1, counter, (i+1)%len(b.Services)) counter++ @@ -2437,8 +2429,8 @@ func TestService_StateChangeStorageCatchUp(t *testing.T) { b.SpawnDummy(nil) b.SpawnDummy(nil) - newServer, newRoster, newService := b.Local.MakeSRS(cothority.Suite, 1, ByzCoinID) - registerContracts(newServer) + _, newRoster, newService := b.Local.MakeSRS(cothority.Suite, 1, ByzCoinID) + registerContracts(newService.(*Service)) newRoster = onet.NewRoster(append(b.Roster.List, newRoster.List...)) ctx, _ := createConfigTxWithCounter(t, b.PropagationInterval, *newRoster, @@ -2729,13 +2721,10 @@ func versionContractFunc(rst ReadOnlyStateTrie, inst Instruction, c []Coin) ([]S return []StateChange{sc}, c, nil } -func registerContracts(servers []*onet.Server) { +func registerContracts(services ...*Service) { // For testing - there must be a better way to do that. But putting // services []skipchain.Service in the method signature doesn't work :( - for _, s := range servers { - service := s.Service(ServiceName).(*Service) - - service.testRegisterContract(DummyContractName, DummyContractFromBytes) + for _, service := range services { service.testRegisterContract(slowContract, adaptor(slowContractFunc)) service.testRegisterContract(invalidContract, adaptor(invalidContractFunc)) service.testRegisterContract(versionContract, adaptor(versionContractFunc)) @@ -2778,15 +2767,17 @@ func testDarcEvolution(b *BCTest, d2 darc.Darc, fail bool) Proof { } type bctArgs struct { - BCTestArgs - RotationWindow int - Version Version + PropagationInterval time.Duration + Nodes int + RotationWindow int + Version Version } var defaultBCTArgs = bctArgs{ - BCTestArgs: defaultBCTestArgs, - RotationWindow: 9999, - Version: CurrentVersion, + Nodes: 3, + PropagationInterval: 500 * time.Millisecond, + RotationWindow: 9999, + Version: CurrentVersion, } func newBCTRun(t *testing.T, args *bctArgs) *BCTest { @@ -2799,23 +2790,21 @@ func newBCT(t *testing.T, args *bctArgs) *BCTest { if args == nil { args = &defaultBCTArgs } - bct := NewBCTest(t, &args.BCTestArgs) + bct := NewBCTest(t, args.PropagationInterval, args.Nodes) for _, sv := range bct.Services { sv.rotationWindow = args.RotationWindow sv.defaultVersion = args.Version } - registerContracts(bct.Servers) + registerContracts(bct.Services...) bct.AddGenesisRules( - "spawn:"+DummyContractName, "spawn:"+invalidContract, "spawn:"+panicContract, "spawn:"+slowContract, "spawn:"+versionContract, - "spawn:"+stateChangeCacheContract, - "delete:"+DummyContractName) + "spawn:"+stateChangeCacheContract) return bct } @@ -2825,3 +2814,27 @@ func transactionOK(t *testing.T, resp *AddTxResponse, err error) { require.NotNil(t, resp) require.Empty(t, resp.Error) } + +// DeleteDBs resets the byzcoin- and skipchain-dbs of the given node. +func deleteDBs(b *BCTest, index int) { + bc := b.Services[index] + log.Lvlf1("%s: Deleting DB of node %d", bc.ServerIdentity(), index) + bc.TestClose() + for scid := range bc.stateTries { + require.NoError(b.T, deleteDB(bc.ServiceProcessor, []byte(scid))) + idStr := hex.EncodeToString([]byte(scid)) + require.NoError(b.T, deleteDB(bc.ServiceProcessor, []byte(idStr))) + } + require.NoError(b.T, deleteDB(bc.ServiceProcessor, storageID)) + sc := bc.Service(skipchain.ServiceName).(*skipchain.Service) + require.NoError(b.T, deleteDB(sc.ServiceProcessor, []byte("skipblocks"))) + require.NoError(b.T, deleteDB(sc.ServiceProcessor, []byte("skipchainconfig"))) + require.NoError(b.T, bc.TestRestart()) +} + +func deleteDB(s *onet.ServiceProcessor, key []byte) error { + db, stBucket := s.GetAdditionalBucket(key) + return db.Update(func(tx *bbolt.Tx) error { + return tx.DeleteBucket(stBucket) + }) +}