Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: change watch ckb mint status way #69

Merged
merged 10 commits into from May 12, 2021
12 changes: 12 additions & 0 deletions offchain-modules/src/packages/db/ckb.ts
Expand Up @@ -39,6 +39,18 @@ export class CkbDb {
});
}

async getMintRecordsToUpdate(mintHash: string): Promise<CkbMint[]> {
return this.connection.getRepository(CkbMint).find({
where: {
mintHash: mintHash,
status: 'pending',
},
order: {
createdAt: 'DESC',
},
});
}

// update mint status
async updateCkbMint(records: CkbMint[]): Promise<void> {
await this.connection.manager.save(records);
Expand Down
3 changes: 1 addition & 2 deletions offchain-modules/src/packages/db/entity/BtcUnlock.ts
@@ -1,4 +1,4 @@
import { Entity, Column, PrimaryColumn, Index, CreateDateColumn, UpdateDateColumn } from 'typeorm';
import { Entity, Column, PrimaryColumn, CreateDateColumn, UpdateDateColumn } from 'typeorm';
import { dbTxStatus } from '@force-bridge/db/entity/CkbMint';

export type BtcUnlockStatus = dbTxStatus;
Expand All @@ -23,7 +23,6 @@ export class BtcUnlock {
@Column({ nullable: true })
btcTxHash: string;

@Index()
@Column({ default: 'todo' })
status: BtcUnlockStatus;

Expand Down
3 changes: 2 additions & 1 deletion offchain-modules/src/packages/db/entity/CkbMint.ts
@@ -1,4 +1,4 @@
import { Entity, Column, PrimaryColumn, CreateDateColumn, UpdateDateColumn } from 'typeorm';
import { Entity, Column, PrimaryColumn, CreateDateColumn, UpdateDateColumn, Index } from 'typeorm';

export type dbTxStatus = 'todo' | 'pending' | 'success' | 'error';
export type CkbMintStatus = dbTxStatus;
Expand Down Expand Up @@ -30,6 +30,7 @@ export class CkbMint {
@Column({ default: 'todo' })
status: CkbMintStatus;

@Index()
@Column({ nullable: true })
mintHash: string;

Expand Down
1 change: 0 additions & 1 deletion offchain-modules/src/packages/db/entity/EosUnlock.ts
Expand Up @@ -20,7 +20,6 @@ export class EosUnlock {
@Column({ nullable: true })
eosTxHash: string;

@Index()
@Column({ default: 'todo' })
status: EosUnlockStatus;

Expand Down
1 change: 0 additions & 1 deletion offchain-modules/src/packages/db/entity/EthUnlock.ts
Expand Up @@ -20,7 +20,6 @@ export class EthUnlock {
@Column({ nullable: true })
ethTxHash: string;

@Index()
@Column({ default: 'todo' })
status: EthUnlockStatus;

Expand Down
43 changes: 37 additions & 6 deletions offchain-modules/src/packages/handlers/ckb.ts
Expand Up @@ -5,7 +5,7 @@ import { asyncSleep, fromHexString, toHexString, uint8ArrayToString } from '../u
import { Asset, BtcAsset, ChainType, EosAsset, EthAsset, TronAsset } from '../ckb/model/asset';
import { Address, AddressType, Amount, HashType, Script } from '@lay2/pw-core';
import { Account } from '@force-bridge/ckb/model/accounts';
import { CkbTxGenerator } from '@force-bridge/ckb/tx-helper/generator';
import { CkbTxGenerator, MintAssetRecord } from '@force-bridge/ckb/tx-helper/generator';
import { IndexerCollector } from '@force-bridge/ckb/tx-helper/collector';
import { ScriptType } from '@force-bridge/ckb/tx-helper/indexer';
import { ForceBridgeCore } from '@force-bridge/core';
Expand Down Expand Up @@ -92,6 +92,13 @@ export class CkbHandler {
}
const burnTxs = new Map();
for (const tx of block.transactions) {
if (await this.isMintTx(tx)) {
const pendingMintTxs = await this.db.getMintRecordsToUpdate(tx.hash);
pendingMintTxs.map((r) => {
r.status = 'success';
});
await this.db.updateCkbMint(pendingMintTxs);
}
const recipientData = tx.outputsData[0];
let cellData;
try {
Expand Down Expand Up @@ -154,6 +161,32 @@ export class CkbHandler {
}
}

async isMintTx(tx: Transaction): Promise<boolean> {
if (tx.outputs.length < 1 || !tx.outputs[0].type) {
return false;
}
const firstOutputTypeCodeHash = tx.outputs[0].type.codeHash;
const expectSudtTypeCodeHash = ForceBridgeCore.config.ckb.deps.sudtType.script.codeHash;
// verify tx output sudt cell
if (firstOutputTypeCodeHash != expectSudtTypeCodeHash) {
return false;
}
const committeeLockHash = await this.getOwnLockHash();
// verify tx input: committee cell.
const preHash = tx.inputs[0].previousOutput.txHash;
const txPrevious = await this.ckb.rpc.getTransaction(preHash);
if (txPrevious == null) {
return false;
}
const firstInputLock = txPrevious.transaction.outputs[Number(tx.inputs[0].previousOutput.index)].lock;
const firstInputLockHash = this.ckb.utils.scriptToHash(<CKBComponents.Script>firstInputLock);

logger.info(
`CkbHandler isMintTx tx ${tx.hash} sender lock hash is ${firstInputLockHash}. first output type code hash is ${firstOutputTypeCodeHash}.`,
);
return firstInputLockHash === committeeLockHash;
}

async isBurnTx(tx: Transaction, cellData: RecipientCellData): Promise<boolean> {
if (tx.outputs.length < 1) {
return false;
Expand Down Expand Up @@ -259,9 +292,7 @@ export class CkbHandler {
});
} else {
mintRecords.map((r) => {
r.status = 'error';
r.mintHash = mintTxHash;
r.message = `mint execute failed.the tx status is ${txStatus.txStatus.status}`;
});
logger.error(
`CkbHandler handleMintRecords mint execute failed txStatus:${txStatus.txStatus.status}, mintIds:${mintIds}`,
Expand All @@ -281,7 +312,7 @@ export class CkbHandler {
}
}

filterMintRecords(r: CkbMint, ownLockHash: string): any {
filterMintRecords(r: CkbMint, ownLockHash: string): MintAssetRecord {
switch (r.chain) {
case ChainType.BTC:
return {
Expand Down Expand Up @@ -312,7 +343,7 @@ export class CkbHandler {
}
}

async filterNewTokens(records: any[]): Promise<any[]> {
async filterNewTokens(records: MintAssetRecord[]): Promise<MintAssetRecord[]> {
const newTokens = [];
const assets = [];
for (const record of records) {
Expand Down Expand Up @@ -344,7 +375,7 @@ export class CkbHandler {
return newTokens;
}

async createBridgeCell(newTokens: any[], generator: CkbTxGenerator) {
async createBridgeCell(newTokens: MintAssetRecord[], generator: CkbTxGenerator) {
const account = new Account(this.PRI_KEY);
const scripts = newTokens.map((r) => {
return {
Expand Down
2 changes: 1 addition & 1 deletion offchain-modules/src/scripts/integration-test/tron.ts
Expand Up @@ -239,7 +239,7 @@ async function main() {

//await checkEffect(trc20TxHash, 'TVWvkCasxAJUyzPKMQ2Rus1NtmBwrkVyBR', 'trc20');
} catch (e) {
logger.warn(`The tron component integration not pass yet. i:${i} error:${e.toString()}`);
logger.warn(`The tron component integration not pass yet. i:${i} error:`, e);
continue;
}
logger.info('The tron component integration test pass!');
Expand Down