From 0db72acb500b0f78d1075b2d508ec87ff2184dd3 Mon Sep 17 00:00:00 2001 From: xiaocheng Date: Fri, 20 May 2022 19:51:08 +0800 Subject: [PATCH 1/3] repair crab<>crab smart history --- subql/crab/project.yaml | 19 ++------ subql/crab/schema.graphql | 2 + subql/crab/src/handlers/account.ts | 4 ++ subql/crab/src/handlers/event.ts | 69 +++++++++++++++++++++--------- 4 files changed, 58 insertions(+), 36 deletions(-) diff --git a/subql/crab/project.yaml b/subql/crab/project.yaml index ceb57131..68d7943b 100644 --- a/subql/crab/project.yaml +++ b/subql/crab/project.yaml @@ -10,7 +10,7 @@ schema: network: genesisHash: '0x34f61bfda344b3fad3c3e38832a91448b3c613b199eb23e5110a635d71c13c65' endpoint: wss://darwinia-crab.api.onfinality.io/public-ws - dictionary: https://api.subquery.network/sq/itering/crab-dictionary/ + #dictionary: https://api.subquery.network/sq/itering/crab-dictionary/ chaintypes: file: ./types.yaml @@ -35,23 +35,12 @@ dataSources: - handler: handleEvent kind: substrate/EventHandler filter: - module: balances - method: Transfer # ring: mainnet -> dvm - - - handler: handleEvent - kind: substrate/EventHandler - filter: - module: kton - method: Transfer # kton: mainnet -> dvm + module: ethereum + method: DVMTransfer - handler: handleEvent kind: substrate/EventHandler filter: module: balances - method: Endowed # ring: dvm -> mainnet + method: Transfer - # - handler: handleEvent - # kind: substrate/EventHandler - # filter: - # module: balances - # method: Transfer diff --git a/subql/crab/schema.graphql b/subql/crab/schema.graphql index f380f2c8..3a56848b 100644 --- a/subql/crab/schema.graphql +++ b/subql/crab/schema.graphql @@ -29,6 +29,8 @@ type Transfer @entity { sender: Account recipient: Account + fromChain: String + toChain: String amount: BigInt section: String method: String diff --git a/subql/crab/src/handlers/account.ts b/subql/crab/src/handlers/account.ts index 8ceba3f0..cd0f1dfb 100644 --- a/subql/crab/src/handlers/account.ts +++ b/subql/crab/src/handlers/account.ts @@ -15,6 +15,10 @@ export class AccountHandler { return u8aToHex(decodeAddress(address)); } + static isDvmAddress(address: string) { + return address.startsWith("0x64766d3a00000000000000") + } + static async ensureAccount(id: string) { const account = await Account.get(id); diff --git a/subql/crab/src/handlers/event.ts b/subql/crab/src/handlers/event.ts index f5a07776..5ff3703e 100644 --- a/subql/crab/src/handlers/event.ts +++ b/subql/crab/src/handlers/event.ts @@ -56,12 +56,10 @@ export class EventHandler { await this.handleBridgeDispatchEvent(); } - if (this.method === 'Transfer' && (this.section === 'balances' || this.section === 'kton')) { - await this.handleMainToSmartTransfer(); - } - - if (this.method === 'Endowed' && this.section === 'balances') { - await this.handleSmartToMainTransfer(); + if (this.method === 'DVMTransfer' && this.section === 'ethereum') { + await this.handleDvmToCrab(); + } else if (this.method === 'Transfer' && this.section === 'balances') { + await this.handleCrabToDvm(); } } @@ -77,10 +75,49 @@ export class EventHandler { await event.save(); } - private async handleTransfer(from: string, to: string, amount: number) { - const sender = AccountHandler.formatAddress(from); - const recipient = AccountHandler.formatAddress(to); + // Dvm -> 15 -> Substrate + private findDvmToCrab(router: string, amount: number) { + const event = this.event?.extrinsic?.events.find((item) => { + if (item.event.method === 'DVMTransfer') { + const [ifrom, ito, iamount] = JSON.parse(item.event.data.toString()); + if (iamount === amount && ito === router) { + return true; + } + } + return false; + }); + return event; + } + private async handleDvmToCrab() { + const [from, to, amount] = JSON.parse(this.data); + var sender = AccountHandler.formatAddress(from); + var recipient = AccountHandler.formatAddress(to); + const senderIsDvm = AccountHandler.isDvmAddress(sender); + const recipientIsDvm = AccountHandler.isDvmAddress(recipient); + if (senderIsDvm && !recipientIsDvm) { + const event = this.findDvmToCrab(from, amount); + if (!event) { + return; + } + const [ifrom, ito, iamount] = JSON.parse(event.event.data.toString()); + sender = AccountHandler.formatAddress(ifrom); + await this.handleTransfer("crab-dvm", "crab", sender, recipient, amount); + } + } + + private async handleCrabToDvm() { + const [from, to, amount] = JSON.parse(this.data); + var sender = AccountHandler.formatAddress(from); + var recipient = AccountHandler.formatAddress(to); + const senderIsDvm = AccountHandler.isDvmAddress(sender); + const recipientIsDvm = AccountHandler.isDvmAddress(recipient); + if (!senderIsDvm && recipientIsDvm) { + await this.handleTransfer("crab", "crab-dvm", sender, recipient, amount); + } + } + + private async handleTransfer(fromChain: string, toChain: string, sender: string, recipient: string, amount: number) { await AccountHandler.ensureAccount(recipient); await AccountHandler.updateTransferStatistic(recipient); await AccountHandler.ensureAccount(sender); @@ -95,6 +132,8 @@ export class EventHandler { transfer.method = this.method; transfer.amount = BigInt(amount ?? 0); transfer.timestamp = this.timestamp; + transfer.fromChain = fromChain; + transfer.toChain = toChain; transfer.block = this.simpleBlock(); @@ -105,18 +144,6 @@ export class EventHandler { } } - private async handleMainToSmartTransfer() { - const [from, to, amount] = JSON.parse(this.data); - - await this.handleTransfer(from, to, amount); - } - - private async handleSmartToMainTransfer() { - const [to, amount] = JSON.parse(this.data); - const from = '0x0000000000000000000000000000000000000015'; - - await this.handleTransfer(from, to, amount); - } private simpleBlock(): Block { return { blockHash: this.blockHash, From 904d9c48eb43a95cac131371d19b1b167c074fa4 Mon Sep 17 00:00:00 2001 From: sxlwar Date: Mon, 23 May 2022 18:07:01 +0800 Subject: [PATCH 2/3] add pangolin rename handler fns --- subql/crab/new.yml | 60 ----------- subql/crab/project.yaml | 2 +- subql/crab/src/handlers/event.ts | 64 ++++++----- subql/pangolin/package.json | 2 +- subql/pangolin/project.yaml | 24 +---- subql/pangolin/schema.graphql | 3 +- subql/pangolin/src/handlers/account.ts | 15 +-- subql/pangolin/src/handlers/event.ts | 142 ++++++++++--------------- 8 files changed, 105 insertions(+), 207 deletions(-) delete mode 100644 subql/crab/new.yml diff --git a/subql/crab/new.yml b/subql/crab/new.yml deleted file mode 100644 index fc894192..00000000 --- a/subql/crab/new.yml +++ /dev/null @@ -1,60 +0,0 @@ -version: '3' - -services: - postgres: - image: postgres:12-alpine - ports: - - 5432:5432 - volumes: - - .data/postgres:/var/lib/postgresql/data - environment: - POSTGRES_PASSWORD: postgres - healthcheck: - test: ['CMD-SHELL', 'pg_isready -U postgres'] - interval: 5s - timeout: 5s - retries: 5 - - subquery-node: - image: onfinality/subql-node:v0.27.2-0 - depends_on: - 'postgres': - condition: service_healthy - restart: always - environment: - DB_USER: postgres - DB_PASS: postgres - DB_DATABASE: postgres - DB_HOST: postgres - DB_PORT: 5432 - volumes: - - ./:/app - command: - - -f=/app - - --db-schema=app - healthcheck: - test: ['CMD', 'curl', '-f', 'http://subquery-node:3000/ready'] - interval: 3s - timeout: 5s - retries: 10 - - graphql-engine: - image: onfinality/subql-query:v0.10.1-0 - ports: - - 3000:3000 - depends_on: - 'postgres': - condition: service_healthy - 'subquery-node': - condition: service_healthy - restart: always - environment: - DB_USER: postgres - DB_PASS: postgres - DB_DATABASE: postgres - DB_HOST: postgres - DB_PORT: 5432 - command: - - --name=app - - --playground - - --indexer=http://subquery-node:3000 diff --git a/subql/crab/project.yaml b/subql/crab/project.yaml index 68d7943b..740ab416 100644 --- a/subql/crab/project.yaml +++ b/subql/crab/project.yaml @@ -10,7 +10,7 @@ schema: network: genesisHash: '0x34f61bfda344b3fad3c3e38832a91448b3c613b199eb23e5110a635d71c13c65' endpoint: wss://darwinia-crab.api.onfinality.io/public-ws - #dictionary: https://api.subquery.network/sq/itering/crab-dictionary/ + dictionary: https://api.subquery.network/sq/itering/crab-dictionary/ chaintypes: file: ./types.yaml diff --git a/subql/crab/src/handlers/event.ts b/subql/crab/src/handlers/event.ts index 5ff3703e..76efd00f 100644 --- a/subql/crab/src/handlers/event.ts +++ b/subql/crab/src/handlers/event.ts @@ -57,9 +57,9 @@ export class EventHandler { } if (this.method === 'DVMTransfer' && this.section === 'ethereum') { - await this.handleDvmToCrab(); + await this.handleDvmToSubstrate(); } else if (this.method === 'Transfer' && this.section === 'balances') { - await this.handleCrabToDvm(); + await this.handleSubstrateToDvm(); } } @@ -76,48 +76,58 @@ export class EventHandler { } // Dvm -> 15 -> Substrate - private findDvmToCrab(router: string, amount: number) { - const event = this.event?.extrinsic?.events.find((item) => { - if (item.event.method === 'DVMTransfer') { - const [ifrom, ito, iamount] = JSON.parse(item.event.data.toString()); - if (iamount === amount && ito === router) { - return true; - } - } - return false; - }); - return event; - } - - private async handleDvmToCrab() { + private findDvmToSubstrate(router: string) { + const event = this.event?.extrinsic?.events.find((item) => { + if (item.event.method === 'DVMTransfer') { + const [_1, to, amount] = JSON.parse(item.event.data.toString()); + if (amount === amount && to === router) { + return true; + } + } + return false; + }); + return event; + } + + private async handleDvmToSubstrate() { const [from, to, amount] = JSON.parse(this.data); - var sender = AccountHandler.formatAddress(from); - var recipient = AccountHandler.formatAddress(to); + let sender = AccountHandler.formatAddress(from); + const recipient = AccountHandler.formatAddress(to); const senderIsDvm = AccountHandler.isDvmAddress(sender); const recipientIsDvm = AccountHandler.isDvmAddress(recipient); + if (senderIsDvm && !recipientIsDvm) { - const event = this.findDvmToCrab(from, amount); + const event = this.findDvmToSubstrate(from); + if (!event) { return; } - const [ifrom, ito, iamount] = JSON.parse(event.event.data.toString()); - sender = AccountHandler.formatAddress(ifrom); - await this.handleTransfer("crab-dvm", "crab", sender, recipient, amount); + + const [iFrom] = JSON.parse(event.event.data.toString()); + sender = AccountHandler.formatAddress(iFrom); + await this.handleTransfer('crab-dvm', 'crab', sender, recipient, amount); } } - private async handleCrabToDvm() { + private async handleSubstrateToDvm() { const [from, to, amount] = JSON.parse(this.data); - var sender = AccountHandler.formatAddress(from); - var recipient = AccountHandler.formatAddress(to); + const sender = AccountHandler.formatAddress(from); + const recipient = AccountHandler.formatAddress(to); const senderIsDvm = AccountHandler.isDvmAddress(sender); const recipientIsDvm = AccountHandler.isDvmAddress(recipient); + if (!senderIsDvm && recipientIsDvm) { - await this.handleTransfer("crab", "crab-dvm", sender, recipient, amount); + await this.handleTransfer('crab', 'crab-dvm', sender, recipient, amount); } } - private async handleTransfer(fromChain: string, toChain: string, sender: string, recipient: string, amount: number) { + private async handleTransfer( + fromChain: string, + toChain: string, + sender: string, + recipient: string, + amount: number + ) { await AccountHandler.ensureAccount(recipient); await AccountHandler.updateTransferStatistic(recipient); await AccountHandler.ensureAccount(sender); diff --git a/subql/pangolin/package.json b/subql/pangolin/package.json index 1b0af56c..99045a6e 100644 --- a/subql/pangolin/package.json +++ b/subql/pangolin/package.json @@ -20,7 +20,7 @@ "author": "sxlwar", "license": "MIT", "devDependencies": { - "@polkadot/api": "^7", + "@polkadot/api": "^8", "@subql/types": "latest", "typescript": "^4.2.4", "@subql/cli": "latest" diff --git a/subql/pangolin/project.yaml b/subql/pangolin/project.yaml index 519e16e1..68d384c3 100644 --- a/subql/pangolin/project.yaml +++ b/subql/pangolin/project.yaml @@ -32,34 +32,16 @@ dataSources: module: bridgePangoroDispatch method: MessageDispatched - - handler: handleEvent - kind: substrate/EventHandler - filter: - module: balances - method: Transfer # ring: mainnet -> dvm - - - handler: handleEvent - kind: substrate/EventHandler - filter: - module: kton - method: Transfer # kton: mainnet -> dvm - - - handler: handleEvent - kind: substrate/EventHandler - filter: - module: ethereum - method: DVMTransfer # ring: dvm -> mainnet - - handler: handleEvent kind: substrate/EventHandler filter: module: ethereum - method: KtonDVMTransfer # kton dvm -> mainnet + method: DVMTransfer - handler: handleEvent kind: substrate/EventHandler filter: - module: ethereum - method: Executed + module: balances + method: Transfer \ No newline at end of file diff --git a/subql/pangolin/schema.graphql b/subql/pangolin/schema.graphql index 3058a65d..3a56848b 100644 --- a/subql/pangolin/schema.graphql +++ b/subql/pangolin/schema.graphql @@ -29,11 +29,12 @@ type Transfer @entity { sender: Account recipient: Account + fromChain: String + toChain: String amount: BigInt section: String method: String timestamp: Date - mediator: Account block: Block } diff --git a/subql/pangolin/src/handlers/account.ts b/subql/pangolin/src/handlers/account.ts index 7d44fe03..cd0f1dfb 100644 --- a/subql/pangolin/src/handlers/account.ts +++ b/subql/pangolin/src/handlers/account.ts @@ -3,7 +3,7 @@ import { decodeAddress } from '@polkadot/util-crypto'; import { u8aToHex, isHex } from '@polkadot/util'; export class AccountHandler { - static convertToDVMAddress(address: string) { + static formatAddress(address: string) { if (isHex(address)) { return address; } @@ -15,17 +15,8 @@ export class AccountHandler { return u8aToHex(decodeAddress(address)); } - static convertToEthereumFormat(address: string): string | null { - if (!address) { - return ''; - } - - const startAt = 2; - const result = u8aToHex(decodeAddress(address)).slice(startAt); - const PREFIX = '64766d3a00000000000000'; - - // eslint-disable-next-line no-magic-numbers - return result.startsWith(PREFIX) ? '0x' + result.slice(-42, -2) : null; + static isDvmAddress(address: string) { + return address.startsWith("0x64766d3a00000000000000") } static async ensureAccount(id: string) { diff --git a/subql/pangolin/src/handlers/event.ts b/subql/pangolin/src/handlers/event.ts index dd80d673..89c57e75 100644 --- a/subql/pangolin/src/handlers/event.ts +++ b/subql/pangolin/src/handlers/event.ts @@ -3,10 +3,6 @@ import { Block, BridgeDispatchEvent, Transfer } from '../types'; import { AccountHandler } from './account'; export class EventHandler { - private dvmKtonContract = '0x8809f9b3acef1da309f49b5ab97a4c0faa64e6ae'; - private dvmWithdrawAddress = '0x0000000000000000000000000000000000000015'; - private dvmWithdrawSS58Format = '5elrpqut7c3mwtjeo28dtksbya7pgzyrtvbrsfrue9efu7jj'; - private event: SubstrateEvent; constructor(event: SubstrateEvent) { @@ -60,12 +56,10 @@ export class EventHandler { await this.handleBridgeDispatchEvent(); } - if (this.method === 'Transfer' && (this.section === 'balances' || this.section === 'kton')) { - await this.handleMainToSmartTransfer(); - } - - if (this.section === 'ethereum') { - await this.handleSmartToMainTransfer(); + if (this.method === 'DVMTransfer' && this.section === 'ethereum') { + await this.handleDvmToSubstrate(); + } else if (this.method === 'Transfer' && this.section === 'balances') { + await this.handleSubstrateToDvm(); } } @@ -81,10 +75,59 @@ export class EventHandler { await event.save(); } - private async handleTransfer(from: string, to: string, amount: number | string) { - const sender = AccountHandler.convertToDVMAddress(from); - const recipient = AccountHandler.convertToDVMAddress(to); + // Dvm -> 15 -> Substrate + private findDvmToSubstrate(router: string) { + const event = this.event?.extrinsic?.events.find((item) => { + if (item.event.method === 'DVMTransfer') { + const [_1, to, amount] = JSON.parse(item.event.data.toString()); + if (amount === amount && to === router) { + return true; + } + } + return false; + }); + return event; + } + + private async handleDvmToSubstrate() { + const [from, to, amount] = JSON.parse(this.data); + let sender = AccountHandler.formatAddress(from); + const recipient = AccountHandler.formatAddress(to); + const senderIsDvm = AccountHandler.isDvmAddress(sender); + const recipientIsDvm = AccountHandler.isDvmAddress(recipient); + + if (senderIsDvm && !recipientIsDvm) { + const event = this.findDvmToSubstrate(from); + + if (!event) { + return; + } + + const [iFrom] = JSON.parse(event.event.data.toString()); + sender = AccountHandler.formatAddress(iFrom); + await this.handleTransfer('crab-dvm', 'crab', sender, recipient, amount); + } + } + private async handleSubstrateToDvm() { + const [from, to, amount] = JSON.parse(this.data); + const sender = AccountHandler.formatAddress(from); + const recipient = AccountHandler.formatAddress(to); + const senderIsDvm = AccountHandler.isDvmAddress(sender); + const recipientIsDvm = AccountHandler.isDvmAddress(recipient); + + if (!senderIsDvm && recipientIsDvm) { + await this.handleTransfer('crab', 'crab-dvm', sender, recipient, amount); + } + } + + private async handleTransfer( + fromChain: string, + toChain: string, + sender: string, + recipient: string, + amount: number + ) { await AccountHandler.ensureAccount(recipient); await AccountHandler.updateTransferStatistic(recipient); await AccountHandler.ensureAccount(sender); @@ -99,6 +142,8 @@ export class EventHandler { transfer.method = this.method; transfer.amount = BigInt(amount ?? 0); transfer.timestamp = this.timestamp; + transfer.fromChain = fromChain; + transfer.toChain = toChain; transfer.block = this.simpleBlock(); @@ -109,77 +154,6 @@ export class EventHandler { } } - private async handleMainToSmartTransfer() { - const [from, to, amount] = JSON.parse(this.data); - - await this.handleTransfer(from, to, amount); - } - - /** - * ring transfer 1 -> from: eth to - */ - - private async handleSmartToMainTransfer() { - const [from, to, amount] = JSON.parse(this.data) as [string, string, string]; - let formattedFrom = from; - let formattedTo = to; - - if (this.method === 'DVMTransfer') { - if (to.toLowerCase() === this.dvmWithdrawSS58Format) { - formattedFrom = AccountHandler.convertToEthereumFormat(from); - } - - if (from.toLowerCase() === this.dvmWithdrawSS58Format) { - formattedTo = AccountHandler.convertToDVMAddress(to); - } - } - - if (this.method === 'KtonDVMTransfer') { - if (to.toLowerCase() === this.dvmKtonContract) { - formattedFrom = AccountHandler.convertToEthereumFormat(from); - } - - if (from.toLowerCase() === this.dvmKtonContract) { - formattedTo = AccountHandler.convertToDVMAddress(to); - } - } - - const transfer = await Transfer.get(this.extrinsicHash); - - /** - * transfer to wkton contract KtonDVMTransfer(who, WKTON_ADDRESS, U256) - * withdraw from wkton contract KtonDVMTransfer(WKTON_ADDRESS, to, U256) - */ - if (transfer && formattedFrom.toLowerCase() === this.dvmWithdrawAddress) { - await AccountHandler.ensureAccount(formattedTo); - await AccountHandler.updateTransferStatistic(formattedTo); - - transfer.mediatorId = transfer.recipientId; - transfer.recipientId = formattedTo; - - await transfer.save(); - - return; - } - - if (transfer && this.method === 'Executed') { - await AccountHandler.ensureAccount(formattedFrom); - await AccountHandler.updateTransferStatistic(formattedFrom); - - // FIXME: if this event belongs to a cross-chain operation, the mediatorId equals to the senderId - transfer.mediatorId = transfer.senderId; - transfer.senderId = formattedFrom; - - await transfer.save(); - - return; - } - - if (this.method === 'DVMTransfer' || this.method === 'KtonDVMTransfer') { - await this.handleTransfer(formattedFrom, formattedTo, amount); - } - } - private simpleBlock(): Block { return { blockHash: this.blockHash, From 0cc6423702675b73d492028a4357f42091620707 Mon Sep 17 00:00:00 2001 From: sxlwar Date: Tue, 24 May 2022 09:49:11 +0800 Subject: [PATCH 3/3] chore: amount param --- subql/crab/src/handlers/event.ts | 6 +++--- subql/pangolin/src/handlers/event.ts | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/subql/crab/src/handlers/event.ts b/subql/crab/src/handlers/event.ts index 76efd00f..5cbbe02f 100644 --- a/subql/crab/src/handlers/event.ts +++ b/subql/crab/src/handlers/event.ts @@ -76,11 +76,11 @@ export class EventHandler { } // Dvm -> 15 -> Substrate - private findDvmToSubstrate(router: string) { + private findDvmToSubstrate(router: string, count: number) { const event = this.event?.extrinsic?.events.find((item) => { if (item.event.method === 'DVMTransfer') { const [_1, to, amount] = JSON.parse(item.event.data.toString()); - if (amount === amount && to === router) { + if (count === amount && to === router) { return true; } } @@ -97,7 +97,7 @@ export class EventHandler { const recipientIsDvm = AccountHandler.isDvmAddress(recipient); if (senderIsDvm && !recipientIsDvm) { - const event = this.findDvmToSubstrate(from); + const event = this.findDvmToSubstrate(from, amount); if (!event) { return; diff --git a/subql/pangolin/src/handlers/event.ts b/subql/pangolin/src/handlers/event.ts index 89c57e75..abeefed3 100644 --- a/subql/pangolin/src/handlers/event.ts +++ b/subql/pangolin/src/handlers/event.ts @@ -76,11 +76,11 @@ export class EventHandler { } // Dvm -> 15 -> Substrate - private findDvmToSubstrate(router: string) { + private findDvmToSubstrate(router: string, count: number) { const event = this.event?.extrinsic?.events.find((item) => { if (item.event.method === 'DVMTransfer') { const [_1, to, amount] = JSON.parse(item.event.data.toString()); - if (amount === amount && to === router) { + if (count === amount && to === router) { return true; } } @@ -97,7 +97,7 @@ export class EventHandler { const recipientIsDvm = AccountHandler.isDvmAddress(recipient); if (senderIsDvm && !recipientIsDvm) { - const event = this.findDvmToSubstrate(from); + const event = this.findDvmToSubstrate(from, amount); if (!event) { return;