@ -1,7 +1,6 @@ | |||||
*.swp | *.swp | ||||
*.swo | *.swo | ||||
.bak | .bak | ||||
tendermint | |||||
debora | |||||
.DS_Store | .DS_Store | ||||
build/* | |||||
rpc/test/.tendermint | rpc/test/.tendermint |
@ -0,0 +1,7 @@ | |||||
package main | |||||
import ( | |||||
"github.com/tendermint/tendermint/logger" | |||||
) | |||||
var log = logger.New("module", "main") |
@ -0,0 +1,127 @@ | |||||
package main | |||||
import ( | |||||
"fmt" | |||||
"io/ioutil" | |||||
"os" | |||||
"sync" | |||||
acm "github.com/tendermint/tendermint/account" | |||||
"github.com/tendermint/tendermint/binary" | |||||
. "github.com/tendermint/tendermint/common" | |||||
pcm "github.com/tendermint/tendermint/process" | |||||
rpc "github.com/tendermint/tendermint/rpc" | |||||
) | |||||
var Routes = map[string]*rpc.RPCFunc{ | |||||
"RunProcess": rpc.NewRPCFunc(RunProcess, []string{"wait", "label", "execPath", "args"}), | |||||
"ListProcesses": rpc.NewRPCFunc(ListProcesses, []string{}), | |||||
"StopProcess": rpc.NewRPCFunc(StopProcess, []string{"label", "kill"}), | |||||
} | |||||
type Validator struct { | |||||
VotingPower uint64 | |||||
PubKey acm.PubKey | |||||
} | |||||
type Options struct { | |||||
Validators []Validator | |||||
ListenAddress string | |||||
} | |||||
// Global instance | |||||
var debora = struct { | |||||
mtx sync.Mutex | |||||
processes map[string]*pcm.Process | |||||
}{sync.Mutex{}, make(map[string]*pcm.Process)} | |||||
func main() { | |||||
// read options from stdin. | |||||
var err error | |||||
optionsBytes, err := ioutil.ReadAll(os.Stdin) | |||||
if err != nil { | |||||
panic(Fmt("Error reading input: %v", err)) | |||||
} | |||||
options := binary.ReadJSON(&Options{}, optionsBytes, &err).(*Options) | |||||
if err != nil { | |||||
panic(Fmt("Error parsing input: %v", err)) | |||||
} | |||||
// Debug. | |||||
fmt.Printf("Validators: %v\n", options.Validators) | |||||
// start rpc server. | |||||
fmt.Println("Listening HTTP-JSONRPC on", options.ListenAddress) | |||||
rpc.StartHTTPServer(options.ListenAddress, Routes, nil) | |||||
TrapSignal(func() { | |||||
fmt.Println("Debora shutting down") | |||||
}) | |||||
} | |||||
//------------------------------------------------------------------------------ | |||||
// RPC functions | |||||
type ResponseRunProcess struct { | |||||
} | |||||
func RunProcess(wait bool, label string, execPath string, args []string) (*ResponseRunProcess, error) { | |||||
debora.mtx.Lock() | |||||
// First, see if there already is a process labeled 'label' | |||||
existing := debora.processes[label] | |||||
if existing != nil { | |||||
debora.mtx.Unlock() | |||||
return nil, Errorf("Process already exists: %v", label) | |||||
} | |||||
// Otherwise, create one. | |||||
proc := pcm.Create(pcm.ProcessModeDaemon, label, execPath, args...) | |||||
debora.processes[label] = proc | |||||
debora.mtx.Unlock() | |||||
if wait { | |||||
exitErr := pcm.Wait(proc) | |||||
return nil, exitErr | |||||
} else { | |||||
return &ResponseRunProcess{}, nil | |||||
} | |||||
} | |||||
//-------------------------------------- | |||||
type ResponseListProcesses struct { | |||||
Processes []*pcm.Process | |||||
} | |||||
func ListProcesses() (*ResponseListProcesses, error) { | |||||
var procs = []*pcm.Process{} | |||||
debora.mtx.Lock() | |||||
for _, proc := range debora.processes { | |||||
procs = append(procs, proc) | |||||
} | |||||
debora.mtx.Unlock() | |||||
return &ResponseListProcesses{ | |||||
Processes: procs, | |||||
}, nil | |||||
} | |||||
//-------------------------------------- | |||||
type ResponseStopProcess struct { | |||||
} | |||||
func StopProcess(label string, kill bool) (*ResponseStopProcess, error) { | |||||
debora.mtx.Lock() | |||||
proc := debora.processes[label] | |||||
debora.mtx.Unlock() | |||||
if proc == nil { | |||||
return nil, Errorf("Process does not exist: %v", label) | |||||
} | |||||
err := pcm.Stop(proc, kill) | |||||
return &ResponseStopProcess{}, err | |||||
} |
@ -0,0 +1,9 @@ | |||||
{ | |||||
"ListenAddress": "0.0.0.0:8082", | |||||
"Validators": [ | |||||
{ | |||||
"VotingPower": 1, | |||||
"PubKey": [1,"3A2C5C341FFC1D5F7AB518519FF8289D3BFAB82DFD6E167B926FAD72C1BF10F8"] | |||||
} | |||||
] | |||||
} |
@ -0,0 +1,20 @@ | |||||
package main | |||||
import ( | |||||
"fmt" | |||||
"github.com/tendermint/tendermint/account" | |||||
"github.com/tendermint/tendermint/binary" | |||||
) | |||||
func gen_account() { | |||||
privAccount := account.GenPrivAccount() | |||||
privAccountJSONBytes := binary.JSONBytes(privAccount) | |||||
fmt.Printf(`Generated a new account! | |||||
%v | |||||
`, | |||||
string(privAccountJSONBytes), | |||||
) | |||||
} |
@ -0,0 +1,115 @@ | |||||
package main | |||||
import ( | |||||
"bufio" | |||||
"bytes" | |||||
"encoding/hex" | |||||
"fmt" | |||||
"os" | |||||
"strconv" | |||||
"github.com/tendermint/tendermint/account" | |||||
"github.com/tendermint/tendermint/binary" | |||||
. "github.com/tendermint/tendermint/common" | |||||
dbm "github.com/tendermint/tendermint/db" | |||||
sm "github.com/tendermint/tendermint/state" | |||||
"github.com/tendermint/tendermint/types" | |||||
) | |||||
func getString(prompt string) string { | |||||
reader := bufio.NewReader(os.Stdin) | |||||
fmt.Print(prompt) | |||||
input, _ := reader.ReadString('\n') | |||||
return input[:len(input)-1] | |||||
} | |||||
func getByteSliceFromHex(prompt string) []byte { | |||||
input := getString(prompt) | |||||
bytes, err := hex.DecodeString(input) | |||||
if err != nil { | |||||
Exit(Fmt("Not in hex format: %v\nError: %v\n", input, err)) | |||||
} | |||||
return bytes | |||||
} | |||||
func getUint64(prompt string) uint64 { | |||||
input := getString(prompt) | |||||
i, err := strconv.Atoi(input) | |||||
if err != nil { | |||||
Exit(Fmt("Not a valid uint64 amount: %v\nError: %v\n", input, err)) | |||||
} | |||||
return uint64(i) | |||||
} | |||||
func gen_tx() { | |||||
// Get State, which may be nil. | |||||
stateDB := dbm.GetDB("state") | |||||
state := sm.LoadState(stateDB) | |||||
// Get source pubkey | |||||
srcPubKeyBytes := getByteSliceFromHex("Enter source pubkey: ") | |||||
r, n, err := bytes.NewReader(srcPubKeyBytes), new(int64), new(error) | |||||
srcPubKey := binary.ReadBinary(struct{ account.PubKey }{}, r, n, err).(struct{ account.PubKey }).PubKey | |||||
if *err != nil { | |||||
Exit(Fmt("Invalid PubKey. Error: %v", err)) | |||||
} | |||||
// Get the state of the account. | |||||
var srcAccount *account.Account | |||||
var srcAccountAddress = srcPubKey.Address() | |||||
var srcAccountBalanceStr = "unknown" | |||||
var srcAccountSequenceStr = "unknown" | |||||
srcAddress := srcPubKey.Address() | |||||
if state != nil { | |||||
srcAccount = state.GetAccount(srcAddress) | |||||
srcAccountBalanceStr = Fmt("%v", srcAccount.Balance) | |||||
srcAccountSequenceStr = Fmt("%v", srcAccount.Sequence+1) | |||||
} | |||||
// Get the amount to send from src account | |||||
srcSendAmount := getUint64(Fmt("Enter amount to send from %X (total: %v): ", srcAccountAddress, srcAccountBalanceStr)) | |||||
// Get the next sequence of src account | |||||
srcSendSequence := uint(getUint64(Fmt("Enter next sequence for %X (guess: %v): ", srcAccountAddress, srcAccountSequenceStr))) | |||||
// Get dest address | |||||
dstAddress := getByteSliceFromHex("Enter destination address: ") | |||||
// Get the amount to send to dst account | |||||
dstSendAmount := getUint64(Fmt("Enter amount to send to %X: ", dstAddress)) | |||||
// Construct SendTx | |||||
tx := &types.SendTx{ | |||||
Inputs: []*types.TxInput{ | |||||
&types.TxInput{ | |||||
Address: srcAddress, | |||||
Amount: srcSendAmount, | |||||
Sequence: srcSendSequence, | |||||
Signature: account.SignatureEd25519{}, | |||||
PubKey: srcPubKey, | |||||
}, | |||||
}, | |||||
Outputs: []*types.TxOutput{ | |||||
&types.TxOutput{ | |||||
Address: dstAddress, | |||||
Amount: dstSendAmount, | |||||
}, | |||||
}, | |||||
} | |||||
// Show the intermediate form. | |||||
fmt.Printf("Generated tx: %X\n", binary.BinaryBytes(tx)) | |||||
// Get source privkey (for signing) | |||||
srcPrivKeyBytes := getByteSliceFromHex("Enter source privkey (for signing): ") | |||||
r, n, err = bytes.NewReader(srcPrivKeyBytes), new(int64), new(error) | |||||
srcPrivKey := binary.ReadBinary(struct{ account.PrivKey }{}, r, n, err).(struct{ account.PrivKey }).PrivKey | |||||
if *err != nil { | |||||
Exit(Fmt("Invalid PrivKey. Error: %v", err)) | |||||
} | |||||
// Sign | |||||
tx.Inputs[0].Signature = srcPrivKey.Sign(account.SignBytes(tx)) | |||||
fmt.Printf("Signed tx: %X\n", binary.BinaryBytes(tx)) | |||||
} |
@ -0,0 +1,24 @@ | |||||
package main | |||||
import ( | |||||
"fmt" | |||||
"github.com/tendermint/tendermint/binary" | |||||
"github.com/tendermint/tendermint/config" | |||||
sm "github.com/tendermint/tendermint/state" | |||||
) | |||||
func gen_validator() { | |||||
privValidator := sm.GenPrivValidator() | |||||
privValidatorJSONBytes := binary.JSONBytes(privValidator) | |||||
fmt.Printf(`Generated a new validator! | |||||
Paste the following JSON into your %v file | |||||
%v | |||||
`, | |||||
config.App().GetString("PrivValidatorFile"), | |||||
string(privValidatorJSONBytes), | |||||
) | |||||
} |
@ -0,0 +1,7 @@ | |||||
package main | |||||
import ( | |||||
"github.com/tendermint/tendermint/logger" | |||||
) | |||||
var log = logger.New("module", "main") |
@ -0,0 +1,46 @@ | |||||
package main | |||||
import ( | |||||
"fmt" | |||||
"os" | |||||
"github.com/tendermint/tendermint/config" | |||||
"github.com/tendermint/tendermint/logger" | |||||
"github.com/tendermint/tendermint/node" | |||||
) | |||||
func main() { | |||||
args := os.Args[1:] | |||||
if len(args) == 0 { | |||||
fmt.Println(`Tendermint | |||||
Commands: | |||||
node Run the tendermint node | |||||
gen_account Generate new account keypair | |||||
gen_validator Generate new validator keypair | |||||
gen_tx Generate new transaction | |||||
probe_upnp Test UPnP functionality | |||||
`) | |||||
return | |||||
} | |||||
switch args[0] { | |||||
case "node": | |||||
config.ParseFlags(args[1:]) | |||||
logger.Reset() | |||||
node.RunNode() | |||||
case "gen_account": | |||||
gen_account() | |||||
case "gen_validator": | |||||
gen_validator() | |||||
case "gen_tx": | |||||
config.ParseFlags(args[1:]) | |||||
logger.Reset() | |||||
gen_tx() | |||||
case "probe_upnp": | |||||
probe_upnp() | |||||
default: | |||||
fmt.Printf("Unknown command %v\n", args[0]) | |||||
} | |||||
} |
@ -0,0 +1,24 @@ | |||||
package main | |||||
import ( | |||||
"encoding/json" | |||||
"fmt" | |||||
"github.com/tendermint/tendermint/p2p/upnp" | |||||
) | |||||
func probe_upnp() { | |||||
capabilities, err := upnp.Probe() | |||||
if err != nil { | |||||
fmt.Println("Probe failed: %v", err) | |||||
} else { | |||||
fmt.Println("Probe success!") | |||||
jsonBytes, err := json.Marshal(capabilities) | |||||
if err != nil { | |||||
panic(err) | |||||
} | |||||
fmt.Println(string(jsonBytes)) | |||||
} | |||||
} |