feat(accounts): re-introduce bundler (#21562)
This commit is contained in:
@@ -1,103 +0,0 @@
|
||||
//go:build app_v1
|
||||
|
||||
package accounts
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"cosmossdk.io/simapp"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
gogoproto "github.com/cosmos/gogoproto/proto"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var (
|
||||
privKey = secp256k1.GenPrivKey()
|
||||
accCreator = []byte("creator")
|
||||
bundlerAddr = secp256k1.GenPrivKey().PubKey().Address()
|
||||
aliceAddr = secp256k1.GenPrivKey().PubKey().Address()
|
||||
)
|
||||
|
||||
/*
|
||||
func TestAccountAbstraction(t *testing.T) {
|
||||
app := setupApp(t)
|
||||
ak := app.AccountsKeeper
|
||||
ctx := sdk.NewContext(app.CommitMultiStore(), false, app.Logger())
|
||||
|
||||
_, aaAddr, err := ak.Init(ctx, "aa_minimal", accCreator, &rotationv1.MsgInit{
|
||||
PubKeyBytes: privKey.PubKey().Bytes(),
|
||||
}, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, aaFullAddr, err := ak.Init(ctx, "aa_full", accCreator, &rotationv1.MsgInit{
|
||||
PubKeyBytes: privKey.PubKey().Bytes(),
|
||||
}, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
aaAddrStr, err := app.AuthKeeper.AddressCodec().BytesToString(aaAddr)
|
||||
require.NoError(t, err)
|
||||
|
||||
aaFullAddrStr, err := app.AuthKeeper.AddressCodec().BytesToString(aaFullAddr)
|
||||
require.NoError(t, err)
|
||||
|
||||
// let's give aa some coins.
|
||||
require.NoError(t, testutil.FundAccount(ctx, app.BankKeeper, aaAddr, sdk.NewCoins(sdk.NewInt64Coin("stake", 100000000000))))
|
||||
require.NoError(t, testutil.FundAccount(ctx, app.BankKeeper, aaFullAddr, sdk.NewCoins(sdk.NewInt64Coin("stake", 100000000000))))
|
||||
|
||||
bundlerAddrStr, err := app.AuthKeeper.AddressCodec().BytesToString(bundlerAddr)
|
||||
require.NoError(t, err)
|
||||
|
||||
aliceAddrStr, err := app.AuthKeeper.AddressCodec().BytesToString(aliceAddr)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run("ok - pay bundler not implemented", func(t *testing.T) {})
|
||||
t.Run("pay bundle impersonation", func(t *testing.T) {})
|
||||
t.Run("auth failure", func(t *testing.T) {})
|
||||
t.Run("pay bundle failure", func(t *testing.T) {})
|
||||
t.Run("exec message failure", func(t *testing.T) {})
|
||||
|
||||
t.Run("implements bundler payment - fail ", func(t *testing.T) {})
|
||||
|
||||
t.Run("implements execution - fail", func(t *testing.T) {})
|
||||
|
||||
t.Run("implements bundler payment and execution - success", func(t *testing.T) {})
|
||||
|
||||
t.Run("Simulate - OK", func(t *testing.T) {})
|
||||
|
||||
t.Run("Simulate - Fail empty user operation", func(t *testing.T) {})
|
||||
}
|
||||
*/
|
||||
|
||||
func intoAny(t *testing.T, msgs ...gogoproto.Message) (anys []*codectypes.Any) {
|
||||
t.Helper()
|
||||
for _, msg := range msgs {
|
||||
any, err := codectypes.NewAnyWithValue(msg)
|
||||
require.NoError(t, err)
|
||||
anys = append(anys, any)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func coins(t *testing.T, s string) sdk.Coins {
|
||||
t.Helper()
|
||||
coins, err := sdk.ParseCoinsNormalized(s)
|
||||
require.NoError(t, err)
|
||||
return coins
|
||||
}
|
||||
|
||||
func balanceIs(t *testing.T, ctx context.Context, app *simapp.SimApp, addr sdk.AccAddress, s string) {
|
||||
t.Helper()
|
||||
balance := app.BankKeeper.GetAllBalances(ctx, addr)
|
||||
require.Equal(t, s, balance.String())
|
||||
}
|
||||
|
||||
var mockSignature = &codectypes.Any{TypeUrl: "signature", Value: []byte("signature")}
|
||||
|
||||
func setupApp(t *testing.T) *simapp.SimApp {
|
||||
t.Helper()
|
||||
app := simapp.Setup(t, false)
|
||||
return app
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
package accounts
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
gogoproto "github.com/cosmos/gogoproto/proto"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
account_abstractionv1 "cosmossdk.io/x/accounts/interfaces/account_abstraction/v1"
|
||||
banktypes "cosmossdk.io/x/bank/types"
|
||||
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
txtypes "github.com/cosmos/cosmos-sdk/types/tx"
|
||||
signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
)
|
||||
|
||||
func TestMsgServer_ExecuteBundle(t *testing.T) {
|
||||
t.Run("bundle success", func(t *testing.T) {
|
||||
f := initFixture(t, func(ctx context.Context, msg *account_abstractionv1.MsgAuthenticate) (*account_abstractionv1.MsgAuthenticateResponse, error) {
|
||||
return &account_abstractionv1.MsgAuthenticateResponse{}, nil
|
||||
})
|
||||
|
||||
recipient := f.mustAddr([]byte("recipient"))
|
||||
feeAmt := sdk.NewInt64Coin("atom", 100)
|
||||
sendAmt := sdk.NewInt64Coin("atom", 200)
|
||||
|
||||
f.mint(f.mockAccountAddress, feeAmt, sendAmt)
|
||||
|
||||
tx := makeTx(t, &banktypes.MsgSend{
|
||||
FromAddress: f.mustAddr(f.mockAccountAddress),
|
||||
ToAddress: recipient,
|
||||
Amount: sdk.NewCoins(sendAmt),
|
||||
}, []byte("pass"), &account_abstractionv1.TxExtension{
|
||||
AuthenticationGasLimit: 2400,
|
||||
BundlerPaymentMessages: []*codectypes.Any{wrapAny(t, &banktypes.MsgSend{
|
||||
FromAddress: f.mustAddr(f.mockAccountAddress),
|
||||
ToAddress: f.bundler,
|
||||
Amount: sdk.NewCoins(feeAmt),
|
||||
})},
|
||||
BundlerPaymentGasLimit: 30000,
|
||||
ExecutionGasLimit: 30000,
|
||||
})
|
||||
|
||||
bundleResp := f.runBundle(tx)
|
||||
require.Len(t, bundleResp.Responses, 1)
|
||||
|
||||
txResp := bundleResp.Responses[0]
|
||||
|
||||
require.Empty(t, txResp.Error)
|
||||
require.NotZero(t, txResp.AuthenticationGasUsed)
|
||||
require.NotZero(t, txResp.BundlerPaymentGasUsed)
|
||||
require.NotZero(t, txResp.ExecutionGasUsed)
|
||||
|
||||
// asses responses
|
||||
require.Len(t, txResp.BundlerPaymentResponses, 1)
|
||||
require.Equal(t, txResp.BundlerPaymentResponses[0].TypeUrl, "/cosmos.bank.v1beta1.MsgSendResponse")
|
||||
|
||||
require.Len(t, txResp.ExecutionResponses, 1)
|
||||
require.Equal(t, txResp.ExecutionResponses[0].TypeUrl, "/cosmos.bank.v1beta1.MsgSendResponse")
|
||||
|
||||
// ensure sends have happened
|
||||
require.Equal(t, f.balance(f.bundler, feeAmt.Denom), feeAmt)
|
||||
require.Equal(t, f.balance(recipient, sendAmt.Denom), sendAmt)
|
||||
})
|
||||
|
||||
t.Run("tx fails at auth step", func(t *testing.T) {
|
||||
f := initFixture(t, func(ctx context.Context, msg *account_abstractionv1.MsgAuthenticate) (*account_abstractionv1.MsgAuthenticateResponse, error) {
|
||||
return &account_abstractionv1.MsgAuthenticateResponse{}, fmt.Errorf("sentinel")
|
||||
})
|
||||
recipient := f.mustAddr([]byte("recipient"))
|
||||
feeAmt := sdk.NewInt64Coin("atom", 100)
|
||||
sendAmt := sdk.NewInt64Coin("atom", 200)
|
||||
f.mint(f.mockAccountAddress, feeAmt, sendAmt)
|
||||
|
||||
tx := makeTx(t, &banktypes.MsgSend{
|
||||
FromAddress: f.mustAddr(f.mockAccountAddress),
|
||||
ToAddress: recipient,
|
||||
Amount: sdk.NewCoins(sendAmt),
|
||||
}, []byte("pass"), &account_abstractionv1.TxExtension{
|
||||
AuthenticationGasLimit: 2400,
|
||||
BundlerPaymentMessages: []*codectypes.Any{wrapAny(t, &banktypes.MsgSend{
|
||||
FromAddress: f.mustAddr(f.mockAccountAddress),
|
||||
ToAddress: f.bundler,
|
||||
Amount: sdk.NewCoins(feeAmt),
|
||||
})},
|
||||
BundlerPaymentGasLimit: 30000,
|
||||
ExecutionGasLimit: 30000,
|
||||
})
|
||||
|
||||
bundleResp := f.runBundle(tx)
|
||||
|
||||
require.Len(t, bundleResp.Responses, 1)
|
||||
|
||||
txResp := bundleResp.Responses[0]
|
||||
require.NotEmpty(t, txResp.Error)
|
||||
require.Contains(t, txResp.Error, "sentinel")
|
||||
require.NotZero(t, txResp.AuthenticationGasUsed)
|
||||
require.Zero(t, txResp.BundlerPaymentGasUsed)
|
||||
require.Zero(t, txResp.ExecutionGasUsed)
|
||||
require.Empty(t, txResp.BundlerPaymentResponses)
|
||||
require.Empty(t, txResp.ExecutionResponses)
|
||||
|
||||
// ensure auth side effects are not persisted in case of failures
|
||||
})
|
||||
|
||||
t.Run("tx fails at pay bundler step", func(t *testing.T) {
|
||||
f := initFixture(t, func(ctx context.Context, msg *account_abstractionv1.MsgAuthenticate) (*account_abstractionv1.MsgAuthenticateResponse, error) {
|
||||
return &account_abstractionv1.MsgAuthenticateResponse{}, nil
|
||||
})
|
||||
|
||||
recipient := f.mustAddr([]byte("recipient"))
|
||||
feeAmt := sdk.NewInt64Coin("atom", 100)
|
||||
sendAmt := sdk.NewInt64Coin("atom", 200)
|
||||
|
||||
f.mint(f.mockAccountAddress, feeAmt, sendAmt)
|
||||
|
||||
tx := makeTx(t, &banktypes.MsgSend{
|
||||
FromAddress: f.mustAddr(f.mockAccountAddress),
|
||||
ToAddress: recipient,
|
||||
Amount: sdk.NewCoins(sendAmt),
|
||||
}, []byte("pass"), &account_abstractionv1.TxExtension{
|
||||
AuthenticationGasLimit: 2400,
|
||||
BundlerPaymentMessages: []*codectypes.Any{
|
||||
wrapAny(t, &banktypes.MsgSend{
|
||||
FromAddress: f.mustAddr(f.mockAccountAddress),
|
||||
ToAddress: f.bundler,
|
||||
Amount: sdk.NewCoins(feeAmt.AddAmount(feeAmt.Amount.AddRaw(100))),
|
||||
}),
|
||||
wrapAny(t, &banktypes.MsgSend{
|
||||
FromAddress: f.mustAddr(f.mockAccountAddress),
|
||||
ToAddress: f.bundler,
|
||||
Amount: sdk.NewCoins(feeAmt.AddAmount(feeAmt.Amount.AddRaw(30000))),
|
||||
}),
|
||||
},
|
||||
BundlerPaymentGasLimit: 30000,
|
||||
ExecutionGasLimit: 30000,
|
||||
})
|
||||
|
||||
bundleResp := f.runBundle(tx)
|
||||
require.Len(t, bundleResp.Responses, 1)
|
||||
|
||||
txResp := bundleResp.Responses[0]
|
||||
|
||||
require.NotEmpty(t, txResp.Error)
|
||||
require.Contains(t, txResp.Error, "bundler payment failed")
|
||||
require.NotZero(t, txResp.AuthenticationGasUsed)
|
||||
require.NotZero(t, txResp.BundlerPaymentGasUsed)
|
||||
|
||||
require.Empty(t, txResp.BundlerPaymentResponses)
|
||||
require.Zero(t, txResp.ExecutionGasUsed)
|
||||
require.Empty(t, txResp.ExecutionResponses)
|
||||
|
||||
// ensure bundler payment side effects are not persisted
|
||||
require.True(t, f.balance(f.bundler, feeAmt.Denom).IsZero())
|
||||
})
|
||||
|
||||
t.Run("tx fails at execution step", func(t *testing.T) {
|
||||
f := initFixture(t, func(ctx context.Context, msg *account_abstractionv1.MsgAuthenticate) (*account_abstractionv1.MsgAuthenticateResponse, error) {
|
||||
return &account_abstractionv1.MsgAuthenticateResponse{}, nil
|
||||
})
|
||||
|
||||
recipient := f.mustAddr([]byte("recipient"))
|
||||
feeAmt := sdk.NewInt64Coin("atom", 100)
|
||||
sendAmt := sdk.NewInt64Coin("atom", 40000) // this fails
|
||||
|
||||
f.mint(f.mockAccountAddress, feeAmt)
|
||||
|
||||
tx := makeTx(t, &banktypes.MsgSend{
|
||||
FromAddress: f.mustAddr(f.mockAccountAddress),
|
||||
ToAddress: recipient,
|
||||
Amount: sdk.NewCoins(sendAmt),
|
||||
}, []byte("pass"), &account_abstractionv1.TxExtension{
|
||||
AuthenticationGasLimit: 2400,
|
||||
BundlerPaymentMessages: []*codectypes.Any{
|
||||
wrapAny(t, &banktypes.MsgSend{
|
||||
FromAddress: f.mustAddr(f.mockAccountAddress),
|
||||
ToAddress: f.bundler,
|
||||
Amount: sdk.NewCoins(feeAmt),
|
||||
}),
|
||||
},
|
||||
BundlerPaymentGasLimit: 30000,
|
||||
ExecutionGasLimit: 30000,
|
||||
})
|
||||
|
||||
bundleResp := f.runBundle(tx)
|
||||
require.Len(t, bundleResp.Responses, 1)
|
||||
|
||||
txResp := bundleResp.Responses[0]
|
||||
|
||||
require.NotEmpty(t, txResp.Error)
|
||||
require.Contains(t, txResp.Error, "execution failed")
|
||||
|
||||
require.NotZero(t, txResp.AuthenticationGasUsed)
|
||||
|
||||
require.NotZero(t, txResp.BundlerPaymentGasUsed)
|
||||
require.NotEmpty(t, txResp.BundlerPaymentResponses)
|
||||
require.Equal(t, f.balance(f.bundler, feeAmt.Denom), feeAmt) // ensure bundler payment side effects are persisted
|
||||
|
||||
require.NotZero(t, txResp.ExecutionGasUsed)
|
||||
require.Empty(t, txResp.ExecutionResponses)
|
||||
|
||||
// ensure execution side effects are not persisted
|
||||
// aka recipient must not have money
|
||||
require.True(t, f.balance(recipient, feeAmt.Denom).IsZero())
|
||||
})
|
||||
}
|
||||
|
||||
func makeTx(t *testing.T, msg gogoproto.Message, sig []byte, xt *account_abstractionv1.TxExtension) []byte {
|
||||
anyMsg, err := codectypes.NewAnyWithValue(msg)
|
||||
require.NoError(t, err)
|
||||
|
||||
anyXt, err := codectypes.NewAnyWithValue(xt)
|
||||
require.NoError(t, err)
|
||||
|
||||
tx := &txtypes.Tx{
|
||||
Body: &txtypes.TxBody{
|
||||
Messages: []*codectypes.Any{anyMsg},
|
||||
Memo: "",
|
||||
TimeoutHeight: 0,
|
||||
Unordered: false,
|
||||
TimeoutTimestamp: nil,
|
||||
ExtensionOptions: []*codectypes.Any{anyXt},
|
||||
NonCriticalExtensionOptions: nil,
|
||||
},
|
||||
AuthInfo: &txtypes.AuthInfo{
|
||||
SignerInfos: []*txtypes.SignerInfo{
|
||||
{
|
||||
PublicKey: nil,
|
||||
ModeInfo: &txtypes.ModeInfo{Sum: &txtypes.ModeInfo_Single_{Single: &txtypes.ModeInfo_Single{Mode: signingtypes.SignMode_SIGN_MODE_UNSPECIFIED}}},
|
||||
Sequence: 0,
|
||||
},
|
||||
},
|
||||
Fee: nil,
|
||||
},
|
||||
Signatures: [][]byte{sig},
|
||||
}
|
||||
|
||||
bodyBytes, err := tx.Body.Marshal()
|
||||
require.NoError(t, err)
|
||||
|
||||
authInfoBytes, err := tx.AuthInfo.Marshal()
|
||||
require.NoError(t, err)
|
||||
|
||||
txRaw, err := (&txtypes.TxRaw{
|
||||
BodyBytes: bodyBytes,
|
||||
AuthInfoBytes: authInfoBytes,
|
||||
Signatures: tx.Signatures,
|
||||
}).Marshal()
|
||||
require.NoError(t, err)
|
||||
return txRaw
|
||||
}
|
||||
|
||||
func wrapAny(t *testing.T, msg gogoproto.Message) *codectypes.Any {
|
||||
t.Helper()
|
||||
any, err := codectypes.NewAnyWithValue(msg)
|
||||
require.NoError(t, err)
|
||||
return any
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
package accounts
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
gogotypes "github.com/cosmos/gogoproto/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"cosmossdk.io/core/appmodule"
|
||||
"cosmossdk.io/log"
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
"cosmossdk.io/x/accounts"
|
||||
"cosmossdk.io/x/accounts/accountstd"
|
||||
account_abstractionv1 "cosmossdk.io/x/accounts/interfaces/account_abstraction/v1"
|
||||
accountsv1 "cosmossdk.io/x/accounts/v1"
|
||||
"cosmossdk.io/x/bank"
|
||||
bankkeeper "cosmossdk.io/x/bank/keeper"
|
||||
banktypes "cosmossdk.io/x/bank/types"
|
||||
minttypes "cosmossdk.io/x/mint/types"
|
||||
txdecode "cosmossdk.io/x/tx/decode"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
addresscodec "github.com/cosmos/cosmos-sdk/codec/address"
|
||||
codectestutil "github.com/cosmos/cosmos-sdk/codec/testutil"
|
||||
"github.com/cosmos/cosmos-sdk/runtime"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/integration"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
|
||||
authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
)
|
||||
|
||||
var _ accountstd.Interface = (*mockAccount)(nil)
|
||||
|
||||
type mockAccount struct {
|
||||
authenticate func(ctx context.Context, msg *account_abstractionv1.MsgAuthenticate) (*account_abstractionv1.MsgAuthenticateResponse, error)
|
||||
}
|
||||
|
||||
func (m mockAccount) RegisterInitHandler(builder *accountstd.InitBuilder) {
|
||||
accountstd.RegisterInitHandler(builder, func(ctx context.Context, req *gogotypes.Empty) (*gogotypes.Empty, error) {
|
||||
return &gogotypes.Empty{}, nil
|
||||
})
|
||||
}
|
||||
|
||||
func (m mockAccount) RegisterExecuteHandlers(builder *accountstd.ExecuteBuilder) {
|
||||
if m.authenticate == nil {
|
||||
return
|
||||
}
|
||||
|
||||
accountstd.RegisterExecuteHandler(builder, m.authenticate)
|
||||
}
|
||||
|
||||
func (m mockAccount) RegisterQueryHandlers(_ *accountstd.QueryBuilder) {}
|
||||
|
||||
type fixture struct {
|
||||
t *testing.T
|
||||
|
||||
app *integration.App
|
||||
|
||||
cdc codec.Codec
|
||||
ctx sdk.Context
|
||||
|
||||
authKeeper authkeeper.AccountKeeper
|
||||
accountsKeeper accounts.Keeper
|
||||
bankKeeper bankkeeper.Keeper
|
||||
|
||||
mockAccountAddress []byte
|
||||
bundler string
|
||||
}
|
||||
|
||||
func (f fixture) mustAddr(address []byte) string {
|
||||
s, _ := f.authKeeper.AddressCodec().BytesToString(address)
|
||||
return s
|
||||
}
|
||||
|
||||
func (f fixture) runBundle(txBytes ...[]byte) *accountsv1.MsgExecuteBundleResponse {
|
||||
f.t.Helper()
|
||||
|
||||
msgSrv := accounts.NewMsgServer(f.accountsKeeper)
|
||||
|
||||
resp, err := msgSrv.ExecuteBundle(f.ctx, &accountsv1.MsgExecuteBundle{
|
||||
Bundler: f.bundler,
|
||||
Txs: txBytes,
|
||||
})
|
||||
require.NoError(f.t, err)
|
||||
return resp
|
||||
}
|
||||
|
||||
func (f fixture) mint(address []byte, coins ...sdk.Coin) {
|
||||
f.t.Helper()
|
||||
for _, coin := range coins {
|
||||
err := f.bankKeeper.MintCoins(f.ctx, minttypes.ModuleName, sdk.NewCoins(coin))
|
||||
require.NoError(f.t, err)
|
||||
err = f.bankKeeper.SendCoinsFromModuleToAccount(f.ctx, minttypes.ModuleName, address, sdk.NewCoins(coin))
|
||||
require.NoError(f.t, err)
|
||||
}
|
||||
}
|
||||
|
||||
func (f fixture) balance(recipient, denom string) sdk.Coin {
|
||||
f.t.Helper()
|
||||
balances, err := f.bankKeeper.Balance(f.ctx, &banktypes.QueryBalanceRequest{
|
||||
Address: recipient,
|
||||
Denom: denom,
|
||||
})
|
||||
require.NoError(f.t, err)
|
||||
return *balances.Balance
|
||||
}
|
||||
|
||||
func initFixture(t *testing.T, f func(ctx context.Context, msg *account_abstractionv1.MsgAuthenticate) (*account_abstractionv1.MsgAuthenticateResponse, error)) *fixture {
|
||||
t.Helper()
|
||||
keys := storetypes.NewKVStoreKeys(
|
||||
authtypes.StoreKey, banktypes.StoreKey, accounts.StoreKey,
|
||||
)
|
||||
encodingCfg := moduletestutil.MakeTestEncodingConfig(codectestutil.CodecOptions{}, auth.AppModule{}, bank.AppModule{}, accounts.AppModule{})
|
||||
cdc := encodingCfg.Codec
|
||||
|
||||
logger := log.NewTestLogger(t)
|
||||
cms := integration.CreateMultiStore(keys, logger)
|
||||
|
||||
newCtx := sdk.NewContext(cms, true, logger)
|
||||
|
||||
router := baseapp.NewMsgServiceRouter()
|
||||
queryRouter := baseapp.NewGRPCQueryRouter()
|
||||
|
||||
txDecoder, err := txdecode.NewDecoder(txdecode.Options{
|
||||
SigningContext: encodingCfg.TxConfig.SigningContext(),
|
||||
ProtoCodec: encodingCfg.Codec,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
accountsKeeper, err := accounts.NewKeeper(
|
||||
cdc,
|
||||
runtime.NewEnvironment(runtime.NewKVStoreService(keys[accounts.StoreKey]), log.NewNopLogger(), runtime.EnvWithQueryRouterService(queryRouter), runtime.EnvWithMsgRouterService(router)),
|
||||
addresscodec.NewBech32Codec("cosmos"),
|
||||
cdc.InterfaceRegistry(),
|
||||
txDecoder,
|
||||
accountstd.AddAccount("mock", func(deps accountstd.Dependencies) (accountstd.Interface, error) {
|
||||
return mockAccount{f}, nil
|
||||
}),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
accountsv1.RegisterQueryServer(queryRouter, accounts.NewQueryServer(accountsKeeper))
|
||||
|
||||
authority := authtypes.NewModuleAddress("gov")
|
||||
|
||||
authKeeper := authkeeper.NewAccountKeeper(
|
||||
runtime.NewEnvironment(runtime.NewKVStoreService(keys[authtypes.StoreKey]), log.NewNopLogger()),
|
||||
cdc,
|
||||
authtypes.ProtoBaseAccount,
|
||||
accountsKeeper,
|
||||
map[string][]string{minttypes.ModuleName: {authtypes.Minter}},
|
||||
addresscodec.NewBech32Codec(sdk.Bech32MainPrefix),
|
||||
sdk.Bech32MainPrefix,
|
||||
authority.String(),
|
||||
)
|
||||
|
||||
blockedAddresses := map[string]bool{
|
||||
authKeeper.GetAuthority(): false,
|
||||
}
|
||||
bankKeeper := bankkeeper.NewBaseKeeper(
|
||||
runtime.NewEnvironment(runtime.NewKVStoreService(keys[banktypes.StoreKey]), log.NewNopLogger()),
|
||||
cdc,
|
||||
authKeeper,
|
||||
blockedAddresses,
|
||||
authority.String(),
|
||||
)
|
||||
|
||||
params := banktypes.DefaultParams()
|
||||
require.NoError(t, bankKeeper.SetParams(newCtx, params))
|
||||
|
||||
accountsModule := accounts.NewAppModule(cdc, accountsKeeper)
|
||||
authModule := auth.NewAppModule(cdc, authKeeper, accountsKeeper, authsims.RandomGenesisAccounts, nil)
|
||||
bankModule := bank.NewAppModule(cdc, bankKeeper, authKeeper)
|
||||
|
||||
integrationApp := integration.NewIntegrationApp(newCtx, logger, keys, cdc,
|
||||
encodingCfg.InterfaceRegistry.SigningContext().AddressCodec(),
|
||||
encodingCfg.InterfaceRegistry.SigningContext().ValidatorAddressCodec(),
|
||||
map[string]appmodule.AppModule{
|
||||
accounts.ModuleName: accountsModule,
|
||||
authtypes.ModuleName: authModule,
|
||||
banktypes.ModuleName: bankModule,
|
||||
}, router, queryRouter)
|
||||
|
||||
authtypes.RegisterInterfaces(cdc.InterfaceRegistry())
|
||||
banktypes.RegisterInterfaces(cdc.InterfaceRegistry())
|
||||
|
||||
authtypes.RegisterMsgServer(integrationApp.MsgServiceRouter(), authkeeper.NewMsgServerImpl(authKeeper))
|
||||
authtypes.RegisterQueryServer(integrationApp.QueryHelper(), authkeeper.NewQueryServer(authKeeper))
|
||||
|
||||
banktypes.RegisterMsgServer(router, bankkeeper.NewMsgServerImpl(bankKeeper))
|
||||
|
||||
// init account
|
||||
_, addr, err := accountsKeeper.Init(newCtx, "mock", []byte("system"), &gogotypes.Empty{}, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
fixture := &fixture{
|
||||
t: t,
|
||||
app: integrationApp,
|
||||
cdc: cdc,
|
||||
ctx: newCtx,
|
||||
authKeeper: authKeeper,
|
||||
accountsKeeper: accountsKeeper,
|
||||
bankKeeper: bankKeeper,
|
||||
mockAccountAddress: addr,
|
||||
bundler: "",
|
||||
}
|
||||
fixture.bundler = fixture.mustAddr([]byte("bundler"))
|
||||
return fixture
|
||||
}
|
||||
@@ -79,6 +79,7 @@ func initFixture(t *testing.T, extraAccs map[string]accountstd.Interface) *fixtu
|
||||
runtime.NewEnvironment(runtime.NewKVStoreService(keys[accounts.StoreKey]), log.NewNopLogger(), runtime.EnvWithQueryRouterService(queryRouter), runtime.EnvWithMsgRouterService(router)),
|
||||
addresscodec.NewBech32Codec("cosmos"),
|
||||
cdc.InterfaceRegistry(),
|
||||
nil,
|
||||
append(accs, account)...,
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
||||
Reference in New Issue
Block a user