Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into rc/v0.46.0-rc8
Browse files Browse the repository at this point in the history
0Tech authored Oct 24, 2022

Unverified

This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
2 parents cfe658b + 1726293 commit cafab15
Showing 26 changed files with 727 additions and 206 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -56,6 +56,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (x/ibc) [\#651](https://github.com/line/lbm-sdk/pull/651) feat: update x/ibc to support github.com/cosmos/[email protected]
* (config) [\#665](https://github.com/line/lbm-sdk/pull/665) remove bech32-cache-size
* (x/foundation) [\#709](https://github.com/line/lbm-sdk/pull/709) add `gov mint` for x/foundation proposal
* (iavl) [\#738](https://github.com/line/lbm-sdk/pull/738) bump github.com/cosmos/iavl from v0.17.3 to v0.19.3

### Improvements

@@ -87,6 +88,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (x/foundation) [\#729](https://github.com/line/lbm-sdk/pull/729) add UpdateParams to x/foundation
* (amino) [\#736](https://github.com/line/lbm-sdk/pull/736) apply the missing amino codec registratoin of cosmos-sdk
* (x/foundation) [\#744](https://github.com/line/lbm-sdk/pull/744) revisit foundation operator
* (store,x/wasm) [\#742](https://github.com/line/lbm-sdk/pull/742) fix to add error message in GetByteCode()

### Bug Fixes
* (x/wasm) [\#453](https://github.com/line/lbm-sdk/pull/453) modify wasm grpc query api path
@@ -116,6 +118,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (x/foundation) [\#732](https://github.com/line/lbm-sdk/pull/732) add verification on accounts into x/foundation Grants cli
* (x/foundation) [\#730](https://github.com/line/lbm-sdk/pull/730) prune stale x/foundation proposals at voting period end
* (cli) [\#734](https://github.com/line/lbm-sdk/pull/734) add restrictions on the number of args in the CLIs
* (client) [\#737](https://github.com/line/lbm-sdk/pull/737) check multisig key list to prevent unexpected key deletion

### Breaking Changes
* (proto) [\#564](https://github.com/line/lbm-sdk/pull/564) change gRPC path to original cosmos path
9 changes: 9 additions & 0 deletions baseapp/abci_test.go
Original file line number Diff line number Diff line change
@@ -98,6 +98,15 @@ func TestGetBlockRentionHeight(t *testing.T) {
commitHeight: 499000,
expected: 0,
},
"iavl disable fast node": {
bapp: NewBaseApp(
name, logger, db, nil,
SetIAVLDisableFastNode(true),
),
maxAgeBlocks: 0,
commitHeight: 499000,
expected: 0,
},
}

for name, tc := range testCases {
5 changes: 5 additions & 0 deletions baseapp/options.go
Original file line number Diff line number Diff line change
@@ -64,6 +64,11 @@ func SetIAVLCacheSize(size int) func(*BaseApp) {
return func(bapp *BaseApp) { bapp.cms.SetIAVLCacheSize(size) }
}

// SetIAVLDisableFastNode enables(false)/disables(true) fast node usage from the IAVL store.
func SetIAVLDisableFastNode(disable bool) func(*BaseApp) {
return func(bapp *BaseApp) { bapp.cms.SetIAVLDisableFastNode(disable) }
}

// SetInterBlockCache provides a BaseApp option function that sets the
// inter-block cache.
func SetInterBlockCache(cache sdk.MultiStorePersistentCache) func(*BaseApp) {
45 changes: 34 additions & 11 deletions client/keys/add.go
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ import (
"math"
"sort"

bip39 "github.com/cosmos/go-bip39"
"github.com/cosmos/go-bip39"
"github.com/spf13/cobra"

"github.com/line/lbm-sdk/client"
@@ -95,15 +95,17 @@ func runAddCmdPrepare(cmd *cobra.Command, args []string) error {

/*
input
- bip39 mnemonic
- bip39 passphrase
- bip44 path
- local encryption password
- bip39 mnemonic
- bip39 passphrase
- bip44 path
- local encryption password
output
- armor encrypted private key (saved to file)
- armor encrypted private key (saved to file)
*/
func runAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *bufio.Reader) error {
var err error
var multisigThreshold int

name := args[0]
interactive, _ := cmd.Flags().GetBool(flagInteractive)
@@ -118,6 +120,18 @@ func runAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *buf
if err != nil {
return err
}
multisigKeys, _ := cmd.Flags().GetStringSlice(flagMultisig)
if len(multisigKeys) != 0 {
multisigThreshold, _ = cmd.Flags().GetInt(flagMultiSigThreshold)
if err = validateMultisigThreshold(multisigThreshold, len(multisigKeys)); err != nil {
return err
}

err = verifyMultisigTarget(kb, multisigKeys, name)
if err != nil {
return err
}
}

if dryRun, _ := cmd.Flags().GetBool(flags.FlagDryRun); dryRun {
// use in memory keybase
@@ -141,13 +155,8 @@ func runAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *buf
}
}

multisigKeys, _ := cmd.Flags().GetStringSlice(flagMultisig)
if len(multisigKeys) != 0 {
pks := make([]cryptotypes.PubKey, len(multisigKeys))
multisigThreshold, _ := cmd.Flags().GetInt(flagMultiSigThreshold)
if err := validateMultisigThreshold(multisigThreshold, len(multisigKeys)); err != nil {
return err
}

for i, keyname := range multisigKeys {
k, err := kb.Key(keyname)
@@ -327,3 +336,17 @@ func printCreate(cmd *cobra.Command, info keyring.Info, showMnemonic bool, mnemo

return nil
}

func verifyMultisigTarget(kb keyring.Keyring, multisigKeys []string, newkey string) error {
if _, err := kb.Key(newkey); err == nil {
return errors.New("you cannot specify a new key as one of the names of the keys that make up a multisig")
}

for _, k := range multisigKeys {
if _, err := kb.Key(k); err != nil {
return errors.New("part of the multisig target key does not exist")
}
}

return nil
}
87 changes: 81 additions & 6 deletions client/keys/add_test.go
Original file line number Diff line number Diff line change
@@ -7,7 +7,8 @@ import (
"io"
"testing"

bip39 "github.com/cosmos/go-bip39"
"github.com/cosmos/go-bip39"
"github.com/spf13/pflag"
"github.com/stretchr/testify/require"

"github.com/line/ostracon/libs/cli"
@@ -32,8 +33,9 @@ func Test_runAddCmdBasic(t *testing.T) {
kb, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendTest, kbHome, mockIn)
require.NoError(t, err)

clientCtx := client.Context{}.WithKeyringDir(kbHome).WithInput(mockIn)
ctx := context.WithValue(context.Background(), client.ClientContextKey, &clientCtx)
clientCtx := client.Context{}.WithKeyringDir(kbHome).WithInput(mockIn).WithKeyring(kb)
clientCtxPtr := &clientCtx
ctx := context.WithValue(context.Background(), client.ClientContextKey, clientCtxPtr)

t.Cleanup(func() {
_ = kb.Delete("keyname1")
@@ -62,7 +64,6 @@ func Test_runAddCmdBasic(t *testing.T) {
})

require.NoError(t, cmd.ExecuteContext(ctx))
require.Error(t, cmd.ExecuteContext(ctx))

mockIn.Reset("y\n")
require.NoError(t, cmd.ExecuteContext(ctx))
@@ -76,7 +77,81 @@ func Test_runAddCmdBasic(t *testing.T) {
})

require.NoError(t, cmd.ExecuteContext(ctx))
require.Error(t, cmd.ExecuteContext(ctx))

// In Multisig
tcs := []struct {
args []string
err string
}{
{[]string{
"keyname1",
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
fmt.Sprintf("--%s=%s", cli.OutputFlag, OutputFormatText),
fmt.Sprintf("--%s=%s", flags.FlagKeyAlgorithm, string(hd.Secp256k1Type)),
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
fmt.Sprintf("--%s=%s", flagMultisig, "keyname1,keyname2"),
},
"you cannot specify a new key as one of the names of the keys that make up a multisig",
},
{[]string{
"keyname-multi",
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
fmt.Sprintf("--%s=%s", cli.OutputFlag, OutputFormatText),
fmt.Sprintf("--%s=%s", flags.FlagKeyAlgorithm, string(hd.Secp256k1Type)),
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
fmt.Sprintf("--%s=%s", flagMultisig, "keyname1,keyname11"),
},
"part of the multisig target key does not exist",
},
{[]string{
"keyname-multi",
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
fmt.Sprintf("--%s=%s", cli.OutputFlag, OutputFormatText),
fmt.Sprintf("--%s=%s", flags.FlagKeyAlgorithm, string(hd.Secp256k1Type)),
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
fmt.Sprintf("--%s=%s", flagMultisig, "keyname1,keyname2"),
fmt.Sprintf("--%s=%d", flagMultiSigThreshold, 3),
},
"threshold k of n multisignature",
},
{[]string{
"keyname-multi",
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
fmt.Sprintf("--%s=%s", cli.OutputFlag, OutputFormatText),
fmt.Sprintf("--%s=%s", flags.FlagKeyAlgorithm, string(hd.Secp256k1Type)),
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
fmt.Sprintf("--%s=%s", flagMultisig, "keyname1,keyname2"),
fmt.Sprintf("--%s=%d", flagMultiSigThreshold, -1),
},
"threshold must be a positive integer",
},
{[]string{
"keyname-multi",
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
fmt.Sprintf("--%s=%s", cli.OutputFlag, OutputFormatText),
fmt.Sprintf("--%s=%s", flags.FlagKeyAlgorithm, string(hd.Secp256k1Type)),
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
fmt.Sprintf("--%s=%s", flagMultisig, "keyname1,keyname2"),
fmt.Sprintf("--%s=%d", flagMultiSigThreshold, 2),
},
"",
},
}

for _, tc := range tcs {
cmd.SetArgs(tc.args)
if tc.err != "" {
require.Contains(t, cmd.ExecuteContext(ctx).Error(), tc.err)
} else {
require.NoError(t, cmd.ExecuteContext(ctx))
}

cmd.Flags().Visit(func(f *pflag.Flag) {
if f.Name == flagMultisig {
f.Value.(pflag.SliceValue).Replace([]string{})
}
})
}

cmd.SetArgs([]string{
"keyname5",
@@ -85,7 +160,7 @@ func Test_runAddCmdBasic(t *testing.T) {
fmt.Sprintf("--%s=%s", cli.OutputFlag, OutputFormatText),
fmt.Sprintf("--%s=%s", flags.FlagKeyAlgorithm, string(hd.Secp256k1Type)),
})

mockIn.Reset("\n")
require.NoError(t, cmd.ExecuteContext(ctx))

// In recovery mode
14 changes: 6 additions & 8 deletions go.mod
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ require (
github.com/confio/ics23/go v0.7.0
github.com/cosmos/btcutil v1.0.4
github.com/cosmos/go-bip39 v1.0.0
github.com/cosmos/iavl v0.17.3
github.com/cosmos/iavl v0.19.3
github.com/cosmos/ledger-cosmos-go v0.11.1
github.com/dgraph-io/ristretto v0.1.0 // indirect
github.com/dvsekhvalnov/jose2go v0.0.0-20200901110807-248326c1351b
@@ -29,7 +29,7 @@ require (
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d
github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3
github.com/improbable-eng/grpc-web v0.15.0
github.com/jhump/protoreflect v1.10.3
github.com/jhump/protoreflect v1.12.1-0.20220721211354-060cc04fc18b
github.com/line/ostracon v1.0.7-0.20220729051742-2231684789c6
github.com/line/wasmvm v1.0.0-0.10.0
github.com/magiconair/properties v1.8.6
@@ -95,7 +95,7 @@ require (
github.com/jmhodges/levigo v1.0.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d // indirect
github.com/klauspost/compress v1.13.6 // indirect
github.com/klauspost/compress v1.15.1 // indirect
github.com/lib/pq v1.10.6 // indirect
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
github.com/line/tm-db/v2 v2.0.0-init.1.0.20220121012851-61d2bc1d9486 // indirect
@@ -105,8 +105,6 @@ require (
github.com/minio/highwayhash v1.0.2 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mtibben/percent v0.2.1 // indirect
github.com/onsi/ginkgo v1.16.4 // indirect
github.com/onsi/gomega v1.18.1 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pelletier/go-toml/v2 v2.0.5 // indirect
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect
@@ -115,19 +113,18 @@ require (
github.com/prometheus/procfs v0.8.0 // indirect
github.com/r2ishiguro/vrf v0.0.0-20180716233122-192de52975eb // indirect
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // indirect
github.com/rogpeppe/go-internal v1.8.1 // indirect
github.com/rs/cors v1.8.2 // indirect
github.com/sasha-s/go-deadlock v0.2.1-0.20190427202633-1595213edefa // indirect
github.com/spf13/afero v1.8.2 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/stretchr/objx v0.4.0 // indirect
github.com/subosito/gotenv v1.4.1 // indirect
github.com/tendermint/tendermint v0.34.14 // indirect
github.com/tendermint/tendermint v0.34.20 // indirect
github.com/zondax/hid v0.9.0 // indirect
go.etcd.io/bbolt v1.3.6 // indirect
golang.org/x/net v0.0.0-20220617184016-355a448f1bc9 // indirect
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
golang.org/x/term v0.0.0-20220526004731-065cf7ba2467 // indirect
golang.org/x/text v0.3.7 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
@@ -137,5 +134,6 @@ require (
replace (
github.com/99designs/keyring => github.com/cosmos/keyring v1.1.7-0.20210622111912-ef00f8ac3d76
github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1
github.com/jhump/protoreflect => github.com/jhump/protoreflect v1.10.3
google.golang.org/grpc => google.golang.org/grpc v1.33.2
)
453 changes: 389 additions & 64 deletions go.sum

Large diffs are not rendered by default.

27 changes: 16 additions & 11 deletions server/config/config.go
Original file line number Diff line number Diff line change
@@ -79,6 +79,9 @@ type BaseConfig struct {
// IAVL cache size; bytes size unit
IAVLCacheSize uint64 `mapstructure:"iavl-cache-size"`

// IAVLDisableFastNode enables or disables the fast sync node.
IAVLDisableFastNode bool `mapstructure:"iavl-disable-fastnode"`

// When true, Prometheus metrics are served under /metrics on prometheus_listen_addr in config.toml.
// It works when tendermint's prometheus option (config.toml) is set to true.
Prometheus bool `mapstructure:"prometheus"`
@@ -221,6 +224,7 @@ func DefaultConfig() *Config {
InterBlockCache: true,
InterBlockCacheSize: cache.DefaultCommitKVStoreCacheSize,
IAVLCacheSize: iavl.DefaultIAVLCacheSize,
IAVLDisableFastNode: false,
Pruning: storetypes.PruningOptionDefault,
PruningKeepRecent: "0",
PruningKeepEvery: "0",
@@ -278,17 +282,18 @@ func GetConfig(v *viper.Viper) Config {

return Config{
BaseConfig: BaseConfig{
MinGasPrices: v.GetString("minimum-gas-prices"),
InterBlockCache: v.GetBool("inter-block-cache"),
Pruning: v.GetString("pruning"),
PruningKeepRecent: v.GetString("pruning-keep-recent"),
PruningKeepEvery: v.GetString("pruning-keep-every"),
PruningInterval: v.GetString("pruning-interval"),
HaltHeight: v.GetUint64("halt-height"),
HaltTime: v.GetUint64("halt-time"),
IndexEvents: v.GetStringSlice("index-events"),
MinRetainBlocks: v.GetUint64("min-retain-blocks"),
IAVLCacheSize: v.GetUint64("iavl-cache-size"),
MinGasPrices: v.GetString("minimum-gas-prices"),
InterBlockCache: v.GetBool("inter-block-cache"),
Pruning: v.GetString("pruning"),
PruningKeepRecent: v.GetString("pruning-keep-recent"),
PruningKeepEvery: v.GetString("pruning-keep-every"),
PruningInterval: v.GetString("pruning-interval"),
HaltHeight: v.GetUint64("halt-height"),
HaltTime: v.GetUint64("halt-time"),
IndexEvents: v.GetStringSlice("index-events"),
MinRetainBlocks: v.GetUint64("min-retain-blocks"),
IAVLDisableFastNode: v.GetBool("iavl-disable-fastnode"),
IAVLCacheSize: v.GetUint64("iavl-cache-size"),
},
Telemetry: telemetry.Config{
ServiceName: v.GetString("telemetry.service-name"),
4 changes: 4 additions & 0 deletions server/config/toml.go
Original file line number Diff line number Diff line change
@@ -71,6 +71,10 @@ inter-block-cache-size = {{ .BaseConfig.InterBlockCacheSize }}
# So be careful that all iavl cache size are difference from this iavl cache size value.
iavl-cache-size = {{ .BaseConfig.IAVLCacheSize }}
# IAVLDisableFastNode enables or disables the fast node feature of IAVL.
# Default is false.
iavl-disable-fastnode = {{ .BaseConfig.IAVLDisableFastNode }}
# IndexEvents defines the set of events in the form {eventType}.{attributeKey},
# which informs Tendermint what to index. If empty, all events will be indexed.
#
4 changes: 4 additions & 0 deletions server/mock/store.go
Original file line number Diff line number Diff line change
@@ -120,6 +120,10 @@ func (ms multiStore) SetIAVLCacheSize(size int) {
panic("not implemented")
}

func (ms multiStore) SetIAVLDisableFastNode(disable bool) {
panic("not implemented")
}

func (ms multiStore) SetInitialVersion(version int64) error {
panic("not implemented")
}
1 change: 1 addition & 0 deletions server/mock/store_test.go
Original file line number Diff line number Diff line change
@@ -38,4 +38,5 @@ func TestMultiStore(t *testing.T) {
store := multiStore{}
require.Panics(t, func() { store.Snapshot(1, nil) }, "Snapshot should panic")
require.Panics(t, func() { store.Restore(1, 1, nil) }, "Restore should panic")
require.Panics(t, func() { store.SetIAVLDisableFastNode(false) }, "SetIAVLDisableFastNode should panic")
}
1 change: 1 addition & 0 deletions simapp/simd/cmd/root.go
Original file line number Diff line number Diff line change
@@ -123,6 +123,7 @@ func initAppConfig() (string, interface{}) {
//
// In simapp, we set the min gas prices to 0.
srvCfg.MinGasPrices = "0stake"
// srvCfg.BaseConfig.IAVLDisableFastNode = true // disable fastnode by default

customAppConfig := CustomAppConfig{
Config: *srvCfg,
6 changes: 3 additions & 3 deletions store/cache/cache_test.go
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@ func TestGetOrSetStoreCache(t *testing.T) {
mngr := cache.NewCommitKVStoreCacheManager(cache.DefaultCommitKVStoreCacheSize, cache.NopMetricsProvider())

sKey := types.NewKVStoreKey("test")
tree, err := iavl.NewMutableTree(db, 100)
tree, err := iavl.NewMutableTree(db, 100, false)
require.NoError(t, err)
store := iavlstore.UnsafeNewStore(tree)
store2 := mngr.GetStoreCache(sKey, store)
@@ -33,7 +33,7 @@ func TestUnwrap(t *testing.T) {
mngr := cache.NewCommitKVStoreCacheManager(cache.DefaultCommitKVStoreCacheSize, cache.NopMetricsProvider())

sKey := types.NewKVStoreKey("test")
tree, err := iavl.NewMutableTree(db, 100)
tree, err := iavl.NewMutableTree(db, 100, false)
require.NoError(t, err)
store := iavlstore.UnsafeNewStore(tree)
_ = mngr.GetStoreCache(sKey, store)
@@ -47,7 +47,7 @@ func TestStoreCache(t *testing.T) {
mngr := cache.NewCommitKVStoreCacheManager(cache.DefaultCommitKVStoreCacheSize, cache.NopMetricsProvider())

sKey := types.NewKVStoreKey("test")
tree, err := iavl.NewMutableTree(db, 100)
tree, err := iavl.NewMutableTree(db, 100, false)
require.NoError(t, err)
store := iavlstore.UnsafeNewStore(tree)
kvStore := mngr.GetStoreCache(sKey, store)
78 changes: 33 additions & 45 deletions store/iavl/store.go
Original file line number Diff line number Diff line change
@@ -44,16 +44,16 @@ type Store struct {
// LoadStore returns an IAVL Store as a CommitKVStore. Internally, it will load the
// store's version (id) from the provided DB. An error is returned if the version
// fails to load, or if called with a positive version on an empty tree.
func LoadStore(db dbm.DB, id types.CommitID, lazyLoading bool, cacheSize int) (types.CommitKVStore, error) {
return LoadStoreWithInitialVersion(db, id, lazyLoading, 0, cacheSize)
func LoadStore(db dbm.DB, id types.CommitID, lazyLoading bool, cacheSize int, disableFastNode bool) (types.CommitKVStore, error) {
return LoadStoreWithInitialVersion(db, id, lazyLoading, 0, cacheSize, disableFastNode)
}

// LoadStoreWithInitialVersion returns an IAVL Store as a CommitKVStore setting its initialVersion
// to the one given. Internally, it will load the store's version (id) from the
// provided DB. An error is returned if the version fails to load, or if called with a positive
// version on an empty tree.
func LoadStoreWithInitialVersion(db dbm.DB, id types.CommitID, lazyLoading bool, initialVersion uint64, cacheSize int) (types.CommitKVStore, error) {
tree, err := iavl.NewMutableTreeWithOpts(db, cacheSize, &iavl.Options{InitialVersion: initialVersion})
func LoadStoreWithInitialVersion(db dbm.DB, id types.CommitID, lazyLoading bool, initialVersion uint64, cacheSize int, disableFastNode bool) (types.CommitKVStore, error) {
tree, err := iavl.NewMutableTreeWithOpts(db, cacheSize, &iavl.Options{InitialVersion: initialVersion}, disableFastNode)
if err != nil {
return nil, err
}
@@ -123,9 +123,14 @@ func (st *Store) Commit() types.CommitID {

// LastCommitID implements Committer.
func (st *Store) LastCommitID() types.CommitID {
hash, err := st.tree.Hash()
if err != nil {
panic(err)
}

return types.CommitID{
Version: st.tree.Version(),
Hash: st.tree.Hash(),
Hash: hash,
}
}

@@ -181,14 +186,21 @@ func (st *Store) Set(key, value []byte) {
// Implements types.KVStore.
func (st *Store) Get(key []byte) []byte {
defer telemetry.MeasureSince(time.Now(), "store", "iavl", "get")
_, value := st.tree.Get(key)
value, err := st.tree.Get(key)
if err != nil {
panic(err)
}
return value
}

// Implements types.KVStore.
func (st *Store) Has(key []byte) (exists bool) {
defer telemetry.MeasureSince(time.Now(), "store", "iavl", "has")
return st.tree.Has(key)
has, err := st.tree.Has(key)
if err != nil {
panic(err)
}
return has
}

// Implements types.KVStore.
@@ -206,30 +218,20 @@ func (st *Store) DeleteVersions(versions ...int64) error {

// Implements types.KVStore.
func (st *Store) Iterator(start, end []byte) types.Iterator {
var iTree *iavl.ImmutableTree

switch tree := st.tree.(type) {
case *immutableTree:
iTree = tree.ImmutableTree
case *iavl.MutableTree:
iTree = tree.ImmutableTree
iterator, err := st.tree.Iterator(start, end, true)
if err != nil {
panic(err)
}

return newIAVLIterator(iTree, start, end, true)
return iterator
}

// Implements types.KVStore.
func (st *Store) ReverseIterator(start, end []byte) types.Iterator {
var iTree *iavl.ImmutableTree

switch tree := st.tree.(type) {
case *immutableTree:
iTree = tree.ImmutableTree
case *iavl.MutableTree:
iTree = tree.ImmutableTree
iterator, err := st.tree.Iterator(start, end, false)
if err != nil {
panic(err)
}

return newIAVLIterator(iTree, start, end, false)
return iterator
}

// SetInitialVersion sets the initial version of the IAVL tree. It is used when
@@ -304,7 +306,12 @@ func (st *Store) Query(req abci.RequestQuery) (res abci.ResponseQuery) {
break
}

_, res.Value = tree.GetVersioned(key, res.Height)
value, err := tree.GetVersioned(key, res.Height)
if err != nil {
panic(err)
}
res.Value = value

if !req.Prove {
break
}
@@ -379,22 +386,3 @@ func getProofFromTree(tree *iavl.MutableTree, key []byte, exists bool) *occrypto
op := types.NewIavlCommitmentOp(key, commitmentProof)
return &occrypto.ProofOps{Ops: []occrypto.ProofOp{op.ProofOp()}}
}

//----------------------------------------

// Implements types.Iterator.
type iavlIterator struct {
*iavl.Iterator
}

var _ types.Iterator = (*iavlIterator)(nil)

// newIAVLIterator will create a new iavlIterator.
// CONTRACT: Caller must release the iavlIterator, as each one creates a new
// goroutine.
func newIAVLIterator(tree *iavl.ImmutableTree, start, end []byte, ascending bool) *iavlIterator {
iter := &iavlIterator{
Iterator: tree.Iterator(start, end, ascending),
}
return iter
}
41 changes: 24 additions & 17 deletions store/iavl/store_test.go
Original file line number Diff line number Diff line change
@@ -32,7 +32,7 @@ func randBytes(numBytes int) []byte {

// make a tree with data from above and save it
func newAlohaTree(t *testing.T, db dbm.DB) (*iavl.MutableTree, types.CommitID) {
tree, err := iavl.NewMutableTree(db, cacheSize)
tree, err := iavl.NewMutableTree(db, cacheSize, false)
require.NoError(t, err)

for k, v := range treeData {
@@ -57,21 +57,27 @@ func TestLoadStore(t *testing.T) {
store := UnsafeNewStore(tree)

// Create non-pruned height H
require.True(t, tree.Set([]byte("hello"), []byte("hallo")))
updated, err := tree.Set([]byte("hello"), []byte("hallo"))
require.NoError(t, err)
require.True(t, updated)
hash, verH, err := tree.SaveVersion()
cIDH := types.CommitID{Version: verH, Hash: hash}
require.Nil(t, err)

// Create pruned height Hp
require.True(t, tree.Set([]byte("hello"), []byte("hola")))
updated, err = tree.Set([]byte("hello"), []byte("hola"))
require.NoError(t, err)
require.True(t, updated)
hash, verHp, err := tree.SaveVersion()
cIDHp := types.CommitID{Version: verHp, Hash: hash}
require.Nil(t, err)

// TODO: Prune this height

// Create current height Hc
require.True(t, tree.Set([]byte("hello"), []byte("ciao")))
updated, err = tree.Set([]byte("hello"), []byte("ciao"))
require.NoError(t, err)
require.True(t, updated)
hash, verHc, err := tree.SaveVersion()
cIDHc := types.CommitID{Version: verHc, Hash: hash}
require.Nil(t, err)
@@ -92,17 +98,17 @@ func TestLoadStore(t *testing.T) {
require.Equal(t, string(hcStore.Get([]byte("hello"))), "ciao")

// Querying a new store at some previous non-pruned height H
newHStore, err := LoadStore(db, cIDH, false, DefaultIAVLCacheSize)
newHStore, err := LoadStore(db, cIDH, false, DefaultIAVLCacheSize, false)
require.NoError(t, err)
require.Equal(t, string(newHStore.Get([]byte("hello"))), "hallo")

// Querying a new store at some previous pruned height Hp
newHpStore, err := LoadStore(db, cIDHp, false, DefaultIAVLCacheSize)
newHpStore, err := LoadStore(db, cIDHp, false, DefaultIAVLCacheSize, false)
require.NoError(t, err)
require.Equal(t, string(newHpStore.Get([]byte("hello"))), "hola")

// Querying a new store at current height H
newHcStore, err := LoadStore(db, cIDHc, false, DefaultIAVLCacheSize)
newHcStore, err := LoadStore(db, cIDHc, false, DefaultIAVLCacheSize, false)
require.NoError(t, err)
require.Equal(t, string(newHcStore.Get([]byte("hello"))), "ciao")
}
@@ -112,7 +118,8 @@ func TestGetImmutable(t *testing.T) {
tree, cID := newAlohaTree(t, db)
store := UnsafeNewStore(tree)

require.True(t, tree.Set([]byte("hello"), []byte("adios")))
updated, err := tree.Set([]byte("hello"), []byte("adios"))
require.True(t, updated)
hash, ver, err := tree.SaveVersion()
cID = types.CommitID{Version: ver, Hash: hash}
require.Nil(t, err)
@@ -272,7 +279,7 @@ func TestIAVLIterator(t *testing.T) {
func TestIAVLReverseIterator(t *testing.T) {
db := dbm.NewMemDB()

tree, err := iavl.NewMutableTree(db, cacheSize)
tree, err := iavl.NewMutableTree(db, cacheSize, false)
require.NoError(t, err)

iavlStore := UnsafeNewStore(tree)
@@ -305,7 +312,7 @@ func TestIAVLReverseIterator(t *testing.T) {

func TestIAVLPrefixIterator(t *testing.T) {
db := dbm.NewMemDB()
tree, err := iavl.NewMutableTree(db, cacheSize)
tree, err := iavl.NewMutableTree(db, cacheSize, false)
require.NoError(t, err)

iavlStore := UnsafeNewStore(tree)
@@ -369,7 +376,7 @@ func TestIAVLPrefixIterator(t *testing.T) {

func TestIAVLReversePrefixIterator(t *testing.T) {
db := dbm.NewMemDB()
tree, err := iavl.NewMutableTree(db, cacheSize)
tree, err := iavl.NewMutableTree(db, cacheSize, false)
require.NoError(t, err)

iavlStore := UnsafeNewStore(tree)
@@ -437,7 +444,7 @@ func nextVersion(iavl *Store) {

func TestIAVLNoPrune(t *testing.T) {
db := dbm.NewMemDB()
tree, err := iavl.NewMutableTree(db, cacheSize)
tree, err := iavl.NewMutableTree(db, cacheSize, false)
require.NoError(t, err)

iavlStore := UnsafeNewStore(tree)
@@ -456,7 +463,7 @@ func TestIAVLNoPrune(t *testing.T) {

func TestIAVLGetAllVersions(t *testing.T) {
db := dbm.NewMemDB()
tree, err := iavl.NewMutableTree(db, cacheSize)
tree, err := iavl.NewMutableTree(db, cacheSize, false)
require.NoError(t, err)

iavlStore := UnsafeNewStore(tree)
@@ -476,7 +483,7 @@ func TestIAVLGetAllVersions(t *testing.T) {

func TestIAVLStoreQuery(t *testing.T) {
db := dbm.NewMemDB()
tree, err := iavl.NewMutableTree(db, cacheSize)
tree, err := iavl.NewMutableTree(db, cacheSize, false)
require.NoError(t, err)

iavlStore := UnsafeNewStore(tree)
@@ -580,7 +587,7 @@ func BenchmarkIAVLIteratorNext(b *testing.B) {
b.ReportAllocs()
db := dbm.NewMemDB()
treeSize := 1000
tree, err := iavl.NewMutableTree(db, cacheSize)
tree, err := iavl.NewMutableTree(db, cacheSize, false)
require.NoError(b, err)

for i := 0; i < treeSize; i++ {
@@ -614,7 +621,7 @@ func TestSetInitialVersion(t *testing.T) {
{
"works with a mutable tree",
func(db *dbm.MemDB) *Store {
tree, err := iavl.NewMutableTree(db, cacheSize)
tree, err := iavl.NewMutableTree(db, cacheSize, false)
require.NoError(t, err)
store := UnsafeNewStore(tree)

@@ -624,7 +631,7 @@ func TestSetInitialVersion(t *testing.T) {
{
"throws error on immutable tree",
func(db *dbm.MemDB) *Store {
tree, err := iavl.NewMutableTree(db, cacheSize)
tree, err := iavl.NewMutableTree(db, cacheSize, false)
require.NoError(t, err)
store := UnsafeNewStore(tree)
_, version, err := store.tree.SaveVersion()
32 changes: 22 additions & 10 deletions store/iavl/tree.go
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@ import (
"fmt"

"github.com/cosmos/iavl"
"github.com/line/lbm-sdk/store/types"
)

var (
@@ -17,20 +18,23 @@ type (
// implemented by an iavl.MutableTree. For an immutable IAVL tree, a wrapper
// must be made.
Tree interface {
Has(key []byte) bool
Get(key []byte) (index int64, value []byte)
Set(key, value []byte) bool
Remove(key []byte) ([]byte, bool)
Has(key []byte) (bool, error)
Get(key []byte) ([]byte, error)
Set(key, value []byte) (bool, error)
Remove(key []byte) ([]byte, bool, error)
SaveVersion() ([]byte, int64, error)
DeleteVersion(version int64) error
DeleteVersions(versions ...int64) error
Version() int64
Hash() []byte
Hash() ([]byte, error)
VersionExists(version int64) bool
GetVersioned(key []byte, version int64) (int64, []byte)
GetVersioned(key []byte, version int64) ([]byte, error)
GetVersionedWithProof(key []byte, version int64) ([]byte, *iavl.RangeProof, error)
GetImmutable(version int64) (*iavl.ImmutableTree, error)
SetInitialVersion(version uint64)
Iterator(start, end []byte, ascending bool) (types.Iterator, error)
AvailableVersions() []int
LoadVersionForOverwriting(targetVersion int64) (int64, error)
}

// immutableTree is a simple wrapper around a reference to an iavl.ImmutableTree
@@ -41,11 +45,11 @@ type (
}
)

func (it *immutableTree) Set(_, _ []byte) bool {
func (it *immutableTree) Set(_, _ []byte) (bool, error) {
panic("cannot call 'Set' on an immutable IAVL tree")
}

func (it *immutableTree) Remove(_ []byte) ([]byte, bool) {
func (it *immutableTree) Remove(_ []byte) ([]byte, bool, error) {
panic("cannot call 'Remove' on an immutable IAVL tree")
}

@@ -69,9 +73,9 @@ func (it *immutableTree) VersionExists(version int64) bool {
return it.Version() == version
}

func (it *immutableTree) GetVersioned(key []byte, version int64) (int64, []byte) {
func (it *immutableTree) GetVersioned(key []byte, version int64) ([]byte, error) {
if it.Version() != version {
return -1, nil
return nil, fmt.Errorf("version mismatch on immutable IAVL tree; got: %d, expected: %d", version, it.Version())
}

return it.Get(key)
@@ -92,3 +96,11 @@ func (it *immutableTree) GetImmutable(version int64) (*iavl.ImmutableTree, error

return it.ImmutableTree, nil
}

func (it *immutableTree) AvailableVersions() []int {
return []int{}
}

func (it *immutableTree) LoadVersionForOverwriting(targetVersion int64) (int64, error) {
panic("cannot call 'LoadVersionForOverwriting' on an immutable IAVL tree")
}
12 changes: 7 additions & 5 deletions store/iavl/tree_test.go
Original file line number Diff line number Diff line change
@@ -11,16 +11,18 @@ import (
func TestImmutableTreePanics(t *testing.T) {
t.Parallel()
db := dbm.NewMemDB()
immTree := iavl.NewImmutableTree(db, 100)
immTree := iavl.NewImmutableTree(db, 100, false)
it := &immutableTree{immTree}
require.Panics(t, func() { it.Set([]byte{}, []byte{}) })
require.Panics(t, func() { it.Remove([]byte{}) })
require.Panics(t, func() { it.SaveVersion() }) // nolint:errcheck
require.Panics(t, func() { it.DeleteVersion(int64(1)) }) // nolint:errcheck
v, _ := it.GetVersioned([]byte{0x01}, 1)
require.Equal(t, int64(-1), v)
v, _ = it.GetVersioned([]byte{0x01}, 0)
require.Equal(t, int64(0), v)
require.Panics(t, func() { it.LoadVersionForOverwriting(int64(1)) })
require.Equal(t, it.AvailableVersions(), []int{})

val, err := it.GetVersioned(nil, 1)
require.Error(t, err)
require.Nil(t, val)

val, proof, err := it.GetVersionedWithProof(nil, 1)
require.Error(t, err)
2 changes: 1 addition & 1 deletion store/prefix/store_test.go
Original file line number Diff line number Diff line change
@@ -89,7 +89,7 @@ func testPrefixStore(t *testing.T, baseStore types.KVStore, prefix []byte) {

func TestIAVLStorePrefix(t *testing.T) {
db := dbm.NewMemDB()
tree, err := liavl.NewMutableTree(db, cacheSize)
tree, err := liavl.NewMutableTree(db, cacheSize, false)
require.NoError(t, err)
iavlStore := iavl.UnsafeNewStore(tree)

2 changes: 1 addition & 1 deletion store/rootmulti/proof_test.go
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ import (
func TestVerifyIAVLStoreQueryProof(t *testing.T) {
// Create main tree for testing.
db := dbm.NewMemDB()
iStore, err := iavl.LoadStore(db, types.CommitID{}, false, iavl.DefaultIAVLCacheSize)
iStore, err := iavl.LoadStore(db, types.CommitID{}, false, iavl.DefaultIAVLCacheSize, false)
store := iStore.(*iavl.Store)
require.Nil(t, err)
store.Set([]byte("MYKEY"), []byte("MYVALUE"))
48 changes: 28 additions & 20 deletions store/rootmulti/store.go
Original file line number Diff line number Diff line change
@@ -28,6 +28,8 @@ import (
sdkerrors "github.com/line/lbm-sdk/types/errors"
)

const iavlDisablefastNodeDefault = false

const (
latestVersionKey = "s/latest"
pruneHeightsKey = "s/pruneheights"
@@ -38,16 +40,17 @@ const (
// cacheMultiStore which is used for branching other MultiStores. It implements
// the CommitMultiStore interface.
type Store struct {
db dbm.DB
lastCommitInfo *types.CommitInfo
pruningOpts types.PruningOptions
iavlCacheSize int
storesParams map[types.StoreKey]storeParams
stores map[types.StoreKey]types.CommitKVStore
keysByName map[string]types.StoreKey
lazyLoading bool
pruneHeights []int64
initialVersion int64
db dbm.DB
lastCommitInfo *types.CommitInfo
pruningOpts types.PruningOptions
iavlCacheSize int
iavlDisableFastNode bool
storesParams map[types.StoreKey]storeParams
stores map[types.StoreKey]types.CommitKVStore
keysByName map[string]types.StoreKey
lazyLoading bool
pruneHeights []int64
initialVersion int64

traceWriter io.Writer
traceContext types.TraceContext
@@ -69,14 +72,15 @@ var (
// LoadVersion must be called.
func NewStore(db dbm.DB) *Store {
return &Store{
db: db,
pruningOpts: types.PruneNothing,
storesParams: make(map[types.StoreKey]storeParams),
stores: make(map[types.StoreKey]types.CommitKVStore),
keysByName: make(map[string]types.StoreKey),
pruneHeights: make([]int64, 0),
listeners: make(map[types.StoreKey][]types.WriteListener),
iavlCacheSize: iavl.DefaultIAVLCacheSize,
db: db,
pruningOpts: types.PruneNothing,
storesParams: make(map[types.StoreKey]storeParams),
stores: make(map[types.StoreKey]types.CommitKVStore),
keysByName: make(map[string]types.StoreKey),
pruneHeights: make([]int64, 0),
listeners: make(map[types.StoreKey][]types.WriteListener),
iavlCacheSize: iavl.DefaultIAVLCacheSize,
iavlDisableFastNode: iavlDisablefastNodeDefault,
}
}

@@ -96,6 +100,10 @@ func (rs *Store) SetIAVLCacheSize(cacheSize int) {
rs.iavlCacheSize = cacheSize
}

func (rs *Store) SetIAVLDisableFastNode(disableFastNode bool) {
rs.iavlDisableFastNode = disableFastNode
}

// SetLazyLoading sets if the iavl store should be loaded lazily or not
func (rs *Store) SetLazyLoading(lazyLoading bool) {
rs.lazyLoading = lazyLoading
@@ -835,9 +843,9 @@ func (rs *Store) loadCommitStoreFromParams(key types.StoreKey, id types.CommitID
var err error

if params.initialVersion == 0 {
store, err = iavl.LoadStore(db, id, rs.lazyLoading, rs.iavlCacheSize)
store, err = iavl.LoadStore(db, id, rs.lazyLoading, rs.iavlCacheSize, rs.iavlDisableFastNode)
} else {
store, err = iavl.LoadStoreWithInitialVersion(db, id, rs.lazyLoading, params.initialVersion, rs.iavlCacheSize)
store, err = iavl.LoadStoreWithInitialVersion(db, id, rs.lazyLoading, params.initialVersion, rs.iavlCacheSize, rs.iavlDisableFastNode)
}

if err != nil {
11 changes: 11 additions & 0 deletions store/rootmulti/store_test.go
Original file line number Diff line number Diff line change
@@ -887,3 +887,14 @@ func hashStores(stores map[types.StoreKey]types.CommitKVStore) []byte {
}
return sdkmaps.HashFromMap(m)
}

func TestSetIAVLDIsableFastNode(t *testing.T) {
db := dbm.NewMemDB()
multi := newMultiStoreWithMounts(db, types.PruneNothing)

multi.SetIAVLDisableFastNode(true)
require.Equal(t, multi.iavlDisableFastNode, true)

multi.SetIAVLDisableFastNode(false)
require.Equal(t, multi.iavlDisableFastNode, false)
}
2 changes: 1 addition & 1 deletion store/types/iterator_test.go
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@ import (

func newMemTestKVStore(t *testing.T) types.KVStore {
db := dbm.NewMemDB()
store, err := iavl.LoadStore(db, types.CommitID{}, false, iavl.DefaultIAVLCacheSize)
store, err := iavl.LoadStore(db, types.CommitID{}, false, iavl.DefaultIAVLCacheSize, false)
require.NoError(t, err)
return store
}
5 changes: 4 additions & 1 deletion store/types/store.go
Original file line number Diff line number Diff line change
@@ -191,6 +191,9 @@ type CommitMultiStore interface {

// SetIAVLCacheSize sets the cache size of the IAVL tree.
SetIAVLCacheSize(size int)

// SetIAVLDisableFastNode enables/disables fastnode feature on iavl.
SetIAVLDisableFastNode(disable bool)
}

//---------subsp-------------------------------
@@ -200,7 +203,7 @@ type CommitMultiStore interface {
type KVStore interface {
Store

// Get returns nil iff key doesn't exist. Panics on nil key.
// Get returns nil if key doesn't exist. Panics on nil key.
Get(key []byte) []byte

// Has checks if a key exists. Panics on nil key.
2 changes: 1 addition & 1 deletion x/wasm/keeper/keeper.go
Original file line number Diff line number Diff line change
@@ -876,7 +876,7 @@ func (k Keeper) GetByteCode(ctx sdk.Context, codeID uint64) ([]byte, error) {
var codeInfo types.CodeInfo
codeInfoBz := store.Get(types.GetCodeKey(codeID))
if codeInfoBz == nil {
return nil, nil
return nil, types.ErrNotFound
}
k.cdc.MustUnmarshal(codeInfoBz, &codeInfo)
return k.wasmVM.GetCode(codeInfo.CodeHash)
37 changes: 37 additions & 0 deletions x/wasm/keeper/keeper_test.go
Original file line number Diff line number Diff line change
@@ -1928,3 +1928,40 @@ func TestIterateInactiveContracts(t *testing.T) {
expectList := []sdk.AccAddress{example1.Contract, example2.Contract}
assert.ElementsMatch(t, expectList, inactiveContracts)
}

func TestKeeper_GetByteCode(t *testing.T) {

ctx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil)
keeper := keepers.ContractKeeper

deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
creator := keepers.Faucet.NewFundedAccount(ctx, deposit...)

em := sdk.NewEventManager()
_, err := keeper.Create(ctx.WithEventManager(em), creator, hackatomWasm, nil)
require.NoError(t, err)

tests := []struct {
name string
codeID uint64
want []byte
wantErr bool
expErr *sdkerrors.Error
}{
{name: "success", codeID: 1, want: hackatomWasm, wantErr: false, expErr: nil},
{name: "not found contract", codeID: 42, want: nil, wantErr: true, expErr: types.ErrNotFound},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := keepers.WasmKeeper.GetByteCode(ctx, tt.codeID)
if tt.wantErr {
require.Equal(t, err, tt.expErr)
return
}
require.NoError(t, err)
require.Equal(t, tt.want, got)

})
}
}
2 changes: 1 addition & 1 deletion x/wasm/types/iavl_range_test.go
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@ import (
// and designed to ensure the IAVL store handles bounds the same way as the mock storage we use in Rust contract tests
func TestIavlRangeBounds(t *testing.T) {
db := dbm.NewMemDB()
tree, err := iavltree.NewMutableTree(db, 50)
tree, err := iavltree.NewMutableTree(db, 50, false)
require.NoError(t, err)
kvstore := iavl.UnsafeNewStore(tree)

0 comments on commit cafab15

Please sign in to comment.