func setUpLoadAllSeries(t *testing.T, namespace walletdb.Namespace, mgr *waddrmgr.Manager, test testLoadAllSeriesTest) *vp.Pool { pool, err := vp.Create(namespace, mgr, []byte{byte(test.id + 1)}) if err != nil { t.Fatalf("Voting Pool creation failed: %v", err) } for _, series := range test.series { err := pool.CreateSeries(series.version, series.id, series.reqSigs, series.pubKeys) if err != nil { t.Fatalf("Test #%d Series #%d: failed to create series: %v", test.id, series.id, err) } for _, privKey := range series.privKeys { vp.TstRunWithManagerUnlocked(t, mgr, func() { if err := pool.EmpowerSeries(series.id, privKey); err != nil { t.Fatalf("Test #%d Series #%d: empower with privKey %v failed: %v", test.id, series.id, privKey, err) } }) } } return pool }
func TestEmpowerSeries(t *testing.T) { tearDown, mgr, pool := vp.TstCreatePool(t) defer tearDown() seriesID := uint32(1) if err := pool.CreateSeries(1, seriesID, 2, vp.TstPubKeys[0:3]); err != nil { t.Fatalf("Failed to create series: %v", err) } vp.TstRunWithManagerUnlocked(t, mgr, func() { if err := pool.EmpowerSeries(seriesID, vp.TstPrivKeys[0]); err != nil { t.Errorf("Failed to empower series: %v", err) } }) }
func TestLoadAllSeries(t *testing.T) { tearDown, manager, pool := vp.TstCreatePool(t) defer tearDown() for _, test := range testLoadAllSeriesTests { pool := setUpLoadAllSeries(t, pool.TstNamespace(), manager, test) pool.TstEmptySeriesLookup() vp.TstRunWithManagerUnlocked(t, manager, func() { if err := pool.LoadAllSeries(); err != nil { t.Fatalf("Test #%d: failed to load voting pool: %v", test.id, err) } }) for _, seriesData := range test.series { validateLoadAllSeries(t, pool, test.id, seriesData) } } }
func TestLoadPoolAndEmpowerSeries(t *testing.T) { tearDown, manager, pool := vp.TstCreatePool(t) defer tearDown() // setup poolID := "test" pubKeys := vp.TstPubKeys[0:3] err := vp.LoadAndCreateSeries(pool.TstNamespace(), manager, 1, poolID, 1, 2, pubKeys) if err != nil { t.Fatalf("Creating voting pool and Creating series failed: %v", err) } vp.TstRunWithManagerUnlocked(t, pool.Manager(), func() { err = vp.LoadAndEmpowerSeries(pool.TstNamespace(), manager, poolID, 1, vp.TstPrivKeys[0]) }) if err != nil { t.Fatalf("Load voting pool and Empower series failed: %v", err) } }
func TestCannotReplaceEmpoweredSeries(t *testing.T) { tearDown, mgr, pool := vp.TstCreatePool(t) defer tearDown() seriesID := uint32(1) if err := pool.CreateSeries(1, seriesID, 3, vp.TstPubKeys[0:4]); err != nil { t.Fatalf("Failed to create series: %v", err) } vp.TstRunWithManagerUnlocked(t, mgr, func() { if err := pool.EmpowerSeries(seriesID, vp.TstPrivKeys[1]); err != nil { t.Fatalf("Failed to empower series: %v", err) } }) err := pool.ReplaceSeries(1, seriesID, 2, []string{vp.TstPubKeys[0], vp.TstPubKeys[2], vp.TstPubKeys[3]}) vp.TstCheckError(t, "", err, vp.ErrSeriesAlreadyEmpowered) }
func TestStartWithdrawal(t *testing.T) { tearDown, pool, store := vp.TstCreatePoolAndTxStore(t) defer tearDown() mgr := pool.Manager() masters := []*hdkeychain.ExtendedKey{ vp.TstCreateMasterKey(t, bytes.Repeat([]byte{0x00, 0x01}, 16)), vp.TstCreateMasterKey(t, bytes.Repeat([]byte{0x02, 0x01}, 16)), vp.TstCreateMasterKey(t, bytes.Repeat([]byte{0x03, 0x01}, 16))} def := vp.TstCreateSeriesDef(t, pool, 2, masters) vp.TstCreateSeries(t, pool, []vp.TstSeriesDef{def}) // Create eligible inputs and the list of outputs we need to fulfil. vp.TstCreateSeriesCreditsOnStore(t, pool, def.SeriesID, []int64{5e6, 4e6}, store) address1 := "34eVkREKgvvGASZW7hkgE2uNc1yycntMK6" address2 := "3PbExiaztsSYgh6zeMswC49hLUwhTQ86XG" requests := []vp.OutputRequest{ vp.TstNewOutputRequest(t, 1, address1, 4e6, mgr.ChainParams()), vp.TstNewOutputRequest(t, 2, address2, 1e6, mgr.ChainParams()), } changeStart := vp.TstNewChangeAddress(t, pool, def.SeriesID, 0) startAddr := vp.TstNewWithdrawalAddress(t, pool, def.SeriesID, 0, 0) lastSeriesID := def.SeriesID dustThreshold := coinutil.Amount(1e4) currentBlock := int32(vp.TstInputsBlock + vp.TstEligibleInputMinConfirmations + 1) var status *vp.WithdrawalStatus var err error vp.TstRunWithManagerUnlocked(t, mgr, func() { status, err = pool.StartWithdrawal(0, requests, *startAddr, lastSeriesID, *changeStart, store, currentBlock, dustThreshold) }) if err != nil { t.Fatal(err) } // Check that all outputs were successfully fulfilled. checkWithdrawalOutputs(t, status, map[string]coinutil.Amount{address1: 4e6, address2: 1e6}) if status.Fees() != coinutil.Amount(1e3) { t.Fatalf("Wrong amount for fees; got %v, want %v", status.Fees(), coinutil.Amount(1e3)) } // This withdrawal generated a single transaction with just one change // output, so the next change address will be on the same series with the // index incremented by 1. nextChangeAddr := status.NextChangeAddr() if nextChangeAddr.SeriesID() != changeStart.SeriesID() { t.Fatalf("Wrong nextChangeStart series; got %d, want %d", nextChangeAddr.SeriesID(), changeStart.SeriesID()) } if nextChangeAddr.Index() != changeStart.Index()+1 { t.Fatalf("Wrong nextChangeStart index; got %d, want %d", nextChangeAddr.Index(), changeStart.Index()+1) } // NOTE: The ntxid is deterministic so we hardcode it here, but if the test // or the code is changed in a way that causes the generated transaction to // change (e.g. different inputs/outputs), the ntxid will change too and // this will have to be updated. ntxid := vp.Ntxid("eb753083db55bd0ad2eb184bfd196a7ea8b90eaa000d9293e892999695af2519") txSigs := status.Sigs()[ntxid] // Finally we use SignTx() to construct the SignatureScripts (using the raw // signatures). Must unlock the manager as signing involves looking up the // redeem script, which is stored encrypted. msgtx := status.TstGetMsgTx(ntxid) vp.TstRunWithManagerUnlocked(t, mgr, func() { if err = vp.SignTx(msgtx, txSigs, mgr, store); err != nil { t.Fatal(err) } }) // Any subsequent StartWithdrawal() calls with the same parameters will // return the previously stored WithdrawalStatus. var status2 *vp.WithdrawalStatus vp.TstRunWithManagerUnlocked(t, mgr, func() { status2, err = pool.StartWithdrawal(0, requests, *startAddr, lastSeriesID, *changeStart, store, currentBlock, dustThreshold) }) if err != nil { t.Fatal(err) } vp.TstCheckWithdrawalStatusMatches(t, *status, *status2) }