mirror of
https://github.com/tendermint/tendermint.git
synced 2026-07-20 23:12:44 +00:00
Merge pull request #465 from tendermint/bytes
RPC Serialization Overhaul
This commit is contained in:
@@ -7,11 +7,11 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
"github.com/tendermint/tendermint/rpc/lib/client"
|
||||
"github.com/tendermint/tendermint/rpc/lib/types"
|
||||
"github.com/tendermint/go-wire"
|
||||
_ "github.com/tendermint/tendermint/rpc/core/types" // Register RPCResponse > Result types
|
||||
"github.com/tendermint/tendermint/rpc/lib/client"
|
||||
"github.com/tendermint/tendermint/rpc/lib/types"
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -37,13 +37,16 @@ func main() {
|
||||
for i := 0; ; i++ {
|
||||
binary.BigEndian.PutUint64(buf, uint64(i))
|
||||
//txBytes := hex.EncodeToString(buf[:n])
|
||||
request := rpctypes.NewRPCRequest("fakeid",
|
||||
request, err := rpctypes.MapToRequest("fakeid",
|
||||
"broadcast_tx",
|
||||
map[string]interface{}{"tx": buf[:8]})
|
||||
if err != nil {
|
||||
Exit(err.Error())
|
||||
}
|
||||
reqBytes := wire.JSONBytes(request)
|
||||
//fmt.Println("!!", string(reqBytes))
|
||||
fmt.Print(".")
|
||||
err := ws.WriteMessage(websocket.TextMessage, reqBytes)
|
||||
err = ws.WriteMessage(websocket.TextMessage, reqBytes)
|
||||
if err != nil {
|
||||
Exit(err.Error())
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/tendermint/go-wire"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
@@ -21,7 +21,7 @@ func init() {
|
||||
|
||||
func genValidator(cmd *cobra.Command, args []string) {
|
||||
privValidator := types.GenPrivValidator()
|
||||
privValidatorJSONBytes := wire.JSONBytesPretty(privValidator)
|
||||
privValidatorJSONBytes, _ := json.MarshalIndent(privValidator, "", "\t")
|
||||
fmt.Printf(`%v
|
||||
`, string(privValidatorJSONBytes))
|
||||
}
|
||||
|
||||
@@ -206,7 +206,7 @@ func subscribeToVoter(cs *ConsensusState, addr []byte) chan interface{} {
|
||||
go func() {
|
||||
for {
|
||||
v := <-voteCh0
|
||||
vote := v.(types.EventDataVote)
|
||||
vote := v.(types.TMEventData).Unwrap().(types.EventDataVote)
|
||||
// we only fire for our own votes
|
||||
if bytes.Equal(addr, vote.Vote.ValidatorAddress) {
|
||||
voteCh <- v
|
||||
|
||||
@@ -44,7 +44,7 @@ func TestTxConcurrentWithCommit(t *testing.T) {
|
||||
for nTxs := 0; nTxs < NTxs; {
|
||||
select {
|
||||
case b := <-newBlockCh:
|
||||
nTxs += b.(types.EventDataNewBlock).Block.Header.NumTxs
|
||||
nTxs += b.(types.TMEventData).Unwrap().(types.EventDataNewBlock).Block.Header.NumTxs
|
||||
case <-ticker.C:
|
||||
panic("Timed out waiting to commit blocks with transactions")
|
||||
}
|
||||
|
||||
@@ -8,11 +8,11 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
"github.com/tendermint/tendermint/p2p"
|
||||
"github.com/tendermint/go-wire"
|
||||
"github.com/tendermint/tendermint/p2p"
|
||||
sm "github.com/tendermint/tendermint/state"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -299,12 +299,12 @@ func (conR *ConsensusReactor) SetEventSwitch(evsw types.EventSwitch) {
|
||||
func (conR *ConsensusReactor) registerEventCallbacks() {
|
||||
|
||||
types.AddListenerForEvent(conR.evsw, "conR", types.EventStringNewRoundStep(), func(data types.TMEventData) {
|
||||
rs := data.(types.EventDataRoundState).RoundState.(*RoundState)
|
||||
rs := data.Unwrap().(types.EventDataRoundState).RoundState.(*RoundState)
|
||||
conR.broadcastNewRoundStep(rs)
|
||||
})
|
||||
|
||||
types.AddListenerForEvent(conR.evsw, "conR", types.EventStringVote(), func(data types.TMEventData) {
|
||||
edv := data.(types.EventDataVote)
|
||||
edv := data.Unwrap().(types.EventDataVote)
|
||||
conR.broadcastHasVoteMessage(edv.Vote)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -8,10 +8,10 @@ import (
|
||||
|
||||
"github.com/tendermint/tendermint/config/tendermint_test"
|
||||
|
||||
"github.com/tendermint/tmlibs/events"
|
||||
"github.com/tendermint/abci/example/dummy"
|
||||
"github.com/tendermint/tendermint/p2p"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
"github.com/tendermint/abci/example/dummy"
|
||||
"github.com/tendermint/tmlibs/events"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -252,7 +252,7 @@ func TestReactorWithTimeoutCommit(t *testing.T) {
|
||||
func waitForAndValidateBlock(t *testing.T, n int, activeVals map[string]struct{}, eventChans []chan interface{}, css []*ConsensusState, txs ...[]byte) {
|
||||
timeoutWaitGroup(t, n, func(wg *sync.WaitGroup, j int) {
|
||||
newBlockI := <-eventChans[j]
|
||||
newBlock := newBlockI.(types.EventDataNewBlock).Block
|
||||
newBlock := newBlockI.(types.TMEventData).Unwrap().(types.EventDataNewBlock).Block
|
||||
log.Warn("Got block", "height", newBlock.Height, "validator", j)
|
||||
err := validateBlock(newBlock, activeVals)
|
||||
if err != nil {
|
||||
|
||||
+15
-15
@@ -6,9 +6,9 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
"github.com/tendermint/tendermint/config/tendermint_test"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -248,7 +248,7 @@ func TestFullRound1(t *testing.T) {
|
||||
|
||||
// grab proposal
|
||||
re := <-propCh
|
||||
propBlockHash := re.(types.EventDataRoundState).RoundState.(*RoundState).ProposalBlock.Hash()
|
||||
propBlockHash := re.(types.TMEventData).Unwrap().(types.EventDataRoundState).RoundState.(*RoundState).ProposalBlock.Hash()
|
||||
|
||||
<-voteCh // wait for prevote
|
||||
// NOTE: voteChan cap of 0 ensures we can complete this
|
||||
@@ -345,7 +345,7 @@ func TestLockNoPOL(t *testing.T) {
|
||||
cs1.startRoutines(0)
|
||||
|
||||
re := <-proposalCh
|
||||
rs := re.(types.EventDataRoundState).RoundState.(*RoundState)
|
||||
rs := re.(types.TMEventData).Unwrap().(types.EventDataRoundState).RoundState.(*RoundState)
|
||||
theBlockHash := rs.ProposalBlock.Hash()
|
||||
|
||||
<-voteCh // prevote
|
||||
@@ -385,7 +385,7 @@ func TestLockNoPOL(t *testing.T) {
|
||||
|
||||
// now we're on a new round and not the proposer, so wait for timeout
|
||||
re = <-timeoutProposeCh
|
||||
rs = re.(types.EventDataRoundState).RoundState.(*RoundState)
|
||||
rs = re.(types.TMEventData).Unwrap().(types.EventDataRoundState).RoundState.(*RoundState)
|
||||
|
||||
if rs.ProposalBlock != nil {
|
||||
panic("Expected proposal block to be nil")
|
||||
@@ -429,7 +429,7 @@ func TestLockNoPOL(t *testing.T) {
|
||||
incrementRound(vs2)
|
||||
|
||||
re = <-proposalCh
|
||||
rs = re.(types.EventDataRoundState).RoundState.(*RoundState)
|
||||
rs = re.(types.TMEventData).Unwrap().(types.EventDataRoundState).RoundState.(*RoundState)
|
||||
|
||||
// now we're on a new round and are the proposer
|
||||
if !bytes.Equal(rs.ProposalBlock.Hash(), rs.LockedBlock.Hash()) {
|
||||
@@ -518,7 +518,7 @@ func TestLockPOLRelock(t *testing.T) {
|
||||
|
||||
<-newRoundCh
|
||||
re := <-proposalCh
|
||||
rs := re.(types.EventDataRoundState).RoundState.(*RoundState)
|
||||
rs := re.(types.TMEventData).Unwrap().(types.EventDataRoundState).RoundState.(*RoundState)
|
||||
theBlockHash := rs.ProposalBlock.Hash()
|
||||
|
||||
<-voteCh // prevote
|
||||
@@ -589,9 +589,9 @@ func TestLockPOLRelock(t *testing.T) {
|
||||
_, _ = <-voteCh, <-voteCh
|
||||
|
||||
be := <-newBlockCh
|
||||
b := be.(types.EventDataNewBlockHeader)
|
||||
b := be.(types.TMEventData).Unwrap().(types.EventDataNewBlockHeader)
|
||||
re = <-newRoundCh
|
||||
rs = re.(types.EventDataRoundState).RoundState.(*RoundState)
|
||||
rs = re.(types.TMEventData).Unwrap().(types.EventDataRoundState).RoundState.(*RoundState)
|
||||
if rs.Height != 2 {
|
||||
panic("Expected height to increment")
|
||||
}
|
||||
@@ -627,7 +627,7 @@ func TestLockPOLUnlock(t *testing.T) {
|
||||
startTestRound(cs1, cs1.Height, 0)
|
||||
<-newRoundCh
|
||||
re := <-proposalCh
|
||||
rs := re.(types.EventDataRoundState).RoundState.(*RoundState)
|
||||
rs := re.(types.TMEventData).Unwrap().(types.EventDataRoundState).RoundState.(*RoundState)
|
||||
theBlockHash := rs.ProposalBlock.Hash()
|
||||
|
||||
<-voteCh // prevote
|
||||
@@ -653,7 +653,7 @@ func TestLockPOLUnlock(t *testing.T) {
|
||||
|
||||
// timeout to new round
|
||||
re = <-timeoutWaitCh
|
||||
rs = re.(types.EventDataRoundState).RoundState.(*RoundState)
|
||||
rs = re.(types.TMEventData).Unwrap().(types.EventDataRoundState).RoundState.(*RoundState)
|
||||
lockedBlockHash := rs.LockedBlock.Hash()
|
||||
|
||||
//XXX: this isnt gauranteed to get there before the timeoutPropose ...
|
||||
@@ -713,7 +713,7 @@ func TestLockPOLSafety1(t *testing.T) {
|
||||
startTestRound(cs1, cs1.Height, 0)
|
||||
<-newRoundCh
|
||||
re := <-proposalCh
|
||||
rs := re.(types.EventDataRoundState).RoundState.(*RoundState)
|
||||
rs := re.(types.TMEventData).Unwrap().(types.EventDataRoundState).RoundState.(*RoundState)
|
||||
propBlock := rs.ProposalBlock
|
||||
|
||||
<-voteCh // prevote
|
||||
@@ -761,7 +761,7 @@ func TestLockPOLSafety1(t *testing.T) {
|
||||
re = <-proposalCh
|
||||
}
|
||||
|
||||
rs = re.(types.EventDataRoundState).RoundState.(*RoundState)
|
||||
rs = re.(types.TMEventData).Unwrap().(types.EventDataRoundState).RoundState.(*RoundState)
|
||||
|
||||
if rs.LockedBlock != nil {
|
||||
panic("we should not be locked!")
|
||||
@@ -1009,7 +1009,7 @@ func TestHalt1(t *testing.T) {
|
||||
startTestRound(cs1, cs1.Height, 0)
|
||||
<-newRoundCh
|
||||
re := <-proposalCh
|
||||
rs := re.(types.EventDataRoundState).RoundState.(*RoundState)
|
||||
rs := re.(types.TMEventData).Unwrap().(types.EventDataRoundState).RoundState.(*RoundState)
|
||||
propBlock := rs.ProposalBlock
|
||||
propBlockParts := propBlock.MakePartSet(partSize)
|
||||
|
||||
@@ -1032,7 +1032,7 @@ func TestHalt1(t *testing.T) {
|
||||
// timeout to new round
|
||||
<-timeoutWaitCh
|
||||
re = <-newRoundCh
|
||||
rs = re.(types.EventDataRoundState).RoundState.(*RoundState)
|
||||
rs = re.(types.TMEventData).Unwrap().(types.EventDataRoundState).RoundState.(*RoundState)
|
||||
|
||||
log.Notice("### ONTO ROUND 1")
|
||||
/*Round2
|
||||
@@ -1050,7 +1050,7 @@ func TestHalt1(t *testing.T) {
|
||||
// receiving that precommit should take us straight to commit
|
||||
<-newBlockCh
|
||||
re = <-newRoundCh
|
||||
rs = re.(types.EventDataRoundState).RoundState.(*RoundState)
|
||||
rs = re.(types.TMEventData).Unwrap().(types.EventDataRoundState).RoundState.(*RoundState)
|
||||
|
||||
if rs.Height != 2 {
|
||||
panic("expected height to increment")
|
||||
|
||||
Generated
+27
-18
@@ -1,8 +1,8 @@
|
||||
hash: 6f8962f6ca0e25b8e43bc6e496bd46c9ff3a79dcf789578efeeaee2fffc39c6e
|
||||
updated: 2017-04-25T14:48:36.999444976-04:00
|
||||
updated: 2017-04-27T19:56:37.342860938-04:00
|
||||
imports:
|
||||
- name: github.com/btcsuite/btcd
|
||||
version: 583684b21bfbde9b5fc4403916fd7c807feb0289
|
||||
version: 4b348c1d33373d672edd83fc576892d0e46686d2
|
||||
subpackages:
|
||||
- btcec
|
||||
- name: github.com/davecgh/go-spew
|
||||
@@ -20,11 +20,12 @@ imports:
|
||||
subpackages:
|
||||
- proto
|
||||
- name: github.com/golang/protobuf
|
||||
version: 8ee79997227bf9b34611aee7946ae64735e6fd93
|
||||
version: 2bba0603135d7d7f5cb73b2125beeda19c09f4ef
|
||||
subpackages:
|
||||
- proto
|
||||
- ptypes/any
|
||||
- name: github.com/golang/snappy
|
||||
version: d9eb7a3d35ec988b8585d4a0068e462c27d28380
|
||||
version: 553a641470496b2327abcac10b36396bd98e45c9
|
||||
- name: github.com/gorilla/websocket
|
||||
version: 3ab3a8b8831546bd18fd182c20687ca853b2bb13
|
||||
- name: github.com/hashicorp/hcl
|
||||
@@ -45,9 +46,9 @@ imports:
|
||||
- name: github.com/magiconair/properties
|
||||
version: 51463bfca2576e06c62a8504b5c0f06d61312647
|
||||
- name: github.com/mattn/go-colorable
|
||||
version: d228849504861217f796da67fae4f6e347643f15
|
||||
version: ded68f7a9561c023e790de24279db7ebf473ea80
|
||||
- name: github.com/mattn/go-isatty
|
||||
version: 30a891c33c7cde7b02a981314b4228ec99380cca
|
||||
version: fc9e8d8ef48496124e79ae0df75490096eccf6fe
|
||||
- name: github.com/mitchellh/mapstructure
|
||||
version: 53818660ed4955e899c0bcafa97299a388bd7c8e
|
||||
- name: github.com/pelletier/go-buffruneio
|
||||
@@ -67,11 +68,11 @@ imports:
|
||||
- name: github.com/spf13/cast
|
||||
version: acbeb36b902d72a7a4c18e8f3241075e7ab763e4
|
||||
- name: github.com/spf13/cobra
|
||||
version: fcd0c5a1df88f5d6784cb4feead962c3f3d0b66c
|
||||
version: 10f6b9d7e1631a54ad07c5c0fb71c28a1abfd3c2
|
||||
- name: github.com/spf13/jwalterweatherman
|
||||
version: fa7ca7e836cf3a8bb4ebf799f472c12d7e903d66
|
||||
- name: github.com/spf13/pflag
|
||||
version: 9ff6c6923cfffbcd502984b8e0c80539a94968b7
|
||||
version: 2300d0f8576fe575f71aaa5b9bbe4e1b0dc2eb51
|
||||
- name: github.com/spf13/viper
|
||||
version: 5d46e70da8c0b6f812e0b170b7a985753b5c63cb
|
||||
- name: github.com/stretchr/testify
|
||||
@@ -80,7 +81,7 @@ imports:
|
||||
- assert
|
||||
- require
|
||||
- name: github.com/syndtr/goleveldb
|
||||
version: 23851d93a2292dcc56e71a18ec9e0624d84a0f65
|
||||
version: 8c81ea47d4c41a385645e133e15510fc6a2a74b4
|
||||
subpackages:
|
||||
- leveldb
|
||||
- leveldb/cache
|
||||
@@ -95,7 +96,7 @@ imports:
|
||||
- leveldb/table
|
||||
- leveldb/util
|
||||
- name: github.com/tendermint/abci
|
||||
version: c709d3cc857929a8dd36a90da3640122d7e75770
|
||||
version: 8d8e35ae537538c9cf6808be3ca9dd7dab81b7f6
|
||||
subpackages:
|
||||
- client
|
||||
- example/counter
|
||||
@@ -108,9 +109,9 @@ imports:
|
||||
- edwards25519
|
||||
- extra25519
|
||||
- name: github.com/tendermint/go-crypto
|
||||
version: 9b95da8fa4187f6799558d89b271dc8ab6485615
|
||||
version: 197a2b270fd94ee03824b158e738fce62862d0b8
|
||||
- name: github.com/tendermint/go-wire
|
||||
version: 334005c236d19c632fb5f073f9de3b0fab6a522b
|
||||
version: b53add0b622662731985485f3a19be7f684660b8
|
||||
subpackages:
|
||||
- data
|
||||
- name: github.com/tendermint/log15
|
||||
@@ -118,7 +119,7 @@ imports:
|
||||
subpackages:
|
||||
- term
|
||||
- name: github.com/tendermint/merkleeyes
|
||||
version: 6fd69aa0871a4e685a5570aa7ab3d12e4068a722
|
||||
version: ea4dd9c7b773435de26bf59fddf90afd43a07d67
|
||||
subpackages:
|
||||
- app
|
||||
- client
|
||||
@@ -137,7 +138,7 @@ imports:
|
||||
- merkle
|
||||
- test
|
||||
- name: golang.org/x/crypto
|
||||
version: 7c6cc321c680f03b9ef0764448e780704f486b51
|
||||
version: 96846453c37f0876340a66a47f3f75b1f3a6cd2d
|
||||
subpackages:
|
||||
- curve25519
|
||||
- nacl/box
|
||||
@@ -148,7 +149,7 @@ imports:
|
||||
- ripemd160
|
||||
- salsa20/salsa
|
||||
- name: golang.org/x/net
|
||||
version: 61557ac0112b576429a0df080e1c2cef5dfbb642
|
||||
version: c8c74377599bd978aee1cf3b9b63a8634051cec2
|
||||
subpackages:
|
||||
- context
|
||||
- http2
|
||||
@@ -158,25 +159,33 @@ imports:
|
||||
- lex/httplex
|
||||
- trace
|
||||
- name: golang.org/x/sys
|
||||
version: d75a52659825e75fff6158388dddc6a5b04f9ba5
|
||||
version: ea9bcade75cb975a0b9738936568ab388b845617
|
||||
subpackages:
|
||||
- unix
|
||||
- name: golang.org/x/text
|
||||
version: f4b4367115ec2de254587813edaa901bc1c723a8
|
||||
version: 19e3104b43db45fca0303f489a9536087b184802
|
||||
subpackages:
|
||||
- secure/bidirule
|
||||
- transform
|
||||
- unicode/bidi
|
||||
- unicode/norm
|
||||
- name: google.golang.org/genproto
|
||||
version: 411e09b969b1170a9f0c467558eb4c4c110d9c77
|
||||
subpackages:
|
||||
- googleapis/rpc/status
|
||||
- name: google.golang.org/grpc
|
||||
version: cbcceb2942a489498cf22b2f918536e819d33f0a
|
||||
version: 6914ab1e338c92da4218a23d27fcd03d0ad78d46
|
||||
subpackages:
|
||||
- codes
|
||||
- credentials
|
||||
- grpclog
|
||||
- internal
|
||||
- keepalive
|
||||
- metadata
|
||||
- naming
|
||||
- peer
|
||||
- stats
|
||||
- status
|
||||
- tap
|
||||
- transport
|
||||
- name: gopkg.in/yaml.v2
|
||||
|
||||
@@ -25,7 +25,7 @@ func TestHeaderEvents(t *testing.T) {
|
||||
evtTyp := types.EventStringNewBlockHeader()
|
||||
evt, err := client.WaitForOneEvent(c, evtTyp, 1*time.Second)
|
||||
require.Nil(err, "%d: %+v", i, err)
|
||||
_, ok := evt.(types.EventDataNewBlockHeader)
|
||||
_, ok := evt.Unwrap().(types.EventDataNewBlockHeader)
|
||||
require.True(ok, "%d: %#v", i, evt)
|
||||
// TODO: more checks...
|
||||
}
|
||||
@@ -56,7 +56,7 @@ func TestTxEvents(t *testing.T) {
|
||||
evt, err := client.WaitForOneEvent(c, evtTyp, 1*time.Second)
|
||||
require.Nil(err, "%d: %+v", i, err)
|
||||
// and make sure it has the proper info
|
||||
txe, ok := evt.(types.EventDataTx)
|
||||
txe, ok := evt.Unwrap().(types.EventDataTx)
|
||||
require.True(ok, "%d: %#v", i, evt)
|
||||
// make sure this is the proper tx
|
||||
require.EqualValues(tx, txe.Tx)
|
||||
|
||||
@@ -4,9 +4,9 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
events "github.com/tendermint/tmlibs/events"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
// Waiter is informed of current height, decided whether to quit early
|
||||
@@ -77,12 +77,12 @@ func WaitForOneEvent(evsw types.EventSwitch,
|
||||
|
||||
select {
|
||||
case <-quit:
|
||||
return nil, errors.New("timed out waiting for event")
|
||||
return types.TMEventData{}, errors.New("timed out waiting for event")
|
||||
case evt := <-evts:
|
||||
tmevt, ok := evt.(types.TMEventData)
|
||||
if ok {
|
||||
return tmevt, nil
|
||||
}
|
||||
return nil, errors.Errorf("Got unexpected event type: %#v", evt)
|
||||
return types.TMEventData{}, errors.Errorf("Got unexpected event type: %#v", evt)
|
||||
}
|
||||
}
|
||||
|
||||
+46
-50
@@ -1,15 +1,15 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
data "github.com/tendermint/go-wire/data"
|
||||
events "github.com/tendermint/tmlibs/events"
|
||||
"github.com/tendermint/tendermint/rpc/lib/client"
|
||||
wire "github.com/tendermint/go-wire"
|
||||
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||
"github.com/tendermint/tendermint/rpc/lib/client"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
events "github.com/tendermint/tmlibs/events"
|
||||
)
|
||||
|
||||
/*
|
||||
@@ -50,42 +50,41 @@ func (c *HTTP) _assertIsEventSwitch() types.EventSwitch {
|
||||
}
|
||||
|
||||
func (c *HTTP) Status() (*ctypes.ResultStatus, error) {
|
||||
tmResult := new(ctypes.TMResult)
|
||||
_, err := c.rpc.Call("status", map[string]interface{}{}, tmResult)
|
||||
result := new(ctypes.ResultStatus)
|
||||
_, err := c.rpc.Call("status", map[string]interface{}{}, result)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Status")
|
||||
}
|
||||
// note: panics if rpc doesn't match. okay???
|
||||
return (*tmResult).(*ctypes.ResultStatus), nil
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *HTTP) ABCIInfo() (*ctypes.ResultABCIInfo, error) {
|
||||
tmResult := new(ctypes.TMResult)
|
||||
_, err := c.rpc.Call("abci_info", map[string]interface{}{}, tmResult)
|
||||
result := new(ctypes.ResultABCIInfo)
|
||||
_, err := c.rpc.Call("abci_info", map[string]interface{}{}, result)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "ABCIInfo")
|
||||
}
|
||||
return (*tmResult).(*ctypes.ResultABCIInfo), nil
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *HTTP) ABCIQuery(path string, data data.Bytes, prove bool) (*ctypes.ResultABCIQuery, error) {
|
||||
tmResult := new(ctypes.TMResult)
|
||||
result := new(ctypes.ResultABCIQuery)
|
||||
_, err := c.rpc.Call("abci_query",
|
||||
map[string]interface{}{"path": path, "data": data, "prove": prove},
|
||||
tmResult)
|
||||
result)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "ABCIQuery")
|
||||
}
|
||||
return (*tmResult).(*ctypes.ResultABCIQuery), nil
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *HTTP) BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
|
||||
tmResult := new(ctypes.TMResult)
|
||||
_, err := c.rpc.Call("broadcast_tx_commit", map[string]interface{}{"tx": tx}, tmResult)
|
||||
result := new(ctypes.ResultBroadcastTxCommit)
|
||||
_, err := c.rpc.Call("broadcast_tx_commit", map[string]interface{}{"tx": tx}, result)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "broadcast_tx_commit")
|
||||
}
|
||||
return (*tmResult).(*ctypes.ResultBroadcastTxCommit), nil
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *HTTP) BroadcastTxAsync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
|
||||
@@ -97,90 +96,90 @@ func (c *HTTP) BroadcastTxSync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
|
||||
}
|
||||
|
||||
func (c *HTTP) broadcastTX(route string, tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
|
||||
tmResult := new(ctypes.TMResult)
|
||||
_, err := c.rpc.Call(route, map[string]interface{}{"tx": tx}, tmResult)
|
||||
result := new(ctypes.ResultBroadcastTx)
|
||||
_, err := c.rpc.Call(route, map[string]interface{}{"tx": tx}, result)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, route)
|
||||
}
|
||||
return (*tmResult).(*ctypes.ResultBroadcastTx), nil
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *HTTP) NetInfo() (*ctypes.ResultNetInfo, error) {
|
||||
tmResult := new(ctypes.TMResult)
|
||||
_, err := c.rpc.Call("net_info", map[string]interface{}{}, tmResult)
|
||||
result := new(ctypes.ResultNetInfo)
|
||||
_, err := c.rpc.Call("net_info", map[string]interface{}{}, result)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "NetInfo")
|
||||
}
|
||||
return (*tmResult).(*ctypes.ResultNetInfo), nil
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *HTTP) DumpConsensusState() (*ctypes.ResultDumpConsensusState, error) {
|
||||
tmResult := new(ctypes.TMResult)
|
||||
_, err := c.rpc.Call("dump_consensus_state", map[string]interface{}{}, tmResult)
|
||||
result := new(ctypes.ResultDumpConsensusState)
|
||||
_, err := c.rpc.Call("dump_consensus_state", map[string]interface{}{}, result)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "DumpConsensusState")
|
||||
}
|
||||
return (*tmResult).(*ctypes.ResultDumpConsensusState), nil
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *HTTP) BlockchainInfo(minHeight, maxHeight int) (*ctypes.ResultBlockchainInfo, error) {
|
||||
tmResult := new(ctypes.TMResult)
|
||||
result := new(ctypes.ResultBlockchainInfo)
|
||||
_, err := c.rpc.Call("blockchain",
|
||||
map[string]interface{}{"minHeight": minHeight, "maxHeight": maxHeight},
|
||||
tmResult)
|
||||
result)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "BlockchainInfo")
|
||||
}
|
||||
return (*tmResult).(*ctypes.ResultBlockchainInfo), nil
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *HTTP) Genesis() (*ctypes.ResultGenesis, error) {
|
||||
tmResult := new(ctypes.TMResult)
|
||||
_, err := c.rpc.Call("genesis", map[string]interface{}{}, tmResult)
|
||||
result := new(ctypes.ResultGenesis)
|
||||
_, err := c.rpc.Call("genesis", map[string]interface{}{}, result)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Genesis")
|
||||
}
|
||||
return (*tmResult).(*ctypes.ResultGenesis), nil
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *HTTP) Block(height int) (*ctypes.ResultBlock, error) {
|
||||
tmResult := new(ctypes.TMResult)
|
||||
_, err := c.rpc.Call("block", map[string]interface{}{"height": height}, tmResult)
|
||||
result := new(ctypes.ResultBlock)
|
||||
_, err := c.rpc.Call("block", map[string]interface{}{"height": height}, result)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Block")
|
||||
}
|
||||
return (*tmResult).(*ctypes.ResultBlock), nil
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *HTTP) Commit(height int) (*ctypes.ResultCommit, error) {
|
||||
tmResult := new(ctypes.TMResult)
|
||||
_, err := c.rpc.Call("commit", map[string]interface{}{"height": height}, tmResult)
|
||||
result := new(ctypes.ResultCommit)
|
||||
_, err := c.rpc.Call("commit", map[string]interface{}{"height": height}, result)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Commit")
|
||||
}
|
||||
return (*tmResult).(*ctypes.ResultCommit), nil
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *HTTP) Tx(hash []byte, prove bool) (*ctypes.ResultTx, error) {
|
||||
tmResult := new(ctypes.TMResult)
|
||||
result := new(ctypes.ResultTx)
|
||||
query := map[string]interface{}{
|
||||
"hash": hash,
|
||||
"prove": prove,
|
||||
}
|
||||
_, err := c.rpc.Call("tx", query, tmResult)
|
||||
_, err := c.rpc.Call("tx", query, result)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Tx")
|
||||
}
|
||||
return (*tmResult).(*ctypes.ResultTx), nil
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *HTTP) Validators() (*ctypes.ResultValidators, error) {
|
||||
tmResult := new(ctypes.TMResult)
|
||||
_, err := c.rpc.Call("validators", map[string]interface{}{}, tmResult)
|
||||
result := new(ctypes.ResultValidators)
|
||||
_, err := c.rpc.Call("validators", map[string]interface{}{}, result)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Validators")
|
||||
}
|
||||
return (*tmResult).(*ctypes.ResultValidators), nil
|
||||
return result, nil
|
||||
}
|
||||
|
||||
/** websocket event stuff here... **/
|
||||
@@ -335,18 +334,15 @@ func (w *WSEvents) eventListener() {
|
||||
// some implementation of types.TMEventData, and sends it off
|
||||
// on the merry way to the EventSwitch
|
||||
func (w *WSEvents) parseEvent(data []byte) (err error) {
|
||||
result := new(ctypes.TMResult)
|
||||
wire.ReadJSONPtr(result, data, &err)
|
||||
result := new(ctypes.ResultEvent)
|
||||
err = json.Unmarshal(data, result)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
event, ok := (*result).(*ctypes.ResultEvent)
|
||||
if !ok {
|
||||
// ignore silently (eg. subscribe, unsubscribe and maybe other events)
|
||||
// TODO: ?
|
||||
return nil
|
||||
}
|
||||
// looks good! let's fire this baby!
|
||||
w.EventSwitch.FireEvent(event.Name, event.Data)
|
||||
w.EventSwitch.FireEvent(result.Name, result.Data)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -25,18 +25,16 @@ func (a ABCIApp) ABCIInfo() (*ctypes.ResultABCIInfo, error) {
|
||||
|
||||
func (a ABCIApp) ABCIQuery(path string, data data.Bytes, prove bool) (*ctypes.ResultABCIQuery, error) {
|
||||
q := a.App.Query(abci.RequestQuery{data, path, 0, prove})
|
||||
return &ctypes.ResultABCIQuery{q}, nil
|
||||
return &ctypes.ResultABCIQuery{q.Result()}, nil
|
||||
}
|
||||
|
||||
func (a ABCIApp) BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
|
||||
res := ctypes.ResultBroadcastTxCommit{}
|
||||
c := a.App.CheckTx(tx)
|
||||
res.CheckTx = &abci.ResponseCheckTx{c.Code, c.Data, c.Log}
|
||||
if !c.IsOK() {
|
||||
res.CheckTx = a.App.CheckTx(tx)
|
||||
if !res.CheckTx.IsOK() {
|
||||
return &res, nil
|
||||
}
|
||||
d := a.App.DeliverTx(tx)
|
||||
res.DeliverTx = &abci.ResponseDeliverTx{d.Code, d.Data, d.Log}
|
||||
res.DeliverTx = a.App.DeliverTx(tx)
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
@@ -85,7 +83,8 @@ func (m ABCIMock) ABCIQuery(path string, data data.Bytes, prove bool) (*ctypes.R
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ctypes.ResultABCIQuery{res.(abci.ResponseQuery)}, nil
|
||||
resQuery := res.(abci.ResponseQuery)
|
||||
return &ctypes.ResultABCIQuery{resQuery.Result()}, nil
|
||||
}
|
||||
|
||||
func (m ABCIMock) BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
|
||||
|
||||
@@ -36,8 +36,8 @@ func TestABCIMock(t *testing.T) {
|
||||
BroadcastCommit: mock.Call{
|
||||
Args: goodTx,
|
||||
Response: &ctypes.ResultBroadcastTxCommit{
|
||||
CheckTx: &abci.ResponseCheckTx{Data: data.Bytes("stand")},
|
||||
DeliverTx: &abci.ResponseDeliverTx{Data: data.Bytes("deliver")},
|
||||
CheckTx: abci.Result{Data: data.Bytes("stand")},
|
||||
DeliverTx: abci.Result{Data: data.Bytes("deliver")},
|
||||
},
|
||||
Error: errors.New("bad tx"),
|
||||
},
|
||||
@@ -53,9 +53,9 @@ func TestABCIMock(t *testing.T) {
|
||||
query, err := m.ABCIQuery("/", nil, false)
|
||||
require.Nil(err)
|
||||
require.NotNil(query)
|
||||
assert.Equal(key, query.Response.GetKey())
|
||||
assert.Equal(value, query.Response.GetValue())
|
||||
assert.Equal(height, query.Response.GetHeight())
|
||||
assert.EqualValues(key, query.Key)
|
||||
assert.EqualValues(value, query.Value)
|
||||
assert.Equal(height, query.Height)
|
||||
|
||||
// non-commit calls always return errors
|
||||
_, err = m.BroadcastTxSync(goodTx)
|
||||
@@ -166,5 +166,5 @@ func TestABCIApp(t *testing.T) {
|
||||
// check the key
|
||||
qres, err := m.ABCIQuery("/key", data.Bytes(key), false)
|
||||
require.Nil(err)
|
||||
assert.EqualValues(value, qres.Response.Value)
|
||||
assert.EqualValues(value, qres.Value)
|
||||
}
|
||||
|
||||
+9
-11
@@ -10,7 +10,6 @@ import (
|
||||
merktest "github.com/tendermint/merkleeyes/testutil"
|
||||
"github.com/tendermint/tendermint/rpc/client"
|
||||
rpctest "github.com/tendermint/tendermint/rpc/test"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
func getHTTPClient() *client.HTTP {
|
||||
@@ -119,17 +118,16 @@ func TestAppCalls(t *testing.T) {
|
||||
k, v, tx := merktest.MakeTxKV()
|
||||
bres, err := c.BroadcastTxCommit(tx)
|
||||
require.Nil(err, "%d: %+v", i, err)
|
||||
require.True(bres.DeliverTx.GetCode().IsOK())
|
||||
require.True(bres.DeliverTx.Code.IsOK())
|
||||
txh := bres.Height
|
||||
apph := txh + 1 // this is where the tx will be applied to the state
|
||||
|
||||
// wait before querying
|
||||
client.WaitForHeight(c, apph, nil)
|
||||
qres, err := c.ABCIQuery("/key", k, false)
|
||||
if assert.Nil(err) && assert.True(qres.Response.Code.IsOK()) {
|
||||
data := qres.Response
|
||||
if assert.Nil(err) && assert.True(qres.Code.IsOK()) {
|
||||
// assert.Equal(k, data.GetKey()) // only returned for proofs
|
||||
assert.Equal(v, data.GetValue())
|
||||
assert.EqualValues(v, qres.Value)
|
||||
}
|
||||
|
||||
// make sure we can lookup the tx with proof
|
||||
@@ -137,7 +135,7 @@ func TestAppCalls(t *testing.T) {
|
||||
ptx, err := c.Tx(bres.Hash, true)
|
||||
require.Nil(err, "%d: %+v", i, err)
|
||||
assert.Equal(txh, ptx.Height)
|
||||
assert.Equal(types.Tx(tx), ptx.Tx)
|
||||
assert.EqualValues(tx, ptx.Tx)
|
||||
|
||||
// and we can even check the block is added
|
||||
block, err := c.Block(apph)
|
||||
@@ -174,12 +172,12 @@ func TestAppCalls(t *testing.T) {
|
||||
|
||||
// and we got a proof that works!
|
||||
pres, err := c.ABCIQuery("/key", k, true)
|
||||
if assert.Nil(err) && assert.True(pres.Response.Code.IsOK()) {
|
||||
proof, err := iavl.ReadProof(pres.Response.GetProof())
|
||||
if assert.Nil(err) && assert.True(pres.Code.IsOK()) {
|
||||
proof, err := iavl.ReadProof(pres.Proof)
|
||||
if assert.Nil(err) {
|
||||
key := pres.Response.GetKey()
|
||||
value := pres.Response.GetValue()
|
||||
assert.Equal(appHash, proof.RootHash)
|
||||
key := pres.Key
|
||||
value := pres.Value
|
||||
assert.EqualValues(appHash, proof.RootHash)
|
||||
valid := proof.Verify(key, value, appHash)
|
||||
assert.True(valid)
|
||||
}
|
||||
|
||||
+3
-1
@@ -18,7 +18,9 @@ func ABCIQuery(path string, data data.Bytes, prove bool) (*ctypes.ResultABCIQuer
|
||||
return nil, err
|
||||
}
|
||||
log.Info("ABCIQuery", "path", path, "data", data, "result", resQuery)
|
||||
return &ctypes.ResultABCIQuery{resQuery}, nil
|
||||
return &ctypes.ResultABCIQuery{
|
||||
resQuery.Result(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func ABCIInfo() (*ctypes.ResultABCIInfo, error) {
|
||||
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"github.com/tendermint/tendermint/rpc/lib/types"
|
||||
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||
"github.com/tendermint/tendermint/rpc/lib/types"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
@@ -11,8 +11,8 @@ func Subscribe(wsCtx rpctypes.WSRPCContext, event string) (*ctypes.ResultSubscri
|
||||
types.AddListenerForEvent(wsCtx.GetEventSwitch(), wsCtx.GetRemoteAddr(), event, func(msg types.TMEventData) {
|
||||
// NOTE: EventSwitch callbacks must be nonblocking
|
||||
// NOTE: RPCResponses of subscribed events have id suffix "#event"
|
||||
tmResult := ctypes.TMResult(&ctypes.ResultEvent{event, msg})
|
||||
wsCtx.TryWriteRPCResponse(rpctypes.NewRPCResponse(wsCtx.Request.ID+"#event", &tmResult, ""))
|
||||
tmResult := &ctypes.ResultEvent{event, msg}
|
||||
wsCtx.TryWriteRPCResponse(rpctypes.NewRPCResponse(wsCtx.Request.ID+"#event", tmResult, ""))
|
||||
})
|
||||
return &ctypes.ResultSubscribe{}, nil
|
||||
}
|
||||
|
||||
+7
-7
@@ -50,7 +50,7 @@ func BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
|
||||
// subscribe to tx being committed in block
|
||||
deliverTxResCh := make(chan types.EventDataTx, 1)
|
||||
types.AddListenerForEvent(eventSwitch, "rpc", types.EventStringTx(tx), func(data types.TMEventData) {
|
||||
deliverTxResCh <- data.(types.EventDataTx)
|
||||
deliverTxResCh <- data.Unwrap().(types.EventDataTx)
|
||||
})
|
||||
|
||||
// broadcast the tx and register checktx callback
|
||||
@@ -67,8 +67,8 @@ func BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
|
||||
if checkTxR.Code != abci.CodeType_OK {
|
||||
// CheckTx failed!
|
||||
return &ctypes.ResultBroadcastTxCommit{
|
||||
CheckTx: checkTxR,
|
||||
DeliverTx: nil,
|
||||
CheckTx: checkTxR.Result(),
|
||||
DeliverTx: abci.Result{},
|
||||
Hash: tx.Hash(),
|
||||
}, nil
|
||||
}
|
||||
@@ -87,16 +87,16 @@ func BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
|
||||
}
|
||||
log.Notice("DeliverTx passed ", "tx", data.Bytes(tx), "response", deliverTxR)
|
||||
return &ctypes.ResultBroadcastTxCommit{
|
||||
CheckTx: checkTxR,
|
||||
DeliverTx: deliverTxR,
|
||||
CheckTx: checkTxR.Result(),
|
||||
DeliverTx: deliverTxR.Result(),
|
||||
Hash: tx.Hash(),
|
||||
Height: deliverTxRes.Height,
|
||||
}, nil
|
||||
case <-timer.C:
|
||||
log.Error("failed to include tx")
|
||||
return &ctypes.ResultBroadcastTxCommit{
|
||||
CheckTx: checkTxR,
|
||||
DeliverTx: nil,
|
||||
CheckTx: checkTxR.Result(),
|
||||
DeliverTx: abci.Result{},
|
||||
Hash: tx.Hash(),
|
||||
}, fmt.Errorf("Timed out waiting for transaction to be included in a block")
|
||||
}
|
||||
|
||||
+23
-126
@@ -1,149 +1,46 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
data "github.com/tendermint/go-wire/data"
|
||||
rpc "github.com/tendermint/tendermint/rpc/lib/server"
|
||||
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||
"github.com/tendermint/tendermint/rpc/lib/types"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
// TODO: better system than "unsafe" prefix
|
||||
var Routes = map[string]*rpc.RPCFunc{
|
||||
// subscribe/unsubscribe are reserved for websocket events.
|
||||
"subscribe": rpc.NewWSRPCFunc(SubscribeResult, "event"),
|
||||
"unsubscribe": rpc.NewWSRPCFunc(UnsubscribeResult, "event"),
|
||||
"subscribe": rpc.NewWSRPCFunc(Subscribe, "event"),
|
||||
"unsubscribe": rpc.NewWSRPCFunc(Unsubscribe, "event"),
|
||||
|
||||
// info API
|
||||
"status": rpc.NewRPCFunc(StatusResult, ""),
|
||||
"net_info": rpc.NewRPCFunc(NetInfoResult, ""),
|
||||
"blockchain": rpc.NewRPCFunc(BlockchainInfoResult, "minHeight,maxHeight"),
|
||||
"genesis": rpc.NewRPCFunc(GenesisResult, ""),
|
||||
"block": rpc.NewRPCFunc(BlockResult, "height"),
|
||||
"commit": rpc.NewRPCFunc(CommitResult, "height"),
|
||||
"tx": rpc.NewRPCFunc(TxResult, "hash,prove"),
|
||||
"validators": rpc.NewRPCFunc(ValidatorsResult, ""),
|
||||
"dump_consensus_state": rpc.NewRPCFunc(DumpConsensusStateResult, ""),
|
||||
"unconfirmed_txs": rpc.NewRPCFunc(UnconfirmedTxsResult, ""),
|
||||
"num_unconfirmed_txs": rpc.NewRPCFunc(NumUnconfirmedTxsResult, ""),
|
||||
"status": rpc.NewRPCFunc(Status, ""),
|
||||
"net_info": rpc.NewRPCFunc(NetInfo, ""),
|
||||
"blockchain": rpc.NewRPCFunc(BlockchainInfo, "minHeight,maxHeight"),
|
||||
"genesis": rpc.NewRPCFunc(Genesis, ""),
|
||||
"block": rpc.NewRPCFunc(Block, "height"),
|
||||
"commit": rpc.NewRPCFunc(Commit, "height"),
|
||||
"tx": rpc.NewRPCFunc(Tx, "hash,prove"),
|
||||
"validators": rpc.NewRPCFunc(Validators, ""),
|
||||
"dump_consensus_state": rpc.NewRPCFunc(DumpConsensusState, ""),
|
||||
"unconfirmed_txs": rpc.NewRPCFunc(UnconfirmedTxs, ""),
|
||||
"num_unconfirmed_txs": rpc.NewRPCFunc(NumUnconfirmedTxs, ""),
|
||||
|
||||
// broadcast API
|
||||
"broadcast_tx_commit": rpc.NewRPCFunc(BroadcastTxCommitResult, "tx"),
|
||||
"broadcast_tx_sync": rpc.NewRPCFunc(BroadcastTxSyncResult, "tx"),
|
||||
"broadcast_tx_async": rpc.NewRPCFunc(BroadcastTxAsyncResult, "tx"),
|
||||
"broadcast_tx_commit": rpc.NewRPCFunc(BroadcastTxCommit, "tx"),
|
||||
"broadcast_tx_sync": rpc.NewRPCFunc(BroadcastTxSync, "tx"),
|
||||
"broadcast_tx_async": rpc.NewRPCFunc(BroadcastTxAsync, "tx"),
|
||||
|
||||
// abci API
|
||||
"abci_query": rpc.NewRPCFunc(ABCIQueryResult, "path,data,prove"),
|
||||
"abci_info": rpc.NewRPCFunc(ABCIInfoResult, ""),
|
||||
"abci_query": rpc.NewRPCFunc(ABCIQuery, "path,data,prove"),
|
||||
"abci_info": rpc.NewRPCFunc(ABCIInfo, ""),
|
||||
|
||||
// control API
|
||||
"dial_seeds": rpc.NewRPCFunc(UnsafeDialSeedsResult, "seeds"),
|
||||
"dial_seeds": rpc.NewRPCFunc(UnsafeDialSeeds, "seeds"),
|
||||
"unsafe_flush_mempool": rpc.NewRPCFunc(UnsafeFlushMempool, ""),
|
||||
|
||||
// config is not in general thread safe. expose specifics if you need em
|
||||
// "unsafe_set_config": rpc.NewRPCFunc(UnsafeSetConfigResult, "type,key,value"),
|
||||
// "unsafe_set_config": rpc.NewRPCFunc(UnsafeSetConfig, "type,key,value"),
|
||||
|
||||
// profiler API
|
||||
"unsafe_start_cpu_profiler": rpc.NewRPCFunc(UnsafeStartCPUProfilerResult, "filename"),
|
||||
"unsafe_stop_cpu_profiler": rpc.NewRPCFunc(UnsafeStopCPUProfilerResult, ""),
|
||||
"unsafe_write_heap_profile": rpc.NewRPCFunc(UnsafeWriteHeapProfileResult, "filename"),
|
||||
}
|
||||
|
||||
func SubscribeResult(wsCtx rpctypes.WSRPCContext, event string) (ctypes.TMResult, error) {
|
||||
return Subscribe(wsCtx, event)
|
||||
}
|
||||
|
||||
func UnsubscribeResult(wsCtx rpctypes.WSRPCContext, event string) (ctypes.TMResult, error) {
|
||||
return Unsubscribe(wsCtx, event)
|
||||
}
|
||||
|
||||
func StatusResult() (ctypes.TMResult, error) {
|
||||
return Status()
|
||||
}
|
||||
|
||||
func NetInfoResult() (ctypes.TMResult, error) {
|
||||
return NetInfo()
|
||||
}
|
||||
|
||||
func UnsafeDialSeedsResult(seeds []string) (ctypes.TMResult, error) {
|
||||
return UnsafeDialSeeds(seeds)
|
||||
}
|
||||
|
||||
func BlockchainInfoResult(min, max int) (ctypes.TMResult, error) {
|
||||
return BlockchainInfo(min, max)
|
||||
}
|
||||
|
||||
func GenesisResult() (ctypes.TMResult, error) {
|
||||
return Genesis()
|
||||
}
|
||||
|
||||
func BlockResult(height int) (ctypes.TMResult, error) {
|
||||
return Block(height)
|
||||
}
|
||||
|
||||
func CommitResult(height int) (ctypes.TMResult, error) {
|
||||
return Commit(height)
|
||||
}
|
||||
|
||||
func ValidatorsResult() (ctypes.TMResult, error) {
|
||||
return Validators()
|
||||
}
|
||||
|
||||
func DumpConsensusStateResult() (ctypes.TMResult, error) {
|
||||
return DumpConsensusState()
|
||||
}
|
||||
|
||||
func UnconfirmedTxsResult() (ctypes.TMResult, error) {
|
||||
return UnconfirmedTxs()
|
||||
}
|
||||
|
||||
func NumUnconfirmedTxsResult() (ctypes.TMResult, error) {
|
||||
return NumUnconfirmedTxs()
|
||||
}
|
||||
|
||||
// Tx allow user to query the transaction results. `nil` could mean the
|
||||
// transaction is in the mempool, invalidated, or was not send in the first
|
||||
// place.
|
||||
func TxResult(hash []byte, prove bool) (ctypes.TMResult, error) {
|
||||
return Tx(hash, prove)
|
||||
}
|
||||
|
||||
func BroadcastTxCommitResult(tx types.Tx) (ctypes.TMResult, error) {
|
||||
return BroadcastTxCommit(tx)
|
||||
}
|
||||
|
||||
func BroadcastTxSyncResult(tx types.Tx) (ctypes.TMResult, error) {
|
||||
return BroadcastTxSync(tx)
|
||||
}
|
||||
|
||||
func BroadcastTxAsyncResult(tx types.Tx) (ctypes.TMResult, error) {
|
||||
return BroadcastTxAsync(tx)
|
||||
}
|
||||
|
||||
func ABCIQueryResult(path string, data data.Bytes, prove bool) (ctypes.TMResult, error) {
|
||||
return ABCIQuery(path, data, prove)
|
||||
}
|
||||
|
||||
func ABCIInfoResult() (ctypes.TMResult, error) {
|
||||
return ABCIInfo()
|
||||
}
|
||||
|
||||
func UnsafeFlushMempoolResult() (ctypes.TMResult, error) {
|
||||
return UnsafeFlushMempool()
|
||||
}
|
||||
|
||||
func UnsafeSetConfigResult(typ, key, value string) (ctypes.TMResult, error) {
|
||||
return UnsafeSetConfig(typ, key, value)
|
||||
}
|
||||
|
||||
func UnsafeStartCPUProfilerResult(filename string) (ctypes.TMResult, error) {
|
||||
return UnsafeStartCPUProfiler(filename)
|
||||
}
|
||||
|
||||
func UnsafeStopCPUProfilerResult() (ctypes.TMResult, error) {
|
||||
return UnsafeStopCPUProfiler()
|
||||
}
|
||||
|
||||
func UnsafeWriteHeapProfileResult(filename string) (ctypes.TMResult, error) {
|
||||
return UnsafeWriteHeapProfile(filename)
|
||||
"unsafe_start_cpu_profiler": rpc.NewRPCFunc(UnsafeStartCPUProfiler, "filename"),
|
||||
"unsafe_stop_cpu_profiler": rpc.NewRPCFunc(UnsafeStopCPUProfiler, ""),
|
||||
"unsafe_write_heap_profile": rpc.NewRPCFunc(UnsafeWriteHeapProfile, "filename"),
|
||||
}
|
||||
|
||||
+4
-1
@@ -8,6 +8,9 @@ import (
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
// Tx allow user to query the transaction results. `nil` could mean the
|
||||
// transaction is in the mempool, invalidated, or was not send in the first
|
||||
// place.
|
||||
func Tx(hash []byte, prove bool) (*ctypes.ResultTx, error) {
|
||||
|
||||
// if index is disabled, return error
|
||||
@@ -36,7 +39,7 @@ func Tx(hash []byte, prove bool) (*ctypes.ResultTx, error) {
|
||||
return &ctypes.ResultTx{
|
||||
Height: height,
|
||||
Index: index,
|
||||
TxResult: r.Result,
|
||||
TxResult: r.Result.Result(),
|
||||
Tx: r.Tx,
|
||||
Proof: proof,
|
||||
}, nil
|
||||
|
||||
+14
-92
@@ -5,10 +5,8 @@ import (
|
||||
|
||||
abci "github.com/tendermint/abci/types"
|
||||
"github.com/tendermint/go-crypto"
|
||||
data "github.com/tendermint/go-wire/data"
|
||||
"github.com/tendermint/go-wire/data"
|
||||
"github.com/tendermint/tendermint/p2p"
|
||||
"github.com/tendermint/tendermint/rpc/lib/types"
|
||||
"github.com/tendermint/go-wire"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
@@ -85,22 +83,22 @@ type ResultBroadcastTx struct {
|
||||
Data data.Bytes `json:"data"`
|
||||
Log string `json:"log"`
|
||||
|
||||
Hash []byte `json:"hash"`
|
||||
Hash data.Bytes `json:"hash"`
|
||||
}
|
||||
|
||||
type ResultBroadcastTxCommit struct {
|
||||
CheckTx *abci.ResponseCheckTx `json:"check_tx"`
|
||||
DeliverTx *abci.ResponseDeliverTx `json:"deliver_tx"`
|
||||
Hash []byte `json:"hash"`
|
||||
Height int `json:"height"`
|
||||
CheckTx abci.Result `json:"check_tx"`
|
||||
DeliverTx abci.Result `json:"deliver_tx"`
|
||||
Hash data.Bytes `json:"hash"`
|
||||
Height int `json:"height"`
|
||||
}
|
||||
|
||||
type ResultTx struct {
|
||||
Height int `json:"height"`
|
||||
Index int `json:"index"`
|
||||
TxResult abci.ResponseDeliverTx `json:"tx_result"`
|
||||
Tx types.Tx `json:"tx"`
|
||||
Proof types.TxProof `json:"proof,omitempty"`
|
||||
Height int `json:"height"`
|
||||
Index int `json:"index"`
|
||||
TxResult abci.Result `json:"tx_result"`
|
||||
Tx types.Tx `json:"tx"`
|
||||
Proof types.TxProof `json:"proof,omitempty"`
|
||||
}
|
||||
|
||||
type ResultUnconfirmedTxs struct {
|
||||
@@ -113,7 +111,7 @@ type ResultABCIInfo struct {
|
||||
}
|
||||
|
||||
type ResultABCIQuery struct {
|
||||
Response abci.ResponseQuery `json:"response"`
|
||||
*abci.ResultQuery `json:"response"`
|
||||
}
|
||||
|
||||
type ResultUnsafeFlushMempool struct{}
|
||||
@@ -122,87 +120,11 @@ type ResultUnsafeSetConfig struct{}
|
||||
|
||||
type ResultUnsafeProfile struct{}
|
||||
|
||||
type ResultSubscribe struct {
|
||||
}
|
||||
type ResultSubscribe struct{}
|
||||
|
||||
type ResultUnsubscribe struct {
|
||||
}
|
||||
type ResultUnsubscribe struct{}
|
||||
|
||||
type ResultEvent struct {
|
||||
Name string `json:"name"`
|
||||
Data types.TMEventData `json:"data"`
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
// response & result types
|
||||
|
||||
const (
|
||||
// 0x0 bytes are for the blockchain
|
||||
ResultTypeGenesis = byte(0x01)
|
||||
ResultTypeBlockchainInfo = byte(0x02)
|
||||
ResultTypeBlock = byte(0x03)
|
||||
ResultTypeCommit = byte(0x04)
|
||||
|
||||
// 0x2 bytes are for the network
|
||||
ResultTypeStatus = byte(0x20)
|
||||
ResultTypeNetInfo = byte(0x21)
|
||||
ResultTypeDialSeeds = byte(0x22)
|
||||
|
||||
// 0x4 bytes are for the consensus
|
||||
ResultTypeValidators = byte(0x40)
|
||||
ResultTypeDumpConsensusState = byte(0x41)
|
||||
|
||||
// 0x6 bytes are for txs / the application
|
||||
ResultTypeBroadcastTx = byte(0x60)
|
||||
ResultTypeUnconfirmedTxs = byte(0x61)
|
||||
ResultTypeBroadcastTxCommit = byte(0x62)
|
||||
ResultTypeTx = byte(0x63)
|
||||
|
||||
// 0x7 bytes are for querying the application
|
||||
ResultTypeABCIQuery = byte(0x70)
|
||||
ResultTypeABCIInfo = byte(0x71)
|
||||
|
||||
// 0x8 bytes are for events
|
||||
ResultTypeSubscribe = byte(0x80)
|
||||
ResultTypeUnsubscribe = byte(0x81)
|
||||
ResultTypeEvent = byte(0x82)
|
||||
|
||||
// 0xa bytes for testing
|
||||
ResultTypeUnsafeSetConfig = byte(0xa0)
|
||||
ResultTypeUnsafeStartCPUProfiler = byte(0xa1)
|
||||
ResultTypeUnsafeStopCPUProfiler = byte(0xa2)
|
||||
ResultTypeUnsafeWriteHeapProfile = byte(0xa3)
|
||||
ResultTypeUnsafeFlushMempool = byte(0xa4)
|
||||
)
|
||||
|
||||
type TMResult interface {
|
||||
rpctypes.Result
|
||||
}
|
||||
|
||||
// for wire.readReflect
|
||||
var _ = wire.RegisterInterface(
|
||||
struct{ TMResult }{},
|
||||
wire.ConcreteType{&ResultGenesis{}, ResultTypeGenesis},
|
||||
wire.ConcreteType{&ResultBlockchainInfo{}, ResultTypeBlockchainInfo},
|
||||
wire.ConcreteType{&ResultBlock{}, ResultTypeBlock},
|
||||
wire.ConcreteType{&ResultCommit{}, ResultTypeCommit},
|
||||
wire.ConcreteType{&ResultStatus{}, ResultTypeStatus},
|
||||
wire.ConcreteType{&ResultNetInfo{}, ResultTypeNetInfo},
|
||||
wire.ConcreteType{&ResultDialSeeds{}, ResultTypeDialSeeds},
|
||||
wire.ConcreteType{&ResultValidators{}, ResultTypeValidators},
|
||||
wire.ConcreteType{&ResultDumpConsensusState{}, ResultTypeDumpConsensusState},
|
||||
wire.ConcreteType{&ResultBroadcastTx{}, ResultTypeBroadcastTx},
|
||||
wire.ConcreteType{&ResultBroadcastTxCommit{}, ResultTypeBroadcastTxCommit},
|
||||
wire.ConcreteType{&ResultTx{}, ResultTypeTx},
|
||||
wire.ConcreteType{&ResultUnconfirmedTxs{}, ResultTypeUnconfirmedTxs},
|
||||
wire.ConcreteType{&ResultSubscribe{}, ResultTypeSubscribe},
|
||||
wire.ConcreteType{&ResultUnsubscribe{}, ResultTypeUnsubscribe},
|
||||
wire.ConcreteType{&ResultEvent{}, ResultTypeEvent},
|
||||
wire.ConcreteType{&ResultUnsafeSetConfig{}, ResultTypeUnsafeSetConfig},
|
||||
wire.ConcreteType{&ResultUnsafeProfile{}, ResultTypeUnsafeStartCPUProfiler},
|
||||
wire.ConcreteType{&ResultUnsafeProfile{}, ResultTypeUnsafeStopCPUProfiler},
|
||||
wire.ConcreteType{&ResultUnsafeProfile{}, ResultTypeUnsafeWriteHeapProfile},
|
||||
wire.ConcreteType{&ResultUnsafeFlushMempool{}, ResultTypeUnsafeFlushMempool},
|
||||
wire.ConcreteType{&ResultABCIQuery{}, ResultTypeABCIQuery},
|
||||
wire.ConcreteType{&ResultABCIInfo{}, ResultTypeABCIInfo},
|
||||
)
|
||||
|
||||
+15
-1
@@ -3,6 +3,8 @@ package core_grpc
|
||||
import (
|
||||
core "github.com/tendermint/tendermint/rpc/core"
|
||||
|
||||
abci "github.com/tendermint/abci/types"
|
||||
|
||||
context "golang.org/x/net/context"
|
||||
)
|
||||
|
||||
@@ -14,5 +16,17 @@ func (bapi *broadcastAPI) BroadcastTx(ctx context.Context, req *RequestBroadcast
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ResponseBroadcastTx{res.CheckTx, res.DeliverTx}, nil
|
||||
return &ResponseBroadcastTx{
|
||||
|
||||
CheckTx: &abci.ResponseCheckTx{
|
||||
Code: res.CheckTx.Code,
|
||||
Data: res.CheckTx.Data,
|
||||
Log: res.CheckTx.Log,
|
||||
},
|
||||
DeliverTx: &abci.ResponseDeliverTx{
|
||||
Code: res.DeliverTx.Code,
|
||||
Data: res.DeliverTx.Data,
|
||||
Log: res.DeliverTx.Log,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
+2
-10
@@ -59,25 +59,17 @@ though this is configurable when starting the server.
|
||||
Define some types and routes:
|
||||
|
||||
```
|
||||
// Define a type for results and register concrete versions with go-wire
|
||||
type Result interface{}
|
||||
|
||||
type ResultStatus struct {
|
||||
Value string
|
||||
}
|
||||
|
||||
var _ = wire.RegisterInterface(
|
||||
struct{ Result }{},
|
||||
wire.ConcreteType{&ResultStatus{}, 0x1},
|
||||
)
|
||||
|
||||
// Define some routes
|
||||
var Routes = map[string]*rpcserver.RPCFunc{
|
||||
"status": rpcserver.NewRPCFunc(StatusResult, "arg"),
|
||||
"status": rpcserver.NewRPCFunc(Status, "arg"),
|
||||
}
|
||||
|
||||
// an rpc function
|
||||
func StatusResult(v string) (Result, error) {
|
||||
func Status(v string) (*ResultStatus, error) {
|
||||
return &ResultStatus{v}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
wire "github.com/tendermint/go-wire"
|
||||
types "github.com/tendermint/tendermint/rpc/lib/types"
|
||||
)
|
||||
|
||||
@@ -68,18 +67,9 @@ func NewJSONRPCClient(remote string) *JSONRPCClient {
|
||||
}
|
||||
|
||||
func (c *JSONRPCClient) Call(method string, params map[string]interface{}, result interface{}) (interface{}, error) {
|
||||
// we need this step because we attempt to decode values using `go-wire`
|
||||
// (handlers.go:176) on the server side
|
||||
encodedParams := make(map[string]interface{})
|
||||
for k, v := range params {
|
||||
bytes := json.RawMessage(wire.JSONBytes(v))
|
||||
encodedParams[k] = &bytes
|
||||
}
|
||||
request := types.RPCRequest{
|
||||
JSONRPC: "2.0",
|
||||
Method: method,
|
||||
Params: encodedParams,
|
||||
ID: "",
|
||||
request, err := types.MapToRequest("", method, params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
requestBytes, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
@@ -153,7 +143,7 @@ func unmarshalResponseBytes(responseBytes []byte, result interface{}) (interface
|
||||
return nil, errors.Errorf("Response error: %v", errorStr)
|
||||
}
|
||||
// unmarshal the RawMessage into the result
|
||||
result = wire.ReadJSONPtr(result, *response.Result, &err)
|
||||
err = json.Unmarshal(*response.Result, result)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("Error unmarshalling rpc response result: %v", err)
|
||||
}
|
||||
@@ -176,8 +166,6 @@ func argsToURLValues(args map[string]interface{}) (url.Values, error) {
|
||||
}
|
||||
|
||||
func argsToJson(args map[string]interface{}) error {
|
||||
var n int
|
||||
var err error
|
||||
for k, v := range args {
|
||||
rt := reflect.TypeOf(v)
|
||||
isByteSlice := rt.Kind() == reflect.Slice && rt.Elem().Kind() == reflect.Uint8
|
||||
@@ -188,12 +176,11 @@ func argsToJson(args map[string]interface{}) error {
|
||||
}
|
||||
|
||||
// Pass everything else to go-wire
|
||||
buf := new(bytes.Buffer)
|
||||
wire.WriteJSON(v, buf, &n, &err)
|
||||
data, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
args[k] = buf.String()
|
||||
args[k] = string(data)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
+14
-26
@@ -8,9 +8,8 @@ import (
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/pkg/errors"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
types "github.com/tendermint/tendermint/rpc/lib/types"
|
||||
wire "github.com/tendermint/go-wire"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -131,42 +130,31 @@ func (wsc *WSClient) receiveEventsRoutine() {
|
||||
// Subscribe to an event. Note the server must have a "subscribe" route
|
||||
// defined.
|
||||
func (wsc *WSClient) Subscribe(eventid string) error {
|
||||
err := wsc.WriteJSON(types.RPCRequest{
|
||||
JSONRPC: "2.0",
|
||||
ID: "",
|
||||
Method: "subscribe",
|
||||
Params: map[string]interface{}{"event": eventid},
|
||||
})
|
||||
params := map[string]interface{}{"event": eventid}
|
||||
request, err := types.MapToRequest("", "subscribe", params)
|
||||
if err == nil {
|
||||
err = wsc.WriteJSON(request)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Unsubscribe from an event. Note the server must have a "unsubscribe" route
|
||||
// defined.
|
||||
func (wsc *WSClient) Unsubscribe(eventid string) error {
|
||||
err := wsc.WriteJSON(types.RPCRequest{
|
||||
JSONRPC: "2.0",
|
||||
ID: "",
|
||||
Method: "unsubscribe",
|
||||
Params: map[string]interface{}{"event": eventid},
|
||||
})
|
||||
params := map[string]interface{}{"event": eventid}
|
||||
request, err := types.MapToRequest("", "unsubscribe", params)
|
||||
if err == nil {
|
||||
err = wsc.WriteJSON(request)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Call asynchronously calls a given method by sending an RPCRequest to the
|
||||
// server. Results will be available on ResultsCh, errors, if any, on ErrorsCh.
|
||||
func (wsc *WSClient) Call(method string, params map[string]interface{}) error {
|
||||
// we need this step because we attempt to decode values using `go-wire`
|
||||
// (handlers.go:470) on the server side
|
||||
encodedParams := make(map[string]interface{})
|
||||
for k, v := range params {
|
||||
bytes := json.RawMessage(wire.JSONBytes(v))
|
||||
encodedParams[k] = &bytes
|
||||
request, err := types.MapToRequest("", method, params)
|
||||
if err == nil {
|
||||
err = wsc.WriteJSON(request)
|
||||
}
|
||||
err := wsc.WriteJSON(types.RPCRequest{
|
||||
JSONRPC: "2.0",
|
||||
Method: method,
|
||||
Params: encodedParams,
|
||||
ID: "",
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
+84
-50
@@ -3,6 +3,7 @@ package rpc
|
||||
import (
|
||||
"bytes"
|
||||
crand "crypto/rand"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
@@ -12,7 +13,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
wire "github.com/tendermint/go-wire"
|
||||
"github.com/tendermint/go-wire/data"
|
||||
client "github.com/tendermint/tendermint/rpc/lib/client"
|
||||
server "github.com/tendermint/tendermint/rpc/lib/server"
|
||||
types "github.com/tendermint/tendermint/rpc/lib/types"
|
||||
@@ -20,50 +21,59 @@ import (
|
||||
|
||||
// Client and Server should work over tcp or unix sockets
|
||||
const (
|
||||
tcpAddr = "tcp://0.0.0.0:46657"
|
||||
tcpAddr = "tcp://0.0.0.0:47768"
|
||||
|
||||
unixSocket = "/tmp/rpc.sock"
|
||||
unixAddr = "unix:///tmp/rpc.sock"
|
||||
unixSocket = "/tmp/rpc_test.sock"
|
||||
unixAddr = "unix://" + unixSocket
|
||||
|
||||
websocketEndpoint = "/websocket/endpoint"
|
||||
)
|
||||
|
||||
// Define a type for results and register concrete versions
|
||||
type Result interface{}
|
||||
|
||||
type ResultEcho struct {
|
||||
Value string
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
type ResultEchoInt struct {
|
||||
Value int `json:"value"`
|
||||
}
|
||||
|
||||
type ResultEchoBytes struct {
|
||||
Value []byte
|
||||
Value []byte `json:"value"`
|
||||
}
|
||||
|
||||
var _ = wire.RegisterInterface(
|
||||
struct{ Result }{},
|
||||
wire.ConcreteType{&ResultEcho{}, 0x1},
|
||||
wire.ConcreteType{&ResultEchoBytes{}, 0x2},
|
||||
)
|
||||
type ResultEchoDataBytes struct {
|
||||
Value data.Bytes `json:"value"`
|
||||
}
|
||||
|
||||
// Define some routes
|
||||
var Routes = map[string]*server.RPCFunc{
|
||||
"echo": server.NewRPCFunc(EchoResult, "arg"),
|
||||
"echo_ws": server.NewWSRPCFunc(EchoWSResult, "arg"),
|
||||
"echo_bytes": server.NewRPCFunc(EchoBytesResult, "arg"),
|
||||
"echo": server.NewRPCFunc(EchoResult, "arg"),
|
||||
"echo_ws": server.NewWSRPCFunc(EchoWSResult, "arg"),
|
||||
"echo_bytes": server.NewRPCFunc(EchoBytesResult, "arg"),
|
||||
"echo_data_bytes": server.NewRPCFunc(EchoDataBytesResult, "arg"),
|
||||
"echo_int": server.NewRPCFunc(EchoIntResult, "arg"),
|
||||
}
|
||||
|
||||
func EchoResult(v string) (Result, error) {
|
||||
func EchoResult(v string) (*ResultEcho, error) {
|
||||
return &ResultEcho{v}, nil
|
||||
}
|
||||
|
||||
func EchoWSResult(wsCtx types.WSRPCContext, v string) (Result, error) {
|
||||
func EchoWSResult(wsCtx types.WSRPCContext, v string) (*ResultEcho, error) {
|
||||
return &ResultEcho{v}, nil
|
||||
}
|
||||
|
||||
func EchoBytesResult(v []byte) (Result, error) {
|
||||
func EchoIntResult(v int) (*ResultEchoInt, error) {
|
||||
return &ResultEchoInt{v}, nil
|
||||
}
|
||||
|
||||
func EchoBytesResult(v []byte) (*ResultEchoBytes, error) {
|
||||
return &ResultEchoBytes{v}, nil
|
||||
}
|
||||
|
||||
func EchoDataBytesResult(v data.Bytes) (*ResultEchoDataBytes, error) {
|
||||
return &ResultEchoDataBytes{v}, nil
|
||||
}
|
||||
|
||||
// launch unix and tcp servers
|
||||
func init() {
|
||||
cmd := exec.Command("rm", "-f", unixSocket)
|
||||
@@ -105,22 +115,44 @@ func echoViaHTTP(cl client.HTTPClient, val string) (string, error) {
|
||||
params := map[string]interface{}{
|
||||
"arg": val,
|
||||
}
|
||||
var result Result
|
||||
if _, err := cl.Call("echo", params, &result); err != nil {
|
||||
result := new(ResultEcho)
|
||||
if _, err := cl.Call("echo", params, result); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return result.(*ResultEcho).Value, nil
|
||||
return result.Value, nil
|
||||
}
|
||||
|
||||
func echoIntViaHTTP(cl client.HTTPClient, val int) (int, error) {
|
||||
params := map[string]interface{}{
|
||||
"arg": val,
|
||||
}
|
||||
result := new(ResultEchoInt)
|
||||
if _, err := cl.Call("echo_int", params, result); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return result.Value, nil
|
||||
}
|
||||
|
||||
func echoBytesViaHTTP(cl client.HTTPClient, bytes []byte) ([]byte, error) {
|
||||
params := map[string]interface{}{
|
||||
"arg": bytes,
|
||||
}
|
||||
var result Result
|
||||
if _, err := cl.Call("echo_bytes", params, &result); err != nil {
|
||||
result := new(ResultEchoBytes)
|
||||
if _, err := cl.Call("echo_bytes", params, result); err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
return result.(*ResultEchoBytes).Value, nil
|
||||
return result.Value, nil
|
||||
}
|
||||
|
||||
func echoDataBytesViaHTTP(cl client.HTTPClient, bytes data.Bytes) (data.Bytes, error) {
|
||||
params := map[string]interface{}{
|
||||
"arg": bytes,
|
||||
}
|
||||
result := new(ResultEchoDataBytes)
|
||||
if _, err := cl.Call("echo_data_bytes", params, result); err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
return result.Value, nil
|
||||
}
|
||||
|
||||
func testWithHTTPClient(t *testing.T, cl client.HTTPClient) {
|
||||
@@ -133,6 +165,16 @@ func testWithHTTPClient(t *testing.T, cl client.HTTPClient) {
|
||||
got2, err := echoBytesViaHTTP(cl, val2)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, got2, val2)
|
||||
|
||||
val3 := data.Bytes(randBytes(t))
|
||||
got3, err := echoDataBytesViaHTTP(cl, val3)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, got3, val3)
|
||||
|
||||
val4 := rand.Intn(10000)
|
||||
got4, err := echoIntViaHTTP(cl, val4)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, got4, val4)
|
||||
}
|
||||
|
||||
func echoViaWS(cl *client.WSClient, val string) (string, error) {
|
||||
@@ -146,12 +188,12 @@ func echoViaWS(cl *client.WSClient, val string) (string, error) {
|
||||
|
||||
select {
|
||||
case msg := <-cl.ResultsCh:
|
||||
result := new(Result)
|
||||
wire.ReadJSONPtr(result, msg, &err)
|
||||
result := new(ResultEcho)
|
||||
err = json.Unmarshal(msg, result)
|
||||
if err != nil {
|
||||
return "", nil
|
||||
}
|
||||
return (*result).(*ResultEcho).Value, nil
|
||||
return result.Value, nil
|
||||
case err := <-cl.ErrorsCh:
|
||||
return "", err
|
||||
}
|
||||
@@ -168,12 +210,12 @@ func echoBytesViaWS(cl *client.WSClient, bytes []byte) ([]byte, error) {
|
||||
|
||||
select {
|
||||
case msg := <-cl.ResultsCh:
|
||||
result := new(Result)
|
||||
wire.ReadJSONPtr(result, msg, &err)
|
||||
result := new(ResultEchoBytes)
|
||||
err = json.Unmarshal(msg, result)
|
||||
if err != nil {
|
||||
return []byte{}, nil
|
||||
}
|
||||
return (*result).(*ResultEchoBytes).Value, nil
|
||||
return result.Value, nil
|
||||
case err := <-cl.ErrorsCh:
|
||||
return []byte{}, err
|
||||
}
|
||||
@@ -241,20 +283,15 @@ func TestWSNewWSRPCFunc(t *testing.T) {
|
||||
params := map[string]interface{}{
|
||||
"arg": val,
|
||||
}
|
||||
err = cl.WriteJSON(types.RPCRequest{
|
||||
JSONRPC: "2.0",
|
||||
ID: "",
|
||||
Method: "echo_ws",
|
||||
Params: params,
|
||||
})
|
||||
err = cl.Call("echo_ws", params)
|
||||
require.Nil(t, err)
|
||||
|
||||
select {
|
||||
case msg := <-cl.ResultsCh:
|
||||
result := new(Result)
|
||||
wire.ReadJSONPtr(result, msg, &err)
|
||||
result := new(ResultEcho)
|
||||
err = json.Unmarshal(msg, result)
|
||||
require.Nil(t, err)
|
||||
got := (*result).(*ResultEcho).Value
|
||||
got := result.Value
|
||||
assert.Equal(t, got, val)
|
||||
case err := <-cl.ErrorsCh:
|
||||
t.Fatal(err)
|
||||
@@ -269,20 +306,17 @@ func TestWSHandlesArrayParams(t *testing.T) {
|
||||
|
||||
val := "acbd"
|
||||
params := []interface{}{val}
|
||||
err = cl.WriteJSON(types.RPCRequest{
|
||||
JSONRPC: "2.0",
|
||||
ID: "",
|
||||
Method: "echo_ws",
|
||||
Params: params,
|
||||
})
|
||||
request, err := types.ArrayToRequest("", "echo_ws", params)
|
||||
require.Nil(t, err)
|
||||
err = cl.WriteJSON(request)
|
||||
require.Nil(t, err)
|
||||
|
||||
select {
|
||||
case msg := <-cl.ResultsCh:
|
||||
result := new(Result)
|
||||
wire.ReadJSONPtr(result, msg, &err)
|
||||
result := new(ResultEcho)
|
||||
err = json.Unmarshal(msg, result)
|
||||
require.Nil(t, err)
|
||||
got := (*result).(*ResultEcho).Value
|
||||
got := result.Value
|
||||
assert.Equal(t, got, val)
|
||||
case err := <-cl.ErrorsCh:
|
||||
t.Fatalf("%+v", err)
|
||||
|
||||
+63
-60
@@ -14,7 +14,7 @@ import (
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/pkg/errors"
|
||||
wire "github.com/tendermint/go-wire"
|
||||
|
||||
types "github.com/tendermint/tendermint/rpc/lib/types"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
events "github.com/tendermint/tmlibs/events"
|
||||
@@ -140,78 +140,84 @@ func makeJSONRPCHandler(funcMap map[string]*RPCFunc) http.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
// Convert a []interface{} OR a map[string]interface{} to properly typed values
|
||||
func mapParamsToArgs(rpcFunc *RPCFunc, params map[string]*json.RawMessage, argsOffset int) ([]reflect.Value, error) {
|
||||
values := make([]reflect.Value, len(rpcFunc.argNames))
|
||||
for i, argName := range rpcFunc.argNames {
|
||||
argType := rpcFunc.args[i+argsOffset]
|
||||
|
||||
if p, ok := params[argName]; ok && len(*p) > 0 {
|
||||
val := reflect.New(argType)
|
||||
err := json.Unmarshal(*p, val.Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
values[i] = val.Elem()
|
||||
} else { // use default for that type
|
||||
values[i] = reflect.Zero(argType)
|
||||
}
|
||||
}
|
||||
|
||||
return values, nil
|
||||
}
|
||||
|
||||
func arrayParamsToArgs(rpcFunc *RPCFunc, params []*json.RawMessage, argsOffset int) ([]reflect.Value, error) {
|
||||
if len(rpcFunc.argNames) != len(params) {
|
||||
return nil, errors.Errorf("Expected %v parameters (%v), got %v (%v)",
|
||||
len(rpcFunc.argNames), rpcFunc.argNames, len(params), params)
|
||||
}
|
||||
|
||||
values := make([]reflect.Value, len(params))
|
||||
for i, p := range params {
|
||||
argType := rpcFunc.args[i+argsOffset]
|
||||
val := reflect.New(argType)
|
||||
err := json.Unmarshal(*p, val.Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
values[i] = val.Elem()
|
||||
}
|
||||
return values, nil
|
||||
}
|
||||
|
||||
// raw is unparsed json (from json.RawMessage) encoding either a map or an array.
|
||||
//
|
||||
// argsOffset should be 0 for RPC calls, and 1 for WS requests, where len(rpcFunc.args) != len(rpcFunc.argNames).
|
||||
// Example:
|
||||
// rpcFunc.args = [rpctypes.WSRPCContext string]
|
||||
// rpcFunc.argNames = ["arg"]
|
||||
func jsonParamsToArgs(rpcFunc *RPCFunc, paramsI interface{}, argsOffset int) ([]reflect.Value, error) {
|
||||
values := make([]reflect.Value, len(rpcFunc.argNames))
|
||||
|
||||
switch params := paramsI.(type) {
|
||||
|
||||
case map[string]interface{}:
|
||||
for i, argName := range rpcFunc.argNames {
|
||||
argType := rpcFunc.args[i+argsOffset]
|
||||
|
||||
// decode param if provided
|
||||
if param, ok := params[argName]; ok && "" != param {
|
||||
v, err := _jsonObjectToArg(argType, param)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
values[i] = v
|
||||
} else { // use default for that type
|
||||
values[i] = reflect.Zero(argType)
|
||||
}
|
||||
}
|
||||
case []interface{}:
|
||||
if len(rpcFunc.argNames) != len(params) {
|
||||
return nil, errors.New(fmt.Sprintf("Expected %v parameters (%v), got %v (%v)",
|
||||
len(rpcFunc.argNames), rpcFunc.argNames, len(params), params))
|
||||
}
|
||||
values := make([]reflect.Value, len(params))
|
||||
for i, p := range params {
|
||||
ty := rpcFunc.args[i+argsOffset]
|
||||
v, err := _jsonObjectToArg(ty, p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
values[i] = v
|
||||
}
|
||||
return values, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("Unknown type for JSON params %v. Expected map[string]interface{} or []interface{}", reflect.TypeOf(paramsI))
|
||||
func jsonParamsToArgs(rpcFunc *RPCFunc, raw []byte, argsOffset int) ([]reflect.Value, error) {
|
||||
// first, try to get the map..
|
||||
var m map[string]*json.RawMessage
|
||||
err := json.Unmarshal(raw, &m)
|
||||
if err == nil {
|
||||
return mapParamsToArgs(rpcFunc, m, argsOffset)
|
||||
}
|
||||
return values, nil
|
||||
|
||||
// otherwise, try an array
|
||||
var a []*json.RawMessage
|
||||
err = json.Unmarshal(raw, &a)
|
||||
if err == nil {
|
||||
return arrayParamsToArgs(rpcFunc, a, argsOffset)
|
||||
}
|
||||
|
||||
// otherwise, bad format, we cannot parse
|
||||
return nil, errors.Errorf("Unknown type for JSON params: %v. Expected map or array", err)
|
||||
}
|
||||
|
||||
// Convert a []interface{} OR a map[string]interface{} to properly typed values
|
||||
func jsonParamsToArgsRPC(rpcFunc *RPCFunc, paramsI interface{}) ([]reflect.Value, error) {
|
||||
return jsonParamsToArgs(rpcFunc, paramsI, 0)
|
||||
func jsonParamsToArgsRPC(rpcFunc *RPCFunc, params *json.RawMessage) ([]reflect.Value, error) {
|
||||
return jsonParamsToArgs(rpcFunc, *params, 0)
|
||||
}
|
||||
|
||||
// Same as above, but with the first param the websocket connection
|
||||
func jsonParamsToArgsWS(rpcFunc *RPCFunc, paramsI interface{}, wsCtx types.WSRPCContext) ([]reflect.Value, error) {
|
||||
values, err := jsonParamsToArgs(rpcFunc, paramsI, 1)
|
||||
func jsonParamsToArgsWS(rpcFunc *RPCFunc, params *json.RawMessage, wsCtx types.WSRPCContext) ([]reflect.Value, error) {
|
||||
values, err := jsonParamsToArgs(rpcFunc, *params, 1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return append([]reflect.Value{reflect.ValueOf(wsCtx)}, values...), nil
|
||||
}
|
||||
|
||||
func _jsonObjectToArg(ty reflect.Type, object interface{}) (reflect.Value, error) {
|
||||
var err error
|
||||
v := reflect.New(ty)
|
||||
wire.ReadJSONObjectPtr(v.Interface(), object, &err)
|
||||
if err != nil {
|
||||
return v, err
|
||||
}
|
||||
v = v.Elem()
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// rpc.json
|
||||
//-----------------------------------------------------------------------------
|
||||
// rpc.http
|
||||
@@ -269,7 +275,6 @@ func httpParamsToArgs(rpcFunc *RPCFunc, r *http.Request) ([]reflect.Value, error
|
||||
continue
|
||||
}
|
||||
|
||||
// Pass values to go-wire
|
||||
values[i], err = _jsonStringToArg(argType, arg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -280,9 +285,8 @@ func httpParamsToArgs(rpcFunc *RPCFunc, r *http.Request) ([]reflect.Value, error
|
||||
}
|
||||
|
||||
func _jsonStringToArg(ty reflect.Type, arg string) (reflect.Value, error) {
|
||||
var err error
|
||||
v := reflect.New(ty)
|
||||
wire.ReadJSONPtr(v.Interface(), []byte(arg), &err)
|
||||
err := json.Unmarshal([]byte(arg), v.Interface())
|
||||
if err != nil {
|
||||
return v, err
|
||||
}
|
||||
@@ -315,9 +319,8 @@ func nonJsonToArg(ty reflect.Type, arg string) (reflect.Value, error, bool) {
|
||||
}
|
||||
|
||||
if isQuotedString && expectingByteSlice {
|
||||
var err error
|
||||
v := reflect.New(reflect.TypeOf(""))
|
||||
wire.ReadJSONPtr(v.Interface(), []byte(arg), &err)
|
||||
err := json.Unmarshal([]byte(arg), v.Interface())
|
||||
if err != nil {
|
||||
return reflect.ValueOf(nil), err, false
|
||||
}
|
||||
|
||||
@@ -58,7 +58,6 @@ func WriteRPCResponseHTTPError(w http.ResponseWriter, httpCode int, res types.RP
|
||||
}
|
||||
|
||||
func WriteRPCResponseHTTP(w http.ResponseWriter, res types.RPCResponse) {
|
||||
// jsonBytes := wire.JSONBytesPretty(res)
|
||||
jsonBytes, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
package rpcserver
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/tendermint/go-wire/data"
|
||||
)
|
||||
|
||||
func TestParseJSONMap(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
input := []byte(`{"value":"1234","height":22}`)
|
||||
|
||||
// naive is float,string
|
||||
var p1 map[string]interface{}
|
||||
err := json.Unmarshal(input, &p1)
|
||||
if assert.Nil(err) {
|
||||
h, ok := p1["height"].(float64)
|
||||
if assert.True(ok, "%#v", p1["height"]) {
|
||||
assert.EqualValues(22, h)
|
||||
}
|
||||
v, ok := p1["value"].(string)
|
||||
if assert.True(ok, "%#v", p1["value"]) {
|
||||
assert.EqualValues("1234", v)
|
||||
}
|
||||
}
|
||||
|
||||
// preloading map with values doesn't help
|
||||
tmp := 0
|
||||
p2 := map[string]interface{}{
|
||||
"value": &data.Bytes{},
|
||||
"height": &tmp,
|
||||
}
|
||||
err = json.Unmarshal(input, &p2)
|
||||
if assert.Nil(err) {
|
||||
h, ok := p2["height"].(float64)
|
||||
if assert.True(ok, "%#v", p2["height"]) {
|
||||
assert.EqualValues(22, h)
|
||||
}
|
||||
v, ok := p2["value"].(string)
|
||||
if assert.True(ok, "%#v", p2["value"]) {
|
||||
assert.EqualValues("1234", v)
|
||||
}
|
||||
}
|
||||
|
||||
// preload here with *pointers* to the desired types
|
||||
// struct has unknown types, but hard-coded keys
|
||||
tmp = 0
|
||||
p3 := struct {
|
||||
Value interface{} `json:"value"`
|
||||
Height interface{} `json:"height"`
|
||||
}{
|
||||
Height: &tmp,
|
||||
Value: &data.Bytes{},
|
||||
}
|
||||
err = json.Unmarshal(input, &p3)
|
||||
if assert.Nil(err) {
|
||||
h, ok := p3.Height.(*int)
|
||||
if assert.True(ok, "%#v", p3.Height) {
|
||||
assert.Equal(22, *h)
|
||||
}
|
||||
v, ok := p3.Value.(*data.Bytes)
|
||||
if assert.True(ok, "%#v", p3.Value) {
|
||||
assert.EqualValues([]byte{0x12, 0x34}, *v)
|
||||
}
|
||||
}
|
||||
|
||||
// simplest solution, but hard-coded
|
||||
p4 := struct {
|
||||
Value data.Bytes `json:"value"`
|
||||
Height int `json:"height"`
|
||||
}{}
|
||||
err = json.Unmarshal(input, &p4)
|
||||
if assert.Nil(err) {
|
||||
assert.EqualValues(22, p4.Height)
|
||||
assert.EqualValues([]byte{0x12, 0x34}, p4.Value)
|
||||
}
|
||||
|
||||
// so, let's use this trick...
|
||||
// dynamic keys on map, and we can deserialize to the desired types
|
||||
var p5 map[string]*json.RawMessage
|
||||
err = json.Unmarshal(input, &p5)
|
||||
if assert.Nil(err) {
|
||||
var h int
|
||||
err = json.Unmarshal(*p5["height"], &h)
|
||||
if assert.Nil(err) {
|
||||
assert.Equal(22, h)
|
||||
}
|
||||
|
||||
var v data.Bytes
|
||||
err = json.Unmarshal(*p5["value"], &v)
|
||||
if assert.Nil(err) {
|
||||
assert.Equal(data.Bytes{0x12, 0x34}, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseJSONArray(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
input := []byte(`["1234",22]`)
|
||||
|
||||
// naive is float,string
|
||||
var p1 []interface{}
|
||||
err := json.Unmarshal(input, &p1)
|
||||
if assert.Nil(err) {
|
||||
v, ok := p1[0].(string)
|
||||
if assert.True(ok, "%#v", p1[0]) {
|
||||
assert.EqualValues("1234", v)
|
||||
}
|
||||
h, ok := p1[1].(float64)
|
||||
if assert.True(ok, "%#v", p1[1]) {
|
||||
assert.EqualValues(22, h)
|
||||
}
|
||||
}
|
||||
|
||||
// preloading map with values helps here (unlike map - p2 above)
|
||||
tmp := 0
|
||||
p2 := []interface{}{&data.Bytes{}, &tmp}
|
||||
err = json.Unmarshal(input, &p2)
|
||||
if assert.Nil(err) {
|
||||
v, ok := p2[0].(*data.Bytes)
|
||||
if assert.True(ok, "%#v", p2[0]) {
|
||||
assert.EqualValues([]byte{0x12, 0x34}, *v)
|
||||
}
|
||||
h, ok := p2[1].(*int)
|
||||
if assert.True(ok, "%#v", p2[1]) {
|
||||
assert.EqualValues(22, *h)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseRPC(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
demo := func(height int, name string) {}
|
||||
call := NewRPCFunc(demo, "height,name")
|
||||
|
||||
cases := []struct {
|
||||
raw string
|
||||
height int64
|
||||
name string
|
||||
fail bool
|
||||
}{
|
||||
// should parse
|
||||
{`[7, "flew"]`, 7, "flew", false},
|
||||
{`{"name": "john", "height": 22}`, 22, "john", false},
|
||||
// defaults
|
||||
{`{"name": "solo", "unused": "stuff"}`, 0, "solo", false},
|
||||
// should fail - wrong types/lenght
|
||||
{`["flew", 7]`, 0, "", true},
|
||||
{`[7,"flew",100]`, 0, "", true},
|
||||
{`{"name": -12, "height": "fred"}`, 0, "", true},
|
||||
}
|
||||
for idx, tc := range cases {
|
||||
i := strconv.Itoa(idx)
|
||||
data := []byte(tc.raw)
|
||||
vals, err := jsonParamsToArgs(call, data, 0)
|
||||
if tc.fail {
|
||||
assert.NotNil(err, i)
|
||||
} else {
|
||||
assert.Nil(err, "%s: %+v", i, err)
|
||||
if assert.Equal(2, len(vals), i) {
|
||||
assert.Equal(tc.height, vals[0].Int(), i)
|
||||
assert.Equal(tc.name, vals[1].String(), i)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+29
-22
@@ -4,40 +4,41 @@ import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
wire "github.com/tendermint/go-wire"
|
||||
events "github.com/tendermint/tmlibs/events"
|
||||
)
|
||||
|
||||
type RPCRequest struct {
|
||||
JSONRPC string `json:"jsonrpc"`
|
||||
ID string `json:"id"`
|
||||
Method string `json:"method"`
|
||||
Params interface{} `json:"params"` // must be map[string]interface{} or []interface{}
|
||||
JSONRPC string `json:"jsonrpc"`
|
||||
ID string `json:"id"`
|
||||
Method string `json:"method"`
|
||||
Params *json.RawMessage `json:"params"` // must be map[string]interface{} or []interface{}
|
||||
}
|
||||
|
||||
func NewRPCRequest(id string, method string, params map[string]interface{}) RPCRequest {
|
||||
func NewRPCRequest(id string, method string, params json.RawMessage) RPCRequest {
|
||||
return RPCRequest{
|
||||
JSONRPC: "2.0",
|
||||
ID: id,
|
||||
Method: method,
|
||||
Params: params,
|
||||
Params: ¶ms,
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
func MapToRequest(id string, method string, params map[string]interface{}) (RPCRequest, error) {
|
||||
payload, err := json.Marshal(params)
|
||||
if err != nil {
|
||||
return RPCRequest{}, err
|
||||
}
|
||||
request := NewRPCRequest(id, method, payload)
|
||||
return request, nil
|
||||
}
|
||||
|
||||
/*
|
||||
Result is a generic interface.
|
||||
Applications should register type-bytes like so:
|
||||
|
||||
var _ = wire.RegisterInterface(
|
||||
struct{ Result }{},
|
||||
wire.ConcreteType{&ResultGenesis{}, ResultTypeGenesis},
|
||||
wire.ConcreteType{&ResultBlockchainInfo{}, ResultTypeBlockchainInfo},
|
||||
...
|
||||
)
|
||||
*/
|
||||
type Result interface {
|
||||
func ArrayToRequest(id string, method string, params []interface{}) (RPCRequest, error) {
|
||||
payload, err := json.Marshal(params)
|
||||
if err != nil {
|
||||
return RPCRequest{}, err
|
||||
}
|
||||
request := NewRPCRequest(id, method, payload)
|
||||
return request, nil
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
@@ -52,8 +53,14 @@ type RPCResponse struct {
|
||||
func NewRPCResponse(id string, res interface{}, err string) RPCResponse {
|
||||
var raw *json.RawMessage
|
||||
if res != nil {
|
||||
rawMsg := json.RawMessage(wire.JSONBytes(res))
|
||||
raw = &rawMsg
|
||||
var js []byte
|
||||
js, err2 := json.Marshal(res)
|
||||
if err2 == nil {
|
||||
rawMsg := json.RawMessage(js)
|
||||
raw = &rawMsg
|
||||
} else {
|
||||
err = err2.Error()
|
||||
}
|
||||
}
|
||||
return RPCResponse{
|
||||
JSONRPC: "2.0",
|
||||
|
||||
+40
-46
@@ -12,9 +12,10 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
abci "github.com/tendermint/abci/types"
|
||||
rpc "github.com/tendermint/tendermint/rpc/lib/client"
|
||||
"github.com/tendermint/go-wire/data"
|
||||
"github.com/tendermint/tendermint/rpc/core"
|
||||
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||
rpc "github.com/tendermint/tendermint/rpc/lib/client"
|
||||
"github.com/tendermint/tendermint/state/txindex/null"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
@@ -38,12 +39,11 @@ func TestJSONStatus(t *testing.T) {
|
||||
|
||||
func testStatus(t *testing.T, client rpc.HTTPClient) {
|
||||
chainID := GetConfig().GetString("chain_id")
|
||||
tmResult := new(ctypes.TMResult)
|
||||
_, err := client.Call("status", map[string]interface{}{}, tmResult)
|
||||
result := new(ctypes.ResultStatus)
|
||||
_, err := client.Call("status", map[string]interface{}{}, result)
|
||||
require.Nil(t, err)
|
||||
|
||||
status := (*tmResult).(*ctypes.ResultStatus)
|
||||
assert.Equal(t, chainID, status.NodeInfo.Network)
|
||||
assert.Equal(t, chainID, result.NodeInfo.Network)
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
@@ -69,13 +69,12 @@ func TestJSONBroadcastTxSync(t *testing.T) {
|
||||
func testBroadcastTxSync(t *testing.T, client rpc.HTTPClient) {
|
||||
mem := node.MempoolReactor().Mempool
|
||||
initMemSize := mem.Size()
|
||||
tmResult := new(ctypes.TMResult)
|
||||
result := new(ctypes.ResultBroadcastTx)
|
||||
tx := randBytes(t)
|
||||
_, err := client.Call("broadcast_tx_sync", map[string]interface{}{"tx": tx}, tmResult)
|
||||
_, err := client.Call("broadcast_tx_sync", map[string]interface{}{"tx": tx}, result)
|
||||
require.Nil(t, err)
|
||||
|
||||
res := (*tmResult).(*ctypes.ResultBroadcastTx)
|
||||
require.Equal(t, abci.CodeType_OK, res.Code)
|
||||
require.Equal(t, abci.CodeType_OK, result.Code)
|
||||
require.Equal(t, initMemSize+1, mem.Size())
|
||||
txs := mem.Reap(1)
|
||||
require.EqualValues(t, tx, txs[0])
|
||||
@@ -92,14 +91,13 @@ func testTxKV(t *testing.T) ([]byte, []byte, types.Tx) {
|
||||
}
|
||||
|
||||
func sendTx(t *testing.T, client rpc.HTTPClient) ([]byte, []byte) {
|
||||
tmResult := new(ctypes.TMResult)
|
||||
result := new(ctypes.ResultBroadcastTxCommit)
|
||||
k, v, tx := testTxKV(t)
|
||||
_, err := client.Call("broadcast_tx_commit", map[string]interface{}{"tx": tx}, tmResult)
|
||||
_, err := client.Call("broadcast_tx_commit", map[string]interface{}{"tx": tx}, result)
|
||||
require.Nil(t, err)
|
||||
bres := (*tmResult).(*ctypes.ResultBroadcastTxCommit)
|
||||
require.NotNil(t, 0, bres.DeliverTx, "%#v", bres)
|
||||
require.EqualValues(t, 0, bres.CheckTx.GetCode(), "%#v", bres)
|
||||
require.EqualValues(t, 0, bres.DeliverTx.GetCode(), "%#v", bres)
|
||||
require.NotNil(t, 0, result.DeliverTx, "%#v", result)
|
||||
require.EqualValues(t, 0, result.CheckTx.Code, "%#v", result)
|
||||
require.EqualValues(t, 0, result.DeliverTx.Code, "%#v", result)
|
||||
return k, v
|
||||
}
|
||||
|
||||
@@ -114,16 +112,15 @@ func TestJSONABCIQuery(t *testing.T) {
|
||||
func testABCIQuery(t *testing.T, client rpc.HTTPClient) {
|
||||
k, _ := sendTx(t, client)
|
||||
time.Sleep(time.Millisecond * 500)
|
||||
tmResult := new(ctypes.TMResult)
|
||||
result := new(ctypes.ResultABCIQuery)
|
||||
_, err := client.Call("abci_query",
|
||||
map[string]interface{}{"path": "", "data": k, "prove": false}, tmResult)
|
||||
map[string]interface{}{"path": "", "data": data.Bytes(k), "prove": false}, result)
|
||||
require.Nil(t, err)
|
||||
|
||||
resQuery := (*tmResult).(*ctypes.ResultABCIQuery)
|
||||
require.EqualValues(t, 0, resQuery.Response.Code)
|
||||
require.EqualValues(t, 0, result.Code)
|
||||
|
||||
// XXX: specific to value returned by the dummy
|
||||
require.NotEqual(t, 0, len(resQuery.Response.Value))
|
||||
require.NotEqual(t, 0, len(result.Value))
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
@@ -140,15 +137,14 @@ func TestJSONBroadcastTxCommit(t *testing.T) {
|
||||
func testBroadcastTxCommit(t *testing.T, client rpc.HTTPClient) {
|
||||
require := require.New(t)
|
||||
|
||||
tmResult := new(ctypes.TMResult)
|
||||
result := new(ctypes.ResultBroadcastTxCommit)
|
||||
tx := randBytes(t)
|
||||
_, err := client.Call("broadcast_tx_commit", map[string]interface{}{"tx": tx}, tmResult)
|
||||
_, err := client.Call("broadcast_tx_commit", map[string]interface{}{"tx": tx}, result)
|
||||
require.Nil(err)
|
||||
|
||||
res := (*tmResult).(*ctypes.ResultBroadcastTxCommit)
|
||||
checkTx := res.CheckTx
|
||||
checkTx := result.CheckTx
|
||||
require.Equal(abci.CodeType_OK, checkTx.Code)
|
||||
deliverTx := res.DeliverTx
|
||||
deliverTx := result.DeliverTx
|
||||
require.Equal(abci.CodeType_OK, deliverTx.Code)
|
||||
mem := node.MempoolReactor().Mempool
|
||||
require.Equal(0, mem.Size())
|
||||
@@ -178,16 +174,15 @@ func testTx(t *testing.T, client rpc.HTTPClient, withIndexer bool) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
|
||||
// first we broadcast a tx
|
||||
tmResult := new(ctypes.TMResult)
|
||||
result := new(ctypes.ResultBroadcastTxCommit)
|
||||
txBytes := randBytes(t)
|
||||
tx := types.Tx(txBytes)
|
||||
_, err := client.Call("broadcast_tx_commit", map[string]interface{}{"tx": txBytes}, tmResult)
|
||||
_, err := client.Call("broadcast_tx_commit", map[string]interface{}{"tx": txBytes}, result)
|
||||
require.Nil(err)
|
||||
|
||||
res := (*tmResult).(*ctypes.ResultBroadcastTxCommit)
|
||||
checkTx := res.CheckTx
|
||||
checkTx := result.CheckTx
|
||||
require.Equal(abci.CodeType_OK, checkTx.Code)
|
||||
deliverTx := res.DeliverTx
|
||||
deliverTx := result.DeliverTx
|
||||
require.Equal(abci.CodeType_OK, deliverTx.Code)
|
||||
mem := node.MempoolReactor().Mempool
|
||||
require.Equal(0, mem.Size())
|
||||
@@ -214,24 +209,23 @@ func testTx(t *testing.T, client rpc.HTTPClient, withIndexer bool) {
|
||||
|
||||
// now we query for the tx.
|
||||
// since there's only one tx, we know index=0.
|
||||
tmResult = new(ctypes.TMResult)
|
||||
result2 := new(ctypes.ResultTx)
|
||||
query := map[string]interface{}{
|
||||
"hash": tc.hash,
|
||||
"prove": tc.prove,
|
||||
}
|
||||
_, err = client.Call("tx", query, tmResult)
|
||||
_, err = client.Call("tx", query, result2)
|
||||
valid := (withIndexer && tc.valid)
|
||||
if !valid {
|
||||
require.NotNil(err, idx)
|
||||
} else {
|
||||
require.Nil(err, idx)
|
||||
res2 := (*tmResult).(*ctypes.ResultTx)
|
||||
assert.Equal(tx, res2.Tx, idx)
|
||||
assert.Equal(res.Height, res2.Height, idx)
|
||||
assert.Equal(0, res2.Index, idx)
|
||||
assert.Equal(abci.CodeType_OK, res2.TxResult.Code, idx)
|
||||
assert.Equal(tx, result2.Tx, idx)
|
||||
assert.Equal(result.Height, result2.Height, idx)
|
||||
assert.Equal(0, result2.Index, idx)
|
||||
assert.Equal(abci.CodeType_OK, result2.TxResult.Code, idx)
|
||||
// time to verify the proof
|
||||
proof := res2.Proof
|
||||
proof := result2.Proof
|
||||
if tc.prove && assert.Equal(tx, proof.Data, idx) {
|
||||
assert.True(proof.Proof.Verify(proof.Index, proof.Total, tx.Hash(), proof.RootHash), idx)
|
||||
}
|
||||
@@ -286,7 +280,7 @@ func TestWSBlockchainGrowth(t *testing.T) {
|
||||
var initBlockN int
|
||||
for i := 0; i < 3; i++ {
|
||||
waitForEvent(t, wsc, eid, true, func() {}, func(eid string, eventData interface{}) error {
|
||||
block := eventData.(types.EventDataNewBlock).Block
|
||||
block := eventData.(types.TMEventData).Unwrap().(types.EventDataNewBlock).Block
|
||||
if i == 0 {
|
||||
initBlockN = block.Header.Height
|
||||
} else {
|
||||
@@ -315,12 +309,12 @@ func TestWSTxEvent(t *testing.T) {
|
||||
}()
|
||||
|
||||
// send an tx
|
||||
tmResult := new(ctypes.TMResult)
|
||||
_, err := GetJSONClient().Call("broadcast_tx_sync", map[string]interface{}{"tx": tx}, tmResult)
|
||||
result := new(ctypes.ResultBroadcastTx)
|
||||
_, err := GetJSONClient().Call("broadcast_tx_sync", map[string]interface{}{"tx": tx}, result)
|
||||
require.Nil(err)
|
||||
|
||||
waitForEvent(t, wsc, eid, true, func() {}, func(eid string, b interface{}) error {
|
||||
evt, ok := b.(types.EventDataTx)
|
||||
evt, ok := b.(types.TMEventData).Unwrap().(types.EventDataTx)
|
||||
require.True(ok, "Got wrong event type: %#v", b)
|
||||
require.Equal(tx, []byte(evt.Tx), "Returned different tx")
|
||||
require.Equal(abci.CodeType_OK, evt.Code)
|
||||
@@ -373,12 +367,12 @@ func TestWSDoubleFire(t *testing.T) {
|
||||
//
|
||||
//func TestURIUnsafeSetConfig(t *testing.T) {
|
||||
// for _, testCase := range testCasesUnsafeSetConfig {
|
||||
// tmResult := new(ctypes.TMResult)
|
||||
// result := new(ctypes.TMResult)
|
||||
// _, err := GetURIClient().Call("unsafe_set_config", map[string]interface{}{
|
||||
// "type": testCase[0],
|
||||
// "key": testCase[1],
|
||||
// "value": testCase[2],
|
||||
// }, tmResult)
|
||||
// }, result)
|
||||
// require.Nil(t, err)
|
||||
// }
|
||||
// testUnsafeSetConfig(t)
|
||||
@@ -386,10 +380,10 @@ func TestWSDoubleFire(t *testing.T) {
|
||||
//
|
||||
//func TestJSONUnsafeSetConfig(t *testing.T) {
|
||||
// for _, testCase := range testCasesUnsafeSetConfig {
|
||||
// tmResult := new(ctypes.TMResult)
|
||||
// result := new(ctypes.TMResult)
|
||||
// _, err := GetJSONClient().Call("unsafe_set_config",
|
||||
// map[string]interface{}{"type": testCase[0], "key": testCase[1], "value": testCase[2]},
|
||||
// tmResult)
|
||||
// result)
|
||||
// require.Nil(t, err)
|
||||
// }
|
||||
// testUnsafeSetConfig(t)
|
||||
|
||||
+8
-9
@@ -1,6 +1,7 @@
|
||||
package rpctest
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
@@ -11,16 +12,15 @@ import (
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"github.com/stretchr/testify/require"
|
||||
wire "github.com/tendermint/go-wire"
|
||||
logger "github.com/tendermint/tmlibs/logger"
|
||||
|
||||
abci "github.com/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/config/tendermint_test"
|
||||
nm "github.com/tendermint/tendermint/node"
|
||||
"github.com/tendermint/tendermint/proxy"
|
||||
client "github.com/tendermint/tendermint/rpc/lib/client"
|
||||
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||
core_grpc "github.com/tendermint/tendermint/rpc/grpc"
|
||||
client "github.com/tendermint/tendermint/rpc/lib/client"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
@@ -131,15 +131,14 @@ func waitForEvent(t *testing.T, wsc *client.WSClient, eventid string, dieOnTimeo
|
||||
for {
|
||||
select {
|
||||
case r := <-wsc.ResultsCh:
|
||||
result := new(ctypes.TMResult)
|
||||
wire.ReadJSONPtr(result, r, &err)
|
||||
result := new(ctypes.ResultEvent)
|
||||
err = json.Unmarshal(r, result)
|
||||
if err != nil {
|
||||
errCh <- err
|
||||
break LOOP
|
||||
// cant distinguish between error and wrong type ...
|
||||
continue
|
||||
}
|
||||
event, ok := (*result).(*ctypes.ResultEvent)
|
||||
if ok && event.Name == eventid {
|
||||
goodCh <- event.Data
|
||||
if result.Name == eventid {
|
||||
goodCh <- result.Data
|
||||
break LOOP
|
||||
}
|
||||
case err := <-wsc.ErrorsCh:
|
||||
|
||||
@@ -33,7 +33,7 @@ function sendTx() {
|
||||
ERROR=`echo $RESPONSE | jq .error`
|
||||
ERROR=$(echo "$ERROR" | tr -d '"') # remove surrounding quotes
|
||||
|
||||
RESPONSE=`echo $RESPONSE | jq .result[1]`
|
||||
RESPONSE=`echo $RESPONSE | jq .result`
|
||||
else
|
||||
if [ -f grpc_client ]; then
|
||||
rm grpc_client
|
||||
|
||||
@@ -57,7 +57,7 @@ echo "... testing query with /abci_query 2"
|
||||
|
||||
# we should be able to look up the key
|
||||
RESPONSE=`curl -s "127.0.0.1:46657/abci_query?path=\"\"&data=$(toHex $KEY)&prove=false"`
|
||||
RESPONSE=`echo $RESPONSE | jq .result[1].response.log`
|
||||
RESPONSE=`echo $RESPONSE | jq .result.response.log`
|
||||
|
||||
set +e
|
||||
A=`echo $RESPONSE | grep 'exists'`
|
||||
@@ -70,7 +70,7 @@ set -e
|
||||
|
||||
# we should not be able to look up the value
|
||||
RESPONSE=`curl -s "127.0.0.1:46657/abci_query?path=\"\"&data=$(toHex $VALUE)&prove=false"`
|
||||
RESPONSE=`echo $RESPONSE | jq .result[1].response.log`
|
||||
RESPONSE=`echo $RESPONSE | jq .result.response.log`
|
||||
set +e
|
||||
A=`echo $RESPONSE | grep 'exists'`
|
||||
if [[ $? == 0 ]]; then
|
||||
|
||||
@@ -17,7 +17,7 @@ for i in `seq 1 $N`; do
|
||||
addr=$(test/p2p/ip.sh $i):46657
|
||||
|
||||
# current state
|
||||
HASH1=`curl -s $addr/status | jq .result[1].latest_app_hash`
|
||||
HASH1=`curl -s $addr/status | jq .result.latest_app_hash`
|
||||
|
||||
# - send a tx
|
||||
TX=aadeadbeefbeefbeef0$i
|
||||
@@ -26,15 +26,15 @@ for i in `seq 1 $N`; do
|
||||
echo ""
|
||||
|
||||
# we need to wait another block to get the new app_hash
|
||||
h1=`curl -s $addr/status | jq .result[1].latest_block_height`
|
||||
h1=`curl -s $addr/status | jq .result.latest_block_height`
|
||||
h2=$h1
|
||||
while [ "$h2" == "$h1" ]; do
|
||||
sleep 1
|
||||
h2=`curl -s $addr/status | jq .result[1].latest_block_height`
|
||||
h2=`curl -s $addr/status | jq .result.latest_block_height`
|
||||
done
|
||||
|
||||
# check that hash was updated
|
||||
HASH2=`curl -s $addr/status | jq .result[1].latest_app_hash`
|
||||
HASH2=`curl -s $addr/status | jq .result.latest_app_hash`
|
||||
if [[ "$HASH1" == "$HASH2" ]]; then
|
||||
echo "Expected state hash to update from $HASH1. Got $HASH2"
|
||||
exit 1
|
||||
@@ -44,7 +44,7 @@ for i in `seq 1 $N`; do
|
||||
for j in `seq 1 $N`; do
|
||||
if [[ "$i" != "$j" ]]; then
|
||||
addrJ=$(test/p2p/ip.sh $j):46657
|
||||
HASH3=`curl -s $addrJ/status | jq .result[1].latest_app_hash`
|
||||
HASH3=`curl -s $addrJ/status | jq .result.latest_app_hash`
|
||||
|
||||
if [[ "$HASH2" != "$HASH3" ]]; then
|
||||
echo "App hash for node $j doesn't match. Got $HASH3, expected $HASH2"
|
||||
|
||||
@@ -31,19 +31,19 @@ for i in `seq 1 $N`; do
|
||||
N_1=$(($N - 1))
|
||||
|
||||
# - assert everyone has N-1 other peers
|
||||
N_PEERS=`curl -s $addr/net_info | jq '.result[1].peers | length'`
|
||||
N_PEERS=`curl -s $addr/net_info | jq '.result.peers | length'`
|
||||
while [ "$N_PEERS" != $N_1 ]; do
|
||||
echo "Waiting for node $i to connect to all peers ..."
|
||||
sleep 1
|
||||
N_PEERS=`curl -s $addr/net_info | jq '.result[1].peers | length'`
|
||||
N_PEERS=`curl -s $addr/net_info | jq '.result.peers | length'`
|
||||
done
|
||||
|
||||
# - assert block height is greater than 1
|
||||
BLOCK_HEIGHT=`curl -s $addr/status | jq .result[1].latest_block_height`
|
||||
BLOCK_HEIGHT=`curl -s $addr/status | jq .result.latest_block_height`
|
||||
while [ "$BLOCK_HEIGHT" -le 1 ]; do
|
||||
echo "Waiting for node $i to commit a block ..."
|
||||
sleep 1
|
||||
BLOCK_HEIGHT=`curl -s $addr/status | jq .result[1].latest_block_height`
|
||||
BLOCK_HEIGHT=`curl -s $addr/status | jq .result.latest_block_height`
|
||||
done
|
||||
echo "Node $i is connected to all peers and at block $BLOCK_HEIGHT"
|
||||
done
|
||||
|
||||
@@ -15,10 +15,10 @@ peerID=$(( $(($ID % 4)) + 1 )) # 1->2 ... 3->4 ... 4->1
|
||||
peer_addr=$(test/p2p/ip.sh $peerID):46657
|
||||
|
||||
# get another peer's height
|
||||
h1=`curl -s $peer_addr/status | jq .result[1].latest_block_height`
|
||||
h1=`curl -s $peer_addr/status | jq .result.latest_block_height`
|
||||
|
||||
# get another peer's state
|
||||
root1=`curl -s $peer_addr/status | jq .result[1].latest_app_hash`
|
||||
root1=`curl -s $peer_addr/status | jq .result.latest_app_hash`
|
||||
|
||||
echo "Other peer is on height $h1 with state $root1"
|
||||
echo "Waiting for peer $ID to catch up"
|
||||
@@ -29,12 +29,12 @@ set +o pipefail
|
||||
h2="0"
|
||||
while [[ "$h2" -lt "$(($h1+3))" ]]; do
|
||||
sleep 1
|
||||
h2=`curl -s $addr/status | jq .result[1].latest_block_height`
|
||||
h2=`curl -s $addr/status | jq .result.latest_block_height`
|
||||
echo "... $h2"
|
||||
done
|
||||
|
||||
# check the app hash
|
||||
root2=`curl -s $addr/status | jq .result[1].latest_app_hash`
|
||||
root2=`curl -s $addr/status | jq .result.latest_app_hash`
|
||||
|
||||
if [[ "$root1" != "$root2" ]]; then
|
||||
echo "App hash after fast sync does not match. Got $root2; expected $root1"
|
||||
|
||||
@@ -23,7 +23,7 @@ set -e
|
||||
|
||||
# get the first peer's height
|
||||
addr=$(test/p2p/ip.sh 1):46657
|
||||
h1=$(curl -s "$addr/status" | jq .result[1].latest_block_height)
|
||||
h1=$(curl -s "$addr/status" | jq .result.latest_block_height)
|
||||
echo "1st peer is on height $h1"
|
||||
|
||||
echo "Waiting until other peers reporting a height higher than the 1st one"
|
||||
@@ -33,14 +33,14 @@ for i in $(seq 2 "$NUM_OF_PEERS"); do
|
||||
|
||||
while [[ $hi -le $h1 ]] ; do
|
||||
addr=$(test/p2p/ip.sh "$i"):46657
|
||||
hi=$(curl -s "$addr/status" | jq .result[1].latest_block_height)
|
||||
hi=$(curl -s "$addr/status" | jq .result.latest_block_height)
|
||||
|
||||
echo "... peer $i is on height $hi"
|
||||
|
||||
((attempt++))
|
||||
if [ "$attempt" -ge $MAX_ATTEMPTS_TO_CATCH_UP ] ; then
|
||||
echo "$attempt unsuccessful attempts were made to catch up"
|
||||
curl -s "$addr/dump_consensus_state" | jq .result[1]
|
||||
curl -s "$addr/dump_consensus_state" | jq .result
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ echo "2. wait until peer $ID connects to other nodes using pex reactor"
|
||||
peers_count="0"
|
||||
while [[ "$peers_count" -lt "$((N-1))" ]]; do
|
||||
sleep 1
|
||||
peers_count=$(curl -s "$addr/net_info" | jq ".result[1].peers | length")
|
||||
peers_count=$(curl -s "$addr/net_info" | jq ".result.peers | length")
|
||||
echo "... peers count = $peers_count, expected = $((N-1))"
|
||||
done
|
||||
|
||||
|
||||
@@ -107,11 +107,11 @@ for failIndex in $(seq $failsStart $failsEnd); do
|
||||
done
|
||||
|
||||
# wait for a new block
|
||||
h1=$(curl -s --unix-socket "$RPC_ADDR" http://localhost/status | jq .result[1].latest_block_height)
|
||||
h1=$(curl -s --unix-socket "$RPC_ADDR" http://localhost/status | jq .result.latest_block_height)
|
||||
h2=$h1
|
||||
while [ "$h2" == "$h1" ]; do
|
||||
sleep 1
|
||||
h2=$(curl -s --unix-socket "$RPC_ADDR" http://localhost/status | jq .result[1].latest_block_height)
|
||||
h2=$(curl -s --unix-socket "$RPC_ADDR" http://localhost/status | jq .result.latest_block_height)
|
||||
done
|
||||
|
||||
kill_procs
|
||||
|
||||
@@ -57,11 +57,11 @@ while [ "$ERR" != 0 ]; do
|
||||
done
|
||||
|
||||
# wait for a new block
|
||||
h1=`curl -s $addr/status | jq .result[1].latest_block_height`
|
||||
h1=`curl -s $addr/status | jq .result.latest_block_height`
|
||||
h2=$h1
|
||||
while [ "$h2" == "$h1" ]; do
|
||||
sleep 1
|
||||
h2=`curl -s $addr/status | jq .result[1].latest_block_height`
|
||||
h2=`curl -s $addr/status | jq .result.latest_block_height`
|
||||
done
|
||||
|
||||
kill_procs
|
||||
|
||||
+12
-11
@@ -8,9 +8,10 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/tendermint/go-wire"
|
||||
"github.com/tendermint/go-wire/data"
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
"github.com/tendermint/tmlibs/merkle"
|
||||
"github.com/tendermint/go-wire"
|
||||
)
|
||||
|
||||
const MaxBlockSize = 22020096 // 21MB TODO make it configurable
|
||||
@@ -150,15 +151,15 @@ func (b *Block) StringShort() string {
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
type Header struct {
|
||||
ChainID string `json:"chain_id"`
|
||||
Height int `json:"height"`
|
||||
Time time.Time `json:"time"`
|
||||
NumTxs int `json:"num_txs"` // XXX: Can we get rid of this?
|
||||
LastBlockID BlockID `json:"last_block_id"`
|
||||
LastCommitHash []byte `json:"last_commit_hash"` // commit from validators from the last block
|
||||
DataHash []byte `json:"data_hash"` // transactions
|
||||
ValidatorsHash []byte `json:"validators_hash"` // validators for the current block
|
||||
AppHash []byte `json:"app_hash"` // state after txs from the previous block
|
||||
ChainID string `json:"chain_id"`
|
||||
Height int `json:"height"`
|
||||
Time time.Time `json:"time"`
|
||||
NumTxs int `json:"num_txs"` // XXX: Can we get rid of this?
|
||||
LastBlockID BlockID `json:"last_block_id"`
|
||||
LastCommitHash data.Bytes `json:"last_commit_hash"` // commit from validators from the last block
|
||||
DataHash data.Bytes `json:"data_hash"` // transactions
|
||||
ValidatorsHash data.Bytes `json:"validators_hash"` // validators for the current block
|
||||
AppHash data.Bytes `json:"app_hash"` // state after txs from the previous block
|
||||
}
|
||||
|
||||
// NOTE: hash is nil if required fields are missing.
|
||||
@@ -388,7 +389,7 @@ func (data *Data) StringIndented(indent string) string {
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
type BlockID struct {
|
||||
Hash []byte `json:"hash"`
|
||||
Hash data.Bytes `json:"hash"`
|
||||
PartsHeader PartSetHeader `json:"parts"`
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"github.com/tendermint/go-wire/data"
|
||||
)
|
||||
|
||||
// canonical json is go-wire's json for structs with fields in alphabetical order
|
||||
|
||||
type CanonicalJSONBlockID struct {
|
||||
Hash []byte `json:"hash,omitempty"`
|
||||
Hash data.Bytes `json:"hash,omitempty"`
|
||||
PartsHeader CanonicalJSONPartSetHeader `json:"parts,omitempty"`
|
||||
}
|
||||
|
||||
type CanonicalJSONPartSetHeader struct {
|
||||
Hash []byte `json:"hash"`
|
||||
Total int `json:"total"`
|
||||
Hash data.Bytes `json:"hash"`
|
||||
Total int `json:"total"`
|
||||
}
|
||||
|
||||
type CanonicalJSONProposal struct {
|
||||
|
||||
+62
-28
@@ -3,9 +3,9 @@ package types
|
||||
import (
|
||||
// for registering TMEventData as events.EventData
|
||||
abci "github.com/tendermint/abci/types"
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
"github.com/tendermint/go-wire/data"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
"github.com/tendermint/tmlibs/events"
|
||||
"github.com/tendermint/go-wire"
|
||||
)
|
||||
|
||||
// Functions to generate eventId strings
|
||||
@@ -16,7 +16,7 @@ func EventStringUnbond() string { return "Unbond" }
|
||||
func EventStringRebond() string { return "Rebond" }
|
||||
func EventStringDupeout() string { return "Dupeout" }
|
||||
func EventStringFork() string { return "Fork" }
|
||||
func EventStringTx(tx Tx) string { return Fmt("Tx:%X", tx.Hash()) }
|
||||
func EventStringTx(tx Tx) string { return cmn.Fmt("Tx:%X", tx.Hash()) }
|
||||
|
||||
func EventStringNewBlock() string { return "NewBlock" }
|
||||
func EventStringNewBlockHeader() string { return "NewBlockHeader" }
|
||||
@@ -33,10 +33,47 @@ func EventStringVote() string { return "Vote" }
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
var (
|
||||
EventDataNameNewBlock = "new_block"
|
||||
EventDataNameNewBlockHeader = "new_block_header"
|
||||
EventDataNameTx = "tx"
|
||||
EventDataNameRoundState = "round_state"
|
||||
EventDataNameVote = "vote"
|
||||
)
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
// implements events.EventData
|
||||
type TMEventData interface {
|
||||
type TMEventDataInner interface {
|
||||
events.EventData
|
||||
AssertIsTMEventData()
|
||||
}
|
||||
|
||||
type TMEventData struct {
|
||||
TMEventDataInner `json:"unwrap"`
|
||||
}
|
||||
|
||||
func (tmr TMEventData) MarshalJSON() ([]byte, error) {
|
||||
return tmEventDataMapper.ToJSON(tmr.TMEventDataInner)
|
||||
}
|
||||
|
||||
func (tmr *TMEventData) UnmarshalJSON(data []byte) (err error) {
|
||||
parsed, err := tmEventDataMapper.FromJSON(data)
|
||||
if err == nil && parsed != nil {
|
||||
tmr.TMEventDataInner = parsed.(TMEventDataInner)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (tmr TMEventData) Unwrap() TMEventDataInner {
|
||||
tmrI := tmr.TMEventDataInner
|
||||
for wrap, ok := tmrI.(TMEventData); ok; wrap, ok = tmrI.(TMEventData) {
|
||||
tmrI = wrap.TMEventDataInner
|
||||
}
|
||||
return tmrI
|
||||
}
|
||||
|
||||
func (tmr TMEventData) Empty() bool {
|
||||
return tmr.TMEventDataInner == nil
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -49,15 +86,12 @@ const (
|
||||
EventDataTypeVote = byte(0x12)
|
||||
)
|
||||
|
||||
var _ = wire.RegisterInterface(
|
||||
struct{ TMEventData }{},
|
||||
wire.ConcreteType{EventDataNewBlock{}, EventDataTypeNewBlock},
|
||||
wire.ConcreteType{EventDataNewBlockHeader{}, EventDataTypeNewBlockHeader},
|
||||
// wire.ConcreteType{EventDataFork{}, EventDataTypeFork },
|
||||
wire.ConcreteType{EventDataTx{}, EventDataTypeTx},
|
||||
wire.ConcreteType{EventDataRoundState{}, EventDataTypeRoundState},
|
||||
wire.ConcreteType{EventDataVote{}, EventDataTypeVote},
|
||||
)
|
||||
var tmEventDataMapper = data.NewMapper(TMEventData{}).
|
||||
RegisterImplementation(EventDataNewBlock{}, EventDataNameNewBlock, EventDataTypeNewBlock).
|
||||
RegisterImplementation(EventDataNewBlockHeader{}, EventDataNameNewBlockHeader, EventDataTypeNewBlockHeader).
|
||||
RegisterImplementation(EventDataTx{}, EventDataNameTx, EventDataTypeTx).
|
||||
RegisterImplementation(EventDataRoundState{}, EventDataNameRoundState, EventDataTypeRoundState).
|
||||
RegisterImplementation(EventDataVote{}, EventDataNameVote, EventDataTypeVote)
|
||||
|
||||
// Most event messages are basic types (a block, a transaction)
|
||||
// but some (an input to a call tx or a receive) are more exotic
|
||||
@@ -75,7 +109,7 @@ type EventDataNewBlockHeader struct {
|
||||
type EventDataTx struct {
|
||||
Height int `json:"height"`
|
||||
Tx Tx `json:"tx"`
|
||||
Data []byte `json:"data"`
|
||||
Data data.Bytes `json:"data"`
|
||||
Log string `json:"log"`
|
||||
Code abci.CodeType `json:"code"`
|
||||
Error string `json:"error"` // this is redundant information for now
|
||||
@@ -146,55 +180,55 @@ func AddListenerForEvent(evsw EventSwitch, id, event string, cb func(data TMEven
|
||||
//--- block, tx, and vote events
|
||||
|
||||
func FireEventNewBlock(fireable events.Fireable, block EventDataNewBlock) {
|
||||
fireEvent(fireable, EventStringNewBlock(), block)
|
||||
fireEvent(fireable, EventStringNewBlock(), TMEventData{block})
|
||||
}
|
||||
|
||||
func FireEventNewBlockHeader(fireable events.Fireable, header EventDataNewBlockHeader) {
|
||||
fireEvent(fireable, EventStringNewBlockHeader(), header)
|
||||
fireEvent(fireable, EventStringNewBlockHeader(), TMEventData{header})
|
||||
}
|
||||
|
||||
func FireEventVote(fireable events.Fireable, vote EventDataVote) {
|
||||
fireEvent(fireable, EventStringVote(), vote)
|
||||
fireEvent(fireable, EventStringVote(), TMEventData{vote})
|
||||
}
|
||||
|
||||
func FireEventTx(fireable events.Fireable, tx EventDataTx) {
|
||||
fireEvent(fireable, EventStringTx(tx.Tx), tx)
|
||||
fireEvent(fireable, EventStringTx(tx.Tx), TMEventData{tx})
|
||||
}
|
||||
|
||||
//--- EventDataRoundState events
|
||||
|
||||
func FireEventNewRoundStep(fireable events.Fireable, rs EventDataRoundState) {
|
||||
fireEvent(fireable, EventStringNewRoundStep(), rs)
|
||||
fireEvent(fireable, EventStringNewRoundStep(), TMEventData{rs})
|
||||
}
|
||||
|
||||
func FireEventTimeoutPropose(fireable events.Fireable, rs EventDataRoundState) {
|
||||
fireEvent(fireable, EventStringTimeoutPropose(), rs)
|
||||
fireEvent(fireable, EventStringTimeoutPropose(), TMEventData{rs})
|
||||
}
|
||||
|
||||
func FireEventTimeoutWait(fireable events.Fireable, rs EventDataRoundState) {
|
||||
fireEvent(fireable, EventStringTimeoutWait(), rs)
|
||||
fireEvent(fireable, EventStringTimeoutWait(), TMEventData{rs})
|
||||
}
|
||||
|
||||
func FireEventNewRound(fireable events.Fireable, rs EventDataRoundState) {
|
||||
fireEvent(fireable, EventStringNewRound(), rs)
|
||||
fireEvent(fireable, EventStringNewRound(), TMEventData{rs})
|
||||
}
|
||||
|
||||
func FireEventCompleteProposal(fireable events.Fireable, rs EventDataRoundState) {
|
||||
fireEvent(fireable, EventStringCompleteProposal(), rs)
|
||||
fireEvent(fireable, EventStringCompleteProposal(), TMEventData{rs})
|
||||
}
|
||||
|
||||
func FireEventPolka(fireable events.Fireable, rs EventDataRoundState) {
|
||||
fireEvent(fireable, EventStringPolka(), rs)
|
||||
fireEvent(fireable, EventStringPolka(), TMEventData{rs})
|
||||
}
|
||||
|
||||
func FireEventUnlock(fireable events.Fireable, rs EventDataRoundState) {
|
||||
fireEvent(fireable, EventStringUnlock(), rs)
|
||||
fireEvent(fireable, EventStringUnlock(), TMEventData{rs})
|
||||
}
|
||||
|
||||
func FireEventRelock(fireable events.Fireable, rs EventDataRoundState) {
|
||||
fireEvent(fireable, EventStringRelock(), rs)
|
||||
fireEvent(fireable, EventStringRelock(), TMEventData{rs})
|
||||
}
|
||||
|
||||
func FireEventLock(fireable events.Fireable, rs EventDataRoundState) {
|
||||
fireEvent(fireable, EventStringLock(), rs)
|
||||
fireEvent(fireable, EventStringLock(), TMEventData{rs})
|
||||
}
|
||||
|
||||
+4
-3
@@ -4,8 +4,9 @@ import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
"github.com/tendermint/go-crypto"
|
||||
"github.com/tendermint/go-wire/data"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
)
|
||||
|
||||
//------------------------------------------------------------
|
||||
@@ -26,7 +27,7 @@ type GenesisDoc struct {
|
||||
GenesisTime time.Time `json:"genesis_time"`
|
||||
ChainID string `json:"chain_id"`
|
||||
Validators []GenesisValidator `json:"validators"`
|
||||
AppHash []byte `json:"app_hash"`
|
||||
AppHash data.Bytes `json:"app_hash"`
|
||||
}
|
||||
|
||||
// Utility method for saving GenensisDoc as JSON file.
|
||||
@@ -35,7 +36,7 @@ func (genDoc *GenesisDoc) SaveAs(file string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return WriteFile(file, genDocBytes, 0644)
|
||||
return cmn.WriteFile(file, genDocBytes, 0644)
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
+14
-13
@@ -9,9 +9,10 @@ import (
|
||||
|
||||
"golang.org/x/crypto/ripemd160"
|
||||
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
"github.com/tendermint/tmlibs/merkle"
|
||||
"github.com/tendermint/go-wire"
|
||||
"github.com/tendermint/go-wire/data"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
"github.com/tendermint/tmlibs/merkle"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -21,7 +22,7 @@ var (
|
||||
|
||||
type Part struct {
|
||||
Index int `json:"index"`
|
||||
Bytes []byte `json:"bytes"`
|
||||
Bytes data.Bytes `json:"bytes"`
|
||||
Proof merkle.SimpleProof `json:"proof"`
|
||||
|
||||
// Cache
|
||||
@@ -49,7 +50,7 @@ func (part *Part) StringIndented(indent string) string {
|
||||
%s Proof: %v
|
||||
%s}`,
|
||||
part.Index,
|
||||
indent, Fingerprint(part.Bytes),
|
||||
indent, cmn.Fingerprint(part.Bytes),
|
||||
indent, part.Proof.StringIndented(indent+" "),
|
||||
indent)
|
||||
}
|
||||
@@ -57,12 +58,12 @@ func (part *Part) StringIndented(indent string) string {
|
||||
//-------------------------------------
|
||||
|
||||
type PartSetHeader struct {
|
||||
Total int `json:"total"`
|
||||
Hash []byte `json:"hash"`
|
||||
Total int `json:"total"`
|
||||
Hash data.Bytes `json:"hash"`
|
||||
}
|
||||
|
||||
func (psh PartSetHeader) String() string {
|
||||
return fmt.Sprintf("%v:%X", psh.Total, Fingerprint(psh.Hash))
|
||||
return fmt.Sprintf("%v:%X", psh.Total, cmn.Fingerprint(psh.Hash))
|
||||
}
|
||||
|
||||
func (psh PartSetHeader) IsZero() bool {
|
||||
@@ -85,7 +86,7 @@ type PartSet struct {
|
||||
|
||||
mtx sync.Mutex
|
||||
parts []*Part
|
||||
partsBitArray *BitArray
|
||||
partsBitArray *cmn.BitArray
|
||||
count int
|
||||
}
|
||||
|
||||
@@ -96,11 +97,11 @@ func NewPartSetFromData(data []byte, partSize int) *PartSet {
|
||||
total := (len(data) + partSize - 1) / partSize
|
||||
parts := make([]*Part, total)
|
||||
parts_ := make([]merkle.Hashable, total)
|
||||
partsBitArray := NewBitArray(total)
|
||||
partsBitArray := cmn.NewBitArray(total)
|
||||
for i := 0; i < total; i++ {
|
||||
part := &Part{
|
||||
Index: i,
|
||||
Bytes: data[i*partSize : MinInt(len(data), (i+1)*partSize)],
|
||||
Bytes: data[i*partSize : cmn.MinInt(len(data), (i+1)*partSize)],
|
||||
}
|
||||
parts[i] = part
|
||||
parts_[i] = part
|
||||
@@ -126,7 +127,7 @@ func NewPartSetFromHeader(header PartSetHeader) *PartSet {
|
||||
total: header.Total,
|
||||
hash: header.Hash,
|
||||
parts: make([]*Part, header.Total),
|
||||
partsBitArray: NewBitArray(header.Total),
|
||||
partsBitArray: cmn.NewBitArray(header.Total),
|
||||
count: 0,
|
||||
}
|
||||
}
|
||||
@@ -150,7 +151,7 @@ func (ps *PartSet) HasHeader(header PartSetHeader) bool {
|
||||
}
|
||||
}
|
||||
|
||||
func (ps *PartSet) BitArray() *BitArray {
|
||||
func (ps *PartSet) BitArray() *cmn.BitArray {
|
||||
ps.mtx.Lock()
|
||||
defer ps.mtx.Unlock()
|
||||
return ps.partsBitArray.Copy()
|
||||
@@ -224,7 +225,7 @@ func (ps *PartSet) IsComplete() bool {
|
||||
|
||||
func (ps *PartSet) GetReader() io.Reader {
|
||||
if !ps.IsComplete() {
|
||||
PanicSanity("Cannot GetReader() on incomplete PartSet")
|
||||
cmn.PanicSanity("Cannot GetReader() on incomplete PartSet")
|
||||
}
|
||||
return NewPartSetReader(ps.parts)
|
||||
}
|
||||
|
||||
+2
-1
@@ -5,6 +5,7 @@ import (
|
||||
"errors"
|
||||
|
||||
abci "github.com/tendermint/abci/types"
|
||||
"github.com/tendermint/go-wire/data"
|
||||
"github.com/tendermint/tmlibs/merkle"
|
||||
)
|
||||
|
||||
@@ -79,7 +80,7 @@ func (txs Txs) Proof(i int) TxProof {
|
||||
|
||||
type TxProof struct {
|
||||
Index, Total int
|
||||
RootHash []byte
|
||||
RootHash data.Bytes
|
||||
Data Tx
|
||||
Proof merkle.SimpleProof
|
||||
}
|
||||
|
||||
+3
-3
@@ -60,9 +60,9 @@ func TestValidTxProof(t *testing.T) {
|
||||
proof := txs.Proof(i)
|
||||
assert.Equal(i, proof.Index, "%d: %d", h, i)
|
||||
assert.Equal(len(txs), proof.Total, "%d: %d", h, i)
|
||||
assert.Equal(root, proof.RootHash, "%d: %d", h, i)
|
||||
assert.Equal(leaf, proof.Data, "%d: %d", h, i)
|
||||
assert.Equal(leafHash, proof.LeafHash(), "%d: %d", h, i)
|
||||
assert.EqualValues(root, proof.RootHash, "%d: %d", h, i)
|
||||
assert.EqualValues(leaf, proof.Data, "%d: %d", h, i)
|
||||
assert.EqualValues(leafHash, proof.LeafHash(), "%d: %d", h, i)
|
||||
assert.Nil(proof.Validate(root), "%d: %d", h, i)
|
||||
assert.NotNil(proof.Validate([]byte("foobar")), "%d: %d", h, i)
|
||||
|
||||
|
||||
+7
-6
@@ -5,16 +5,17 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
"github.com/tendermint/go-crypto"
|
||||
"github.com/tendermint/go-wire"
|
||||
"github.com/tendermint/go-wire/data"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
)
|
||||
|
||||
// Volatile state for each Validator
|
||||
// TODO: make non-volatile identity
|
||||
// - Remove Accum - it can be computed, and now valset becomes identifying
|
||||
type Validator struct {
|
||||
Address []byte `json:"address"`
|
||||
Address data.Bytes `json:"address"`
|
||||
PubKey crypto.PubKey `json:"pub_key"`
|
||||
VotingPower int64 `json:"voting_power"`
|
||||
Accum int64 `json:"accum"`
|
||||
@@ -51,7 +52,7 @@ func (v *Validator) CompareAccum(other *Validator) *Validator {
|
||||
} else if bytes.Compare(v.Address, other.Address) > 0 {
|
||||
return other
|
||||
} else {
|
||||
PanicSanity("Cannot compare identical validators")
|
||||
cmn.PanicSanity("Cannot compare identical validators")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -87,7 +88,7 @@ func (vc validatorCodec) Decode(r io.Reader, n *int, err *error) interface{} {
|
||||
}
|
||||
|
||||
func (vc validatorCodec) Compare(o1 interface{}, o2 interface{}) int {
|
||||
PanicSanity("ValidatorCodec.Compare not implemented")
|
||||
cmn.PanicSanity("ValidatorCodec.Compare not implemented")
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -96,11 +97,11 @@ func (vc validatorCodec) Compare(o1 interface{}, o2 interface{}) int {
|
||||
|
||||
func RandValidator(randPower bool, minPower int64) (*Validator, *PrivValidator) {
|
||||
privVal := GenPrivValidator()
|
||||
_, tempFilePath := Tempfile("priv_validator_")
|
||||
_, tempFilePath := cmn.Tempfile("priv_validator_")
|
||||
privVal.SetFile(tempFilePath)
|
||||
votePower := minPower
|
||||
if randPower {
|
||||
votePower += int64(RandUint32())
|
||||
votePower += int64(cmn.RandUint32())
|
||||
}
|
||||
val := NewValidator(privVal.PubKey, votePower)
|
||||
return val, privVal
|
||||
|
||||
+6
-5
@@ -5,9 +5,10 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
"github.com/tendermint/go-crypto"
|
||||
"github.com/tendermint/go-wire"
|
||||
"github.com/tendermint/go-wire/data"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -47,7 +48,7 @@ func IsVoteTypeValid(type_ byte) bool {
|
||||
|
||||
// Represents a prevote, precommit, or commit vote from validators for consensus.
|
||||
type Vote struct {
|
||||
ValidatorAddress []byte `json:"validator_address"`
|
||||
ValidatorAddress data.Bytes `json:"validator_address"`
|
||||
ValidatorIndex int `json:"validator_index"`
|
||||
Height int `json:"height"`
|
||||
Round int `json:"round"`
|
||||
@@ -79,11 +80,11 @@ func (vote *Vote) String() string {
|
||||
case VoteTypePrecommit:
|
||||
typeString = "Precommit"
|
||||
default:
|
||||
PanicSanity("Unknown vote type")
|
||||
cmn.PanicSanity("Unknown vote type")
|
||||
}
|
||||
|
||||
return fmt.Sprintf("Vote{%v:%X %v/%02d/%v(%v) %X %v}",
|
||||
vote.ValidatorIndex, Fingerprint(vote.ValidatorAddress),
|
||||
vote.ValidatorIndex, cmn.Fingerprint(vote.ValidatorAddress),
|
||||
vote.Height, vote.Round, vote.Type, typeString,
|
||||
Fingerprint(vote.BlockID.Hash), vote.Signature)
|
||||
cmn.Fingerprint(vote.BlockID.Hash), vote.Signature)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user