-
-
Notifications
You must be signed in to change notification settings - Fork 7
Cosmos SDK and chain Package Inclusion and Versioning
The application makes use of the Cosmos SDK and various modules developed in Osmosis to support indexing the blockchain transactions found there.
At its most basic, the application uses the actual types and interfaces provided in the blockchain code to parse out the data received from the nodes for each transaction. We turn the data provided by the node into the actual message types found in the blockchain code. This allows the application to use the actual message as it is represented in the code.
There are a few implications for this that are important to know:
- The application must be provided the packages that correspond to the blockchain messages being indexed
- These packages must have the correct interface definitions based on the message type being parsed
- As blockchains update their modules, either deprecating old message types or introducing new ones, the application will need to be updated to support these module updates
Depending on whether a new message type is added or an old one is deprecated, the application will need to be updated to support these changes.
When a new message type is added, we need to do the following:
- Update the package that supports this type to the latest version
- Build the parser to support this new type
For example, say Osmosis releases v15 with a new message type we need to parse, but our application includes Osmosis v14.
We would need to update our application's Osmosis version and build the parser to support this new message type.
Chain developers sometimes remove old message types as they are deprecated. Unfortunately, this does not remove the messages from the node since they are written into old state.
This makes it particularly difficult for the application to handle missing message types. Without the type in the code, we cannot parse the message into its underlying type and we cannot support the message.
We handle this by:
- Finding the old message definition codec in the old version of the chain code
- Include this message definition codec in our fork of
Lens
so that Lens can figure out how to handle the type.
This allows Lens
to handle old types internally instead of trying to rely on chain developers to always include their old message definitions.
The above 2 instances have some serious implications that need to be understood. With the fast-paced nature of some of these blockchain codebases, we will need to be on top of the module changes introduced in order to support new versions.
Sometimes chain developers will, when releasing a new version, introduce new types and deprecate old types at the same time. That means both methods above will have to happen at once.
Every message in the Cosmos SDK must satisfy the Msg
interface. Messages are "module-specific objects that trigger state transitions within the scope of the module they belong to."
We use this to our application's advantage by:
- Taking the raw Message in
Msg
received from the block processor - Figuring out the actual type of the Message
- Passing the
Msg
to a custom-built parser for that message type - Turning the
Msg
into its actual Message type - Using that type during Message parsing
As a simple example, take our support for the base Cosmos SDK message type /cosmos.bank.v1beta1.MsgMultiSend
. Lets dive into the lifecycle of a transaction that includes this message.
For Block N, our block processor gathers the full list of transactions. These transactions include a list of messages, all of the base Msg
type.
Each of the transactions in the block get passed to our Transaction Processor.
When a transaction reaches the transaction processor function, we loop through each of the messages in the transaction.
For each message, the application:
- Gets the message type string
- Finds the appropriate handler function for the message type
- Passes the raw
Msg
value to the handler parser function for processing
Source found here.
In the code found above, the application does the following:
- Casts the raw
Msg
into the actual message type and stores that in our interface for later
sf.CosmosMsgMultiSend = msg.(*bankTypes.MsgMultiSend)
- Uses the actual code provided by the Cosmos
bank
module to parse out the required data. In the below code block, the application uses the MsgMultiSend.Inputs variable to pull the Sent coins out of the message.
for _, input := range sf.CosmosMsgMultiSend.Inputs {
for _, coin := range input.Coins {
if currentTotal, ok := sentMap[coin.Denom]; ok {
sentMap[coin.Denom] = currentTotal.Add(coin.Amount)
} else {
sentMap[coin.Denom] = coin.Amount
}
}
}
This allows the application to use the actual block chain code to handle data stored on the blockchain.