create root manager
MODIFY
src/interfaces/pos_client_config.ts
src/interfaces/pos_client_config.ts
@@ -14,5 +14,7 @@ export interface IPOSClientConfig {
}
};
rootChainManager?: string;
+ rootChain?: string;
log?: boolean;
+ requestConcurrency?: number;
}
\ No newline at end of file

MODIFY
src/pos/erc20.ts
src/pos/erc20.ts
@@ -150,5 +150,9 @@ export class ERC20 extends POSToken {
);
}
+ isCheckPointed(txHash: string) {
+
+ }
+
}
\ No newline at end of file

MODIFY
src/pos/exit_manager.ts
src/pos/exit_manager.ts
import { BaseWeb3Client } from "../model";
-import { RootChainManager } from "./root_chain_manager";
+import { RootChain } from "./root_chain";
import { formatAmount, ProofUtil } from "../utils";
import assert from "assert";
import BN from "bn.js";
@@ -10,13 +10,13 @@ import { NetworkService } from "../services";
export class ExitManager {
private maticClient_: BaseWeb3Client;
- rootChainManager: RootChainManager;
+ rootChain: RootChain;
requestConcurrency: number;
- constructor(maticClient: BaseWeb3Client, rootChainManager: RootChainManager, requestConcurrency: number) {
+ constructor(maticClient: BaseWeb3Client, rootChainManager: RootChain, requestConcurrency: number) {
this.maticClient_ = maticClient;
- this.rootChainManager = rootChainManager;
+ this.rootChain = rootChainManager;
this.requestConcurrency = requestConcurrency;
}
@@ -26,9 +26,9 @@ export class ExitManager {
logSignature,
this.requestConcurrency
);
- const method = this.rootChainManager.method("exit", payload);
+ const method = this.rootChain.method("exit", payload);
- return this.rootChainManager['processWrite'](
+ return this.rootChain['processWrite'](
method,
option
);
@@ -39,9 +39,9 @@ export class ExitManager {
burnTxHash,
logSignature,
);
- const method = this.rootChainManager.method("exit", payload);
+ const method = this.rootChain.method("exit", payload);
- return this.rootChainManager['processWrite'](
+ return this.rootChain['processWrite'](
method,
option
);
@@ -59,7 +59,7 @@ export class ExitManager {
async buildPayloadForFastExit(burnTxHash, logEventSig) {
// check checkpoint
- const lastChildBlock = await this.rootChainManager.getLastChildBlock();
+ const lastChildBlock = await this.rootChain.getLastChildBlock();
const receipt = await this.maticClient_.getTransactionReceipt(burnTxHash);
const block: any = await this.maticClient_.getBlock(receipt.blockNumber);
@@ -70,7 +70,7 @@ export class ExitManager {
let headerBlock;
const service = new NetworkService(
- this.rootChainManager['client'].metaNetwork.Matic.NetworkAPI
+ this.rootChain['client'].metaNetwork.Matic.NetworkAPI
);
try {
headerBlock = await service.getBlockIncluded(receipt.blockNumber as any);
@@ -78,8 +78,8 @@ export class ExitManager {
throw Error('Network API Error');
}
} catch (err) {
- const rootBlockNumber = await this.rootChainManager.findRootBlockFromChild(receipt.blockNumber);
- headerBlock = await this.rootChainManager.method(
+ const rootBlockNumber = await this.rootChain.findRootBlockFromChild(receipt.blockNumber);
+ headerBlock = await this.rootChain.method(
"headerBlocks", formatAmount(rootBlockNumber)
).read<{ start: string, end: string }>();
}
@@ -156,7 +156,7 @@ export class ExitManager {
async buildPayloadForExit(burnTxHash: string, logEventSig: string, requestConcurrency?) {
// check checkpoint
const [lastChildBlock, burnTx, receipt] = await Promise.all([
- this.rootChainManager.getLastChildBlock(),
+ this.rootChain.getLastChildBlock(),
this.maticClient_.getTransaction(burnTxHash),
this.maticClient_.getTransactionReceipt(burnTxHash)
]);
@@ -167,9 +167,9 @@ export class ExitManager {
new BN(lastChildBlock).gte(new BN(burnTx.blockNumber)),
'Burn transaction has not been checkpointed as yet'
);
- const rootBlockNumber = await this.rootChainManager.findRootBlockFromChild(burnTx.blockNumber);
+ const rootBlockNumber = await this.rootChain.findRootBlockFromChild(burnTx.blockNumber);
- const rootBlockInfo = await this.rootChainManager.method(
+ const rootBlockInfo = await this.rootChain.method(
"headerBlocks", formatAmount(rootBlockNumber)
).read<{ start: string, end: string }>();
@@ -235,7 +235,7 @@ export class ExitManager {
}
async getExitHash(burnTxHash, logEventSig, requestConcurrency?) {
- const lastChildBlock = await this.rootChainManager.getLastChildBlock();
+ const lastChildBlock = await this.rootChain.getLastChildBlock();
const receipt = await this.maticClient_.getTransactionReceipt(burnTxHash);
const block = await this.maticClient_.getBlockWithTransaction(receipt.blockNumber);
@@ -267,7 +267,7 @@ export class ExitManager {
const exitHash = this.getExitHash(
burnTxHash, logSignature, this.requestConcurrency
);
- return this.rootChainManager.method(
+ return this.rootChain.method(
"processedExits", exitHash
).read<boolean>();
}

MODIFY
src/pos/index.ts
src/pos/index.ts
@@ -4,10 +4,12 @@ import { Web3SideChainClient } from "../model";
import { IPOSClientConfig } from "../interfaces";
import { LOGGER } from "../constant";
import { ExitManager } from "./exit_manager";
+import { RootChain } from "./root_chain";
export class POSClient {
rootChainManager: RootChainManager;
+ rootChain: RootChain;
private client_: Web3SideChainClient;
exitManager: ExitManager;
@@ -17,11 +19,12 @@ export class POSClient {
this.client_ = new Web3SideChainClient(config);
- const mainContracts = this.client_.mainPOSContracts;
+ const mainPOSContracts = this.client_.mainPOSContracts;
config = Object.assign(
{
- rootChainManager: mainContracts.RootChainManagerProxy
+ rootChainManager: mainPOSContracts.RootChainManagerProxy,
+ rootChain: this.client_.mainPlasmaContracts.RootChainProxy
} as IPOSClientConfig,
config
);
@@ -31,10 +34,15 @@ export class POSClient {
config.rootChainManager,
);
+ this.rootChain = new RootChain(
+ this.client_,
+ config.rootChain,
+ );
+
this.exitManager = new ExitManager(
this.client_.child.client,
- this.rootChainManager,
- null
+ this.rootChain,
+ config.requestConcurrency
);
LOGGER.enableLog(config.log);

ADD
src/pos/root_chain.ts
+import { BaseContract, BaseWeb3Client, BaseToken, Web3SideChainClient } from "../model";
+import { TYPE_AMOUNT } from "../types";
+import BN from "bn.js";
+import { BIG_ONE, CHECKPOINT_INTERVAL, BIG_TWO, LOGGER } from "../constant";
+import { ITransactionOption } from "../interfaces";
+
+export class RootChain extends BaseToken {
+
+ constructor(client_: Web3SideChainClient, address: string) {
+ super({
+ tokenAddress: address,
+ abi: client_.getABI('RootChain'),
+ isParent: true
+ }, client_);
+ }
+
+ method(methodName: string, ...args) {
+ return this.contract.method(methodName, ...args);
+ }
+
+ getLastChildBlock() {
+ return this.method("getLastChildBlock").read<string>();
+ }
+
+ async findRootBlockFromChild(childBlockNumber: TYPE_AMOUNT): Promise<BN> {
+ childBlockNumber = new BN(childBlockNumber);
+ // first checkpoint id = start * 10000
+ let start = BIG_ONE;
+
+ // last checkpoint id = end * 10000
+ const currentHeaderBlock = await this.method("currentHeaderBlock").read<string>();
+ let end = new BN(currentHeaderBlock).div(
+ CHECKPOINT_INTERVAL
+ );
+
+ // binary search on all the checkpoints to find the checkpoint that contains the childBlockNumber
+ let ans;
+ while (start.lte(end)) {
+ if (start.eq(end)) {
+ ans = start;
+ break;
+ }
+ const mid = start.add(end).div(BIG_TWO);
+
+ const headerBlock = await this.method("headerBlocks", mid.mul(CHECKPOINT_INTERVAL).toString()).read<{ start: number, end: number }>();
+
+ const headerStart = new BN(headerBlock.start);
+ const headerEnd = new BN(headerBlock.end);
+
+ if (headerStart.lte(childBlockNumber) && childBlockNumber.lte(headerEnd)) {
+ // if childBlockNumber is between the upper and lower bounds of the headerBlock, we found our answer
+ ans = mid;
+ break;
+ } else if (headerStart.gt(childBlockNumber)) {
+ // childBlockNumber was checkpointed before this header
+ end = mid.sub(BIG_ONE);
+ } else if (headerEnd.lt(childBlockNumber)) {
+ // childBlockNumber was checkpointed after this header
+ start = mid.add(BIG_ONE);
+ }
+ }
+ return ans.mul(CHECKPOINT_INTERVAL);
+ }
+
+ deposit(userAddress: string, tokenAddress: string, depositData: string, option?: ITransactionOption) {
+ const method = this.method(
+ "depositFor",
+ userAddress,
+ tokenAddress,
+ depositData
+ );
+
+ return this.processWrite(method, option);
+ }
+
+}
\ No newline at end of file

MODIFY
src/pos/root_chain_manager.ts
src/pos/root_chain_manager.ts
@@ -19,50 +19,6 @@ export class RootChainManager extends BaseToken {
return this.contract.method(methodName, ...args);
}
- getLastChildBlock() {
- return this.method("getLastChildBlock").read<string>();
- }
-
- async findRootBlockFromChild(childBlockNumber: TYPE_AMOUNT): Promise<BN> {
- childBlockNumber = new BN(childBlockNumber);
- // first checkpoint id = start * 10000
- let start = BIG_ONE;
-
- // last checkpoint id = end * 10000
- const currentHeaderBlock = await this.method("currentHeaderBlock").read<string>();
- let end = new BN(currentHeaderBlock).div(
- CHECKPOINT_INTERVAL
- );
-
- // binary search on all the checkpoints to find the checkpoint that contains the childBlockNumber
- let ans;
- while (start.lte(end)) {
- if (start.eq(end)) {
- ans = start;
- break;
- }
- const mid = start.add(end).div(BIG_TWO);
-
- const headerBlock = await this.method("headerBlocks", mid.mul(CHECKPOINT_INTERVAL).toString()).read<{ start: number, end: number }>();
-
- const headerStart = new BN(headerBlock.start);
- const headerEnd = new BN(headerBlock.end);
-
- if (headerStart.lte(childBlockNumber) && childBlockNumber.lte(headerEnd)) {
- // if childBlockNumber is between the upper and lower bounds of the headerBlock, we found our answer
- ans = mid;
- break;
- } else if (headerStart.gt(childBlockNumber)) {
- // childBlockNumber was checkpointed before this header
- end = mid.sub(BIG_ONE);
- } else if (headerEnd.lt(childBlockNumber)) {
- // childBlockNumber was checkpointed after this header
- start = mid.add(BIG_ONE);
- }
- }
- return ans.mul(CHECKPOINT_INTERVAL);
- }
-
deposit(userAddress: string, tokenAddress: string, depositData: string, option?: ITransactionOption) {
const method = this.method(
"depositFor",

MODIFY
test/debug.js
test/debug.js
@@ -47,17 +47,21 @@ const execute = async () => {
}
});
- // const childErc20 = maticPOS.erc20(erc20POSTokenMumbai);
+ const childErc20 = maticPOS.erc20(erc20POSTokenMumbai);
// const balance = await childErc20.getBalance(from);
// console.log('balance', balance);
- const parentErc20 = maticPOS.erc20(erc20POSTokenGoerli, true);
+ // const parentErc20 = maticPOS.erc20(erc20POSTokenGoerli, true);
// const balance = await parentErc20.getBalance(from);
// console.log('balance', balance);
- const approveResult = await parentErc20.deposit('1000000000000000', from);
+ // const approveResult = await parentErc20.deposit('1000000000000000', from);
+ // console.log('txHash', await approveResult.getTransactionHash());
+ // console.log('receipt', await approveResult.getReceipt());
+
+ const approveResult = await childErc20.withdrawExit('0xe078925f8bbe43f99bb325cef6e895946f4086fbc05cf4686766b0a172fae396');
console.log('txHash', await approveResult.getTransactionHash());
console.log('receipt', await approveResult.getReceipt());

create root manager