|
@ -5,11 +5,14 @@ import ( |
|
|
"encoding/hex" |
|
|
"encoding/hex" |
|
|
"encoding/json" |
|
|
"encoding/json" |
|
|
"fmt" |
|
|
"fmt" |
|
|
|
|
|
"github.com/tendermint/tendermint/account" |
|
|
"github.com/tendermint/tendermint/binary" |
|
|
"github.com/tendermint/tendermint/binary" |
|
|
"github.com/tendermint/tendermint/config" |
|
|
"github.com/tendermint/tendermint/config" |
|
|
"github.com/tendermint/tendermint/daemon" |
|
|
"github.com/tendermint/tendermint/daemon" |
|
|
|
|
|
"github.com/tendermint/tendermint/logger" |
|
|
"github.com/tendermint/tendermint/p2p" |
|
|
"github.com/tendermint/tendermint/p2p" |
|
|
"github.com/tendermint/tendermint/rpc" |
|
|
"github.com/tendermint/tendermint/rpc" |
|
|
|
|
|
"github.com/tendermint/tendermint/types" |
|
|
"io/ioutil" |
|
|
"io/ioutil" |
|
|
"net/http" |
|
|
"net/http" |
|
|
"net/url" |
|
|
"net/url" |
|
@ -22,6 +25,9 @@ var ( |
|
|
chainId string |
|
|
chainId string |
|
|
node *daemon.Node |
|
|
node *daemon.Node |
|
|
userAddr = "D7DFF9806078899C8DA3FE3633CC0BF3C6C2B1BB" |
|
|
userAddr = "D7DFF9806078899C8DA3FE3633CC0BF3C6C2B1BB" |
|
|
|
|
|
userPriv = "FDE3BD94CB327D19464027BA668194C5EFA46AE83E8419D7542CFF41F00C81972239C21C81EA7173A6C489145490C015E05D4B97448933B708A7EC5B7B4921E3" |
|
|
|
|
|
|
|
|
|
|
|
userPub = "2239C21C81EA7173A6C489145490C015E05D4B97448933B708A7EC5B7B4921E3" |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
func newNode(ready chan struct{}) { |
|
|
func newNode(ready chan struct{}) { |
|
@ -49,7 +55,9 @@ func init() { |
|
|
app.Set("RPC.HTTP.ListenAddr", rpcAddr) |
|
|
app.Set("RPC.HTTP.ListenAddr", rpcAddr) |
|
|
app.Set("GenesisFile", rootDir+"/genesis.json") |
|
|
app.Set("GenesisFile", rootDir+"/genesis.json") |
|
|
app.Set("PrivValidatorFile", rootDir+"/priv_validator.json") |
|
|
app.Set("PrivValidatorFile", rootDir+"/priv_validator.json") |
|
|
|
|
|
app.Set("Log.Stdout.Level", "debug") |
|
|
config.SetApp(app) |
|
|
config.SetApp(app) |
|
|
|
|
|
logger.InitLog() |
|
|
// start a node
|
|
|
// start a node
|
|
|
ready := make(chan struct{}) |
|
|
ready := make(chan struct{}) |
|
|
go newNode(ready) |
|
|
go newNode(ready) |
|
@ -105,10 +113,9 @@ func TestGenPriv(t *testing.T) { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func TestGetAccount(t *testing.T) { |
|
|
|
|
|
byteAddr, _ := hex.DecodeString(userAddr) |
|
|
|
|
|
|
|
|
func getAccount(t *testing.T, addr []byte) *account.Account { |
|
|
resp, err := http.PostForm(requestAddr+"get_account", |
|
|
resp, err := http.PostForm(requestAddr+"get_account", |
|
|
url.Values{"address": {string(byteAddr)}}) |
|
|
|
|
|
|
|
|
url.Values{"address": {string(addr)}}) |
|
|
if err != nil { |
|
|
if err != nil { |
|
|
t.Fatal(err) |
|
|
t.Fatal(err) |
|
|
} |
|
|
} |
|
@ -120,54 +127,159 @@ func TestGetAccount(t *testing.T) { |
|
|
var status struct { |
|
|
var status struct { |
|
|
Status string |
|
|
Status string |
|
|
Data rpc.ResponseGetAccount |
|
|
Data rpc.ResponseGetAccount |
|
|
|
|
|
Error string |
|
|
} |
|
|
} |
|
|
fmt.Println(string(body)) |
|
|
fmt.Println(string(body)) |
|
|
binary.ReadJSON(&status, body, &err) |
|
|
binary.ReadJSON(&status, body, &err) |
|
|
if err != nil { |
|
|
if err != nil { |
|
|
t.Fatal(err) |
|
|
t.Fatal(err) |
|
|
} |
|
|
} |
|
|
if bytes.Compare(status.Data.Account.Address, byteAddr) != 0 { |
|
|
|
|
|
t.Fatalf("Failed to get correct account. Got %x, expected %x", status.Data.Account.Address, byteAddr) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return status.Data.Account |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func TestSignedTx(t *testing.T) { |
|
|
|
|
|
|
|
|
func TestGetAccount(t *testing.T) { |
|
|
|
|
|
byteAddr, _ := hex.DecodeString(userAddr) |
|
|
|
|
|
acc := getAccount(t, byteAddr) |
|
|
|
|
|
if bytes.Compare(acc.Address, byteAddr) != 0 { |
|
|
|
|
|
t.Fatalf("Failed to get correct account. Got %x, expected %x", acc.Address, byteAddr) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* |
|
|
|
|
|
acc := mint.MempoolReactor.Mempool.GetState().GetAccount(mint.priv.Address) |
|
|
|
|
|
|
|
|
func makeTx(t *testing.T, from, to []byte, amt uint64) *types.SendTx { |
|
|
|
|
|
acc := getAccount(t, from) |
|
|
nonce := 0 |
|
|
nonce := 0 |
|
|
if acc != nil { |
|
|
if acc != nil { |
|
|
nonce = int(acc.Sequence) + 1 |
|
|
nonce = int(acc.Sequence) + 1 |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
amtInt, err := strconv.Atoi(amt) |
|
|
|
|
|
|
|
|
bytePub, err := hex.DecodeString(userPub) |
|
|
if err != nil { |
|
|
if err != nil { |
|
|
return "", err |
|
|
|
|
|
|
|
|
t.Fatal(err) |
|
|
} |
|
|
} |
|
|
amtUint64 := uint64(amtInt) |
|
|
|
|
|
|
|
|
|
|
|
tx := &blk.SendTx{ |
|
|
|
|
|
Inputs: []*blk.TxInput{ |
|
|
|
|
|
&blk.TxInput{ |
|
|
|
|
|
Address: mint.priv.Address, |
|
|
|
|
|
Amount: amtUint64, |
|
|
|
|
|
|
|
|
tx := &types.SendTx{ |
|
|
|
|
|
Inputs: []*types.TxInput{ |
|
|
|
|
|
&types.TxInput{ |
|
|
|
|
|
Address: from, |
|
|
|
|
|
Amount: amt, |
|
|
Sequence: uint(nonce), |
|
|
Sequence: uint(nonce), |
|
|
Signature: account.SignatureEd25519{}, |
|
|
Signature: account.SignatureEd25519{}, |
|
|
PubKey: mint.priv.PubKey, |
|
|
|
|
|
|
|
|
PubKey: account.PubKeyEd25519(bytePub), |
|
|
}, |
|
|
}, |
|
|
}, |
|
|
}, |
|
|
Outputs: []*blk.TxOutput{ |
|
|
|
|
|
&blk.TxOutput{ |
|
|
|
|
|
Address: addrB, |
|
|
|
|
|
Amount: amtUint64, |
|
|
|
|
|
|
|
|
Outputs: []*types.TxOutput{ |
|
|
|
|
|
&types.TxOutput{ |
|
|
|
|
|
Address: to, |
|
|
|
|
|
Amount: amt, |
|
|
}, |
|
|
}, |
|
|
}, |
|
|
}, |
|
|
} |
|
|
} |
|
|
tx.Inputs[0].Signature = mint.priv.PrivKey.Sign(account.SignBytes(tx)) |
|
|
|
|
|
err = mint.MempoolReactor.BroadcastTx(tx) |
|
|
|
|
|
return hex.EncodeToString(merkle.HashFromBinary(tx)), err |
|
|
|
|
|
|
|
|
return tx |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func requestResponse(t *testing.T, method string, values url.Values, status interface{}) { |
|
|
|
|
|
resp, err := http.PostForm(requestAddr+method, values) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
t.Fatal(err) |
|
|
|
|
|
} |
|
|
|
|
|
defer resp.Body.Close() |
|
|
|
|
|
body, err := ioutil.ReadAll(resp.Body) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
t.Fatal(err) |
|
|
|
|
|
} |
|
|
|
|
|
fmt.Println(string(body)) |
|
|
|
|
|
binary.ReadJSON(status, body, &err) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
t.Fatal(err) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestSignedTx(t *testing.T) { |
|
|
|
|
|
byteAddr, _ := hex.DecodeString(userAddr) |
|
|
|
|
|
var byteKey [64]byte |
|
|
|
|
|
oh, _ := hex.DecodeString(userPriv) |
|
|
|
|
|
copy(byteKey[:], oh) |
|
|
|
|
|
|
|
|
|
|
|
amt := uint64(100) |
|
|
|
|
|
toAddr := []byte{20, 143, 25, 63, 16, 177, 83, 29, 91, 91, 54, 23, 233, 46, 190, 121, 122, 34, 86, 54} |
|
|
|
|
|
tx := makeTx(t, byteAddr, toAddr, amt) |
|
|
|
|
|
|
|
|
|
|
|
/*b, err := json.Marshal(rpc.InterfaceType{types.TxTypeSend, tx}) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
t.Fatal(err) |
|
|
|
|
|
}*/ |
|
|
|
|
|
|
|
|
|
|
|
n := new(int64) |
|
|
|
|
|
var err error |
|
|
|
|
|
w := new(bytes.Buffer) |
|
|
|
|
|
binary.WriteJSON(tx, w, n, &err) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
t.Fatal(err) |
|
|
|
|
|
} |
|
|
|
|
|
b := w.Bytes() |
|
|
|
|
|
|
|
|
|
|
|
privAcc := account.GenPrivAccountFromKey(byteKey) |
|
|
|
|
|
if bytes.Compare(privAcc.PubKey.Address(), byteAddr) != 0 { |
|
|
|
|
|
t.Fatal("Faield to generate correct priv acc") |
|
|
|
|
|
} |
|
|
|
|
|
w = new(bytes.Buffer) |
|
|
|
|
|
binary.WriteJSON([]*account.PrivAccount{privAcc}, w, n, &err) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
t.Fatal(err) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var status struct { |
|
|
|
|
|
Status string |
|
|
|
|
|
Data rpc.ResponseSignTx |
|
|
|
|
|
Error string |
|
|
|
|
|
} |
|
|
|
|
|
requestResponse(t, "unsafe/sign_tx", url.Values{"tx": {string(b)}, "privAccounts": {string(w.Bytes())}}, &status) |
|
|
|
|
|
|
|
|
|
|
|
if status.Status == "ERROR" { |
|
|
|
|
|
t.Fatal(status.Error) |
|
|
|
|
|
} |
|
|
|
|
|
response := status.Data |
|
|
|
|
|
//tx = status.Data.(rpc.ResponseSignTx).Tx.(*types.SendTx)
|
|
|
|
|
|
tx = response.Tx.(*types.SendTx) |
|
|
|
|
|
if bytes.Compare(tx.Inputs[0].Address, byteAddr) != 0 { |
|
|
|
|
|
t.Fatal("Tx input addresses don't match!") |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
signBytes := account.SignBytes(tx) |
|
|
|
|
|
in := tx.Inputs[0] //(*types.SendTx).Inputs[0]
|
|
|
|
|
|
|
|
|
|
|
|
if err := in.ValidateBasic(); err != nil { |
|
|
|
|
|
t.Fatal(err) |
|
|
|
|
|
} |
|
|
|
|
|
fmt.Println(privAcc.PubKey, in.PubKey) |
|
|
|
|
|
// Check signatures
|
|
|
|
|
|
// acc := getAccount(t, byteAddr)
|
|
|
|
|
|
// NOTE: using the acc here instead of the in fails; its PubKeyNil ... ?
|
|
|
|
|
|
if !in.PubKey.VerifyBytes(signBytes, in.Signature) { |
|
|
|
|
|
t.Fatal(types.ErrTxInvalidSignature) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestBroadcastTx(t *testing.T) { |
|
|
|
|
|
/* |
|
|
|
|
|
byteAddr, _ := hex.DecodeString(userAddr) |
|
|
|
|
|
|
|
|
|
|
|
amt := uint64(100) |
|
|
|
|
|
toAddr := []byte{20, 143, 25, 63, 16, 177, 83, 29, 91, 91, 54, 23, 233, 46, 190, 121, 122, 34, 86, 54} |
|
|
|
|
|
tx := makeTx(t, byteAddr, toAddr, amt) |
|
|
|
|
|
|
|
|
|
|
|
b, err := json.Marshal([]interface{}{types.TxTypeSend, tx}) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
t.Fatal(err) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var status struct { |
|
|
|
|
|
Status string |
|
|
|
|
|
Data rpc.ResponseSignTx |
|
|
|
|
|
} |
|
|
|
|
|
// TODO ...
|
|
|
|
|
|
*/ |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
/*tx.Inputs[0].Signature = mint.priv.PrivKey.Sign(account.SignBytes(tx)) |
|
|
|
|
|
err = mint.MempoolReactor.BroadcastTx(tx) |
|
|
|
|
|
return hex.EncodeToString(merkle.HashFromBinary(tx)), err*/ |