// createExplorerTester creates a tester object for the explorer module. func createExplorerTester(name string) (*explorerTester, error) { // Create and assemble the dependencies. testdir := build.TempDir(modules.HostDir, name) g, err := gateway.New(":0", filepath.Join(testdir, modules.GatewayDir)) if err != nil { return nil, err } cs, err := consensus.New(g, filepath.Join(testdir, modules.ConsensusDir)) if err != nil { return nil, err } tp, err := transactionpool.New(cs, g) if err != nil { return nil, err } w, err := wallet.New(cs, tp, filepath.Join(testdir, modules.WalletDir)) if err != nil { return nil, err } key, err := crypto.GenerateTwofishKey() if err != nil { return nil, err } _, err = w.Encrypt(key) if err != nil { return nil, err } err = w.Unlock(key) if err != nil { return nil, err } m, err := miner.New(cs, tp, w, filepath.Join(testdir, modules.RenterDir)) if err != nil { return nil, err } e, err := New(cs, filepath.Join(testdir, modules.ExplorerDir)) if err != nil { return nil, err } et := &explorerTester{ cs: cs, gateway: g, miner: m, tpool: tp, wallet: w, walletKey: key, explorer: e, } // Mine until the wallet has money. for i := types.BlockHeight(0); i <= types.MaturityDelay; i++ { b, _ := et.miner.FindBlock() err = et.cs.AcceptBlock(b) if err != nil { return nil, err } } return et, nil }
// TestGatewayPeerConnect checks that /gateway/connect is adding a peer to the // gateway's peerlist. func TestGatewayPeerConnect(t *testing.T) { if testing.Short() { t.SkipNow() } st, err := createServerTester("TestGatewayPeerConnect1") if err != nil { t.Fatal(err) } defer st.server.Close() peer, err := gateway.New("localhost:0", build.TempDir("api", "TestGatewayPeerConnect2", "gateway")) if err != nil { t.Fatal(err) } err = st.stdPostAPI("/gateway/connect/"+string(peer.Address()), nil) if err != nil { t.Fatal(err) } var info GatewayInfo err = st.getAPI("/gateway", &info) if err != nil { t.Fatal(err) } if len(info.Peers) != 1 || info.Peers[0].NetAddress != peer.Address() { t.Fatal("/gateway/connect did not connect to peer", peer.Address()) } }
// TestIntegrationWalletBlankEncrypt tries to encrypt and unlock the wallet // through the api using a blank encryption key - meaning that the wallet seed // returned by the encryption call can be used as the encryption key. func TestIntegrationWalletBlankEncrypt(t *testing.T) { if testing.Short() { t.SkipNow() } // Create a server object without encrypting or unlocking the wallet. testdir := build.TempDir("api", "TestIntegrationWalletBlankEncrypt") g, err := gateway.New(":0", filepath.Join(testdir, modules.GatewayDir)) if err != nil { t.Fatal(err) } cs, err := consensus.New(g, filepath.Join(testdir, modules.ConsensusDir)) if err != nil { t.Fatal(err) } tp, err := transactionpool.New(cs, g) if err != nil { t.Fatal(err) } w, err := wallet.New(cs, tp, filepath.Join(testdir, modules.WalletDir)) if err != nil { t.Fatal(err) } srv, err := NewServer(":0", cs, g, nil, nil, nil, nil, tp, w, nil) if err != nil { t.Fatal(err) } // Assemble the serverTester. st := &serverTester{ cs: cs, gateway: g, tpool: tp, wallet: w, server: srv, } go func() { listenErr := srv.Serve() if listenErr != nil { panic(listenErr) } }() // Make a call to /wallet/encrypt and get the seed. Provide no encryption // key so that the encryption key is the seed that gets returned. var wep WalletEncryptPOST err = st.postAPI("/wallet/encrypt", url.Values{}, &wep) if err != nil { t.Fatal(err) } // Use the seed to call /wallet/unlock. unlockValues := url.Values{} unlockValues.Set("encryptionpassword", wep.PrimarySeed) err = st.stdPostAPI("/wallet/unlock", unlockValues) if err != nil { t.Fatal(err) } // Check that the wallet actually unlocked. if !w.Unlocked() { t.Error("wallet is not unlocked") } }
// TestExplorerGenesisHeight checks that when the explorer is initialized and given the // genesis block, the result has the correct height. func TestExplorerGenesisHeight(t *testing.T) { // Create the dependencies. testdir := build.TempDir(modules.HostDir, "TestExplorerGenesisHeight") g, err := gateway.New("localhost:0", false, filepath.Join(testdir, modules.GatewayDir)) if err != nil { t.Fatal(err) } cs, err := consensus.New(g, false, filepath.Join(testdir, modules.ConsensusDir)) if err != nil { t.Fatal(err) } // Create the explorer - from the subscription only the genesis block will // be received. e, err := New(cs, testdir) if err != nil { t.Fatal(err) } block, height, exists := e.Block(types.GenesisID) if !exists { t.Error("explorer missing genesis block after initialization") } if block.ID() != types.GenesisID { t.Error("explorer returned wrong genesis block") } if height != 0 { t.Errorf("genesis block hash wrong height: expected 0, got %v", height) } }
func TestGatewayPeerRemove(t *testing.T) { if testing.Short() { t.SkipNow() } st, err := createServerTester("TestGatewayPeerRemove") if err != nil { t.Fatal(err) } defer st.server.Close() peer, err := gateway.New(":0", build.TempDir("api", "TestGatewayPeerRemove", "gateway")) if err != nil { t.Fatal(err) } st.stdPostAPI("/gateway/add/"+string(peer.Address()), nil) var info GatewayInfo st.getAPI("/gateway", &info) if len(info.Peers) != 1 || info.Peers[0] != peer.Address() { t.Fatal("/gateway/add did not add peer", peer.Address()) } st.stdPostAPI("/gateway/remove/"+string(peer.Address()), nil) st.getAPI("/gateway", &info) if len(info.Peers) != 0 { t.Fatal("/gateway/remove did not remove peer", peer.Address()) } }
// createMinerTester creates a minerTester that's ready for use. func createMinerTester(name string) (*minerTester, error) { testdir := build.TempDir(modules.MinerDir, name) // Create the modules. g, err := gateway.New(":0", filepath.Join(testdir, modules.GatewayDir)) if err != nil { return nil, err } cs, err := consensus.New(g, filepath.Join(testdir, modules.ConsensusDir)) if err != nil { return nil, err } tp, err := transactionpool.New(cs, g) if err != nil { return nil, err } w, err := wallet.New(cs, tp, filepath.Join(testdir, modules.WalletDir)) if err != nil { return nil, err } var key crypto.TwofishKey _, err = rand.Read(key[:]) if err != nil { return nil, err } _, err = w.Encrypt(key) if err != nil { return nil, err } err = w.Unlock(key) if err != nil { return nil, err } m, err := New(cs, tp, w, filepath.Join(testdir, modules.MinerDir)) if err != nil { return nil, err } // Assemble the minerTester. mt := &minerTester{ gateway: g, cs: cs, tpool: tp, wallet: w, walletKey: key, miner: m, } // Mine until the wallet has money. for i := types.BlockHeight(0); i <= types.MaturityDelay; i++ { b, _ := m.FindBlock() err = cs.AcceptBlock(b) if err != nil { return nil, err } } return mt, nil }
// TestNilInputs tries starting the wallet using nil inputs. func TestNilInputs(t *testing.T) { testdir := build.TempDir(modules.WalletDir, "TestNilInputs") g, err := gateway.New(":0", filepath.Join(testdir, modules.GatewayDir)) if err != nil { t.Fatal(err) } cs, err := consensus.New(g, filepath.Join(testdir, modules.ConsensusDir)) if err != nil { t.Fatal(err) } tp, err := transactionpool.New(cs, g) if err != nil { t.Fatal(err) } wdir := filepath.Join(testdir, modules.WalletDir) _, err = New(cs, nil, wdir) if err != errNilTpool { t.Error(err) } _, err = New(nil, tp, wdir) if err != errNilConsensusSet { t.Error(err) } _, err = New(nil, nil, wdir) if err != errNilConsensusSet { t.Error(err) } }
// createWalletTester takes a testing.T and creates a WalletTester. func createWalletTester(name string) (*walletTester, error) { // Create the modules testdir := build.TempDir(modules.WalletDir, name) g, err := gateway.New(":0", filepath.Join(testdir, modules.GatewayDir)) if err != nil { return nil, err } cs, err := consensus.New(g, filepath.Join(testdir, modules.ConsensusDir)) if err != nil { return nil, err } tp, err := transactionpool.New(cs, g) if err != nil { return nil, err } w, err := New(cs, tp, filepath.Join(testdir, modules.WalletDir)) if err != nil { return nil, err } var masterKey crypto.TwofishKey _, err = rand.Read(masterKey[:]) if err != nil { return nil, err } _, err = w.Encrypt(masterKey) if err != nil { return nil, err } err = w.Unlock(masterKey) if err != nil { return nil, err } m, err := miner.New(cs, tp, w, filepath.Join(testdir, modules.WalletDir)) if err != nil { return nil, err } // Assemble all componenets into a wallet tester. wt := &walletTester{ cs: cs, gateway: g, tpool: tp, miner: m, wallet: w, walletMasterKey: masterKey, persistDir: testdir, } // Mine blocks until there is money in the wallet. for i := types.BlockHeight(0); i <= types.MaturityDelay; i++ { b, _ := wt.miner.FindBlock() err := wt.cs.AcceptBlock(b) if err != nil { return nil, err } } return wt, nil }
// newHostDBTester creates a ready-to-use hostdb tester with money in the // wallet. func newHostDBTester(name string) (*hostdbTester, error) { // Create the modules. testdir := build.TempDir("hostdb", name) g, err := gateway.New(":0", filepath.Join(testdir, modules.GatewayDir)) if err != nil { return nil, err } cs, err := consensus.New(g, filepath.Join(testdir, modules.ConsensusDir)) if err != nil { return nil, err } tp, err := transactionpool.New(cs, g) if err != nil { return nil, err } w, err := modWallet.New(cs, tp, filepath.Join(testdir, modules.WalletDir)) if err != nil { return nil, err } key, err := crypto.GenerateTwofishKey() if err != nil { return nil, err } _, err = w.Encrypt(key) if err != nil { return nil, err } err = w.Unlock(key) if err != nil { return nil, err } hdb, err := New(cs, w, tp, filepath.Join(testdir, modules.RenterDir)) if err != nil { return nil, err } m, err := miner.New(cs, tp, w, filepath.Join(testdir, modules.MinerDir)) if err != nil { return nil, err } // Assemble all pieces into a hostdb tester. ht := &hostdbTester{ cs: cs, gateway: g, miner: m, tpool: tp, wallet: w, hostdb: hdb, } // Mine blocks until there is money in the wallet. for i := types.BlockHeight(0); i <= types.MaturityDelay; i++ { _, err := ht.miner.AddBlock() if err != nil { return nil, err } } return ht, nil }
// createConsensusSetTester creates a consensusSetTester that's ready for use. func createConsensusSetTester(name string) (*consensusSetTester, error) { testdir := build.TempDir(modules.ConsensusDir, name) // Create modules. g, err := gateway.New(":0", filepath.Join(testdir, modules.GatewayDir)) if err != nil { return nil, err } cs, err := New(g, filepath.Join(testdir, modules.ConsensusDir)) if err != nil { return nil, err } tp, err := transactionpool.New(cs, g) if err != nil { return nil, err } w, err := wallet.New(cs, tp, filepath.Join(testdir, modules.WalletDir)) if err != nil { return nil, err } key, err := crypto.GenerateTwofishKey() if err != nil { return nil, err } _, err = w.Encrypt(key) if err != nil { return nil, err } err = w.Unlock(key) if err != nil { return nil, err } m, err := miner.New(cs, tp, w, filepath.Join(testdir, modules.MinerDir)) if err != nil { return nil, err } // Assemble all objects into a consensusSetTester. cst := &consensusSetTester{ gateway: g, miner: m, tpool: tp, wallet: w, walletKey: key, cs: cs, persistDir: testdir, } // Mine until the wallet has money. for i := types.BlockHeight(0); i <= types.MaturityDelay; i++ { b, _ := cst.miner.FindBlock() err = cst.cs.AcceptBlock(b) if err != nil { return nil, err } } return cst, nil }
// TestIntegrationNewNilInputs tries to trigger a panic with nil inputs. func TestIntegrationNewNilInputs(t *testing.T) { // Create a gateway and consensus set. testdir := build.TempDir(modules.TransactionPoolDir, "TestNewNilInputs") g, err := gateway.New(":0", filepath.Join(testdir, modules.GatewayDir)) if err != nil { t.Fatal(err) } cs, err := consensus.New(g, filepath.Join(testdir, modules.ConsensusDir)) if err != nil { t.Fatal(err) } // Try all combinations of nil inputs. _, err = New(nil, nil) if err == nil { t.Error(err) } _, err = New(nil, g) if err != errNilCS { t.Error(err) } _, err = New(cs, nil) if err != errNilGateway { t.Error(err) } _, err = New(cs, g) if err != nil { t.Error(err) } }
// TestCloseWallet tries to close the wallet. func TestCloseWallet(t *testing.T) { if testing.Short() { t.Skip() } testdir := build.TempDir(modules.WalletDir, "TestCloseWallet") g, err := gateway.New("localhost:0", filepath.Join(testdir, modules.GatewayDir)) if err != nil { t.Fatal(err) } cs, err := consensus.New(g, filepath.Join(testdir, modules.ConsensusDir)) if err != nil { t.Fatal(err) } tp, err := transactionpool.New(cs, g, filepath.Join(testdir, modules.TransactionPoolDir)) if err != nil { t.Fatal(err) } wdir := filepath.Join(testdir, modules.WalletDir) w, err := New(cs, tp, wdir) if err != nil { t.Fatal(err) } if err := w.Close(); err != nil { t.Fatal(err) } }
// newRenterTester creates a ready-to-use renter tester with money in the // wallet. func newRenterTester(name string) (*renterTester, error) { // Create the modules. testdir := build.TempDir("renter", name) g, err := gateway.New("localhost:0", false, filepath.Join(testdir, modules.GatewayDir)) if err != nil { return nil, err } cs, err := consensus.New(g, false, filepath.Join(testdir, modules.ConsensusDir)) if err != nil { return nil, err } tp, err := transactionpool.New(cs, g, filepath.Join(testdir, modules.TransactionPoolDir)) if err != nil { return nil, err } w, err := wallet.New(cs, tp, filepath.Join(testdir, modules.WalletDir)) if err != nil { return nil, err } key, err := crypto.GenerateTwofishKey() if err != nil { return nil, err } _, err = w.Encrypt(key) if err != nil { return nil, err } err = w.Unlock(key) if err != nil { return nil, err } r, err := New(cs, w, tp, filepath.Join(testdir, modules.RenterDir)) if err != nil { return nil, err } m, err := miner.New(cs, tp, w, filepath.Join(testdir, modules.MinerDir)) if err != nil { return nil, err } // Assemble all pieces into a renter tester. rt := &renterTester{ cs: cs, gateway: g, miner: m, tpool: tp, wallet: w, renter: r, } // Mine blocks until there is money in the wallet. for i := types.BlockHeight(0); i <= types.MaturityDelay; i++ { _, err := rt.miner.AddBlock() if err != nil { return nil, err } } return rt, nil }
func TestGatewayPeerRemove(t *testing.T) { if testing.Short() { t.SkipNow() } st, err := createServerTester("TestGatewayPeerRemove") if err != nil { t.Fatal(err) } peer, err := gateway.New(":0", build.TempDir("api", "TestGatewayPeerRemove", "gateway")) if err != nil { t.Fatal(err) } st.stdGetAPI("/gateway/peers/add?address=" + string(peer.Address())) var info GatewayInfo st.getAPI("/gateway/status", &info) if len(info.Peers) != 1 || info.Peers[0] != peer.Address() { t.Fatal("/gateway/peers/add did not add peer", peer.Address()) } st.stdGetAPI("/gateway/peers/remove?address=" + string(peer.Address())) st.getAPI("/gateway/status", &info) if len(info.Peers) != 0 { t.Fatal("/gateway/peer/add did not add peer", peer.Address()) } }
// createTpoolTester returns a ready-to-use tpool tester, with all modules // initialized. func createTpoolTester(name string) (*tpoolTester, error) { // Initialize the modules. testdir := build.TempDir(modules.TransactionPoolDir, name) g, err := gateway.New("localhost:0", false, filepath.Join(testdir, modules.GatewayDir)) if err != nil { return nil, err } cs, err := consensus.New(g, false, filepath.Join(testdir, modules.ConsensusDir)) if err != nil { return nil, err } tp, err := New(cs, g, filepath.Join(testdir, modules.TransactionPoolDir)) if err != nil { return nil, err } w, err := wallet.New(cs, tp, filepath.Join(testdir, modules.WalletDir)) if err != nil { return nil, err } var key crypto.TwofishKey _, err = rand.Read(key[:]) if err != nil { return nil, err } _, err = w.Encrypt(key) if err != nil { return nil, err } err = w.Unlock(key) if err != nil { return nil, err } m, err := miner.New(cs, tp, w, filepath.Join(testdir, modules.MinerDir)) if err != nil { return nil, err } // Assemble all of the objects into a tpoolTester tpt := &tpoolTester{ cs: cs, gateway: g, tpool: tp, miner: m, wallet: w, walletKey: key, persistDir: testdir, } // Mine blocks until there is money in the wallet. for i := types.BlockHeight(0); i <= types.MaturityDelay; i++ { b, _ := tpt.miner.FindBlock() err = tpt.cs.AcceptBlock(b) if err != nil { return nil, err } } return tpt, nil }
// TestSaveLoad populates a blockchain, saves it, loads it, and checks // the consensus set hash before and after func TestSaveLoad(t *testing.T) { if testing.Short() { t.SkipNow() } t.Parallel() cst, err := createConsensusSetTester("TestSaveLoad") if err != nil { t.Fatal(err) } defer cst.Close() cst.testBlockSuite() oldHash := cst.cs.dbConsensusChecksum() cst.cs.Close() // Reassigning this will lose subscribers and such, but we // just want to call load and get a hash g, err := gateway.New("localhost:0", false, build.TempDir(modules.ConsensusDir, "TestSaveLoad", modules.GatewayDir)) if err != nil { t.Fatal(err) } d := filepath.Join(build.SiaTestingDir, modules.ConsensusDir, "TestSaveLoad", modules.ConsensusDir) cst.cs, err = New(g, false, d) if err != nil { t.Fatal(err) } newHash := cst.cs.dbConsensusChecksum() if oldHash != newHash { t.Fatal("consensus set hash changed after load") } }
// TestIntegrationWalletGETEncrypted probes the GET call to /wallet when the // wallet has never been encrypted. func TestIntegrationWalletGETEncrypted(t *testing.T) { if testing.Short() { t.SkipNow() } // Check a wallet that has never been encrypted. testdir := build.TempDir("api", "TestIntegrationWalletGETEncrypted") g, err := gateway.New(":0", filepath.Join(testdir, modules.GatewayDir)) if err != nil { t.Fatal("Failed to create gateway:", err) } cs, err := consensus.New(g, filepath.Join(testdir, modules.ConsensusDir)) if err != nil { t.Fatal("Failed to create consensus set:", err) } tp, err := transactionpool.New(cs, g) if err != nil { t.Fatal("Failed to create tpool:", err) } w, err := wallet.New(cs, tp, filepath.Join(testdir, modules.WalletDir)) if err != nil { t.Fatal("Failed to create wallet:", err) } srv, err := NewServer(":0", "Sia-Agent", cs, nil, g, nil, nil, nil, tp, w) if err != nil { t.Fatal(err) } // Assemble the serverTester and start listening for api requests. st := &serverTester{ cs: cs, gateway: g, tpool: tp, wallet: w, server: srv, } go func() { listenErr := srv.Serve() if listenErr != nil { t.Fatal("API server quit:", listenErr) } }() defer st.server.Close() var wg WalletGET err = st.getAPI("/wallet", &wg) if err != nil { t.Fatal(err) } if wg.Encrypted { t.Error("Wallet has never been unlocked") } if wg.Unlocked { t.Error("Wallet has never been unlocked") } }
// BenchmarkAcceptEmptyBlocks measures how quckly empty blocks are integrated // into the consensus set. // // i7-4770, 1d60d69: 1.356 ms / op func BenchmarkAcceptEmptyBlocks(b *testing.B) { cst, err := createConsensusSetTester("BenchmarkEmptyBlocks") if err != nil { b.Fatal("Error creating tester: " + err.Error()) } defer cst.Close() // Create an alternate testing consensus set, which does not // have any subscribers testdir := build.TempDir(modules.ConsensusDir, "BenchmarkEmptyBlocks - 2") g, err := gateway.New("localhost:0", false, filepath.Join(testdir, modules.GatewayDir)) if err != nil { b.Fatal(err) } cs, err := New(g, false, filepath.Join(testdir, modules.ConsensusDir)) if err != nil { b.Fatal(err) } defer cs.Close() // Synchronisze the cst and the subscriberless consensus set. h := cst.cs.dbBlockHeight() for i := types.BlockHeight(1); i <= h; i++ { id, err := cst.cs.dbGetPath(i) if err != nil { b.Fatal(err) } processedBlock, err := cst.cs.dbGetBlockMap(id) if err != nil { b.Fatal(err) } err = cs.AcceptBlock(processedBlock.Block) if err != nil { b.Fatal(err) } } b.ResetTimer() b.StopTimer() for j := 0; j < b.N; j++ { // Submit a block to the consensus set tester - which has many // subscribers. (untimed) block, err := cst.miner.AddBlock() if err != nil { b.Fatal(err) } // Submit a block to the consensus set which has no subscribers. // (timed) b.StartTimer() err = cs.AcceptBlock(block) if err != nil { b.Fatal("error accepting a block:", err) } b.StopTimer() } }
// benchmarkEmptyBlocks is a benchmark that mines many blocks, and // measures how long it takes to add them to the consensusset func benchmarkAcceptEmptyBlocks(b *testing.B) error { // Create an alternate testing consensus set, which does not // have any subscribers testdir := build.TempDir(modules.ConsensusDir, "BenchmarkEmptyBlocksB") g, err := gateway.New(":0", filepath.Join(testdir, modules.GatewayDir)) if err != nil { return err } cs, err := New(g, filepath.Join(testdir, modules.ConsensusDir)) if err != nil { return errors.New("Error creating consensus: " + err.Error()) } defer cs.Close() // The test dir will be reset each time the benchmark // is done. cst, err := createConsensusSetTester("BenchmarkEmptyBlocks") if err != nil { return errors.New("Error creating tester: " + err.Error()) } defer cst.closeCst() h := cst.cs.db.pathHeight() for i := types.BlockHeight(1); i < h; i++ { err = cs.AcceptBlock(cst.cs.db.getBlockMap(cst.cs.db.getPath(i)).Block) if err != nil { return err } } b.ResetTimer() for j := 0; j < b.N; j++ { // Submit a block to the consensus set tester - which has many // subscribers. (untimed) b.StopTimer() block, err := cst.miner.FindBlock() if err != nil { return err } err = cst.cs.AcceptBlock(block) if err != nil { errstr := fmt.Sprintf("Error accepting %d from mined: %s", j, err.Error()) return errors.New(errstr) } b.StartTimer() // Submit a block to the consensus set which has no subscribers. // (timed) err = cs.AcceptBlock(block) if err != nil { errstr := fmt.Sprintf("Error accepting %d for timing: %s", j, err.Error()) return errors.New(errstr) } } return nil }
// createConsensusSetTester creates a consensusSetTester that's ready for use. func createConsensusSetTester(name string) (*consensusSetTester, error) { testdir := build.TempDir(modules.ConsensusDir, name) // Create modules. g, err := gateway.New(":0", filepath.Join(testdir, modules.GatewayDir)) if err != nil { return nil, err } cs, err := New(g, filepath.Join(testdir, modules.ConsensusDir)) if err != nil { return nil, err } tp, err := transactionpool.New(cs, g) if err != nil { return nil, err } w, err := wallet.New(cs, tp, filepath.Join(testdir, modules.WalletDir)) if err != nil { return nil, err } m, err := miner.New(cs, tp, w, filepath.Join(testdir, modules.MinerDir)) if err != nil { return nil, err } // Assemble all objects into a consensusSetTester. cst := &consensusSetTester{ gateway: g, miner: m, tpool: tp, wallet: w, cs: cs, persistDir: testdir, csUpdateChan: cs.ConsensusSetNotify(), minerUpdateChan: m.MinerNotify(), tpoolUpdateChan: tp.TransactionPoolNotify(), walletUpdateChan: w.WalletNotify(), } cst.csUpdateWait() // Mine until the wallet has money. for i := types.BlockHeight(0); i <= types.MaturityDelay; i++ { b, _ := cst.miner.FindBlock() err = cst.cs.AcceptBlock(b) if err != nil { return nil, err } cst.csUpdateWait() } return cst, nil }
// createConsensusSetTester creates a consensusSetTester that's ready for use. func createConsensusSetTester(name string) (*consensusSetTester, error) { testdir := build.TempDir(modules.ConsensusDir, name) // Create modules. g, err := gateway.New(":0", filepath.Join(testdir, modules.GatewayDir)) if err != nil { return nil, err } cs, err := New(g, filepath.Join(testdir, modules.ConsensusDir)) if err != nil { return nil, err } tp, err := transactionpool.New(cs, g) if err != nil { return nil, err } w, err := wallet.New(cs, tp, filepath.Join(testdir, modules.WalletDir)) if err != nil { return nil, err } key, err := crypto.GenerateTwofishKey() if err != nil { return nil, err } _, err = w.Encrypt(key) if err != nil { return nil, err } err = w.Unlock(key) if err != nil { return nil, err } m, err := miner.New(cs, tp, w, filepath.Join(testdir, modules.MinerDir)) if err != nil { return nil, err } // Assemble all objects into a consensusSetTester. cst := &consensusSetTester{ gateway: g, miner: m, tpool: tp, wallet: w, walletKey: key, cs: cs, persistDir: testdir, } cst.addSiafunds() cst.mineSiacoins() return cst, nil }
// blankHostTester creates a host tester where the modules are created but no // extra initialization has been done, for example no blocks have been mined // and the wallet keys have not been created. func blankHostTester(name string) (*hostTester, error) { testdir := build.TempDir(modules.HostDir, name) // Create the modules. g, err := gateway.New("localhost:0", filepath.Join(testdir, modules.GatewayDir)) if err != nil { return nil, err } cs, err := consensus.New(g, filepath.Join(testdir, modules.ConsensusDir)) if err != nil { return nil, err } tp, err := transactionpool.New(cs, g, filepath.Join(testdir, modules.TransactionPoolDir)) if err != nil { return nil, err } w, err := wallet.New(cs, tp, filepath.Join(testdir, modules.WalletDir)) if err != nil { return nil, err } m, err := miner.New(cs, tp, w, filepath.Join(testdir, modules.MinerDir)) if err != nil { return nil, err } h, err := New(cs, tp, w, "localhost:0", filepath.Join(testdir, modules.HostDir)) if err != nil { return nil, err } /* r, err := renter.New(cs, w, tp, filepath.Join(testdir, modules.RenterDir)) if err != nil { return nil, err } */ // Assemble all objects into a hostTester ht := &hostTester{ cs: cs, gateway: g, miner: m, // renter: r, tpool: tp, wallet: w, host: h, persistDir: testdir, } return ht, nil }
// reorgToBlank creates a bunch of empty blocks on top of the genesis block // that reorgs the explorer to a state of all blank blocks. func (et *explorerTester) reorgToBlank() error { // Get a unique directory name to house the persistence of the miner // dependencies. dir := et.testdir + " - " + persist.RandomSuffix() // Create a miner and all dependencies to create an alternate chain. g, err := gateway.New("localhost:0", false, filepath.Join(dir, modules.GatewayDir)) if err != nil { return err } cs, err := consensus.New(g, false, filepath.Join(dir, modules.ConsensusDir)) if err != nil { return err } tp, err := transactionpool.New(cs, g, filepath.Join(dir, modules.TransactionPoolDir)) if err != nil { return err } w, err := wallet.New(cs, tp, filepath.Join(dir, modules.WalletDir)) if err != nil { return err } key, err := crypto.GenerateTwofishKey() if err != nil { return err } _, err = w.Encrypt(key) if err != nil { return err } err = w.Unlock(key) if err != nil { return err } m, err := miner.New(cs, tp, w, filepath.Join(dir, modules.RenterDir)) if err != nil { return err } // Mine blocks until the height is higher than the existing consensus, // submitting each block to the explorerTester. currentHeight := cs.Height() for i := types.BlockHeight(0); i <= currentHeight+1; i++ { block, err := m.AddBlock() if err != nil { return err } et.cs.AcceptBlock(block) // error is not checked, will not always be nil } return nil }
func createExplorerTester(name string, t *testing.T) *explorerTester { testdir := build.TempDir(modules.HostDir, name) // Create the modules g, err := gateway.New(":0", filepath.Join(testdir, modules.GatewayDir)) if err != nil { t.Fatal(err) } cs, err := consensus.New(g, filepath.Join(testdir, modules.ConsensusDir)) if err != nil { t.Fatal(err) } tp, err := transactionpool.New(cs, g) if err != nil { t.Fatal(err) } w, err := wallet.New(cs, tp, filepath.Join(testdir, modules.WalletDir)) if err != nil { t.Fatal(err) } m, err := miner.New(cs, tp, w, filepath.Join(testdir, modules.RenterDir)) if err != nil { t.Fatal(err) } be, err := New(cs) if err != nil { t.Fatal(err) } et := &explorerTester{ cs: cs, gateway: g, miner: m, tpool: tp, wallet: w, explorer: be, csUpdateChan: cs.ConsensusSetNotify(), beUpdateChan: be.BlockExplorerNotify(), tpoolUpdateChan: tp.TransactionPoolNotify(), minerUpdateChan: m.MinerNotify(), walletUpdateChan: w.WalletNotify(), t: t, } et.csUpdateWait() return et }
func TestGatewayPeerAdd(t *testing.T) { st := newServerTester("TestGatewayPeerAdd", t) peer, err := gateway.New(":0", build.TempDir("api", "TestGatewayPeerAdd", "gateway")) if err != nil { t.Fatal(err) } st.callAPI("/gateway/peers/add?address=" + string(peer.Address())) var info GatewayInfo st.getAPI("/gateway/status", &info) if len(info.Peers) != 1 || info.Peers[0] != peer.Address() { t.Fatal("/gateway/peers/add did not add peer", peer.Address()) } }
// startDaemonCmd uses the config parameters to start siad. func startDaemon() error { // Establish multithreading. runtime.GOMAXPROCS(runtime.NumCPU()) // Create all of the modules. gateway, err := gateway.New(config.Siad.RPCaddr, filepath.Join(config.Siad.SiaDir, modules.GatewayDir)) if err != nil { return err } state, err := consensus.New(gateway, filepath.Join(config.Siad.SiaDir, modules.ConsensusDir)) if err != nil { return err } hostdb, err := hostdb.New(state, gateway) if err != nil { return err } explorer, err := explorer.New(state, filepath.Join(config.Siad.SiaDir, modules.ExplorerDir)) if err != nil { return err } srv, err := api.NewServer(config.Siad.APIaddr, state, gateway, nil, hostdb, nil, nil, nil, nil, explorer) if err != nil { return err } // Bootstrap to the network. if !config.Siad.NoBootstrap { for i := range modules.BootstrapPeers { go gateway.Connect(modules.BootstrapPeers[i]) } } // Send a struct down the started channel, so the testing package knows // that daemon startup has completed. A gofunc is used with the hope that // srv.Serve() will start running before the value is sent down the // channel. go func() { started <- struct{}{} }() // Start serving api requests. err = srv.Serve() if err != nil { return err } return nil }
// TestClosing tries to close a consenuss set. func TestDatabaseClosing(t *testing.T) { testdir := build.TempDir(modules.ConsensusDir, "TestClosing") // Create the gateway. g, err := gateway.New(":0", filepath.Join(testdir, modules.GatewayDir)) if err != nil { t.Fatal(err) } cs, err := New(g, testdir) if err != nil { t.Fatal(err) } err = cs.Close() if err != nil { t.Error(err) } }
// assembleExplorerServerTester creates all the explorer dependencies and // explorer module without creating any directories. The user agent requirement // is disabled. func assembleExplorerServerTester(testdir string) (*serverTester, error) { // assembleExplorerServerTester should not get called during short tests, // as it takes a long time to run. if testing.Short() { panic("assembleServerTester called during short tests") } // Create the modules. g, err := gateway.New("localhost:0", false, filepath.Join(testdir, modules.GatewayDir)) if err != nil { return nil, err } cs, err := consensus.New(g, false, filepath.Join(testdir, modules.ConsensusDir)) if err != nil { return nil, err } e, err := explorer.New(cs, filepath.Join(testdir, modules.ExplorerDir)) if err != nil { return nil, err } srv, err := NewServer("localhost:0", "", "", cs, e, g, nil, nil, nil, nil, nil) if err != nil { return nil, err } // Assemble the serverTester. st := &serverTester{ cs: cs, explorer: e, gateway: g, server: srv, dir: testdir, } // TODO: A more reasonable way of listening for server errors. go func() { listenErr := srv.Serve() if listenErr != nil { panic(listenErr) } }() return st, nil }
// TestClosing tries to close a consenuss set. func TestDatabaseClosing(t *testing.T) { if testing.Short() { t.SkipNow() } t.Parallel() testdir := build.TempDir(modules.ConsensusDir, "TestClosing") // Create the gateway. g, err := gateway.New("localhost:0", filepath.Join(testdir, modules.GatewayDir)) if err != nil { t.Fatal(err) } cs, err := New(g, testdir) if err != nil { t.Fatal(err) } err = cs.Close() if err != nil { t.Error(err) } }
// assembleExplorerServerTester creates all the explorer dependencies and // explorer module without creating any directories. The user agent requirement // is disabled. func assembleExplorerServerTester(testdir string) (*serverTester, error) { // Create the modules. g, err := gateway.New(":0", filepath.Join(testdir, modules.GatewayDir)) if err != nil { return nil, err } cs, err := consensus.New(g, filepath.Join(testdir, modules.ConsensusDir)) if err != nil { return nil, err } e, err := explorer.New(cs, filepath.Join(testdir, modules.ExplorerDir)) if err != nil { return nil, err } srv, err := NewServer(":0", "", cs, e, g, nil, nil, nil, nil, nil) if err != nil { return nil, err } // Assemble the serverTester. st := &serverTester{ cs: cs, explorer: e, gateway: g, server: srv, dir: testdir, } // TODO: A more reasonable way of listening for server errors. go func() { listenErr := srv.Serve() if listenErr != nil { panic(listenErr) } }() return st, nil }