From b4dc0f7c332556a2e89a1610ebf9184266f484d1 Mon Sep 17 00:00:00 2001 From: Aayush Date: Mon, 28 Feb 2022 22:57:40 -0500 Subject: [PATCH] Implement FIP-0031 --- build/openrpc/full.json.gz | Bin 27023 -> 27023 bytes build/openrpc/miner.json.gz | Bin 13154 -> 13154 bytes build/params_2k.go | 2 + build/params_butterfly.go | 2 + build/params_calibnet.go | 2 + build/params_interop.go | 4 + build/params_mainnet.go | 2 + build/params_shared_vals.go | 2 +- build/params_testground.go | 1 + chain/actors/builtin/account/account.go | 15 + chain/actors/builtin/account/v8.go | 40 ++ chain/actors/builtin/builtin.go | 62 +- chain/actors/builtin/cron/cron.go | 12 +- chain/actors/builtin/cron/v8.go | 35 ++ chain/actors/builtin/init/init.go | 19 +- chain/actors/builtin/init/v8.go | 114 ++++ chain/actors/builtin/market/market.go | 22 +- chain/actors/builtin/market/v8.go | 252 ++++++++ chain/actors/builtin/miner/miner.go | 17 +- chain/actors/builtin/miner/v8.go | 571 ++++++++++++++++++ chain/actors/builtin/multisig/message8.go | 71 +++ chain/actors/builtin/multisig/multisig.go | 32 +- chain/actors/builtin/multisig/v8.go | 119 ++++ chain/actors/builtin/paych/message8.go | 76 +++ chain/actors/builtin/paych/paych.go | 20 +- chain/actors/builtin/paych/v8.go | 130 ++++ chain/actors/builtin/power/power.go | 19 +- chain/actors/builtin/power/v8.go | 187 ++++++ chain/actors/builtin/reward/reward.go | 19 +- chain/actors/builtin/reward/v8.go | 98 +++ chain/actors/builtin/system/system.go | 10 +- chain/actors/builtin/system/v8.go | 35 ++ .../actors/builtin/verifreg/actor.go.template | 2 +- chain/actors/builtin/verifreg/v8.go | 83 +++ chain/actors/builtin/verifreg/verifreg.go | 31 +- chain/actors/policy/policy.go | 84 ++- chain/actors/version.go | 7 +- chain/consensus/filcns/compute_state.go | 2 + chain/consensus/filcns/upgrades.go | 107 ++++ chain/state/statetree.go | 2 +- chain/sync_test.go | 8 + chain/vm/mkactor.go | 3 + chain/vm/runtime.go | 2 + chain/vm/vmi.go | 6 + documentation/en/api-v0-methods-miner.md | 2 +- documentation/en/api-v0-methods.md | 2 +- documentation/en/api-v1-unstable-methods.md | 2 +- gen/inlinegen-data.json | 8 +- go.mod | 1 + go.sum | 3 + itests/kit/ensemble_opts_nv.go | 6 +- lotuspond/front/src/chain/methods.json | 108 ++++ 52 files changed, 2389 insertions(+), 70 deletions(-) create mode 100644 chain/actors/builtin/account/v8.go create mode 100644 chain/actors/builtin/cron/v8.go create mode 100644 chain/actors/builtin/init/v8.go create mode 100644 chain/actors/builtin/market/v8.go create mode 100644 chain/actors/builtin/miner/v8.go create mode 100644 chain/actors/builtin/multisig/message8.go create mode 100644 chain/actors/builtin/multisig/v8.go create mode 100644 chain/actors/builtin/paych/message8.go create mode 100644 chain/actors/builtin/paych/v8.go create mode 100644 chain/actors/builtin/power/v8.go create mode 100644 chain/actors/builtin/reward/v8.go create mode 100644 chain/actors/builtin/system/v8.go create mode 100644 chain/actors/builtin/verifreg/v8.go diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 2261c102e43d406b7c5ee9f32fe6e6669891ea72..cdf7c1e6dd33cdd15786dc523f2032e5a661b481 100644 GIT binary patch delta 5309 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 diff --git a/build/openrpc/miner.json.gz b/build/openrpc/miner.json.gz index 2ef745e363f046bd79be12f9150368b0af11e933..4230d59e1fb6f7e32f95d78b71f50fb8cb1e502c 100644 GIT binary patch delta 11882 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 HAp;Z$AS5=wT%# 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 diff --git a/build/params_2k.go b/build/params_2k.go index aa1beed36a0..19d70282b63 100644 --- a/build/params_2k.go +++ b/build/params_2k.go @@ -48,6 +48,7 @@ var UpgradeHyperdriveHeight = abi.ChainEpoch(-16) var UpgradeChocolateHeight = abi.ChainEpoch(-17) var UpgradeOhSnapHeight = abi.ChainEpoch(-18) +var UpgradeFVM1Height = abi.ChainEpoch(-19) var DrandSchedule = map[abi.ChainEpoch]DrandEnum{ 0: DrandMainnet, @@ -91,6 +92,7 @@ func init() { UpgradeHyperdriveHeight = getUpgradeHeight("LOTUS_HYPERDRIVE_HEIGHT", UpgradeHyperdriveHeight) UpgradeChocolateHeight = getUpgradeHeight("LOTUS_CHOCOLATE_HEIGHT", UpgradeChocolateHeight) UpgradeOhSnapHeight = getUpgradeHeight("LOTUS_OHSNAP_HEIGHT", UpgradeOhSnapHeight) + UpgradeFVM1Height = getUpgradeHeight("LOTUS_FVM1_HEIGHT", UpgradeFVM1Height) BuildType |= Build2k diff --git a/build/params_butterfly.go b/build/params_butterfly.go index 804bdde93ac..2fe758e7278 100644 --- a/build/params_butterfly.go +++ b/build/params_butterfly.go @@ -44,6 +44,8 @@ const UpgradeChocolateHeight = -17 const UpgradeOhSnapHeight = 240 +var UpgradeFVM1Height = abi.ChainEpoch(99999999999999) + func init() { policy.SetConsensusMinerMinPower(abi.NewStoragePower(2 << 30)) policy.SetSupportedProofTypes( diff --git a/build/params_calibnet.go b/build/params_calibnet.go index a8f5b472049..462e03de176 100644 --- a/build/params_calibnet.go +++ b/build/params_calibnet.go @@ -57,6 +57,8 @@ const UpgradeChocolateHeight = 312746 // 2022-02-10T19:23:00Z const UpgradeOhSnapHeight = 682006 +var UpgradeFVM1Height = abi.ChainEpoch(99999999999999) + func init() { policy.SetConsensusMinerMinPower(abi.NewStoragePower(32 << 30)) policy.SetSupportedProofTypes( diff --git a/build/params_interop.go b/build/params_interop.go index a483e7188d5..14c63d1dc86 100644 --- a/build/params_interop.go +++ b/build/params_interop.go @@ -48,6 +48,7 @@ var UpgradeTurboHeight = abi.ChainEpoch(-15) var UpgradeHyperdriveHeight = abi.ChainEpoch(-16) var UpgradeChocolateHeight = abi.ChainEpoch(-17) var UpgradeOhSnapHeight = abi.ChainEpoch(-18) +var UpgradeFVM1Height = abi.ChainEpoch(-19) var DrandSchedule = map[abi.ChainEpoch]DrandEnum{ 0: DrandMainnet, @@ -93,6 +94,9 @@ func init() { UpgradeNorwegianHeight = getUpgradeHeight("LOTUS_NORWEGIAN_HEIGHT", UpgradeNorwegianHeight) UpgradeTurboHeight = getUpgradeHeight("LOTUS_ACTORSV4_HEIGHT", UpgradeTurboHeight) UpgradeHyperdriveHeight = getUpgradeHeight("LOTUS_HYPERDRIVE_HEIGHT", UpgradeHyperdriveHeight) + UpgradeChocolateHeight = getUpgradeHeight("LOTUS_CHOCOLATE_HEIGHT", UpgradeChocolateHeight) + UpgradeOhSnapHeight = getUpgradeHeight("LOTUS_OHSNAP_HEIGHT", UpgradeOhSnapHeight) + UpgradeFVM1Height = getUpgradeHeight("LOTUS_FVM1_HEIGHT", UpgradeFVM1Height) BuildType |= BuildInteropnet SetAddressNetwork(address.Testnet) diff --git a/build/params_mainnet.go b/build/params_mainnet.go index 0a9f6e77552..80051e0d1d7 100644 --- a/build/params_mainnet.go +++ b/build/params_mainnet.go @@ -70,6 +70,8 @@ const UpgradeChocolateHeight = 1231620 // 2022-03-01T15:00:00Z var UpgradeOhSnapHeight = abi.ChainEpoch(1594680) +var UpgradeFVM1Height = abi.ChainEpoch(99999999999999) + func init() { if os.Getenv("LOTUS_USE_TEST_ADDRESSES") != "1" { SetAddressNetwork(address.Mainnet) diff --git a/build/params_shared_vals.go b/build/params_shared_vals.go index 704c84639e2..d8d0a538281 100644 --- a/build/params_shared_vals.go +++ b/build/params_shared_vals.go @@ -34,7 +34,7 @@ const NewestNetworkVersion = network.Version{{.latestNetworkVersion}} /* inline-gen start */ -const NewestNetworkVersion = network.Version15 +const NewestNetworkVersion = network.Version16 /* inline-gen end */ diff --git a/build/params_testground.go b/build/params_testground.go index 41c46d41edf..6718053e6bb 100644 --- a/build/params_testground.go +++ b/build/params_testground.go @@ -100,6 +100,7 @@ var ( UpgradeHyperdriveHeight abi.ChainEpoch = -15 UpgradeChocolateHeight abi.ChainEpoch = -16 UpgradeOhSnapHeight abi.ChainEpoch = -17 + UpgradeFVM1Height abi.ChainEpoch = -18 DrandSchedule = map[abi.ChainEpoch]DrandEnum{ 0: DrandMainnet, diff --git a/chain/actors/builtin/account/account.go b/chain/actors/builtin/account/account.go index 57ea510bb3d..9fb92d88d82 100644 --- a/chain/actors/builtin/account/account.go +++ b/chain/actors/builtin/account/account.go @@ -25,6 +25,8 @@ import ( builtin6 "github.com/filecoin-project/specs-actors/v6/actors/builtin" builtin7 "github.com/filecoin-project/specs-actors/v7/actors/builtin" + + builtin8 "github.com/filecoin-project/specs-actors/v8/actors/builtin" ) func init() { @@ -56,6 +58,10 @@ func init() { builtin.RegisterActorState(builtin7.AccountActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load7(store, root) }) + + builtin.RegisterActorState(builtin8.AccountActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load8(store, root) + }) } var Methods = builtin4.MethodsAccount @@ -84,6 +90,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case builtin7.AccountActorCodeID: return load7(store, act.Head) + case builtin8.AccountActorCodeID: + return load8(store, act.Head) + } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } @@ -112,6 +121,9 @@ func MakeState(store adt.Store, av actors.Version, addr address.Address) (State, case actors.Version7: return make7(store, addr) + case actors.Version8: + return make8(store, addr) + } return nil, xerrors.Errorf("unknown actor version %d", av) } @@ -140,6 +152,9 @@ func GetActorCodeID(av actors.Version) (cid.Cid, error) { case actors.Version7: return builtin7.AccountActorCodeID, nil + case actors.Version8: + return builtin8.AccountActorCodeID, nil + } return cid.Undef, xerrors.Errorf("unknown actor version %d", av) diff --git a/chain/actors/builtin/account/v8.go b/chain/actors/builtin/account/v8.go new file mode 100644 index 00000000000..5404b32620c --- /dev/null +++ b/chain/actors/builtin/account/v8.go @@ -0,0 +1,40 @@ +package account + +import ( + "github.com/filecoin-project/go-address" + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/chain/actors/adt" + + account8 "github.com/filecoin-project/specs-actors/v8/actors/builtin/account" +) + +var _ State = (*state8)(nil) + +func load8(store adt.Store, root cid.Cid) (State, error) { + out := state8{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make8(store adt.Store, addr address.Address) (State, error) { + out := state8{store: store} + out.State = account8.State{Address: addr} + return &out, nil +} + +type state8 struct { + account8.State + store adt.Store +} + +func (s *state8) PubkeyAddress() (address.Address, error) { + return s.Address, nil +} + +func (s *state8) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/builtin.go b/chain/actors/builtin/builtin.go index febbca4796c..079918c5005 100644 --- a/chain/actors/builtin/builtin.go +++ b/chain/actors/builtin/builtin.go @@ -26,47 +26,50 @@ import ( builtin7 "github.com/filecoin-project/specs-actors/v7/actors/builtin" smoothing7 "github.com/filecoin-project/specs-actors/v7/actors/util/smoothing" + builtin8 "github.com/filecoin-project/specs-actors/v8/actors/builtin" + smoothing8 "github.com/filecoin-project/specs-actors/v8/actors/util/smoothing" + "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/cbor" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/types" - miner7 "github.com/filecoin-project/specs-actors/v7/actors/builtin/miner" - proof7 "github.com/filecoin-project/specs-actors/v7/actors/runtime/proof" + miner8 "github.com/filecoin-project/specs-actors/v8/actors/builtin/miner" + proof8 "github.com/filecoin-project/specs-actors/v8/actors/runtime/proof" ) -var SystemActorAddr = builtin7.SystemActorAddr -var BurntFundsActorAddr = builtin7.BurntFundsActorAddr -var CronActorAddr = builtin7.CronActorAddr +var SystemActorAddr = builtin8.SystemActorAddr +var BurntFundsActorAddr = builtin8.BurntFundsActorAddr +var CronActorAddr = builtin8.CronActorAddr var SaftAddress = makeAddress("t0122") var ReserveAddress = makeAddress("t090") var RootVerifierAddress = makeAddress("t080") var ( - ExpectedLeadersPerEpoch = builtin7.ExpectedLeadersPerEpoch + ExpectedLeadersPerEpoch = builtin8.ExpectedLeadersPerEpoch ) const ( - EpochDurationSeconds = builtin7.EpochDurationSeconds - EpochsInDay = builtin7.EpochsInDay - SecondsInDay = builtin7.SecondsInDay + EpochDurationSeconds = builtin8.EpochDurationSeconds + EpochsInDay = builtin8.EpochsInDay + SecondsInDay = builtin8.SecondsInDay ) const ( - MethodSend = builtin7.MethodSend - MethodConstructor = builtin7.MethodConstructor + MethodSend = builtin8.MethodSend + MethodConstructor = builtin8.MethodConstructor ) // These are all just type aliases across actor versions. In the future, that might change // and we might need to do something fancier. -type SectorInfo = proof7.SectorInfo -type ExtendedSectorInfo = proof7.ExtendedSectorInfo -type PoStProof = proof7.PoStProof +type SectorInfo = proof8.SectorInfo +type ExtendedSectorInfo = proof8.ExtendedSectorInfo +type PoStProof = proof8.PoStProof type FilterEstimate = smoothing0.FilterEstimate func QAPowerForWeight(size abi.SectorSize, duration abi.ChainEpoch, dealWeight, verifiedWeight abi.DealWeight) abi.StoragePower { - return miner7.QAPowerForWeight(size, duration, dealWeight, verifiedWeight) + return miner8.QAPowerForWeight(size, duration, dealWeight, verifiedWeight) } func FromV0FilterEstimate(v0 smoothing0.FilterEstimate) FilterEstimate { @@ -111,6 +114,12 @@ func FromV7FilterEstimate(v7 smoothing7.FilterEstimate) FilterEstimate { } +func FromV8FilterEstimate(v8 smoothing8.FilterEstimate) FilterEstimate { + + return (FilterEstimate)(v8) + +} + type ActorStateLoader func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) var ActorStateLoaders = make(map[cid.Cid]ActorStateLoader) @@ -151,6 +160,9 @@ func ActorNameByCode(c cid.Cid) string { case builtin7.IsBuiltinActor(c): return builtin7.ActorNameByCode(c) + case builtin8.IsBuiltinActor(c): + return builtin8.ActorNameByCode(c) + default: return "" } @@ -186,6 +198,10 @@ func IsBuiltinActor(c cid.Cid) bool { return true } + if builtin8.IsBuiltinActor(c) { + return true + } + return false } @@ -219,6 +235,10 @@ func IsAccountActor(c cid.Cid) bool { return true } + if c == builtin8.AccountActorCodeID { + return true + } + return false } @@ -252,6 +272,10 @@ func IsStorageMinerActor(c cid.Cid) bool { return true } + if c == builtin8.StorageMinerActorCodeID { + return true + } + return false } @@ -285,6 +309,10 @@ func IsMultisigActor(c cid.Cid) bool { return true } + if c == builtin8.MultisigActorCodeID { + return true + } + return false } @@ -318,6 +346,10 @@ func IsPaymentChannelActor(c cid.Cid) bool { return true } + if c == builtin8.PaymentChannelActorCodeID { + return true + } + return false } diff --git a/chain/actors/builtin/cron/cron.go b/chain/actors/builtin/cron/cron.go index f27a14ac791..e0a08408b15 100644 --- a/chain/actors/builtin/cron/cron.go +++ b/chain/actors/builtin/cron/cron.go @@ -19,6 +19,8 @@ import ( builtin6 "github.com/filecoin-project/specs-actors/v6/actors/builtin" builtin7 "github.com/filecoin-project/specs-actors/v7/actors/builtin" + + builtin8 "github.com/filecoin-project/specs-actors/v8/actors/builtin" ) func MakeState(store adt.Store, av actors.Version) (State, error) { @@ -45,6 +47,9 @@ func MakeState(store adt.Store, av actors.Version) (State, error) { case actors.Version7: return make7(store) + case actors.Version8: + return make8(store) + } return nil, xerrors.Errorf("unknown actor version %d", av) } @@ -73,14 +78,17 @@ func GetActorCodeID(av actors.Version) (cid.Cid, error) { case actors.Version7: return builtin7.CronActorCodeID, nil + case actors.Version8: + return builtin8.CronActorCodeID, nil + } return cid.Undef, xerrors.Errorf("unknown actor version %d", av) } var ( - Address = builtin7.CronActorAddr - Methods = builtin7.MethodsCron + Address = builtin8.CronActorAddr + Methods = builtin8.MethodsCron ) type State interface { diff --git a/chain/actors/builtin/cron/v8.go b/chain/actors/builtin/cron/v8.go new file mode 100644 index 00000000000..97c0aa980c8 --- /dev/null +++ b/chain/actors/builtin/cron/v8.go @@ -0,0 +1,35 @@ +package cron + +import ( + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/chain/actors/adt" + + cron8 "github.com/filecoin-project/specs-actors/v8/actors/builtin/cron" +) + +var _ State = (*state8)(nil) + +func load8(store adt.Store, root cid.Cid) (State, error) { + out := state8{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make8(store adt.Store) (State, error) { + out := state8{store: store} + out.State = *cron8.ConstructState(cron8.BuiltInEntries()) + return &out, nil +} + +type state8 struct { + cron8.State + store adt.Store +} + +func (s *state8) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/init/init.go b/chain/actors/builtin/init/init.go index 737241ffea0..cdae9b503e5 100644 --- a/chain/actors/builtin/init/init.go +++ b/chain/actors/builtin/init/init.go @@ -27,6 +27,8 @@ import ( builtin6 "github.com/filecoin-project/specs-actors/v6/actors/builtin" builtin7 "github.com/filecoin-project/specs-actors/v7/actors/builtin" + + builtin8 "github.com/filecoin-project/specs-actors/v8/actors/builtin" ) func init() { @@ -58,11 +60,15 @@ func init() { builtin.RegisterActorState(builtin7.InitActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load7(store, root) }) + + builtin.RegisterActorState(builtin8.InitActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load8(store, root) + }) } var ( - Address = builtin7.InitActorAddr - Methods = builtin7.MethodsInit + Address = builtin8.InitActorAddr + Methods = builtin8.MethodsInit ) func Load(store adt.Store, act *types.Actor) (State, error) { @@ -89,6 +95,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case builtin7.InitActorCodeID: return load7(store, act.Head) + case builtin8.InitActorCodeID: + return load8(store, act.Head) + } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } @@ -117,6 +126,9 @@ func MakeState(store adt.Store, av actors.Version, networkName string) (State, e case actors.Version7: return make7(store, networkName) + case actors.Version8: + return make8(store, networkName) + } return nil, xerrors.Errorf("unknown actor version %d", av) } @@ -145,6 +157,9 @@ func GetActorCodeID(av actors.Version) (cid.Cid, error) { case actors.Version7: return builtin7.InitActorCodeID, nil + case actors.Version8: + return builtin8.InitActorCodeID, nil + } return cid.Undef, xerrors.Errorf("unknown actor version %d", av) diff --git a/chain/actors/builtin/init/v8.go b/chain/actors/builtin/init/v8.go new file mode 100644 index 00000000000..1fc2859a0ea --- /dev/null +++ b/chain/actors/builtin/init/v8.go @@ -0,0 +1,114 @@ +package init + +import ( + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + "github.com/ipfs/go-cid" + cbg "github.com/whyrusleeping/cbor-gen" + "golang.org/x/xerrors" + + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/node/modules/dtypes" + + builtin8 "github.com/filecoin-project/specs-actors/v8/actors/builtin" + + init8 "github.com/filecoin-project/specs-actors/v8/actors/builtin/init" + adt8 "github.com/filecoin-project/specs-actors/v8/actors/util/adt" +) + +var _ State = (*state8)(nil) + +func load8(store adt.Store, root cid.Cid) (State, error) { + out := state8{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make8(store adt.Store, networkName string) (State, error) { + out := state8{store: store} + + s, err := init8.ConstructState(store, networkName) + if err != nil { + return nil, err + } + + out.State = *s + + return &out, nil +} + +type state8 struct { + init8.State + store adt.Store +} + +func (s *state8) ResolveAddress(address address.Address) (address.Address, bool, error) { + return s.State.ResolveAddress(s.store, address) +} + +func (s *state8) MapAddressToNewID(address address.Address) (address.Address, error) { + return s.State.MapAddressToNewID(s.store, address) +} + +func (s *state8) ForEachActor(cb func(id abi.ActorID, address address.Address) error) error { + addrs, err := adt8.AsMap(s.store, s.State.AddressMap, builtin8.DefaultHamtBitwidth) + if err != nil { + return err + } + var actorID cbg.CborInt + return addrs.ForEach(&actorID, func(key string) error { + addr, err := address.NewFromBytes([]byte(key)) + if err != nil { + return err + } + return cb(abi.ActorID(actorID), addr) + }) +} + +func (s *state8) NetworkName() (dtypes.NetworkName, error) { + return dtypes.NetworkName(s.State.NetworkName), nil +} + +func (s *state8) SetNetworkName(name string) error { + s.State.NetworkName = name + return nil +} + +func (s *state8) SetNextID(id abi.ActorID) error { + s.State.NextID = id + return nil +} + +func (s *state8) Remove(addrs ...address.Address) (err error) { + m, err := adt8.AsMap(s.store, s.State.AddressMap, builtin8.DefaultHamtBitwidth) + if err != nil { + return err + } + for _, addr := range addrs { + if err = m.Delete(abi.AddrKey(addr)); err != nil { + return xerrors.Errorf("failed to delete entry for address: %s; err: %w", addr, err) + } + } + amr, err := m.Root() + if err != nil { + return xerrors.Errorf("failed to get address map root: %w", err) + } + s.State.AddressMap = amr + return nil +} + +func (s *state8) SetAddressMap(mcid cid.Cid) error { + s.State.AddressMap = mcid + return nil +} + +func (s *state8) AddressMap() (adt.Map, error) { + return adt8.AsMap(s.store, s.State.AddressMap, builtin8.DefaultHamtBitwidth) +} + +func (s *state8) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/market/market.go b/chain/actors/builtin/market/market.go index 6781b55e360..00524f0cb69 100644 --- a/chain/actors/builtin/market/market.go +++ b/chain/actors/builtin/market/market.go @@ -27,6 +27,8 @@ import ( builtin7 "github.com/filecoin-project/specs-actors/v7/actors/builtin" + builtin8 "github.com/filecoin-project/specs-actors/v8/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" @@ -62,11 +64,15 @@ func init() { builtin.RegisterActorState(builtin7.StorageMarketActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load7(store, root) }) + + builtin.RegisterActorState(builtin8.StorageMarketActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load8(store, root) + }) } var ( - Address = builtin7.StorageMarketActorAddr - Methods = builtin7.MethodsMarket + Address = builtin8.StorageMarketActorAddr + Methods = builtin8.MethodsMarket ) func Load(store adt.Store, act *types.Actor) (State, error) { @@ -93,6 +99,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case builtin7.StorageMarketActorCodeID: return load7(store, act.Head) + case builtin8.StorageMarketActorCodeID: + return load8(store, act.Head) + } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } @@ -121,6 +130,9 @@ func MakeState(store adt.Store, av actors.Version) (State, error) { case actors.Version7: return make7(store) + case actors.Version8: + return make8(store) + } return nil, xerrors.Errorf("unknown actor version %d", av) } @@ -149,6 +161,9 @@ func GetActorCodeID(av actors.Version) (cid.Cid, error) { case actors.Version7: return builtin7.StorageMarketActorCodeID, nil + case actors.Version8: + return builtin8.StorageMarketActorCodeID, nil + } return cid.Undef, xerrors.Errorf("unknown actor version %d", av) @@ -229,6 +244,9 @@ func DecodePublishStorageDealsReturn(b []byte, nv network.Version) (PublishStora case actors.Version7: return decodePublishStorageDealsReturn7(b) + case actors.Version8: + return decodePublishStorageDealsReturn8(b) + } return nil, xerrors.Errorf("unknown actor version %d", av) } diff --git a/chain/actors/builtin/market/v8.go b/chain/actors/builtin/market/v8.go new file mode 100644 index 00000000000..d2e6f9189dc --- /dev/null +++ b/chain/actors/builtin/market/v8.go @@ -0,0 +1,252 @@ +package market + +import ( + "bytes" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + "github.com/ipfs/go-cid" + cbg "github.com/whyrusleeping/cbor-gen" + "golang.org/x/xerrors" + + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/types" + + market8 "github.com/filecoin-project/specs-actors/v8/actors/builtin/market" + adt8 "github.com/filecoin-project/specs-actors/v8/actors/util/adt" +) + +var _ State = (*state8)(nil) + +func load8(store adt.Store, root cid.Cid) (State, error) { + out := state8{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make8(store adt.Store) (State, error) { + out := state8{store: store} + + s, err := market8.ConstructState(store) + if err != nil { + return nil, err + } + + out.State = *s + + return &out, nil +} + +type state8 struct { + market8.State + store adt.Store +} + +func (s *state8) TotalLocked() (abi.TokenAmount, error) { + fml := types.BigAdd(s.TotalClientLockedCollateral, s.TotalProviderLockedCollateral) + fml = types.BigAdd(fml, s.TotalClientStorageFee) + return fml, nil +} + +func (s *state8) BalancesChanged(otherState State) (bool, error) { + otherState8, ok := otherState.(*state8) + if !ok { + // there's no way to compare different versions of the state, so let's + // just say that means the state of balances has changed + return true, nil + } + return !s.State.EscrowTable.Equals(otherState8.State.EscrowTable) || !s.State.LockedTable.Equals(otherState8.State.LockedTable), nil +} + +func (s *state8) StatesChanged(otherState State) (bool, error) { + otherState8, ok := otherState.(*state8) + if !ok { + // there's no way to compare different versions of the state, so let's + // just say that means the state of balances has changed + return true, nil + } + return !s.State.States.Equals(otherState8.State.States), nil +} + +func (s *state8) States() (DealStates, error) { + stateArray, err := adt8.AsArray(s.store, s.State.States, market8.StatesAmtBitwidth) + if err != nil { + return nil, err + } + return &dealStates8{stateArray}, nil +} + +func (s *state8) ProposalsChanged(otherState State) (bool, error) { + otherState8, ok := otherState.(*state8) + if !ok { + // there's no way to compare different versions of the state, so let's + // just say that means the state of balances has changed + return true, nil + } + return !s.State.Proposals.Equals(otherState8.State.Proposals), nil +} + +func (s *state8) Proposals() (DealProposals, error) { + proposalArray, err := adt8.AsArray(s.store, s.State.Proposals, market8.ProposalsAmtBitwidth) + if err != nil { + return nil, err + } + return &dealProposals8{proposalArray}, nil +} + +func (s *state8) EscrowTable() (BalanceTable, error) { + bt, err := adt8.AsBalanceTable(s.store, s.State.EscrowTable) + if err != nil { + return nil, err + } + return &balanceTable8{bt}, nil +} + +func (s *state8) LockedTable() (BalanceTable, error) { + bt, err := adt8.AsBalanceTable(s.store, s.State.LockedTable) + if err != nil { + return nil, err + } + return &balanceTable8{bt}, nil +} + +func (s *state8) VerifyDealsForActivation( + minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch, +) (weight, verifiedWeight abi.DealWeight, err error) { + w, vw, _, err := market8.ValidateDealsForActivation(&s.State, s.store, deals, minerAddr, sectorExpiry, currEpoch) + return w, vw, err +} + +func (s *state8) NextID() (abi.DealID, error) { + return s.State.NextID, nil +} + +type balanceTable8 struct { + *adt8.BalanceTable +} + +func (bt *balanceTable8) ForEach(cb func(address.Address, abi.TokenAmount) error) error { + asMap := (*adt8.Map)(bt.BalanceTable) + var ta abi.TokenAmount + return asMap.ForEach(&ta, func(key string) error { + a, err := address.NewFromBytes([]byte(key)) + if err != nil { + return err + } + return cb(a, ta) + }) +} + +type dealStates8 struct { + adt.Array +} + +func (s *dealStates8) Get(dealID abi.DealID) (*DealState, bool, error) { + var deal8 market8.DealState + found, err := s.Array.Get(uint64(dealID), &deal8) + if err != nil { + return nil, false, err + } + if !found { + return nil, false, nil + } + deal := fromV8DealState(deal8) + return &deal, true, nil +} + +func (s *dealStates8) ForEach(cb func(dealID abi.DealID, ds DealState) error) error { + var ds8 market8.DealState + return s.Array.ForEach(&ds8, func(idx int64) error { + return cb(abi.DealID(idx), fromV8DealState(ds8)) + }) +} + +func (s *dealStates8) decode(val *cbg.Deferred) (*DealState, error) { + var ds8 market8.DealState + if err := ds8.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { + return nil, err + } + ds := fromV8DealState(ds8) + return &ds, nil +} + +func (s *dealStates8) array() adt.Array { + return s.Array +} + +func fromV8DealState(v8 market8.DealState) DealState { + return (DealState)(v8) +} + +type dealProposals8 struct { + adt.Array +} + +func (s *dealProposals8) Get(dealID abi.DealID) (*DealProposal, bool, error) { + var proposal8 market8.DealProposal + found, err := s.Array.Get(uint64(dealID), &proposal8) + if err != nil { + return nil, false, err + } + if !found { + return nil, false, nil + } + proposal := fromV8DealProposal(proposal8) + return &proposal, true, nil +} + +func (s *dealProposals8) ForEach(cb func(dealID abi.DealID, dp DealProposal) error) error { + var dp8 market8.DealProposal + return s.Array.ForEach(&dp8, func(idx int64) error { + return cb(abi.DealID(idx), fromV8DealProposal(dp8)) + }) +} + +func (s *dealProposals8) decode(val *cbg.Deferred) (*DealProposal, error) { + var dp8 market8.DealProposal + if err := dp8.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { + return nil, err + } + dp := fromV8DealProposal(dp8) + return &dp, nil +} + +func (s *dealProposals8) array() adt.Array { + return s.Array +} + +func fromV8DealProposal(v8 market8.DealProposal) DealProposal { + return (DealProposal)(v8) +} + +func (s *state8) GetState() interface{} { + return &s.State +} + +var _ PublishStorageDealsReturn = (*publishStorageDealsReturn8)(nil) + +func decodePublishStorageDealsReturn8(b []byte) (PublishStorageDealsReturn, error) { + var retval market8.PublishStorageDealsReturn + if err := retval.UnmarshalCBOR(bytes.NewReader(b)); err != nil { + return nil, xerrors.Errorf("failed to unmarshal PublishStorageDealsReturn: %w", err) + } + + return &publishStorageDealsReturn8{retval}, nil +} + +type publishStorageDealsReturn8 struct { + market8.PublishStorageDealsReturn +} + +func (r *publishStorageDealsReturn8) IsDealValid(index uint64) (bool, error) { + + return r.ValidDeals.IsSet(index) + +} + +func (r *publishStorageDealsReturn8) DealIDs() ([]abi.DealID, error) { + return r.IDs, nil +} diff --git a/chain/actors/builtin/miner/miner.go b/chain/actors/builtin/miner/miner.go index 7889d7a4dff..1e0c46183cf 100644 --- a/chain/actors/builtin/miner/miner.go +++ b/chain/actors/builtin/miner/miner.go @@ -38,6 +38,8 @@ import ( builtin6 "github.com/filecoin-project/specs-actors/v6/actors/builtin" builtin7 "github.com/filecoin-project/specs-actors/v7/actors/builtin" + + builtin8 "github.com/filecoin-project/specs-actors/v8/actors/builtin" ) func init() { @@ -70,9 +72,13 @@ func init() { return load7(store, root) }) + builtin.RegisterActorState(builtin8.StorageMinerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load8(store, root) + }) + } -var Methods = builtin7.MethodsMiner +var Methods = builtin8.MethodsMiner // Unchanged between v0, v2, v3, v4, and v5 actors var WPoStProvingPeriod = miner0.WPoStProvingPeriod @@ -112,6 +118,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case builtin7.StorageMinerActorCodeID: return load7(store, act.Head) + case builtin8.StorageMinerActorCodeID: + return load8(store, act.Head) + } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } @@ -140,6 +149,9 @@ func MakeState(store adt.Store, av actors.Version) (State, error) { case actors.Version7: return make7(store) + case actors.Version8: + return make8(store) + } return nil, xerrors.Errorf("unknown actor version %d", av) } @@ -168,6 +180,9 @@ func GetActorCodeID(av actors.Version) (cid.Cid, error) { case actors.Version7: return builtin7.StorageMinerActorCodeID, nil + case actors.Version8: + return builtin8.StorageMinerActorCodeID, nil + } return cid.Undef, xerrors.Errorf("unknown actor version %d", av) diff --git a/chain/actors/builtin/miner/v8.go b/chain/actors/builtin/miner/v8.go new file mode 100644 index 00000000000..82b8d0e20b1 --- /dev/null +++ b/chain/actors/builtin/miner/v8.go @@ -0,0 +1,571 @@ +package miner + +import ( + "bytes" + "errors" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-bitfield" + rle "github.com/filecoin-project/go-bitfield/rle" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/dline" + "github.com/ipfs/go-cid" + "github.com/libp2p/go-libp2p-core/peer" + cbg "github.com/whyrusleeping/cbor-gen" + "golang.org/x/xerrors" + + "github.com/filecoin-project/lotus/chain/actors/adt" + + builtin8 "github.com/filecoin-project/specs-actors/v8/actors/builtin" + + miner8 "github.com/filecoin-project/specs-actors/v8/actors/builtin/miner" + adt8 "github.com/filecoin-project/specs-actors/v8/actors/util/adt" +) + +var _ State = (*state8)(nil) + +func load8(store adt.Store, root cid.Cid) (State, error) { + out := state8{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make8(store adt.Store) (State, error) { + out := state8{store: store} + out.State = miner8.State{} + return &out, nil +} + +type state8 struct { + miner8.State + store adt.Store +} + +type deadline8 struct { + miner8.Deadline + store adt.Store +} + +type partition8 struct { + miner8.Partition + store adt.Store +} + +func (s *state8) AvailableBalance(bal abi.TokenAmount) (available abi.TokenAmount, err error) { + defer func() { + if r := recover(); r != nil { + err = xerrors.Errorf("failed to get available balance: %w", r) + available = abi.NewTokenAmount(0) + } + }() + // this panics if the miner doesnt have enough funds to cover their locked pledge + available, err = s.GetAvailableBalance(bal) + return available, err +} + +func (s *state8) VestedFunds(epoch abi.ChainEpoch) (abi.TokenAmount, error) { + return s.CheckVestedFunds(s.store, epoch) +} + +func (s *state8) LockedFunds() (LockedFunds, error) { + return LockedFunds{ + VestingFunds: s.State.LockedFunds, + InitialPledgeRequirement: s.State.InitialPledge, + PreCommitDeposits: s.State.PreCommitDeposits, + }, nil +} + +func (s *state8) FeeDebt() (abi.TokenAmount, error) { + return s.State.FeeDebt, nil +} + +func (s *state8) InitialPledge() (abi.TokenAmount, error) { + return s.State.InitialPledge, nil +} + +func (s *state8) PreCommitDeposits() (abi.TokenAmount, error) { + return s.State.PreCommitDeposits, nil +} + +func (s *state8) GetSector(num abi.SectorNumber) (*SectorOnChainInfo, error) { + info, ok, err := s.State.GetSector(s.store, num) + if !ok || err != nil { + return nil, err + } + + ret := fromV8SectorOnChainInfo(*info) + return &ret, nil +} + +func (s *state8) FindSector(num abi.SectorNumber) (*SectorLocation, error) { + dlIdx, partIdx, err := s.State.FindSector(s.store, num) + if err != nil { + return nil, err + } + return &SectorLocation{ + Deadline: dlIdx, + Partition: partIdx, + }, nil +} + +func (s *state8) NumLiveSectors() (uint64, error) { + dls, err := s.State.LoadDeadlines(s.store) + if err != nil { + return 0, err + } + var total uint64 + if err := dls.ForEach(s.store, func(dlIdx uint64, dl *miner8.Deadline) error { + total += dl.LiveSectors + return nil + }); err != nil { + return 0, err + } + return total, nil +} + +// GetSectorExpiration returns the effective expiration of the given sector. +// +// If the sector does not expire early, the Early expiration field is 0. +func (s *state8) GetSectorExpiration(num abi.SectorNumber) (*SectorExpiration, error) { + dls, err := s.State.LoadDeadlines(s.store) + if err != nil { + return nil, err + } + // NOTE: this can be optimized significantly. + // 1. If the sector is non-faulty, it will expire on-time (can be + // learned from the sector info). + // 2. If it's faulty, it will expire early within the first 42 entries + // of the expiration queue. + + stopErr := errors.New("stop") + out := SectorExpiration{} + err = dls.ForEach(s.store, func(dlIdx uint64, dl *miner8.Deadline) error { + partitions, err := dl.PartitionsArray(s.store) + if err != nil { + return err + } + quant := s.State.QuantSpecForDeadline(dlIdx) + var part miner8.Partition + return partitions.ForEach(&part, func(partIdx int64) error { + if found, err := part.Sectors.IsSet(uint64(num)); err != nil { + return err + } else if !found { + return nil + } + if found, err := part.Terminated.IsSet(uint64(num)); err != nil { + return err + } else if found { + // already terminated + return stopErr + } + + q, err := miner8.LoadExpirationQueue(s.store, part.ExpirationsEpochs, quant, miner8.PartitionExpirationAmtBitwidth) + if err != nil { + return err + } + var exp miner8.ExpirationSet + return q.ForEach(&exp, func(epoch int64) error { + if early, err := exp.EarlySectors.IsSet(uint64(num)); err != nil { + return err + } else if early { + out.Early = abi.ChainEpoch(epoch) + return nil + } + if onTime, err := exp.OnTimeSectors.IsSet(uint64(num)); err != nil { + return err + } else if onTime { + out.OnTime = abi.ChainEpoch(epoch) + return stopErr + } + return nil + }) + }) + }) + if err == stopErr { + err = nil + } + if err != nil { + return nil, err + } + if out.Early == 0 && out.OnTime == 0 { + return nil, xerrors.Errorf("failed to find sector %d", num) + } + return &out, nil +} + +func (s *state8) GetPrecommittedSector(num abi.SectorNumber) (*SectorPreCommitOnChainInfo, error) { + info, ok, err := s.State.GetPrecommittedSector(s.store, num) + if !ok || err != nil { + return nil, err + } + + ret := fromV8SectorPreCommitOnChainInfo(*info) + + return &ret, nil +} + +func (s *state8) ForEachPrecommittedSector(cb func(SectorPreCommitOnChainInfo) error) error { + precommitted, err := adt8.AsMap(s.store, s.State.PreCommittedSectors, builtin8.DefaultHamtBitwidth) + if err != nil { + return err + } + + var info miner8.SectorPreCommitOnChainInfo + if err := precommitted.ForEach(&info, func(_ string) error { + return cb(fromV8SectorPreCommitOnChainInfo(info)) + }); err != nil { + return err + } + + return nil +} + +func (s *state8) LoadSectors(snos *bitfield.BitField) ([]*SectorOnChainInfo, error) { + sectors, err := miner8.LoadSectors(s.store, s.State.Sectors) + if err != nil { + return nil, err + } + + // If no sector numbers are specified, load all. + if snos == nil { + infos := make([]*SectorOnChainInfo, 0, sectors.Length()) + var info8 miner8.SectorOnChainInfo + if err := sectors.ForEach(&info8, func(_ int64) error { + info := fromV8SectorOnChainInfo(info8) + infos = append(infos, &info) + return nil + }); err != nil { + return nil, err + } + return infos, nil + } + + // Otherwise, load selected. + infos8, err := sectors.Load(*snos) + if err != nil { + return nil, err + } + infos := make([]*SectorOnChainInfo, len(infos8)) + for i, info8 := range infos8 { + info := fromV8SectorOnChainInfo(*info8) + infos[i] = &info + } + return infos, nil +} + +func (s *state8) loadAllocatedSectorNumbers() (bitfield.BitField, error) { + var allocatedSectors bitfield.BitField + err := s.store.Get(s.store.Context(), s.State.AllocatedSectors, &allocatedSectors) + return allocatedSectors, err +} + +func (s *state8) IsAllocated(num abi.SectorNumber) (bool, error) { + allocatedSectors, err := s.loadAllocatedSectorNumbers() + if err != nil { + return false, err + } + + return allocatedSectors.IsSet(uint64(num)) +} + +func (s *state8) GetProvingPeriodStart() (abi.ChainEpoch, error) { + return s.State.ProvingPeriodStart, nil +} + +func (s *state8) UnallocatedSectorNumbers(count int) ([]abi.SectorNumber, error) { + allocatedSectors, err := s.loadAllocatedSectorNumbers() + if err != nil { + return nil, err + } + + allocatedRuns, err := allocatedSectors.RunIterator() + if err != nil { + return nil, err + } + + unallocatedRuns, err := rle.Subtract( + &rle.RunSliceIterator{Runs: []rle.Run{{Val: true, Len: abi.MaxSectorNumber}}}, + allocatedRuns, + ) + if err != nil { + return nil, err + } + + iter, err := rle.BitsFromRuns(unallocatedRuns) + if err != nil { + return nil, err + } + + sectors := make([]abi.SectorNumber, 0, count) + for iter.HasNext() && len(sectors) < count { + nextNo, err := iter.Next() + if err != nil { + return nil, err + } + sectors = append(sectors, abi.SectorNumber(nextNo)) + } + + return sectors, nil +} + +func (s *state8) GetAllocatedSectors() (*bitfield.BitField, error) { + var allocatedSectors bitfield.BitField + if err := s.store.Get(s.store.Context(), s.State.AllocatedSectors, &allocatedSectors); err != nil { + return nil, err + } + + return &allocatedSectors, nil +} + +func (s *state8) LoadDeadline(idx uint64) (Deadline, error) { + dls, err := s.State.LoadDeadlines(s.store) + if err != nil { + return nil, err + } + dl, err := dls.LoadDeadline(s.store, idx) + if err != nil { + return nil, err + } + return &deadline8{*dl, s.store}, nil +} + +func (s *state8) ForEachDeadline(cb func(uint64, Deadline) error) error { + dls, err := s.State.LoadDeadlines(s.store) + if err != nil { + return err + } + return dls.ForEach(s.store, func(i uint64, dl *miner8.Deadline) error { + return cb(i, &deadline8{*dl, s.store}) + }) +} + +func (s *state8) NumDeadlines() (uint64, error) { + return miner8.WPoStPeriodDeadlines, nil +} + +func (s *state8) DeadlinesChanged(other State) (bool, error) { + other8, ok := other.(*state8) + if !ok { + // treat an upgrade as a change, always + return true, nil + } + + return !s.State.Deadlines.Equals(other8.Deadlines), nil +} + +func (s *state8) MinerInfoChanged(other State) (bool, error) { + other0, ok := other.(*state8) + if !ok { + // treat an upgrade as a change, always + return true, nil + } + return !s.State.Info.Equals(other0.State.Info), nil +} + +func (s *state8) Info() (MinerInfo, error) { + info, err := s.State.GetInfo(s.store) + if err != nil { + return MinerInfo{}, err + } + + var pid *peer.ID + if peerID, err := peer.IDFromBytes(info.PeerId); err == nil { + pid = &peerID + } + + mi := MinerInfo{ + Owner: info.Owner, + Worker: info.Worker, + ControlAddresses: info.ControlAddresses, + + NewWorker: address.Undef, + WorkerChangeEpoch: -1, + + PeerId: pid, + Multiaddrs: info.Multiaddrs, + WindowPoStProofType: info.WindowPoStProofType, + SectorSize: info.SectorSize, + WindowPoStPartitionSectors: info.WindowPoStPartitionSectors, + ConsensusFaultElapsed: info.ConsensusFaultElapsed, + } + + if info.PendingWorkerKey != nil { + mi.NewWorker = info.PendingWorkerKey.NewWorker + mi.WorkerChangeEpoch = info.PendingWorkerKey.EffectiveAt + } + + return mi, nil +} + +func (s *state8) DeadlineInfo(epoch abi.ChainEpoch) (*dline.Info, error) { + return s.State.RecordedDeadlineInfo(epoch), nil +} + +func (s *state8) DeadlineCronActive() (bool, error) { + return s.State.DeadlineCronActive, nil +} + +func (s *state8) sectors() (adt.Array, error) { + return adt8.AsArray(s.store, s.Sectors, miner8.SectorsAmtBitwidth) +} + +func (s *state8) decodeSectorOnChainInfo(val *cbg.Deferred) (SectorOnChainInfo, error) { + var si miner8.SectorOnChainInfo + err := si.UnmarshalCBOR(bytes.NewReader(val.Raw)) + if err != nil { + return SectorOnChainInfo{}, err + } + + return fromV8SectorOnChainInfo(si), nil +} + +func (s *state8) precommits() (adt.Map, error) { + return adt8.AsMap(s.store, s.PreCommittedSectors, builtin8.DefaultHamtBitwidth) +} + +func (s *state8) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (SectorPreCommitOnChainInfo, error) { + var sp miner8.SectorPreCommitOnChainInfo + err := sp.UnmarshalCBOR(bytes.NewReader(val.Raw)) + if err != nil { + return SectorPreCommitOnChainInfo{}, err + } + + return fromV8SectorPreCommitOnChainInfo(sp), nil +} + +func (s *state8) EraseAllUnproven() error { + + dls, err := s.State.LoadDeadlines(s.store) + if err != nil { + return err + } + + err = dls.ForEach(s.store, func(dindx uint64, dl *miner8.Deadline) error { + ps, err := dl.PartitionsArray(s.store) + if err != nil { + return err + } + + var part miner8.Partition + err = ps.ForEach(&part, func(pindx int64) error { + _ = part.ActivateUnproven() + err = ps.Set(uint64(pindx), &part) + return nil + }) + + if err != nil { + return err + } + + dl.Partitions, err = ps.Root() + if err != nil { + return err + } + + return dls.UpdateDeadline(s.store, dindx, dl) + }) + if err != nil { + return err + } + + return s.State.SaveDeadlines(s.store, dls) + +} + +func (d *deadline8) LoadPartition(idx uint64) (Partition, error) { + p, err := d.Deadline.LoadPartition(d.store, idx) + if err != nil { + return nil, err + } + return &partition8{*p, d.store}, nil +} + +func (d *deadline8) ForEachPartition(cb func(uint64, Partition) error) error { + ps, err := d.Deadline.PartitionsArray(d.store) + if err != nil { + return err + } + var part miner8.Partition + return ps.ForEach(&part, func(i int64) error { + return cb(uint64(i), &partition8{part, d.store}) + }) +} + +func (d *deadline8) PartitionsChanged(other Deadline) (bool, error) { + other8, ok := other.(*deadline8) + if !ok { + // treat an upgrade as a change, always + return true, nil + } + + return !d.Deadline.Partitions.Equals(other8.Deadline.Partitions), nil +} + +func (d *deadline8) PartitionsPoSted() (bitfield.BitField, error) { + return d.Deadline.PartitionsPoSted, nil +} + +func (d *deadline8) DisputableProofCount() (uint64, error) { + + ops, err := d.OptimisticProofsSnapshotArray(d.store) + if err != nil { + return 0, err + } + + return ops.Length(), nil + +} + +func (p *partition8) AllSectors() (bitfield.BitField, error) { + return p.Partition.Sectors, nil +} + +func (p *partition8) FaultySectors() (bitfield.BitField, error) { + return p.Partition.Faults, nil +} + +func (p *partition8) RecoveringSectors() (bitfield.BitField, error) { + return p.Partition.Recoveries, nil +} + +func (p *partition8) UnprovenSectors() (bitfield.BitField, error) { + return p.Partition.Unproven, nil +} + +func fromV8SectorOnChainInfo(v8 miner8.SectorOnChainInfo) SectorOnChainInfo { + info := SectorOnChainInfo{ + SectorNumber: v8.SectorNumber, + SealProof: v8.SealProof, + SealedCID: v8.SealedCID, + DealIDs: v8.DealIDs, + Activation: v8.Activation, + Expiration: v8.Expiration, + DealWeight: v8.DealWeight, + VerifiedDealWeight: v8.VerifiedDealWeight, + InitialPledge: v8.InitialPledge, + ExpectedDayReward: v8.ExpectedDayReward, + ExpectedStoragePledge: v8.ExpectedStoragePledge, + + SectorKeyCID: v8.SectorKeyCID, + } + return info +} + +func fromV8SectorPreCommitOnChainInfo(v8 miner8.SectorPreCommitOnChainInfo) SectorPreCommitOnChainInfo { + + return SectorPreCommitOnChainInfo{ + Info: (SectorPreCommitInfo)(v8.Info), + PreCommitDeposit: v8.PreCommitDeposit, + PreCommitEpoch: v8.PreCommitEpoch, + DealWeight: v8.DealWeight, + VerifiedDealWeight: v8.VerifiedDealWeight, + } + +} + +func (s *state8) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/multisig/message8.go b/chain/actors/builtin/multisig/message8.go new file mode 100644 index 00000000000..9852af105ad --- /dev/null +++ b/chain/actors/builtin/multisig/message8.go @@ -0,0 +1,71 @@ +package multisig + +import ( + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + + builtin8 "github.com/filecoin-project/specs-actors/v8/actors/builtin" + init8 "github.com/filecoin-project/specs-actors/v8/actors/builtin/init" + multisig8 "github.com/filecoin-project/specs-actors/v8/actors/builtin/multisig" + + "github.com/filecoin-project/lotus/chain/actors" + init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init" + "github.com/filecoin-project/lotus/chain/types" +) + +type message8 struct{ message0 } + +func (m message8) Create( + signers []address.Address, threshold uint64, + unlockStart, unlockDuration abi.ChainEpoch, + initialAmount abi.TokenAmount, +) (*types.Message, error) { + + lenAddrs := uint64(len(signers)) + + if lenAddrs < threshold { + return nil, xerrors.Errorf("cannot require signing of more addresses than provided for multisig") + } + + if threshold == 0 { + threshold = lenAddrs + } + + if m.from == address.Undef { + return nil, xerrors.Errorf("must provide source address") + } + + // Set up constructor parameters for multisig + msigParams := &multisig8.ConstructorParams{ + Signers: signers, + NumApprovalsThreshold: threshold, + UnlockDuration: unlockDuration, + StartEpoch: unlockStart, + } + + enc, actErr := actors.SerializeParams(msigParams) + if actErr != nil { + return nil, actErr + } + + // new actors are created by invoking 'exec' on the init actor with the constructor params + execParams := &init8.ExecParams{ + CodeCID: builtin8.MultisigActorCodeID, + ConstructorParams: enc, + } + + enc, actErr = actors.SerializeParams(execParams) + if actErr != nil { + return nil, actErr + } + + return &types.Message{ + To: init_.Address, + From: m.from, + Method: builtin8.MethodsInit.Exec, + Params: enc, + Value: initialAmount, + }, nil +} diff --git a/chain/actors/builtin/multisig/multisig.go b/chain/actors/builtin/multisig/multisig.go index f1b50475af4..0ccce071c06 100644 --- a/chain/actors/builtin/multisig/multisig.go +++ b/chain/actors/builtin/multisig/multisig.go @@ -13,7 +13,7 @@ import ( "github.com/ipfs/go-cid" msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig" - msig7 "github.com/filecoin-project/specs-actors/v7/actors/builtin/multisig" + msig8 "github.com/filecoin-project/specs-actors/v8/actors/builtin/multisig" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" @@ -29,6 +29,8 @@ import ( builtin7 "github.com/filecoin-project/specs-actors/v7/actors/builtin" + builtin8 "github.com/filecoin-project/specs-actors/v8/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" @@ -64,6 +66,10 @@ func init() { builtin.RegisterActorState(builtin7.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load7(store, root) }) + + builtin.RegisterActorState(builtin8.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load8(store, root) + }) } func Load(store adt.Store, act *types.Actor) (State, error) { @@ -90,6 +96,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case builtin7.MultisigActorCodeID: return load7(store, act.Head) + case builtin8.MultisigActorCodeID: + return load8(store, act.Head) + } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } @@ -118,6 +127,9 @@ func MakeState(store adt.Store, av actors.Version, signers []address.Address, th case actors.Version7: return make7(store, signers, threshold, startEpoch, unlockDuration, initialBalance) + case actors.Version8: + return make8(store, signers, threshold, startEpoch, unlockDuration, initialBalance) + } return nil, xerrors.Errorf("unknown actor version %d", av) } @@ -146,6 +158,9 @@ func GetActorCodeID(av actors.Version) (cid.Cid, error) { case actors.Version7: return builtin7.MultisigActorCodeID, nil + case actors.Version8: + return builtin8.MultisigActorCodeID, nil + } return cid.Undef, xerrors.Errorf("unknown actor version %d", av) @@ -171,7 +186,7 @@ type State interface { type Transaction = msig0.Transaction -var Methods = builtin7.MethodsMultisig +var Methods = builtin8.MethodsMultisig func Message(version actors.Version, from address.Address) MessageBuilder { switch version { @@ -196,6 +211,9 @@ func Message(version actors.Version, from address.Address) MessageBuilder { case actors.Version7: return message7{message0{from}} + + case actors.Version8: + return message8{message0{from}} default: panic(fmt.Sprintf("unsupported actors version: %d", version)) } @@ -219,13 +237,13 @@ type MessageBuilder interface { } // this type is the same between v0 and v2 -type ProposalHashData = msig7.ProposalHashData -type ProposeReturn = msig7.ProposeReturn -type ProposeParams = msig7.ProposeParams -type ApproveReturn = msig7.ApproveReturn +type ProposalHashData = msig8.ProposalHashData +type ProposeReturn = msig8.ProposeReturn +type ProposeParams = msig8.ProposeParams +type ApproveReturn = msig8.ApproveReturn func txnParams(id uint64, data *ProposalHashData) ([]byte, error) { - params := msig7.TxnIDParams{ID: msig7.TxnID(id)} + params := msig8.TxnIDParams{ID: msig8.TxnID(id)} if data != nil { if data.Requester.Protocol() != address.ID { return nil, xerrors.Errorf("proposer address must be an ID address, was %s", data.Requester) diff --git a/chain/actors/builtin/multisig/v8.go b/chain/actors/builtin/multisig/v8.go new file mode 100644 index 00000000000..9ac8224da40 --- /dev/null +++ b/chain/actors/builtin/multisig/v8.go @@ -0,0 +1,119 @@ +package multisig + +import ( + "bytes" + "encoding/binary" + + adt8 "github.com/filecoin-project/specs-actors/v8/actors/util/adt" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + "github.com/ipfs/go-cid" + cbg "github.com/whyrusleeping/cbor-gen" + "golang.org/x/xerrors" + + "github.com/filecoin-project/lotus/chain/actors/adt" + + builtin8 "github.com/filecoin-project/specs-actors/v8/actors/builtin" + + msig8 "github.com/filecoin-project/specs-actors/v8/actors/builtin/multisig" +) + +var _ State = (*state8)(nil) + +func load8(store adt.Store, root cid.Cid) (State, error) { + out := state8{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make8(store adt.Store, signers []address.Address, threshold uint64, startEpoch abi.ChainEpoch, unlockDuration abi.ChainEpoch, initialBalance abi.TokenAmount) (State, error) { + out := state8{store: store} + out.State = msig8.State{} + out.State.Signers = signers + out.State.NumApprovalsThreshold = threshold + out.State.StartEpoch = startEpoch + out.State.UnlockDuration = unlockDuration + out.State.InitialBalance = initialBalance + + em, err := adt8.StoreEmptyMap(store, builtin8.DefaultHamtBitwidth) + if err != nil { + return nil, err + } + + out.State.PendingTxns = em + + return &out, nil +} + +type state8 struct { + msig8.State + store adt.Store +} + +func (s *state8) LockedBalance(currEpoch abi.ChainEpoch) (abi.TokenAmount, error) { + return s.State.AmountLocked(currEpoch - s.State.StartEpoch), nil +} + +func (s *state8) StartEpoch() (abi.ChainEpoch, error) { + return s.State.StartEpoch, nil +} + +func (s *state8) UnlockDuration() (abi.ChainEpoch, error) { + return s.State.UnlockDuration, nil +} + +func (s *state8) InitialBalance() (abi.TokenAmount, error) { + return s.State.InitialBalance, nil +} + +func (s *state8) Threshold() (uint64, error) { + return s.State.NumApprovalsThreshold, nil +} + +func (s *state8) Signers() ([]address.Address, error) { + return s.State.Signers, nil +} + +func (s *state8) ForEachPendingTxn(cb func(id int64, txn Transaction) error) error { + arr, err := adt8.AsMap(s.store, s.State.PendingTxns, builtin8.DefaultHamtBitwidth) + if err != nil { + return err + } + var out msig8.Transaction + return arr.ForEach(&out, func(key string) error { + txid, n := binary.Varint([]byte(key)) + if n <= 0 { + return xerrors.Errorf("invalid pending transaction key: %v", key) + } + return cb(txid, (Transaction)(out)) //nolint:unconvert + }) +} + +func (s *state8) PendingTxnChanged(other State) (bool, error) { + other8, ok := other.(*state8) + if !ok { + // treat an upgrade as a change, always + return true, nil + } + return !s.State.PendingTxns.Equals(other8.PendingTxns), nil +} + +func (s *state8) transactions() (adt.Map, error) { + return adt8.AsMap(s.store, s.PendingTxns, builtin8.DefaultHamtBitwidth) +} + +func (s *state8) decodeTransaction(val *cbg.Deferred) (Transaction, error) { + var tx msig8.Transaction + if err := tx.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { + return Transaction{}, err + } + return tx, nil +} + +func (s *state8) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/paych/message8.go b/chain/actors/builtin/paych/message8.go new file mode 100644 index 00000000000..f49f457e819 --- /dev/null +++ b/chain/actors/builtin/paych/message8.go @@ -0,0 +1,76 @@ +package paych + +import ( + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + + builtin8 "github.com/filecoin-project/specs-actors/v8/actors/builtin" + init8 "github.com/filecoin-project/specs-actors/v8/actors/builtin/init" + paych8 "github.com/filecoin-project/specs-actors/v8/actors/builtin/paych" + + "github.com/filecoin-project/lotus/chain/actors" + init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init" + "github.com/filecoin-project/lotus/chain/types" +) + +type message8 struct{ from address.Address } + +func (m message8) Create(to address.Address, initialAmount abi.TokenAmount) (*types.Message, error) { + params, aerr := actors.SerializeParams(&paych8.ConstructorParams{From: m.from, To: to}) + if aerr != nil { + return nil, aerr + } + enc, aerr := actors.SerializeParams(&init8.ExecParams{ + CodeCID: builtin8.PaymentChannelActorCodeID, + ConstructorParams: params, + }) + if aerr != nil { + return nil, aerr + } + + return &types.Message{ + To: init_.Address, + From: m.from, + Value: initialAmount, + Method: builtin8.MethodsInit.Exec, + Params: enc, + }, nil +} + +func (m message8) Update(paych address.Address, sv *SignedVoucher, secret []byte) (*types.Message, error) { + params, aerr := actors.SerializeParams(&paych8.UpdateChannelStateParams{ + + Sv: toV8SignedVoucher(*sv), + + Secret: secret, + }) + if aerr != nil { + return nil, aerr + } + + return &types.Message{ + To: paych, + From: m.from, + Value: abi.NewTokenAmount(0), + Method: builtin8.MethodsPaych.UpdateChannelState, + Params: params, + }, nil +} + +func (m message8) Settle(paych address.Address) (*types.Message, error) { + return &types.Message{ + To: paych, + From: m.from, + Value: abi.NewTokenAmount(0), + Method: builtin8.MethodsPaych.Settle, + }, nil +} + +func (m message8) Collect(paych address.Address) (*types.Message, error) { + return &types.Message{ + To: paych, + From: m.from, + Value: abi.NewTokenAmount(0), + Method: builtin8.MethodsPaych.Collect, + }, nil +} diff --git a/chain/actors/builtin/paych/paych.go b/chain/actors/builtin/paych/paych.go index f807b33edce..2e0c932cd83 100644 --- a/chain/actors/builtin/paych/paych.go +++ b/chain/actors/builtin/paych/paych.go @@ -29,6 +29,8 @@ import ( builtin7 "github.com/filecoin-project/specs-actors/v7/actors/builtin" + builtin8 "github.com/filecoin-project/specs-actors/v8/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" @@ -64,6 +66,10 @@ func init() { builtin.RegisterActorState(builtin7.PaymentChannelActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load7(store, root) }) + + builtin.RegisterActorState(builtin8.PaymentChannelActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load8(store, root) + }) } // Load returns an abstract copy of payment channel state, irregardless of actor version @@ -91,6 +97,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case builtin7.PaymentChannelActorCodeID: return load7(store, act.Head) + case builtin8.PaymentChannelActorCodeID: + return load8(store, act.Head) + } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } @@ -119,6 +128,9 @@ func MakeState(store adt.Store, av actors.Version) (State, error) { case actors.Version7: return make7(store) + case actors.Version8: + return make8(store) + } return nil, xerrors.Errorf("unknown actor version %d", av) } @@ -147,6 +159,9 @@ func GetActorCodeID(av actors.Version) (cid.Cid, error) { case actors.Version7: return builtin7.PaymentChannelActorCodeID, nil + case actors.Version8: + return builtin8.PaymentChannelActorCodeID, nil + } return cid.Undef, xerrors.Errorf("unknown actor version %d", av) @@ -200,7 +215,7 @@ func DecodeSignedVoucher(s string) (*SignedVoucher, error) { return &sv, nil } -var Methods = builtin7.MethodsPaych +var Methods = builtin8.MethodsPaych func Message(version actors.Version, from address.Address) MessageBuilder { switch version { @@ -226,6 +241,9 @@ func Message(version actors.Version, from address.Address) MessageBuilder { case actors.Version7: return message7{from} + case actors.Version8: + return message8{from} + default: panic(fmt.Sprintf("unsupported actors version: %d", version)) } diff --git a/chain/actors/builtin/paych/v8.go b/chain/actors/builtin/paych/v8.go new file mode 100644 index 00000000000..06e724e4cc1 --- /dev/null +++ b/chain/actors/builtin/paych/v8.go @@ -0,0 +1,130 @@ +package paych + +import ( + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/big" + + "github.com/filecoin-project/lotus/chain/actors/adt" + + paych8 "github.com/filecoin-project/specs-actors/v8/actors/builtin/paych" + adt8 "github.com/filecoin-project/specs-actors/v8/actors/util/adt" +) + +var _ State = (*state8)(nil) + +func load8(store adt.Store, root cid.Cid) (State, error) { + out := state8{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make8(store adt.Store) (State, error) { + out := state8{store: store} + out.State = paych8.State{} + return &out, nil +} + +type state8 struct { + paych8.State + store adt.Store + lsAmt *adt8.Array +} + +// Channel owner, who has funded the actor +func (s *state8) From() (address.Address, error) { + return s.State.From, nil +} + +// Recipient of payouts from channel +func (s *state8) To() (address.Address, error) { + return s.State.To, nil +} + +// Height at which the channel can be `Collected` +func (s *state8) SettlingAt() (abi.ChainEpoch, error) { + return s.State.SettlingAt, nil +} + +// Amount successfully redeemed through the payment channel, paid out on `Collect()` +func (s *state8) ToSend() (abi.TokenAmount, error) { + return s.State.ToSend, nil +} + +func (s *state8) getOrLoadLsAmt() (*adt8.Array, error) { + if s.lsAmt != nil { + return s.lsAmt, nil + } + + // Get the lane state from the chain + lsamt, err := adt8.AsArray(s.store, s.State.LaneStates, paych8.LaneStatesAmtBitwidth) + if err != nil { + return nil, err + } + + s.lsAmt = lsamt + return lsamt, nil +} + +// Get total number of lanes +func (s *state8) LaneCount() (uint64, error) { + lsamt, err := s.getOrLoadLsAmt() + if err != nil { + return 0, err + } + return lsamt.Length(), nil +} + +func (s *state8) GetState() interface{} { + return &s.State +} + +// Iterate lane states +func (s *state8) ForEachLaneState(cb func(idx uint64, dl LaneState) error) error { + // Get the lane state from the chain + lsamt, err := s.getOrLoadLsAmt() + if err != nil { + return err + } + + // Note: we use a map instead of an array to store laneStates because the + // client sets the lane ID (the index) and potentially they could use a + // very large index. + var ls paych8.LaneState + return lsamt.ForEach(&ls, func(i int64) error { + return cb(uint64(i), &laneState8{ls}) + }) +} + +type laneState8 struct { + paych8.LaneState +} + +func (ls *laneState8) Redeemed() (big.Int, error) { + return ls.LaneState.Redeemed, nil +} + +func (ls *laneState8) Nonce() (uint64, error) { + return ls.LaneState.Nonce, nil +} + +func toV8SignedVoucher(sv SignedVoucher) paych8.SignedVoucher { + return paych8.SignedVoucher{ + ChannelAddr: sv.ChannelAddr, + TimeLockMin: sv.TimeLockMin, + TimeLockMax: sv.TimeLockMax, + SecretHash: sv.SecretPreimage, + Extra: sv.Extra, + Lane: sv.Lane, + Nonce: sv.Nonce, + Amount: sv.Amount, + MinSettleHeight: sv.MinSettleHeight, + Merges: sv.Merges, + Signature: sv.Signature, + } +} diff --git a/chain/actors/builtin/power/power.go b/chain/actors/builtin/power/power.go index 9b73cdd603e..ffc5cd7029a 100644 --- a/chain/actors/builtin/power/power.go +++ b/chain/actors/builtin/power/power.go @@ -28,6 +28,8 @@ import ( builtin6 "github.com/filecoin-project/specs-actors/v6/actors/builtin" builtin7 "github.com/filecoin-project/specs-actors/v7/actors/builtin" + + builtin8 "github.com/filecoin-project/specs-actors/v8/actors/builtin" ) func init() { @@ -59,11 +61,15 @@ func init() { builtin.RegisterActorState(builtin7.StoragePowerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load7(store, root) }) + + builtin.RegisterActorState(builtin8.StoragePowerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load8(store, root) + }) } var ( - Address = builtin7.StoragePowerActorAddr - Methods = builtin7.MethodsPower + Address = builtin8.StoragePowerActorAddr + Methods = builtin8.MethodsPower ) func Load(store adt.Store, act *types.Actor) (State, error) { @@ -90,6 +96,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case builtin7.StoragePowerActorCodeID: return load7(store, act.Head) + case builtin8.StoragePowerActorCodeID: + return load8(store, act.Head) + } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } @@ -118,6 +127,9 @@ func MakeState(store adt.Store, av actors.Version) (State, error) { case actors.Version7: return make7(store) + case actors.Version8: + return make8(store) + } return nil, xerrors.Errorf("unknown actor version %d", av) } @@ -146,6 +158,9 @@ func GetActorCodeID(av actors.Version) (cid.Cid, error) { case actors.Version7: return builtin7.StoragePowerActorCodeID, nil + case actors.Version8: + return builtin8.StoragePowerActorCodeID, nil + } return cid.Undef, xerrors.Errorf("unknown actor version %d", av) diff --git a/chain/actors/builtin/power/v8.go b/chain/actors/builtin/power/v8.go new file mode 100644 index 00000000000..622dd96ba00 --- /dev/null +++ b/chain/actors/builtin/power/v8.go @@ -0,0 +1,187 @@ +package power + +import ( + "bytes" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + "github.com/ipfs/go-cid" + cbg "github.com/whyrusleeping/cbor-gen" + + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin" + + builtin8 "github.com/filecoin-project/specs-actors/v8/actors/builtin" + + power8 "github.com/filecoin-project/specs-actors/v8/actors/builtin/power" + adt8 "github.com/filecoin-project/specs-actors/v8/actors/util/adt" +) + +var _ State = (*state8)(nil) + +func load8(store adt.Store, root cid.Cid) (State, error) { + out := state8{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make8(store adt.Store) (State, error) { + out := state8{store: store} + + s, err := power8.ConstructState(store) + if err != nil { + return nil, err + } + + out.State = *s + + return &out, nil +} + +type state8 struct { + power8.State + store adt.Store +} + +func (s *state8) TotalLocked() (abi.TokenAmount, error) { + return s.TotalPledgeCollateral, nil +} + +func (s *state8) TotalPower() (Claim, error) { + return Claim{ + RawBytePower: s.TotalRawBytePower, + QualityAdjPower: s.TotalQualityAdjPower, + }, nil +} + +// Committed power to the network. Includes miners below the minimum threshold. +func (s *state8) TotalCommitted() (Claim, error) { + return Claim{ + RawBytePower: s.TotalBytesCommitted, + QualityAdjPower: s.TotalQABytesCommitted, + }, nil +} + +func (s *state8) MinerPower(addr address.Address) (Claim, bool, error) { + claims, err := s.claims() + if err != nil { + return Claim{}, false, err + } + var claim power8.Claim + ok, err := claims.Get(abi.AddrKey(addr), &claim) + if err != nil { + return Claim{}, false, err + } + return Claim{ + RawBytePower: claim.RawBytePower, + QualityAdjPower: claim.QualityAdjPower, + }, ok, nil +} + +func (s *state8) MinerNominalPowerMeetsConsensusMinimum(a address.Address) (bool, error) { + return s.State.MinerNominalPowerMeetsConsensusMinimum(s.store, a) +} + +func (s *state8) TotalPowerSmoothed() (builtin.FilterEstimate, error) { + return builtin.FromV8FilterEstimate(s.State.ThisEpochQAPowerSmoothed), nil +} + +func (s *state8) MinerCounts() (uint64, uint64, error) { + return uint64(s.State.MinerAboveMinPowerCount), uint64(s.State.MinerCount), nil +} + +func (s *state8) ListAllMiners() ([]address.Address, error) { + claims, err := s.claims() + if err != nil { + return nil, err + } + + var miners []address.Address + err = claims.ForEach(nil, func(k string) error { + a, err := address.NewFromBytes([]byte(k)) + if err != nil { + return err + } + miners = append(miners, a) + return nil + }) + if err != nil { + return nil, err + } + + return miners, nil +} + +func (s *state8) ForEachClaim(cb func(miner address.Address, claim Claim) error) error { + claims, err := s.claims() + if err != nil { + return err + } + + var claim power8.Claim + return claims.ForEach(&claim, func(k string) error { + a, err := address.NewFromBytes([]byte(k)) + if err != nil { + return err + } + return cb(a, Claim{ + RawBytePower: claim.RawBytePower, + QualityAdjPower: claim.QualityAdjPower, + }) + }) +} + +func (s *state8) ClaimsChanged(other State) (bool, error) { + other8, ok := other.(*state8) + if !ok { + // treat an upgrade as a change, always + return true, nil + } + return !s.State.Claims.Equals(other8.State.Claims), nil +} + +func (s *state8) SetTotalQualityAdjPower(p abi.StoragePower) error { + s.State.TotalQualityAdjPower = p + return nil +} + +func (s *state8) SetTotalRawBytePower(p abi.StoragePower) error { + s.State.TotalRawBytePower = p + return nil +} + +func (s *state8) SetThisEpochQualityAdjPower(p abi.StoragePower) error { + s.State.ThisEpochQualityAdjPower = p + return nil +} + +func (s *state8) SetThisEpochRawBytePower(p abi.StoragePower) error { + s.State.ThisEpochRawBytePower = p + return nil +} + +func (s *state8) GetState() interface{} { + return &s.State +} + +func (s *state8) claims() (adt.Map, error) { + return adt8.AsMap(s.store, s.Claims, builtin8.DefaultHamtBitwidth) +} + +func (s *state8) decodeClaim(val *cbg.Deferred) (Claim, error) { + var ci power8.Claim + if err := ci.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { + return Claim{}, err + } + return fromV8Claim(ci), nil +} + +func fromV8Claim(v8 power8.Claim) Claim { + return Claim{ + RawBytePower: v8.RawBytePower, + QualityAdjPower: v8.QualityAdjPower, + } +} diff --git a/chain/actors/builtin/reward/reward.go b/chain/actors/builtin/reward/reward.go index b6ee2f14668..a83a3362ef9 100644 --- a/chain/actors/builtin/reward/reward.go +++ b/chain/actors/builtin/reward/reward.go @@ -23,6 +23,8 @@ import ( builtin7 "github.com/filecoin-project/specs-actors/v7/actors/builtin" + builtin8 "github.com/filecoin-project/specs-actors/v8/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/types" @@ -57,11 +59,15 @@ func init() { builtin.RegisterActorState(builtin7.RewardActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load7(store, root) }) + + builtin.RegisterActorState(builtin8.RewardActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load8(store, root) + }) } var ( - Address = builtin7.RewardActorAddr - Methods = builtin7.MethodsReward + Address = builtin8.RewardActorAddr + Methods = builtin8.MethodsReward ) func Load(store adt.Store, act *types.Actor) (State, error) { @@ -88,6 +94,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case builtin7.RewardActorCodeID: return load7(store, act.Head) + case builtin8.RewardActorCodeID: + return load8(store, act.Head) + } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } @@ -116,6 +125,9 @@ func MakeState(store adt.Store, av actors.Version, currRealizedPower abi.Storage case actors.Version7: return make7(store, currRealizedPower) + case actors.Version8: + return make8(store, currRealizedPower) + } return nil, xerrors.Errorf("unknown actor version %d", av) } @@ -144,6 +156,9 @@ func GetActorCodeID(av actors.Version) (cid.Cid, error) { case actors.Version7: return builtin7.RewardActorCodeID, nil + case actors.Version8: + return builtin8.RewardActorCodeID, nil + } return cid.Undef, xerrors.Errorf("unknown actor version %d", av) diff --git a/chain/actors/builtin/reward/v8.go b/chain/actors/builtin/reward/v8.go new file mode 100644 index 00000000000..23ebf6f573c --- /dev/null +++ b/chain/actors/builtin/reward/v8.go @@ -0,0 +1,98 @@ +package reward + +import ( + "github.com/filecoin-project/go-state-types/abi" + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin" + + miner8 "github.com/filecoin-project/specs-actors/v8/actors/builtin/miner" + reward8 "github.com/filecoin-project/specs-actors/v8/actors/builtin/reward" + smoothing8 "github.com/filecoin-project/specs-actors/v8/actors/util/smoothing" +) + +var _ State = (*state8)(nil) + +func load8(store adt.Store, root cid.Cid) (State, error) { + out := state8{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make8(store adt.Store, currRealizedPower abi.StoragePower) (State, error) { + out := state8{store: store} + out.State = *reward8.ConstructState(currRealizedPower) + return &out, nil +} + +type state8 struct { + reward8.State + store adt.Store +} + +func (s *state8) ThisEpochReward() (abi.TokenAmount, error) { + return s.State.ThisEpochReward, nil +} + +func (s *state8) ThisEpochRewardSmoothed() (builtin.FilterEstimate, error) { + + return builtin.FilterEstimate{ + PositionEstimate: s.State.ThisEpochRewardSmoothed.PositionEstimate, + VelocityEstimate: s.State.ThisEpochRewardSmoothed.VelocityEstimate, + }, nil + +} + +func (s *state8) ThisEpochBaselinePower() (abi.StoragePower, error) { + return s.State.ThisEpochBaselinePower, nil +} + +func (s *state8) TotalStoragePowerReward() (abi.TokenAmount, error) { + return s.State.TotalStoragePowerReward, nil +} + +func (s *state8) EffectiveBaselinePower() (abi.StoragePower, error) { + return s.State.EffectiveBaselinePower, nil +} + +func (s *state8) EffectiveNetworkTime() (abi.ChainEpoch, error) { + return s.State.EffectiveNetworkTime, nil +} + +func (s *state8) CumsumBaseline() (reward8.Spacetime, error) { + return s.State.CumsumBaseline, nil +} + +func (s *state8) CumsumRealized() (reward8.Spacetime, error) { + return s.State.CumsumRealized, nil +} + +func (s *state8) InitialPledgeForPower(qaPower abi.StoragePower, networkTotalPledge abi.TokenAmount, networkQAPower *builtin.FilterEstimate, circSupply abi.TokenAmount) (abi.TokenAmount, error) { + return miner8.InitialPledgeForPower( + qaPower, + s.State.ThisEpochBaselinePower, + s.State.ThisEpochRewardSmoothed, + smoothing8.FilterEstimate{ + PositionEstimate: networkQAPower.PositionEstimate, + VelocityEstimate: networkQAPower.VelocityEstimate, + }, + circSupply, + ), nil +} + +func (s *state8) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, sectorWeight abi.StoragePower) (abi.TokenAmount, error) { + return miner8.PreCommitDepositForPower(s.State.ThisEpochRewardSmoothed, + smoothing8.FilterEstimate{ + PositionEstimate: networkQAPower.PositionEstimate, + VelocityEstimate: networkQAPower.VelocityEstimate, + }, + sectorWeight), nil +} + +func (s *state8) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/system/system.go b/chain/actors/builtin/system/system.go index fb7515f3547..c4d00e8f128 100644 --- a/chain/actors/builtin/system/system.go +++ b/chain/actors/builtin/system/system.go @@ -19,10 +19,12 @@ import ( builtin6 "github.com/filecoin-project/specs-actors/v6/actors/builtin" builtin7 "github.com/filecoin-project/specs-actors/v7/actors/builtin" + + builtin8 "github.com/filecoin-project/specs-actors/v8/actors/builtin" ) var ( - Address = builtin7.SystemActorAddr + Address = builtin8.SystemActorAddr ) func MakeState(store adt.Store, av actors.Version) (State, error) { @@ -49,6 +51,9 @@ func MakeState(store adt.Store, av actors.Version) (State, error) { case actors.Version7: return make7(store) + case actors.Version8: + return make8(store) + } return nil, xerrors.Errorf("unknown actor version %d", av) } @@ -77,6 +82,9 @@ func GetActorCodeID(av actors.Version) (cid.Cid, error) { case actors.Version7: return builtin7.SystemActorCodeID, nil + case actors.Version8: + return builtin8.SystemActorCodeID, nil + } return cid.Undef, xerrors.Errorf("unknown actor version %d", av) diff --git a/chain/actors/builtin/system/v8.go b/chain/actors/builtin/system/v8.go new file mode 100644 index 00000000000..b218c7a52b9 --- /dev/null +++ b/chain/actors/builtin/system/v8.go @@ -0,0 +1,35 @@ +package system + +import ( + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/chain/actors/adt" + + system8 "github.com/filecoin-project/specs-actors/v8/actors/builtin/system" +) + +var _ State = (*state8)(nil) + +func load8(store adt.Store, root cid.Cid) (State, error) { + out := state8{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make8(store adt.Store) (State, error) { + out := state8{store: store} + out.State = system8.State{} + return &out, nil +} + +type state8 struct { + system8.State + store adt.Store +} + +func (s *state8) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/verifreg/actor.go.template b/chain/actors/builtin/verifreg/actor.go.template index adc15694850..715dd6d6168 100644 --- a/chain/actors/builtin/verifreg/actor.go.template +++ b/chain/actors/builtin/verifreg/actor.go.template @@ -16,7 +16,7 @@ import ( "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/types" - verifreg7 "github.com/filecoin-project/specs-actors/v7/actors/builtin/verifreg" + verifreg{{.latestVersion}} "github.com/filecoin-project/specs-actors/v7/actors/builtin/verifreg" ) func init() { diff --git a/chain/actors/builtin/verifreg/v8.go b/chain/actors/builtin/verifreg/v8.go new file mode 100644 index 00000000000..bb0b199095c --- /dev/null +++ b/chain/actors/builtin/verifreg/v8.go @@ -0,0 +1,83 @@ +package verifreg + +import ( + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/adt" + + builtin8 "github.com/filecoin-project/specs-actors/v8/actors/builtin" + verifreg8 "github.com/filecoin-project/specs-actors/v8/actors/builtin/verifreg" + adt8 "github.com/filecoin-project/specs-actors/v8/actors/util/adt" +) + +var _ State = (*state8)(nil) + +func load8(store adt.Store, root cid.Cid) (State, error) { + out := state8{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make8(store adt.Store, rootKeyAddress address.Address) (State, error) { + out := state8{store: store} + + s, err := verifreg8.ConstructState(store, rootKeyAddress) + if err != nil { + return nil, err + } + + out.State = *s + + return &out, nil +} + +type state8 struct { + verifreg8.State + store adt.Store +} + +func (s *state8) RootKey() (address.Address, error) { + return s.State.RootKey, nil +} + +func (s *state8) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) { + return getDataCap(s.store, actors.Version8, s.verifiedClients, addr) +} + +func (s *state8) VerifierDataCap(addr address.Address) (bool, abi.StoragePower, error) { + return getDataCap(s.store, actors.Version8, s.verifiers, addr) +} + +func (s *state8) RemoveDataCapProposalID(verifier address.Address, client address.Address) (bool, uint64, error) { + return getRemoveDataCapProposalID(s.store, actors.Version8, s.removeDataCapProposalIDs, verifier, client) +} + +func (s *state8) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error { + return forEachCap(s.store, actors.Version8, s.verifiers, cb) +} + +func (s *state8) ForEachClient(cb func(addr address.Address, dcap abi.StoragePower) error) error { + return forEachCap(s.store, actors.Version8, s.verifiedClients, cb) +} + +func (s *state8) verifiedClients() (adt.Map, error) { + return adt8.AsMap(s.store, s.VerifiedClients, builtin8.DefaultHamtBitwidth) +} + +func (s *state8) verifiers() (adt.Map, error) { + return adt8.AsMap(s.store, s.Verifiers, builtin8.DefaultHamtBitwidth) +} + +func (s *state8) removeDataCapProposalIDs() (adt.Map, error) { + return adt8.AsMap(s.store, s.RemoveDataCapProposalIDs, builtin8.DefaultHamtBitwidth) +} + +func (s *state8) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/verifreg/verifreg.go b/chain/actors/builtin/verifreg/verifreg.go index cb26e324b47..35f9db21cb1 100644 --- a/chain/actors/builtin/verifreg/verifreg.go +++ b/chain/actors/builtin/verifreg/verifreg.go @@ -23,11 +23,13 @@ import ( builtin7 "github.com/filecoin-project/specs-actors/v7/actors/builtin" + builtin8 "github.com/filecoin-project/specs-actors/v8/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/types" - verifreg7 "github.com/filecoin-project/specs-actors/v7/actors/builtin/verifreg" + verifreg8 "github.com/filecoin-project/specs-actors/v7/actors/builtin/verifreg" ) func init() { @@ -60,11 +62,15 @@ func init() { return load7(store, root) }) + builtin.RegisterActorState(builtin8.VerifiedRegistryActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load8(store, root) + }) + } var ( - Address = builtin7.VerifiedRegistryActorAddr - Methods = builtin7.MethodsVerifiedRegistry + Address = builtin8.VerifiedRegistryActorAddr + Methods = builtin8.MethodsVerifiedRegistry ) func Load(store adt.Store, act *types.Actor) (State, error) { @@ -91,6 +97,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case builtin7.VerifiedRegistryActorCodeID: return load7(store, act.Head) + case builtin8.VerifiedRegistryActorCodeID: + return load8(store, act.Head) + } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } @@ -119,6 +128,9 @@ func MakeState(store adt.Store, av actors.Version, rootKeyAddress address.Addres case actors.Version7: return make7(store, rootKeyAddress) + case actors.Version8: + return make8(store, rootKeyAddress) + } return nil, xerrors.Errorf("unknown actor version %d", av) } @@ -147,17 +159,20 @@ func GetActorCodeID(av actors.Version) (cid.Cid, error) { case actors.Version7: return builtin7.VerifiedRegistryActorCodeID, nil + case actors.Version8: + return builtin8.VerifiedRegistryActorCodeID, nil + } return cid.Undef, xerrors.Errorf("unknown actor version %d", av) } -type RemoveDataCapProposal = verifreg7.RemoveDataCapProposal -type RemoveDataCapRequest = verifreg7.RemoveDataCapRequest -type RemoveDataCapParams = verifreg7.RemoveDataCapParams -type RmDcProposalID = verifreg7.RmDcProposalID +type RemoveDataCapProposal = verifreg8.RemoveDataCapProposal +type RemoveDataCapRequest = verifreg8.RemoveDataCapRequest +type RemoveDataCapParams = verifreg8.RemoveDataCapParams +type RmDcProposalID = verifreg8.RmDcProposalID -const SignatureDomainSeparation_RemoveDataCap = verifreg7.SignatureDomainSeparation_RemoveDataCap +const SignatureDomainSeparation_RemoveDataCap = verifreg8.SignatureDomainSeparation_RemoveDataCap type State interface { cbor.Marshaler diff --git a/chain/actors/policy/policy.go b/chain/actors/policy/policy.go index f51da7aa7d5..673bbf57cb8 100644 --- a/chain/actors/policy/policy.go +++ b/chain/actors/policy/policy.go @@ -45,14 +45,19 @@ import ( miner7 "github.com/filecoin-project/specs-actors/v7/actors/builtin/miner" verifreg7 "github.com/filecoin-project/specs-actors/v7/actors/builtin/verifreg" - paych7 "github.com/filecoin-project/specs-actors/v7/actors/builtin/paych" + builtin8 "github.com/filecoin-project/specs-actors/v8/actors/builtin" + market8 "github.com/filecoin-project/specs-actors/v8/actors/builtin/market" + miner8 "github.com/filecoin-project/specs-actors/v8/actors/builtin/miner" + verifreg8 "github.com/filecoin-project/specs-actors/v8/actors/builtin/verifreg" + + paych8 "github.com/filecoin-project/specs-actors/v8/actors/builtin/paych" ) const ( - ChainFinality = miner7.ChainFinality + ChainFinality = miner8.ChainFinality SealRandomnessLookback = ChainFinality - PaychSettleDelay = paych7.SettleDelay - MaxPreCommitRandomnessLookback = builtin7.EpochsInDay + SealRandomnessLookback + PaychSettleDelay = paych8.SettleDelay + MaxPreCommitRandomnessLookback = builtin8.EpochsInDay + SealRandomnessLookback ) // SetSupportedProofTypes sets supported proof types, across all actor versions. @@ -79,6 +84,8 @@ func SetSupportedProofTypes(types ...abi.RegisteredSealProof) { miner7.PreCommitSealProofTypesV8 = make(map[abi.RegisteredSealProof]struct{}, len(types)) + miner8.PreCommitSealProofTypesV8 = make(map[abi.RegisteredSealProof]struct{}, len(types)) + AddSupportedProofTypes(types...) } @@ -135,6 +142,15 @@ func AddSupportedProofTypes(types ...abi.RegisteredSealProof) { miner7.WindowPoStProofTypes[wpp] = struct{}{} + miner8.PreCommitSealProofTypesV8[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{} + wpp, err = t.RegisteredWindowPoStProof() + if err != nil { + // Fine to panic, this is a test-only method + panic(err) + } + + miner8.WindowPoStProofTypes[wpp] = struct{}{} + } } @@ -157,11 +173,13 @@ func SetPreCommitChallengeDelay(delay abi.ChainEpoch) { miner7.PreCommitChallengeDelay = delay + miner8.PreCommitChallengeDelay = delay + } // TODO: this function shouldn't really exist. Instead, the API should expose the precommit delay. func GetPreCommitChallengeDelay() abi.ChainEpoch { - return miner7.PreCommitChallengeDelay + return miner8.PreCommitChallengeDelay } // SetConsensusMinerMinPower sets the minimum power of an individual miner must @@ -195,6 +213,10 @@ func SetConsensusMinerMinPower(p abi.StoragePower) { policy.ConsensusMinerMinPower = p } + for _, policy := range builtin8.PoStProofPolicies { + policy.ConsensusMinerMinPower = p + } + } // SetMinVerifiedDealSize sets the minimum size of a verified deal. This should @@ -215,6 +237,8 @@ func SetMinVerifiedDealSize(size abi.StoragePower) { verifreg7.MinVerifiedDealSize = size + verifreg8.MinVerifiedDealSize = size + } func GetMaxProveCommitDuration(ver actors.Version, t abi.RegisteredSealProof) (abi.ChainEpoch, error) { @@ -248,6 +272,10 @@ func GetMaxProveCommitDuration(ver actors.Version, t abi.RegisteredSealProof) (a return miner7.MaxProveCommitDuration[t], nil + case actors.Version8: + + return miner8.MaxProveCommitDuration[t], nil + default: return 0, xerrors.Errorf("unsupported actors version") } @@ -288,6 +316,11 @@ func SetProviderCollateralSupplyTarget(num, denom big.Int) { Denominator: denom, } + market8.ProviderCollateralSupplyTarget = builtin8.BigFrac{ + Numerator: num, + Denominator: denom, + } + } func DealProviderCollateralBounds( @@ -336,13 +369,18 @@ func DealProviderCollateralBounds( min, max := market7.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil) return min, max, nil + case actors.Version8: + + min, max := market8.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil) + return min, max, nil + default: return big.Zero(), big.Zero(), xerrors.Errorf("unsupported actors version") } } func DealDurationBounds(pieceSize abi.PaddedPieceSize) (min, max abi.ChainEpoch) { - return market7.DealDurationBounds(pieceSize) + return market8.DealDurationBounds(pieceSize) } // Sets the challenge window and scales the proving period to match (such that @@ -390,6 +428,13 @@ func SetWPoStChallengeWindow(period abi.ChainEpoch) { // scale it if we're scaling the challenge period. miner7.WPoStDisputeWindow = period * 30 + miner8.WPoStChallengeWindow = period + miner8.WPoStProvingPeriod = period * abi.ChainEpoch(miner8.WPoStPeriodDeadlines) + + // by default, this is 2x finality which is 30 periods. + // scale it if we're scaling the challenge period. + miner8.WPoStDisputeWindow = period * 30 + } func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch { @@ -402,15 +447,15 @@ func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch { } func GetMaxSectorExpirationExtension() abi.ChainEpoch { - return miner7.MaxSectorExpirationExtension + return miner8.MaxSectorExpirationExtension } func GetMinSectorExpiration() abi.ChainEpoch { - return miner7.MinSectorExpiration + return miner8.MinSectorExpiration } func GetMaxPoStPartitions(nv network.Version, p abi.RegisteredPoStProof) (int, error) { - sectorsPerPart, err := builtin7.PoStProofWindowPoStPartitionSectors(p) + sectorsPerPart, err := builtin8.PoStProofWindowPoStPartitionSectors(p) if err != nil { return 0, err } @@ -423,8 +468,8 @@ func GetMaxPoStPartitions(nv network.Version, p abi.RegisteredPoStProof) (int, e func GetDefaultSectorSize() abi.SectorSize { // supported sector sizes are the same across versions. - szs := make([]abi.SectorSize, 0, len(miner7.PreCommitSealProofTypesV8)) - for spt := range miner7.PreCommitSealProofTypesV8 { + szs := make([]abi.SectorSize, 0, len(miner8.PreCommitSealProofTypesV8)) + for spt := range miner8.PreCommitSealProofTypesV8 { ss, err := spt.SectorSize() if err != nil { panic(err) @@ -449,7 +494,7 @@ func GetSectorMaxLifetime(proof abi.RegisteredSealProof, nwVer network.Version) return builtin4.SealProofPoliciesV0[proof].SectorMaxLifetime } - return builtin7.SealProofPoliciesV11[proof].SectorMaxLifetime + return builtin8.SealProofPoliciesV11[proof].SectorMaxLifetime } func GetAddressedSectorsMax(nwVer network.Version) (int, error) { @@ -480,6 +525,9 @@ func GetAddressedSectorsMax(nwVer network.Version) (int, error) { case actors.Version7: return miner7.AddressedSectorsMax, nil + case actors.Version8: + return miner8.AddressedSectorsMax, nil + default: return 0, xerrors.Errorf("unsupported network version") } @@ -521,6 +569,10 @@ func GetDeclarationsMax(nwVer network.Version) (int, error) { return miner7.DeclarationsMax, nil + case actors.Version8: + + return miner8.DeclarationsMax, nil + default: return 0, xerrors.Errorf("unsupported network version") } @@ -561,6 +613,10 @@ func AggregateProveCommitNetworkFee(nwVer network.Version, aggregateSize int, ba return miner7.AggregateProveCommitNetworkFee(aggregateSize, baseFee), nil + case actors.Version8: + + return miner8.AggregateProveCommitNetworkFee(aggregateSize, baseFee), nil + default: return big.Zero(), xerrors.Errorf("unsupported network version") } @@ -601,6 +657,10 @@ func AggregatePreCommitNetworkFee(nwVer network.Version, aggregateSize int, base return miner7.AggregatePreCommitNetworkFee(aggregateSize, baseFee), nil + case actors.Version8: + + return miner8.AggregatePreCommitNetworkFee(aggregateSize, baseFee), nil + default: return big.Zero(), xerrors.Errorf("unsupported network version") } diff --git a/chain/actors/version.go b/chain/actors/version.go index af51161c9a1..1a17a69720f 100644 --- a/chain/actors/version.go +++ b/chain/actors/version.go @@ -20,9 +20,9 @@ const ({{range .actorVersions}} /* inline-gen start */ -var LatestVersion = 7 +var LatestVersion = 8 -var Versions = []int{0, 2, 3, 4, 5, 6, 7} +var Versions = []int{0, 2, 3, 4, 5, 6, 7, 8} const ( Version0 Version = 0 @@ -32,6 +32,7 @@ const ( Version5 Version = 5 Version6 Version = 6 Version7 Version = 7 + Version8 Version = 8 ) /* inline-gen end */ @@ -53,6 +54,8 @@ func VersionForNetwork(version network.Version) (Version, error) { return Version6, nil case network.Version15: return Version7, nil + case network.Version16: + return Version8, nil default: return -1, fmt.Errorf("unsupported network version %d", version) } diff --git a/chain/consensus/filcns/compute_state.go b/chain/consensus/filcns/compute_state.go index addf641ed69..5513532d4fd 100644 --- a/chain/consensus/filcns/compute_state.go +++ b/chain/consensus/filcns/compute_state.go @@ -30,6 +30,7 @@ import ( exported5 "github.com/filecoin-project/specs-actors/v5/actors/builtin/exported" exported6 "github.com/filecoin-project/specs-actors/v6/actors/builtin/exported" exported7 "github.com/filecoin-project/specs-actors/v7/actors/builtin/exported" + exported8 "github.com/filecoin-project/specs-actors/v8/actors/builtin/exported" /* inline-gen end */ @@ -63,6 +64,7 @@ func NewActorRegistry() *vm.ActorRegistry { inv.Register(vm.ActorsVersionPredicate(actors.Version5), exported5.BuiltinActors()...) inv.Register(vm.ActorsVersionPredicate(actors.Version6), exported6.BuiltinActors()...) inv.Register(vm.ActorsVersionPredicate(actors.Version7), exported7.BuiltinActors()...) + inv.Register(vm.ActorsVersionPredicate(actors.Version8), exported8.BuiltinActors()...) /* inline-gen end */ diff --git a/chain/consensus/filcns/upgrades.go b/chain/consensus/filcns/upgrades.go index 116684b9f44..83a36cfa3ef 100644 --- a/chain/consensus/filcns/upgrades.go +++ b/chain/consensus/filcns/upgrades.go @@ -5,6 +5,8 @@ import ( "runtime" "time" + "github.com/filecoin-project/specs-actors/v8/actors/migration/nv16" + "github.com/docker/go-units" "github.com/filecoin-project/specs-actors/v6/actors/migration/nv14" @@ -170,6 +172,17 @@ func DefaultUpgradeSchedule() stmgr.UpgradeSchedule { StopWithin: 5, }}, Expensive: true, + }, { + Height: build.UpgradeFVM1Height, + Network: network.Version16, + Migration: UpgradeActorsV8, + PreMigrations: []stmgr.PreMigration{{ + PreMigration: PreUpgradeActorsV8, + StartWithin: 180, + DontStartWithin: 60, + StopWithin: 5, + }}, + Expensive: true, }, } @@ -1304,6 +1317,100 @@ func upgradeActorsV7Common( return newRoot, nil } +func UpgradeActorsV8(ctx context.Context, sm *stmgr.StateManager, cache stmgr.MigrationCache, cb stmgr.ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { + // Use all the CPUs except 3. + workerCount := runtime.NumCPU() - 3 + if workerCount <= 0 { + workerCount = 1 + } + + config := nv16.Config{ + MaxWorkers: uint(workerCount), + JobQueueSize: 1000, + ResultQueueSize: 100, + ProgressLogPeriod: 10 * time.Second, + } + + newRoot, err := upgradeActorsV8Common(ctx, sm, cache, root, epoch, ts, config) + if err != nil { + return cid.Undef, xerrors.Errorf("migrating actors v6 state: %w", err) + } + + return newRoot, nil +} + +func PreUpgradeActorsV8(ctx context.Context, sm *stmgr.StateManager, cache stmgr.MigrationCache, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) error { + // Use half the CPUs for pre-migration, but leave at least 3. + workerCount := runtime.NumCPU() + if workerCount <= 4 { + workerCount = 1 + } else { + workerCount /= 2 + } + + lbts, lbRoot, err := stmgr.GetLookbackTipSetForRound(ctx, sm, ts, epoch) + if err != nil { + return xerrors.Errorf("error getting lookback ts for premigration: %w", err) + } + + config := nv16.Config{MaxWorkers: uint(workerCount), + ProgressLogPeriod: time.Minute * 5} + + _, err = upgradeActorsV8Common(ctx, sm, cache, lbRoot, epoch, lbts, config) + return err +} + +func upgradeActorsV8Common( + ctx context.Context, sm *stmgr.StateManager, cache stmgr.MigrationCache, + root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet, + config nv16.Config, +) (cid.Cid, error) { + buf := blockstore.NewTieredBstore(sm.ChainStore().StateBlockstore(), blockstore.NewMemorySync()) + store := store.ActorStore(ctx, buf) + + // Load the state root. + var stateRoot types.StateRoot + if err := store.Get(ctx, root, &stateRoot); err != nil { + return cid.Undef, xerrors.Errorf("failed to decode state root: %w", err) + } + + if stateRoot.Version != types.StateTreeVersion4 { + return cid.Undef, xerrors.Errorf( + "expected state root version 4 for actors v8 upgrade, got %d", + stateRoot.Version, + ) + } + + // Perform the migration + newHamtRoot, err := nv16.MigrateStateTree(ctx, store, stateRoot.Actors, epoch, config, migrationLogger{}, cache) + if err != nil { + return cid.Undef, xerrors.Errorf("upgrading to actors v8: %w", err) + } + + // Persist the result. + newRoot, err := store.Put(ctx, &types.StateRoot{ + Version: types.StateTreeVersion4, + Actors: newHamtRoot, + Info: stateRoot.Info, + }) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to persist new state root: %w", err) + } + + // Persist the new tree. + + { + from := buf + to := buf.Read() + + if err := vm.Copy(ctx, from, to, newRoot); err != nil { + return cid.Undef, xerrors.Errorf("copying migrated tree: %w", err) + } + } + + return newRoot, nil +} + type migrationLogger struct{} func (ml migrationLogger) Log(level rt.LogLevel, msg string, args ...interface{}) { diff --git a/chain/state/statetree.go b/chain/state/statetree.go index 9a518a6227a..7d6876c3c51 100644 --- a/chain/state/statetree.go +++ b/chain/state/statetree.go @@ -159,7 +159,7 @@ func VersionForNetwork(ver network.Version) (types.StateTreeVersion, error) { /* inline-gen start */ - case network.Version13, network.Version14, network.Version15: + case network.Version13, network.Version14, network.Version15, network.Version16: /* inline-gen end */ return types.StateTreeVersion4, nil diff --git a/chain/sync_test.go b/chain/sync_test.go index 96ed1440e92..e97645fe9ed 100644 --- a/chain/sync_test.go +++ b/chain/sync_test.go @@ -143,6 +143,14 @@ func prepSyncTestWithV5Height(t testing.TB, h int, v5height abi.ChainEpoch) *syn Network: network.Version14, Height: v5height + 10, Migration: filcns.UpgradeActorsV6, + }, { + Network: network.Version15, + Height: v5height + 15, + Migration: filcns.UpgradeActorsV7, + }, { + Network: network.Version16, + Height: v5height + 20, + Migration: filcns.UpgradeActorsV8, }} g, err := gen.NewGeneratorWithUpgradeSchedule(sched) diff --git a/chain/vm/mkactor.go b/chain/vm/mkactor.go index 5716b50067b..2967ac0b657 100644 --- a/chain/vm/mkactor.go +++ b/chain/vm/mkactor.go @@ -27,6 +27,7 @@ import ( builtin5 "github.com/filecoin-project/specs-actors/v5/actors/builtin" builtin6 "github.com/filecoin-project/specs-actors/v6/actors/builtin" builtin7 "github.com/filecoin-project/specs-actors/v7/actors/builtin" + builtin8 "github.com/filecoin-project/specs-actors/v8/actors/builtin" /* inline-gen end */ @@ -133,6 +134,8 @@ func newAccountActor(ver actors.Version) *types.Actor { code = builtin6.AccountActorCodeID case actors.Version7: code = builtin7.AccountActorCodeID + case actors.Version8: + code = builtin8.AccountActorCodeID /* inline-gen end */ default: panic("unsupported actors version") diff --git a/chain/vm/runtime.go b/chain/vm/runtime.go index 0e2adc87983..6a55606f2d2 100644 --- a/chain/vm/runtime.go +++ b/chain/vm/runtime.go @@ -23,6 +23,7 @@ import ( rt5 "github.com/filecoin-project/specs-actors/v5/actors/runtime" rt6 "github.com/filecoin-project/specs-actors/v6/actors/runtime" rt7 "github.com/filecoin-project/specs-actors/v7/actors/runtime" + rt8 "github.com/filecoin-project/specs-actors/v8/actors/runtime" "github.com/ipfs/go-cid" ipldcbor "github.com/ipfs/go-ipld-cbor" "go.opencensus.io/trace" @@ -153,6 +154,7 @@ var _ rt4.Runtime = (*Runtime)(nil) var _ rt5.Runtime = (*Runtime)(nil) var _ rt6.Runtime = (*Runtime)(nil) var _ rt7.Runtime = (*Runtime)(nil) +var _ rt8.Runtime = (*Runtime)(nil) func (rt *Runtime) shimCall(f func() interface{}) (rval []byte, aerr aerrors.ActorError) { defer func() { diff --git a/chain/vm/vmi.go b/chain/vm/vmi.go index ee7fd046cae..88ee844648b 100644 --- a/chain/vm/vmi.go +++ b/chain/vm/vmi.go @@ -4,6 +4,7 @@ import ( "context" "os" + "github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/lotus/chain/types" "github.com/ipfs/go-cid" ) @@ -15,6 +16,11 @@ type VMI interface { } func NewVM(ctx context.Context, opts *VMOpts) (VMI, error) { + if opts.NetworkVersion >= network.Version16 { + return NewFVM(ctx, opts) + } + + // Remove after v16 upgrade, this is only to support testing and validation of the FVM if os.Getenv("LOTUS_USE_FVM_EXPERIMENTAL") == "1" { return NewFVM(ctx, opts) } diff --git a/documentation/en/api-v0-methods-miner.md b/documentation/en/api-v0-methods-miner.md index a941d04c0f4..dad6c070052 100644 --- a/documentation/en/api-v0-methods-miner.md +++ b/documentation/en/api-v0-methods-miner.md @@ -382,7 +382,7 @@ Inputs: ], "Bw==", 10101, - 15 + 16 ] ``` diff --git a/documentation/en/api-v0-methods.md b/documentation/en/api-v0-methods.md index eb195df8a7a..f2d82e019ca 100644 --- a/documentation/en/api-v0-methods.md +++ b/documentation/en/api-v0-methods.md @@ -6063,7 +6063,7 @@ Inputs: ] ``` -Response: `15` +Response: `16` ### StateReadState StateReadState returns the indicated actor's state. diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index 48b4540fef7..e34fe591803 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -6474,7 +6474,7 @@ Inputs: ] ``` -Response: `15` +Response: `16` ### StateReadState StateReadState returns the indicated actor's state. diff --git a/gen/inlinegen-data.json b/gen/inlinegen-data.json index ef97db6518f..8b8081ac457 100644 --- a/gen/inlinegen-data.json +++ b/gen/inlinegen-data.json @@ -1,7 +1,7 @@ { - "actorVersions": [0, 2, 3, 4, 5, 6, 7], - "latestActorsVersion": 7, + "actorVersions": [0, 2, 3, 4, 5, 6, 7, 8], + "latestActorsVersion": 8, - "networkVersions": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], - "latestNetworkVersion": 15 + "networkVersions": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], + "latestNetworkVersion": 16 } diff --git a/go.mod b/go.mod index 1e87b0292b3..a6acbc9793b 100644 --- a/go.mod +++ b/go.mod @@ -55,6 +55,7 @@ require ( github.com/filecoin-project/specs-actors/v5 v5.0.4 github.com/filecoin-project/specs-actors/v6 v6.0.1 github.com/filecoin-project/specs-actors/v7 v7.0.0 + github.com/filecoin-project/specs-actors/v8 v8.0.0-20220301040630-7465555c2e22 github.com/filecoin-project/specs-storage v0.2.0 github.com/filecoin-project/test-vectors/schema v0.0.5 github.com/gbrlsnchs/jwt/v3 v3.0.1 diff --git a/go.sum b/go.sum index a25ddb72d46..fb09c4d85be 100644 --- a/go.sum +++ b/go.sum @@ -393,6 +393,8 @@ github.com/filecoin-project/specs-actors/v7 v7.0.0-20211222192039-c83bea50c402/g github.com/filecoin-project/specs-actors/v7 v7.0.0-rc1.0.20220118005651-2470cb39827e/go.mod h1:TA5FwCna+Yi36POaT7SLKXsgEDvJwc0V/L6ZsO19B9M= github.com/filecoin-project/specs-actors/v7 v7.0.0 h1:FQN7tjt3o68hfb3qLFSJBoLMuOFY0REkFVLO/zXj8RU= github.com/filecoin-project/specs-actors/v7 v7.0.0/go.mod h1:TA5FwCna+Yi36POaT7SLKXsgEDvJwc0V/L6ZsO19B9M= +github.com/filecoin-project/specs-actors/v8 v8.0.0-20220301040630-7465555c2e22 h1:zf32sRuUQUDGZ8gc50CFFibzAboWleLW4EwR4apgpAw= +github.com/filecoin-project/specs-actors/v8 v8.0.0-20220301040630-7465555c2e22/go.mod h1:UYIPg65iPWoFw5NEftREdJwv9b/5yaLKdCgTvNI/2FA= github.com/filecoin-project/specs-storage v0.2.0 h1:Y4UDv0apRQ3zI2GiPPubi8JblpUZZphEdaJUxCutfyg= github.com/filecoin-project/specs-storage v0.2.0/go.mod h1:Tb88Zq+IBJbvAn3mS89GYj3jdRThBTE/771HCVZdRJU= github.com/filecoin-project/storetheindex v0.3.5 h1:KoS9TvjPm6zIZfUH8atAHJbVHOO7GTP1MdTG+v0eE+Q= @@ -1942,6 +1944,7 @@ github.com/whyrusleeping/cbor-gen v0.0.0-20200826160007-0b9f6c5fb163/go.mod h1:f github.com/whyrusleeping/cbor-gen v0.0.0-20210118024343-169e9d70c0c2/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/cbor-gen v0.0.0-20210219115102-f37d292932f2/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/cbor-gen v0.0.0-20210303213153-67a261a1d291/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= +github.com/whyrusleeping/cbor-gen v0.0.0-20210713220151-be142a5ae1a8/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/cbor-gen v0.0.0-20220224212727-7a699437a831/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/cbor-gen v0.0.0-20220302191723-37c43cae8e14 h1:vo2wkP2ceHyGyZwFFtAabpot03EeSxxwAe57pOI9E/4= github.com/whyrusleeping/cbor-gen v0.0.0-20220302191723-37c43cae8e14/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= diff --git a/itests/kit/ensemble_opts_nv.go b/itests/kit/ensemble_opts_nv.go index 45ed514439d..b51b82bd546 100644 --- a/itests/kit/ensemble_opts_nv.go +++ b/itests/kit/ensemble_opts_nv.go @@ -49,12 +49,12 @@ func LatestActorsAt(upgradeHeight abi.ChainEpoch) EnsembleOpt { }) /* inline-gen start */ return UpgradeSchedule(stmgr.Upgrade{ - Network: network.Version14, + Network: network.Version15, Height: -1, }, stmgr.Upgrade{ - Network: network.Version15, + Network: network.Version16, Height: upgradeHeight, - Migration: filcns.UpgradeActorsV7, + Migration: filcns.UpgradeActorsV8, }) /* inline-gen end */ } diff --git a/lotuspond/front/src/chain/methods.json b/lotuspond/front/src/chain/methods.json index 15c04ca2834..93810552896 100644 --- a/lotuspond/front/src/chain/methods.json +++ b/lotuspond/front/src/chain/methods.json @@ -730,5 +730,113 @@ "UseBytes", "RestoreBytes", "RemoveVerifiedClientDataCap" + ], + "fil/8/account": [ + "Send", + "Constructor", + "PubkeyAddress" + ], + "fil/8/cron": [ + "Send", + "Constructor", + "EpochTick" + ], + "fil/8/init": [ + "Send", + "Constructor", + "Exec" + ], + "fil/8/multisig": [ + "Send", + "Constructor", + "Propose", + "Approve", + "Cancel", + "AddSigner", + "RemoveSigner", + "SwapSigner", + "ChangeNumApprovalsThreshold", + "LockBalance" + ], + "fil/8/paymentchannel": [ + "Send", + "Constructor", + "UpdateChannelState", + "Settle", + "Collect" + ], + "fil/8/reward": [ + "Send", + "Constructor", + "AwardBlockReward", + "ThisEpochReward", + "UpdateNetworkKPI" + ], + "fil/8/storagemarket": [ + "Send", + "Constructor", + "AddBalance", + "WithdrawBalance", + "PublishStorageDeals", + "VerifyDealsForActivation", + "ActivateDeals", + "OnMinerSectorsTerminate", + "ComputeDataCommitment", + "CronTick" + ], + "fil/8/storageminer": [ + "Send", + "Constructor", + "ControlAddresses", + "ChangeWorkerAddress", + "ChangePeerID", + "SubmitWindowedPoSt", + "PreCommitSector", + "ProveCommitSector", + "ExtendSectorExpiration", + "TerminateSectors", + "DeclareFaults", + "DeclareFaultsRecovered", + "OnDeferredCronEvent", + "CheckSectorProven", + "ApplyRewards", + "ReportConsensusFault", + "WithdrawBalance", + "ConfirmSectorProofsValid", + "ChangeMultiaddrs", + "CompactPartitions", + "CompactSectorNumbers", + "ConfirmUpdateWorkerKey", + "RepayDebt", + "ChangeOwnerAddress", + "DisputeWindowedPoSt", + "PreCommitSectorBatch", + "ProveCommitAggregate", + "ProveReplicaUpdates" + ], + "fil/8/storagepower": [ + "Send", + "Constructor", + "CreateMiner", + "UpdateClaimedPower", + "EnrollCronEvent", + "CronTick", + "UpdatePledgeTotal", + "SubmitPoRepForBulkVerify", + "CurrentTotalPower" + ], + "fil/8/system": [ + "Send", + "Constructor" + ], + "fil/8/verifiedregistry": [ + "Send", + "Constructor", + "AddVerifier", + "RemoveVerifier", + "AddVerifiedClient", + "UseBytes", + "RestoreBytes", + "RemoveVerifiedClientDataCap" ] } \ No newline at end of file