diff --git a/Gopkg.lock b/Gopkg.lock
index 8dc60b9351f9b552f450ce676e7040bc992788db..cfbe1eb2ad3350a5f84406bd92fa18dee8c48a59 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -529,6 +529,6 @@
 [solve-meta]
   analyzer-name = "dep"
   analyzer-version = 1
-  inputs-digest = "e967fbd5455762e55b443957abeda0cdd7a1c368d170b18909351d4a2ff7b75b"
+  inputs-digest = "449c3a942d77db009d3da12dbe9b807d6697ab68e7baaef18fbf62ebbe42cc21"
   solver-name = "gps-cdcl"
   solver-version = 1
diff --git a/Gopkg.toml b/Gopkg.toml
index d326efb02d3f5cbf7dc397cf39178723ec812017..2f689175faf605949d7a71c0a815d495b4384b3d 100644
--- a/Gopkg.toml
+++ b/Gopkg.toml
@@ -29,8 +29,8 @@
   branch = "develop"
 
 [[constraint]]
-name = "github.com/prometheus/client_golang"
-branch = "master"
+  name = "github.com/prometheus/client_golang"
+  branch = "master"
 
 [[override]]
   name = "github.com/tendermint/tmlibs"
diff --git a/account/state/state_cache.go b/account/state/state_cache.go
index 869842431bc3213eda869d65103ddf384d13738f..a4f4c44374023fa8e4ab8448fbe0fb1d7e8e8a31 100644
--- a/account/state/state_cache.go
+++ b/account/state/state_cache.go
@@ -24,14 +24,7 @@ import (
 	"github.com/hyperledger/burrow/crypto"
 )
 
-type Cache interface {
-	Writer
-	Sync(state Writer) error
-	Reset(backend Iterable)
-	Flush(state IterableWriter) error
-}
-
-type stateCache struct {
+type Cache struct {
 	sync.RWMutex
 	name     string
 	backend  Reader
@@ -46,12 +39,12 @@ type accountInfo struct {
 	updated bool
 }
 
-type CacheOption func(*stateCache)
+type CacheOption func(*Cache)
 
 // Returns a Cache that wraps an underlying Reader to use on a cache miss, can write to an output Writer
 // via Sync. Goroutine safe for concurrent access.
-func NewCache(backend Reader, options ...CacheOption) Cache {
-	cache := &stateCache{
+func NewCache(backend Reader, options ...CacheOption) *Cache {
+	cache := &Cache{
 		backend:  backend,
 		accounts: make(map[crypto.Address]*accountInfo),
 	}
@@ -62,12 +55,12 @@ func NewCache(backend Reader, options ...CacheOption) Cache {
 }
 
 func Name(name string) CacheOption {
-	return func(cache *stateCache) {
+	return func(cache *Cache) {
 		cache.name = name
 	}
 }
 
-func (cache *stateCache) GetAccount(address crypto.Address) (acm.Account, error) {
+func (cache *Cache) GetAccount(address crypto.Address) (acm.Account, error) {
 	accInfo, err := cache.get(address)
 	if err != nil {
 		return nil, err
@@ -80,7 +73,7 @@ func (cache *stateCache) GetAccount(address crypto.Address) (acm.Account, error)
 	return accInfo.account, nil
 }
 
-func (cache *stateCache) UpdateAccount(account acm.Account) error {
+func (cache *Cache) UpdateAccount(account acm.Account) error {
 	accInfo, err := cache.get(account.Address())
 	if err != nil {
 		return err
@@ -95,7 +88,7 @@ func (cache *stateCache) UpdateAccount(account acm.Account) error {
 	return nil
 }
 
-func (cache *stateCache) RemoveAccount(address crypto.Address) error {
+func (cache *Cache) RemoveAccount(address crypto.Address) error {
 	accInfo, err := cache.get(address)
 	if err != nil {
 		return err
@@ -110,7 +103,7 @@ func (cache *stateCache) RemoveAccount(address crypto.Address) error {
 }
 
 // Iterates over all cached accounts first in cache and then in backend until consumer returns true for 'stop'
-func (cache *stateCache) IterateCachedAccount(consumer func(acm.Account) (stop bool)) (stopped bool, err error) {
+func (cache *Cache) IterateCachedAccount(consumer func(acm.Account) (stop bool)) (stopped bool, err error) {
 	// Try cache first for early exit
 	cache.RLock()
 	for _, info := range cache.accounts {
@@ -123,7 +116,7 @@ func (cache *stateCache) IterateCachedAccount(consumer func(acm.Account) (stop b
 	return false, nil
 }
 
-func (cache *stateCache) GetStorage(address crypto.Address, key binary.Word256) (binary.Word256, error) {
+func (cache *Cache) GetStorage(address crypto.Address, key binary.Word256) (binary.Word256, error) {
 	accInfo, err := cache.get(address)
 	if err != nil {
 		return binary.Zero256, err
@@ -149,7 +142,7 @@ func (cache *stateCache) GetStorage(address crypto.Address, key binary.Word256)
 }
 
 // NOTE: Set value to zero to remove.
-func (cache *stateCache) SetStorage(address crypto.Address, key binary.Word256, value binary.Word256) error {
+func (cache *Cache) SetStorage(address crypto.Address, key binary.Word256, value binary.Word256) error {
 	accInfo, err := cache.get(address)
 	accInfo.Lock()
 	defer accInfo.Unlock()
@@ -165,7 +158,7 @@ func (cache *stateCache) SetStorage(address crypto.Address, key binary.Word256,
 }
 
 // Iterates over all cached storage items first in cache and then in backend until consumer returns true for 'stop'
-func (cache *stateCache) IterateCachedStorage(address crypto.Address,
+func (cache *Cache) IterateCachedStorage(address crypto.Address,
 	consumer func(key, value binary.Word256) (stop bool)) (stopped bool, err error) {
 	accInfo, err := cache.get(address)
 	if err != nil {
@@ -185,7 +178,7 @@ func (cache *stateCache) IterateCachedStorage(address crypto.Address,
 
 // Syncs changes to the backend in deterministic order. Sends storage updates before updating
 // the account they belong so that storage values can be taken account of in the update.
-func (cache *stateCache) Sync(state Writer) error {
+func (cache *Cache) Sync(state Writer) error {
 	cache.Lock()
 	defer cache.Unlock()
 	var addresses crypto.Addresses
@@ -229,7 +222,7 @@ func (cache *stateCache) Sync(state Writer) error {
 }
 
 // Resets the cache to empty initialising the backing map to the same size as the previous iteration.
-func (cache *stateCache) Reset(backend Iterable) {
+func (cache *Cache) Reset(backend Iterable) {
 	cache.Lock()
 	defer cache.Unlock()
 	cache.backend = backend
@@ -237,7 +230,7 @@ func (cache *stateCache) Reset(backend Iterable) {
 }
 
 // Syncs the Cache and Resets it to use as the backend Reader
-func (cache *stateCache) Flush(state IterableWriter) error {
+func (cache *Cache) Flush(state IterableWriter) error {
 	err := cache.Sync(state)
 	if err != nil {
 		return err
@@ -246,7 +239,7 @@ func (cache *stateCache) Flush(state IterableWriter) error {
 	return nil
 }
 
-func (cache *stateCache) String() string {
+func (cache *Cache) String() string {
 	if cache.name == "" {
 		return fmt.Sprintf("StateCache{Length: %v}", len(cache.accounts))
 	}
@@ -254,7 +247,7 @@ func (cache *stateCache) String() string {
 }
 
 // Get the cache accountInfo item creating it if necessary
-func (cache *stateCache) get(address crypto.Address) (*accountInfo, error) {
+func (cache *Cache) get(address crypto.Address) (*accountInfo, error) {
 	cache.RLock()
 	accInfo := cache.accounts[address]
 	cache.RUnlock()
diff --git a/binary/bytes.go b/binary/bytes.go
index 2b0dd8d72acf783b91601e27922a062748cdec87..03a736c45df1e1ebddb7b2535051899a97194138 100644
--- a/binary/bytes.go
+++ b/binary/bytes.go
@@ -14,5 +14,9 @@ func (hb *HexBytes) UnmarshalText(hexBytes []byte) error {
 }
 
 func (hb HexBytes) MarshalText() ([]byte, error) {
-	return []byte(hex.EncodeUpperToString(hb)), nil
+	return []byte(hb.String()), nil
+}
+
+func (hb HexBytes) String() string {
+	return hex.EncodeUpperToString(hb)
 }
diff --git a/binary/integer_test.go b/binary/integer_test.go
index 2f40ae258d4011e389f11fae2b706363ac7451ad..3e30e2163d511f9b40c0a4adbe5af26f90e72302 100644
--- a/binary/integer_test.go
+++ b/binary/integer_test.go
@@ -99,8 +99,8 @@ func TestS256(t *testing.T) {
 
 func TestPutUint64BE(t *testing.T) {
 	bs := make([]byte, 8)
-	PutUint64LE(bs, 245343)
-	assert.Equal(t, "5FBE030000000000", fmt.Sprintf("%X", bs))
+	PutUint64BE(bs, 245343)
+	assert.Equal(t, "000000000003BE5F", fmt.Sprintf("%X", bs))
 }
 
 func TestSignExtend(t *testing.T) {
diff --git a/consensus/tendermint/events.go b/consensus/tendermint/events.go
index db069d683404f3fe763b6c17e0a63802af70bad4..c85f976c0d20cad99722976c4393e9d0d261df41 100644
--- a/consensus/tendermint/events.go
+++ b/consensus/tendermint/events.go
@@ -4,6 +4,7 @@ import (
 	"context"
 
 	"github.com/hyperledger/burrow/event"
+	"github.com/hyperledger/burrow/event/query"
 	"github.com/hyperledger/burrow/logging/structure"
 	"github.com/tendermint/tendermint/libs/pubsub"
 	tm_types "github.com/tendermint/tendermint/types"
@@ -55,7 +56,7 @@ func PublishEvent(ctx context.Context, fromSubscribable event.Subscribable, subs
 		tm_types.EventTypeKey:  eventType,
 		event.EventIDKey:       eventType,
 	}
-	return event.PublishAll(ctx, fromSubscribable, subscriber, event.WrapQuery(tm_types.QueryForEvent(eventType)),
+	return event.PublishAll(ctx, fromSubscribable, subscriber, query.WrapQuery(tm_types.QueryForEvent(eventType)),
 		toPublisher, tags)
 }
 
@@ -67,17 +68,17 @@ func EventBusAsSubscribable(eventBus tm_types.EventBusSubscriber) event.Subscrib
 	return eventBusSubscriber{eventBus}
 }
 
-func (ebs eventBusSubscriber) Subscribe(ctx context.Context, subscriber string, query event.Queryable,
+func (ebs eventBusSubscriber) Subscribe(ctx context.Context, subscriber string, queryable query.Queryable,
 	out chan<- interface{}) error {
-	qry, err := query.Query()
+	qry, err := queryable.Query()
 	if err != nil {
 		return err
 	}
 	return ebs.EventBusSubscriber.Subscribe(ctx, subscriber, qry, out)
 }
 
-func (ebs eventBusSubscriber) Unsubscribe(ctx context.Context, subscriber string, query event.Queryable) error {
-	qry, err := query.Query()
+func (ebs eventBusSubscriber) Unsubscribe(ctx context.Context, subscriber string, queryable query.Queryable) error {
+	qry, err := queryable.Query()
 	if err != nil {
 		return err
 	}
@@ -92,11 +93,11 @@ func SubscribableAsEventBus(subscribable event.Subscribable) tm_types.EventBusSu
 	return subscribableEventBus{subscribable}
 }
 
-func (seb subscribableEventBus) Subscribe(ctx context.Context, subscriber string, query pubsub.Query,
+func (seb subscribableEventBus) Subscribe(ctx context.Context, subscriber string, qry pubsub.Query,
 	out chan<- interface{}) error {
-	return seb.Subscribable.Subscribe(ctx, subscriber, event.WrapQuery(query), out)
+	return seb.Subscribable.Subscribe(ctx, subscriber, query.WrapQuery(qry), out)
 }
 
-func (seb subscribableEventBus) Unsubscribe(ctx context.Context, subscriber string, query pubsub.Query) error {
-	return seb.Subscribable.Unsubscribe(ctx, subscriber, event.WrapQuery(query))
+func (seb subscribableEventBus) Unsubscribe(ctx context.Context, subscriber string, qry pubsub.Query) error {
+	return seb.Subscribable.Unsubscribe(ctx, subscriber, query.WrapQuery(qry))
 }
diff --git a/core/kernel.go b/core/kernel.go
index 51e880e999de428171f080556065af21b77afabe..1927df067a9b5e5297f4c0d4ca8ae89dbb0a6c78 100644
--- a/core/kernel.go
+++ b/core/kernel.go
@@ -65,6 +65,7 @@ type Kernel struct {
 	Emitter        event.Emitter
 	Service        *rpc.Service
 	Launchers      []process.Launcher
+	State          *execution.State
 	Logger         *logging.Logger
 	processes      map[string]process.Process
 	shutdownNotify chan struct{}
@@ -111,8 +112,9 @@ func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_t
 	transactor := execution.NewTransactor(blockchain.Tip, emitter, tmNode.MempoolReactor().BroadcastTx, txCodec,
 		logger)
 
-	nameReg := state
-	service := rpc.NewService(ctx, state, nameReg, checker, emitter, blockchain, keyClient, transactor,
+	nameRegState := state
+	accountState := state
+	service := rpc.NewService(ctx, accountState, nameRegState, checker, emitter, blockchain, keyClient, transactor,
 		query.NewNodeView(tmNode, txCodec), logger)
 
 	launchers := []process.Launcher{
@@ -220,7 +222,7 @@ func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_t
 			},
 		},
 		{
-			Name:    "GRPC",
+			Name:    "RPC/GRPC",
 			Enabled: rpcConfig.GRPC.Enabled,
 			Launch: func() (process.Process, error) {
 				listen, err := net.Listen("tcp", rpcConfig.GRPC.ListenAddress)
@@ -246,7 +248,7 @@ func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_t
 
 				pbevents.RegisterEventsServer(grpcServer, rpcevents.NewEventsServer(rpc.NewSubscriptions(service)))
 
-				pbevents.RegisterExecutionEventsServer(grpcServer, rpcevents.NewExecutionEventsServer())
+				pbevents.RegisterExecutionEventsServer(grpcServer, rpcevents.NewExecutionEventsServer(state))
 
 				go grpcServer.Serve(listen)
 
@@ -263,8 +265,9 @@ func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_t
 		Emitter:        emitter,
 		Service:        service,
 		Launchers:      launchers,
-		processes:      make(map[string]process.Process),
+		State:          state,
 		Logger:         logger,
+		processes:      make(map[string]process.Process),
 		shutdownNotify: make(chan struct{}),
 	}, nil
 }
diff --git a/event/cache.go b/event/cache.go
index f2f4bfb61513b99c01cfbe49f5999a231f59b2db..28f6babc91150512b0be4e0d64b61943d138a150 100644
--- a/event/cache.go
+++ b/event/cache.go
@@ -13,6 +13,11 @@ type Cache struct {
 	events []messageInfo
 }
 
+// If message implement this interface we will provide them with an index in the cache
+type Indexable interface {
+	ProvideIndex(index uint64)
+}
+
 var _ Publisher = &Cache{}
 
 // Create a new Cache with an EventSwitch as backend
@@ -26,15 +31,15 @@ type messageInfo struct {
 	// empty context
 	ctx     context.Context
 	message interface{}
-	tags    map[string]interface{}
+	tags    Tags
 }
 
 // Cache an event to be fired upon finality.
-func (evc *Cache) Publish(ctx context.Context, message interface{}, tags map[string]interface{}) error {
+func (evc *Cache) Publish(ctx context.Context, message interface{}, tags Tags) error {
 	// append to list (go will grow our backing array exponentially)
 	evc.events = append(evc.events, messageInfo{
 		ctx:     ctx,
-		message: message,
+		message: evc.provideIndex(message),
 		tags:    tags,
 	})
 	return nil
@@ -74,3 +79,10 @@ func (evc *Cache) Reset() {
 		evc.events = evc.events[:0]
 	}
 }
+
+func (evc *Cache) provideIndex(message interface{}) interface{} {
+	if im, ok := message.(Indexable); ok {
+		im.ProvideIndex(uint64(len(evc.events)))
+	}
+	return message
+}
diff --git a/event/cache_test.go b/event/cache_test.go
index e67dba9e8070240712702fb7a6bbf210aba6c230..90d5e33c86496152ca93b6769ef501227c56a9cb 100644
--- a/event/cache_test.go
+++ b/event/cache_test.go
@@ -6,6 +6,7 @@ import (
 	"testing"
 	"time"
 
+	"github.com/hyperledger/burrow/event/query"
 	"github.com/hyperledger/burrow/logging"
 	"github.com/stretchr/testify/assert"
 )
@@ -18,7 +19,7 @@ func TestEventCache_Flush(t *testing.T) {
 	flushed := false
 
 	em := NewEmitter(logging.NewNoopLogger())
-	SubscribeCallback(ctx, em, "nothingness", NewQueryBuilder(), func(message interface{}) bool {
+	SubscribeCallback(ctx, em, "nothingness", query.NewBuilder(), func(message interface{}) bool {
 		// Check against sending a buffer of zeroed messages
 		if message == nil {
 			errCh <- fmt.Errorf("recevied empty message but none sent")
@@ -29,7 +30,7 @@ func TestEventCache_Flush(t *testing.T) {
 	evc.Flush(em)
 	// Check after reset
 	evc.Flush(em)
-	SubscribeCallback(ctx, em, "somethingness", NewQueryBuilder().AndEquals("foo", "bar"),
+	SubscribeCallback(ctx, em, "somethingness", query.NewBuilder().AndEquals("foo", "bar"),
 		func(interface{}) bool {
 			if flushed {
 				errCh <- nil
@@ -41,7 +42,7 @@ func TestEventCache_Flush(t *testing.T) {
 		})
 
 	numMessages := 3
-	tags := map[string]interface{}{"foo": "bar"}
+	tags := TagMap{"foo": "bar"}
 	for i := 0; i < numMessages; i++ {
 		evc.Publish(ctx, fmt.Sprintf("something_%v", i), tags)
 	}
diff --git a/event/convention.go b/event/convention.go
index 33a66a501f7e686898ecbaf86654ce8eb601ee52..5e0f9efa960e25842094609594250d9198f0ef60 100644
--- a/event/convention.go
+++ b/event/convention.go
@@ -2,44 +2,39 @@ package event
 
 import (
 	"context"
-	"fmt"
-	"reflect"
+
+	"github.com/hyperledger/burrow/event/query"
 )
 
 const (
+	EventTypeKey   = "EventType"
 	EventIDKey     = "EventID"
 	MessageTypeKey = "MessageType"
 	TxTypeKey      = "TxType"
 	TxHashKey      = "TxHash"
+	HeightKey      = "Height"
+	IndexKey       = "Index"
+	NameKey        = "Name"
+	PermissionKey  = "Permission"
 	StackDepthKey  = "StackDepth"
+	AddressKey     = "Address"
+	OriginKey      = "Origin"
+	CalleeKey      = "Callee"
+	CallerKey      = "Caller"
+	ValueKey       = "Value"
+	GasKey         = "Gas"
+	ExceptionKey   = "Exception"
 )
 
 // Get a query that matches events with a specific eventID
-func QueryForEventID(eventID string) *QueryBuilder {
+func QueryForEventID(eventID string) *query.Builder {
 	// Since we're accepting external output here there is a chance it won't parse...
-	return NewQueryBuilder().AndEquals(EventIDKey, eventID)
-}
-
-func PublishWithEventID(publisher Publisher, eventID string, eventData interface{},
-	extraTags map[string]interface{}) error {
-
-	if extraTags[EventIDKey] != nil {
-		return fmt.Errorf("PublishWithEventID was passed the extraTags with %s already set: %s = '%s'",
-			EventIDKey, EventIDKey, eventID)
-	}
-	tags := map[string]interface{}{
-		EventIDKey:     eventID,
-		MessageTypeKey: reflect.TypeOf(eventData).String(),
-	}
-	for k, v := range extraTags {
-		tags[k] = v
-	}
-	return publisher.Publish(context.Background(), eventData, tags)
+	return query.NewBuilder().AndEquals(EventIDKey, eventID)
 }
 
 // Subscribe to messages matching query and launch a goroutine to run a callback for each one. The goroutine will exit
 // when the context is done or the subscription is removed.
-func SubscribeCallback(ctx context.Context, subscribable Subscribable, subscriber string, query Queryable,
+func SubscribeCallback(ctx context.Context, subscribable Subscribable, subscriber string, queryable query.Queryable,
 	callback func(message interface{}) bool) error {
 
 	out := make(chan interface{})
@@ -47,7 +42,7 @@ func SubscribeCallback(ctx context.Context, subscribable Subscribable, subscribe
 		for msg := range out {
 			if !callback(msg) {
 				// Callback is requesting stop so unsubscribe and drain channel
-				subscribable.Unsubscribe(context.Background(), subscriber, query)
+				subscribable.Unsubscribe(context.Background(), subscriber, queryable)
 				// Not draining channel can starve other subscribers
 				for range out {
 				}
@@ -55,7 +50,7 @@ func SubscribeCallback(ctx context.Context, subscribable Subscribable, subscribe
 			}
 		}
 	}()
-	err := subscribable.Subscribe(ctx, subscriber, query, out)
+	err := subscribable.Subscribe(ctx, subscriber, queryable, out)
 	if err != nil {
 		// To clean up goroutine - otherwise subscribable should close channel for us
 		close(out)
@@ -63,16 +58,16 @@ func SubscribeCallback(ctx context.Context, subscribable Subscribable, subscribe
 	return err
 }
 
-func PublishAll(ctx context.Context, subscribable Subscribable, subscriber string, query Queryable,
+func PublishAll(ctx context.Context, subscribable Subscribable, subscriber string, queryable query.Queryable,
 	publisher Publisher, extraTags map[string]interface{}) error {
 
-	return SubscribeCallback(ctx, subscribable, subscriber, query, func(message interface{}) bool {
+	return SubscribeCallback(ctx, subscribable, subscriber, queryable, func(message interface{}) bool {
 		tags := make(map[string]interface{})
 		for k, v := range extraTags {
 			tags[k] = v
 		}
 		// Help! I can't tell which tags the original publisher used - so I can't forward them on
-		publisher.Publish(ctx, message, tags)
+		publisher.Publish(ctx, message, TagMap(tags))
 		return true
 	})
 }
diff --git a/event/convention_test.go b/event/convention_test.go
index 35c8f7d675cc2ddb870893b5545955e4d1b3d451..3fa5a0401cc5a4e4c38338d717e5ba81d469e841 100644
--- a/event/convention_test.go
+++ b/event/convention_test.go
@@ -5,6 +5,7 @@ import (
 	"testing"
 	"time"
 
+	"github.com/hyperledger/burrow/event/query"
 	"github.com/hyperledger/burrow/logging"
 	"github.com/stretchr/testify/assert"
 )
@@ -13,7 +14,7 @@ func TestSubscribeCallback(t *testing.T) {
 	ctx := context.Background()
 	em := NewEmitter(logging.NewNoopLogger())
 	ch := make(chan interface{})
-	SubscribeCallback(ctx, em, "TestSubscribeCallback", MatchAllQueryable(), func(msg interface{}) bool {
+	SubscribeCallback(ctx, em, "TestSubscribeCallback", query.MatchAllQueryable(), func(msg interface{}) bool {
 		ch <- msg
 		return true
 	})
diff --git a/event/emitter.go b/event/emitter.go
index 738104fdea49cdd1b1f15e8709257fa887862e60..597cb4f13010c8b8b98dd37a7b05630230d9c5ec 100644
--- a/event/emitter.go
+++ b/event/emitter.go
@@ -21,6 +21,7 @@ import (
 	"fmt"
 	"strings"
 
+	"github.com/hyperledger/burrow/event/query"
 	"github.com/hyperledger/burrow/logging"
 	"github.com/hyperledger/burrow/logging/structure"
 	"github.com/hyperledger/burrow/process"
@@ -32,14 +33,14 @@ const DefaultEventBufferCapacity = 2 << 10
 
 type Subscribable interface {
 	// Subscribe to all events matching query, which is a valid tmlibs Query
-	Subscribe(ctx context.Context, subscriber string, query Queryable, out chan<- interface{}) error
+	Subscribe(ctx context.Context, subscriber string, queryable query.Queryable, out chan<- interface{}) error
 	// Unsubscribe subscriber from a specific query string
-	Unsubscribe(ctx context.Context, subscriber string, query Queryable) error
+	Unsubscribe(ctx context.Context, subscriber string, queryable query.Queryable) error
 	UnsubscribeAll(ctx context.Context, subscriber string) error
 }
 
 type Publisher interface {
-	Publish(ctx context.Context, message interface{}, tags map[string]interface{}) error
+	Publish(ctx context.Context, message interface{}, tag Tags) error
 }
 
 type PublisherFunc func(ctx context.Context, message interface{}, tags map[string]interface{}) error
@@ -77,21 +78,21 @@ func (em *emitter) Shutdown(ctx context.Context) error {
 }
 
 // Publisher
-func (em *emitter) Publish(ctx context.Context, message interface{}, tags map[string]interface{}) error {
-	return em.pubsubServer.PublishWithTags(ctx, message, tagMap(tags))
+func (em *emitter) Publish(ctx context.Context, message interface{}, tags Tags) error {
+	return em.pubsubServer.PublishWithTags(ctx, message, tags)
 }
 
 // Subscribable
-func (em *emitter) Subscribe(ctx context.Context, subscriber string, query Queryable, out chan<- interface{}) error {
-	pubsubQuery, err := query.Query()
+func (em *emitter) Subscribe(ctx context.Context, subscriber string, queryable query.Queryable, out chan<- interface{}) error {
+	pubsubQuery, err := queryable.Query()
 	if err != nil {
 		return nil
 	}
 	return em.pubsubServer.Subscribe(ctx, subscriber, pubsubQuery, out)
 }
 
-func (em *emitter) Unsubscribe(ctx context.Context, subscriber string, query Queryable) error {
-	pubsubQuery, err := query.Query()
+func (em *emitter) Unsubscribe(ctx context.Context, subscriber string, queryable query.Queryable) error {
+	pubsubQuery, err := queryable.Query()
 	if err != nil {
 		return nil
 	}
@@ -110,7 +111,7 @@ func NewNoOpPublisher() Publisher {
 type noOpPublisher struct {
 }
 
-func (nop *noOpPublisher) Publish(ctx context.Context, message interface{}, tags map[string]interface{}) error {
+func (nop *noOpPublisher) Publish(ctx context.Context, message interface{}, tags Tags) error {
 	return nil
 }
 
@@ -127,11 +128,3 @@ func GenerateSubscriptionID() (string, error) {
 	rStr := hex.EncodeToString(b)
 	return strings.ToUpper(rStr), nil
 }
-
-func tagMap(tags map[string]interface{}) pubsub.TagMap {
-	mp := make(map[string]string, len(tags))
-	for k, v := range tags {
-		mp[k] = structure.StringifyKey(v)
-	}
-	return pubsub.NewTagMap(mp)
-}
diff --git a/event/emitter_test.go b/event/emitter_test.go
index d9709d6d62bf432f8b2161564d9ffd0e7663e1e0..8325456db81515e406e6705e962ce362b1b110d1 100644
--- a/event/emitter_test.go
+++ b/event/emitter_test.go
@@ -5,6 +5,7 @@ import (
 	"testing"
 	"time"
 
+	"github.com/hyperledger/burrow/event/query"
 	"github.com/hyperledger/burrow/logging"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
@@ -15,15 +16,15 @@ func TestEmitter(t *testing.T) {
 	ctx := context.Background()
 	out := make(chan interface{})
 
-	err := em.Subscribe(ctx, "TestEmitter", NewQueryBuilder().AndStrictlyGreaterThan("foo", 10), out)
+	err := em.Subscribe(ctx, "TestEmitter", query.NewBuilder().AndStrictlyGreaterThan("foo", 10), out)
 	require.NoError(t, err)
 
 	msgMiss := struct{ flob string }{"flib"}
-	err = em.Publish(ctx, msgMiss, map[string]interface{}{"foo": 10})
+	err = em.Publish(ctx, msgMiss, TagMap(map[string]interface{}{"foo": 10}))
 	assert.NoError(t, err)
 
 	msgHit := struct{ blib string }{"blab"}
-	err = em.Publish(ctx, msgHit, map[string]interface{}{"foo": 11})
+	err = em.Publish(ctx, msgHit, TagMap(map[string]interface{}{"foo": 11}))
 	assert.NoError(t, err)
 
 	select {
@@ -39,14 +40,14 @@ func TestOrdering(t *testing.T) {
 	ctx := context.Background()
 	out := make(chan interface{})
 
-	err := em.Subscribe(ctx, "TestOrdering1", NewQueryBuilder().AndEquals("foo", "bar"), out)
+	err := em.Subscribe(ctx, "TestOrdering1", query.NewBuilder().AndEquals("foo", "bar"), out)
 	require.NoError(t, err)
 
-	err = em.Subscribe(ctx, "TestOrdering2", NewQueryBuilder().AndEquals("foo", "baz"), out)
+	err = em.Subscribe(ctx, "TestOrdering2", query.NewBuilder().AndEquals("foo", "baz"), out)
 	require.NoError(t, err)
 
-	barTag := map[string]interface{}{"foo": "bar"}
-	bazTag := map[string]interface{}{"foo": "baz"}
+	barTag := TagMap{"foo": "bar"}
+	bazTag := TagMap{"foo": "baz"}
 
 	msgs := [][]interface{}{
 		{"baz1", bazTag},
@@ -60,7 +61,7 @@ func TestOrdering(t *testing.T) {
 
 	go func() {
 		for _, msg := range msgs {
-			em.Publish(ctx, msg[0], msg[1].(map[string]interface{}))
+			em.Publish(ctx, msg[0], msg[1].(TagMap))
 		}
 		em.Publish(ctx, "stop", bazTag)
 	}()
diff --git a/event/query/empty.go b/event/query/empty.go
new file mode 100644
index 0000000000000000000000000000000000000000..c83169e18b5224a178d6812439393bac69231dd2
--- /dev/null
+++ b/event/query/empty.go
@@ -0,0 +1,13 @@
+package query
+
+import (
+	"github.com/tendermint/tendermint/libs/pubsub"
+	"github.com/tendermint/tendermint/libs/pubsub/query"
+)
+
+// Matches everything
+type Empty query.Empty
+
+func (Empty) Query() (pubsub.Query, error) {
+	return query.Empty{}, nil
+}
diff --git a/event/query.go b/event/query/query.go
similarity index 53%
rename from event/query.go
rename to event/query/query.go
index 41f4ca712753e7f0d8fbf5ae852ce4e47984658f..a6d6969d239df2ebe010e690bec28d28e40fe403 100644
--- a/event/query.go
+++ b/event/query/query.go
@@ -1,4 +1,4 @@
-package event
+package query
 
 import (
 	"bytes"
@@ -34,9 +34,9 @@ type Queryable interface {
 }
 
 // A yet-to-parsed query
-type QueryString string
+type String string
 
-func (qs QueryString) Query() (pubsub.Query, error) {
+func (qs String) Query() (pubsub.Query, error) {
 	if isEmpty(string(qs)) {
 		return query.Empty{}, nil
 	}
@@ -61,7 +61,7 @@ func (q Query) Query() (pubsub.Query, error) {
 }
 
 // A fluent query builder
-type QueryBuilder struct {
+type Builder struct {
 	queryString string
 	condition
 	// reusable buffer for building queryString
@@ -79,17 +79,17 @@ type condition struct {
 var conditionTemplate = template.Must(template.New("condition").Parse("{{.Tag}} {{.Op}} {{.Operand}}"))
 
 // Creates a new query builder with a base query that is the conjunction of all queries passed
-func NewQueryBuilder(queries ...string) *QueryBuilder {
-	qb := new(QueryBuilder)
+func NewBuilder(queries ...string) *Builder {
+	qb := new(Builder)
 	qb.queryString = qb.and(stringIterator(queries...))
 	return qb
 }
 
-func (qb *QueryBuilder) String() string {
+func (qb *Builder) String() string {
 	return qb.queryString
 }
 
-func (qb *QueryBuilder) Query() (pubsub.Query, error) {
+func (qb *Builder) Query() (pubsub.Query, error) {
 	if qb.error != nil {
 		return nil, qb.error
 	}
@@ -99,55 +99,55 @@ func (qb *QueryBuilder) Query() (pubsub.Query, error) {
 	return query.New(qb.String())
 }
 
-// Creates the conjunction of QueryBuilder and rightQuery
-func (qb *QueryBuilder) And(queryBuilders ...*QueryBuilder) *QueryBuilder {
-	return NewQueryBuilder(qb.and(queryBuilderIterator(queryBuilders...)))
+// Creates the conjunction of Builder and rightQuery
+func (qb *Builder) And(queryBuilders ...*Builder) *Builder {
+	return NewBuilder(qb.and(queryBuilderIterator(queryBuilders...)))
 }
 
-// Creates the conjunction of QueryBuilder and tag = operand
-func (qb *QueryBuilder) AndEquals(tag string, operand interface{}) *QueryBuilder {
+// Creates the conjunction of Builder and tag = operand
+func (qb *Builder) AndEquals(tag string, operand interface{}) *Builder {
 	qb.condition.Tag = tag
 	qb.condition.Op = equalString
-	qb.condition.Operand = qb.operand(operand)
-	return NewQueryBuilder(qb.and(stringIterator(qb.conditionString())))
+	qb.condition.Operand = operandString(operand)
+	return NewBuilder(qb.and(stringIterator(qb.conditionString())))
 }
 
-func (qb *QueryBuilder) AndGreaterThanOrEqual(tag string, operand interface{}) *QueryBuilder {
+func (qb *Builder) AndGreaterThanOrEqual(tag string, operand interface{}) *Builder {
 	qb.condition.Tag = tag
 	qb.condition.Op = greaterOrEqualString
-	qb.condition.Operand = qb.operand(operand)
-	return NewQueryBuilder(qb.and(stringIterator(qb.conditionString())))
+	qb.condition.Operand = operandString(operand)
+	return NewBuilder(qb.and(stringIterator(qb.conditionString())))
 }
 
-func (qb *QueryBuilder) AndLessThanOrEqual(tag string, operand interface{}) *QueryBuilder {
+func (qb *Builder) AndLessThanOrEqual(tag string, operand interface{}) *Builder {
 	qb.condition.Tag = tag
 	qb.condition.Op = lessOrEqualString
-	qb.condition.Operand = qb.operand(operand)
-	return NewQueryBuilder(qb.and(stringIterator(qb.conditionString())))
+	qb.condition.Operand = operandString(operand)
+	return NewBuilder(qb.and(stringIterator(qb.conditionString())))
 }
 
-func (qb *QueryBuilder) AndStrictlyGreaterThan(tag string, operand interface{}) *QueryBuilder {
+func (qb *Builder) AndStrictlyGreaterThan(tag string, operand interface{}) *Builder {
 	qb.condition.Tag = tag
 	qb.condition.Op = greaterThanString
-	qb.condition.Operand = qb.operand(operand)
-	return NewQueryBuilder(qb.and(stringIterator(qb.conditionString())))
+	qb.condition.Operand = operandString(operand)
+	return NewBuilder(qb.and(stringIterator(qb.conditionString())))
 }
 
-func (qb *QueryBuilder) AndStrictlyLessThan(tag string, operand interface{}) *QueryBuilder {
+func (qb *Builder) AndStrictlyLessThan(tag string, operand interface{}) *Builder {
 	qb.condition.Tag = tag
 	qb.condition.Op = lessThanString
-	qb.condition.Operand = qb.operand(operand)
-	return NewQueryBuilder(qb.and(stringIterator(qb.conditionString())))
+	qb.condition.Operand = operandString(operand)
+	return NewBuilder(qb.and(stringIterator(qb.conditionString())))
 }
 
-func (qb *QueryBuilder) AndContains(tag string, operand interface{}) *QueryBuilder {
+func (qb *Builder) AndContains(tag string, operand interface{}) *Builder {
 	qb.condition.Tag = tag
 	qb.condition.Op = containsString
-	qb.condition.Operand = qb.operand(operand)
-	return NewQueryBuilder(qb.and(stringIterator(qb.conditionString())))
+	qb.condition.Operand = operandString(operand)
+	return NewBuilder(qb.and(stringIterator(qb.conditionString())))
 }
 
-func (qb *QueryBuilder) and(queryIterator func(func(string))) string {
+func (qb *Builder) and(queryIterator func(func(string))) string {
 	defer qb.Buffer.Reset()
 	qb.Buffer.WriteString(qb.queryString)
 	queryIterator(func(q string) {
@@ -163,44 +163,56 @@ func (qb *QueryBuilder) and(queryIterator func(func(string))) string {
 	return qb.Buffer.String()
 }
 
-func (qb *QueryBuilder) operand(operand interface{}) string {
-	defer qb.Buffer.Reset()
-	switch oper := operand.(type) {
+func operandString(value interface{}) string {
+	buf := new(bytes.Buffer)
+	switch v := value.(type) {
+	case string:
+		buf.WriteByte('\'')
+		buf.WriteString(v)
+		buf.WriteByte('\'')
+		return buf.String()
+	case fmt.Stringer:
+		return operandString(v.String())
+	default:
+		return StringFromValue(v)
+	}
+}
+
+func StringFromValue(value interface{}) string {
+	switch v := value.(type) {
 	case string:
-		qb.Buffer.WriteByte('\'')
-		qb.Buffer.WriteString(oper)
-		qb.Buffer.WriteByte('\'')
-		return qb.Buffer.String()
+		return v
 	case fmt.Stringer:
-		return qb.operand(oper.String())
+		return v.String()
 	case bool:
-		if oper {
+		if v {
 			return trueString
 		}
 		return falseString
 	case int:
-		return strconv.FormatInt(int64(oper), 10)
+		return strconv.FormatInt(int64(v), 10)
+	case int32:
+		return strconv.FormatInt(int64(v), 10)
 	case int64:
-		return strconv.FormatInt(oper, 10)
+		return strconv.FormatInt(v, 10)
 	case uint:
-		return strconv.FormatUint(uint64(oper), 10)
+		return strconv.FormatUint(uint64(v), 10)
+	case uint32:
+		return strconv.FormatUint(uint64(v), 10)
 	case uint64:
-		return strconv.FormatUint(oper, 10)
+		return strconv.FormatUint(v, 10)
 	case float32:
-		return strconv.FormatFloat(float64(oper), 'f', -1, 32)
+		return strconv.FormatFloat(float64(v), 'f', -1, 32)
 	case float64:
-		return strconv.FormatFloat(float64(oper), 'f', -1, 64)
+		return strconv.FormatFloat(float64(v), 'f', -1, 64)
 	case time.Time:
-		qb.Buffer.WriteString(timeString)
-		qb.Buffer.WriteByte(' ')
-		qb.Buffer.WriteString(oper.Format(time.RFC3339))
-		return qb.Buffer.String()
+		return timeString + " " + v.Format(time.RFC3339)
 	default:
-		return fmt.Sprintf("%v", oper)
+		return fmt.Sprintf("%v", v)
 	}
 }
 
-func (qb *QueryBuilder) conditionString() string {
+func (qb *Builder) conditionString() string {
 	defer qb.Buffer.Reset()
 	err := conditionTemplate.Execute(&qb.Buffer, qb.condition)
 	if err != nil && qb.error == nil {
@@ -222,7 +234,7 @@ func stringIterator(strs ...string) func(func(string)) {
 	}
 }
 
-func queryBuilderIterator(qbs ...*QueryBuilder) func(func(string)) {
+func queryBuilderIterator(qbs ...*Builder) func(func(string)) {
 	return func(callback func(string)) {
 		for _, qb := range qbs {
 			callback(qb.String())
diff --git a/event/query_test.go b/event/query/query_test.go
similarity index 91%
rename from event/query_test.go
rename to event/query/query_test.go
index 35e9b36a791785e52ebeebd869d9809cc9e21a1a..a7116b0a8b43c50e2099f82b6ede2178fa22bcdc 100644
--- a/event/query_test.go
+++ b/event/query/query_test.go
@@ -1,4 +1,4 @@
-package event
+package query
 
 import (
 	"testing"
@@ -10,7 +10,7 @@ import (
 )
 
 func TestQueryBuilder(t *testing.T) {
-	qb := NewQueryBuilder()
+	qb := NewBuilder()
 	qry, err := qb.Query()
 	require.NoError(t, err)
 	assert.Equal(t, emptyString, qry.String())
@@ -37,8 +37,8 @@ func TestQueryBuilder(t *testing.T) {
 	assert.True(t, qry.Matches(makeTagMap("foo.size", 80, "bar.name", "marmot", "bar.desc", "lives in a burrow")))
 	assert.False(t, qry.Matches(makeTagMap("foo.size", 80, "bar.name", "marmot", "bar.desc", "lives in a shoe")))
 
-	qb = NewQueryBuilder().AndEquals("foo", "bar")
-	qb = qb.And(NewQueryBuilder().AndGreaterThanOrEqual("frogs", 4))
+	qb = NewBuilder().AndEquals("foo", "bar")
+	qb = qb.And(NewBuilder().AndGreaterThanOrEqual("frogs", 4))
 	qry, err = qb.Query()
 	require.NoError(t, err)
 	assert.Equal(t, "foo = 'bar' AND frogs >= 4", qry.String())
diff --git a/event/tags.go b/event/tags.go
new file mode 100644
index 0000000000000000000000000000000000000000..00e76c0dfdfe07331c360fd8e64df67c985485ef
--- /dev/null
+++ b/event/tags.go
@@ -0,0 +1,88 @@
+package event
+
+import (
+	"fmt"
+
+	"github.com/tendermint/tendermint/libs/pubsub"
+)
+
+type Tags interface {
+	pubsub.TagMap
+	Map() map[string]interface{}
+	Keys() []string
+}
+
+type TagMap map[string]interface{}
+
+func (ts TagMap) Get(key string) (value string, ok bool) {
+	var vint interface{}
+	vint, ok = ts[key]
+	if !ok {
+		return
+	}
+	switch v := vint.(type) {
+	case string:
+		value = v
+	case fmt.Stringer:
+		value = v.String()
+	default:
+		value = fmt.Sprintf("%v", v)
+	}
+	return
+}
+
+func (ts TagMap) Len() int {
+	return len(ts)
+}
+
+func (ts TagMap) Map() map[string]interface{} {
+	return ts
+}
+
+func (ts TagMap) Keys() []string {
+	keys := make([]string, 0, len(ts))
+	for k := range ts {
+		keys = append(keys, k)
+	}
+	return keys
+}
+
+type CombinedTags []Tags
+
+func (ct CombinedTags) Get(key string) (value string, ok bool) {
+	for _, t := range ct {
+		value, ok = t.Get(key)
+		if ok {
+			return
+		}
+	}
+	return
+}
+
+func (ct CombinedTags) Len() (length int) {
+	for _, t := range ct {
+		length += t.Len()
+	}
+	return length
+}
+
+func (ct CombinedTags) Map() map[string]interface{} {
+	tags := make(map[string]interface{})
+	for _, t := range ct {
+		for _, k := range t.Keys() {
+			v, ok := t.Get(k)
+			if ok {
+				tags[k] = v
+			}
+		}
+	}
+	return tags
+}
+
+func (ct CombinedTags) Keys() []string {
+	var keys []string
+	for _, t := range ct {
+		keys = append(keys, t.Keys()...)
+	}
+	return keys
+}
diff --git a/execution/errors/errors.go b/execution/errors/errors.go
index f4c96e8054a83d716ec23210db77321269695b68..ba15497f0212b37909f772f9b2f321a89ef08567 100644
--- a/execution/errors/errors.go
+++ b/execution/errors/errors.go
@@ -32,6 +32,7 @@ const (
 	ErrorCodeExecutionReverted
 	ErrorCodePermissionDenied
 	ErrorCodeNativeFunction
+	ErrorCodeEventPublish
 )
 
 func (c Code) ErrorCode() Code {
@@ -74,6 +75,8 @@ func (c Code) Error() string {
 		return "Execution reverted"
 	case ErrorCodeNativeFunction:
 		return "Native function error"
+	case ErrorCodeEventPublish:
+		return "Event publish error"
 	case ErrorCodeGeneric:
 		return "Generic error"
 	default:
@@ -136,7 +139,7 @@ func (e *Exception) Error() string {
 	if e == nil {
 		return ""
 	}
-	return fmt.Sprintf("Error %v: %s", e.Code, e.Exception)
+	return fmt.Sprintf("Error %v: %s", e.Code.Code, e.Exception)
 }
 
 func NewErrorCode(code Code) *ErrorCode {
diff --git a/execution/events/call.go b/execution/events/call.go
index 1640faefa1456fc9d37891a9d9f23dbc68c4c235..b174b77c95de4190b666c2b76463a3be01a5739f 100644
--- a/execution/events/call.go
+++ b/execution/events/call.go
@@ -21,7 +21,9 @@ import (
 	"github.com/hyperledger/burrow/binary"
 	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/event"
+	"github.com/hyperledger/burrow/event/query"
 	"github.com/hyperledger/burrow/execution/errors"
+	"github.com/hyperledger/burrow/txs"
 	"github.com/tmthrgd/go-hex"
 )
 
@@ -33,7 +35,6 @@ func EventStringAccountCall(addr crypto.Address) string { return fmt.Sprintf("Ac
 
 // EventDataCall fires when we call a contract, and when a contract calls another contract
 type EventDataCall struct {
-	TxHash     binary.HexBytes
 	CallData   *CallData
 	Origin     crypto.Address
 	StackDepth uint64
@@ -49,21 +50,82 @@ type CallData struct {
 	Gas    uint64
 }
 
+var callTagKeys = []string{
+	event.CalleeKey,
+	event.CallerKey,
+	event.ValueKey,
+	event.GasKey,
+	event.StackDepthKey,
+	event.OriginKey,
+	event.ExceptionKey,
+}
+
+// Implements Tags for events
+func (call *EventDataCall) Get(key string) (string, bool) {
+	var value interface{}
+	switch key {
+	case event.CalleeKey:
+		value = call.CallData.Callee
+	case event.CallerKey:
+		value = call.CallData.Caller
+	case event.ValueKey:
+		value = call.CallData.Value
+	case event.GasKey:
+		value = call.CallData.Gas
+	case event.StackDepthKey:
+		value = call.StackDepth
+	case event.OriginKey:
+		value = call.Origin
+	case event.ExceptionKey:
+		value = call.Exception
+	default:
+		return "", false
+	}
+	return query.StringFromValue(value), true
+}
+
+func (call *EventDataCall) Len() int {
+	return len(callTagKeys)
+}
+
+func (call *EventDataCall) Map() map[string]interface{} {
+	tags := make(map[string]interface{})
+	for _, key := range callTagKeys {
+		tags[key], _ = call.Get(key)
+	}
+	return tags
+}
+
+func (call *EventDataCall) Keys() []string {
+	return callTagKeys
+}
+func (call *EventDataCall) Tags(tags map[string]interface{}) map[string]interface{} {
+	tags[event.CalleeKey] = call.CallData.Callee
+	tags[event.CallerKey] = call.CallData.Caller
+	tags[event.ValueKey] = call.CallData.Value
+	tags[event.GasKey] = call.CallData.Gas
+	tags[event.StackDepthKey] = call.StackDepth
+	tags[event.OriginKey] = call.Origin
+	if call.Exception != nil {
+		tags[event.ExceptionKey] = call.Exception
+	}
+	return tags
+}
+
 // Publish/Subscribe
-func PublishAccountCall(publisher event.Publisher, address crypto.Address, call *EventDataCall) error {
-
-	return event.PublishWithEventID(publisher, EventStringAccountCall(address),
-		&Event{
-			Header: &Header{
-				TxHash: call.TxHash,
-			},
-			Call: call,
+func PublishAccountCall(publisher event.Publisher, tx *txs.Tx, height uint64, call *EventDataCall) error {
+	eventID := EventStringAccountCall(call.CallData.Callee)
+	ev := &Event{
+		Header: &Header{
+			TxType:    tx.Type(),
+			TxHash:    tx.Hash(),
+			EventType: TypeCall,
+			EventID:   eventID,
+			Height:    height,
 		},
-		map[string]interface{}{
-			"address":           address,
-			event.TxHashKey:     hex.EncodeUpperToString(call.TxHash),
-			event.StackDepthKey: call.StackDepth,
-		})
+		Call: call,
+	}
+	return publisher.Publish(context.Background(), ev, ev.Tags())
 }
 
 // Subscribe to account call event - if TxHash is provided listens for a specifc Tx otherwise captures all, if
diff --git a/execution/events/event.go b/execution/events/event.go
index cd9f99fb973604f88bf8d9f1e59bad9db34ebf21..30255c33cb22514eec73a3e6bc660b848155fd77 100644
--- a/execution/events/event.go
+++ b/execution/events/event.go
@@ -1,12 +1,80 @@
 package events
 
-import "github.com/hyperledger/burrow/binary"
+import (
+	"fmt"
+
+	"reflect"
+
+	"github.com/hyperledger/burrow/event"
+	"github.com/hyperledger/burrow/event/query"
+	"github.com/hyperledger/burrow/txs"
+)
+
+var cdc = txs.NewAminoCodec()
+
+var eventMessageTag = event.TagMap{event.MessageTypeKey: reflect.TypeOf(&Event{}).String()}
+
+type Provider interface {
+	GetEvents(startBlock, finalBlock uint64, queryable query.Queryable) (<-chan *Event, error)
+}
 
 type Event struct {
 	Header *Header
 	Call   *EventDataCall `json:",omitempty"`
 	Log    *EventDataLog  `json:",omitempty"`
 	Tx     *EventDataTx   `json:",omitempty"`
+	tags   event.Tags
+}
+
+func DecodeEvent(bs []byte) (*Event, error) {
+	ev := new(Event)
+	err := cdc.UnmarshalBinary(bs, ev)
+	if err != nil {
+		return nil, err
+	}
+	return ev, nil
+}
+
+func (ev *Event) Encode() ([]byte, error) {
+	return cdc.MarshalBinary(ev)
+}
+
+func (ev *Event) Tags() event.Tags {
+	if ev.tags == nil {
+		ev.tags = event.CombinedTags{
+			ev.Header,
+			eventMessageTag,
+			ev.Tx,
+			ev.Call,
+			ev.Log,
+		}
+	}
+	return ev.tags
+}
+
+func (ev *Event) Get(key string) (value string, ok bool) {
+	return ev.Tags().Get(key)
+}
+
+func (ev *Event) Keys() []string {
+	return ev.Tags().Keys()
+}
+
+func (ev *Event) Len() int {
+	return ev.Tags().Len()
+}
+
+func (ev *Event) Map() map[string]interface{} {
+	return ev.Tags().Map()
+}
+
+// event.Cache will provide an index through this methods of Indexable
+func (ev *Event) ProvideIndex(index uint64) {
+	ev.Header.Index = index
+}
+
+func (ev *Event) String() string {
+	return fmt.Sprintf("%v", ev.Header)
 }
 
 func (ev *Event) GetTx() *EventDataTx {
@@ -29,9 +97,3 @@ func (ev *Event) GetLog() *EventDataLog {
 	}
 	return ev.Log
 }
-
-type Header struct {
-	TxHash binary.HexBytes
-	Height uint64
-	Index  uint64
-}
diff --git a/execution/events/event_test.go b/execution/events/event_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..562fb81775cdc99fd9d4454e2cf3077b78f1a5fc
--- /dev/null
+++ b/execution/events/event_test.go
@@ -0,0 +1,30 @@
+package events
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/tmthrgd/go-hex"
+)
+
+func TestHeader_Key(t *testing.T) {
+	h := &Header{
+		EventID: "Foos",
+		Height:  2345345232,
+		Index:   34,
+	}
+	key := h.Key()
+	keyString := hex.EncodeUpperToString(key)
+	assert.Equal(t, "000000008BCB20D00000000000000022", keyString)
+	assert.Len(t, keyString, 32, "should be 16 bytes")
+	assert.Equal(t, h.Height, key.Height())
+	assert.Equal(t, h.Index, key.Index())
+}
+
+func TestKey_IsSuccessorOf(t *testing.T) {
+	assert.True(t, NewKey(1, 0).IsSuccessorOf(NewKey(0, 1)))
+	assert.True(t, NewKey(100, 24).IsSuccessorOf(NewKey(100, 23)))
+	assert.False(t, NewKey(100, 23).IsSuccessorOf(NewKey(100, 25)))
+	assert.False(t, NewKey(1, 1).IsSuccessorOf(NewKey(0, 25)))
+	assert.True(t, NewKey(3, 0).IsSuccessorOf(NewKey(2, 0)))
+}
diff --git a/execution/events/header.go b/execution/events/header.go
new file mode 100644
index 0000000000000000000000000000000000000000..d5b09749b3c3bbbe3d57b1e6ea3f8800c81d0b5b
--- /dev/null
+++ b/execution/events/header.go
@@ -0,0 +1,76 @@
+package events
+
+import (
+	"fmt"
+
+	"github.com/hyperledger/burrow/binary"
+	"github.com/hyperledger/burrow/event"
+	"github.com/hyperledger/burrow/event/query"
+	"github.com/hyperledger/burrow/txs/payload"
+)
+
+type Header struct {
+	TxType    payload.Type
+	TxHash    binary.HexBytes
+	EventType Type
+	EventID   string
+	Height    uint64
+	Index     uint64
+}
+
+var headerTagKeys = []string{
+	event.TxTypeKey,
+	event.TxHashKey,
+	event.EventTypeKey,
+	event.EventIDKey,
+	event.HeightKey,
+	event.IndexKey,
+}
+
+// Implements Tags for events
+func (h *Header) Get(key string) (value string, ok bool) {
+	var v interface{}
+	switch key {
+	case event.TxTypeKey:
+		v = h.TxType
+	case event.TxHashKey:
+		v = h.TxHash
+	case event.EventTypeKey:
+		v = h.EventType
+	case event.EventIDKey:
+		v = h.EventID
+	case event.HeightKey:
+		v = h.Height
+	case event.IndexKey:
+		v = h.Index
+	default:
+		return "", false
+	}
+	return query.StringFromValue(v), true
+}
+
+func (h *Header) Len() int {
+	return len(headerTagKeys)
+}
+
+func (h *Header) Map() map[string]interface{} {
+	tags := make(map[string]interface{})
+	for _, key := range headerTagKeys {
+		tags[key], _ = h.Get(key)
+	}
+	return tags
+}
+
+func (h *Header) Keys() []string {
+	return headerTagKeys
+}
+
+// Returns a lexicographically sortable key encoding the height and index of this event
+func (h *Header) Key() Key {
+	return NewKey(h.Height, h.Index)
+}
+
+func (h *Header) String() string {
+	return fmt.Sprintf("Header{Tx{%v}: %v; Event{%v}: %v; Height: %v; Index: %v}",
+		h.TxType, h.TxHash, h.EventType, h.EventID, h.Height, h.Index)
+}
diff --git a/execution/events/key.go b/execution/events/key.go
new file mode 100644
index 0000000000000000000000000000000000000000..f78463e16d8f521ee4fdbf9dc3389b05b0443121
--- /dev/null
+++ b/execution/events/key.go
@@ -0,0 +1,53 @@
+package events
+
+import (
+	"bytes"
+	"fmt"
+
+	"github.com/hyperledger/burrow/binary"
+)
+
+type Key []byte
+
+func NewKey(height, index uint64) Key {
+	k := make(Key, 16)
+	// Will order first by height then by index so events from the same block will be consecutive
+	binary.PutUint64BE(k[:8], height)
+	binary.PutUint64BE(k[8:], index)
+	return k
+}
+
+// -1 if k < k2
+//  0 if k == k2
+//  1 if k > k2
+func (k Key) Compare(k2 Key) int {
+	return bytes.Compare(k, k2)
+}
+
+// Returns true iff k is a valid successor key to p;
+// iff (the height is the same and the index is one greater) or (the height is greater and the index is zero) or (p
+// is uninitialised)
+func (k Key) IsSuccessorOf(p Key) bool {
+	if len(p) == 0 {
+		return true
+	}
+	ph, kh := p.Height(), k.Height()
+	pi, ki := p.Index(), k.Index()
+	return ph == kh && pi+1 == ki || ph < kh && ki == 0
+}
+
+func (k Key) Bytes() []byte {
+	return k
+}
+
+func (k Key) Height() uint64 {
+	return binary.GetUint64BE(k[:8])
+}
+
+func (k Key) Index() uint64 {
+	return binary.GetUint64BE(k[8:])
+}
+
+func (k Key) String() string {
+	return fmt.Sprintf("Key{Height: %v; Index: %v}", k.Height(), k.Index())
+}
diff --git a/execution/events/log.go b/execution/events/log.go
index 1ad55c9e3d3cb46ef36505f8db6c6a27b78c63e4..500427d695bcc516253ca7bce018c040555828ea 100644
--- a/execution/events/log.go
+++ b/execution/events/log.go
@@ -22,6 +22,8 @@ import (
 	. "github.com/hyperledger/burrow/binary"
 	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/event"
+	"github.com/hyperledger/burrow/event/query"
+	"github.com/hyperledger/burrow/txs"
 )
 
 // Functions to generate eventId strings
@@ -32,24 +34,54 @@ func EventStringLogEvent(addr crypto.Address) string { return fmt.Sprintf("Log/%
 
 // EventDataLog fires when a contract executes the LOG opcode
 type EventDataLog struct {
-	TxHash  binary.HexBytes
+	Height  uint64
 	Address crypto.Address
 	Topics  []Word256
 	Data    binary.HexBytes
-	Height  uint64
+}
+
+var logTagKeys = []string{event.AddressKey}
+
+func (log *EventDataLog) Get(key string) (string, bool) {
+	var value interface{}
+	switch key {
+	case event.AddressKey:
+		value = log.Address
+	default:
+		return "", false
+	}
+	return query.StringFromValue(value), true
+}
+
+func (log *EventDataLog) Len() int {
+	return len(logTagKeys)
+}
+
+func (log *EventDataLog) Map() map[string]interface{} {
+	tags := make(map[string]interface{})
+	for _, key := range logTagKeys {
+		tags[key], _ = log.Get(key)
+	}
+	return tags
+}
+
+func (log *EventDataLog) Keys() []string {
+	return logTagKeys
 }
 
 // Publish/Subscribe
-func PublishLogEvent(publisher event.Publisher, address crypto.Address, log *EventDataLog) error {
-
-	return event.PublishWithEventID(publisher, EventStringLogEvent(address),
-		&Event{
-			Header: &Header{
-				TxHash: log.TxHash,
-			},
-			Log: log,
+func PublishLogEvent(publisher event.Publisher, tx *txs.Tx, log *EventDataLog) error {
+	ev := &Event{
+		Header: &Header{
+			TxType:    tx.Type(),
+			TxHash:    tx.Hash(),
+			EventType: TypeLog,
+			EventID:   EventStringLogEvent(log.Address),
+			Height:    log.Height,
 		},
-		map[string]interface{}{"address": address})
+		Log: log,
+	}
+	return publisher.Publish(context.Background(), ev, ev.Tags())
 }
 
 func SubscribeLogEvent(ctx context.Context, subscribable event.Subscribable, subscriber string, address crypto.Address,
diff --git a/execution/events/pbevents/blocks.go b/execution/events/pbevents/blocks.go
new file mode 100644
index 0000000000000000000000000000000000000000..e7977b8f63d0e426e4b49ace722ff13c150c1323
--- /dev/null
+++ b/execution/events/pbevents/blocks.go
@@ -0,0 +1,18 @@
+package pbevents
+
+func (br *BlockRange) Bounds() (start uint64, end uint64) {
+	return br.GetStart().GetIndex(), br.GetEnd().GetIndex()
+}
+
+func SimpleBlockRange(start, end uint64) *BlockRange {
+	return &BlockRange{
+		Start: &Bound{
+			Type:  Bound_ABSOLUTE,
+			Index: start,
+		},
+		End: &Bound{
+			Type:  Bound_ABSOLUTE,
+			Index: end,
+		},
+	}
+}
diff --git a/execution/events/pbevents/events.go b/execution/events/pbevents/events.go
index 99958308b8da9469f0b8e2cece979e6b83018db9..df28c3de689ac2b6330c39dec8d041c049b4a6b4 100644
--- a/execution/events/pbevents/events.go
+++ b/execution/events/pbevents/events.go
@@ -2,9 +2,14 @@ package pbevents
 
 import (
 	"github.com/hyperledger/burrow/binary"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/execution/events"
+	"github.com/hyperledger/burrow/txs/payload"
 )
 
+// this mostly contains tedious mapping between protobuf and our domain objects, but it may be worth
+// the pain to avoid complexity and edge cases using gogoproto or other techniques.
+
 func GetEventDataCall(edt *events.EventDataCall) *EventDataCall {
 	return &EventDataCall{
 		Origin:     edt.Origin.Bytes(),
@@ -24,23 +29,21 @@ func GetCallData(cd *events.CallData) *CallData {
 	}
 }
 
-func GetEvent(event interface{}) *ExecutionEvent {
-	switch ev := event.(type) {
-	case *events.Event:
-		return &ExecutionEvent{
-			Header:    GetEventHeader(ev.Header),
-			EventData: GetEventData(ev),
-		}
-	default:
-		return nil
+func GetEvent(event *events.Event) *ExecutionEvent {
+	return &ExecutionEvent{
+		Header:    GetEventHeader(event.Header),
+		EventData: GetEventData(event),
 	}
 }
 
 func GetEventHeader(header *events.Header) *EventHeader {
 	return &EventHeader{
-		TxHash: header.TxHash,
-		Height: header.Height,
-		Index:  header.Index,
+		TxType:    header.TxType.String(),
+		TxHash:    header.TxHash,
+		EventType: header.EventType.String(),
+		EventID:   header.EventID,
+		Height:    header.Height,
+		Index:     header.Index,
 	}
 }
 
@@ -86,3 +89,72 @@ func GetTopic(topics []binary.Word256) [][]byte {
 	}
 	return topicBytes
 }
+
+func (ee *ExecutionEvent) Event() *events.Event {
+	return &events.Event{
+		Header: ee.GetHeader().Header(),
+		Tx:     ee.GetEventDataTx().Tx(),
+		Log:    ee.GetEventDataLog().Log(ee.Header.Height),
+		Call:   ee.GetEventDataCall().Call(ee.Header.TxHash),
+	}
+}
+
+func (h *EventHeader) Header() *events.Header {
+	return &events.Header{
+		TxType:    payload.TxTypeFromString(h.TxType),
+		TxHash:    h.TxHash,
+		EventType: events.EventTypeFromString(h.EventType),
+		EventID:   h.EventID,
+		Height:    h.Height,
+		Index:     h.Index,
+	}
+}
+
+func (tx *EventDataTx) Tx() *events.EventDataTx {
+	if tx == nil {
+		return nil
+	}
+	return &events.EventDataTx{
+		Return:    tx.Return,
+		Exception: tx.Exception,
+	}
+}
+
+func (log *EventDataLog) Log(height uint64) *events.EventDataLog {
+	if log == nil {
+		return nil
+	}
+	topicWords := make([]binary.Word256, len(log.Topics))
+	for i, bs := range log.Topics {
+		topicWords[i] = binary.LeftPadWord256(bs)
+	}
+	return &events.EventDataLog{
+		Height:  height,
+		Topics:  topicWords,
+		Address: crypto.MustAddressFromBytes(log.Address),
+		Data:    log.Data,
+	}
+}
+
+func (call *EventDataCall) Call(txHash []byte) *events.EventDataCall {
+	if call == nil {
+		return nil
+	}
+	return &events.EventDataCall{
+		Return:     call.Return,
+		CallData:   call.CallData.CallData(),
+		Origin:     crypto.MustAddressFromBytes(call.Origin),
+		StackDepth: call.StackDepth,
+		Exception:  call.Exception,
+	}
+}
+
+func (cd *CallData) CallData() *events.CallData {
+	return &events.CallData{
+		Caller: crypto.MustAddressFromBytes(cd.Caller),
+		Callee: crypto.MustAddressFromBytes(cd.Callee),
+		Value:  cd.Value,
+		Gas:    cd.Gas,
+		Data:   cd.Data,
+	}
+}
diff --git a/execution/events/pbevents/events.pb.go b/execution/events/pbevents/events.pb.go
index c1c6c2c4735546356d25c83c6b53b4442f07f9a3..ab80044f12f892c1f470304bdb99cc358cf5ffdc 100644
--- a/execution/events/pbevents/events.pb.go
+++ b/execution/events/pbevents/events.pb.go
@@ -24,6 +24,39 @@ var _ = math.Inf
 // proto package needs to be updated.
 const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
 
+type Bound_BoundType int32
+
+const (
+	// Index is absolute index of object in collection
+	Bound_ABSOLUTE Bound_BoundType = 0
+	// Index is an offset reltiave to another bound determined by context
+	Bound_RELATIVE Bound_BoundType = 1
+	// Ignore provided index and evaluate to latest index
+	Bound_LATEST Bound_BoundType = 2
+	// Ignore provided index and stream new objects as they are generated
+	Bound_STREAM Bound_BoundType = 3
+)
+
+var Bound_BoundType_name = map[int32]string{
+	0: "ABSOLUTE",
+	1: "RELATIVE",
+	2: "LATEST",
+	3: "STREAM",
+}
+var Bound_BoundType_value = map[string]int32{
+	"ABSOLUTE": 0,
+	"RELATIVE": 1,
+	"LATEST":   2,
+	"STREAM":   3,
+}
+
+func (x Bound_BoundType) String() string {
+	return proto.EnumName(Bound_BoundType_name, int32(x))
+}
+func (Bound_BoundType) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_events_4b6532afacd9adee, []int{6, 0}
+}
+
 // Params
 type EventIdParam struct {
 	EventId              string   `protobuf:"bytes,1,opt,name=eventId,proto3" json:"eventId,omitempty"`
@@ -36,7 +69,7 @@ func (m *EventIdParam) Reset()         { *m = EventIdParam{} }
 func (m *EventIdParam) String() string { return proto.CompactTextString(m) }
 func (*EventIdParam) ProtoMessage()    {}
 func (*EventIdParam) Descriptor() ([]byte, []int) {
-	return fileDescriptor_events_6fac182aceb87b11, []int{0}
+	return fileDescriptor_events_4b6532afacd9adee, []int{0}
 }
 func (m *EventIdParam) XXX_Unmarshal(b []byte) error {
 	return xxx_messageInfo_EventIdParam.Unmarshal(m, b)
@@ -74,7 +107,7 @@ func (m *SubIdParam) Reset()         { *m = SubIdParam{} }
 func (m *SubIdParam) String() string { return proto.CompactTextString(m) }
 func (*SubIdParam) ProtoMessage()    {}
 func (*SubIdParam) Descriptor() ([]byte, []int) {
-	return fileDescriptor_events_6fac182aceb87b11, []int{1}
+	return fileDescriptor_events_4b6532afacd9adee, []int{1}
 }
 func (m *SubIdParam) XXX_Unmarshal(b []byte) error {
 	return xxx_messageInfo_SubIdParam.Unmarshal(m, b)
@@ -113,7 +146,7 @@ func (m *EventUnSub) Reset()         { *m = EventUnSub{} }
 func (m *EventUnSub) String() string { return proto.CompactTextString(m) }
 func (*EventUnSub) ProtoMessage()    {}
 func (*EventUnSub) Descriptor() ([]byte, []int) {
-	return fileDescriptor_events_6fac182aceb87b11, []int{2}
+	return fileDescriptor_events_4b6532afacd9adee, []int{2}
 }
 func (m *EventUnSub) XXX_Unmarshal(b []byte) error {
 	return xxx_messageInfo_EventUnSub.Unmarshal(m, b)
@@ -151,7 +184,7 @@ func (m *PollResponse) Reset()         { *m = PollResponse{} }
 func (m *PollResponse) String() string { return proto.CompactTextString(m) }
 func (*PollResponse) ProtoMessage()    {}
 func (*PollResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_events_6fac182aceb87b11, []int{3}
+	return fileDescriptor_events_4b6532afacd9adee, []int{3}
 }
 func (m *PollResponse) XXX_Unmarshal(b []byte) error {
 	return xxx_messageInfo_PollResponse.Unmarshal(m, b)
@@ -180,6 +213,8 @@ func (m *PollResponse) GetEvents() []*ExecutionEvent {
 
 type GetEventsRequest struct {
 	BlockRange           *BlockRange `protobuf:"bytes,1,opt,name=BlockRange,proto3" json:"BlockRange,omitempty"`
+	BatchSize            uint32      `protobuf:"varint,2,opt,name=BatchSize,proto3" json:"BatchSize,omitempty"`
+	Query                string      `protobuf:"bytes,3,opt,name=Query,proto3" json:"Query,omitempty"`
 	XXX_NoUnkeyedLiteral struct{}    `json:"-"`
 	XXX_unrecognized     []byte      `json:"-"`
 	XXX_sizecache        int32       `json:"-"`
@@ -189,7 +224,7 @@ func (m *GetEventsRequest) Reset()         { *m = GetEventsRequest{} }
 func (m *GetEventsRequest) String() string { return proto.CompactTextString(m) }
 func (*GetEventsRequest) ProtoMessage()    {}
 func (*GetEventsRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_events_6fac182aceb87b11, []int{4}
+	return fileDescriptor_events_4b6532afacd9adee, []int{4}
 }
 func (m *GetEventsRequest) XXX_Unmarshal(b []byte) error {
 	return xxx_messageInfo_GetEventsRequest.Unmarshal(m, b)
@@ -216,6 +251,20 @@ func (m *GetEventsRequest) GetBlockRange() *BlockRange {
 	return nil
 }
 
+func (m *GetEventsRequest) GetBatchSize() uint32 {
+	if m != nil {
+		return m.BatchSize
+	}
+	return 0
+}
+
+func (m *GetEventsRequest) GetQuery() string {
+	if m != nil {
+		return m.Query
+	}
+	return ""
+}
+
 type GetEventsResponse struct {
 	Events               []*ExecutionEvent `protobuf:"bytes,1,rep,name=events,proto3" json:"events,omitempty"`
 	XXX_NoUnkeyedLiteral struct{}          `json:"-"`
@@ -227,7 +276,7 @@ func (m *GetEventsResponse) Reset()         { *m = GetEventsResponse{} }
 func (m *GetEventsResponse) String() string { return proto.CompactTextString(m) }
 func (*GetEventsResponse) ProtoMessage()    {}
 func (*GetEventsResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_events_6fac182aceb87b11, []int{5}
+	return fileDescriptor_events_4b6532afacd9adee, []int{5}
 }
 func (m *GetEventsResponse) XXX_Unmarshal(b []byte) error {
 	return xxx_messageInfo_GetEventsResponse.Unmarshal(m, b)
@@ -254,10 +303,57 @@ func (m *GetEventsResponse) GetEvents() []*ExecutionEvent {
 	return nil
 }
 
+type Bound struct {
+	Type                 Bound_BoundType `protobuf:"varint,1,opt,name=Type,proto3,enum=pbevents.Bound_BoundType" json:"Type,omitempty"`
+	Index                uint64          `protobuf:"varint,2,opt,name=Index,proto3" json:"Index,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}        `json:"-"`
+	XXX_unrecognized     []byte          `json:"-"`
+	XXX_sizecache        int32           `json:"-"`
+}
+
+func (m *Bound) Reset()         { *m = Bound{} }
+func (m *Bound) String() string { return proto.CompactTextString(m) }
+func (*Bound) ProtoMessage()    {}
+func (*Bound) Descriptor() ([]byte, []int) {
+	return fileDescriptor_events_4b6532afacd9adee, []int{6}
+}
+func (m *Bound) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Bound.Unmarshal(m, b)
+}
+func (m *Bound) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Bound.Marshal(b, m, deterministic)
+}
+func (dst *Bound) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Bound.Merge(dst, src)
+}
+func (m *Bound) XXX_Size() int {
+	return xxx_messageInfo_Bound.Size(m)
+}
+func (m *Bound) XXX_DiscardUnknown() {
+	xxx_messageInfo_Bound.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Bound proto.InternalMessageInfo
+
+func (m *Bound) GetType() Bound_BoundType {
+	if m != nil {
+		return m.Type
+	}
+	return Bound_ABSOLUTE
+}
+
+func (m *Bound) GetIndex() uint64 {
+	if m != nil {
+		return m.Index
+	}
+	return 0
+}
+
 // An inclusive range of blocks to include
 type BlockRange struct {
-	StartBlock           uint64   `protobuf:"varint,1,opt,name=StartBlock,proto3" json:"StartBlock,omitempty"`
-	FinalBlock           uint64   `protobuf:"varint,2,opt,name=FinalBlock,proto3" json:"FinalBlock,omitempty"`
+	// How to interpret StartBlock
+	Start                *Bound   `protobuf:"bytes,1,opt,name=Start,proto3" json:"Start,omitempty"`
+	End                  *Bound   `protobuf:"bytes,2,opt,name=End,proto3" json:"End,omitempty"`
 	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 	XXX_unrecognized     []byte   `json:"-"`
 	XXX_sizecache        int32    `json:"-"`
@@ -267,7 +363,7 @@ func (m *BlockRange) Reset()         { *m = BlockRange{} }
 func (m *BlockRange) String() string { return proto.CompactTextString(m) }
 func (*BlockRange) ProtoMessage()    {}
 func (*BlockRange) Descriptor() ([]byte, []int) {
-	return fileDescriptor_events_6fac182aceb87b11, []int{6}
+	return fileDescriptor_events_4b6532afacd9adee, []int{7}
 }
 func (m *BlockRange) XXX_Unmarshal(b []byte) error {
 	return xxx_messageInfo_BlockRange.Unmarshal(m, b)
@@ -287,27 +383,33 @@ func (m *BlockRange) XXX_DiscardUnknown() {
 
 var xxx_messageInfo_BlockRange proto.InternalMessageInfo
 
-func (m *BlockRange) GetStartBlock() uint64 {
+func (m *BlockRange) GetStart() *Bound {
 	if m != nil {
-		return m.StartBlock
+		return m.Start
 	}
-	return 0
+	return nil
 }
 
-func (m *BlockRange) GetFinalBlock() uint64 {
+func (m *BlockRange) GetEnd() *Bound {
 	if m != nil {
-		return m.FinalBlock
+		return m.End
 	}
-	return 0
+	return nil
 }
 
 type EventHeader struct {
+	// Transaction type
+	TxType string `protobuf:"bytes,1,opt,name=TxType,proto3" json:"TxType,omitempty"`
 	// The hash of the transaction that caused this event to be generated
-	TxHash []byte `protobuf:"bytes,1,opt,name=TxHash,proto3" json:"TxHash,omitempty"`
+	TxHash []byte `protobuf:"bytes,2,opt,name=TxHash,proto3" json:"TxHash,omitempty"`
+	// The type of event
+	EventType string `protobuf:"bytes,3,opt,name=EventType,proto3" json:"EventType,omitempty"`
+	// EventID published with event
+	EventID string `protobuf:"bytes,4,opt,name=EventID,proto3" json:"EventID,omitempty"`
 	// The block height at which this event was emitted
-	Height uint64 `protobuf:"varint,2,opt,name=Height,proto3" json:"Height,omitempty"`
+	Height uint64 `protobuf:"varint,5,opt,name=Height,proto3" json:"Height,omitempty"`
 	// The index amongst all other events in the block of this event
-	Index                uint64   `protobuf:"varint,3,opt,name=Index,proto3" json:"Index,omitempty"`
+	Index                uint64   `protobuf:"varint,6,opt,name=Index,proto3" json:"Index,omitempty"`
 	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 	XXX_unrecognized     []byte   `json:"-"`
 	XXX_sizecache        int32    `json:"-"`
@@ -317,7 +419,7 @@ func (m *EventHeader) Reset()         { *m = EventHeader{} }
 func (m *EventHeader) String() string { return proto.CompactTextString(m) }
 func (*EventHeader) ProtoMessage()    {}
 func (*EventHeader) Descriptor() ([]byte, []int) {
-	return fileDescriptor_events_6fac182aceb87b11, []int{7}
+	return fileDescriptor_events_4b6532afacd9adee, []int{8}
 }
 func (m *EventHeader) XXX_Unmarshal(b []byte) error {
 	return xxx_messageInfo_EventHeader.Unmarshal(m, b)
@@ -337,6 +439,13 @@ func (m *EventHeader) XXX_DiscardUnknown() {
 
 var xxx_messageInfo_EventHeader proto.InternalMessageInfo
 
+func (m *EventHeader) GetTxType() string {
+	if m != nil {
+		return m.TxType
+	}
+	return ""
+}
+
 func (m *EventHeader) GetTxHash() []byte {
 	if m != nil {
 		return m.TxHash
@@ -344,6 +453,20 @@ func (m *EventHeader) GetTxHash() []byte {
 	return nil
 }
 
+func (m *EventHeader) GetEventType() string {
+	if m != nil {
+		return m.EventType
+	}
+	return ""
+}
+
+func (m *EventHeader) GetEventID() string {
+	if m != nil {
+		return m.EventID
+	}
+	return ""
+}
+
 func (m *EventHeader) GetHeight() uint64 {
 	if m != nil {
 		return m.Height
@@ -358,8 +481,6 @@ func (m *EventHeader) GetIndex() uint64 {
 	return 0
 }
 
-// --------------------------------------------------
-// Event types
 type ExecutionEvent struct {
 	Header *EventHeader `protobuf:"bytes,1,opt,name=Header,proto3" json:"Header,omitempty"`
 	// Types that are valid to be assigned to EventData:
@@ -376,7 +497,7 @@ func (m *ExecutionEvent) Reset()         { *m = ExecutionEvent{} }
 func (m *ExecutionEvent) String() string { return proto.CompactTextString(m) }
 func (*ExecutionEvent) ProtoMessage()    {}
 func (*ExecutionEvent) Descriptor() ([]byte, []int) {
-	return fileDescriptor_events_6fac182aceb87b11, []int{8}
+	return fileDescriptor_events_4b6532afacd9adee, []int{9}
 }
 func (m *ExecutionEvent) XXX_Unmarshal(b []byte) error {
 	return xxx_messageInfo_ExecutionEvent.Unmarshal(m, b)
@@ -555,7 +676,7 @@ func (m *EventDataLog) Reset()         { *m = EventDataLog{} }
 func (m *EventDataLog) String() string { return proto.CompactTextString(m) }
 func (*EventDataLog) ProtoMessage()    {}
 func (*EventDataLog) Descriptor() ([]byte, []int) {
-	return fileDescriptor_events_6fac182aceb87b11, []int{9}
+	return fileDescriptor_events_4b6532afacd9adee, []int{10}
 }
 func (m *EventDataLog) XXX_Unmarshal(b []byte) error {
 	return xxx_messageInfo_EventDataLog.Unmarshal(m, b)
@@ -608,7 +729,7 @@ func (m *EventDataTx) Reset()         { *m = EventDataTx{} }
 func (m *EventDataTx) String() string { return proto.CompactTextString(m) }
 func (*EventDataTx) ProtoMessage()    {}
 func (*EventDataTx) Descriptor() ([]byte, []int) {
-	return fileDescriptor_events_6fac182aceb87b11, []int{10}
+	return fileDescriptor_events_4b6532afacd9adee, []int{11}
 }
 func (m *EventDataTx) XXX_Unmarshal(b []byte) error {
 	return xxx_messageInfo_EventDataTx.Unmarshal(m, b)
@@ -657,7 +778,7 @@ func (m *EventDataCall) Reset()         { *m = EventDataCall{} }
 func (m *EventDataCall) String() string { return proto.CompactTextString(m) }
 func (*EventDataCall) ProtoMessage()    {}
 func (*EventDataCall) Descriptor() ([]byte, []int) {
-	return fileDescriptor_events_6fac182aceb87b11, []int{11}
+	return fileDescriptor_events_4b6532afacd9adee, []int{12}
 }
 func (m *EventDataCall) XXX_Unmarshal(b []byte) error {
 	return xxx_messageInfo_EventDataCall.Unmarshal(m, b)
@@ -727,7 +848,7 @@ func (m *CallData) Reset()         { *m = CallData{} }
 func (m *CallData) String() string { return proto.CompactTextString(m) }
 func (*CallData) ProtoMessage()    {}
 func (*CallData) Descriptor() ([]byte, []int) {
-	return fileDescriptor_events_6fac182aceb87b11, []int{12}
+	return fileDescriptor_events_4b6532afacd9adee, []int{13}
 }
 func (m *CallData) XXX_Unmarshal(b []byte) error {
 	return xxx_messageInfo_CallData.Unmarshal(m, b)
@@ -789,6 +910,7 @@ func init() {
 	proto.RegisterType((*PollResponse)(nil), "pbevents.PollResponse")
 	proto.RegisterType((*GetEventsRequest)(nil), "pbevents.GetEventsRequest")
 	proto.RegisterType((*GetEventsResponse)(nil), "pbevents.GetEventsResponse")
+	proto.RegisterType((*Bound)(nil), "pbevents.Bound")
 	proto.RegisterType((*BlockRange)(nil), "pbevents.BlockRange")
 	proto.RegisterType((*EventHeader)(nil), "pbevents.EventHeader")
 	proto.RegisterType((*ExecutionEvent)(nil), "pbevents.ExecutionEvent")
@@ -796,6 +918,7 @@ func init() {
 	proto.RegisterType((*EventDataTx)(nil), "pbevents.EventDataTx")
 	proto.RegisterType((*EventDataCall)(nil), "pbevents.EventDataCall")
 	proto.RegisterType((*CallData)(nil), "pbevents.CallData")
+	proto.RegisterEnum("pbevents.Bound_BoundType", Bound_BoundType_name, Bound_BoundType_value)
 }
 
 // Reference imports to suppress errors if they are not otherwise used.
@@ -940,7 +1063,7 @@ var _Events_serviceDesc = grpc.ServiceDesc{
 //
 // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
 type ExecutionEventsClient interface {
-	GetEvents(ctx context.Context, in *GetEventsRequest, opts ...grpc.CallOption) (*GetEventsResponse, error)
+	GetEvents(ctx context.Context, in *GetEventsRequest, opts ...grpc.CallOption) (ExecutionEvents_GetEventsClient, error)
 }
 
 type executionEventsClient struct {
@@ -951,103 +1074,139 @@ func NewExecutionEventsClient(cc *grpc.ClientConn) ExecutionEventsClient {
 	return &executionEventsClient{cc}
 }
 
-func (c *executionEventsClient) GetEvents(ctx context.Context, in *GetEventsRequest, opts ...grpc.CallOption) (*GetEventsResponse, error) {
-	out := new(GetEventsResponse)
-	err := c.cc.Invoke(ctx, "/pbevents.ExecutionEvents/GetEvents", in, out, opts...)
+func (c *executionEventsClient) GetEvents(ctx context.Context, in *GetEventsRequest, opts ...grpc.CallOption) (ExecutionEvents_GetEventsClient, error) {
+	stream, err := c.cc.NewStream(ctx, &_ExecutionEvents_serviceDesc.Streams[0], "/pbevents.ExecutionEvents/GetEvents", opts...)
 	if err != nil {
 		return nil, err
 	}
-	return out, nil
+	x := &executionEventsGetEventsClient{stream}
+	if err := x.ClientStream.SendMsg(in); err != nil {
+		return nil, err
+	}
+	if err := x.ClientStream.CloseSend(); err != nil {
+		return nil, err
+	}
+	return x, nil
+}
+
+type ExecutionEvents_GetEventsClient interface {
+	Recv() (*GetEventsResponse, error)
+	grpc.ClientStream
+}
+
+type executionEventsGetEventsClient struct {
+	grpc.ClientStream
+}
+
+func (x *executionEventsGetEventsClient) Recv() (*GetEventsResponse, error) {
+	m := new(GetEventsResponse)
+	if err := x.ClientStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
 }
 
 // ExecutionEventsServer is the server API for ExecutionEvents service.
 type ExecutionEventsServer interface {
-	GetEvents(context.Context, *GetEventsRequest) (*GetEventsResponse, error)
+	GetEvents(*GetEventsRequest, ExecutionEvents_GetEventsServer) error
 }
 
 func RegisterExecutionEventsServer(s *grpc.Server, srv ExecutionEventsServer) {
 	s.RegisterService(&_ExecutionEvents_serviceDesc, srv)
 }
 
-func _ExecutionEvents_GetEvents_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(GetEventsRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(ExecutionEventsServer).GetEvents(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/pbevents.ExecutionEvents/GetEvents",
+func _ExecutionEvents_GetEvents_Handler(srv interface{}, stream grpc.ServerStream) error {
+	m := new(GetEventsRequest)
+	if err := stream.RecvMsg(m); err != nil {
+		return err
 	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(ExecutionEventsServer).GetEvents(ctx, req.(*GetEventsRequest))
-	}
-	return interceptor(ctx, in, info, handler)
+	return srv.(ExecutionEventsServer).GetEvents(m, &executionEventsGetEventsServer{stream})
+}
+
+type ExecutionEvents_GetEventsServer interface {
+	Send(*GetEventsResponse) error
+	grpc.ServerStream
+}
+
+type executionEventsGetEventsServer struct {
+	grpc.ServerStream
+}
+
+func (x *executionEventsGetEventsServer) Send(m *GetEventsResponse) error {
+	return x.ServerStream.SendMsg(m)
 }
 
 var _ExecutionEvents_serviceDesc = grpc.ServiceDesc{
 	ServiceName: "pbevents.ExecutionEvents",
 	HandlerType: (*ExecutionEventsServer)(nil),
-	Methods: []grpc.MethodDesc{
+	Methods:     []grpc.MethodDesc{},
+	Streams: []grpc.StreamDesc{
 		{
-			MethodName: "GetEvents",
-			Handler:    _ExecutionEvents_GetEvents_Handler,
+			StreamName:    "GetEvents",
+			Handler:       _ExecutionEvents_GetEvents_Handler,
+			ServerStreams: true,
 		},
 	},
-	Streams:  []grpc.StreamDesc{},
 	Metadata: "github.com/hyperledger/burrow/execution/events/pbevents/events.proto",
 }
 
 func init() {
-	proto.RegisterFile("github.com/hyperledger/burrow/execution/events/pbevents/events.proto", fileDescriptor_events_6fac182aceb87b11)
-}
-
-var fileDescriptor_events_6fac182aceb87b11 = []byte{
-	// 692 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0xdb, 0x6e, 0xd3, 0x4c,
-	0x10, 0x6e, 0x9a, 0x34, 0x7f, 0x33, 0xc9, 0x5f, 0xda, 0x55, 0x28, 0x56, 0x90, 0x50, 0x65, 0x71,
-	0xd1, 0x1b, 0x12, 0x14, 0x90, 0x50, 0x05, 0x2a, 0x50, 0x12, 0xea, 0x4a, 0x95, 0xa8, 0x36, 0xa5,
-	0x48, 0xdc, 0xd9, 0xce, 0xc8, 0xb1, 0xea, 0xda, 0x66, 0x77, 0x5d, 0xc2, 0x0b, 0xf0, 0x5c, 0x48,
-	0xbc, 0x18, 0xda, 0x83, 0x4f, 0x21, 0x48, 0x55, 0xaf, 0xec, 0x6f, 0x66, 0xf6, 0xdb, 0x6f, 0x0e,
-	0x1e, 0xc3, 0x24, 0x08, 0xc5, 0x22, 0xf3, 0x86, 0x7e, 0x72, 0x33, 0x5a, 0xfc, 0x48, 0x91, 0x45,
-	0x38, 0x0f, 0x90, 0x8d, 0xbc, 0x8c, 0xb1, 0xe4, 0xfb, 0x08, 0x97, 0xe8, 0x67, 0x22, 0x4c, 0xe2,
-	0x11, 0xde, 0x62, 0x2c, 0xf8, 0x28, 0xf5, 0xcc, 0x8b, 0x7e, 0x0c, 0x53, 0x96, 0x88, 0x84, 0x6c,
-	0xe7, 0xe6, 0xc1, 0xeb, 0x3b, 0xf3, 0x31, 0x96, 0x30, 0x6e, 0x1e, 0x9a, 0xc6, 0x3e, 0x84, 0xde,
-	0x54, 0xd2, 0x9c, 0xcd, 0x2f, 0x5c, 0xe6, 0xde, 0x10, 0x0b, 0xfe, 0x43, 0x8d, 0xad, 0xc6, 0x41,
-	0xe3, 0xb0, 0x43, 0x73, 0x68, 0xdb, 0x00, 0xb3, 0xcc, 0xcb, 0xe3, 0xfa, 0xb0, 0xc5, 0x25, 0x32,
-	0x51, 0x1a, 0xd8, 0x4f, 0x01, 0x14, 0xdb, 0xe7, 0x78, 0x96, 0x79, 0x64, 0x1f, 0xda, 0x0c, 0x79,
-	0x16, 0x09, 0x15, 0xb4, 0x4d, 0x0d, 0xb2, 0xdf, 0x41, 0xef, 0x22, 0x89, 0x22, 0x8a, 0x3c, 0x4d,
-	0x62, 0x8e, 0xe4, 0x39, 0xb4, 0x75, 0x2a, 0x56, 0xe3, 0xa0, 0x79, 0xd8, 0x1d, 0x5b, 0xc3, 0x3c,
-	0xb7, 0xe1, 0x34, 0x17, 0xaf, 0x68, 0xa9, 0x89, 0xb3, 0x1d, 0xd8, 0x3d, 0x45, 0xa1, 0x6c, 0x9c,
-	0xe2, 0xb7, 0x0c, 0xb9, 0x20, 0x2f, 0x01, 0x4e, 0xa2, 0xc4, 0xbf, 0xa6, 0x6e, 0x1c, 0xa0, 0xba,
-	0xb1, 0x3b, 0xee, 0x97, 0x4c, 0xa5, 0x8f, 0x56, 0xe2, 0xec, 0x29, 0xec, 0x55, 0x98, 0xee, 0x2d,
-	0xe8, 0xbc, 0x7a, 0x39, 0x79, 0x02, 0x30, 0x13, 0x2e, 0x13, 0xca, 0xa4, 0xa4, 0xb4, 0x68, 0xc5,
-	0x22, 0xfd, 0x1f, 0xc3, 0xd8, 0x8d, 0xb4, 0x7f, 0x53, 0xfb, 0x4b, 0x8b, 0x3d, 0x83, 0xae, 0xa2,
-	0x77, 0xd0, 0x9d, 0x23, 0x93, 0x75, 0xbc, 0x5c, 0x3a, 0x2e, 0x5f, 0x28, 0xaa, 0x1e, 0x35, 0x48,
-	0xda, 0x1d, 0x0c, 0x83, 0x85, 0x30, 0x14, 0x06, 0xc9, 0xde, 0x9c, 0xc5, 0x73, 0x5c, 0x5a, 0x4d,
-	0x65, 0xd6, 0xc0, 0xfe, 0xb9, 0x09, 0x3b, 0x75, 0xf5, 0xe4, 0x99, 0x24, 0x90, 0x57, 0x98, 0x72,
-	0x3d, 0xac, 0xe4, 0x59, 0xde, 0x4f, 0x4d, 0x10, 0x39, 0x32, 0xb2, 0x26, 0xae, 0x70, 0x2f, 0x97,
-	0xea, 0xd2, 0xbf, 0xcf, 0x68, 0xa7, 0xb3, 0x41, 0xab, 0xb1, 0xe4, 0x2d, 0xfc, 0x5f, 0xc0, 0x0f,
-	0x6e, 0x14, 0x29, 0x69, 0xdd, 0xf1, 0xa3, 0x35, 0x87, 0xa5, 0xdb, 0xd9, 0xa0, 0xf5, 0x78, 0xf2,
-	0xc6, 0xcc, 0xa9, 0x34, 0x9c, 0x27, 0x81, 0xd5, 0x52, 0xe7, 0xf7, 0xd7, 0x9c, 0x3f, 0x4f, 0x02,
-	0x67, 0x83, 0xd6, 0xa2, 0x4f, 0xba, 0xd0, 0x29, 0xb0, 0x7d, 0x59, 0xa7, 0x92, 0x23, 0xff, 0x7e,
-	0x3e, 0x67, 0xc8, 0xb9, 0xa9, 0x6f, 0x0e, 0x09, 0x81, 0x96, 0x0c, 0x52, 0x99, 0xf6, 0xa8, 0x7a,
-	0x57, 0xcd, 0x48, 0xd2, 0xd0, 0xe7, 0x56, 0xf3, 0xa0, 0xa9, 0x9a, 0xa1, 0x90, 0x7d, 0x55, 0x2b,
-	0x8e, 0x0c, 0xa3, 0x28, 0x32, 0x16, 0xe7, 0x3d, 0xd3, 0x88, 0x8c, 0xa0, 0x33, 0x5d, 0xfa, 0x98,
-	0xca, 0x26, 0x98, 0x0a, 0xee, 0x0d, 0xcd, 0x17, 0x59, 0x38, 0x68, 0x19, 0x63, 0xff, 0x6a, 0xac,
-	0x94, 0x8e, 0x0c, 0x61, 0x5b, 0x3e, 0x95, 0x32, 0xdd, 0x37, 0x52, 0x96, 0x21, 0xf7, 0xd0, 0x22,
-	0x46, 0x4a, 0xf9, 0xc4, 0xc2, 0x20, 0x8c, 0x4d, 0x1e, 0x06, 0x99, 0x29, 0xf5, 0xaf, 0x27, 0x98,
-	0x8a, 0x85, 0x99, 0x95, 0x8a, 0xa5, 0x92, 0x42, 0xeb, 0xdf, 0x29, 0x6c, 0xdd, 0x21, 0x85, 0x5b,
-	0xa8, 0x89, 0x91, 0xef, 0x66, 0xe4, 0x7a, 0xd4, 0xa0, 0xc2, 0x8e, 0xb9, 0x48, 0x8d, 0x8a, 0x16,
-	0x34, 0x2b, 0x2d, 0xe8, 0xc3, 0xd6, 0x95, 0x1b, 0x65, 0xa8, 0x74, 0xb5, 0xa8, 0x06, 0x64, 0x17,
-	0x9a, 0xa7, 0x2e, 0x57, 0x82, 0x5a, 0x54, 0xbe, 0x8e, 0x7f, 0x37, 0xa0, 0xad, 0xbf, 0x6c, 0x72,
-	0x64, 0x06, 0x40, 0xee, 0x1d, 0x52, 0xd9, 0x0a, 0xe5, 0x46, 0x1b, 0x54, 0x66, 0xa9, 0xb6, 0x9d,
-	0x8e, 0x61, 0x47, 0x1d, 0x9d, 0x65, 0x1e, 0xf7, 0x59, 0xe8, 0x21, 0x59, 0x9d, 0xba, 0x9c, 0x61,
-	0x2d, 0x2f, 0x39, 0x86, 0x5d, 0xb3, 0x13, 0x79, 0xc1, 0xb0, 0x5e, 0x41, 0x7f, 0x85, 0x57, 0x6d,
-	0xd1, 0xf1, 0x17, 0x78, 0x50, 0xff, 0x6c, 0x39, 0x99, 0x40, 0xa7, 0x58, 0x5a, 0x64, 0x50, 0x9e,
-	0x5a, 0xdd, 0x89, 0x83, 0xc7, 0x6b, 0x7d, 0x3a, 0xb1, 0x93, 0xa3, 0xaf, 0xaf, 0xee, 0xf9, 0x27,
-	0xf2, 0xda, 0xea, 0xe7, 0xf1, 0xe2, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x2f, 0x19, 0xb9, 0x08,
-	0xcb, 0x06, 0x00, 0x00,
+	proto.RegisterFile("github.com/hyperledger/burrow/execution/events/pbevents/events.proto", fileDescriptor_events_4b6532afacd9adee)
+}
+
+var fileDescriptor_events_4b6532afacd9adee = []byte{
+	// 843 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0xdd, 0xae, 0xdb, 0x44,
+	0x10, 0x8e, 0x8f, 0x93, 0x90, 0x4c, 0xd2, 0xd3, 0x74, 0x15, 0x8a, 0x09, 0x08, 0x05, 0x0b, 0xa4,
+	0xdc, 0x34, 0xa9, 0x02, 0x12, 0x3a, 0x02, 0xb5, 0x24, 0xc4, 0x34, 0x47, 0x0a, 0x6a, 0x59, 0xbb,
+	0x91, 0xe0, 0xce, 0x3f, 0xab, 0xc4, 0xaa, 0x6b, 0x9b, 0x5d, 0xbb, 0xe4, 0x20, 0xae, 0xb9, 0xe3,
+	0x29, 0x78, 0x11, 0x24, 0x5e, 0x0c, 0xed, 0x8f, 0xff, 0xa2, 0x54, 0xaa, 0x7a, 0x13, 0xef, 0x37,
+	0xf3, 0xed, 0x64, 0xe6, 0x9b, 0xd9, 0x5d, 0xd8, 0x1c, 0xc2, 0xec, 0x98, 0x7b, 0x73, 0x3f, 0x79,
+	0xbd, 0x38, 0xde, 0xa5, 0x84, 0x46, 0x24, 0x38, 0x10, 0xba, 0xf0, 0x72, 0x4a, 0x93, 0xdf, 0x17,
+	0xe4, 0x44, 0xfc, 0x3c, 0x0b, 0x93, 0x78, 0x41, 0xde, 0x90, 0x38, 0x63, 0x8b, 0xd4, 0x53, 0x0b,
+	0xf9, 0x99, 0xa7, 0x34, 0xc9, 0x12, 0xd4, 0x2b, 0xcc, 0x93, 0x6f, 0xdf, 0x39, 0x1e, 0xa5, 0x09,
+	0x65, 0xea, 0x23, 0xc3, 0x98, 0x33, 0x18, 0x5a, 0x3c, 0xcc, 0x6d, 0xf0, 0xc2, 0xa5, 0xee, 0x6b,
+	0x64, 0xc0, 0x07, 0x44, 0x62, 0x43, 0x9b, 0x6a, 0xb3, 0x3e, 0x2e, 0xa0, 0x69, 0x02, 0xd8, 0xb9,
+	0x57, 0xf0, 0xc6, 0xd0, 0x61, 0x1c, 0x29, 0x96, 0x04, 0xe6, 0x17, 0x00, 0x22, 0xda, 0xcb, 0xd8,
+	0xce, 0x3d, 0xf4, 0x10, 0xba, 0x94, 0xb0, 0x3c, 0xca, 0x04, 0xa9, 0x87, 0x15, 0x32, 0xbf, 0x87,
+	0xe1, 0x8b, 0x24, 0x8a, 0x30, 0x61, 0x69, 0x12, 0x33, 0x82, 0x1e, 0x43, 0x57, 0x96, 0x62, 0x68,
+	0x53, 0x7d, 0x36, 0x58, 0x1a, 0xf3, 0xa2, 0xb6, 0xb9, 0x55, 0x24, 0x2f, 0xc2, 0x62, 0xc5, 0x33,
+	0xff, 0x84, 0xd1, 0x33, 0x92, 0x09, 0x1b, 0xc3, 0xe4, 0xb7, 0x9c, 0xb0, 0x0c, 0x7d, 0x0d, 0xb0,
+	0x8e, 0x12, 0xff, 0x15, 0x76, 0xe3, 0x03, 0x11, 0xff, 0x38, 0x58, 0x8e, 0xab, 0x48, 0x95, 0x0f,
+	0xd7, 0x78, 0xe8, 0x53, 0xe8, 0xaf, 0xdd, 0xcc, 0x3f, 0xda, 0xe1, 0x1f, 0xc4, 0xb8, 0x9a, 0x6a,
+	0xb3, 0x7b, 0xb8, 0x32, 0xf0, 0x2a, 0x7f, 0xce, 0x09, 0xbd, 0x33, 0x74, 0x59, 0xa5, 0x00, 0xa6,
+	0x05, 0x0f, 0x6a, 0xff, 0xfe, 0xde, 0x45, 0xfc, 0xad, 0x41, 0x67, 0x9d, 0xe4, 0x71, 0x80, 0x1e,
+	0x41, 0xdb, 0xb9, 0x4b, 0x65, 0xd2, 0xd7, 0xcb, 0x8f, 0x6b, 0x49, 0x73, 0xb7, 0xfc, 0xe5, 0x04,
+	0x2c, 0x68, 0x3c, 0xab, 0xdb, 0x38, 0x20, 0x27, 0x91, 0x6f, 0x1b, 0x4b, 0x60, 0x3e, 0x85, 0x7e,
+	0x49, 0x44, 0x43, 0xe8, 0xad, 0xd6, 0xf6, 0xf3, 0xdd, 0x4b, 0xc7, 0x1a, 0xb5, 0x38, 0xc2, 0xd6,
+	0x6e, 0xe5, 0xdc, 0xee, 0xad, 0x91, 0x86, 0x00, 0xba, 0xbb, 0x95, 0x63, 0xd9, 0xce, 0xe8, 0x8a,
+	0xaf, 0x6d, 0x07, 0x5b, 0xab, 0x9f, 0x46, 0xba, 0xb9, 0xaf, 0x0b, 0x88, 0xbe, 0x84, 0x8e, 0x9d,
+	0xb9, 0x34, 0x53, 0x4a, 0xde, 0x3f, 0x4b, 0x0a, 0x4b, 0x2f, 0xfa, 0x1c, 0x74, 0x2b, 0x0e, 0x44,
+	0x26, 0x17, 0x48, 0xdc, 0x67, 0xfe, 0xa3, 0xc1, 0x40, 0x54, 0xbe, 0x25, 0x6e, 0x40, 0x28, 0x1f,
+	0x0b, 0xe7, 0x54, 0xd6, 0xdb, 0xc7, 0x0a, 0x49, 0xfb, 0xd6, 0x65, 0x47, 0x11, 0x6d, 0x88, 0x15,
+	0xe2, 0x2d, 0x12, 0xdb, 0xc5, 0x16, 0xd9, 0x88, 0xca, 0xc0, 0x07, 0x56, 0x0e, 0xf0, 0xc6, 0x68,
+	0xcb, 0x81, 0x55, 0x90, 0xc7, 0xdb, 0x92, 0xf0, 0x70, 0xcc, 0x8c, 0x8e, 0xd0, 0x49, 0xa1, 0x4a,
+	0xbe, 0x6e, 0x5d, 0xbe, 0xbf, 0xae, 0xe0, 0xba, 0xd9, 0x28, 0xf4, 0x88, 0x07, 0xe0, 0x29, 0x2b,
+	0x0d, 0x3e, 0xac, 0xb5, 0xb4, 0xaa, 0x07, 0x2b, 0x12, 0xba, 0x51, 0x65, 0x6e, 0xdc, 0xcc, 0x75,
+	0x4e, 0x4a, 0x92, 0xf3, 0x3d, 0xd2, 0xb9, 0x6d, 0xe1, 0x3a, 0x17, 0x3d, 0x85, 0x7b, 0x25, 0xfc,
+	0xc1, 0x8d, 0x22, 0x51, 0xe6, 0x60, 0xf9, 0xd1, 0x85, 0xcd, 0xdc, 0xbd, 0x6d, 0xe1, 0x26, 0x1f,
+	0x7d, 0xa7, 0x8e, 0x31, 0x37, 0xec, 0x92, 0x83, 0x90, 0x62, 0xb0, 0x7c, 0x78, 0x61, 0xff, 0x2e,
+	0x39, 0x6c, 0x5b, 0xb8, 0xc1, 0x5e, 0x0f, 0x94, 0xc2, 0x1c, 0x9b, 0x4e, 0x33, 0x14, 0x17, 0x78,
+	0x15, 0x04, 0x94, 0x30, 0x26, 0x64, 0x18, 0xe2, 0x02, 0x22, 0x04, 0x6d, 0x4e, 0x52, 0xed, 0x12,
+	0x6b, 0xd1, 0xc4, 0x24, 0x0d, 0x7d, 0x66, 0xe8, 0x53, 0x5d, 0x34, 0x51, 0x20, 0x73, 0xdf, 0x10,
+	0x87, 0xd3, 0x30, 0xc9, 0x72, 0x1a, 0xab, 0x98, 0x0a, 0xa1, 0x05, 0xf4, 0xad, 0x93, 0x4f, 0x52,
+	0xde, 0x04, 0xa5, 0xe0, 0x83, 0xb9, 0xba, 0xb0, 0x4a, 0x07, 0xae, 0x38, 0xe6, 0xbf, 0xda, 0x99,
+	0x74, 0x68, 0x0e, 0x3d, 0xfe, 0x15, 0x99, 0xc9, 0xbe, 0xa1, 0x4a, 0x86, 0xc2, 0x83, 0x4b, 0x0e,
+	0x4f, 0xe5, 0x39, 0x0d, 0x0f, 0x61, 0x5c, 0x8c, 0x9d, 0x44, 0xe8, 0x33, 0x00, 0x3b, 0x73, 0xfd,
+	0x57, 0x1b, 0x92, 0x66, 0x47, 0xd1, 0x90, 0x36, 0xae, 0x59, 0x6a, 0x25, 0xb4, 0xdf, 0x5e, 0x42,
+	0xe7, 0x1d, 0x4a, 0x78, 0x03, 0x8d, 0x64, 0xf8, 0x5a, 0x8d, 0xdc, 0x10, 0x2b, 0x54, 0xda, 0x49,
+	0x91, 0xa4, 0x44, 0x65, 0x0b, 0xf4, 0x5a, 0x0b, 0xc6, 0xd0, 0xd9, 0xbb, 0x51, 0x4e, 0x44, 0x5e,
+	0x6d, 0x2c, 0x01, 0x1a, 0x81, 0xfe, 0xcc, 0x65, 0xea, 0x28, 0xf0, 0xe5, 0xf2, 0x3f, 0x0d, 0xba,
+	0xf2, 0x12, 0x43, 0x37, 0x6a, 0x00, 0xf8, 0xb5, 0x8c, 0x6a, 0x97, 0x66, 0x75, 0xe1, 0x4f, 0x6a,
+	0xb3, 0xd4, 0xb8, 0xbc, 0x9f, 0xc0, 0xb5, 0xd8, 0x6a, 0xe7, 0x1e, 0xf3, 0x69, 0xe8, 0x11, 0x74,
+	0x3e, 0x75, 0x45, 0x84, 0x8b, 0x71, 0xd1, 0x13, 0x18, 0xa9, 0x27, 0x83, 0x95, 0x11, 0x2e, 0x67,
+	0x30, 0x3e, 0x8b, 0x2b, 0x1e, 0x99, 0xe5, 0x2f, 0x70, 0xbf, 0x79, 0x6c, 0x19, 0xfa, 0x11, 0xfa,
+	0xe5, 0xfd, 0x8c, 0x26, 0xd5, 0xae, 0xf3, 0x27, 0x63, 0xf2, 0xc9, 0x45, 0x9f, 0x2c, 0xec, 0xb1,
+	0xb6, 0xbe, 0xf9, 0xf5, 0x9b, 0xf7, 0x7c, 0xaa, 0xbd, 0xae, 0x78, 0x5d, 0xbf, 0xfa, 0x3f, 0x00,
+	0x00, 0xff, 0xff, 0x64, 0x13, 0x5b, 0x2c, 0xec, 0x07, 0x00, 0x00,
 }
diff --git a/execution/events/pbevents/events.proto b/execution/events/pbevents/events.proto
index e6586d9da99ed3e31947e18cdfc0c2761978b234..7912a7f553059fb9ee8e3584e78c67934e99f1e9 100644
--- a/execution/events/pbevents/events.proto
+++ b/execution/events/pbevents/events.proto
@@ -36,33 +36,59 @@ message PollResponse {
 // Event dump
 
 service ExecutionEvents {
-    rpc GetEvents (GetEventsRequest) returns (GetEventsResponse);
+    rpc GetEvents (GetEventsRequest) returns (stream GetEventsResponse);
 }
 
 message GetEventsRequest {
     BlockRange BlockRange = 1;
+    uint32 BatchSize = 2;
+    string Query = 3;
 }
 
 message GetEventsResponse {
     repeated ExecutionEvent events = 1;
 }
 
+message Bound {
+    BoundType Type = 1;
+    uint64 Index = 2;
+    enum BoundType {
+        // Index is absolute index of object in collection
+        ABSOLUTE = 0;
+        // Index is an offset reltiave to another bound determined by context
+        RELATIVE = 1;
+        // Ignore provided index and evaluate to latest index
+        LATEST = 2;
+        // Ignore provided index and stream new objects as they are generated
+        STREAM = 3;
+    }
+}
+
 // An inclusive range of blocks to include
 message BlockRange {
-    uint64 StartBlock = 1;
-    uint64 FinalBlock = 2;
+    // How to interpret StartBlock
+    Bound Start = 1;
+    Bound End = 2;
 }
 
+//--------------------------------------------------
+// Event types
+
 message EventHeader {
+    // Transaction type
+    string TxType = 1;
     // The hash of the transaction that caused this event to be generated
-    bytes TxHash = 1;
+    bytes TxHash = 2;
+    // The type of event
+    string EventType = 3;
+    // EventID published with event
+    string EventID = 4;
     // The block height at which this event was emitted
-    uint64 Height = 2;
+    uint64 Height = 5;
     // The index amongst all other events in the block of this event
-    uint64 Index = 3;
+    uint64 Index = 6;
 }
-//--------------------------------------------------
-// Event types
+
 message ExecutionEvent {
     EventHeader Header = 1;
     oneof EventData {
diff --git a/execution/events/tx.go b/execution/events/tx.go
index a544b4f7774db5f2fa2cf634e47e6c7a11925d16..b7d49ec9e2f8dcb8e47e470d418900d34f40788c 100644
--- a/execution/events/tx.go
+++ b/execution/events/tx.go
@@ -7,6 +7,7 @@ import (
 	"github.com/hyperledger/burrow/binary"
 	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/event"
+	"github.com/hyperledger/burrow/event/query"
 	"github.com/hyperledger/burrow/execution/errors"
 	ptypes "github.com/hyperledger/burrow/permission/types"
 	"github.com/hyperledger/burrow/txs"
@@ -28,64 +29,81 @@ type EventDataTx struct {
 	Exception *errors.Exception
 }
 
+var txTagKeys = []string{event.ExceptionKey}
+
+func (tx *EventDataTx) Get(key string) (string, bool) {
+	var value interface{}
+	switch key {
+	case event.ExceptionKey:
+		value = tx.Exception
+	default:
+		return "", false
+	}
+	return query.StringFromValue(value), true
+}
+
+func (tx *EventDataTx) Len() int {
+	return len(txTagKeys)
+}
+
+func (tx *EventDataTx) Map() map[string]interface{} {
+	tags := make(map[string]interface{})
+	for _, key := range txTagKeys {
+		tags[key], _ = tx.Get(key)
+	}
+	return tags
+}
+
+func (tx *EventDataTx) Keys() []string {
+	return txTagKeys
+}
+
 // For re-use
-var sendTxQuery = event.NewQueryBuilder().
+var sendTxQuery = query.NewBuilder().
 	AndEquals(event.TxTypeKey, payload.TypeSend.String())
 
-var callTxQuery = event.NewQueryBuilder().
+var callTxQuery = query.NewBuilder().
 	AndEquals(event.TxTypeKey, payload.TypeCall.String())
 
 // Publish/Subscribe
-func PublishAccountOutput(publisher event.Publisher, address crypto.Address, tx *txs.Tx, ret []byte,
+func PublishAccountInput(publisher event.Publisher, height uint64, address crypto.Address, tx *txs.Tx, ret []byte,
 	exception *errors.Exception) error {
 
-	return event.PublishWithEventID(publisher, EventStringAccountOutput(address),
-		eventDataTx(tx, ret, exception),
-		map[string]interface{}{
-			"address":       address,
-			event.TxTypeKey: tx.Type().String(),
-			event.TxHashKey: hex.EncodeUpperToString(tx.Hash()),
-		})
+	ev := txEvent(height, TypeAccountInput, EventStringAccountInput(address), tx, ret, exception)
+	return publisher.Publish(context.Background(), ev, event.CombinedTags{ev.Tags(), event.TagMap{
+		event.AddressKey: address,
+	}})
 }
 
-func PublishAccountInput(publisher event.Publisher, address crypto.Address, tx *txs.Tx, ret []byte,
+func PublishAccountOutput(publisher event.Publisher, height uint64, address crypto.Address, tx *txs.Tx, ret []byte,
 	exception *errors.Exception) error {
 
-	return event.PublishWithEventID(publisher, EventStringAccountInput(address),
-		eventDataTx(tx, ret, exception),
-		map[string]interface{}{
-			"address":       address,
-			event.TxTypeKey: tx.Type().String(),
-			event.TxHashKey: hex.EncodeUpperToString(tx.Hash()),
-		})
+	ev := txEvent(height, TypeAccountOutput, EventStringAccountOutput(address), tx, ret, exception)
+	return publisher.Publish(context.Background(), ev, event.CombinedTags{ev.Tags(), event.TagMap{
+		event.AddressKey: address,
+	}})
 }
 
-func PublishNameReg(publisher event.Publisher, tx *txs.Tx) error {
+func PublishNameReg(publisher event.Publisher, height uint64, tx *txs.Tx) error {
 	nameTx, ok := tx.Payload.(*payload.NameTx)
 	if !ok {
 		return fmt.Errorf("Tx payload must be NameTx to PublishNameReg")
 	}
-	return event.PublishWithEventID(publisher, EventStringNameReg(nameTx.Name),
-		eventDataTx(tx, nil, nil),
-		map[string]interface{}{
-			"name":          nameTx.Name,
-			event.TxTypeKey: tx.Type().String(),
-			event.TxHashKey: hex.EncodeUpperToString(tx.Hash()),
-		})
+	ev := txEvent(height, TypeAccountInput, EventStringNameReg(nameTx.Name), tx, nil, nil)
+	return publisher.Publish(context.Background(), ev, event.CombinedTags{ev.Tags(), event.TagMap{
+		event.NameKey: nameTx.Name,
+	}})
 }
 
-func PublishPermissions(publisher event.Publisher, perm ptypes.PermFlag, tx *txs.Tx) error {
-	_, ok := tx.Payload.(*payload.PermissionsTx)
+func PublishPermissions(publisher event.Publisher, height uint64, tx *txs.Tx) error {
+	permTx, ok := tx.Payload.(*payload.PermissionsTx)
 	if !ok {
 		return fmt.Errorf("Tx payload must be PermissionsTx to PublishPermissions")
 	}
-	return event.PublishWithEventID(publisher, EventStringPermissions(perm),
-		eventDataTx(tx, nil, nil),
-		map[string]interface{}{
-			"name":          perm.String(),
-			event.TxTypeKey: tx.Type().String(),
-			event.TxHashKey: hex.EncodeUpperToString(tx.Hash()),
-		})
+	ev := txEvent(height, TypeAccountInput, EventStringPermissions(permTx.PermArgs.PermFlag), tx, nil, nil)
+	return publisher.Publish(context.Background(), ev, event.CombinedTags{ev.Tags(), event.TagMap{
+		event.PermissionKey: permTx.PermArgs.PermFlag.String(),
+	}})
 }
 
 func SubscribeAccountOutputSendTx(ctx context.Context, subscribable event.Subscribable, subscriber string,
@@ -104,10 +122,14 @@ func SubscribeAccountOutputSendTx(ctx context.Context, subscribable event.Subscr
 	})
 }
 
-func eventDataTx(tx *txs.Tx, ret []byte, exception *errors.Exception) *Event {
+func txEvent(height uint64, eventType Type, eventID string, tx *txs.Tx, ret []byte, exception *errors.Exception) *Event {
 	return &Event{
 		Header: &Header{
-			TxHash: tx.Hash(),
+			TxType:    tx.Type(),
+			TxHash:    tx.Hash(),
+			EventType: eventType,
+			EventID:   eventID,
+			Height:    height,
 		},
 		Tx: &EventDataTx{
 			Tx:        tx,
diff --git a/execution/events/type.go b/execution/events/type.go
new file mode 100644
index 0000000000000000000000000000000000000000..8fe49f60df52439f06d14a9b12473601a9133119
--- /dev/null
+++ b/execution/events/type.go
@@ -0,0 +1,47 @@
+package events
+
+type Type int8
+
+// Execution event types
+const (
+	TypeCall          = Type(0x00)
+	TypeLog           = Type(0x01)
+	TypeAccountInput  = Type(0x02)
+	TypeAccountOutput = Type(0x03)
+)
+
+var nameFromType = map[Type]string{
+	TypeCall:          "CallEvent",
+	TypeLog:           "LogEvent",
+	TypeAccountInput:  "AccountInputEvent",
+	TypeAccountOutput: "AccountOutputEvent",
+}
+
+var typeFromName = make(map[string]Type)
+
+func init() {
+	for t, n := range nameFromType {
+		typeFromName[n] = t
+	}
+}
+
+func EventTypeFromString(name string) Type {
+	return typeFromName[name]
+}
+
+func (typ Type) String() string {
+	name, ok := nameFromType[typ]
+	if ok {
+		return name
+	}
+	return "UnknownTx"
+}
+
+func (typ Type) MarshalText() ([]byte, error) {
+	return []byte(typ.String()), nil
+}
+
+func (typ *Type) UnmarshalText(data []byte) error {
+	*typ = EventTypeFromString(string(data))
+	return nil
+}
diff --git a/execution/evm/log_event_test.go b/execution/evm/log_event_test.go
index e90b51eddd0def2710ec61ea8da268d80c036753..7789c3b96824859001cd3d5573b0fd209ff6364e 100644
--- a/execution/evm/log_event_test.go
+++ b/execution/evm/log_event_test.go
@@ -42,7 +42,6 @@ var expectedTopics = []Word256{
 
 // Tests logs and events.
 func TestLog4(t *testing.T) {
-
 	st := newAppState()
 	cache := state.NewCache(st)
 	// Create accounts
diff --git a/execution/evm/vm.go b/execution/evm/vm.go
index df6b1eeeb4c922cbd71f9e273b7943839ece7fec..041c1e7d728c95ebcfc3b8b937e8a64516c848dc 100644
--- a/execution/evm/vm.go
+++ b/execution/evm/vm.go
@@ -32,6 +32,7 @@ import (
 	"github.com/hyperledger/burrow/execution/evm/sha3"
 	"github.com/hyperledger/burrow/logging"
 	ptypes "github.com/hyperledger/burrow/permission/types"
+	"github.com/hyperledger/burrow/txs"
 )
 
 const (
@@ -50,7 +51,7 @@ type VM struct {
 	memoryProvider   func() Memory
 	params           Params
 	origin           crypto.Address
-	txHash           []byte
+	tx               *txs.Tx
 	stackDepth       uint64
 	nestedCallErrors []errors.NestedCall
 	publisher        event.Publisher
@@ -60,14 +61,13 @@ type VM struct {
 	dumpTokens       bool
 }
 
-func NewVM(params Params, origin crypto.Address, txid []byte,
-	logger *logging.Logger, options ...func(*VM)) *VM {
+func NewVM(params Params, origin crypto.Address, tx *txs.Tx, logger *logging.Logger, options ...func(*VM)) *VM {
 	vm := &VM{
 		memoryProvider: DefaultDynamicMemoryProvider,
 		params:         params,
 		origin:         origin,
 		stackDepth:     0,
-		txHash:         txid,
+		tx:             tx,
 		logger:         logger.WithScope("NewVM"),
 	}
 	for _, option := range options {
@@ -101,7 +101,7 @@ func HasPermission(stateWriter state.Writer, acc acm.Account, perm ptypes.PermFl
 func (vm *VM) fireCallEvent(exception *errors.CodedError, output *[]byte, callerAddress, calleeAddress crypto.Address, input []byte, value uint64, gas *uint64) {
 	// fire the post call event (including exception if applicable)
 	if vm.publisher != nil {
-		events.PublishAccountCall(vm.publisher, calleeAddress,
+		events.PublishAccountCall(vm.publisher, vm.tx, vm.params.BlockHeight,
 			&events.EventDataCall{
 				CallData: &events.CallData{
 					Caller: callerAddress,
@@ -111,7 +111,6 @@ func (vm *VM) fireCallEvent(exception *errors.CodedError, output *[]byte, caller
 					Gas:    *gas,
 				},
 				Origin:     vm.origin,
-				TxHash:     vm.txHash,
 				StackDepth: vm.stackDepth,
 				Return:     *output,
 				Exception:  errors.AsCodedError(*exception),
@@ -125,7 +124,7 @@ func (vm *VM) fireCallEvent(exception *errors.CodedError, output *[]byte, caller
 // value: To be transferred from caller to callee. Refunded upon errors.CodedError.
 // gas:   Available gas. No refunds for gas.
 // code: May be nil, since the CALL opcode may be used to send value from contracts to accounts
-func (vm *VM) Call(callState state.Cache, caller, callee acm.MutableAccount, code, input []byte, value uint64, gas *uint64) (output []byte, err errors.CodedError) {
+func (vm *VM) Call(callState *state.Cache, caller, callee acm.MutableAccount, code, input []byte, value uint64, gas *uint64) (output []byte, err errors.CodedError) {
 
 	exception := new(errors.CodedError)
 	// fire the post call event (including exception if applicable)
@@ -169,7 +168,7 @@ func (vm *VM) Call(callState state.Cache, caller, callee acm.MutableAccount, cod
 // The intent of delegate call is to run the code of the callee in the storage context of the caller;
 // while preserving the original caller to the previous callee.
 // Different to the normal CALL or CALLCODE, the value does not need to be transferred to the callee.
-func (vm *VM) DelegateCall(callState state.Cache, caller acm.Account, callee acm.MutableAccount, code, input []byte, value uint64, gas *uint64) (output []byte, err errors.CodedError) {
+func (vm *VM) DelegateCall(callState *state.Cache, caller acm.Account, callee acm.MutableAccount, code, input []byte, value uint64, gas *uint64) (output []byte, err errors.CodedError) {
 
 	exception := new(string)
 	// fire the post call event (including exception if applicable)
@@ -209,14 +208,14 @@ func useGasNegative(gasLeft *uint64, gasToUse uint64, err *errors.CodedError) bo
 }
 
 // Just like Call() but does not transfer 'value' or modify the callDepth.
-func (vm *VM) call(callState state.Cache, caller acm.Account, callee acm.MutableAccount, code, input []byte, value uint64, gas *uint64) (output []byte, err errors.CodedError) {
+func (vm *VM) call(callState *state.Cache, caller acm.Account, callee acm.MutableAccount, code, input []byte, value uint64, gas *uint64) (output []byte, err errors.CodedError) {
 	vm.Debugf("(%d) (%X) %X (code=%d) gas: %v (d) %X\n", vm.stackDepth, caller.Address().Bytes()[:4], callee.Address(),
 		len(callee.Code()), *gas, input)
 
-	logger := vm.logger.With("tx_hash", vm.txHash)
+	logger := vm.logger.With("tx_hash", vm.tx)
 
 	if vm.dumpTokens {
-		dumpTokens(vm.txHash, caller, callee, code)
+		dumpTokens(vm.tx.Hash(), caller, callee, code)
 	}
 
 	var (
@@ -840,13 +839,16 @@ func (vm *VM) call(callState state.Cache, caller acm.Account, callee acm.Mutable
 				return nil, firstErr(err, errors.ErrorCodeMemoryOutOfBounds)
 			}
 			if vm.publisher != nil {
-				events.PublishLogEvent(vm.publisher, callee.Address(), &events.EventDataLog{
-					TxHash:  vm.txHash,
+				publishErr := events.PublishLogEvent(vm.publisher, vm.tx, &events.EventDataLog{
+					Height:  vm.params.BlockHeight,
 					Address: callee.Address(),
 					Topics:  topics,
 					Data:    data,
-					Height:  vm.params.BlockHeight,
 				})
+				if publishErr != nil {
+					vm.Debugf(" => Log event publish err: %s", publishErr)
+					return nil, firstErr(err, errors.ErrorCodeEventPublish)
+				}
 			}
 			vm.Debugf(" => T:%X D:%X\n", topics, data)
 
@@ -1109,7 +1111,7 @@ func (vm *VM) call(callState state.Cache, caller acm.Account, callee acm.Mutable
 	}
 }
 
-func (vm *VM) createAccount(callState state.Cache, callee acm.MutableAccount, logger *logging.Logger) (acm.MutableAccount, errors.CodedError) {
+func (vm *VM) createAccount(callState *state.Cache, callee acm.MutableAccount, logger *logging.Logger) (acm.MutableAccount, errors.CodedError) {
 	newAccount := DeriveNewAccount(callee, state.GlobalAccountPermissions(callState), logger)
 	err := callState.UpdateAccount(newAccount)
 	if err != nil {
diff --git a/execution/evm/vm_test.go b/execution/evm/vm_test.go
index 374e760941528dccbd041a5b7652d143b832a88f..42c205becb2e30dd9fc30dd5341c93bde9d166de 100644
--- a/execution/evm/vm_test.go
+++ b/execution/evm/vm_test.go
@@ -1012,7 +1012,7 @@ func makeAccountWithCode(accountUpdater state.AccountUpdater, name string,
 // and then waits for any exceptions transmitted by Data in the AccCall
 // event (in the case of no direct error from call we will block waiting for
 // at least 1 AccCall event)
-func runVMWaitError(vmCache state.Cache, ourVm *VM, caller, callee acm.MutableAccount, subscribeAddr crypto.Address,
+func runVMWaitError(vmCache *state.Cache, ourVm *VM, caller, callee acm.MutableAccount, subscribeAddr crypto.Address,
 	contractCode []byte, gas uint64) ([]byte, error) {
 	eventCh := make(chan *events.EventDataCall)
 	output, err := runVM(eventCh, vmCache, ourVm, caller, callee, subscribeAddr, contractCode, gas)
@@ -1030,7 +1030,7 @@ func runVMWaitError(vmCache state.Cache, ourVm *VM, caller, callee acm.MutableAc
 
 // Subscribes to an AccCall, runs the vm, returns the output and any direct
 // exception
-func runVM(eventCh chan<- *events.EventDataCall, vmCache state.Cache, ourVm *VM, caller, callee acm.MutableAccount,
+func runVM(eventCh chan<- *events.EventDataCall, vmCache *state.Cache, ourVm *VM, caller, callee acm.MutableAccount,
 	subscribeAddr crypto.Address, contractCode []byte, gas uint64) ([]byte, error) {
 
 	// we need to catch the event from the CALL to check for exceptions
diff --git a/execution/execution.go b/execution/execution.go
index 715f109fdcf7b220844769672703528f8fc01cbc..897737b207f31fba440629424b862463adee1274 100644
--- a/execution/execution.go
+++ b/execution/execution.go
@@ -38,6 +38,12 @@ type Executor interface {
 	Execute(txEnv *txs.Envelope) error
 }
 
+type ExecutorState interface {
+	Update(updater func(ws Updatable))
+	names.Getter
+	state.Iterable
+}
+
 type BatchExecutor interface {
 	// Provides access to write lock for a BatchExecutor so reads can be prevented for the duration of a commit
 	sync.Locker
@@ -60,8 +66,8 @@ type executor struct {
 	sync.RWMutex
 	runCall      bool
 	publisher    event.Publisher
-	state        *State
-	stateCache   state.Cache
+	state        ExecutorState
+	stateCache   *state.Cache
 	nameRegCache *names.Cache
 	eventCache   *event.Cache
 	logger       *logging.Logger
@@ -72,21 +78,21 @@ type executor struct {
 var _ BatchExecutor = (*executor)(nil)
 
 // Wraps a cache of what is variously known as the 'check cache' and 'mempool'
-func NewBatchChecker(backend *State, tip *bcm.Tip, logger *logging.Logger,
+func NewBatchChecker(backend ExecutorState, tip *bcm.Tip, logger *logging.Logger,
 	options ...ExecutionOption) BatchExecutor {
 
 	return newExecutor("CheckCache", false, backend, tip, event.NewNoOpPublisher(),
 		logger.WithScope("NewBatchExecutor"), options...)
 }
 
-func NewBatchCommitter(backend *State, tip *bcm.Tip, publisher event.Publisher, logger *logging.Logger,
+func NewBatchCommitter(backend ExecutorState, tip *bcm.Tip, publisher event.Publisher, logger *logging.Logger,
 	options ...ExecutionOption) BatchCommitter {
 
 	return newExecutor("CommitCache", true, backend, tip, publisher,
 		logger.WithScope("NewBatchCommitter"), options...)
 }
 
-func newExecutor(name string, runCall bool, backend *State, tip *bcm.Tip, publisher event.Publisher,
+func newExecutor(name string, runCall bool, backend ExecutorState, tip *bcm.Tip, publisher event.Publisher,
 	logger *logging.Logger, options ...ExecutionOption) *executor {
 
 	exe := &executor{
@@ -103,26 +109,28 @@ func newExecutor(name string, runCall bool, backend *State, tip *bcm.Tip, publis
 	}
 	exe.txExecutors = map[payload.Type]Executor{
 		payload.TypeSend: &executors.SendContext{
+			Tip:            tip,
 			StateWriter:    exe.stateCache,
 			EventPublisher: exe.eventCache,
 			Logger:         exe.logger,
 		},
 		payload.TypeCall: &executors.CallContext{
+			Tip:            tip,
 			StateWriter:    exe.stateCache,
 			EventPublisher: exe.eventCache,
-			Tip:            tip,
 			RunCall:        runCall,
 			VMOptions:      exe.vmOptions,
 			Logger:         exe.logger,
 		},
 		payload.TypeName: &executors.NameContext{
+			Tip:            tip,
 			StateWriter:    exe.stateCache,
 			EventPublisher: exe.eventCache,
 			NameReg:        exe.nameRegCache,
-			Tip:            tip,
 			Logger:         exe.logger,
 		},
 		payload.TypePermissions: &executors.PermissionsContext{
+			Tip:            tip,
 			StateWriter:    exe.stateCache,
 			EventPublisher: exe.eventCache,
 			Logger:         exe.logger,
@@ -159,25 +167,6 @@ func (exe *executor) Execute(txEnv *txs.Envelope) (err error) {
 	return fmt.Errorf("unknown transaction type: %v", txEnv.Tx.Type())
 }
 
-// executor exposes access to the underlying state cache protected by a RWMutex that prevents access while locked
-// (during an ABCI commit). while access can occur (and needs to continue for CheckTx/DeliverTx to make progress)
-// through calls to Execute() external readers will be blocked until the executor is unlocked that allows the Transactor
-// to always access the freshest mempool state as needed by accounts.SequentialSigningAccount
-//
-// Accounts
-func (exe *executor) GetAccount(address crypto.Address) (acm.Account, error) {
-	exe.RLock()
-	defer exe.RUnlock()
-	return exe.stateCache.GetAccount(address)
-}
-
-// Storage
-func (exe *executor) GetStorage(address crypto.Address, key binary.Word256) (binary.Word256, error) {
-	exe.RLock()
-	defer exe.RUnlock()
-	return exe.stateCache.GetStorage(address, key)
-}
-
 func (exe *executor) Commit() (hash []byte, err error) {
 	// The write lock to the executor is controlled by the caller (e.g. abci.App) so we do not acquire it here to avoid
 	// deadlock
@@ -186,29 +175,36 @@ func (exe *executor) Commit() (hash []byte, err error) {
 			err = fmt.Errorf("recovered from panic in executor.Commit(): %v\n%v", r, debug.Stack())
 		}
 	}()
-	// flush the caches
-	err = exe.stateCache.Flush(exe.state)
-	if err != nil {
-		return nil, err
-	}
-	err = exe.nameRegCache.Flush(exe.state)
-	if err != nil {
-		return nil, err
-	}
-	//err = exe.eventCache.Sync(exe.state)
-	//if err != nil {
-	//	return nil, err
-	//}
-	// save state to disk
-	err = exe.state.Save()
+	exe.state.Update(func(ws Updatable) {
+		// flush the caches
+		err = exe.stateCache.Flush(ws)
+		if err != nil {
+			return
+		}
+		err = exe.nameRegCache.Flush(ws)
+		if err != nil {
+			return
+		}
+		err = exe.eventCache.Sync(ws)
+		if err != nil {
+			return
+		}
+		//save state to disk
+		err = ws.Save()
+		if err != nil {
+			return
+		}
+		// flush events to listeners
+		err = exe.eventCache.Flush(exe.publisher)
+		if err != nil {
+			return
+		}
+		hash = ws.Hash()
+	})
 	if err != nil {
 		return nil, err
 	}
-	// flush events to listeners
-	defer func() {
-		err = exe.eventCache.Flush(exe.publisher)
-	}()
-	return exe.state.Hash(), nil
+	return hash, nil
 }
 
 func (exe *executor) Reset() error {
@@ -217,3 +213,22 @@ func (exe *executor) Reset() error {
 	exe.nameRegCache.Reset(exe.state)
 	return nil
 }
+
+// executor exposes access to the underlying state cache protected by a RWMutex that prevents access while locked
+// (during an ABCI commit). while access can occur (and needs to continue for CheckTx/DeliverTx to make progress)
+// through calls to Execute() external readers will be blocked until the executor is unlocked that allows the Transactor
+// to always access the freshest mempool state as needed by accounts.SequentialSigningAccount
+//
+// Accounts
+func (exe *executor) GetAccount(address crypto.Address) (acm.Account, error) {
+	exe.RLock()
+	defer exe.RUnlock()
+	return exe.stateCache.GetAccount(address)
+}
+
+// Storage
+func (exe *executor) GetStorage(address crypto.Address, key binary.Word256) (binary.Word256, error) {
+	exe.RLock()
+	defer exe.RUnlock()
+	return exe.stateCache.GetStorage(address, key)
+}
diff --git a/execution/execution_test.go b/execution/execution_test.go
index f67a278d8707b6796ac90bc7b2d0e0fca6767db1..9255bdb1b9284ad213c4b1bc382e97d3c7932381 100644
--- a/execution/execution_test.go
+++ b/execution/execution_test.go
@@ -124,6 +124,12 @@ var testGenesisDoc, testPrivAccounts, _ = deterministicGenesis.
 	GenesisDoc(3, true, 1000, 1, true, 1000)
 var testChainID = testGenesisDoc.ChainID()
 
+type testExecutor struct {
+	*executor
+	blockchain *bcm.Blockchain
+	event.Emitter
+}
+
 func makeUsers(n int) []acm.AddressableSigner {
 	users := make([]acm.AddressableSigner, n)
 	for i := 0; i < n; i++ {
@@ -139,10 +145,14 @@ func newBlockchain(genesisDoc *genesis.GenesisDoc) *bcm.Blockchain {
 	return bc
 }
 
-func makeExecutor(state *State) (*executor, event.Emitter) {
+func makeExecutor(state *State) *testExecutor {
 	emitter := event.NewEmitter(logger)
-	return newExecutor("makeExecutorCache", true, state,
-		newBlockchain(testGenesisDoc).Tip, emitter, logger), emitter
+	blockchain := newBlockchain(testGenesisDoc)
+	return &testExecutor{
+		executor:   newExecutor("makeExecutorCache", true, state, blockchain.Tip, emitter, logger),
+		blockchain: blockchain,
+		Emitter:    emitter,
+	}
 }
 
 func newBaseGenDoc(globalPerm, accountPerm ptypes.AccountPermissions) genesis.GenesisDoc {
@@ -193,46 +203,46 @@ func TestSendFails(t *testing.T) {
 	genDoc.Accounts[3].Permissions.Base.Set(ptypes.CreateContract, true)
 	st, err := MakeGenesisState(stateDB, &genDoc)
 	require.NoError(t, err)
-	batchCommitter, _ := makeExecutor(st)
+	exe := makeExecutor(st)
 
 	//-------------------
 	// send txs
 
 	// simple send tx should fail
 	tx := payload.NewSendTx()
-	if err := tx.AddInput(batchCommitter.stateCache, users[0].PublicKey(), 5); err != nil {
+	if err := tx.AddInput(exe.stateCache, users[0].PublicKey(), 5); err != nil {
 		t.Fatal(err)
 	}
 	tx.AddOutput(users[1].Address(), 5)
-	signAndExecute(t, true, batchCommitter, testChainID, tx, users[0])
+	signAndExecute(t, true, exe, testChainID, tx, users[0])
 
 	// simple send tx with call perm should fail
 	tx = payload.NewSendTx()
-	if err := tx.AddInput(batchCommitter.stateCache, users[2].PublicKey(), 5); err != nil {
+	if err := tx.AddInput(exe.stateCache, users[2].PublicKey(), 5); err != nil {
 		t.Fatal(err)
 	}
 	tx.AddOutput(users[4].Address(), 5)
 
-	signAndExecute(t, true, batchCommitter, testChainID, tx, users[2])
+	signAndExecute(t, true, exe, testChainID, tx, users[2])
 
 	// simple send tx with create perm should fail
 	tx = payload.NewSendTx()
-	if err := tx.AddInput(batchCommitter.stateCache, users[3].PublicKey(), 5); err != nil {
+	if err := tx.AddInput(exe.stateCache, users[3].PublicKey(), 5); err != nil {
 		t.Fatal(err)
 	}
 	tx.AddOutput(users[4].Address(), 5)
-	signAndExecute(t, true, batchCommitter, testChainID, tx, users[3])
+	signAndExecute(t, true, exe, testChainID, tx, users[3])
 
 	// simple send tx to unknown account without create_account perm should fail
-	acc := getAccount(batchCommitter.stateCache, users[3].Address())
+	acc := getAccount(exe.stateCache, users[3].Address())
 	acc.MutablePermissions().Base.Set(ptypes.Send, true)
-	batchCommitter.stateCache.UpdateAccount(acc)
+	exe.stateCache.UpdateAccount(acc)
 	tx = payload.NewSendTx()
-	if err := tx.AddInput(batchCommitter.stateCache, users[3].PublicKey(), 5); err != nil {
+	if err := tx.AddInput(exe.stateCache, users[3].PublicKey(), 5); err != nil {
 		t.Fatal(err)
 	}
 	tx.AddOutput(users[6].Address(), 5)
-	signAndExecute(t, true, batchCommitter, testChainID, tx, users[3])
+	signAndExecute(t, true, exe, testChainID, tx, users[3])
 }
 
 func TestName(t *testing.T) {
@@ -243,7 +253,7 @@ func TestName(t *testing.T) {
 	genDoc.Accounts[1].Permissions.Base.Set(ptypes.Name, true)
 	st, err := MakeGenesisState(stateDB, &genDoc)
 	require.NoError(t, err)
-	batchCommitter, _ := makeExecutor(st)
+	batchCommitter := makeExecutor(st)
 
 	//-------------------
 	// name txs
@@ -272,7 +282,7 @@ func TestCallFails(t *testing.T) {
 	genDoc.Accounts[3].Permissions.Base.Set(ptypes.CreateContract, true)
 	st, err := MakeGenesisState(stateDB, &genDoc)
 	require.NoError(t, err)
-	batchCommitter, _ := makeExecutor(st)
+	batchCommitter := makeExecutor(st)
 
 	//-------------------
 	// call txs
@@ -313,7 +323,7 @@ func TestSendPermission(t *testing.T) {
 	genDoc.Accounts[0].Permissions.Base.Set(ptypes.Send, true) // give the 0 account permission
 	st, err := MakeGenesisState(stateDB, &genDoc)
 	require.NoError(t, err)
-	batchCommitter, _ := makeExecutor(st)
+	batchCommitter := makeExecutor(st)
 
 	// A single input, having the permission, should succeed
 	tx := payload.NewSendTx()
@@ -338,7 +348,7 @@ func TestCallPermission(t *testing.T) {
 	genDoc.Accounts[0].Permissions.Base.Set(ptypes.Call, true) // give the 0 account permission
 	st, err := MakeGenesisState(stateDB, &genDoc)
 	require.NoError(t, err)
-	batchCommitter, emitter := makeExecutor(st)
+	exe := makeExecutor(st)
 
 	//------------------------------
 	// call to simple contract
@@ -354,11 +364,11 @@ func TestCallPermission(t *testing.T) {
 		StorageRoot: Zero256.Bytes(),
 		Permissions: permission.ZeroAccountPermissions,
 	}.MutableAccount()
-	st.UpdateAccount(simpleAcc)
+	st.writeState.UpdateAccount(simpleAcc)
 
 	// A single input, having the permission, should succeed
-	tx, _ := payload.NewCallTx(batchCommitter.stateCache, users[0].PublicKey(), &simpleContractAddr, nil, 100, 100, 100)
-	signAndExecute(t, false, batchCommitter, testChainID, tx, users[0])
+	tx, _ := payload.NewCallTx(exe.stateCache, users[0].PublicKey(), &simpleContractAddr, nil, 100, 100, 100)
+	signAndExecute(t, false, exe, testChainID, tx, users[0])
 
 	//----------------------------------------------------------
 	// call to contract that calls simple contract - without perm
@@ -375,15 +385,15 @@ func TestCallPermission(t *testing.T) {
 		StorageRoot: Zero256.Bytes(),
 		Permissions: permission.ZeroAccountPermissions,
 	}.MutableAccount()
-	batchCommitter.stateCache.UpdateAccount(caller1Acc)
+	exe.stateCache.UpdateAccount(caller1Acc)
 
 	// A single input, having the permission, but the contract doesn't have permission
-	tx, _ = payload.NewCallTx(batchCommitter.stateCache, users[0].PublicKey(), &caller1ContractAddr, nil, 100, 10000, 100)
+	tx, _ = payload.NewCallTx(exe.stateCache, users[0].PublicKey(), &caller1ContractAddr, nil, 100, 10000, 100)
 	txEnv := txs.Enclose(testChainID, tx)
 	require.NoError(t, txEnv.Sign(users[0]))
 
 	// we need to subscribe to the Call event to detect the exception
-	_, err = execTxWaitAccountCall(t, batchCommitter, emitter, txEnv, caller1ContractAddr) //
+	_, err = execTxWaitAccountCall(t, exe, txEnv, caller1ContractAddr) //
 	require.Error(t, err)
 
 	//----------------------------------------------------------
@@ -392,13 +402,13 @@ func TestCallPermission(t *testing.T) {
 
 	// A single input, having the permission, and the contract has permission
 	caller1Acc.MutablePermissions().Base.Set(ptypes.Call, true)
-	batchCommitter.stateCache.UpdateAccount(caller1Acc)
-	tx, _ = payload.NewCallTx(batchCommitter.stateCache, users[0].PublicKey(), &caller1ContractAddr, nil, 100, 10000, 100)
+	exe.stateCache.UpdateAccount(caller1Acc)
+	tx, _ = payload.NewCallTx(exe.stateCache, users[0].PublicKey(), &caller1ContractAddr, nil, 100, 10000, 100)
 	txEnv = txs.Enclose(testChainID, tx)
 	require.NoError(t, txEnv.Sign(users[0]))
 
 	// we need to subscribe to the Call event to detect the exception
-	_, err = execTxWaitAccountCall(t, batchCommitter, emitter, txEnv, caller1ContractAddr) //
+	_, err = execTxWaitAccountCall(t, exe, txEnv, caller1ContractAddr) //
 	require.NoError(t, err)
 
 	//----------------------------------------------------------
@@ -419,14 +429,14 @@ func TestCallPermission(t *testing.T) {
 	}.MutableAccount()
 	caller1Acc.MutablePermissions().Base.Set(ptypes.Call, false)
 	caller2Acc.MutablePermissions().Base.Set(ptypes.Call, true)
-	batchCommitter.stateCache.UpdateAccount(caller1Acc)
-	batchCommitter.stateCache.UpdateAccount(caller2Acc)
+	exe.stateCache.UpdateAccount(caller1Acc)
+	exe.stateCache.UpdateAccount(caller2Acc)
 
-	tx, _ = payload.NewCallTx(batchCommitter.stateCache, users[0].PublicKey(), &caller2ContractAddr, nil, 100, 10000, 100)
+	tx, _ = payload.NewCallTx(exe.stateCache, users[0].PublicKey(), &caller2ContractAddr, nil, 100, 10000, 100)
 	txEnv = txs.Enclose(testChainID, tx)
 	require.NoError(t, txEnv.Sign(users[0]))
 	// we need to subscribe to the Call event to detect the exception
-	_, err = execTxWaitAccountCall(t, batchCommitter, emitter, txEnv, caller1ContractAddr) //
+	_, err = execTxWaitAccountCall(t, exe, txEnv, caller1ContractAddr) //
 	require.Error(t, err)
 
 	//----------------------------------------------------------
@@ -436,14 +446,14 @@ func TestCallPermission(t *testing.T) {
 	fmt.Println("\n##### CALL TO CONTRACT CALLING SIMPLE CONTRACT (PASS)")
 
 	caller1Acc.MutablePermissions().Base.Set(ptypes.Call, true)
-	batchCommitter.stateCache.UpdateAccount(caller1Acc)
+	exe.stateCache.UpdateAccount(caller1Acc)
 
-	tx, _ = payload.NewCallTx(batchCommitter.stateCache, users[0].PublicKey(), &caller2ContractAddr, nil, 100, 10000, 100)
+	tx, _ = payload.NewCallTx(exe.stateCache, users[0].PublicKey(), &caller2ContractAddr, nil, 100, 10000, 100)
 	txEnv = txs.Enclose(testChainID, tx)
 	require.NoError(t, txEnv.Sign(users[0]))
 
 	// we need to subscribe to the Call event to detect the exception
-	_, err = execTxWaitAccountCall(t, batchCommitter, emitter, txEnv, caller1ContractAddr) //
+	_, err = execTxWaitAccountCall(t, exe, txEnv, caller1ContractAddr) //
 	require.NoError(t, err)
 }
 
@@ -455,7 +465,7 @@ func TestCreatePermission(t *testing.T) {
 	genDoc.Accounts[0].Permissions.Base.Set(ptypes.Call, true)           // give the 0 account permission
 	st, err := MakeGenesisState(stateDB, &genDoc)
 	require.NoError(t, err)
-	batchCommitter, emitter := makeExecutor(st)
+	exe := makeExecutor(st)
 
 	//------------------------------
 	// create a simple contract
@@ -465,12 +475,12 @@ func TestCreatePermission(t *testing.T) {
 	createCode := wrapContractForCreate(contractCode)
 
 	// A single input, having the permission, should succeed
-	tx, _ := payload.NewCallTx(batchCommitter.stateCache, users[0].PublicKey(), nil, createCode, 100, 100, 100)
-	signAndExecute(t, false, batchCommitter, testChainID, tx, users[0])
+	tx, _ := payload.NewCallTx(exe.stateCache, users[0].PublicKey(), nil, createCode, 100, 100, 100)
+	signAndExecute(t, false, exe, testChainID, tx, users[0])
 
 	// ensure the contract is there
 	contractAddr := crypto.NewContractAddress(tx.Input.Address, tx.Input.Sequence)
-	contractAcc := getAccount(batchCommitter.stateCache, contractAddr)
+	contractAcc := getAccount(exe.stateCache, contractAddr)
 	if contractAcc == nil {
 		t.Fatalf("failed to create contract %s", contractAddr)
 	}
@@ -488,12 +498,12 @@ func TestCreatePermission(t *testing.T) {
 	createFactoryCode := wrapContractForCreate(factoryCode)
 
 	// A single input, having the permission, should succeed
-	tx, _ = payload.NewCallTx(batchCommitter.stateCache, users[0].PublicKey(), nil, createFactoryCode, 100, 100, 100)
-	signAndExecute(t, false, batchCommitter, testChainID, tx, users[0])
+	tx, _ = payload.NewCallTx(exe.stateCache, users[0].PublicKey(), nil, createFactoryCode, 100, 100, 100)
+	signAndExecute(t, false, exe, testChainID, tx, users[0])
 
 	// ensure the contract is there
 	contractAddr = crypto.NewContractAddress(tx.Input.Address, tx.Input.Sequence)
-	contractAcc = getAccount(batchCommitter.stateCache, contractAddr)
+	contractAcc = getAccount(exe.stateCache, contractAddr)
 	if contractAcc == nil {
 		t.Fatalf("failed to create contract %s", contractAddr)
 	}
@@ -506,11 +516,11 @@ func TestCreatePermission(t *testing.T) {
 	fmt.Println("\n###### CALL THE FACTORY (FAIL)")
 
 	// A single input, having the permission, should succeed
-	tx, _ = payload.NewCallTx(batchCommitter.stateCache, users[0].PublicKey(), &contractAddr, createCode, 100, 100, 100)
+	tx, _ = payload.NewCallTx(exe.stateCache, users[0].PublicKey(), &contractAddr, createCode, 100, 100, 100)
 	txEnv := txs.Enclose(testChainID, tx)
 	require.NoError(t, txEnv.Sign(users[0]))
 	// we need to subscribe to the Call event to detect the exception
-	_, err = execTxWaitAccountCall(t, batchCommitter, emitter, txEnv, contractAddr) //
+	_, err = execTxWaitAccountCall(t, exe, txEnv, contractAddr) //
 	require.Error(t, err)
 
 	//------------------------------
@@ -518,14 +528,14 @@ func TestCreatePermission(t *testing.T) {
 	fmt.Println("\n###### CALL THE FACTORY (PASS)")
 
 	contractAcc.MutablePermissions().Base.Set(ptypes.CreateContract, true)
-	batchCommitter.stateCache.UpdateAccount(contractAcc)
+	exe.stateCache.UpdateAccount(contractAcc)
 
 	// A single input, having the permission, should succeed
-	tx, _ = payload.NewCallTx(batchCommitter.stateCache, users[0].PublicKey(), &contractAddr, createCode, 100, 100, 100)
+	tx, _ = payload.NewCallTx(exe.stateCache, users[0].PublicKey(), &contractAddr, createCode, 100, 100, 100)
 	txEnv = txs.Enclose(testChainID, tx)
 	require.NoError(t, txEnv.Sign(users[0]))
 	// we need to subscribe to the Call event to detect the exception
-	_, err = execTxWaitAccountCall(t, batchCommitter, emitter, txEnv, contractAddr) //
+	_, err = execTxWaitAccountCall(t, exe, txEnv, contractAddr) //
 	require.NoError(t, err)
 
 	//--------------------------------
@@ -543,16 +553,16 @@ func TestCreatePermission(t *testing.T) {
 	}.MutableAccount()
 	contractAcc.MutablePermissions().Base.Set(ptypes.Call, true)
 	contractAcc.MutablePermissions().Base.Set(ptypes.CreateContract, true)
-	batchCommitter.stateCache.UpdateAccount(contractAcc)
+	exe.stateCache.UpdateAccount(contractAcc)
 
 	// this should call the 0 address but not create ...
-	tx, _ = payload.NewCallTx(batchCommitter.stateCache, users[0].PublicKey(), &contractAddr, createCode, 100, 10000, 100)
+	tx, _ = payload.NewCallTx(exe.stateCache, users[0].PublicKey(), &contractAddr, createCode, 100, 10000, 100)
 	txEnv = txs.Enclose(testChainID, tx)
 	require.NoError(t, txEnv.Sign(users[0]))
 	// we need to subscribe to the Call event to detect the exception
-	_, err = execTxWaitAccountCall(t, batchCommitter, emitter, txEnv, crypto.Address{}) //
+	_, err = execTxWaitAccountCall(t, exe, txEnv, crypto.Address{}) //
 	require.NoError(t, err)
-	zeroAcc := getAccount(batchCommitter.stateCache, crypto.Address{})
+	zeroAcc := getAccount(exe.stateCache, crypto.Address{})
 	if len(zeroAcc.Code()) != 0 {
 		t.Fatal("the zero account was given code from a CALL!")
 	}
@@ -567,7 +577,7 @@ func TestCreateAccountPermission(t *testing.T) {
 	genDoc.Accounts[0].Permissions.Base.Set(ptypes.CreateAccount, true) // give the 0 account permission
 	st, err := MakeGenesisState(stateDB, &genDoc)
 	require.NoError(t, err)
-	batchCommitter, emitter := makeExecutor(st)
+	batchCommitter := makeExecutor(st)
 
 	//----------------------------------------------------------
 	// SendTx to unknown account
@@ -656,7 +666,7 @@ func TestCreateAccountPermission(t *testing.T) {
 	txCallEnv.Sign(users[0])
 
 	// we need to subscribe to the Call event to detect the exception
-	_, err = execTxWaitAccountCall(t, batchCommitter, emitter, txCallEnv, caller1ContractAddr) //
+	_, err = execTxWaitAccountCall(t, batchCommitter, txCallEnv, caller1ContractAddr) //
 	require.Error(t, err)
 
 	// NOTE: for a contract to be able to CreateAccount, it must be able to call
@@ -670,7 +680,7 @@ func TestCreateAccountPermission(t *testing.T) {
 	txCallEnv.Sign(users[0])
 
 	// we need to subscribe to the Call event to detect the exception
-	_, err = execTxWaitAccountCall(t, batchCommitter, emitter, txCallEnv, caller1ContractAddr) //
+	_, err = execTxWaitAccountCall(t, batchCommitter, txCallEnv, caller1ContractAddr) //
 	require.NoError(t, err)
 
 }
@@ -692,7 +702,7 @@ func TestSNativeCALL(t *testing.T) {
 	genDoc.Accounts[3].Permissions.AddRole("bee")
 	st, err := MakeGenesisState(stateDB, &genDoc)
 	require.NoError(t, err)
-	batchCommitter, emitter := makeExecutor(st)
+	exe := makeExecutor(st)
 
 	//----------------------------------------------------------
 	// Test CALL to SNative contracts
@@ -709,13 +719,13 @@ func TestSNativeCALL(t *testing.T) {
 
 	doug.MutablePermissions().Base.Set(ptypes.Call, true)
 	//doug.Permissions.Base.Set(permission.HasBase, true)
-	batchCommitter.stateCache.UpdateAccount(doug)
+	exe.stateCache.UpdateAccount(doug)
 
 	fmt.Println("\n#### HasBase")
 	// HasBase
 	snativeAddress, pF, data := snativePermTestInputCALL("hasBase", users[3], ptypes.Bond, false)
-	testSNativeCALLExpectFail(t, batchCommitter, emitter, doug, snativeAddress, data)
-	testSNativeCALLExpectPass(t, batchCommitter, emitter, doug, pF, snativeAddress, data, func(ret []byte) error {
+	testSNativeCALLExpectFail(t, exe, doug, snativeAddress, data)
+	testSNativeCALLExpectPass(t, exe, doug, pF, snativeAddress, data, func(ret []byte) error {
 		// return value should be true or false as a 32 byte array...
 		if !IsZeros(ret[:31]) || ret[31] != byte(1) {
 			return fmt.Errorf("Expected 1. Got %X", ret)
@@ -726,10 +736,10 @@ func TestSNativeCALL(t *testing.T) {
 	fmt.Println("\n#### SetBase")
 	// SetBase
 	snativeAddress, pF, data = snativePermTestInputCALL("setBase", users[3], ptypes.Bond, false)
-	testSNativeCALLExpectFail(t, batchCommitter, emitter, doug, snativeAddress, data)
-	testSNativeCALLExpectPass(t, batchCommitter, emitter, doug, pF, snativeAddress, data, func(ret []byte) error { return nil })
+	testSNativeCALLExpectFail(t, exe, doug, snativeAddress, data)
+	testSNativeCALLExpectPass(t, exe, doug, pF, snativeAddress, data, func(ret []byte) error { return nil })
 	snativeAddress, pF, data = snativePermTestInputCALL("hasBase", users[3], ptypes.Bond, false)
-	testSNativeCALLExpectPass(t, batchCommitter, emitter, doug, pF, snativeAddress, data, func(ret []byte) error {
+	testSNativeCALLExpectPass(t, exe, doug, pF, snativeAddress, data, func(ret []byte) error {
 		// return value should be true or false as a 32 byte array...
 		if !IsZeros(ret) {
 			return fmt.Errorf("Expected 0. Got %X", ret)
@@ -737,9 +747,9 @@ func TestSNativeCALL(t *testing.T) {
 		return nil
 	})
 	snativeAddress, pF, data = snativePermTestInputCALL("setBase", users[3], ptypes.CreateContract, true)
-	testSNativeCALLExpectPass(t, batchCommitter, emitter, doug, pF, snativeAddress, data, func(ret []byte) error { return nil })
+	testSNativeCALLExpectPass(t, exe, doug, pF, snativeAddress, data, func(ret []byte) error { return nil })
 	snativeAddress, pF, data = snativePermTestInputCALL("hasBase", users[3], ptypes.CreateContract, false)
-	testSNativeCALLExpectPass(t, batchCommitter, emitter, doug, pF, snativeAddress, data, func(ret []byte) error {
+	testSNativeCALLExpectPass(t, exe, doug, pF, snativeAddress, data, func(ret []byte) error {
 		// return value should be true or false as a 32 byte array...
 		if !IsZeros(ret[:31]) || ret[31] != byte(1) {
 			return fmt.Errorf("Expected 1. Got %X", ret)
@@ -750,10 +760,10 @@ func TestSNativeCALL(t *testing.T) {
 	fmt.Println("\n#### UnsetBase")
 	// UnsetBase
 	snativeAddress, pF, data = snativePermTestInputCALL("unsetBase", users[3], ptypes.CreateContract, false)
-	testSNativeCALLExpectFail(t, batchCommitter, emitter, doug, snativeAddress, data)
-	testSNativeCALLExpectPass(t, batchCommitter, emitter, doug, pF, snativeAddress, data, func(ret []byte) error { return nil })
+	testSNativeCALLExpectFail(t, exe, doug, snativeAddress, data)
+	testSNativeCALLExpectPass(t, exe, doug, pF, snativeAddress, data, func(ret []byte) error { return nil })
 	snativeAddress, pF, data = snativePermTestInputCALL("hasBase", users[3], ptypes.CreateContract, false)
-	testSNativeCALLExpectPass(t, batchCommitter, emitter, doug, pF, snativeAddress, data, func(ret []byte) error {
+	testSNativeCALLExpectPass(t, exe, doug, pF, snativeAddress, data, func(ret []byte) error {
 		if !IsZeros(ret) {
 			return fmt.Errorf("Expected 0. Got %X", ret)
 		}
@@ -763,10 +773,10 @@ func TestSNativeCALL(t *testing.T) {
 	fmt.Println("\n#### SetGlobal")
 	// SetGlobalPerm
 	snativeAddress, pF, data = snativePermTestInputCALL("setGlobal", users[3], ptypes.CreateContract, true)
-	testSNativeCALLExpectFail(t, batchCommitter, emitter, doug, snativeAddress, data)
-	testSNativeCALLExpectPass(t, batchCommitter, emitter, doug, pF, snativeAddress, data, func(ret []byte) error { return nil })
+	testSNativeCALLExpectFail(t, exe, doug, snativeAddress, data)
+	testSNativeCALLExpectPass(t, exe, doug, pF, snativeAddress, data, func(ret []byte) error { return nil })
 	snativeAddress, pF, data = snativePermTestInputCALL("hasBase", users[3], ptypes.CreateContract, false)
-	testSNativeCALLExpectPass(t, batchCommitter, emitter, doug, pF, snativeAddress, data, func(ret []byte) error {
+	testSNativeCALLExpectPass(t, exe, doug, pF, snativeAddress, data, func(ret []byte) error {
 		// return value should be true or false as a 32 byte array...
 		if !IsZeros(ret[:31]) || ret[31] != byte(1) {
 			return fmt.Errorf("Expected 1. Got %X", ret)
@@ -777,8 +787,8 @@ func TestSNativeCALL(t *testing.T) {
 	fmt.Println("\n#### HasRole")
 	// HasRole
 	snativeAddress, pF, data = snativeRoleTestInputCALL("hasRole", users[3], "bumble")
-	testSNativeCALLExpectFail(t, batchCommitter, emitter, doug, snativeAddress, data)
-	testSNativeCALLExpectPass(t, batchCommitter, emitter, doug, pF, snativeAddress, data, func(ret []byte) error {
+	testSNativeCALLExpectFail(t, exe, doug, snativeAddress, data)
+	testSNativeCALLExpectPass(t, exe, doug, pF, snativeAddress, data, func(ret []byte) error {
 		if !IsZeros(ret[:31]) || ret[31] != byte(1) {
 			return fmt.Errorf("Expected 1. Got %X", ret)
 		}
@@ -788,17 +798,17 @@ func TestSNativeCALL(t *testing.T) {
 	fmt.Println("\n#### AddRole")
 	// AddRole
 	snativeAddress, pF, data = snativeRoleTestInputCALL("hasRole", users[3], "chuck")
-	testSNativeCALLExpectPass(t, batchCommitter, emitter, doug, pF, snativeAddress, data, func(ret []byte) error {
+	testSNativeCALLExpectPass(t, exe, doug, pF, snativeAddress, data, func(ret []byte) error {
 		if !IsZeros(ret) {
 			return fmt.Errorf("Expected 0. Got %X", ret)
 		}
 		return nil
 	})
 	snativeAddress, pF, data = snativeRoleTestInputCALL("addRole", users[3], "chuck")
-	testSNativeCALLExpectFail(t, batchCommitter, emitter, doug, snativeAddress, data)
-	testSNativeCALLExpectPass(t, batchCommitter, emitter, doug, pF, snativeAddress, data, func(ret []byte) error { return nil })
+	testSNativeCALLExpectFail(t, exe, doug, snativeAddress, data)
+	testSNativeCALLExpectPass(t, exe, doug, pF, snativeAddress, data, func(ret []byte) error { return nil })
 	snativeAddress, pF, data = snativeRoleTestInputCALL("hasRole", users[3], "chuck")
-	testSNativeCALLExpectPass(t, batchCommitter, emitter, doug, pF, snativeAddress, data, func(ret []byte) error {
+	testSNativeCALLExpectPass(t, exe, doug, pF, snativeAddress, data, func(ret []byte) error {
 		if !IsZeros(ret[:31]) || ret[31] != byte(1) {
 			return fmt.Errorf("Expected 1. Got %X", ret)
 		}
@@ -808,10 +818,10 @@ func TestSNativeCALL(t *testing.T) {
 	fmt.Println("\n#### RemoveRole")
 	// RemoveRole
 	snativeAddress, pF, data = snativeRoleTestInputCALL("removeRole", users[3], "chuck")
-	testSNativeCALLExpectFail(t, batchCommitter, emitter, doug, snativeAddress, data)
-	testSNativeCALLExpectPass(t, batchCommitter, emitter, doug, pF, snativeAddress, data, func(ret []byte) error { return nil })
+	testSNativeCALLExpectFail(t, exe, doug, snativeAddress, data)
+	testSNativeCALLExpectPass(t, exe, doug, pF, snativeAddress, data, func(ret []byte) error { return nil })
 	snativeAddress, pF, data = snativeRoleTestInputCALL("hasRole", users[3], "chuck")
-	testSNativeCALLExpectPass(t, batchCommitter, emitter, doug, pF, snativeAddress, data, func(ret []byte) error {
+	testSNativeCALLExpectPass(t, exe, doug, pF, snativeAddress, data, func(ret []byte) error {
 		if !IsZeros(ret) {
 			return fmt.Errorf("Expected 0. Got %X", ret)
 		}
@@ -829,7 +839,7 @@ func TestSNativeTx(t *testing.T) {
 	genDoc.Accounts[3].Permissions.AddRole("bee")
 	st, err := MakeGenesisState(stateDB, &genDoc)
 	require.NoError(t, err)
-	batchCommitter, _ := makeExecutor(st)
+	batchCommitter := makeExecutor(st)
 
 	//----------------------------------------------------------
 	// Test SNativeTx
@@ -935,9 +945,9 @@ func TestTxSequence(t *testing.T) {
 }
 
 func TestNameTxs(t *testing.T) {
-	state, err := MakeGenesisState(dbm.NewMemDB(), testGenesisDoc)
+	st, err := MakeGenesisState(dbm.NewMemDB(), testGenesisDoc)
 	require.NoError(t, err)
-	state.Save()
+	st.writeState.Save()
 
 	names.MinNameRegistrationPeriod = 5
 	blockchain := newBlockchain(testGenesisDoc)
@@ -952,11 +962,11 @@ func TestNameTxs(t *testing.T) {
 	for _, name := range nameStrings {
 		amt := fee + numDesiredBlocks*names.NameByteCostMultiplier*names.NameBlockCostMultiplier*
 			names.NameBaseCost(name, data)
-		tx, _ := payload.NewNameTx(state, testPrivAccounts[0].PublicKey(), name, data, amt, fee)
+		tx, _ := payload.NewNameTx(st, testPrivAccounts[0].PublicKey(), name, data, amt, fee)
 		txEnv := txs.Enclose(testChainID, tx)
 		txEnv.Sign(testPrivAccounts[0])
 
-		if err := execTxWithState(state, txEnv); err == nil {
+		if err := execTxWithState(st, txEnv); err == nil {
 			t.Fatalf("Expected invalid name error from %s", name)
 		}
 	}
@@ -967,17 +977,16 @@ func TestNameTxs(t *testing.T) {
 	for _, data := range datas {
 		amt := fee + numDesiredBlocks*names.NameByteCostMultiplier*names.NameBlockCostMultiplier*
 			names.NameBaseCost(name, data)
-		tx, _ := payload.NewNameTx(state, testPrivAccounts[0].PublicKey(), name, data, amt, fee)
+		tx, _ := payload.NewNameTx(st, testPrivAccounts[0].PublicKey(), name, data, amt, fee)
 		txEnv := txs.Enclose(testChainID, tx)
 		txEnv.Sign(testPrivAccounts[0])
 
-		if err := execTxWithState(state, txEnv); err == nil {
+		if err := execTxWithState(st, txEnv); err == nil {
 			t.Fatalf("Expected invalid data error from %s", data)
 		}
 	}
 
 	validateEntry := func(t *testing.T, entry *names.Entry, name, data string, addr crypto.Address, expires uint64) {
-
 		if entry == nil {
 			t.Fatalf("Could not find name %s", name)
 		}
@@ -991,7 +1000,7 @@ func TestNameTxs(t *testing.T) {
 			t.Fatalf("Wrong name. Got %s expected %s", entry.Name, name)
 		}
 		if expires != entry.Expires {
-			t.Fatalf("Wrong expiry. Got %d, expected %d", entry.Expires, expires)
+			t.Fatalf("Wrong expiry. Got %d, expected %d: %s", entry.Expires, expires, debug.Stack())
 		}
 	}
 
@@ -999,96 +1008,97 @@ func TestNameTxs(t *testing.T) {
 	name = "@looking_good/karaoke_bar.broadband"
 	data = "on this side of neptune there are 1234567890 people: first is OMNIVORE+-3. Or is it. Ok this is pretty restrictive. No exclamations :(. Faces tho :')"
 	amt := fee + numDesiredBlocks*names.NameByteCostMultiplier*names.NameBlockCostMultiplier*names.NameBaseCost(name, data)
-	tx, _ := payload.NewNameTx(state, testPrivAccounts[0].PublicKey(), name, data, amt, fee)
+	tx, _ := payload.NewNameTx(st, testPrivAccounts[0].PublicKey(), name, data, amt, fee)
 	txEnv := txs.Enclose(testChainID, tx)
 	require.NoError(t, txEnv.Sign(testPrivAccounts[0]))
-	if err := execTxWithState(state, txEnv); err != nil {
+	if err := execTxWithState(st, txEnv); err != nil {
 		t.Fatal(err)
 	}
-	entry, err := state.GetNameEntry(name)
+	entry, err := st.GetNameEntry(name)
 	require.NoError(t, err)
 	validateEntry(t, entry, name, data, testPrivAccounts[0].Address(), startingBlock+numDesiredBlocks)
 
 	// fail to update it as non-owner, in same block
-	tx, _ = payload.NewNameTx(state, testPrivAccounts[1].PublicKey(), name, data, amt, fee)
+	tx, _ = payload.NewNameTx(st, testPrivAccounts[1].PublicKey(), name, data, amt, fee)
 	txEnv = txs.Enclose(testChainID, tx)
 	require.NoError(t, txEnv.Sign(testPrivAccounts[1]))
-	if err := execTxWithState(state, txEnv); err == nil {
+	if err := execTxWithState(st, txEnv); err == nil {
 		t.Fatal("Expected error")
 	}
 
 	// update it as owner, just to increase expiry, in same block
 	// NOTE: we have to resend the data or it will clear it (is this what we want?)
-	tx, _ = payload.NewNameTx(state, testPrivAccounts[0].PublicKey(), name, data, amt, fee)
+	tx, _ = payload.NewNameTx(st, testPrivAccounts[0].PublicKey(), name, data, amt, fee)
 	txEnv = txs.Enclose(testChainID, tx)
 	require.NoError(t, txEnv.Sign(testPrivAccounts[0]))
-	if err := execTxWithStateNewBlock(state, blockchain, txEnv); err != nil {
+	if err := execTxWithStateNewBlock(st, blockchain, txEnv); err != nil {
 		t.Fatal(err)
 	}
-	entry, err = state.GetNameEntry(name)
+	entry, err = st.GetNameEntry(name)
 	require.NoError(t, err)
 	validateEntry(t, entry, name, data, testPrivAccounts[0].Address(), startingBlock+numDesiredBlocks*2)
 
 	// update it as owner, just to increase expiry, in next block
-	tx, _ = payload.NewNameTx(state, testPrivAccounts[0].PublicKey(), name, data, amt, fee)
+	tx, _ = payload.NewNameTx(st, testPrivAccounts[0].PublicKey(), name, data, amt, fee)
 	txEnv = txs.Enclose(testChainID, tx)
 	require.NoError(t, txEnv.Sign(testPrivAccounts[0]))
-	if err := execTxWithStateNewBlock(state, blockchain, txEnv); err != nil {
+	if err := execTxWithStateNewBlock(st, blockchain, txEnv); err != nil {
 		t.Fatal(err)
 	}
-	entry, err = state.GetNameEntry(name)
+	entry, err = st.GetNameEntry(name)
 	require.NoError(t, err)
 	validateEntry(t, entry, name, data, testPrivAccounts[0].Address(), startingBlock+numDesiredBlocks*3)
 
 	// fail to update it as non-owner
 	// Fast forward
 	for blockchain.Tip.LastBlockHeight() < entry.Expires-1 {
-		commitNewBlock(state, blockchain)
+		commitNewBlock(st, blockchain)
 	}
-	tx, _ = payload.NewNameTx(state, testPrivAccounts[1].PublicKey(), name, data, amt, fee)
+	tx, _ = payload.NewNameTx(st, testPrivAccounts[1].PublicKey(), name, data, amt, fee)
 	txEnv = txs.Enclose(testChainID, tx)
 	require.NoError(t, txEnv.Sign(testPrivAccounts[1]))
-	if err := execTxWithStateAndBlockchain(state, blockchain.Tip, txEnv); err == nil {
+	if err := execTxWithStateAndBlockchain(st, blockchain, txEnv); err == nil {
 		t.Fatal("Expected error")
 	}
-	commitNewBlock(state, blockchain)
+	commitNewBlock(st, blockchain)
 
 	// once expires, non-owner succeeds
-	tx, _ = payload.NewNameTx(state, testPrivAccounts[1].PublicKey(), name, data, amt, fee)
+	startingBlock = blockchain.LastBlockHeight()
+	tx, _ = payload.NewNameTx(st, testPrivAccounts[1].PublicKey(), name, data, amt, fee)
 	txEnv = txs.Enclose(testChainID, tx)
 	require.NoError(t, txEnv.Sign(testPrivAccounts[1]))
-	if err := execTxWithStateAndBlockchain(state, blockchain.Tip, txEnv); err != nil {
+	if err := execTxWithStateAndBlockchain(st, blockchain, txEnv); err != nil {
 		t.Fatal(err)
 	}
-	entry, err = state.GetNameEntry(name)
+	entry, err = st.GetNameEntry(name)
 	require.NoError(t, err)
-	validateEntry(t, entry, name, data, testPrivAccounts[1].Address(), blockchain.LastBlockHeight()+numDesiredBlocks)
+	validateEntry(t, entry, name, data, testPrivAccounts[1].Address(), startingBlock+numDesiredBlocks)
 
 	// update it as new owner, with new data (longer), but keep the expiry!
 	data = "In the beginning there was no thing, not even the beginning. It hadn't been here, no there, nor for that matter anywhere, not especially because it had not to even exist, let alone to not. Nothing especially odd about that."
 	oldCredit := amt - fee
 	numDesiredBlocks = 10
 	amt = fee + numDesiredBlocks*names.NameByteCostMultiplier*names.NameBlockCostMultiplier*names.NameBaseCost(name, data) - oldCredit
-	tx, _ = payload.NewNameTx(state, testPrivAccounts[1].PublicKey(), name, data, amt, fee)
+	tx, _ = payload.NewNameTx(st, testPrivAccounts[1].PublicKey(), name, data, amt, fee)
 	txEnv = txs.Enclose(testChainID, tx)
 	require.NoError(t, txEnv.Sign(testPrivAccounts[1]))
-	if err := execTxWithStateAndBlockchain(state, blockchain.Tip, txEnv); err != nil {
+	if err := execTxWithStateAndBlockchain(st, blockchain, txEnv); err != nil {
 		t.Fatal(err)
 	}
-	entry, err = state.GetNameEntry(name)
+	entry, err = st.GetNameEntry(name)
 	require.NoError(t, err)
-	validateEntry(t, entry, name, data, testPrivAccounts[1].Address(), blockchain.LastBlockHeight()+numDesiredBlocks)
+	validateEntry(t, entry, name, data, testPrivAccounts[1].Address(), startingBlock+numDesiredBlocks)
 
 	// test removal
 	amt = fee
 	data = ""
-	tx, _ = payload.NewNameTx(state, testPrivAccounts[1].PublicKey(), name, data, amt, fee)
+	tx, _ = payload.NewNameTx(st, testPrivAccounts[1].PublicKey(), name, data, amt, fee)
 	txEnv = txs.Enclose(testChainID, tx)
 	require.NoError(t, txEnv.Sign(testPrivAccounts[1]))
-	if err := execTxWithStateNewBlock(state, blockchain, txEnv); err != nil {
+	if err := execTxWithStateNewBlock(st, blockchain, txEnv); err != nil {
 		t.Fatal(err)
 	}
-	entry, err = state.GetNameEntry(name)
+	entry, err = st.GetNameEntry(name)
 	require.NoError(t, err)
 	if entry != nil {
 		t.Fatal("Expected removed entry to be nil")
@@ -1096,32 +1106,33 @@ func TestNameTxs(t *testing.T) {
 
 	// create entry by key0,
 	// test removal by key1 after expiry
+	startingBlock = blockchain.LastBlockHeight()
 	name = "looking_good/karaoke_bar"
 	data = "some data"
 	amt = fee + numDesiredBlocks*names.NameByteCostMultiplier*names.NameBlockCostMultiplier*names.NameBaseCost(name, data)
-	tx, _ = payload.NewNameTx(state, testPrivAccounts[0].PublicKey(), name, data, amt, fee)
+	tx, _ = payload.NewNameTx(st, testPrivAccounts[0].PublicKey(), name, data, amt, fee)
 	txEnv = txs.Enclose(testChainID, tx)
 	require.NoError(t, txEnv.Sign(testPrivAccounts[0]))
-	if err := execTxWithStateAndBlockchain(state, blockchain.Tip, txEnv); err != nil {
+	if err := execTxWithStateAndBlockchain(st, blockchain, txEnv); err != nil {
 		t.Fatal(err)
 	}
-	entry, err = state.GetNameEntry(name)
+	entry, err = st.GetNameEntry(name)
 	require.NoError(t, err)
-	validateEntry(t, entry, name, data, testPrivAccounts[0].Address(), blockchain.LastBlockHeight()+numDesiredBlocks)
+	validateEntry(t, entry, name, data, testPrivAccounts[0].Address(), startingBlock+numDesiredBlocks)
 	// Fast forward
 	for blockchain.Tip.LastBlockHeight() < entry.Expires {
-		commitNewBlock(state, blockchain)
+		commitNewBlock(st, blockchain)
 	}
 
 	amt = fee
 	data = ""
-	tx, _ = payload.NewNameTx(state, testPrivAccounts[1].PublicKey(), name, data, amt, fee)
+	tx, _ = payload.NewNameTx(st, testPrivAccounts[1].PublicKey(), name, data, amt, fee)
 	txEnv = txs.Enclose(testChainID, tx)
 	require.NoError(t, txEnv.Sign(testPrivAccounts[1]))
-	if err := execTxWithStateNewBlock(state, blockchain, txEnv); err != nil {
+	if err := execTxWithStateNewBlock(st, blockchain, txEnv); err != nil {
 		t.Fatal(err)
 	}
-	entry, err = state.GetNameEntry(name)
+	entry, err = st.GetNameEntry(name)
 	require.NoError(t, err)
 	if entry != nil {
 		t.Fatal("Expected removed entry to be nil")
@@ -1166,8 +1177,8 @@ func TestCreates(t *testing.T) {
 	newAcc2 := getAccount(state, acc2.Address())
 	newAcc2.SetCode(factoryCode)
 
-	state.UpdateAccount(newAcc1)
-	state.UpdateAccount(newAcc2)
+	state.writeState.UpdateAccount(newAcc1)
+	state.writeState.UpdateAccount(newAcc2)
 
 	createData = append(createData, acc2.Address().Word256().Bytes()...)
 
@@ -1243,7 +1254,7 @@ func TestContractSend(t *testing.T) {
 
 	newAcc1 := getAccount(state, acc1.Address())
 	newAcc1.SetCode(callerCode)
-	state.UpdateAccount(newAcc1)
+	state.writeState.UpdateAccount(newAcc1)
 
 	sendData = append(sendData, acc2.Address().Word256().Bytes()...)
 	sendAmt := uint64(10)
@@ -1282,7 +1293,7 @@ func TestMerklePanic(t *testing.T) {
 	acc0 := getAccount(state, privAccounts[0].Address())
 	acc1 := getAccount(state, privAccounts[1].Address())
 
-	state.Save()
+	state.writeState.Save()
 	// SendTx.
 	{
 		stateSendTx := state.Copy(dbm.NewMemDB())
@@ -1317,7 +1328,7 @@ func TestMerklePanic(t *testing.T) {
 		stateCallTx := state.Copy(dbm.NewMemDB())
 		newAcc1 := getAccount(stateCallTx, acc1.Address())
 		newAcc1.SetCode([]byte{0x60})
-		stateCallTx.UpdateAccount(newAcc1)
+		stateCallTx.writeState.UpdateAccount(newAcc1)
 		tx := &payload.CallTx{
 			Input: &payload.TxInput{
 				Address:  acc0.Address(),
@@ -1335,7 +1346,7 @@ func TestMerklePanic(t *testing.T) {
 			t.Errorf("Got error in executing call transaction, %v", err)
 		}
 	}
-	state.Save()
+	state.writeState.Save()
 	trygetacc0 := getAccount(state, privAccounts[0].Address())
 	fmt.Println(trygetacc0.Address())
 }
@@ -1391,7 +1402,7 @@ func TestTxs(t *testing.T) {
 		stateCallTx := state.Copy(dbm.NewMemDB())
 		newAcc1 := getAccount(stateCallTx, acc1.Address())
 		newAcc1.SetCode([]byte{0x60})
-		stateCallTx.UpdateAccount(newAcc1)
+		stateCallTx.writeState.UpdateAccount(newAcc1)
 		tx := &payload.CallTx{
 			Input: &payload.TxInput{
 				Address:  acc0.Address(),
@@ -1555,7 +1566,7 @@ func TestSelfDestruct(t *testing.T) {
 	contractCode = append(contractCode, acc2.Address().Bytes()...)
 	contractCode = append(contractCode, 0xff)
 	newAcc1.SetCode(contractCode)
-	state.UpdateAccount(newAcc1)
+	state.writeState.UpdateAccount(newAcc1)
 
 	// send call tx with no data, cause self-destruct
 	tx := payload.NewCallTxWithSequence(acc0PubKey, addressPtr(acc1), nil, sendingAmount, 1000, 0, acc0.Sequence()+1)
@@ -1598,28 +1609,29 @@ func signAndExecute(t *testing.T, shouldFail bool, exe BatchExecutor, chainID st
 	return env
 }
 
-func execTxWithStateAndBlockchain(state *State, tip *bcm.Tip, txEnv *txs.Envelope) error {
-	exe := newExecutor("execTxWithStateAndBlockchainCache", true, state, tip,
+func execTxWithStateAndBlockchain(state *State, blockchain *bcm.Blockchain, txEnv *txs.Envelope) error {
+	exe := newExecutor("execTxWithStateAndBlockchainCache", true, state, blockchain.Tip,
 		event.NewNoOpPublisher(), logger)
 	if err := exe.Execute(txEnv); err != nil {
 		return err
 	} else {
 		exe.Commit()
+		commitNewBlock(state, blockchain)
 		return nil
 	}
 }
 
 func execTxWithState(state *State, txEnv *txs.Envelope) error {
-	return execTxWithStateAndBlockchain(state, newBlockchain(testGenesisDoc).Tip, txEnv)
+	return execTxWithStateAndBlockchain(state, newBlockchain(testGenesisDoc), txEnv)
 }
 
 func commitNewBlock(state *State, blockchain *bcm.Blockchain) {
 	blockchain.CommitBlock(blockchain.LastBlockTime().Add(time.Second), sha3.Sha3(blockchain.LastBlockHash()),
-		state.Hash())
+		state.writeState.Hash())
 }
 
 func execTxWithStateNewBlock(state *State, blockchain *bcm.Blockchain, txEnv *txs.Envelope) error {
-	if err := execTxWithStateAndBlockchain(state, blockchain.Tip, txEnv); err != nil {
+	if err := execTxWithStateAndBlockchain(state, blockchain, txEnv); err != nil {
 		return err
 	}
 	commitNewBlock(state, blockchain)
@@ -1634,7 +1646,7 @@ func makeGenesisState(numAccounts int, randBalance bool, minBalance uint64, numV
 	if err != nil {
 		panic(fmt.Errorf("could not make genesis state: %v", err))
 	}
-	s0.Save()
+	s0.writeState.Save()
 	return s0, privAccounts
 }
 
@@ -1658,19 +1670,20 @@ var ExceptionTimeOut = errors.NewCodedError(errors.ErrorCodeGeneric, "timed out
 
 // run ExecTx and wait for the Call event on given addr
 // returns the msg data and an error/exception
-func execTxWaitAccountCall(t *testing.T, batchCommitter *executor, emitter event.Emitter, txEnv *txs.Envelope,
+func execTxWaitAccountCall(t *testing.T, exe *testExecutor, txEnv *txs.Envelope,
 	address crypto.Address) (*events.EventDataCall, error) {
 
 	ch := make(chan *events.EventDataCall)
 	ctx := context.Background()
 	const subscriber = "execTxWaitEvent"
-	events.SubscribeAccountCall(ctx, emitter, subscriber, address, txEnv.Tx.Hash(), -1, ch)
-	defer emitter.UnsubscribeAll(ctx, subscriber)
-	err := batchCommitter.Execute(txEnv)
+	events.SubscribeAccountCall(ctx, exe, subscriber, address, txEnv.Tx.Hash(), -1, ch)
+	defer exe.UnsubscribeAll(ctx, subscriber)
+	err := exe.Execute(txEnv)
 	if err != nil {
 		return nil, err
 	}
-	batchCommitter.Commit()
+	exe.Commit()
+	exe.blockchain.CommitBlock(time.Time{}, nil, nil)
 	ticker := time.NewTicker(5 * time.Second)
 
 	select {
@@ -1685,18 +1698,18 @@ func execTxWaitAccountCall(t *testing.T, batchCommitter *executor, emitter event
 }
 
 // give a contract perms for an snative, call it, it calls the snative, but shouldn't have permission
-func testSNativeCALLExpectFail(t *testing.T, batchCommitter *executor, emitter event.Emitter, doug acm.MutableAccount,
+func testSNativeCALLExpectFail(t *testing.T, exe *testExecutor, doug acm.MutableAccount,
 	snativeAddress crypto.Address, data []byte) {
-	testSNativeCALL(t, false, batchCommitter, emitter, doug, 0, snativeAddress, data, nil)
+	testSNativeCALL(t, false, exe, doug, 0, snativeAddress, data, nil)
 }
 
 // give a contract perms for an snative, call it, it calls the snative, ensure the check funciton (f) succeeds
-func testSNativeCALLExpectPass(t *testing.T, batchCommitter *executor, emitter event.Emitter, doug acm.MutableAccount, snativePerm ptypes.PermFlag,
+func testSNativeCALLExpectPass(t *testing.T, exe *testExecutor, doug acm.MutableAccount, snativePerm ptypes.PermFlag,
 	snativeAddress crypto.Address, data []byte, f func([]byte) error) {
-	testSNativeCALL(t, true, batchCommitter, emitter, doug, snativePerm, snativeAddress, data, f)
+	testSNativeCALL(t, true, exe, doug, snativePerm, snativeAddress, data, f)
 }
 
-func testSNativeCALL(t *testing.T, expectPass bool, batchCommitter *executor, emitter event.Emitter, doug acm.MutableAccount,
+func testSNativeCALL(t *testing.T, expectPass bool, exe *testExecutor, doug acm.MutableAccount,
 	snativePerm ptypes.PermFlag, snativeAddress crypto.Address, data []byte, f func([]byte) error) {
 	if expectPass {
 		doug.MutablePermissions().Base.Set(snativePerm, true)
@@ -1705,12 +1718,12 @@ func testSNativeCALL(t *testing.T, expectPass bool, batchCommitter *executor, em
 	doug.SetCode(callContractCode(snativeAddress))
 	dougAddress := doug.Address()
 
-	batchCommitter.stateCache.UpdateAccount(doug)
-	tx, _ := payload.NewCallTx(batchCommitter.stateCache, users[0].PublicKey(), &dougAddress, data, 100, 10000, 100)
+	exe.stateCache.UpdateAccount(doug)
+	tx, _ := payload.NewCallTx(exe.stateCache, users[0].PublicKey(), &dougAddress, data, 100, 10000, 100)
 	txEnv := txs.Enclose(testChainID, tx)
 	require.NoError(t, txEnv.Sign(users[0]))
 	t.Logf("subscribing to %v", events.EventStringAccountCall(snativeAddress))
-	ev, err := execTxWaitAccountCall(t, batchCommitter, emitter, txEnv, snativeAddress)
+	ev, err := execTxWaitAccountCall(t, exe, txEnv, snativeAddress)
 	if err == ExceptionTimeOut {
 		t.Fatal("Timed out waiting for event")
 	}
@@ -1725,16 +1738,16 @@ func testSNativeCALL(t *testing.T, expectPass bool, batchCommitter *executor, em
 	}
 }
 
-func testSNativeTxExpectFail(t *testing.T, batchCommitter *executor, snativeArgs snatives.PermArgs) {
+func testSNativeTxExpectFail(t *testing.T, batchCommitter *testExecutor, snativeArgs snatives.PermArgs) {
 	testSNativeTx(t, false, batchCommitter, 0, snativeArgs)
 }
 
-func testSNativeTxExpectPass(t *testing.T, batchCommitter *executor, perm ptypes.PermFlag,
+func testSNativeTxExpectPass(t *testing.T, batchCommitter *testExecutor, perm ptypes.PermFlag,
 	snativeArgs snatives.PermArgs) {
 	testSNativeTx(t, true, batchCommitter, perm, snativeArgs)
 }
 
-func testSNativeTx(t *testing.T, expectPass bool, batchCommitter *executor, perm ptypes.PermFlag,
+func testSNativeTx(t *testing.T, expectPass bool, batchCommitter *testExecutor, perm ptypes.PermFlag,
 	snativeArgs snatives.PermArgs) {
 	if expectPass {
 		acc := getAccount(batchCommitter.stateCache, users[0].Address())
diff --git a/execution/executors/call.go b/execution/executors/call.go
index f377e9147eb14d022400aa3380b26ced004bc292..06ba79865ae90bea801e19bb15ebe672ac167ef6 100644
--- a/execution/executors/call.go
+++ b/execution/executors/call.go
@@ -206,7 +206,7 @@ func (ctx *CallContext) Deliver(inAcc, outAcc acm.Account, value uint64) error {
 
 	txCache.UpdateAccount(caller)
 	txCache.UpdateAccount(callee)
-	vmach := evm.NewVM(params, caller.Address(), ctx.txEnv.Tx.Hash(), ctx.Logger, ctx.VMOptions...)
+	vmach := evm.NewVM(params, caller.Address(), ctx.txEnv.Tx, ctx.Logger, ctx.VMOptions...)
 	vmach.SetPublisher(ctx.EventPublisher)
 	// NOTE: Call() transfers the value from caller to callee iff call succeeds.
 	ret, exception := vmach.Call(txCache, caller, callee, code, ctx.tx.Data, value, &gas)
@@ -238,9 +238,11 @@ func (ctx *CallContext) FireCallEvents(ret []byte, err error) {
 	// Fire Events for sender and receiver
 	// a separate event will be fired from vm for each additional call
 	if ctx.EventPublisher != nil {
-		events.PublishAccountInput(ctx.EventPublisher, ctx.tx.Input.Address, ctx.txEnv.Tx, ret, errors.AsCodedError(err))
+		events.PublishAccountInput(ctx.EventPublisher, ctx.Tip.LastBlockHeight(), ctx.tx.Input.Address, ctx.txEnv.Tx,
+			ret, errors.AsCodedError(err))
 		if ctx.tx.Address != nil {
-			events.PublishAccountOutput(ctx.EventPublisher, *ctx.tx.Address, ctx.txEnv.Tx, ret, errors.AsCodedError(err))
+			events.PublishAccountOutput(ctx.EventPublisher, ctx.Tip.LastBlockHeight(), *ctx.tx.Address, ctx.txEnv.Tx,
+				ret, errors.AsCodedError(err))
 		}
 	}
 }
diff --git a/execution/executors/name.go b/execution/executors/name.go
index dbd2978a82395e5ca5a19adb6c951405f6c800d5..a94cd149a53ad96b81f5ac070e20bf80b599ed31 100644
--- a/execution/executors/name.go
+++ b/execution/executors/name.go
@@ -177,8 +177,8 @@ func (ctx *NameContext) Execute(txEnv *txs.Envelope) error {
 	// TODO: maybe we want to take funds on error and allow txs in that don't do anythingi?
 
 	if ctx.EventPublisher != nil {
-		events.PublishAccountInput(ctx.EventPublisher, ctx.tx.Input.Address, txEnv.Tx, nil, nil)
-		events.PublishNameReg(ctx.EventPublisher, txEnv.Tx)
+		events.PublishAccountInput(ctx.EventPublisher, ctx.Tip.LastBlockHeight(), ctx.tx.Input.Address, txEnv.Tx, nil, nil)
+		events.PublishNameReg(ctx.EventPublisher, ctx.Tip.LastBlockHeight(), txEnv.Tx)
 	}
 
 	return nil
diff --git a/execution/executors/permissions.go b/execution/executors/permissions.go
index 06dbd8c0acb3ddc1d96ead562557b7cb58dfb7d0..9b4f705ebd8622e853e9c2c522e411ac8ca3c2f9 100644
--- a/execution/executors/permissions.go
+++ b/execution/executors/permissions.go
@@ -5,6 +5,7 @@ import (
 
 	acm "github.com/hyperledger/burrow/account"
 	"github.com/hyperledger/burrow/account/state"
+	"github.com/hyperledger/burrow/blockchain"
 	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/event"
 	"github.com/hyperledger/burrow/execution/events"
@@ -16,6 +17,7 @@ import (
 )
 
 type PermissionsContext struct {
+	Tip            blockchain.TipInfo
 	StateWriter    state.Writer
 	EventPublisher event.Publisher
 	Logger         *logging.Logger
@@ -130,8 +132,8 @@ func (ctx *PermissionsContext) Execute(txEnv *txs.Envelope) error {
 	}
 
 	if ctx.EventPublisher != nil {
-		events.PublishAccountInput(ctx.EventPublisher, ctx.tx.Input.Address, txEnv.Tx, nil, nil)
-		events.PublishPermissions(ctx.EventPublisher, permFlag, txEnv.Tx)
+		events.PublishAccountInput(ctx.EventPublisher, ctx.Tip.LastBlockHeight(), ctx.tx.Input.Address, txEnv.Tx, nil, nil)
+		events.PublishPermissions(ctx.EventPublisher, ctx.Tip.LastBlockHeight(), txEnv.Tx)
 	}
 
 	return nil
diff --git a/execution/executors/send.go b/execution/executors/send.go
index 6c79eba84f00fd214cc45e92d405c60e29ecbbc8..8751497a728a8e4763f58e12a77ea64c8b588368 100644
--- a/execution/executors/send.go
+++ b/execution/executors/send.go
@@ -4,6 +4,7 @@ import (
 	"fmt"
 
 	"github.com/hyperledger/burrow/account/state"
+	"github.com/hyperledger/burrow/blockchain"
 	"github.com/hyperledger/burrow/event"
 	"github.com/hyperledger/burrow/execution/events"
 	"github.com/hyperledger/burrow/logging"
@@ -12,6 +13,7 @@ import (
 )
 
 type SendContext struct {
+	Tip            blockchain.TipInfo
 	StateWriter    state.Writer
 	EventPublisher event.Publisher
 	Logger         *logging.Logger
@@ -70,11 +72,11 @@ func (ctx *SendContext) Execute(txEnv *txs.Envelope) error {
 
 	if ctx.EventPublisher != nil {
 		for _, i := range ctx.tx.Inputs {
-			events.PublishAccountInput(ctx.EventPublisher, i.Address, txEnv.Tx, nil, nil)
+			events.PublishAccountInput(ctx.EventPublisher, ctx.Tip.LastBlockHeight(), i.Address, txEnv.Tx, nil, nil)
 		}
 
 		for _, o := range ctx.tx.Outputs {
-			events.PublishAccountOutput(ctx.EventPublisher, o.Address, txEnv.Tx, nil, nil)
+			events.PublishAccountOutput(ctx.EventPublisher, ctx.Tip.LastBlockHeight(), o.Address, txEnv.Tx, nil, nil)
 		}
 	}
 	return nil
diff --git a/execution/names/names.go b/execution/names/names.go
index 96cd2f1dae4cdd85e07d4ccedcf36495901d0c7c..1b088a7108cc5ff370f9365ebafb4c3f32c5ab71 100644
--- a/execution/names/names.go
+++ b/execution/names/names.go
@@ -83,6 +83,11 @@ type Iterable interface {
 	IterateNameEntries(consumer func(*Entry) (stop bool)) (stopped bool, err error)
 }
 
+type IterableWriter interface {
+	Iterable
+	Updater
+}
+
 // base cost is "effective" number of bytes
 func NameBaseCost(name, data string) uint64 {
 	return uint64(len(data) + 32)
diff --git a/execution/state.go b/execution/state.go
index 4d066dfb75366c5518c32f6f7be65fd9ad0bc012..fda93bc8520bf59a96efdecb4529dcded422e7e8 100644
--- a/execution/state.go
+++ b/execution/state.go
@@ -24,12 +24,17 @@ import (
 	"github.com/hyperledger/burrow/account/state"
 	"github.com/hyperledger/burrow/binary"
 	"github.com/hyperledger/burrow/crypto"
+	"github.com/hyperledger/burrow/event"
+	"github.com/hyperledger/burrow/event/query"
+	"github.com/hyperledger/burrow/execution/events"
 	"github.com/hyperledger/burrow/execution/names"
 	"github.com/hyperledger/burrow/genesis"
 	"github.com/hyperledger/burrow/logging"
+	"github.com/hyperledger/burrow/logging/structure"
 	"github.com/hyperledger/burrow/permission"
 	ptypes "github.com/hyperledger/burrow/permission/types"
 	"github.com/tendermint/iavl"
+	"github.com/tendermint/tendermint/libs/pubsub"
 	dbm "github.com/tendermint/tmlibs/db"
 )
 
@@ -43,6 +48,7 @@ const (
 	accountsPrefix = "a/"
 	storagePrefix  = "s/"
 	nameRegPrefix  = "n/"
+	eventPrefix    = "e/"
 )
 
 var (
@@ -52,22 +58,42 @@ var (
 )
 
 // Implements account and blockchain state
-var _ state.AccountUpdater = &State{}
 var _ state.Iterable = &State{}
-var _ state.Writer = &State{}
+var _ names.Iterable = &State{}
+var _ Updatable = &writeState{}
+
+type Updatable interface {
+	state.IterableWriter
+	names.IterableWriter
+	event.Publisher
+	Hash() []byte
+	Save() error
+}
+
+// Wraps state to give access to writer methods
+type writeState struct {
+	state *State
+}
 
+// Writers to state are responsible for calling State.Lock() before calling
 type State struct {
 	sync.RWMutex
-	db     dbm.DB
-	tree   *iavl.VersionedTree
-	logger *logging.Logger
+	writeState *writeState
+	// High water mark for height/index - make sure we do not overwrite events - can only increase
+	eventKeyHighWatermark events.Key
+	db                    dbm.DB
+	tree                  *iavl.VersionedTree
+	logger                *logging.Logger
 }
 
+// Create a new State object
 func NewState(db dbm.DB) *State {
-	return &State{
+	s := &State{
 		db:   db,
 		tree: iavl.NewVersionedTree(db, defaultCacheCapacity),
 	}
+	s.writeState = &writeState{state: s}
+	return s
 }
 
 // Make genesis state from GenesisDoc and save to DB
@@ -76,7 +102,7 @@ func MakeGenesisState(db dbm.DB, genesisDoc *genesis.GenesisDoc) (*State, error)
 		return nil, fmt.Errorf("the genesis file has no validators")
 	}
 
-	state := NewState(db)
+	s := NewState(db)
 
 	if genesisDoc.GenesisTime.IsZero() {
 		// NOTE: [ben] change GenesisTime to requirement on v0.17
@@ -95,7 +121,7 @@ func MakeGenesisState(db dbm.DB, genesisDoc *genesis.GenesisDoc) (*State, error)
 			Balance:     genAcc.Amount,
 			Permissions: perm,
 		}
-		err := state.UpdateAccount(acc.Account())
+		err := s.writeState.UpdateAccount(acc.Account())
 		if err != nil {
 			return nil, err
 		}
@@ -114,17 +140,17 @@ func MakeGenesisState(db dbm.DB, genesisDoc *genesis.GenesisDoc) (*State, error)
 		Balance:     1337,
 		Permissions: globalPerms,
 	}
-	err := state.UpdateAccount(permsAcc.Account())
+	err := s.writeState.UpdateAccount(permsAcc.Account())
 	if err != nil {
 		return nil, err
 	}
 
 	// IAVLTrees must be persisted before copy operations.
-	err = state.Save()
+	err = s.writeState.Save()
 	if err != nil {
 		return nil, err
 	}
-	return state, nil
+	return s, nil
 
 }
 
@@ -132,7 +158,7 @@ func MakeGenesisState(db dbm.DB, genesisDoc *genesis.GenesisDoc) (*State, error)
 func LoadState(db dbm.DB, hash []byte) (*State, error) {
 	s := NewState(db)
 	// Get the version associated with this state hash
-	version, err := s.GetVersion(hash)
+	version, err := s.writeState.GetVersion(hash)
 	if err != nil {
 		return nil, err
 	}
@@ -147,11 +173,17 @@ func LoadState(db dbm.DB, hash []byte) (*State, error) {
 	return s, nil
 }
 
-func (s *State) Save() error {
+// Perform updates to state whilst holding the write lock, allows a commit to hold the write lock across multiple
+// operations while preventing interlaced reads and writes
+func (s *State) Update(updater func(up Updatable)) {
 	s.Lock()
 	defer s.Unlock()
+	updater(s.writeState)
+}
+
+func (s *writeState) Save() error {
 	// Save state at a new version may still be orphaned before we save the version against the hash
-	hash, treeVersion, err := s.tree.SaveVersion()
+	hash, treeVersion, err := s.state.tree.SaveVersion()
 	if err != nil {
 		return err
 	}
@@ -161,8 +193,8 @@ func (s *State) Save() error {
 }
 
 // Get a previously saved tree version stored by state hash
-func (s *State) GetVersion(hash []byte) (int64, error) {
-	versionBytes := s.db.Get(prefixedKey(versionPrefix, hash))
+func (s *writeState) GetVersion(hash []byte) (int64, error) {
+	versionBytes := s.state.db.Get(prefixedKey(versionPrefix, hash))
 	if versionBytes == nil {
 		return -1, fmt.Errorf("could not retrieve version corresponding to state hash '%X' in database", hash)
 	}
@@ -170,33 +202,33 @@ func (s *State) GetVersion(hash []byte) (int64, error) {
 }
 
 // Set the tree version associated with a particular hash
-func (s *State) SetVersion(hash []byte, version int64) {
+func (s *writeState) SetVersion(hash []byte, version int64) {
 	versionBytes := make([]byte, 8)
 	binary.PutInt64BE(versionBytes, version)
-	s.db.SetSync(prefixedKey(versionPrefix, hash), versionBytes)
+	s.state.db.SetSync(prefixedKey(versionPrefix, hash), versionBytes)
 }
 
 // Computes the state hash, also computed on save where it is returned
-func (s *State) Hash() []byte {
-	s.RLock()
-	defer s.RUnlock()
-	return s.tree.Hash()
+func (s *writeState) Hash() []byte {
+	return s.state.tree.Hash()
 }
 
 // Returns nil if account does not exist with given address.
 func (s *State) GetAccount(address crypto.Address) (acm.Account, error) {
 	s.RLock()
 	defer s.RUnlock()
-	_, accBytes := s.tree.Get(prefixedKey(accountsPrefix, address.Bytes()))
+	return s.writeState.GetAccount(address)
+}
+
+func (s *writeState) GetAccount(address crypto.Address) (acm.Account, error) {
+	_, accBytes := s.state.tree.Get(prefixedKey(accountsPrefix, address.Bytes()))
 	if accBytes == nil {
 		return nil, nil
 	}
 	return acm.Decode(accBytes)
 }
 
-func (s *State) UpdateAccount(account acm.Account) error {
-	s.Lock()
-	defer s.Unlock()
+func (s *writeState) UpdateAccount(account acm.Account) error {
 	if account == nil {
 		return fmt.Errorf("UpdateAccount passed nil account in execution.State")
 	}
@@ -208,21 +240,23 @@ func (s *State) UpdateAccount(account acm.Account) error {
 	if err != nil {
 		return err
 	}
-	s.tree.Set(prefixedKey(accountsPrefix, account.Address().Bytes()), encodedAccount)
+	s.state.tree.Set(prefixedKey(accountsPrefix, account.Address().Bytes()), encodedAccount)
 	return nil
 }
 
-func (s *State) RemoveAccount(address crypto.Address) error {
-	s.Lock()
-	defer s.Unlock()
-	s.tree.Remove(prefixedKey(accountsPrefix, address.Bytes()))
+func (s *writeState) RemoveAccount(address crypto.Address) error {
+	s.state.tree.Remove(prefixedKey(accountsPrefix, address.Bytes()))
 	return nil
 }
 
 func (s *State) IterateAccounts(consumer func(acm.Account) (stop bool)) (stopped bool, err error) {
 	s.RLock()
 	defer s.RUnlock()
-	stopped = s.tree.IterateRange(accountsStart, accountsEnd, true, func(key, value []byte) bool {
+	return s.writeState.IterateAccounts(consumer)
+}
+
+func (s *writeState) IterateAccounts(consumer func(acm.Account) (stop bool)) (stopped bool, err error) {
+	stopped = s.state.tree.IterateRange(accountsStart, accountsEnd, true, func(key, value []byte) bool {
 		var account acm.Account
 		account, err = acm.Decode(value)
 		if err != nil {
@@ -236,17 +270,19 @@ func (s *State) IterateAccounts(consumer func(acm.Account) (stop bool)) (stopped
 func (s *State) GetStorage(address crypto.Address, key binary.Word256) (binary.Word256, error) {
 	s.RLock()
 	defer s.RUnlock()
-	_, value := s.tree.Get(prefixedKey(storagePrefix, address.Bytes(), key.Bytes()))
+	return s.writeState.GetStorage(address, key)
+}
+
+func (s *writeState) GetStorage(address crypto.Address, key binary.Word256) (binary.Word256, error) {
+	_, value := s.state.tree.Get(prefixedKey(storagePrefix, address.Bytes(), key.Bytes()))
 	return binary.LeftPadWord256(value), nil
 }
 
-func (s *State) SetStorage(address crypto.Address, key, value binary.Word256) error {
-	s.Lock()
-	defer s.Unlock()
+func (s *writeState) SetStorage(address crypto.Address, key, value binary.Word256) error {
 	if value == binary.Zero256 {
-		s.tree.Remove(key.Bytes())
+		s.state.tree.Remove(key.Bytes())
 	} else {
-		s.tree.Set(prefixedKey(storagePrefix, address.Bytes(), key.Bytes()), value.Bytes())
+		s.state.tree.Set(prefixedKey(storagePrefix, address.Bytes(), key.Bytes()), value.Bytes())
 	}
 	return nil
 }
@@ -255,8 +291,13 @@ func (s *State) IterateStorage(address crypto.Address,
 	consumer func(key, value binary.Word256) (stop bool)) (stopped bool, err error) {
 	s.RLock()
 	defer s.RUnlock()
+	return s.writeState.IterateStorage(address, consumer)
+
+}
 
-	stopped = s.tree.IterateRange(storageStart, storageEnd, true, func(key []byte, value []byte) (stop bool) {
+func (s *writeState) IterateStorage(address crypto.Address,
+	consumer func(key, value binary.Word256) (stop bool)) (stopped bool, err error) {
+	stopped = s.state.tree.IterateRange(storageStart, storageEnd, true, func(key []byte, value []byte) (stop bool) {
 		// Note: no left padding should occur unless there is a bug and non-words have been writte to this storage tree
 		if len(key) != binary.Word256Length {
 			err = fmt.Errorf("key '%X' stored for account %s is not a %v-byte word",
@@ -277,9 +318,55 @@ func (s *State) IterateStorage(address crypto.Address,
 //-------------------------------------
 // Events
 
-// Sevents
-func (s *State) Publish(ctx context.Context, message interface{}, tags map[string]interface{}) error {
-	panic("implement me")
+// Execution events
+func (s *writeState) Publish(ctx context.Context, msg interface{}, tags event.Tags) error {
+	if exeEvent, ok := msg.(*events.Event); ok {
+		key := exeEvent.Header.Key()
+		if !key.IsSuccessorOf(s.state.eventKeyHighWatermark) {
+			return fmt.Errorf("received event with non-increasing key compared with current high watermark %v: %v",
+				s.state.eventKeyHighWatermark, exeEvent)
+		}
+		s.state.eventKeyHighWatermark = key
+		bs, err := exeEvent.Encode()
+		if err != nil {
+			return err
+		}
+		s.state.tree.Set(prefixedKey(eventPrefix, key), bs)
+	}
+	return nil
+}
+
+func (s *State) GetEvents(startBlock, endBlock uint64, queryable query.Queryable) (<-chan *events.Event, error) {
+	var query pubsub.Query
+	var err error
+	query, err = queryable.Query()
+	if err != nil {
+		return nil, err
+	}
+	ch := make(chan *events.Event)
+	go func() {
+		s.RLock()
+		defer s.RUnlock()
+		// Close channel to signal end of iteration
+		defer close(ch)
+		//if endBlock == 0 {
+		//endBlock = s.eventKeyHighWatermark.Height()
+		//}
+		s.tree.IterateRange(eventKey(startBlock, 0), eventKey(endBlock+1, 0), true,
+			func(_, value []byte) bool {
+				exeEvent, err := events.DecodeEvent(value)
+				if err != nil {
+					s.logger.InfoMsg("error unmarshalling ExecutionEvent in GetEvents", structure.ErrorKey, err)
+					// stop iteration on error
+					return true
+				}
+				if query.Matches(exeEvent) {
+					ch <- exeEvent
+				}
+				return false
+			})
+	}()
+	return ch, nil
 }
 
 // Events
@@ -289,7 +376,13 @@ func (s *State) Publish(ctx context.Context, message interface{}, tags map[strin
 var _ names.Iterable = &State{}
 
 func (s *State) GetNameEntry(name string) (*names.Entry, error) {
-	_, entryBytes := s.tree.Get(prefixedKey(nameRegPrefix, []byte(name)))
+	s.RLock()
+	defer s.RUnlock()
+	return s.writeState.GetNameEntry(name)
+}
+
+func (s *writeState) GetNameEntry(name string) (*names.Entry, error) {
+	_, entryBytes := s.state.tree.Get(prefixedKey(nameRegPrefix, []byte(name)))
 	if entryBytes == nil {
 		return nil, nil
 	}
@@ -298,7 +391,13 @@ func (s *State) GetNameEntry(name string) (*names.Entry, error) {
 }
 
 func (s *State) IterateNameEntries(consumer func(*names.Entry) (stop bool)) (stopped bool, err error) {
-	return s.tree.IterateRange(nameRegStart, nameRegEnd, true, func(key []byte, value []byte) (stop bool) {
+	s.RLock()
+	defer s.RUnlock()
+	return s.writeState.IterateNameEntries(consumer)
+}
+
+func (s *writeState) IterateNameEntries(consumer func(*names.Entry) (stop bool)) (stopped bool, err error) {
+	return s.state.tree.IterateRange(nameRegStart, nameRegEnd, true, func(key []byte, value []byte) (stop bool) {
 		var entry *names.Entry
 		entry, err = names.DecodeEntry(value)
 		if err != nil {
@@ -308,28 +407,34 @@ func (s *State) IterateNameEntries(consumer func(*names.Entry) (stop bool)) (sto
 	}), err
 }
 
-func (s *State) UpdateNameEntry(entry *names.Entry) error {
+func (s *writeState) UpdateNameEntry(entry *names.Entry) error {
 	bs, err := entry.Encode()
 	if err != nil {
 		return err
 	}
-	s.tree.Set(prefixedKey(nameRegPrefix, []byte(entry.Name)), bs)
+	s.state.tree.Set(prefixedKey(nameRegPrefix, []byte(entry.Name)), bs)
 	return nil
 }
 
-func (s *State) RemoveNameEntry(name string) error {
-	s.tree.Remove(prefixedKey(nameRegPrefix, []byte(name)))
+func (s *writeState) RemoveNameEntry(name string) error {
+	s.state.tree.Remove(prefixedKey(nameRegPrefix, []byte(name)))
 	return nil
 }
 
 // Creates a copy of the database to the supplied db
 func (s *State) Copy(db dbm.DB) *State {
-	state := NewState(db)
+	s.RLock()
+	defer s.RUnlock()
+	stateCopy := NewState(db)
 	s.tree.Iterate(func(key []byte, value []byte) bool {
-		state.tree.Set(key, value)
+		stateCopy.tree.Set(key, value)
 		return false
 	})
-	return state
+	return stateCopy
+}
+
+func eventKey(height, index uint64) events.Key {
+	return prefixedKey(eventPrefix, events.NewKey(height, index))
 }
 
 func prefixedKey(prefix string, suffices ...[]byte) []byte {
diff --git a/execution/state_test.go b/execution/state_test.go
index e72076b1359f6d07294c123a2a36b6637fd32278..0cd3663cf5fcee6db4b343b95c8cc0c7cc87ea07 100644
--- a/execution/state_test.go
+++ b/execution/state_test.go
@@ -15,24 +15,103 @@
 package execution
 
 import (
+	"context"
+	"encoding/json"
+	"fmt"
 	"testing"
 
+	"github.com/golang/protobuf/proto"
 	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/binary"
+	"github.com/hyperledger/burrow/crypto"
+	"github.com/hyperledger/burrow/event/query"
+	"github.com/hyperledger/burrow/execution/events"
+	"github.com/hyperledger/burrow/execution/events/pbevents"
+	"github.com/hyperledger/burrow/execution/evm/sha3"
 	permission "github.com/hyperledger/burrow/permission/types"
+	"github.com/hyperledger/burrow/txs"
+	"github.com/hyperledger/burrow/txs/payload"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 	"github.com/tendermint/tmlibs/db"
 )
 
 func TestState_UpdateAccount(t *testing.T) {
-	state := NewState(db.NewMemDB())
+	s := NewState(db.NewMemDB())
 	account := acm.NewConcreteAccountFromSecret("Foo").MutableAccount()
 	account.MutablePermissions().Base.Perms = permission.SetGlobal | permission.HasRole
-	err := state.UpdateAccount(account)
-	err = state.Save()
+	var err error
+	s.Update(func(ws Updatable) {
+		err = ws.UpdateAccount(account)
+		err = ws.Save()
+	})
 
 	require.NoError(t, err)
-	accountOut, err := state.GetAccount(account.Address())
+	accountOut, err := s.GetAccount(account.Address())
 	require.NoError(t, err)
 	assert.Equal(t, account, accountOut)
 }
+
+func TestState_Publish(t *testing.T) {
+	s := NewState(db.NewMemDB())
+	ctx := context.Background()
+	evs := []*events.Event{
+		mkEvent(100, 0),
+		mkEvent(100, 1),
+	}
+	s.Update(func(ws Updatable) {
+		for _, ev := range evs {
+			require.NoError(t, ws.Publish(ctx, ev, nil))
+		}
+	})
+	i := 0
+	ch, err := s.GetEvents(100, 100, query.Empty{})
+	require.NoError(t, err)
+	for ev := range ch {
+		assert.Equal(t, evs[i], ev)
+		i++
+	}
+	// non-increasing events
+	s.Update(func(ws Updatable) {
+		require.Error(t, ws.Publish(ctx, mkEvent(100, 0), nil))
+		require.Error(t, ws.Publish(ctx, mkEvent(100, 1), nil))
+		require.Error(t, ws.Publish(ctx, mkEvent(99, 1324234), nil))
+		require.NoError(t, ws.Publish(ctx, mkEvent(100, 2), nil))
+		require.NoError(t, ws.Publish(ctx, mkEvent(101, 0), nil))
+	})
+}
+
+func TestProtobufEventSerialisation(t *testing.T) {
+	ev := mkEvent(112, 23)
+	pbEvent := pbevents.GetEvent(ev)
+	bs, err := proto.Marshal(pbEvent)
+	require.NoError(t, err)
+	pbEventOut := new(pbevents.ExecutionEvent)
+	require.NoError(t, proto.Unmarshal(bs, pbEventOut))
+	fmt.Println(pbEventOut)
+	assert.Equal(t, asJSON(t, pbEvent), asJSON(t, pbEventOut))
+}
+
+func mkEvent(height, index uint64) *events.Event {
+	return &events.Event{
+		Header: &events.Header{
+			Height:  height,
+			Index:   index,
+			TxHash:  sha3.Sha3([]byte(fmt.Sprintf("txhash%v%v", height, index))),
+			EventID: fmt.Sprintf("eventID: %v%v", height, index),
+		},
+		Tx: &events.EventDataTx{
+			Tx: txs.Enclose("foo", &payload.CallTx{}).Tx,
+		},
+		Log: &events.EventDataLog{
+			Address: crypto.Address{byte(height), byte(index)},
+			Topics:  []binary.Word256{{1, 2, 3}},
+		},
+	}
+}
+
+func asJSON(t *testing.T, v interface{}) string {
+	bs, err := json.Marshal(v)
+	require.NoError(t, err)
+	return string(bs)
+}
diff --git a/logging/metadata.go b/logging/metadata.go
deleted file mode 100644
index 485c8f2be568d20c70c0d9041c44d035401d4ce2..0000000000000000000000000000000000000000
--- a/logging/metadata.go
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package logging
-
-import (
-	kitlog "github.com/go-kit/kit/log"
-	"github.com/go-stack/stack"
-	"github.com/hyperledger/burrow/logging/structure"
-)
-
-const (
-	// To get the Caller information correct on the log, we need to count the
-	// number of calls from a log call in the code to the time it hits a kitlog
-	// context: [log call site (5), Info/Trace (4), MultipleChannelLogger.Log (3),
-	// kitlog.Context.Log (2), kitlog.bindValues (1) (binding occurs),
-	// kitlog.Caller (0), stack.caller]
-	infoTraceLoggerCallDepth = 5
-)
-
-func WithMetadata(logger *Logger) *Logger {
-	return logger.With(structure.TimeKey, kitlog.DefaultTimestampUTC,
-		structure.TraceKey, TraceValuer(),
-		structure.CallerKey, kitlog.Caller(infoTraceLoggerCallDepth))
-}
-
-func TraceValuer() kitlog.Valuer {
-	return func() interface{} { return stack.Trace() }
-}
diff --git a/rpc/burrow.proto.stashed b/rpc/burrow.proto.stashed
new file mode 100644
index 0000000000000000000000000000000000000000..4fe98c95f5edae68f590c3ba45b7e8b66542eebc
--- /dev/null
+++ b/rpc/burrow.proto.stashed
@@ -0,0 +1,501 @@
+// Keeping this for source material to fold into burrow over time
+// Original Author: Tyler Jackson
+
+syntax = "proto3";
+
+
+// #BEGIN(common)
+// Common Messages
+message Empty {
+
+}
+
+message InputAccount {
+	bytes privateKey = 1;
+	bytes address = 2;
+}
+
+message FilterData {
+	string field = 1;
+	string op = 2;
+	string value = 3;
+}
+
+message FilterListParam {
+	repeated FilterData filters = 1;
+}
+
+// This is here because it is required by both transactions and namereg
+// This situation can be remedied multiple ways 
+message TxReceipt {
+	bytes TxHash          = 1;
+	bool  CreatesContract = 2;
+	bytes ContractAddress = 3;
+}
+
+// This is here because it is used in both the Account Service (GenPrivAccount)
+// And in the transaction service (SignTx)
+message PrivateAccount {
+	bytes PrivateKey = 1;
+}
+
+// This is hear because it is used by both the Events service (Poll) and the
+// Transaction service (TransactAndHold)
+message EventDataCall {
+	CallData CallData = 1;
+	bytes Origin      = 2;
+	bytes TxHash      = 3;
+	int64 StackDepth  = 4;
+	bytes Return      = 5;     
+	string Exception  = 6;
+}
+
+message CallData {
+	bytes Caller = 1;
+	bytes Callee = 2;
+	bytes Data   = 3;
+	uint64 Value = 4;
+	uint64 Gas   = 5;
+}
+
+
+
+// #BEGIN(account)
+// Account Service definition
+service Accounts {
+	rpc GenPrivAccount(Empty) returns (PrivateAccount);
+	rpc GenPrivAccountFromKey(PrivateKeyParam) returns (PrivateAccount);
+	rpc GetAccount(AddressParam) returns (Account);
+	rpc GetAccounts(FilterListParam) returns (AccountList);
+	rpc GetValidators(Empty) returns (ValidatorList);
+	rpc GetStorage(AddressParam) returns (StorageDump);
+	rpc GetStorageAt(StorageAtParam) returns (StorageItem);
+}
+
+// Params
+message AddressParam {
+	bytes address = 1;
+}
+
+message PrivateKeyParam {
+	bytes privateKey = 1;
+}
+
+message StorageAtParam {
+	bytes address = 1;
+	bytes key = 2;
+}
+
+// Results
+
+message BasePermissions {
+	uint64 Perms = 1;
+	uint64 SetBit = 2;
+}
+
+message AccountPermissions {
+	BasePermissions Base  = 1;
+	repeated string Roles = 2;
+}
+
+message Account {
+	bytes Address 	= 1;
+	bytes PublicKey = 2;
+	uint64 Sequence = 3;
+	uint64 Balance 	= 4;
+	bytes Code 		= 5;
+	bytes StorageRoot = 6;
+	AccountPermissions Permissions = 7;
+}
+
+message AccountList {
+	uint64 BlockHeight = 1;
+	repeated Account Accounts = 2;
+}
+
+message Validator {
+	bytes   Address   = 1;
+	bytes   PublicKey = 2;
+	uint64  Power     = 3;
+}
+
+message ValidatorList {
+	uint64 BlockHeight  = 1;
+	repeated Validator BondedValidators = 2;
+	repeated Validator UnbondingValidators = 3;
+}
+
+message StorageItem {
+	bytes Key = 1;
+	bytes Value = 2;
+}
+
+message StorageDump {
+	bytes StorageRoot = 1;
+	repeated StorageItem StorageItems = 2;
+}
+
+
+//-----------------------------------------------
+
+
+// #BEGIN(blockchain)
+// Blockchain Service Definition
+service Blockchain {
+	rpc GetBlock(HeightParam) returns (Block);
+	rpc GetBlocks(BlocksParam) returns (BlockList);
+	rpc GetBlockchainInfo(Empty) returns (Status);
+	rpc GetChainId(Empty) returns (ChainId);
+	rpc GetGenesis(Empty) returns (GenesisDoc);            			// NI - go
+	rpc GetLatestBlock(Empty) returns (Block);
+	rpc GetUnconfirmedTxs(Empty) returns (UnconfirmedTxList);
+
+	rpc GetConsensusState(Empty) returns (ConsensusState); // WE NEED TO DISCUSS THIS ONE
+}
+
+// Params
+message HeightParam {
+	uint64 height = 1;
+}
+
+message BlocksParam {
+	uint64 minHeight = 1;
+	uint64 maxHeight = 2;
+}
+
+// Results
+message Header {
+	string ChainID       = 1;
+	int64 Height         = 2;
+	int64 Time           = 3;
+	int64 NumTxs         = 4;
+	bytes LastBlockID    = 5;
+	bytes LastCommitHash = 6;
+	bytes DataHash       = 7;
+	bytes ValidatorsHash = 8;
+	bytes AppHash        = 9;
+}
+
+
+message Data {
+	repeated bytes Txs = 1;
+	bytes hash = 2;
+}
+
+message Block {
+	bytes   BlockID    = 1;
+	Header  Header     = 2;
+	Data    Data       = 3;
+}
+
+message BlockMeta {
+	bytes   BlockID = 1;
+	Header  Header  = 2;
+}
+
+message BlockList {
+	uint64 LastHeight = 1;
+	repeated BlockMeta BlockMetas = 2;
+}
+
+message ChainId {
+	string ChainName  = 1;
+	string ChainId    = 2;
+	bytes GenesisHash = 3;
+}
+
+
+message GenesisDoc {
+	message GenesisAccount {
+		bytes Address   = 1;
+		bytes PublicKey = 2;
+		uint64 Amount   = 3;
+		string Name     = 4;
+		AccountPermissions Permissions = 5;
+	}
+
+	message GenesisValidator {
+		bytes Address   = 1;
+		bytes PublicKey = 2;
+		uint64 Amount   = 3;
+		string Name     = 4;
+		repeated bytes UnbondTo = 5;
+	}
+	uint64 GenesisTime       = 1;
+	string ChainName         = 2;
+	bytes Salt               = 3;
+	uint64 GlobalPermissions = 4;
+	repeated GenesisAccount   Accounts   = 5;
+	repeated GenesisValidator Validators = 6;
+}
+
+message UnconfirmedTxList {
+	uint64 NumTxs = 1;
+	repeated bytes Txs = 2;
+}
+
+message Status {
+	NodeInfo NodeInfo 		   = 1;
+	bytes 	 GenesisHash	   = 2;
+	bytes 	 PublicKey         = 3;
+	bytes 	 LatestBlockHash   = 4;
+	uint64 	 LatestBlockHeight = 5;
+	int64 	 LatestBlockTime   = 6;
+	string 	 NodeVersion 	   = 7;
+}
+
+
+// These are used for get consensus state. There is a lot of information that could be included
+// We should decided what the minimum we want inccluded is.
+message RoundState {
+	int64 Height       = 1;
+	int64 Round        = 2;
+	int64 Step         = 3;
+	uint64 StartTime   = 4;
+	uint64 CommitTime  = 5;
+/*	Validators         *types.ValidatorSet `json:"validators"`
+	Proposal           *types.Proposal     `json:"proposal"`
+	ProposalBlock      *types.Block        `json:"proposal_block"`
+	ProposalBlockParts *types.PartSet      `json:"proposal_block_parts"`
+	LockedRound        int                 `json:"locked_round"`
+	LockedBlock        *types.Block        `json:"locked_block"`
+	LockedBlockParts   *types.PartSet      `json:"locked_block_parts"`
+	ValidRound         int                 `json:"valid_round"`       // Last known round with POL for non-nil valid block.
+	ValidBlock         *types.Block        `json:"valid_block"`       // Last known block of POL mentioned above.
+	ValidBlockParts    *types.PartSet      `json:"valid_block_parts"` // Last known block parts of POL metnioned above.
+	Votes              *HeightVoteSet      `json:"votes"`
+	CommitRound        int                 `json:"commit_round"` //
+	LastCommit         *types.VoteSet      `json:"last_commit"`  // Last precommits at Height-1
+	LastValidators     *types.ValidatorSet `json:"last_validators"`*/
+}
+
+message PeerRoundState {
+	int64 Height             = 1;
+	int64 Round              = 2;
+	int64 Step               = 3;
+	uint64 StartTime         = 4;
+	bool Proposal            = 5;
+/*
+	ProposalBlockPartsHeader types.PartSetHeader `json:"proposal_block_parts_header"` //
+	ProposalBlockParts       *cmn.BitArray       `json:"proposal_block_parts"`        //
+	ProposalPOLRound         int                 `json:"proposal_pol_round"`          // Proposal's POL round. -1 if none.
+	ProposalPOL              *cmn.BitArray       `json:"proposal_pol"`                // nil until ProposalPOLMessage received.
+	Prevotes                 *cmn.BitArray       `json:"prevotes"`                    // All votes peer has for this round
+	Precommits               *cmn.BitArray       `json:"precommits"`                  // All precommits peer has for this round
+	LastCommitRound          int                 `json:"last_commit_round"`           // Round of commit for last height. -1 if none.
+	LastCommit               *cmn.BitArray       `json:"last_commit"`                 // All commit precommits of commit for last height.
+	CatchupCommitRound       int                 `json:"catchup_commit_round"`        // Round that we have commit for. Not necessarily unique. -1 if none.
+	CatchupCommit            *cmn.BitArray       `json:"catchup_commit"`              // All commit precommits peer has for this height & CatchupCommitRound
+*/
+}
+
+message ConsensusState {
+	RoundState RoundState   = 1;
+	repeated PeerRoundState PeerRoundStates = 2;
+}
+
+//--------------------------------------------------
+
+
+// #BEGIN(event)
+// Event Service Definition
+service Events {
+	rpc EventPoll(SubIdParam) returns (PollResponse);
+	rpc EventSubscribe(EventIdParam) returns (SubIdParam);
+	rpc EventUnsubscribe(SubIdParam) returns (EventUnSub);
+}
+
+// Params
+message EventIdParam {
+	string eventId = 1;
+}
+
+message SubIdParam {
+	string subId = 1;
+}
+
+// Results
+message EventUnSub {
+	bool result = 1;
+}
+
+message EventDataLog {
+	bytes  Address = 1;
+	bytes  Data    = 2;    
+	uint64 Height  = 3;
+	repeated string Topics  = 4;
+}
+
+message EventDataTx {
+	bytes Tx         = 1;
+	bytes Return     = 2;
+	string Exception = 3;
+}
+
+message Event {
+	string Event 				= 1; // This message is missing the tendermint object part. this might not be important?
+	EventDataTx EventDataTx    	= 2;
+	EventDataCall EventDataCall = 3;
+	EventDataLog EventDataLog   = 4;
+}
+
+
+message PollResponse {
+	repeated Event events = 1;
+}
+//--------------------------------------------------
+
+
+// #BEGIN(namereg)
+// Name Registry Service Definition 
+service NameReg {
+	rpc GetEntry(NameRegEntryParam) returns (NameRegEntry);
+	rpc GetEntries(FilterListParam) returns (NameRegEntryList);
+	rpc TransactNameReg(TransactNameRegParam) returns (TxReceipt);
+	rpc TransactNameRegAndHold(TransactNameRegParam) returns (NameRegEntry);
+}
+
+// Params
+message NameRegEntryParam {
+	string name = 1;
+}
+
+message TransactNameRegParam {
+	InputAccount inputAccount = 1;
+	string name = 2;
+	string data = 3;
+	uint64 fee = 4;
+	uint64 amount = 5;
+}
+
+// Results
+message NameRegEntry {
+	// registered name for the entry
+	string Name    = 1;
+	bytes  Owner   = 2;
+	string Data    = 3;
+	uint64 Expires = 4;
+}
+
+message NameRegEntryList {
+	uint64 BlockHeight = 1;
+	repeated NameRegEntry Names = 2;
+}
+
+
+//--------------------------------------------------
+
+
+// #BEGIN(network)
+// Network Service Definition
+service Network {
+	rpc GetClientVersion(Empty) returns (ClientVersion); 	// NI - go
+	rpc GetNetworkInfo(Empty) returns (NetworkInfo);
+	rpc GetNodeInfo(Empty) returns (NodeInfo);  			// NI - go
+	rpc GetPeer(PeerParam) returns (Peer);					// NI - go
+	rpc GetPeers(Empty) returns (PeerList);
+}
+
+// Params
+message PeerParam {
+	bytes address = 1;
+}
+
+// Results
+message ClientVersion {
+	string version = 1;
+}
+
+message NodeID {
+	string Name = 1;
+	bytes  PublicKey = 2;
+}
+
+message NodeInfo {
+	NodeID ID  			= 1;
+	string ListenAddr  	= 2;
+	string Network  	= 3;
+	string Version 		= 4; 
+	bytes  Channels  	= 5;
+	string Moniker 		= 6;
+	repeated string Other = 7;
+}
+
+message NetworkInfo {
+	bool Listening = 1;
+	repeated string Listeners = 2;
+	repeated Peer Peers = 3;
+}
+
+message Peer {
+	NodeInfo NodeInfo   = 1;
+	bool     IsOutbound = 2;
+}
+
+message PeerList {
+	repeated Peer Peers = 1;
+}
+
+//-------------------------------------------------
+
+
+// #BEGIN(transaction)
+// Transaction Service Definition
+service Transaction {
+	rpc BroadcastTx(TxParam) returns (TxReceipt);
+	rpc Call(CallParam) returns (CallResult);
+	rpc CallCode(CallCodeParam) returns (CallResult);
+	rpc Transact(TransactParam) returns (TxReceipt);
+	rpc TransactAndHold(TransactParam) returns (EventDataCall);
+	rpc Send(SendParam) returns (TxReceipt);
+	rpc SendAndHold(SendParam) returns (TxReceipt);
+	rpc SignTx(SignTxParam) returns (SignedTx);
+}
+
+// Params
+message CallParam {
+	bytes from    = 1;
+	bytes address = 2;
+	bytes data 	  = 3;
+}
+
+message CallCodeParam {
+	bytes from = 1;
+	bytes code = 2;
+	bytes data = 3;
+}
+
+message TransactParam {
+	InputAccount inputAccount = 1;
+	bytes address = 2;
+	bytes data = 3;
+	uint64 gasLimit =4;
+	uint64 fee = 5;
+}
+
+message SendParam {
+	InputAccount inputAccount = 1;
+	bytes toAddress = 2;
+	uint64 amount = 3;
+}
+
+message TxParam {
+	bytes tx = 1;
+}
+
+message SignTxParam {
+	bytes tx = 1;
+	repeated PrivateAccount privateAccounts = 2;
+}
+
+// Results
+message SignedTx {
+	bytes tx = 1;
+}
+
+message CallResult {
+	bytes Return   = 1;
+	uint64 GasUsed = 2;
+}
+
+//--------------------------------------------------
\ No newline at end of file
diff --git a/rpc/burrow/account.pb.go b/rpc/burrow/account.pb.go
deleted file mode 100644
index 18771ad43e8143c139272e2ace8d3801e775ebb6..0000000000000000000000000000000000000000
--- a/rpc/burrow/account.pb.go
+++ /dev/null
@@ -1,900 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// source: rpc/burrow/account.proto
-
-package burrow
-
-import proto "github.com/golang/protobuf/proto"
-import fmt "fmt"
-import math "math"
-
-import (
-	context "golang.org/x/net/context"
-	grpc "google.golang.org/grpc"
-)
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ = proto.Marshal
-var _ = fmt.Errorf
-var _ = math.Inf
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the proto package it is being compiled against.
-// A compilation error at this line likely means your copy of the
-// proto package needs to be updated.
-const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
-
-// Params
-type AddressParam struct {
-	Address              []byte   `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *AddressParam) Reset()         { *m = AddressParam{} }
-func (m *AddressParam) String() string { return proto.CompactTextString(m) }
-func (*AddressParam) ProtoMessage()    {}
-func (*AddressParam) Descriptor() ([]byte, []int) {
-	return fileDescriptor_account_ff00efb2ede9d492, []int{0}
-}
-func (m *AddressParam) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_AddressParam.Unmarshal(m, b)
-}
-func (m *AddressParam) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_AddressParam.Marshal(b, m, deterministic)
-}
-func (dst *AddressParam) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_AddressParam.Merge(dst, src)
-}
-func (m *AddressParam) XXX_Size() int {
-	return xxx_messageInfo_AddressParam.Size(m)
-}
-func (m *AddressParam) XXX_DiscardUnknown() {
-	xxx_messageInfo_AddressParam.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_AddressParam proto.InternalMessageInfo
-
-func (m *AddressParam) GetAddress() []byte {
-	if m != nil {
-		return m.Address
-	}
-	return nil
-}
-
-type PrivateKeyParam struct {
-	PrivateKey           []byte   `protobuf:"bytes,1,opt,name=privateKey,proto3" json:"privateKey,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *PrivateKeyParam) Reset()         { *m = PrivateKeyParam{} }
-func (m *PrivateKeyParam) String() string { return proto.CompactTextString(m) }
-func (*PrivateKeyParam) ProtoMessage()    {}
-func (*PrivateKeyParam) Descriptor() ([]byte, []int) {
-	return fileDescriptor_account_ff00efb2ede9d492, []int{1}
-}
-func (m *PrivateKeyParam) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_PrivateKeyParam.Unmarshal(m, b)
-}
-func (m *PrivateKeyParam) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_PrivateKeyParam.Marshal(b, m, deterministic)
-}
-func (dst *PrivateKeyParam) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_PrivateKeyParam.Merge(dst, src)
-}
-func (m *PrivateKeyParam) XXX_Size() int {
-	return xxx_messageInfo_PrivateKeyParam.Size(m)
-}
-func (m *PrivateKeyParam) XXX_DiscardUnknown() {
-	xxx_messageInfo_PrivateKeyParam.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_PrivateKeyParam proto.InternalMessageInfo
-
-func (m *PrivateKeyParam) GetPrivateKey() []byte {
-	if m != nil {
-		return m.PrivateKey
-	}
-	return nil
-}
-
-type StorageAtParam struct {
-	Address              []byte   `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
-	Key                  []byte   `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *StorageAtParam) Reset()         { *m = StorageAtParam{} }
-func (m *StorageAtParam) String() string { return proto.CompactTextString(m) }
-func (*StorageAtParam) ProtoMessage()    {}
-func (*StorageAtParam) Descriptor() ([]byte, []int) {
-	return fileDescriptor_account_ff00efb2ede9d492, []int{2}
-}
-func (m *StorageAtParam) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_StorageAtParam.Unmarshal(m, b)
-}
-func (m *StorageAtParam) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_StorageAtParam.Marshal(b, m, deterministic)
-}
-func (dst *StorageAtParam) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_StorageAtParam.Merge(dst, src)
-}
-func (m *StorageAtParam) XXX_Size() int {
-	return xxx_messageInfo_StorageAtParam.Size(m)
-}
-func (m *StorageAtParam) XXX_DiscardUnknown() {
-	xxx_messageInfo_StorageAtParam.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_StorageAtParam proto.InternalMessageInfo
-
-func (m *StorageAtParam) GetAddress() []byte {
-	if m != nil {
-		return m.Address
-	}
-	return nil
-}
-
-func (m *StorageAtParam) GetKey() []byte {
-	if m != nil {
-		return m.Key
-	}
-	return nil
-}
-
-type BasePermissions struct {
-	Perms                uint64   `protobuf:"varint,1,opt,name=Perms,proto3" json:"Perms,omitempty"`
-	SetBit               uint64   `protobuf:"varint,2,opt,name=SetBit,proto3" json:"SetBit,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *BasePermissions) Reset()         { *m = BasePermissions{} }
-func (m *BasePermissions) String() string { return proto.CompactTextString(m) }
-func (*BasePermissions) ProtoMessage()    {}
-func (*BasePermissions) Descriptor() ([]byte, []int) {
-	return fileDescriptor_account_ff00efb2ede9d492, []int{3}
-}
-func (m *BasePermissions) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_BasePermissions.Unmarshal(m, b)
-}
-func (m *BasePermissions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_BasePermissions.Marshal(b, m, deterministic)
-}
-func (dst *BasePermissions) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_BasePermissions.Merge(dst, src)
-}
-func (m *BasePermissions) XXX_Size() int {
-	return xxx_messageInfo_BasePermissions.Size(m)
-}
-func (m *BasePermissions) XXX_DiscardUnknown() {
-	xxx_messageInfo_BasePermissions.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_BasePermissions proto.InternalMessageInfo
-
-func (m *BasePermissions) GetPerms() uint64 {
-	if m != nil {
-		return m.Perms
-	}
-	return 0
-}
-
-func (m *BasePermissions) GetSetBit() uint64 {
-	if m != nil {
-		return m.SetBit
-	}
-	return 0
-}
-
-type AccountPermissions struct {
-	Base                 *BasePermissions `protobuf:"bytes,1,opt,name=Base,proto3" json:"Base,omitempty"`
-	Roles                []string         `protobuf:"bytes,2,rep,name=Roles,proto3" json:"Roles,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}         `json:"-"`
-	XXX_unrecognized     []byte           `json:"-"`
-	XXX_sizecache        int32            `json:"-"`
-}
-
-func (m *AccountPermissions) Reset()         { *m = AccountPermissions{} }
-func (m *AccountPermissions) String() string { return proto.CompactTextString(m) }
-func (*AccountPermissions) ProtoMessage()    {}
-func (*AccountPermissions) Descriptor() ([]byte, []int) {
-	return fileDescriptor_account_ff00efb2ede9d492, []int{4}
-}
-func (m *AccountPermissions) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_AccountPermissions.Unmarshal(m, b)
-}
-func (m *AccountPermissions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_AccountPermissions.Marshal(b, m, deterministic)
-}
-func (dst *AccountPermissions) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_AccountPermissions.Merge(dst, src)
-}
-func (m *AccountPermissions) XXX_Size() int {
-	return xxx_messageInfo_AccountPermissions.Size(m)
-}
-func (m *AccountPermissions) XXX_DiscardUnknown() {
-	xxx_messageInfo_AccountPermissions.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_AccountPermissions proto.InternalMessageInfo
-
-func (m *AccountPermissions) GetBase() *BasePermissions {
-	if m != nil {
-		return m.Base
-	}
-	return nil
-}
-
-func (m *AccountPermissions) GetRoles() []string {
-	if m != nil {
-		return m.Roles
-	}
-	return nil
-}
-
-type Account struct {
-	Address              []byte              `protobuf:"bytes,1,opt,name=Address,proto3" json:"Address,omitempty"`
-	PublicKey            []byte              `protobuf:"bytes,2,opt,name=PublicKey,proto3" json:"PublicKey,omitempty"`
-	Sequence             uint64              `protobuf:"varint,3,opt,name=Sequence,proto3" json:"Sequence,omitempty"`
-	Balance              uint64              `protobuf:"varint,4,opt,name=Balance,proto3" json:"Balance,omitempty"`
-	Code                 []byte              `protobuf:"bytes,5,opt,name=Code,proto3" json:"Code,omitempty"`
-	StorageRoot          []byte              `protobuf:"bytes,6,opt,name=StorageRoot,proto3" json:"StorageRoot,omitempty"`
-	Permissions          *AccountPermissions `protobuf:"bytes,7,opt,name=Permissions,proto3" json:"Permissions,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}            `json:"-"`
-	XXX_unrecognized     []byte              `json:"-"`
-	XXX_sizecache        int32               `json:"-"`
-}
-
-func (m *Account) Reset()         { *m = Account{} }
-func (m *Account) String() string { return proto.CompactTextString(m) }
-func (*Account) ProtoMessage()    {}
-func (*Account) Descriptor() ([]byte, []int) {
-	return fileDescriptor_account_ff00efb2ede9d492, []int{5}
-}
-func (m *Account) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_Account.Unmarshal(m, b)
-}
-func (m *Account) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_Account.Marshal(b, m, deterministic)
-}
-func (dst *Account) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_Account.Merge(dst, src)
-}
-func (m *Account) XXX_Size() int {
-	return xxx_messageInfo_Account.Size(m)
-}
-func (m *Account) XXX_DiscardUnknown() {
-	xxx_messageInfo_Account.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Account proto.InternalMessageInfo
-
-func (m *Account) GetAddress() []byte {
-	if m != nil {
-		return m.Address
-	}
-	return nil
-}
-
-func (m *Account) GetPublicKey() []byte {
-	if m != nil {
-		return m.PublicKey
-	}
-	return nil
-}
-
-func (m *Account) GetSequence() uint64 {
-	if m != nil {
-		return m.Sequence
-	}
-	return 0
-}
-
-func (m *Account) GetBalance() uint64 {
-	if m != nil {
-		return m.Balance
-	}
-	return 0
-}
-
-func (m *Account) GetCode() []byte {
-	if m != nil {
-		return m.Code
-	}
-	return nil
-}
-
-func (m *Account) GetStorageRoot() []byte {
-	if m != nil {
-		return m.StorageRoot
-	}
-	return nil
-}
-
-func (m *Account) GetPermissions() *AccountPermissions {
-	if m != nil {
-		return m.Permissions
-	}
-	return nil
-}
-
-type AccountList struct {
-	BlockHeight          uint64     `protobuf:"varint,1,opt,name=BlockHeight,proto3" json:"BlockHeight,omitempty"`
-	Accounts             []*Account `protobuf:"bytes,2,rep,name=Accounts,proto3" json:"Accounts,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}   `json:"-"`
-	XXX_unrecognized     []byte     `json:"-"`
-	XXX_sizecache        int32      `json:"-"`
-}
-
-func (m *AccountList) Reset()         { *m = AccountList{} }
-func (m *AccountList) String() string { return proto.CompactTextString(m) }
-func (*AccountList) ProtoMessage()    {}
-func (*AccountList) Descriptor() ([]byte, []int) {
-	return fileDescriptor_account_ff00efb2ede9d492, []int{6}
-}
-func (m *AccountList) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_AccountList.Unmarshal(m, b)
-}
-func (m *AccountList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_AccountList.Marshal(b, m, deterministic)
-}
-func (dst *AccountList) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_AccountList.Merge(dst, src)
-}
-func (m *AccountList) XXX_Size() int {
-	return xxx_messageInfo_AccountList.Size(m)
-}
-func (m *AccountList) XXX_DiscardUnknown() {
-	xxx_messageInfo_AccountList.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_AccountList proto.InternalMessageInfo
-
-func (m *AccountList) GetBlockHeight() uint64 {
-	if m != nil {
-		return m.BlockHeight
-	}
-	return 0
-}
-
-func (m *AccountList) GetAccounts() []*Account {
-	if m != nil {
-		return m.Accounts
-	}
-	return nil
-}
-
-type Validator struct {
-	Address              []byte   `protobuf:"bytes,1,opt,name=Address,proto3" json:"Address,omitempty"`
-	PublicKey            []byte   `protobuf:"bytes,2,opt,name=PublicKey,proto3" json:"PublicKey,omitempty"`
-	Power                uint64   `protobuf:"varint,3,opt,name=Power,proto3" json:"Power,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *Validator) Reset()         { *m = Validator{} }
-func (m *Validator) String() string { return proto.CompactTextString(m) }
-func (*Validator) ProtoMessage()    {}
-func (*Validator) Descriptor() ([]byte, []int) {
-	return fileDescriptor_account_ff00efb2ede9d492, []int{7}
-}
-func (m *Validator) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_Validator.Unmarshal(m, b)
-}
-func (m *Validator) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_Validator.Marshal(b, m, deterministic)
-}
-func (dst *Validator) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_Validator.Merge(dst, src)
-}
-func (m *Validator) XXX_Size() int {
-	return xxx_messageInfo_Validator.Size(m)
-}
-func (m *Validator) XXX_DiscardUnknown() {
-	xxx_messageInfo_Validator.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Validator proto.InternalMessageInfo
-
-func (m *Validator) GetAddress() []byte {
-	if m != nil {
-		return m.Address
-	}
-	return nil
-}
-
-func (m *Validator) GetPublicKey() []byte {
-	if m != nil {
-		return m.PublicKey
-	}
-	return nil
-}
-
-func (m *Validator) GetPower() uint64 {
-	if m != nil {
-		return m.Power
-	}
-	return 0
-}
-
-type ValidatorList struct {
-	BlockHeight          uint64       `protobuf:"varint,1,opt,name=BlockHeight,proto3" json:"BlockHeight,omitempty"`
-	BondedValidators     []*Validator `protobuf:"bytes,2,rep,name=BondedValidators,proto3" json:"BondedValidators,omitempty"`
-	UnbondingValidators  []*Validator `protobuf:"bytes,3,rep,name=UnbondingValidators,proto3" json:"UnbondingValidators,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}     `json:"-"`
-	XXX_unrecognized     []byte       `json:"-"`
-	XXX_sizecache        int32        `json:"-"`
-}
-
-func (m *ValidatorList) Reset()         { *m = ValidatorList{} }
-func (m *ValidatorList) String() string { return proto.CompactTextString(m) }
-func (*ValidatorList) ProtoMessage()    {}
-func (*ValidatorList) Descriptor() ([]byte, []int) {
-	return fileDescriptor_account_ff00efb2ede9d492, []int{8}
-}
-func (m *ValidatorList) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_ValidatorList.Unmarshal(m, b)
-}
-func (m *ValidatorList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_ValidatorList.Marshal(b, m, deterministic)
-}
-func (dst *ValidatorList) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_ValidatorList.Merge(dst, src)
-}
-func (m *ValidatorList) XXX_Size() int {
-	return xxx_messageInfo_ValidatorList.Size(m)
-}
-func (m *ValidatorList) XXX_DiscardUnknown() {
-	xxx_messageInfo_ValidatorList.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_ValidatorList proto.InternalMessageInfo
-
-func (m *ValidatorList) GetBlockHeight() uint64 {
-	if m != nil {
-		return m.BlockHeight
-	}
-	return 0
-}
-
-func (m *ValidatorList) GetBondedValidators() []*Validator {
-	if m != nil {
-		return m.BondedValidators
-	}
-	return nil
-}
-
-func (m *ValidatorList) GetUnbondingValidators() []*Validator {
-	if m != nil {
-		return m.UnbondingValidators
-	}
-	return nil
-}
-
-type StorageItem struct {
-	Key                  []byte   `protobuf:"bytes,1,opt,name=Key,proto3" json:"Key,omitempty"`
-	Value                []byte   `protobuf:"bytes,2,opt,name=Value,proto3" json:"Value,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *StorageItem) Reset()         { *m = StorageItem{} }
-func (m *StorageItem) String() string { return proto.CompactTextString(m) }
-func (*StorageItem) ProtoMessage()    {}
-func (*StorageItem) Descriptor() ([]byte, []int) {
-	return fileDescriptor_account_ff00efb2ede9d492, []int{9}
-}
-func (m *StorageItem) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_StorageItem.Unmarshal(m, b)
-}
-func (m *StorageItem) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_StorageItem.Marshal(b, m, deterministic)
-}
-func (dst *StorageItem) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_StorageItem.Merge(dst, src)
-}
-func (m *StorageItem) XXX_Size() int {
-	return xxx_messageInfo_StorageItem.Size(m)
-}
-func (m *StorageItem) XXX_DiscardUnknown() {
-	xxx_messageInfo_StorageItem.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_StorageItem proto.InternalMessageInfo
-
-func (m *StorageItem) GetKey() []byte {
-	if m != nil {
-		return m.Key
-	}
-	return nil
-}
-
-func (m *StorageItem) GetValue() []byte {
-	if m != nil {
-		return m.Value
-	}
-	return nil
-}
-
-type StorageDump struct {
-	StorageRoot          []byte         `protobuf:"bytes,1,opt,name=StorageRoot,proto3" json:"StorageRoot,omitempty"`
-	StorageItems         []*StorageItem `protobuf:"bytes,2,rep,name=StorageItems,proto3" json:"StorageItems,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}       `json:"-"`
-	XXX_unrecognized     []byte         `json:"-"`
-	XXX_sizecache        int32          `json:"-"`
-}
-
-func (m *StorageDump) Reset()         { *m = StorageDump{} }
-func (m *StorageDump) String() string { return proto.CompactTextString(m) }
-func (*StorageDump) ProtoMessage()    {}
-func (*StorageDump) Descriptor() ([]byte, []int) {
-	return fileDescriptor_account_ff00efb2ede9d492, []int{10}
-}
-func (m *StorageDump) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_StorageDump.Unmarshal(m, b)
-}
-func (m *StorageDump) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_StorageDump.Marshal(b, m, deterministic)
-}
-func (dst *StorageDump) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_StorageDump.Merge(dst, src)
-}
-func (m *StorageDump) XXX_Size() int {
-	return xxx_messageInfo_StorageDump.Size(m)
-}
-func (m *StorageDump) XXX_DiscardUnknown() {
-	xxx_messageInfo_StorageDump.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_StorageDump proto.InternalMessageInfo
-
-func (m *StorageDump) GetStorageRoot() []byte {
-	if m != nil {
-		return m.StorageRoot
-	}
-	return nil
-}
-
-func (m *StorageDump) GetStorageItems() []*StorageItem {
-	if m != nil {
-		return m.StorageItems
-	}
-	return nil
-}
-
-func init() {
-	proto.RegisterType((*AddressParam)(nil), "AddressParam")
-	proto.RegisterType((*PrivateKeyParam)(nil), "PrivateKeyParam")
-	proto.RegisterType((*StorageAtParam)(nil), "StorageAtParam")
-	proto.RegisterType((*BasePermissions)(nil), "BasePermissions")
-	proto.RegisterType((*AccountPermissions)(nil), "AccountPermissions")
-	proto.RegisterType((*Account)(nil), "Account")
-	proto.RegisterType((*AccountList)(nil), "AccountList")
-	proto.RegisterType((*Validator)(nil), "Validator")
-	proto.RegisterType((*ValidatorList)(nil), "ValidatorList")
-	proto.RegisterType((*StorageItem)(nil), "StorageItem")
-	proto.RegisterType((*StorageDump)(nil), "StorageDump")
-}
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ context.Context
-var _ grpc.ClientConn
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the grpc package it is being compiled against.
-const _ = grpc.SupportPackageIsVersion4
-
-// AccountsClient is the client API for Accounts service.
-//
-// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
-type AccountsClient interface {
-	GenPrivAccount(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*PrivateAccount, error)
-	GenPrivAccountFromKey(ctx context.Context, in *PrivateKeyParam, opts ...grpc.CallOption) (*PrivateAccount, error)
-	GetAccount(ctx context.Context, in *AddressParam, opts ...grpc.CallOption) (*Account, error)
-	GetAccounts(ctx context.Context, in *FilterListParam, opts ...grpc.CallOption) (*AccountList, error)
-	GetValidators(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ValidatorList, error)
-	GetStorage(ctx context.Context, in *AddressParam, opts ...grpc.CallOption) (*StorageDump, error)
-	GetStorageAt(ctx context.Context, in *StorageAtParam, opts ...grpc.CallOption) (*StorageItem, error)
-}
-
-type accountsClient struct {
-	cc *grpc.ClientConn
-}
-
-func NewAccountsClient(cc *grpc.ClientConn) AccountsClient {
-	return &accountsClient{cc}
-}
-
-func (c *accountsClient) GenPrivAccount(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*PrivateAccount, error) {
-	out := new(PrivateAccount)
-	err := c.cc.Invoke(ctx, "/Accounts/GenPrivAccount", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *accountsClient) GenPrivAccountFromKey(ctx context.Context, in *PrivateKeyParam, opts ...grpc.CallOption) (*PrivateAccount, error) {
-	out := new(PrivateAccount)
-	err := c.cc.Invoke(ctx, "/Accounts/GenPrivAccountFromKey", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *accountsClient) GetAccount(ctx context.Context, in *AddressParam, opts ...grpc.CallOption) (*Account, error) {
-	out := new(Account)
-	err := c.cc.Invoke(ctx, "/Accounts/GetAccount", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *accountsClient) GetAccounts(ctx context.Context, in *FilterListParam, opts ...grpc.CallOption) (*AccountList, error) {
-	out := new(AccountList)
-	err := c.cc.Invoke(ctx, "/Accounts/GetAccounts", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *accountsClient) GetValidators(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ValidatorList, error) {
-	out := new(ValidatorList)
-	err := c.cc.Invoke(ctx, "/Accounts/GetValidators", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *accountsClient) GetStorage(ctx context.Context, in *AddressParam, opts ...grpc.CallOption) (*StorageDump, error) {
-	out := new(StorageDump)
-	err := c.cc.Invoke(ctx, "/Accounts/GetStorage", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *accountsClient) GetStorageAt(ctx context.Context, in *StorageAtParam, opts ...grpc.CallOption) (*StorageItem, error) {
-	out := new(StorageItem)
-	err := c.cc.Invoke(ctx, "/Accounts/GetStorageAt", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-// AccountsServer is the server API for Accounts service.
-type AccountsServer interface {
-	GenPrivAccount(context.Context, *Empty) (*PrivateAccount, error)
-	GenPrivAccountFromKey(context.Context, *PrivateKeyParam) (*PrivateAccount, error)
-	GetAccount(context.Context, *AddressParam) (*Account, error)
-	GetAccounts(context.Context, *FilterListParam) (*AccountList, error)
-	GetValidators(context.Context, *Empty) (*ValidatorList, error)
-	GetStorage(context.Context, *AddressParam) (*StorageDump, error)
-	GetStorageAt(context.Context, *StorageAtParam) (*StorageItem, error)
-}
-
-func RegisterAccountsServer(s *grpc.Server, srv AccountsServer) {
-	s.RegisterService(&_Accounts_serviceDesc, srv)
-}
-
-func _Accounts_GenPrivAccount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(Empty)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(AccountsServer).GenPrivAccount(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/Accounts/GenPrivAccount",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(AccountsServer).GenPrivAccount(ctx, req.(*Empty))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Accounts_GenPrivAccountFromKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(PrivateKeyParam)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(AccountsServer).GenPrivAccountFromKey(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/Accounts/GenPrivAccountFromKey",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(AccountsServer).GenPrivAccountFromKey(ctx, req.(*PrivateKeyParam))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Accounts_GetAccount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(AddressParam)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(AccountsServer).GetAccount(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/Accounts/GetAccount",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(AccountsServer).GetAccount(ctx, req.(*AddressParam))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Accounts_GetAccounts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(FilterListParam)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(AccountsServer).GetAccounts(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/Accounts/GetAccounts",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(AccountsServer).GetAccounts(ctx, req.(*FilterListParam))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Accounts_GetValidators_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(Empty)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(AccountsServer).GetValidators(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/Accounts/GetValidators",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(AccountsServer).GetValidators(ctx, req.(*Empty))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Accounts_GetStorage_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(AddressParam)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(AccountsServer).GetStorage(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/Accounts/GetStorage",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(AccountsServer).GetStorage(ctx, req.(*AddressParam))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Accounts_GetStorageAt_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(StorageAtParam)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(AccountsServer).GetStorageAt(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/Accounts/GetStorageAt",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(AccountsServer).GetStorageAt(ctx, req.(*StorageAtParam))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-var _Accounts_serviceDesc = grpc.ServiceDesc{
-	ServiceName: "Accounts",
-	HandlerType: (*AccountsServer)(nil),
-	Methods: []grpc.MethodDesc{
-		{
-			MethodName: "GenPrivAccount",
-			Handler:    _Accounts_GenPrivAccount_Handler,
-		},
-		{
-			MethodName: "GenPrivAccountFromKey",
-			Handler:    _Accounts_GenPrivAccountFromKey_Handler,
-		},
-		{
-			MethodName: "GetAccount",
-			Handler:    _Accounts_GetAccount_Handler,
-		},
-		{
-			MethodName: "GetAccounts",
-			Handler:    _Accounts_GetAccounts_Handler,
-		},
-		{
-			MethodName: "GetValidators",
-			Handler:    _Accounts_GetValidators_Handler,
-		},
-		{
-			MethodName: "GetStorage",
-			Handler:    _Accounts_GetStorage_Handler,
-		},
-		{
-			MethodName: "GetStorageAt",
-			Handler:    _Accounts_GetStorageAt_Handler,
-		},
-	},
-	Streams:  []grpc.StreamDesc{},
-	Metadata: "rpc/burrow/account.proto",
-}
-
-func init() { proto.RegisterFile("rpc/burrow/account.proto", fileDescriptor_account_ff00efb2ede9d492) }
-
-var fileDescriptor_account_ff00efb2ede9d492 = []byte{
-	// 612 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x54, 0xdd, 0x6e, 0xd3, 0x4c,
-	0x10, 0x55, 0x9a, 0x34, 0x4d, 0xc7, 0x6e, 0x13, 0x6d, 0xbf, 0x0f, 0xac, 0x08, 0xa1, 0xca, 0x2a,
-	0xa2, 0xbd, 0xe8, 0x16, 0x8a, 0xca, 0x05, 0xaa, 0x84, 0x62, 0xa0, 0x01, 0x95, 0x8b, 0xc8, 0x51,
-	0x2b, 0xc1, 0xdd, 0xc6, 0x5e, 0x05, 0xab, 0xb6, 0x37, 0xac, 0xd7, 0x54, 0x79, 0x22, 0xde, 0x85,
-	0xe7, 0xe0, 0x41, 0xd0, 0xfe, 0xd8, 0x59, 0x27, 0x48, 0x20, 0xee, 0x7c, 0x66, 0xce, 0xcc, 0xec,
-	0x9c, 0x19, 0x0f, 0x78, 0x7c, 0x11, 0x9d, 0xcd, 0x4a, 0xce, 0xd9, 0xfd, 0x19, 0x89, 0x22, 0x56,
-	0xe6, 0x02, 0x2f, 0x38, 0x13, 0x6c, 0xf8, 0xd0, 0xf2, 0x44, 0x2c, 0xcb, 0x58, 0xae, 0x1d, 0xfe,
-	0x31, 0xb8, 0xa3, 0x38, 0xe6, 0xb4, 0x28, 0x26, 0x84, 0x93, 0x0c, 0x79, 0xb0, 0x43, 0x34, 0xf6,
-	0x5a, 0x87, 0xad, 0x63, 0x37, 0xac, 0xa0, 0xff, 0x1c, 0xfa, 0x13, 0x9e, 0x7c, 0x23, 0x82, 0x5e,
-	0xd3, 0xa5, 0x26, 0x3f, 0x06, 0x58, 0xd4, 0x26, 0xc3, 0xb7, 0x2c, 0xfe, 0x25, 0xec, 0x4f, 0x05,
-	0xe3, 0x64, 0x4e, 0x47, 0xe2, 0x0f, 0xe9, 0xd1, 0x00, 0xda, 0x77, 0x74, 0xe9, 0x6d, 0x29, 0xab,
-	0xfc, 0xf4, 0x5f, 0x43, 0x3f, 0x20, 0x05, 0x9d, 0x50, 0x9e, 0x25, 0x45, 0x91, 0xb0, 0xbc, 0x40,
-	0xff, 0xc1, 0xb6, 0x84, 0x3a, 0xb8, 0x13, 0x6a, 0x80, 0x1e, 0x40, 0x77, 0x4a, 0x45, 0x90, 0x08,
-	0x15, 0xdd, 0x09, 0x0d, 0xf2, 0x27, 0x80, 0x46, 0x5a, 0x05, 0x3b, 0xc7, 0x11, 0x74, 0x64, 0x5a,
-	0x95, 0xc2, 0x39, 0x1f, 0xe0, 0xb5, 0x1a, 0xa1, 0xf2, 0xca, 0x4a, 0x21, 0x4b, 0x69, 0xe1, 0x6d,
-	0x1d, 0xb6, 0x8f, 0x77, 0x43, 0x0d, 0xfc, 0x9f, 0x2d, 0xd8, 0x31, 0x29, 0x65, 0x2b, 0xa3, 0x66,
-	0x2b, 0x06, 0xa2, 0x47, 0xb0, 0x3b, 0x29, 0x67, 0x69, 0x12, 0x5d, 0xd7, 0x0d, 0xad, 0x0c, 0x68,
-	0x08, 0xbd, 0x29, 0xfd, 0x5a, 0xd2, 0x3c, 0xa2, 0x5e, 0x5b, 0xbd, 0xb7, 0xc6, 0x32, 0x67, 0x40,
-	0x52, 0x22, 0x5d, 0x1d, 0xe5, 0xaa, 0x20, 0x42, 0xd0, 0x79, 0xc3, 0x62, 0xea, 0x6d, 0xab, 0x74,
-	0xea, 0x1b, 0x1d, 0x82, 0x63, 0xe4, 0x0d, 0x19, 0x13, 0x5e, 0x57, 0xb9, 0x6c, 0x13, 0xba, 0x00,
-	0xc7, 0x6a, 0xcd, 0xdb, 0x51, 0x2d, 0x1f, 0xe0, 0x4d, 0x55, 0x42, 0x9b, 0xe7, 0xdf, 0x80, 0x63,
-	0x28, 0x1f, 0x93, 0x42, 0xc8, 0x3a, 0x41, 0xca, 0xa2, 0xbb, 0xf7, 0x34, 0x99, 0x7f, 0x11, 0x46,
-	0x7b, 0xdb, 0x84, 0x8e, 0xa0, 0x67, 0x02, 0xb4, 0x60, 0xce, 0x79, 0xaf, 0x2a, 0x12, 0xd6, 0x1e,
-	0xff, 0x13, 0xec, 0xde, 0x92, 0x34, 0x89, 0x89, 0x60, 0xfc, 0x9f, 0xe5, 0x93, 0x2b, 0xc0, 0xee,
-	0x29, 0x37, 0xda, 0x69, 0xe0, 0x7f, 0x6f, 0xc1, 0x5e, 0x9d, 0xfb, 0x2f, 0x1f, 0xfd, 0x12, 0x06,
-	0x01, 0xcb, 0x63, 0x1a, 0xd7, 0x81, 0xd5, 0xe3, 0x01, 0xd7, 0xa6, 0x70, 0x83, 0x83, 0x2e, 0xe1,
-	0xe0, 0x26, 0x9f, 0xb1, 0x3c, 0x4e, 0xf2, 0xb9, 0x15, 0xda, 0xde, 0x08, 0xfd, 0x1d, 0xcd, 0xbf,
-	0xa8, 0x87, 0xf6, 0x41, 0xd0, 0x4c, 0xae, 0xfd, 0xea, 0xdf, 0x69, 0x9b, 0x06, 0x6f, 0x49, 0x5a,
-	0x52, 0xd3, 0xba, 0x06, 0x3e, 0xa9, 0xc3, 0xde, 0x96, 0xd9, 0x62, 0x7d, 0xf4, 0xad, 0xcd, 0xd1,
-	0x3f, 0x03, 0xd7, 0xaa, 0x53, 0x75, 0xe6, 0x62, 0xcb, 0x18, 0x36, 0x18, 0xe7, 0x3f, 0xb6, 0x56,
-	0x53, 0x44, 0x27, 0xb0, 0x3f, 0xa6, 0xb9, 0xfc, 0xe1, 0xab, 0x7d, 0xef, 0xe2, 0x77, 0xd9, 0x42,
-	0x2c, 0x87, 0x7d, 0x6c, 0xce, 0x40, 0xe5, 0x78, 0x05, 0xff, 0x37, 0xa9, 0x57, 0x9c, 0x65, 0xb2,
-	0x93, 0x01, 0x5e, 0x3b, 0x18, 0x9b, 0xb1, 0x4f, 0x00, 0xc6, 0x54, 0x54, 0x68, 0x0f, 0xdb, 0xb7,
-	0x68, 0x58, 0xef, 0x10, 0x3a, 0x05, 0x67, 0x45, 0x2b, 0xd0, 0x00, 0x5f, 0x25, 0xa9, 0xa0, 0x6a,
-	0xd0, 0x9a, 0xea, 0x62, 0x7b, 0x61, 0x9f, 0xc2, 0xde, 0x98, 0x0a, 0x6b, 0x64, 0xd5, 0xdb, 0xf7,
-	0x71, 0x73, 0x49, 0x4e, 0x54, 0x79, 0xa3, 0xc2, 0x7a, 0xf9, 0x5a, 0x2b, 0xa5, 0xf8, 0x29, 0xb8,
-	0x2b, 0xea, 0x48, 0xa0, 0x3e, 0x6e, 0x9e, 0xb6, 0x61, 0x43, 0xda, 0xa0, 0xf7, 0xb9, 0xab, 0xcf,
-	0xed, 0xac, 0xab, 0x0e, 0xed, 0x8b, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xb2, 0xd4, 0xb8, 0x59,
-	0x9d, 0x05, 0x00, 0x00,
-}
diff --git a/rpc/burrow/account.proto b/rpc/burrow/account.proto
deleted file mode 100644
index 72d4bb459e14367876b66041a4c961b1393b3558..0000000000000000000000000000000000000000
--- a/rpc/burrow/account.proto
+++ /dev/null
@@ -1,82 +0,0 @@
-syntax = 'proto3';
-
-option go_package = "burrow";
-
-import "rpc/burrow/common.proto";
-
-// Account Service definition
-service Accounts {
-    rpc GenPrivAccount (Empty) returns (PrivateAccount);
-    rpc GenPrivAccountFromKey (PrivateKeyParam) returns (PrivateAccount);
-    rpc GetAccount (AddressParam) returns (Account);
-    rpc GetAccounts (FilterListParam) returns (AccountList);
-    rpc GetValidators (Empty) returns (ValidatorList);
-    rpc GetStorage (AddressParam) returns (StorageDump);
-    rpc GetStorageAt (StorageAtParam) returns (StorageItem);
-}
-
-// Params
-message AddressParam {
-    bytes address = 1;
-}
-
-message PrivateKeyParam {
-    bytes privateKey = 1;
-}
-
-message StorageAtParam {
-    bytes address = 1;
-    bytes key = 2;
-}
-
-// Results
-
-message BasePermissions {
-    uint64 Perms = 1;
-    uint64 SetBit = 2;
-}
-
-message AccountPermissions {
-    BasePermissions Base = 1;
-    repeated string Roles = 2;
-}
-
-message Account {
-    bytes Address = 1;
-    bytes PublicKey = 2;
-    uint64 Sequence = 3;
-    uint64 Balance = 4;
-    bytes Code = 5;
-    bytes StorageRoot = 6;
-    AccountPermissions Permissions = 7;
-}
-
-message AccountList {
-    uint64 BlockHeight = 1;
-    repeated Account Accounts = 2;
-}
-
-message Validator {
-    bytes Address = 1;
-    bytes PublicKey = 2;
-    uint64 Power = 3;
-}
-
-message ValidatorList {
-    uint64 BlockHeight = 1;
-    repeated Validator BondedValidators = 2;
-    repeated Validator UnbondingValidators = 3;
-}
-
-message StorageItem {
-    bytes Key = 1;
-    bytes Value = 2;
-}
-
-message StorageDump {
-    bytes StorageRoot = 1;
-    repeated StorageItem StorageItems = 2;
-}
-
-//-----------------------------------------------
-
diff --git a/rpc/burrow/blockchain.pb.go b/rpc/burrow/blockchain.pb.go
deleted file mode 100644
index 5f4e526da9c53a31a30beb34ade80bfd2dbc3779..0000000000000000000000000000000000000000
--- a/rpc/burrow/blockchain.pb.go
+++ /dev/null
@@ -1,1387 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// source: rpc/burrow/blockchain.proto
-
-package burrow
-
-import proto "github.com/golang/protobuf/proto"
-import fmt "fmt"
-import math "math"
-
-import (
-	context "golang.org/x/net/context"
-	grpc "google.golang.org/grpc"
-)
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ = proto.Marshal
-var _ = fmt.Errorf
-var _ = math.Inf
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the proto package it is being compiled against.
-// A compilation error at this line likely means your copy of the
-// proto package needs to be updated.
-const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
-
-// Params
-type HeightParam struct {
-	Height               uint64   `protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *HeightParam) Reset()         { *m = HeightParam{} }
-func (m *HeightParam) String() string { return proto.CompactTextString(m) }
-func (*HeightParam) ProtoMessage()    {}
-func (*HeightParam) Descriptor() ([]byte, []int) {
-	return fileDescriptor_blockchain_8510b9aa600a1d3c, []int{0}
-}
-func (m *HeightParam) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_HeightParam.Unmarshal(m, b)
-}
-func (m *HeightParam) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_HeightParam.Marshal(b, m, deterministic)
-}
-func (dst *HeightParam) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_HeightParam.Merge(dst, src)
-}
-func (m *HeightParam) XXX_Size() int {
-	return xxx_messageInfo_HeightParam.Size(m)
-}
-func (m *HeightParam) XXX_DiscardUnknown() {
-	xxx_messageInfo_HeightParam.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_HeightParam proto.InternalMessageInfo
-
-func (m *HeightParam) GetHeight() uint64 {
-	if m != nil {
-		return m.Height
-	}
-	return 0
-}
-
-type BlocksParam struct {
-	MinHeight            uint64   `protobuf:"varint,1,opt,name=minHeight,proto3" json:"minHeight,omitempty"`
-	MaxHeight            uint64   `protobuf:"varint,2,opt,name=maxHeight,proto3" json:"maxHeight,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *BlocksParam) Reset()         { *m = BlocksParam{} }
-func (m *BlocksParam) String() string { return proto.CompactTextString(m) }
-func (*BlocksParam) ProtoMessage()    {}
-func (*BlocksParam) Descriptor() ([]byte, []int) {
-	return fileDescriptor_blockchain_8510b9aa600a1d3c, []int{1}
-}
-func (m *BlocksParam) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_BlocksParam.Unmarshal(m, b)
-}
-func (m *BlocksParam) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_BlocksParam.Marshal(b, m, deterministic)
-}
-func (dst *BlocksParam) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_BlocksParam.Merge(dst, src)
-}
-func (m *BlocksParam) XXX_Size() int {
-	return xxx_messageInfo_BlocksParam.Size(m)
-}
-func (m *BlocksParam) XXX_DiscardUnknown() {
-	xxx_messageInfo_BlocksParam.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_BlocksParam proto.InternalMessageInfo
-
-func (m *BlocksParam) GetMinHeight() uint64 {
-	if m != nil {
-		return m.MinHeight
-	}
-	return 0
-}
-
-func (m *BlocksParam) GetMaxHeight() uint64 {
-	if m != nil {
-		return m.MaxHeight
-	}
-	return 0
-}
-
-// Results
-type Header struct {
-	ChainID              string   `protobuf:"bytes,1,opt,name=ChainID,proto3" json:"ChainID,omitempty"`
-	Height               int64    `protobuf:"varint,2,opt,name=Height,proto3" json:"Height,omitempty"`
-	Time                 int64    `protobuf:"varint,3,opt,name=Time,proto3" json:"Time,omitempty"`
-	NumTxs               int64    `protobuf:"varint,4,opt,name=NumTxs,proto3" json:"NumTxs,omitempty"`
-	LastBlockID          []byte   `protobuf:"bytes,5,opt,name=LastBlockID,proto3" json:"LastBlockID,omitempty"`
-	LastCommitHash       []byte   `protobuf:"bytes,6,opt,name=LastCommitHash,proto3" json:"LastCommitHash,omitempty"`
-	DataHash             []byte   `protobuf:"bytes,7,opt,name=DataHash,proto3" json:"DataHash,omitempty"`
-	ValidatorsHash       []byte   `protobuf:"bytes,8,opt,name=ValidatorsHash,proto3" json:"ValidatorsHash,omitempty"`
-	AppHash              []byte   `protobuf:"bytes,9,opt,name=AppHash,proto3" json:"AppHash,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *Header) Reset()         { *m = Header{} }
-func (m *Header) String() string { return proto.CompactTextString(m) }
-func (*Header) ProtoMessage()    {}
-func (*Header) Descriptor() ([]byte, []int) {
-	return fileDescriptor_blockchain_8510b9aa600a1d3c, []int{2}
-}
-func (m *Header) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_Header.Unmarshal(m, b)
-}
-func (m *Header) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_Header.Marshal(b, m, deterministic)
-}
-func (dst *Header) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_Header.Merge(dst, src)
-}
-func (m *Header) XXX_Size() int {
-	return xxx_messageInfo_Header.Size(m)
-}
-func (m *Header) XXX_DiscardUnknown() {
-	xxx_messageInfo_Header.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Header proto.InternalMessageInfo
-
-func (m *Header) GetChainID() string {
-	if m != nil {
-		return m.ChainID
-	}
-	return ""
-}
-
-func (m *Header) GetHeight() int64 {
-	if m != nil {
-		return m.Height
-	}
-	return 0
-}
-
-func (m *Header) GetTime() int64 {
-	if m != nil {
-		return m.Time
-	}
-	return 0
-}
-
-func (m *Header) GetNumTxs() int64 {
-	if m != nil {
-		return m.NumTxs
-	}
-	return 0
-}
-
-func (m *Header) GetLastBlockID() []byte {
-	if m != nil {
-		return m.LastBlockID
-	}
-	return nil
-}
-
-func (m *Header) GetLastCommitHash() []byte {
-	if m != nil {
-		return m.LastCommitHash
-	}
-	return nil
-}
-
-func (m *Header) GetDataHash() []byte {
-	if m != nil {
-		return m.DataHash
-	}
-	return nil
-}
-
-func (m *Header) GetValidatorsHash() []byte {
-	if m != nil {
-		return m.ValidatorsHash
-	}
-	return nil
-}
-
-func (m *Header) GetAppHash() []byte {
-	if m != nil {
-		return m.AppHash
-	}
-	return nil
-}
-
-type Data struct {
-	Txs                  [][]byte `protobuf:"bytes,1,rep,name=Txs,proto3" json:"Txs,omitempty"`
-	Hash                 []byte   `protobuf:"bytes,2,opt,name=hash,proto3" json:"hash,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *Data) Reset()         { *m = Data{} }
-func (m *Data) String() string { return proto.CompactTextString(m) }
-func (*Data) ProtoMessage()    {}
-func (*Data) Descriptor() ([]byte, []int) {
-	return fileDescriptor_blockchain_8510b9aa600a1d3c, []int{3}
-}
-func (m *Data) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_Data.Unmarshal(m, b)
-}
-func (m *Data) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_Data.Marshal(b, m, deterministic)
-}
-func (dst *Data) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_Data.Merge(dst, src)
-}
-func (m *Data) XXX_Size() int {
-	return xxx_messageInfo_Data.Size(m)
-}
-func (m *Data) XXX_DiscardUnknown() {
-	xxx_messageInfo_Data.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Data proto.InternalMessageInfo
-
-func (m *Data) GetTxs() [][]byte {
-	if m != nil {
-		return m.Txs
-	}
-	return nil
-}
-
-func (m *Data) GetHash() []byte {
-	if m != nil {
-		return m.Hash
-	}
-	return nil
-}
-
-type Block struct {
-	BlockID              []byte   `protobuf:"bytes,1,opt,name=BlockID,proto3" json:"BlockID,omitempty"`
-	Header               *Header  `protobuf:"bytes,2,opt,name=Header,proto3" json:"Header,omitempty"`
-	Data                 *Data    `protobuf:"bytes,3,opt,name=Data,proto3" json:"Data,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *Block) Reset()         { *m = Block{} }
-func (m *Block) String() string { return proto.CompactTextString(m) }
-func (*Block) ProtoMessage()    {}
-func (*Block) Descriptor() ([]byte, []int) {
-	return fileDescriptor_blockchain_8510b9aa600a1d3c, []int{4}
-}
-func (m *Block) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_Block.Unmarshal(m, b)
-}
-func (m *Block) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_Block.Marshal(b, m, deterministic)
-}
-func (dst *Block) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_Block.Merge(dst, src)
-}
-func (m *Block) XXX_Size() int {
-	return xxx_messageInfo_Block.Size(m)
-}
-func (m *Block) XXX_DiscardUnknown() {
-	xxx_messageInfo_Block.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Block proto.InternalMessageInfo
-
-func (m *Block) GetBlockID() []byte {
-	if m != nil {
-		return m.BlockID
-	}
-	return nil
-}
-
-func (m *Block) GetHeader() *Header {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func (m *Block) GetData() *Data {
-	if m != nil {
-		return m.Data
-	}
-	return nil
-}
-
-type BlockMeta struct {
-	BlockID              []byte   `protobuf:"bytes,1,opt,name=BlockID,proto3" json:"BlockID,omitempty"`
-	Header               *Header  `protobuf:"bytes,2,opt,name=Header,proto3" json:"Header,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *BlockMeta) Reset()         { *m = BlockMeta{} }
-func (m *BlockMeta) String() string { return proto.CompactTextString(m) }
-func (*BlockMeta) ProtoMessage()    {}
-func (*BlockMeta) Descriptor() ([]byte, []int) {
-	return fileDescriptor_blockchain_8510b9aa600a1d3c, []int{5}
-}
-func (m *BlockMeta) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_BlockMeta.Unmarshal(m, b)
-}
-func (m *BlockMeta) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_BlockMeta.Marshal(b, m, deterministic)
-}
-func (dst *BlockMeta) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_BlockMeta.Merge(dst, src)
-}
-func (m *BlockMeta) XXX_Size() int {
-	return xxx_messageInfo_BlockMeta.Size(m)
-}
-func (m *BlockMeta) XXX_DiscardUnknown() {
-	xxx_messageInfo_BlockMeta.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_BlockMeta proto.InternalMessageInfo
-
-func (m *BlockMeta) GetBlockID() []byte {
-	if m != nil {
-		return m.BlockID
-	}
-	return nil
-}
-
-func (m *BlockMeta) GetHeader() *Header {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-type BlockList struct {
-	LastHeight           uint64       `protobuf:"varint,1,opt,name=LastHeight,proto3" json:"LastHeight,omitempty"`
-	BlockMetas           []*BlockMeta `protobuf:"bytes,2,rep,name=BlockMetas,proto3" json:"BlockMetas,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}     `json:"-"`
-	XXX_unrecognized     []byte       `json:"-"`
-	XXX_sizecache        int32        `json:"-"`
-}
-
-func (m *BlockList) Reset()         { *m = BlockList{} }
-func (m *BlockList) String() string { return proto.CompactTextString(m) }
-func (*BlockList) ProtoMessage()    {}
-func (*BlockList) Descriptor() ([]byte, []int) {
-	return fileDescriptor_blockchain_8510b9aa600a1d3c, []int{6}
-}
-func (m *BlockList) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_BlockList.Unmarshal(m, b)
-}
-func (m *BlockList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_BlockList.Marshal(b, m, deterministic)
-}
-func (dst *BlockList) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_BlockList.Merge(dst, src)
-}
-func (m *BlockList) XXX_Size() int {
-	return xxx_messageInfo_BlockList.Size(m)
-}
-func (m *BlockList) XXX_DiscardUnknown() {
-	xxx_messageInfo_BlockList.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_BlockList proto.InternalMessageInfo
-
-func (m *BlockList) GetLastHeight() uint64 {
-	if m != nil {
-		return m.LastHeight
-	}
-	return 0
-}
-
-func (m *BlockList) GetBlockMetas() []*BlockMeta {
-	if m != nil {
-		return m.BlockMetas
-	}
-	return nil
-}
-
-type ChainId struct {
-	ChainName            string   `protobuf:"bytes,1,opt,name=ChainName,proto3" json:"ChainName,omitempty"`
-	ChainId              string   `protobuf:"bytes,2,opt,name=ChainId,proto3" json:"ChainId,omitempty"`
-	GenesisHash          []byte   `protobuf:"bytes,3,opt,name=GenesisHash,proto3" json:"GenesisHash,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *ChainId) Reset()         { *m = ChainId{} }
-func (m *ChainId) String() string { return proto.CompactTextString(m) }
-func (*ChainId) ProtoMessage()    {}
-func (*ChainId) Descriptor() ([]byte, []int) {
-	return fileDescriptor_blockchain_8510b9aa600a1d3c, []int{7}
-}
-func (m *ChainId) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_ChainId.Unmarshal(m, b)
-}
-func (m *ChainId) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_ChainId.Marshal(b, m, deterministic)
-}
-func (dst *ChainId) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_ChainId.Merge(dst, src)
-}
-func (m *ChainId) XXX_Size() int {
-	return xxx_messageInfo_ChainId.Size(m)
-}
-func (m *ChainId) XXX_DiscardUnknown() {
-	xxx_messageInfo_ChainId.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_ChainId proto.InternalMessageInfo
-
-func (m *ChainId) GetChainName() string {
-	if m != nil {
-		return m.ChainName
-	}
-	return ""
-}
-
-func (m *ChainId) GetChainId() string {
-	if m != nil {
-		return m.ChainId
-	}
-	return ""
-}
-
-func (m *ChainId) GetGenesisHash() []byte {
-	if m != nil {
-		return m.GenesisHash
-	}
-	return nil
-}
-
-type GenesisDoc struct {
-	GenesisTime          uint64                         `protobuf:"varint,1,opt,name=GenesisTime,proto3" json:"GenesisTime,omitempty"`
-	ChainName            string                         `protobuf:"bytes,2,opt,name=ChainName,proto3" json:"ChainName,omitempty"`
-	Salt                 []byte                         `protobuf:"bytes,3,opt,name=Salt,proto3" json:"Salt,omitempty"`
-	GlobalPermissions    uint64                         `protobuf:"varint,4,opt,name=GlobalPermissions,proto3" json:"GlobalPermissions,omitempty"`
-	Accounts             []*GenesisDoc_GenesisAccount   `protobuf:"bytes,5,rep,name=Accounts,proto3" json:"Accounts,omitempty"`
-	Validators           []*GenesisDoc_GenesisValidator `protobuf:"bytes,6,rep,name=Validators,proto3" json:"Validators,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}                       `json:"-"`
-	XXX_unrecognized     []byte                         `json:"-"`
-	XXX_sizecache        int32                          `json:"-"`
-}
-
-func (m *GenesisDoc) Reset()         { *m = GenesisDoc{} }
-func (m *GenesisDoc) String() string { return proto.CompactTextString(m) }
-func (*GenesisDoc) ProtoMessage()    {}
-func (*GenesisDoc) Descriptor() ([]byte, []int) {
-	return fileDescriptor_blockchain_8510b9aa600a1d3c, []int{8}
-}
-func (m *GenesisDoc) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_GenesisDoc.Unmarshal(m, b)
-}
-func (m *GenesisDoc) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_GenesisDoc.Marshal(b, m, deterministic)
-}
-func (dst *GenesisDoc) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_GenesisDoc.Merge(dst, src)
-}
-func (m *GenesisDoc) XXX_Size() int {
-	return xxx_messageInfo_GenesisDoc.Size(m)
-}
-func (m *GenesisDoc) XXX_DiscardUnknown() {
-	xxx_messageInfo_GenesisDoc.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_GenesisDoc proto.InternalMessageInfo
-
-func (m *GenesisDoc) GetGenesisTime() uint64 {
-	if m != nil {
-		return m.GenesisTime
-	}
-	return 0
-}
-
-func (m *GenesisDoc) GetChainName() string {
-	if m != nil {
-		return m.ChainName
-	}
-	return ""
-}
-
-func (m *GenesisDoc) GetSalt() []byte {
-	if m != nil {
-		return m.Salt
-	}
-	return nil
-}
-
-func (m *GenesisDoc) GetGlobalPermissions() uint64 {
-	if m != nil {
-		return m.GlobalPermissions
-	}
-	return 0
-}
-
-func (m *GenesisDoc) GetAccounts() []*GenesisDoc_GenesisAccount {
-	if m != nil {
-		return m.Accounts
-	}
-	return nil
-}
-
-func (m *GenesisDoc) GetValidators() []*GenesisDoc_GenesisValidator {
-	if m != nil {
-		return m.Validators
-	}
-	return nil
-}
-
-type GenesisDoc_GenesisAccount struct {
-	Address              []byte              `protobuf:"bytes,1,opt,name=Address,proto3" json:"Address,omitempty"`
-	PublicKey            []byte              `protobuf:"bytes,2,opt,name=PublicKey,proto3" json:"PublicKey,omitempty"`
-	Amount               uint64              `protobuf:"varint,3,opt,name=Amount,proto3" json:"Amount,omitempty"`
-	Name                 string              `protobuf:"bytes,4,opt,name=Name,proto3" json:"Name,omitempty"`
-	Permissions          *AccountPermissions `protobuf:"bytes,5,opt,name=Permissions,proto3" json:"Permissions,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}            `json:"-"`
-	XXX_unrecognized     []byte              `json:"-"`
-	XXX_sizecache        int32               `json:"-"`
-}
-
-func (m *GenesisDoc_GenesisAccount) Reset()         { *m = GenesisDoc_GenesisAccount{} }
-func (m *GenesisDoc_GenesisAccount) String() string { return proto.CompactTextString(m) }
-func (*GenesisDoc_GenesisAccount) ProtoMessage()    {}
-func (*GenesisDoc_GenesisAccount) Descriptor() ([]byte, []int) {
-	return fileDescriptor_blockchain_8510b9aa600a1d3c, []int{8, 0}
-}
-func (m *GenesisDoc_GenesisAccount) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_GenesisDoc_GenesisAccount.Unmarshal(m, b)
-}
-func (m *GenesisDoc_GenesisAccount) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_GenesisDoc_GenesisAccount.Marshal(b, m, deterministic)
-}
-func (dst *GenesisDoc_GenesisAccount) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_GenesisDoc_GenesisAccount.Merge(dst, src)
-}
-func (m *GenesisDoc_GenesisAccount) XXX_Size() int {
-	return xxx_messageInfo_GenesisDoc_GenesisAccount.Size(m)
-}
-func (m *GenesisDoc_GenesisAccount) XXX_DiscardUnknown() {
-	xxx_messageInfo_GenesisDoc_GenesisAccount.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_GenesisDoc_GenesisAccount proto.InternalMessageInfo
-
-func (m *GenesisDoc_GenesisAccount) GetAddress() []byte {
-	if m != nil {
-		return m.Address
-	}
-	return nil
-}
-
-func (m *GenesisDoc_GenesisAccount) GetPublicKey() []byte {
-	if m != nil {
-		return m.PublicKey
-	}
-	return nil
-}
-
-func (m *GenesisDoc_GenesisAccount) GetAmount() uint64 {
-	if m != nil {
-		return m.Amount
-	}
-	return 0
-}
-
-func (m *GenesisDoc_GenesisAccount) GetName() string {
-	if m != nil {
-		return m.Name
-	}
-	return ""
-}
-
-func (m *GenesisDoc_GenesisAccount) GetPermissions() *AccountPermissions {
-	if m != nil {
-		return m.Permissions
-	}
-	return nil
-}
-
-type GenesisDoc_GenesisValidator struct {
-	Address              []byte   `protobuf:"bytes,1,opt,name=Address,proto3" json:"Address,omitempty"`
-	PublicKey            []byte   `protobuf:"bytes,2,opt,name=PublicKey,proto3" json:"PublicKey,omitempty"`
-	Amount               uint64   `protobuf:"varint,3,opt,name=Amount,proto3" json:"Amount,omitempty"`
-	Name                 string   `protobuf:"bytes,4,opt,name=Name,proto3" json:"Name,omitempty"`
-	UnbondTo             [][]byte `protobuf:"bytes,5,rep,name=UnbondTo,proto3" json:"UnbondTo,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *GenesisDoc_GenesisValidator) Reset()         { *m = GenesisDoc_GenesisValidator{} }
-func (m *GenesisDoc_GenesisValidator) String() string { return proto.CompactTextString(m) }
-func (*GenesisDoc_GenesisValidator) ProtoMessage()    {}
-func (*GenesisDoc_GenesisValidator) Descriptor() ([]byte, []int) {
-	return fileDescriptor_blockchain_8510b9aa600a1d3c, []int{8, 1}
-}
-func (m *GenesisDoc_GenesisValidator) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_GenesisDoc_GenesisValidator.Unmarshal(m, b)
-}
-func (m *GenesisDoc_GenesisValidator) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_GenesisDoc_GenesisValidator.Marshal(b, m, deterministic)
-}
-func (dst *GenesisDoc_GenesisValidator) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_GenesisDoc_GenesisValidator.Merge(dst, src)
-}
-func (m *GenesisDoc_GenesisValidator) XXX_Size() int {
-	return xxx_messageInfo_GenesisDoc_GenesisValidator.Size(m)
-}
-func (m *GenesisDoc_GenesisValidator) XXX_DiscardUnknown() {
-	xxx_messageInfo_GenesisDoc_GenesisValidator.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_GenesisDoc_GenesisValidator proto.InternalMessageInfo
-
-func (m *GenesisDoc_GenesisValidator) GetAddress() []byte {
-	if m != nil {
-		return m.Address
-	}
-	return nil
-}
-
-func (m *GenesisDoc_GenesisValidator) GetPublicKey() []byte {
-	if m != nil {
-		return m.PublicKey
-	}
-	return nil
-}
-
-func (m *GenesisDoc_GenesisValidator) GetAmount() uint64 {
-	if m != nil {
-		return m.Amount
-	}
-	return 0
-}
-
-func (m *GenesisDoc_GenesisValidator) GetName() string {
-	if m != nil {
-		return m.Name
-	}
-	return ""
-}
-
-func (m *GenesisDoc_GenesisValidator) GetUnbondTo() [][]byte {
-	if m != nil {
-		return m.UnbondTo
-	}
-	return nil
-}
-
-type UnconfirmedTxList struct {
-	NumTxs               uint64   `protobuf:"varint,1,opt,name=NumTxs,proto3" json:"NumTxs,omitempty"`
-	Txs                  [][]byte `protobuf:"bytes,2,rep,name=Txs,proto3" json:"Txs,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *UnconfirmedTxList) Reset()         { *m = UnconfirmedTxList{} }
-func (m *UnconfirmedTxList) String() string { return proto.CompactTextString(m) }
-func (*UnconfirmedTxList) ProtoMessage()    {}
-func (*UnconfirmedTxList) Descriptor() ([]byte, []int) {
-	return fileDescriptor_blockchain_8510b9aa600a1d3c, []int{9}
-}
-func (m *UnconfirmedTxList) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_UnconfirmedTxList.Unmarshal(m, b)
-}
-func (m *UnconfirmedTxList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_UnconfirmedTxList.Marshal(b, m, deterministic)
-}
-func (dst *UnconfirmedTxList) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_UnconfirmedTxList.Merge(dst, src)
-}
-func (m *UnconfirmedTxList) XXX_Size() int {
-	return xxx_messageInfo_UnconfirmedTxList.Size(m)
-}
-func (m *UnconfirmedTxList) XXX_DiscardUnknown() {
-	xxx_messageInfo_UnconfirmedTxList.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_UnconfirmedTxList proto.InternalMessageInfo
-
-func (m *UnconfirmedTxList) GetNumTxs() uint64 {
-	if m != nil {
-		return m.NumTxs
-	}
-	return 0
-}
-
-func (m *UnconfirmedTxList) GetTxs() [][]byte {
-	if m != nil {
-		return m.Txs
-	}
-	return nil
-}
-
-type Status struct {
-	NodeInfo             *NodeInfo `protobuf:"bytes,1,opt,name=NodeInfo,proto3" json:"NodeInfo,omitempty"`
-	GenesisHash          []byte    `protobuf:"bytes,2,opt,name=GenesisHash,proto3" json:"GenesisHash,omitempty"`
-	PublicKey            []byte    `protobuf:"bytes,3,opt,name=PublicKey,proto3" json:"PublicKey,omitempty"`
-	LatestBlockHash      []byte    `protobuf:"bytes,4,opt,name=LatestBlockHash,proto3" json:"LatestBlockHash,omitempty"`
-	LatestBlockHeight    uint64    `protobuf:"varint,5,opt,name=LatestBlockHeight,proto3" json:"LatestBlockHeight,omitempty"`
-	LatestBlockTime      int64     `protobuf:"varint,6,opt,name=LatestBlockTime,proto3" json:"LatestBlockTime,omitempty"`
-	NodeVersion          string    `protobuf:"bytes,7,opt,name=NodeVersion,proto3" json:"NodeVersion,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}  `json:"-"`
-	XXX_unrecognized     []byte    `json:"-"`
-	XXX_sizecache        int32     `json:"-"`
-}
-
-func (m *Status) Reset()         { *m = Status{} }
-func (m *Status) String() string { return proto.CompactTextString(m) }
-func (*Status) ProtoMessage()    {}
-func (*Status) Descriptor() ([]byte, []int) {
-	return fileDescriptor_blockchain_8510b9aa600a1d3c, []int{10}
-}
-func (m *Status) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_Status.Unmarshal(m, b)
-}
-func (m *Status) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_Status.Marshal(b, m, deterministic)
-}
-func (dst *Status) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_Status.Merge(dst, src)
-}
-func (m *Status) XXX_Size() int {
-	return xxx_messageInfo_Status.Size(m)
-}
-func (m *Status) XXX_DiscardUnknown() {
-	xxx_messageInfo_Status.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Status proto.InternalMessageInfo
-
-func (m *Status) GetNodeInfo() *NodeInfo {
-	if m != nil {
-		return m.NodeInfo
-	}
-	return nil
-}
-
-func (m *Status) GetGenesisHash() []byte {
-	if m != nil {
-		return m.GenesisHash
-	}
-	return nil
-}
-
-func (m *Status) GetPublicKey() []byte {
-	if m != nil {
-		return m.PublicKey
-	}
-	return nil
-}
-
-func (m *Status) GetLatestBlockHash() []byte {
-	if m != nil {
-		return m.LatestBlockHash
-	}
-	return nil
-}
-
-func (m *Status) GetLatestBlockHeight() uint64 {
-	if m != nil {
-		return m.LatestBlockHeight
-	}
-	return 0
-}
-
-func (m *Status) GetLatestBlockTime() int64 {
-	if m != nil {
-		return m.LatestBlockTime
-	}
-	return 0
-}
-
-func (m *Status) GetNodeVersion() string {
-	if m != nil {
-		return m.NodeVersion
-	}
-	return ""
-}
-
-// These are used for get consensus state. There is a lot of information that could be included
-// We should decided what the minimum we want inccluded is.
-type RoundState struct {
-	Height               int64    `protobuf:"varint,1,opt,name=Height,proto3" json:"Height,omitempty"`
-	Round                int64    `protobuf:"varint,2,opt,name=Round,proto3" json:"Round,omitempty"`
-	Step                 int64    `protobuf:"varint,3,opt,name=Step,proto3" json:"Step,omitempty"`
-	StartTime            uint64   `protobuf:"varint,4,opt,name=StartTime,proto3" json:"StartTime,omitempty"`
-	CommitTime           uint64   `protobuf:"varint,5,opt,name=CommitTime,proto3" json:"CommitTime,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *RoundState) Reset()         { *m = RoundState{} }
-func (m *RoundState) String() string { return proto.CompactTextString(m) }
-func (*RoundState) ProtoMessage()    {}
-func (*RoundState) Descriptor() ([]byte, []int) {
-	return fileDescriptor_blockchain_8510b9aa600a1d3c, []int{11}
-}
-func (m *RoundState) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_RoundState.Unmarshal(m, b)
-}
-func (m *RoundState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_RoundState.Marshal(b, m, deterministic)
-}
-func (dst *RoundState) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_RoundState.Merge(dst, src)
-}
-func (m *RoundState) XXX_Size() int {
-	return xxx_messageInfo_RoundState.Size(m)
-}
-func (m *RoundState) XXX_DiscardUnknown() {
-	xxx_messageInfo_RoundState.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_RoundState proto.InternalMessageInfo
-
-func (m *RoundState) GetHeight() int64 {
-	if m != nil {
-		return m.Height
-	}
-	return 0
-}
-
-func (m *RoundState) GetRound() int64 {
-	if m != nil {
-		return m.Round
-	}
-	return 0
-}
-
-func (m *RoundState) GetStep() int64 {
-	if m != nil {
-		return m.Step
-	}
-	return 0
-}
-
-func (m *RoundState) GetStartTime() uint64 {
-	if m != nil {
-		return m.StartTime
-	}
-	return 0
-}
-
-func (m *RoundState) GetCommitTime() uint64 {
-	if m != nil {
-		return m.CommitTime
-	}
-	return 0
-}
-
-type PeerRoundState struct {
-	Height               int64    `protobuf:"varint,1,opt,name=Height,proto3" json:"Height,omitempty"`
-	Round                int64    `protobuf:"varint,2,opt,name=Round,proto3" json:"Round,omitempty"`
-	Step                 int64    `protobuf:"varint,3,opt,name=Step,proto3" json:"Step,omitempty"`
-	StartTime            uint64   `protobuf:"varint,4,opt,name=StartTime,proto3" json:"StartTime,omitempty"`
-	Proposal             bool     `protobuf:"varint,5,opt,name=Proposal,proto3" json:"Proposal,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *PeerRoundState) Reset()         { *m = PeerRoundState{} }
-func (m *PeerRoundState) String() string { return proto.CompactTextString(m) }
-func (*PeerRoundState) ProtoMessage()    {}
-func (*PeerRoundState) Descriptor() ([]byte, []int) {
-	return fileDescriptor_blockchain_8510b9aa600a1d3c, []int{12}
-}
-func (m *PeerRoundState) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_PeerRoundState.Unmarshal(m, b)
-}
-func (m *PeerRoundState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_PeerRoundState.Marshal(b, m, deterministic)
-}
-func (dst *PeerRoundState) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_PeerRoundState.Merge(dst, src)
-}
-func (m *PeerRoundState) XXX_Size() int {
-	return xxx_messageInfo_PeerRoundState.Size(m)
-}
-func (m *PeerRoundState) XXX_DiscardUnknown() {
-	xxx_messageInfo_PeerRoundState.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_PeerRoundState proto.InternalMessageInfo
-
-func (m *PeerRoundState) GetHeight() int64 {
-	if m != nil {
-		return m.Height
-	}
-	return 0
-}
-
-func (m *PeerRoundState) GetRound() int64 {
-	if m != nil {
-		return m.Round
-	}
-	return 0
-}
-
-func (m *PeerRoundState) GetStep() int64 {
-	if m != nil {
-		return m.Step
-	}
-	return 0
-}
-
-func (m *PeerRoundState) GetStartTime() uint64 {
-	if m != nil {
-		return m.StartTime
-	}
-	return 0
-}
-
-func (m *PeerRoundState) GetProposal() bool {
-	if m != nil {
-		return m.Proposal
-	}
-	return false
-}
-
-type ConsensusState struct {
-	RoundState           *RoundState       `protobuf:"bytes,1,opt,name=RoundState,proto3" json:"RoundState,omitempty"`
-	PeerRoundStates      []*PeerRoundState `protobuf:"bytes,2,rep,name=PeerRoundStates,proto3" json:"PeerRoundStates,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}          `json:"-"`
-	XXX_unrecognized     []byte            `json:"-"`
-	XXX_sizecache        int32             `json:"-"`
-}
-
-func (m *ConsensusState) Reset()         { *m = ConsensusState{} }
-func (m *ConsensusState) String() string { return proto.CompactTextString(m) }
-func (*ConsensusState) ProtoMessage()    {}
-func (*ConsensusState) Descriptor() ([]byte, []int) {
-	return fileDescriptor_blockchain_8510b9aa600a1d3c, []int{13}
-}
-func (m *ConsensusState) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_ConsensusState.Unmarshal(m, b)
-}
-func (m *ConsensusState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_ConsensusState.Marshal(b, m, deterministic)
-}
-func (dst *ConsensusState) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_ConsensusState.Merge(dst, src)
-}
-func (m *ConsensusState) XXX_Size() int {
-	return xxx_messageInfo_ConsensusState.Size(m)
-}
-func (m *ConsensusState) XXX_DiscardUnknown() {
-	xxx_messageInfo_ConsensusState.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_ConsensusState proto.InternalMessageInfo
-
-func (m *ConsensusState) GetRoundState() *RoundState {
-	if m != nil {
-		return m.RoundState
-	}
-	return nil
-}
-
-func (m *ConsensusState) GetPeerRoundStates() []*PeerRoundState {
-	if m != nil {
-		return m.PeerRoundStates
-	}
-	return nil
-}
-
-func init() {
-	proto.RegisterType((*HeightParam)(nil), "HeightParam")
-	proto.RegisterType((*BlocksParam)(nil), "BlocksParam")
-	proto.RegisterType((*Header)(nil), "Header")
-	proto.RegisterType((*Data)(nil), "Data")
-	proto.RegisterType((*Block)(nil), "Block")
-	proto.RegisterType((*BlockMeta)(nil), "BlockMeta")
-	proto.RegisterType((*BlockList)(nil), "BlockList")
-	proto.RegisterType((*ChainId)(nil), "ChainId")
-	proto.RegisterType((*GenesisDoc)(nil), "GenesisDoc")
-	proto.RegisterType((*GenesisDoc_GenesisAccount)(nil), "GenesisDoc.GenesisAccount")
-	proto.RegisterType((*GenesisDoc_GenesisValidator)(nil), "GenesisDoc.GenesisValidator")
-	proto.RegisterType((*UnconfirmedTxList)(nil), "UnconfirmedTxList")
-	proto.RegisterType((*Status)(nil), "Status")
-	proto.RegisterType((*RoundState)(nil), "RoundState")
-	proto.RegisterType((*PeerRoundState)(nil), "PeerRoundState")
-	proto.RegisterType((*ConsensusState)(nil), "ConsensusState")
-}
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ context.Context
-var _ grpc.ClientConn
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the grpc package it is being compiled against.
-const _ = grpc.SupportPackageIsVersion4
-
-// BlockchainClient is the client API for Blockchain service.
-//
-// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
-type BlockchainClient interface {
-	GetBlock(ctx context.Context, in *HeightParam, opts ...grpc.CallOption) (*Block, error)
-	GetBlocks(ctx context.Context, in *BlocksParam, opts ...grpc.CallOption) (*BlockList, error)
-	GetBlockchainInfo(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Status, error)
-	GetChainId(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ChainId, error)
-	GetGenesis(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GenesisDoc, error)
-	GetLatestBlock(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Block, error)
-	GetUnconfirmedTxs(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*UnconfirmedTxList, error)
-	GetConsensusState(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ConsensusState, error)
-}
-
-type blockchainClient struct {
-	cc *grpc.ClientConn
-}
-
-func NewBlockchainClient(cc *grpc.ClientConn) BlockchainClient {
-	return &blockchainClient{cc}
-}
-
-func (c *blockchainClient) GetBlock(ctx context.Context, in *HeightParam, opts ...grpc.CallOption) (*Block, error) {
-	out := new(Block)
-	err := c.cc.Invoke(ctx, "/Blockchain/GetBlock", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *blockchainClient) GetBlocks(ctx context.Context, in *BlocksParam, opts ...grpc.CallOption) (*BlockList, error) {
-	out := new(BlockList)
-	err := c.cc.Invoke(ctx, "/Blockchain/GetBlocks", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *blockchainClient) GetBlockchainInfo(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Status, error) {
-	out := new(Status)
-	err := c.cc.Invoke(ctx, "/Blockchain/GetBlockchainInfo", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *blockchainClient) GetChainId(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ChainId, error) {
-	out := new(ChainId)
-	err := c.cc.Invoke(ctx, "/Blockchain/GetChainId", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *blockchainClient) GetGenesis(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GenesisDoc, error) {
-	out := new(GenesisDoc)
-	err := c.cc.Invoke(ctx, "/Blockchain/GetGenesis", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *blockchainClient) GetLatestBlock(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Block, error) {
-	out := new(Block)
-	err := c.cc.Invoke(ctx, "/Blockchain/GetLatestBlock", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *blockchainClient) GetUnconfirmedTxs(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*UnconfirmedTxList, error) {
-	out := new(UnconfirmedTxList)
-	err := c.cc.Invoke(ctx, "/Blockchain/GetUnconfirmedTxs", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *blockchainClient) GetConsensusState(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ConsensusState, error) {
-	out := new(ConsensusState)
-	err := c.cc.Invoke(ctx, "/Blockchain/GetConsensusState", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-// BlockchainServer is the server API for Blockchain service.
-type BlockchainServer interface {
-	GetBlock(context.Context, *HeightParam) (*Block, error)
-	GetBlocks(context.Context, *BlocksParam) (*BlockList, error)
-	GetBlockchainInfo(context.Context, *Empty) (*Status, error)
-	GetChainId(context.Context, *Empty) (*ChainId, error)
-	GetGenesis(context.Context, *Empty) (*GenesisDoc, error)
-	GetLatestBlock(context.Context, *Empty) (*Block, error)
-	GetUnconfirmedTxs(context.Context, *Empty) (*UnconfirmedTxList, error)
-	GetConsensusState(context.Context, *Empty) (*ConsensusState, error)
-}
-
-func RegisterBlockchainServer(s *grpc.Server, srv BlockchainServer) {
-	s.RegisterService(&_Blockchain_serviceDesc, srv)
-}
-
-func _Blockchain_GetBlock_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(HeightParam)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(BlockchainServer).GetBlock(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/Blockchain/GetBlock",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(BlockchainServer).GetBlock(ctx, req.(*HeightParam))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Blockchain_GetBlocks_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(BlocksParam)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(BlockchainServer).GetBlocks(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/Blockchain/GetBlocks",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(BlockchainServer).GetBlocks(ctx, req.(*BlocksParam))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Blockchain_GetBlockchainInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(Empty)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(BlockchainServer).GetBlockchainInfo(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/Blockchain/GetBlockchainInfo",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(BlockchainServer).GetBlockchainInfo(ctx, req.(*Empty))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Blockchain_GetChainId_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(Empty)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(BlockchainServer).GetChainId(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/Blockchain/GetChainId",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(BlockchainServer).GetChainId(ctx, req.(*Empty))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Blockchain_GetGenesis_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(Empty)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(BlockchainServer).GetGenesis(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/Blockchain/GetGenesis",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(BlockchainServer).GetGenesis(ctx, req.(*Empty))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Blockchain_GetLatestBlock_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(Empty)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(BlockchainServer).GetLatestBlock(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/Blockchain/GetLatestBlock",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(BlockchainServer).GetLatestBlock(ctx, req.(*Empty))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Blockchain_GetUnconfirmedTxs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(Empty)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(BlockchainServer).GetUnconfirmedTxs(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/Blockchain/GetUnconfirmedTxs",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(BlockchainServer).GetUnconfirmedTxs(ctx, req.(*Empty))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Blockchain_GetConsensusState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(Empty)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(BlockchainServer).GetConsensusState(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/Blockchain/GetConsensusState",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(BlockchainServer).GetConsensusState(ctx, req.(*Empty))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-var _Blockchain_serviceDesc = grpc.ServiceDesc{
-	ServiceName: "Blockchain",
-	HandlerType: (*BlockchainServer)(nil),
-	Methods: []grpc.MethodDesc{
-		{
-			MethodName: "GetBlock",
-			Handler:    _Blockchain_GetBlock_Handler,
-		},
-		{
-			MethodName: "GetBlocks",
-			Handler:    _Blockchain_GetBlocks_Handler,
-		},
-		{
-			MethodName: "GetBlockchainInfo",
-			Handler:    _Blockchain_GetBlockchainInfo_Handler,
-		},
-		{
-			MethodName: "GetChainId",
-			Handler:    _Blockchain_GetChainId_Handler,
-		},
-		{
-			MethodName: "GetGenesis",
-			Handler:    _Blockchain_GetGenesis_Handler,
-		},
-		{
-			MethodName: "GetLatestBlock",
-			Handler:    _Blockchain_GetLatestBlock_Handler,
-		},
-		{
-			MethodName: "GetUnconfirmedTxs",
-			Handler:    _Blockchain_GetUnconfirmedTxs_Handler,
-		},
-		{
-			MethodName: "GetConsensusState",
-			Handler:    _Blockchain_GetConsensusState_Handler,
-		},
-	},
-	Streams:  []grpc.StreamDesc{},
-	Metadata: "rpc/burrow/blockchain.proto",
-}
-
-func init() {
-	proto.RegisterFile("rpc/burrow/blockchain.proto", fileDescriptor_blockchain_8510b9aa600a1d3c)
-}
-
-var fileDescriptor_blockchain_8510b9aa600a1d3c = []byte{
-	// 974 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0x51, 0x6f, 0xdc, 0x44,
-	0x10, 0xd6, 0xdd, 0xf9, 0x1c, 0xdf, 0x38, 0x4a, 0x9a, 0x05, 0x81, 0x31, 0x55, 0x39, 0x2c, 0x82,
-	0x22, 0x88, 0x1c, 0x29, 0x08, 0x24, 0x24, 0x78, 0x48, 0x13, 0x48, 0x22, 0x42, 0x14, 0x6d, 0xd2,
-	0x22, 0x21, 0xf1, 0xb0, 0x67, 0x6f, 0x39, 0xab, 0x67, 0xef, 0xc9, 0xde, 0x53, 0xd3, 0xff, 0x80,
-	0x78, 0x80, 0x9f, 0xc1, 0x8f, 0xe0, 0x91, 0xbf, 0x85, 0x76, 0x76, 0xd7, 0x5e, 0x3b, 0x7d, 0xab,
-	0xd4, 0xb7, 0x9d, 0x6f, 0xbe, 0x1d, 0xcf, 0x8c, 0xbf, 0x19, 0x1b, 0x3e, 0xae, 0xd7, 0xd9, 0xd1,
-	0x62, 0x53, 0xd7, 0xe2, 0xd5, 0xd1, 0x62, 0x25, 0xb2, 0x97, 0xd9, 0x92, 0x15, 0x55, 0xba, 0xae,
-	0x85, 0x14, 0xf1, 0x87, 0x8e, 0x33, 0x13, 0x65, 0x29, 0xac, 0x23, 0x72, 0x1c, 0x2c, 0xcb, 0xc4,
-	0xa6, 0x92, 0x6f, 0xf0, 0x54, 0x5c, 0xbe, 0x12, 0xf5, 0x4b, 0xed, 0x49, 0xf6, 0x21, 0xbc, 0xe0,
-	0xc5, 0xef, 0x4b, 0x79, 0xc3, 0x6a, 0x56, 0x92, 0x0f, 0xc0, 0x5f, 0xa2, 0x19, 0x8d, 0xe6, 0xa3,
-	0x03, 0x8f, 0x1a, 0x2b, 0xb9, 0x84, 0xf0, 0xa9, 0xca, 0xa3, 0xd1, 0xb4, 0xc7, 0x30, 0x2b, 0x8b,
-	0xea, 0xc2, 0x65, 0x76, 0x00, 0x7a, 0xd9, 0xbd, 0xf1, 0x8e, 0x8d, 0xd7, 0x02, 0xc9, 0x9f, 0x63,
-	0xf0, 0x2f, 0x38, 0xcb, 0x79, 0x4d, 0x22, 0xd8, 0x3a, 0x55, 0x85, 0x5d, 0x9e, 0x61, 0x90, 0x19,
-	0xb5, 0xa6, 0xca, 0xc3, 0xb9, 0x3f, 0xa1, 0xc6, 0x22, 0x04, 0xbc, 0xbb, 0xa2, 0xe4, 0xd1, 0x04,
-	0x51, 0x3c, 0x2b, 0xee, 0xf5, 0xa6, 0xbc, 0xbb, 0x6f, 0x22, 0x4f, 0x73, 0xb5, 0x45, 0xe6, 0x10,
-	0x5e, 0xb1, 0x46, 0x62, 0xde, 0x97, 0x67, 0xd1, 0x74, 0x3e, 0x3a, 0xd8, 0xa6, 0x2e, 0x44, 0x3e,
-	0x87, 0x1d, 0x65, 0x9e, 0x8a, 0xb2, 0x2c, 0xe4, 0x05, 0x6b, 0x96, 0x91, 0x8f, 0xa4, 0x01, 0x4a,
-	0x62, 0x08, 0xce, 0x98, 0x64, 0xc8, 0xd8, 0x42, 0x46, 0x6b, 0xab, 0x18, 0xcf, 0xd9, 0xaa, 0xc8,
-	0x99, 0x14, 0x75, 0x83, 0x8c, 0x40, 0xc7, 0xe8, 0xa3, 0xaa, 0xd6, 0x93, 0xf5, 0x1a, 0x09, 0x33,
-	0x24, 0x58, 0x33, 0x39, 0x04, 0x4f, 0x45, 0x23, 0x8f, 0x60, 0xa2, 0x8a, 0x18, 0xcd, 0x27, 0x07,
-	0xdb, 0x54, 0x1d, 0x55, 0xb5, 0x4b, 0x75, 0x61, 0x8c, 0x17, 0xf0, 0x9c, 0xfc, 0x06, 0x53, 0x4c,
-	0x5f, 0x05, 0xb4, 0xa5, 0x8d, 0x74, 0x40, 0x5b, 0xd6, 0x27, 0xb6, 0xc1, 0x78, 0x31, 0x3c, 0xde,
-	0x4a, 0xb5, 0x49, 0x6d, 0xdf, 0x3f, 0xd2, 0x4f, 0xc4, 0x2e, 0x86, 0xc7, 0xd3, 0x54, 0x19, 0x14,
-	0xa1, 0xe4, 0x47, 0x98, 0x61, 0x98, 0x9f, 0xb9, 0x64, 0x6f, 0xf1, 0x88, 0xe4, 0x17, 0x13, 0xe7,
-	0xaa, 0x68, 0x24, 0x79, 0x02, 0xa0, 0x3a, 0xda, 0xd3, 0x8b, 0x83, 0x90, 0x2f, 0x00, 0xda, 0x87,
-	0x36, 0xd1, 0x78, 0x3e, 0x39, 0x08, 0x8f, 0x21, 0x6d, 0x21, 0xea, 0x78, 0x93, 0xcc, 0x6a, 0x26,
-	0x57, 0x3a, 0xc3, 0xe3, 0x35, 0x2b, 0xb9, 0x11, 0x50, 0x07, 0x74, 0xe2, 0xca, 0x31, 0xc7, 0x56,
-	0x5c, 0xb9, 0x12, 0xc6, 0x39, 0xaf, 0x78, 0x53, 0xe8, 0xf7, 0x35, 0xd1, 0xc2, 0x70, 0xa0, 0xe4,
-	0x3f, 0x0f, 0xc0, 0xd8, 0x67, 0x22, 0x73, 0x2e, 0xa0, 0xf8, 0x74, 0x01, 0x2e, 0xd4, 0x4f, 0x65,
-	0x3c, 0x4c, 0x85, 0x80, 0x77, 0xcb, 0x56, 0xd2, 0x3c, 0x09, 0xcf, 0xe4, 0x10, 0xf6, 0xce, 0x57,
-	0x62, 0xc1, 0x56, 0x37, 0xbc, 0x2e, 0x8b, 0xa6, 0x29, 0x44, 0xa5, 0x05, 0xec, 0xd1, 0x87, 0x0e,
-	0xf2, 0x0d, 0x04, 0x27, 0x7a, 0xa2, 0x9b, 0x68, 0x8a, 0xfd, 0x89, 0xd3, 0x2e, 0x41, 0x7b, 0x34,
-	0x14, 0xda, 0x72, 0xc9, 0x77, 0x00, 0x9d, 0x0e, 0x23, 0x1f, 0x6f, 0x3e, 0x7e, 0xc3, 0xcd, 0x96,
-	0x44, 0x1d, 0x7e, 0xfc, 0xcf, 0x08, 0x76, 0xfa, 0xa1, 0x51, 0xc6, 0x79, 0x5e, 0xf3, 0xa6, 0xb1,
-	0x92, 0x30, 0xa6, 0x6a, 0xc1, 0xcd, 0x66, 0xb1, 0x2a, 0xb2, 0x9f, 0xf8, 0x6b, 0xa3, 0xd8, 0x0e,
-	0x50, 0x43, 0x7a, 0x52, 0xaa, 0x08, 0xd8, 0x04, 0x8f, 0x1a, 0x4b, 0xb5, 0x06, 0x7b, 0xe6, 0x61,
-	0xcf, 0xf0, 0x4c, 0xbe, 0x86, 0xd0, 0x6d, 0xca, 0x14, 0x15, 0xf6, 0x5e, 0x6a, 0x52, 0x70, 0x5c,
-	0xd4, 0xe5, 0xc5, 0x7f, 0x8d, 0xe0, 0xd1, 0xb0, 0x9c, 0x77, 0x92, 0x6f, 0x0c, 0xc1, 0xb3, 0x6a,
-	0x21, 0xaa, 0xfc, 0x4e, 0xe0, 0xcb, 0xd9, 0xa6, 0xad, 0x9d, 0x7c, 0x0f, 0x7b, 0xcf, 0xaa, 0x4c,
-	0x54, 0x2f, 0x8a, 0xba, 0xe4, 0xf9, 0xdd, 0x3d, 0xce, 0x43, 0xb7, 0xb1, 0xcc, 0x96, 0x35, 0x1b,
-	0xcb, 0x6c, 0x80, 0x71, 0xbb, 0x01, 0x92, 0xbf, 0xc7, 0xe0, 0xdf, 0x4a, 0x26, 0x37, 0x0d, 0xd9,
-	0x87, 0xe0, 0x5a, 0xe4, 0xfc, 0xb2, 0x7a, 0x21, 0xf0, 0x5a, 0x78, 0x3c, 0x4b, 0x2d, 0x40, 0x5b,
-	0xd7, 0x50, 0xdc, 0xe3, 0x07, 0xe2, 0xee, 0x17, 0x3e, 0x19, 0x16, 0x7e, 0x00, 0xbb, 0x57, 0x4c,
-	0x72, 0xb3, 0x24, 0x31, 0x86, 0x87, 0x9c, 0x21, 0xac, 0x14, 0xec, 0x42, 0x7a, 0xb8, 0xa7, 0x5a,
-	0xc1, 0x0f, 0x1c, 0x83, 0xb8, 0x38, 0x47, 0x3e, 0xae, 0xeb, 0x21, 0xac, 0x2a, 0x50, 0xd5, 0x3c,
-	0xe7, 0xb5, 0x7a, 0xaf, 0xb8, 0x70, 0x67, 0xd4, 0x85, 0x92, 0x3f, 0x46, 0x00, 0x54, 0x6c, 0xaa,
-	0x5c, 0xb5, 0x86, 0x3b, 0x1f, 0x8b, 0x51, 0xef, 0x63, 0xf1, 0x3e, 0x4c, 0x91, 0x65, 0xbe, 0x21,
-	0xda, 0xc0, 0x61, 0x94, 0x7c, 0x6d, 0x3f, 0x21, 0xea, 0xac, 0x5a, 0x72, 0x2b, 0x59, 0x2d, 0x31,
-	0x2d, 0x3d, 0x84, 0x1d, 0xa0, 0xd6, 0x97, 0xfe, 0x18, 0xa0, 0x5b, 0x57, 0xe8, 0x20, 0x2a, 0x9d,
-	0x9d, 0x1b, 0xce, 0xeb, 0x77, 0x98, 0x52, 0x0c, 0xc1, 0x4d, 0x2d, 0xd6, 0xa2, 0x61, 0x2b, 0x4c,
-	0x28, 0xa0, 0xad, 0x9d, 0xdc, 0xc3, 0xce, 0xa9, 0xa8, 0x1a, 0x5e, 0x35, 0x9b, 0x46, 0x67, 0xf3,
-	0xa5, 0xdb, 0x2e, 0x23, 0x9e, 0x30, 0xed, 0x20, 0xea, 0x76, 0xf3, 0x5b, 0xd8, 0xed, 0x17, 0x63,
-	0x37, 0xf2, 0x6e, 0xda, 0xc7, 0xe9, 0x90, 0x77, 0xfc, 0xef, 0xd8, 0x2c, 0x72, 0xfc, 0x5d, 0x21,
-	0x73, 0x08, 0xce, 0xb9, 0x7e, 0xb1, 0x64, 0x3b, 0x75, 0x7e, 0x33, 0x62, 0x5f, 0x2f, 0x77, 0xb2,
-	0x0f, 0x33, 0xcb, 0x68, 0xc8, 0x76, 0xea, 0xfc, 0x62, 0xc4, 0x66, 0xff, 0xe3, 0xbc, 0x7c, 0x06,
-	0x7b, 0x96, 0x86, 0x91, 0x51, 0xe8, 0x7e, 0xfa, 0x43, 0xb9, 0x96, 0xaf, 0xe3, 0xad, 0xd4, 0x0c,
-	0xc8, 0x13, 0xb5, 0xb3, 0xa5, 0x5d, 0xf2, 0xd6, 0x1d, 0xa4, 0x16, 0xf9, 0x14, 0xfd, 0x66, 0x12,
-	0x5a, 0x7f, 0x98, 0xf6, 0x16, 0xfd, 0xce, 0x39, 0x97, 0x8e, 0x20, 0x5b, 0x9a, 0xcd, 0xf8, 0x08,
-	0x53, 0xe9, 0x8d, 0x74, 0x17, 0x8b, 0xa4, 0x0f, 0x67, 0xfd, 0x10, 0x2f, 0x0c, 0x5e, 0x88, 0xbd,
-	0xb0, 0x9b, 0xf6, 0x1d, 0x4f, 0x83, 0x5f, 0x7d, 0xfd, 0x9b, 0xb6, 0xf0, 0xf1, 0xff, 0xec, 0xab,
-	0xff, 0x03, 0x00, 0x00, 0xff, 0xff, 0x42, 0x0e, 0xfe, 0x43, 0x0b, 0x0a, 0x00, 0x00,
-}
diff --git a/rpc/burrow/blockchain.proto b/rpc/burrow/blockchain.proto
deleted file mode 100644
index 95da46b43a2a11c3806e3c79c5d3f9105158441c..0000000000000000000000000000000000000000
--- a/rpc/burrow/blockchain.proto
+++ /dev/null
@@ -1,163 +0,0 @@
-syntax = 'proto3';
-
-option go_package = "burrow";
-
-import "rpc/burrow/common.proto";
-import "rpc/burrow/account.proto";
-import "rpc/burrow/network.proto";
-
-// Blockchain Service Definition
-service Blockchain {
-    rpc GetBlock (HeightParam) returns (Block);
-    rpc GetBlocks (BlocksParam) returns (BlockList);
-    rpc GetBlockchainInfo (Empty) returns (Status);
-    rpc GetChainId (Empty) returns (ChainId);
-    rpc GetGenesis (Empty) returns (GenesisDoc); // NI - go
-    rpc GetLatestBlock (Empty) returns (Block);
-    rpc GetUnconfirmedTxs (Empty) returns (UnconfirmedTxList);
-
-    rpc GetConsensusState (Empty) returns (ConsensusState); // WE NEED TO DISCUSS THIS ONE
-}
-
-// Params
-message HeightParam {
-    uint64 height = 1;
-}
-
-message BlocksParam {
-    uint64 minHeight = 1;
-    uint64 maxHeight = 2;
-}
-
-// Results
-message Header {
-    string ChainID = 1;
-    int64 Height = 2;
-    int64 Time = 3;
-    int64 NumTxs = 4;
-    bytes LastBlockID = 5;
-    bytes LastCommitHash = 6;
-    bytes DataHash = 7;
-    bytes ValidatorsHash = 8;
-    bytes AppHash = 9;
-}
-
-
-message Data {
-    repeated bytes Txs = 1;
-    bytes hash = 2;
-}
-
-message Block {
-    bytes BlockID = 1;
-    Header Header = 2;
-    Data Data = 3;
-}
-
-message BlockMeta {
-    bytes BlockID = 1;
-    Header Header = 2;
-}
-
-message BlockList {
-    uint64 LastHeight = 1;
-    repeated BlockMeta BlockMetas = 2;
-}
-
-message ChainId {
-    string ChainName = 1;
-    string ChainId = 2;
-    bytes GenesisHash = 3;
-}
-
-
-message GenesisDoc {
-    message GenesisAccount {
-        bytes Address = 1;
-        bytes PublicKey = 2;
-        uint64 Amount = 3;
-        string Name = 4;
-        AccountPermissions Permissions = 5;
-    }
-
-    message GenesisValidator {
-        bytes Address = 1;
-        bytes PublicKey = 2;
-        uint64 Amount = 3;
-        string Name = 4;
-        repeated bytes UnbondTo = 5;
-    }
-    uint64 GenesisTime = 1;
-    string ChainName = 2;
-    bytes Salt = 3;
-    uint64 GlobalPermissions = 4;
-    repeated GenesisAccount Accounts = 5;
-    repeated GenesisValidator Validators = 6;
-}
-
-message UnconfirmedTxList {
-    uint64 NumTxs = 1;
-    repeated bytes Txs = 2;
-}
-
-message Status {
-    NodeInfo NodeInfo = 1;
-    bytes GenesisHash = 2;
-    bytes PublicKey = 3;
-    bytes LatestBlockHash = 4;
-    uint64 LatestBlockHeight = 5;
-    int64 LatestBlockTime = 6;
-    string NodeVersion = 7;
-}
-
-// These are used for get consensus state. There is a lot of information that could be included
-// We should decided what the minimum we want inccluded is.
-message RoundState {
-    int64 Height = 1;
-    int64 Round = 2;
-    int64 Step = 3;
-    uint64 StartTime = 4;
-    uint64 CommitTime = 5;
-    /*	Validators         *types.ValidatorSet `json:"validators"`
-        Proposal           *types.Proposal     `json:"proposal"`
-        ProposalBlock      *types.Block        `json:"proposal_block"`
-        ProposalBlockParts *types.PartSet      `json:"proposal_block_parts"`
-        LockedRound        int                 `json:"locked_round"`
-        LockedBlock        *types.Block        `json:"locked_block"`
-        LockedBlockParts   *types.PartSet      `json:"locked_block_parts"`
-        ValidRound         int                 `json:"valid_round"`       // Last known round with POL for non-nil valid block.
-        ValidBlock         *types.Block        `json:"valid_block"`       // Last known block of POL mentioned above.
-        ValidBlockParts    *types.PartSet      `json:"valid_block_parts"` // Last known block parts of POL metnioned above.
-        Votes              *HeightVoteSet      `json:"votes"`
-        CommitRound        int                 `json:"commit_round"` //
-        LastCommit         *types.VoteSet      `json:"last_commit"`  // Last precommits at Height-1
-        LastValidators     *types.ValidatorSet `json:"last_validators"`*/
-}
-
-message PeerRoundState {
-    int64 Height = 1;
-    int64 Round = 2;
-    int64 Step = 3;
-    uint64 StartTime = 4;
-    bool Proposal = 5;
-    /*
-        ProposalBlockPartsHeader types.PartSetHeader `json:"proposal_block_parts_header"` //
-        ProposalBlockParts       *cmn.BitArray       `json:"proposal_block_parts"`        //
-        ProposalPOLRound         int                 `json:"proposal_pol_round"`          // Proposal's POL round. -1 if none.
-        ProposalPOL              *cmn.BitArray       `json:"proposal_pol"`                // nil until ProposalPOLMessage received.
-        Prevotes                 *cmn.BitArray       `json:"prevotes"`                    // All votes peer has for this round
-        Precommits               *cmn.BitArray       `json:"precommits"`                  // All precommits peer has for this round
-        LastCommitRound          int                 `json:"last_commit_round"`           // Round of commit for last height. -1 if none.
-        LastCommit               *cmn.BitArray       `json:"last_commit"`                 // All commit precommits of commit for last height.
-        CatchupCommitRound       int                 `json:"catchup_commit_round"`        // Round that we have commit for. Not necessarily unique. -1 if none.
-        CatchupCommit            *cmn.BitArray       `json:"catchup_commit"`              // All commit precommits peer has for this height & CatchupCommitRound
-    */
-}
-
-message ConsensusState {
-    RoundState RoundState = 1;
-    repeated PeerRoundState PeerRoundStates = 2;
-}
-
-//--------------------------------------------------
-
diff --git a/rpc/burrow/common.pb.go b/rpc/burrow/common.pb.go
deleted file mode 100644
index f866428e140ff5f3c2c2acb9985ab95ecf2b1299..0000000000000000000000000000000000000000
--- a/rpc/burrow/common.pb.go
+++ /dev/null
@@ -1,317 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// source: rpc/burrow/common.proto
-
-package burrow
-
-import proto "github.com/golang/protobuf/proto"
-import fmt "fmt"
-import math "math"
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ = proto.Marshal
-var _ = fmt.Errorf
-var _ = math.Inf
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the proto package it is being compiled against.
-// A compilation error at this line likely means your copy of the
-// proto package needs to be updated.
-const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
-
-// Common Messages
-type Empty struct {
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *Empty) Reset()         { *m = Empty{} }
-func (m *Empty) String() string { return proto.CompactTextString(m) }
-func (*Empty) ProtoMessage()    {}
-func (*Empty) Descriptor() ([]byte, []int) {
-	return fileDescriptor_common_5e5d896650e7b950, []int{0}
-}
-func (m *Empty) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_Empty.Unmarshal(m, b)
-}
-func (m *Empty) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_Empty.Marshal(b, m, deterministic)
-}
-func (dst *Empty) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_Empty.Merge(dst, src)
-}
-func (m *Empty) XXX_Size() int {
-	return xxx_messageInfo_Empty.Size(m)
-}
-func (m *Empty) XXX_DiscardUnknown() {
-	xxx_messageInfo_Empty.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Empty proto.InternalMessageInfo
-
-type InputAccount struct {
-	PrivateKey           []byte   `protobuf:"bytes,1,opt,name=privateKey,proto3" json:"privateKey,omitempty"`
-	Address              []byte   `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *InputAccount) Reset()         { *m = InputAccount{} }
-func (m *InputAccount) String() string { return proto.CompactTextString(m) }
-func (*InputAccount) ProtoMessage()    {}
-func (*InputAccount) Descriptor() ([]byte, []int) {
-	return fileDescriptor_common_5e5d896650e7b950, []int{1}
-}
-func (m *InputAccount) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_InputAccount.Unmarshal(m, b)
-}
-func (m *InputAccount) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_InputAccount.Marshal(b, m, deterministic)
-}
-func (dst *InputAccount) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_InputAccount.Merge(dst, src)
-}
-func (m *InputAccount) XXX_Size() int {
-	return xxx_messageInfo_InputAccount.Size(m)
-}
-func (m *InputAccount) XXX_DiscardUnknown() {
-	xxx_messageInfo_InputAccount.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_InputAccount proto.InternalMessageInfo
-
-func (m *InputAccount) GetPrivateKey() []byte {
-	if m != nil {
-		return m.PrivateKey
-	}
-	return nil
-}
-
-func (m *InputAccount) GetAddress() []byte {
-	if m != nil {
-		return m.Address
-	}
-	return nil
-}
-
-type FilterData struct {
-	Field                string   `protobuf:"bytes,1,opt,name=field,proto3" json:"field,omitempty"`
-	Op                   string   `protobuf:"bytes,2,opt,name=op,proto3" json:"op,omitempty"`
-	Value                string   `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *FilterData) Reset()         { *m = FilterData{} }
-func (m *FilterData) String() string { return proto.CompactTextString(m) }
-func (*FilterData) ProtoMessage()    {}
-func (*FilterData) Descriptor() ([]byte, []int) {
-	return fileDescriptor_common_5e5d896650e7b950, []int{2}
-}
-func (m *FilterData) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_FilterData.Unmarshal(m, b)
-}
-func (m *FilterData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_FilterData.Marshal(b, m, deterministic)
-}
-func (dst *FilterData) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_FilterData.Merge(dst, src)
-}
-func (m *FilterData) XXX_Size() int {
-	return xxx_messageInfo_FilterData.Size(m)
-}
-func (m *FilterData) XXX_DiscardUnknown() {
-	xxx_messageInfo_FilterData.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_FilterData proto.InternalMessageInfo
-
-func (m *FilterData) GetField() string {
-	if m != nil {
-		return m.Field
-	}
-	return ""
-}
-
-func (m *FilterData) GetOp() string {
-	if m != nil {
-		return m.Op
-	}
-	return ""
-}
-
-func (m *FilterData) GetValue() string {
-	if m != nil {
-		return m.Value
-	}
-	return ""
-}
-
-type FilterListParam struct {
-	Filters              []*FilterData `protobuf:"bytes,1,rep,name=filters,proto3" json:"filters,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}      `json:"-"`
-	XXX_unrecognized     []byte        `json:"-"`
-	XXX_sizecache        int32         `json:"-"`
-}
-
-func (m *FilterListParam) Reset()         { *m = FilterListParam{} }
-func (m *FilterListParam) String() string { return proto.CompactTextString(m) }
-func (*FilterListParam) ProtoMessage()    {}
-func (*FilterListParam) Descriptor() ([]byte, []int) {
-	return fileDescriptor_common_5e5d896650e7b950, []int{3}
-}
-func (m *FilterListParam) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_FilterListParam.Unmarshal(m, b)
-}
-func (m *FilterListParam) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_FilterListParam.Marshal(b, m, deterministic)
-}
-func (dst *FilterListParam) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_FilterListParam.Merge(dst, src)
-}
-func (m *FilterListParam) XXX_Size() int {
-	return xxx_messageInfo_FilterListParam.Size(m)
-}
-func (m *FilterListParam) XXX_DiscardUnknown() {
-	xxx_messageInfo_FilterListParam.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_FilterListParam proto.InternalMessageInfo
-
-func (m *FilterListParam) GetFilters() []*FilterData {
-	if m != nil {
-		return m.Filters
-	}
-	return nil
-}
-
-// This is here because it is required by both transactions and namereg
-// This situation can be remedied multiple ways
-type TxReceipt struct {
-	TxHash               []byte   `protobuf:"bytes,1,opt,name=TxHash,proto3" json:"TxHash,omitempty"`
-	CreatesContract      bool     `protobuf:"varint,2,opt,name=CreatesContract,proto3" json:"CreatesContract,omitempty"`
-	ContractAddress      []byte   `protobuf:"bytes,3,opt,name=ContractAddress,proto3" json:"ContractAddress,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *TxReceipt) Reset()         { *m = TxReceipt{} }
-func (m *TxReceipt) String() string { return proto.CompactTextString(m) }
-func (*TxReceipt) ProtoMessage()    {}
-func (*TxReceipt) Descriptor() ([]byte, []int) {
-	return fileDescriptor_common_5e5d896650e7b950, []int{4}
-}
-func (m *TxReceipt) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_TxReceipt.Unmarshal(m, b)
-}
-func (m *TxReceipt) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_TxReceipt.Marshal(b, m, deterministic)
-}
-func (dst *TxReceipt) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_TxReceipt.Merge(dst, src)
-}
-func (m *TxReceipt) XXX_Size() int {
-	return xxx_messageInfo_TxReceipt.Size(m)
-}
-func (m *TxReceipt) XXX_DiscardUnknown() {
-	xxx_messageInfo_TxReceipt.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_TxReceipt proto.InternalMessageInfo
-
-func (m *TxReceipt) GetTxHash() []byte {
-	if m != nil {
-		return m.TxHash
-	}
-	return nil
-}
-
-func (m *TxReceipt) GetCreatesContract() bool {
-	if m != nil {
-		return m.CreatesContract
-	}
-	return false
-}
-
-func (m *TxReceipt) GetContractAddress() []byte {
-	if m != nil {
-		return m.ContractAddress
-	}
-	return nil
-}
-
-// This is here because it is used in both the Account Service (GenPrivAccount)
-// And in the transaction service (SignTx)
-type PrivateAccount struct {
-	PrivateKey           []byte   `protobuf:"bytes,1,opt,name=PrivateKey,proto3" json:"PrivateKey,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *PrivateAccount) Reset()         { *m = PrivateAccount{} }
-func (m *PrivateAccount) String() string { return proto.CompactTextString(m) }
-func (*PrivateAccount) ProtoMessage()    {}
-func (*PrivateAccount) Descriptor() ([]byte, []int) {
-	return fileDescriptor_common_5e5d896650e7b950, []int{5}
-}
-func (m *PrivateAccount) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_PrivateAccount.Unmarshal(m, b)
-}
-func (m *PrivateAccount) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_PrivateAccount.Marshal(b, m, deterministic)
-}
-func (dst *PrivateAccount) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_PrivateAccount.Merge(dst, src)
-}
-func (m *PrivateAccount) XXX_Size() int {
-	return xxx_messageInfo_PrivateAccount.Size(m)
-}
-func (m *PrivateAccount) XXX_DiscardUnknown() {
-	xxx_messageInfo_PrivateAccount.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_PrivateAccount proto.InternalMessageInfo
-
-func (m *PrivateAccount) GetPrivateKey() []byte {
-	if m != nil {
-		return m.PrivateKey
-	}
-	return nil
-}
-
-func init() {
-	proto.RegisterType((*Empty)(nil), "Empty")
-	proto.RegisterType((*InputAccount)(nil), "InputAccount")
-	proto.RegisterType((*FilterData)(nil), "FilterData")
-	proto.RegisterType((*FilterListParam)(nil), "FilterListParam")
-	proto.RegisterType((*TxReceipt)(nil), "TxReceipt")
-	proto.RegisterType((*PrivateAccount)(nil), "PrivateAccount")
-}
-
-func init() { proto.RegisterFile("rpc/burrow/common.proto", fileDescriptor_common_5e5d896650e7b950) }
-
-var fileDescriptor_common_5e5d896650e7b950 = []byte{
-	// 284 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x91, 0xbf, 0x6b, 0xfb, 0x30,
-	0x10, 0xc5, 0xb1, 0x4d, 0xec, 0xf8, 0x12, 0x12, 0x10, 0x5f, 0xbe, 0xf5, 0x54, 0x82, 0xa0, 0xe0,
-	0x29, 0x29, 0xed, 0xd2, 0x35, 0x4d, 0x5b, 0x5c, 0xda, 0xc1, 0x88, 0x4c, 0xdd, 0x14, 0x59, 0xa1,
-	0x06, 0xdb, 0x12, 0xd2, 0x39, 0x3f, 0xfe, 0xfb, 0x52, 0xd9, 0x21, 0x21, 0xdd, 0xf4, 0x3e, 0x77,
-	0x7a, 0xd2, 0xbd, 0x83, 0x1b, 0xa3, 0xc5, 0x62, 0xd3, 0x1a, 0xa3, 0xf6, 0x0b, 0xa1, 0xea, 0x5a,
-	0x35, 0x73, 0x6d, 0x14, 0x2a, 0x1a, 0xc1, 0xe0, 0xb5, 0xd6, 0x78, 0xa4, 0x19, 0x8c, 0xdf, 0x1b,
-	0xdd, 0xe2, 0x52, 0x08, 0xd5, 0x36, 0x48, 0x6e, 0x01, 0xb4, 0x29, 0x77, 0x1c, 0xe5, 0x87, 0x3c,
-	0x26, 0xde, 0xcc, 0x4b, 0xc7, 0xec, 0x82, 0x90, 0x04, 0x22, 0x5e, 0x14, 0x46, 0x5a, 0x9b, 0xf8,
-	0xae, 0x78, 0x92, 0x34, 0x03, 0x78, 0x2b, 0x2b, 0x94, 0xe6, 0x85, 0x23, 0x27, 0xff, 0x60, 0xb0,
-	0x2d, 0x65, 0x55, 0x38, 0x8b, 0x98, 0x75, 0x82, 0x4c, 0xc0, 0x57, 0xda, 0x5d, 0x8c, 0x99, 0xaf,
-	0xf4, 0x6f, 0xd7, 0x8e, 0x57, 0xad, 0x4c, 0x82, 0xae, 0xcb, 0x09, 0xfa, 0x04, 0xd3, 0xce, 0xe9,
-	0xb3, 0xb4, 0x98, 0x73, 0xc3, 0x6b, 0x72, 0x07, 0xd1, 0xd6, 0x21, 0x9b, 0x78, 0xb3, 0x20, 0x1d,
-	0x3d, 0x8c, 0xe6, 0xe7, 0xc7, 0xd8, 0xa9, 0x46, 0xf7, 0x10, 0xaf, 0x0f, 0x4c, 0x0a, 0x59, 0x6a,
-	0x24, 0xff, 0x21, 0x5c, 0x1f, 0x32, 0x6e, 0xbf, 0xfb, 0x31, 0x7a, 0x45, 0x52, 0x98, 0xae, 0x8c,
-	0xe4, 0x28, 0xed, 0x4a, 0x35, 0x68, 0xb8, 0x40, 0xf7, 0xa3, 0x21, 0xbb, 0xc6, 0xae, 0xb3, 0x3f,
-	0x2f, 0xfb, 0xa1, 0x03, 0x67, 0x75, 0x8d, 0xe9, 0x3d, 0x4c, 0xf2, 0x2e, 0xa4, 0x8b, 0x20, 0xf3,
-	0x3f, 0x41, 0x9e, 0xc9, 0xf3, 0xf0, 0x2b, 0xec, 0x16, 0xb3, 0x09, 0xdd, 0x4a, 0x1e, 0x7f, 0x02,
-	0x00, 0x00, 0xff, 0xff, 0x98, 0x63, 0x0b, 0xe0, 0xad, 0x01, 0x00, 0x00,
-}
diff --git a/rpc/burrow/common.proto b/rpc/burrow/common.proto
deleted file mode 100644
index ac54e03261afb733445f573b908bed35e950ce0c..0000000000000000000000000000000000000000
--- a/rpc/burrow/common.proto
+++ /dev/null
@@ -1,38 +0,0 @@
-syntax = 'proto3';
-
-option go_package = "burrow";
-
-// Common Messages
-message Empty {
-
-}
-
-message InputAccount {
-    bytes privateKey = 1;
-    bytes address = 2;
-}
-
-message FilterData {
-    string field = 1;
-    string op = 2;
-    string value = 3;
-}
-
-message FilterListParam {
-    repeated FilterData filters = 1;
-}
-
-// This is here because it is required by both transactions and namereg
-// This situation can be remedied multiple ways 
-message TxReceipt {
-    bytes TxHash = 1;
-    bool CreatesContract = 2;
-    bytes ContractAddress = 3;
-}
-
-// This is here because it is used in both the Account Service (GenPrivAccount)
-// And in the transaction service (SignTx)
-message PrivateAccount {
-    bytes PrivateKey = 1;
-}
-
diff --git a/rpc/burrow/namereg.pb.go b/rpc/burrow/namereg.pb.go
deleted file mode 100644
index 35da753e0137ee12ffd8de452ad7600fbf22c81b..0000000000000000000000000000000000000000
--- a/rpc/burrow/namereg.pb.go
+++ /dev/null
@@ -1,451 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// source: rpc/burrow/namereg.proto
-
-package burrow
-
-import proto "github.com/golang/protobuf/proto"
-import fmt "fmt"
-import math "math"
-
-import (
-	context "golang.org/x/net/context"
-	grpc "google.golang.org/grpc"
-)
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ = proto.Marshal
-var _ = fmt.Errorf
-var _ = math.Inf
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the proto package it is being compiled against.
-// A compilation error at this line likely means your copy of the
-// proto package needs to be updated.
-const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
-
-// Params
-type NameRegEntryParam struct {
-	Name                 string   `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *NameRegEntryParam) Reset()         { *m = NameRegEntryParam{} }
-func (m *NameRegEntryParam) String() string { return proto.CompactTextString(m) }
-func (*NameRegEntryParam) ProtoMessage()    {}
-func (*NameRegEntryParam) Descriptor() ([]byte, []int) {
-	return fileDescriptor_namereg_4496634bf2190c58, []int{0}
-}
-func (m *NameRegEntryParam) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_NameRegEntryParam.Unmarshal(m, b)
-}
-func (m *NameRegEntryParam) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_NameRegEntryParam.Marshal(b, m, deterministic)
-}
-func (dst *NameRegEntryParam) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_NameRegEntryParam.Merge(dst, src)
-}
-func (m *NameRegEntryParam) XXX_Size() int {
-	return xxx_messageInfo_NameRegEntryParam.Size(m)
-}
-func (m *NameRegEntryParam) XXX_DiscardUnknown() {
-	xxx_messageInfo_NameRegEntryParam.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_NameRegEntryParam proto.InternalMessageInfo
-
-func (m *NameRegEntryParam) GetName() string {
-	if m != nil {
-		return m.Name
-	}
-	return ""
-}
-
-type TransactNameRegParam struct {
-	InputAccount         *InputAccount `protobuf:"bytes,1,opt,name=inputAccount,proto3" json:"inputAccount,omitempty"`
-	Name                 string        `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
-	Data                 string        `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"`
-	Fee                  uint64        `protobuf:"varint,4,opt,name=fee,proto3" json:"fee,omitempty"`
-	Amount               uint64        `protobuf:"varint,5,opt,name=amount,proto3" json:"amount,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}      `json:"-"`
-	XXX_unrecognized     []byte        `json:"-"`
-	XXX_sizecache        int32         `json:"-"`
-}
-
-func (m *TransactNameRegParam) Reset()         { *m = TransactNameRegParam{} }
-func (m *TransactNameRegParam) String() string { return proto.CompactTextString(m) }
-func (*TransactNameRegParam) ProtoMessage()    {}
-func (*TransactNameRegParam) Descriptor() ([]byte, []int) {
-	return fileDescriptor_namereg_4496634bf2190c58, []int{1}
-}
-func (m *TransactNameRegParam) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_TransactNameRegParam.Unmarshal(m, b)
-}
-func (m *TransactNameRegParam) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_TransactNameRegParam.Marshal(b, m, deterministic)
-}
-func (dst *TransactNameRegParam) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_TransactNameRegParam.Merge(dst, src)
-}
-func (m *TransactNameRegParam) XXX_Size() int {
-	return xxx_messageInfo_TransactNameRegParam.Size(m)
-}
-func (m *TransactNameRegParam) XXX_DiscardUnknown() {
-	xxx_messageInfo_TransactNameRegParam.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_TransactNameRegParam proto.InternalMessageInfo
-
-func (m *TransactNameRegParam) GetInputAccount() *InputAccount {
-	if m != nil {
-		return m.InputAccount
-	}
-	return nil
-}
-
-func (m *TransactNameRegParam) GetName() string {
-	if m != nil {
-		return m.Name
-	}
-	return ""
-}
-
-func (m *TransactNameRegParam) GetData() string {
-	if m != nil {
-		return m.Data
-	}
-	return ""
-}
-
-func (m *TransactNameRegParam) GetFee() uint64 {
-	if m != nil {
-		return m.Fee
-	}
-	return 0
-}
-
-func (m *TransactNameRegParam) GetAmount() uint64 {
-	if m != nil {
-		return m.Amount
-	}
-	return 0
-}
-
-// Results
-type NameRegEntry struct {
-	// registered name for the entry
-	Name                 string   `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"`
-	Owner                []byte   `protobuf:"bytes,2,opt,name=Owner,proto3" json:"Owner,omitempty"`
-	Data                 string   `protobuf:"bytes,3,opt,name=Data,proto3" json:"Data,omitempty"`
-	Expires              uint64   `protobuf:"varint,4,opt,name=Expires,proto3" json:"Expires,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *NameRegEntry) Reset()         { *m = NameRegEntry{} }
-func (m *NameRegEntry) String() string { return proto.CompactTextString(m) }
-func (*NameRegEntry) ProtoMessage()    {}
-func (*NameRegEntry) Descriptor() ([]byte, []int) {
-	return fileDescriptor_namereg_4496634bf2190c58, []int{2}
-}
-func (m *NameRegEntry) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_NameRegEntry.Unmarshal(m, b)
-}
-func (m *NameRegEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_NameRegEntry.Marshal(b, m, deterministic)
-}
-func (dst *NameRegEntry) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_NameRegEntry.Merge(dst, src)
-}
-func (m *NameRegEntry) XXX_Size() int {
-	return xxx_messageInfo_NameRegEntry.Size(m)
-}
-func (m *NameRegEntry) XXX_DiscardUnknown() {
-	xxx_messageInfo_NameRegEntry.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_NameRegEntry proto.InternalMessageInfo
-
-func (m *NameRegEntry) GetName() string {
-	if m != nil {
-		return m.Name
-	}
-	return ""
-}
-
-func (m *NameRegEntry) GetOwner() []byte {
-	if m != nil {
-		return m.Owner
-	}
-	return nil
-}
-
-func (m *NameRegEntry) GetData() string {
-	if m != nil {
-		return m.Data
-	}
-	return ""
-}
-
-func (m *NameRegEntry) GetExpires() uint64 {
-	if m != nil {
-		return m.Expires
-	}
-	return 0
-}
-
-type NameRegEntryList struct {
-	BlockHeight          uint64          `protobuf:"varint,1,opt,name=BlockHeight,proto3" json:"BlockHeight,omitempty"`
-	Names                []*NameRegEntry `protobuf:"bytes,2,rep,name=Names,proto3" json:"Names,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}        `json:"-"`
-	XXX_unrecognized     []byte          `json:"-"`
-	XXX_sizecache        int32           `json:"-"`
-}
-
-func (m *NameRegEntryList) Reset()         { *m = NameRegEntryList{} }
-func (m *NameRegEntryList) String() string { return proto.CompactTextString(m) }
-func (*NameRegEntryList) ProtoMessage()    {}
-func (*NameRegEntryList) Descriptor() ([]byte, []int) {
-	return fileDescriptor_namereg_4496634bf2190c58, []int{3}
-}
-func (m *NameRegEntryList) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_NameRegEntryList.Unmarshal(m, b)
-}
-func (m *NameRegEntryList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_NameRegEntryList.Marshal(b, m, deterministic)
-}
-func (dst *NameRegEntryList) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_NameRegEntryList.Merge(dst, src)
-}
-func (m *NameRegEntryList) XXX_Size() int {
-	return xxx_messageInfo_NameRegEntryList.Size(m)
-}
-func (m *NameRegEntryList) XXX_DiscardUnknown() {
-	xxx_messageInfo_NameRegEntryList.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_NameRegEntryList proto.InternalMessageInfo
-
-func (m *NameRegEntryList) GetBlockHeight() uint64 {
-	if m != nil {
-		return m.BlockHeight
-	}
-	return 0
-}
-
-func (m *NameRegEntryList) GetNames() []*NameRegEntry {
-	if m != nil {
-		return m.Names
-	}
-	return nil
-}
-
-func init() {
-	proto.RegisterType((*NameRegEntryParam)(nil), "NameRegEntryParam")
-	proto.RegisterType((*TransactNameRegParam)(nil), "TransactNameRegParam")
-	proto.RegisterType((*NameRegEntry)(nil), "NameRegEntry")
-	proto.RegisterType((*NameRegEntryList)(nil), "NameRegEntryList")
-}
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ context.Context
-var _ grpc.ClientConn
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the grpc package it is being compiled against.
-const _ = grpc.SupportPackageIsVersion4
-
-// NameRegClient is the client API for NameReg service.
-//
-// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
-type NameRegClient interface {
-	GetEntry(ctx context.Context, in *NameRegEntryParam, opts ...grpc.CallOption) (*NameRegEntry, error)
-	GetEntries(ctx context.Context, in *FilterListParam, opts ...grpc.CallOption) (*NameRegEntryList, error)
-	TransactNameReg(ctx context.Context, in *TransactNameRegParam, opts ...grpc.CallOption) (*TxReceipt, error)
-	TransactNameRegAndHold(ctx context.Context, in *TransactNameRegParam, opts ...grpc.CallOption) (*NameRegEntry, error)
-}
-
-type nameRegClient struct {
-	cc *grpc.ClientConn
-}
-
-func NewNameRegClient(cc *grpc.ClientConn) NameRegClient {
-	return &nameRegClient{cc}
-}
-
-func (c *nameRegClient) GetEntry(ctx context.Context, in *NameRegEntryParam, opts ...grpc.CallOption) (*NameRegEntry, error) {
-	out := new(NameRegEntry)
-	err := c.cc.Invoke(ctx, "/NameReg/GetEntry", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *nameRegClient) GetEntries(ctx context.Context, in *FilterListParam, opts ...grpc.CallOption) (*NameRegEntryList, error) {
-	out := new(NameRegEntryList)
-	err := c.cc.Invoke(ctx, "/NameReg/GetEntries", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *nameRegClient) TransactNameReg(ctx context.Context, in *TransactNameRegParam, opts ...grpc.CallOption) (*TxReceipt, error) {
-	out := new(TxReceipt)
-	err := c.cc.Invoke(ctx, "/NameReg/TransactNameReg", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *nameRegClient) TransactNameRegAndHold(ctx context.Context, in *TransactNameRegParam, opts ...grpc.CallOption) (*NameRegEntry, error) {
-	out := new(NameRegEntry)
-	err := c.cc.Invoke(ctx, "/NameReg/TransactNameRegAndHold", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-// NameRegServer is the server API for NameReg service.
-type NameRegServer interface {
-	GetEntry(context.Context, *NameRegEntryParam) (*NameRegEntry, error)
-	GetEntries(context.Context, *FilterListParam) (*NameRegEntryList, error)
-	TransactNameReg(context.Context, *TransactNameRegParam) (*TxReceipt, error)
-	TransactNameRegAndHold(context.Context, *TransactNameRegParam) (*NameRegEntry, error)
-}
-
-func RegisterNameRegServer(s *grpc.Server, srv NameRegServer) {
-	s.RegisterService(&_NameReg_serviceDesc, srv)
-}
-
-func _NameReg_GetEntry_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(NameRegEntryParam)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(NameRegServer).GetEntry(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/NameReg/GetEntry",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(NameRegServer).GetEntry(ctx, req.(*NameRegEntryParam))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _NameReg_GetEntries_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(FilterListParam)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(NameRegServer).GetEntries(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/NameReg/GetEntries",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(NameRegServer).GetEntries(ctx, req.(*FilterListParam))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _NameReg_TransactNameReg_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(TransactNameRegParam)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(NameRegServer).TransactNameReg(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/NameReg/TransactNameReg",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(NameRegServer).TransactNameReg(ctx, req.(*TransactNameRegParam))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _NameReg_TransactNameRegAndHold_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(TransactNameRegParam)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(NameRegServer).TransactNameRegAndHold(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/NameReg/TransactNameRegAndHold",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(NameRegServer).TransactNameRegAndHold(ctx, req.(*TransactNameRegParam))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-var _NameReg_serviceDesc = grpc.ServiceDesc{
-	ServiceName: "NameReg",
-	HandlerType: (*NameRegServer)(nil),
-	Methods: []grpc.MethodDesc{
-		{
-			MethodName: "GetEntry",
-			Handler:    _NameReg_GetEntry_Handler,
-		},
-		{
-			MethodName: "GetEntries",
-			Handler:    _NameReg_GetEntries_Handler,
-		},
-		{
-			MethodName: "TransactNameReg",
-			Handler:    _NameReg_TransactNameReg_Handler,
-		},
-		{
-			MethodName: "TransactNameRegAndHold",
-			Handler:    _NameReg_TransactNameRegAndHold_Handler,
-		},
-	},
-	Streams:  []grpc.StreamDesc{},
-	Metadata: "rpc/burrow/namereg.proto",
-}
-
-func init() { proto.RegisterFile("rpc/burrow/namereg.proto", fileDescriptor_namereg_4496634bf2190c58) }
-
-var fileDescriptor_namereg_4496634bf2190c58 = []byte{
-	// 370 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x52, 0x5d, 0x4f, 0x2a, 0x31,
-	0x10, 0xcd, 0xc2, 0xf2, 0x71, 0x07, 0x6e, 0x2e, 0x34, 0x5c, 0xee, 0x86, 0xa7, 0xcd, 0xde, 0x07,
-	0x79, 0x71, 0x09, 0xe8, 0xb3, 0x09, 0x44, 0x14, 0x13, 0x83, 0xa6, 0xe1, 0x45, 0xdf, 0xca, 0x52,
-	0x70, 0x23, 0xdb, 0x6e, 0xba, 0x25, 0xe0, 0x6f, 0xf1, 0xd7, 0xf9, 0x4f, 0x4c, 0xdb, 0x55, 0x0b,
-	0xe8, 0xdb, 0xcc, 0x99, 0x33, 0xe7, 0xcc, 0x74, 0x0a, 0x9e, 0x48, 0xa3, 0xde, 0x7c, 0x23, 0x04,
-	0xdf, 0xf6, 0x18, 0x49, 0xa8, 0xa0, 0xab, 0x30, 0x15, 0x5c, 0xf2, 0xce, 0x3f, 0xab, 0x12, 0xf1,
-	0x24, 0xe1, 0xcc, 0x14, 0x82, 0x13, 0x68, 0x4e, 0x49, 0x42, 0x31, 0x5d, 0x8d, 0x99, 0x14, 0x2f,
-	0xf7, 0x44, 0x90, 0x04, 0x21, 0x70, 0x55, 0xbb, 0xe7, 0xf8, 0x4e, 0xf7, 0x17, 0xd6, 0x71, 0xf0,
-	0xea, 0x40, 0x6b, 0x26, 0x08, 0xcb, 0x48, 0x24, 0xf3, 0x0e, 0x43, 0xee, 0x43, 0x3d, 0x66, 0xe9,
-	0x46, 0x0e, 0xa3, 0x88, 0x6f, 0x98, 0xd4, 0x4d, 0xb5, 0xc1, 0xef, 0xf0, 0xc6, 0x02, 0xf1, 0x1e,
-	0xe5, 0x53, 0xbf, 0xf0, 0xa5, 0xaf, 0xb0, 0x05, 0x91, 0xc4, 0x2b, 0x1a, 0x4c, 0xc5, 0xa8, 0x01,
-	0xc5, 0x25, 0xa5, 0x9e, 0xeb, 0x3b, 0x5d, 0x17, 0xab, 0x10, 0xb5, 0xa1, 0x4c, 0x12, 0x6d, 0x53,
-	0xd2, 0x60, 0x9e, 0x05, 0x4b, 0xa8, 0xdb, 0x6b, 0x28, 0xb5, 0xa9, 0xb5, 0x81, 0x8a, 0x51, 0x0b,
-	0x4a, 0x77, 0x5b, 0x46, 0x85, 0xb6, 0xad, 0x63, 0x93, 0x28, 0xe6, 0xa5, 0xe5, 0xab, 0x62, 0xe4,
-	0x41, 0x65, 0xbc, 0x4b, 0x63, 0x41, 0xb3, 0xdc, 0xfb, 0x23, 0x0d, 0x1e, 0xa0, 0x61, 0xfb, 0xdc,
-	0xc6, 0x99, 0x44, 0x3e, 0xd4, 0x46, 0x6b, 0x1e, 0x3d, 0x4f, 0x68, 0xbc, 0x7a, 0x32, 0xfb, 0xbb,
-	0xd8, 0x86, 0xd0, 0x7f, 0x28, 0xa9, 0xae, 0xcc, 0x2b, 0xf8, 0x45, 0xfd, 0x36, 0xb6, 0x06, 0x36,
-	0xb5, 0xc1, 0x9b, 0x03, 0x95, 0x1c, 0x47, 0xa7, 0x50, 0xbd, 0xa6, 0x32, 0x5f, 0x25, 0x3c, 0x3a,
-	0x50, 0x67, 0x5f, 0x01, 0xf5, 0x01, 0x72, 0x7a, 0x4c, 0x33, 0xd4, 0x08, 0xaf, 0xe2, 0xb5, 0xa4,
-	0x42, 0x0d, 0x67, 0xe8, 0xcd, 0xf0, 0x68, 0xe8, 0x73, 0xf8, 0x73, 0x70, 0x4d, 0xf4, 0x37, 0xfc,
-	0xee, 0xbe, 0x1d, 0x08, 0x67, 0x3b, 0x4c, 0x23, 0x1a, 0xa7, 0x12, 0x5d, 0x40, 0xfb, 0x80, 0x33,
-	0x64, 0x8b, 0x09, 0x5f, 0x2f, 0x7e, 0x6a, 0xde, 0x1f, 0x74, 0x54, 0x7d, 0x2c, 0x9b, 0x4f, 0x38,
-	0x2f, 0xeb, 0xef, 0x77, 0xf6, 0x1e, 0x00, 0x00, 0xff, 0xff, 0x69, 0xcb, 0xf2, 0xea, 0xb3, 0x02,
-	0x00, 0x00,
-}
diff --git a/rpc/burrow/namereg.proto b/rpc/burrow/namereg.proto
deleted file mode 100644
index 0462e88a00fb54538075bee4c42569daf17d5ffc..0000000000000000000000000000000000000000
--- a/rpc/burrow/namereg.proto
+++ /dev/null
@@ -1,43 +0,0 @@
-syntax = 'proto3';
-
-option go_package = "burrow";
-
-import "rpc/burrow/common.proto";
-
-// Name Registry Service Definition 
-service NameReg {
-    rpc GetEntry (NameRegEntryParam) returns (NameRegEntry);
-    rpc GetEntries (FilterListParam) returns (NameRegEntryList);
-    rpc TransactNameReg (TransactNameRegParam) returns (TxReceipt);
-    rpc TransactNameRegAndHold (TransactNameRegParam) returns (NameRegEntry);
-}
-
-// Params
-message NameRegEntryParam {
-    string name = 1;
-}
-
-message TransactNameRegParam {
-    InputAccount inputAccount = 1;
-    string name = 2;
-    string data = 3;
-    uint64 fee = 4;
-    uint64 amount = 5;
-}
-
-// Results
-message NameRegEntry {
-    // registered name for the entry
-    string Name = 1;
-    bytes Owner = 2;
-    string Data = 3;
-    uint64 Expires = 4;
-}
-
-message NameRegEntryList {
-    uint64 BlockHeight = 1;
-    repeated NameRegEntry Names = 2;
-}
-
-//--------------------------------------------------
-
diff --git a/rpc/burrow/network.pb.go b/rpc/burrow/network.pb.go
deleted file mode 100644
index fccd3423dce48dfb55e0beed66193ebbfc0ca708..0000000000000000000000000000000000000000
--- a/rpc/burrow/network.pb.go
+++ /dev/null
@@ -1,620 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// source: rpc/burrow/network.proto
-
-package burrow
-
-import proto "github.com/golang/protobuf/proto"
-import fmt "fmt"
-import math "math"
-
-import (
-	context "golang.org/x/net/context"
-	grpc "google.golang.org/grpc"
-)
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ = proto.Marshal
-var _ = fmt.Errorf
-var _ = math.Inf
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the proto package it is being compiled against.
-// A compilation error at this line likely means your copy of the
-// proto package needs to be updated.
-const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
-
-// Params
-type PeerParam struct {
-	Address              []byte   `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *PeerParam) Reset()         { *m = PeerParam{} }
-func (m *PeerParam) String() string { return proto.CompactTextString(m) }
-func (*PeerParam) ProtoMessage()    {}
-func (*PeerParam) Descriptor() ([]byte, []int) {
-	return fileDescriptor_network_549d0b14318a838d, []int{0}
-}
-func (m *PeerParam) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_PeerParam.Unmarshal(m, b)
-}
-func (m *PeerParam) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_PeerParam.Marshal(b, m, deterministic)
-}
-func (dst *PeerParam) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_PeerParam.Merge(dst, src)
-}
-func (m *PeerParam) XXX_Size() int {
-	return xxx_messageInfo_PeerParam.Size(m)
-}
-func (m *PeerParam) XXX_DiscardUnknown() {
-	xxx_messageInfo_PeerParam.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_PeerParam proto.InternalMessageInfo
-
-func (m *PeerParam) GetAddress() []byte {
-	if m != nil {
-		return m.Address
-	}
-	return nil
-}
-
-// Results
-type ClientVersion struct {
-	Version              string   `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *ClientVersion) Reset()         { *m = ClientVersion{} }
-func (m *ClientVersion) String() string { return proto.CompactTextString(m) }
-func (*ClientVersion) ProtoMessage()    {}
-func (*ClientVersion) Descriptor() ([]byte, []int) {
-	return fileDescriptor_network_549d0b14318a838d, []int{1}
-}
-func (m *ClientVersion) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_ClientVersion.Unmarshal(m, b)
-}
-func (m *ClientVersion) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_ClientVersion.Marshal(b, m, deterministic)
-}
-func (dst *ClientVersion) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_ClientVersion.Merge(dst, src)
-}
-func (m *ClientVersion) XXX_Size() int {
-	return xxx_messageInfo_ClientVersion.Size(m)
-}
-func (m *ClientVersion) XXX_DiscardUnknown() {
-	xxx_messageInfo_ClientVersion.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_ClientVersion proto.InternalMessageInfo
-
-func (m *ClientVersion) GetVersion() string {
-	if m != nil {
-		return m.Version
-	}
-	return ""
-}
-
-type NodeID struct {
-	Name                 string   `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"`
-	PublicKey            []byte   `protobuf:"bytes,2,opt,name=PublicKey,proto3" json:"PublicKey,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *NodeID) Reset()         { *m = NodeID{} }
-func (m *NodeID) String() string { return proto.CompactTextString(m) }
-func (*NodeID) ProtoMessage()    {}
-func (*NodeID) Descriptor() ([]byte, []int) {
-	return fileDescriptor_network_549d0b14318a838d, []int{2}
-}
-func (m *NodeID) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_NodeID.Unmarshal(m, b)
-}
-func (m *NodeID) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_NodeID.Marshal(b, m, deterministic)
-}
-func (dst *NodeID) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_NodeID.Merge(dst, src)
-}
-func (m *NodeID) XXX_Size() int {
-	return xxx_messageInfo_NodeID.Size(m)
-}
-func (m *NodeID) XXX_DiscardUnknown() {
-	xxx_messageInfo_NodeID.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_NodeID proto.InternalMessageInfo
-
-func (m *NodeID) GetName() string {
-	if m != nil {
-		return m.Name
-	}
-	return ""
-}
-
-func (m *NodeID) GetPublicKey() []byte {
-	if m != nil {
-		return m.PublicKey
-	}
-	return nil
-}
-
-type NodeInfo struct {
-	ID                   *NodeID  `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`
-	ListenAddr           string   `protobuf:"bytes,2,opt,name=ListenAddr,proto3" json:"ListenAddr,omitempty"`
-	Network              string   `protobuf:"bytes,3,opt,name=Network,proto3" json:"Network,omitempty"`
-	Version              string   `protobuf:"bytes,4,opt,name=Version,proto3" json:"Version,omitempty"`
-	Channels             []byte   `protobuf:"bytes,5,opt,name=Channels,proto3" json:"Channels,omitempty"`
-	Moniker              string   `protobuf:"bytes,6,opt,name=Moniker,proto3" json:"Moniker,omitempty"`
-	Other                []string `protobuf:"bytes,7,rep,name=Other,proto3" json:"Other,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *NodeInfo) Reset()         { *m = NodeInfo{} }
-func (m *NodeInfo) String() string { return proto.CompactTextString(m) }
-func (*NodeInfo) ProtoMessage()    {}
-func (*NodeInfo) Descriptor() ([]byte, []int) {
-	return fileDescriptor_network_549d0b14318a838d, []int{3}
-}
-func (m *NodeInfo) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_NodeInfo.Unmarshal(m, b)
-}
-func (m *NodeInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_NodeInfo.Marshal(b, m, deterministic)
-}
-func (dst *NodeInfo) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_NodeInfo.Merge(dst, src)
-}
-func (m *NodeInfo) XXX_Size() int {
-	return xxx_messageInfo_NodeInfo.Size(m)
-}
-func (m *NodeInfo) XXX_DiscardUnknown() {
-	xxx_messageInfo_NodeInfo.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_NodeInfo proto.InternalMessageInfo
-
-func (m *NodeInfo) GetID() *NodeID {
-	if m != nil {
-		return m.ID
-	}
-	return nil
-}
-
-func (m *NodeInfo) GetListenAddr() string {
-	if m != nil {
-		return m.ListenAddr
-	}
-	return ""
-}
-
-func (m *NodeInfo) GetNetwork() string {
-	if m != nil {
-		return m.Network
-	}
-	return ""
-}
-
-func (m *NodeInfo) GetVersion() string {
-	if m != nil {
-		return m.Version
-	}
-	return ""
-}
-
-func (m *NodeInfo) GetChannels() []byte {
-	if m != nil {
-		return m.Channels
-	}
-	return nil
-}
-
-func (m *NodeInfo) GetMoniker() string {
-	if m != nil {
-		return m.Moniker
-	}
-	return ""
-}
-
-func (m *NodeInfo) GetOther() []string {
-	if m != nil {
-		return m.Other
-	}
-	return nil
-}
-
-type NetworkInfo struct {
-	Listening            bool     `protobuf:"varint,1,opt,name=Listening,proto3" json:"Listening,omitempty"`
-	Listeners            []string `protobuf:"bytes,2,rep,name=Listeners,proto3" json:"Listeners,omitempty"`
-	Peers                []*Peer  `protobuf:"bytes,3,rep,name=Peers,proto3" json:"Peers,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *NetworkInfo) Reset()         { *m = NetworkInfo{} }
-func (m *NetworkInfo) String() string { return proto.CompactTextString(m) }
-func (*NetworkInfo) ProtoMessage()    {}
-func (*NetworkInfo) Descriptor() ([]byte, []int) {
-	return fileDescriptor_network_549d0b14318a838d, []int{4}
-}
-func (m *NetworkInfo) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_NetworkInfo.Unmarshal(m, b)
-}
-func (m *NetworkInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_NetworkInfo.Marshal(b, m, deterministic)
-}
-func (dst *NetworkInfo) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_NetworkInfo.Merge(dst, src)
-}
-func (m *NetworkInfo) XXX_Size() int {
-	return xxx_messageInfo_NetworkInfo.Size(m)
-}
-func (m *NetworkInfo) XXX_DiscardUnknown() {
-	xxx_messageInfo_NetworkInfo.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_NetworkInfo proto.InternalMessageInfo
-
-func (m *NetworkInfo) GetListening() bool {
-	if m != nil {
-		return m.Listening
-	}
-	return false
-}
-
-func (m *NetworkInfo) GetListeners() []string {
-	if m != nil {
-		return m.Listeners
-	}
-	return nil
-}
-
-func (m *NetworkInfo) GetPeers() []*Peer {
-	if m != nil {
-		return m.Peers
-	}
-	return nil
-}
-
-type Peer struct {
-	NodeInfo             *NodeInfo `protobuf:"bytes,1,opt,name=NodeInfo,proto3" json:"NodeInfo,omitempty"`
-	IsOutbound           bool      `protobuf:"varint,2,opt,name=IsOutbound,proto3" json:"IsOutbound,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}  `json:"-"`
-	XXX_unrecognized     []byte    `json:"-"`
-	XXX_sizecache        int32     `json:"-"`
-}
-
-func (m *Peer) Reset()         { *m = Peer{} }
-func (m *Peer) String() string { return proto.CompactTextString(m) }
-func (*Peer) ProtoMessage()    {}
-func (*Peer) Descriptor() ([]byte, []int) {
-	return fileDescriptor_network_549d0b14318a838d, []int{5}
-}
-func (m *Peer) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_Peer.Unmarshal(m, b)
-}
-func (m *Peer) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_Peer.Marshal(b, m, deterministic)
-}
-func (dst *Peer) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_Peer.Merge(dst, src)
-}
-func (m *Peer) XXX_Size() int {
-	return xxx_messageInfo_Peer.Size(m)
-}
-func (m *Peer) XXX_DiscardUnknown() {
-	xxx_messageInfo_Peer.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Peer proto.InternalMessageInfo
-
-func (m *Peer) GetNodeInfo() *NodeInfo {
-	if m != nil {
-		return m.NodeInfo
-	}
-	return nil
-}
-
-func (m *Peer) GetIsOutbound() bool {
-	if m != nil {
-		return m.IsOutbound
-	}
-	return false
-}
-
-type PeerList struct {
-	Peers                []*Peer  `protobuf:"bytes,1,rep,name=Peers,proto3" json:"Peers,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *PeerList) Reset()         { *m = PeerList{} }
-func (m *PeerList) String() string { return proto.CompactTextString(m) }
-func (*PeerList) ProtoMessage()    {}
-func (*PeerList) Descriptor() ([]byte, []int) {
-	return fileDescriptor_network_549d0b14318a838d, []int{6}
-}
-func (m *PeerList) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_PeerList.Unmarshal(m, b)
-}
-func (m *PeerList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_PeerList.Marshal(b, m, deterministic)
-}
-func (dst *PeerList) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_PeerList.Merge(dst, src)
-}
-func (m *PeerList) XXX_Size() int {
-	return xxx_messageInfo_PeerList.Size(m)
-}
-func (m *PeerList) XXX_DiscardUnknown() {
-	xxx_messageInfo_PeerList.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_PeerList proto.InternalMessageInfo
-
-func (m *PeerList) GetPeers() []*Peer {
-	if m != nil {
-		return m.Peers
-	}
-	return nil
-}
-
-func init() {
-	proto.RegisterType((*PeerParam)(nil), "PeerParam")
-	proto.RegisterType((*ClientVersion)(nil), "ClientVersion")
-	proto.RegisterType((*NodeID)(nil), "NodeID")
-	proto.RegisterType((*NodeInfo)(nil), "NodeInfo")
-	proto.RegisterType((*NetworkInfo)(nil), "NetworkInfo")
-	proto.RegisterType((*Peer)(nil), "Peer")
-	proto.RegisterType((*PeerList)(nil), "PeerList")
-}
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ context.Context
-var _ grpc.ClientConn
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the grpc package it is being compiled against.
-const _ = grpc.SupportPackageIsVersion4
-
-// NetworkClient is the client API for Network service.
-//
-// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
-type NetworkClient interface {
-	GetClientVersion(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ClientVersion, error)
-	GetNetworkInfo(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*NetworkInfo, error)
-	GetNodeInfo(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*NodeInfo, error)
-	GetPeer(ctx context.Context, in *PeerParam, opts ...grpc.CallOption) (*Peer, error)
-	GetPeers(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*PeerList, error)
-}
-
-type networkClient struct {
-	cc *grpc.ClientConn
-}
-
-func NewNetworkClient(cc *grpc.ClientConn) NetworkClient {
-	return &networkClient{cc}
-}
-
-func (c *networkClient) GetClientVersion(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ClientVersion, error) {
-	out := new(ClientVersion)
-	err := c.cc.Invoke(ctx, "/Network/GetClientVersion", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *networkClient) GetNetworkInfo(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*NetworkInfo, error) {
-	out := new(NetworkInfo)
-	err := c.cc.Invoke(ctx, "/Network/GetNetworkInfo", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *networkClient) GetNodeInfo(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*NodeInfo, error) {
-	out := new(NodeInfo)
-	err := c.cc.Invoke(ctx, "/Network/GetNodeInfo", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *networkClient) GetPeer(ctx context.Context, in *PeerParam, opts ...grpc.CallOption) (*Peer, error) {
-	out := new(Peer)
-	err := c.cc.Invoke(ctx, "/Network/GetPeer", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *networkClient) GetPeers(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*PeerList, error) {
-	out := new(PeerList)
-	err := c.cc.Invoke(ctx, "/Network/GetPeers", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-// NetworkServer is the server API for Network service.
-type NetworkServer interface {
-	GetClientVersion(context.Context, *Empty) (*ClientVersion, error)
-	GetNetworkInfo(context.Context, *Empty) (*NetworkInfo, error)
-	GetNodeInfo(context.Context, *Empty) (*NodeInfo, error)
-	GetPeer(context.Context, *PeerParam) (*Peer, error)
-	GetPeers(context.Context, *Empty) (*PeerList, error)
-}
-
-func RegisterNetworkServer(s *grpc.Server, srv NetworkServer) {
-	s.RegisterService(&_Network_serviceDesc, srv)
-}
-
-func _Network_GetClientVersion_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(Empty)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(NetworkServer).GetClientVersion(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/Network/GetClientVersion",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(NetworkServer).GetClientVersion(ctx, req.(*Empty))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Network_GetNetworkInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(Empty)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(NetworkServer).GetNetworkInfo(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/Network/GetNetworkInfo",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(NetworkServer).GetNetworkInfo(ctx, req.(*Empty))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Network_GetNodeInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(Empty)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(NetworkServer).GetNodeInfo(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/Network/GetNodeInfo",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(NetworkServer).GetNodeInfo(ctx, req.(*Empty))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Network_GetPeer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(PeerParam)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(NetworkServer).GetPeer(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/Network/GetPeer",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(NetworkServer).GetPeer(ctx, req.(*PeerParam))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Network_GetPeers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(Empty)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(NetworkServer).GetPeers(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/Network/GetPeers",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(NetworkServer).GetPeers(ctx, req.(*Empty))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-var _Network_serviceDesc = grpc.ServiceDesc{
-	ServiceName: "Network",
-	HandlerType: (*NetworkServer)(nil),
-	Methods: []grpc.MethodDesc{
-		{
-			MethodName: "GetClientVersion",
-			Handler:    _Network_GetClientVersion_Handler,
-		},
-		{
-			MethodName: "GetNetworkInfo",
-			Handler:    _Network_GetNetworkInfo_Handler,
-		},
-		{
-			MethodName: "GetNodeInfo",
-			Handler:    _Network_GetNodeInfo_Handler,
-		},
-		{
-			MethodName: "GetPeer",
-			Handler:    _Network_GetPeer_Handler,
-		},
-		{
-			MethodName: "GetPeers",
-			Handler:    _Network_GetPeers_Handler,
-		},
-	},
-	Streams:  []grpc.StreamDesc{},
-	Metadata: "rpc/burrow/network.proto",
-}
-
-func init() { proto.RegisterFile("rpc/burrow/network.proto", fileDescriptor_network_549d0b14318a838d) }
-
-var fileDescriptor_network_549d0b14318a838d = []byte{
-	// 445 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x53, 0xcf, 0x6f, 0xd3, 0x30,
-	0x14, 0x56, 0xfa, 0x23, 0x4d, 0x5e, 0xc7, 0x84, 0x2c, 0xa4, 0x59, 0xa5, 0x4c, 0x55, 0xa4, 0x41,
-	0xe1, 0x90, 0x49, 0xe5, 0xc6, 0x0d, 0x56, 0x54, 0x55, 0xb0, 0xae, 0xf2, 0x81, 0x03, 0xb7, 0xb4,
-	0x79, 0x63, 0xd1, 0x1a, 0xbb, 0xb2, 0x5d, 0xa6, 0xfd, 0x6f, 0xdc, 0xf8, 0xc7, 0x90, 0xed, 0xb8,
-	0x4e, 0xc5, 0xed, 0x7d, 0xdf, 0xfb, 0xf9, 0x7d, 0x89, 0x81, 0xca, 0xfd, 0xf6, 0x7a, 0x73, 0x90,
-	0x52, 0x3c, 0x5d, 0x73, 0xd4, 0x4f, 0x42, 0x3e, 0xe6, 0x7b, 0x29, 0xb4, 0x18, 0x5d, 0xb4, 0x32,
-	0x5b, 0x51, 0xd7, 0x82, 0xbb, 0x44, 0x76, 0x05, 0xe9, 0x1a, 0x51, 0xae, 0x0b, 0x59, 0xd4, 0x84,
-	0xc2, 0xa0, 0x28, 0x4b, 0x89, 0x4a, 0xd1, 0x68, 0x12, 0x4d, 0xcf, 0x98, 0x87, 0xd9, 0x7b, 0x78,
-	0x71, 0xb3, 0xab, 0x90, 0xeb, 0x1f, 0x28, 0x55, 0x25, 0xb8, 0x29, 0xfd, 0xed, 0x42, 0x5b, 0x9a,
-	0x32, 0x0f, 0xb3, 0x4f, 0x10, 0xaf, 0x44, 0x89, 0xcb, 0x39, 0x21, 0xd0, 0x5b, 0x15, 0x35, 0x36,
-	0x05, 0x36, 0x26, 0x63, 0x48, 0xd7, 0x87, 0xcd, 0xae, 0xda, 0x7e, 0xc3, 0x67, 0xda, 0xb1, 0x4b,
-	0x02, 0x91, 0xfd, 0x8d, 0x20, 0xb1, 0xcd, 0xfc, 0x5e, 0x90, 0x0b, 0xe8, 0x2c, 0xe7, 0xb6, 0x79,
-	0x38, 0x1b, 0xe4, 0x6e, 0x26, 0xeb, 0x2c, 0xe7, 0xe4, 0x12, 0xe0, 0x7b, 0xa5, 0x34, 0xf2, 0xcf,
-	0x65, 0x29, 0xed, 0x90, 0x94, 0xb5, 0x18, 0x73, 0xdb, 0xca, 0xa9, 0xa7, 0x5d, 0x77, 0x5b, 0x03,
-	0x4d, 0xa6, 0x11, 0x40, 0x7b, 0x2e, 0xe3, 0xf5, 0x8c, 0x20, 0xb9, 0x79, 0x28, 0x38, 0xc7, 0x9d,
-	0xa2, 0x7d, 0x7b, 0xd6, 0x11, 0x9b, 0xae, 0x5b, 0xc1, 0xab, 0x47, 0x94, 0x34, 0x76, 0x5d, 0x0d,
-	0x24, 0xaf, 0xa0, 0x7f, 0xa7, 0x1f, 0x50, 0xd2, 0xc1, 0xa4, 0x3b, 0x4d, 0x99, 0x03, 0xd9, 0x3d,
-	0x0c, 0x9b, 0x85, 0x56, 0xc7, 0x18, 0x52, 0x77, 0x5c, 0xc5, 0x7f, 0x59, 0x39, 0x09, 0x0b, 0x44,
-	0xc8, 0xa2, 0x54, 0xb4, 0x63, 0xc7, 0x04, 0x82, 0xbc, 0x86, 0xbe, 0xf9, 0x3c, 0x8a, 0x76, 0x27,
-	0xdd, 0xe9, 0x70, 0xd6, 0xcf, 0x0d, 0x62, 0x8e, 0xcb, 0x6e, 0xa1, 0x67, 0x02, 0x72, 0x15, 0x4c,
-	0x6b, 0xec, 0x4a, 0x73, 0x4f, 0xb0, 0xe0, 0xe7, 0x25, 0xc0, 0x52, 0xdd, 0x1d, 0xf4, 0x46, 0x1c,
-	0x78, 0x69, 0x6d, 0x4b, 0x58, 0x8b, 0xc9, 0xde, 0x41, 0x62, 0xc6, 0x99, 0xe5, 0x61, 0x6f, 0xf4,
-	0xff, 0xde, 0xd9, 0x9f, 0xe8, 0x68, 0x30, 0xf9, 0x00, 0x2f, 0x17, 0xa8, 0x4f, 0xff, 0x8d, 0x38,
-	0xff, 0x5a, 0xef, 0xf5, 0xf3, 0xe8, 0x3c, 0x3f, 0xe5, 0xdf, 0xc2, 0xf9, 0x02, 0x75, 0xdb, 0x1a,
-	0x5f, 0x79, 0x96, 0xb7, 0xd9, 0x09, 0x0c, 0x4d, 0x9d, 0xbf, 0xdb, 0x17, 0x05, 0x51, 0x64, 0x0c,
-	0x83, 0x05, 0x6a, 0x2b, 0x1e, 0xf2, 0xe3, 0xff, 0x3b, 0x72, 0x67, 0x92, 0x37, 0x90, 0x34, 0x59,
-	0xd5, 0x6a, 0xf6, 0xda, 0xbe, 0x24, 0x3f, 0x63, 0xf7, 0x12, 0x36, 0xb1, 0x7d, 0x03, 0x1f, 0xff,
-	0x05, 0x00, 0x00, 0xff, 0xff, 0xa1, 0x95, 0xeb, 0x57, 0x38, 0x03, 0x00, 0x00,
-}
diff --git a/rpc/burrow/network.proto b/rpc/burrow/network.proto
deleted file mode 100644
index 093b2e24e7c4899967d4d9f41fde022fc6fe4a21..0000000000000000000000000000000000000000
--- a/rpc/burrow/network.proto
+++ /dev/null
@@ -1,57 +0,0 @@
-syntax = 'proto3';
-
-option go_package = "burrow";
-
-import "rpc/burrow/common.proto";
-
-// Network Service Definition
-service Network {
-    rpc GetClientVersion (Empty) returns (ClientVersion); // NI - go
-    rpc GetNetworkInfo (Empty) returns (NetworkInfo);
-    rpc GetNodeInfo (Empty) returns (NodeInfo); // NI - go
-    rpc GetPeer (PeerParam) returns (Peer); // NI - go
-    rpc GetPeers (Empty) returns (PeerList);
-}
-
-// Params
-message PeerParam {
-    bytes address = 1;
-}
-
-// Results
-message ClientVersion {
-    string version = 1;
-}
-
-message NodeID {
-    string Name = 1;
-    bytes PublicKey = 2;
-}
-
-message NodeInfo {
-    NodeID ID = 1;
-    string ListenAddr = 2;
-    string Network = 3;
-    string Version = 4;
-    bytes Channels = 5;
-    string Moniker = 6;
-    repeated string Other = 7;
-}
-
-message NetworkInfo {
-    bool Listening = 1;
-    repeated string Listeners = 2;
-    repeated Peer Peers = 3;
-}
-
-message Peer {
-    NodeInfo NodeInfo = 1;
-    bool IsOutbound = 2;
-}
-
-message PeerList {
-    repeated Peer Peers = 1;
-}
-
-//-------------------------------------------------
-
diff --git a/rpc/grpc.go b/rpc/grpc.go
index 49a42fd04a22be9a56b35c1bd3600cbcac757a15..eb9ec8dd106bf8f34804010ec78981f32b484a46 100644
--- a/rpc/grpc.go
+++ b/rpc/grpc.go
@@ -3,6 +3,8 @@ package rpc
 import (
 	"fmt"
 
+	"runtime/debug"
+
 	"github.com/hyperledger/burrow/logging"
 	"github.com/hyperledger/burrow/logging/structure"
 	"golang.org/x/net/context"
@@ -38,7 +40,7 @@ func streamInterceptor(logger *logging.Logger) grpc.StreamServerInterceptor {
 				logger.InfoMsg("panic in GRPC stream", "method", info.FullMethod,
 					"is_client_stream", info.IsClientStream, "is_server_stream", info.IsServerStream,
 					structure.ErrorKey, fmt.Sprintf("%v", r))
-				err = fmt.Errorf("panic in GRPC stream %s: %v", info.FullMethod, r)
+				err = fmt.Errorf("panic in GRPC stream %s: %v: %s", info.FullMethod, r, debug.Stack())
 			}
 		}()
 		return handler(srv, ss)
diff --git a/rpc/rpcevents/events_server.go b/rpc/rpcevents/events_server.go
index 7ee673c5f6a84022ff525d510225e800849c2fd8..6e55d39177831a686f1e3b49d1d0f0f3be565464 100644
--- a/rpc/rpcevents/events_server.go
+++ b/rpc/rpcevents/events_server.go
@@ -1,6 +1,7 @@
 package rpcevents
 
 import (
+	"github.com/hyperledger/burrow/execution/events"
 	"github.com/hyperledger/burrow/execution/events/pbevents"
 	"github.com/hyperledger/burrow/rpc"
 	"golang.org/x/net/context"
@@ -25,9 +26,8 @@ func (es *eventServer) EventPoll(ctx context.Context, param *pbevents.SubIdParam
 		Events: make([]*pbevents.ExecutionEvent, 0, len(msgs)),
 	}
 	for _, msg := range msgs {
-		ev := pbevents.GetEvent(msg)
-		if ev != nil {
-			resp.Events = append(resp.Events, ev)
+		if exeEvent, ok := msg.(*events.Event); ok {
+			resp.Events = append(resp.Events, pbevents.GetEvent(exeEvent))
 		}
 	}
 	return resp, nil
diff --git a/rpc/rpcevents/execution_events_server.go b/rpc/rpcevents/execution_events_server.go
index b7e22e2ca780db8f1ad585e8196c38a8f80a5be7..45794d5607a74adb93a2af7d6b74835241f240ca 100644
--- a/rpc/rpcevents/execution_events_server.go
+++ b/rpc/rpcevents/execution_events_server.go
@@ -1,17 +1,47 @@
 package rpcevents
 
 import (
+	"github.com/hyperledger/burrow/event/query"
+	"github.com/hyperledger/burrow/execution/events"
 	"github.com/hyperledger/burrow/execution/events/pbevents"
-	"golang.org/x/net/context"
 )
 
 type executionEventsServer struct {
+	eventsProvider events.Provider
 }
 
-func NewExecutionEventsServer() pbevents.ExecutionEventsServer {
-	return &executionEventsServer{}
+func NewExecutionEventsServer(eventsProvider events.Provider) pbevents.ExecutionEventsServer {
+	return &executionEventsServer{eventsProvider: eventsProvider}
 }
 
-func (executionEventsServer) GetEvents(context.Context, *pbevents.GetEventsRequest) (*pbevents.GetEventsResponse, error) {
-	panic("implement me")
+func (ees executionEventsServer) GetEvents(request *pbevents.GetEventsRequest,
+	stream pbevents.ExecutionEvents_GetEventsServer) error {
+
+	buf := new(pbevents.GetEventsResponse)
+
+	blockRange := request.GetBlockRange()
+	batchSize := request.GetBatchSize()
+	start, end := blockRange.Bounds()
+	ch, err := ees.eventsProvider.GetEvents(start, end, query.NewBuilder(request.Query))
+	if err != nil {
+		return err
+	}
+	for ev := range ch {
+		buf.Events = append(buf.Events, pbevents.GetEvent(ev))
+		if batchSize == 0 || uint32(len(buf.Events))%batchSize == 0 {
+			err := stream.Send(buf)
+			if err != nil {
+				return err
+			}
+			buf = new(pbevents.GetEventsResponse)
+		}
+	}
+
+	if len(buf.Events) > 0 {
+		err := stream.Send(buf)
+		if err != nil {
+			return err
+		}
+	}
+	return nil
 }
diff --git a/rpc/rpcevents/integration/execution_events_server_test.go b/rpc/rpcevents/integration/execution_events_server_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..a5ffcd44a539b60d3e302d9dd256cf7e3047a599
--- /dev/null
+++ b/rpc/rpcevents/integration/execution_events_server_test.go
@@ -0,0 +1,116 @@
+// +build integration
+
+// Space above here matters
+// Copyright 2017 Monax Industries Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package integration
+
+import (
+	"context"
+	"testing"
+
+	"io"
+
+	"github.com/hyperledger/burrow/event"
+	"github.com/hyperledger/burrow/event/query"
+	"github.com/hyperledger/burrow/execution/events"
+	"github.com/hyperledger/burrow/execution/events/pbevents"
+	"github.com/hyperledger/burrow/execution/pbtransactor"
+	"github.com/hyperledger/burrow/rpc/test"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+var committedTxCountIndex = 0
+var inputAccount = &pbtransactor.InputAccount{Address: privateAccounts[0].Address().Bytes()}
+
+func TestSend(t *testing.T) {
+	tcli := test.NewTransactorClient(t)
+	numSends := 1500
+	countCh := test.CommittedTxCount(t, kern.Emitter, &committedTxCountIndex)
+	for i := 0; i < numSends; i++ {
+		send, err := tcli.Send(context.Background(), &pbtransactor.SendParam{
+			InputAccount: inputAccount,
+			Amount:       2003,
+			ToAddress:    privateAccounts[3].Address().Bytes(),
+		})
+		require.NoError(t, err)
+		assert.Equal(t, false, send.CreatesContract)
+	}
+	require.Equal(t, numSends, <-countCh)
+
+	ecli := test.NewExecutionEventsClient(t)
+
+	evs, err := ecli.GetEvents(context.Background(), &pbevents.GetEventsRequest{
+		BlockRange: pbevents.SimpleBlockRange(0, 100),
+	})
+	require.NoError(t, err)
+	i := 0
+	for {
+		resp, err := evs.Recv()
+		if err != nil {
+			if err == io.EOF {
+				break
+			}
+			require.NoError(t, err)
+		}
+		for _, ev := range resp.Events {
+			assert.Len(t, ev.Header.TxHash, 20)
+			i++
+		}
+	}
+	// Input/output events for each
+	assert.Equal(t, numSends*2, i)
+}
+
+func TestSendFiltered(t *testing.T) {
+	tcli := test.NewTransactorClient(t)
+	numSends := 1500
+	countCh := test.CommittedTxCount(t, kern.Emitter, &committedTxCountIndex)
+	for i := 0; i < numSends; i++ {
+		send, err := tcli.Send(context.Background(), &pbtransactor.SendParam{
+			InputAccount: inputAccount,
+			Amount:       2003,
+			ToAddress:    privateAccounts[3].Address().Bytes(),
+		})
+		require.NoError(t, err)
+		assert.Equal(t, false, send.CreatesContract)
+	}
+	require.Equal(t, numSends, <-countCh)
+
+	ecli := test.NewExecutionEventsClient(t)
+
+	evs, err := ecli.GetEvents(context.Background(), &pbevents.GetEventsRequest{
+		BlockRange: pbevents.SimpleBlockRange(0, 100),
+		Query:      query.NewBuilder().AndEquals(event.EventTypeKey, events.TypeAccountInput.String()).String(),
+	})
+	require.NoError(t, err)
+	i := 0
+	for {
+		resp, err := evs.Recv()
+		if err != nil {
+			if err == io.EOF {
+				break
+			}
+			require.NoError(t, err)
+		}
+		for _, ev := range resp.Events {
+			assert.Len(t, ev.Header.TxHash, 20)
+			i++
+		}
+	}
+	// Should only get input events
+	assert.Equal(t, numSends, i)
+}
diff --git a/rpc/rpcevents/integration/main_test.go b/rpc/rpcevents/integration/main_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..a83a08b5158c70bc5236c3a042e1e6ceab4eb827
--- /dev/null
+++ b/rpc/rpcevents/integration/main_test.go
@@ -0,0 +1,42 @@
+// +build integration
+
+// Space above here matters
+// Copyright 2017 Monax Industries Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package integration
+
+import (
+	"os"
+	"testing"
+	"time"
+
+	"github.com/hyperledger/burrow/core"
+	"github.com/hyperledger/burrow/core/integration"
+)
+
+var privateAccounts = integration.MakePrivateAccounts(5) // make keys
+var genesisDoc = integration.TestGenesisDoc(privateAccounts)
+var kern *core.Kernel
+
+// Needs to be in a _test.go file to be picked up
+func TestMain(m *testing.M) {
+	returnValue := integration.TestWrapper(privateAccounts, genesisDoc, func(k *core.Kernel) int {
+		kern = k
+		return m.Run()
+	})
+
+	time.Sleep(3 * time.Second)
+	os.Exit(returnValue)
+}
diff --git a/rpc/rpctransactor/integration/strange_loop.go b/rpc/rpctransactor/integration/strange_loop.go
deleted file mode 100644
index f8137df9465c72ab725616c6463092a4006d9db0..0000000000000000000000000000000000000000
--- a/rpc/rpctransactor/integration/strange_loop.go
+++ /dev/null
@@ -1,3 +0,0 @@
-package integration
-
-const strangeLoopBytecode = "60606040526017600055602260015560116002556001600360006101000a81548160ff021916908315150217905550341561003957600080fd5b6102c9806100486000396000f300606060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063ebb384dd14610046575b600080fd5b341561005157600080fd5b61005961006f565b6040518082815260200191505060405180910390f35b60006002549050600360009054906101000a900460ff16156101cf57600154600254121561012e5760026000815480929190600101919050555060025490503073ffffffffffffffffffffffffffffffffffffffff1663ebb384dd6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b151561011157600080fd5b5af1151561011e57600080fd5b50505060405180519050506101ca565b6000600360006101000a81548160ff02191690831515021790555060025490503073ffffffffffffffffffffffffffffffffffffffff1663ebb384dd6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15156101b157600080fd5b5af115156101be57600080fd5b50505060405180519050505b610299565b6000546002541315610273576002600081548092919060019003919050555060025490503073ffffffffffffffffffffffffffffffffffffffff1663ebb384dd6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b151561025657600080fd5b5af1151561026357600080fd5b5050506040518051905050610298565b6001600360006101000a81548160ff021916908315150217905550600254905061029a565b5b5b905600a165627a7a7230582071446a8de59540361bd59bb4f5a84f884006f53e50c1c89d2bfbdb72f92fd4700029"
diff --git a/rpc/rpctransactor/integration/transactor_server_test.go b/rpc/rpctransactor/integration/transactor_server_test.go
index 810989cbd6f03d651e741d688b6e863e70d3ddee..b970f85c31d223f9a6c0e96416ed916fa8a6f9fd 100644
--- a/rpc/rpctransactor/integration/transactor_server_test.go
+++ b/rpc/rpctransactor/integration/transactor_server_test.go
@@ -29,6 +29,7 @@ import (
 	"github.com/hyperledger/burrow/execution/evm/abi"
 	"github.com/hyperledger/burrow/execution/pbtransactor"
 	"github.com/hyperledger/burrow/rpc"
+	"github.com/hyperledger/burrow/rpc/test"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 	"github.com/tendermint/tendermint/types"
@@ -65,7 +66,7 @@ func TestTransactCreate(t *testing.T) {
 	wg := new(sync.WaitGroup)
 	wg.Add(numGoroutines)
 	// Flip flops between sending private key and input address to test private key and address based signing
-	bc, err := hex.DecodeString(strangeLoopBytecode)
+	bc, err := hex.DecodeString(test.StrangeLoopByteCode)
 	require.NoError(t, err)
 	countCh := committedTxCount(t)
 	for i := 0; i < numGoroutines; i++ {
@@ -92,7 +93,7 @@ func TestTransactCreate(t *testing.T) {
 
 func BenchmarkTransactCreateContract(b *testing.B) {
 	cli := newClient(b)
-	bc, err := hex.DecodeString(strangeLoopBytecode)
+	bc, err := hex.DecodeString(test.StrangeLoopByteCode)
 	require.NoError(b, err)
 	for i := 0; i < b.N; i++ {
 		create, err := cli.Transact(context.Background(), &pbtransactor.TransactParam{
@@ -109,7 +110,7 @@ func BenchmarkTransactCreateContract(b *testing.B) {
 
 func TestTransactAndHold(t *testing.T) {
 	cli := newClient(t)
-	bc, err := hex.DecodeString(strangeLoopBytecode)
+	bc, err := hex.DecodeString(test.StrangeLoopByteCode)
 	require.NoError(t, err)
 	numGoroutines := 5
 	numRuns := 2
diff --git a/rpc/test/helpers.go b/rpc/test/helpers.go
new file mode 100644
index 0000000000000000000000000000000000000000..e0091353ae9756a2bbc37eda4554135106ae5664
--- /dev/null
+++ b/rpc/test/helpers.go
@@ -0,0 +1,59 @@
+package test
+
+import (
+	"context"
+	"fmt"
+	"testing"
+
+	"github.com/hyperledger/burrow/consensus/tendermint"
+	"github.com/hyperledger/burrow/event"
+	"github.com/hyperledger/burrow/execution/events/pbevents"
+	"github.com/hyperledger/burrow/execution/pbtransactor"
+	"github.com/hyperledger/burrow/rpc"
+	"github.com/stretchr/testify/require"
+	"github.com/tendermint/tendermint/types"
+	"google.golang.org/grpc"
+)
+
+// Helpers
+func NewTransactorClient(t testing.TB) pbtransactor.TransactorClient {
+	conn, err := grpc.Dial(rpc.DefaultGRPCConfig().ListenAddress, grpc.WithInsecure())
+	require.NoError(t, err)
+	return pbtransactor.NewTransactorClient(conn)
+}
+
+func NewExecutionEventsClient(t testing.TB) pbevents.ExecutionEventsClient {
+	conn, err := grpc.Dial(rpc.DefaultGRPCConfig().ListenAddress, grpc.WithInsecure())
+	require.NoError(t, err)
+	return pbevents.NewExecutionEventsClient(conn)
+}
+
+func CommittedTxCount(t *testing.T, em event.Emitter, committedTxCountIndex *int) chan int {
+	var numTxs int64
+	emptyBlocks := 0
+	maxEmptyBlocks := 2
+	outCh := make(chan int)
+	ch := make(chan *types.EventDataNewBlock)
+	ctx := context.Background()
+	subscriber := fmt.Sprintf("committedTxCount_%v", *committedTxCountIndex)
+	*committedTxCountIndex++
+	require.NoError(t, tendermint.SubscribeNewBlock(ctx, em, subscriber, ch))
+
+	go func() {
+		for ed := range ch {
+			if ed.Block.NumTxs == 0 {
+				emptyBlocks++
+			} else {
+				emptyBlocks = 0
+			}
+			if emptyBlocks > maxEmptyBlocks {
+				break
+			}
+			numTxs += ed.Block.NumTxs
+			t.Logf("Total TXs committed at block %v: %v (+%v)\n", ed.Block.Height, numTxs, ed.Block.NumTxs)
+		}
+		require.NoError(t, em.UnsubscribeAll(ctx, subscriber))
+		outCh <- int(numTxs)
+	}()
+	return outCh
+}
diff --git a/rpc/v0/integration/strange_loop.go b/rpc/test/strange_loop.go
similarity index 94%
rename from rpc/v0/integration/strange_loop.go
rename to rpc/test/strange_loop.go
index f8137df9465c72ab725616c6463092a4006d9db0..7d30938f339d3055d1fe968918fe4e6a871c0e17 100644
--- a/rpc/v0/integration/strange_loop.go
+++ b/rpc/test/strange_loop.go
@@ -1,3 +1,3 @@
-package integration
+package test
 
-const strangeLoopBytecode = "60606040526017600055602260015560116002556001600360006101000a81548160ff021916908315150217905550341561003957600080fd5b6102c9806100486000396000f300606060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063ebb384dd14610046575b600080fd5b341561005157600080fd5b61005961006f565b6040518082815260200191505060405180910390f35b60006002549050600360009054906101000a900460ff16156101cf57600154600254121561012e5760026000815480929190600101919050555060025490503073ffffffffffffffffffffffffffffffffffffffff1663ebb384dd6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b151561011157600080fd5b5af1151561011e57600080fd5b50505060405180519050506101ca565b6000600360006101000a81548160ff02191690831515021790555060025490503073ffffffffffffffffffffffffffffffffffffffff1663ebb384dd6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15156101b157600080fd5b5af115156101be57600080fd5b50505060405180519050505b610299565b6000546002541315610273576002600081548092919060019003919050555060025490503073ffffffffffffffffffffffffffffffffffffffff1663ebb384dd6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b151561025657600080fd5b5af1151561026357600080fd5b5050506040518051905050610298565b6001600360006101000a81548160ff021916908315150217905550600254905061029a565b5b5b905600a165627a7a7230582071446a8de59540361bd59bb4f5a84f884006f53e50c1c89d2bfbdb72f92fd4700029"
+const StrangeLoopByteCode = "60606040526017600055602260015560116002556001600360006101000a81548160ff021916908315150217905550341561003957600080fd5b6102c9806100486000396000f300606060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063ebb384dd14610046575b600080fd5b341561005157600080fd5b61005961006f565b6040518082815260200191505060405180910390f35b60006002549050600360009054906101000a900460ff16156101cf57600154600254121561012e5760026000815480929190600101919050555060025490503073ffffffffffffffffffffffffffffffffffffffff1663ebb384dd6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b151561011157600080fd5b5af1151561011e57600080fd5b50505060405180519050506101ca565b6000600360006101000a81548160ff02191690831515021790555060025490503073ffffffffffffffffffffffffffffffffffffffff1663ebb384dd6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15156101b157600080fd5b5af115156101be57600080fd5b50505060405180519050505b610299565b6000546002541315610273576002600081548092919060019003919050555060025490503073ffffffffffffffffffffffffffffffffffffffff1663ebb384dd6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b151561025657600080fd5b5af1151561026357600080fd5b5050506040518051905050610298565b6001600360006101000a81548160ff021916908315150217905550600254905061029a565b5b5b905600a165627a7a7230582071446a8de59540361bd59bb4f5a84f884006f53e50c1c89d2bfbdb72f92fd4700029"
diff --git a/rpc/rpctransactor/integration/strange_loop.sh b/rpc/test/strange_loop.sh
similarity index 100%
rename from rpc/rpctransactor/integration/strange_loop.sh
rename to rpc/test/strange_loop.sh
diff --git a/rpc/rpctransactor/integration/strange_loop.sol b/rpc/test/strange_loop.sol
similarity index 100%
rename from rpc/rpctransactor/integration/strange_loop.sol
rename to rpc/test/strange_loop.sol
diff --git a/rpc/tm/integration/client_test.go b/rpc/tm/integration/server_test.go
similarity index 100%
rename from rpc/tm/integration/client_test.go
rename to rpc/tm/integration/server_test.go
diff --git a/rpc/tm/integration/websocket_helpers.go b/rpc/tm/integration/websocket_helpers.go
index bd00cf7a115253742afa92b1cb180239d4d070c2..6e19d8fee2f0c83328fe2c3b4cc361bc388ec010 100644
--- a/rpc/tm/integration/websocket_helpers.go
+++ b/rpc/tm/integration/websocket_helpers.go
@@ -314,9 +314,9 @@ func unmarshalValidateCall(origin crypto.Address, returnCode []byte, txid *[]byt
 		if !bytes.Equal(ret, returnCode) {
 			return true, fmt.Errorf("call did not return correctly. Got %x, expected %x", ret, returnCode)
 		}
-		if !bytes.Equal(data.TxHash, *txid) {
+		if !bytes.Equal(resultEvent.Execution.Header.TxHash, *txid) {
 			return true, fmt.Errorf("TxIDs do not match up! Got %x, expected %x",
-				data.TxHash, *txid)
+				resultEvent.Execution.Header.TxHash, *txid)
 		}
 		return true, nil
 	}
diff --git a/rpc/v0/integration/main_test.go b/rpc/v0/integration/main_test.go
index 5a0375653533e0e49b14512aca4d1517115783fc..a83a08b5158c70bc5236c3a042e1e6ceab4eb827 100644
--- a/rpc/v0/integration/main_test.go
+++ b/rpc/v0/integration/main_test.go
@@ -28,12 +28,12 @@ import (
 
 var privateAccounts = integration.MakePrivateAccounts(5) // make keys
 var genesisDoc = integration.TestGenesisDoc(privateAccounts)
-var kernel *core.Kernel
+var kern *core.Kernel
 
 // Needs to be in a _test.go file to be picked up
 func TestMain(m *testing.M) {
-	returnValue := integration.TestWrapper(privateAccounts, genesisDoc, func(kern *core.Kernel) int {
-		kernel = kern
+	returnValue := integration.TestWrapper(privateAccounts, genesisDoc, func(k *core.Kernel) int {
+		kern = k
 		return m.Run()
 	})
 
diff --git a/rpc/v0/integration/strange_loop.sh b/rpc/v0/integration/strange_loop.sh
deleted file mode 100755
index d0cf04eecf86779b63ccdfb604aeee15792a52ec..0000000000000000000000000000000000000000
--- a/rpc/v0/integration/strange_loop.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/env bash
-
-script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-
-echo -e "package integration\n\nconst strangeLoopBytecode = \"$(solc --bin rpc/v0/integration/strange_loop.sol | tail -1)\"" > "${script_dir}/strange_loop.go"
diff --git a/rpc/v0/integration/strange_loop.sol b/rpc/v0/integration/strange_loop.sol
deleted file mode 100644
index 2a3e07f242d5da224a6e5a9e502c8df38e308a39..0000000000000000000000000000000000000000
--- a/rpc/v0/integration/strange_loop.sol
+++ /dev/null
@@ -1,31 +0,0 @@
-pragma solidity ^0.4.16;
-
-contract StrangeLoop {
-    int top = 23;
-    int bottom = 34;
-    int depth = 17;
-    bool down = true;
-
-    function UpsieDownsie() public returns (int i) {
-        i = depth;
-        if (down) {
-            if (depth < bottom) {
-                depth++;
-                i = depth;
-                this.UpsieDownsie();
-            } else {
-                down = false;
-                i = depth;
-                this.UpsieDownsie();
-            }
-        } else if (depth > top) {
-            depth--;
-            i = depth;
-            this.UpsieDownsie();
-        } else {
-            down = true;
-            i = depth;
-            return;
-        }
-    }
-}
\ No newline at end of file
diff --git a/rpc/v0/integration/v0_test.go b/rpc/v0/integration/v0_test.go
index 5b280a759d4c0069d4d25a93575c9b1b8a002302..b75594cc88fb0d7c2975d5355c6b4047419ed0dd 100644
--- a/rpc/v0/integration/v0_test.go
+++ b/rpc/v0/integration/v0_test.go
@@ -18,19 +18,16 @@
 package integration
 
 import (
-	"context"
 	"encoding/hex"
-	"fmt"
 	"sync"
 	"testing"
 
 	"github.com/hyperledger/burrow/binary"
-	"github.com/hyperledger/burrow/consensus/tendermint"
 	"github.com/hyperledger/burrow/execution/evm/abi"
+	"github.com/hyperledger/burrow/rpc/test"
 	"github.com/hyperledger/burrow/rpc/v0"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
-	"github.com/tendermint/tendermint/types"
 )
 
 func TestTransactCallNoCode(t *testing.T) {
@@ -40,7 +37,7 @@ func TestTransactCallNoCode(t *testing.T) {
 	toAddress := privateAccounts[2].Address()
 
 	numCreates := 1000
-	countCh := committedTxCount(t)
+	countCh := test.CommittedTxCount(t, kern.Emitter, &committedTxCountIndex)
 	for i := 0; i < numCreates; i++ {
 		receipt, err := cli.Transact(v0.TransactParam{
 			InputAccount: inputAccount(i),
@@ -63,9 +60,9 @@ func TestTransactCreate(t *testing.T) {
 	wg.Add(numGoroutines)
 	cli := v0.NewV0Client("http://localhost:1337/rpc")
 	// Flip flops between sending private key and input address to test private key and address based signing
-	bc, err := hex.DecodeString(strangeLoopBytecode)
+	bc, err := hex.DecodeString(test.StrangeLoopByteCode)
 	require.NoError(t, err)
-	countCh := committedTxCount(t)
+	countCh := test.CommittedTxCount(t, kern.Emitter, &committedTxCountIndex)
 	for i := 0; i < numGoroutines; i++ {
 		go func() {
 			for j := 0; j < numCreates; j++ {
@@ -91,7 +88,7 @@ func TestTransactCreate(t *testing.T) {
 func BenchmarkTransactCreateContract(b *testing.B) {
 	cli := v0.NewV0Client("http://localhost:1337/rpc")
 
-	bc, err := hex.DecodeString(strangeLoopBytecode)
+	bc, err := hex.DecodeString(test.StrangeLoopByteCode)
 	require.NoError(b, err)
 	for i := 0; i < b.N; i++ {
 		create, err := cli.Transact(v0.TransactParam{
@@ -108,12 +105,12 @@ func BenchmarkTransactCreateContract(b *testing.B) {
 
 func TestTransactAndHold(t *testing.T) {
 	cli := v0.NewV0Client("http://localhost:1337/rpc")
-	bc, err := hex.DecodeString(strangeLoopBytecode)
+	bc, err := hex.DecodeString(test.StrangeLoopByteCode)
 	require.NoError(t, err)
 
 	numGoroutines := 5
 	numRuns := 2
-	countCh := committedTxCount(t)
+	countCh := test.CommittedTxCount(t, kern.Emitter, &committedTxCountIndex)
 	for i := 0; i < numGoroutines; i++ {
 		for j := 0; j < numRuns; j++ {
 			create, err := cli.TransactAndHold(v0.TransactParam{
@@ -144,9 +141,8 @@ func TestTransactAndHold(t *testing.T) {
 
 func TestSend(t *testing.T) {
 	cli := v0.NewV0Client("http://localhost:1337/rpc")
-
 	numSends := 1000
-	countCh := committedTxCount(t)
+	countCh := test.CommittedTxCount(t, kern.Emitter, &committedTxCountIndex)
 	for i := 0; i < numSends; i++ {
 		send, err := cli.Send(v0.SendParam{
 			InputAccount: inputAccount(i),
@@ -177,36 +173,6 @@ func TestSendAndHold(t *testing.T) {
 
 var committedTxCountIndex = 0
 
-func committedTxCount(t *testing.T) chan int {
-	var numTxs int64
-	emptyBlocks := 0
-	maxEmptyBlocks := 2
-	outCh := make(chan int)
-	ch := make(chan *types.EventDataNewBlock)
-	ctx := context.Background()
-	subscriber := fmt.Sprintf("committedTxCount_%v", committedTxCountIndex)
-	committedTxCountIndex++
-	require.NoError(t, tendermint.SubscribeNewBlock(ctx, kernel.Emitter, subscriber, ch))
-
-	go func() {
-		for ed := range ch {
-			if ed.Block.NumTxs == 0 {
-				emptyBlocks++
-			} else {
-				emptyBlocks = 0
-			}
-			if emptyBlocks > maxEmptyBlocks {
-				break
-			}
-			numTxs += ed.Block.NumTxs
-			t.Logf("Total TXs committed at block %v: %v (+%v)\n", ed.Block.Height, numTxs, ed.Block.NumTxs)
-		}
-		require.NoError(t, kernel.Emitter.UnsubscribeAll(ctx, subscriber))
-		outCh <- int(numTxs)
-	}()
-	return outCh
-}
-
 var inputPrivateKey = privateAccounts[0].PrivateKey().RawBytes()
 var inputAddress = privateAccounts[0].Address().Bytes()
 
diff --git a/scripts/deps/bos.sh b/scripts/deps/bos.sh
index 83f969127237163fb89d6bcbe5ce09ea44940151..19645c8504ce598542a4a466a18b75409cef7704 100755
--- a/scripts/deps/bos.sh
+++ b/scripts/deps/bos.sh
@@ -2,4 +2,5 @@
 
 # The git revision of Bosmarmot/bos we will build and install into ./bin/ for integration tests
 
-echo "4731b612c040e8b0ab7c6cbab3eb0b2fe0e49298"
+echo "36b811cb86272eba79b64bd16ffcd3a1e378f468"
+
diff --git a/txs/payload/payload.go b/txs/payload/payload.go
index e1c2433d621ad5576bcf775ff72d99355813defb..cc0c5e181466e3d76eeb33da2495fb0f4e0faedf 100644
--- a/txs/payload/payload.go
+++ b/txs/payload/payload.go
@@ -54,6 +54,27 @@ func init() {
 	}
 }
 
+func TxTypeFromString(name string) Type {
+	return typeFromName[name]
+}
+
+func (typ Type) String() string {
+	name, ok := nameFromType[typ]
+	if ok {
+		return name
+	}
+	return "UnknownTx"
+}
+
+func (typ Type) MarshalText() ([]byte, error) {
+	return []byte(typ.String()), nil
+}
+
+func (typ *Type) UnmarshalText(data []byte) error {
+	*typ = TxTypeFromString(string(data))
+	return nil
+}
+
 type Payload interface {
 	String() string
 	GetInputs() []*TxInput
@@ -77,24 +98,3 @@ func New(txType Type) Payload {
 	}
 	return nil
 }
-
-func TxTypeFromString(name string) Type {
-	return typeFromName[name]
-}
-
-func (typ Type) String() string {
-	name, ok := nameFromType[typ]
-	if ok {
-		return name
-	}
-	return "UnknownTx"
-}
-
-func (typ Type) MarshalText() ([]byte, error) {
-	return []byte(typ.String()), nil
-}
-
-func (typ *Type) UnmarshalText(data []byte) error {
-	*typ = TxTypeFromString(string(data))
-	return nil
-}
diff --git a/txs/tx.go b/txs/tx.go
index c80fac1a7fbe3df553521d8cd20610b2170b81d6..0025a449e94ccf2a60aa4ee7bc9e0ac6d724aba2 100644
--- a/txs/tx.go
+++ b/txs/tx.go
@@ -34,12 +34,6 @@ type Tx struct {
 
 // Wrap the Payload in Tx required for signing and serialisation
 func NewTx(payload payload.Payload) *Tx {
-	switch t := payload.(type) {
-	case Tx:
-		return &t
-	case *Tx:
-		return t
-	}
 	return &Tx{
 		Payload: payload,
 	}
@@ -111,9 +105,19 @@ func (tx *Tx) UnmarshalJSON(data []byte) error {
 	return json.Unmarshal(w.Payload, tx.Payload)
 }
 
+func (tx *Tx) Type() payload.Type {
+	if tx == nil {
+		return payload.TypeUnknown
+	}
+	return tx.Payload.Type()
+}
+
 // Generate a Hash for this transaction based on the SignBytes. The hash is memoized over the lifetime
 // of the Tx so repeated calls to Hash() are effectively free
 func (tx *Tx) Hash() []byte {
+	if tx == nil {
+		return nil
+	}
 	if tx.txHash == nil {
 		return tx.Rehash()
 	}