Merge branch 'feature/expose-historical-queries' into develop
This commit is contained in:
commit
ad04aba0a4
|
@ -218,13 +218,13 @@ func TestInitState(t *testing.T) {
|
|||
assert.Equal(unsortCoins, coins)
|
||||
|
||||
err = app.InitState("base", "dslfkgjdas", "")
|
||||
require.NotNil(err)
|
||||
require.Error(err)
|
||||
|
||||
err = app.InitState("", "dslfkgjdas", "")
|
||||
require.NotNil(err)
|
||||
require.Error(err)
|
||||
|
||||
err = app.InitState("dslfkgjdas", "szfdjzs", "")
|
||||
require.NotNil(err)
|
||||
require.Error(err)
|
||||
}
|
||||
|
||||
// Test CheckTx and DeliverTx with insufficient and sufficient balance
|
||||
|
|
32
app/store.go
32
app/store.go
|
@ -17,6 +17,9 @@ import (
|
|||
sm "github.com/cosmos/cosmos-sdk/state"
|
||||
)
|
||||
|
||||
// DefaultHistorySize is how many blocks of history to store for ABCI queries
|
||||
const DefaultHistorySize = 10
|
||||
|
||||
// StoreApp contains a data store and all info needed
|
||||
// to perform queries and handshakes.
|
||||
//
|
||||
|
@ -41,7 +44,7 @@ type StoreApp struct {
|
|||
|
||||
// NewStoreApp creates a data store to handle queries
|
||||
func NewStoreApp(appName, dbName string, cacheSize int, logger log.Logger) (*StoreApp, error) {
|
||||
state, err := loadState(dbName, cacheSize)
|
||||
state, err := loadState(dbName, cacheSize, DefaultHistorySize)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -143,11 +146,12 @@ func (app *StoreApp) Query(reqQuery abci.RequestQuery) (resQuery abci.ResponseQu
|
|||
// we must retrun most recent, even if apphash
|
||||
// is not yet in the blockchain
|
||||
|
||||
// if tree.Tree.VersionExists(app.height - 1) {
|
||||
// height = app.height - 1
|
||||
// } else {
|
||||
height = app.CommittedHeight()
|
||||
// }
|
||||
withProof := app.CommittedHeight() - 1
|
||||
if tree.Tree.VersionExists(withProof) {
|
||||
height = withProof
|
||||
} else {
|
||||
height = app.CommittedHeight()
|
||||
}
|
||||
}
|
||||
resQuery.Height = height
|
||||
|
||||
|
@ -234,11 +238,11 @@ func pubKeyIndex(val *abci.Validator, list []*abci.Validator) int {
|
|||
return -1
|
||||
}
|
||||
|
||||
func loadState(dbName string, cacheSize int) (*sm.State, error) {
|
||||
func loadState(dbName string, cacheSize int, historySize uint64) (*sm.State, error) {
|
||||
// memory backed case, just for testing
|
||||
if dbName == "" {
|
||||
tree := iavl.NewVersionedTree(0, dbm.NewMemDB())
|
||||
return sm.NewState(tree), nil
|
||||
return sm.NewState(tree, historySize), nil
|
||||
}
|
||||
|
||||
// Expand the path fully
|
||||
|
@ -254,18 +258,12 @@ func loadState(dbName string, cacheSize int) (*sm.State, error) {
|
|||
dir := path.Dir(dbPath)
|
||||
name := path.Base(dbPath)
|
||||
|
||||
// Make sure the path exists
|
||||
empty, _ := cmn.IsDirEmpty(dbPath + ".db")
|
||||
|
||||
// Open database called "dir/name.db", if it doesn't exist it will be created
|
||||
db := dbm.NewDB(name, dbm.LevelDBBackendStr, dir)
|
||||
tree := iavl.NewVersionedTree(cacheSize, db)
|
||||
|
||||
if !empty {
|
||||
if err = tree.Load(); err != nil {
|
||||
return nil, errors.ErrInternal("Loading tree: " + err.Error())
|
||||
}
|
||||
if err = tree.Load(); err != nil {
|
||||
return nil, errors.ErrInternal("Loading tree: " + err.Error())
|
||||
}
|
||||
|
||||
return sm.NewState(tree), nil
|
||||
return sm.NewState(tree, historySize), nil
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"github.com/tendermint/go-wire/data"
|
||||
"github.com/tendermint/iavl"
|
||||
"github.com/tendermint/light-client/proofs"
|
||||
rpcclient "github.com/tendermint/tendermint/rpc/client"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/commands"
|
||||
|
@ -24,8 +25,8 @@ import (
|
|||
// It will try to get the proof for the given key. If it is successful,
|
||||
// it will return the height and also unserialize proof.Data into the data
|
||||
// argument (so pass in a pointer to the appropriate struct)
|
||||
func GetParsed(key []byte, data interface{}, prove bool) (uint64, error) {
|
||||
bs, h, err := Get(key, prove)
|
||||
func GetParsed(key []byte, data interface{}, height int, prove bool) (uint64, error) {
|
||||
bs, h, err := Get(key, height, prove)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -44,26 +45,31 @@ func GetParsed(key []byte, data interface{}, prove bool) (uint64, error) {
|
|||
// we just repeat whatever any (potentially malicious) node gives us.
|
||||
// Only use that if you are running the full node yourself,
|
||||
// and it is localhost or you have a secure connection (not HTTP)
|
||||
func Get(key []byte, prove bool) (data.Bytes, uint64, error) {
|
||||
func Get(key []byte, height int, prove bool) (data.Bytes, uint64, error) {
|
||||
if height < 0 {
|
||||
return nil, 0, fmt.Errorf("Height cannot be negative")
|
||||
}
|
||||
|
||||
if !prove {
|
||||
node := commands.GetNode()
|
||||
resp, err := node.ABCIQuery("/key", key, false)
|
||||
resp, err := node.ABCIQueryWithOptions("/key", key,
|
||||
rpcclient.ABCIQueryOptions{Trusted: true, Height: uint64(height)})
|
||||
return data.Bytes(resp.Value), resp.Height, err
|
||||
}
|
||||
val, h, _, err := GetWithProof(key)
|
||||
val, h, _, err := GetWithProof(key, height)
|
||||
return val, h, err
|
||||
}
|
||||
|
||||
// GetWithProof returns the values stored under a given key at the named
|
||||
// height as in Get. Additionally, it will return a validated merkle
|
||||
// proof for the key-value pair if it exists, and all checks pass.
|
||||
func GetWithProof(key []byte) (data.Bytes, uint64, iavl.KeyProof, error) {
|
||||
func GetWithProof(key []byte, height int) (data.Bytes, uint64, iavl.KeyProof, error) {
|
||||
node := commands.GetNode()
|
||||
cert, err := commands.GetCertifier()
|
||||
if err != nil {
|
||||
return nil, 0, nil, err
|
||||
}
|
||||
return client.GetWithProof(key, node, cert)
|
||||
return client.GetWithProof(key, height, node, cert)
|
||||
}
|
||||
|
||||
// ParseHexKey parses the key flag as hex and converts to bytes or returns error
|
||||
|
|
|
@ -28,7 +28,7 @@ func keyQueryCmd(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||
|
||||
val, h, err := Get(key, prove)
|
||||
val, h, err := Get(key, GetHeight(), prove)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -17,10 +17,17 @@ import (
|
|||
// If there is any error in checking, returns an error.
|
||||
// If val is non-empty, proof should be KeyExistsProof
|
||||
// If val is empty, proof should be KeyMissingProof
|
||||
func GetWithProof(key []byte, node client.Client, cert certifiers.Certifier) (
|
||||
func GetWithProof(key []byte, reqHeight int, node client.Client,
|
||||
cert certifiers.Certifier) (
|
||||
val data.Bytes, height uint64, proof iavl.KeyProof, err error) {
|
||||
|
||||
resp, err := node.ABCIQuery("/key", key, true)
|
||||
if reqHeight < 0 {
|
||||
err = errors.Errorf("Height cannot be negative")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := node.ABCIQueryWithOptions("/key", key,
|
||||
client.ABCIQueryOptions{Height: uint64(reqHeight)})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ func TestAppProofs(t *testing.T) {
|
|||
require.NoError(err, "%+v", err)
|
||||
require.EqualValues(0, br.CheckTx.Code, "%#v", br.CheckTx)
|
||||
require.EqualValues(0, br.DeliverTx.Code)
|
||||
brh := br.Height
|
||||
|
||||
// This sets up our trust on the node based on some past point.
|
||||
source := certclient.New(cl)
|
||||
|
@ -71,7 +72,14 @@ func TestAppProofs(t *testing.T) {
|
|||
// Test existing key.
|
||||
var data eyes.Data
|
||||
|
||||
bs, height, proof, err := GetWithProof(k, cl, cert)
|
||||
// verify a query before the tx block has no data (and valid non-exist proof)
|
||||
bs, height, proof, err := GetWithProof(k, brh-1, cl, cert)
|
||||
require.NotNil(err)
|
||||
require.True(lc.IsNoDataErr(err))
|
||||
require.Nil(bs)
|
||||
|
||||
// but given that block it is good
|
||||
bs, height, proof, err = GetWithProof(k, brh, cl, cert)
|
||||
require.NoError(err, "%+v", err)
|
||||
require.NotNil(proof)
|
||||
require.True(height >= uint64(latest.Header.Height))
|
||||
|
@ -89,7 +97,7 @@ func TestAppProofs(t *testing.T) {
|
|||
|
||||
// Test non-existing key.
|
||||
missing := []byte("my-missing-key")
|
||||
bs, _, proof, err = GetWithProof(missing, cl, cert)
|
||||
bs, _, proof, err = GetWithProof(missing, 0, cl, cert)
|
||||
require.True(lc.IsNoDataErr(err))
|
||||
require.Nil(bs)
|
||||
require.NotNil(proof)
|
||||
|
|
|
@ -40,10 +40,10 @@ test01SendTx() {
|
|||
HASH=$(echo $TX | jq .hash | tr -d \")
|
||||
TX_HEIGHT=$(echo $TX | jq .height)
|
||||
|
||||
checkAccount $SENDER "9007199254740000"
|
||||
checkAccount $SENDER "9007199254740000" "$TX_HEIGHT"
|
||||
# make sure 0x prefix also works
|
||||
checkAccount "0x$SENDER" "9007199254740000"
|
||||
checkAccount $RECV "992"
|
||||
checkAccount "0x$SENDER" "9007199254740000" "$TX_HEIGHT"
|
||||
checkAccount $RECV "992" "$TX_HEIGHT"
|
||||
|
||||
# Make sure tx is indexed
|
||||
checkSendTx $HASH $TX_HEIGHT $SENDER "992"
|
||||
|
@ -60,8 +60,8 @@ test02SendTxWithFee() {
|
|||
TX_HEIGHT=$(echo $TX | jq .height)
|
||||
|
||||
# deduct 100 from sender, add 90 to receiver... fees "vanish"
|
||||
checkAccount $SENDER "9007199254739900"
|
||||
checkAccount $RECV "1082"
|
||||
checkAccount $SENDER "9007199254739900" "$TX_HEIGHT"
|
||||
checkAccount $RECV "1082" "$TX_HEIGHT"
|
||||
|
||||
# Make sure tx is indexed
|
||||
checkSendFeeTx $HASH $TX_HEIGHT $SENDER "90" "10"
|
||||
|
@ -71,8 +71,8 @@ test02SendTxWithFee() {
|
|||
assertFalse "line=${LINENO}, replay: $TX" $?
|
||||
|
||||
# checking normally
|
||||
checkAccount $SENDER "9007199254739900"
|
||||
checkAccount $RECV "1082"
|
||||
checkAccount $SENDER "9007199254739900" "$TX_HEIGHT"
|
||||
checkAccount $RECV "1082" "$TX_HEIGHT"
|
||||
|
||||
# make sure we can query the proper nonce
|
||||
NONCE=$(${CLIENT_EXE} query nonce $SENDER)
|
||||
|
@ -89,8 +89,8 @@ test02SendTxWithFee() {
|
|||
export BC_TRUST_NODE=1
|
||||
export BC_NODE=localhost:46657
|
||||
checkSendFeeTx $HASH $TX_HEIGHT $SENDER "90" "10"
|
||||
checkAccount $SENDER "9007199254739900"
|
||||
checkAccount $RECV "1082"
|
||||
checkAccount $SENDER "9007199254739900" "$TX_HEIGHT"
|
||||
checkAccount $RECV "1082" "$TX_HEIGHT"
|
||||
unset BC_TRUST_NODE
|
||||
unset BC_NODE
|
||||
export BC_HOME=$OLD_BC_HOME
|
||||
|
@ -109,8 +109,8 @@ test03CreditTx() {
|
|||
TX_HEIGHT=$(echo $TX | jq .height)
|
||||
|
||||
# receiver got cash, sender didn't lose any (1000 more than last check)
|
||||
checkAccount $RECV "2082"
|
||||
checkAccount $SENDER "9007199254739900"
|
||||
checkAccount $RECV "2082" "$TX_HEIGHT"
|
||||
checkAccount $SENDER "9007199254739900" "$TX_HEIGHT"
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -184,20 +184,21 @@ test04SendIBCPacket() {
|
|||
TX_HEIGHT=$(echo $TX | jq .height)
|
||||
|
||||
# Make sure balance went down and tx is indexed
|
||||
checkAccount $SENDER "9007199254720990"
|
||||
checkAccount $SENDER "9007199254720990" "$TX_HEIGHT"
|
||||
checkSendTx $HASH $TX_HEIGHT $SENDER "20002"
|
||||
|
||||
# look, we wrote a packet
|
||||
PACKETS=$(${CLIENT_EXE} query ibc packets --to=$CHAIN_ID_2)
|
||||
PACKETS=$(${CLIENT_EXE} query ibc packets --to=$CHAIN_ID_2 --height=$TX_HEIGHT)
|
||||
assertTrue "line=${LINENO}, packets query" $?
|
||||
assertEquals "line=${LINENO}, packet count" 1 $(echo $PACKETS | jq .data)
|
||||
|
||||
# and look at the packet itself
|
||||
PACKET=$(${CLIENT_EXE} query ibc packet --to=$CHAIN_ID_2 --sequence=0)
|
||||
PACKET=$(${CLIENT_EXE} query ibc packet --to=$CHAIN_ID_2 --sequence=0 --height=$TX_HEIGHT)
|
||||
assertTrue "line=${LINENO}, packet query" $?
|
||||
assertEquals "line=${LINENO}, proper src" "\"$CHAIN_ID_1\"" $(echo $PACKET | jq .src_chain)
|
||||
assertEquals "line=${LINENO}, proper dest" "\"$CHAIN_ID_2\"" $(echo $PACKET | jq .packet.dest_chain)
|
||||
assertEquals "line=${LINENO}, proper sequence" "0" $(echo $PACKET | jq .packet.sequence)
|
||||
if [ -n "$DEBUG" ]; then echo $PACKET; echo; fi
|
||||
|
||||
# nothing arrived
|
||||
ARRIVED=$(${CLIENT_EXE} query ibc packets --from=$CHAIN_ID_1 --home=$CLIENT_2 2>/dev/null)
|
||||
|
@ -207,52 +208,65 @@ test04SendIBCPacket() {
|
|||
|
||||
test05ReceiveIBCPacket() {
|
||||
export BC_HOME=${CLIENT_2}
|
||||
RECV=$(getAddr $POOR)
|
||||
|
||||
# make some credit, so we can accept the packet
|
||||
TX=$(echo qwertyuiop | ${CLIENT_EXE} tx credit --amount=60006mycoin --to=$CHAIN_ID_1:: --name=$RICH)
|
||||
txSucceeded $? "$TX" "${CHAIN_ID_1}::"
|
||||
checkAccount $CHAIN_ID_1:: "60006"
|
||||
TX_HEIGHT=$(echo $TX | jq .height)
|
||||
|
||||
# make sure there is enough credit
|
||||
checkAccount $CHAIN_ID_1:: "60006" "$TX_HEIGHT"
|
||||
# and the poor guy doesn't have a penny to his name
|
||||
ACCT2=$(${CLIENT_EXE} query account $RECV 2>/dev/null)
|
||||
assertFalse "line=${LINENO}, has no genesis account" $?
|
||||
|
||||
|
||||
# now, we try to post it.... (this is PACKET from last test)
|
||||
|
||||
# get the seed and post it
|
||||
# get the seed with the proof and post it
|
||||
SRC_HEIGHT=$(echo $PACKET | jq .src_height)
|
||||
PROOF_HEIGHT=$(expr $SRC_HEIGHT + 1)
|
||||
# FIXME: this should auto-update on proofs...
|
||||
${CLIENT_EXE} seeds update --height=$SRC_HEIGHT --home=${CLIENT_1} > /dev/null
|
||||
${CLIENT_EXE} seeds update --height=$PROOF_HEIGHT --home=${CLIENT_1} > /dev/null
|
||||
assertTrue "line=${LINENO}, update seed failed" $?
|
||||
|
||||
PACKET_SEED="$BASE_DIR_1/packet_seed.json"
|
||||
${CLIENT_EXE} seeds export $PACKET_SEED --home=${CLIENT_1} #--height=$SRC_HEIGHT
|
||||
${CLIENT_EXE} seeds export $PACKET_SEED --home=${CLIENT_1} --height=$PROOF_HEIGHT
|
||||
assertTrue "line=${LINENO}, export seed failed" $?
|
||||
# echo "**** SEED ****"
|
||||
# cat $PACKET_SEED | jq .
|
||||
if [ -n "$DEBUG" ]; then
|
||||
echo "**** SEED ****"
|
||||
cat $PACKET_SEED | jq .checkpoint.header
|
||||
echo
|
||||
fi
|
||||
|
||||
TX=$(echo qwertyuiop | ${CLIENT_EXE} tx ibc-update \
|
||||
--seed=${PACKET_SEED} --name=$POOR)
|
||||
--seed=${PACKET_SEED} --name=$POOR --sequence=3)
|
||||
txSucceeded $? "$TX" "prepare packet chain1 on chain 2"
|
||||
# an example to quit early if there is no point in more tests
|
||||
if [ $? != 0 ]; then echo "aborting!"; return 1; fi
|
||||
TX_HEIGHT=$(echo $TX | jq .height)
|
||||
|
||||
# write the packet to the file
|
||||
POST_PACKET="$BASE_DIR_1/post_packet.json"
|
||||
echo $PACKET > $POST_PACKET
|
||||
# echo "**** POST ****"
|
||||
# cat $POST_PACKET | jq .
|
||||
|
||||
# post it as a tx (cross-fingers)
|
||||
TX=$(echo qwertyuiop | ${CLIENT_EXE} tx ibc-post \
|
||||
--packet=${POST_PACKET} --name=$POOR)
|
||||
--packet=${POST_PACKET} --name=$POOR --sequence=4)
|
||||
txSucceeded $? "$TX" "post packet from chain1 on chain 2"
|
||||
TX_HEIGHT=$(echo $TX | jq .height)
|
||||
|
||||
# TODO: more queries on stuff...
|
||||
# ensure $POOR balance was incremented, and credit for CHAIN_1 decremented
|
||||
checkAccount $CHAIN_ID_1:: "40004" "$TX_HEIGHT"
|
||||
checkAccount $RECV "20002" "$TX_HEIGHT"
|
||||
|
||||
# look, we wrote a packet
|
||||
PACKETS=$(${CLIENT_EXE} query ibc packets --from=$CHAIN_ID_1)
|
||||
PACKETS=$(${CLIENT_EXE} query ibc packets --height=$TX_HEIGHT --from=$CHAIN_ID_1)
|
||||
assertTrue "line=${LINENO}, packets query" $?
|
||||
assertEquals "line=${LINENO}, packet count" 1 $(echo $PACKETS | jq .data)
|
||||
}
|
||||
|
||||
|
||||
# XXX Ex Usage: assertNewHeight $MSG $SEED_1 $SEED_2
|
||||
# Desc: Asserts that seed2 has a higher block height than seed 1
|
||||
assertNewHeight() {
|
||||
|
@ -262,95 +276,6 @@ assertNewHeight() {
|
|||
return $?
|
||||
}
|
||||
|
||||
# test01SendIBCTx() {
|
||||
# # Trigger a cross-chain sendTx... from RICH on chain1 to POOR on chain2
|
||||
# # we make sure the money was reduced, but nothing arrived
|
||||
# SENDER=$(BC_HOME=${CLIENT_1} getAddr $RICH)
|
||||
# RECV=$(BC_HOME=${CLIENT_2} getAddr $POOR)
|
||||
|
||||
# export BC_HOME=${CLIENT_1}
|
||||
# TX=$(echo qwertyuiop | ${CLIENT_EXE} tx send --amount=20002mycoin \
|
||||
# --sequence=1 --to=${CHAIN_ID_2}/${RECV} --name=$RICH)
|
||||
# txSucceeded $? "$TX" "${CHAIN_ID_2}/${RECV}"
|
||||
# # an example to quit early if there is no point in more tests
|
||||
# if [ $? != 0 ]; then echo "aborting!"; return 1; fi
|
||||
|
||||
# HASH=$(echo $TX | jq .hash | tr -d \")
|
||||
# TX_HEIGHT=$(echo $TX | jq .height)
|
||||
|
||||
# # Make sure balance went down and tx is indexed
|
||||
# checkAccount $SENDER "1" "9007199254720990"
|
||||
# checkSendTx $HASH $TX_HEIGHT $SENDER "20002"
|
||||
|
||||
# # Make sure nothing arrived - yet
|
||||
# waitForBlock ${PORT_1}
|
||||
# assertFalse "line=${LINENO}, no relay running" "BC_HOME=${CLIENT_2} ${CLIENT_EXE} query account $RECV"
|
||||
|
||||
# # Start the relay and wait a few blocks...
|
||||
# # (already sent a tx on chain1, so use higher sequence)
|
||||
# startRelay 2 1
|
||||
# if [ $? != 0 ]; then echo "can't start relay"; cat ${BASE_DIR_1}/../relay.log; return 1; fi
|
||||
|
||||
# # Give it a little time, then make sure the money arrived
|
||||
# echo "waiting for relay..."
|
||||
# sleep 1
|
||||
# waitForBlock ${PORT_1}
|
||||
# waitForBlock ${PORT_2}
|
||||
|
||||
# # Check the new account
|
||||
# echo "checking ibc recipient..."
|
||||
# BC_HOME=${CLIENT_2} checkAccount $RECV "0" "20002"
|
||||
|
||||
# # Stop relay
|
||||
# printf "stoping relay\n"
|
||||
# kill -9 $PID_RELAY
|
||||
# }
|
||||
|
||||
# # StartRelay $seq1 $seq2
|
||||
# # startRelay hooks up a relay between chain1 and chain2
|
||||
# # it needs the proper sequence number for $RICH on chain1 and chain2 as args
|
||||
# startRelay() {
|
||||
# # Send some cash to the default key, so it can send messages
|
||||
# RELAY_KEY=${BASE_DIR_1}/server/key.json
|
||||
# RELAY_ADDR=$(cat $RELAY_KEY | jq .address | tr -d \")
|
||||
# echo starting relay $PID_RELAY ...
|
||||
|
||||
# # Get paid on chain1
|
||||
# export BC_HOME=${CLIENT_1}
|
||||
# SENDER=$(getAddr $RICH)
|
||||
# RES=$(echo qwertyuiop | ${CLIENT_EXE} tx send --amount=100000mycoin \
|
||||
# --sequence=$1 --to=$RELAY_ADDR --name=$RICH)
|
||||
# txSucceeded $? "$RES" "$RELAY_ADDR"
|
||||
# if [ $? != 0 ]; then echo "can't pay chain1!"; return 1; fi
|
||||
|
||||
# # Get paid on chain2
|
||||
# export BC_HOME=${CLIENT_2}
|
||||
# SENDER=$(getAddr $RICH)
|
||||
# RES=$(echo qwertyuiop | ${CLIENT_EXE} tx send --amount=100000mycoin \
|
||||
# --sequence=$2 --to=$RELAY_ADDR --name=$RICH)
|
||||
# txSucceeded $? "$RES" "$RELAY_ADDR"
|
||||
# if [ $? != 0 ]; then echo "can't pay chain2!"; return 1; fi
|
||||
|
||||
# # Initialize the relay (register both chains)
|
||||
# ${SERVER_EXE} relay init --chain1-id=$CHAIN_ID_1 --chain2-id=$CHAIN_ID_2 \
|
||||
# --chain1-addr=tcp://localhost:${PORT_1} --chain2-addr=tcp://localhost:${PORT_2} \
|
||||
# --genesis1=${BASE_DIR_1}/server/genesis.json --genesis2=${BASE_DIR_2}/server/genesis.json \
|
||||
# --from=$RELAY_KEY > ${BASE_DIR_1}/../relay.log
|
||||
# if [ $? != 0 ]; then echo "can't initialize relays"; cat ${BASE_DIR_1}/../relay.log; return 1; fi
|
||||
|
||||
# # Now start the relay (constantly send packets)
|
||||
# ${SERVER_EXE} relay start --chain1-id=$CHAIN_ID_1 --chain2-id=$CHAIN_ID_2 \
|
||||
# --chain1-addr=tcp://localhost:${PORT_1} --chain2-addr=tcp://localhost:${PORT_2} \
|
||||
# --from=$RELAY_KEY >> ${BASE_DIR_1}/../relay.log &
|
||||
# sleep 2
|
||||
# PID_RELAY=$!
|
||||
# disown
|
||||
|
||||
# # Return an error if it dies in the first two seconds to make sure it is running
|
||||
# ps $PID_RELAY >/dev/null
|
||||
# return $?
|
||||
# }
|
||||
|
||||
# Load common then run these tests with shunit2!
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" #get this files directory
|
||||
CLI_DIR=$GOPATH/src/github.com/cosmos/cosmos-sdk/tests/cli
|
||||
|
|
|
@ -15,9 +15,9 @@ oneTimeSetUp() {
|
|||
exit 1;
|
||||
fi
|
||||
baseserver serve --port $BPORT >/dev/null &
|
||||
sleep 0.1 # for startup
|
||||
PID_PROXY=$!
|
||||
disown
|
||||
sleep 0.1 # for startup
|
||||
}
|
||||
|
||||
oneTimeTearDown() {
|
||||
|
@ -35,12 +35,16 @@ restAddr() {
|
|||
echo $ADDR
|
||||
}
|
||||
|
||||
# XXX Ex Usage: restAccount $ADDR $AMOUNT
|
||||
# XXX Ex Usage: restAccount $ADDR $AMOUNT [$HEIGHT]
|
||||
# Desc: Assumes just one coin, checks the balance of first coin in any case
|
||||
restAccount() {
|
||||
assertNotNull "line=${LINENO}, address required" "$1"
|
||||
ACCT=$(curl ${URL}/query/account/sigs:$1 2>/dev/null)
|
||||
if [ -n "$DEBUG" ]; then echo $ACCT; echo; fi
|
||||
QUERY=${URL}/query/account/sigs:$1
|
||||
if [ -n "$3" ]; then
|
||||
QUERY="${QUERY}?height=${3}"
|
||||
fi
|
||||
ACCT=$(curl ${QUERY} 2>/dev/null)
|
||||
if [ -n "$DEBUG" ]; then echo $QUERY; echo $ACCT; echo; fi
|
||||
assertEquals "line=${LINENO}, proper money" "$2" $(echo $ACCT | jq .data.coins[0].amount)
|
||||
return $?
|
||||
}
|
||||
|
@ -76,8 +80,8 @@ test01SendTx() {
|
|||
HASH=$(echo $TX | jq .hash | tr -d \")
|
||||
TX_HEIGHT=$(echo $TX | jq .height)
|
||||
|
||||
restAccount $SENDER "9007199254740000"
|
||||
restAccount $RECV "992"
|
||||
restAccount $SENDER "9007199254740000" "$TX_HEIGHT"
|
||||
restAccount $RECV "992" "$TX_HEIGHT"
|
||||
|
||||
# Make sure tx is indexed
|
||||
checkSendTx $HASH $TX_HEIGHT $SENDER "992"
|
||||
|
@ -126,8 +130,8 @@ test04CreateRoleInvalid() {
|
|||
# TX_HEIGHT=$(echo $TX | jq .height)
|
||||
|
||||
# # deduct 100 from sender, add 90 to receiver... fees "vanish"
|
||||
# checkAccount $SENDER "9007199254739900"
|
||||
# checkAccount $RECV "1082"
|
||||
# checkAccount $SENDER "9007199254739900" "$TX_HEIGHT"
|
||||
# checkAccount $RECV "1082" "$TX_HEIGHT"
|
||||
|
||||
# # Make sure tx is indexed
|
||||
# checkSendFeeTx $HASH $TX_HEIGHT $SENDER "90" "10"
|
||||
|
@ -135,8 +139,8 @@ test04CreateRoleInvalid() {
|
|||
# # assert replay protection
|
||||
# TX=$(echo qwertyuiop | ${CLIENT_EXE} tx send --amount=90mycoin --fee=10mycoin --sequence=2 --to=$RECV --name=$RICH 2>/dev/null)
|
||||
# assertFalse "line=${LINENO}, replay: $TX" $?
|
||||
# checkAccount $SENDER "9007199254739900"
|
||||
# checkAccount $RECV "1082"
|
||||
# checkAccount $SENDER "9007199254739900" "$TX_HEIGHT"
|
||||
# checkAccount $RECV "1082" "$TX_HEIGHT"
|
||||
|
||||
# # make sure we can query the proper nonce
|
||||
# NONCE=$(${CLIENT_EXE} query nonce $SENDER)
|
||||
|
|
|
@ -26,8 +26,8 @@ test00PreRestart() {
|
|||
HASH=$(echo $TX | jq .hash | tr -d \")
|
||||
TX_HEIGHT=$(echo $TX | jq .height)
|
||||
|
||||
checkAccount $SENDER "9007199254740000"
|
||||
checkAccount $RECV "992"
|
||||
checkAccount $SENDER "9007199254740000" "$TX_HEIGHT"
|
||||
checkAccount $RECV "992" "$TX_HEIGHT"
|
||||
|
||||
# make sure tx is indexed
|
||||
checkSendTx $HASH $TX_HEIGHT $SENDER "992"
|
||||
|
|
|
@ -35,7 +35,7 @@ test01SetupRole() {
|
|||
HASH=$(echo $TX | jq .hash | tr -d \")
|
||||
TX_HEIGHT=$(echo $TX | jq .height)
|
||||
|
||||
checkRole "${ROLE}" $SIGS 3
|
||||
checkRole "${ROLE}" $SIGS 3 "$TX_HEIGHT"
|
||||
|
||||
# Make sure tx is indexed
|
||||
checkRoleTx $HASH $TX_HEIGHT "${ROLE}" 3
|
||||
|
@ -51,8 +51,8 @@ test02SendTxToRole() {
|
|||
TX_HEIGHT=$(echo $TX | jq .height)
|
||||
|
||||
# reduce by 10090
|
||||
checkAccount $SENDER "9007199254730902"
|
||||
checkAccount $RECV "10000"
|
||||
checkAccount $SENDER "9007199254730902" "$TX_HEIGHT"
|
||||
checkAccount $RECV "10000" "$TX_HEIGHT"
|
||||
|
||||
checkSendFeeTx $HASH $TX_HEIGHT $SENDER "10000" "90"
|
||||
}
|
||||
|
@ -82,9 +82,10 @@ test03SendMultiFromRole() {
|
|||
# and get some dude to sign it for the full access
|
||||
TX=$(echo qwertyuiop | ${CLIENT_EXE} tx --in=$TX_FILE --name=$DUDE)
|
||||
txSucceeded $? "$TX" "multi-bank"
|
||||
TX_HEIGHT=$(echo $TX | jq .height)
|
||||
|
||||
checkAccount $TWO "6000"
|
||||
checkAccount $BANK "4000"
|
||||
checkAccount $TWO "6000" "$TX_HEIGHT"
|
||||
checkAccount $BANK "4000" "$TX_HEIGHT"
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ func counterQueryCmd(cmd *cobra.Command, args []string) error {
|
|||
|
||||
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||
key := stack.PrefixedKey(counter.NameCounter, counter.StateKey())
|
||||
h, err := query.GetParsed(key, &cp, prove)
|
||||
h, err := query.GetParsed(key, &cp, query.GetHeight(), prove)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -41,8 +41,8 @@ test01SendTx() {
|
|||
HASH=$(echo $TX | jq .hash | tr -d \")
|
||||
TX_HEIGHT=$(echo $TX | jq .height)
|
||||
|
||||
checkAccount $SENDER "9007199254740000"
|
||||
checkAccount $RECV "992"
|
||||
checkAccount $SENDER "9007199254740000" "$TX_HEIGHT"
|
||||
checkAccount $RECV "992" "$TX_HEIGHT"
|
||||
|
||||
# make sure tx is indexed
|
||||
checkSendTx $HASH $TX_HEIGHT $SENDER "992"
|
||||
|
@ -53,11 +53,15 @@ test02GetCounter() {
|
|||
assertFalse "Line=${LINENO}, no default count" $?
|
||||
}
|
||||
|
||||
# checkCounter $COUNT $BALANCE
|
||||
# checkCounter $COUNT $BALANCE [$HEIGHT]
|
||||
# Assumes just one coin, checks the balance of first coin in any case
|
||||
# pass optional height to query which block to query
|
||||
checkCounter() {
|
||||
# default height of 0, but accept an argument
|
||||
HEIGHT=${3:-0}
|
||||
|
||||
# make sure sender goes down
|
||||
ACCT=$(${CLIENT_EXE} query counter)
|
||||
ACCT=$(${CLIENT_EXE} query counter --height=$HEIGHT)
|
||||
if assertTrue "Line=${LINENO}, count is set" $?; then
|
||||
assertEquals "Line=${LINENO}, proper count" "$1" $(echo $ACCT | jq .data.counter)
|
||||
assertEquals "Line=${LINENO}, proper money" "$2" $(echo $ACCT | jq .data.total_fees[0].amount)
|
||||
|
@ -74,10 +78,10 @@ test03AddCount() {
|
|||
TX_HEIGHT=$(echo $TX | jq .height)
|
||||
|
||||
# make sure the counter was updated
|
||||
checkCounter "1" "10"
|
||||
checkCounter "1" "10" "$TX_HEIGHT"
|
||||
|
||||
# make sure the account was debited
|
||||
checkAccount $SENDER "9007199254739990"
|
||||
checkAccount $SENDER "9007199254739990" "$TX_HEIGHT"
|
||||
|
||||
# make sure tx is indexed
|
||||
TX=$(${CLIENT_EXE} query tx $HASH --trace)
|
||||
|
@ -96,18 +100,20 @@ test03AddCount() {
|
|||
# test again with fees...
|
||||
TX=$(echo qwertyuiop | ${CLIENT_EXE} tx counter --countfee=7mycoin --fee=4mycoin --sequence=3 --name=${RICH} --valid)
|
||||
txSucceeded $? "$TX" "counter"
|
||||
TX_HEIGHT=$(echo $TX | jq .height)
|
||||
|
||||
# make sure the counter was updated, added 7
|
||||
checkCounter "2" "17"
|
||||
|
||||
checkCounter "2" "17" "$TX_HEIGHT"
|
||||
# make sure the account was debited 11
|
||||
checkAccount $SENDER "9007199254739979"
|
||||
checkAccount $SENDER "9007199254739979" "$TX_HEIGHT"
|
||||
|
||||
# make sure we cannot replay the counter, no state change
|
||||
TX=$(echo qwertyuiop | ${CLIENT_EXE} tx counter --countfee=10mycoin --sequence=2 --name=${RICH} --valid 2>/dev/null)
|
||||
assertFalse "line=${LINENO}, replay: $TX" $?
|
||||
checkCounter "2" "17"
|
||||
checkAccount $SENDER "9007199254739979"
|
||||
TX_HEIGHT=$(echo $TX | jq .height)
|
||||
|
||||
checkCounter "2" "17" "$TX_HEIGHT"
|
||||
checkAccount $SENDER "9007199254739979" "$TX_HEIGHT"
|
||||
}
|
||||
|
||||
# Load common then run these tests with shunit2!
|
||||
|
|
|
@ -49,7 +49,7 @@ test00SetGetRemove() {
|
|||
TX_HEIGHT=$(echo $TXRES | jq .height)
|
||||
|
||||
# make sure it is set
|
||||
DATA=$(${CLIENT_EXE} query eyes ${KEY})
|
||||
DATA=$(${CLIENT_EXE} query eyes ${KEY} --height=$TX_HEIGHT)
|
||||
assertTrue "line=${LINENO} data not set" $?
|
||||
assertEquals "line=${LINENO}" "\"${VALUE}\"" $(echo $DATA | jq .data.value)
|
||||
|
||||
|
|
|
@ -10,6 +10,10 @@ import (
|
|||
cmn "github.com/tendermint/tmlibs/common"
|
||||
)
|
||||
|
||||
// KeyDelimiter is used to separate module and key in
|
||||
// the options
|
||||
const KeyDelimiter = "/"
|
||||
|
||||
// Option just holds module/key/value triples from
|
||||
// parsing the genesis file
|
||||
type Option struct {
|
||||
|
@ -54,22 +58,18 @@ func GetOptions(path string) ([]Option, error) {
|
|||
|
||||
opts := genDoc.AppOptions
|
||||
cnt := 1 + len(opts.Accounts) + len(opts.pluginOptions)
|
||||
res := make([]Option, cnt)
|
||||
|
||||
res[0] = Option{sdk.ModuleNameBase, sdk.ChainKey, genDoc.ChainID}
|
||||
i := 1
|
||||
res := make([]Option, 0, cnt)
|
||||
res = append(res, Option{sdk.ModuleNameBase, sdk.ChainKey, genDoc.ChainID})
|
||||
|
||||
// set accounts
|
||||
for _, acct := range opts.Accounts {
|
||||
res[i] = Option{"coin", "account", string(acct)}
|
||||
i++
|
||||
res = append(res, Option{"coin", "account", string(acct)})
|
||||
}
|
||||
|
||||
// set plugin options
|
||||
for _, kv := range opts.pluginOptions {
|
||||
module, key := splitKey(kv.Key)
|
||||
res[i] = Option{module, key, kv.Value}
|
||||
i++
|
||||
res = append(res, Option{module, key, kv.Value})
|
||||
}
|
||||
|
||||
return res, nil
|
||||
|
@ -145,8 +145,8 @@ func parseList(kvzIn []json.RawMessage) (kvz []keyValue, err error) {
|
|||
// Splits the string at the first '/'.
|
||||
// if there are none, assign default module ("base").
|
||||
func splitKey(key string) (string, string) {
|
||||
if strings.Contains(key, "/") {
|
||||
keyParts := strings.SplitN(key, "/", 2)
|
||||
if strings.Contains(key, KeyDelimiter) {
|
||||
keyParts := strings.SplitN(key, KeyDelimiter, 2)
|
||||
return keyParts[0], keyParts[1]
|
||||
}
|
||||
return sdk.ModuleNameBase, key
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
hash: 738b6ed5402dee4f77a7063db84011a2ef776cda203a9c843a9830c9d0458a89
|
||||
updated: 2017-10-11T17:06:42.651532377-04:00
|
||||
hash: fbfdd03c0367bb0785ceb81ed34059df219e55d5a9c71c12597e505fbce14165
|
||||
updated: 2017-10-23T14:49:22.891642342+02:00
|
||||
imports:
|
||||
- name: github.com/bgentry/speakeasy
|
||||
version: 4aabc24848ce5fd31929f7d1e4ea74d3709c14cd
|
||||
|
@ -11,10 +11,6 @@ imports:
|
|||
version: 637e656429416087660c84436a2a035d69d54e2e
|
||||
- name: github.com/BurntSushi/toml
|
||||
version: a368813c5e648fee92e5f6c30e3944ff9d5e8895
|
||||
- name: github.com/davecgh/go-spew
|
||||
version: 6d212800a42e8ab5c146b8ace3490ee17e5225f9
|
||||
subpackages:
|
||||
- spew
|
||||
- name: github.com/ebuchman/fail-test
|
||||
version: 95f809107225be108efcf10a3509e4ea6ceef3c4
|
||||
- name: github.com/fsnotify/fsnotify
|
||||
|
@ -79,10 +75,6 @@ imports:
|
|||
version: 13d49d4606eb801b8f01ae542b4afc4c6ee3d84a
|
||||
- name: github.com/pkg/errors
|
||||
version: 645ef00459ed84a119197bfb8d8205042c6df63d
|
||||
- name: github.com/pmezard/go-difflib
|
||||
version: d8ed2627bdf02c080bf22230dbb337003b7aba2d
|
||||
subpackages:
|
||||
- difflib
|
||||
- name: github.com/rcrowley/go-metrics
|
||||
version: 1f30fe9094a513ce4c700b9a54458bbb0c96996c
|
||||
- name: github.com/spf13/afero
|
||||
|
@ -99,11 +91,6 @@ imports:
|
|||
version: e57e3eeb33f795204c1ca35f56c44f83227c6e66
|
||||
- name: github.com/spf13/viper
|
||||
version: 0967fc9aceab2ce9da34061253ac10fb99bba5b2
|
||||
- name: github.com/stretchr/testify
|
||||
version: 69483b4bd14f5845b5a1e55bca19e954e827f1d0
|
||||
subpackages:
|
||||
- assert
|
||||
- require
|
||||
- name: github.com/syndtr/goleveldb
|
||||
version: 8c81ea47d4c41a385645e133e15510fc6a2a74b4
|
||||
subpackages:
|
||||
|
@ -120,7 +107,7 @@ imports:
|
|||
- leveldb/table
|
||||
- leveldb/util
|
||||
- name: github.com/tendermint/abci
|
||||
version: 15cd7fb1e3b75c436b6dee89a44db35f3d265bd0
|
||||
version: bb9bb4aa465a31fd6a272765be381888e6898c74
|
||||
subpackages:
|
||||
- client
|
||||
- example/dummy
|
||||
|
@ -132,33 +119,30 @@ imports:
|
|||
- edwards25519
|
||||
- extra25519
|
||||
- name: github.com/tendermint/go-crypto
|
||||
version: 0418d32276d7d0f080e4c0e58b49c6ba2f717954
|
||||
version: 8e7f0e7701f92206679ad093d013b9b162427631
|
||||
subpackages:
|
||||
- bcrypt
|
||||
- keys
|
||||
- keys/cryptostore
|
||||
- keys/storage/filestorage
|
||||
- keys/storage/memstorage
|
||||
- keys/wordlist
|
||||
- name: github.com/tendermint/go-wire
|
||||
version: 26ee079df7fca1958da8995c727b59759b197534
|
||||
version: 55ae61f1fc83cfaa57ab7d54250d7a1a2be0b83c
|
||||
subpackages:
|
||||
- data
|
||||
- data/base58
|
||||
- name: github.com/tendermint/iavl
|
||||
version: 9233811d241ac8d4441a7223a4e79b83931dfae0
|
||||
version: 721710e7aa59f61dbfbf558943a207ba3fe6b926
|
||||
- name: github.com/tendermint/light-client
|
||||
version: ac2e4bf47b31aaf5d3d336691ac786ec751bfc32
|
||||
version: 569e1583da8a52e499764533f3a05d05be6d56d6
|
||||
subpackages:
|
||||
- certifiers
|
||||
- certifiers/client
|
||||
- certifiers/files
|
||||
- proofs
|
||||
- name: github.com/tendermint/merkleeyes
|
||||
version: 2f6e5d31e7a35045d8d0a5895cb1fec33dd4d32b
|
||||
subpackages:
|
||||
- iavl
|
||||
- name: github.com/tendermint/tendermint
|
||||
version: d4634dc6832a7168c2536e7c71bfba4a8ca857be
|
||||
version: fa56e8c0ce463f77c87ab17a3d7cf5431d9f2c0b
|
||||
subpackages:
|
||||
- blockchain
|
||||
- cmd/tendermint/commands
|
||||
|
@ -186,7 +170,7 @@ imports:
|
|||
- types
|
||||
- version
|
||||
- name: github.com/tendermint/tmlibs
|
||||
version: 7166252a521951eb8b6bd26db28b2b90586941a9
|
||||
version: 8e5266a9ef2527e68a1571f932db8228a331b556
|
||||
subpackages:
|
||||
- autofile
|
||||
- cli
|
||||
|
@ -199,10 +183,10 @@ imports:
|
|||
- log
|
||||
- logger
|
||||
- merkle
|
||||
- test
|
||||
- name: golang.org/x/crypto
|
||||
version: c7af5bf2638a1164f2eb5467c39c6cffbd13a02e
|
||||
subpackages:
|
||||
- blowfish
|
||||
- curve25519
|
||||
- nacl/box
|
||||
- nacl/secretbox
|
||||
|
@ -256,4 +240,17 @@ imports:
|
|||
version: 6d8c18553ea1ac493d049edd6f102f52e618f085
|
||||
- name: gopkg.in/yaml.v2
|
||||
version: cd8b52f8269e0feb286dfeef29f8fe4d5b397e0b
|
||||
testImports: []
|
||||
testImports:
|
||||
- name: github.com/davecgh/go-spew
|
||||
version: 6d212800a42e8ab5c146b8ace3490ee17e5225f9
|
||||
subpackages:
|
||||
- spew
|
||||
- name: github.com/pmezard/go-difflib
|
||||
version: d8ed2627bdf02c080bf22230dbb337003b7aba2d
|
||||
subpackages:
|
||||
- difflib
|
||||
- name: github.com/stretchr/testify
|
||||
version: 69483b4bd14f5845b5a1e55bca19e954e827f1d0
|
||||
subpackages:
|
||||
- assert
|
||||
- require
|
||||
|
|
|
@ -29,7 +29,7 @@ import:
|
|||
- package: github.com/tendermint/iavl
|
||||
version: develop
|
||||
- package: github.com/tendermint/tendermint
|
||||
version: 0.11.1
|
||||
version: develop
|
||||
subpackages:
|
||||
- config
|
||||
- node
|
||||
|
|
|
@ -34,7 +34,7 @@ func accountQueryCmd(cmd *cobra.Command, args []string) error {
|
|||
|
||||
acc := coin.Account{}
|
||||
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||
height, err := query.GetParsed(key, &acc, prove)
|
||||
height, err := query.GetParsed(key, &acc, query.GetHeight(), prove)
|
||||
if lc.IsNoDataErr(err) {
|
||||
return errors.Errorf("Account bytes are empty for address %s ", addr)
|
||||
} else if err != nil {
|
||||
|
|
|
@ -3,6 +3,7 @@ package rest
|
|||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
|
@ -32,7 +33,7 @@ type SendInput struct {
|
|||
|
||||
To *sdk.Actor `json:"to"`
|
||||
From *sdk.Actor `json:"from"`
|
||||
Amount coin.Coins `json:"amount"`
|
||||
Amount coin.Coins `json:"amount"`
|
||||
}
|
||||
|
||||
// doQueryAccount is the HTTP handlerfunc to query an account
|
||||
|
@ -45,11 +46,22 @@ func doQueryAccount(w http.ResponseWriter, r *http.Request) {
|
|||
common.WriteError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
var h int
|
||||
qHeight := r.URL.Query().Get("height")
|
||||
if qHeight != "" {
|
||||
h, err = strconv.Atoi(qHeight)
|
||||
if err != nil {
|
||||
common.WriteError(w, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
actor = coin.ChainAddr(actor)
|
||||
key := stack.PrefixedKey(coin.NameCoin, actor.Bytes())
|
||||
account := new(coin.Account)
|
||||
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||
height, err := query.GetParsed(key, account, prove)
|
||||
height, err := query.GetParsed(key, account, h, prove)
|
||||
if lightclient.IsNoDataErr(err) {
|
||||
err := fmt.Errorf("account bytes are empty for address: %q", signature)
|
||||
common.WriteError(w, err)
|
||||
|
@ -152,4 +164,3 @@ func RegisterAll(r *mux.Router) error {
|
|||
}
|
||||
|
||||
// End of mux.Router registrars
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ func eyesQueryCmd(cmd *cobra.Command, args []string) error {
|
|||
|
||||
key = stack.PrefixedKey(eyes.Name, key)
|
||||
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||
height, err := query.GetParsed(key, &res, prove)
|
||||
height, err := query.GetParsed(key, &res, query.GetHeight(), prove)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ func ibcQueryCmd(cmd *cobra.Command, args []string) error {
|
|||
var res ibc.HandlerInfo
|
||||
key := stack.PrefixedKey(ibc.NameIBC, ibc.HandlerKey())
|
||||
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||
h, err := query.GetParsed(key, &res, prove)
|
||||
h, err := query.GetParsed(key, &res, query.GetHeight(), prove)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ func chainsQueryCmd(cmd *cobra.Command, args []string) error {
|
|||
list := [][]byte{}
|
||||
key := stack.PrefixedKey(ibc.NameIBC, ibc.ChainsKey())
|
||||
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||
h, err := query.GetParsed(key, &list, prove)
|
||||
h, err := query.GetParsed(key, &list, query.GetHeight(), prove)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ func chainQueryCmd(cmd *cobra.Command, args []string) error {
|
|||
var res ibc.ChainInfo
|
||||
key := stack.PrefixedKey(ibc.NameIBC, ibc.ChainKey(arg))
|
||||
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||
h, err := query.GetParsed(key, &res, prove)
|
||||
h, err := query.GetParsed(key, &res, query.GetHeight(), prove)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -158,7 +158,7 @@ func packetsQueryCmd(cmd *cobra.Command, args []string) error {
|
|||
|
||||
var res uint64
|
||||
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||
h, err := query.GetParsed(key, &res, prove)
|
||||
h, err := query.GetParsed(key, &res, query.GetHeight(), prove)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -190,7 +190,7 @@ func packetQueryCmd(cmd *cobra.Command, args []string) error {
|
|||
// Input queue just display the results
|
||||
var packet ibc.Packet
|
||||
if from != "" {
|
||||
h, err := query.GetParsed(key, &packet, prove)
|
||||
h, err := query.GetParsed(key, &packet, query.GetHeight(), prove)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ func packetQueryCmd(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
|
||||
// output queue, create a post packet
|
||||
bs, height, proof, err := query.GetWithProof(key)
|
||||
bs, height, proof, err := query.GetWithProof(key, query.GetHeight())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -94,7 +94,10 @@ func (m Middleware) verifyPost(ctx sdk.Context, store state.SimpleDB,
|
|||
// look up the referenced header
|
||||
space := stack.PrefixedStore(from, store)
|
||||
provider := newDBProvider(space)
|
||||
seed, err := provider.GetExactHeight(int(tx.FromChainHeight))
|
||||
|
||||
// if the query was on height H, the proof is in header H+1
|
||||
proofHeight := int(tx.FromChainHeight + 1)
|
||||
seed, err := provider.GetExactHeight(proofHeight)
|
||||
if err != nil {
|
||||
return ictx, itx, err
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ import (
|
|||
type MockChain struct {
|
||||
keys certifiers.ValKeys
|
||||
chainID string
|
||||
tree *iavl.IAVLTree
|
||||
tree *iavl.Tree
|
||||
}
|
||||
|
||||
// NewMockChain initializes a teststore and test validators
|
||||
|
@ -26,7 +26,7 @@ func NewMockChain(chainID string, numKeys int) MockChain {
|
|||
return MockChain{
|
||||
keys: certifiers.GenValKeys(numKeys),
|
||||
chainID: chainID,
|
||||
tree: iavl.NewIAVLTree(0, nil),
|
||||
tree: iavl.NewTree(0, nil),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ func (m MockChain) MakePostPacket(packet Packet, h int) (
|
|||
PostPacketTx, UpdateChainTx) {
|
||||
|
||||
post := makePostPacket(m.tree, packet, m.chainID, h)
|
||||
seed := genEmptySeed(m.keys, m.chainID, h, m.tree.Hash(), len(m.keys))
|
||||
seed := genEmptySeed(m.keys, m.chainID, h+1, m.tree.Hash(), len(m.keys))
|
||||
update := UpdateChainTx{seed}
|
||||
|
||||
return post, update
|
||||
|
@ -56,7 +56,7 @@ func genEmptySeed(keys certifiers.ValKeys, chain string, h int,
|
|||
return certifiers.Seed{cp, vals}
|
||||
}
|
||||
|
||||
func makePostPacket(tree *iavl.IAVLTree, packet Packet, fromID string, fromHeight int) PostPacketTx {
|
||||
func makePostPacket(tree *iavl.Tree, packet Packet, fromID string, fromHeight int) PostPacketTx {
|
||||
key := []byte(fmt.Sprintf("some-long-prefix-%06d", packet.Sequence))
|
||||
tree.Set(key, packet.Bytes())
|
||||
_, proof, err := tree.GetWithProof(key)
|
||||
|
|
|
@ -113,6 +113,7 @@ type PostPacketTx struct {
|
|||
// The immediate source of the packet, not always Packet.SrcChainID
|
||||
FromChainID string `json:"src_chain"`
|
||||
// The block height in which Packet was committed, to check Proof
|
||||
// AppHash for the proof in header for FromChainHeight+1
|
||||
FromChainHeight uint64 `json:"src_height"`
|
||||
// this proof must match the header and the packet.Bytes()
|
||||
Proof *iavl.KeyExistsProof `json:"proof"`
|
||||
|
|
|
@ -45,7 +45,7 @@ func nonceQueryCmd(cmd *cobra.Command, args []string) error {
|
|||
func doNonceQuery(signers []sdk.Actor) (sequence uint32, height uint64, err error) {
|
||||
key := stack.PrefixedKey(nonce.NameNonce, nonce.GetSeqKey(signers))
|
||||
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||
height, err = query.GetParsed(key, &sequence, prove)
|
||||
height, err = query.GetParsed(key, &sequence, query.GetHeight(), prove)
|
||||
if lc.IsNoDataErr(err) {
|
||||
// no data, return sequence 0
|
||||
return 0, 0, nil
|
||||
|
|
|
@ -3,6 +3,7 @@ package rest
|
|||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/spf13/viper"
|
||||
|
@ -28,6 +29,17 @@ func doQueryNonce(w http.ResponseWriter, r *http.Request) {
|
|||
common.WriteError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
var h int
|
||||
qHeight := r.URL.Query().Get("height")
|
||||
if qHeight != "" {
|
||||
h, err = strconv.Atoi(qHeight)
|
||||
if err != nil {
|
||||
common.WriteError(w, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
actor = coin.ChainAddr(actor)
|
||||
key := nonce.GetSeqKey([]sdk.Actor{actor})
|
||||
key = stack.PrefixedKey(nonce.NameNonce, key)
|
||||
|
@ -35,7 +47,7 @@ func doQueryNonce(w http.ResponseWriter, r *http.Request) {
|
|||
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||
|
||||
// query sequence number
|
||||
data, height, err := query.Get(key, prove)
|
||||
data, height, err := query.Get(key, h, prove)
|
||||
if lightclient.IsNoDataErr(err) {
|
||||
err = fmt.Errorf("nonce empty for address: %q", signature)
|
||||
common.WriteError(w, err)
|
||||
|
|
|
@ -30,7 +30,7 @@ func roleQueryCmd(cmd *cobra.Command, args []string) error {
|
|||
var res roles.Role
|
||||
key := stack.PrefixedKey(roles.NameRole, role)
|
||||
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||
height, err := query.GetParsed(key, &res, prove)
|
||||
height, err := query.GetParsed(key, &res, query.GetHeight(), prove)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ func NewBonsai(tree *iavl.VersionedTree) *Bonsai {
|
|||
|
||||
// Get matches the signature of KVStore
|
||||
func (b *Bonsai) Get(key []byte) []byte {
|
||||
_, value, _ := b.Tree.Get(key)
|
||||
_, value := b.Tree.Get(key)
|
||||
return value
|
||||
}
|
||||
|
||||
|
|
|
@ -5,45 +5,65 @@ import "github.com/tendermint/iavl"
|
|||
// State represents the app states, separating the commited state (for queries)
|
||||
// from the working state (for CheckTx and AppendTx)
|
||||
type State struct {
|
||||
committed *Bonsai
|
||||
deliverTx SimpleDB
|
||||
checkTx SimpleDB
|
||||
committed *Bonsai
|
||||
deliverTx SimpleDB
|
||||
checkTx SimpleDB
|
||||
historySize uint64
|
||||
}
|
||||
|
||||
func NewState(tree *iavl.VersionedTree) *State {
|
||||
// NewState wraps a versioned tree and maintains all needed
|
||||
// states for the abci app
|
||||
func NewState(tree *iavl.VersionedTree, historySize uint64) *State {
|
||||
base := NewBonsai(tree)
|
||||
return &State{
|
||||
committed: base,
|
||||
deliverTx: base.Checkpoint(),
|
||||
checkTx: base.Checkpoint(),
|
||||
committed: base,
|
||||
deliverTx: base.Checkpoint(),
|
||||
checkTx: base.Checkpoint(),
|
||||
historySize: historySize,
|
||||
}
|
||||
}
|
||||
|
||||
// Size is the number of nodes in the last commit
|
||||
func (s State) Size() int {
|
||||
return s.committed.Tree.Size()
|
||||
}
|
||||
|
||||
// IsEmpty is true is no data was ever in the tree
|
||||
// (and signals it is unsafe to save)
|
||||
func (s State) IsEmpty() bool {
|
||||
return s.committed.Tree.IsEmpty()
|
||||
}
|
||||
|
||||
// Committed gives us read-only access to the committed
|
||||
// state(s), including historical queries
|
||||
func (s State) Committed() *Bonsai {
|
||||
return s.committed
|
||||
}
|
||||
|
||||
// Append gives us read-write access to the current working
|
||||
// state (to be committed at EndBlock)
|
||||
func (s State) Append() SimpleDB {
|
||||
return s.deliverTx
|
||||
}
|
||||
|
||||
// Append gives us read-write access to the current scratch
|
||||
// state (to be reset at EndBlock)
|
||||
func (s State) Check() SimpleDB {
|
||||
return s.checkTx
|
||||
}
|
||||
|
||||
// LatestHeight is the last block height we have committed
|
||||
func (s State) LatestHeight() uint64 {
|
||||
return s.committed.Tree.LatestVersion()
|
||||
}
|
||||
|
||||
// LatestHash is the root hash of the last state we have
|
||||
// committed
|
||||
func (s State) LatestHash() []byte {
|
||||
return s.committed.Tree.Hash()
|
||||
}
|
||||
|
||||
// Commit save persistent nodes to the database and re-copies the trees
|
||||
// Commit saves persistent nodes to the database and re-copies the trees
|
||||
func (s *State) Commit(version uint64) ([]byte, error) {
|
||||
// commit (if we didn't do hash earlier)
|
||||
err := s.committed.Commit(s.deliverTx)
|
||||
|
@ -51,14 +71,20 @@ func (s *State) Commit(version uint64) ([]byte, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// store a new version
|
||||
var hash []byte
|
||||
if s.committed.Tree.Size() > 0 || s.committed.Tree.LatestVersion() > 0 {
|
||||
if !s.IsEmpty() {
|
||||
hash, err = s.committed.Tree.SaveVersion(version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// release an old version
|
||||
if version > s.historySize {
|
||||
s.committed.Tree.DeleteVersion(version - s.historySize)
|
||||
}
|
||||
|
||||
s.deliverTx = s.committed.Checkpoint()
|
||||
s.checkTx = s.committed.Checkpoint()
|
||||
return hash, nil
|
||||
|
|
|
@ -66,7 +66,7 @@ func TestStateCommitHash(t *testing.T) {
|
|||
|
||||
// make the store...
|
||||
tree := iavl.NewVersionedTree(0, db.NewMemDB())
|
||||
store := NewState(tree)
|
||||
store := NewState(tree, 2)
|
||||
|
||||
for n, r := range tc.rounds {
|
||||
// start the cache
|
||||
|
|
|
@ -124,11 +124,15 @@ getAddr() {
|
|||
echo $RAW | cut -d' ' -f2
|
||||
}
|
||||
|
||||
# XXX Ex Usage: checkAccount $ADDR $AMOUNT
|
||||
# XXX Ex Usage: checkAccount $ADDR $AMOUNT [$HEIGHT]
|
||||
# Desc: Assumes just one coin, checks the balance of first coin in any case
|
||||
# pass optional height to query which block to query
|
||||
checkAccount() {
|
||||
# default height of 0, but accept an argument
|
||||
HEIGHT=${3:-0}
|
||||
|
||||
# make sure sender goes down
|
||||
ACCT=$(${CLIENT_EXE} query account $1)
|
||||
ACCT=$(${CLIENT_EXE} query account $1 --height=$HEIGHT)
|
||||
if ! assertTrue "line=${LINENO}, account must exist" $?; then
|
||||
return 1
|
||||
fi
|
||||
|
@ -138,11 +142,14 @@ checkAccount() {
|
|||
return $?
|
||||
}
|
||||
|
||||
# XXX Ex Usage: checkRole $ROLE $SIGS $NUM_SIGNERS
|
||||
# XXX Ex Usage: checkRole $ROLE $SIGS $NUM_SIGNERS [$HEIGHT]
|
||||
# Desc: Ensures this named role exists, and has the number of members and required signatures as above
|
||||
checkRole() {
|
||||
# default height of 0, but accept an argument
|
||||
HEIGHT=${4:-0}
|
||||
|
||||
# make sure sender goes down
|
||||
QROLE=$(${CLIENT_EXE} query role $1)
|
||||
QROLE=$(${CLIENT_EXE} query role $1 --height=$HEIGHT)
|
||||
if ! assertTrue "line=${LINENO}, role must exist" $?; then
|
||||
return 1
|
||||
fi
|
||||
|
|
Loading…
Reference in New Issue