/
genesis_eth.go
139 lines (114 loc) · 4.26 KB
/
genesis_eth.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
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
}