Skip to content

Instantly share code, notes, and snippets.

@MSevey
Created September 23, 2019 17:43
Show Gist options
  • Save MSevey/b92cf609996f881de4e3a52c2c93c680 to your computer and use it in GitHub Desktop.
Save MSevey/b92cf609996f881de4e3a52c2c93c680 to your computer and use it in GitHub Desktop.
package main
// This code is for creating copies of a clean Sia node and initiallizing the
// wallet, sending Siacoins to it, setting an allowance, and waiting for
// contracts to form.
// For this context, a clean Sia node is defined as a node that was created with
// ./siad and allowed to fully sync. No other commands or initialization took
// place.
import (
"fmt"
"os"
"os/exec"
"time"
"gitlab.com/NebulousLabs/Sia/modules"
"gitlab.com/NebulousLabs/Sia/node/api/client"
"gitlab.com/NebulousLabs/Sia/types"
)
// bash is a helpfer function for running bash commands
func bash(cmd string, args ...string) {
// Execute bash command
out, err := exec.Command(cmd, args...).Output()
if err != nil {
panic(err)
}
// Check if there is any output for the command
if len(out) == 0 {
return
}
// Print output
output := string(out[:])
fmt.Println(output)
}
// main executes the copynode code
func main() {
timeTotalStart := time.Now()
// Custom fields to update
user := "<user>" // Update with your user profile name on your machine
home := os.Getenv("HOME") // Update with your Home path
bootstrapNode := fmt.Sprintf("%v/Sia/newNode", home) // Update with location of your clean node
nodeNums := []int{1, 2, 3}
for _, nodeNum := range nodeNums {
timeNode := time.Now()
// USB location assumes the USB was formatted and mounted as such:
//
// /media/<user>/SiaNode<node number>/
//
// update as needed
usb := fmt.Sprintf("/media/%v/SiaNode%v/Sia", user, nodeNum)
// siadir directory assumed to be in a "Sia" folder as such:
//
// /home/<user>/Sia/
//
// Update as needed
siaDir := fmt.Sprintf("%v/Sia/node%v", home, nodeNum)
// Copy Bootstrap node
fmt.Println("== Copying bootstrap node")
bash("cp", "-a", bootstrapNode, siaDir)
// Create file for wallet seed
seedFile := fmt.Sprintf("%v/Sia/node%v/seed.txt", home, nodeNum)
sf, err := os.Create(seedFile) // Create truncates the file if it exists
if err != nil {
panic(err)
}
// Launch siad in that directory
//
// Disabling API authenication to avoid failures due to API passwords
// for all the nodes
fmt.Println("== Launching siad")
siaDirArg := fmt.Sprintf("--sia-directory=%v", siaDir)
apiArg := fmt.Sprintf("--authenticate-api=%v", false)
go bash("siad", siaDirArg, apiArg)
// Block until sync'd
fmt.Println("== Waiting for Synced")
client := client.New("localhost:9980")
for {
time.Sleep(100 * time.Millisecond)
cg, err := client.ConsensusGet()
if err != nil {
continue
}
if cg.Synced {
break
}
}
// Initialize new Wallet
fmt.Println("== Initializing Wallet")
wip, err := client.WalletInitPost("", false)
if err != nil {
panic(err)
}
// Save wallet seed to file
fmt.Println("== Saving Seed to file")
_, err = sf.WriteString(wip.PrimarySeed)
if err != nil {
panic(err)
}
err = sf.Sync()
if err != nil {
panic(err)
}
// Display seed for reference
fmt.Println(" Seed:")
bash("cat", seedFile)
// Unlock Wallet
fmt.Println("== Unlocking wallet")
err = client.WalletUnlockPost(wip.PrimarySeed)
if err != nil {
panic(err)
}
// Get address to send money to
fmt.Println("== Wallet address")
wag, err := client.WalletAddressGet()
if err != nil {
panic(err)
}
fmt.Println(" Wallet Address:", wag.Address)
// TODO - fund siacoin from some source of funds
// Block until siacoin balance is non-zero
fmt.Println("== Waiting for Siacoins to appear in Wallet")
wg, err := client.WalletGet()
if err != nil {
panic(err)
}
for wg.ConfirmedSiacoinBalance.Cmp(types.ZeroCurrency) == 0 {
time.Sleep(100 * time.Millisecond)
wg, err = client.WalletGet()
if err != nil {
panic(err)
}
}
// Set allowance
fmt.Println("== Setting Allowance")
allowance := modules.Allowance{
Funds: types.SiacoinPrecision.Mul64(1000),
Period: types.BlockHeight(3 * types.BlocksPerMonth),
Hosts: uint64(50),
RenewWindow: types.BlockHeight(types.BlocksPerMonth),
ExpectedStorage: 1e12,
ExpectedUpload: uint64(200e9), // types.BlocksPerMonth,
ExpectedDownload: uint64(100e9), // types.BlocksPerMonth,
ExpectedRedundancy: 3.0,
}
err = client.RenterPostAllowance(allowance)
if err != nil {
panic(err)
}
// Wait for Contracts
fmt.Println("== Waiting for Contracts")
rc, err := client.RenterContractsGet()
if err != nil {
panic(err)
}
// Wait for at least 30 so that on start up the renter should be able to
// fully upload a file.
for len(rc.Contracts) < 30 {
time.Sleep(5 * time.Second)
rc, err = client.RenterContractsGet()
if err != nil {
panic(err)
}
}
// Shut Down Node
fmt.Println("== Shutting down siad")
bash("siac", "stop")
// Copy to USB
fmt.Println("== Copying to USB")
bash("cp -a", siaDir, usb)
// Delete original directory
fmt.Println("== Deleting Original Directory")
bash("rm", "-rf", siaDir)
// Signal that node copy is done and how long it took
fmt.Println("Done with Node", nodeNum)
fmt.Println("Node Copy took", time.Since(timeNode))
}
fmt.Println("Total Node Copy time:", time.Since(timeTotalStart))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment