Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/smartaccounts/wasm #263

Merged
merged 12 commits into from
Feb 26, 2024
36 changes: 26 additions & 10 deletions app/ante/ante.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import (
ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper"
feesharekeeper "github.com/terra-money/core/v2/x/feeshare/keeper"

smartaccountante "github.com/terra-money/core/v2/x/smartaccount/ante"
smartaccountkeeper "github.com/terra-money/core/v2/x/smartaccount/keeper"

"github.com/cosmos/cosmos-sdk/client"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
Expand All @@ -14,19 +17,22 @@ import (

wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
wasmTypes "github.com/CosmWasm/wasmd/x/wasm/types"
terrawasmkeeper "github.com/terra-money/core/v2/x/wasm/keeper"
)

// HandlerOptions extends the SDK's AnteHandler options by requiring the IBC
// channel keeper.
type HandlerOptions struct {
ante.HandlerOptions

IBCkeeper *ibckeeper.Keeper
FeeShareKeeper feesharekeeper.Keeper
BankKeeper bankKeeper.Keeper
TxCounterStoreKey storetypes.StoreKey
WasmConfig wasmTypes.WasmConfig
TxConfig client.TxConfig
IBCkeeper *ibckeeper.Keeper
FeeShareKeeper feesharekeeper.Keeper
BankKeeper bankKeeper.Keeper
SmartAccountKeeper *smartaccountkeeper.Keeper
WasmKeeper *terrawasmkeeper.Keeper
TxCounterStoreKey storetypes.StoreKey
WasmConfig wasmTypes.WasmConfig
TxConfig client.TxConfig
}

// NewAnteHandler returns an AnteHandler that checks and increments sequence
Expand All @@ -45,6 +51,14 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) {
return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "sign mode handler is required for ante builder")
}

if options.SmartAccountKeeper == nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "smart account keeper is required for ante builder")
}

if options.WasmKeeper == nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "wasm keeper is required for ante builder")
}

sigGasConsumer := options.SigGasConsumer
if sigGasConsumer == nil {
sigGasConsumer = ante.DefaultSigVerificationGasConsumer
Expand All @@ -60,11 +74,13 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) {
ante.NewValidateMemoDecorator(options.AccountKeeper),
ante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper),
ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper, options.TxFeeChecker),
// TODO: remove the following line after the migration to the new signature verification decorator is done
// SetPubKeyDecorator must be called before all signature verification decorators
ante.NewSetPubKeyDecorator(options.AccountKeeper),
ante.NewValidateSigCountDecorator(options.AccountKeeper),
ante.NewSigGasConsumeDecorator(options.AccountKeeper, sigGasConsumer),
ante.NewSigVerificationDecorator(options.AccountKeeper, options.SignModeHandler),
// ante.NewSetPubKeyDecorator(options.AccountKeeper),
// ante.NewValidateSigCountDecorator(options.AccountKeeper),
// ante.NewSigGasConsumeDecorator(options.AccountKeeper, sigGasConsumer),
// ante.NewSigVerificationDecorator(options.AccountKeeper, options.SignModeHandler),
smartaccountante.NewSmartAccountAuthDecorator(*options.SmartAccountKeeper, options.WasmKeeper, options.AccountKeeper, sigGasConsumer, options.SignModeHandler),
ante.NewIncrementSequenceDecorator(options.AccountKeeper),
ibcante.NewRedundantRelayDecorator(options.IBCkeeper),
}
Expand Down
12 changes: 7 additions & 5 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,11 +258,13 @@ func NewTerraApp(
SignModeHandler: encodingConfig.TxConfig.SignModeHandler(),
SigGasConsumer: cosmosante.DefaultSigVerificationGasConsumer,
},
BankKeeper: app.Keepers.BankKeeper,
FeeShareKeeper: app.Keepers.FeeShareKeeper,
IBCkeeper: app.Keepers.IBCKeeper,
TxCounterStoreKey: app.keys[wasmtypes.StoreKey],
WasmConfig: wasmConfig,
BankKeeper: app.Keepers.BankKeeper,
SmartAccountKeeper: &app.Keepers.SmartAccountKeeper,
WasmKeeper: &app.Keepers.WasmKeeper,
FeeShareKeeper: app.Keepers.FeeShareKeeper,
IBCkeeper: app.Keepers.IBCKeeper,
TxCounterStoreKey: app.keys[wasmtypes.StoreKey],
WasmConfig: wasmConfig,
},
)
if err != nil {
Expand Down
11 changes: 11 additions & 0 deletions app/keepers/keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ import (
feesharekeeper "github.com/terra-money/core/v2/x/feeshare/keeper"
feesharetypes "github.com/terra-money/core/v2/x/feeshare/types"

smartaccountkeeper "github.com/terra-money/core/v2/x/smartaccount/keeper"
smartaccounttypes "github.com/terra-money/core/v2/x/smartaccount/types"

terraappconfig "github.com/terra-money/core/v2/app/config"
// unnamed import of statik for swagger UI support
_ "github.com/terra-money/core/v2/client/docs/statik"
Expand All @@ -123,6 +126,7 @@ var maccPerms = map[string][]string{
tokenfactorytypes.ModuleName: {authtypes.Burner, authtypes.Minter},
alliancetypes.ModuleName: {authtypes.Burner, authtypes.Minter},
alliancetypes.RewardsPoolName: nil,
smartaccounttypes.ModuleName: nil,
}

type TerraAppKeepers struct {
Expand Down Expand Up @@ -157,6 +161,7 @@ type TerraAppKeepers struct {
AllianceKeeper alliancekeeper.Keeper
FeeShareKeeper feesharekeeper.Keeper
ICQKeeper icqkeeper.Keeper
SmartAccountKeeper smartaccountkeeper.Keeper

// IBC hooks
IBCHooksKeeper *ibchookskeeper.Keeper
Expand Down Expand Up @@ -469,6 +474,11 @@ func NewTerraAppKeepers(
wasmOpts...,
)

keepers.SmartAccountKeeper = smartaccountkeeper.NewKeeper(
appCodec,
keys[smartaccounttypes.StoreKey],
)

keepers.Ics20WasmHooks.ContractKeeper = keepers.WasmKeeper.Keeper
// Setup the contract keepers.WasmKeeper before the
// hook for the BankKeeper othrwise the WasmKeeper
Expand Down Expand Up @@ -571,6 +581,7 @@ func (app *TerraAppKeepers) initParamsKeeper(appCodec codec.BinaryCodec, legacyA
paramsKeeper.Subspace(tokenfactorytypes.ModuleName).WithKeyTable(tokenfactorytypes.ParamKeyTable())
paramsKeeper.Subspace(feesharetypes.ModuleName).WithKeyTable(feesharetypes.ParamKeyTable())
paramsKeeper.Subspace(alliancetypes.ModuleName).WithKeyTable(alliancetypes.ParamKeyTable())
paramsKeeper.Subspace(smartaccounttypes.ModuleName).WithKeyTable(smartaccounttypes.ParamKeyTable())

return paramsKeeper
}
Expand Down
3 changes: 3 additions & 0 deletions app/keepers/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ import (
alliancetypes "github.com/terra-money/alliance/x/alliance/types"
feesharetypes "github.com/terra-money/core/v2/x/feeshare/types"

smartaccounttypes "github.com/terra-money/core/v2/x/smartaccount/types"

// unnamed import of statik for swagger UI support
_ "github.com/terra-money/core/v2/client/docs/statik"
)
Expand All @@ -61,6 +63,7 @@ func (keepers *TerraAppKeepers) GenerateKeys() {
consensusparamtypes.StoreKey, tokenfactorytypes.StoreKey, wasmtypes.StoreKey,
ibcfeetypes.StoreKey, ibchookstypes.StoreKey, crisistypes.StoreKey,
alliancetypes.StoreKey, feesharetypes.StoreKey, icqtypes.StoreKey,
smartaccounttypes.StoreKey,
)

keepers.tkeys = sdk.NewTransientStoreKeys(paramstypes.TStoreKey)
Expand Down
8 changes: 8 additions & 0 deletions app/modules.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ import (
"github.com/terra-money/alliance/x/alliance"
feeshare "github.com/terra-money/core/v2/x/feeshare"

"github.com/terra-money/core/v2/x/smartaccount"
smartaccounttypes "github.com/terra-money/core/v2/x/smartaccount/types"

ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported"
terrappsparams "github.com/terra-money/core/v2/app/params"

Expand Down Expand Up @@ -117,6 +120,7 @@ var ModuleBasics = module.NewBasicManager(
alliance.AppModuleBasic{},
feeshare.AppModuleBasic{},
icq.AppModuleBasic{},
smartaccount.AppModuleBasic{},
)

// NOTE: Any module instantiated in the module manager that is later modified
Expand Down Expand Up @@ -154,6 +158,7 @@ func appModules(app *TerraApp, encodingConfig terrappsparams.EncodingConfig, ski
alliance.NewAppModule(app.appCodec, app.Keepers.AllianceKeeper, app.Keepers.StakingKeeper, app.Keepers.AccountKeeper, app.Keepers.BankKeeper, app.interfaceRegistry, app.GetSubspace(alliancetypes.ModuleName)),
feeshare.NewAppModule(app.Keepers.FeeShareKeeper, app.Keepers.AccountKeeper, app.GetSubspace(feesharetypes.ModuleName)),
icq.NewAppModule(app.Keepers.ICQKeeper),
smartaccount.NewAppModule(app.Keepers.SmartAccountKeeper, app.GetSubspace(smartaccounttypes.ModuleName)),
}
}

Expand Down Expand Up @@ -191,6 +196,7 @@ var initGenesisOrder = []string{
feesharetypes.ModuleName,
consensusparamtypes.ModuleName,
icqtypes.ModuleName,
smartaccounttypes.ModuleName,
}

var beginBlockersOrder = []string{
Expand Down Expand Up @@ -223,6 +229,7 @@ var beginBlockersOrder = []string{
feesharetypes.ModuleName,
consensusparamtypes.ModuleName,
icqtypes.ModuleName,
smartaccounttypes.ModuleName,
}

var endBlockerOrder = []string{
Expand Down Expand Up @@ -255,4 +262,5 @@ var endBlockerOrder = []string{
feesharetypes.ModuleName,
consensusparamtypes.ModuleName,
icqtypes.ModuleName,
smartaccounttypes.ModuleName,
}
12 changes: 12 additions & 0 deletions proto/terra/smartaccount/v1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package terra.smartaccount.v1;
import "gogoproto/gogo.proto";
import "google/api/annotations.proto";
import "terra/smartaccount/v1/params.proto";
import "terra/smartaccount/v1/setting.proto";

option go_package = "github.com/terra-money/core/v2/x/smartaccount/types";

Expand All @@ -12,6 +13,10 @@ service Query {
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/terra/smartaccount/v1/params";
}

rpc Setting(QuerySettingRequest) returns (QuerySettingResponse) {
option (google.api.http).get = "/terra/smartaccount/v1/params/{address}";
}
}

// QueryParamsRequest is the request type for the Query/Params RPC method.
Expand All @@ -23,3 +28,10 @@ message QueryParamsResponse {
Params params = 1 [ (gogoproto.nullable) = false ];
}

message QuerySettingRequest {
string address = 1;
}

message QuerySettingResponse {
Setting setting = 1 [ (gogoproto.nullable) = false ];
}
4 changes: 4 additions & 0 deletions x/smartaccount/ante/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@ import (
type SmartAccountKeeper interface {
GetSetting(ctx sdk.Context, ownerAddr string) (*smartaccounttypes.Setting, error)
}

type WasmKeeper interface {
Sudo(ctx sdk.Context, contractAddress sdk.AccAddress, msg []byte) ([]byte, error)
}
49 changes: 0 additions & 49 deletions x/smartaccount/ante/smartaccount.go

This file was deleted.

98 changes: 98 additions & 0 deletions x/smartaccount/ante/smartaccount_auth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package ante

import (
"encoding/json"

sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
authante "github.com/cosmos/cosmos-sdk/x/auth/ante"
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/terra-money/core/v2/x/smartaccount/types"
)

// SmartAccountAuthDecorator does authentication for smart accounts
type SmartAccountAuthDecorator struct {
sak SmartAccountKeeper
wk WasmKeeper
ak authante.AccountKeeper
defaultVerifySigDecorator sdk.AnteHandler
}

func NewSmartAccountAuthDecorator(
sak SmartAccountKeeper,
wk WasmKeeper,
ak authante.AccountKeeper,
sigGasConsumer func(meter sdk.GasMeter, sig signing.SignatureV2, params authtypes.Params) error,
signModeHandler authsigning.SignModeHandler,
) SmartAccountAuthDecorator {
if sigGasConsumer == nil {
sigGasConsumer = authante.DefaultSigVerificationGasConsumer
}
defaultVerifySigDecorator := sdk.ChainAnteDecorators(
authante.NewSetPubKeyDecorator(ak),
authante.NewValidateSigCountDecorator(ak),
authante.NewSigGasConsumeDecorator(ak, sigGasConsumer),
authante.NewSigVerificationDecorator(ak, signModeHandler),
)
return SmartAccountAuthDecorator{
sak: sak,
wk: wk,
defaultVerifySigDecorator: defaultVerifySigDecorator,
}
}

// AnteHandle checks if the tx provides sufficient fee to cover the required fee from the fee market.
func (sad SmartAccountAuthDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) {
// check if the tx is from a smart account
setting, err := sad.sak.GetSetting(ctx, tx.GetMsgs()[0].GetSigners()[0].String())
if sdkerrors.ErrKeyNotFound.Is(err) {
// run through the default handlers for signature verification
newCtx, err := sad.defaultVerifySigDecorator(ctx, tx, simulate)
if err != nil {
return newCtx, err
}
// continue to the next handler after default signature verification
return next(newCtx, tx, simulate)
} else if err != nil {
return ctx, err
}

if setting.Authorization != nil && len(setting.Authorization) > 0 {
freeelancer marked this conversation as resolved.
Show resolved Hide resolved
for _, auth := range setting.Authorization {
// TODO: add code that calls authorization on contracts
authMsg := types.Authorization{
// TODO: check these fields
Sender: sad.ak.GetModuleAddress(types.ModuleName).String(),
Account: tx.GetMsgs()[0].GetSigners()[0].String(),
Data: []byte(auth.InitMsg),
// TODO: fill the below fields
Signatures: [][]byte{},
SignedBytes: []byte{},
}
authMsgBz, err := json.Marshal(authMsg)
if err != nil {
return ctx, err
}
if _, err = sad.wk.Sudo(ctx, sdk.AccAddress(auth.ContractAddress), authMsgBz); err != nil {
return ctx, err
}
if err != nil && setting.Fallback {
return next(ctx, tx, simulate)
} else if err != nil {
return ctx, err
}
}
} else if setting.Fallback {
// run through the default handlers for signature verification
newCtx, err := sad.defaultVerifySigDecorator(ctx, tx, simulate)
if err != nil {
return newCtx, err
}
// continue to the next handler after default signature verification
return next(newCtx, tx, simulate)
}

return next(ctx, tx, simulate)
}
Loading
Loading