feat: add store name in `tracekv`-emitted store traces (#11646)
* feature: Clone and Merge methods on TraceContext * chore: use TraceContext.Merge method in SetTracingContext * feature: add Store name in TraceContext during execution * chore: update rootmulti Store TraceContext on *Store after Merge()
This commit is contained in:
parent
0dbf7dce06
commit
ce44b35cac
|
@ -13,6 +13,10 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/store/types"
|
||||
)
|
||||
|
||||
// storeNameCtxKey is the TraceContext metadata key that identifies
|
||||
// the store which emitted a given trace.
|
||||
const storeNameCtxKey = "store_name"
|
||||
|
||||
//----------------------------------------
|
||||
// Store
|
||||
|
||||
|
@ -52,7 +56,11 @@ func NewFromKVStore(
|
|||
|
||||
for key, store := range stores {
|
||||
if cms.TracingEnabled() {
|
||||
store = tracekv.NewStore(store.(types.KVStore), cms.traceWriter, cms.traceContext)
|
||||
tctx := cms.traceContext.Clone().Merge(types.TraceContext{
|
||||
storeNameCtxKey: key.Name(),
|
||||
})
|
||||
|
||||
store = tracekv.NewStore(store.(types.KVStore), cms.traceWriter, tctx)
|
||||
}
|
||||
if cms.ListeningEnabled(key) {
|
||||
store = listenkv.NewStore(store.(types.KVStore), key, listeners[key])
|
||||
|
|
|
@ -330,13 +330,7 @@ func (rs *Store) SetTracer(w io.Writer) types.MultiStore {
|
|||
func (rs *Store) SetTracingContext(tc types.TraceContext) types.MultiStore {
|
||||
rs.traceContextMutex.Lock()
|
||||
defer rs.traceContextMutex.Unlock()
|
||||
if rs.traceContext != nil {
|
||||
for k, v := range tc {
|
||||
rs.traceContext[k] = v
|
||||
}
|
||||
} else {
|
||||
rs.traceContext = tc
|
||||
}
|
||||
rs.traceContext = rs.traceContext.Merge(tc)
|
||||
|
||||
return rs
|
||||
}
|
||||
|
|
|
@ -418,6 +418,29 @@ type KVPair kv.Pair
|
|||
// every trace operation.
|
||||
type TraceContext map[string]interface{}
|
||||
|
||||
// Clone clones tc into another instance of TraceContext.
|
||||
func (tc TraceContext) Clone() TraceContext {
|
||||
ret := TraceContext{}
|
||||
for k, v := range tc {
|
||||
ret[k] = v
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
// Merge merges value of newTc into tc.
|
||||
func (tc TraceContext) Merge(newTc TraceContext) TraceContext {
|
||||
if tc == nil {
|
||||
tc = TraceContext{}
|
||||
}
|
||||
|
||||
for k, v := range newTc {
|
||||
tc[k] = v
|
||||
}
|
||||
|
||||
return tc
|
||||
}
|
||||
|
||||
// MultiStorePersistentCache defines an interface which provides inter-block
|
||||
// (persistent) caching capabilities for multiple CommitKVStores based on StoreKeys.
|
||||
type MultiStorePersistentCache interface {
|
||||
|
|
|
@ -90,3 +90,120 @@ func TestTransientStoreKey(t *testing.T) {
|
|||
require.Equal(t, key.name, key.Name())
|
||||
require.Equal(t, fmt.Sprintf("TransientStoreKey{%p, test}", key), key.String())
|
||||
}
|
||||
|
||||
func TestTraceContext_Clone(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
tc TraceContext
|
||||
want TraceContext
|
||||
}{
|
||||
{
|
||||
"nil TraceContext yields empty TraceContext",
|
||||
nil,
|
||||
TraceContext{},
|
||||
},
|
||||
{
|
||||
"non-nil TraceContext yields equal TraceContext",
|
||||
TraceContext{
|
||||
"value": 42,
|
||||
},
|
||||
TraceContext{
|
||||
"value": 42,
|
||||
},
|
||||
},
|
||||
{
|
||||
"non-nil TraceContext yields equal TraceContext, for more than one key",
|
||||
TraceContext{
|
||||
"value": 42,
|
||||
"another": 24,
|
||||
"weird": "string",
|
||||
},
|
||||
TraceContext{
|
||||
"value": 42,
|
||||
"another": 24,
|
||||
"weird": "string",
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
require.Equal(t, tt.want, tt.tc.Clone())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestTraceContext_Clone_is_deep(t *testing.T) {
|
||||
original := TraceContext{
|
||||
"value": 42,
|
||||
"another": 24,
|
||||
"weird": "string",
|
||||
}
|
||||
|
||||
clone := original.Clone()
|
||||
|
||||
clone["other"] = true
|
||||
|
||||
require.NotEqual(t, original, clone)
|
||||
}
|
||||
|
||||
func TestTraceContext_Merge(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
tc TraceContext
|
||||
other TraceContext
|
||||
want TraceContext
|
||||
}{
|
||||
{
|
||||
"tc is nil, other is empty, yields an empty TraceContext",
|
||||
nil,
|
||||
TraceContext{},
|
||||
TraceContext{},
|
||||
},
|
||||
{
|
||||
"tc is nil, other is nil, yields an empty TraceContext",
|
||||
nil,
|
||||
nil,
|
||||
TraceContext{},
|
||||
},
|
||||
{
|
||||
"tc is not nil, other is nil, yields tc",
|
||||
TraceContext{
|
||||
"data": 42,
|
||||
},
|
||||
nil,
|
||||
TraceContext{
|
||||
"data": 42,
|
||||
},
|
||||
},
|
||||
{
|
||||
"tc is not nil, other is not nil, yields tc + other",
|
||||
TraceContext{
|
||||
"data": 42,
|
||||
},
|
||||
TraceContext{
|
||||
"data2": 42,
|
||||
},
|
||||
TraceContext{
|
||||
"data": 42,
|
||||
"data2": 42,
|
||||
},
|
||||
},
|
||||
{
|
||||
"tc is not nil, other is not nil, other updates value in tc, yields tc updated with value from other",
|
||||
TraceContext{
|
||||
"data": 42,
|
||||
},
|
||||
TraceContext{
|
||||
"data": 24,
|
||||
},
|
||||
TraceContext{
|
||||
"data": 24,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
require.Equal(t, tt.want, tt.tc.Merge(tt.other))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue