merge fastproof and normal proof
MODIFY
src/pos/erc20.ts
src/pos/erc20.ts
@@ -112,6 +112,7 @@ export class ERC20 extends POSToken {
return this.exitManager.buildPayloadForExit(
burnTransactionHash,
Log_Event_Signature.Erc20Transfer,
+ false
).then(payload => {
return this.rootChainManager.exit(
payload, option
@@ -130,11 +131,15 @@ export class ERC20 extends POSToken {
* @memberof ERC20
*/
withdrawExitFaster(burnTransactionHash: string, option?: ITransactionOption) {
- return this.exitManager.exitFast(
+ return this.exitManager.buildPayloadForExit(
burnTransactionHash,
Log_Event_Signature.Erc20Transfer,
- option
+ true
+ ).then(payload => {
+ return this.rootChainManager.exit(
+ payload, option
);
+ });
}
/**

MODIFY
src/pos/exit_manager.ts
src/pos/exit_manager.ts
@@ -12,6 +12,12 @@ interface IChainBlockInfo {
txBlockNumber: number;
}
+interface IRootBlockInfo {
+ start: string;
+ end: string;
+ blockNumber: BN;
+}
+
export class ExitManager {
private maticClient_: BaseWeb3Client;
@@ -25,95 +31,6 @@ export class ExitManager {
this.requestConcurrency = requestConcurrency;
}
- async exitFast(burnTxHash: string, logSignature: string, option: ITransactionOption) {
- const payload = await this.buildPayloadForFastExit(
- burnTxHash,
- logSignature,
- );
- const method = this.rootChain.method("exit", payload);
-
- return this.rootChain['processWrite'](
- method,
- option
- );
- }
-
- private buildPayloadForExitFastMerkle_(start, end, blockNumber) {
- // build block proof
- return ProofUtil.buildBlockProof(
- this.maticClient_,
- parseInt(start, 10),
- parseInt(end, 10),
- parseInt(blockNumber + '', 10)
- );
- }
-
- async buildPayloadForFastExit(burnTxHash, logEventSig) {
- // check checkpoint
- const lastChildBlock = await this.rootChain.getLastChildBlock();
- const receipt = await this.maticClient_.getTransactionReceipt(burnTxHash);
- const block: any = await this.maticClient_.getBlock(receipt.blockNumber);
-
- assert.ok(
- new BN(lastChildBlock).gte(new BN(receipt.blockNumber)),
- 'Burn transaction has not been checkpointed as yet'
- );
-
- let headerBlock;
- const service = new NetworkService(
- this.rootChain['client'].metaNetwork.Matic.NetworkAPI
- );
- try {
- headerBlock = await service.getBlockIncluded(receipt.blockNumber as any);
- if (!headerBlock || !headerBlock.start || !headerBlock.end || !headerBlock.headerBlockNumber) {
- throw Error('Network API Error');
- }
- } catch (err) {
- const rootBlockNumber = await this.rootChain.findRootBlockFromChild(receipt.blockNumber);
- headerBlock = await this.rootChain.method(
- "headerBlocks", formatAmount(rootBlockNumber)
- ).read<{ start: string, end: string }>();
- }
-
- // build block proof
-
- const start = parseInt(headerBlock.start, 10);
- const end = parseInt(headerBlock.end, 10);
- const receiptBlockNumber = parseInt(receipt.blockNumber + '', 10);
- let blockProof;
-
- try {
- blockProof = await service.getProof(
- start, end, receiptBlockNumber
- );
- if (!blockProof) {
- throw Error('Network API Error');
- }
- } catch (err) {
- blockProof = await this.buildPayloadForExitFastMerkle_(start, end, receiptBlockNumber);
- }
-
- const receiptProof: any = await ProofUtil.getReceiptProof(
- receipt, block, this.maticClient_
- );
- const logIndex = this.getLogIndex_(
- logEventSig, receipt
- );
-
- return this._encodePayload(
- headerBlock.headerBlockNumber,
- blockProof,
- receipt.blockNumber,
- block.timestamp,
- Buffer.from(block.transactionsRoot.slice(2), 'hex'),
- Buffer.from(block.receiptsRoot.slice(2), 'hex'),
- ProofUtil.getReceiptBytes(receipt), // rlp encoded
- receiptProof.parentNodes,
- receiptProof.path,
- logIndex
- );
- }
-
private getLogIndex_(logEventSig: string, receipt: ITransactionReceipt) {
let logIndex = -1;
@@ -171,7 +88,62 @@ export class ExitManager {
});
}
- async buildPayloadForExit(burnTxHash: string, logEventSig: string) {
+ private async getRootBlockInfo(txBlockNumber: number) {
+ // find in which block child was included in parent
+ const rootBlockNumber = await this.rootChain.findRootBlockFromChild(
+ txBlockNumber
+ );
+
+ const rootBlockInfo = await this.rootChain.method(
+ "headerBlocks", formatAmount(rootBlockNumber)
+ ).read<IRootBlockInfo>();
+ rootBlockInfo.blockNumber = rootBlockNumber;
+ return rootBlockInfo;
+ }
+
+ private async getRootBlockInfoFromAPI(txBlockNumber: number) {
+ const service = new NetworkService(
+ this.rootChain['client'].metaNetwork.Matic.NetworkAPI
+ );
+ try {
+ const headerBlock = await service.getBlockIncluded(txBlockNumber);
+ if (!headerBlock || !headerBlock.start || !headerBlock.end || !headerBlock.headerBlockNumber) {
+ throw Error('Network API Error');
+ }
+ return headerBlock;
+ } catch (err) {
+ return this.getRootBlockInfo(txBlockNumber);
+ }
+ }
+
+ private async getBlockProof(txBlockNumber: number, rootBlockInfo: { start, end }) {
+ return ProofUtil.buildBlockProof(
+ this.maticClient_,
+ parseInt(rootBlockInfo.start, 10),
+ parseInt(rootBlockInfo.end, 10),
+ parseInt(txBlockNumber + '', 10)
+ );
+ }
+
+ private async getBlockProofFromAPI(txBlockNumber: number, rootBlockInfo: { start, end }) {
+ const service = new NetworkService(
+ this.rootChain['client'].metaNetwork.Matic.NetworkAPI
+ );
+ try {
+ const blockProof = await service.getProof(
+ rootBlockInfo.start, rootBlockInfo.end,
+ txBlockNumber
+ );
+ if (!blockProof) {
+ throw Error('Network API Error');
+ }
+ return blockProof;
+ } catch (err) {
+ return this.getBlockProof(txBlockNumber, rootBlockInfo);
+ }
+ }
+
+ async buildPayloadForExit(burnTxHash: string, logEventSig: string, isFast: boolean) {
const blockInfo = await this.getChainBlockInfo(
burnTxHash
@@ -183,31 +155,22 @@ export class ExitManager {
);
}
- const { lastChildBlock, txBlockNumber } = blockInfo;
+ const { txBlockNumber } = blockInfo;
- // check checkpoint
const [receipt, block] = await Promise.all([
this.maticClient_.getTransactionReceipt(burnTxHash),
this.maticClient_.getBlockWithTransaction(txBlockNumber)
]);
- assert.ok(
- new BN(lastChildBlock).gte(new BN(txBlockNumber)),
- 'Burn transaction has not been checkpointed as yet'
+ const rootBlockInfo = await (
+ isFast ? this.getRootBlockInfoFromAPI(txBlockNumber) :
+ this.getRootBlockInfo(txBlockNumber)
);
- const rootBlockNumber = await this.rootChain.findRootBlockFromChild(txBlockNumber);
-
- const rootBlockInfo = await this.rootChain.method(
- "headerBlocks", formatAmount(rootBlockNumber)
- ).read<{ start: string, end: string }>();
-
// build block proof
- const blockProof = await ProofUtil.buildBlockProof(
- this.maticClient_,
- parseInt(rootBlockInfo.start, 10),
- parseInt(rootBlockInfo.end, 10),
- parseInt(txBlockNumber + '', 10)
+ const blockProof = await (
+ isFast ? this.getBlockProofFromAPI(txBlockNumber, rootBlockInfo) :
+ this.getBlockProof(txBlockNumber, rootBlockInfo)
);
const receiptProof: any = await ProofUtil.getReceiptProof(
@@ -222,7 +185,7 @@ export class ExitManager {
);
return this._encodePayload(
- rootBlockNumber,
+ rootBlockInfo.blockNumber,
blockProof,
txBlockNumber,
block.timestamp,

MODIFY
src/services/index.ts
src/services/index.ts
import { HttpRequest } from "../utils";
+import BN from "bn.js";
export class NetworkService {
httpRequest: HttpRequest;
@@ -7,13 +8,17 @@ export class NetworkService {
this.httpRequest = new HttpRequest(baseUrl);
}
- getBlockIncluded(blockNumber: string) {
+ getBlockIncluded(blockNumber: number) {
const url = `block-included/${blockNumber}`;
return this.httpRequest.get<{
start: string;
end: string;
headerBlockNumber: string;
- }>(url);
+ blockNumber: BN
+ }>(url).then(result => {
+ result['blockNumber'] = result.headerBlockNumber as any;
+ return result;
+ });
}
getProof(start, end, blockNumber) {

MODIFY
test/debug.js
test/debug.js
@@ -65,7 +65,7 @@ const execute = async () => {
'0xbb7670ba7bf40f0f2909b544e78bbf9dca8b666e28f74ffdf9beda6726e164bd',
'0xa712bfe19bc53825da425f50276a84f72f85c9f660c28c88f3a4d7a2b03a3415',
]
- const exitHash = exitHashes[0];
+ const exitHash = exitHashes[1];
// const isCheckPointed = await maticPOS.isCheckPointed(exitHash);
// const isCheckPointed = await parentErc20.isCheckPointed(exitHash);
// return console.log("isCheckPointed", isCheckPointed);

merge fastproof and normal proof