diff --git a/erisdb/serve.go b/erisdb/serve.go
index 478ae9aa7b3a1b09d79e7b6dab45ae5fbd2df481..ec998c56feba1fef9f0ec1b5b9272bb8228b025b 100644
--- a/erisdb/serve.go
+++ b/erisdb/serve.go
@@ -19,6 +19,7 @@ import (
 	"github.com/tendermint/tendermint/node"
 
 	ep "github.com/eris-ltd/eris-db/erisdb/pipe"
+	evm "github.com/eris-ltd/eris-db/evm"
 	"github.com/eris-ltd/eris-db/server"
 
 	edbapp "github.com/eris-ltd/eris-db/tmsp"
@@ -105,6 +106,8 @@ func ServeErisDB(workDir string) (*server.ServeProcess, error) {
 	app := edbapp.NewErisDBApp(state, evsw)
 	app.SetHostAddress(sConf.Consensus.TendermintHost)
 
+	evm.SetDebug(sConf.Logging.VMLog)
+
 	// Start the tmsp listener for state update commands
 	go func() {
 		// TODO config
diff --git a/evm/vm.go b/evm/vm.go
index af947fbc3456d1df428f1d68fd27d690a8d64c68..656350bf5e7c653da00722e58598ed3f9d21b73d 100644
--- a/evm/vm.go
+++ b/evm/vm.go
@@ -36,15 +36,20 @@ func (err ErrPermission) Error() string {
 	return fmt.Sprintf("Contract does not have permission to %s", err.typ)
 }
 
-type Debug bool
-
 const (
-	dataStackCapacity       = 1024
-	callStackCapacity       = 100         // TODO ensure usage.
-	memoryCapacity          = 1024 * 1024 // 1 MB
-	dbg               Debug = true
+	dataStackCapacity = 1024
+	callStackCapacity = 100         // TODO ensure usage.
+	memoryCapacity    = 1024 * 1024 // 1 MB
 )
 
+type Debug bool
+
+var dbg Debug
+
+func SetDebug(d bool) {
+	dbg = Debug(d)
+}
+
 func (d Debug) Printf(s string, a ...interface{}) {
 	if d {
 		fmt.Printf(s, a...)
diff --git a/server/config.go b/server/config.go
index 7354408ff26e997e04da58191c5fb41ee86f449c..24b948926c9f153defb2f361e9850ad8512a2ce6 100644
--- a/server/config.go
+++ b/server/config.go
@@ -54,6 +54,7 @@ type (
 		ConsoleLogLevel string `toml:"console_log_level"`
 		FileLogLevel    string `toml:"file_log_level"`
 		LogFile         string `toml:"log_file"`
+		VMLog           bool   `toml:"vm_log"`
 	}
 
 	Consensus struct {
diff --git a/tmsp/erisdb.go b/tmsp/erisdb.go
index f649a48807145f61b6031ca106112c0f6fe0e464..514f219806b8e8101aa56f8b754870626cff7b87 100644
--- a/tmsp/erisdb.go
+++ b/tmsp/erisdb.go
@@ -35,6 +35,8 @@ type ErisDBApp struct {
 	// client to the tendermint core rpc
 	client *client.ClientURI
 	host   string // tendermint core endpoint
+
+	nTxs int // count txs in a block
 }
 
 func (app *ErisDBApp) GetState() *sm.State {
@@ -43,18 +45,13 @@ func (app *ErisDBApp) GetState() *sm.State {
 	return app.state.Copy()
 }
 
+// TODO: this is used for call/callcode and to get nonces during mempool.
+// the former should work on last committed state only and the later should
+// be handled by the client, or a separate wallet-like nonce tracker thats not part of the app
 func (app *ErisDBApp) GetCheckCache() *sm.BlockCache {
-	app.mtx.Lock()
-	defer app.mtx.Unlock()
 	return app.checkCache
 }
 
-func (app *ErisDBApp) ResetCheckCache() {
-	app.mtx.Lock()
-	defer app.mtx.Unlock()
-	app.checkCache = sm.NewBlockCache(app.state)
-}
-
 func (app *ErisDBApp) SetHostAddress(host string) {
 	app.host = host
 	app.client = client.NewClientURI(host) //fmt.Sprintf("http://%s", host))
@@ -100,7 +97,10 @@ func (app *ErisDBApp) SetOption(key string, value string) (log string) {
 }
 
 // Implements tmsp.Application
-func (app ErisDBApp) AppendTx(txBytes []byte) (res tmsp.Result) {
+func (app *ErisDBApp) AppendTx(txBytes []byte) (res tmsp.Result) {
+
+	app.nTxs += 1
+
 	// XXX: if we had tx ids we could cache the decoded txs on CheckTx
 	var n int
 	var err error
@@ -111,19 +111,17 @@ func (app ErisDBApp) AppendTx(txBytes []byte) (res tmsp.Result) {
 		return tmsp.NewError(tmsp.CodeType_EncodingError, fmt.Sprintf("Encoding error: %v", err))
 	}
 
+	log.Info("AppendTx", "tx", *tx)
+
 	err = sm.ExecTx(app.cache, *tx, true, app.evc)
 	if err != nil {
-		return tmsp.NewError(tmsp.CodeType_InternalError, fmt.Sprintf("Encoding error: %v", err))
+		return tmsp.NewError(tmsp.CodeType_InternalError, fmt.Sprintf("Internal error: %v", err))
 	}
 	return tmsp.NewResultOK(nil, "Success")
 }
 
 // Implements tmsp.Application
-func (app ErisDBApp) CheckTx(txBytes []byte) (res tmsp.Result) {
-	log.Info("Check Tx", "tx", txBytes)
-	defer func() {
-		log.Info("Check Tx", "res", res)
-	}()
+func (app *ErisDBApp) CheckTx(txBytes []byte) (res tmsp.Result) {
 	var n int
 	var err error
 	tx := new(types.Tx)
@@ -133,13 +131,12 @@ func (app ErisDBApp) CheckTx(txBytes []byte) (res tmsp.Result) {
 		return tmsp.NewError(tmsp.CodeType_EncodingError, fmt.Sprintf("Encoding error: %v", err))
 	}
 
-	// we need the lock because CheckTx can run concurrently with Commit,
-	// and Commit refreshes the checkCache
-	app.mtx.Lock()
-	defer app.mtx.Unlock()
+	log.Info("CheckTx", "tx", *tx)
+
+	// TODO: make errors tmsp aware
 	err = sm.ExecTx(app.checkCache, *tx, false, nil)
 	if err != nil {
-		return tmsp.NewError(tmsp.CodeType_InternalError, fmt.Sprintf("Encoding error: %v", err))
+		return tmsp.NewError(tmsp.CodeType_InternalError, fmt.Sprintf("Internal error: %v", err))
 	}
 
 	return tmsp.NewResultOK(nil, "Success")
@@ -147,12 +144,25 @@ func (app ErisDBApp) CheckTx(txBytes []byte) (res tmsp.Result) {
 
 // Implements tmsp.Application
 // Commit the state (called at end of block)
+// NOTE: CheckTx/AppendTx must not run concurrently with Commit -
+//	the mempool should run during AppendTxs, but lock for Commit and Update
 func (app *ErisDBApp) Commit() (res tmsp.Result) {
+	app.mtx.Lock() // the lock protects app.state
+	defer app.mtx.Unlock()
+
+	app.state.LastBlockHeight += 1
+	log.Info("Commit", "block", app.state.LastBlockHeight)
+
 	// sync the AppendTx cache
 	app.cache.Sync()
 
+	// if there were any txs in the block,
 	// reset the check cache to the new height
-	app.ResetCheckCache()
+	if app.nTxs > 0 {
+		log.Info("Reset checkCache", "txs", app.nTxs)
+		app.checkCache = sm.NewBlockCache(app.state)
+	}
+	app.nTxs = 0
 
 	// save state to disk
 	app.state.Save()