diff --git a/runtime/v2/go.mod b/runtime/v2/go.mod index 30bbf0dd2e2..307943a9c33 100644 --- a/runtime/v2/go.mod +++ b/runtime/v2/go.mod @@ -5,6 +5,7 @@ go 1.23 // server v2 integration replace ( cosmossdk.io/api => ../../api + cosmossdk.io/core/testing => ../../core/testing cosmossdk.io/server/v2/appmanager => ../../server/v2/appmanager cosmossdk.io/server/v2/stf => ../../server/v2/stf cosmossdk.io/store/v2 => ../../store/v2 @@ -30,7 +31,7 @@ require ( require ( buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.35.1-20240701160653-fedbb9acfd2f.1 // indirect buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.35.1-20240130113600-88ef6483f90f.1 // indirect - cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 // indirect + cosmossdk.io/core/testing v0.0.0 // indirect cosmossdk.io/errors/v2 v2.0.0-20240731132947-df72853b3ca5 // indirect github.com/DataDog/zstd v1.5.5 // indirect github.com/beorn7/perks v1.0.1 // indirect diff --git a/runtime/v2/go.sum b/runtime/v2/go.sum index 204d0c2758d..85f9a2d675a 100644 --- a/runtime/v2/go.sum +++ b/runtime/v2/go.sum @@ -4,8 +4,6 @@ buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.35.1-20240130113600-88e buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.35.1-20240130113600-88ef6483f90f.1/go.mod h1:zqi/LZjZhyvjCMTEVIwAf5VRlkLduuCfqmZxgoormq0= cosmossdk.io/core v1.0.0-alpha.5 h1:McjYXAQ6XcT20v2uHyH7PhoWH8V+mebzfVFqT3GinsI= cosmossdk.io/core v1.0.0-alpha.5/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= -cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY= -cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs= cosmossdk.io/depinject v1.1.0 h1:wLan7LG35VM7Yo6ov0jId3RHWCGRhe8E8bsuARorl5E= cosmossdk.io/depinject v1.1.0/go.mod h1:kkI5H9jCGHeKeYWXTqYdruogYrEeWvBQCw1Pj4/eCFI= cosmossdk.io/errors/v2 v2.0.0-20240731132947-df72853b3ca5 h1:IQNdY2kB+k+1OM2DvqFG1+UgeU1JzZrWtwuWzI3ZfwA= diff --git a/server/v2/cometbft/go.mod b/server/v2/cometbft/go.mod index 9953c7fe6aa..4547e6b48e3 100644 --- a/server/v2/cometbft/go.mod +++ b/server/v2/cometbft/go.mod @@ -4,6 +4,7 @@ go 1.23.1 replace ( cosmossdk.io/api => ../../../api + cosmossdk.io/core/testing => ../../../core/testing cosmossdk.io/server/v2 => ../ cosmossdk.io/server/v2/appmanager => ../appmanager cosmossdk.io/server/v2/stf => ../stf @@ -43,7 +44,7 @@ require ( require ( buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.35.1-20240701160653-fedbb9acfd2f.1 // indirect buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.35.1-20240130113600-88ef6483f90f.1 // indirect - cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 // indirect + cosmossdk.io/core/testing v0.0.0 // indirect cosmossdk.io/depinject v1.1.0 // indirect cosmossdk.io/errors v1.0.1 // indirect cosmossdk.io/math v1.3.0 // indirect diff --git a/server/v2/cometbft/go.sum b/server/v2/cometbft/go.sum index a938ee149eb..4b735e0d542 100644 --- a/server/v2/cometbft/go.sum +++ b/server/v2/cometbft/go.sum @@ -8,8 +8,6 @@ cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s= cosmossdk.io/collections v0.4.0/go.mod h1:oa5lUING2dP+gdDquow+QjlF45eL1t4TJDypgGd+tv0= cosmossdk.io/core v1.0.0-alpha.5 h1:McjYXAQ6XcT20v2uHyH7PhoWH8V+mebzfVFqT3GinsI= cosmossdk.io/core v1.0.0-alpha.5/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= -cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY= -cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs= cosmossdk.io/depinject v1.1.0 h1:wLan7LG35VM7Yo6ov0jId3RHWCGRhe8E8bsuARorl5E= cosmossdk.io/depinject v1.1.0/go.mod h1:kkI5H9jCGHeKeYWXTqYdruogYrEeWvBQCw1Pj4/eCFI= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= diff --git a/server/v2/stf/branch/bench_test.go b/server/v2/stf/branch/bench_test.go new file mode 100644 index 00000000000..db46846c167 --- /dev/null +++ b/server/v2/stf/branch/bench_test.go @@ -0,0 +1,83 @@ +package branch + +import ( + "fmt" + "testing" + + "cosmossdk.io/core/store" + coretesting "cosmossdk.io/core/testing" +) + +var ( + stackSizes = []int{1, 10, 100} + elemsInStack = 10 +) + +func Benchmark_CacheStack_Set(b *testing.B) { + for _, stackSize := range stackSizes { + b.Run(fmt.Sprintf("StackSize%d", stackSize), func(b *testing.B) { + bs := makeBranchStack(b, stackSize) + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = bs.Set([]byte{0}, []byte{0}) + } + }) + } +} + +func Benchmark_Get(b *testing.B) { + for _, stackSize := range stackSizes { + b.Run(fmt.Sprintf("StackSize%d", stackSize), func(b *testing.B) { + bs := makeBranchStack(b, stackSize) + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _, _ = bs.Get([]byte{0}) + } + }) + } +} + +func Benchmark_Iterate(b *testing.B) { + var keySink, valueSink any + + for _, stackSize := range stackSizes { + b.Run(fmt.Sprintf("StackSize%d", stackSize), func(b *testing.B) { + bs := makeBranchStack(b, stackSize) + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + iter, _ := bs.Iterator(nil, nil) + for iter.Valid() { + keySink = iter.Key() + valueSink = iter.Value() + iter.Next() + } + _ = iter.Close() + } + }) + } + + _ = keySink + _ = valueSink +} + +// makeBranchStack creates a branch stack of the given size and initializes it with unique key-value pairs. +func makeBranchStack(b *testing.B, stackSize int) Store[store.KVStore] { + parent := coretesting.NewMemKV() + branch := NewStore[store.KVStore](parent) + for i := 1; i < stackSize; i++ { + branch = NewStore[store.KVStore](branch) + for j := 0; j < elemsInStack; j++ { + // create unique keys by including the branch index. + key := []byte{byte(i), byte(j)} + value := []byte{byte(j)} + err := branch.Set(key, value) + if err != nil { + b.Fatal(err) + } + } + } + return branch +} diff --git a/server/v2/stf/branch/changeset.go b/server/v2/stf/branch/changeset.go index 07a29345aee..a5f168a515d 100644 --- a/server/v2/stf/branch/changeset.go +++ b/server/v2/stf/branch/changeset.go @@ -15,7 +15,7 @@ const ( var errKeyEmpty = errors.New("key cannot be empty") -// changeSet implements the sorted cache for cachekv store, +// changeSet implements the sorted tree for cachekv store, // we don't use MemDB here because cachekv is used extensively in sdk core path, // we need it to be as fast as possible, while `MemDB` is mainly used as a mocking db in unit tests. // diff --git a/server/v2/stf/branch/mergeiter.go b/server/v2/stf/branch/mergeiter.go index e71b88cffc4..58d237c0992 100644 --- a/server/v2/stf/branch/mergeiter.go +++ b/server/v2/stf/branch/mergeiter.go @@ -7,229 +7,162 @@ import ( corestore "cosmossdk.io/core/store" ) -// mergedIterator merges a parent Iterator and a cache Iterator. -// The cache iterator may return nil keys to signal that an item -// had been deleted (but not deleted in the parent). -// If the cache iterator has the same key as the parent, the -// cache shadows (overrides) the parent. -type mergedIterator struct { - parent corestore.Iterator - cache corestore.Iterator - ascending bool - - valid bool +var ( + errInvalidIterator = errors.New("invalid iterator") +) + +// mergedIterator merges a parent Iterator and a child Iterator. +// The child iterator may contain items that shadow or override items in the parent iterator. +// If the child iterator has the same key as the parent, the child's value takes precedence. +// Deleted items in the child (indicated by nil values) are skipped. +type mergedIterator[Parent, Child corestore.Iterator] struct { + parent Parent // Iterator for the parent store + child Child // Iterator for the child store + ascending bool // Direction of iteration + valid bool // Indicates if the iterator is in a valid state + currKey []byte // Current key pointed by the iterator + currValue []byte // Current value corresponding to currKey + err error // Error encountered during iteration } -var _ corestore.Iterator = (*mergedIterator)(nil) +// Ensure mergedIterator implements the corestore.Iterator interface. +var _ corestore.Iterator = (*mergedIterator[corestore.Iterator, corestore.Iterator])(nil) -// mergeIterators merges two iterators. -func mergeIterators(parent, cache corestore.Iterator, ascending bool) corestore.Iterator { - iter := &mergedIterator{ +// mergeIterators creates a new merged iterator from parent and child iterators. +// The 'ascending' parameter determines the direction of iteration. +func mergeIterators[Parent, Child corestore.Iterator](parent Parent, child Child, ascending bool) *mergedIterator[Parent, Child] { + iter := &mergedIterator[Parent, Child]{ parent: parent, - cache: cache, + child: child, ascending: ascending, } - - iter.valid = iter.skipUntilExistsOrInvalid() + iter.advance() // Initialize the iterator by advancing to the first valid item return iter } -// Domain implements Iterator. -// Returns parent domain because cache and parent domains are the same. -func (iter *mergedIterator) Domain() (start, end []byte) { - return iter.parent.Domain() +// Domain returns the start and end range of the iterator. +// It delegates to the parent iterator as both iterators share the same domain. +func (i *mergedIterator[Parent, Child]) Domain() (start, end []byte) { + return i.parent.Domain() } -// Valid implements Iterator. -func (iter *mergedIterator) Valid() bool { - return iter.valid +// Valid checks if the iterator is in a valid state. +// It returns true if the iterator has not reached the end. +func (i *mergedIterator[Parent, Child]) Valid() bool { + return i.valid } -// Next implements Iterator -func (iter *mergedIterator) Next() { - iter.assertValid() - - switch { - case !iter.parent.Valid(): - // If parent is invalid, get the next cache item. - iter.cache.Next() - case !iter.cache.Valid(): - // If cache is invalid, get the next parent item. - iter.parent.Next() - default: - // Both are valid. Compare keys. - keyP, keyC := iter.parent.Key(), iter.cache.Key() - switch iter.compare(keyP, keyC) { - case -1: // parent < cache - iter.parent.Next() - case 0: // parent == cache - iter.parent.Next() - iter.cache.Next() - case 1: // parent > cache - iter.cache.Next() - } +// Next advances the iterator to the next valid item. +// It skips over deleted items (with nil values) and updates the current key and value. +func (i *mergedIterator[Parent, Child]) Next() { + if !i.valid { + i.err = errInvalidIterator + return } - iter.valid = iter.skipUntilExistsOrInvalid() + i.advance() } -// Key implements Iterator -func (iter *mergedIterator) Key() []byte { - iter.assertValid() - - // If parent is invalid, get the cache key. - if !iter.parent.Valid() { - return iter.cache.Key() - } - - // If cache is invalid, get the parent key. - if !iter.cache.Valid() { - return iter.parent.Key() - } - - // Both are valid. Compare keys. - keyP, keyC := iter.parent.Key(), iter.cache.Key() - - cmp := iter.compare(keyP, keyC) - switch cmp { - case -1: // parent < cache - return keyP - case 0: // parent == cache - return keyP - case 1: // parent > cache - return keyC - default: - panic("invalid compare result") +// Key returns the current key pointed by the iterator. +// If the iterator is invalid, it returns nil. +func (i *mergedIterator[Parent, Child]) Key() []byte { + if !i.valid { + panic("called key on invalid iterator") } + return i.currKey } -// Value implements Iterator -func (iter *mergedIterator) Value() []byte { - iter.assertValid() - - // If parent is invalid, get the cache value. - if !iter.parent.Valid() { - return iter.cache.Value() - } - - // If cache is invalid, get the parent value. - if !iter.cache.Valid() { - return iter.parent.Value() - } - - // Both are valid. Compare keys. - keyP, keyC := iter.parent.Key(), iter.cache.Key() - - cmp := iter.compare(keyP, keyC) - switch cmp { - case -1: // parent < cache - return iter.parent.Value() - case 0: // parent == cache - return iter.cache.Value() - case 1: // parent > cache - return iter.cache.Value() - default: - panic("invalid comparison result") +// Value returns the current value corresponding to the current key. +// If the iterator is invalid, it returns nil. +func (i *mergedIterator[Parent, Child]) Value() []byte { + if !i.valid { + panic("called value on invalid iterator") } + return i.currValue } -// Close implements Iterator -func (iter *mergedIterator) Close() error { - err1 := iter.cache.Close() - if err := iter.parent.Close(); err != nil { - return err - } - - return err1 +// Close closes both the parent and child iterators. +// It returns any error encountered during the closing of the iterators. +func (i *mergedIterator[Parent, Child]) Close() (err error) { + err = errors.Join(err, i.parent.Close()) + err = errors.Join(err, i.child.Close()) + i.valid = false + return err } -var errInvalidIterator = errors.New("invalid merged iterator") - -// Error returns an error if the mergedIterator is invalid defined by the -// Valid method. -func (iter *mergedIterator) Error() error { - if !iter.Valid() { - return errInvalidIterator - } - - return nil +// Error returns any error that occurred during iteration. +// If the iterator is valid, it returns nil. +func (i *mergedIterator[Parent, Child]) Error() error { + return i.err } -// If not valid, panics. -// NOTE: May have side-effect of iterating over cache. -func (iter *mergedIterator) assertValid() { - if err := iter.Error(); err != nil { - panic(err) - } -} - -// Like bytes.Compare but opposite if not ascending. -func (iter *mergedIterator) compare(a, b []byte) int { - if iter.ascending { - return bytes.Compare(a, b) - } - - return bytes.Compare(a, b) * -1 -} - -// Skip all delete-items from the cache w/ `key < until`. After this function, -// current cache item is a non-delete-item, or `until <= key`. -// If the current cache item is not a delete item, does nothing. -// If `until` is nil, there is no limit, and cache may end up invalid. -// CONTRACT: cache is valid. -func (iter *mergedIterator) skipCacheDeletes(until []byte) { - for iter.cache.Valid() && - iter.cache.Value() == nil && - (until == nil || iter.compare(iter.cache.Key(), until) < 0) { - iter.cache.Next() - } -} - -// Fast forwards cache (or parent+cache in case of deleted items) until current -// item exists, or until iterator becomes invalid. -// Returns whether the iterator is valid. -func (iter *mergedIterator) skipUntilExistsOrInvalid() bool { +// advance moves the iterator to the next valid (non-deleted) item. +// It handles merging logic between the parent and child iterators. +func (i *mergedIterator[Parent, Child]) advance() { for { - // If parent is invalid, fast-forward cache. - if !iter.parent.Valid() { - iter.skipCacheDeletes(nil) - return iter.cache.Valid() + // Check if both iterators have reached the end + if !i.parent.Valid() && !i.child.Valid() { + i.valid = false + return } - // Parent is valid. - if !iter.cache.Valid() { - return true + var key, value []byte + + // If parent iterator is exhausted, use the child iterator + if !i.parent.Valid() { + key = i.child.Key() + value = i.child.Value() + i.child.Next() + } else if !i.child.Valid() { + // If child iterator is exhausted, use the parent iterator + key = i.parent.Key() + value = i.parent.Value() + i.parent.Next() + } else { + // Both iterators are valid; compare keys + keyP, keyC := i.parent.Key(), i.child.Key() + switch cmp := i.compare(keyP, keyC); { + case cmp < 0: + // Parent key is less than child key + key = keyP + value = i.parent.Value() + i.parent.Next() + case cmp == 0: + // Keys are equal; child overrides parent + key = keyC + value = i.child.Value() + i.parent.Next() + i.child.Next() + case cmp > 0: + // Child key is less than parent key + key = keyC + value = i.child.Value() + i.child.Next() + } } - // Parent is valid, cache is valid. - - // Compare parent and cache. - keyP := iter.parent.Key() - keyC := iter.cache.Key() - switch iter.compare(keyP, keyC) { - case -1: // parent < cache. - return true + // Skip deleted items (value is nil) + if value == nil { + continue + } - case 0: // parent == cache. - // Skip over if cache item is a delete. - valueC := iter.cache.Value() - if valueC == nil { - iter.parent.Next() - iter.cache.Next() + // Update the current key and value, and mark iterator as valid + i.currKey = key + i.currValue = value + i.valid = true + return + } +} - continue - } - // Cache is not a delete. - - return true // cache exists. - case 1: // cache < parent - // Skip over if cache item is a delete. - valueC := iter.cache.Value() - if valueC == nil { - iter.skipCacheDeletes(keyP) - continue - } - // Cache is not a delete. - return true // cache exists. - } +// compare compares two byte slices a and b. +// It returns an integer comparing a and b: +// - Negative if a < b +// - Zero if a == b +// - Positive if a > b +// +// The comparison respects the iterator's direction (ascending or descending). +func (i *mergedIterator[Parent, Child]) compare(a, b []byte) int { + if i.ascending { + return bytes.Compare(a, b) } + return bytes.Compare(b, a) } diff --git a/server/v2/stf/branch/mergeiter_test.go b/server/v2/stf/branch/mergeiter_test.go index 1a9e13bbe65..1b7253f8112 100644 --- a/server/v2/stf/branch/mergeiter_test.go +++ b/server/v2/stf/branch/mergeiter_test.go @@ -7,6 +7,52 @@ import ( corestore "cosmossdk.io/core/store" ) +func TestMergedIterator_Validity(t *testing.T) { + panics := func(f func()) { + defer func() { + r := recover() + if r == nil { + t.Error("panic expected") + } + }() + + f() + } + + t.Run("panics when calling key on invalid iter", func(t *testing.T) { + parent, err := newMemState().Iterator(nil, nil) + if err != nil { + t.Fatal(err) + } + cache, err := newMemState().Iterator(nil, nil) + if err != nil { + t.Fatal(err) + } + + it := mergeIterators(parent, cache, true) + panics(func() { + it.Key() + }) + }) + + t.Run("panics when calling value on invalid iter", func(t *testing.T) { + parent, err := newMemState().Iterator(nil, nil) + if err != nil { + t.Fatal(err) + } + cache, err := newMemState().Iterator(nil, nil) + if err != nil { + t.Fatal(err) + } + + it := mergeIterators(parent, cache, true) + + panics(func() { + it.Value() + }) + }) +} + func TestMergedIterator_Next(t *testing.T) { specs := map[string]struct { setup func() corestore.Iterator @@ -19,7 +65,7 @@ func TestMergedIterator_Next(t *testing.T) { return mergeIterators(must(parent.Iterator(nil, nil)), must(cache.Iterator(nil, nil)), true) }, }, - "parent iterator has one item, cache is empty": { + "parent iterator has one item, child is empty": { setup: func() corestore.Iterator { parent := newMemState() if err := parent.Set([]byte("k1"), []byte("1")); err != nil { @@ -30,7 +76,7 @@ func TestMergedIterator_Next(t *testing.T) { }, exp: [][2]string{{"k1", "1"}}, }, - "cache has one item, parent is empty": { + "child has one item, parent is empty": { setup: func() corestore.Iterator { parent := newMemState() cache := newMemState() @@ -41,21 +87,21 @@ func TestMergedIterator_Next(t *testing.T) { }, exp: [][2]string{{"k1", "1"}}, }, - "both iterators have same key, cache preferred": { + "both iterators have same key, child preferred": { setup: func() corestore.Iterator { parent := newMemState() if err := parent.Set([]byte("k1"), []byte("parent-val")); err != nil { t.Fatal(err) } cache := newMemState() - if err := cache.Set([]byte("k1"), []byte("cache-val")); err != nil { + if err := cache.Set([]byte("k1"), []byte("child-val")); err != nil { t.Fatal(err) } return mergeIterators(must(parent.Iterator(nil, nil)), must(cache.Iterator(nil, nil)), true) }, - exp: [][2]string{{"k1", "cache-val"}}, + exp: [][2]string{{"k1", "child-val"}}, }, - "both iterators have same key, but cache value is nil": { + "both iterators have same key, but child value is nil": { setup: func() corestore.Iterator { parent := newMemState() if err := parent.Set([]byte("k1"), []byte("1")); err != nil { @@ -68,7 +114,7 @@ func TestMergedIterator_Next(t *testing.T) { return mergeIterators(must(parent.Iterator(nil, nil)), must(cache.Iterator(nil, nil)), true) }, }, - "parent and cache are ascending": { + "parent and child are ascending": { setup: func() corestore.Iterator { parent := newMemState() if err := parent.Set([]byte("k2"), []byte("v2")); err != nil { @@ -88,7 +134,7 @@ func TestMergedIterator_Next(t *testing.T) { }, exp: [][2]string{{"k1", "v1"}, {"k2", "v2"}, {"k3", "v3"}, {"k4", "v4"}}, }, - "parent and cache are descending": { + "parent and child are descending": { setup: func() corestore.Iterator { parent := newMemState() if err := parent.Set([]byte("k3"), []byte("v3")); err != nil { diff --git a/server/v2/stf/branch/store.go b/server/v2/stf/branch/store.go index f0d6d0b3a1e..19e32e8392a 100644 --- a/server/v2/stf/branch/store.go +++ b/server/v2/stf/branch/store.go @@ -8,9 +8,9 @@ import ( var _ store.Writer = (*Store[store.Reader])(nil) -// Store wraps an in-memory cache around an underlying types.KVStore. +// Store wraps an in-memory child around an underlying types.KVStore. type Store[T store.Reader] struct { - changeSet changeSet // always ascending sorted + changeSet changeSet // ordered changeset. parent T } @@ -24,11 +24,18 @@ func NewStore[T store.Reader](parent T) Store[T] { // Get implements types.KVStore. func (s Store[T]) Get(key []byte) (value []byte, err error) { + // if found in memory cache, immediately return. value, found := s.changeSet.get(key) if found { return } - return s.parent.Get(key) + // after we get it from parent store, we cache it. + // if it is not found in parent store, we still cache it as nil. + value, err = s.parent.Get(key) + if err != nil { + return nil, err + } + return value, nil } // Set implements types.KVStore. @@ -36,7 +43,6 @@ func (s Store[T]) Set(key, value []byte) error { if value == nil { return errors.New("cannot set a nil value") } - s.changeSet.set(key, value) return nil } diff --git a/server/v2/stf/go.mod b/server/v2/stf/go.mod index ee80284cfd4..527eb2671cf 100644 --- a/server/v2/stf/go.mod +++ b/server/v2/stf/go.mod @@ -4,6 +4,7 @@ go 1.23 require ( cosmossdk.io/core v1.0.0-alpha.5 + cosmossdk.io/core/testing v0.0.0 cosmossdk.io/schema v0.3.0 github.com/cosmos/gogoproto v1.7.0 github.com/tidwall/btree v1.7.0 @@ -13,3 +14,5 @@ require ( github.com/google/go-cmp v0.6.0 // indirect google.golang.org/protobuf v1.35.1 // indirect ) + +replace cosmossdk.io/core/testing => ../../../core/testing diff --git a/simapp/v2/go.mod b/simapp/v2/go.mod index 9e624a42b33..48ce4fef183 100644 --- a/simapp/v2/go.mod +++ b/simapp/v2/go.mod @@ -58,7 +58,7 @@ require ( cloud.google.com/go/iam v1.1.13 // indirect cloud.google.com/go/storage v1.43.0 // indirect cosmossdk.io/collections v0.4.1-0.20241104084251-838f1557af0a // indirect - cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 // indirect + cosmossdk.io/core/testing v0.0.0 // indirect cosmossdk.io/errors v1.0.1 // indirect cosmossdk.io/errors/v2 v2.0.0-20240731132947-df72853b3ca5 // indirect cosmossdk.io/schema v0.3.1-0.20241010135032-192601639cac // indirect @@ -291,6 +291,7 @@ replace ( // server v2 integration replace ( cosmossdk.io/api => ../../api + cosmossdk.io/core/testing => ../../core/testing cosmossdk.io/runtime/v2 => ../../runtime/v2 cosmossdk.io/server/v2 => ../../server/v2 cosmossdk.io/server/v2/appmanager => ../../server/v2/appmanager diff --git a/simapp/v2/go.sum b/simapp/v2/go.sum index dc3317e0354..ac9547348b7 100644 --- a/simapp/v2/go.sum +++ b/simapp/v2/go.sum @@ -194,8 +194,6 @@ cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1V cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= cosmossdk.io/core v1.0.0-alpha.5 h1:McjYXAQ6XcT20v2uHyH7PhoWH8V+mebzfVFqT3GinsI= cosmossdk.io/core v1.0.0-alpha.5/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= -cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY= -cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs= cosmossdk.io/depinject v1.1.0 h1:wLan7LG35VM7Yo6ov0jId3RHWCGRhe8E8bsuARorl5E= cosmossdk.io/depinject v1.1.0/go.mod h1:kkI5H9jCGHeKeYWXTqYdruogYrEeWvBQCw1Pj4/eCFI= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= diff --git a/tests/go.mod b/tests/go.mod index ecfb14d397c..08a69289f96 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -32,7 +32,7 @@ require ( ) require ( - cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 + cosmossdk.io/core/testing v0.0.0 cosmossdk.io/runtime/v2 v2.0.0-20240911143651-72620a577660 cosmossdk.io/server/v2/stf v0.0.0-00010101000000-000000000000 cosmossdk.io/store/v2 v2.0.0-00010101000000-000000000000 @@ -248,6 +248,7 @@ replace ( cosmossdk.io/api => ../api cosmossdk.io/client/v2 => ../client/v2 cosmossdk.io/collections => ../collections + cosmossdk.io/core/testing => ../core/testing cosmossdk.io/indexer/postgres => ../indexer/postgres cosmossdk.io/runtime/v2 => ../runtime/v2 cosmossdk.io/server/v2/appmanager => ../server/v2/appmanager diff --git a/tests/go.sum b/tests/go.sum index 0afc406fdc3..9deb1100ce8 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -194,8 +194,6 @@ cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1V cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= cosmossdk.io/core v1.0.0-alpha.5 h1:McjYXAQ6XcT20v2uHyH7PhoWH8V+mebzfVFqT3GinsI= cosmossdk.io/core v1.0.0-alpha.5/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= -cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY= -cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs= cosmossdk.io/depinject v1.1.0 h1:wLan7LG35VM7Yo6ov0jId3RHWCGRhe8E8bsuARorl5E= cosmossdk.io/depinject v1.1.0/go.mod h1:kkI5H9jCGHeKeYWXTqYdruogYrEeWvBQCw1Pj4/eCFI= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0=