Added genesis file; Added draft of Tendermint tests

This commit is contained in:
Jae Kwon 2016-02-07 22:54:49 -08:00
parent d31a8d8258
commit 436e0ba7d7
7 changed files with 264 additions and 19 deletions

View File

@ -1,4 +1,4 @@
package blackstar
package app
import (
"github.com/tendermint/blackstar/types"
@ -25,18 +25,13 @@ func (app *Blackstar) Info() string {
return "Blackstar v" + version
}
type SetAccount struct {
PubKey crypto.PubKey
Account types.Account
}
func (app *Blackstar) SetOption(key string, value string) (log string) {
if key == "setAccount" {
var err error
var setAccount SetAccount
var setAccount types.PubAccount
wire.ReadJSONPtr(&setAccount, []byte(value), &err)
if err != nil {
return "Error decoding SetAccount message: " + err.Error()
return "Error decoding setAccount message: " + err.Error()
}
pubKeyBytes := wire.BinaryBytes(setAccount.PubKey)
accBytes := wire.BinaryBytes(setAccount.Account)
@ -225,8 +220,8 @@ func allPubKeys(tx types.Tx) (pubKeys []crypto.PubKey) {
}
// Returns accounts in order of types.Tx inputs and outputs
func execTx(tx types.Tx, accMap map[string]types.Account) (accs []types.Account, code tmsp.CodeType, errStr string) {
accs = make([]types.Account, 0, len(tx.Inputs)+len(tx.Outputs))
func execTx(tx types.Tx, accMap map[string]types.PubAccount) (accs []types.PubAccount, code tmsp.CodeType, errStr string) {
accs = make([]types.PubAccount, 0, len(tx.Inputs)+len(tx.Outputs))
// Deduct from inputs
for _, input := range tx.Inputs {
var acc, ok = accMap[input.PubKey.KeyString()]
@ -249,9 +244,11 @@ func execTx(tx types.Tx, accMap map[string]types.Account) (accs []types.Account,
var acc, ok = accMap[output.PubKey.KeyString()]
if !ok {
// Create new account if it doesn't already exist.
acc = types.Account{
PubKey: output.PubKey,
Balance: output.Amount,
acc = types.PubAccount{
PubKey: output.PubKey,
Account: types.Account{
Balance: output.Amount,
},
}
accMap[output.PubKey.KeyString()] = acc
continue
@ -268,9 +265,34 @@ func execTx(tx types.Tx, accMap map[string]types.Account) (accs []types.Account,
//----------------------------------------
func loadAccounts(eyesCli *eyes.MerkleEyesClient, pubKeys []crypto.PubKey) map[string]types.Account {
return nil
func loadAccounts(eyesCli *eyes.MerkleEyesClient, pubKeys []crypto.PubKey) (accMap map[string]types.PubAccount) {
accMap = make(map[string]types.PubAccount, len(pubKeys))
for _, pubKey := range pubKeys {
keyString := pubKey.KeyString()
accBytes, err := eyesCli.GetSync([]byte(keyString))
if err != nil {
panic("Error loading account: " + err.Error())
}
var acc types.PubAccount
err = wire.ReadBinaryBytes(accBytes, &acc)
if err != nil {
panic("Error reading account: " + err.Error())
}
acc.PubKey = pubKey // Set volatile field
accMap[keyString] = acc
}
return
}
func storeAccounts(eyesCli *eyes.MerkleEyesClient, accs []types.Account) {
// NOTE: accs must be stored in deterministic order.
func storeAccounts(eyesCli *eyes.MerkleEyesClient, accs []types.PubAccount) {
for _, acc := range accs {
accBytes := wire.BinaryBytes(acc.Account)
err := eyesCli.SetSync([]byte(acc.PubKey.KeyString()), accBytes)
if err != nil {
panic("Error storing account: " + err.Error())
}
}
}
//----------------------------------------

6
genesis.json Normal file
View File

@ -0,0 +1,6 @@
{"Accounts":[
{
"PubKey":[1,"31F4BF201D3606E33707B098B1EEA7D03A4BB9E9795F0116ED1A038D7B5A6BDE"],
"Account":{"Sequence":0,"Balance":2100000000000000}
}
]}

62
main.go Normal file
View File

@ -0,0 +1,62 @@
package main
import (
"flag"
"fmt"
"github.com/tendermint/blackstar/app"
"github.com/tendermint/blackstar/types"
. "github.com/tendermint/go-common"
"github.com/tendermint/go-wire"
eyes "github.com/tendermint/merkleeyes/client"
"github.com/tendermint/tmsp/server"
)
func main() {
addrPtr := flag.String("address", "tcp://0.0.0.0:46658", "Listen address")
eyesPtr := flag.String("eyes", "tcp://0.0.0.0:46659", "MerkleEyes address")
genPtr := flag.String("genesis", "genesis.json", "Genesis JSON file")
flag.Parse()
// Connect to MerkleEyes
eyesCli, err := eyes.NewMerkleEyesClient(*eyesPtr)
if err != nil {
Exit("connect to MerkleEyes: " + err.Error())
}
// Create BlackStar app
app := app.NewBlackstar(eyesCli)
// Load GenesisState
jsonBytes, err := ReadFile(*genPtr)
if err != nil {
Exit("read genesis: " + err.Error())
}
genesisState := types.GenesisState{}
wire.ReadJSONPtr(&genesisState, jsonBytes, &err)
if err != nil {
Exit("parsing genesis JSON: " + err.Error())
}
for _, account := range genesisState.Accounts {
pubKeyBytes := wire.BinaryBytes(account.PubKey)
accBytes := wire.BinaryBytes(account.Account)
err = eyesCli.SetSync(pubKeyBytes, accBytes)
if err != nil {
Exit("loading genesis accounts: " + err.Error())
}
fmt.Println("Loaded ", account)
}
// Start the listener
_, err = server.StartListener(*addrPtr, app)
if err != nil {
Exit("create listener: " + err.Error())
}
// Wait forever
TrapSignal(func() {
// Cleanup
})
}

47
tests/common.go Normal file
View File

@ -0,0 +1,47 @@
package tests
import (
"github.com/tendermint/blackstar/types"
. "github.com/tendermint/go-common"
"github.com/tendermint/go-crypto"
)
// Creates a PrivAccount from secret.
// The amount is not set.
func PrivAccountFromSecret(secret string) types.PrivAccount {
privKey := crypto.GenPrivKeyEd25519FromSecret(secret)
privAccount := types.PrivAccount{
PrivKey: privKey,
PubKey: privKey.PubKey(),
Account: types.Account{
Sequence: 0,
Balance: 0,
},
}
return privAccount
}
// Make `num` random accounts
func RandAccounts(num int, minAmount uint64, maxAmount uint64) []types.PrivAccount {
privAccs := make([]types.PrivAccount, num)
for i := 0; i < num; i++ {
balance := minAmount
if maxAmount > minAmount {
balance += RandUint64() % (maxAmount - minAmount)
}
privKey := crypto.GenPrivKeyEd25519()
pubKey := privKey.PubKey()
privAccs[i] = types.PrivAccount{
PrivKey: privKey,
PubKey: pubKey,
Account: types.Account{
Sequence: 0,
Balance: balance,
},
}
}
return privAccs
}

Binary file not shown.

96
tests/tendermint/main.go Normal file
View File

@ -0,0 +1,96 @@
package main
import (
"encoding/hex"
"fmt"
"github.com/gorilla/websocket"
"github.com/tendermint/blackstar/tests"
"github.com/tendermint/blackstar/types"
. "github.com/tendermint/go-common"
"github.com/tendermint/go-rpc/client"
"github.com/tendermint/go-rpc/types"
"github.com/tendermint/go-wire"
_ "github.com/tendermint/tendermint/rpc/core/types" // Register RPCResponse > Result types
)
func main() {
ws := rpcclient.NewWSClient("ws://127.0.0.1:46657/websocket")
// ws := rpcclient.NewWSClient("ws://104.236.69.128:46657/websocket")
_, err := ws.Start()
if err != nil {
Exit(err.Error())
}
// Read a bunch of responses
go func() {
for {
res, ok := <-ws.ResultsCh
if !ok {
break
}
fmt.Println("res:", Blue(string(res)))
}
}()
// Get the root account
root := tests.PrivAccountFromSecret("root")
sequence := uint(0)
// Make a bunch of PrivAccounts
privAccounts := tests.RandAccounts(1000, 1000000, 0)
// Send coins to each account
for i := 0; i < len(privAccounts); i++ {
privAccount := privAccounts[i]
tx := types.Tx{
Inputs: []types.Input{
types.Input{
PubKey: root.PubKey,
Amount: 1000002,
Sequence: sequence,
},
},
Outputs: []types.Output{
types.Output{
PubKey: privAccount.PubKey,
Amount: 1000000,
},
},
}
sequence += 1
// Write request
txBytes := wire.BinaryBytes(tx)
fmt.Println("tx:", hex.EncodeToString(txBytes))
request := rpctypes.NewRPCRequest("fakeid", "broadcast_tx", Arr(txBytes))
reqBytes := wire.JSONBytes(request)
fmt.Println("req:", hex.EncodeToString(reqBytes))
//fmt.Print(".")
err := ws.WriteMessage(websocket.TextMessage, reqBytes)
if err != nil {
Exit("writing websocket request: " + err.Error())
}
}
/*
// Make a bunch of requests
for i := 0; ; i++ {
binary.BigEndian.PutUint64(buf, uint64(i))
//txBytes := hex.EncodeToString(buf[:n])
request := rpctypes.NewRPCRequest("fakeid", "broadcast_tx", Arr(buf[:8]))
reqBytes := wire.JSONBytes(request)
//fmt.Println("!!", string(reqBytes))
fmt.Print(".")
err := ws.WriteMessage(websocket.TextMessage, reqBytes)
if err != nil {
Exit(err.Error())
}
if i%1000 == 0 {
fmt.Println(i)
}
time.Sleep(time.Microsecond * 1000)
}
*/
ws.Stop()
}

View File

@ -24,7 +24,19 @@ type Output struct {
type Account struct {
Sequence uint
Balance uint64
// For convenience
crypto.PubKey `json:"-"`
}
type PubAccount struct {
crypto.PubKey
Account
}
type PrivAccount struct {
crypto.PubKey
crypto.PrivKey
Account
}
type GenesisState struct {
Accounts []PubAccount
}