From d49a5166ac1c1bfb048851450e81f7181da38f4a Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Wed, 12 Jul 2017 01:05:21 -0400 Subject: [PATCH 1/4] scripts/txs: add 0x and randomness --- scripts/txs/random.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/txs/random.sh b/scripts/txs/random.sh index 742d981c2..231fabcfe 100644 --- a/scripts/txs/random.sh +++ b/scripts/txs/random.sh @@ -10,10 +10,10 @@ PORT=$2 for i in `seq 1 $N`; do # store key value pair - KEY="abcd$i" - VALUE="dcba$i" - echo "$KEY:$VALUE" - curl 127.0.0.1:$PORT/broadcast_tx_sync?tx=\"$(toHex $KEY=$VALUE)\" + KEY=$(head -c 10 /dev/urandom) + VALUE="$i" + echo $(toHex $KEY=$VALUE) + curl 127.0.0.1:$PORT/broadcast_tx_sync?tx=0x$(toHex $KEY=$VALUE) done From 311f18bebfe885bd8adc7e45174035cc352752b4 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Thu, 13 Jul 2017 13:07:04 -0400 Subject: [PATCH 2/4] mempool: comments --- mempool/mempool.go | 39 +++++++++++++++++++++++++-------------- mempool/reactor.go | 22 ++++++++++++++++------ 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/mempool/mempool.go b/mempool/mempool.go index fd922ed8e..e804f9b35 100644 --- a/mempool/mempool.go +++ b/mempool/mempool.go @@ -50,6 +50,9 @@ TODO: Better handle abci client errors. (make it automatically handle connection const cacheSize = 100000 +// Mempool is an ordered in-memory pool for transactions before they are proposed in a consensus round. +// Transaction validity is checked using the CheckTx abci message before the transaction is added to the pool. +// The Mempool uses a concurrent list structure for storing transactions that can be efficiently accessed by multiple concurrent readers. type Mempool struct { config *cfg.MempoolConfig @@ -72,6 +75,7 @@ type Mempool struct { logger log.Logger } +// NewMempool returns a new Mempool with the given configuration and connection to an application. func NewMempool(config *cfg.MempoolConfig, proxyAppConn proxy.AppConnMempool) *Mempool { mempool := &Mempool{ config: config, @@ -90,7 +94,7 @@ func NewMempool(config *cfg.MempoolConfig, proxyAppConn proxy.AppConnMempool) *M return mempool } -// SetLogger allows you to set your own Logger. +// SetLogger sets the Logger. func (mem *Mempool) SetLogger(l log.Logger) { mem.logger = l } @@ -110,21 +114,22 @@ func (mem *Mempool) initWAL() { } } -// consensus must be able to hold lock to safely update +// Lock locks the mempool. The consensus must be able to hold lock to safely update. func (mem *Mempool) Lock() { mem.proxyMtx.Lock() } +// Unlock unlocks the mempool. func (mem *Mempool) Unlock() { mem.proxyMtx.Unlock() } -// Number of transactions in the mempool clist +// Size returns the number of transactions in the mempool. func (mem *Mempool) Size() int { return mem.txs.Len() } -// Remove all transactions from mempool and cache +// Flush removes all transactions from the mempool and cache func (mem *Mempool) Flush() { mem.proxyMtx.Lock() defer mem.proxyMtx.Unlock() @@ -137,14 +142,15 @@ func (mem *Mempool) Flush() { } } -// Return the first element of mem.txs for peer goroutines to call .NextWait() on. -// Blocks until txs has elements. +// TxsFrontWait returns the first transaction in the ordered list for peer goroutines to call .NextWait() on. +// It blocks until the mempool is not empty (ie. until the internal `mem.txs` has at least one element) func (mem *Mempool) TxsFrontWait() *clist.CElement { return mem.txs.FrontWait() } -// Try a new transaction in the mempool. -// Potentially blocking if we're blocking on Update() or Reap(). +// CheckTx executes a new transaction against the application to determine its validity +// and whether it should be added to the mempool. +// It blocks if we're waiting on Update() or Reap(). // cb: A callback from the CheckTx command. // It gets called from another goroutine. // CONTRACT: Either cb will get called, or err returned. @@ -256,8 +262,8 @@ func (mem *Mempool) resCbRecheck(req *abci.Request, res *abci.Response) { } } -// Get the valid transactions remaining -// If maxTxs is -1, there is no cap on returned transactions. +// Reap returns a list of transactions currently in the mempool. +// If maxTxs is -1, there is no cap on the number of returned transactions. func (mem *Mempool) Reap(maxTxs int) types.Txs { mem.proxyMtx.Lock() defer mem.proxyMtx.Unlock() @@ -286,8 +292,7 @@ func (mem *Mempool) collectTxs(maxTxs int) types.Txs { return txs } -// Tell mempool that these txs were committed. -// Mempool will discard these txs. +// Update informs the mempool that the given txs were committed and can be discarded. // NOTE: this should be called *after* block is committed by consensus. // NOTE: unsafe; Lock/Unlock must be managed by caller func (mem *Mempool) Update(height int, txs types.Txs) { @@ -354,19 +359,21 @@ func (mem *Mempool) recheckTxs(goodTxs []types.Tx) { //-------------------------------------------------------------------------------- -// A transaction that successfully ran +// mempoolTx is a transaction that successfully ran type mempoolTx struct { counter int64 // a simple incrementing counter height int64 // height that this tx had been validated in tx types.Tx // } +// Height returns the height for this transaction func (memTx *mempoolTx) Height() int { return int(atomic.LoadInt64(&memTx.height)) } //-------------------------------------------------------------------------------- +// txCache maintains a cache of transactions. type txCache struct { mtx sync.Mutex size int @@ -374,6 +381,7 @@ type txCache struct { list *list.List // to remove oldest tx when cache gets too big } +// newTxCache returns a new txCache. func newTxCache(cacheSize int) *txCache { return &txCache{ size: cacheSize, @@ -382,6 +390,7 @@ func newTxCache(cacheSize int) *txCache { } } +// Reset resets the txCache to empty. func (cache *txCache) Reset() { cache.mtx.Lock() cache.map_ = make(map[string]struct{}, cacheSize) @@ -389,6 +398,7 @@ func (cache *txCache) Reset() { cache.mtx.Unlock() } +// Exists returns true if the given tx is cached. func (cache *txCache) Exists(tx types.Tx) bool { cache.mtx.Lock() _, exists := cache.map_[string(tx)] @@ -396,7 +406,7 @@ func (cache *txCache) Exists(tx types.Tx) bool { return exists } -// Returns false if tx is in cache. +// Push adds the given tx to the txCache. It returns false if tx is already in the cache. func (cache *txCache) Push(tx types.Tx) bool { cache.mtx.Lock() defer cache.mtx.Unlock() @@ -418,6 +428,7 @@ func (cache *txCache) Push(tx types.Tx) bool { return true } +// Remove removes the given tx from the cache. func (cache *txCache) Remove(tx types.Tx) { cache.mtx.Lock() delete(cache.map_, string(tx)) diff --git a/mempool/reactor.go b/mempool/reactor.go index 25806c00f..e4ee417fd 100644 --- a/mempool/reactor.go +++ b/mempool/reactor.go @@ -30,6 +30,7 @@ type MempoolReactor struct { evsw types.EventSwitch } +// NewMempoolReactor returns a new MempoolReactor with the given config and mempool. func NewMempoolReactor(config *cfg.MempoolConfig, mempool *Mempool) *MempoolReactor { memR := &MempoolReactor{ config: config, @@ -39,7 +40,8 @@ func NewMempoolReactor(config *cfg.MempoolConfig, mempool *Mempool) *MempoolReac return memR } -// Implements Reactor +// GetChannels implements Reactor. +// It returns the list of channels for this reactor. func (memR *MempoolReactor) GetChannels() []*p2p.ChannelDescriptor { return []*p2p.ChannelDescriptor{ &p2p.ChannelDescriptor{ @@ -49,17 +51,19 @@ func (memR *MempoolReactor) GetChannels() []*p2p.ChannelDescriptor { } } -// Implements Reactor +// AddPeer implements Reactor. +// It starts a broadcast routine ensuring all txs are forwarded to the given peer. func (memR *MempoolReactor) AddPeer(peer *p2p.Peer) { go memR.broadcastTxRoutine(peer) } -// Implements Reactor +// RemovePeer implements Reactor. func (memR *MempoolReactor) RemovePeer(peer *p2p.Peer, reason interface{}) { // broadcast routine checks if peer is gone and returns } -// Implements Reactor +// Receive implements Reactor. +// It adds any received transactions to the mempool. func (memR *MempoolReactor) Receive(chID byte, src *p2p.Peer, msgBytes []byte) { _, msg, err := DecodeMessage(msgBytes) if err != nil { @@ -84,15 +88,17 @@ func (memR *MempoolReactor) Receive(chID byte, src *p2p.Peer, msgBytes []byte) { } } -// Just an alias for CheckTx since broadcasting happens in peer routines +// BroadcastTx is an alias for Mempool.CheckTx. Broadcasting itself happens in peer routines. func (memR *MempoolReactor) BroadcastTx(tx types.Tx, cb func(*abci.Response)) error { return memR.Mempool.CheckTx(tx, cb) } +// PeerState describes the state of a peer. type PeerState interface { GetHeight() int } +// Peer describes a peer. type Peer interface { IsRunning() bool Send(byte, interface{}) bool @@ -141,7 +147,7 @@ func (memR *MempoolReactor) broadcastTxRoutine(peer Peer) { } } -// implements events.Eventable +// SetEventSwitch implements events.Eventable. func (memR *MempoolReactor) SetEventSwitch(evsw types.EventSwitch) { memR.evsw = evsw } @@ -153,6 +159,7 @@ const ( msgTypeTx = byte(0x01) ) +// MempoolMessage is a message sent or received by the MempoolReactor. type MempoolMessage interface{} var _ = wire.RegisterInterface( @@ -160,6 +167,7 @@ var _ = wire.RegisterInterface( wire.ConcreteType{&TxMessage{}, msgTypeTx}, ) +// DecodeMessage decodes a byte-array into a MempoolMessage. func DecodeMessage(bz []byte) (msgType byte, msg MempoolMessage, err error) { msgType = bz[0] n := new(int) @@ -170,10 +178,12 @@ func DecodeMessage(bz []byte) (msgType byte, msg MempoolMessage, err error) { //------------------------------------- +// TxMessage is a MempoolMessage containing a transaction. type TxMessage struct { Tx types.Tx } +// String returns a string representation of the TxMessage. func (m *TxMessage) String() string { return fmt.Sprintf("[TxMessage %v]", m.Tx) } From 525fc0ae5b6b517ab4e09f28c9b58565c2bb5ca9 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sun, 9 Jul 2017 14:00:14 -0400 Subject: [PATCH 3/4] types: block comments --- types/block.go | 67 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 50 insertions(+), 17 deletions(-) diff --git a/types/block.go b/types/block.go index 6592ad5dd..fee62e98c 100644 --- a/types/block.go +++ b/types/block.go @@ -10,7 +10,7 @@ import ( wire "github.com/tendermint/go-wire" "github.com/tendermint/go-wire/data" - . "github.com/tendermint/tmlibs/common" + cmn "github.com/tendermint/tmlibs/common" "github.com/tendermint/tmlibs/merkle" ) @@ -19,12 +19,14 @@ const ( DefaultBlockPartSize = 65536 // 64kB TODO: put part size in parts header? ) +// Block defines the atomic unit of a Tendermint blockchain type Block struct { *Header `json:"header"` *Data `json:"data"` LastCommit *Commit `json:"last_commit"` } +// MakeBlock returns a new block and corresponding part set from the given information // TODO: version func MakeBlock(height int, chainID string, txs []Tx, commit *Commit, prevBlockID BlockID, valHash, appHash []byte, partSize int) (*Block, *PartSet) { @@ -47,14 +49,14 @@ func MakeBlock(height int, chainID string, txs []Tx, commit *Commit, return block, block.MakePartSet(partSize) } -// Basic validation that doesn't involve state data. +// ValidateBasic performs basic validation that doesn't involve state data. func (b *Block) ValidateBasic(chainID string, lastBlockHeight int, lastBlockID BlockID, lastBlockTime time.Time, appHash []byte) error { if b.ChainID != chainID { - return errors.New(Fmt("Wrong Block.Header.ChainID. Expected %v, got %v", chainID, b.ChainID)) + return errors.New(cmn.Fmt("Wrong Block.Header.ChainID. Expected %v, got %v", chainID, b.ChainID)) } if b.Height != lastBlockHeight+1 { - return errors.New(Fmt("Wrong Block.Header.Height. Expected %v, got %v", lastBlockHeight+1, b.Height)) + return errors.New(cmn.Fmt("Wrong Block.Header.Height. Expected %v, got %v", lastBlockHeight+1, b.Height)) } /* TODO: Determine bounds for Time See blockchain/reactor "stopSyncingDurationMinutes" @@ -64,13 +66,13 @@ func (b *Block) ValidateBasic(chainID string, lastBlockHeight int, lastBlockID B } */ if b.NumTxs != len(b.Data.Txs) { - return errors.New(Fmt("Wrong Block.Header.NumTxs. Expected %v, got %v", len(b.Data.Txs), b.NumTxs)) + return errors.New(cmn.Fmt("Wrong Block.Header.NumTxs. Expected %v, got %v", len(b.Data.Txs), b.NumTxs)) } if !b.LastBlockID.Equals(lastBlockID) { - return errors.New(Fmt("Wrong Block.Header.LastBlockID. Expected %v, got %v", lastBlockID, b.LastBlockID)) + return errors.New(cmn.Fmt("Wrong Block.Header.LastBlockID. Expected %v, got %v", lastBlockID, b.LastBlockID)) } if !bytes.Equal(b.LastCommitHash, b.LastCommit.Hash()) { - return errors.New(Fmt("Wrong Block.Header.LastCommitHash. Expected %v, got %v", b.LastCommitHash, b.LastCommit.Hash())) + return errors.New(cmn.Fmt("Wrong Block.Header.LastCommitHash. Expected %v, got %v", b.LastCommitHash, b.LastCommit.Hash())) } if b.Header.Height != 1 { if err := b.LastCommit.ValidateBasic(); err != nil { @@ -78,15 +80,16 @@ func (b *Block) ValidateBasic(chainID string, lastBlockHeight int, lastBlockID B } } if !bytes.Equal(b.DataHash, b.Data.Hash()) { - return errors.New(Fmt("Wrong Block.Header.DataHash. Expected %v, got %v", b.DataHash, b.Data.Hash())) + return errors.New(cmn.Fmt("Wrong Block.Header.DataHash. Expected %v, got %v", b.DataHash, b.Data.Hash())) } if !bytes.Equal(b.AppHash, appHash) { - return errors.New(Fmt("Wrong Block.Header.AppHash. Expected %X, got %v", appHash, b.AppHash)) + return errors.New(cmn.Fmt("Wrong Block.Header.AppHash. Expected %X, got %v", appHash, b.AppHash)) } // NOTE: the AppHash and ValidatorsHash are validated later. return nil } +// FillHeader fills in any remaining header fields that are a function of the block data func (b *Block) FillHeader() { if b.LastCommitHash == nil { b.LastCommitHash = b.LastCommit.Hash() @@ -96,7 +99,7 @@ func (b *Block) FillHeader() { } } -// Computes and returns the block hash. +// Hash computes and returns the block hash. // If the block is incomplete, block hash is nil for safety. func (b *Block) Hash() data.Bytes { // fmt.Println(">>", b.Data) @@ -107,13 +110,14 @@ func (b *Block) Hash() data.Bytes { return b.Header.Hash() } +// MakePartSet returns a PartSet containing parts of a serialized block. +// This is the form in which the block is gossipped to peers. func (b *Block) MakePartSet(partSize int) *PartSet { return NewPartSetFromData(wire.BinaryBytes(b), partSize) } -// Convenience. -// A nil block never hashes to anything. -// Nothing hashes to a nil hash. +// HashesTo is a convenience function that checks if a block hashes to the given argument. +// A nil block never hashes to anything, and nothing hashes to a nil hash. func (b *Block) HashesTo(hash []byte) bool { if len(hash) == 0 { return false @@ -124,10 +128,12 @@ func (b *Block) HashesTo(hash []byte) bool { return bytes.Equal(b.Hash(), hash) } +// String returns a string representation of the block func (b *Block) String() string { return b.StringIndented("") } +// StringIndented returns a string representation of the block func (b *Block) StringIndented(indent string) string { if b == nil { return "nil-Block" @@ -143,6 +149,7 @@ func (b *Block) StringIndented(indent string) string { indent, b.Hash()) } +// StringShort returns a shortened string representation of the block func (b *Block) StringShort() string { if b == nil { return "nil-Block" @@ -153,6 +160,7 @@ func (b *Block) StringShort() string { //----------------------------------------------------------------------------- +// Header defines the structure of a Tendermint block header type Header struct { ChainID string `json:"chain_id"` Height int `json:"height"` @@ -165,6 +173,7 @@ type Header struct { AppHash data.Bytes `json:"app_hash"` // state after txs from the previous block } +// Hash returns the hash of the header. // NOTE: hash is nil if required fields are missing. func (h *Header) Hash() data.Bytes { if len(h.ValidatorsHash) == 0 { @@ -183,6 +192,7 @@ func (h *Header) Hash() data.Bytes { }) } +// StringIndented returns a string representation of the header func (h *Header) StringIndented(indent string) string { if h == nil { return "nil-Header" @@ -212,6 +222,7 @@ func (h *Header) StringIndented(indent string) string { //------------------------------------- +// Commit contains the evidence that a block was committed by a set of validators. // NOTE: Commit is empty for height 1, but never nil. type Commit struct { // NOTE: The Precommits are in order of address to preserve the bonded ValidatorSet order. @@ -223,9 +234,10 @@ type Commit struct { // Volatile firstPrecommit *Vote hash data.Bytes - bitArray *BitArray + bitArray *cmn.BitArray } +// FirstPrecommit returns the first non-nil precommit in the commit func (commit *Commit) FirstPrecommit() *Vote { if len(commit.Precommits) == 0 { return nil @@ -242,6 +254,7 @@ func (commit *Commit) FirstPrecommit() *Vote { return nil } +// Height returns the height of the commit func (commit *Commit) Height() int { if len(commit.Precommits) == 0 { return 0 @@ -249,6 +262,7 @@ func (commit *Commit) Height() int { return commit.FirstPrecommit().Height } +// Round returns the round of the commit func (commit *Commit) Round() int { if len(commit.Precommits) == 0 { return 0 @@ -256,10 +270,12 @@ func (commit *Commit) Round() int { return commit.FirstPrecommit().Round } +// Type returns the vote type of the commit, which is always VoteTypePrecommit func (commit *Commit) Type() byte { return VoteTypePrecommit } +// Size returns the number of votes in the commit func (commit *Commit) Size() int { if commit == nil { return 0 @@ -267,24 +283,30 @@ func (commit *Commit) Size() int { return len(commit.Precommits) } -func (commit *Commit) BitArray() *BitArray { +// BitArray returns a BitArray of which validators voted in this commit +func (commit *Commit) BitArray() *cmn.BitArray { if commit.bitArray == nil { - commit.bitArray = NewBitArray(len(commit.Precommits)) + commit.bitArray = cmn.NewBitArray(len(commit.Precommits)) for i, precommit := range commit.Precommits { + // TODO: need to check the BlockID otherwise we could be counting conflicts, + // not just the one with +2/3 ! commit.bitArray.SetIndex(i, precommit != nil) } } return commit.bitArray } +// GetByIndex returns the vote corresponding to a given validator index func (commit *Commit) GetByIndex(index int) *Vote { return commit.Precommits[index] } +// IsCommit returns true if there is at least one vote func (commit *Commit) IsCommit() bool { return len(commit.Precommits) != 0 } +// ValidateBasic performs basic validation that doesn't involve state data. func (commit *Commit) ValidateBasic() error { if commit.BlockID.IsZero() { return errors.New("Commit cannot be for nil block") @@ -319,6 +341,7 @@ func (commit *Commit) ValidateBasic() error { return nil } +// Hash returns the hash of the commit func (commit *Commit) Hash() data.Bytes { if commit.hash == nil { bs := make([]interface{}, len(commit.Precommits)) @@ -330,6 +353,7 @@ func (commit *Commit) Hash() data.Bytes { return commit.hash } +// StringIndented returns a string representation of the commit func (commit *Commit) StringIndented(indent string) string { if commit == nil { return "nil-Commit" @@ -349,6 +373,7 @@ func (commit *Commit) StringIndented(indent string) string { //----------------------------------------------------------------------------- +// Data contains the set of transactions included in the block type Data struct { // Txs that will be applied by state @ block.Height+1. @@ -360,6 +385,7 @@ type Data struct { hash data.Bytes } +// Hash returns the hash of the data func (data *Data) Hash() data.Bytes { if data.hash == nil { data.hash = data.Txs.Hash() // NOTE: leaves of merkle tree are TxIDs @@ -367,11 +393,12 @@ func (data *Data) Hash() data.Bytes { return data.hash } +// StringIndented returns a string representation of the transactions func (data *Data) StringIndented(indent string) string { if data == nil { return "nil-Data" } - txStrings := make([]string, MinInt(len(data.Txs), 21)) + txStrings := make([]string, cmn.MinInt(len(data.Txs), 21)) for i, tx := range data.Txs { if i == 20 { txStrings[i] = fmt.Sprintf("... (%v total)", len(data.Txs)) @@ -388,24 +415,29 @@ func (data *Data) StringIndented(indent string) string { //-------------------------------------------------------------------------------- +// BlockID defines the unique ID of a block as its Hash and its PartSetHeader type BlockID struct { Hash data.Bytes `json:"hash"` PartsHeader PartSetHeader `json:"parts"` } +// IsZero returns true if this is the BlockID for a nil-block func (blockID BlockID) IsZero() bool { return len(blockID.Hash) == 0 && blockID.PartsHeader.IsZero() } +// Equals returns true if the BlockID matches the given BlockID func (blockID BlockID) Equals(other BlockID) bool { return bytes.Equal(blockID.Hash, other.Hash) && blockID.PartsHeader.Equals(other.PartsHeader) } +// Key returns a machine-readable string representation of the BlockID func (blockID BlockID) Key() string { return string(blockID.Hash) + string(wire.BinaryBytes(blockID.PartsHeader)) } +// WriteSignBytes writes the canonical bytes of the BlockID to the given writer for digital signing func (blockID BlockID) WriteSignBytes(w io.Writer, n *int, err *error) { if blockID.IsZero() { wire.WriteTo([]byte("null"), w, n, err) @@ -415,6 +447,7 @@ func (blockID BlockID) WriteSignBytes(w io.Writer, n *int, err *error) { } +// String returns a human readable string representation of the BlockID func (blockID BlockID) String() string { return fmt.Sprintf(`%v:%v`, blockID.Hash, blockID.PartsHeader) } From d8ca0580a8f92284dd8c8b7a221f23f54fdaad58 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Thu, 13 Jul 2017 13:40:19 -0400 Subject: [PATCH 4/4] rpc: move grpc_test from test/ to grpc/ --- rpc/grpc/grpc_test.go | 33 +++++++++++++++++++++++++++++++++ rpc/test/grpc_test.go | 18 ------------------ rpc/test/main_test.go | 36 ------------------------------------ 3 files changed, 33 insertions(+), 54 deletions(-) create mode 100644 rpc/grpc/grpc_test.go delete mode 100644 rpc/test/grpc_test.go delete mode 100644 rpc/test/main_test.go diff --git a/rpc/grpc/grpc_test.go b/rpc/grpc/grpc_test.go new file mode 100644 index 000000000..cc8c9951c --- /dev/null +++ b/rpc/grpc/grpc_test.go @@ -0,0 +1,33 @@ +package core_grpc_test + +import ( + "os" + "testing" + + "github.com/stretchr/testify/require" + "golang.org/x/net/context" + + "github.com/tendermint/abci/example/dummy" + "github.com/tendermint/tendermint/rpc/grpc" + "github.com/tendermint/tendermint/rpc/test" +) + +func TestMain(m *testing.M) { + // start a tendermint node (and merkleeyes) in the background to test against + app := dummy.NewDummyApplication() + node := rpctest.StartTendermint(app) + code := m.Run() + + // and shut down proper at the end + node.Stop() + node.Wait() + os.Exit(code) +} + +func TestBroadcastTx(t *testing.T) { + require := require.New(t) + res, err := rpctest.GetGRPCClient().BroadcastTx(context.Background(), &core_grpc.RequestBroadcastTx{[]byte("this is a tx")}) + require.Nil(err, "%+v", err) + require.EqualValues(0, res.CheckTx.Code) + require.EqualValues(0, res.DeliverTx.Code) +} diff --git a/rpc/test/grpc_test.go b/rpc/test/grpc_test.go deleted file mode 100644 index 5ca40a3b0..000000000 --- a/rpc/test/grpc_test.go +++ /dev/null @@ -1,18 +0,0 @@ -package rpctest - -import ( - "testing" - - "golang.org/x/net/context" - - "github.com/stretchr/testify/require" - core_grpc "github.com/tendermint/tendermint/rpc/grpc" -) - -func TestBroadcastTx(t *testing.T) { - require := require.New(t) - res, err := GetGRPCClient().BroadcastTx(context.Background(), &core_grpc.RequestBroadcastTx{[]byte("this is a tx")}) - require.Nil(err, "%+v", err) - require.EqualValues(0, res.CheckTx.Code) - require.EqualValues(0, res.DeliverTx.Code) -} diff --git a/rpc/test/main_test.go b/rpc/test/main_test.go deleted file mode 100644 index f95176d9b..000000000 --- a/rpc/test/main_test.go +++ /dev/null @@ -1,36 +0,0 @@ -/* -package tests contain integration tests and helper functions for testing -the RPC interface - -In particular, it allows us to spin up a tendermint node in process, with -a live RPC server, which we can use to verify our rpc calls. It provides -all data structures, enabling us to do more complex tests (like node_test.go) -that introspect the blocks themselves to validate signatures and the like. - -It currently only spins up one node, it would be interesting to expand it -to multiple nodes to see the real effects of validating partially signed -blocks. -*/ -package rpctest - -import ( - "os" - "testing" - - "github.com/tendermint/abci/example/dummy" - nm "github.com/tendermint/tendermint/node" -) - -var node *nm.Node - -func TestMain(m *testing.M) { - // start a tendermint node (and merkleeyes) in the background to test against - app := dummy.NewDummyApplication() - node = StartTendermint(app) - code := m.Run() - - // and shut down proper at the end - node.Stop() - node.Wait() - os.Exit(code) -}