Skip to content

Commit

Permalink
Feat: Get colony creation event
Browse files Browse the repository at this point in the history
Feat: Get colony creation event and update colony model
Chore: Update block ingestor hash
  • Loading branch information
bassgeta authored and mmioana committed Dec 13, 2024
1 parent 4c26eff commit c9753d7
Show file tree
Hide file tree
Showing 9 changed files with 239 additions and 33 deletions.
15 changes: 13 additions & 2 deletions amplify/backend/api/colonycdapp/schema/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -1533,6 +1533,17 @@ type ColonyContributor @model @searchable {
@hasMany(indexName: "byTargetAddress", fields: ["contributorAddress"])
}

type ColonyCreateEvent {
"""
The block number the colony was created at
"""
blockNumber: Int!
"""
The address that signed the transaction
"""
signerAddress: String!
}

"""
Represents a Colony within the Colony Network
"""
Expand All @@ -1546,9 +1557,9 @@ type Colony @model {
"""
name: String! @index(name: "byName", queryField: "getColonyByName")
"""
The block number the colony was created attached
Colony creation data
"""
createdAtBlock: Int
colonyCreateEvent: ColonyCreateEvent
"""
The unique address of the native token of the Colony
"""
Expand Down
2 changes: 1 addition & 1 deletion docker/colony-cdapp-dev-env-block-ingestor
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM colony-cdapp-dev-env/base:latest

ENV BLOCK_INGESTOR_HASH=6b1d83ebfbaa34096b823f2a50113636277607e4
ENV BLOCK_INGESTOR_HASH=9f9904afa30c7401f365e9e8e972d18d93e68cd4

# Declare volumes to set up metadata
VOLUME [ "/colonyCDapp/amplify/mock-data" ]
Expand Down
2 changes: 1 addition & 1 deletion docker/colony-cdapp-dev-env-proxy-block-ingestor
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
FROM colony-cdapp-dev-env/base:latest

# @TODO maybe add a PROXY_BLOCK_INGESTOR_HASH and fallback to BLOCK_INGESTOR_HASH
ENV BLOCK_INGESTOR_HASH=6b1d83ebfbaa34096b823f2a50113636277607e4
ENV BLOCK_INGESTOR_HASH=9f9904afa30c7401f365e9e8e972d18d93e68cd4
# @TODO do we need here a contract to be in the format:
# {
# name: 'ColonyNetwork',
Expand Down
163 changes: 163 additions & 0 deletions scripts/getColonyCreatedBlock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
const { graphqlRequest } = require('./utils/graphqlRequest');
const { providers, utils } = require('ethers');

const API_KEY = 'da2-fakeApiId123456';
const GRAPHQL_URI =
process.env.AWS_APPSYNC_GRAPHQL_URL || 'http://localhost:20002/graphql';
const RPC_URL = 'http://localhost:8545';

const getColonies = /* GraphQL */ `
query GetColonies($nextToken: String, $limit: Int) {
listColonies(nextToken: $nextToken, limit: $limit) {
items {
id
colonyCreateEvent {
blockNumber
signerAddress
}
}
}
}
`;

const updateColony = /* GraphQL */ `
mutation UpdateColony($input: UpdateColonyInput!) {
updateColony(input: $input) {
id
}
}
`;

const getAllPages = async (getData, params) => {
let items = [];
let nextToken = null;

do {
const actionsData = await getData({ ...params, nextToken, limit: 1000 });
nextToken = actionsData?.nextToken;
if (actionsData?.items) {
items.push(...actionsData.items);
}
} while (nextToken);

return items;
};

// @TODO maybe try to filter out colonies having the colonyCreateEvent set
const getColoniesData = async ({ limit, nextToken }) => {
const result = await graphqlRequest(
getColonies,
{
limit,
nextToken,
},
GRAPHQL_URI,
API_KEY,
);

if (!result) {
console.warn('Could not find any colonies in db.');
}

return result.data.listColonies;
};

const getAllColonies = async () => {
return getAllPages(getColoniesData);
};

const updateColonyCreateEvent = async (
colonyAddress,
blockNumber,
signerAddress,
) => {
await graphqlRequest(
updateColony,
{
input: {
id: colonyAddress,
colonyCreateEvent: {
blockNumber,
signerAddress,
},
},
},
GRAPHQL_URI,
API_KEY,
);
};

const ContractEventsSignatures = {
ContractCreation: 'ContractCreation(address)',
};

async function getColonyCreationBlock() {
try {
const provider = new providers.StaticJsonRpcProvider(RPC_URL);

const allColonies = await getAllColonies();

for (const colony of allColonies) {
const colonyAddress = colony.id;
if (colony.colonyCreateEvent) {
console.log(
`Colony with colonyAddress ${colonyAddress} already has the creation event set`,
);
continue;
}

console.log(
`Colony with colonyAddress ${colonyAddress} doesn't have the creation event set. Migrating...`,
);

try {
const createLogs = await provider.getLogs({
fromBlock: 0,
topics: [
utils.id(ContractEventsSignatures.ContractCreation),
// We need to make sure the address is 32 bytes long
`0x${colonyAddress.slice(2).padStart(64, '0')}`,
],
});

if (createLogs.length === 0) {
throw new Error(
`Couldn't fetch colony creation event for colonyAddress: ${colonyAddress}`,
);
}

const createLogBlockNumber = createLogs[0].blockNumber;
const txHash = createLogs[0].transactionHash;

const transaction = await provider.getTransaction(txHash);
const signerAddress = transaction.from;

if (!signerAddress) {
throw new Error(
`Couldn't find the signer for transaction with txHash: ${txHash}`,
);
}

console.log(
`Updating the createEvent details for colonyAddress: ${colonyAddress}`,
);
await updateColonyCreateEvent(
colonyAddress,
createLogBlockNumber,
signerAddress,
);
} catch (error) {
console.error(
`Encountered error while executing migration for colonyAddress ${colonyAddress}: ${error}`,
);
}
}
} catch (error) {
console.error(
'Error while executing the colony-create-event-details migration',
error,
);
}
}

getColonyCreationBlock();
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,15 @@ export const TmpProxyColonyDeploy = () => {
});

const handleClick = async () => {
if (!colony.colonyCreateEvent) {
console.warn('No colony creation data');
return;
}

await createProxyColony({
colonyAddress: colony.colonyAddress,
createdAtBlock: colony.createdAtBlock,
signerAddress: colony.colonyCreateEvent.signerAddress,
blockNumber: colony.colonyCreateEvent.blockNumber,
foreignChainId: chainId,
});
};
Expand Down
5 changes: 4 additions & 1 deletion src/graphql/fragments/colony.graphql
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
fragment Colony on Colony {
colonyAddress: id
name
createdAtBlock
colonyCreateEvent {
blockNumber
signerAddress
}
nativeToken {
...Token
}
Expand Down
49 changes: 31 additions & 18 deletions src/graphql/generated.ts

Large diffs are not rendered by default.

25 changes: 17 additions & 8 deletions src/redux/sagas/proxyColonies/createProxyColony.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ClientType, type ColonyNetworkClient } from '@colony/colony-js';
import { type CustomContract } from '@colony/sdk';
import { utils } from 'ethers';
import { put, takeEvery } from 'redux-saga/effects';
import { call, put, takeEvery } from 'redux-saga/effects';

import { colonyAbi } from '~constants/abis.ts';
import { ContextModule, getContext } from '~context/index.ts';
Expand All @@ -27,32 +27,41 @@ export type CreateProxyColonyPayload =

// @TODO if metatx are enabled sent a metaTx instead of tx
function* createProxyColony({
payload: { colonyAddress, createdAtBlock, foreignChainId },
payload: { colonyAddress, signerAddress, blockNumber, foreignChainId },
meta,
}: Action<ActionTypes.PROXY_COLONY_CREATE>) {
const batchKey = TRANSACTION_METHODS.CreateProxyColony;

const colonyManager = yield getColonyManager();
const networkClient: ColonyNetworkClient = yield getNetworkClient();
const { address } = getContext(ContextModule.Wallet);

const walletAddress = utils.getAddress(address);

/**
* For the networkClient.getColonyCreationSalt to properly work when passing the `from` value
* We need to instantiate the ColonyNetworkClient using a provider
*/
const networkClient: ColonyNetworkClient = yield call(
getNetworkClient,
colonyManager.provider, // @NOTE should we use the colonyManager.provider or just use edthers.providers?
);

try {
const colonyCreationSalt = yield networkClient.getColonyCreationSalt({
blockTag: createdAtBlock,
const generatedColonySalt = yield networkClient.getColonyCreationSalt({
blockTag: blockNumber,
from: signerAddress,
});

const proxyColonyContract: CustomContract<typeof colonyAbi> =
colonyManager.getCustomContract(colonyAddress, colonyAbi);
const params = [foreignChainId, colonyCreationSalt];
const params = [foreignChainId, generatedColonySalt];

yield addTransactionToDb(meta.id, {
context: ClientType.ColonyClient, // @NOTE we want to add a new context type
createdAt: new Date(),
methodName: 'createProxyColony',
from: walletAddress,
params: [foreignChainId, colonyCreationSalt],
params,
status: TransactionStatus.Ready,
group: {
key: batchKey,
Expand All @@ -64,7 +73,7 @@ function* createProxyColony({
const [transaction, waitForMined] = yield proxyColonyContract
.createTxCreator('createProxyColony', [
BigInt(foreignChainId),
colonyCreationSalt,
generatedColonySalt,
{
gasLimit: BigInt(10_000_000),
},
Expand Down
3 changes: 2 additions & 1 deletion src/redux/types/actions/proxyColonies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ export type ProxyColoniesActionTypes =
ActionTypes.PROXY_COLONY_CREATE,
{
colonyAddress: Address;
createdAtBlock: number;
signerAddress: Address;
blockNumber: number;
foreignChainId: number;
},
object
Expand Down

0 comments on commit c9753d7

Please sign in to comment.