diff --git a/cmd/serve.go b/cmd/serve.go
index 61fdda0e4b85ea3aa2f8a55fccc4674fb5a86d6c..6d3f82d556b53a9d463c157bc9eb0063c9f4c453 100644
--- a/cmd/serve.go
+++ b/cmd/serve.go
@@ -143,6 +143,7 @@ func Serve(cmd *cobra.Command, args []string) {
 			log.Fatalf("Failed to load server configuration: %s.", err)
 			os.Exit(1)
 		}
+
 		serverProcess, err := newCore.NewGatewayV0(serverConfig)
 		if err != nil {
 			log.Fatalf("Failed to load servers: %s.", err)
diff --git a/consensus/tendermint/tendermint.go b/consensus/tendermint/tendermint.go
index a18e35311bc60c7ccc1051d2d30bd3143617dc25..65a58d48603e00ab83bdb63237c64d17c0715e17 100644
--- a/consensus/tendermint/tendermint.go
+++ b/consensus/tendermint/tendermint.go
@@ -27,6 +27,7 @@ import (
 
 	crypto "github.com/tendermint/go-crypto"
 	p2p "github.com/tendermint/go-p2p"
+	tendermint_consensus "github.com/tendermint/tendermint/consensus"
 	node "github.com/tendermint/tendermint/node"
 	proxy "github.com/tendermint/tendermint/proxy"
 	tendermint_types "github.com/tendermint/tendermint/types"
@@ -40,6 +41,8 @@ import (
 	// files  "github.com/eris-ltd/eris-db/files"
 	blockchain_types "github.com/eris-ltd/eris-db/blockchain/types"
 	consensus_types "github.com/eris-ltd/eris-db/consensus/types"
+	"github.com/eris-ltd/eris-db/txs"
+	"github.com/tendermint/go-wire"
 )
 
 type Tendermint struct {
@@ -222,6 +225,44 @@ func (tendermint *Tendermint) BroadcastTransaction(transaction []byte,
 	return tendermint.tmintNode.MempoolReactor().BroadcastTx(transaction, callback)
 }
 
+func (tendermint *Tendermint) ListUnconfirmedTxs(
+	maxTxs int) ([]txs.Tx, error) {
+	tendermintTxs := tendermint.tmintNode.MempoolReactor().Mempool.Reap(maxTxs)
+	transactions := make([]txs.Tx, len(tendermintTxs))
+	for i, txBytes := range tendermintTxs {
+		tx, err := txs.DecodeTx(txBytes)
+		if err != nil {
+			return nil, err
+		}
+		transactions[i] = tx
+	}
+	return transactions, nil
+}
+
+func (tendermint *Tendermint) ListValidators() []consensus_types.Validator {
+	return consensus_types.FromTendermintValidators(tendermint.tmintNode.
+		ConsensusState().Validators.Validators)
+}
+
+func (tendermint *Tendermint) ConsensusState() *consensus_types.ConsensusState {
+	return consensus_types.FromRoundState(tendermint.tmintNode.ConsensusState().
+			GetRoundState())
+}
+
+func (tendermint *Tendermint) PeerConsensusStates() map[string]string {
+	peers := tendermint.tmintNode.Switch().Peers().List()
+	peerConsensusStates := make(map[string]string,
+		len(peers))
+	for _, peer := range peers {
+		peerState := peer.Data.Get(tendermint_types.PeerStateKey).(*tendermint_consensus.PeerState)
+		peerRoundState := peerState.GetRoundState()
+		// TODO: implement a proper mapping, this is a nasty way of marshalling
+		// to JSON
+		peerConsensusStates[peer.Key] = string(wire.JSONBytes(peerRoundState))
+	}
+	return peerConsensusStates
+}
+
 //------------------------------------------------------------------------------
 // Helper functions
 
diff --git a/consensus/types/consensus_engine.go b/consensus/types/consensus_engine.go
index 893ea85ecdbbd0504862236215bda7dcc5e09d55..8600bb3e827091cb22f99be2956449fad0f76783 100644
--- a/consensus/types/consensus_engine.go
+++ b/consensus/types/consensus_engine.go
@@ -2,6 +2,7 @@ package types
 
 import (
 	"github.com/eris-ltd/eris-db/event"
+	"github.com/eris-ltd/eris-db/txs"
 	"github.com/tendermint/go-crypto"
 	"github.com/tendermint/go-p2p"
 	tmsp_types "github.com/tendermint/tmsp/types"
@@ -24,4 +25,13 @@ type ConsensusEngine interface {
 	// Events
 	// For consensus events like NewBlock
 	Events() event.EventEmitter
+
+	// List pending transactions in the mempool, passing 0 for maxTxs gets an
+	// unbounded number of transactions
+	ListUnconfirmedTxs(maxTxs int) ([]txs.Tx, error)
+	ListValidators() []Validator
+	ConsensusState() *ConsensusState
+	// TODO: Consider creating a real type for PeerRoundState, but at the looks
+	// quite coupled to tendermint
+	PeerConsensusStates() map[string]string
 }
diff --git a/consensus/types/consensus_state.go b/consensus/types/consensus_state.go
new file mode 100644
index 0000000000000000000000000000000000000000..a22febd4fcd8ea4d37023b3a4ac00e84583ae7e5
--- /dev/null
+++ b/consensus/types/consensus_state.go
@@ -0,0 +1,32 @@
+package types
+
+import (
+	"time"
+
+	tendermint_consensus "github.com/tendermint/tendermint/consensus"
+	tendermint_types "github.com/tendermint/tendermint/types"
+)
+
+// ConsensusState
+type ConsensusState struct {
+	Height     int                        `json:"height"`
+	Round      int                        `json:"round"`
+	Step       uint8                      `json:"step"`
+	StartTime  time.Time                  `json:"start_time"`
+	CommitTime time.Time                  `json:"commit_time"`
+	Validators []Validator                `json:"validators"`
+	Proposal   *tendermint_types.Proposal `json:"proposal"`
+}
+
+func FromRoundState(rs *tendermint_consensus.RoundState) *ConsensusState {
+	cs := &ConsensusState{
+		StartTime:  rs.StartTime,
+		CommitTime: rs.CommitTime,
+		Height:     rs.Height,
+		Proposal:   rs.Proposal,
+		Round:      rs.Round,
+		Step:       uint8(rs.Step),
+		Validators: FromTendermintValidators(rs.Validators.Validators),
+	}
+	return cs
+}
diff --git a/consensus/types/validator.go b/consensus/types/validator.go
new file mode 100644
index 0000000000000000000000000000000000000000..f5567bbbb0692daea3593d2b6feaf081cbbf793b
--- /dev/null
+++ b/consensus/types/validator.go
@@ -0,0 +1,37 @@
+package types
+
+import (
+	"github.com/tendermint/go-wire"
+	tendermint_types "github.com/tendermint/tendermint/types"
+)
+
+var _ = wire.RegisterInterface(
+	struct{ Validator }{},
+	wire.ConcreteType{&TendermintValidator{}, byte(0x01)},
+)
+
+type Validator interface {
+	AssertIsValidator()
+}
+
+// Anticipating moving to our own definition of Validator, or at least
+// augmenting Tendermint's.
+type TendermintValidator struct {
+	*tendermint_types.Validator `json:"validator"`
+}
+
+func (validator *TendermintValidator) AssertIsValidator() {
+
+}
+
+var _ Validator = (*TendermintValidator)(nil)
+
+func FromTendermintValidators(tmValidators []*tendermint_types.Validator) []Validator {
+	validators := make([]Validator, len(tmValidators))
+	for i, tmValidator := range tmValidators {
+		// This embedding could be replaced by a mapping once if we want to describe
+		// a more general notion of validator
+		validators[i] = &TendermintValidator{tmValidator}
+	}
+	return validators
+}
diff --git a/core/types/types.go b/core/types/types.go
index 738bfb2fc2cf9f86ee64788023b6248d72cb22ab..274900ee723b91a8d6c06fec7a3a58294c3fc183 100644
--- a/core/types/types.go
+++ b/core/types/types.go
@@ -21,14 +21,12 @@ package types
 
 import (
 	"github.com/tendermint/go-p2p" // NodeInfo (drop this!)
-	tendermint_consensus "github.com/tendermint/tendermint/consensus"
 	"github.com/tendermint/tendermint/types"
 
 	account "github.com/eris-ltd/eris-db/account"
 )
 
 type (
-
 	// *********************************** Address ***********************************
 
 	// Accounts
@@ -81,17 +79,6 @@ type (
 
 	// *********************************** Consensus ***********************************
 
-	// ConsensusState
-	ConsensusState struct {
-		Height     int                `json:"height"`
-		Round      int                `json:"round"`
-		Step       uint8              `json:"step"`
-		StartTime  string             `json:"start_time"`
-		CommitTime string             `json:"commit_time"`
-		Validators []*types.Validator `json:"validators"`
-		Proposal   *types.Proposal    `json:"proposal"`
-	}
-
 	// Validators
 	ValidatorList struct {
 		BlockHeight         int                `json:"block_height"`
@@ -159,19 +146,6 @@ type (
 	}
 )
 
-func FromRoundState(rs *tendermint_consensus.RoundState) *ConsensusState {
-	cs := &ConsensusState{
-		CommitTime: rs.CommitTime.String(),
-		Height:     rs.Height,
-		Proposal:   rs.Proposal,
-		Round:      rs.Round,
-		StartTime:  rs.StartTime.String(),
-		Step:       uint8(rs.Step),
-		Validators: rs.Validators.Validators,
-	}
-	return cs
-}
-
 //------------------------------------------------------------------------------
 // copied in from NameReg
 
diff --git a/definitions/pipe.go b/definitions/pipe.go
index 0a045442a3fac19e655fad1e8aaf92fc24ed9d69..285f8b53fccac575cd034b8742d8fcb83c9a18c2 100644
--- a/definitions/pipe.go
+++ b/definitions/pipe.go
@@ -38,7 +38,6 @@ import (
 type Pipe interface {
 	Accounts() Accounts
 	Blockchain() blockchain_types.Blockchain
-	Consensus() consensus_types.ConsensusEngine
 	Events() event.EventEmitter
 	NameReg() NameReg
 	Net() Net
@@ -91,6 +90,5 @@ type Transactor interface {
 		fee int64) (*txs.EventDataCall, error)
 	TransactNameReg(privKey []byte, name, data string, amount,
 		fee int64) (*txs.Receipt, error)
-	UnconfirmedTxs() (*txs.UnconfirmedTxs, error)
 	SignTx(tx txs.Tx, privAccounts []*account.PrivAccount) (txs.Tx, error)
 }
diff --git a/definitions/tendermint_pipe.go b/definitions/tendermint_pipe.go
index bffa94ad935ba507e82f97f9c87cde93abbe480b..37973ce4dcaffc918d477a19d809ae1a7d808175 100644
--- a/definitions/tendermint_pipe.go
+++ b/definitions/tendermint_pipe.go
@@ -69,4 +69,10 @@ type TendermintPipe interface {
 
 	// Blockchain
 	BlockchainInfo(minHeight, maxHeight, maxBlockLookback int) (*rpc_tm_types.ResultBlockchainInfo, error)
+	ListUnconfirmedTxs(maxTxs int) (*rpc_tm_types.ResultListUnconfirmedTxs, error)
+	GetBlock(height int) (*rpc_tm_types.ResultGetBlock, error)
+
+	// Consensus
+	ListValidators() (*rpc_tm_types.ResultListValidators, error)
+	DumpConsensusState() (*rpc_tm_types.ResultDumpConsensusState, error)
 }
diff --git a/manager/eris-mint/eris-mint.go b/manager/eris-mint/eris-mint.go
index 809540879b1d262b843adadcd544dff5126e609e..55d7374d175569234d9254301204f180e2502229 100644
--- a/manager/eris-mint/eris-mint.go
+++ b/manager/eris-mint/eris-mint.go
@@ -124,8 +124,7 @@ func (app *ErisMint) SetOption(key string, value string) (log string) {
 }
 
 // Implements manager/types.Application
-func (app *ErisMint) AppendTx(txBytes []byte) (res tmsp.Result) {
-
+func (app *ErisMint) AppendTx(txBytes []byte) tmsp.Result {
 	app.nTxs += 1
 
 	// XXX: if we had tx ids we could cache the decoded txs on CheckTx
@@ -149,7 +148,7 @@ func (app *ErisMint) AppendTx(txBytes []byte) (res tmsp.Result) {
 }
 
 // Implements manager/types.Application
-func (app *ErisMint) CheckTx(txBytes []byte) (res tmsp.Result) {
+func (app *ErisMint) CheckTx(txBytes []byte) tmsp.Result {
 	var n int
 	var err error
 	tx := new(txs.Tx)
diff --git a/manager/eris-mint/pipe.go b/manager/eris-mint/pipe.go
index 6339abc2daab3c055b5c1a226223d61036797957..fe07891316f8961262c01d48c9fad34aa4798017 100644
--- a/manager/eris-mint/pipe.go
+++ b/manager/eris-mint/pipe.go
@@ -47,8 +47,8 @@ import (
 )
 
 type erisMintPipe struct {
-	erisMintState   *state.State
-	erisMint        *ErisMint
+	erisMintState *state.State
+	erisMint      *ErisMint
 	// Pipe implementations
 	accounts        *accounts
 	blockchain      blockchain_types.Blockchain
@@ -58,8 +58,8 @@ type erisMintPipe struct {
 	network         *network
 	transactor      *transactor
 	// Genesis cache
-	genesisDoc      *state_types.GenesisDoc
-	genesisState    *state.State
+	genesisDoc   *state_types.GenesisDoc
+	genesisState *state.State
 }
 
 // NOTE [ben] Compiler check to ensure erisMintPipe successfully implements
@@ -112,11 +112,11 @@ func NewErisMintPipe(moduleConfig *config.ModuleConfig,
 		genesisDoc:   genesisDoc,
 		genesisState: nil,
 		// TODO: What network-level information do we need?
-		network:       newNetwork(),
+		network: newNetwork(),
 		// consensus and blockchain should both be loaded into the pipe by a higher
 		// authority - this is a sort of dependency injection pattern
-		consensusEngine:     nil,
-		blockchain: nil,
+		consensusEngine: nil,
+		blockchain:      nil,
 	}, nil
 }
 
@@ -181,10 +181,6 @@ func (pipe *erisMintPipe) Blockchain() blockchain_types.Blockchain {
 	return pipe.blockchain
 }
 
-func (pipe *erisMintPipe) Consensus() consensus_types.ConsensusEngine {
-	return pipe.consensusEngine
-}
-
 func (pipe *erisMintPipe) Events() edb_event.EventEmitter {
 	return pipe.events
 }
@@ -395,7 +391,7 @@ func (pipe *erisMintPipe) DumpStorage(address []byte) (*rpc_tm_types.ResultDumpS
 	return &rpc_tm_types.ResultDumpStorage{storageRoot, storageItems}, nil
 }
 
-// Call 
+// Call
 // NOTE: this function is used from 46657 and has sibling on 1337
 // in transactor.go
 // TODO: [ben] resolve incompatibilities in byte representation for 0.12.0 release
@@ -522,26 +518,34 @@ func (pipe *erisMintPipe) ListNames() (*rpc_tm_types.ResultListNames, error) {
 	return &rpc_tm_types.ResultListNames{blockHeight, names}, nil
 }
 
-// Memory pool
-// NOTE: txs must be signed
-func (pipe *erisMintPipe) BroadcastTxAsync(tx txs.Tx) (
-	*rpc_tm_types.ResultBroadcastTx, error) {
-	err := pipe.consensusEngine.BroadcastTransaction(txs.EncodeTx(tx), nil)
+func (pipe *erisMintPipe) broadcastTx(tx txs.Tx,
+	callback func(res *tmsp_types.Response)) (*rpc_tm_types.ResultBroadcastTx, error) {
+
+	txBytes, err := txs.EncodeTx(tx)
+	if err != nil {
+		return nil, fmt.Errorf("Error encoding transaction: %v", err)
+	}
+	err = pipe.consensusEngine.BroadcastTransaction(txBytes, callback)
 	if err != nil {
-		return nil, fmt.Errorf("Error broadcasting txs: %v", err)
+		return nil, fmt.Errorf("Error broadcasting transaction: %v", err)
 	}
 	return &rpc_tm_types.ResultBroadcastTx{}, nil
 }
 
-func (pipe *erisMintPipe) BroadcastTxSync(tx txs.Tx) (*rpc_tm_types.ResultBroadcastTx,
-	error) {
+// Memory pool
+// NOTE: txs must be signed
+func (pipe *erisMintPipe) BroadcastTxAsync(tx txs.Tx) (*rpc_tm_types.ResultBroadcastTx, error) {
+	return pipe.broadcastTx(tx, nil)
+}
+
+func (pipe *erisMintPipe) BroadcastTxSync(tx txs.Tx) (*rpc_tm_types.ResultBroadcastTx, error) {
 	responseChannel := make(chan *tmsp_types.Response, 1)
-	err := pipe.consensusEngine.BroadcastTransaction(txs.EncodeTx(tx),
+	_, err := pipe.broadcastTx(tx,
 		func(res *tmsp_types.Response) {
 			responseChannel <- res
 		})
 	if err != nil {
-		return nil, fmt.Errorf("Error broadcasting txs: %v", err)
+		return nil, err
 	}
 	// NOTE: [ben] This Response is set in /consensus/tendermint/local_client.go
 	// a call to Application, here implemented by ErisMint, over local callback,
@@ -574,6 +578,18 @@ func (pipe *erisMintPipe) BroadcastTxSync(tx txs.Tx) (*rpc_tm_types.ResultBroadc
 	}
 }
 
+func (pipe *erisMintPipe) ListUnconfirmedTxs(maxTxs int) (*rpc_tm_types.ResultListUnconfirmedTxs, error) {
+	// Get all transactions for now
+	transactions, err := pipe.consensusEngine.ListUnconfirmedTxs(maxTxs)
+	if err != nil {
+		return nil, err
+	}
+	return &rpc_tm_types.ResultListUnconfirmedTxs{
+		N:   len(transactions),
+		Txs: transactions,
+	}, nil
+}
+
 // Returns the current blockchain height and metadata for a range of blocks
 // between minHeight and maxHeight. Only returns maxBlockLookback block metadata
 // from the top of the range of blocks.
@@ -599,5 +615,43 @@ func (pipe *erisMintPipe) BlockchainInfo(minHeight, maxHeight,
 		blockMetas = append(blockMetas, blockMeta)
 	}
 
-	return &rpc_tm_types.ResultBlockchainInfo{latestHeight, blockMetas}, nil
+	return &rpc_tm_types.ResultBlockchainInfo{
+		LastHeight: latestHeight,
+		BlockMetas: blockMetas,
+	}, nil
+}
+
+func (pipe *erisMintPipe) GetBlock(height int) (*rpc_tm_types.ResultGetBlock, error) {
+	return &rpc_tm_types.ResultGetBlock{
+		Block:     pipe.blockchain.Block(height),
+		BlockMeta: pipe.blockchain.BlockMeta(height),
+	}, nil
+}
+
+func (pipe *erisMintPipe) ListValidators() (*rpc_tm_types.ResultListValidators, error) {
+	validators := pipe.consensusEngine.ListValidators()
+	consensusState := pipe.consensusEngine.ConsensusState()
+	// TODO: when we reintroduce support for bonding and unbonding update this
+	// to reflect the mutable bonding state
+	return &rpc_tm_types.ResultListValidators{
+		BlockHeight:         consensusState.Height,
+		BondedValidators:    validators,
+		UnbondingValidators: nil,
+	}, nil
+}
+
+func (pipe *erisMintPipe) DumpConsensusState() (*rpc_tm_types.ResultDumpConsensusState, error) {
+	statesMap := pipe.consensusEngine.PeerConsensusStates()
+	peerStates := make([]*rpc_tm_types.ResultPeerConsensusState, len(statesMap))
+	for key, peerState := range statesMap {
+		peerStates = append(peerStates, &rpc_tm_types.ResultPeerConsensusState{
+			PeerKey:            key,
+			PeerConsensusState: peerState,
+		})
+	}
+	dump := rpc_tm_types.ResultDumpConsensusState{
+		ConsensusState:      pipe.consensusEngine.ConsensusState(),
+		PeerConsensusStates: peerStates,
+	}
+	return &dump, nil
 }
diff --git a/manager/eris-mint/transactor.go b/manager/eris-mint/transactor.go
index 71c342a85f47a4e6216f3a44b9d898755648b270..3b971d3702d72040d7132b7aba7f24d913686be7 100644
--- a/manager/eris-mint/transactor.go
+++ b/manager/eris-mint/transactor.go
@@ -151,12 +151,6 @@ func (this *transactor) BroadcastTx(tx txs.Tx) (*txs.Receipt, error) {
 	return &txs.Receipt{txHash, createsContract, contractAddr}, nil
 }
 
-// Get all unconfirmed txs.
-func (this *transactor) UnconfirmedTxs() (*txs.UnconfirmedTxs, error) {
-	// TODO-RPC
-	return &txs.UnconfirmedTxs{}, nil
-}
-
 // Orders calls to BroadcastTx using lock (waits for response from core before releasing)
 func (this *transactor) Transact(privKey, address, data []byte, gasLimit,
 	fee int64) (*txs.Receipt, error) {
diff --git a/rpc/tendermint/client/client.go b/rpc/tendermint/client/client.go
index 0758eb20f487ea230557acf905fe6a55738b6a3b..3108c3f0325befcbfc1791e0697a0030940cd5f8 100644
--- a/rpc/tendermint/client/client.go
+++ b/rpc/tendermint/client/client.go
@@ -126,6 +126,39 @@ func BlockchainInfo(client rpcclient.Client, minHeight,
 	return res.(*rpc_types.ResultBlockchainInfo), err
 }
 
+func GetBlock(client rpcclient.Client, height int) (*rpc_types.ResultGetBlock, error) {
+	res, err := performCall(client, "get_block",
+		"height", height)
+	if err != nil {
+		return nil, err
+	}
+	return res.(*rpc_types.ResultGetBlock), err
+}
+
+func ListUnconfirmedTxs(client rpcclient.Client) (*rpc_types.ResultListUnconfirmedTxs, error) {
+	res, err := performCall(client, "list_unconfirmed_txs")
+	if err != nil {
+		return nil, err
+	}
+	return res.(*rpc_types.ResultListUnconfirmedTxs), err
+}
+
+func ListValidators(client rpcclient.Client) (*rpc_types.ResultListValidators, error) {
+	res, err := performCall(client, "list_validators")
+	if err != nil {
+		return nil, err
+	}
+	return res.(*rpc_types.ResultListValidators), err
+}
+
+func DumpConsensusState(client rpcclient.Client) (*rpc_types.ResultDumpConsensusState, error) {
+	res, err := performCall(client, "dump_consensus_state")
+	if err != nil {
+		return nil, err
+	}
+	return res.(*rpc_types.ResultDumpConsensusState), err
+}
+
 func performCall(client rpcclient.Client, method string,
 	paramKeyVals ...interface{}) (res rpc_types.ErisDBResult, err error) {
 	paramsMap, paramsSlice, err := mapAndValues(paramKeyVals...)
@@ -137,6 +170,9 @@ func performCall(client rpcclient.Client, method string,
 		_, err = cli.Call(method, paramsSlice, &res)
 	case *rpcclient.ClientURI:
 		_, err = cli.Call(method, paramsMap, &res)
+	default:
+		panic(fmt.Errorf("peformCall called against an unknown rpcclient.Client %v",
+			cli))
 	}
 	return
 
diff --git a/rpc/tendermint/core/routes.go b/rpc/tendermint/core/routes.go
index 714c1066d290c7f5cddf148e1064ae9eaf488cd0..a9dfa887eecdc7d9d50bf54c1ceefef099500bbb 100644
--- a/rpc/tendermint/core/routes.go
+++ b/rpc/tendermint/core/routes.go
@@ -38,15 +38,13 @@ func (tmRoutes *TendermintRoutes) GetRoutes() map[string]*rpc.RPCFunc {
 		"get_name":                rpc.NewRPCFunc(tmRoutes.GetNameResult, "name"),
 		"list_names":              rpc.NewRPCFunc(tmRoutes.ListNamesResult, ""),
 		"broadcast_tx":            rpc.NewRPCFunc(tmRoutes.BroadcastTxResult, "tx"),
+		"blockchain":              rpc.NewRPCFunc(tmRoutes.BlockchainInfo, "minHeight,maxHeight"),
+		"get_block":               rpc.NewRPCFunc(tmRoutes.GetBlock, "height"),
+		"list_unconfirmed_txs":    rpc.NewRPCFunc(tmRoutes.ListUnconfirmedTxs, ""),
+		"list_validators":         rpc.NewRPCFunc(tmRoutes.ListValidators, ""),
+		"dump_consensus_state":    rpc.NewRPCFunc(tmRoutes.DumpConsensusState, ""),
 		"unsafe/gen_priv_account": rpc.NewRPCFunc(tmRoutes.GenPrivAccountResult, ""),
 		"unsafe/sign_tx":          rpc.NewRPCFunc(tmRoutes.SignTxResult, "tx,privAccounts"),
-
-		// TODO: hookup
-		"blockchain": rpc.NewRPCFunc(tmRoutes.BlockchainInfo, "minHeight,maxHeight"),
-		//	"get_block":               rpc.NewRPCFunc(GetBlock, "height"),
-		// "list_validators":         rpc.NewRPCFunc(ListValidators, ""),
-		// "dump_consensus_state":    rpc.NewRPCFunc(DumpConsensusState, ""),
-		// "list_unconfirmed_txs":    rpc.NewRPCFunc(ListUnconfirmedTxs, ""),
 		// TODO: [Silas] do we also carry forward "consensus_state" as in v0?
 	}
 	return routes
@@ -211,5 +209,34 @@ func (tmRoutes *TendermintRoutes) BlockchainInfo(minHeight,
 	} else {
 		return r, nil
 	}
+}
 
+func (tmRoutes *TendermintRoutes) ListUnconfirmedTxs() (ctypes.ErisDBResult, error) {
+	// Get all Txs for now
+	r, err := tmRoutes.tendermintPipe.ListUnconfirmedTxs(-1)
+	if err != nil {
+		return nil, err
+	} else {
+		return r, nil
+	}
 }
+func (tmRoutes *TendermintRoutes) GetBlock(height int) (ctypes.ErisDBResult, error) {
+	r, err := tmRoutes.tendermintPipe.GetBlock(height)
+	if err != nil {
+		return nil, err
+	} else {
+		return r, nil
+	}
+}
+func (tmRoutes *TendermintRoutes) ListValidators() (ctypes.ErisDBResult, error) {
+	r, err := tmRoutes.tendermintPipe.ListValidators()
+	if err != nil {
+		return nil, err
+	} else {
+		return r, nil
+	}
+}
+func (tmRoutes *TendermintRoutes) DumpConsensusState() (ctypes.ErisDBResult, error) {
+	return tmRoutes.tendermintPipe.DumpConsensusState()
+}
+
diff --git a/rpc/tendermint/core/types/responses.go b/rpc/tendermint/core/types/responses.go
index cacb5f5ff0beb38fc2fc7ec60807a8d9cb079571..a9cf010e939fcc207b1bfd8d2f5d1ea84162ab53 100644
--- a/rpc/tendermint/core/types/responses.go
+++ b/rpc/tendermint/core/types/responses.go
@@ -1,11 +1,11 @@
-package core_types
+package types
 
 import (
 	acm "github.com/eris-ltd/eris-db/account"
 	core_types "github.com/eris-ltd/eris-db/core/types"
 	stypes "github.com/eris-ltd/eris-db/manager/eris-mint/state/types"
 	"github.com/eris-ltd/eris-db/txs"
-	"github.com/tendermint/tendermint/types"
+	tendermint_types "github.com/tendermint/tendermint/types"
 
 	consensus_types "github.com/eris-ltd/eris-db/consensus/types"
 	"github.com/tendermint/go-crypto"
@@ -42,13 +42,13 @@ type StorageItem struct {
 }
 
 type ResultBlockchainInfo struct {
-	LastHeight int                `json:"last_height"`
-	BlockMetas []*types.BlockMeta `json:"block_metas"`
+	LastHeight int                           `json:"last_height"`
+	BlockMetas []*tendermint_types.BlockMeta `json:"block_metas"`
 }
 
 type ResultGetBlock struct {
-	BlockMeta *types.BlockMeta `json:"block_meta"`
-	Block     *types.Block     `json:"block"`
+	BlockMeta *tendermint_types.BlockMeta `json:"block_meta"`
+	Block     *tendermint_types.Block     `json:"block"`
 }
 
 type ResultStatus struct {
@@ -76,14 +76,19 @@ type ResultNetInfo struct {
 }
 
 type ResultListValidators struct {
-	BlockHeight         int                `json:"block_height"`
-	BondedValidators    []*types.Validator `json:"bonded_validators"`
-	UnbondingValidators []*types.Validator `json:"unbonding_validators"`
+	BlockHeight         int                         `json:"block_height"`
+	BondedValidators    []consensus_types.Validator `json:"bonded_validators"`
+	UnbondingValidators []consensus_types.Validator `json:"unbonding_validators"`
 }
 
 type ResultDumpConsensusState struct {
-	RoundState      string   `json:"round_state"`
-	PeerRoundStates []string `json:"peer_round_states"`
+	ConsensusState      *consensus_types.ConsensusState `json:"consensus_state"`
+	PeerConsensusStates []*ResultPeerConsensusState      `json:"peer_consensus_states"`
+}
+
+type ResultPeerConsensusState struct {
+	PeerKey            string `json:"peer_key"`
+	PeerConsensusState string `json:"peer_consensus_state"`
 }
 
 type ResultListNames struct {
@@ -152,34 +157,38 @@ const (
 	ResultTypeEvent              = byte(0x13) // so websockets can respond to rpc functions
 	ResultTypeSubscribe          = byte(0x14)
 	ResultTypeUnsubscribe        = byte(0x15)
+	ResultTypePeerConsensusState = byte(0x16)
 )
 
 type ErisDBResult interface {
 	rpctypes.Result
 }
 
-// for wire.readReflect
-var _ = wire.RegisterInterface(
-	struct{ ErisDBResult }{},
-	wire.ConcreteType{&ResultGetStorage{}, ResultTypeGetStorage},
-	wire.ConcreteType{&ResultCall{}, ResultTypeCall},
-	wire.ConcreteType{&ResultListAccounts{}, ResultTypeListAccounts},
-	wire.ConcreteType{&ResultDumpStorage{}, ResultTypeDumpStorage},
-	wire.ConcreteType{&ResultBlockchainInfo{}, ResultTypeBlockchainInfo},
-	wire.ConcreteType{&ResultGetBlock{}, ResultTypeGetBlock},
-	wire.ConcreteType{&ResultStatus{}, ResultTypeStatus},
-	wire.ConcreteType{&ResultNetInfo{}, ResultTypeNetInfo},
-	wire.ConcreteType{&ResultListValidators{}, ResultTypeListValidators},
-	wire.ConcreteType{&ResultDumpConsensusState{}, ResultTypeDumpConsensusState},
-	wire.ConcreteType{&ResultListNames{}, ResultTypeListNames},
-	wire.ConcreteType{&ResultGenPrivAccount{}, ResultTypeGenPrivAccount},
-	wire.ConcreteType{&ResultGetAccount{}, ResultTypeGetAccount},
-	wire.ConcreteType{&ResultBroadcastTx{}, ResultTypeBroadcastTx},
-	wire.ConcreteType{&ResultListUnconfirmedTxs{}, ResultTypeListUnconfirmedTxs},
-	wire.ConcreteType{&ResultGetName{}, ResultTypeGetName},
-	wire.ConcreteType{&ResultGenesis{}, ResultTypeGenesis},
-	wire.ConcreteType{&ResultSignTx{}, ResultTypeSignTx},
-	wire.ConcreteType{&ResultEvent{}, ResultTypeEvent},
-	wire.ConcreteType{&ResultSubscribe{}, ResultTypeSubscribe},
-	wire.ConcreteType{&ResultUnsubscribe{}, ResultTypeUnsubscribe},
-)
+func ConcreteTypes() []wire.ConcreteType {
+	return []wire.ConcreteType{
+		{&ResultGetStorage{}, ResultTypeGetStorage},
+		{&ResultCall{}, ResultTypeCall},
+		{&ResultListAccounts{}, ResultTypeListAccounts},
+		{&ResultDumpStorage{}, ResultTypeDumpStorage},
+		{&ResultBlockchainInfo{}, ResultTypeBlockchainInfo},
+		{&ResultGetBlock{}, ResultTypeGetBlock},
+		{&ResultStatus{}, ResultTypeStatus},
+		{&ResultNetInfo{}, ResultTypeNetInfo},
+		{&ResultListValidators{}, ResultTypeListValidators},
+		{&ResultDumpConsensusState{}, ResultTypeDumpConsensusState},
+		{&ResultDumpConsensusState{}, ResultTypePeerConsensusState},
+		{&ResultListNames{}, ResultTypeListNames},
+		{&ResultGenPrivAccount{}, ResultTypeGenPrivAccount},
+		{&ResultGetAccount{}, ResultTypeGetAccount},
+		{&ResultBroadcastTx{}, ResultTypeBroadcastTx},
+		{&ResultListUnconfirmedTxs{}, ResultTypeListUnconfirmedTxs},
+		{&ResultGetName{}, ResultTypeGetName},
+		{&ResultGenesis{}, ResultTypeGenesis},
+		{&ResultSignTx{}, ResultTypeSignTx},
+		{&ResultEvent{}, ResultTypeEvent},
+		{&ResultSubscribe{}, ResultTypeSubscribe},
+		{&ResultUnsubscribe{}, ResultTypeUnsubscribe},
+	}
+}
+
+var _ = wire.RegisterInterface(struct{ ErisDBResult }{}, ConcreteTypes()...)
diff --git a/rpc/tendermint/core/types/responses_test.go b/rpc/tendermint/core/types/responses_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..bf009eab11b57c3dd3df384f8cf903c3ae2f01a4
--- /dev/null
+++ b/rpc/tendermint/core/types/responses_test.go
@@ -0,0 +1,34 @@
+package types
+
+import (
+	"testing"
+
+	"time"
+
+	consensus_types "github.com/eris-ltd/eris-db/consensus/types"
+	"github.com/tendermint/go-wire"
+	tendermint_types "github.com/tendermint/tendermint/types"
+)
+
+func TestResultDumpConsensusState(t *testing.T) {
+	result := ResultDumpConsensusState{
+		ConsensusState: &consensus_types.ConsensusState{
+			Height:     3,
+			Round:      1,
+			Step:       uint8(1),
+			StartTime:  time.Now().Add(-time.Second * 100),
+			CommitTime: time.Now().Add(-time.Second * 10),
+			Validators: []consensus_types.Validator{
+				&consensus_types.TendermintValidator{},
+			},
+			Proposal: &tendermint_types.Proposal{},
+		},
+		PeerConsensusStates: []*ResultPeerConsensusState{
+			{
+				PeerKey:            "Foo",
+				PeerConsensusState: "Bar",
+			},
+		},
+	}
+	wire.JSONBytes(result)
+}
diff --git a/rpc/tendermint/test/client_rpc_test.go b/rpc/tendermint/test/client_rpc_test.go
deleted file mode 100644
index 1a0a725df29d089b1180435a74e9df380f243a96..0000000000000000000000000000000000000000
--- a/rpc/tendermint/test/client_rpc_test.go
+++ /dev/null
@@ -1,118 +0,0 @@
-// +build integration
-
-// Space above here matters
-package test
-
-import (
-	"testing"
-
-	//	ctypes "github.com/eris-ltd/eris-db/rpc/core/types"
-	_ "github.com/tendermint/tendermint/config/tendermint_test"
-)
-
-// When run with `-test.short` we only run:
-// TestHTTPStatus, TestHTTPBroadcast, TestJSONStatus, TestJSONBroadcast, TestWSConnect, TestWSSend
-
-//--------------------------------------------------------------------------------
-func TestHTTPStatus(t *testing.T) {
-	testStatus(t, "HTTP")
-}
-
-func TestHTTPGetAccount(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping test in short mode.")
-	}
-	testGetAccount(t, "HTTP")
-}
-
-func TestHTTPBroadcastTx(t *testing.T) {
-	testBroadcastTx(t, "HTTP")
-}
-
-func TestHTTPGetStorage(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping test in short mode.")
-	}
-	testGetStorage(t, "HTTP")
-}
-
-func TestHTTPCallCode(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping test in short mode.")
-	}
-	testCallCode(t, "HTTP")
-}
-
-func TestHTTPCallContract(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping test in short mode.")
-	}
-	testCall(t, "HTTP")
-}
-
-func TestHTTPNameReg(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping test in short mode.")
-	}
-	testNameReg(t, "HTTP")
-}
-
-func TestHTTPBlockchainInfo(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping test in short mode.")
-	}
-	testBlockchainInfo(t, "HTTP")
-}
-
-//--------------------------------------------------------------------------------
-// Test the JSONRPC client
-
-func TestJSONStatus(t *testing.T) {
-	testStatus(t, "JSONRPC")
-}
-
-func TestJSONGetAccount(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping test in short mode.")
-	}
-	testGetAccount(t, "JSONRPC")
-}
-
-func TestJSONBroadcastTx(t *testing.T) {
-	testBroadcastTx(t, "JSONRPC")
-}
-
-func TestJSONGetStorage(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping test in short mode.")
-	}
-	testGetStorage(t, "JSONRPC")
-}
-
-func TestJSONCallCode(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping test in short mode.")
-	}
-	testCallCode(t, "JSONRPC")
-}
-
-func TestJSONCallContract(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping test in short mode.")
-	}
-	testCall(t, "JSONRPC")
-}
-
-func TestJSONNameReg(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping test in short mode.")
-	}
-	testNameReg(t, "JSONRPC")
-}
-
-func TestJSONBlockchainInfo(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping test in short mode.")
-	}
-	testBlockchainInfo(t, "JSONRPC")
-}
diff --git a/rpc/tendermint/test/common.go b/rpc/tendermint/test/common.go
index 211d3549991fccb6d68a0754f254609311a0591a..76909182df98801eab3e08db5b5c4bbfd03617cf 100644
--- a/rpc/tendermint/test/common.go
+++ b/rpc/tendermint/test/common.go
@@ -4,10 +4,10 @@
 package test
 
 import (
-	"github.com/eris-ltd/eris-db/test/fixtures"
-	rpc_core "github.com/eris-ltd/eris-db/rpc/tendermint/core"
-	"testing"
 	"fmt"
+
+	rpc_core "github.com/eris-ltd/eris-db/rpc/tendermint/core"
+	"github.com/eris-ltd/eris-db/test/fixtures"
 )
 
 // Needs to be referenced by a *_test.go file to be picked up
@@ -26,7 +26,7 @@ func TestWrapper(runner func() int) int {
 	// start a node
 	ready := make(chan error)
 	server := make(chan *rpc_core.TendermintWebsocketServer)
-	defer func(){
+	defer func() {
 		// Shutdown -- make sure we don't hit a race on ffs.RemoveAll
 		tmServer := <-server
 		tmServer.Shutdown()
@@ -48,9 +48,9 @@ func TestWrapper(runner func() int) int {
 // inconsequential, so feel free to insert your own code if you want to use it
 // as an application entry point for delve debugging.
 func DebugMain() {
-	t := &testing.T{}
+	//t := &testing.T{}
 	TestWrapper(func() int {
-		testNameReg(t, "JSONRPC")
+		//testNameReg(t, "JSONRPC")
 		return 0
 	})
 }
diff --git a/rpc/tendermint/test/rpc_client_test.go b/rpc/tendermint/test/rpc_client_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..7183f2df8f1effbafe76705e344fd1658c01852a
--- /dev/null
+++ b/rpc/tendermint/test/rpc_client_test.go
@@ -0,0 +1,402 @@
+// +build integration
+
+// Space above here matters
+package test
+
+import (
+	"bytes"
+	"fmt"
+	"testing"
+
+	"golang.org/x/crypto/ripemd160"
+
+	"time"
+
+	consensus_types "github.com/eris-ltd/eris-db/consensus/types"
+	edbcli "github.com/eris-ltd/eris-db/rpc/tendermint/client"
+	"github.com/eris-ltd/eris-db/txs"
+	"github.com/stretchr/testify/assert"
+	tm_common "github.com/tendermint/go-common"
+	rpcclient "github.com/tendermint/go-rpc/client"
+	_ "github.com/tendermint/tendermint/config/tendermint_test"
+)
+
+// When run with `-test.short` we only run:
+// TestHTTPStatus, TestHTTPBroadcast, TestJSONStatus, TestJSONBroadcast, TestWSConnect, TestWSSend
+
+// Note: the reason that we have tests implemented in tests.go is I believe
+// due to weirdness with go-wire's interface registration, and those global
+// registrations not being available within a *_test.go runtime context.
+func testWithAllClients(t *testing.T,
+	testFunction func(*testing.T, string, rpcclient.Client)) {
+	for clientName, client := range clients {
+		testFunction(t, clientName, client)
+	}
+}
+
+//--------------------------------------------------------------------------------
+func TestStatus(t *testing.T) {
+	testWithAllClients(t, func(t *testing.T, clientName string, client rpcclient.Client) {
+		resp, err := edbcli.Status(client)
+		assert.NoError(t, err)
+		fmt.Println(resp)
+		if resp.NodeInfo.Network != chainID {
+			t.Fatal(fmt.Errorf("ChainID mismatch: got %s expected %s",
+				resp.NodeInfo.Network, chainID))
+		}
+	})
+}
+
+func TestBroadcastTx(t *testing.T) {
+	wsc := newWSClient()
+	testWithAllClients(t, func(t *testing.T, clientName string, client rpcclient.Client) {
+		// Avoid duplicate Tx in mempool
+		amt := hashString(clientName) % 1000
+		toAddr := user[1].Address
+		tx := makeDefaultSendTxSigned(t, client, toAddr, amt)
+		//receipt := broadcastTx(t, client, tx)
+		receipt, err := broadcastTxAndWaitForBlock(t, client, wsc, tx)
+		assert.NoError(t, err)
+		if receipt.CreatesContract > 0 {
+			t.Fatal("This tx does not create a contract")
+		}
+		if len(receipt.TxHash) == 0 {
+			t.Fatal("Failed to compute tx hash")
+		}
+		n, errp := new(int), new(error)
+		buf := new(bytes.Buffer)
+		hasher := ripemd160.New()
+		tx.WriteSignBytes(chainID, buf, n, errp)
+		assert.NoError(t, *errp)
+		txSignBytes := buf.Bytes()
+		hasher.Write(txSignBytes)
+		txHashExpected := hasher.Sum(nil)
+		if bytes.Compare(receipt.TxHash, txHashExpected) != 0 {
+			t.Fatalf("The receipt hash '%x' does not equal the ripemd160 hash of the "+
+				"transaction signed bytes calculated in the test: '%x'",
+				receipt.TxHash, txHashExpected)
+		}
+	})
+}
+
+func TestGetAccount(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping test in short mode.")
+	}
+	testWithAllClients(t, func(t *testing.T, clientName string, client rpcclient.Client) {
+		acc := getAccount(t, client, user[0].Address)
+		if acc == nil {
+			t.Fatal("Account was nil")
+		}
+		if bytes.Compare(acc.Address, user[0].Address) != 0 {
+			t.Fatalf("Failed to get correct account. Got %x, expected %x", acc.Address,
+				user[0].Address)
+		}
+	})
+}
+
+func TestGetStorage(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping test in short mode.")
+	}
+	wsc := newWSClient()
+	testWithAllClients(t, func(t *testing.T, clientName string, client rpcclient.Client) {
+		eid := txs.EventStringNewBlock()
+		subscribe(t, wsc, eid)
+		defer func() {
+			unsubscribe(t, wsc, eid)
+			wsc.Stop()
+		}()
+
+		amt, gasLim, fee := int64(1100), int64(1000), int64(1000)
+		code := []byte{0x60, 0x5, 0x60, 0x1, 0x55}
+		// Call with nil address will create a contract
+		tx := makeDefaultCallTx(t, client, nil, code, amt, gasLim, fee)
+		receipt, err := broadcastTxAndWaitForBlock(t, client, wsc, tx)
+		assert.NoError(t, err)
+		assert.Equal(t, uint8(1), receipt.CreatesContract, "This transaction should"+
+			" create a contract")
+		assert.NotEqual(t, 0, len(receipt.TxHash), "Receipt should contain a"+
+			" transaction hash")
+		contractAddr := receipt.ContractAddr
+		assert.NotEqual(t, 0, len(contractAddr), "Transactions claims to have"+
+			" created a contract but the contract address is empty")
+
+		v := getStorage(t, client, contractAddr, []byte{0x1})
+		got := tm_common.LeftPadWord256(v)
+		expected := tm_common.LeftPadWord256([]byte{0x5})
+		if got.Compare(expected) != 0 {
+			t.Fatalf("Wrong storage value. Got %x, expected %x", got.Bytes(),
+				expected.Bytes())
+		}
+	})
+}
+
+func TestCallCode(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping test in short mode.")
+	}
+
+	testWithAllClients(t, func(t *testing.T, clientName string, client rpcclient.Client) {
+		// add two integers and return the result
+		code := []byte{0x60, 0x5, 0x60, 0x6, 0x1, 0x60, 0x0, 0x52, 0x60, 0x20, 0x60,
+			0x0, 0xf3}
+		data := []byte{}
+		expected := []byte{0xb}
+		callCode(t, client, user[0].PubKey.Address(), code, data, expected)
+
+		// pass two ints as calldata, add, and return the result
+		code = []byte{0x60, 0x0, 0x35, 0x60, 0x20, 0x35, 0x1, 0x60, 0x0, 0x52, 0x60,
+			0x20, 0x60, 0x0, 0xf3}
+		data = append(tm_common.LeftPadWord256([]byte{0x5}).Bytes(),
+			tm_common.LeftPadWord256([]byte{0x6}).Bytes()...)
+		expected = []byte{0xb}
+		callCode(t, client, user[0].PubKey.Address(), code, data, expected)
+	})
+}
+
+func TestCallContract(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping test in short mode.")
+	}
+	wsc := newWSClient()
+	testWithAllClients(t, func(t *testing.T, clientName string, client rpcclient.Client) {
+		eid := txs.EventStringNewBlock()
+		subscribe(t, wsc, eid)
+		defer func() {
+			unsubscribe(t, wsc, eid)
+			wsc.Stop()
+		}()
+
+		// create the contract
+		amt, gasLim, fee := int64(6969), int64(1000), int64(1000)
+		code, _, _ := simpleContract()
+		tx := makeDefaultCallTx(t, client, nil, code, amt, gasLim, fee)
+		receipt, err := broadcastTxAndWaitForBlock(t, client, wsc, tx)
+		assert.NoError(t, err)
+		if err != nil {
+			t.Fatalf("Problem broadcasting transaction: %v", err)
+		}
+		assert.Equal(t, uint8(1), receipt.CreatesContract, "This transaction should"+
+			" create a contract")
+		assert.NotEqual(t, 0, len(receipt.TxHash), "Receipt should contain a"+
+			" transaction hash")
+		contractAddr := receipt.ContractAddr
+		assert.NotEqual(t, 0, len(contractAddr), "Transactions claims to have"+
+			" created a contract but the contract address is empty")
+
+		// run a call through the contract
+		data := []byte{}
+		expected := []byte{0xb}
+		callContract(t, client, user[0].PubKey.Address(), contractAddr, data, expected)
+	})
+}
+
+func TestNameReg(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping test in short mode.")
+	}
+	wsc := newWSClient()
+	testWithAllClients(t, func(t *testing.T, clientName string, client rpcclient.Client) {
+
+		txs.MinNameRegistrationPeriod = 1
+
+		// register a new name, check if its there
+		// since entries ought to be unique and these run against different clients, we append the client
+		name := "ye_old_domain_name_" + clientName
+		const data = "if not now, when"
+		fee := int64(1000)
+		numDesiredBlocks := int64(2)
+		amt := fee + numDesiredBlocks*txs.NameByteCostMultiplier*txs.NameBlockCostMultiplier*txs.NameBaseCost(name, data)
+
+		tx := makeDefaultNameTx(t, client, name, data, amt, fee)
+		// verify the name by both using the event and by checking get_name
+		subscribeAndWaitForNext(t, wsc, txs.EventStringNameReg(name),
+			func() {
+				broadcastTxAndWaitForBlock(t, client, wsc, tx)
+			},
+			func(eid string, eventData txs.EventData) (bool, error) {
+				eventDataTx := asEventDataTx(t, eventData)
+				tx, ok := eventDataTx.Tx.(*txs.NameTx)
+				if !ok {
+					t.Fatalf("Could not convert %v to *NameTx", eventDataTx)
+				}
+				assert.Equal(t, name, tx.Name)
+				assert.Equal(t, data, tx.Data)
+				return true, nil
+			})
+		mempoolCount = 0
+
+		entry := getNameRegEntry(t, client, name)
+		assert.Equal(t, data, entry.Data)
+		assert.Equal(t, user[0].Address, entry.Owner)
+
+		// update the data as the owner, make sure still there
+		numDesiredBlocks = int64(5)
+		const updatedData = "these are amongst the things I wish to bestow upon " +
+			"the youth of generations come: a safe supply of honey, and a better " +
+			"money. For what else shall they need"
+		amt = fee + numDesiredBlocks*txs.NameByteCostMultiplier*
+			txs.NameBlockCostMultiplier*txs.NameBaseCost(name, updatedData)
+		tx = makeDefaultNameTx(t, client, name, updatedData, amt, fee)
+		broadcastTxAndWaitForBlock(t, client, wsc, tx)
+		mempoolCount = 0
+		entry = getNameRegEntry(t, client, name)
+
+		assert.Equal(t, updatedData, entry.Data)
+
+		// try to update as non owner, should fail
+		tx = txs.NewNameTxWithNonce(user[1].PubKey, name, "never mind", amt, fee,
+			getNonce(t, client, user[1].Address)+1)
+		tx.Sign(chainID, user[1])
+
+		_, err := broadcastTxAndWaitForBlock(t, client, wsc, tx)
+		assert.Error(t, err, "Expected error when updating someone else's unexpired"+
+			" name registry entry")
+		if err != nil {
+			assert.Contains(t, err.Error(), "permission denied", "Error should be "+
+				"permission denied")
+		}
+
+		// Wait a couple of blocks to make sure name registration expires
+		waitNBlocks(t, wsc, 3)
+
+		//now the entry should be expired, so we can update as non owner
+		const data2 = "this is not my beautiful house"
+		tx = txs.NewNameTxWithNonce(user[1].PubKey, name, data2, amt, fee,
+			getNonce(t, client, user[1].Address)+1)
+		tx.Sign(chainID, user[1])
+		_, err = broadcastTxAndWaitForBlock(t, client, wsc, tx)
+		assert.NoError(t, err, "Should be able to update a previously expired name"+
+			" registry entry as a different address")
+		mempoolCount = 0
+		entry = getNameRegEntry(t, client, name)
+		assert.Equal(t, data2, entry.Data)
+		assert.Equal(t, user[1].Address, entry.Owner)
+	})
+}
+
+func TestBlockchainInfo(t *testing.T) {
+	wsc := newWSClient()
+	testWithAllClients(t, func(t *testing.T, clientName string, client rpcclient.Client) {
+		nBlocks := 4
+		waitNBlocks(t, wsc, nBlocks)
+
+		resp, err := edbcli.BlockchainInfo(client, 0, 0)
+		if err != nil {
+			t.Fatalf("Failed to get blockchain info: %v", err)
+		}
+		//TODO: [Silas] reintroduce this when Tendermint changes logic to fire
+		// NewBlock after saving a block
+		// see https://github.com/tendermint/tendermint/issues/273
+		//assert.Equal(t, 4, resp.LastHeight, "Last height should be 4 after waiting for first 4 blocks")
+		assert.True(t, nBlocks <= len(resp.BlockMetas),
+			"Should see at least 4 BlockMetas after waiting for first 4 blocks")
+
+		lastBlockHash := resp.BlockMetas[nBlocks-1].Hash
+		for i := nBlocks - 2; i >= 0; i-- {
+			assert.Equal(t, lastBlockHash, resp.BlockMetas[i].Header.LastBlockHash,
+				"Blockchain should be a hash tree!")
+			lastBlockHash = resp.BlockMetas[i].Hash
+		}
+
+		resp, err = edbcli.BlockchainInfo(client, 1, 2)
+		assert.NoError(t, err)
+		assert.Equal(t, 2, len(resp.BlockMetas),
+			"Should see 2 BlockMetas after extracting 2 blocks")
+	})
+}
+
+func TestListUnconfirmedTxs(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping test in short mode.")
+	}
+	wsc := newWSClient()
+	testWithAllClients(t, func(t *testing.T, clientName string, client rpcclient.Client) {
+		amt, gasLim, fee := int64(1100), int64(1000), int64(1000)
+		code := []byte{0x60, 0x5, 0x60, 0x1, 0x55}
+		// Call with nil address will create a contract
+		tx := makeDefaultCallTx(t, client, []byte{}, code, amt, gasLim, fee)
+		txChan := make(chan []txs.Tx)
+
+		// We want to catch the Tx in mempool before it gets reaped by tendermint
+		// consensus. We should be able to do this almost always if we broadcast our
+		// transaction immediately after a block has been committed. There is about
+		// 1 second between blocks, and we will have the lock on Reap
+		// So we wait for a block here
+		waitNBlocks(t, wsc, 1)
+
+		go func() {
+			for {
+				resp, err := edbcli.ListUnconfirmedTxs(client)
+				assert.NoError(t, err)
+				if resp.N > 0 {
+					txChan <- resp.Txs
+				}
+			}
+		}()
+
+		runThenWaitForBlock(t, wsc, nextBlockPredicateFn(), func() {
+			broadcastTx(t, client, tx)
+			select {
+			case <-time.After(time.Second * timeoutSeconds):
+				t.Fatal("Timeout out waiting for unconfirmed transactions to appear")
+			case transactions := <-txChan:
+				assert.Len(t, transactions, 1,
+					"There should only be a single transaction in the mempool during "+
+						"this test (previous txs should have made it into a block)")
+				assert.Contains(t, transactions, tx,
+					"Transaction should be returned by ListUnconfirmedTxs")
+			}
+		})
+	})
+}
+
+func TestGetBlock(t *testing.T) {
+	wsc := newWSClient()
+	testWithAllClients(t, func(t *testing.T, clientName string, client rpcclient.Client) {
+		waitNBlocks(t, wsc, 3)
+		resp, err := edbcli.GetBlock(client, 2)
+		assert.NoError(t, err)
+		assert.Equal(t, 2, resp.Block.Height)
+		assert.Equal(t, 2, resp.BlockMeta.Header.Height)
+	})
+}
+
+func TestListValidators(t *testing.T) {
+	wsc := newWSClient()
+	testWithAllClients(t, func(t *testing.T, clientName string, client rpcclient.Client) {
+		waitNBlocks(t, wsc, 3)
+		resp, err := edbcli.ListValidators(client)
+		assert.NoError(t, err)
+		assert.Len(t, resp.BondedValidators, 1)
+		validator := resp.BondedValidators[0].(*consensus_types.TendermintValidator)
+		assert.Equal(t, genesisDoc.Validators[0].PubKey, validator.PubKey)
+	})
+}
+
+func TestDumpConsensusState(t *testing.T) {
+	wsc := newWSClient()
+	testWithAllClients(t, func(t *testing.T, clientName string, client rpcclient.Client) {
+		waitNBlocks(t, wsc, 3)
+		resp, err := edbcli.DumpConsensusState(client)
+		assert.NoError(t, err)
+		startTime := resp.ConsensusState.StartTime
+		// TODO: uncomment lines involving commitTime when
+		// https://github.com/tendermint/tendermint/issues/277 is fixed in Tendermint
+		//commitTime := resp.ConsensusState.CommitTime
+		assert.NotZero(t, startTime)
+		//assert.NotZero(t, commitTime)
+		//assert.True(t, commitTime.Unix() > startTime.Unix(),
+		//	"Commit time %v should be later than start time %v", commitTime, startTime)
+		assert.Equal(t, uint8(1), resp.ConsensusState.Step)
+	})
+}
+
+func asEventDataTx(t *testing.T, eventData txs.EventData) txs.EventDataTx {
+	eventDataTx, ok := eventData.(txs.EventDataTx)
+	if !ok {
+		t.Fatalf("Expected eventData to be EventDataTx was %v", eventData)
+	}
+	return eventDataTx
+}
diff --git a/rpc/tendermint/test/shared.go b/rpc/tendermint/test/shared.go
index d705d27857ecc5db7223f5ecddf5cb3d31a91c5b..16dbf7abaf869e0cbc54460657ff7f078b8b6bc0 100644
--- a/rpc/tendermint/test/shared.go
+++ b/rpc/tendermint/test/shared.go
@@ -2,6 +2,7 @@ package test
 
 import (
 	"bytes"
+	"hash/fnv"
 	"strconv"
 	"testing"
 
@@ -20,6 +21,7 @@ import (
 
 	"path"
 
+	state_types "github.com/eris-ltd/eris-db/manager/eris-mint/state/types"
 	"github.com/spf13/viper"
 	tm_common "github.com/tendermint/go-common"
 	"github.com/tendermint/tendermint/types"
@@ -32,12 +34,13 @@ var (
 	mempoolCount      = 0
 	chainID           string
 	websocketAddr     string
+	genesisDoc        *state_types.GenesisDoc
 	websocketEndpoint string
-
-	user    = makeUsers(5) // make keys
-	clients map[string]rpcclient.Client
-
-	testCore *core.Core
+	user              = makeUsers(5) // make keys
+	jsonRpcClient     rpcclient.Client
+	httpClient        rpcclient.Client
+	clients           map[string]rpcclient.Client
+	testCore          *core.Core
 )
 
 // initialize config and create new node
@@ -46,6 +49,7 @@ func initGlobalVariables(ffs *fixtures.FileFixtures) error {
 	rootWorkDir = ffs.AddDir("rootWorkDir")
 	rootDataDir := ffs.AddDir("rootDataDir")
 	genesisFile := ffs.AddFile("rootWorkDir/genesis.json", defaultGenesis)
+	genesisDoc = state_types.GenesisDocFromJSON([]byte(defaultGenesis))
 
 	if ffs.Error != nil {
 		return ffs.Error
@@ -85,9 +89,12 @@ func initGlobalVariables(ffs *fixtures.FileFixtures) error {
 		return err
 	}
 
+	jsonRpcClient = rpcclient.NewClientJSONRPC(rpcAddr)
+	httpClient = rpcclient.NewClientURI(rpcAddr)
+
 	clients = map[string]rpcclient.Client{
-		"JSONRPC": rpcclient.NewClientURI(rpcAddr),
-		"HTTP":    rpcclient.NewClientJSONRPC(rpcAddr),
+		"JSONRPC": jsonRpcClient,
+		"HTTP":    httpClient,
 	}
 	return nil
 }
@@ -125,34 +132,34 @@ func saveNewPriv() {
 //-------------------------------------------------------------------------------
 // some default transaction functions
 
-func makeDefaultSendTx(t *testing.T, typ string, addr []byte,
+func makeDefaultSendTx(t *testing.T, client rpcclient.Client, addr []byte,
 	amt int64) *txs.SendTx {
-	nonce := getNonce(t, typ, user[0].Address)
+	nonce := getNonce(t, client, user[0].Address)
 	tx := txs.NewSendTx()
 	tx.AddInputWithNonce(user[0].PubKey, amt, nonce+1)
 	tx.AddOutput(addr, amt)
 	return tx
 }
 
-func makeDefaultSendTxSigned(t *testing.T, typ string, addr []byte,
+func makeDefaultSendTxSigned(t *testing.T, client rpcclient.Client, addr []byte,
 	amt int64) *txs.SendTx {
-	tx := makeDefaultSendTx(t, typ, addr, amt)
+	tx := makeDefaultSendTx(t, client, addr, amt)
 	tx.SignInput(chainID, 0, user[0])
 	return tx
 }
 
-func makeDefaultCallTx(t *testing.T, typ string, addr, code []byte, amt, gasLim,
+func makeDefaultCallTx(t *testing.T, client rpcclient.Client, addr, code []byte, amt, gasLim,
 	fee int64) *txs.CallTx {
-	nonce := getNonce(t, typ, user[0].Address)
+	nonce := getNonce(t, client, user[0].Address)
 	tx := txs.NewCallTxWithNonce(user[0].PubKey, addr, code, amt, gasLim, fee,
 		nonce+1)
 	tx.Sign(chainID, user[0])
 	return tx
 }
 
-func makeDefaultNameTx(t *testing.T, typ string, name, value string, amt,
+func makeDefaultNameTx(t *testing.T, client rpcclient.Client, name, value string, amt,
 	fee int64) *txs.NameTx {
-	nonce := getNonce(t, typ, user[0].Address)
+	nonce := getNonce(t, client, user[0].Address)
 	tx := txs.NewNameTxWithNonce(user[0].PubKey, name, value, amt, fee, nonce+1)
 	tx.Sign(chainID, user[0])
 	return tx
@@ -162,8 +169,7 @@ func makeDefaultNameTx(t *testing.T, typ string, name, value string, amt,
 // rpc call wrappers (fail on err)
 
 // get an account's nonce
-func getNonce(t *testing.T, typ string, addr []byte) int {
-	client := clients[typ]
+func getNonce(t *testing.T, client rpcclient.Client, addr []byte) int {
 	ac, err := edbcli.GetAccount(client, addr)
 	if err != nil {
 		t.Fatal(err)
@@ -175,8 +181,7 @@ func getNonce(t *testing.T, typ string, addr []byte) int {
 }
 
 // get the account
-func getAccount(t *testing.T, typ string, addr []byte) *acm.Account {
-	client := clients[typ]
+func getAccount(t *testing.T, client rpcclient.Client, addr []byte) *acm.Account {
 	ac, err := edbcli.GetAccount(client, addr)
 	if err != nil {
 		t.Fatal(err)
@@ -185,9 +190,8 @@ func getAccount(t *testing.T, typ string, addr []byte) *acm.Account {
 }
 
 // sign transaction
-func signTx(t *testing.T, typ string, tx txs.Tx,
+func signTx(t *testing.T, client rpcclient.Client, tx txs.Tx,
 	privAcc *acm.PrivAccount) txs.Tx {
-	client := clients[typ]
 	signedTx, err := edbcli.SignTx(client, tx, []*acm.PrivAccount{privAcc})
 	if err != nil {
 		t.Fatal(err)
@@ -196,8 +200,7 @@ func signTx(t *testing.T, typ string, tx txs.Tx,
 }
 
 // broadcast transaction
-func broadcastTx(t *testing.T, typ string, tx txs.Tx) txs.Receipt {
-	client := clients[typ]
+func broadcastTx(t *testing.T, client rpcclient.Client, tx txs.Tx) txs.Receipt {
 	rec, err := edbcli.BroadcastTx(client, tx)
 	if err != nil {
 		t.Fatal(err)
@@ -216,8 +219,7 @@ func dumpStorage(t *testing.T, addr []byte) *rpc_types.ResultDumpStorage {
 	return resp
 }
 
-func getStorage(t *testing.T, typ string, addr, key []byte) []byte {
-	client := clients[typ]
+func getStorage(t *testing.T, client rpcclient.Client, addr, key []byte) []byte {
 	resp, err := edbcli.GetStorage(client, addr, key)
 	if err != nil {
 		t.Fatal(err)
@@ -252,8 +254,7 @@ func callContract(t *testing.T, client rpcclient.Client, fromAddress, toAddress,
 }
 
 // get the namereg entry
-func getNameRegEntry(t *testing.T, typ string, name string) *core_types.NameRegEntry {
-	client := clients[typ]
+func getNameRegEntry(t *testing.T, client rpcclient.Client, name string) *core_types.NameRegEntry {
 	entry, err := edbcli.GetName(client, name)
 	if err != nil {
 		t.Fatal(err)
@@ -261,29 +262,21 @@ func getNameRegEntry(t *testing.T, typ string, name string) *core_types.NameRegE
 	return entry
 }
 
-//--------------------------------------------------------------------------------
-// utility verification function
-
-func checkTx(t *testing.T, fromAddr []byte, priv *acm.PrivAccount,
-	tx *txs.SendTx) {
-	if bytes.Compare(tx.Inputs[0].Address, fromAddr) != 0 {
-		t.Fatal("Tx input addresses don't match!")
-	}
-
-	signBytes := acm.SignBytes(chainID, tx)
-	in := tx.Inputs[0] //(*types.SendTx).Inputs[0]
-
-	if err := in.ValidateBasic(); err != nil {
-		t.Fatal(err)
-	}
-	// Check signatures
-	// acc := getAccount(t, byteAddr)
-	// NOTE: using the acc here instead of the in fails; it is nil.
-	if !in.PubKey.VerifyBytes(signBytes, in.Signature) {
-		t.Fatal(txs.ErrTxInvalidSignature)
+// Returns a positive int64 hash of text (consumers want int64 instead of uint64)
+func hashString(text string) int64 {
+	hasher := fnv.New64()
+	hasher.Write([]byte(text))
+	value := int64(hasher.Sum64())
+	// Flip the sign if we wrapped
+	if value < 0 {
+		return -value
 	}
+	return value
 }
 
+//--------------------------------------------------------------------------------
+// utility verification function
+
 // simple contract returns 5 + 6 = 0xb
 func simpleContract() ([]byte, []byte, []byte) {
 	// this is the code we want to run when the contract is called
diff --git a/rpc/tendermint/test/tests.go b/rpc/tendermint/test/tests.go
deleted file mode 100644
index 43769b4b0f6f972c151b41c35ed2269ab9ad7a40..0000000000000000000000000000000000000000
--- a/rpc/tendermint/test/tests.go
+++ /dev/null
@@ -1,342 +0,0 @@
-package test
-
-import (
-	"bytes"
-	"fmt"
-	"testing"
-
-	edbcli "github.com/eris-ltd/eris-db/rpc/tendermint/client"
-	core_types "github.com/eris-ltd/eris-db/rpc/tendermint/core/types"
-	"github.com/eris-ltd/eris-db/txs"
-	"github.com/stretchr/testify/assert"
-
-	"time"
-
-	tm_common "github.com/tendermint/go-common"
-	"golang.org/x/crypto/ripemd160"
-)
-
-func testStatus(t *testing.T, typ string) {
-	client := clients[typ]
-	resp, err := edbcli.Status(client)
-	if err != nil {
-		t.Fatal(err)
-	}
-	fmt.Println(resp)
-	if resp.NodeInfo.Network != chainID {
-		t.Fatal(fmt.Errorf("ChainID mismatch: got %s expected %s",
-			resp.NodeInfo.Network, chainID))
-	}
-}
-
-func testGetAccount(t *testing.T, typ string) {
-	acc := getAccount(t, typ, user[0].Address)
-	if acc == nil {
-		t.Fatal("Account was nil")
-	}
-	if bytes.Compare(acc.Address, user[0].Address) != 0 {
-		t.Fatalf("Failed to get correct account. Got %x, expected %x", acc.Address, user[0].Address)
-	}
-}
-
-func testOneSignTx(t *testing.T, typ string, addr []byte, amt int64) {
-	tx := makeDefaultSendTx(t, typ, addr, amt)
-	tx2 := signTx(t, typ, tx, user[0])
-	tx2hash := txs.TxHash(chainID, tx2)
-	tx.SignInput(chainID, 0, user[0])
-	txhash := txs.TxHash(chainID, tx)
-	if bytes.Compare(txhash, tx2hash) != 0 {
-		t.Fatal("Got different signatures for signing via rpc vs tx_utils")
-	}
-
-	tx_ := signTx(t, typ, tx, user[0])
-	tx = tx_.(*txs.SendTx)
-	checkTx(t, user[0].Address, user[0], tx)
-}
-
-func testBroadcastTx(t *testing.T, typ string) {
-	amt := int64(100)
-	toAddr := user[1].Address
-	tx := makeDefaultSendTxSigned(t, typ, toAddr, amt)
-	receipt := broadcastTx(t, typ, tx)
-	if receipt.CreatesContract > 0 {
-		t.Fatal("This tx does not create a contract")
-	}
-	if len(receipt.TxHash) == 0 {
-		t.Fatal("Failed to compute tx hash")
-	}
-	n, err := new(int), new(error)
-	buf := new(bytes.Buffer)
-	hasher := ripemd160.New()
-	tx.WriteSignBytes(chainID, buf, n, err)
-	// [Silas] Currently tx.TxHash uses go-wire, we we drop that we can drop the prefix here
-	goWireBytes := append([]byte{0x01, 0xcf}, buf.Bytes()...)
-	hasher.Write(goWireBytes)
-	txHashExpected := hasher.Sum(nil)
-	if bytes.Compare(receipt.TxHash, txHashExpected) != 0 {
-		t.Fatalf("The receipt hash '%x' does not equal the ripemd160 hash of the "+
-			"transaction signed bytes calculated in the test: '%x'",
-			receipt.TxHash, txHashExpected)
-	}
-}
-
-func testGetStorage(t *testing.T, typ string) {
-	wsc := newWSClient(t)
-	eid := txs.EventStringNewBlock()
-	subscribe(t, wsc, eid)
-	defer func() {
-		unsubscribe(t, wsc, eid)
-		wsc.Stop()
-	}()
-
-	amt, gasLim, fee := int64(1100), int64(1000), int64(1000)
-	code := []byte{0x60, 0x5, 0x60, 0x1, 0x55}
-	// Call with nil address will create a contract
-	tx := makeDefaultCallTx(t, typ, nil, code, amt, gasLim, fee)
-	receipt, err := broadcastTxAndWaitForBlock(t, typ, wsc, tx)
-	if err != nil {
-		t.Fatalf("Problem broadcasting transaction: %v", err)
-	}
-	assert.Equal(t, uint8(1), receipt.CreatesContract, "This transaction should"+
-		" create a contract")
-	assert.NotEqual(t, 0, len(receipt.TxHash), "Receipt should contain a"+
-		" transaction hash")
-	contractAddr := receipt.ContractAddr
-	assert.NotEqual(t, 0, len(contractAddr), "Transactions claims to have"+
-		" created a contract but the contract address is empty")
-
-	v := getStorage(t, typ, contractAddr, []byte{0x1})
-	got := tm_common.LeftPadWord256(v)
-	expected := tm_common.LeftPadWord256([]byte{0x5})
-	if got.Compare(expected) != 0 {
-		t.Fatalf("Wrong storage value. Got %x, expected %x", got.Bytes(),
-			expected.Bytes())
-	}
-}
-
-func testCallCode(t *testing.T, typ string) {
-	client := clients[typ]
-
-	// add two integers and return the result
-	code := []byte{0x60, 0x5, 0x60, 0x6, 0x1, 0x60, 0x0, 0x52, 0x60, 0x20, 0x60,
-		0x0, 0xf3}
-	data := []byte{}
-	expected := []byte{0xb}
-	callCode(t, client, user[0].PubKey.Address(), code, data, expected)
-
-	// pass two ints as calldata, add, and return the result
-	code = []byte{0x60, 0x0, 0x35, 0x60, 0x20, 0x35, 0x1, 0x60, 0x0, 0x52, 0x60,
-		0x20, 0x60, 0x0, 0xf3}
-	data = append(tm_common.LeftPadWord256([]byte{0x5}).Bytes(),
-		tm_common.LeftPadWord256([]byte{0x6}).Bytes()...)
-	expected = []byte{0xb}
-	callCode(t, client, user[0].PubKey.Address(), code, data, expected)
-}
-
-func testCall(t *testing.T, typ string) {
-	wsc := newWSClient(t)
-	eid := txs.EventStringNewBlock()
-	subscribe(t, wsc, eid)
-	defer func() {
-		unsubscribe(t, wsc, eid)
-		wsc.Stop()
-	}()
-
-	client := clients[typ]
-
-	// create the contract
-	amt, gasLim, fee := int64(6969), int64(1000), int64(1000)
-	code, _, _ := simpleContract()
-	tx := makeDefaultCallTx(t, typ, nil, code, amt, gasLim, fee)
-	receipt, err := broadcastTxAndWaitForBlock(t, typ, wsc, tx)
-	if err != nil {
-		t.Fatalf("Problem broadcasting transaction: %v", err)
-	}
-	assert.Equal(t, uint8(1), receipt.CreatesContract, "This transaction should"+
-		" create a contract")
-	assert.NotEqual(t, 0, len(receipt.TxHash), "Receipt should contain a"+
-		" transaction hash")
-	contractAddr := receipt.ContractAddr
-	assert.NotEqual(t, 0, len(contractAddr), "Transactions claims to have"+
-		" created a contract but the contract address is empty")
-
-	// run a call through the contract
-	data := []byte{}
-	expected := []byte{0xb}
-	callContract(t, client, user[0].PubKey.Address(), contractAddr, data, expected)
-}
-
-func testNameReg(t *testing.T, typ string) {
-	wsc := newWSClient(t)
-
-	txs.MinNameRegistrationPeriod = 1
-
-	// register a new name, check if its there
-	// since entries ought to be unique and these run against different clients, we append the typ
-	name := "ye_old_domain_name_" + typ
-	const data = "if not now, when"
-	fee := int64(1000)
-	numDesiredBlocks := int64(2)
-	amt := fee + numDesiredBlocks*txs.NameByteCostMultiplier*txs.NameBlockCostMultiplier*txs.NameBaseCost(name, data)
-
-	tx := makeDefaultNameTx(t, typ, name, data, amt, fee)
-	// verify the name by both using the event and by checking get_name
-	subscribeAndWaitForNext(t, wsc, txs.EventStringNameReg(name),
-		func() {
-			broadcastTxAndWaitForBlock(t, typ, wsc, tx)
-		},
-		func(eid string, eventData txs.EventData) (bool, error) {
-			eventDataTx := asEventDataTx(t, eventData)
-			tx, ok := eventDataTx.Tx.(*txs.NameTx)
-			if !ok {
-				t.Fatalf("Could not convert %v to *NameTx", eventDataTx)
-			}
-			assert.Equal(t, name, tx.Name)
-			assert.Equal(t, data, tx.Data)
-			return true, nil
-		})
-	mempoolCount = 0
-
-	entry := getNameRegEntry(t, typ, name)
-	assert.Equal(t, data, entry.Data)
-	assert.Equal(t, user[0].Address, entry.Owner)
-
-	// update the data as the owner, make sure still there
-	numDesiredBlocks = int64(5)
-	const updatedData = "these are amongst the things I wish to bestow upon the youth of generations come: a safe supply of honey, and a better money. For what else shall they need"
-	amt = fee + numDesiredBlocks*txs.NameByteCostMultiplier*txs.NameBlockCostMultiplier*txs.NameBaseCost(name, updatedData)
-	tx = makeDefaultNameTx(t, typ, name, updatedData, amt, fee)
-	broadcastTxAndWaitForBlock(t, typ, wsc, tx)
-	mempoolCount = 0
-	entry = getNameRegEntry(t, typ, name)
-
-	assert.Equal(t, updatedData, entry.Data)
-
-	// try to update as non owner, should fail
-	tx = txs.NewNameTxWithNonce(user[1].PubKey, name, "never mind", amt, fee,
-		getNonce(t, typ, user[1].Address)+1)
-	tx.Sign(chainID, user[1])
-
-	_, err := broadcastTxAndWaitForBlock(t, typ, wsc, tx)
-	assert.Error(t, err, "Expected error when updating someone else's unexpired"+
-		" name registry entry")
-	assert.Contains(t, err.Error(), "permission denied", "Error should be " +
-			"permission denied")
-
-	// Wait a couple of blocks to make sure name registration expires
-	waitNBlocks(t, wsc, 3)
-
-	//now the entry should be expired, so we can update as non owner
-	const data2 = "this is not my beautiful house"
-	tx = txs.NewNameTxWithNonce(user[1].PubKey, name, data2, amt, fee,
-		getNonce(t, typ, user[1].Address)+1)
-	tx.Sign(chainID, user[1])
-	_, err = broadcastTxAndWaitForBlock(t, typ, wsc, tx)
-	assert.NoError(t, err, "Should be able to update a previously expired name"+
-		" registry entry as a different address")
-	mempoolCount = 0
-	entry = getNameRegEntry(t, typ, name)
-	assert.Equal(t, data2, entry.Data)
-	assert.Equal(t, user[1].Address, entry.Owner)
-}
-
-// ------ Test Utils -------
-
-func asEventDataTx(t *testing.T, eventData txs.EventData) txs.EventDataTx {
-	eventDataTx, ok := eventData.(txs.EventDataTx)
-	if !ok {
-		t.Fatalf("Expected eventData to be EventDataTx was %v", eventData)
-	}
-	return eventDataTx
-}
-
-func doNothing(_ string, _ txs.EventData) (bool, error) {
-	// And ask waitForEvent to stop waiting
-	return true, nil
-}
-
-func testSubscribe(t *testing.T) {
-	var subId string
-	wsc := newWSClient(t)
-	subscribe(t, wsc, txs.EventStringNewBlock())
-
-	timeout := time.NewTimer(timeoutSeconds * time.Second)
-Subscribe:
-	for {
-		select {
-		case <-timeout.C:
-			t.Fatal("Timed out waiting for subscription result")
-
-		case bs := <-wsc.ResultsCh:
-			resultSubscribe, ok := readResult(t, bs).(*core_types.ResultSubscribe)
-			if ok {
-				assert.Equal(t, txs.EventStringNewBlock(), resultSubscribe.Event)
-				subId = resultSubscribe.SubscriptionId
-				break Subscribe
-			}
-		}
-	}
-
-	seenBlock := false
-	timeout = time.NewTimer(timeoutSeconds * time.Second)
-	for {
-		select {
-		case <-timeout.C:
-			if !seenBlock {
-				t.Fatal("Timed out without seeing a NewBlock event")
-			}
-			return
-
-		case bs := <-wsc.ResultsCh:
-			resultEvent, ok := readResult(t, bs).(*core_types.ResultEvent)
-			if ok {
-				_, ok := resultEvent.Data.(txs.EventDataNewBlock)
-				if ok {
-					if seenBlock {
-						// There's a mild race here, but when we enter we've just seen a block
-						// so we should be able to unsubscribe before we see another block
-						t.Fatal("Continued to see NewBlock event after unsubscribing")
-					} else {
-						seenBlock = true
-						unsubscribe(t, wsc, subId)
-					}
-				}
-			}
-		}
-	}
-}
-
-func testBlockchainInfo(t *testing.T, typ string) {
-	client := clients[typ]
-	wsc := newWSClient(t)
-	nBlocks := 4
-	waitNBlocks(t, wsc, nBlocks)
-
-	resp, err := edbcli.BlockchainInfo(client, 0, 0)
-	if err != nil {
-		t.Fatalf("Failed to get blockchain info: %v", err)
-	}
-	//TODO: [Silas] reintroduce this when Tendermint changes logic to fire
-	// NewBlock after saving a block
-	// see https://github.com/tendermint/tendermint/issues/273
-	//assert.Equal(t, 4, resp.LastHeight, "Last height should be 4 after waiting for first 4 blocks")
-	assert.True(t, nBlocks <= len(resp.BlockMetas),
-		"Should see at least 4 BlockMetas after waiting for first 4 blocks")
-
-	lastBlockHash := resp.BlockMetas[nBlocks-1].Hash
-	for i := nBlocks - 2; i >= 0; i-- {
-		assert.Equal(t, lastBlockHash, resp.BlockMetas[i].Header.LastBlockHash,
-			"Blockchain should be a hash tree!")
-		lastBlockHash = resp.BlockMetas[i].Hash
-	}
-
-	resp, err = edbcli.BlockchainInfo(client, 1, 2)
-	if err != nil {
-		t.Fatalf("Failed to get blockchain info: %v", err)
-	}
-
-	assert.Equal(t, 2, len(resp.BlockMetas),
-		"Should see 2 BlockMetas after extracting 2 blocks")
-
-	fmt.Printf("%v\n", resp)
-}
diff --git a/rpc/tendermint/test/client_ws_test.go b/rpc/tendermint/test/websocket_client_test.go
similarity index 70%
rename from rpc/tendermint/test/client_ws_test.go
rename to rpc/tendermint/test/websocket_client_test.go
index 76c61fde59a4bf39d5973a3981c14333f3433e37..60e665bdce2a2ecfdf4791deec6c75672446523c 100644
--- a/rpc/tendermint/test/client_ws_test.go
+++ b/rpc/tendermint/test/websocket_client_test.go
@@ -7,25 +7,26 @@ import (
 	"fmt"
 	"testing"
 
+	"time"
+
+	core_types "github.com/eris-ltd/eris-db/rpc/tendermint/core/types"
 	"github.com/eris-ltd/eris-db/txs"
 	"github.com/stretchr/testify/assert"
 	_ "github.com/tendermint/tendermint/config/tendermint_test"
 )
 
-var wsTyp = "JSONRPC"
-
 //--------------------------------------------------------------------------------
 // Test the websocket service
 
 // make a simple connection to the server
 func TestWSConnect(t *testing.T) {
-	wsc := newWSClient(t)
+	wsc := newWSClient()
 	wsc.Stop()
 }
 
 // receive a new block message
 func TestWSNewBlock(t *testing.T) {
-	wsc := newWSClient(t)
+	wsc := newWSClient()
 	eid := txs.EventStringNewBlock()
 	subId := subscribeAndGetSubscriptionId(t, wsc, eid)
 	defer func() {
@@ -44,7 +45,7 @@ func TestWSBlockchainGrowth(t *testing.T) {
 	if testing.Short() {
 		t.Skip("skipping test in short mode.")
 	}
-	wsc := newWSClient(t)
+	wsc := newWSClient()
 	eid := txs.EventStringNewBlock()
 	subId := subscribeAndGetSubscriptionId(t, wsc, eid)
 	defer func() {
@@ -77,10 +78,9 @@ func TestWSBlockchainGrowth(t *testing.T) {
 
 // send a transaction and validate the events from listening for both sender and receiver
 func TestWSSend(t *testing.T) {
+	wsc := newWSClient()
 	toAddr := user[1].Address
 	amt := int64(100)
-
-	wsc := newWSClient(t)
 	eidInput := txs.EventStringAccInput(user[0].Address)
 	eidOutput := txs.EventStringAccOutput(toAddr)
 	subIdInput := subscribeAndGetSubscriptionId(t, wsc, eidInput)
@@ -91,8 +91,8 @@ func TestWSSend(t *testing.T) {
 		wsc.Stop()
 	}()
 	waitForEvent(t, wsc, eidInput, func() {
-		tx := makeDefaultSendTxSigned(t, wsTyp, toAddr, amt)
-		broadcastTx(t, wsTyp, tx)
+		tx := makeDefaultSendTxSigned(t, jsonRpcClient, toAddr, amt)
+		broadcastTx(t, jsonRpcClient, tx)
 	}, unmarshalValidateSend(amt, toAddr))
 
 	waitForEvent(t, wsc, eidOutput, func() {},
@@ -104,7 +104,7 @@ func TestWSDoubleFire(t *testing.T) {
 	if testing.Short() {
 		t.Skip("skipping test in short mode.")
 	}
-	wsc := newWSClient(t)
+	wsc := newWSClient()
 	eid := txs.EventStringAccInput(user[0].Address)
 	subId := subscribeAndGetSubscriptionId(t, wsc, eid)
 	defer func() {
@@ -115,8 +115,8 @@ func TestWSDoubleFire(t *testing.T) {
 	toAddr := user[1].Address
 	// broadcast the transaction, wait to hear about it
 	waitForEvent(t, wsc, eid, func() {
-		tx := makeDefaultSendTxSigned(t, wsTyp, toAddr, amt)
-		broadcastTx(t, wsTyp, tx)
+		tx := makeDefaultSendTxSigned(t, jsonRpcClient, toAddr, amt)
+		broadcastTx(t, jsonRpcClient, tx)
 	}, func(eid string, b txs.EventData) (bool, error) {
 		return true, nil
 	})
@@ -135,7 +135,7 @@ func TestWSCallWait(t *testing.T) {
 	if testing.Short() {
 		t.Skip("skipping test in short mode.")
 	}
-	wsc := newWSClient(t)
+	wsc := newWSClient()
 	eid1 := txs.EventStringAccInput(user[0].Address)
 	subId1 := subscribeAndGetSubscriptionId(t, wsc, eid1)
 	defer func() {
@@ -147,8 +147,8 @@ func TestWSCallWait(t *testing.T) {
 	var contractAddr []byte
 	// wait for the contract to be created
 	waitForEvent(t, wsc, eid1, func() {
-		tx := makeDefaultCallTx(t, wsTyp, nil, code, amt, gasLim, fee)
-		receipt := broadcastTx(t, wsTyp, tx)
+		tx := makeDefaultCallTx(t, jsonRpcClient, nil, code, amt, gasLim, fee)
+		receipt := broadcastTx(t, jsonRpcClient, tx)
 		contractAddr = receipt.ContractAddr
 	}, unmarshalValidateTx(amt, returnCode))
 
@@ -162,8 +162,8 @@ func TestWSCallWait(t *testing.T) {
 	// get the return value from a call
 	data := []byte{0x1}
 	waitForEvent(t, wsc, eid2, func() {
-		tx := makeDefaultCallTx(t, wsTyp, contractAddr, data, amt, gasLim, fee)
-		receipt := broadcastTx(t, wsTyp, tx)
+		tx := makeDefaultCallTx(t, jsonRpcClient, contractAddr, data, amt, gasLim, fee)
+		receipt := broadcastTx(t, jsonRpcClient, tx)
 		contractAddr = receipt.ContractAddr
 	}, unmarshalValidateTx(amt, returnVal))
 }
@@ -174,12 +174,12 @@ func TestWSCallNoWait(t *testing.T) {
 	if testing.Short() {
 		t.Skip("skipping test in short mode.")
 	}
-	wsc := newWSClient(t)
+	wsc := newWSClient()
 	amt, gasLim, fee := int64(10000), int64(1000), int64(1000)
 	code, _, returnVal := simpleContract()
 
-	tx := makeDefaultCallTx(t, wsTyp, nil, code, amt, gasLim, fee)
-	receipt := broadcastTx(t, wsTyp, tx)
+	tx := makeDefaultCallTx(t, jsonRpcClient, nil, code, amt, gasLim, fee)
+	receipt := broadcastTx(t, jsonRpcClient, tx)
 	contractAddr := receipt.ContractAddr
 
 	// susbscribe to the new contract
@@ -193,8 +193,8 @@ func TestWSCallNoWait(t *testing.T) {
 	// get the return value from a call
 	data := []byte{0x1}
 	waitForEvent(t, wsc, eid, func() {
-		tx := makeDefaultCallTx(t, wsTyp, contractAddr, data, amt, gasLim, fee)
-		broadcastTx(t, wsTyp, tx)
+		tx := makeDefaultCallTx(t, jsonRpcClient, contractAddr, data, amt, gasLim, fee)
+		broadcastTx(t, jsonRpcClient, tx)
 	}, unmarshalValidateTx(amt, returnVal))
 }
 
@@ -203,19 +203,19 @@ func TestWSCallCall(t *testing.T) {
 	if testing.Short() {
 		t.Skip("skipping test in short mode.")
 	}
-	wsc := newWSClient(t)
+	wsc := newWSClient()
 	amt, gasLim, fee := int64(10000), int64(1000), int64(1000)
 	code, _, returnVal := simpleContract()
 	txid := new([]byte)
 
 	// deploy the two contracts
-	tx := makeDefaultCallTx(t, wsTyp, nil, code, amt, gasLim, fee)
-	receipt := broadcastTx(t, wsTyp, tx)
+	tx := makeDefaultCallTx(t, jsonRpcClient, nil, code, amt, gasLim, fee)
+	receipt := broadcastTx(t, jsonRpcClient, tx)
 	contractAddr1 := receipt.ContractAddr
 
 	code, _, _ = simpleCallContract(contractAddr1)
-	tx = makeDefaultCallTx(t, wsTyp, nil, code, amt, gasLim, fee)
-	receipt = broadcastTx(t, wsTyp, tx)
+	tx = makeDefaultCallTx(t, jsonRpcClient, nil, code, amt, gasLim, fee)
+	receipt = broadcastTx(t, jsonRpcClient, tx)
 	contractAddr2 := receipt.ContractAddr
 
 	// subscribe to the new contracts
@@ -235,12 +235,59 @@ func TestWSCallCall(t *testing.T) {
 	})
 	// call it
 	waitForEvent(t, wsc, eid, func() {
-		tx := makeDefaultCallTx(t, wsTyp, contractAddr2, nil, amt, gasLim, fee)
-		broadcastTx(t, wsTyp, tx)
+		tx := makeDefaultCallTx(t, jsonRpcClient, contractAddr2, nil, amt, gasLim, fee)
+		broadcastTx(t, jsonRpcClient, tx)
 		*txid = txs.TxHash(chainID, tx)
 	}, unmarshalValidateCall(user[0].Address, returnVal, txid))
 }
 
 func TestSubscribe(t *testing.T) {
-	testSubscribe(t)
+	wsc := newWSClient()
+	var subId string
+	subscribe(t, wsc, txs.EventStringNewBlock())
+
+	timeout := time.NewTimer(timeoutSeconds * time.Second)
+Subscribe:
+	for {
+		select {
+		case <-timeout.C:
+			t.Fatal("Timed out waiting for subscription result")
+
+		case bs := <-wsc.ResultsCh:
+			resultSubscribe, ok := readResult(t, bs).(*core_types.ResultSubscribe)
+			if ok {
+				assert.Equal(t, txs.EventStringNewBlock(), resultSubscribe.Event)
+				subId = resultSubscribe.SubscriptionId
+				break Subscribe
+			}
+		}
+	}
+
+	seenBlock := false
+	timeout = time.NewTimer(timeoutSeconds * time.Second)
+	for {
+		select {
+		case <-timeout.C:
+			if !seenBlock {
+				t.Fatal("Timed out without seeing a NewBlock event")
+			}
+			return
+
+		case bs := <-wsc.ResultsCh:
+			resultEvent, ok := readResult(t, bs).(*core_types.ResultEvent)
+			if ok {
+				_, ok := resultEvent.Data.(txs.EventDataNewBlock)
+				if ok {
+					if seenBlock {
+						// There's a mild race here, but when we enter we've just seen a block
+						// so we should be able to unsubscribe before we see another block
+						t.Fatal("Continued to see NewBlock event after unsubscribing")
+					} else {
+						seenBlock = true
+						unsubscribe(t, wsc, subId)
+					}
+				}
+			}
+		}
+	}
 }
diff --git a/rpc/tendermint/test/ws_helpers.go b/rpc/tendermint/test/websocket_helpers.go
similarity index 68%
rename from rpc/tendermint/test/ws_helpers.go
rename to rpc/tendermint/test/websocket_helpers.go
index 1c71a72b812193f75004e8886e562b090c2f6d83..b5a7f79f002d54601677142adc8fd82d991df8ba 100644
--- a/rpc/tendermint/test/ws_helpers.go
+++ b/rpc/tendermint/test/websocket_helpers.go
@@ -2,20 +2,16 @@ package test
 
 import (
 	"bytes"
-	"encoding/json"
 	"fmt"
 	"testing"
 	"time"
 
 	ctypes "github.com/eris-ltd/eris-db/rpc/tendermint/core/types"
 	"github.com/eris-ltd/eris-db/txs"
-	"github.com/tendermint/tendermint/types"
 	tm_types "github.com/tendermint/tendermint/types"
 
 	edbcli "github.com/eris-ltd/eris-db/rpc/tendermint/client"
-	"github.com/tendermint/go-events"
-	client "github.com/tendermint/go-rpc/client"
-	rpctypes "github.com/tendermint/go-rpc/types"
+	rpcclient "github.com/tendermint/go-rpc/client"
 	"github.com/tendermint/go-wire"
 )
 
@@ -25,24 +21,25 @@ const (
 
 //--------------------------------------------------------------------------------
 // Utilities for testing the websocket service
+type blockPredicate func(block *tm_types.Block) bool
 
 // create a new connection
-func newWSClient(t *testing.T) *client.WSClient {
-	wsc := client.NewWSClient(websocketAddr, websocketEndpoint)
+func newWSClient() *rpcclient.WSClient {
+	wsc := rpcclient.NewWSClient(websocketAddr, websocketEndpoint)
 	if _, err := wsc.Start(); err != nil {
-		t.Fatal(err)
+		panic(err)
 	}
 	return wsc
 }
 
 // subscribe to an event
-func subscribe(t *testing.T, wsc *client.WSClient, eventId string) {
+func subscribe(t *testing.T, wsc *rpcclient.WSClient, eventId string) {
 	if err := wsc.Subscribe(eventId); err != nil {
 		t.Fatal(err)
 	}
 }
 
-func subscribeAndGetSubscriptionId(t *testing.T, wsc *client.WSClient,
+func subscribeAndGetSubscriptionId(t *testing.T, wsc *rpcclient.WSClient,
 	eventId string) string {
 	if err := wsc.Subscribe(eventId); err != nil {
 		t.Fatal(err)
@@ -63,40 +60,43 @@ func subscribeAndGetSubscriptionId(t *testing.T, wsc *client.WSClient,
 }
 
 // unsubscribe from an event
-func unsubscribe(t *testing.T, wsc *client.WSClient, subscriptionId string) {
+func unsubscribe(t *testing.T, wsc *rpcclient.WSClient, subscriptionId string) {
 	if err := wsc.Unsubscribe(subscriptionId); err != nil {
 		t.Fatal(err)
 	}
 }
 
 // broadcast transaction and wait for new block
-func broadcastTxAndWaitForBlock(t *testing.T, typ string, wsc *client.WSClient,
+func broadcastTxAndWaitForBlock(t *testing.T, client rpcclient.Client, wsc *rpcclient.WSClient,
 	tx txs.Tx) (txs.Receipt, error) {
 	var rec txs.Receipt
 	var err error
-	initialHeight := -1
-	runThenWaitForBlock(t, wsc,
-		func(block *tm_types.Block) bool {
-			if initialHeight < 0 {
-				initialHeight = block.Height
-				return false
-			} else {
-				// TODO: [Silas] remove the + 1 here. It is a workaround for the fact
-				// that tendermint fires the NewBlock event before it has finalised its
-				// state updates, so we have to wait for the block after the block we
-				// want in order for the Tx to be genuinely final.
-				// This should be addressed by: https://github.com/tendermint/tendermint/pull/265
-				return block.Height > initialHeight + 1
-			}
-		},
+	runThenWaitForBlock(t, wsc, nextBlockPredicateFn(),
 		func() {
-			rec, err = edbcli.BroadcastTx(clients[typ], tx)
+			rec, err = edbcli.BroadcastTx(client, tx)
 			mempoolCount += 1
 		})
 	return rec, err
 }
 
-func waitNBlocks(t *testing.T, wsc *client.WSClient, n int) {
+func nextBlockPredicateFn() blockPredicate {
+	initialHeight := -1
+	return func(block *tm_types.Block) bool {
+		if initialHeight <= 0 {
+			initialHeight = block.Height
+			return false
+		} else {
+			// TODO: [Silas] remove the + 1 here. It is a workaround for the fact
+			// that tendermint fires the NewBlock event before it has finalised its
+			// state updates, so we have to wait for the block after the block we
+			// want in order for the Tx to be genuinely final.
+			// This should be addressed by: https://github.com/tendermint/tendermint/pull/265
+			return block.Height > initialHeight+1
+		}
+	}
+}
+
+func waitNBlocks(t *testing.T, wsc *rpcclient.WSClient, n int) {
 	i := 0
 	runThenWaitForBlock(t, wsc,
 		func(block *tm_types.Block) bool {
@@ -106,16 +106,16 @@ func waitNBlocks(t *testing.T, wsc *client.WSClient, n int) {
 		func() {})
 }
 
-func runThenWaitForBlock(t *testing.T, wsc *client.WSClient,
-	blockPredicate func(*tm_types.Block) bool, runner func()) {
+func runThenWaitForBlock(t *testing.T, wsc *rpcclient.WSClient,
+	predicate blockPredicate, runner func()) {
 	subscribeAndWaitForNext(t, wsc, txs.EventStringNewBlock(),
 		runner,
 		func(event string, eventData txs.EventData) (bool, error) {
-			return blockPredicate(eventData.(txs.EventDataNewBlock).Block), nil
+			return predicate(eventData.(txs.EventDataNewBlock).Block), nil
 		})
 }
 
-func subscribeAndWaitForNext(t *testing.T, wsc *client.WSClient, event string,
+func subscribeAndWaitForNext(t *testing.T, wsc *rpcclient.WSClient, event string,
 	runner func(),
 	eventDataChecker func(string, txs.EventData) (bool, error)) {
 	subId := subscribeAndGetSubscriptionId(t, wsc, event)
@@ -134,7 +134,7 @@ func subscribeAndWaitForNext(t *testing.T, wsc *client.WSClient, event string,
 // stopWaiting is true waitForEvent will return or if stopWaiting is false
 // waitForEvent will keep listening for new events. If an error is returned
 // waitForEvent will fail the test.
-func waitForEvent(t *testing.T, wsc *client.WSClient, eventid string,
+func waitForEvent(t *testing.T, wsc *rpcclient.WSClient, eventid string,
 	runner func(),
 	eventDataChecker func(string, txs.EventData) (bool, error)) waitForEventResult {
 
@@ -207,45 +207,8 @@ func (err waitForEventResult) Timeout() bool {
 	return err.timeout
 }
 
-func acceptFirstBlock(_ *tm_types.Block) bool {
-	return true
-}
-
 //--------------------------------------------------------------------------------
 
-func unmarshalResponseNewBlock(b []byte) (*types.Block, error) {
-	// unmarshall and assert somethings
-	var response rpctypes.RPCResponse
-	var err error
-	wire.ReadJSON(&response, b, &err)
-	if err != nil {
-		return nil, err
-	}
-	if response.Error != "" {
-		return nil, fmt.Errorf(response.Error)
-	}
-	// TODO
-	//block := response.Result.(*ctypes.ResultEvent).Data.(types.EventDataNewBlock).Block
-	// return block, nil
-	return nil, nil
-}
-
-func unmarshalResponseNameReg(b []byte) (*txs.NameTx, error) {
-	// unmarshall and assert somethings
-	var response rpctypes.RPCResponse
-	var err error
-	wire.ReadJSON(&response, b, &err)
-	if err != nil {
-		return nil, err
-	}
-	if response.Error != "" {
-		return nil, fmt.Errorf(response.Error)
-	}
-	_, val := UnmarshalEvent(*response.Result)
-	tx := txs.DecodeTx(val.(types.EventDataTx).Tx).(*txs.NameTx)
-	return tx, nil
-}
-
 func unmarshalValidateSend(amt int64,
 	toAddr []byte) func(string, txs.EventData) (bool, error) {
 	return func(eid string, eventData txs.EventData) (bool, error) {
@@ -314,22 +277,6 @@ func unmarshalValidateCall(origin,
 	}
 }
 
-// Unmarshal a json event
-func UnmarshalEvent(b json.RawMessage) (string, events.EventData) {
-	var err error
-	result := new(ctypes.ErisDBResult)
-	wire.ReadJSONPtr(result, b, &err)
-	if err != nil {
-		panic(err)
-	}
-	event, ok := (*result).(*ctypes.ResultEvent)
-	if !ok {
-		return "", nil // TODO: handle non-event messages (ie. return from subscribe/unsubscribe)
-		// fmt.Errorf("Result is not type *ctypes.ResultEvent. Got %v", reflect.TypeOf(*result))
-	}
-	return event.Event, event.Data
-}
-
 func readResult(t *testing.T, bs []byte) ctypes.ErisDBResult {
 	var err error
 	result := new(ctypes.ErisDBResult)
diff --git a/rpc/v0/methods.go b/rpc/v0/methods.go
index b3aac0e9d5ea0a8a9d53dd18c283151d3e0900c8..a7bcf609ad334f1a6e160e752d1da35a3b28f247 100644
--- a/rpc/v0/methods.go
+++ b/rpc/v0/methods.go
@@ -256,17 +256,11 @@ func (erisDbMethods *ErisDbMethods) Block(request *rpc.RPCRequest, requester int
 // *************************************** Consensus ************************************
 
 func (erisDbMethods *ErisDbMethods) ConsensusState(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-	// TODO: [Silas] erisDbMethods has not implemented this since the refactor
-	// core_types.FromRoundState() will do it, but only if we have access to
-	// Tendermint's RonudState..
-	state := &core_types.ConsensusState{}
-	return state, 0, nil
+	return erisDbMethods.pipe.GetConsensusEngine().ConsensusState(), 0, nil
 }
 
 func (erisDbMethods *ErisDbMethods) Validators(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-	// TODO: [Silas] erisDbMethods has not implemented this since the refactor
-	validators := &core_types.ValidatorList{}
-	return validators, 0, nil
+	return erisDbMethods.pipe.GetConsensusEngine().ListValidators(), 0, nil
 }
 
 // *************************************** Net ************************************
@@ -420,11 +414,11 @@ func (erisDbMethods *ErisDbMethods) TransactNameReg(request *rpc.RPCRequest, req
 }
 
 func (erisDbMethods *ErisDbMethods) UnconfirmedTxs(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-	txs, errC := erisDbMethods.pipe.Transactor().UnconfirmedTxs()
+	trans, errC := erisDbMethods.pipe.GetConsensusEngine().ListUnconfirmedTxs(-1)
 	if errC != nil {
 		return nil, rpc.INTERNAL_ERROR, errC
 	}
-	return txs, 0, nil
+	return txs.UnconfirmedTxs{trans}, 0, nil
 }
 
 func (erisDbMethods *ErisDbMethods) SignTx(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
diff --git a/rpc/v0/restServer.go b/rpc/v0/restServer.go
index d6ad13bd29589c3ebbff44d86696446ace251dce..2c94bdfe708e1b30cd67be181c07879d5b57d574 100644
--- a/rpc/v0/restServer.go
+++ b/rpc/v0/restServer.go
@@ -221,17 +221,13 @@ func (restServer *RestServer) handleBlock(c *gin.Context) {
 
 // ********************************* Consensus *********************************
 func (restServer *RestServer) handleConsensusState(c *gin.Context) {
-	// TODO: [Silas] erisDbMethods has not implemented this since the refactor
-	// core_types.FromRoundState() will do it, but only if we have access to
-	// Tendermint's RonudState..
-	cs := &core_types.ConsensusState{}
+	cs := restServer.pipe.GetConsensusEngine().ConsensusState()
 	c.Writer.WriteHeader(200)
 	restServer.codec.Encode(cs, c.Writer)
 }
 
 func (restServer *RestServer) handleValidatorList(c *gin.Context) {
-	// TODO: [Silas] erisDbMethods has not implemented this since the refactor
-	vl := &core_types.ValidatorList{}
+	vl := restServer.pipe.GetConsensusEngine().ListValidators()
 	c.Writer.WriteHeader(200)
 	restServer.codec.Encode(vl, c.Writer)
 }
@@ -381,13 +377,12 @@ func (restServer *RestServer) handleBroadcastTx(c *gin.Context) {
 }
 
 func (restServer *RestServer) handleUnconfirmedTxs(c *gin.Context) {
-
-	txs, err := restServer.pipe.Transactor().UnconfirmedTxs()
+	trans, err := restServer.pipe.GetConsensusEngine().ListUnconfirmedTxs(-1)
 	if err != nil {
 		c.AbortWithError(500, err)
 	}
 	c.Writer.WriteHeader(200)
-	restServer.codec.Encode(txs, c.Writer)
+	restServer.codec.Encode(txs.UnconfirmedTxs{trans}, c.Writer)
 }
 
 func (restServer *RestServer) handleCall(c *gin.Context) {
diff --git a/test/mock/pipe.go b/test/mock/pipe.go
index 78ba9d38783445c94f85e70f6871ca71dffd91c6..d57f781e7c6a6965e07f21846f2e1663b0c8ba70 100644
--- a/test/mock/pipe.go
+++ b/test/mock/pipe.go
@@ -39,7 +39,7 @@ func NewMockPipe(td *td.TestData) definitions.Pipe {
 	consensusEngine := &consensusEngine{td}
 	eventer := &eventer{td}
 	namereg := &namereg{td}
-	net := &net{td}
+	net := &network{td}
 	transactor := &transactor{td}
 	return &MockPipe{
 		td,
@@ -58,63 +58,59 @@ func NewDefaultMockPipe() definitions.Pipe {
 	return NewMockPipe(td.LoadTestData())
 }
 
-func (this *MockPipe) Accounts() definitions.Accounts {
-	return this.accounts
+func (pipe *MockPipe) Accounts() definitions.Accounts {
+	return pipe.accounts
 }
 
-func (this *MockPipe) Blockchain() blockchain_types.Blockchain {
-	return this.blockchain
+func (pipe *MockPipe) Blockchain() blockchain_types.Blockchain {
+	return pipe.blockchain
 }
 
-func (this *MockPipe) Consensus() consensus_types.ConsensusEngine {
-	return this.consensusEngine
+func (pipe *MockPipe) Events() event.EventEmitter {
+	return pipe.events
 }
 
-func (this *MockPipe) Events() event.EventEmitter {
-	return this.events
+func (pipe *MockPipe) NameReg() definitions.NameReg {
+	return pipe.namereg
 }
 
-func (this *MockPipe) NameReg() definitions.NameReg {
-	return this.namereg
+func (pipe *MockPipe) Net() definitions.Net {
+	return pipe.net
 }
 
-func (this *MockPipe) Net() definitions.Net {
-	return this.net
+func (pipe *MockPipe) Transactor() definitions.Transactor {
+	return pipe.transactor
 }
 
-func (this *MockPipe) Transactor() definitions.Transactor {
-	return this.transactor
-}
-
-func (this *MockPipe) GetApplication() manager_types.Application {
+func (pipe *MockPipe) GetApplication() manager_types.Application {
 	// TODO: [ben] mock application
 	return nil
 }
 
-func (this *MockPipe) SetConsensusEngine(_ consensus_types.ConsensusEngine) error {
+func (pipe *MockPipe) SetConsensusEngine(_ consensus_types.ConsensusEngine) error {
 	// TODO: [ben] mock consensus engine
 	return nil
 }
 
-func (this *MockPipe) GetConsensusEngine() consensus_types.ConsensusEngine {
-	return nil
+func (pipe *MockPipe) GetConsensusEngine() consensus_types.ConsensusEngine {
+	return pipe.consensusEngine
 }
 
-func (this *MockPipe) SetBlockchain(_ blockchain_types.Blockchain) error {
+func (pipe *MockPipe) SetBlockchain(_ blockchain_types.Blockchain) error {
 	// TODO: [ben] mock consensus engine
 	return nil
 }
 
-func (this *MockPipe) GetBlockchain() blockchain_types.Blockchain {
+func (pipe *MockPipe) GetBlockchain() blockchain_types.Blockchain {
 	return nil
 }
 
-func (this *MockPipe) GetTendermintPipe() (definitions.TendermintPipe, error) {
+func (pipe *MockPipe) GetTendermintPipe() (definitions.TendermintPipe, error) {
 	return nil, fmt.Errorf("Tendermint pipe is not supported by mocked pipe.")
 }
 
-func (this *MockPipe) GenesisHash() []byte {
-	return this.testData.GetGenesisHash.Output.Hash
+func (pipe *MockPipe) GenesisHash() []byte {
+	return pipe.testData.GetGenesisHash.Output.Hash
 }
 
 // Components
@@ -124,28 +120,28 @@ type accounts struct {
 	testData *td.TestData
 }
 
-func (this *accounts) GenPrivAccount() (*account.PrivAccount, error) {
-	return this.testData.GenPrivAccount.Output, nil
+func (acc *accounts) GenPrivAccount() (*account.PrivAccount, error) {
+	return acc.testData.GenPrivAccount.Output, nil
 }
 
-func (this *accounts) GenPrivAccountFromKey(key []byte) (*account.PrivAccount, error) {
-	return this.testData.GenPrivAccount.Output, nil
+func (acc *accounts) GenPrivAccountFromKey(key []byte) (*account.PrivAccount, error) {
+	return acc.testData.GenPrivAccount.Output, nil
 }
 
-func (this *accounts) Accounts([]*event.FilterData) (*core_types.AccountList, error) {
-	return this.testData.GetAccounts.Output, nil
+func (acc *accounts) Accounts([]*event.FilterData) (*core_types.AccountList, error) {
+	return acc.testData.GetAccounts.Output, nil
 }
 
-func (this *accounts) Account(address []byte) (*account.Account, error) {
-	return this.testData.GetAccount.Output, nil
+func (acc *accounts) Account(address []byte) (*account.Account, error) {
+	return acc.testData.GetAccount.Output, nil
 }
 
-func (this *accounts) Storage(address []byte) (*core_types.Storage, error) {
-	return this.testData.GetStorage.Output, nil
+func (acc *accounts) Storage(address []byte) (*core_types.Storage, error) {
+	return acc.testData.GetStorage.Output, nil
 }
 
-func (this *accounts) StorageAt(address, key []byte) (*core_types.StorageItem, error) {
-	return this.testData.GetStorageAt.Output, nil
+func (acc *accounts) StorageAt(address, key []byte) (*core_types.StorageItem, error) {
+	return acc.testData.GetStorageAt.Output, nil
 }
 
 // Blockchain
@@ -208,16 +204,32 @@ func (cons *consensusEngine) Events() event.EventEmitter {
 	return nil
 }
 
+func (cons *consensusEngine) ListUnconfirmedTxs(maxTxs int) ([]txs.Tx, error) {
+	return cons.testData.GetUnconfirmedTxs.Output.Txs, nil
+}
+
+func (cons *consensusEngine) ListValidators() []consensus_types.Validator {
+	return nil
+}
+
+func (cons *consensusEngine) ConsensusState() *consensus_types.ConsensusState {
+	return &consensus_types.ConsensusState{}
+}
+
+func (cons *consensusEngine) PeerConsensusStates() map[string]string {
+	return map[string]string{}
+}
+
 // Events
 type eventer struct {
 	testData *td.TestData
 }
 
-func (this *eventer) Subscribe(subId, event string, callback func(txs.EventData)) error {
+func (evntr *eventer) Subscribe(subId, event string, callback func(txs.EventData)) error {
 	return nil
 }
 
-func (this *eventer) Unsubscribe(subId string) error {
+func (evntr *eventer) Unsubscribe(subId string) error {
 	return nil
 }
 
@@ -226,45 +238,45 @@ type namereg struct {
 	testData *td.TestData
 }
 
-func (this *namereg) Entry(key string) (*core_types.NameRegEntry, error) {
-	return this.testData.GetNameRegEntry.Output, nil
+func (nmreg *namereg) Entry(key string) (*core_types.NameRegEntry, error) {
+	return nmreg.testData.GetNameRegEntry.Output, nil
 }
 
-func (this *namereg) Entries(filters []*event.FilterData) (*core_types.ResultListNames, error) {
-	return this.testData.GetNameRegEntries.Output, nil
+func (nmreg *namereg) Entries(filters []*event.FilterData) (*core_types.ResultListNames, error) {
+	return nmreg.testData.GetNameRegEntries.Output, nil
 }
 
 // Net
-type net struct {
+type network struct {
 	testData *td.TestData
 }
 
-func (this *net) Info() (*core_types.NetworkInfo, error) {
-	return this.testData.GetNetworkInfo.Output, nil
+func (net *network) Info() (*core_types.NetworkInfo, error) {
+	return net.testData.GetNetworkInfo.Output, nil
 }
 
-func (this *net) ClientVersion() (string, error) {
-	return this.testData.GetClientVersion.Output.ClientVersion, nil
+func (net *network) ClientVersion() (string, error) {
+	return net.testData.GetClientVersion.Output.ClientVersion, nil
 }
 
-func (this *net) Moniker() (string, error) {
-	return this.testData.GetMoniker.Output.Moniker, nil
+func (net *network) Moniker() (string, error) {
+	return net.testData.GetMoniker.Output.Moniker, nil
 }
 
-func (this *net) Listening() (bool, error) {
-	return this.testData.IsListening.Output.Listening, nil
+func (net *network) Listening() (bool, error) {
+	return net.testData.IsListening.Output.Listening, nil
 }
 
-func (this *net) Listeners() ([]string, error) {
-	return this.testData.GetListeners.Output.Listeners, nil
+func (net *network) Listeners() ([]string, error) {
+	return net.testData.GetListeners.Output.Listeners, nil
 }
 
-func (this *net) Peers() ([]*core_types.Peer, error) {
-	return this.testData.GetPeers.Output, nil
+func (net *network) Peers() ([]*core_types.Peer, error) {
+	return net.testData.GetPeers.Output, nil
 }
 
-func (this *net) Peer(address string) (*core_types.Peer, error) {
-	// return this.testData.GetPeer.Output, nil
+func (net *network) Peer(address string) (*core_types.Peer, error) {
+	// return net.testData.GetPeer.Output, nil
 	return nil, nil
 }
 
@@ -273,45 +285,41 @@ type transactor struct {
 	testData *td.TestData
 }
 
-func (this *transactor) Call(fromAddress, toAddress, data []byte) (*core_types.Call, error) {
-	return this.testData.Call.Output, nil
+func (trans *transactor) Call(fromAddress, toAddress, data []byte) (*core_types.Call, error) {
+	return trans.testData.Call.Output, nil
 }
 
-func (this *transactor) CallCode(from, code, data []byte) (*core_types.Call, error) {
-	return this.testData.CallCode.Output, nil
+func (trans *transactor) CallCode(from, code, data []byte) (*core_types.Call, error) {
+	return trans.testData.CallCode.Output, nil
 }
 
-func (this *transactor) BroadcastTx(tx txs.Tx) (*txs.Receipt, error) {
+func (trans *transactor) BroadcastTx(tx txs.Tx) (*txs.Receipt, error) {
 	return nil, nil
 }
 
-func (this *transactor) UnconfirmedTxs() (*txs.UnconfirmedTxs, error) {
-	return this.testData.GetUnconfirmedTxs.Output, nil
-}
-
-func (this *transactor) Transact(privKey, address, data []byte, gasLimit, fee int64) (*txs.Receipt, error) {
+func (trans *transactor) Transact(privKey, address, data []byte, gasLimit, fee int64) (*txs.Receipt, error) {
 	if address == nil || len(address) == 0 {
-		return this.testData.TransactCreate.Output, nil
+		return trans.testData.TransactCreate.Output, nil
 	}
-	return this.testData.Transact.Output, nil
+	return trans.testData.Transact.Output, nil
 }
 
-func (this *transactor) TransactAndHold(privKey, address, data []byte, gasLimit, fee int64) (*txs.EventDataCall, error) {
+func (trans *transactor) TransactAndHold(privKey, address, data []byte, gasLimit, fee int64) (*txs.EventDataCall, error) {
 	return nil, nil
 }
 
-func (this *transactor) Send(privKey, toAddress []byte, amount int64) (*txs.Receipt, error) {
+func (trans *transactor) Send(privKey, toAddress []byte, amount int64) (*txs.Receipt, error) {
 	return nil, nil
 }
 
-func (this *transactor) SendAndHold(privKey, toAddress []byte, amount int64) (*txs.Receipt, error) {
+func (trans *transactor) SendAndHold(privKey, toAddress []byte, amount int64) (*txs.Receipt, error) {
 	return nil, nil
 }
 
-func (this *transactor) TransactNameReg(privKey []byte, name, data string, amount, fee int64) (*txs.Receipt, error) {
-	return this.testData.TransactNameReg.Output, nil
+func (trans *transactor) TransactNameReg(privKey []byte, name, data string, amount, fee int64) (*txs.Receipt, error) {
+	return trans.testData.TransactNameReg.Output, nil
 }
 
-func (this *transactor) SignTx(tx txs.Tx, privAccounts []*account.PrivAccount) (txs.Tx, error) {
+func (trans *transactor) SignTx(tx txs.Tx, privAccounts []*account.PrivAccount) (txs.Tx, error) {
 	return nil, nil
 }
diff --git a/test/testdata/testdata/testdata.go b/test/testdata/testdata/testdata.go
index 56894ecb5a55601ba90f8d542e458dfce66f7442..89b24a470acdaa7f407dc630d97af61ca138502f 100644
--- a/test/testdata/testdata/testdata.go
+++ b/test/testdata/testdata/testdata.go
@@ -2,16 +2,22 @@ package testdata
 
 import (
 	account "github.com/eris-ltd/eris-db/account"
+	consensus_types "github.com/eris-ltd/eris-db/consensus/types"
 	core_types "github.com/eris-ltd/eris-db/core/types"
 	event "github.com/eris-ltd/eris-db/event"
 	stypes "github.com/eris-ltd/eris-db/manager/eris-mint/state/types"
 	rpc_v0 "github.com/eris-ltd/eris-db/rpc/v0"
 	transaction "github.com/eris-ltd/eris-db/txs"
-
 	mintTypes "github.com/tendermint/tendermint/types"
 )
 
-var testDataJson = `{
+// TODO: [Silas] This would really be much better as a composite literal in go
+// where the compiler/type system/IDE would make it easier to maintain
+// not entirely straightforward to convert it, but shouldn't be that hard either
+// with recursive use of fmt.Printf("%#v", subStruct) on the decoded in-memory
+// object
+var testDataJson = `
+{
   "chain_data": {
     "priv_validator": {
       "address": "37236DF251AB70022B1DA351F08A20FB52443E37",
@@ -53,7 +59,10 @@ var testDataJson = `{
       ],
       "validators": [
         {
-          "pub_key": [1, "CB3688B7561D488A2A4834E1AEE9398BEF94844D8BDBBCA980C11E3654A45906"],
+          "pub_key": [
+            1,
+            "CB3688B7561D488A2A4834E1AEE9398BEF94844D8BDBBCA980C11E3654A45906"
+          ],
           "amount": 5000000000,
           "unbond_to": [
             {
@@ -92,20 +101,20 @@ var testDataJson = `{
     "output": {
       "accounts": [
         {
-	      "address": "0000000000000000000000000000000000000000",
-	      "pub_key": null,
-	      "sequence": 0,
-	      "balance": 1337,
-	      "code": "",
-	      "storage_root": "",
-	      "permissions": {
-	        "base": {
-	          "perms": 2302,
-	          "set": 16383
-	        },
-	        "roles": []
-	      }
-	    },
+          "address": "0000000000000000000000000000000000000000",
+          "pub_key": null,
+          "sequence": 0,
+          "balance": 1337,
+          "code": "",
+          "storage_root": "",
+          "permissions": {
+            "base": {
+              "perms": 2302,
+              "set": 16383
+            },
+            "roles": []
+          }
+        },
         {
           "address": "0000000000000000000000000000000000000002",
           "pub_key": null,
@@ -243,7 +252,9 @@ var testDataJson = `{
     "output": {}
   },
   "GetBlock": {
-    "input": {"height": 0},
+    "input": {
+      "height": 0
+    },
     "output": null
   },
   "GetBlocks": {
@@ -261,18 +272,26 @@ var testDataJson = `{
       "height": 1,
       "round": 0,
       "step": 1,
-      "start_time": "",
-      "commit_time": "0001-01-01 00:00:00 +0000 UTC",
+      "start_time": "2016-09-18T10:03:55.100Z",
+      "commit_time": "2016-09-18T10:04:00.100Z",
       "validators": [
-        {
-          "address": "37236DF251AB70022B1DA351F08A20FB52443E37",
-          "pub_key": [1, "CB3688B7561D488A2A4834E1AEE9398BEF94844D8BDBBCA980C11E3654A45906"],
-          "bond_height": 0,
-          "unbond_height": 0,
-          "last_commit_height": 0,
-          "voting_power": 5000000000,
-          "accum": 0
-        }
+        [
+          1,
+          {
+            "validator": {
+              "address": "37236DF251AB70022B1DA351F08A20FB52443E37",
+              "pub_key": [
+                1,
+                "CB3688B7561D488A2A4834E1AEE9398BEF94844D8BDBBCA980C11E3654A45906"
+              ],
+              "bond_height": 0,
+              "unbond_height": 0,
+              "last_commit_height": 0,
+              "voting_power": 5000000000,
+              "accum": 0
+            }
+          }
+        ]
       ],
       "proposal": null
     }
@@ -283,7 +302,10 @@ var testDataJson = `{
       "bonded_validators": [
         {
           "address": "37236DF251AB70022B1DA351F08A20FB52443E37",
-          "pub_key": [1, "CB3688B7561D488A2A4834E1AEE9398BEF94844D8BDBBCA980C11E3654A45906"],
+          "pub_key": [
+            1,
+            "CB3688B7561D488A2A4834E1AEE9398BEF94844D8BDBBCA980C11E3654A45906"
+          ],
           "bond_height": 0,
           "unbond_height": 0,
           "last_commit_height": 0,
@@ -327,7 +349,9 @@ var testDataJson = `{
     "output": []
   },
   "GetPeer": {
-    "input": {"address": "127.0.0.1:30000"},
+    "input": {
+      "address": "127.0.0.1:30000"
+    },
     "output": {
       "is_outbound": false,
       "node_info": null
@@ -420,7 +444,11 @@ var testDataJson = `{
     }
   },
   "Call": {
-    "input": {"address": "9FC1ECFCAE2A554D4D1A000D0D80F748E66359E3", "from": "DEADBEEF", "data": ""},
+    "input": {
+      "address": "9FC1ECFCAE2A554D4D1A000D0D80F748E66359E3",
+      "from": "DEADBEEF",
+      "data": ""
+    },
     "output": {
       "return": "6000357c01000000000000000000000000000000000000000000000000000000009004806337f428411461004557806340c10f191461005a578063d0679d341461006e57005b610050600435610244565b8060005260206000f35b610068600435602435610082565b60006000f35b61007c600435602435610123565b60006000f35b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156100dd576100e2565b61011f565b80600160005060008473ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828282505401925050819055505b5050565b80600160005060003373ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600050541061015e57610163565b610240565b80600160005060003373ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282825054039250508190555080600160005060008473ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828282505401925050819055507f93eb3c629eb575edaf0252e4f9fc0c5ccada50496f8c1d32f0f93a65a8257eb560003373ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020016000a15b5050565b6000600160005060008373ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060005054905061027d565b91905056",
       "gas_used": 0
@@ -484,7 +512,8 @@ var testDataJson = `{
       "name": "testKey",
       "owner": "37236DF251AB70022B1DA351F08A20FB52443E37",
       "data": "testData",
-      "expires": 250 }
+      "expires": 250
+    }
   },
   "GetNameRegEntries": {
     "input": {
@@ -492,15 +521,18 @@ var testDataJson = `{
     },
     "output": {
       "block_height": 1,
-      "names":[ {
-        "name": "testKey",
-        "owner": "37236DF251AB70022B1DA351F08A20FB52443E37",
-        "data": "testData",
-        "expires": 250
-      } ]
+      "names": [
+        {
+          "name": "testKey",
+          "owner": "37236DF251AB70022B1DA351F08A20FB52443E37",
+          "data": "testData",
+          "expires": 250
+        }
+      ]
     }
   }
-}`
+}
+`
 
 var serverDuration uint = 100
 
@@ -565,7 +597,7 @@ type (
 	}
 
 	GetConsensusStateData struct {
-		Output *core_types.ConsensusState `json:"output"`
+		Output *consensus_types.ConsensusState `json:"output"`
 	}
 
 	GetValidatorsData struct {
diff --git a/txs/tx.go b/txs/tx.go
index 9957d570060d6c37ae266e8fc3b75adcb63e7796..a216332031d24951fdc63d1f12a57b9f8f932fc7 100644
--- a/txs/tx.go
+++ b/txs/tx.go
@@ -14,7 +14,7 @@ import (
 	"github.com/tendermint/go-wire"
 
 	"github.com/tendermint/go-crypto"
-	"github.com/tendermint/tendermint/types" // votes for dupeout ..
+	tendermint_types "github.com/tendermint/tendermint/types" // votes for dupeout ..
 )
 
 var (
@@ -340,9 +340,9 @@ func (tx *RebondTx) String() string {
 //-----------------------------------------------------------------------------
 
 type DupeoutTx struct {
-	Address []byte     `json:"address"`
-	VoteA   types.Vote `json:"vote_a"`
-	VoteB   types.Vote `json:"vote_b"`
+	Address []byte                `json:"address"`
+	VoteA   tendermint_types.Vote `json:"vote_a"`
+	VoteB   tendermint_types.Vote `json:"vote_b"`
 }
 
 func (tx *DupeoutTx) WriteSignBytes(chainID string, w io.Writer, n *int, err *error) {
@@ -378,12 +378,6 @@ func (tx *PermissionsTx) String() string {
 //-----------------------------------------------------------------------------
 
 func TxHash(chainID string, tx Tx) []byte {
-	signBytes := acm.SignBytes(chainID, tx)
-	return wire.BinaryRipemd160(signBytes)
-}
-
-// [Silas] Leaving this implementation here for when we transition
-func TxHashFuture(chainID string, tx Tx) []byte {
 	signBytes := acm.SignBytes(chainID, tx)
 	hasher := ripemd160.New()
 	hasher.Write(signBytes)
@@ -393,34 +387,28 @@ func TxHashFuture(chainID string, tx Tx) []byte {
 
 //-----------------------------------------------------------------------------
 
-func EncodeTx(tx Tx) []byte {
-	wrapTx := struct {
-		Tx Tx `json:"unwrap"`
-	}{tx}
-	return wire.BinaryBytes(wrapTx)
+func EncodeTx(tx Tx) ([]byte, error) {
+	var n int
+	var err error
+	buf := new(bytes.Buffer)
+	wire.WriteBinary(struct{ Tx }{tx}, buf, &n, &err)
+	if err != nil {
+		return nil, err
+	}
+	return buf.Bytes(), nil
 }
 
-//func EncodeTx(tx txs.Tx) []byte {
-//	buf := new(bytes.Buffer)
-//	var n int
-//	var err error
-//	wire.WriteBinary(struct{ types.Tx }{tx}, buf, &n, &err)
-//	if err != nil {
-//		return err
-//	}
-//}
-
 // panic on err
-func DecodeTx(txBytes []byte) Tx {
+func DecodeTx(txBytes []byte) (Tx, error) {
 	var n int
 	var err error
 	tx := new(Tx)
 	buf := bytes.NewBuffer(txBytes)
 	wire.ReadBinaryPtr(tx, buf, len(txBytes), &n, &err)
 	if err != nil {
-		panic(err)
+		return nil, err
 	}
-	return *tx
+	return *tx, nil
 }
 
 func GenerateReceipt(chainId string, tx Tx) Receipt {
diff --git a/txs/tx_test.go b/txs/tx_test.go
index 5a73d351cab29b7fefc51c425e6f385a05abf3aa..e3f092da5679bd78f2b0ff1e1a4423f8eb960565 100644
--- a/txs/tx_test.go
+++ b/txs/tx_test.go
@@ -6,9 +6,9 @@ import (
 	acm "github.com/eris-ltd/eris-db/account"
 	ptypes "github.com/eris-ltd/eris-db/permission/types"
 
+	"github.com/stretchr/testify/assert"
 	. "github.com/tendermint/go-common"
 	"github.com/tendermint/go-crypto"
-	//"github.com/tendermint/tendermint/types"
 )
 
 var chainID = "myChainID"
@@ -177,6 +177,30 @@ func TestPermissionsTxSignable(t *testing.T) {
 	}
 }
 
+func TestEncodeTxDecodeTx(t *testing.T) {
+	inputAddress := []byte{1, 2, 3, 4, 5}
+	outputAddress := []byte{5, 4, 3, 2, 1}
+	amount := int64(2)
+	sequence := 3
+	tx := &SendTx{
+		Inputs: []*TxInput{{
+			Address:  inputAddress,
+			Amount:   amount,
+			Sequence: sequence,
+		}},
+		Outputs: []*TxOutput{{
+			Address: outputAddress,
+			Amount:  amount,
+		}},
+	}
+	txBytes, err := EncodeTx(tx)
+	if err != nil {
+		t.Fatal(err)
+	}
+	txOut, err := DecodeTx(txBytes)
+	assert.Equal(t, tx, txOut)
+}
+
 /*
 func TestDupeoutTxSignable(t *testing.T) {
 	privAcc := acm.GenPrivAccount()