Skip to content

Commit

Permalink
rm mutex and iavlv import/export
Browse files Browse the repository at this point in the history
  • Loading branch information
kocubinski committed Dec 10, 2024
1 parent ec91784 commit 4b43c99
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 101 deletions.
11 changes: 11 additions & 0 deletions scripts/init-simapp-v2.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,23 @@ sed -i '' 's/prometheus = false/prometheus = true/' "$SIMD_HOME"/config/config.t

$SIMD_BIN keys add alice --indiscreet
$SIMD_BIN keys add bob --indiscreet
aliases=""
for i in $(seq 10); do
alias=$(dd if=/dev/urandom bs=16 count=24 2> /dev/null | base32 | head -c 32)
$SIMD_BIN keys add "$alias" --indiscreet
aliases="$aliases $alias"
done
echo "Generated aliases: $aliases"

$SIMD_BIN init simapp-v2-node --chain-id simapp-v2-chain
# to change the voting_period
jq '.app_state.gov.params.voting_period = "600s"' $SIMD_HOME/config/genesis.json > temp.json && mv temp.json $SIMD_HOME/config/genesis.json
jq '.app_state.gov.params.expedited_voting_period = "300s"' $SIMD_HOME/config/genesis.json > temp.json && mv temp.json $SIMD_HOME/config/genesis.json
jq '.app_state.mint.minter.inflation = "0.300000000000000000"' $SIMD_HOME/config/genesis.json > temp.json && mv temp.json $SIMD_HOME/config/genesis.json # to change the inflation
$SIMD_BIN genesis add-genesis-account alice 5000000000stake --keyring-backend test
$SIMD_BIN genesis add-genesis-account bob 5000000000stake --keyring-backend test
for a in $aliases; do
$SIMD_BIN genesis add-genesis-account "$a" 100000000stake --keyring-backend test
done
$SIMD_BIN genesis gentx alice 1000000stake --chain-id simapp-v2-chain
$SIMD_BIN genesis collect-gentxs
5 changes: 3 additions & 2 deletions server/v2/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,9 @@ func createStartCommand[T transaction.Tx](
// wrapCPUProfile starts CPU profiling, if enabled, and executes the provided
// callbackFn, then waits for it to return.
func wrapCPUProfile(logger log.Logger, cfg server.ConfigMap, callbackFn func() error) error {
cpuProfileFile, ok := cfg[FlagCPUProfiling]
if !ok {
serverCfg := cfg[serverName].(map[string]any)
cpuProfileFile, ok := serverCfg["cpu-profile"]
if !ok || cpuProfileFile == "" {
// if cpu profiling is not enabled, just run the callback
return callbackFn()
}
Expand Down
2 changes: 1 addition & 1 deletion simapp/app_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ var (
GenesisParams: &benchmarkmodulev1.GeneratorParams{
Seed: 34,
BucketCount: 3,
GenesisCount: 10_000_000,
GenesisCount: 1_000_000,
KeyMean: 64,
KeyStdDev: 12,
ValueMean: 1024,
Expand Down
59 changes: 59 additions & 0 deletions store/v2/commitment/iavlv2/snapshot.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package iavlv2

import (
"errors"

"github.com/cosmos/iavl/v2"

"cosmossdk.io/store/v2/commitment"
snapshotstypes "cosmossdk.io/store/v2/snapshots/types"
)

// Exporter is a wrapper around iavl.Exporter.
type Exporter struct {
exporter *iavl.Exporter
}

// Next returns the next item in the exporter.
func (e *Exporter) Next() (*snapshotstypes.SnapshotIAVLItem, error) {
item, err := e.exporter.Next()
if err != nil {
if errors.Is(err, iavl.ErrorExportDone) {
return nil, commitment.ErrorExportDone
}
return nil, err
}

return &snapshotstypes.SnapshotIAVLItem{
Key: item.Key(),
Value: item.Value(),
Version: item.Version(),
Height: int32(item.Height()),
}, nil
}

// Close closes the exporter.
func (e *Exporter) Close() error {
return e.exporter.Close()
}

type Importer struct {
importer *iavl.Importer
}

// Add adds the given item to the importer.
func (i *Importer) Add(item *snapshotstypes.SnapshotIAVLItem) error {
return i.importer.Add(iavl.NewImportNode(item.Key, item.Value, item.Version, int8(item.Height)))
}

// Commit commits the importer.
func (i *Importer) Commit() error {
return i.importer.Commit()
}

// Close closes the importer.
func (i *Importer) Close() error {
i.importer.Close()

return nil
}
125 changes: 52 additions & 73 deletions store/v2/commitment/iavlv2/tree.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package iavlv2

import (
"errors"
"fmt"

"cosmossdk.io/core/log"
Expand Down Expand Up @@ -101,52 +100,28 @@ func (t *Tree) Get(version uint64, key []byte) ([]byte, error) {
if err := isHighBitSet(version); err != nil {
return nil, err
}
h := t.tree.Version()
v := int64(version)
switch {
// TODO permit h+1 read only if the tree is dirty (i.e. has uncommitted changes from WriteChangeset)
case v == h || v == h+1:
return t.tree.Get(key)
case v > h:
h := t.tree.Version()
if v > h {
return nil, fmt.Errorf("get: cannot read future version %d; h: %d path=%s", v, h, t.path)
case v < h:
cloned, err := t.tree.ReadonlyClone()
if err != nil {
return nil, err
}
if err = cloned.LoadVersion(int64(version)); err != nil {
return nil, err
}
return cloned.Get(key)
default:
return nil, fmt.Errorf("unexpected version comparison: tree version: %d, requested: %d", h, v)
}
versionFound, val, err := t.tree.GetRecent(v, key)
if versionFound {
return val, err
}
cloned, err := t.tree.ReadonlyClone()
if err != nil {
return nil, err
}
if err = cloned.LoadVersion(int64(version)); err != nil {
return nil, err
}
return cloned.Get(key)
}

func (t *Tree) Has(version uint64, key []byte) (bool, error) {
if err := isHighBitSet(version); err != nil {
return false, err
}
h := t.tree.Version()
v := int64(version)
switch {
// TODO permit h+1 read only if the tree is dirty (i.e. has uncommitted changes from WriteChangeset)
case v == h || v == h+1:
return t.tree.Has(key)
case v > h:
return false, fmt.Errorf("has: cannot read future version %d; h: %d", v, h)
case v < h:
cloned, err := t.tree.ReadonlyClone()
if err != nil {
return false, err
}
if err = cloned.LoadVersion(int64(version)); err != nil {
return false, err
}
return cloned.Has(key)
default:
return false, fmt.Errorf("unexpected version comparison: tree version: %d, requested: %d", h, v)
}
res, err := t.Get(version, key)
return res != nil, err
}

func (t *Tree) Iterator(version uint64, start, end []byte, ascending bool) (corestore.Iterator, error) {
Expand All @@ -155,45 +130,49 @@ func (t *Tree) Iterator(version uint64, start, end []byte, ascending bool) (core
}
h := t.tree.Version()
v := int64(version)

switch {
// TODO permit h+1 read only if the tree is dirty (i.e. has uncommitted changes from WriteChangeset)
case v == h || v == h+1:
if ascending {
// inclusive = false is IAVL v1's default behavior.
// the read expectations of certain modules (like x/staking) will cause a panic if this is changed.
return t.tree.Iterator(start, end, false)
} else {
return t.tree.ReverseIterator(start, end)
}
case v > h:
return nil, fmt.Errorf("has: cannot read future version %d; h: %d", v, h)
case v < h:
cloned, err := t.tree.ReadonlyClone()
if err != nil {
return nil, err
}
if err = cloned.LoadVersion(int64(version)); err != nil {
return nil, err
}
if ascending {
// inclusive = false is IAVL v1's default behavior.
// the read expectations of certain modules (like x/staking) will cause a panic if this is changed.
return t.tree.Iterator(start, end, false)
} else {
return t.tree.ReverseIterator(start, end)
}
default:
return nil, fmt.Errorf("unexpected version comparison: tree version: %d, requested: %d", h, v)
if v > h {
return nil, fmt.Errorf("iterator: cannot read future version %d; h: %d", v, h)
}
ok, itr := t.tree.IterateRecent(v, start, end, ascending)
if ok {
return itr, nil
}
cloned, err := t.tree.ReadonlyClone()
if err != nil {
return nil, err
}
if err = cloned.LoadVersion(int64(version)); err != nil {
return nil, err
}
if ascending {
// inclusive = false is IAVL v1's default behavior.
// the read expectations of certain modules (like x/staking) will cause a panic if this is changed.
return t.tree.Iterator(start, end, false)
} else {
return t.tree.ReverseIterator(start, end)
}
}

func (t *Tree) Export(version uint64) (commitment.Exporter, error) {
return nil, errors.New("snapshot import/export not yet supported")
if err := isHighBitSet(version); err != nil {
return nil, err
}
e, err := t.tree.Export(int64(version), iavl.PostOrder)
if err != nil {
return nil, err
}
return &Exporter{e}, nil
}

func (t *Tree) Import(version uint64) (commitment.Importer, error) {
return nil, errors.New("snapshot import/export not yet supported")
if err := isHighBitSet(version); err != nil {
return nil, err
}
importer, err := t.tree.Import(int64(version))
if err != nil {
return nil, err
}
return &Importer{importer}, nil
}

func (t *Tree) Close() error {
Expand Down
2 changes: 1 addition & 1 deletion store/v2/root/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ func CreateRootStore(opts *FactoryOptions) (store.RootStore, error) {
dir := fmt.Sprintf("%s/data/iavl-v2/%s", opts.RootDir, key)
// TODO load from config YAML or at least simapp
iavlOpts := iavl_v2.DefaultTreeOptions()
iavlOpts.EvictionDepth = 18
iavlOpts.EvictionDepth = 22
iavlOpts.HeightFilter = 1
iavlOpts.CheckpointInterval = 55
return iavlv2.NewTree(iavlOpts, iavl_v2.SqliteDbOptions{Path: dir}, opts.Logger)
Expand Down
32 changes: 8 additions & 24 deletions store/v2/root/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,6 @@ type Store struct {
chDone chan struct{}
// isMigrating reflects whether the store is currently migrating
isMigrating bool

preCommit sync.RWMutex
preCommitVersion uint64
}

// New creates a new root Store instance.
Expand Down Expand Up @@ -124,18 +121,16 @@ func (s *Store) StateAt(v uint64) (corestore.ReaderMap, error) {
}

func (s *Store) StateLatest() (uint64, corestore.ReaderMap, error) {
s.preCommit.RLock()
v := s.preCommitVersion
s.preCommit.RUnlock()
if v == 0 {
var err error
v, err = s.GetLatestVersion()
if err != nil {
return 0, nil, err
}
v, err := s.GetLatestVersion()
if err != nil {
return 0, nil, err
}
vReader, err := s.getVersionedReader(v)
if err != nil {
return 0, nil, err
}

return v, NewReaderMap(v, s.stateCommitment), nil
return v, NewReaderMap(v, vReader), nil
}

func (s *Store) GetStateCommitment() store.Committer {
Expand Down Expand Up @@ -313,28 +308,17 @@ func (s *Store) Commit(cs *corestore.Changeset) ([]byte, error) {
s.pruningManager.PausePruning()

st := time.Now()
s.preCommit.Lock()
if err := s.stateCommitment.WriteChangeset(cs); err != nil {
s.preCommit.Unlock()
return nil, fmt.Errorf("failed to write batch to SC store: %w", err)
}
lastVersion := s.preCommitVersion
s.preCommitVersion = cs.Version
s.preCommit.Unlock()

cInfo, err := s.stateCommitment.Commit(cs.Version)
if err != nil {
s.preCommit.Lock()
s.preCommitVersion = lastVersion
s.preCommit.Unlock()
return nil, fmt.Errorf("failed to commit SC store: %w", err)
}
s.logger.Warn(fmt.Sprintf("sc commit version %d took %s", cs.Version, time.Since(st)))

if cInfo.Version != cs.Version {
s.preCommit.Lock()
s.preCommitVersion = lastVersion
s.preCommit.Unlock()
return nil, fmt.Errorf("commit version mismatch: got %d, expected %d", cInfo.Version, cs.Version)
}
s.lastCommitInfo = cInfo
Expand Down
1 change: 1 addition & 0 deletions x/auth/ante/sigverify.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,7 @@ func (svd SigVerificationDecorator) verifySig(ctx context.Context, tx sdk.Tx, ac
// and therefore communicate sequence number as a potential cause of error.
errMsg = fmt.Sprintf("signature verification failed; please verify account number (%d), sequence (%d) and chain-id (%s): (%s)", accNum, acc.GetSequence(), chainID, err.Error())
} else {
fmt.Printf("signature verification failed!!!! account number (%d)", accNum)
errMsg = fmt.Sprintf("signature verification failed; please verify account number (%d) and chain-id (%s): (%s)", accNum, chainID, err.Error())
}
return errorsmod.Wrap(sdkerrors.ErrUnauthorized, errMsg)
Expand Down

0 comments on commit 4b43c99

Please sign in to comment.