Added genesis file; Added draft of Tendermint tests
This commit is contained in:
parent
d31a8d8258
commit
436e0ba7d7
|
@ -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{
|
||||
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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------
|
|
@ -0,0 +1,6 @@
|
|||
{"Accounts":[
|
||||
{
|
||||
"PubKey":[1,"31F4BF201D3606E33707B098B1EEA7D03A4BB9E9795F0116ED1A038D7B5A6BDE"],
|
||||
"Account":{"Sequence":0,"Balance":2100000000000000}
|
||||
}
|
||||
]}
|
|
@ -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
|
||||
})
|
||||
|
||||
}
|
|
@ -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.
|
@ -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()
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue