// Allows us to scatter transactions across all nodes. // func rotateWSAPI(rotate *int, value int, wsapiNode *int) { for *rotate == value { // Only if true *wsapiNode = rand.Int() % len(fnodes) fnode := fnodes[*wsapiNode] wsapi.SetState(fnode.State) time.Sleep(3 * time.Second) } }
func SimControl(listenTo int) { var _ = time.Sleep var summary int var watchPL int var watchMessages int var rotate int var wsapiNode int var faulting bool for { l := make([]byte, 100) var err error // When running as a detatched process, this routine becomes a very tight loop and starves other goroutines. // So, we will sleep before letting it check to see if Stdin has been reconnected if _, err = os.Stdin.Read(l); err != nil { time.Sleep(2 * time.Second) continue } // This splits up the command at anycodepoint that is not a letter, number of punctuation, so usually by spaces. parseFunc := func(c rune) bool { return !unicode.IsLetter(c) && !unicode.IsNumber(c) && !unicode.IsPunct(c) } // cmd is not a list of the parameters, much like command line args show up in args[] cmd := strings.FieldsFunc(string(l), parseFunc) if 0 == len(cmd) { cmd = []string{"h"} } b := string(cmd[0]) v, err := strconv.Atoi(string(b)) if err == nil && v >= 0 && v < len(fnodes) && fnodes[listenTo].State != nil { listenTo = v os.Stderr.WriteString(fmt.Sprintf("Switching to Node %d\n", listenTo)) // Update which node will be displayed on the controlPanel page connectionMetricsChannel := make(chan interface{}, p2p.StandardChannelSize) go controlPanel.ServeControlPanel(fnodes[listenTo].State.ControlPanelChannel, fnodes[listenTo].State, connectionMetricsChannel, p2pNetwork, Build) } else { // fmt.Printf("Parsing command, found %d elements. The first element is: %+v / %s \n Full command: %+v\n", len(cmd), b[0], string(b), cmd) switch { case '!' == b[0]: if listenTo < 0 || listenTo > len(fnodes) { break } s := fnodes[listenTo].State os.Stderr.WriteString("Reset Node: " + s.FactomNodeName + "\n") s.Reset() case 'g' == b[0]: if len(b) > 1 { if b[1] == 'c' { copyOver(fnodes[listenTo].State) break } } if listenTo < 0 || listenTo > len(fnodes) { break } wsapiNode = listenTo wsapi.SetState(fnodes[wsapiNode].State) if nextAuthority == -1 { err := fundWallet(fnodes[wsapiNode].State, 2e7) if err != nil { os.Stderr.WriteString(fmt.Sprintf("Error in funding the wallet, %s\n", err.Error())) break } setUpAuthorites(fnodes[wsapiNode].State, true) os.Stderr.WriteString(fmt.Sprintf("%d Authorities added to the stack and funds are in wallet\n", len(authStack))) } if len(b) == 1 { os.Stderr.WriteString(fmt.Sprint("Authorities are ready to be made. 'gN' where N is the number to be made.\n")) } if len(b) > 1 { count, err := strconv.Atoi(b[1:]) if err != nil { os.Stderr.WriteString(fmt.Sprintf("Error in input bN, %s\n", err.Error())) } else { if count > 100 { os.Stderr.WriteString(fmt.Sprint("You can only pop a max of 100 off the stack at a time.")) count = 100 } err := fundWallet(fnodes[wsapiNode].State, uint64(count*5e7)) if err != nil { os.Stderr.WriteString(fmt.Sprintf("Error in funding the wallet, %s\n", err.Error())) break } auths, skipped, err := authorityToBlockchain(count, fnodes[wsapiNode].State) if err != nil { os.Stderr.WriteString(fmt.Sprintf("Error making authorites, %s\n", err.Error())) } os.Stderr.WriteString(fmt.Sprintf("=== %d Identities added to blockchain, %d remain in stack, %d skipped (Added by someone else) ===\n", len(auths), len(authStack), skipped)) for _, ele := range auths { fmt.Println(ele.ChainID.String()) } } } case '/' == b[0]: sortByID = !sortByID if sortByID { os.Stderr.WriteString("Sort Status by Chain IDs\n") } else { os.Stderr.WriteString("Sort Status by Node Name\n") } case 'w' == b[0]: if listenTo >= 0 && listenTo < len(fnodes) { wsapiNode = listenTo wsapi.SetState(fnodes[wsapiNode].State) os.Stderr.WriteString(fmt.Sprintf("--Listen to %s --\n", fnodes[wsapiNode].State.FactomNodeName)) } case 's' == b[0]: if len(b) > 1 { ht, err := strconv.Atoi(string(b[1:])) if err != nil { os.Stderr.WriteString("type snnn where nnn is the number of status messages to print\n") break } if listenTo < 0 || listenTo > len(fnodes) { os.Stderr.WriteString("Select a node first\n") break } f := fnodes[listenTo] fmt.Println("-----------------------------", f.State.FactomNodeName, "--------------------------------------", string(b)) l := len(f.State.StatusStrs) if l < ht { ht = l } for i := 0; i < ht; i++ { os.Stderr.WriteString(f.State.StatusStrs[l-1] + "\n") l-- } break } summary++ if summary%2 == 1 { os.Stderr.WriteString("--Print Summary On--\n") go printSummary(&summary, summary, &listenTo, &wsapiNode) } else { os.Stderr.WriteString("--Print Summary Off--\n") } case 'p' == b[0]: if len(b) > 1 { ht, err := strconv.Atoi(string(b[1:])) if err != nil { os.Stderr.WriteString("Dump Process List with pn where n = blockheight, i.e. 'p10'") break } if listenTo < 0 || listenTo > len(fnodes) { os.Stderr.WriteString("Select a node first") break } f := fnodes[listenTo] pl := f.State.ProcessLists.Get(uint32(ht)) if pl == nil { os.Stderr.WriteString("No Process List found") } else { fmt.Println("-----------------------------", f.State.FactomNodeName, "--------------------------------------", string(b)) fmt.Println(pl.String()) } break } watchPL++ if watchPL%2 == 1 { os.Stderr.WriteString("--Print Process Lists On--\n") go printProcessList(&watchPL, watchPL, &listenTo) } else { os.Stderr.WriteString("--Print Process Lists Off--\n") } case 'r' == b[0]: rotate++ if rotate%2 == 1 { os.Stderr.WriteString("--Rotate the WSAPI around the nodes--\n") go rotateWSAPI(&rotate, rotate, &wsapiNode) } else { os.Stderr.WriteString("--Stop Rotation of the WSAPI around the nodes. Now --\n") wsapi.SetState(fnodes[wsapiNode].State) } case 'a' == b[0]: mLog.all = false for _, fnode := range fnodes { fnode.State.SetOut(false) } if listenTo < 0 || listenTo > len(fnodes) { fmt.Println("Select a node first") break } f := fnodes[listenTo] fmt.Println("-----------------------------", f.State.FactomNodeName, "--------------------------------------", string(b[:len(b)])) if len(b) < 2 { break } ht, err := strconv.Atoi(string(b[1:])) if err != nil { fmt.Println(err, "Dump Adminblock block with an where n = blockheight, i.e. 'a10'") } else { msg, err := f.State.LoadDBState(uint32(ht)) if err == nil && msg != nil { dsmsg := msg.(*messages.DBStateMsg) ABlock := dsmsg.AdminBlock fmt.Println(ABlock.String()) } else { pl := f.State.ProcessLists.Get(uint32(ht)) if pl == nil || pl.AdminBlock == nil { fmt.Println("Could not find this Admin block") } else { fmt.Printf(pl.AdminBlock.String()) } } } case 'e' == b[0]: mLog.all = false for _, fnode := range fnodes { fnode.State.SetOut(false) } if listenTo < 0 || listenTo > len(fnodes) { fmt.Println("Select a node first") break } f := fnodes[listenTo] fmt.Println("-----------------------------", f.State.FactomNodeName, "--------------------------------------", string(b[:len(b)])) if len(b) < 2 { break } ht, err := strconv.Atoi(string(b[1:])) if err != nil { fmt.Println(err, "Dump Entry Credit block with fn where n = blockheight, i.e. 'e10'") } else { msg, err := f.State.LoadDBState(uint32(ht)) if err == nil && msg != nil { dsmsg := msg.(*messages.DBStateMsg) ECBlock := dsmsg.EntryCreditBlock fmt.Printf(ECBlock.String()) } else { pl := f.State.ProcessLists.Get(uint32(ht)) if pl == nil || pl.EntryCreditBlock == nil { fmt.Println("Could not find this Entry Credit Block") } else { fmt.Printf(pl.EntryCreditBlock.String()) } } } case 'f' == b[0]: mLog.all = false for _, fnode := range fnodes { fnode.State.SetOut(false) } if listenTo < 0 || listenTo > len(fnodes) { fmt.Println("Select a node first") break } f := fnodes[listenTo] fmt.Println("-----------------------------", f.State.FactomNodeName, "--------------------------------------", string(b[:len(b)])) if len(b) < 2 { break } ht, err := strconv.Atoi(string(b[1:])) if err != nil { fmt.Println(err, "Dump Factoid block with fn where n = blockheight, i.e. 'f10'") } else { msg, err := f.State.LoadDBState(uint32(ht)) if err == nil && msg != nil { dsmsg := msg.(*messages.DBStateMsg) FBlock := dsmsg.FactoidBlock fmt.Printf(FBlock.String()) } else { dbstate := f.State.DBStates.Get(ht) if dbstate == nil || dbstate.FactoidBlock == nil { fmt.Println("Could not find this Factoid block") } else { fmt.Printf(dbstate.FactoidBlock.String()) } } } case 'd' == b[0]: mLog.all = false for _, fnode := range fnodes { fnode.State.SetOut(false) } if listenTo < 0 || listenTo > len(fnodes) { fmt.Println("Select a node first") break } f := fnodes[listenTo] fmt.Println("-----------------------------", f.State.FactomNodeName, "--------------------------------------", string(b[:len(b)])) if len(b) < 2 { break } ht, err := strconv.Atoi(string(b[1:])) if err != nil { fmt.Println(err, "Dump Directory block with dn where n = blockheight, i.e. 'd10'") } else { msg, err := f.State.LoadDBState(uint32(ht)) if err == nil && msg != nil { dsmsg := msg.(*messages.DBStateMsg) DBlock := dsmsg.DirectoryBlock fmt.Printf(DBlock.String()) } else { pl := f.State.ProcessLists.Get(uint32(ht)) if pl == nil || pl.DirectoryBlock == nil { fmt.Println("Could not find this directory block") } else { fmt.Printf(pl.DirectoryBlock.String()) } } } case 'v' == b[0]: if verboseFaultOutput { verboseFaultOutput = false os.Stderr.WriteString("Vnnn Set full fault timeout to the given number of seconds. Helps debugging.\n") } else { verboseFaultOutput = true os.Stderr.WriteString("--VerboseFaultOutput On--\n") } case 'V' == b[0]: if len(b) == 1 { os.Stderr.WriteString("Vnnn -- Set the timeout for faulting a server to nnn seconds\n") os.Stderr.WriteString("Vt -- Start an automated Faulting Test, or stop a running Faulting Test\n") os.Stderr.WriteString("VL -- Display all the authority sets in the Status update\n") os.Stderr.WriteString("Vr -- Reset all nodes in the simulation\n") break } if b[1] == 't' { faulting = !faulting if faulting { os.Stderr.WriteString("Start Faulting Test\n") go faultTest(&faulting) } else { os.Stderr.WriteString("Stop Faulting Test\n") } break } // Reset Everything if b[1] == 'r' { os.Stderr.WriteString("Reset all nodes in the simulation!\n") for _, f := range fnodes { f.State.Reset() } break } if b[1] == 'l' || b[1] == 'L' { if verboseAuthoritySet { verboseAuthoritySet = false os.Stderr.WriteString("--VerboseAuthoritySet Off--\n") } else { verboseAuthoritySet = true os.Stderr.WriteString("--VerboseAuthoritySet On--\n") } break } if b[1] == 'd' || b[1] == 'D' { if verboseAuthorityDeltas { verboseAuthorityDeltas = false os.Stderr.WriteString("--VerboseAuthorityDeltas Off--\n") } else { verboseAuthorityDeltas = true os.Stderr.WriteString("--VerboseAuthorityDeltas On--\n") } break } nnn, err := strconv.Atoi(string(b[1:])) if err != nil || nnn < 0 || nnn > 99 { os.Stderr.WriteString("Specifiy a FaultTimeout between 0 and 100\n") break } for _, fn := range fnodes { fn.State.FaultTimeout = nnn os.Stderr.WriteString(fmt.Sprintf("Setting FaultTimeout of %10s to %d\n", fn.State.FactomNodeName, nnn)) } case 'k' == b[0]: mLog.all = false for _, fnode := range fnodes { fnode.State.SetOut(false) } if listenTo < 0 || listenTo > len(fnodes) { fmt.Println("Select a node first") break } f := fnodes[listenTo] fmt.Println("-----------------------------", f.State.FactomNodeName, "--------------------------------------", string(b)) if len(b) < 2 { fmt.Println("No Parms found.") break } parms := strings.Split(string(b[1:]), ".") if len(parms) >= 2 { os.Stderr.WriteString("Print Entry String with: k<db #>.<entry #>\n") } db, err1 := strconv.Atoi(string(parms[0])) entry, err2 := strconv.Atoi(string(parms[1])) if err1 != nil || err2 != nil { os.Stderr.WriteString("Bad Parameters") } else { msg, err := f.State.LoadDBState(uint32(db)) if err == nil && msg != nil { dsmsg := msg.(*messages.DBStateMsg) DBlock := dsmsg.DirectoryBlock entries := DBlock.GetDBEntries() if entry < len(entries) && entry >= 0 { fmt.Println(fmt.Sprintf("Looking for EB with KeyMR %x", entries[entry].GetKeyMR().Bytes())) eb1, _ := f.State.DB.FetchEBlockHead(entries[entry].GetChainID()) if eb1 != nil { fmt.Println("Chain Head:") fmt.Println(eb1.String()) } eb2, _ := f.State.DB.FetchEBlock(entries[entry].GetKeyMR()) if eb2 != nil { fmt.Println("Entry Block:") fmt.Println(eb2.String()) } else { fmt.Println("No Entry Block Found") } } } else { fmt.Println("Error: ", err, msg) } } case 'x' == b[0]: if listenTo >= 0 && listenTo < len(fnodes) { f := fnodes[listenTo] v := f.State.GetNetStateOff() if v { os.Stderr.WriteString("Bring " + f.State.FactomNodeName + " Back onto the network\n") } else { os.Stderr.WriteString("Take " + f.State.FactomNodeName + " off the network\n") } f.State.SetNetStateOff(!v) } case 'y' == b[0]: if listenTo >= 0 && listenTo < len(fnodes) { f := fnodes[listenTo] fmt.Println("Holding:") for k := range f.State.Holding { fmt.Println(f.State.Holding[k].String()) } } case 'm' == b[0]: watchMessages++ if watchMessages%2 == 1 { os.Stderr.WriteString("--Print Messages On--\n") go printMessages(&watchMessages, watchMessages, &listenTo) } else { os.Stderr.WriteString("--Print Messages Off--\n") } case 'z' == b[0]: // Add Audit server, Remove server, and Add Leader fall through to 'n', switch to next node. if len(b) > 1 && b[1] == 'a' { msg := messages.NewRemoveServerMsg(fnodes[listenTo].State, fnodes[listenTo].State.IdentityChainID, 1) fnodes[listenTo].State.InMsgQueue() <- msg os.Stderr.WriteString(fmt.Sprintln("Attempting to remove", fnodes[listenTo].State.GetFactomNodeName(), "as a server")) } else { msg := messages.NewRemoveServerMsg(fnodes[listenTo].State, fnodes[listenTo].State.IdentityChainID, 0) fnodes[listenTo].State.InMsgQueue() <- msg os.Stderr.WriteString(fmt.Sprintln("Attempting to remove", fnodes[listenTo].State.GetFactomNodeName(), "as a server")) } fallthrough case 'o' == b[0]: // Add Audit server and Add Leader fall through to 'n', switch to next node. if b[0] == 'o' { // (Don't do anything if just passing along the remove server) if len(b) > 1 && b[1] == 'n' { index := 0 for index < len(authKeyLibrary) { if authKeyLibrary[index].Taken == false { authKeyLibrary[index].Taken = true fnodes[listenTo].State.IdentityChainID = authKeyLibrary[index].ChainID key, pKey, _ := authKeyLookup(fnodes[listenTo].State.IdentityChainID) fnodes[listenTo].State.LocalServerPrivKey = key fnodes[listenTo].State.SimSetNewKeys(pKey) os.Stderr.WriteString(fmt.Sprintf("Identity of " + fnodes[listenTo].State.GetFactomNodeName() + " changed to [" + authKeyLibrary[index].ChainID.String()[:10] + "]\n")) break } index++ } } msg := messages.NewAddServerMsg(fnodes[listenTo].State, 1) fnodes[listenTo].State.InMsgQueue() <- msg os.Stderr.WriteString(fmt.Sprintln("Attempting to make", fnodes[listenTo].State.GetFactomNodeName(), "a Audit Server")) } fallthrough case 'l' == b[0]: // Add Audit server, Remove server, and Add Leader fall through to 'n', switch to next node. if b[0] == 'l' { // (Don't do anything if just passing along the audit server) feds := fnodes[listenTo].State.LeaderPL.FedServers exists := false for _, fed := range feds { if fed.GetChainID().IsSameAs(fnodes[listenTo].State.IdentityChainID) { exists = true } } if len(b) > 1 && b[1] == 't' && fnodes[listenTo].State.IdentityChainID.String()[:6] != "888888" && !exists { index := 0 for index < len(authKeyLibrary) { if authKeyLibrary[index].Taken == false { authKeyLibrary[index].Taken = true fnodes[listenTo].State.IdentityChainID = authKeyLibrary[index].ChainID key, pKey, _ := authKeyLookup(fnodes[listenTo].State.IdentityChainID) fnodes[listenTo].State.LocalServerPrivKey = key fnodes[listenTo].State.SimSetNewKeys(pKey) os.Stderr.WriteString(fmt.Sprintf("Identity of " + fnodes[listenTo].State.GetFactomNodeName() + " changed to [" + authKeyLibrary[index].ChainID.String()[:10] + "]\n")) break } index++ } if index >= len(authKeyLibrary) { os.Stderr.WriteString(fmt.Sprint("Did not make a leader, ran out of identities. Type 'g1' for one more identity.\n")) break } } msg := messages.NewAddServerMsg(fnodes[listenTo].State, 0) fnodes[listenTo].State.InMsgQueue() <- msg os.Stderr.WriteString(fmt.Sprintln("Attempting to make", fnodes[listenTo].State.GetFactomNodeName(), "a Leader")) } fallthrough case 'n' == b[0]: fnodes[listenTo].State.SetOut(false) listenTo++ if listenTo >= len(fnodes) { listenTo = 0 } fnodes[listenTo].State.SetOut(true) os.Stderr.WriteString(fmt.Sprint("\r\nSwitching to Node ", listenTo, "\r\n")) case 'c' == b[0]: c := !fnodes[0].State.DebugConsensus for _, n := range fnodes { n.State.DebugConsensus = fnodes[0].State.DebugConsensus } if c { os.Stderr.WriteString(fmt.Sprint("\r\nTrace Consensus\n")) } else { os.Stderr.WriteString(fmt.Sprint("\r\nTurn off Consensus Trace \n")) } for _, f := range fnodes { f.State.DebugConsensus = c } case 'i' == b[0]: show := 0 amt := -1 if len(b) > 1 && (b[1] == 'H' || b[1] == 'h') { os.Stderr.WriteString("------------------------ Identity Commands --------------------------------\n") os.Stderr.WriteString("iH -Show this help\n") os.Stderr.WriteString("gN -Adds 'N' identities to your identity pool from the identity stack. Cannot add \n") os.Stderr.WriteString(" identities that another instance of Factomd has added to their identity pool.\n") os.Stderr.WriteString(" Each Factomd instance has its own identity pool it can use (t), but everyone\n") os.Stderr.WriteString(" will share the identities in the identity stack. This stack is fixed and will\n") os.Stderr.WriteString(" be the same each time Factomd launches. It may grow in the future. Used for testing\n") os.Stderr.WriteString("tN -Attaches Nth identity in pool(0 indexed) to current node. If that identity is taken, \n") os.Stderr.WriteString(" will grab the next available identity in the local identity pool. Can also just type \n") os.Stderr.WriteString(" 't' and it will grab the next available identity.\n") os.Stderr.WriteString("tm -Shows the current node's identity information. \n") os.Stderr.WriteString("tc -Changes the current node's signing key. \n") os.Stderr.WriteString("t[CHAINID] -Attaches the identity associated with the root chainID given to current node \n") os.Stderr.WriteString("u Shows the authorities being monitored for change.\n") os.Stderr.WriteString("i Shows the identities being monitored for change.\n") os.Stderr.WriteString("i[t/m/b/a][N] Shows only the Chains, Mhash, block signing key, or anchor key up to the Nth identity\n") os.Stderr.WriteString("isN Shows only Nth identity\n") os.Stderr.WriteString("-------------------------------------------------------------------------------\n\n") } else { if len(b) > 1 { if b[1] == 't' { show = 1 } else if b[1] == 'm' { show = 2 } else if b[1] == 'b' { show = 3 } else if b[1] == 'a' { show = 4 } if len(b) > 2 { amt, err = strconv.Atoi(b[2:]) if b[1] == 's' { show = 5 } else if err == nil { } else { show = 0 amt = -1 } } } if amt == -1 { os.Stderr.WriteString(fmt.Sprintf("=== Identity List === Total: %d Displaying: All\n", len(fnodes[listenTo].State.Identities))) } else if show == 5 { os.Stderr.WriteString(fmt.Sprintf("=== Identity List === Total: %d Displaying Only: %d\n", len(fnodes[listenTo].State.Identities), amt)) } else { os.Stderr.WriteString(fmt.Sprintf("=== Identity List === Total: %d Displaying: %d\n", len(fnodes[listenTo].State.Identities), amt)) } for c, i := range fnodes[listenTo].State.Identities { if amt != -1 && c == amt+1 { break } stat := returnStatString(i.Status) if show == 5 { if c != amt { } else { os.Stderr.WriteString(fmt.Sprint("-----------------------------------Identity: ", amt, "---------------------------------------\n")) } } else { os.Stderr.WriteString(fmt.Sprint("-----------------------------------Identity: ", c, "---------------------------------------\n")) } if show == 0 || show == 5 { if show == 0 || c == amt { os.Stderr.WriteString(fmt.Sprint("Server Status: ", stat, "\n")) os.Stderr.WriteString(fmt.Sprint("Identity Chain: ", i.IdentityChainID, "\n")) os.Stderr.WriteString(fmt.Sprint("Management Chain: ", i.ManagementChainID, "\n")) os.Stderr.WriteString(fmt.Sprint("Matryoshka Hash: ", i.MatryoshkaHash, "\n")) os.Stderr.WriteString(fmt.Sprint("Key 1: ", i.Key1, "\n")) os.Stderr.WriteString(fmt.Sprint("Key 2: ", i.Key2, "\n")) os.Stderr.WriteString(fmt.Sprint("Key 3: ", i.Key3, "\n")) os.Stderr.WriteString(fmt.Sprint("Key 4: ", i.Key4, "\n")) os.Stderr.WriteString(fmt.Sprint("Signing Key: ", i.SigningKey, "\n")) for _, a := range i.AnchorKeys { os.Stderr.WriteString(fmt.Sprintf("Anchor Key: {'%s' L%x T%x K:%x}\n", a.BlockChain, a.KeyLevel, a.KeyType, a.SigningKey)) } } } else if show == 1 { os.Stderr.WriteString(fmt.Sprint("Server Salt: ", fnodes[c].State.Salt.String()[:16], "\n")) os.Stderr.WriteString(fmt.Sprint("Server Status: ", stat, "\n")) os.Stderr.WriteString(fmt.Sprint("Identity Chain: ", i.IdentityChainID, "\n")) os.Stderr.WriteString(fmt.Sprint("Management Chain: ", i.ManagementChainID, "\n")) } else if show == 2 { os.Stderr.WriteString(fmt.Sprint("Server Salt: ", fnodes[c].State.Salt.String()[:16], "\n")) os.Stderr.WriteString(fmt.Sprint("Server Status: ", stat, "\n")) os.Stderr.WriteString(fmt.Sprint("Identity Chain: ", i.IdentityChainID, "\n")) os.Stderr.WriteString(fmt.Sprint("Matryoshka Hash: ", i.MatryoshkaHash, "\n")) } else if show == 3 { os.Stderr.WriteString(fmt.Sprint("Server Salt: ", fnodes[c].State.Salt.String()[:16], "\n")) os.Stderr.WriteString(fmt.Sprint("Server Status: ", stat, "\n")) os.Stderr.WriteString(fmt.Sprint("Identity Chain: ", i.IdentityChainID, "\n")) os.Stderr.WriteString(fmt.Sprint("Signing Key: ", i.SigningKey, "\n")) } else if show == 4 { os.Stderr.WriteString(fmt.Sprint("Server Salt: ", fnodes[c].State.Salt.String()[:16], "\n")) os.Stderr.WriteString(fmt.Sprint("Server Status: ", stat, "\n")) os.Stderr.WriteString(fmt.Sprint("Identity Chain: ", i.IdentityChainID, "\n")) for _, a := range i.AnchorKeys { os.Stderr.WriteString(fmt.Sprintf("Anchor Key: {'%s' L%x T%x K:%x}\n", a.BlockChain, a.KeyLevel, a.KeyType, a.SigningKey)) } } } } case 't' == b[0]: if len(b) == 2 && b[1] == 'm' { _, _, auth := authKeyLookup(fnodes[listenTo].State.IdentityChainID) if auth == nil { break } fullSk := []byte{0x4d, 0xb6, 0xc9} fullSk = append(fullSk[:], auth.Sk1[:32]...) shadSk := shad(fullSk) fullSk = append(fullSk[:], shadSk[:4]...) os.Stderr.WriteString(fmt.Sprint("Identity of Current Node Information\n")) os.Stderr.WriteString(fmt.Sprintf("Server Salt: %s\n", fnodes[listenTo].State.Salt.String()[:16])) os.Stderr.WriteString(fmt.Sprintf("Root Chain ID: %s\n", fnodes[listenTo].State.IdentityChainID.String())) os.Stderr.WriteString(fmt.Sprintf("Sub Chain ID : %s\n", auth.ManageChain)) os.Stderr.WriteString(fmt.Sprintf("Sk1 Key (hex): %x\n", fullSk)) os.Stderr.WriteString(fmt.Sprintf("Signing Key (hex): %s\n", fnodes[listenTo].State.SimGetSigKey())) p := fnodes[listenTo].State.GetServerPrivateKey() str := hex.EncodeToString((p.Key)[:32]) os.Stderr.WriteString(fmt.Sprintf("Private Key (hex): %s\n", str)) break } else if len(b) == 2 && b[1] == 'c' { _, _, auth := authKeyLookup(fnodes[listenTo].State.IdentityChainID) if auth == nil { break } wsapiNode = listenTo wsapi.SetState(fnodes[wsapiNode].State) err := fundWallet(fnodes[listenTo].State, 1e8) if err != nil { os.Stderr.WriteString(fmt.Sprintf("Error in funding the wallet, %s\n", err.Error())) break } newKey, err := changeSigningKey(fnodes[listenTo].State.IdentityChainID, fnodes[listenTo].State) if err != nil { os.Stderr.WriteString(fmt.Sprintf("Error: %s\n", err.Error())) break } fnodes[listenTo].State.LocalServerPrivKey = newKey.PrivateKeyString() fnodes[listenTo].State.SetPendingSigningKey(newKey) os.Stderr.WriteString(fmt.Sprintf("New public key for [%s]: %s\n", fnodes[listenTo].State.IdentityChainID.String()[:8], newKey.Pub.String())) break } index := 0 if len(b) == 65 { hash, err := fnodes[listenTo].State.IdentityChainID.HexToHash(b[1:]) if err != nil { os.Stderr.WriteString(fmt.Sprintf("Error: %s\n", err.Error())) } else { fnodes[listenTo].State.IdentityChainID = hash key, pKey, _ := authKeyLookup(fnodes[listenTo].State.IdentityChainID) if len(key) == 64 { fnodes[listenTo].State.LocalServerPrivKey = key fnodes[listenTo].State.SimSetNewKeys(pKey) } os.Stderr.WriteString(fmt.Sprintf("Identity of " + fnodes[listenTo].State.GetFactomNodeName() + " changed to [" + hash.String()[:10] + "]\n")) } break } else if len(authKeyLibrary) == 0 { os.Stderr.WriteString(fmt.Sprint("There are no available identities in this node. Type 'g1' to claim another identity\n")) break } else if len(b) > 1 { index, err = strconv.Atoi(string(b[1:])) if err != nil { os.Stderr.WriteString(fmt.Sprint("Incorrect input. bN where N is a number\n")) break } } if index >= len(authKeyLibrary) { os.Stderr.WriteString(fmt.Sprintf("Identity index out of bounds, only %d in the list.\n", len(authKeyLibrary))) break } if authKeyLibrary[index].Taken == true { os.Stderr.WriteString(fmt.Sprintf("Identity %d already taken, taking next available identity in list\n", index)) } for index < len(authKeyLibrary) { if authKeyLibrary[index].Taken == false { authKeyLibrary[index].Taken = true fnodes[listenTo].State.IdentityChainID = authKeyLibrary[index].ChainID key, pKey, _ := authKeyLookup(fnodes[listenTo].State.IdentityChainID) fnodes[listenTo].State.LocalServerPrivKey = key fnodes[listenTo].State.SimSetNewKeys(pKey) os.Stderr.WriteString(fmt.Sprintf("Identity of " + fnodes[listenTo].State.GetFactomNodeName() + " changed to [" + authKeyLibrary[index].ChainID.String()[:10] + "]\n")) break } index++ } if index >= len(authKeyLibrary) { os.Stderr.WriteString(fmt.Sprint("There are no more available identities in this node. Type 'g1' to claim another identity\n")) } case 'u' == b[0]: os.Stderr.WriteString(fmt.Sprintf("=== Authority List === Total: %d Displaying: All\n", len(fnodes[listenTo].State.Authorities))) for _, i := range fnodes[listenTo].State.Authorities { os.Stderr.WriteString("-------------------------------------------------------------------------------\n") var stat string switch i.Status { case 0: stat = "Unassigned" case 1: stat = "Federated Server" case 2: stat = "Audit Server" case 3: stat = "Full" case 4: stat = "Pending Federated Server" case 5: stat = "Pending Audit Server" case 6: stat = "Pending Full" case 7: stat = "Pending" } os.Stderr.WriteString(fmt.Sprint("Server Status: ", stat, "\n")) os.Stderr.WriteString(fmt.Sprint("Identity Chain: ", i.AuthorityChainID, "\n")) os.Stderr.WriteString(fmt.Sprint("Management Chain: ", i.ManagementChainID, "\n")) os.Stderr.WriteString(fmt.Sprint("Matryoshka Hash: ", i.MatryoshkaHash, "\n")) os.Stderr.WriteString(fmt.Sprint("Signing Key: ", i.SigningKey.String(), "\n")) for _, a := range i.AnchorKeys { os.Stderr.WriteString(fmt.Sprintf("Anchor Key: {'%s' L%x T%x K:%x}\n", a.BlockChain, a.KeyLevel, a.KeyType, a.SigningKey)) } } case 'q' == b[0]: eHashes := fnodes[listenTo].State.GetPendingEntries() os.Stderr.WriteString("Pending Entry Hash\n") os.Stderr.WriteString("------------------\n") for _, eh := range eHashes { os.Stderr.WriteString(fmt.Sprint(eh.String(), "\n")) } case 'j' == b[0]: fpl := fnodes[listenTo].State.GetPendingTransactions() fmt.Println(fpl) case 'S' == b[0]: nnn, err := strconv.Atoi(string(b[1:])) if err != nil || nnn < 0 || nnn > 999 { os.Stderr.WriteString("Specifiy a drop amount between 0 and 1000\n") break } for _, fn := range fnodes { fn.State.DropRate = nnn os.Stderr.WriteString(fmt.Sprintf("Setting drop rate of %10s to %2d.%01d\n", fn.State.FactomNodeName, nnn/10, nnn%10)) } case 'O' == b[0]: if listenTo < 0 || listenTo > len(fnodes) { os.Stderr.WriteString("No Factom Node selected\n") break } nnn, err := strconv.Atoi(string(b[1:])) if err != nil || nnn < 0 || nnn > 999 { os.Stderr.WriteString("Specifiy a drop amount between 0 and 1000\n") break } fnodes[listenTo].State.DropRate = nnn os.Stderr.WriteString(fmt.Sprintf("Setting drop rate of %10s to %2d.%01d percent\n", fnodes[listenTo].State.FactomNodeName, nnn/10, nnn%10)) case 'F' == b[0]: nn, err := strconv.Atoi(string(b[1:])) nnn := int64(nn) if err != nil || nnn < 0 || nnn > 99999 { os.Stderr.WriteString("Specifiy a delay amount in milliseconds less than 100 seconds\n") break } for _, fn := range fnodes { fn.State.Delay = nnn os.Stderr.WriteString(fmt.Sprintf("Setting Delay on communications from %10s to %2d.%03d Seconds\n", fn.State.FactomNodeName, nnn/1000, nnn%1000)) } for _, f := range fnodes { for _, p := range f.Peers { sim, ok := p.(*SimPeer) if ok { sim.Delay = nnn } } } case 'D' == b[0]: if listenTo < 0 || listenTo > len(fnodes) { os.Stderr.WriteString("No Factom Node selected\n") break } nn, err := strconv.Atoi(string(b[1:])) nnn := int64(nn) if err != nil || nnn < 0 || nnn > 99999 { os.Stderr.WriteString("Specifiy a delay amount in milliseconds less than 100 seconds\n") break } for _, f := range fnodes { for _, p := range f.Peers { sim, ok := p.(*SimPeer) if ok { if sim.FromName == fnodes[listenTo].State.FactomNodeName { sim.Delay = nnn } } } } fnodes[listenTo].State.Delay = nnn os.Stderr.WriteString(fmt.Sprintf("Setting Delay on communications from %10s to %2d.%03d Seconds\n", fnodes[listenTo].State.FactomNodeName, nnn/1000, nnn%1000)) case 'h' == b[0]: os.Stderr.WriteString("-------------------------------------------------------------------------------\n") os.Stderr.WriteString("Vtest Run the fault test. Faults 1 to n/2-1 servers. Waits for next block + 60 sec. Repeats.\n") os.Stderr.WriteString("nnn For some number nnn < the number of nodes: Set focus on that node\n") os.Stderr.WriteString("n increment (with wrap) the node under focus. i.e. if on 1, focus is set to 2\n") os.Stderr.WriteString("Vtest Run the fault test. Faults 1 to n/2-1 servers. Waits for next block + 60 sec. Repeats.\n") os.Stderr.WriteString("aN Show Admin block N. Indicate node eg:\"a5\" to shows blocks for that node.\n") os.Stderr.WriteString("eN Show Entry Credit Block N. Indicate node eg:\"f5\" to shows blocks for that node.\n") os.Stderr.WriteString("fN Show Factoid block N. Indicate node eg:\"f5\" to shows blocks for that node.\n") os.Stderr.WriteString("dN Show Directory block N. Indicate node eg:\"d5\" to shows blocks for that node.\n") os.Stderr.WriteString("kN.M Show Entry Block and Chain Head. N is the directory block, and M is the Entry in that block.\n") os.Stderr.WriteString(" So K3.6 gets the directory block at height 3, and prints the entry at index 6.\n") os.Stderr.WriteString("y Dump what is in the Holding Map. Can crash, but oh well.\n") os.Stderr.WriteString("m Show Messages as they are passed through the simulator.\n") os.Stderr.WriteString("c Trace the Consensus Process\n") os.Stderr.WriteString("s Show the state of all nodes as their state changes in the simulator.\n") os.Stderr.WriteString("p Show the process lists and directory block states as they change.\n") os.Stderr.WriteString("n Change the focus to the next node.\n") os.Stderr.WriteString("l Make focused node the Leader.\n") os.Stderr.WriteString("lt Attach the next available identity to node and make focused node the Leader.\n") os.Stderr.WriteString("z Attempt to remove focused node as a federated server\n") os.Stderr.WriteString("za Attempt to remove focused node as a audit server\n") os.Stderr.WriteString("o Make focused an audit server.\n") os.Stderr.WriteString("x Take the given node out of the netork or bring an offline node back in.\n") os.Stderr.WriteString("w Point the WSAPI to send API calls to the current node.\n") os.Stderr.WriteString("iH To learn about identity control through simulator.\n") os.Stderr.WriteString("gN Adds 'N' identities to your identity pool. (Cannot add identities already taken)\n") os.Stderr.WriteString("tN Attaches Nth identity in pool to current node. Can also just press 't' to grab the next\n") os.Stderr.WriteString("i Shows the identities being monitored for change.\n") os.Stderr.WriteString("u Shows the current Authorities (federated or audit servers)\n") os.Stderr.WriteString("v Verbose Fault Debug Output\n") os.Stderr.WriteString("Vnnn Set full fault timeout to the given number of seconds. Helps debugging.\n") os.Stderr.WriteString("Vtest Run the fault test. Faults 1 to n/2-1 servers. Waits for next block + 60 sec. Repeats.\n") os.Stderr.WriteString("Vreset Reset all fnodes in the simulation.\n") os.Stderr.WriteString("! Reset the current node with the focus (i.e. the 'f' by it)\n") os.Stderr.WriteString("Snnn Set Drop Rate to nnn on everyone\n") os.Stderr.WriteString("Onnn Set Drop Rate to nnn on this node\n") os.Stderr.WriteString("Dnnn Set the Delay on messages from the current node to nnn milliseconds\n") os.Stderr.WriteString("Fnnn Set the Delay on messages from all nodes to nnn milliseconds\n") os.Stderr.WriteString("/ Toggle the sort order between ChainID and Factom Node Name\n") //os.Stderr.WriteString("i[m/b/a][N] Shows only the Mhash, block signing key, or anchor key up to the Nth identity\n") //os.Stderr.WriteString("isN Shows only Nth identity\n") os.Stderr.WriteString("h or <enter> Show help\n") os.Stderr.WriteString("\n") os.Stderr.WriteString("Commands are case sensitive.\n") os.Stderr.WriteString("-------------------------------------------------------------------------------\n\n") default: } } } }