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
5 changes: 5 additions & 0 deletions .changeset/lovely-pumas-sing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@eth-optimism/contracts': patch
---

Use a gas price of zero for static calls in the deploy process
5 changes: 5 additions & 0 deletions .changeset/sharp-ants-act.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@eth-optimism/contracts': patch
---

Adds additional deploy step to transfer messenger ownership
5 changes: 5 additions & 0 deletions .changeset/spicy-spoons-jog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@eth-optimism/l2geth': patch
---

Fixes deadlock
5 changes: 4 additions & 1 deletion l2geth/core/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ import (
)

// NewTxsEvent is posted when a batch of transactions enter the transaction pool.
type NewTxsEvent struct{ Txs []*types.Transaction }
type NewTxsEvent struct {
Txs []*types.Transaction
ErrCh chan error
}

// NewMinedBlockEvent is posted when a block has been imported.
type NewMinedBlockEvent struct{ Block *types.Block }
Expand Down
2 changes: 1 addition & 1 deletion l2geth/core/tx_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -1090,7 +1090,7 @@ func (pool *TxPool) runReorg(done chan struct{}, reset *txpoolResetRequest, dirt
for _, set := range events {
txs = append(txs, set.Flatten()...)
}
pool.txFeed.Send(NewTxsEvent{txs})
pool.txFeed.Send(NewTxsEvent{Txs: txs})
}
}

Expand Down
14 changes: 12 additions & 2 deletions l2geth/miner/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,10 @@ func (w *worker) mainLoop() {
}
w.pendingMu.Unlock()
} else {
log.Debug("Problem committing transaction", "msg", err)
log.Error("Problem committing transaction", "msg", err)
if ev.ErrCh != nil {
ev.ErrCh <- err
}
}

case ev := <-w.txsCh:
Expand Down Expand Up @@ -781,6 +784,11 @@ func (w *worker) commitTransactions(txs *types.TransactionsByPriceAndNonce, coin
}

var coalescedLogs []*types.Log
// UsingOVM
// Keep track of the number of transactions being added to the block.
// Blocks should only have a single transaction. This value is used to
// compute a success return value
var txCount int

for {
// In the following three cases, we will interrupt the execution of the transaction.
Expand Down Expand Up @@ -814,6 +822,8 @@ func (w *worker) commitTransactions(txs *types.TransactionsByPriceAndNonce, coin
break
}

txCount++

// Error may be ignored here. The error has already been checked
// during transaction acceptance is the transaction pool.
//
Expand Down Expand Up @@ -881,7 +891,7 @@ func (w *worker) commitTransactions(txs *types.TransactionsByPriceAndNonce, coin
if interrupt != nil {
w.resubmitAdjustCh <- &intervalAdjust{inc: false}
}
return false
return txCount == 0
}

// commitNewTx is an OVM addition that mines a block with a single tx in it.
Expand Down
51 changes: 32 additions & 19 deletions l2geth/rollup/sync_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -806,27 +806,25 @@ func (s *SyncService) applyTransactionToTip(tx *types.Transaction) error {
// Note that Ethereum Layer one consensus rules dictate that the timestamp
// must be strictly increasing between blocks, so no need to check both the
// timestamp and the blocknumber.
ts := s.GetLatestL1Timestamp()
bn := s.GetLatestL1BlockNumber()
if tx.L1Timestamp() == 0 {
ts := s.GetLatestL1Timestamp()
bn := s.GetLatestL1BlockNumber()
tx.SetL1Timestamp(ts)
tx.SetL1BlockNumber(bn)
} else if tx.L1Timestamp() > s.GetLatestL1Timestamp() {
// If the timestamp of the transaction is greater than the sync
// service's locally maintained timestamp, update the timestamp and
// blocknumber to equal that of the transaction's. This should happen
// with `enqueue` transactions.
ts := tx.L1Timestamp()
bn := tx.L1BlockNumber()
s.SetLatestL1Timestamp(ts)
s.SetLatestL1BlockNumber(bn.Uint64())
log.Debug("Updating OVM context based on new transaction", "timestamp", ts, "blocknumber", bn.Uint64(), "queue-origin", tx.QueueOrigin())
s.SetLatestL1Timestamp(tx.L1Timestamp())
s.SetLatestL1BlockNumber(tx.L1BlockNumber().Uint64())
log.Debug("Updating OVM context based on new transaction", "timestamp", ts, "blocknumber", tx.L1BlockNumber().Uint64(), "queue-origin", tx.QueueOrigin())
} else if tx.L1Timestamp() < s.GetLatestL1Timestamp() {
log.Error("Timestamp monotonicity violation", "hash", tx.Hash().Hex())
}

index := s.GetLatestIndex()
if tx.GetMeta().Index == nil {
index := s.GetLatestIndex()
if index == nil {
tx.SetIndex(0)
} else {
Expand All @@ -846,21 +844,36 @@ func (s *SyncService) applyTransactionToTip(tx *types.Transaction) error {
log.Debug("Applying transaction to tip", "index", *tx.GetMeta().Index, "hash", tx.Hash().Hex(), "origin", tx.QueueOrigin().String())

txs := types.Transactions{tx}
s.txFeed.Send(core.NewTxsEvent{Txs: txs})
errCh := make(chan error, 1)
s.txFeed.Send(core.NewTxsEvent{
Txs: txs,
ErrCh: errCh,
})
// Block until the transaction has been added to the chain
log.Trace("Waiting for transaction to be added to chain", "hash", tx.Hash().Hex())
<-s.chainHeadCh

// Update the cache when the transaction is from the owner
// of the gas price oracle
sender, _ := types.Sender(s.signer, tx)
owner := s.GasPriceOracleOwnerAddress()
if owner != nil && sender == *owner {
if err := s.updateGasPriceOracleCache(nil); err != nil {
return err

select {
case err := <-errCh:
log.Error("Got error waiting for transaction to be added to chain", "msg", err)
s.SetLatestL1Timestamp(ts)
s.SetLatestL1BlockNumber(bn)
s.SetLatestIndex(index)
return err
case <-s.chainHeadCh:
// Update the cache when the transaction is from the owner
// of the gas price oracle
sender, _ := types.Sender(s.signer, tx)
owner := s.GasPriceOracleOwnerAddress()
if owner != nil && sender == *owner {
if err := s.updateGasPriceOracleCache(nil); err != nil {
s.SetLatestL1Timestamp(ts)
s.SetLatestL1BlockNumber(bn)
s.SetLatestIndex(index)
return err
}
}
return nil
}
return nil
}

// applyBatchedTransaction applies transactions that were batched to layer one.
Expand Down
2 changes: 1 addition & 1 deletion packages/contracts/deploy/000-hardhat-setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
fundAccount,
sendImpersonatedTx,
BIG_BALANCE,
} from '../src/hardhat-deploy-ethers'
} from '../src/deploy-utils'
import { names } from '../src/address-names'
import { awaitCondition } from '@eth-optimism/core-utils'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { DeployFunction } from 'hardhat-deploy/dist/types'
import {
deployAndVerifyAndThen,
getContractFromArtifact,
} from '../src/hardhat-deploy-ethers'
} from '../src/deploy-utils'
import { names } from '../src/address-names'

const deployFn: DeployFunction = async (hre) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { DeployFunction } from 'hardhat-deploy/dist/types'
import {
deployAndVerifyAndThen,
getContractFromArtifact,
} from '../src/hardhat-deploy-ethers'
} from '../src/deploy-utils'
import { names } from '../src/address-names'

const deployFn: DeployFunction = async (hre) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { DeployFunction } from 'hardhat-deploy/dist/types'
import {
deployAndVerifyAndThen,
getContractFromArtifact,
} from '../src/hardhat-deploy-ethers'
} from '../src/deploy-utils'
import { names } from '../src/address-names'

const deployFn: DeployFunction = async (hre) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { DeployFunction } from 'hardhat-deploy/dist/types'
import {
deployAndVerifyAndThen,
getContractFromArtifact,
} from '../src/hardhat-deploy-ethers'
} from '../src/deploy-utils'
import { names } from '../src/address-names'

const deployFn: DeployFunction = async (hre) => {
Expand Down
2 changes: 1 addition & 1 deletion packages/contracts/deploy/006-OVM_BondManager.deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { DeployFunction } from 'hardhat-deploy/dist/types'
import {
deployAndVerifyAndThen,
getContractFromArtifact,
} from '../src/hardhat-deploy-ethers'
} from '../src/deploy-utils'
import { names } from '../src/address-names'

const deployFn: DeployFunction = async (hre) => {
Expand Down
21 changes: 19 additions & 2 deletions packages/contracts/deploy/007-OVM_L1CrossDomainMessenger.deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { hexStringEquals, awaitCondition } from '@eth-optimism/core-utils'
import {
deployAndVerifyAndThen,
getContractFromArtifact,
} from '../src/hardhat-deploy-ethers'
} from '../src/deploy-utils'
import { names } from '../src/address-names'

const deployFn: DeployFunction = async (hre) => {
Expand All @@ -25,7 +25,7 @@ const deployFn: DeployFunction = async (hre) => {
// a proxy. However, it's best practice to initialize it anyway just in case there's
// some unknown security hole. It also prevents another user from appearing like an
// official address because it managed to call the initialization function.
console.log(`Initializing L1CrossDomainMessenger...`)
console.log(`Initializing L1CrossDomainMessenger (implementation)...`)
await contract.initialize(Lib_AddressManager.address)

console.log(`Checking that contract was correctly initialized...`)
Expand All @@ -39,6 +39,23 @@ const deployFn: DeployFunction = async (hre) => {
5000,
100
)

// Same thing as above, we want to transfer ownership of this contract to the owner of the
// AddressManager. Not technically necessary but seems like the right thing to do.
console.log(
`Transferring ownership of L1CrossDomainMessenger (implementation)...`
)
const owner = (hre as any).deployConfig.ovmAddressManagerOwner
await contract.transferOwnership(owner)

console.log(`Checking that contract owner was correctly set...`)
await awaitCondition(
async () => {
return hexStringEquals(await contract.owner(), owner)
},
5000,
100
)
},
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { DeployFunction } from 'hardhat-deploy/dist/types'
import {
deployAndVerifyAndThen,
getContractFromArtifact,
} from '../src/hardhat-deploy-ethers'
} from '../src/deploy-utils'
import { names } from '../src/address-names'

const deployFn: DeployFunction = async (hre) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { DeployFunction } from 'hardhat-deploy/dist/types'

/* Imports: Internal */
import { deployAndVerifyAndThen } from '../src/hardhat-deploy-ethers'
import { deployAndVerifyAndThen } from '../src/deploy-utils'
import { names } from '../src/address-names'

const deployFn: DeployFunction = async (hre) => {
Expand Down
2 changes: 1 addition & 1 deletion packages/contracts/deploy/010-AddressDictator.deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { hexStringEquals } from '@eth-optimism/core-utils'
import {
deployAndVerifyAndThen,
getContractFromArtifact,
} from '../src/hardhat-deploy-ethers'
} from '../src/deploy-utils'
import { names } from '../src/address-names'
import { predeploys } from '../src/predeploys'

Expand Down
5 changes: 1 addition & 4 deletions packages/contracts/deploy/011-set-addresses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@ import { hexStringEquals, awaitCondition } from '@eth-optimism/core-utils'
import { DeployFunction } from 'hardhat-deploy/dist/types'

/* Imports: Internal */
import {
getContractFromArtifact,
isHardhatNode,
} from '../src/hardhat-deploy-ethers'
import { getContractFromArtifact, isHardhatNode } from '../src/deploy-utils'
import { names } from '../src/address-names'

const deployFn: DeployFunction = async (hre) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@ import { DeployFunction } from 'hardhat-deploy/dist/types'
import { hexStringEquals, awaitCondition } from '@eth-optimism/core-utils'

/* Imports: Internal */
import { getContractFromArtifact } from '../src/hardhat-deploy-ethers'
import { getContractFromArtifact } from '../src/deploy-utils'
import { names } from '../src/address-names'

const deployFn: DeployFunction = async (hre) => {
const { deployer } = await hre.getNamedAccounts()

console.log(`Initializing Proxy__L1CrossDomainMessenger...`)

// There's a risk that we could get front-run during a fresh deployment, which would brick this
// contract and require that the proxy be re-deployed. We will not have this risk once we move
// entirely to chugsplash-style deployments. It's unlikely to happen and relatively easy to
Expand All @@ -29,6 +27,7 @@ const deployFn: DeployFunction = async (hre) => {
names.unmanaged.Lib_AddressManager
)

console.log(`Initializing Proxy__OVM_L1CrossDomainMessenger...`)
await Proxy__OVM_L1CrossDomainMessenger.initialize(Lib_AddressManager.address)

console.log(`Checking that contract was correctly initialized...`)
Expand All @@ -42,6 +41,22 @@ const deployFn: DeployFunction = async (hre) => {
5000,
100
)

console.log(`Setting Proxy__OVM_L1CrossDomainMessenger owner...`)
const owner = (hre as any).deployConfig.ovmAddressManagerOwner
await Proxy__OVM_L1CrossDomainMessenger.transferOwnership(owner)

console.log(`Checking that the contract owner was correctly set...`)
await awaitCondition(
async () => {
return hexStringEquals(
await Proxy__OVM_L1CrossDomainMessenger.owner(),
owner
)
},
5000,
100
)
}

deployFn.tags = ['finalize']
Expand Down
2 changes: 1 addition & 1 deletion packages/contracts/deploy/013-ChugSplashDictator.deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { getContractDefinition } from '../src/contract-defs'
import {
getContractFromArtifact,
deployAndVerifyAndThen,
} from '../src/hardhat-deploy-ethers'
} from '../src/deploy-utils'
import { names } from '../src/address-names'

const deployFn: DeployFunction = async (hre) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
getContractFromArtifact,
deployAndVerifyAndThen,
isHardhatNode,
} from '../src/hardhat-deploy-ethers'
} from '../src/deploy-utils'
import { names } from '../src/address-names'

const deployFn: DeployFunction = async (hre) => {
Expand Down
2 changes: 1 addition & 1 deletion packages/contracts/deploy/015-finalize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { DeployFunction } from 'hardhat-deploy/dist/types'
import { hexStringEquals, awaitCondition } from '@eth-optimism/core-utils'

/* Imports: Internal */
import { getContractFromArtifact } from '../src/hardhat-deploy-ethers'
import { getContractFromArtifact } from '../src/deploy-utils'

const deployFn: DeployFunction = async (hre) => {
const { deployer } = await hre.getNamedAccounts()
Expand Down
5 changes: 1 addition & 4 deletions packages/contracts/deploy/016-fund-accounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ import { defaultHardhatNetworkHdAccountsConfigParams } from 'hardhat/internal/co
import { normalizeHardhatNetworkAccountsConfig } from 'hardhat/internal/core/providers/util'

/* Imports: Internal */
import {
getContractFromArtifact,
isHardhatNode,
} from '../src/hardhat-deploy-ethers'
import { getContractFromArtifact, isHardhatNode } from '../src/deploy-utils'
import { names } from '../src/address-names'

// This is a TEMPORARY way to fund the default hardhat accounts on L2. The better way to do this is
Expand Down
Loading