Skip to content

Commit

Permalink
fix(bridge-ui): fix proof (#13748)
Browse files Browse the repository at this point in the history
Co-authored-by: jeff <113397187+cyberhorsey@users.noreply.github.com>
  • Loading branch information
jscriptcoder and cyberhorsey committed May 12, 2023
1 parent e3746ee commit 497d7ab
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 129 deletions.
20 changes: 0 additions & 20 deletions packages/bridge-ui/src/domain/block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,3 @@ export type Block = {
mixHash: string;
withdrawalsRoot?: string;
};

export type BlockHeader = {
parentHash: string;
ommersHash: string;
beneficiary: string;
stateRoot: string;
transactionsRoot: string;
receiptsRoot: string;
logsBloom: string[];
difficulty: number;
height: number;
gasLimit: number;
gasUsed: number;
timestamp: number;
extraData: string;
mixHash: string;
nonce: number;
baseFeePerGas: number;
withdrawalsRoot: string;
};
65 changes: 2 additions & 63 deletions packages/bridge-ui/src/proof/ProofService.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ const mockContract = {
};

jest.mock('ethers', () => ({
/* eslint-disable-next-line */
...(jest.requireActual('ethers') as object),
...jest.requireActual('ethers'),
Contract: function () {
return mockContract;
},
Expand Down Expand Up @@ -105,9 +104,7 @@ const invalidStorageProof2: EthGetProofResponse = {
};

const expectedProof =
'0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000380a7881266ca0a344c43cb24175d9dbd243b58d45d6ae6ad71310a273a3d1d3afb1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347000000000000000000000000ea674fdde714fd979de3edf0f56aa9716b898ec8c0dcf937b3f6136dd70a1ad11cc57b040fd410f3c49a5146f20c732895a3cc217273ade6b6ed865a9975ac281da23b90b141a8b607d874d2cd95e65e81336f8e74bb61e381e9238a08b169580f3cbf9b8b79d7d5ee708d3e286103eb291dfd0800000000000400000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000020000000000000000000000000000000000000000000000000100000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000007b0000000000000000000000000000000000000000000000000000000000000300f5ba25df1e92e89a09e0b32063b81795f631100801158f5fa733f2ba26843bd0000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001265746865726d696e652d75732d776573743100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022e1a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000';
const expectedProofWithBaseFee =
'0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000380a7881266ca0a344c43cb24175d9dbd243b58d45d6ae6ad71310a273a3d1d3afb1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347000000000000000000000000ea674fdde714fd979de3edf0f56aa9716b898ec8c0dcf937b3f6136dd70a1ad11cc57b040fd410f3c49a5146f20c732895a3cc217273ade6b6ed865a9975ac281da23b90b141a8b607d874d2cd95e65e81336f8e74bb61e381e9238a08b169580f3cbf9b8b79d7d5ee708d3e286103eb291dfd0800000000000400000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000020000000000000000000000000000000000000000000000000100000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000007b0000000000000000000000000000000000000000000000000000000000000300f5ba25df1e92e89a09e0b32063b81795f631100801158f5fa733f2ba26843bd0000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001265746865726d696e652d75732d776573743100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022e1a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000';
'0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000022e1a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000';
const srcChain = 167001;
const destChain = 31336;

Expand Down Expand Up @@ -176,35 +173,6 @@ describe('prover tests', () => {
});
expect(proof).toBe(expectedProof);
});

it('generates proof with baseFeePerGas set', async () => {
mockProvider.send.mockImplementation(
(method: string, params: unknown[]) => {
if (method === 'eth_getBlockByHash') {
return block;
}

if (method === 'eth_getProof') {
return storageProof;
}
},
);

block.baseFeePerGas = '1';

const prover: ProofService = new ProofService(map);

const proof = await prover.generateProof({
msgHash: ethers.constants.HashZero,
sender: ethers.constants.AddressZero,
srcBridgeAddress: ethers.constants.AddressZero,
srcChain: srcChain,
destChain: destChain,
destCrossChainSyncAddress: ethers.constants.AddressZero,
srcSignalServiceAddress: ethers.constants.AddressZero,
});
expect(proof).toBe(expectedProofWithBaseFee);
});
});

describe('generate release proof tests', () => {
Expand Down Expand Up @@ -267,33 +235,4 @@ describe('generate release proof tests', () => {
});
expect(proof).toBe(expectedProof);
});

it('generates proof with baseFeePerGas set', async () => {
mockProvider.send.mockImplementation(
(method: string, params: unknown[]) => {
if (method === 'eth_getBlockByHash') {
return block;
}

if (method === 'eth_getProof') {
return storageProof2;
}
},
);

block.baseFeePerGas = '1';

const prover: ProofService = new ProofService(map);

const proof = await prover.generateReleaseProof({
msgHash: ethers.constants.HashZero,
sender: ethers.constants.AddressZero,
destBridgeAddress: ethers.constants.AddressZero,
srcChain: srcChain,
destChain: destChain,
destCrossChainSyncAddress: ethers.constants.AddressZero,
srcCrossChainSyncAddress: ethers.constants.AddressZero,
});
expect(proof).toBe(expectedProofWithBaseFee);
});
});
68 changes: 22 additions & 46 deletions packages/bridge-ui/src/proof/ProofService.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Contract, ethers } from 'ethers';
import { RLP } from 'ethers/lib/utils.js';
import { crossChainSyncABI } from '../constants/abi';
import type { Block, BlockHeader } from '../domain/block';
import type { Block } from '../domain/block';
import type {
Prover,
GenerateProofOpts,
Expand Down Expand Up @@ -32,55 +32,35 @@ export class ProofService implements Prover {
return key;
}

private static async getBlockAndBlockHeader(
private static async getBlock(
contract: ethers.Contract,
provider: ethers.providers.StaticJsonRpcProvider,
): Promise<{ block: Block; blockHeader: BlockHeader }> {
const latestSyncedHeader = await contract.getCrossChainBlockHash(0);
): Promise<Block> {
const latestBlockHash = await contract.getCrossChainBlockHash(0);

const block: Block = await provider.send('eth_getBlockByHash', [
latestSyncedHeader,
latestBlockHash,
false,
]);

const logsBloom = block.logsBloom.toString().substring(2);

const blockHeader: BlockHeader = {
parentHash: block.parentHash,
ommersHash: block.sha3Uncles,
beneficiary: block.miner,
stateRoot: block.stateRoot,
transactionsRoot: block.transactionsRoot,
receiptsRoot: block.receiptsRoot,
logsBloom: logsBloom.match(/.{1,64}/g)!.map((s: string) => '0x' + s),
difficulty: block.difficulty,
height: block.number,
gasLimit: block.gasLimit,
gasUsed: block.gasUsed,
timestamp: block.timestamp,
extraData: block.extraData,
mixHash: block.mixHash,
nonce: block.nonce,
baseFeePerGas: block.baseFeePerGas ? parseInt(block.baseFeePerGas) : 0,
withdrawalsRoot: block.withdrawalsRoot ?? ethers.constants.HashZero,
};

return { block, blockHeader };
return block;
}

private static getSignalProof(
proof: EthGetProofResponse,
blockHeader: BlockHeader,
blockHeight: number,
) {
// RLP encode the proof together for LibTrieProof to decode
const encodedProof = RLP.encode(proof.storageProof[0].proof);

// encode the SignalProof struct from LibBridgeSignal
// Encode the SignalProof struct:
// struct SignalProof {
// uint256 height;
// bytes proof;
// }
const signalProof = ethers.utils.defaultAbiCoder.encode(
[
'tuple(tuple(bytes32 parentHash, bytes32 ommersHash, address beneficiary, bytes32 stateRoot, bytes32 transactionsRoot, bytes32 receiptsRoot, bytes32[8] logsBloom, uint256 difficulty, uint128 height, uint64 gasLimit, uint64 gasUsed, uint64 timestamp, bytes extraData, bytes32 mixHash, uint64 nonce, uint256 baseFeePerGas, bytes32 withdrawalsRoot) header, bytes proof)',
],
[{ header: blockHeader, proof: encodedProof }],
['tuple(uint256 height, bytes proof)'],
[{ height: blockHeight, proof: encodedProof }],
);

return signalProof;
Expand All @@ -97,10 +77,7 @@ export class ProofService implements Prover {
this.providers[opts.destChain],
);

const { block, blockHeader } = await ProofService.getBlockAndBlockHeader(
contract,
provider,
);
const block = await ProofService.getBlock(contract, provider);

// rpc call to get the merkle proof what value is at key on the SignalService contract
const proof: EthGetProofResponse = await provider.send('eth_getProof', [
Expand All @@ -113,8 +90,9 @@ export class ProofService implements Prover {
throw Error('invalid proof');
}

const p = ProofService.getSignalProof(proof, blockHeader);
return p;
const signalProof = ProofService.getSignalProof(proof, block.number);

return signalProof;
}

async generateReleaseProof(opts: GenerateReleaseProofOpts): Promise<string> {
Expand All @@ -128,10 +106,7 @@ export class ProofService implements Prover {
this.providers[opts.srcChain],
);

const { block, blockHeader } = await ProofService.getBlockAndBlockHeader(
contract,
provider,
);
const block = await ProofService.getBlock(contract, provider);

// rpc call to get the merkle proof what value is at key on the SignalService contract
const proof: EthGetProofResponse = await provider.send('eth_getProof', [
Expand All @@ -144,7 +119,8 @@ export class ProofService implements Prover {
throw Error('invalid proof');
}

const p = ProofService.getSignalProof(proof, blockHeader);
return p;
const signalProof = ProofService.getSignalProof(proof, block.number);

return signalProof;
}
}

0 comments on commit 497d7ab

Please sign in to comment.