implement isExited
MODIFY
src/inherited/web3_client.ts
src/inherited/web3_client.ts
@@ -98,4 +98,8 @@ export class MaticWeb3Client extends BaseWeb3Client {
encodeParameters(params: any[], types: any[]) {
return this.web3_.eth.abi.encodeParameters(types, params);
}
+
+ etheriumSha3(...value) {
+ return Web3.utils.soliditySha3(...value);
+ }
}
\ No newline at end of file

MODIFY
src/model/web3_client.ts
src/model/web3_client.ts
@@ -35,4 +35,5 @@ export abstract class BaseWeb3Client {
abstract sendRPCRequest(request: IJsonRpcRequestPayload): Promise<IJsonRpcResponse>;
abstract encodeParameters(params: any[], types: any[]): string;
+ abstract etheriumSha3(...value): string;
}

MODIFY
src/pos/erc20.ts
src/pos/erc20.ts
@@ -109,4 +109,20 @@ export class ERC20 extends POSToken {
option
);
}
+
+ /**
+ * check if exit has been completed for a transaction hash
+ *
+ * @param {string} txHash
+ * @returns
+ * @memberof ERC20
+ */
+ isExited(txHash: string) {
+ if (!txHash) {
+ throw new Error(`txHash not provided`);
+ }
+ return this.exitManager.isExitProcessed(
+ txHash, Log_Event_Signature.Erc20Transfer
+ );
+ }
}
\ No newline at end of file

MODIFY
src/pos/exit_manager.ts
src/pos/exit_manager.ts
@@ -164,8 +164,6 @@ export class ExitManager {
const block = await this.maticClient_.getBlockWithTransaction(burnTx.blockNumber);
- LOGGER.log({ 'burnTx.blockNumber': burnTx.blockNumber, lastCheckPointedBlockNumber: lastChildBlock });
-
assert.ok(
new BN(lastChildBlock).gte(new BN(burnTx.blockNumber)),
'Burn transaction has not been checkpointed as yet'
@@ -236,4 +234,42 @@ export class ExitManager {
])
);
}
+
+ async getExitHash(burnTxHash, logEventSig, requestConcurrency?) {
+ const lastChildBlock = await this.rootChainManager.getLastChildBlock();
+ const receipt = await this.maticClient_.getTransactionReceipt(burnTxHash);
+ const block = await this.maticClient_.getBlockWithTransaction(receipt.blockNumber);
+
+ assert.ok(
+ new BN(lastChildBlock).gte(new BN(receipt.blockNumber)),
+ 'Burn transaction has not been checkpointed as yet'
+ );
+
+ const receiptProof: any = await ProofUtil.getReceiptProof(
+ receipt,
+ block,
+ this.maticClient_,
+ requestConcurrency
+ );
+
+ const logIndex = this.getLogIndex_(logEventSig, receipt);
+ const nibbleArr = [];
+ receiptProof.path.forEach(byte => {
+ nibbleArr.push(Buffer.from('0' + (byte / 0x10).toString(16), 'hex'));
+ nibbleArr.push(Buffer.from('0' + (byte % 0x10).toString(16), 'hex'));
+ });
+
+ return this.maticClient_.etheriumSha3(
+ receipt.blockNumber, ethUtils.bufferToHex(Buffer.concat(nibbleArr)), logIndex
+ );
+ }
+
+ isExitProcessed(burnTxHash: string, logSignature: string) {
+ const exitHash = this.getExitHash(
+ burnTxHash, logSignature, this.requestConcurrency
+ );
+ return this.rootChainManager.method(
+ "processedExits", exitHash
+ ).read<boolean>();
+ }
}
\ No newline at end of file

MODIFY
src/pos/root_chain_manager.ts
src/pos/root_chain_manager.ts
@@ -60,4 +60,6 @@ export class RootChainManager extends BaseToken {
}
return ans.mul(CHECKPOINT_INTERVAL);
}
+
+
}
\ No newline at end of file

implement isExited