2015-05-16 15:04:00 -07:00
package rpctest
2015-03-28 21:22:39 -07:00
import (
"bytes"
"fmt"
2015-04-01 17:30:16 -07:00
. "github.com/tendermint/tendermint/common"
"github.com/tendermint/tendermint/types"
2015-03-28 21:22:39 -07:00
"testing"
)
2015-05-23 03:46:02 -04:00
var doNothing = func ( eid string , b [ ] byte ) error { return nil }
2015-04-02 18:11:37 -07:00
func testStatus ( t * testing . T , typ string ) {
client := clients [ typ ]
2015-04-02 03:06:46 -07:00
resp , err := client . Status ( )
2015-03-28 21:22:39 -07:00
if err != nil {
t . Fatal ( err )
}
2015-07-10 15:50:58 +00:00
if resp . NodeInfo . ChainID != chainID {
2015-05-29 14:13:45 -04:00
t . Fatal ( fmt . Errorf ( "ChainID mismatch: got %s expected %s" ,
2015-07-10 15:50:58 +00:00
resp . NodeInfo . ChainID , chainID ) )
2015-04-02 18:11:37 -07:00
}
2015-03-28 21:22:39 -07:00
}
2015-04-02 18:11:37 -07:00
func testGenPriv ( t * testing . T , typ string ) {
client := clients [ typ ]
2015-06-01 13:51:03 -04:00
privAcc , err := client . GenPrivAccount ( )
2015-03-28 21:22:39 -07:00
if err != nil {
t . Fatal ( err )
}
2015-06-01 13:51:03 -04:00
if len ( privAcc . Address ) == 0 {
2015-04-02 18:11:37 -07:00
t . Fatal ( "Failed to generate an address" )
}
2015-03-28 21:22:39 -07:00
}
2015-04-02 18:11:37 -07:00
func testGetAccount ( t * testing . T , typ string ) {
2015-05-22 18:22:57 -04:00
acc := getAccount ( t , typ , user [ 0 ] . Address )
2015-03-30 15:14:33 -07:00
if acc == nil {
t . Fatalf ( "Account was nil" )
}
2015-05-22 18:22:57 -04:00
if bytes . Compare ( acc . Address , user [ 0 ] . Address ) != 0 {
t . Fatalf ( "Failed to get correct account. Got %x, expected %x" , acc . Address , user [ 0 ] . Address )
2015-03-28 21:22:39 -07:00
}
}
2015-04-02 18:11:37 -07:00
func testSignedTx ( t * testing . T , typ string ) {
2015-06-25 20:28:34 -07:00
amt := int64 ( 100 )
2015-05-23 03:46:02 -04:00
toAddr := user [ 1 ] . Address
2015-05-22 18:22:57 -04:00
testOneSignTx ( t , typ , toAddr , amt )
2015-03-28 21:22:39 -07:00
2015-05-23 03:46:02 -04:00
toAddr = user [ 2 ] . Address
2015-05-22 18:22:57 -04:00
testOneSignTx ( t , typ , toAddr , amt )
2015-03-28 21:22:39 -07:00
2015-05-23 03:46:02 -04:00
toAddr = user [ 3 ] . Address
2015-05-22 18:22:57 -04:00
testOneSignTx ( t , typ , toAddr , amt )
}
2015-06-25 20:28:34 -07:00
func testOneSignTx ( t * testing . T , typ string , addr [ ] byte , amt int64 ) {
2015-05-22 18:22:57 -04:00
tx := makeDefaultSendTx ( t , typ , addr , amt )
tx2 := signTx ( t , typ , tx , user [ 0 ] )
2015-07-10 05:56:38 +00:00
tx2hash := types . TxID ( chainID , tx2 )
2015-05-29 17:53:57 -04:00
tx . SignInput ( chainID , 0 , user [ 0 ] )
2015-07-10 05:56:38 +00:00
txhash := types . TxID ( chainID , tx )
2015-05-22 18:22:57 -04:00
if bytes . Compare ( txhash , tx2hash ) != 0 {
t . Fatal ( "Got different signatures for signing via rpc vs tx_utils" )
}
tx_ := signTx ( t , typ , tx , user [ 0 ] )
tx = tx_ . ( * types . SendTx )
checkTx ( t , user [ 0 ] . Address , user [ 0 ] , tx )
2015-03-28 21:22:39 -07:00
}
2015-04-02 18:11:37 -07:00
func testBroadcastTx ( t * testing . T , typ string ) {
2015-06-25 20:28:34 -07:00
amt := int64 ( 100 )
2015-05-23 03:46:02 -04:00
toAddr := user [ 1 ] . Address
2015-05-22 18:22:57 -04:00
tx := makeDefaultSendTxSigned ( t , typ , toAddr , amt )
receipt := broadcastTx ( t , typ , tx )
2015-03-28 21:22:39 -07:00
if receipt . CreatesContract > 0 {
t . Fatal ( "This tx does not create a contract" )
}
if len ( receipt . TxHash ) == 0 {
t . Fatal ( "Failed to compute tx hash" )
}
pool := node . MempoolReactor ( ) . Mempool
txs := pool . GetProposalTxs ( )
2015-04-07 02:02:03 -05:00
if len ( txs ) != mempoolCount {
t . Fatalf ( "The mem pool has %d txs. Expected %d" , len ( txs ) , mempoolCount )
2015-03-28 21:22:39 -07:00
}
2015-04-07 02:02:03 -05:00
tx2 := txs [ mempoolCount - 1 ] . ( * types . SendTx )
2015-04-02 18:11:37 -07:00
n , err := new ( int64 ) , new ( error )
buf1 , buf2 := new ( bytes . Buffer ) , new ( bytes . Buffer )
2015-05-29 17:53:57 -04:00
tx . WriteSignBytes ( chainID , buf1 , n , err )
tx2 . WriteSignBytes ( chainID , buf2 , n , err )
2015-04-02 18:11:37 -07:00
if bytes . Compare ( buf1 . Bytes ( ) , buf2 . Bytes ( ) ) != 0 {
2015-03-28 21:22:39 -07:00
t . Fatal ( "inconsistent hashes for mempool tx and sent tx" )
}
}
2015-04-02 18:11:37 -07:00
func testGetStorage ( t * testing . T , typ string ) {
2015-04-14 01:42:11 -07:00
con := newWSCon ( t )
eid := types . EventStringNewBlock ( )
subscribe ( t , con , eid )
defer func ( ) {
unsubscribe ( t , con , eid )
con . Close ( )
} ( )
2015-03-31 04:53:34 -07:00
2015-06-25 20:28:34 -07:00
amt , gasLim , fee := int64 ( 1100 ) , int64 ( 1000 ) , int64 ( 1000 )
2015-03-31 04:53:34 -07:00
code := [ ] byte { 0x60 , 0x5 , 0x60 , 0x1 , 0x55 }
2015-05-22 18:22:57 -04:00
tx := makeDefaultCallTx ( t , typ , nil , code , amt , gasLim , fee )
receipt := broadcastTx ( t , typ , tx )
2015-03-31 04:53:34 -07:00
if receipt . CreatesContract == 0 {
t . Fatal ( "This tx creates a contract" )
}
if len ( receipt . TxHash ) == 0 {
t . Fatal ( "Failed to compute tx hash" )
}
contractAddr := receipt . ContractAddr
if len ( contractAddr ) == 0 {
t . Fatal ( "Creates contract but resulting address is empty" )
}
2015-04-07 02:02:03 -05:00
// allow it to get mined
2015-05-23 03:46:02 -04:00
waitForEvent ( t , con , eid , true , func ( ) { } , doNothing )
2015-04-07 02:02:03 -05:00
mempoolCount = 0
2015-03-31 04:53:34 -07:00
2015-04-02 18:11:37 -07:00
v := getStorage ( t , typ , contractAddr , [ ] byte { 0x1 } )
2015-04-17 17:39:50 -07:00
got := LeftPadWord256 ( v )
expected := LeftPadWord256 ( [ ] byte { 0x5 } )
2015-03-31 04:53:34 -07:00
if got . Compare ( expected ) != 0 {
t . Fatalf ( "Wrong storage value. Got %x, expected %x" , got . Bytes ( ) , expected . Bytes ( ) )
}
}
2015-04-02 19:15:23 -07:00
func testCallCode ( t * testing . T , typ string ) {
client := clients [ typ ]
// add two integers and return the result
code := [ ] byte { 0x60 , 0x5 , 0x60 , 0x6 , 0x1 , 0x60 , 0x0 , 0x52 , 0x60 , 0x20 , 0x60 , 0x0 , 0xf3 }
data := [ ] byte { }
expected := [ ] byte { 0xb }
2015-07-22 18:43:20 -04:00
callCode ( t , client , user [ 0 ] . PubKey . Address ( ) , code , data , expected )
2015-04-02 19:15:23 -07:00
// pass two ints as calldata, add, and return the result
code = [ ] byte { 0x60 , 0x0 , 0x35 , 0x60 , 0x20 , 0x35 , 0x1 , 0x60 , 0x0 , 0x52 , 0x60 , 0x20 , 0x60 , 0x0 , 0xf3 }
data = append ( LeftPadWord256 ( [ ] byte { 0x5 } ) . Bytes ( ) , LeftPadWord256 ( [ ] byte { 0x6 } ) . Bytes ( ) ... )
expected = [ ] byte { 0xb }
2015-07-22 18:43:20 -04:00
callCode ( t , client , user [ 0 ] . PubKey . Address ( ) , code , data , expected )
2015-04-02 19:15:23 -07:00
}
func testCall ( t * testing . T , typ string ) {
2015-04-14 01:42:11 -07:00
con := newWSCon ( t )
eid := types . EventStringNewBlock ( )
subscribe ( t , con , eid )
defer func ( ) {
unsubscribe ( t , con , eid )
con . Close ( )
} ( )
2015-04-02 19:15:23 -07:00
client := clients [ typ ]
// create the contract
2015-06-25 20:28:34 -07:00
amt , gasLim , fee := int64 ( 6969 ) , int64 ( 1000 ) , int64 ( 1000 )
2015-04-14 19:29:18 -07:00
code , _ , _ := simpleContract ( )
2015-05-22 18:22:57 -04:00
tx := makeDefaultCallTx ( t , typ , nil , code , amt , gasLim , fee )
receipt := broadcastTx ( t , typ , tx )
2015-04-02 19:15:23 -07:00
if receipt . CreatesContract == 0 {
t . Fatal ( "This tx creates a contract" )
}
if len ( receipt . TxHash ) == 0 {
t . Fatal ( "Failed to compute tx hash" )
}
contractAddr := receipt . ContractAddr
if len ( contractAddr ) == 0 {
t . Fatal ( "Creates contract but resulting address is empty" )
}
// allow it to get mined
2015-05-23 03:46:02 -04:00
waitForEvent ( t , con , eid , true , func ( ) { } , doNothing )
2015-04-07 02:02:03 -05:00
mempoolCount = 0
2015-04-02 19:15:23 -07:00
// run a call through the contract
data := [ ] byte { }
expected := [ ] byte { 0xb }
2015-07-22 18:43:20 -04:00
callContract ( t , client , user [ 0 ] . PubKey . Address ( ) , contractAddr , data , expected )
2015-04-02 19:15:23 -07:00
}
2015-05-22 17:03:22 -04:00
func testNameReg ( t * testing . T , typ string ) {
2015-05-23 03:46:02 -04:00
client := clients [ typ ]
2015-05-22 17:03:22 -04:00
con := newWSCon ( t )
2015-05-24 14:41:42 -04:00
types . MinNameRegistrationPeriod = 1
2015-05-23 03:46:02 -04:00
// register a new name, check if its there
2015-05-22 17:03:22 -04:00
// since entries ought to be unique and these run against different clients, we append the typ
2015-05-23 03:46:02 -04:00
name := "ye_old_domain_name_" + typ
2015-05-24 14:41:42 -04:00
data := "if not now, when"
2015-06-25 20:28:34 -07:00
fee := int64 ( 1000 )
numDesiredBlocks := int64 ( 2 )
2015-05-24 14:41:42 -04:00
amt := fee + numDesiredBlocks * types . NameCostPerByte * types . NameCostPerBlock * types . BaseEntryCost ( name , data )
2015-05-23 03:46:02 -04:00
2015-07-30 17:34:38 -04:00
eid := types . EventStringNameReg ( name )
subscribe ( t , con , eid )
2015-05-22 17:03:22 -04:00
tx := makeDefaultNameTx ( t , typ , name , data , amt , fee )
broadcastTx ( t , typ , tx )
2015-07-30 17:34:38 -04:00
// verify the name by both using the event and by checking get_name
waitForEvent ( t , con , eid , true , func ( ) { } , func ( eid string , b [ ] byte ) error {
// TODO: unmarshal the response
tx , err := unmarshalResponseNameReg ( b )
if err != nil {
return err
}
if tx . Name != name {
t . Fatal ( fmt . Sprintf ( "Err on received event tx.Name: Got %s, expected %s" , tx . Name , name ) )
}
if tx . Data != data {
t . Fatal ( fmt . Sprintf ( "Err on received event tx.Data: Got %s, expected %s" , tx . Data , data ) )
}
return nil
} )
2015-05-23 03:46:02 -04:00
mempoolCount = 0
2015-05-22 17:03:22 -04:00
entry := getNameRegEntry ( t , typ , name )
2015-05-23 03:46:02 -04:00
if entry . Data != data {
2015-05-24 14:41:42 -04:00
t . Fatal ( fmt . Sprintf ( "Err on entry.Data: Got %s, expected %s" , entry . Data , data ) )
}
if bytes . Compare ( entry . Owner , user [ 0 ] . Address ) != 0 {
t . Fatal ( fmt . Sprintf ( "Err on entry.Owner: Got %s, expected %s" , entry . Owner , user [ 0 ] . Address ) )
2015-05-23 03:46:02 -04:00
}
2015-05-22 17:03:22 -04:00
2015-07-30 17:34:38 -04:00
unsubscribe ( t , con , eid )
// for the rest we just use new block event
// since we already tested the namereg event
eid = types . EventStringNewBlock ( )
subscribe ( t , con , eid )
defer func ( ) {
unsubscribe ( t , con , eid )
con . Close ( )
} ( )
2015-05-23 03:46:02 -04:00
// update the data as the owner, make sure still there
2015-06-25 20:28:34 -07:00
numDesiredBlocks = int64 ( 2 )
2015-05-24 14:41:42 -04:00
data = "these are amongst the things I wish to bestow upon the youth of generations come: a safe supply of honey, and a better money. For what else shall they need"
amt = fee + numDesiredBlocks * types . NameCostPerByte * types . NameCostPerBlock * types . BaseEntryCost ( name , data )
2015-05-23 03:46:02 -04:00
tx = makeDefaultNameTx ( t , typ , name , data , amt , fee )
broadcastTx ( t , typ , tx )
2015-05-24 14:41:42 -04:00
// commit block
2015-05-23 03:46:02 -04:00
waitForEvent ( t , con , eid , true , func ( ) { } , doNothing )
mempoolCount = 0
entry = getNameRegEntry ( t , typ , name )
2015-05-23 02:05:56 -04:00
if entry . Data != data {
2015-05-24 14:41:42 -04:00
t . Fatal ( fmt . Sprintf ( "Err on entry.Data: Got %s, expected %s" , entry . Data , data ) )
2015-05-22 17:03:22 -04:00
}
2015-05-23 03:46:02 -04:00
// try to update as non owner, should fail
nonce := getNonce ( t , typ , user [ 1 ] . Address )
data2 := "this is not my beautiful house"
2015-05-27 15:24:45 -04:00
tx = types . NewNameTxWithNonce ( user [ 1 ] . PubKey , name , data2 , amt , fee , nonce + 1 )
2015-05-30 01:54:05 -04:00
tx . Sign ( chainID , user [ 1 ] )
2015-05-23 03:46:02 -04:00
_ , err := client . BroadcastTx ( tx )
if err == nil {
t . Fatal ( "Expected error on NameTx" )
}
2015-05-24 14:41:42 -04:00
// commit block
waitForEvent ( t , con , eid , true , func ( ) { } , doNothing )
// now the entry should be expired, so we can update as non owner
_ , err = client . BroadcastTx ( tx )
waitForEvent ( t , con , eid , true , func ( ) { } , doNothing )
mempoolCount = 0
entry = getNameRegEntry ( t , typ , name )
if entry . Data != data2 {
t . Fatal ( fmt . Sprintf ( "Error on entry.Data: Got %s, expected %s" , entry . Data , data2 ) )
}
if bytes . Compare ( entry . Owner , user [ 1 ] . Address ) != 0 {
t . Fatal ( fmt . Sprintf ( "Err on entry.Owner: Got %s, expected %s" , entry . Owner , user [ 1 ] . Address ) )
}
2015-05-22 17:03:22 -04:00
}