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/#443 cosmwasm MsgExecuteContract indexing strategy #557

Merged
merged 1 commit into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion cmd/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ func setupIndexer() *Indexer {
// Setup chain specific stuff
core.SetupAddressRegex(indexer.cfg.Lens.AccountPrefix + "(valoper)?1[a-z0-9]{38}")
core.SetupAddressPrefix(indexer.cfg.Lens.AccountPrefix)
core.ChainSpecificMessageTypeHandlerBootstrap(indexer.cfg.Lens.ChainID)
core.ChainSpecificBeginBlockerEventTypeHandlerBootstrap(indexer.cfg.Lens.ChainID)
core.ChainSpecificEndBlockerEventTypeHandlerBootstrap(indexer.cfg.Lens.ChainID)
core.ChainSpecificEpochIdentifierEventTypeHandlersBootstrap(indexer.cfg.Lens.ChainID)
Expand All @@ -121,6 +120,8 @@ func setupIndexer() *Indexer {
tasks.DoChainSpecificUpsertDenoms(indexer.db, indexer.cfg.Lens.ChainID, indexer.cfg.Base.RequestRetryAttempts, indexer.cfg.Base.RequestRetryMaxWait)
indexer.cl = config.GetLensClient(indexer.cfg.Lens)

core.ChainSpecificMessageTypeHandlerBootstrap(indexer.cfg.Lens.ChainID, indexer.cl)

// Depending on the app configuration, wait for the chain to catch up
chainCatchingUp, err := rpc.IsCatchingUp(indexer.cl)
for indexer.cfg.Base.WaitForChain && chainCatchingUp && err == nil {
Expand Down
19 changes: 17 additions & 2 deletions core/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/DefiantLabs/cosmos-tax-cli/cosmos/modules/staking"
txtypes "github.com/DefiantLabs/cosmos-tax-cli/cosmos/modules/tx"
"github.com/DefiantLabs/cosmos-tax-cli/cosmos/modules/vesting"
"github.com/DefiantLabs/cosmos-tax-cli/cosmwasm"
"github.com/DefiantLabs/cosmos-tax-cli/cosmwasm/modules/wasm"
dbTypes "github.com/DefiantLabs/cosmos-tax-cli/db"
"github.com/DefiantLabs/cosmos-tax-cli/osmosis"
Expand Down Expand Up @@ -159,7 +160,6 @@ var messageTypeIgnorer = map[string]interface{}{
/////// Possible Taxable Events, future work ///////
////////////////////////////////////////////////////
// CosmWasm
wasm.MsgExecuteContract: nil,
wasm.MsgInstantiateContract: nil,
wasm.MsgInstantiateContract2: nil,
wasm.MsgStoreCode: nil,
Expand All @@ -179,18 +179,33 @@ var messageTypeIgnorer = map[string]interface{}{

// Merge the chain specific message type handlers into the core message type handler map.
// Chain specific handlers will be registered BEFORE any generic handlers.
func ChainSpecificMessageTypeHandlerBootstrap(chainID string) {
func ChainSpecificMessageTypeHandlerBootstrap(chainID string, lensClient *client.ChainClient) {
var customContractAddressHandlers []wasm.ContractExecutionMessageHandler
var chainSpecificMessageTpeHandler map[string][]func() txtypes.CosmosMessage
if chainID == osmosis.ChainID {
chainSpecificMessageTpeHandler = osmosis.MessageTypeHandler
}

for key, value := range chainSpecificMessageTpeHandler {
if list, ok := messageTypeHandler[key]; ok {
messageTypeHandler[key] = append(value, list...)
} else {
messageTypeHandler[key] = value
}
}

cosmWasmHandlers, err := cosmwasm.GetCosmWasmMessageTypeHandlers(customContractAddressHandlers, lensClient)
if err != nil {
config.Log.Fatal("Error getting CosmWasm message type handlers.", err)
}

for key, value := range cosmWasmHandlers {
if list, ok := messageTypeHandler[key]; ok {
messageTypeHandler[key] = append(value, list...)
} else {
messageTypeHandler[key] = value
}
}
}

// ParseCosmosMessageJSON - Parse a SINGLE Cosmos Message into the appropriate type.
Expand Down
52 changes: 52 additions & 0 deletions cosmwasm/handlers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package cosmwasm

import (
txTypes "github.com/DefiantLabs/cosmos-tax-cli/cosmos/modules/tx"
"github.com/DefiantLabs/cosmos-tax-cli/cosmwasm/modules/wasm"
"github.com/DefiantLabs/cosmos-tax-cli/rpc"
"github.com/DefiantLabs/lens/client"
)

var defaultMessageTypeHandler = map[string][]func() txTypes.CosmosMessage{}

var contractAddressRegistry = map[string]wasm.ContractExecutionMessageHandler{}

func GetCosmWasmMessageTypeHandlers(customContractAddressHandlers []wasm.ContractExecutionMessageHandler, lensClient *client.ChainClient) (map[string][]func() txTypes.CosmosMessage, error) {
msgExecuteContractHandlers, err := configureMsgExecuteContractHandler(customContractAddressHandlers, lensClient)
if err != nil {
return nil, err
}

defaultMessageTypeHandler[wasm.MsgExecuteContract] = msgExecuteContractHandlers

return defaultMessageTypeHandler, nil
}

// Configures a handler wrapper that will allow using registry values to find custom message handlers
func configureMsgExecuteContractHandler(customContractAddressHandlers []wasm.ContractExecutionMessageHandler, lensClient *client.ChainClient) ([]func() txTypes.CosmosMessage, error) {
for _, handler := range customContractAddressHandlers {
if castHandler, ok := handler.(wasm.ContractExecutionMessageHandlerByContractAddress); ok {
contractAddressRegistry[castHandler.ContractAddress()] = handler
} else if castHandler, ok := handler.(wasm.ContractExecutionMessageHandlerByCodeID); ok {
// Query for code ID contract addresses using wasm querying
resp, err := rpc.GetContractsByCodeIDAtHeight(lensClient, castHandler.CodeID(), 0)
if err != nil {
return nil, err
}

for _, contractAddress := range resp.Contracts {
contractAddressRegistry[contractAddress] = handler
}
}
}

configuredExecuteContractWrapper := wasm.WrapperMsgExecuteContract{
ContractAddressRegistry: contractAddressRegistry,
}

return []func() txTypes.CosmosMessage{
func() txTypes.CosmosMessage {
return configuredExecuteContractWrapper
},
}, nil
}
66 changes: 66 additions & 0 deletions cosmwasm/modules/wasm/types.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
package wasm

import (
"fmt"

wasmTypes "github.com/CosmWasm/wasmd/x/wasm/types"
parsingTypes "github.com/DefiantLabs/cosmos-tax-cli/cosmos/modules"
txTypes "github.com/DefiantLabs/cosmos-tax-cli/cosmos/modules/tx"
sdk "github.com/cosmos/cosmos-sdk/types"
)

const (
MsgExecuteContract = "/cosmwasm.wasm.v1.MsgExecuteContract"
MsgInstantiateContract = "/cosmwasm.wasm.v1.MsgInstantiateContract"
Expand All @@ -18,3 +27,60 @@ const (
MsgAddCodeUploadParamsAddresses = "/cosmwasm.wasm.v1.MsgAddCodeUploadParamsAddresses"
MsgStoreAndMigrateContract = "/cosmwasm.wasm.v1.MsgStoreAndMigrateContract"
)

type ContractExecutionMessageHandler interface {
txTypes.CosmosMessage
ContractFriendlyName() string
TopLevelFieldIdentifiers() []string
TopLevelIdentifierType() any
CosmosMessageType() txTypes.CosmosMessage
}

type ContractExecutionMessageHandlerByCodeID interface {
ContractExecutionMessageHandler
CodeID() uint64
}

type ContractExecutionMessageHandlerByContractAddress interface {
ContractExecutionMessageHandler
ContractAddress() string
}

type WrapperMsgExecuteContract struct {
txTypes.Message
CosmosMsgExecuteContract *wasmTypes.MsgExecuteContract
ContractAddressRegistry map[string]ContractExecutionMessageHandler
CurrentHandler ContractExecutionMessageHandler
ContractAddress string
}

func (w WrapperMsgExecuteContract) HandleMsg(typeURL string, msg sdk.Msg, log *txTypes.LogMessage) error {
w.Type = typeURL
w.CosmosMsgExecuteContract = msg.(*wasmTypes.MsgExecuteContract)

if handler, ok := w.ContractAddressRegistry[w.CosmosMsgExecuteContract.Contract]; ok {
w.CurrentHandler = handler
return w.CurrentHandler.HandleMsg(typeURL, msg, log)
}

return nil
}

func (w WrapperMsgExecuteContract) ParseRelevantData() []parsingTypes.MessageRelevantInformation {
if w.CurrentHandler != nil {
return w.CurrentHandler.ParseRelevantData()
}

return nil
}

func (w WrapperMsgExecuteContract) GetType() string {
return MsgExecuteContract
}

func (w WrapperMsgExecuteContract) String() string {
if w.CurrentHandler != nil {
return w.CurrentHandler.String()
}
return fmt.Sprintf("MsgExecuteContract: No handler found for contract address %s", w.ContractAddress)
}
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ toolchain go1.21.11

require (
github.com/BurntSushi/toml v1.3.2
// Our lens library is pinned to this specific SHA and branch: 7732945f81598e4d6aff47e0d4ca81b0ec26d8b3, https://github.com/DefiantLabs/lens/tree/v0.0.21-dl
github.com/DefiantLabs/lens v0.3.1-0.20240626071018-7732945f8159
// Our lens library is pinned to this specific SHA and branch: 2ff2d8138af66fb3f3e3429b9837db1e720ed39f, https://github.com/DefiantLabs/lens/tree/v0.0.22-dl
github.com/DefiantLabs/lens v0.3.1-0.20240627235205-2ff2d8138af6
github.com/cosmos/cosmos-sdk v0.47.8
github.com/gin-gonic/gin v1.9.1
github.com/go-co-op/gocron v1.13.0
Expand All @@ -26,6 +26,7 @@ require (

require (
cosmossdk.io/math v1.3.0
github.com/CosmWasm/wasmd v0.45.1-0.20231128163306-4b9b61faeaa3
github.com/cometbft/cometbft v0.38.0
github.com/cosmos/ibc-go/v7 v7.4.1
github.com/go-git/go-git/v5 v5.11.0
Expand Down Expand Up @@ -53,7 +54,6 @@ require (
dario.cat/mergo v1.0.0 // indirect
filippo.io/edwards25519 v1.0.0 // indirect
github.com/99designs/keyring v1.2.1 // indirect
github.com/CosmWasm/wasmd v0.45.1-0.20231128163306-4b9b61faeaa3 // indirect
github.com/CosmWasm/wasmvm v1.5.2 // indirect
github.com/DataDog/zstd v1.5.0 // indirect
github.com/KyleBanks/depth v1.2.1 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -558,8 +558,8 @@ github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/DataDog/zstd v1.5.0 h1:+K/VEwIAaPcHiMtQvpLD4lqW7f0Gk3xdYZmI1hD+CXo=
github.com/DataDog/zstd v1.5.0/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw=
github.com/DefiantLabs/lens v0.3.1-0.20240626071018-7732945f8159 h1:GB/lSc4/UT7M64scdyh0lrwyRRi3UyCto9RvwJekVKI=
github.com/DefiantLabs/lens v0.3.1-0.20240626071018-7732945f8159/go.mod h1:nTPf+NQkhPH6NcBY5p0lpdb14WPiZOeMZDDkq1IWl30=
github.com/DefiantLabs/lens v0.3.1-0.20240627235205-2ff2d8138af6 h1:n1wKVmFX2hUfL3B+PDbPrEbYAD47hNdNUQOnyPn32TE=
github.com/DefiantLabs/lens v0.3.1-0.20240627235205-2ff2d8138af6/go.mod h1:nTPf+NQkhPH6NcBY5p0lpdb14WPiZOeMZDDkq1IWl30=
github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
Expand Down
12 changes: 12 additions & 0 deletions rpc/requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
osmosisProtorev "github.com/osmosis-labs/osmosis/v25/x/protorev/types"
osmosisEpochs "github.com/osmosis-labs/osmosis/x/epochs/types"

wasmTypes "github.com/CosmWasm/wasmd/x/wasm/types"
"github.com/DefiantLabs/cosmos-tax-cli/config"
lensClient "github.com/DefiantLabs/lens/client"
lensQuery "github.com/DefiantLabs/lens/client/query"
Expand Down Expand Up @@ -193,3 +194,14 @@ func GetProtorevDeveloperAccount(cl *lensClient.ChainClient) (*osmosisProtorev.Q
resp, err := query.ProtorevDeveloperAccount()
return resp, err
}

func GetContractsByCodeIDAtHeight(cl *lensClient.ChainClient, codeID uint64, height int64) (*wasmTypes.QueryContractsByCodeResponse, error) {
pg := query.PageRequest{Limit: 100}
options := lensQuery.QueryOptions{Height: height, Pagination: &pg}
query := lensQuery.Query{Client: cl, Options: &options}
resp, err := query.ContractsByCodeIDAtHeight(codeID, height)
if err != nil {
return nil, err
}
return resp, nil
}
Loading