Skip to content

Commit

Permalink
Sims app v2
Browse files Browse the repository at this point in the history
  • Loading branch information
alpe committed Jan 7, 2025
1 parent c1192da commit 4b8d17b
Show file tree
Hide file tree
Showing 30 changed files with 1,851 additions and 60 deletions.
5 changes: 5 additions & 0 deletions runtime/v2/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,8 @@ func (a *App[T]) SchemaDecoderResolver() decoding.DecoderResolver {
func (a *App[T]) Close() error {
return nil
}

// GetApp return self
func (a *App[T]) GetApp() *App[T] {
return a
}
10 changes: 8 additions & 2 deletions scripts/build/simulations.mk
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,16 @@ test-sim-multi-seed-long:
# @cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -timeout=2h -tags='sims' -run TestFullAppSimulation \
# -NumBlocks=150 -Period=50

test-sim-multi-seed-short:
test-sim-multi-seed-short: test-v2-sim-wip
# @echo "Running short multi-seed application simulation. This may take awhile!"
# @cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -timeout 30m -tags='sims' -run TestFullAppSimulation \
# -NumBlocks=50 -Period=10 -FauxMerkle=true
# -NumBlocks=50 -Period=10 -FauxMerkle=true

.Phony: test-v2-sim-wip
test-v2-sim-wip:
@echo "Running short multi-seed application simulation. This may take awhile!"
@cd ${CURRENT_DIR}/simapp/v2 && go test -failfast -mod=readonly -timeout 30m -tags='sims' -run TestSimsAppV2 \
# -NumBlocks=50 -Period=10 -FauxMerkle=true

test-sim-benchmark-invariants:
# @echo "Running simulation invariant benchmarks..."
Expand Down
29 changes: 29 additions & 0 deletions server/v2/appmanager/appmanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"encoding/json"
"errors"
"fmt"
"iter"

"cosmossdk.io/core/server"
corestore "cosmossdk.io/core/store"
Expand Down Expand Up @@ -53,6 +54,12 @@ type AppManager[T transaction.Tx] interface {
// independently of the db state. For example, it can be used to process a query with temporary
// and uncommitted state
QueryWithState(ctx context.Context, state corestore.ReaderMap, request transaction.Msg) (transaction.Msg, error)

DeliverSims(
ctx context.Context,
block *server.BlockRequest[T],
simsBuilder func(ctx context.Context) iter.Seq[T],
) (*server.BlockResponse, corestore.WriterMap, error)
}

// Store defines the underlying storage behavior needed by AppManager.
Expand Down Expand Up @@ -187,6 +194,28 @@ func (a appManager[T]) DeliverBlock(
return blockResponse, newState, nil
}

func (a appManager[T]) DeliverSims(
ctx context.Context,
block *server.BlockRequest[T],
simsBuilder func(ctx context.Context) iter.Seq[T],
) (*server.BlockResponse, corestore.WriterMap, error) {
latestVersion, currentState, err := a.db.StateLatest()
if err != nil {
return nil, nil, fmt.Errorf("unable to create new state for height %d: %w", block.Height, err)
}

if latestVersion+1 != block.Height {
return nil, nil, fmt.Errorf("invalid DeliverBlock height wanted %d, got %d", latestVersion+1, block.Height)
}

blockResponse, newState, err := a.stf.DeliverSims(ctx, block, currentState, simsBuilder)
if err != nil {
return nil, nil, fmt.Errorf("block delivery failed: %w", err)
}

return blockResponse, newState, nil
}

// ValidateTx will validate the tx against the latest storage state. This means that
// only the stateful validation will be run, not the execution portion of the tx.
// If full execution is needed, Simulate must be used.
Expand Down
8 changes: 8 additions & 0 deletions server/v2/appmanager/stf.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package appmanager

import (
"context"
"iter"

"cosmossdk.io/core/server"
"cosmossdk.io/core/store"
Expand Down Expand Up @@ -40,4 +41,11 @@ type StateTransitionFunction[T transaction.Tx] interface {
gasLimit uint64,
req transaction.Msg,
) (transaction.Msg, error)

DeliverSims(
ctx context.Context,
block *server.BlockRequest[T],
state store.ReaderMap,
simsBuilder func(ctx context.Context) iter.Seq[T],
) (blockResult *server.BlockResponse, newState store.WriterMap, err error)
}
34 changes: 34 additions & 0 deletions server/v2/stf/sims_entry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package stf

import (
"context"
"iter"

"cosmossdk.io/core/header"
"cosmossdk.io/core/server"
"cosmossdk.io/core/store"
"cosmossdk.io/core/transaction"
)

// doSimsTXs constructs a function to simulate transactions in a block execution context using the provided simsBuilder.
func (s STF[T]) doSimsTXs(simsBuilder func(ctx context.Context) iter.Seq[T]) doInBlockDeliveryFn[T] {
return func(
exCtx context.Context,
_ []T,
newState store.WriterMap,
hi header.Info,
) ([]server.TxResult, error) {
const key = "sims.header.time"
simsCtx := context.WithValue(exCtx, key, hi.Time) //nolint: staticcheck // using string key to decouple
var results []server.TxResult
var i int32
for tx := range simsBuilder(simsCtx) {
if err := isCtxCancelled(simsCtx); err != nil {
return nil, err
}
results = append(results, s.deliverTx(simsCtx, newState, tx, transaction.ExecModeFinalize, hi, i+1))
i++
}
return results, nil
}
}
58 changes: 50 additions & 8 deletions server/v2/stf/stf.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/json"
"errors"
"fmt"
"iter"
"strings"

appmodulev2 "cosmossdk.io/core/appmodule/v2"
Expand Down Expand Up @@ -84,13 +85,40 @@ func New[T transaction.Tx](
}, nil
}

// DeliverSims entrypoint to processes sims transactions similar to DeliverBlock.
func (s STF[T]) DeliverSims(
ctx context.Context,
block *server.BlockRequest[T],
state store.ReaderMap,
simsBuilder func(ctx context.Context) iter.Seq[T],
) (blockResult *server.BlockResponse, newState store.WriterMap, err error) {
return s.deliverBlock(ctx, block, state, s.doSimsTXs(simsBuilder))
}

// DeliverBlock is our state transition function.
// It takes a read only view of the state to apply the block to,
// executes the block and returns the block results and the new state.
func (s STF[T]) DeliverBlock(
ctx context.Context,
block *server.BlockRequest[T],
state store.ReaderMap,
) (blockResult *server.BlockResponse, newState store.WriterMap, err error) {
return s.deliverBlock(ctx, block, state, s.doDeliverTXs)
}

// common code path for DeliverSims and DeliverBlock
type doInBlockDeliveryFn[T transaction.Tx] func(
ctx context.Context,
txs []T,
newState store.WriterMap,
hi header.Info,
) ([]server.TxResult, error)

func (s STF[T]) deliverBlock(
ctx context.Context,
block *server.BlockRequest[T],
state store.ReaderMap,
doInBlockDelivery doInBlockDeliveryFn[T],
) (blockResult *server.BlockResponse, newState store.WriterMap, err error) {
// creates a new branchFn state, from the readonly view of the state
// that can be written to.
Expand Down Expand Up @@ -141,14 +169,9 @@ func (s STF[T]) DeliverBlock(
}

// execute txs
txResults := make([]server.TxResult, len(block.Txs))
// TODO: skip first tx if vote extensions are enabled (marko)
for i, txBytes := range block.Txs {
// check if we need to return early or continue delivering txs
if err = isCtxCancelled(ctx); err != nil {
return nil, nil, err
}
txResults[i] = s.deliverTx(exCtx, newState, txBytes, transaction.ExecModeFinalize, hi, int32(i+1))
txResults, err := doInBlockDelivery(exCtx, block.Txs, newState, hi)
if err != nil {
return nil, nil, err
}
// reset events
exCtx.events = make([]event.Event, 0)
Expand All @@ -167,6 +190,25 @@ func (s STF[T]) DeliverBlock(
}, newState, nil
}

func (s STF[T]) doDeliverTXs(
exCtx context.Context,
txs []T,
newState store.WriterMap,
hi header.Info,
) ([]server.TxResult, error) {
// execute txs
txResults := make([]server.TxResult, len(txs))
// TODO: skip first tx if vote extensions are enabled (marko)
for i, txBytes := range txs {
// check if we need to return early or continue delivering txs
if err := isCtxCancelled(exCtx); err != nil {
return nil, err
}
txResults[i] = s.deliverTx(exCtx, newState, txBytes, transaction.ExecModeFinalize, hi, int32(i+1))
}
return txResults, nil
}

// deliverTx executes a TX and returns the result.
func (s STF[T]) deliverTx(
ctx context.Context,
Expand Down
3 changes: 2 additions & 1 deletion server/v2/streaming/examples/file/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import (
"os"
"path/filepath"

"cosmossdk.io/server/v2/streaming"
"github.com/hashicorp/go-plugin"

"cosmossdk.io/server/v2/streaming"
)

// FilePlugin is the implementation of the baseapp.ABCIListener interface
Expand Down
Loading

0 comments on commit 4b8d17b

Please sign in to comment.