Use yarn 3 and update to latest sdk (#8)
* Add SDK * Newline * Prettier * Add deploy * Deploy tests passing * Add missed files * Scripts working * Cleanup * Use upstream yorhodes/sdk-types * Use yarn 3 * Commit WIP * Make deploy test pass * Make all tests passing * Move to 0.1.0 of sdk * Prettier * Update to 0.1.1-alpha1 * Keep counters per sending/receiving domain * Remove unused type * Fully rename to Yo * Update ci * Make initializer external * Update yarn.lock * Update to alpha3 * Prettier Co-authored-by: Asa Oines <asaoines@Asas-MacBook-Pro.local> Co-authored-by: nambrot <nambrot@googlemail.com>pull/2435/head
parent
71f157ab8e
commit
aec667da99
@ -0,0 +1,2 @@ |
||||
src/types |
||||
test/outputs |
File diff suppressed because one or more lines are too long
@ -0,0 +1,3 @@ |
||||
nodeLinker: node-modules |
||||
|
||||
yarnPath: .yarn/releases/yarn-3.2.0.cjs |
@ -1,60 +0,0 @@ |
||||
// SPDX-License-Identifier: MIT OR Apache-2.0 |
||||
pragma solidity ^0.8.13; |
||||
|
||||
// ============ External Imports ============ |
||||
import {Router} from "@abacus-network/app/contracts/Router.sol"; |
||||
|
||||
/* |
||||
============ PingPong ============ |
||||
The PingPong app is capable of initiating PingPong "matches" between two chains. |
||||
A match consists of "volleys" sent back-and-forth between the two chains via Abacus. |
||||
|
||||
The first volley in a match is always a Ping volley. |
||||
When a contract receives a Ping volley, it returns a Pong. |
||||
When a contract receives a Pong volley, it returns a Ping. |
||||
|
||||
The contracts keep track of the number of volleys they've sent and received, |
||||
and emit events for each Sent and Received volley so that spectators can watch. |
||||
*/ |
||||
contract PingPong is Router { |
||||
uint256 public sent; |
||||
uint256 public received; |
||||
|
||||
// ============ Events ============ |
||||
event Sent(uint32 indexed origin, uint32 indexed destination, bool isPing); |
||||
|
||||
event Received( |
||||
uint32 indexed origin, |
||||
uint32 indexed destination, |
||||
bool isPing |
||||
); |
||||
|
||||
// ============ Constructor ============ |
||||
constructor(address _connectionManager) { |
||||
__Router_initialize(_connectionManager); |
||||
} |
||||
|
||||
function pingRemote(uint32 _destination) external { |
||||
_send(_destination, true); |
||||
} |
||||
|
||||
function _handle( |
||||
uint32 _origin, |
||||
bytes32, |
||||
bytes memory _message |
||||
) internal override { |
||||
received += 1; |
||||
bool _isPing = abi.decode(_message, (bool)); |
||||
uint32 localDomain = _localDomain(); |
||||
emit Received(_origin, localDomain, _isPing); |
||||
_send(_origin, !_isPing); |
||||
} |
||||
|
||||
function _send(uint32 _destination, bool _isPing) internal { |
||||
sent += 1; |
||||
uint32 localDomain = _localDomain(); |
||||
bytes memory message = abi.encode(_isPing); |
||||
_dispatchToRemoteRouter(_destination, message); |
||||
emit Sent(localDomain, _destination, _isPing); |
||||
} |
||||
} |
@ -0,0 +1,54 @@ |
||||
// SPDX-License-Identifier: MIT OR Apache-2.0 |
||||
pragma solidity ^0.8.13; |
||||
|
||||
// ============ External Imports ============ |
||||
import {Router} from "@abacus-network/app/contracts/Router.sol"; |
||||
|
||||
/* |
||||
============ Yo ============ |
||||
The Yo app |
||||
*/ |
||||
contract Yo is Router { |
||||
uint256 public sent; |
||||
uint256 public received; |
||||
|
||||
mapping(uint32 => uint256) public sentTo; |
||||
mapping(uint32 => uint256) public receivedFrom; |
||||
|
||||
// ============ Events ============ |
||||
event SentYo(uint32 indexed origin, uint32 indexed destination); |
||||
event ReceivedYo(uint32 indexed origin, uint32 indexed destination); |
||||
|
||||
// ============ Constructor ============ |
||||
|
||||
constructor() {} |
||||
|
||||
// ============ Initializer ============ |
||||
|
||||
function initialize(address _abacusConnectionManager) external initializer { |
||||
__Router_initialize(_abacusConnectionManager); |
||||
} |
||||
|
||||
function yoRemote(uint32 _destination) external { |
||||
_send(_destination); |
||||
} |
||||
|
||||
function _handle( |
||||
uint32 _origin, |
||||
bytes32, |
||||
bytes memory // _message |
||||
) internal override { |
||||
received += 1; |
||||
receivedFrom[_origin] += 1; |
||||
uint32 localDomain = _localDomain(); |
||||
emit ReceivedYo(_origin, localDomain); |
||||
} |
||||
|
||||
function _send(uint32 _destinationDomain) internal { |
||||
sent += 1; |
||||
sentTo[_destinationDomain] += 1; |
||||
uint32 localDomain = _localDomain(); |
||||
_dispatchWithGasAndCheckpoint(_destinationDomain, "", 0); |
||||
emit SentYo(localDomain, _destinationDomain); |
||||
} |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,14 @@ |
||||
import { AbacusRouterChecker } from '@abacus-network/deploy'; |
||||
import { ChainName } from '@abacus-network/sdk'; |
||||
import { YoApp } from '../sdk'; |
||||
import { YoConfig } from '../sdk/types'; |
||||
|
||||
export class YoChecker<Networks extends ChainName> extends AbacusRouterChecker< |
||||
Networks, |
||||
YoApp<Networks>, |
||||
YoConfig |
||||
> { |
||||
mustGetRouter(network: Networks) { |
||||
return this.app.getContracts(network).router; |
||||
} |
||||
} |
@ -0,0 +1,58 @@ |
||||
import { AbacusRouterDeployer } from '@abacus-network/deploy'; |
||||
import { |
||||
AbacusCore, |
||||
ChainName, |
||||
ChainMap, |
||||
MultiProvider, |
||||
} from '@abacus-network/sdk'; |
||||
import { YoAddresses } from '../sdk/contracts'; |
||||
import { YoConfig } from '../sdk/types'; |
||||
import { Yo__factory } from '../types'; |
||||
|
||||
export class YoDeployer< |
||||
Networks extends ChainName, |
||||
> extends AbacusRouterDeployer<Networks, YoConfig, YoAddresses> { |
||||
constructor( |
||||
multiProvider: MultiProvider<Networks>, |
||||
config: YoConfig, |
||||
core: AbacusCore<Networks>, |
||||
) { |
||||
const networks = multiProvider.networks(); |
||||
const crossConfigMap = Object.fromEntries( |
||||
networks.map((network) => [network, config]), |
||||
) as ChainMap<Networks, YoConfig>; |
||||
super(multiProvider, crossConfigMap, core); |
||||
} |
||||
|
||||
async deployContracts( |
||||
network: Networks, |
||||
config: YoConfig, |
||||
): Promise<YoAddresses> { |
||||
const dc = this.multiProvider.getDomainConnection(network); |
||||
const signer = dc.signer!; |
||||
|
||||
const router = await this.deployContract( |
||||
network, |
||||
'Yo', |
||||
new Yo__factory(signer), |
||||
[], |
||||
); |
||||
|
||||
const abacusConnectionManager = |
||||
this.core?.getContracts(network).abacusConnectionManager!; |
||||
const initTx = await router.initialize(abacusConnectionManager.address); |
||||
await initTx.wait(dc.confirmations); |
||||
|
||||
return { |
||||
router: router.address, |
||||
abacusConnectionManager: abacusConnectionManager.address, |
||||
}; |
||||
} |
||||
|
||||
mustGetRouter(network: Networks, addresses: YoAddresses) { |
||||
return Yo__factory.connect( |
||||
addresses.router, |
||||
this.multiProvider.getDomainConnection(network).signer!, |
||||
); |
||||
} |
||||
} |
@ -0,0 +1,11 @@ |
||||
import { EnvironmentConfig, RouterConfig } from '@abacus-network/deploy'; |
||||
import { TemplateNetworks } from '../../deploy/networks'; |
||||
import { environment as testEnvironment } from './test'; |
||||
|
||||
export type YoConfig = EnvironmentConfig<TemplateNetworks> & { |
||||
config: RouterConfig; |
||||
}; |
||||
|
||||
export const environments = { |
||||
test: testEnvironment, |
||||
}; |
@ -0,0 +1,7 @@ |
||||
import { configs } from '../networks'; |
||||
import { YoConfig } from './index'; |
||||
|
||||
export const environment: YoConfig = { |
||||
...configs, |
||||
config: {}, |
||||
}; |
@ -0,0 +1,2 @@ |
||||
export { YoDeployer } from './deploy'; |
||||
export { YoChecker } from './check'; |
@ -0,0 +1,58 @@ |
||||
import { TransactionConfig } from '@abacus-network/deploy'; |
||||
import { ChainMap } from '@abacus-network/sdk'; |
||||
|
||||
export const alfajores: TransactionConfig = { |
||||
confirmations: 1, |
||||
overrides: {}, |
||||
}; |
||||
|
||||
export const fuji: TransactionConfig = { |
||||
confirmations: 1, |
||||
overrides: {}, |
||||
}; |
||||
|
||||
export const mumbai: TransactionConfig = { |
||||
confirmations: 3, |
||||
overrides: {}, |
||||
}; |
||||
|
||||
export const kovan: TransactionConfig = { |
||||
confirmations: 3, |
||||
overrides: {}, |
||||
}; |
||||
|
||||
export const test1: TransactionConfig = { |
||||
confirmations: 1, |
||||
overrides: {}, |
||||
}; |
||||
|
||||
export const test2: TransactionConfig = { |
||||
confirmations: 1, |
||||
overrides: {}, |
||||
}; |
||||
|
||||
export const test3: TransactionConfig = { |
||||
confirmations: 1, |
||||
overrides: {}, |
||||
}; |
||||
|
||||
const _configs = { |
||||
alfajores, |
||||
fuji, |
||||
mumbai, |
||||
kovan, |
||||
test1, |
||||
test2, |
||||
test3, |
||||
}; |
||||
|
||||
export type TemplateNetworks = keyof typeof _configs; |
||||
export type TestNetworks = 'test1' | 'test2' | 'test3'; |
||||
export const testConfigs: ChainMap<TestNetworks, TransactionConfig> = { |
||||
test1, |
||||
test2, |
||||
test3, |
||||
}; |
||||
|
||||
export const configs: ChainMap<keyof typeof _configs, TransactionConfig> = |
||||
_configs; |
@ -0,0 +1,18 @@ |
||||
export const addresses = { |
||||
alfajores: { |
||||
router: '0xCace1b78160AE76398F486c8a18044da0d66d86D', |
||||
xAppConnectionManager: '0x610178dA211FEF7D417bC0e6FeD39F05609AD788', |
||||
}, |
||||
kovan: { |
||||
router: '0xD5ac451B0c50B9476107823Af206eD814a2e2580', |
||||
xAppConnectionManager: '0xc3e53F4d16Ae77Db1c982e75a937B9f60FE63690', |
||||
}, |
||||
mumbai: { |
||||
router: '0xF8e31cb472bc70500f08Cd84917E5A1912Ec8397', |
||||
xAppConnectionManager: '0xb7278A61aa25c888815aFC32Ad3cC52fF24fE575', |
||||
}, |
||||
fuji: { |
||||
router: '0xc0F115A19107322cFBf1cDBC7ea011C19EbDB4F8', |
||||
xAppConnectionManager: '0xDC11f7E700A4c898AE5CAddB1082cFfa76512aDD', |
||||
}, |
||||
}; |
@ -0,0 +1,8 @@ |
||||
[ |
||||
{ |
||||
"name": "Yo", |
||||
"address": "0xCace1b78160AE76398F486c8a18044da0d66d86D", |
||||
"constructorArguments": ["0x610178dA211FEF7D417bC0e6FeD39F05609AD788"], |
||||
"isProxy": false |
||||
} |
||||
] |
@ -0,0 +1,8 @@ |
||||
[ |
||||
{ |
||||
"name": "Yo", |
||||
"address": "0xc0F115A19107322cFBf1cDBC7ea011C19EbDB4F8", |
||||
"constructorArguments": ["0xDC11f7E700A4c898AE5CAddB1082cFfa76512aDD"], |
||||
"isProxy": false |
||||
} |
||||
] |
@ -0,0 +1,8 @@ |
||||
[ |
||||
{ |
||||
"name": "Yo", |
||||
"address": "0xD5ac451B0c50B9476107823Af206eD814a2e2580", |
||||
"constructorArguments": ["0xc3e53F4d16Ae77Db1c982e75a937B9f60FE63690"], |
||||
"isProxy": false |
||||
} |
||||
] |
@ -0,0 +1,8 @@ |
||||
[ |
||||
{ |
||||
"name": "Yo", |
||||
"address": "0xF8e31cb472bc70500f08Cd84917E5A1912Ec8397", |
||||
"constructorArguments": ["0xb7278A61aa25c888815aFC32Ad3cC52fF24fE575"], |
||||
"isProxy": false |
||||
} |
||||
] |
@ -0,0 +1,25 @@ |
||||
import { utils } from '@abacus-network/deploy'; |
||||
import { ethers } from 'hardhat'; |
||||
import { YoApp } from '../../sdk'; |
||||
import { environments } from '../../sdk/environments'; |
||||
import { YoChecker } from '../check'; |
||||
import { testConfigs } from '../networks'; |
||||
|
||||
async function check() { |
||||
const [signer] = await ethers.getSigners(); |
||||
const multiProvider = utils.getMultiProviderFromConfigAndSigner( |
||||
testConfigs, |
||||
signer, |
||||
); |
||||
|
||||
const app = new YoApp(environments.test, multiProvider); |
||||
const yoChecker = new YoChecker(multiProvider, app, { |
||||
test1: { owner: signer.address }, |
||||
test2: { owner: signer.address }, |
||||
test3: { owner: signer.address }, |
||||
}); |
||||
await yoChecker.check(); |
||||
yoChecker.expectEmpty(); |
||||
} |
||||
|
||||
check().then(console.log).catch(console.error); |
@ -0,0 +1,30 @@ |
||||
import { utils } from '@abacus-network/deploy'; |
||||
import { AbacusCore } from '@abacus-network/sdk'; |
||||
import '@nomiclabs/hardhat-ethers'; |
||||
import { ethers } from 'hardhat'; |
||||
import path from 'path'; |
||||
import { YoDeployer } from '..'; |
||||
import { testConfigs } from '../networks'; |
||||
|
||||
async function main() { |
||||
const [signer] = await ethers.getSigners(); |
||||
const environment = 'test'; |
||||
const multiProvider = utils.getMultiProviderFromConfigAndSigner( |
||||
testConfigs, |
||||
signer, |
||||
); |
||||
const core = AbacusCore.fromEnvironment('test', multiProvider); |
||||
|
||||
const deployer = new YoDeployer( |
||||
multiProvider, |
||||
{ owner: signer.address }, |
||||
core, |
||||
); |
||||
const addresses = await deployer.deploy(); |
||||
deployer.writeContracts( |
||||
addresses, |
||||
path.join('./src/sdk/environments/', environment + '.ts'), |
||||
); |
||||
} |
||||
|
||||
main().then(console.log).catch(console.error); |
@ -0,0 +1,7 @@ |
||||
import { environments, YoConfig } from '../environments'; |
||||
|
||||
export async function getEnvironmentConfig( |
||||
environment: keyof typeof environments, |
||||
): Promise<YoConfig> { |
||||
return environments[environment]; |
||||
} |
@ -0,0 +1,4 @@ |
||||
export { YoApp, YoAddresses, YoContracts } from './sdk'; |
||||
export * as contracts from './types'; |
||||
|
||||
export { YoDeployer, YoChecker } from './deploy'; |
@ -0,0 +1,42 @@ |
||||
import { |
||||
AbacusApp, |
||||
ChainMap, |
||||
ChainName, |
||||
ChainNameToDomainId, |
||||
MultiProvider, |
||||
} from '@abacus-network/sdk'; |
||||
import { ethers } from 'ethers'; |
||||
import { YoAddresses, YoContracts } from './contracts'; |
||||
import { environments } from './environments'; |
||||
|
||||
type Environments = typeof environments; |
||||
type EnvironmentName = keyof Environments; |
||||
|
||||
export class YoApp<Networks extends ChainName = ChainName> extends AbacusApp< |
||||
YoContracts, |
||||
Networks |
||||
> { |
||||
constructor( |
||||
networkAddresses: ChainMap<Networks, YoAddresses>, |
||||
multiProvider: MultiProvider<Networks>, |
||||
) { |
||||
super(YoContracts, networkAddresses, multiProvider); |
||||
} |
||||
|
||||
static fromEnvironment( |
||||
name: EnvironmentName, |
||||
multiProvider: MultiProvider<keyof Environments[typeof name]>, |
||||
) { |
||||
return new YoApp(environments[name], multiProvider); |
||||
} |
||||
|
||||
async yoRemote( |
||||
from: Networks, |
||||
to: Networks, |
||||
): Promise<ethers.ContractReceipt> { |
||||
const router = this.getContracts(from).router; |
||||
const toDomain = ChainNameToDomainId[to]; |
||||
const tx = await router.yoRemote(toDomain); |
||||
return tx.wait(); |
||||
} |
||||
} |
@ -0,0 +1,22 @@ |
||||
import { |
||||
AbacusContracts, |
||||
RouterAddresses, |
||||
routerFactories, |
||||
} from '@abacus-network/sdk'; |
||||
import { Yo__factory } from '../types'; |
||||
|
||||
export type YoAddresses = RouterAddresses; |
||||
|
||||
export const yoFactories = { |
||||
...routerFactories, |
||||
router: Yo__factory.connect, |
||||
}; |
||||
|
||||
export type YoFactories = typeof yoFactories; |
||||
|
||||
export class YoContracts extends AbacusContracts<YoAddresses, YoFactories> { |
||||
// necessary for factories be defined in the constructor
|
||||
factories() { |
||||
return yoFactories; |
||||
} |
||||
} |
@ -0,0 +1,5 @@ |
||||
import { addresses as test } from './test'; |
||||
|
||||
export const environments = { |
||||
test, |
||||
}; |
@ -0,0 +1,14 @@ |
||||
export const addresses = { |
||||
test1: { |
||||
router: '0x5FbDB2315678afecb367f032d93F642f64180aa3', |
||||
abacusConnectionManager: '0x0165878A594ca255338adfa4d48449f69242Eb8F', |
||||
}, |
||||
test2: { |
||||
router: '0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0', |
||||
abacusConnectionManager: '0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44', |
||||
}, |
||||
test3: { |
||||
router: '0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9', |
||||
abacusConnectionManager: '0x70e0bA845a1A0F2DA3359C97E0285013525FFC49', |
||||
}, |
||||
}; |
@ -0,0 +1,2 @@ |
||||
export { YoApp } from './app'; |
||||
export { YoAddresses, YoContracts } from './contracts'; |
@ -0,0 +1,5 @@ |
||||
import { RouterConfig } from '@abacus-network/deploy'; |
||||
|
||||
export type YoConfig = RouterConfig & { |
||||
owner: string; |
||||
}; |
@ -1,28 +0,0 @@ |
||||
import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; |
||||
import { types } from '@abacus-network/utils'; |
||||
import { TestAbacusDeploy, TestRouterDeploy } from '@abacus-network/hardhat'; |
||||
|
||||
import { PingPong__factory, PingPong } from '../src/types'; |
||||
|
||||
// PingPong has no configurable variables.
|
||||
export type PingPongConfig = { |
||||
signer: SignerWithAddress; |
||||
}; |
||||
|
||||
export class PingPongDeploy extends TestRouterDeploy<PingPong, PingPongConfig> { |
||||
async deployInstance( |
||||
domain: types.Domain, |
||||
abacus: TestAbacusDeploy, |
||||
): Promise<PingPong> { |
||||
const pingPongFactory = new PingPong__factory(this.config.signer); |
||||
const router = await pingPongFactory.deploy( |
||||
abacus.xAppConnectionManager(domain).address, |
||||
); |
||||
await router.transferOwnership(this.config.signer.address); |
||||
return router; |
||||
} |
||||
|
||||
router(domain: types.Domain): PingPong { |
||||
return this.instances[domain]; |
||||
} |
||||
} |
@ -0,0 +1,27 @@ |
||||
import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; |
||||
import { types } from '@abacus-network/utils'; |
||||
import { TestAbacusDeploy, TestRouterDeploy } from '@abacus-network/hardhat'; |
||||
|
||||
import { Yo__factory, Yo } from '../src/types'; |
||||
|
||||
// Yo has no configurable variables.
|
||||
export type YoConfig = { |
||||
signer: SignerWithAddress; |
||||
}; |
||||
|
||||
export class YoDeploy extends TestRouterDeploy<Yo, YoConfig> { |
||||
async deployInstance( |
||||
domain: types.Domain, |
||||
abacus: TestAbacusDeploy, |
||||
): Promise<Yo> { |
||||
const yoFactory = new Yo__factory(this.config.signer); |
||||
const router = await yoFactory.deploy(); |
||||
await router.initialize(abacus.abacusConnectionManager(domain).address); |
||||
await router.transferOwnership(this.config.signer.address); |
||||
return router; |
||||
} |
||||
|
||||
router(domain: types.Domain): Yo { |
||||
return this.instances[domain]; |
||||
} |
||||
} |
@ -0,0 +1,60 @@ |
||||
import path from 'path'; |
||||
import '@nomiclabs/hardhat-waffle'; |
||||
import { ethers } from 'hardhat'; |
||||
import { utils } from '@abacus-network/deploy'; |
||||
|
||||
import { YoAddresses, YoApp } from '../src'; |
||||
import { YoChecker, YoDeployer } from '../src/deploy'; |
||||
import { configs } from '../src/deploy/networks'; |
||||
import { AbacusCore } from '@abacus-network/sdk'; |
||||
|
||||
describe('deploy', async () => { |
||||
let deployer: YoDeployer<'test1' | 'test2' | 'test3'>; |
||||
let addresses: Record<'test1' | 'test2' | 'test3', YoAddresses>; |
||||
|
||||
before(async () => { |
||||
const transactionConfigs = { |
||||
test1: configs.test1, |
||||
test2: configs.test2, |
||||
test3: configs.test3, |
||||
}; |
||||
const [signer] = await ethers.getSigners(); |
||||
const multiProvider = utils.getMultiProviderFromConfigAndSigner( |
||||
transactionConfigs, |
||||
signer, |
||||
); |
||||
const core = AbacusCore.fromEnvironment('test', multiProvider); |
||||
deployer = new YoDeployer(multiProvider, { owner: signer.address }, core); |
||||
}); |
||||
|
||||
it('deploys', async () => { |
||||
addresses = await deployer.deploy(); |
||||
}); |
||||
|
||||
it('writes', async () => { |
||||
const base = './test/outputs/yo'; |
||||
deployer.writeVerification(path.join(base, 'verification')); |
||||
deployer.writeContracts(addresses, path.join(base, 'contracts.ts')); |
||||
}); |
||||
|
||||
it('checks', async () => { |
||||
const transactionConfigs = { |
||||
test1: configs.test1, |
||||
test2: configs.test2, |
||||
test3: configs.test3, |
||||
}; |
||||
const [signer] = await ethers.getSigners(); |
||||
const multiProvider = utils.getMultiProviderFromConfigAndSigner( |
||||
transactionConfigs, |
||||
signer, |
||||
); |
||||
const app = new YoApp(addresses, multiProvider); |
||||
const checker = new YoChecker(multiProvider, app, { |
||||
test1: { owner: signer.address }, |
||||
test2: { owner: signer.address }, |
||||
test3: { owner: signer.address }, |
||||
}); |
||||
await checker.check(); |
||||
checker.expectEmpty(); |
||||
}); |
||||
}); |
@ -1,73 +0,0 @@ |
||||
import { ethers, abacus } from 'hardhat'; |
||||
import { expect } from 'chai'; |
||||
import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; |
||||
|
||||
import { PingPongDeploy } from './PingPongDeploy'; |
||||
import { PingPong } from '../src/types'; |
||||
|
||||
const localDomain = 1000; |
||||
const remoteDomain = 2000; |
||||
const domains = [localDomain, remoteDomain]; |
||||
|
||||
describe('PingPong', async () => { |
||||
let signer: SignerWithAddress, |
||||
router: PingPong, |
||||
remote: PingPong, |
||||
pingPong: PingPongDeploy; |
||||
|
||||
before(async () => { |
||||
[signer] = await ethers.getSigners(); |
||||
await abacus.deploy(domains, signer); |
||||
}); |
||||
|
||||
beforeEach(async () => { |
||||
const config = { signer }; |
||||
pingPong = new PingPongDeploy(config); |
||||
await pingPong.deploy(abacus); |
||||
router = pingPong.router(localDomain); |
||||
remote = pingPong.router(remoteDomain); |
||||
expect(await router.sent()).to.equal(0); |
||||
expect(await router.received()).to.equal(0); |
||||
expect(await remote.sent()).to.equal(0); |
||||
expect(await remote.received()).to.equal(0); |
||||
}); |
||||
|
||||
it('sends an initial ping', async () => { |
||||
await expect(router.pingRemote(remoteDomain)).to.emit( |
||||
abacus.outbox(localDomain), |
||||
'Dispatch', |
||||
); |
||||
expect(await router.sent()).to.equal(1); |
||||
expect(await router.received()).to.equal(0); |
||||
}); |
||||
|
||||
it('responds to a ping with a pong', async () => { |
||||
await router.pingRemote(remoteDomain); |
||||
// Processing the initial ping causes a pong to be dispatched from the remote domain.
|
||||
await abacus.processOutboundMessages(localDomain); |
||||
// The initial ping has been dispatched.
|
||||
expect(await router.sent()).to.equal(1); |
||||
// The pong has been dispatched but not processed..
|
||||
expect(await router.received()).to.equal(0); |
||||
// The pong has been dispatched.
|
||||
expect(await remote.sent()).to.equal(1); |
||||
// The initial ping has been processed.
|
||||
expect(await remote.received()).to.equal(1); |
||||
}); |
||||
|
||||
it('responds to a pong with a ping', async () => { |
||||
await router.pingRemote(remoteDomain); |
||||
// Processing the initial ping causes a pong to be dispatched from the remote domain.
|
||||
await abacus.processOutboundMessages(localDomain); |
||||
// Processing the pong response causes a ping to be dispatched from the local domain.
|
||||
await abacus.processOutboundMessages(remoteDomain); |
||||
// The initial ping and the response to the pong.
|
||||
expect(await router.sent()).to.equal(2); |
||||
// The pong.
|
||||
expect(await router.received()).to.equal(1); |
||||
// The pong has been dispatched.
|
||||
expect(await remote.sent()).to.equal(1); |
||||
// The initial ping has been processed.
|
||||
expect(await remote.received()).to.equal(1); |
||||
}); |
||||
}); |
@ -0,0 +1,52 @@ |
||||
import { ethers, abacus } from 'hardhat'; |
||||
import { expect } from 'chai'; |
||||
import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; |
||||
|
||||
import { YoDeploy } from './YoDeploy'; |
||||
import { Yo } from '../src/types'; |
||||
|
||||
const localDomain = 1000; |
||||
const remoteDomain = 2000; |
||||
const domains = [localDomain, remoteDomain]; |
||||
|
||||
describe('Yo', async () => { |
||||
let signer: SignerWithAddress, router: Yo, remote: Yo, yo: YoDeploy; |
||||
|
||||
before(async () => { |
||||
[signer] = await ethers.getSigners(); |
||||
await abacus.deploy(domains, signer); |
||||
}); |
||||
|
||||
beforeEach(async () => { |
||||
const config = { signer }; |
||||
yo = new YoDeploy(config); |
||||
await yo.deploy(abacus); |
||||
router = yo.router(localDomain); |
||||
remote = yo.router(remoteDomain); |
||||
expect(await router.sent()).to.equal(0); |
||||
expect(await router.received()).to.equal(0); |
||||
expect(await remote.sent()).to.equal(0); |
||||
expect(await remote.received()).to.equal(0); |
||||
}); |
||||
|
||||
it('sends an initial yo', async () => { |
||||
await expect(router.yoRemote(remoteDomain)).to.emit( |
||||
abacus.outbox(localDomain), |
||||
'Dispatch', |
||||
); |
||||
expect(await router.sent()).to.equal(1); |
||||
expect(await router.sentTo(remoteDomain)).to.equal(1); |
||||
expect(await router.received()).to.equal(0); |
||||
}); |
||||
|
||||
it('handles a yo', async () => { |
||||
await router.yoRemote(remoteDomain); |
||||
// Processing the initial yo causes a pong to be dispatched from the remote domain.
|
||||
await abacus.processOutboundMessages(localDomain); |
||||
// The initial yo has been dispatched.
|
||||
expect(await router.sent()).to.equal(1); |
||||
// The initial yo has been processed.
|
||||
expect(await remote.received()).to.equal(1); |
||||
expect(await remote.receivedFrom(localDomain)).to.equal(1); |
||||
}); |
||||
}); |
Loading…
Reference in new issue