Skip to content

CosmWasm MsgExecuteContract Indexing Strategy ‐ Pre‐Development

Peter edited this page Jun 27, 2024 · 5 revisions

Basic Facts

  1. Contracts are at known (or discoverable) contract addresses
  2. Contracts deploy known (or discoverable) code IDs
  3. Contracts are executed by specifying the contract address in the MsgExecuteContract message type
  4. Some contract protocols have many contracts deployed on-chain
  5. Contracts allow executing contract specific behavior through the use of raw contract Msg types
  6. Contract messages are JSON maps - See the CosmWasm repo README and the docs at this search on the CosmWasm docsite

Goal

  1. Support for CosmWasm MsgExecuteContract indexing in a generalized manner
  2. Way to register contract specific support for known contract types
    • By code ID or;
    • By known contract address. Then;
    • By contract execution JSON message formats based on contract execution requirements
  3. Way to check if a contract execution JSON message fits known formats on contract addresses we have not registered
    • Either throw warning or fail entire block so we can ensure support is valid
  4. Contract addresses should be linkable to execution-specific message type handlers that parse the message into taxable data, but generalized enough that the entrypoint does not care what is called

Pre-Development Decisions

  1. We will rely on known code IDs and contract addresses to determine parsing requirements
    • This will require research and continued development if contracts are continually deployed
    • This may be a losing approach if we cannot ensure we have valid contract addresses across the blockchain
  2. Using contract message fields as the parser finder will be avoided in preference to (1)
    • Since its possibly more error prone if contracts share fields
    • If the above is determined to be not an issue, the generalization goal should make it easy to switch if needed
  3. If (1) is not sufficient, it may require (1) and (2) to determine parser

CosmWasm MsgExecuteContract Indexer Generalization

We should add a single entrypoint handler in the cosmwasm package. We should add registration functionality in the same package. The goal for these will be:

  1. Registration will happen on application configuration time.
    • It will handle registering known, hard-coded contract addresses based on chain ID
    • It will handle registering code IDs, which can be used to query for current deployed addresses to register as well
    • It will then register types of indexable contract address execution formats
  2. During indexing, a function will be executed as a single entrypoint for all MsgExecuteContract calls
    • It will check the contract address against the known contract addresses
    • If a match is found, execute parsers
    • If a match is not found, check the execution JSON format against our type registry
      • If a type match is found, either:
        • Throw an error and fail the entire block, so we can ensure we check the block for support
        • Throw a warning
        • Possibly create a new table for this specific case so we can save the data but not fail the entire block
      • If a type match is not found, do nothing
  3. Early decision needed: Should the entrypoint handle type parsing and calling a subsequent function, or should it be passed down to a contract specific type checker?

CodeID/Address and Execution Message Type Registries

These registries will handle identifying known contracts we have specific support for.

  1. Contract address registry: A map of string keys that can be looked up quickly
  2. Execution Message Type registry:
    • Contract Level: Each contract support will require its own type registry for indexable/non-indexable contract execution message types. These will determine the path for the parser.
    • Entrypoint level:
      • We may need a type registry at the entrypoint
      • This will allow us to check types and throw errors if we see a contract executing where we are not tracking the address properly
      • We should consider using json.RawMessage as much as possible to
  3. Since contracts execution messages are raw JSON, we need either:
    • Struct types for deserialization - would make type checks
    • Generic JSON parsers and search for fields

Contract Message Type Parsers - Specific Contract Support

For contract support, the goal will be the following:

  1. Add types for deserializing supported message types
  2. Add parser support for each supported message type

We will want the type deserialization to be fast and efficient.

There will be a few options, all with potential significant performance impacts due to JSON parsing requirements.

  1. Most likely inefficiant approaches:
    • Attempt to parse the type out into all known types, use the first type match
    • For each contract address, build a single type that contains top level fields we care about:
      • Either:
        • json.RawMessage as values
        • Pointers to underlying types as values
      • Parse out the type and determine what fields matched
      • Use the fields to determine the parser
    • Using a map[string]json.RawMessage
  2. Attempt to make use of more efficient libraries to deal with unmarshalling known data with possible other unknown data

We will use one of the naive approaces to determine if the MsgExecuteContract parsing is a performance bottleneck to avoid premature optimization.

Parsing Support

Once the underlying contract or type has been determined, we can pass the cosmos message to downstream parsers.