Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion packages/contracts/buidler.config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { usePlugin, BuidlerConfig } from '@nomiclabs/buidler/config'
import * as path from 'path'
import { usePlugin, BuidlerConfig, task } from '@nomiclabs/buidler/config'

import {
DEFAULT_ACCOUNTS_BUIDLER,
Expand Down Expand Up @@ -27,6 +28,18 @@ const parseSolppFlags = (): { [flag: string]: boolean } => {
return flags
}

task('compile')
.addFlag('ovm', 'Compile using OVM solc compiler')
.setAction(async (taskArguments, bre: any, runSuper) => {
if (taskArguments.ovm) {
bre.config.solc = {
path: path.resolve(__dirname, '../../node_modules/@eth-optimism/solc'),
}
bre.config.paths.artifacts = './build/ovm_artifacts'
}
await runSuper(taskArguments)
})

const config: BuidlerConfig = {
networks: {
buidlerevm: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ contract L1CrossDomainMessenger is BaseCrossDomainMessenger, ContractResolver {

event RelayedL2ToL1Message(bytes32 msgHash);

address public l1ToL2QueueAddress;

/*
* Data Structures
*/
Expand All @@ -44,6 +46,11 @@ contract L1CrossDomainMessenger is BaseCrossDomainMessenger, ContractResolver {
ContractResolver(_addressResolver)
{}

function tempInit(address _l1ToL2QueueAddress) public {
require(l1ToL2QueueAddress == address(0));
l1ToL2QueueAddress = _l1ToL2QueueAddress;
}


/*
* Public Functions
Expand Down Expand Up @@ -236,7 +243,10 @@ contract L1CrossDomainMessenger is BaseCrossDomainMessenger, ContractResolver {
view
returns (L1ToL2TransactionQueue)
{
return L1ToL2TransactionQueue(resolveContract("L1ToL2TransactionQueue"));
if (l1ToL2QueueAddress == address(0)) {
return L1ToL2TransactionQueue(resolveContract("L1ToL2TransactionQueue"));
}
return L1ToL2TransactionQueue(l1ToL2QueueAddress);
}

function resolveStateCommitmentChain()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ contract L2CrossDomainMessenger is BaseCrossDomainMessenger {
address private l1MessageSenderPrecompileAddress;
address private l2ToL1MessagePasserPrecompileAddress;

address public authenticatedAddress;

/*
* Constructor
*/
Expand Down Expand Up @@ -102,9 +104,17 @@ contract L2CrossDomainMessenger is BaseCrossDomainMessenger {
bool
)
{
IL1MessageSender l1MessageSenderPrecompile = IL1MessageSender(l1MessageSenderPrecompileAddress);
address l1MessageSenderAddress = l1MessageSenderPrecompile.getL1MessageSender();
return l1MessageSenderAddress == targetMessengerAddress;
if (authenticatedAddress == address(0)) {
IL1MessageSender l1MessageSenderPrecompile = IL1MessageSender(l1MessageSenderPrecompileAddress);
address l1MessageSenderAddress = l1MessageSenderPrecompile.getL1MessageSender();
return l1MessageSenderAddress == targetMessengerAddress;
}
return msg.sender == authenticatedAddress;
}

function tempInit(address _authenticatedAddress) public {
require(authenticatedAddress == address(0));
authenticatedAddress = _authenticatedAddress;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ contract L1ToL2TransactionQueue is ContractResolver, RollupQueue {

uint constant public L2_GAS_DISCOUNT_DIVISOR = 10;

address public l1MessengerAddress;

/*
* Constructor
*/
Expand All @@ -49,6 +51,11 @@ contract L1ToL2TransactionQueue is ContractResolver, RollupQueue {
* Public Functions
*/

function tempInit(address _l1MessengerAddress) public {
require(l1MessengerAddress == address(0));
l1MessengerAddress = _l1MessengerAddress;
}

/**
* Checks that that a dequeue is authenticated, and dequques if authenticated.
*/
Expand All @@ -69,6 +76,8 @@ contract L1ToL2TransactionQueue is ContractResolver, RollupQueue {
)
external
{
require(l1MessengerAddress == address(0) || msg.sender == l1MessengerAddress);

uint gasToBurn = _ovmGasLimit / L2_GAS_DISCOUNT_DIVISOR;
resolveGasConsumer().consumeGasInternalCall(gasToBurn);

Expand Down
9 changes: 6 additions & 3 deletions packages/contracts/package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
{
"name": "@eth-optimism/rollup-contracts",
"private": true,
"version": "0.0.1-alpha.33",
"version": "0.0.1-alpha.35",
"main": "build/index.js",
"files": [
"build/**/*.js",
"build/contracts/*",
"build/artifacts/*json"
"build/artifacts/*json",
"build/ovm_artifacts/*json"
],
"license": "MIT",
"workspaces": {
Expand All @@ -29,6 +30,7 @@
"coverage:contracts": "cross-env SOLPP_FLAGS=\"FLAG_IS_TEST\" buidler coverage --network coverage --show-stack-traces --testfiles \"test/contracts/**/*.spec.ts\"",
"build": "yarn run build:contracts && yarn run build:typescript && yarn run build:copy",
"build:contracts": "buidler compile",
"build:contracts:ovm": "buidler compile --ovm",
"build:typescript": "tsc -p .",
"build:copy": "yarn run build:copy:contracts",
"build:copy:contracts": "copyfiles -u 2 \"contracts/optimistic-ethereum/**/*.sol\" \"build/contracts\"",
Expand All @@ -37,7 +39,8 @@
"lint:typescript": "tslint --format stylish --project .",
"fix": "yarn run fix:typescript",
"fix:typescript": "prettier --config ../../prettier-config.json --write \"index.ts\" \"buidler.config.ts\" \"{src,test,plugins}/**/*.ts\"",
"deploy:all": "env DEBUG=\"info:*,error:*,debug:*\" node ./build/src/exec/deploy-contracts.js"
"deploy:all": "env DEBUG=\"info:*,error:*,debug:*\" node ./build/src/exec/deploy-contracts.js",
"prepublish": "yarn run build && yarn run build:contracts:ovm"
},
"dependencies": {
"@ethersproject/keccak256": "5.0.3",
Expand Down
26 changes: 26 additions & 0 deletions packages/ovm-toolchain/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,30 @@ const config = {
}

export default config
```

#### Watcher
Our `Watcher` allows you to retrieve all transaction hashes related to cross domain messages such as deposits and withdrawals. In order to use, first send a transaction which sends a cross domain message, for example a deposit from L1 into L2. After sending the deposit transaction and storing the transaction hash, use `getMessageHashesFromL1Tx(l1TxHash)` to get an array of the message hashes of all of the L1->L2 messages that were sent inside of that L1 tx (This will usually just be a single element array, but it can return multiple if one L1 transaction triggers multiple deposits). `getMessageHashesFromL2Tx(l2TxHash)` does the same for L2->L1 messages. `onceL2Relay(messageHash, callback)` takes in an L1->L2 message hash and a callback that will be triggered after 2-5 minutes with the hash of the L2 tx that the message ends up getting relayed in. `onceL1Relay(messageHash, callback)` does the same for L2->L1 messages, except the delay is 7 days.

```typescript
import { Watcher } from '@eth-optimism/ovm-toolchain/'
import { JsonRpcProvider } from 'ethers/providers'

const watcher = new Watcher({
l1: {
provider: new JsonRpcProvider('INFURA_L1_URL'),
messengerAddress: '0x...'
},
l2: {
provider: new JsonRpcProvider('OPTIMISM_L2_URL'),
messengerAddress: '0x...'
}
})
const l1TxHash = (await depositContract.deposit(100)).hash
const [messageHash] = await watcher.getMessageHashesFromL1Tx(l1TxHash)
console.log('L1->L2 message hash:', messageHash)
watcher.onceL2Relay(messageHash, (l2txhash) => {
// Takes 2-5 minutes
console.log('Got L2 Tx Hash:', l2txhash)
})
```
2 changes: 1 addition & 1 deletion packages/ovm-toolchain/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@eth-optimism/ovm-toolchain",
"version": "0.0.1-alpha.7",
"version": "0.0.1-alpha.8",
"description": "Wrappers for Ethereum dev tools",
"private": true,
"main": "build/index.js",
Expand Down
1 change: 1 addition & 0 deletions packages/ovm-toolchain/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './ganache'
export * from './waffle'
export * from './x-domain-utils'
export * from './watcher'
68 changes: 68 additions & 0 deletions packages/ovm-toolchain/src/watcher.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/* External Imports */
import { ethers } from 'ethers-v4'

interface Layer {
provider: any
messengerAddress: string
}

interface WatcherOptions {
l1: Layer
l2: Layer
}

export class Watcher {
public l1: Layer
public l2: Layer

constructor(opts: WatcherOptions) {
this.l1 = opts.l1
this.l2 = opts.l2
}

public async getMessageHashesFromL1Tx(l1TxHash: string): Promise<string[]> {
return this._getMessageHashesFromTx(true, l1TxHash)
}
public async getMessageHashesFromL2Tx(l2TxHash: string): Promise<string[]> {
return this._getMessageHashesFromTx(false, l2TxHash)
}

public onceL2Relay(msgHash: string, callback: Function): void {
return this._onceRelay(false, msgHash, callback)
}

public onceL1Relay(msgHash: string, callback: Function): void {
return this._onceRelay(true, msgHash, callback)
}

private async _getMessageHashesFromTx(
isL1: boolean,
txHash: string
): Promise<string[]> {
const layer = isL1 ? this.l1 : this.l2
const l1Receipt = await layer.provider.getTransactionReceipt(txHash)
const filtered = l1Receipt.logs.filter((log: any) => {
return (
log.address === layer.messengerAddress &&
log.topics[0] === ethers.utils.id('SentMessage(bytes32)')
)
})
return filtered.map((log: any) => log.data)
}

private _onceRelay(isL1: boolean, msgHash: string, callback: Function) {
const layer = isL1 ? this.l1 : this.l2
const filter = {
address: layer.messengerAddress,
topics: [
ethers.utils.id(`Relayed${isL1 ? 'L2ToL1' : 'L1ToL2'}Message(bytes32)`),
],
}

layer.provider.on(filter, (log: any) => {
if (log.data === msgHash) {
callback(log.transactionHash)
}
})
}
}
26 changes: 0 additions & 26 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5410,32 +5410,6 @@ ethereumjs-common@^1.1.0, ethereumjs-common@^1.3.2, ethereumjs-common@^1.5.0:
util.promisify "^1.0.0"
uuid "^8.3.0"

"ethereumjs-ovm@git+https://github.com/ethereum-optimism/ethereumjs-vm.git":
version "4.2.0"
uid "02ba6e77a88339b04a053b5e653f644acb1555b8"
resolved "git+https://github.com/ethereum-optimism/ethereumjs-vm.git#02ba6e77a88339b04a053b5e653f644acb1555b8"
dependencies:
"@types/debug" "^4.1.5"
"@types/uuid" "^8.3.0"
async "^2.1.2"
async-eventemitter "^0.2.2"
core-js-pure "^3.0.1"
debug "^4.1.1"
ethereumjs-account "^3.0.0"
ethereumjs-block "^2.2.2"
ethereumjs-blockchain "^4.0.3"
ethereumjs-common "^1.5.0"
ethereumjs-tx "^2.1.2"
ethereumjs-util "^6.2.0"
ethers "^5.0.0"
fake-merkle-patricia-tree "^1.0.1"
functional-red-black-tree "^1.0.1"
merkle-patricia-tree "^2.3.2"
rustbn.js "~0.2.0"
safe-buffer "^5.1.1"
util.promisify "^1.0.0"
uuid "^8.3.0"

ethereumjs-tx@1.3.7, ethereumjs-tx@^1.1.1, ethereumjs-tx@^1.2.0, ethereumjs-tx@^1.2.2, ethereumjs-tx@^1.3.3:
version "1.3.7"
resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz#88323a2d875b10549b8347e09f4862b546f3d89a"
Expand Down