From bbcbc074c92db56ae34573a8239d21c0dd42f155 Mon Sep 17 00:00:00 2001 From: Mark Rushakoff Date: Tue, 22 Oct 2024 16:47:46 -0400 Subject: [PATCH] feat(server/v2): add SimulateWithState to AppManager There is already the QueryWithState method to query against a modified state, but the Simulate analog was missing. This is useful in particular when a server component receives different transactions at different times, and wants to ensure that subsequent transactions would be valid to apply after the prior transactions. In other words, the first received transaction can be validated with Simulate; then the returned corestore.WriterMap is used to seed the input to the following call to SimulateWithState; and then the returned corestore.WriterMap is used for all following SimulateWithState calls. While it is currently impossible for SimulateWithState to return an error, an error value is in the return signature for symmetry with other AppManager methods and to allow the possibility of returned errors in the future. There were no existing tests in the server/v2/appmanager package, to be expanded to include test coverage for the new method. --- server/v2/appmanager/appmanager.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/server/v2/appmanager/appmanager.go b/server/v2/appmanager/appmanager.go index af54936ebf03..9380efb0bf21 100644 --- a/server/v2/appmanager/appmanager.go +++ b/server/v2/appmanager/appmanager.go @@ -41,6 +41,10 @@ type AppManager[T transaction.Tx] interface { // Simulate runs validation and execution flow of a Tx. Simulate(ctx context.Context, tx T) (server.TxResult, corestore.WriterMap, error) + // SimulateWithState runs validation and execution flow of a Tx, + // using the provided state instead of loading the latest state from the underlying database. + SimulateWithState(ctx context.Context, state corestore.ReaderMap, tx T) (server.TxResult, corestore.WriterMap, error) + // Query queries the application at the provided version. // CONTRACT: Version must always be provided, if 0, get latest Query(ctx context.Context, version uint64, request transaction.Msg) (transaction.Msg, error) @@ -193,6 +197,13 @@ func (a appManager[T]) Simulate(ctx context.Context, tx T) (server.TxResult, cor return result, cs, nil } +// SimulateWithState runs validation and execution flow of a Tx, +// using the provided state instead of loading the latest state from the underlying database. +func (a appManager[T]) SimulateWithState(ctx context.Context, state corestore.ReaderMap, tx T) (server.TxResult, corestore.WriterMap, error) { + result, cs := a.stf.Simulate(ctx, state, a.config.SimulationGasLimit, tx) // TODO: check if this is done in the antehandler + return result, cs, nil +} + // Query queries the application at the provided version. // CONTRACT: Version must always be provided, if 0, get latest func (a appManager[T]) Query(ctx context.Context, version uint64, request transaction.Msg) (transaction.Msg, error) {