forked from palomachain/paloma
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: experimental wasm bindings for token factory & scheduler (#1321)
# Related Github tickets - #2459 # Background This change adds experimental bindings for the token factory, as well as a limited scope of the scheduler module, allowing jobs to be queried and created from smart contracts. Bindings are untested and should be treated as experimental. # Testing completed - [ ] test coverage exists or has been added/updated - [x] tested in a private testnet # Breaking changes - [x] I have checked my code for breaking changes - [x] If there are breaking changes, there is a supporting migration.
- Loading branch information
1 parent
288cbcc
commit ec53cca
Showing
16 changed files
with
910 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
package bindings | ||
|
||
import ( | ||
"encoding/json" | ||
|
||
sdkerrors "cosmossdk.io/errors" | ||
wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" | ||
wasmvmtypes "github.com/CosmWasm/wasmvm/v2/types" | ||
codectypes "github.com/cosmos/cosmos-sdk/codec/types" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
errtypes "github.com/cosmos/cosmos-sdk/types/errors" | ||
bindingstypes "github.com/palomachain/paloma/v2/x/scheduler/bindings/types" | ||
schedulerkeeper "github.com/palomachain/paloma/v2/x/scheduler/keeper" | ||
schedulertypes "github.com/palomachain/paloma/v2/x/scheduler/types" | ||
) | ||
|
||
func CustomMessageDecorator(scheduler *schedulerkeeper.Keeper) func(wasmkeeper.Messenger) wasmkeeper.Messenger { | ||
return func(old wasmkeeper.Messenger) wasmkeeper.Messenger { | ||
return &CustomMessenger{ | ||
wrapped: old, | ||
scheduler: scheduler, | ||
} | ||
} | ||
} | ||
|
||
type CustomMessenger struct { | ||
wrapped wasmkeeper.Messenger | ||
scheduler *schedulerkeeper.Keeper | ||
} | ||
|
||
var _ wasmkeeper.Messenger = (*CustomMessenger)(nil) | ||
|
||
func (m *CustomMessenger) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) ([]sdk.Event, [][]byte, [][]*codectypes.Any, error) { | ||
if msg.Custom != nil { | ||
var contractMsg bindingstypes.SchedulerMsg | ||
if err := json.Unmarshal(msg.Custom, &contractMsg); err != nil { | ||
return nil, nil, nil, sdkerrors.Wrap(err, "scheduler msg") | ||
} | ||
if contractMsg.Message == nil { | ||
return nil, nil, nil, sdkerrors.Wrap(errtypes.ErrUnknownRequest, "nil message field") | ||
} | ||
msgType := contractMsg.Message | ||
if msgType.CreateJob != nil { | ||
return m.createJob(ctx, contractAddr, msgType.CreateJob) | ||
} | ||
} | ||
return m.wrapped.DispatchMsg(ctx, contractAddr, contractIBCPortID, msg) | ||
} | ||
|
||
func (m *CustomMessenger) createJob(ctx sdk.Context, contractAddr sdk.AccAddress, createJob *bindingstypes.CreateJob) ([]sdk.Event, [][]byte, [][]*codectypes.Any, error) { | ||
if createJob == nil { | ||
return nil, nil, nil, wasmvmtypes.InvalidRequest{Err: "null create job"} | ||
} | ||
if createJob.Job == nil { | ||
return nil, nil, nil, wasmvmtypes.InvalidRequest{Err: "null job"} | ||
} | ||
|
||
j := &schedulertypes.Job{ | ||
ID: createJob.Job.JobId, | ||
Routing: schedulertypes.Routing{ | ||
ChainType: createJob.Job.ChainType, | ||
ChainReferenceID: createJob.Job.ChainReferenceId, | ||
}, | ||
Definition: []byte(createJob.Job.Definition), | ||
Payload: []byte(createJob.Job.Payload), | ||
IsPayloadModifiable: createJob.Job.PayloadModifiable, | ||
EnforceMEVRelay: createJob.Job.IsMEV, | ||
} | ||
|
||
if err := j.ValidateBasic(); err != nil { | ||
return nil, nil, nil, sdkerrors.Wrap(err, "failed to validate job") | ||
} | ||
|
||
msgServer := schedulerkeeper.NewMsgServerImpl(m.scheduler) | ||
msgCreateJob := schedulertypes.NewMsgCreateJob(contractAddr.String(), j) | ||
if err := msgCreateJob.ValidateBasic(); err != nil { | ||
return nil, nil, nil, sdkerrors.Wrap(err, "failed validating MsgCreateJob") | ||
} | ||
|
||
resp, err := msgServer.CreateJob(ctx, msgCreateJob) | ||
if err != nil { | ||
return nil, nil, nil, sdkerrors.Wrap(err, "failed to create job") | ||
} | ||
|
||
bz, err := resp.Marshal() | ||
if err != nil { | ||
return nil, nil, nil, sdkerrors.Wrap(err, "failed to marshal response") | ||
} | ||
return nil, [][]byte{bz}, nil, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package bindings | ||
|
||
import ( | ||
"encoding/json" | ||
|
||
sdkerrors "cosmossdk.io/errors" | ||
wasmvmtypes "github.com/CosmWasm/wasmvm/v2/types" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
errtypes "github.com/cosmos/cosmos-sdk/types/errors" | ||
bindingstypes "github.com/palomachain/paloma/v2/x/scheduler/bindings/types" | ||
schedulerkeeper "github.com/palomachain/paloma/v2/x/scheduler/keeper" | ||
) | ||
|
||
type QueryPlugin struct { | ||
scheduler *schedulerkeeper.Keeper | ||
} | ||
|
||
func NewQueryPlugin(s *schedulerkeeper.Keeper) *QueryPlugin { | ||
return &QueryPlugin{ | ||
scheduler: s, | ||
} | ||
} | ||
|
||
func CustomQuerier(qp *QueryPlugin) func(ctx sdk.Context, request json.RawMessage) ([]byte, error) { | ||
return func(ctx sdk.Context, request json.RawMessage) ([]byte, error) { | ||
var contractQuery bindingstypes.SchedulerQuery | ||
if err := json.Unmarshal(request, &contractQuery); err != nil { | ||
return nil, sdkerrors.Wrap(err, "query") | ||
} | ||
if contractQuery.Query == nil { | ||
return nil, sdkerrors.Wrap(errtypes.ErrUnknownRequest, "nil query field") | ||
} | ||
queryType := contractQuery.Query | ||
|
||
switch { | ||
case queryType.JobById != nil: | ||
j, err := qp.scheduler.GetJob(ctx, queryType.JobById.JobId) | ||
if err != nil { | ||
return nil, sdkerrors.Wrap(err, "failed to query for job") | ||
} | ||
if j == nil { | ||
return nil, sdkerrors.Wrap(errtypes.ErrNotFound, "job id") | ||
} | ||
|
||
res := bindingstypes.JobByIdResponse{ | ||
Job: &bindingstypes.Job{ | ||
JobId: j.ID, | ||
ChainType: j.Routing.ChainType, | ||
ChainReferenceId: j.Routing.ChainReferenceID, | ||
Definition: string(j.Definition), | ||
Payload: string(j.Payload), | ||
PayloadModifiable: j.IsPayloadModifiable, | ||
IsMEV: j.EnforceMEVRelay, | ||
}, | ||
} | ||
|
||
bz, err := json.Marshal(res) | ||
if err != nil { | ||
return nil, sdkerrors.Wrap(err, "failed to marshal response") | ||
} | ||
|
||
return bz, nil | ||
default: | ||
return nil, wasmvmtypes.UnsupportedRequest{Kind: "unknown scheduler query variant"} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package types | ||
|
||
type SchedulerMsg struct { | ||
Message *SchedulerMsgType `json:"scheduler_msg_type,omitempty"` | ||
} | ||
|
||
type SchedulerMsgType struct { | ||
// Contracts can create new jobs. Any number of jobs | ||
// may be created, so lang as job IDs stay unique. | ||
CreateJob *CreateJob `json:"create_job,omitempty"` | ||
} | ||
|
||
// CreateJob is a message to create a new job. | ||
// JobId is a unique identifier for the job. | ||
// ChainType is the type of chain the job is for (e.g. "evm"). | ||
// ChainReferenceId is the reference for the chain (e.g. "eth-main"). | ||
// Definition containts the ABI of the target contract. | ||
// Payload is the data to be sent to the contract. | ||
// PayloadModifiable indicates whether the payload can be modified. | ||
// IsMEV indicates whether the job should be routed via an MEV pool. | ||
type CreateJob struct { | ||
Job *Job `json:"job,omitempty"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package types | ||
|
||
type SchedulerQuery struct { | ||
Query *SchedulerQueryType `json:"query,omitempty"` | ||
} | ||
|
||
type SchedulerQueryType struct { | ||
JobById *JobByIdRequest `json:"full_denom,omitempty"` | ||
} | ||
|
||
type JobByIdRequest struct { | ||
JobId string `json:"job_id"` | ||
} | ||
|
||
type JobByIdResponse struct { | ||
Job *Job `json:"job"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package types | ||
|
||
// JobId is a unique identifier for the job. | ||
// ChainType is the type of chain the job is for (e.g. "evm"). | ||
// ChainReferenceId is the reference for the chain (e.g. "eth-main"). | ||
// Definition containts the ABI of the target contract. | ||
// Payload is the data to be sent to the contract. | ||
// PayloadModifiable indicates whether the payload can be modified. | ||
// IsMEV indicates whether the job should be routed via an MEV pool. | ||
type Job struct { | ||
JobId string `json:"job_id"` | ||
ChainType string `json:"chain_type"` | ||
ChainReferenceId string `json:"chain_reference_id"` | ||
Definition string `json:"definition"` | ||
Payload string `json:"payload"` | ||
PayloadModifiable bool `json:"payload_modifiable"` | ||
IsMEV bool `json:"is_mev"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package bindings | ||
|
||
import ( | ||
wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" | ||
schedulerkeeper "github.com/palomachain/paloma/v2/x/scheduler/keeper" | ||
) | ||
|
||
func RegisterCustomPlugins( | ||
scheduler *schedulerkeeper.Keeper, | ||
) []wasmkeeper.Option { | ||
wasmQueryPlugin := NewQueryPlugin(scheduler) | ||
queryPluginOpt := wasmkeeper.WithQueryPlugins(&wasmkeeper.QueryPlugins{ | ||
Custom: CustomQuerier(wasmQueryPlugin), | ||
}) | ||
messengerDecoratorOpt := wasmkeeper.WithMessageHandlerDecorator( | ||
CustomMessageDecorator(scheduler), | ||
) | ||
|
||
return []wasmkeeper.Option{ | ||
queryPluginOpt, | ||
messengerDecoratorOpt, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.