diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 2261c102e43..cdf7c1e6dd3 100644 Binary files a/build/openrpc/full.json.gz and b/build/openrpc/full.json.gz differ diff --git a/build/openrpc/miner.json.gz b/build/openrpc/miner.json.gz index 2ef745e363f..4230d59e1fb 100644 Binary files a/build/openrpc/miner.json.gz and b/build/openrpc/miner.json.gz differ 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