Skip to content

Commit

Permalink
feat: track almanac registrations
Browse files Browse the repository at this point in the history
  • Loading branch information
bryanchriswhite committed Dec 7, 2022
1 parent 6f5235b commit cbf7aa7
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 10 deletions.
7 changes: 7 additions & 0 deletions project.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,10 @@ dataSources:
kind: cosmos/MessageHandler
filter:
type: "/cosmos.authz.v1beta1.MsgExec"
- handler: handleAlmanacRegistration
kind: cosmos/EventHandler
filter:
type: "wasm"
messageFilter:
type: "/cosmwasm.wasm.v1.MsgExecuteContract"
contractCall: "register"
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
//Exports all handler functions
export * from "./mappings/mappingHandlers";
export {parseAttributes} from "./mappings/utils";
1 change: 1 addition & 0 deletions src/mappings/almanac/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./registrations";
110 changes: 110 additions & 0 deletions src/mappings/almanac/registrations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import {
attemptHandling,
messageId,
parseAttributes,
unprocessedEventHandler,
WasmdEventAttributesI
} from "../utils";
import {CosmosEvent} from "@subql/types-cosmos";
import {Agent, AlmanacRecord, AlmanacRegistration, Contract} from "../../types";

export async function handleAlmanacRegistration(event: CosmosEvent): Promise<void> {
await attemptHandling(event, _handleAlmanacRegistration, unprocessedEventHandler);
}

export interface RegisterAttributes extends WasmdEventAttributesI {
expiry_height?: string,
sequence?: number;
signature?: string;
agent_address?: string;
record?: string,
}

async function _handleAlmanacRegistration(event: CosmosEvent): Promise<void> {
const id = messageId(event);
logger.info(`[handleAlmanacRegistration] (tx ${event.tx.hash}): indexing AlmanacRegistration ${id}`);
logger.debug(`[handleAlmanacRegistration] (event.log.log): ${JSON.stringify(event.log.log, null, 2)}`);

/* NB: signature verification is handled by the almanac contract!
* This handler assumes that the contract will only emit events
* with valid signatures corresponding to the agent address.
*/

const {
_contract_address,
agent_address,
expiry_height,
sequence,
signature,
record: recordStr,
} = parseAttributes<RegisterAttributes>(event.event.attributes);

if (!agent_address) {
logger.warn("[handleAlmanacRegistration]: missing address");
return;
}

if (!signature) {
logger.warn("[handleAlmanacRegistration]: missing signature");
return;
}

if (!sequence) {
logger.warn("[handleAlmanacRegistration]: missing sequence");
return;
}

if (!expiry_height) {
logger.warn("[handleAlmanacRegistration]: missing expiry_height");
return;
}

if (!recordStr) {
logger.warn("[handleAlmanacRegistration]: missing record");
return;
}

const record = JSON.parse(recordStr);
if (!record || !record.service) {
logger.warn("[handleAlmanacRegistration]: missing record service");
return;
}

// NB: ensure agent exists
const agent = await Agent.get(agent_address);
if (!agent) {
await Agent.create({
id: agent_address,
}).save();
}

// NB: ensure contract exists
const contract = await Contract.get(_contract_address);
if (!contract) {
logger.warn(`[handleAlmanacRegistration]: unable to find contract with address: ${_contract_address}`);
return;
}

const recordEntity = AlmanacRecord.create({
id,
service: record.service,
// eventId: id,
transactionId: event.tx.hash,
blockId: event.block.block.id,
});
await recordEntity.save();

const registrationEntity = AlmanacRegistration.create({
id,
expiryHeight: BigInt(expiry_height),
signature,
sequence,
agentId: agent_address,
recordId: id,
contractId: _contract_address,
// eventId: id,
transactionId: event.tx.hash,
blockId: event.block.block.id,
});
await registrationEntity.save();
}
1 change: 1 addition & 0 deletions src/mappings/mappingHandlers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from "./authz";
export * from "./almanac";
export * from "./bank";
export * from "./dist";
export * from "./gov";
Expand Down
38 changes: 28 additions & 10 deletions src/mappings/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
import {CosmosBlock, CosmosEvent, CosmosMessage, CosmosTransaction} from "@subql/types-cosmos";
import {Account, Interface, UnprocessedEntity} from "../types";
import { createHash } from "crypto";
import {createHash} from "crypto";
import {Attribute} from "@cosmjs/stargate/build/logs";

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

export interface Primitives {
event?: CosmosEvent;
msg?: CosmosMessage;
tx?: CosmosTransaction;
block?: CosmosBlock;
}

// messageId returns the id of the message passed or
// that of the message which generated the event passed.
Expand Down Expand Up @@ -43,15 +53,6 @@ export function getJaccardResult(payload: object): Interface {
return prediction.getInterface(); // return best matched Interface to contract
}

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

export interface Primitives {
event?: CosmosEvent;
msg?: CosmosMessage;
tx?: CosmosTransaction;
block?: CosmosBlock;
}

export async function attemptHandling(input: Primitive,
handlerFn: (primitive) => Promise<void>,
errorFn: (Error, Primitive) => void): Promise<void> {
Expand Down Expand Up @@ -168,3 +169,20 @@ class LegacyBridgeSwapStructure extends Structure {
return Interface.LegacyBridgeSwap;
}
}

export interface BaseEventAttributesI {
action: string;
}

// (see: https://github.com/CosmWasm/wasmd/blob/main/x/wasm/keeper/events.go)
export interface WasmdEventAttributesI extends BaseEventAttributesI {
_contract_address: string;
}

export function parseAttributes<T extends BaseEventAttributesI>(attributes: readonly Attribute[]): T {
// @ts-ignore
return attributes.reduce((acc, curr) => {
acc[curr.key] = curr.value;
return acc as T;
}, {});
}

0 comments on commit cbf7aa7

Please sign in to comment.