From 442e67730026f99e6991e32d11a20b83eee6e7a6 Mon Sep 17 00:00:00 2001 From: mossid Date: Tue, 10 Apr 2018 17:04:27 +0200 Subject: [PATCH 1/4] add CacheContext --- types/context.go | 11 +++++++++-- types/context_test.go | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/types/context.go b/types/context.go index 3c90b016a..85eb9e493 100644 --- a/types/context.go +++ b/types/context.go @@ -16,12 +16,13 @@ The intent of Context is for it to be an immutable object that can be cloned and updated cheaply with WithValue() and passed forward to the next decorator or handler. For example, - func MsgHandler(ctx Context, tx Tx) Result { + func MsgHandler(context Context, tx Tx) Result { ... - ctx = ctx.WithValue(key, value) + context = context.WithValue(key, value) ... } */ + type Context struct { context.Context pst *thePast @@ -171,6 +172,12 @@ func (c Context) WithTxBytes(txBytes []byte) Context { return c.withValue(contextKeyTxBytes, txBytes) } +func (c Context) CacheContext() (Context, func()) { + cms := c.multiStore().CacheMultiStore() + cc := c.WithMultiStore(cms) + return cc, cms.Write +} + //---------------------------------------- // thePast diff --git a/types/context_test.go b/types/context_test.go index 36d8099b9..b40e79dc2 100644 --- a/types/context_test.go +++ b/types/context_test.go @@ -3,6 +3,11 @@ package types_test import ( "testing" + "github.com/stretchr/testify/assert" + + dbm "github.com/tendermint/tmlibs/db" + + "github.com/cosmos/cosmos-sdk/store" "github.com/cosmos/cosmos-sdk/types" abci "github.com/tendermint/abci/types" ) @@ -18,3 +23,39 @@ func TestContextGetOpShouldNeverPanic(t *testing.T) { _, _ = ctx.GetOp(index) } } + +func defaultContext(key types.StoreKey) types.Context { + db := dbm.NewMemDB() + cms := store.NewCommitMultiStore(db) + cms.MountStoreWithDB(key, types.StoreTypeIAVL, db) + cms.LoadLatestVersion() + ctx := types.NewContext(cms, abci.Header{}, false, nil) + return ctx +} + +func TestCacheContext(t *testing.T) { + key := types.NewKVStoreKey(t.Name()) + k1 := []byte("hello") + v1 := []byte("world") + k2 := []byte("key") + v2 := []byte("value") + + ctx := defaultContext(key) + store := ctx.KVStore(key) + store.Set(k1, v1) + assert.Equal(t, v1, store.Get(k1)) + assert.Nil(t, store.Get(k2)) + + cctx, write := ctx.CacheContext() + cstore := cctx.KVStore(key) + assert.Equal(t, v1, cstore.Get(k1)) + assert.Nil(t, cstore.Get(k2)) + + cstore.Set(k2, v2) + assert.Equal(t, v2, cstore.Get(k2)) + assert.Nil(t, store.Get(k2)) + + write() + + assert.Equal(t, v2, store.Get(k2)) +} From 8ed15f7e9d33d1127107c1f445311fe50dbfac08 Mon Sep 17 00:00:00 2001 From: mossid Date: Tue, 10 Apr 2018 17:06:02 +0200 Subject: [PATCH 2/4] typo --- types/context.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/types/context.go b/types/context.go index 85eb9e493..a6d6b3c3b 100644 --- a/types/context.go +++ b/types/context.go @@ -16,9 +16,9 @@ The intent of Context is for it to be an immutable object that can be cloned and updated cheaply with WithValue() and passed forward to the next decorator or handler. For example, - func MsgHandler(context Context, tx Tx) Result { + func MsgHandler(ctx Context, tx Tx) Result { ... - context = context.WithValue(key, value) + ctx = context.WithValue(key, value) ... } */ From 1c8094c6bde1a137422be2a77480e91154011781 Mon Sep 17 00:00:00 2001 From: Joon Date: Tue, 10 Apr 2018 17:07:54 +0200 Subject: [PATCH 3/4] Update context.go --- types/context.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/context.go b/types/context.go index a6d6b3c3b..1ec81ca0e 100644 --- a/types/context.go +++ b/types/context.go @@ -18,7 +18,7 @@ next decorator or handler. For example, func MsgHandler(ctx Context, tx Tx) Result { ... - ctx = context.WithValue(key, value) + ctx = ctx.WithValue(key, value) ... } */ From bdc7fe56bac8bf4e1d74d505b792d4b7117284a1 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Tue, 10 Apr 2018 15:44:49 -0400 Subject: [PATCH 4/4] cachecontext comments and changelog update --- CHANGELOG.md | 4 ++++ types/context.go | 7 ++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79cb396c6..2801c932b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ BREAKING CHANGES * Remove go-wire, use go-amino * [store] Add `SubspaceIterator` and `ReverseSubspaceIterator` to `KVStore` interface +FEATURES: + +* Add CacheContext + ## 0.14.1 (April 9, 2018) BUG FIXES diff --git a/types/context.go b/types/context.go index 1ec81ca0e..8c91175bc 100644 --- a/types/context.go +++ b/types/context.go @@ -22,7 +22,6 @@ next decorator or handler. For example, ... } */ - type Context struct { context.Context pst *thePast @@ -172,9 +171,11 @@ func (c Context) WithTxBytes(txBytes []byte) Context { return c.withValue(contextKeyTxBytes, txBytes) } -func (c Context) CacheContext() (Context, func()) { +// Cache the multistore and return a new cached context. The cached context is +// written to the context when writeCache is called. +func (c Context) CacheContext() (cc Context, writeCache func()) { cms := c.multiStore().CacheMultiStore() - cc := c.WithMultiStore(cms) + cc = c.WithMultiStore(cms) return cc, cms.Write }