lotus/chain/gen/genesis/genesis_eth.go

140 lines
4.3 KiB
Go
Raw Normal View History

package genesis
import (
"context"
"fmt"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
actorstypes "github.com/filecoin-project/go-state-types/actors"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/builtin"
"github.com/filecoin-project/go-state-types/manifest"
"github.com/filecoin-project/go-state-types/network"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/actors/adt"
init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init"
"github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/types/ethtypes"
"github.com/filecoin-project/lotus/chain/vm"
)
// EthNullAddresses are the Ethereum addresses we want to create zero-balanced EthAccounts in.
// We may want to add null addresses for precompiles going forward.
var EthNullAddresses = []string{
"0x0000000000000000000000000000000000000000",
}
func SetupEAM(_ context.Context, nst *state.StateTree, nv network.Version) error {
av, err := actorstypes.VersionForNetwork(nv)
if err != nil {
return fmt.Errorf("failed to get actors version for network version %d: %w", nv, err)
}
if av < actorstypes.Version10 {
// Not defined before version 10; migration has to create.
return nil
}
codecid, ok := actors.GetActorCodeID(av, manifest.EamKey)
if !ok {
return fmt.Errorf("failed to get CodeCID for EAM during genesis")
}
header := &types.Actor{
Code: codecid,
Head: vm.EmptyObjectCid,
Balance: big.Zero(),
Address: &builtin.EthereumAddressManagerActorAddr, // so that it can create ETH0
}
return nst.SetActor(builtin.EthereumAddressManagerActorAddr, header)
}
// MakeEthNullAddressActor creates a null address actor at the specified Ethereum address.
func MakeEthNullAddressActor(av actorstypes.Version, addr address.Address) (*types.Actor, error) {
actcid, ok := actors.GetActorCodeID(av, manifest.EthAccountKey)
if !ok {
return nil, xerrors.Errorf("failed to get EthAccount actor code ID for actors version %d", av)
}
act := &types.Actor{
Code: actcid,
Head: vm.EmptyObjectCid,
Nonce: 0,
Balance: big.Zero(),
Address: &addr,
}
return act, nil
}
func SetupEthNullAddresses(ctx context.Context, st *state.StateTree, nv network.Version) ([]address.Address, error) {
av, err := actorstypes.VersionForNetwork(nv)
if err != nil {
return nil, xerrors.Errorf("failed to resolve actors version for network version %d: %w", av, err)
}
if av < actorstypes.Version10 {
// Not defined before version 10.
return nil, nil
}
var ethAddresses []ethtypes.EthAddress
for _, addr := range EthNullAddresses {
a, err := ethtypes.ParseEthAddress(addr)
if err != nil {
return nil, xerrors.Errorf("failed to represent the 0x0 as an EthAddress: %w", err)
}
ethAddresses = append(ethAddresses, a)
}
initAct, err := st.GetActor(builtin.InitActorAddr)
if err != nil {
return nil, xerrors.Errorf("failed to load init actor: %w", err)
}
initState, err := init_.Load(adt.WrapStore(ctx, st.Store), initAct)
if err != nil {
return nil, xerrors.Errorf("failed to load init actor state: %w", err)
}
var ret []address.Address
for _, ethAddr := range ethAddresses {
// Place an EthAccount at the 0x0 Eth Null Address.
f4Addr, err := ethAddr.ToFilecoinAddress()
if err != nil {
return nil, xerrors.Errorf("failed to compute Filecoin address for Eth addr 0x0: %w", err)
}
idAddr, err := initState.MapAddressToNewID(f4Addr)
if err != nil {
return nil, xerrors.Errorf("failed to map addr in init actor: %w", err)
}
actState, err := MakeEthNullAddressActor(av, f4Addr)
if err != nil {
return nil, xerrors.Errorf("failed to create EthAccount actor for null address: %w", err)
}
if err := st.SetActor(idAddr, actState); err != nil {
return nil, xerrors.Errorf("failed to set Eth Null Address EthAccount actor state: %w", err)
}
ret = append(ret, idAddr)
}
initAct.Head, err = st.Store.Put(ctx, initState)
if err != nil {
return nil, xerrors.Errorf("failed to add init actor state to store: %w", err)
}
if err := st.SetActor(builtin.InitActorAddr, initAct); err != nil {
return nil, xerrors.Errorf("failed to set updated state for init actor: %w", err)
}
return ret, nil
}