Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Map internal transactions to external (OVM) transactions #97

Merged
merged 14 commits into from
Apr 22, 2020
Merged
11 changes: 11 additions & 0 deletions packages/ovm/src/contracts/L2ExecutionManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {ExecutionManager} from "./ExecutionManager.sol";
*/
contract L2ExecutionManager is ExecutionManager {
mapping(bytes32 => bytes32) ovmHashToEvmHash;
mapping(bytes32 => bytes32) evmHashToOvmHash;
mapping(bytes32 => bytes) ovmHashToOvmTx;

constructor(
Expand All @@ -28,10 +29,20 @@ contract L2ExecutionManager is ExecutionManager {
@param signedOvmTx The signed OVM tx that we received
*/
function storeOvmTransaction(bytes32 ovmTransactionHash, bytes32 internalTransactionHash, bytes memory signedOvmTx) public {
evmHashToOvmHash[internalTransactionHash] = ovmTransactionHash;
ovmHashToEvmHash[ovmTransactionHash] = internalTransactionHash;
ovmHashToOvmTx[ovmTransactionHash] = signedOvmTx;
}

/**
@notice Gets the OVM transaction hash associated with the provided EVM transaction hash.
@param evmTransactionHash The EVM transaction hash.
@return The associated OVM transaction hash.
*/
function getOvmTransactionHash(bytes32 evmTransactionHash) public view returns (bytes32) {
return evmHashToOvmHash[evmTransactionHash];
}

/**
@notice Gets the EVM transaction hash associated with the provided OVM transaction hash.
@param ovmTransactionHash The OVM transaction hash.
Expand Down
25 changes: 22 additions & 3 deletions packages/rollup-full-node/src/app/web3-rpc-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -361,15 +361,24 @@ export class DefaultWeb3Handler
block['transactions'] = (
await Promise.all(
block['transactions'].map(async (transaction) => {
transaction['hash'] = await this.getInternalTxHash(
transaction['hash']
)
transaction['hash'] = await this.getOvmTxHash(transaction['hash'])
let ovmTx = await this.getTransactionByHash(transaction['hash'])
transaction['from'] = ovmTx.from
transaction['to'] = ovmTx.to
transaction['gasLimit'] = ovmTx.gasLimit.toNumber()
masonforest marked this conversation as resolved.
Show resolved Hide resolved

return transaction
})
)
)
// Filter transactions that aren't included in the execution manager
.filter((transaction) => transaction['hash'] !== add0x('00'.repeat(32)))
} else {
block['transactions'] = await Promise.all(
block['transactions'].map(async (transactionHash) =>
this.getOvmTxHash(transactionHash)
)
)
}

log.debug(
Expand Down Expand Up @@ -771,6 +780,16 @@ export class DefaultWeb3Handler
)
}

/**
* Gets the external OVM transaction hash for the provided EVM transaction hash, if one exists.
*
* @param evmTxHash The EVM transaction hash
* @returns The OVM tx hash if one exists, else undefined.
*/
private async getOvmTxHash(evmTxHash: string): Promise<string> {
return this.context.executionManager.getOvmTransactionHash(add0x(evmTxHash))
}

/**
* Gets the signed OVM transaction that we received by its hash.
*
Expand Down
36 changes: 36 additions & 0 deletions packages/rollup-full-node/test/app/web-rpc-handler.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
getLogger,
keccak256,
numberToHexString,
hexStrToBuf,
ZERO_ADDRESS,
} from '@eth-optimism/core-utils'
import { CHAIN_ID } from '@eth-optimism/ovm'
Expand Down Expand Up @@ -178,6 +179,41 @@ describe('Web3Handler', () => {
const block = await httpProvider.getBlock('latest', true)
block.timestamp.should.be.gte(timestamp)
})

it('should return the latest block with transaction objects', async () => {
const executionManagerAddress = await httpProvider.send(
'ovm_getExecutionManagerAddress',
[]
)
const wallet = getWallet(httpProvider)
const simpleStorage = await deploySimpleStorage(wallet)
await setAndGetStorage(
simpleStorage,
httpProvider,
executionManagerAddress
)

const block = await httpProvider.getBlock('latest', true)
block.transactions[0].from.should.eq(wallet.address)
block.transactions[0].to.should.eq(simpleStorage.address)
})

it('should return the latest block with transaction hashes', async () => {
const executionManagerAddress = await httpProvider.send(
'ovm_getExecutionManagerAddress',
[]
)
const wallet = getWallet(httpProvider)
const simpleStorage = await deploySimpleStorage(wallet)
await setAndGetStorage(
simpleStorage,
httpProvider,
executionManagerAddress
)

const block = await httpProvider.getBlock('latest', false)
hexStrToBuf(block.transactions[0]).length.should.eq(32)
})
})

describe('the getBlockByHash endpoint', () => {
Expand Down