Skip to content

Commit

Permalink
state: remote state download (ethereum#137)
Browse files Browse the repository at this point in the history
* remote state: decouple state dumps from codebase

* uat: add default regenesis

* core: fix comment

* bugfix: wrong value

* fixes: default value ensure

* quick fixes

* fix comment

* eth: default use the master state

* node: remove os getenv

* skip unused test

* workflows: remove buildkit

* debugging ci

* fix bulid

* test: update

* internal: revert debug commit

* les: remove dead test

* gitflows: add back docker_buildkit
  • Loading branch information
tynes authored Dec 8, 2020
1 parent d24b127 commit f8b6a24
Show file tree
Hide file tree
Showing 19 changed files with 179 additions and 213,805 deletions.
1 change: 1 addition & 0 deletions cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ var (
// Enable verifier mode
utils.RollupEnableVerifierFlag,
utils.RollupAddressManagerOwnerAddressFlag,
utils.RollupStateDumpPathFlag,
}

rpcFlags = []cli.Flag{
Expand Down
1 change: 1 addition & 0 deletions cmd/geth/usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ var AppHelpFlagGroups = []flagGroup{
utils.Eth1HTTPFlag,
utils.RollupAddressManagerOwnerAddressFlag,
utils.RollupEnableVerifierFlag,
utils.RollupStateDumpPathFlag,
},
},
{
Expand Down
33 changes: 24 additions & 9 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,12 @@ var (
Value: "0x0000000000000000000000000000000000000000",
EnvVar: "ROLLUP_ADDRESS_MANAGER_OWNER_ADDRESS",
}
RollupStateDumpPathFlag = cli.StringFlag{
Name: "rollup.statedumppath",
Usage: "Path to the state dump",
Value: eth.DefaultConfig.Rollup.StateDumpPath,
EnvVar: "ROLLUP_STATE_DUMP_PATH",
}
)

// MakeDataDir retrieves the currently requested data directory, terminating
Expand Down Expand Up @@ -1114,14 +1120,6 @@ func setEth1(ctx *cli.Context, cfg *rollup.Config) {
if ctx.GlobalIsSet(MinerGasTargetFlag.Name) {
cfg.GasLimit = ctx.GlobalUint64(MinerGasTargetFlag.Name)
}
if ctx.GlobalIsSet(RollupAddressManagerOwnerAddressFlag.Name) {
addr := ctx.GlobalString(RollupAddressManagerOwnerAddressFlag.Name)
cfg.AddressManagerOwnerAddress = common.HexToAddress(addr)
}
if ctx.GlobalIsSet(RollupEnableVerifierFlag.Name) {
cfg.IsVerifier = true
}

var (
hex = ctx.GlobalString(TxIngestionSignerKeyHexFlag.Name)
file = ctx.GlobalString(TxIngestionSignerKeyFileFlag.Name)
Expand All @@ -1144,6 +1142,21 @@ func setEth1(ctx *cli.Context, cfg *rollup.Config) {
}
}

func setRollup(ctx *cli.Context, cfg *rollup.Config) {
if ctx.GlobalIsSet(RollupAddressManagerOwnerAddressFlag.Name) {
addr := ctx.GlobalString(RollupAddressManagerOwnerAddressFlag.Name)
cfg.AddressManagerOwnerAddress = common.HexToAddress(addr)
}
if ctx.GlobalIsSet(RollupEnableVerifierFlag.Name) {
cfg.IsVerifier = true
}
if ctx.GlobalIsSet(RollupStateDumpPathFlag.Name) {
cfg.StateDumpPath = ctx.GlobalString(RollupStateDumpPathFlag.Name)
} else {
cfg.StateDumpPath = eth.DefaultConfig.Rollup.StateDumpPath
}
}

// setLes configures the les server and ultra light client settings from the command line flags.
func setLes(ctx *cli.Context, cfg *eth.Config) {
if ctx.GlobalIsSet(LightLegacyServFlag.Name) {
Expand Down Expand Up @@ -1602,6 +1615,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
setWhitelist(ctx, cfg)
setLes(ctx, cfg)
setEth1(ctx, &cfg.Rollup)
setRollup(ctx, &cfg.Rollup)

if ctx.GlobalIsSet(SyncModeFlag.Name) {
cfg.SyncMode = *GlobalTextMarshaler(ctx, SyncModeFlag.Name).(*downloader.SyncMode)
Expand Down Expand Up @@ -1692,7 +1706,8 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {

xdomainAddress := cfg.Rollup.L1CrossDomainMessengerAddress
addrManagerOwnerAddress := cfg.Rollup.AddressManagerOwnerAddress
cfg.Genesis = core.DeveloperGenesisBlock(uint64(ctx.GlobalInt(DeveloperPeriodFlag.Name)), developer.Address, xdomainAddress, addrManagerOwnerAddress)
stateDumpPath := cfg.Rollup.StateDumpPath
cfg.Genesis = core.DeveloperGenesisBlock(uint64(ctx.GlobalInt(DeveloperPeriodFlag.Name)), developer.Address, xdomainAddress, addrManagerOwnerAddress, stateDumpPath)
if !ctx.GlobalIsSet(MinerGasPriceFlag.Name) && !ctx.GlobalIsSet(MinerLegacyGasPriceFlag.Name) {
cfg.Miner.GasPrice = big.NewInt(1)
}
Expand Down
6 changes: 2 additions & 4 deletions console/console_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,16 +98,14 @@ func newTester(t *testing.T, confOverride func(*eth.Config)) *tester {
t.Fatalf("failed to create node: %v", err)
}
ethConf := &eth.Config{
Genesis: core.DeveloperGenesisBlock(15, common.Address{}, common.Address{}, common.Address{}),
Genesis: core.DeveloperGenesisBlock(15, common.Address{}, common.Address{}, common.Address{}, ""),
Miner: miner.Config{
Etherbase: common.HexToAddress(testAddress),
},
Ethash: ethash.Config{
PowMode: ethash.ModeTest,
},
Rollup: rollup.Config{
TxIngestionPollInterval: 1 * time.Millisecond,
},
Rollup: rollup.Config{},
}
if confOverride != nil {
confOverride(ethConf)
Expand Down
100 changes: 80 additions & 20 deletions core/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"math/big"
"os"
"net/http"
"sort"
"strings"

Expand All @@ -39,6 +40,7 @@ import (
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rollup/dump"
)

//go:generate gencodec -type Genesis -field-override genesisSpecMarshaling -out gen_genesis.go
Expand Down Expand Up @@ -262,34 +264,39 @@ func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig {
}

// ApplyOvmStateToState applies the initial OVM state to a state object.
func ApplyOvmStateToState(statedb *state.StateDB, xDomainMessengerAddress, addrManagerOwnerAddress common.Address) {
acctKeys := make([]string, len(vm.OvmStateDump.Accounts))
func ApplyOvmStateToState(statedb *state.StateDB, xDomainMessengerAddress, addrManagerOwnerAddress common.Address, stateDump *dump.OvmDump) {
if len(stateDump.Accounts) == 0 {
return
}
acctKeys := make([]string, len(stateDump.Accounts))
i := 0
for k := range vm.OvmStateDump.Accounts {
for k := range stateDump.Accounts {
acctKeys[i] = k
i++
}
sort.Strings(acctKeys)
for _, acctKey := range acctKeys {
account := vm.OvmStateDump.Accounts[acctKey]
account := stateDump.Accounts[acctKey]
statedb.SetCode(account.Address, common.FromHex(account.Code))
statedb.SetNonce(account.Address, account.Nonce)
for key, val := range account.Storage {
statedb.SetState(account.Address, key, common.HexToHash(val))
}
}
AddressManager := vm.OvmStateDump.Accounts["Lib_AddressManager"]
// Set the owner of the address manager
ownerSlot := common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000")
ownerValue := common.BytesToHash(addrManagerOwnerAddress.Bytes())
statedb.SetState(AddressManager.Address, ownerSlot, ownerValue)
log.Info("Setting AddressManager Owner", "owner", addrManagerOwnerAddress.Hex())
// Set the storage slot associated with the cross domain messenger
// to the cross domain messenger address.
slot := common.HexToHash("0x515216935740e67dfdda5cf8e248ea32b3277787818ab59153061ac875c9385e")
value := common.BytesToHash(xDomainMessengerAddress.Bytes())
statedb.SetState(AddressManager.Address, slot, value)
log.Info("Setting CrossDomainMessenger in AddressManager", "address", xDomainMessengerAddress.Hex())
AddressManager, ok := stateDump.Accounts["Lib_AddressManager"]
if ok {
// Set the owner of the address manager
ownerSlot := common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000")
ownerValue := common.BytesToHash(addrManagerOwnerAddress.Bytes())
statedb.SetState(AddressManager.Address, ownerSlot, ownerValue)
log.Info("Setting AddressManager Owner", "owner", addrManagerOwnerAddress.Hex())
// Set the storage slot associated with the cross domain messenger
// to the cross domain messenger address.
slot := common.HexToHash("0x515216935740e67dfdda5cf8e248ea32b3277787818ab59153061ac875c9385e")
value := common.BytesToHash(xDomainMessengerAddress.Bytes())
statedb.SetState(AddressManager.Address, slot, value)
log.Info("Setting CrossDomainMessenger in AddressManager", "address", xDomainMessengerAddress.Hex())
}
}

// ToBlock creates the genesis block and writes state of a genesis specification
Expand All @@ -300,9 +307,9 @@ func (g *Genesis) ToBlock(db ethdb.Database) *types.Block {
}
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))

if os.Getenv("USING_OVM") == "true" {
if vm.UsingOVM {
// OVM_ENABLED
ApplyOvmStateToState(statedb, g.L1CrossDomainMessengerAddress, g.AddressManagerOwnerAddress)
ApplyOvmStateToState(statedb, g.L1CrossDomainMessengerAddress, g.AddressManagerOwnerAddress, g.Config.StateDump)
}

for addr, account := range g.Alloc {
Expand Down Expand Up @@ -429,11 +436,41 @@ func DefaultGoerliGenesisBlock() *Genesis {
}

// DeveloperGenesisBlock returns the 'geth --dev' genesis block.
func DeveloperGenesisBlock(period uint64, faucet, xDomainMessengerAddress, addrManagerOwnerAddress common.Address) *Genesis {
func DeveloperGenesisBlock(period uint64, faucet, xDomainMessengerAddress, addrManagerOwnerAddress common.Address, stateDumpPath string) *Genesis {
// Override the default period to the user requested one
config := *params.AllCliqueProtocolChanges
config.Clique.Period = period

stateDump := dump.OvmDump{}
if vm.UsingOVM {
// Fetch the state dump from the state dump path
if stateDumpPath == "" {
panic("Must pass state dump path")
}
log.Info("Fetching state dump", "path", stateDumpPath)
err := fetchStateDump(stateDumpPath, &stateDump)
if err != nil {
panic(fmt.Sprintf("Cannot fetch state dump: %s", err))
}
_, ok := stateDump.Accounts["Lib_AddressManager"]
if !ok {
panic("Lib_AddressManager not in state dump")
}
_, ok = stateDump.Accounts["OVM_StateManager"]
if !ok {
panic("OVM_StateManager not in state dump")
}
_, ok = stateDump.Accounts["OVM_ExecutionManager"]
if !ok {
panic("OVM_ExecutionManager not in state dump")
}
_, ok = stateDump.Accounts["OVM_SequencerEntrypoint"]
if !ok {
panic("OVM_SequencerEntrypoint not in state dump")
}
}
config.StateDump = &stateDump

// Assemble and return the genesis with the precompiles and faucet pre-funded
return &Genesis{
Config: &config,
Expand Down Expand Up @@ -466,3 +503,26 @@ func decodePrealloc(data string) GenesisAlloc {
}
return ga
}

func fetchStateDump(path string, stateDump *dump.OvmDump) error {
if stateDump == nil {
return errors.New("Unable to fetch state dump")
}
resp, err := http.Get(path)
if resp.StatusCode >= 400 {
return errors.New("State dump not found")
}
if err != nil {
return fmt.Errorf("Unable to GET state dump: %w", err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("Unable to read response body: %w", err)
}
err = json.Unmarshal(body, stateDump)
if err != nil {
return fmt.Errorf("Unable to unmarshal response body: %w", err)
}
return nil
}
3 changes: 2 additions & 1 deletion core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo
return nil, err
}
} else {
msg, err = asOvmMessage(tx, types.MakeSigner(config, header.Number))
decompressor := config.StateDump.Accounts["OVM_SequencerEntrypoint"]
msg, err = asOvmMessage(tx, types.MakeSigner(config, header.Number), decompressor.Address)
if err != nil {
return nil, err
}
Expand Down
16 changes: 8 additions & 8 deletions core/state_transition_ovm.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"math/big"

"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
Expand Down Expand Up @@ -33,10 +34,10 @@ func toExecutionManagerRun(evm *vm.EVM, msg Message) (Message, error) {
msg.Data(),
}

var abi = vm.OvmExecutionManager.ABI
var abi = evm.Context.OvmExecutionManager.ABI
var args = []interface{}{
tx,
vm.OvmStateManager.Address,
evm.Context.OvmStateManager.Address,
}

ret, err := abi.Pack("run", args...)
Expand All @@ -47,7 +48,7 @@ func toExecutionManagerRun(evm *vm.EVM, msg Message) (Message, error) {
outputmsg, err := modMessage(
msg,
msg.From(),
&vm.OvmExecutionManager.Address,
&evm.Context.OvmExecutionManager.Address,
ret,
evm.Context.GasLimit,
)
Expand All @@ -58,7 +59,7 @@ func toExecutionManagerRun(evm *vm.EVM, msg Message) (Message, error) {
return outputmsg, nil
}

func asOvmMessage(tx *types.Transaction, signer types.Signer) (Message, error) {
func asOvmMessage(tx *types.Transaction, signer types.Signer, decompressor common.Address) (Message, error) {
msg, err := tx.AsMessage(signer)
if err != nil {
return msg, err
Expand Down Expand Up @@ -109,11 +110,10 @@ func asOvmMessage(tx *types.Transaction, signer types.Signer) (Message, error) {

// Sequencer transactions get sent to the "sequencer entrypoint," a contract that decompresses
// the incoming transaction data.
decompressor := vm.OvmStateDump.Accounts["OVM_SequencerEntrypoint"]
outmsg, err := modMessage(
msg,
msg.From(),
&(decompressor.Address),
&decompressor,
data.Bytes(),
msg.Gas(),
)
Expand All @@ -127,15 +127,15 @@ func asOvmMessage(tx *types.Transaction, signer types.Signer) (Message, error) {

func EncodeFakeMessage(
msg Message,
account abi.ABI,
) (Message, error) {
var input = []interface{}{
big.NewInt(int64(msg.Gas())),
msg.To(),
msg.Data(),
}

var abi = vm.OvmStateDump.Accounts["mockOVM_ECDSAContractAccount"].ABI
output, err := abi.Pack("qall", input...)
output, err := account.Pack("qall", input...)
if err != nil {
return nil, err
}
Expand Down
8 changes: 4 additions & 4 deletions core/tx_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import (
"fmt"
"math"
"math/big"
"os"
"sort"
"sync"
"time"
Expand All @@ -31,6 +30,7 @@ import (
"github.com/ethereum/go-ethereum/common/prque"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics"
Expand Down Expand Up @@ -1182,7 +1182,7 @@ func (pool *TxPool) reset(oldHead, newHead *types.Header) {

// OVM Change. Do not reinject reorganized transactions
// into the mempool.
if os.Getenv("USING_OVM") != "true" {
if vm.UsingOVM {
// Inject any transactions discarded due to reorgs
log.Debug("Reinjecting stale transactions", "count", len(reinject))
senderCacher.recover(pool.signer, reinject)
Expand Down Expand Up @@ -1228,7 +1228,7 @@ func (pool *TxPool) promoteExecutables(accounts []common.Address) []*types.Trans
var readies types.Transactions
// QueueOriginL1ToL2 transactions do not increment the nonce
// and the sender is the zero address, always promote them.
if os.Getenv("USING_OVM") == "true" {
if vm.UsingOVM {
if addr == (common.Address{}) {
readies = list.Flatten()
for _, tx := range readies {
Expand Down Expand Up @@ -1413,7 +1413,7 @@ func (pool *TxPool) demoteUnexecutables(txn *types.Transaction) {
// Iterate over all accounts and demote any non-executable transactions
for addr, list := range pool.pending {
nonce := pool.currentState.GetNonce(addr)
if os.Getenv("USING_OVM") == "true" {
if vm.UsingOVM {
from, _ := types.Sender(pool.signer, txn)
if txn != nil && bytes.Equal(from.Bytes(), addr.Bytes()) {
nonce = txn.Nonce() + 1
Expand Down
Loading

0 comments on commit f8b6a24

Please sign in to comment.