Remove caching of checkpoints from the Inbox (#523)
parent
099cd93cec
commit
81b66b58aa
@ -1,6 +1,6 @@ |
|||||||
// SPDX-License-Identifier: MIT OR Apache-2.0 |
// SPDX-License-Identifier: MIT OR Apache-2.0 |
||||||
pragma solidity >=0.8.0; |
pragma solidity >=0.8.0; |
||||||
|
|
||||||
contract BadRecipientHandle { |
contract BadRecipient2 { |
||||||
function handle(uint32, bytes32) external pure {} // solhint-disable-line no-empty-blocks |
function handle(uint32, bytes32) external pure {} // solhint-disable-line no-empty-blocks |
||||||
} |
} |
@ -1,69 +0,0 @@ |
|||||||
import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; |
|
||||||
import { expect } from 'chai'; |
|
||||||
import { ethers } from 'hardhat'; |
|
||||||
|
|
||||||
import { TestMailbox, TestMailbox__factory } from '../types'; |
|
||||||
|
|
||||||
const localDomain = 1000; |
|
||||||
const ONLY_OWNER_REVERT_MSG = 'Ownable: caller is not the owner'; |
|
||||||
|
|
||||||
describe('Mailbox', async () => { |
|
||||||
let owner: SignerWithAddress, |
|
||||||
nonowner: SignerWithAddress, |
|
||||||
mailbox: TestMailbox; |
|
||||||
|
|
||||||
before(async () => { |
|
||||||
[owner, nonowner] = await ethers.getSigners(); |
|
||||||
}); |
|
||||||
|
|
||||||
beforeEach(async () => { |
|
||||||
const mailboxFactory = new TestMailbox__factory(owner); |
|
||||||
mailbox = await mailboxFactory.deploy(localDomain); |
|
||||||
// The ValidatorManager is unused in these tests *but* needs to be a
|
|
||||||
// contract.
|
|
||||||
await mailbox.initialize(mailbox.address); |
|
||||||
expect(await mailbox.validatorManager()).to.equal(mailbox.address); |
|
||||||
}); |
|
||||||
|
|
||||||
it('Cannot be initialized twice', async () => { |
|
||||||
await expect(mailbox.initialize(mailbox.address)).to.be.revertedWith( |
|
||||||
'Initializable: contract is already initialized', |
|
||||||
); |
|
||||||
}); |
|
||||||
|
|
||||||
it('Allows owner to update the ValidatorManager', async () => { |
|
||||||
const mailboxFactory = new TestMailbox__factory(owner); |
|
||||||
const newValidatorManager = await mailboxFactory.deploy(localDomain); |
|
||||||
await mailbox.setValidatorManager(newValidatorManager.address); |
|
||||||
expect(await mailbox.validatorManager()).to.equal( |
|
||||||
newValidatorManager.address, |
|
||||||
); |
|
||||||
}); |
|
||||||
|
|
||||||
it('Does not allow nonowner to update the ValidatorManager', async () => { |
|
||||||
await expect( |
|
||||||
mailbox.connect(nonowner).setValidatorManager(mailbox.address), |
|
||||||
).to.be.revertedWith(ONLY_OWNER_REVERT_MSG); |
|
||||||
}); |
|
||||||
|
|
||||||
it('Caches a checkpoint', async () => { |
|
||||||
const root = |
|
||||||
'0x9c7a007113f829cfd019a91e4ca5e7f6760589fd6bc7925c877f6971ffee1647'; |
|
||||||
const index = 1; |
|
||||||
await mailbox.cacheCheckpoint(root, index); |
|
||||||
expect(await mailbox.latestCachedRoot()).to.equal(root); |
|
||||||
expect(await mailbox.cachedCheckpoints(root)).to.equal(index); |
|
||||||
const [actualRoot, actualIndex] = await mailbox.latestCachedCheckpoint(); |
|
||||||
expect(actualRoot).to.equal(root); |
|
||||||
expect(actualIndex).to.equal(index); |
|
||||||
}); |
|
||||||
|
|
||||||
it('Reverts when caching a checkpoint with index zero', async () => { |
|
||||||
const root = |
|
||||||
'0x9c7a007113f829cfd019a91e4ca5e7f6760589fd6bc7925c877f6971ffee1647'; |
|
||||||
const index = 0; |
|
||||||
await expect(mailbox.cacheCheckpoint(root, index)).to.be.revertedWith( |
|
||||||
'!index', |
|
||||||
); |
|
||||||
}); |
|
||||||
}); |
|
@ -0,0 +1,56 @@ |
|||||||
|
import { expect } from 'chai'; |
||||||
|
import { BigNumber, ethers } from 'ethers'; |
||||||
|
|
||||||
|
import { utils } from '@abacus-network/utils'; |
||||||
|
|
||||||
|
import { TestOutbox } from '../../types'; |
||||||
|
import { DispatchEvent } from '../../types/contracts/Outbox'; |
||||||
|
|
||||||
|
export const dispatchMessage = async ( |
||||||
|
outbox: TestOutbox, |
||||||
|
destination: number, |
||||||
|
recipient: string, |
||||||
|
messageStr: string, |
||||||
|
) => { |
||||||
|
const tx = await outbox.dispatch( |
||||||
|
destination, |
||||||
|
recipient, |
||||||
|
ethers.utils.toUtf8Bytes(messageStr), |
||||||
|
); |
||||||
|
const receipt = await tx.wait(); |
||||||
|
const dispatch = receipt.events![0] as DispatchEvent; |
||||||
|
expect(dispatch.event).to.equal('Dispatch'); |
||||||
|
return dispatch.args!; |
||||||
|
}; |
||||||
|
|
||||||
|
export const dispatchMessageAndReturnProof = async ( |
||||||
|
outbox: TestOutbox, |
||||||
|
destination: number, |
||||||
|
recipient: string, |
||||||
|
messageStr: string, |
||||||
|
): Promise<MerkleProof> => { |
||||||
|
const { leafIndex, message } = await dispatchMessage( |
||||||
|
outbox, |
||||||
|
destination, |
||||||
|
recipient, |
||||||
|
messageStr, |
||||||
|
); |
||||||
|
const messageHash = utils.messageHash(message, leafIndex.toNumber()); |
||||||
|
const root = await outbox.root(); |
||||||
|
const proof = await outbox.proof(); |
||||||
|
return { |
||||||
|
root, |
||||||
|
proof: proof, |
||||||
|
leaf: messageHash, |
||||||
|
index: leafIndex, |
||||||
|
message, |
||||||
|
}; |
||||||
|
}; |
||||||
|
|
||||||
|
export interface MerkleProof { |
||||||
|
root: string; |
||||||
|
proof: string[]; |
||||||
|
leaf: string; |
||||||
|
index: BigNumber; |
||||||
|
message: string; |
||||||
|
} |
@ -1,23 +1,13 @@ |
|||||||
import type { |
import type { ProcessEvent } from '@abacus-network/core/types/contracts/Inbox'; |
||||||
CheckpointCachedEvent, |
|
||||||
ProcessEvent, |
|
||||||
} from '@abacus-network/core/types/contracts/Inbox'; |
|
||||||
import type { DispatchEvent } from '@abacus-network/core/types/contracts/Outbox'; |
import type { DispatchEvent } from '@abacus-network/core/types/contracts/Outbox'; |
||||||
|
|
||||||
import { Annotated } from '../events'; |
import { Annotated } from '../events'; |
||||||
|
|
||||||
export { DispatchEvent, CheckpointCachedEvent, ProcessEvent }; |
export { DispatchEvent, ProcessEvent }; |
||||||
|
|
||||||
export type AbacusLifecyleEvent = |
export type AbacusLifecyleEvent = ProcessEvent | DispatchEvent; |
||||||
| ProcessEvent |
|
||||||
| CheckpointCachedEvent |
|
||||||
| DispatchEvent; |
|
||||||
|
|
||||||
export type AnnotatedDispatch = Annotated<DispatchEvent>; |
export type AnnotatedDispatch = Annotated<DispatchEvent>; |
||||||
export type AnnotatedCheckpoint = Annotated<CheckpointCachedEvent>; |
|
||||||
export type AnnotatedProcess = Annotated<ProcessEvent>; |
export type AnnotatedProcess = Annotated<ProcessEvent>; |
||||||
|
|
||||||
export type AnnotatedLifecycleEvent = |
export type AnnotatedLifecycleEvent = AnnotatedDispatch | AnnotatedProcess; |
||||||
| AnnotatedDispatch |
|
||||||
| AnnotatedCheckpoint |
|
||||||
| AnnotatedProcess; |
|
||||||
|
Loading…
Reference in new issue