Commit 9d15e1ad authored by Mark Tyneway's avatar Mark Tyneway Committed by GitHub

contracts-bedrock: remove fund dev accounts (#3285)

* contracts-bedrock: always fund dev accounts

Reduces config complexity

* op-chain-ops: clean up genesis package
Co-authored-by: default avatarMatthew Slipper <me@matthewslipper.com>
parent 2106bdb7
......@@ -36,7 +36,6 @@ type DeployConfig struct {
CliqueSignerAddress common.Address `json:"cliqueSignerAddress"`
OptimismBaseFeeRecipient common.Address `json:"optimismBaseFeeRecipient"`
OptimismL1FeeRecipient common.Address `json:"optimismL1FeeRecipient"`
FundDevAccounts bool `json:"fundDevAccounts"`
GasPriceOracleOwner common.Address `json:"gasPriceOracleOwner"`
GasPriceOracleOverhead uint `json:"gasPriceOracleOverhead"`
GasPriceOracleScalar uint `json:"gasPriceOracleScalar"`
......
......@@ -6,16 +6,10 @@ import (
"fmt"
"math/big"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/hardhat"
"github.com/ethereum-optimism/optimism/op-chain-ops/immutables"
"github.com/ethereum-optimism/optimism/op-chain-ops/state"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/rpc"
)
......@@ -64,111 +58,6 @@ var DevAccounts = []common.Address{
// The devBalance is the amount of wei that a dev account is funded with.
var devBalance = hexutil.MustDecodeBig("0x200000000000000000000000000000000000000000000000000000000000000")
// FundDevAccounts will fund each of the development accounts.
func FundDevAccounts(db vm.StateDB) {
for _, account := range DevAccounts {
db.CreateAccount(account)
db.AddBalance(account, devBalance)
}
}
// SetProxies will set each of the proxies in the state. It requires
// a Proxy and ProxyAdmin deployment present so that the Proxy bytecode
// can be set in state and the ProxyAdmin can be set as the admin of the
// Proxy.
func SetProxies(hh *hardhat.Hardhat, db vm.StateDB) error {
proxy, err := hh.GetArtifact("Proxy")
if err != nil {
return err
}
proxyAdmin, err := hh.GetDeployment("ProxyAdmin")
if err != nil {
return err
}
for i := uint64(0); i <= 2048; i++ {
bigAddr := new(big.Int).Or(bigPredeployNamespace, new(big.Int).SetUint64(i))
addr := common.BigToAddress(bigAddr)
// There is no proxy at the governance token address
if addr == predeploys.GovernanceTokenAddr {
continue
}
db.CreateAccount(addr)
db.SetCode(addr, proxy.DeployedBytecode)
db.SetState(addr, AdminSlot, proxyAdmin.Address.Hash())
}
return nil
}
// SetImplementations will set the implmentations of the contracts in the state
// and configure the proxies to point to the implementations. It also sets
// the appropriate storage values for each contract at the proxy address.
func SetImplementations(hh *hardhat.Hardhat, db vm.StateDB, storage StorageConfig) error {
deployResults, err := immutables.BuildOptimism()
if err != nil {
return err
}
for name, address := range predeploys.Predeploys {
// Get the hardhat artifact to access the deployed bytecode
artifact, err := hh.GetArtifact(name)
if err != nil {
return err
}
// Convert the address to the code address
var addr common.Address
switch *address {
case predeploys.GovernanceTokenAddr:
addr = predeploys.GovernanceTokenAddr
case predeploys.LegacyERC20ETHAddr:
addr = predeploys.LegacyERC20ETHAddr
default:
addr, err = AddressToCodeNamespace(*address)
if err != nil {
return err
}
// Set the implmentation slot in the predeploy proxy
db.SetState(*address, ImplementationSlot, addr.Hash())
}
// Create the account
db.CreateAccount(addr)
// Use the genrated bytecode when there are immutables
// otherwise use the artifact deployed bytecode
if bytecode, ok := deployResults[name]; ok {
db.SetCode(addr, bytecode)
} else {
db.SetCode(addr, artifact.DeployedBytecode)
}
// Set the storage values
if storageConfig, ok := storage[name]; ok {
layout, err := hh.GetStorageLayout(name)
if err != nil {
return err
}
slots, err := state.ComputeStorageSlots(layout, storageConfig)
if err != nil {
return err
}
// The storage values must go in the proxy address
for _, slot := range slots {
db.SetState(*address, slot.Key, slot.Value)
}
}
code := db.GetCode(addr)
if len(code) == 0 {
return fmt.Errorf("code not set for %s", name)
}
}
return nil
}
// AddressToCodeNamespace takes a predeploy address and computes
// the implmentation address that the implementation should be deployed at
func AddressToCodeNamespace(addr common.Address) (common.Address, error) {
......@@ -181,37 +70,6 @@ func AddressToCodeNamespace(addr common.Address) (common.Address, error) {
return common.BigToAddress(num), nil
}
// Get the storage layout of the L2ToL1MessagePasser
// Iterate over the storage layout to know which storage slots to ignore
// Iterate over each storage slot, compute the migration
func MigrateDepositHashes(hh *hardhat.Hardhat, db vm.StateDB) error {
layout, err := hh.GetStorageLayout("L2ToL1MessagePasser")
if err != nil {
return err
}
// Build a list of storage slots to ignore. The values in the
// mapping are guaranteed to not be in this list because they are
// hashes.
ignore := make(map[common.Hash]bool)
for _, entry := range layout.Storage {
encoded, err := state.EncodeUintValue(entry.Slot, 0)
if err != nil {
return err
}
ignore[encoded] = true
}
db.ForEachStorage(predeploys.L2ToL1MessagePasserAddr, func(key, value common.Hash) bool {
if _, ok := ignore[key]; ok {
return true
}
// TODO(tynes): Do the value migration here
return true
})
return nil
}
// getBlockFromTag will resolve a Block given an rpc block tag
func getBlockFromTag(chain ethereum.ChainReader, tag rpc.BlockNumberOrHash) (*types.Block, error) {
if hash, ok := tag.Hash(); ok {
......
......@@ -15,8 +15,7 @@ func BuildL1DeveloperGenesis(hh *hardhat.Hardhat, config *DeployConfig) (*core.G
db := state.NewMemoryStateDB(genesis)
if config.FundDevAccounts {
FundDevAccounts(db)
}
FundDevAccounts(db)
return db.Genesis(), nil
}
......@@ -8,19 +8,23 @@ import (
"github.com/ethereum/go-ethereum/core"
)
// BuildOptimismGenesis
func BuildOptimismGenesis(hh *hardhat.Hardhat, config *DeployConfig, chain ethereum.ChainReader) (*core.Genesis, error) {
genesis, err := NewL2Genesis(config, chain)
// BuildOptimismDeveloperGenesis will build the developer Optimism Genesis
// Block. Suitable for devnets.
func BuildOptimismDeveloperGenesis(hh *hardhat.Hardhat, config *DeployConfig, chain ethereum.ChainReader) (*core.Genesis, error) {
genspec, err := NewL2Genesis(config, chain)
if err != nil {
return nil, err
}
db := state.NewMemoryStateDB(genesis)
db := state.NewMemoryStateDB(genspec)
if config.FundDevAccounts {
FundDevAccounts(db)
}
FundDevAccounts(db)
return BuildOptimismGenesis(db, hh, config, chain)
}
// BuildOptimismGenesis will build the L2 Optimism Genesis Block
func BuildOptimismGenesis(db *state.MemoryStateDB, hh *hardhat.Hardhat, config *DeployConfig, chain ethereum.ChainReader) (*core.Genesis, error) {
// TODO(tynes): need a function for clearing old, unused storage slots.
// Each deployed contract on L2 needs to have its existing storage
// inspected and then cleared if they are no longer used.
......
......@@ -46,12 +46,14 @@ func TestBuildOptimismGenesis(t *testing.T) {
15000000,
)
gen, err := genesis.BuildOptimismGenesis(hh, config, backend)
gen, err := genesis.BuildOptimismDeveloperGenesis(hh, config, backend)
require.Nil(t, err)
require.NotNil(t, gen)
proxyAdmin, err := hh.GetDeployment("ProxyAdmin")
require.Nil(t, err)
proxy, err := hh.GetArtifact("Proxy")
require.Nil(t, err)
for name, address := range predeploys.Predeploys {
addr := *address
......@@ -67,6 +69,7 @@ func TestBuildOptimismGenesis(t *testing.T) {
adminSlot, ok := account.Storage[genesis.AdminSlot]
require.Equal(t, ok, true)
require.Equal(t, adminSlot, proxyAdmin.Address.Hash())
require.Equal(t, account.Code, []byte(proxy.DeployedBytecode))
}
if writeFile {
......
package genesis
import (
"fmt"
"math/big"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/hardhat"
"github.com/ethereum-optimism/optimism/op-chain-ops/immutables"
"github.com/ethereum-optimism/optimism/op-chain-ops/state"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/vm"
)
// FundDevAccounts will fund each of the development accounts.
func FundDevAccounts(db vm.StateDB) {
for _, account := range DevAccounts {
db.CreateAccount(account)
db.AddBalance(account, devBalance)
}
}
// SetProxies will set each of the proxies in the state. It requires
// a Proxy and ProxyAdmin deployment present so that the Proxy bytecode
// can be set in state and the ProxyAdmin can be set as the admin of the
// Proxy.
func SetProxies(hh *hardhat.Hardhat, db vm.StateDB) error {
proxy, err := hh.GetArtifact("Proxy")
if err != nil {
return err
}
proxyAdmin, err := hh.GetDeployment("ProxyAdmin")
if err != nil {
return err
}
for i := uint64(0); i <= 2048; i++ {
bigAddr := new(big.Int).Or(bigPredeployNamespace, new(big.Int).SetUint64(i))
addr := common.BigToAddress(bigAddr)
// There is no proxy at the governance token address
if addr == predeploys.GovernanceTokenAddr {
continue
}
db.CreateAccount(addr)
db.SetCode(addr, proxy.DeployedBytecode)
db.SetState(addr, AdminSlot, proxyAdmin.Address.Hash())
}
return nil
}
// SetImplementations will set the implmentations of the contracts in the state
// and configure the proxies to point to the implementations. It also sets
// the appropriate storage values for each contract at the proxy address.
func SetImplementations(hh *hardhat.Hardhat, db vm.StateDB, storage StorageConfig) error {
deployResults, err := immutables.BuildOptimism()
if err != nil {
return err
}
for name, address := range predeploys.Predeploys {
// Get the hardhat artifact to access the deployed bytecode
artifact, err := hh.GetArtifact(name)
if err != nil {
return err
}
// Convert the address to the code address
var addr common.Address
switch *address {
case predeploys.GovernanceTokenAddr:
addr = predeploys.GovernanceTokenAddr
case predeploys.LegacyERC20ETHAddr:
addr = predeploys.LegacyERC20ETHAddr
default:
addr, err = AddressToCodeNamespace(*address)
if err != nil {
return err
}
// Set the implmentation slot in the predeploy proxy
db.SetState(*address, ImplementationSlot, addr.Hash())
}
// Create the account
db.CreateAccount(addr)
// Use the genrated bytecode when there are immutables
// otherwise use the artifact deployed bytecode
if bytecode, ok := deployResults[name]; ok {
db.SetCode(addr, bytecode)
} else {
db.SetCode(addr, artifact.DeployedBytecode)
}
// Set the storage values
if storageConfig, ok := storage[name]; ok {
layout, err := hh.GetStorageLayout(name)
if err != nil {
return err
}
slots, err := state.ComputeStorageSlots(layout, storageConfig)
if err != nil {
return err
}
// The storage values must go in the proxy address
for _, slot := range slots {
db.SetState(*address, slot.Key, slot.Value)
}
}
code := db.GetCode(addr)
if len(code) == 0 {
return fmt.Errorf("code not set for %s", name)
}
}
return nil
}
// Get the storage layout of the L2ToL1MessagePasser
// Iterate over the storage layout to know which storage slots to ignore
// Iterate over each storage slot, compute the migration
func MigrateDepositHashes(hh *hardhat.Hardhat, db vm.StateDB) error {
layout, err := hh.GetStorageLayout("L2ToL1MessagePasser")
if err != nil {
return err
}
// Build a list of storage slots to ignore. The values in the
// mapping are guaranteed to not be in this list because they are
// hashes.
ignore := make(map[common.Hash]bool)
for _, entry := range layout.Storage {
encoded, err := state.EncodeUintValue(entry.Slot, 0)
if err != nil {
return err
}
ignore[encoded] = true
}
db.ForEachStorage(predeploys.L2ToL1MessagePasserAddr, func(key, value common.Hash) bool {
if _, ok := ignore[key]; ok {
return true
}
// TODO(tynes): Do the value migration here
return true
})
return nil
}
......@@ -22,7 +22,6 @@
"optimismBaseFeeRecipient": "0xBcd4042DE499D14e55001CcbB24a551F3b954096",
"optimismL1FeeRecipient": "0x71bE63f3384f5fb98995898A86B02Fb2426c5788",
"fundDevAccounts": true,
"deploymentWaitConfirmations": 1
}
......@@ -19,7 +19,6 @@
"optimismBaseFeeRecipient": "0xf116a24056b647e3211d095c667e951536cdebaa",
"optimismL1FeeRecipient": "0xc731837b696ca3d9720d23336925368ceaa58f83",
"fundDevAccounts": true,
"deploymentWaitConfirmations": 1
}
......@@ -17,7 +17,5 @@
"l2OutputOracleProposer": "0x70997970C51812dc3A010C7d01b50e0d17dc79C8",
"l2OutputOracleOwner": "0x70997970C51812dc3A010C7d01b50e0d17dc79C8",
"fundDevAccounts": true,
"deploymentWaitConfirmations": 1
}
......@@ -320,10 +320,6 @@ const config: HardhatUserConfig = {
type: 'number',
default: 6,
},
fundDevAccounts: {
type: 'boolean',
default: false,
},
deploymentWaitConfirmations: {
type: 'number',
default: 1,
......
......@@ -39,36 +39,34 @@ task('genesis-l1', 'create a genesis config')
}
}
if (deployConfig.fundDevAccounts) {
const accounts = [
'0x14dC79964da2C08b23698B3D3cc7Ca32193d9955',
'0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65',
'0x1CBd3b2770909D4e10f157cABC84C7264073C9Ec',
'0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f',
'0x2546BcD3c84621e976D8185a91A922aE77ECEc30',
'0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC',
'0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
'0x71bE63f3384f5fb98995898A86B02Fb2426c5788',
'0x8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199',
'0x90F79bf6EB2c4f870365E785982E1f101E93b906',
'0x976EA74026E726554dB657fA54763abd0C3a0aa9',
'0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc',
'0xBcd4042DE499D14e55001CcbB24a551F3b954096',
'0xFABB0ac9d68B0B445fB7357272Ff202C5651694a',
'0xa0Ee7A142d267C1f36714E4a8F75612F20a79720',
'0xbDA5747bFD65F08deb54cb465eB87D40e51B197E',
'0xcd3B766CCDd6AE721141F452C550Ca635964ce71',
'0xdD2FD4581271e230360230F9337D5c0430Bf44C0',
'0xdF3e18d64BC6A983f673Ab319CCaE4f1a57C7097',
'0xde3829a23df1479438622a08a116e8eb3f620bb5',
'0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
]
const accounts = [
'0x14dC79964da2C08b23698B3D3cc7Ca32193d9955',
'0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65',
'0x1CBd3b2770909D4e10f157cABC84C7264073C9Ec',
'0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f',
'0x2546BcD3c84621e976D8185a91A922aE77ECEc30',
'0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC',
'0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
'0x71bE63f3384f5fb98995898A86B02Fb2426c5788',
'0x8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199',
'0x90F79bf6EB2c4f870365E785982E1f101E93b906',
'0x976EA74026E726554dB657fA54763abd0C3a0aa9',
'0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc',
'0xBcd4042DE499D14e55001CcbB24a551F3b954096',
'0xFABB0ac9d68B0B445fB7357272Ff202C5651694a',
'0xa0Ee7A142d267C1f36714E4a8F75612F20a79720',
'0xbDA5747bFD65F08deb54cb465eB87D40e51B197E',
'0xcd3B766CCDd6AE721141F452C550Ca635964ce71',
'0xdD2FD4581271e230360230F9337D5c0430Bf44C0',
'0xdF3e18d64BC6A983f673Ab319CCaE4f1a57C7097',
'0xde3829a23df1479438622a08a116e8eb3f620bb5',
'0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
]
for (const account of accounts) {
alloc[ethers.utils.getAddress(account)] = {
balance:
'0x200000000000000000000000000000000000000000000000000000000000000',
}
for (const account of accounts) {
alloc[ethers.utils.getAddress(account)] = {
balance:
'0x200000000000000000000000000000000000000000000000000000000000000',
}
}
......
......@@ -380,36 +380,34 @@ task('genesis-l2', 'create a genesis config')
}
}
if (deployConfig.fundDevAccounts) {
const accounts = [
'0x14dC79964da2C08b23698B3D3cc7Ca32193d9955',
'0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65',
'0x1CBd3b2770909D4e10f157cABC84C7264073C9Ec',
'0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f',
'0x2546BcD3c84621e976D8185a91A922aE77ECEc30',
'0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC',
'0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
'0x71bE63f3384f5fb98995898A86B02Fb2426c5788',
'0x8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199',
'0x90F79bf6EB2c4f870365E785982E1f101E93b906',
'0x976EA74026E726554dB657fA54763abd0C3a0aa9',
'0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc',
'0xBcd4042DE499D14e55001CcbB24a551F3b954096',
'0xFABB0ac9d68B0B445fB7357272Ff202C5651694a',
'0xa0Ee7A142d267C1f36714E4a8F75612F20a79720',
'0xbDA5747bFD65F08deb54cb465eB87D40e51B197E',
'0xcd3B766CCDd6AE721141F452C550Ca635964ce71',
'0xdD2FD4581271e230360230F9337D5c0430Bf44C0',
'0xdF3e18d64BC6A983f673Ab319CCaE4f1a57C7097',
'0xde3829a23df1479438622a08a116e8eb3f620bb5',
'0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
]
for (const account of accounts) {
alloc[account] = {
balance:
'0x200000000000000000000000000000000000000000000000000000000000000',
}
const accounts = [
'0x14dC79964da2C08b23698B3D3cc7Ca32193d9955',
'0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65',
'0x1CBd3b2770909D4e10f157cABC84C7264073C9Ec',
'0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f',
'0x2546BcD3c84621e976D8185a91A922aE77ECEc30',
'0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC',
'0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
'0x71bE63f3384f5fb98995898A86B02Fb2426c5788',
'0x8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199',
'0x90F79bf6EB2c4f870365E785982E1f101E93b906',
'0x976EA74026E726554dB657fA54763abd0C3a0aa9',
'0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc',
'0xBcd4042DE499D14e55001CcbB24a551F3b954096',
'0xFABB0ac9d68B0B445fB7357272Ff202C5651694a',
'0xa0Ee7A142d267C1f36714E4a8F75612F20a79720',
'0xbDA5747bFD65F08deb54cb465eB87D40e51B197E',
'0xcd3B766CCDd6AE721141F452C550Ca635964ce71',
'0xdD2FD4581271e230360230F9337D5c0430Bf44C0',
'0xdF3e18d64BC6A983f673Ab319CCaE4f1a57C7097',
'0xde3829a23df1479438622a08a116e8eb3f620bb5',
'0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
]
for (const account of accounts) {
alloc[account] = {
balance:
'0x200000000000000000000000000000000000000000000000000000000000000',
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment