Skip to content

Commit 96397ea

Browse files
wip: resolutions handler
(cherry picked from commit 0821694c105d3bfb71d04a19d7530ffe636b8dc6)
1 parent 5669a93 commit 96397ea

File tree

4 files changed

+62
-32
lines changed

4 files changed

+62
-32
lines changed

src/mappings/almanac/resolutions.ts

+55-27
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
1-
import {AlmanacRecord, AlmanacResolution, Block, Event, Transaction} from "../../types";
1+
import {
2+
AlmanacRecord,
3+
AlmanacResolution,
4+
Block,
5+
Contract,
6+
Event, EventAttribute,
7+
InstantiateContractMessage,
8+
Interface,
9+
} from "../../types";
210
import {parseAttributes, WasmdEventAttributesI} from "../utils";
311

412
export async function cacheAlmanacResolution(contractId: string, agentId: string, record: AlmanacRecord): Promise<void> {
513
try {
6-
logger.info(`[cacheAlmanacResolution] (recordId ${record.id}): caching record`);
14+
logger.info(`[cacheAlmanacResolution] (recordId: ${record.id}): caching record`);
715
const resolutionEntity = AlmanacResolution.create({
816
id: record.id,
917
agentId,
@@ -17,39 +25,59 @@ export async function cacheAlmanacResolution(contractId: string, agentId: string
1725
}
1826

1927
export async function expireAlmanacResolutionsRelativeToHeight(height: bigint): Promise<void> {
20-
/* for contract in almanac contracts {
21-
* expiryHeight = contract.expiryHeight
22-
* }
23-
*/
24-
25-
const blocks = await Block.getByHeight(BigInt(height));
26-
// const blocks = await Block.getByHeight(BigInt(expiryHeight));
27-
if (!blocks || blocks.length !== 1) {
28-
logger.error(`[expireAlmanacResolutionAtHeight] (height: ${height}): found ${blocks?.length ?? 0} blocks at that height`);
29-
}
28+
// TODO: optimize with custom `Store` methods exposing more sequelize functionality.
29+
const almanacContracts = await store.getByField("Contract", "interface", Interface.MicroAgentAlmanac) as Contract[];
3030

31-
const events = await Event.getByBlockId(blocks[0].id);
32-
if (!events || events.length !== 1) {
33-
logger.error(`[expireAlmanacResolutionAtHeight] (height: ${height}): found ${events?.length ?? 0} events at that height`);
34-
}
31+
for (const contract of almanacContracts) {
32+
const instantiateMsg = await InstantiateContractMessage.get(contract.instantiateMessageId);
33+
try {
34+
const {expiry_height} = JSON.parse(instantiateMsg.payload);
35+
if (!expiry_height) {
36+
logger.warn(`[expireAlmanacResolutionsRelativeToHeight] (height: ${height}): falsey expiry_height: ${expiry_height}`);
37+
continue;
38+
}
3539

36-
for (const event of events) {
37-
const attributes = parseAttributes<WasmdEventAttributesI>(event.attributes);
38-
if (!attributes.action || attributes.action !== "register") {
39-
continue;
40-
}
40+
const blocks = await Block.getByHeight(BigInt(expiry_height));
41+
if (!blocks || blocks.length !== 1) {
42+
logger.error(`[expireAlmanacResolutionAtHeight] (height: ${height}): found ${blocks?.length ?? 0} blocks at that height`);
43+
continue;
44+
}
45+
46+
const events = await Event.getByBlockId(blocks[0].id);
47+
if (!events || events.length !== 1) {
48+
logger.error(`[expireAlmanacResolutionAtHeight] (height: ${height}): found ${events?.length ?? 0} events at that height`);
49+
continue;
50+
}
4151

42-
// NB: recordId is equivalent to ID of register event.
43-
await expireAlmanacResolution(event.id);
52+
// TODO: consider relating EventAttributes to Blocks to reduce # of serial lookups.
53+
for (const event of events) {
54+
const eventAttributes = await EventAttribute.getByEventId(event.id);
55+
if (!events || events.length !== 1) {
56+
logger.error(`[expireAlmanacResolutionAtHeight] (height: ${height}): found ${eventAttributes?.length ?? 0} event attributes with event ID: ${event.id}`);
57+
continue;
58+
}
59+
60+
const attributes = parseAttributes<WasmdEventAttributesI>(eventAttributes);
61+
if (!attributes.action || attributes.action !== "register") {
62+
logger.warn(`[expireAlmanacResolutionsRelativeToHeight] (height: ${height}): expected "register" action, got: ${attributes.action}`);
63+
continue;
64+
}
65+
66+
// NB: resolution ID is equivalent to register event ID.
67+
await expireAlmanacResolution(event.id);
68+
}
69+
} catch (error) {
70+
logger.warn(`[expireAlmanacResolutionsRelativeToHeight] (height: ${height}): unable to parse instantiate message payload`);
71+
}
4472
}
4573
}
4674

47-
export async function expireAlmanacResolution(recordId: string): Promise<void> {
75+
export async function expireAlmanacResolution(id: string): Promise<void> {
4876
try {
49-
logger.info(`[expireAlmanacResolution] (recordId ${recordId}): expiring record`);
50-
await AlmanacResolution.remove(recordId);
77+
logger.info(`[expireAlmanacResolution] (recordId: ${id}): expiring record`);
78+
await AlmanacResolution.remove(id);
5179
} catch (error) {
52-
logger.warn(`[expireAlmanacResolution] (recordId: ${recordId}): ${error.stack}`);
80+
logger.warn(`[expireAlmanacResolution] (recordId: ${id}): ${error.stack}`);
5381
}
5482
}
5583

src/mappings/primitives.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
} from "./utils";
1111
import {createHash} from "crypto";
1212
import {toBech32} from "@cosmjs/encoding";
13-
import {expireAlmanacResolutionsRelativeToHeight} from "./almanac/resolutions";
13+
// import {expireAlmanacResolutionsRelativeToHeight} from "./almanac/resolutions";
1414

1515
export async function handleBlock(block: CosmosBlock): Promise<void> {
1616
await attemptHandling(block, _handleBlock, _handleBlockError);
@@ -42,7 +42,7 @@ async function _handleBlock(block: CosmosBlock): Promise<void> {
4242
});
4343

4444
await blockEntity.save();
45-
await expireAlmanacResolutionsAtHeight(height);
45+
// await expireAlmanacResolutionsAtHeight(height);
4646
}
4747

4848
async function _handleTransaction(tx: CosmosTransaction): Promise<void> {

src/mappings/utils.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {Attribute} from "@cosmjs/stargate/build/logs";
55
import {LegacyBridgeSwapStructure} from "./wasm/contracts/bridge";
66
import {CW20Structure} from "./wasm/contracts/cw20";
77
import {Structure} from "./wasm/contracts/types";
8+
import {MicroAgentAlmanacStructure} from "./wasm/contracts/almanac";
89

910
export type Primitive = CosmosEvent | CosmosMessage | CosmosTransaction | CosmosBlock;
1011

@@ -32,7 +33,8 @@ export async function checkBalancesAccount(address: string, chainId: string) {
3233
export function getJaccardResult(payload: object): Interface {
3334
let prediction = Structure, prediction_coefficient = 0.5; // prediction coefficient can be set as a minimum threshold for the certainty of an output
3435
let diff = 0, match = 0, coefficient = 0; // where coefficient of 1 is a perfect property key match, 2 is a perfect match of property and type
35-
const structs = [CW20Structure, LegacyBridgeSwapStructure];
36+
// TODO: refactor
37+
const structs = [CW20Structure, LegacyBridgeSwapStructure, MicroAgentAlmanacStructure];
3638
structs.forEach((struct) => {
3739
Object.keys(payload).forEach((payload_key) => {
3840
if (struct.listProperties().some((prop) => prop === payload_key)) { // If payload property exists as a property within current structure

tests/e2e/entities/test_almanac.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import time
22
import unittest
33
from dataclasses import dataclass
4-
from typing import Any, Dict, List, Tuple
4+
from typing import Dict, List, Tuple
55

66
import graphql
77
from cosmpy.aerial.tx_helpers import SubmittedTx
88
from gql import gql
99

10-
from src.genesis.helpers.field_enums import Agents, AlmanacRecords, AlmanacRegistrations
10+
from src.genesis.helpers.field_enums import Agents, AlmanacRecords, AlmanacRegistrations, ContractFields
1111
from tests.helpers.contracts import AlmanacContract, DefaultAlmanacContractConfig
1212
from tests.helpers.entity_test import EntityTest
1313
from tests.helpers.graphql import filtered_test_query

0 commit comments

Comments
 (0)