From ebad0ded3d394e9e1c87d8e5f700628d3ad70c7a Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Fri, 18 Sep 2020 23:46:03 -0400 Subject: [PATCH 001/115] Introduce v1 actors --- chain/actors/builtin/account/account.go | 8 + chain/actors/builtin/account/v1.go | 18 + chain/actors/builtin/builtin.go | 5 + chain/actors/builtin/init/init.go | 8 + chain/actors/builtin/init/v1.go | 47 +++ chain/actors/builtin/market/market.go | 13 +- chain/actors/builtin/market/v1.go | 186 ++++++++++ chain/actors/builtin/miner/v1.go | 403 ++++++++++++++++++++++ chain/actors/builtin/multisig/multisig.go | 8 + chain/actors/builtin/multisig/v1.go | 30 ++ chain/actors/builtin/paych/paych.go | 9 + chain/actors/builtin/paych/v1.go | 91 +++++ chain/actors/builtin/power/v1.go | 85 +++++ chain/actors/builtin/reward/reward.go | 8 + chain/actors/builtin/reward/v1.go | 74 ++++ chain/actors/builtin/verifreg/v1.go | 39 +++ chain/actors/builtin/verifreg/verifreg.go | 8 + chain/stmgr/utils.go | 26 ++ chain/vm/invoker.go | 26 +- go.mod | 1 + go.sum | 6 + 21 files changed, 1096 insertions(+), 3 deletions(-) create mode 100644 chain/actors/builtin/account/v1.go create mode 100644 chain/actors/builtin/init/v1.go create mode 100644 chain/actors/builtin/market/v1.go create mode 100644 chain/actors/builtin/miner/v1.go create mode 100644 chain/actors/builtin/multisig/v1.go create mode 100644 chain/actors/builtin/paych/v1.go create mode 100644 chain/actors/builtin/power/v1.go create mode 100644 chain/actors/builtin/reward/v1.go create mode 100644 chain/actors/builtin/verifreg/v1.go diff --git a/chain/actors/builtin/account/account.go b/chain/actors/builtin/account/account.go index 5b90580ec..07f4c4fc7 100644 --- a/chain/actors/builtin/account/account.go +++ b/chain/actors/builtin/account/account.go @@ -6,6 +6,7 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/cbor" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/types" @@ -20,6 +21,13 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, err } return &out, nil + case builtin1.AccountActorCodeID: + out := state1{store: store} + err := store.Get(store.Context(), act.Head, &out) + if err != nil { + return nil, err + } + return &out, nil } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } diff --git a/chain/actors/builtin/account/v1.go b/chain/actors/builtin/account/v1.go new file mode 100644 index 000000000..ed0fb0104 --- /dev/null +++ b/chain/actors/builtin/account/v1.go @@ -0,0 +1,18 @@ +package account + +import ( + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/specs-actors/v2/actors/builtin/account" +) + +var _ State = (*state1)(nil) + +type state1 struct { + account.State + store adt.Store +} + +func (s *state1) PubkeyAddress() (address.Address, error) { + return s.Address, nil +} diff --git a/chain/actors/builtin/builtin.go b/chain/actors/builtin/builtin.go index 4079e694a..e25cfcf36 100644 --- a/chain/actors/builtin/builtin.go +++ b/chain/actors/builtin/builtin.go @@ -8,6 +8,7 @@ import ( proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof" smoothing0 "github.com/filecoin-project/specs-actors/actors/util/smoothing" + smoothing1 "github.com/filecoin-project/specs-actors/v2/actors/util/smoothing" "github.com/filecoin-project/go-state-types/network" ) @@ -41,3 +42,7 @@ func FromV0FilterEstimate(v0 smoothing0.FilterEstimate) FilterEstimate { func QAPowerForWeight(size abi.SectorSize, duration abi.ChainEpoch, dealWeight, verifiedWeight abi.DealWeight) abi.StoragePower { return miner0.QAPowerForWeight(size, duration, dealWeight, verifiedWeight) } + +func FromV1FilterEstimate(v1 smoothing1.FilterEstimate) FilterEstimate { + return (FilterEstimate)(v1) +} diff --git a/chain/actors/builtin/init/init.go b/chain/actors/builtin/init/init.go index f235450c2..a9fd25a1a 100644 --- a/chain/actors/builtin/init/init.go +++ b/chain/actors/builtin/init/init.go @@ -7,6 +7,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/cbor" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/types" @@ -24,6 +25,13 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, err } return &out, nil + case builtin1.InitActorCodeID: + out := state1{store: store} + err := store.Get(store.Context(), act.Head, &out) + if err != nil { + return nil, err + } + return &out, nil } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } diff --git a/chain/actors/builtin/init/v1.go b/chain/actors/builtin/init/v1.go new file mode 100644 index 000000000..d11071bdd --- /dev/null +++ b/chain/actors/builtin/init/v1.go @@ -0,0 +1,47 @@ +package init + +import ( + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + cbg "github.com/whyrusleeping/cbor-gen" + + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/node/modules/dtypes" + + init_ "github.com/filecoin-project/specs-actors/v2/actors/builtin/init" + adt1 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" +) + +var _ State = (*state1)(nil) + +type state1 struct { + init_.State + store adt.Store +} + +func (s *state1) ResolveAddress(address address.Address) (address.Address, bool, error) { + return s.State.ResolveAddress(s.store, address) +} + +func (s *state1) MapAddressToNewID(address address.Address) (address.Address, error) { + return s.State.MapAddressToNewID(s.store, address) +} + +func (s *state1) ForEachActor(cb func(id abi.ActorID, address address.Address) error) error { + addrs, err := adt1.AsMap(s.store, s.State.AddressMap) + 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 *state1) NetworkName() (dtypes.NetworkName, error) { + return dtypes.NetworkName(s.State.NetworkName), nil +} diff --git a/chain/actors/builtin/market/market.go b/chain/actors/builtin/market/market.go index fef0c03f9..b1c9d7a7e 100644 --- a/chain/actors/builtin/market/market.go +++ b/chain/actors/builtin/market/market.go @@ -6,11 +6,13 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/cbor" - builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - market0 "github.com/filecoin-project/specs-actors/actors/builtin/market" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" + builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + market0 "github.com/filecoin-project/specs-actors/actors/builtin/market" + builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/types" ) @@ -26,6 +28,13 @@ func Load(store adt.Store, act *types.Actor) (st State, err error) { return nil, err } return &out, nil + case builtin1.StorageMarketActorCodeID: + out := state1{store: store} + err := store.Get(store.Context(), act.Head, &out) + if err != nil { + return nil, err + } + return &out, nil } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } diff --git a/chain/actors/builtin/market/v1.go b/chain/actors/builtin/market/v1.go new file mode 100644 index 000000000..8a634ddd2 --- /dev/null +++ b/chain/actors/builtin/market/v1.go @@ -0,0 +1,186 @@ +package market + +import ( + "bytes" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/specs-actors/v2/actors/builtin/market" + adt1 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" + cbg "github.com/whyrusleeping/cbor-gen" +) + +var _ State = (*state1)(nil) + +type state1 struct { + market.State + store adt.Store +} + +func (s *state1) TotalLocked() (abi.TokenAmount, error) { + fml := types.BigAdd(s.TotalClientLockedCollateral, s.TotalProviderLockedCollateral) + fml = types.BigAdd(fml, s.TotalClientStorageFee) + return fml, nil +} + +func (s *state1) BalancesChanged(otherState State) bool { + otherState1, ok := otherState.(*state1) + 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 + } + return !s.State.EscrowTable.Equals(otherState1.State.EscrowTable) || !s.State.LockedTable.Equals(otherState1.State.LockedTable) +} + +func (s *state1) StatesChanged(otherState State) bool { + otherState1, ok := otherState.(*state1) + 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 + } + return !s.State.States.Equals(otherState1.State.States) +} + +func (s *state1) States() (DealStates, error) { + stateArray, err := adt1.AsArray(s.store, s.State.States) + if err != nil { + return nil, err + } + return &dealStates1{stateArray}, nil +} + +func (s *state1) ProposalsChanged(otherState State) bool { + otherState1, ok := otherState.(*state1) + 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 + } + return !s.State.Proposals.Equals(otherState1.State.Proposals) +} + +func (s *state1) Proposals() (DealProposals, error) { + proposalArray, err := adt1.AsArray(s.store, s.State.Proposals) + if err != nil { + return nil, err + } + return &dealProposals1{proposalArray}, nil +} + +func (s *state1) EscrowTable() (BalanceTable, error) { + bt, err := adt1.AsBalanceTable(s.store, s.State.EscrowTable) + if err != nil { + return nil, err + } + return &balanceTable1{bt}, nil +} + +func (s *state1) LockedTable() (BalanceTable, error) { + bt, err := adt1.AsBalanceTable(s.store, s.State.LockedTable) + if err != nil { + return nil, err + } + return &balanceTable1{bt}, nil +} + +func (s *state1) VerifyDealsForActivation( + minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch, +) (weight, verifiedWeight abi.DealWeight, err error) { + w, vw, _, err := market.ValidateDealsForActivation(&s.State, s.store, deals, minerAddr, sectorExpiry, currEpoch) + return w, vw, err +} + +type balanceTable1 struct { + *adt1.BalanceTable +} + +func (bt *balanceTable1) ForEach(cb func(address.Address, abi.TokenAmount) error) error { + asMap := (*adt1.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 dealStates1 struct { + adt.Array +} + +func (s *dealStates1) Get(dealID abi.DealID) (*DealState, bool, error) { + var deal1 market.DealState + found, err := s.Array.Get(uint64(dealID), &deal1) + if err != nil { + return nil, false, err + } + if !found { + return nil, false, nil + } + deal := fromV1DealState(deal1) + return &deal, true, nil +} + +func (s *dealStates1) decode(val *cbg.Deferred) (*DealState, error) { + var ds1 market.DealState + if err := ds1.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { + return nil, err + } + ds := fromV1DealState(ds1) + return &ds, nil +} + +func (s *dealStates1) array() adt.Array { + return s.Array +} + +func fromV1DealState(v1 market.DealState) DealState { + return (DealState)(v1) +} + +type dealProposals1 struct { + adt.Array +} + +func (s *dealProposals1) Get(dealID abi.DealID) (*DealProposal, bool, error) { + var proposal1 market.DealProposal + found, err := s.Array.Get(uint64(dealID), &proposal1) + if err != nil { + return nil, false, err + } + if !found { + return nil, false, nil + } + proposal := fromV1DealProposal(proposal1) + return &proposal, true, nil +} + +func (s *dealProposals1) ForEach(cb func(dealID abi.DealID, dp DealProposal) error) error { + var dp1 market.DealProposal + return s.Array.ForEach(&dp1, func(idx int64) error { + return cb(abi.DealID(idx), fromV1DealProposal(dp1)) + }) +} + +func (s *dealProposals1) decode(val *cbg.Deferred) (*DealProposal, error) { + var dp1 market.DealProposal + if err := dp1.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { + return nil, err + } + dp := fromV1DealProposal(dp1) + return &dp, nil +} + +func (s *dealProposals1) array() adt.Array { + return s.Array +} + +func fromV1DealProposal(v1 market.DealProposal) DealProposal { + return (DealProposal)(v1) +} diff --git a/chain/actors/builtin/miner/v1.go b/chain/actors/builtin/miner/v1.go new file mode 100644 index 000000000..9c0486eb0 --- /dev/null +++ b/chain/actors/builtin/miner/v1.go @@ -0,0 +1,403 @@ +package miner + +import ( + "bytes" + "errors" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-bitfield" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/dline" + "github.com/filecoin-project/lotus/chain/actors/adt" + adt1 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" + "github.com/libp2p/go-libp2p-core/peer" + cbg "github.com/whyrusleeping/cbor-gen" + "golang.org/x/xerrors" + + miner1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" +) + +var _ State = (*state1)(nil) + +type state1 struct { + miner1.State + store adt.Store +} + +type deadline1 struct { + miner1.Deadline + store adt.Store +} + +type partition1 struct { + miner1.Partition + store adt.Store +} + +func (s *state1) AvailableBalance(bal abi.TokenAmount) (abi.TokenAmount, error) { + return s.GetAvailableBalance(bal), nil +} + +func (s *state1) VestedFunds(epoch abi.ChainEpoch) (abi.TokenAmount, error) { + return s.CheckVestedFunds(s.store, epoch) +} + +func (s *state1) LockedFunds() (LockedFunds, error) { + return LockedFunds{ + VestingFunds: s.State.LockedFunds, + InitialPledgeRequirement: s.State.InitialPledge, + PreCommitDeposits: s.State.PreCommitDeposits, + }, nil +} + +func (s *state1) InitialPledge() (abi.TokenAmount, error) { + return s.State.InitialPledge, nil +} + +func (s *state1) PreCommitDeposits() (abi.TokenAmount, error) { + return s.State.PreCommitDeposits, nil +} + +func (s *state1) GetSector(num abi.SectorNumber) (*SectorOnChainInfo, error) { + info, ok, err := s.State.GetSector(s.store, num) + if !ok || err != nil { + return nil, err + } + + ret := fromV1SectorOnChainInfo(*info) + return &ret, nil +} + +func (s *state1) 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 +} + +// GetSectorExpiration returns the effective expiration of the given sector. +// +// If the sector isn't found or has already been terminated, this method returns +// nil and no error. If the sector does not expire early, the Early expiration +// field is 0. +func (s *state1) 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 either expire on-time (can be + // learned from the sector info), or in the next quantized expiration + // epoch (i.e., the first element in the partition's expiration queue. + // 2. If it's faulty, it will expire early within the first 14 entries + // of the expiration queue. + stopErr := errors.New("stop") + out := SectorExpiration{} + err = dls.ForEach(s.store, func(dlIdx uint64, dl *miner1.Deadline) error { + partitions, err := dl.PartitionsArray(s.store) + if err != nil { + return err + } + quant := s.State.QuantSpecForDeadline(dlIdx) + var part miner1.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 := miner1.LoadExpirationQueue(s.store, part.ExpirationsEpochs, quant) + if err != nil { + return err + } + var exp miner1.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, nil + } + return &out, nil +} + +func (s *state1) GetPrecommittedSector(num abi.SectorNumber) (*SectorPreCommitOnChainInfo, error) { + info, ok, err := s.State.GetPrecommittedSector(s.store, num) + if !ok || err != nil { + return nil, err + } + + ret := fromV1SectorPreCommitOnChainInfo(*info) + + return &ret, nil +} + +func (s *state1) LoadSectorsFromSet(filter *bitfield.BitField, filterOut bool) (adt.Array, error) { + a, err := adt1.AsArray(s.store, s.State.Sectors) + if err != nil { + return nil, err + } + + ret := adt1.MakeEmptyArray(s.store) + var v cbg.Deferred + if err := a.ForEach(&v, func(i int64) error { + include := true + if filter != nil { + set, err := filter.IsSet(uint64(i)) + if err != nil { + return xerrors.Errorf("filter check error: %w", err) + } + if set == filterOut { + include = false + } + } + + if include { + var oci miner1.SectorOnChainInfo + if err := oci.UnmarshalCBOR(bytes.NewReader(v.Raw)); err != nil { + return err + } + + noci := SectorOnChainInfo{ + SectorNumber: oci.SectorNumber, + SealProof: oci.SealProof, + SealedCID: oci.SealedCID, + DealIDs: oci.DealIDs, + Activation: oci.Activation, + Expiration: oci.Expiration, + DealWeight: oci.DealWeight, + VerifiedDealWeight: oci.VerifiedDealWeight, + InitialPledge: oci.InitialPledge, + ExpectedDayReward: oci.ExpectedDayReward, + ExpectedStoragePledge: oci.ExpectedStoragePledge, + } + + if err := ret.Set(uint64(i), &noci); err != nil { + return err + } + } + return nil + }); err != nil { + return nil, err + } + + return ret, nil +} + +func (s *state1) LoadPreCommittedSectors() (adt.Map, error) { + return adt1.AsMap(s.store, s.State.PreCommittedSectors) +} + +func (s *state1) IsAllocated(num abi.SectorNumber) (bool, error) { + var allocatedSectors bitfield.BitField + if err := s.store.Get(s.store.Context(), s.State.AllocatedSectors, &allocatedSectors); err != nil { + return false, err + } + + return allocatedSectors.IsSet(uint64(num)) +} + +func (s *state1) 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 &deadline1{*dl, s.store}, nil +} + +func (s *state1) 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 *miner1.Deadline) error { + return cb(i, &deadline1{*dl, s.store}) + }) +} + +func (s *state1) NumDeadlines() (uint64, error) { + return miner1.WPoStPeriodDeadlines, nil +} + +func (s *state1) DeadlinesChanged(other State) bool { + other1, ok := other.(*state1) + if !ok { + // treat an upgrade as a change, always + return true + } + + return s.State.Deadlines.Equals(other1.Deadlines) +} + +func (s *state1) 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, + SealProofType: info.SealProofType, + SectorSize: info.SectorSize, + WindowPoStPartitionSectors: info.WindowPoStPartitionSectors, + } + + if info.PendingWorkerKey != nil { + mi.NewWorker = info.PendingWorkerKey.NewWorker + mi.WorkerChangeEpoch = info.PendingWorkerKey.EffectiveAt + } + + return mi, nil +} + +func (s *state1) DeadlineInfo(epoch abi.ChainEpoch) *dline.Info { + return s.State.DeadlineInfo(epoch) +} + +func (s *state1) sectors() (adt.Array, error) { + return adt1.AsArray(s.store, s.Sectors) +} + +func (s *state1) decodeSectorOnChainInfo(val *cbg.Deferred) (SectorOnChainInfo, error) { + var si miner1.SectorOnChainInfo + err := si.UnmarshalCBOR(bytes.NewReader(val.Raw)) + if err != nil { + return SectorOnChainInfo{}, err + } + + ret := fromV1SectorOnChainInfo(si) + return ret, nil +} + +func (s *state1) precommits() (adt.Map, error) { + return adt1.AsMap(s.store, s.PreCommittedSectors) +} + +func (s *state1) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (SectorPreCommitOnChainInfo, error) { + var sp miner1.SectorPreCommitOnChainInfo + err := sp.UnmarshalCBOR(bytes.NewReader(val.Raw)) + if err != nil { + return SectorPreCommitOnChainInfo{}, err + } + + ret := fromV1SectorPreCommitOnChainInfo(sp) + return ret, nil +} + +func (d *deadline1) LoadPartition(idx uint64) (Partition, error) { + p, err := d.Deadline.LoadPartition(d.store, idx) + if err != nil { + return nil, err + } + return &partition1{*p, d.store}, nil +} + +func (d *deadline1) ForEachPartition(cb func(uint64, Partition) error) error { + ps, err := d.Deadline.PartitionsArray(d.store) + if err != nil { + return err + } + var part miner1.Partition + return ps.ForEach(&part, func(i int64) error { + return cb(uint64(i), &partition1{part, d.store}) + }) +} + +func (d *deadline1) PartitionsChanged(other Deadline) bool { + other1, ok := other.(*deadline1) + if !ok { + // treat an upgrade as a change, always + return true + } + + return d.Deadline.Partitions.Equals(other1.Deadline.Partitions) +} + +func (d *deadline1) PostSubmissions() (bitfield.BitField, error) { + return d.Deadline.PostSubmissions, nil +} + +func (p *partition1) AllSectors() (bitfield.BitField, error) { + return p.Partition.Sectors, nil +} + +func (p *partition1) FaultySectors() (bitfield.BitField, error) { + return p.Partition.Faults, nil +} + +func (p *partition1) RecoveringSectors() (bitfield.BitField, error) { + return p.Partition.Recoveries, nil +} + +func fromV1SectorOnChainInfo(v1 miner1.SectorOnChainInfo) SectorOnChainInfo { + return SectorOnChainInfo{ + SectorNumber: v1.SectorNumber, + SealProof: v1.SealProof, + SealedCID: v1.SealedCID, + DealIDs: v1.DealIDs, + Activation: v1.Activation, + Expiration: v1.Expiration, + DealWeight: v1.DealWeight, + VerifiedDealWeight: v1.VerifiedDealWeight, + InitialPledge: v1.InitialPledge, + ExpectedDayReward: v1.ExpectedDayReward, + ExpectedStoragePledge: v1.ExpectedStoragePledge, + } +} + +func fromV1SectorPreCommitOnChainInfo(v1 miner1.SectorPreCommitOnChainInfo) SectorPreCommitOnChainInfo { + return SectorPreCommitOnChainInfo{ + Info: (SectorPreCommitInfo)(v1.Info), + PreCommitDeposit: v1.PreCommitDeposit, + PreCommitEpoch: v1.PreCommitEpoch, + DealWeight: v1.DealWeight, + VerifiedDealWeight: v1.VerifiedDealWeight, + } +} diff --git a/chain/actors/builtin/multisig/multisig.go b/chain/actors/builtin/multisig/multisig.go index 884b6f493..a30082824 100644 --- a/chain/actors/builtin/multisig/multisig.go +++ b/chain/actors/builtin/multisig/multisig.go @@ -9,6 +9,7 @@ import ( builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig" + builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/types" @@ -23,6 +24,13 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, err } return &out, nil + case builtin1.MultisigActorCodeID: + out := state1{store: store} + err := store.Get(store.Context(), act.Head, &out) + if err != nil { + return nil, err + } + return &out, nil } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } diff --git a/chain/actors/builtin/multisig/v1.go b/chain/actors/builtin/multisig/v1.go new file mode 100644 index 000000000..cf2d67453 --- /dev/null +++ b/chain/actors/builtin/multisig/v1.go @@ -0,0 +1,30 @@ +package multisig + +import ( + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig" +) + +var _ State = (*state1)(nil) + +type state1 struct { + multisig.State + store adt.Store +} + +func (s *state1) LockedBalance(currEpoch abi.ChainEpoch) (abi.TokenAmount, error) { + return s.State.AmountLocked(currEpoch - s.State.StartEpoch), nil +} + +func (s *state1) StartEpoch() abi.ChainEpoch { + return s.State.StartEpoch +} + +func (s *state1) UnlockDuration() abi.ChainEpoch { + return s.State.UnlockDuration +} + +func (s *state1) InitialBalance() abi.TokenAmount { + return s.State.InitialBalance +} diff --git a/chain/actors/builtin/paych/paych.go b/chain/actors/builtin/paych/paych.go index dad54163f..36cf56e63 100644 --- a/chain/actors/builtin/paych/paych.go +++ b/chain/actors/builtin/paych/paych.go @@ -7,8 +7,10 @@ import ( "github.com/filecoin-project/go-state-types/abi" big "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/cbor" + builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych" + builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/types" @@ -24,6 +26,13 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, err } return &out, nil + case builtin1.PaymentChannelActorCodeID: + out := state1{store: store} + err := store.Get(store.Context(), act.Head, &out) + if err != nil { + return nil, err + } + return &out, nil } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } diff --git a/chain/actors/builtin/paych/v1.go b/chain/actors/builtin/paych/v1.go new file mode 100644 index 000000000..bbe3bbebf --- /dev/null +++ b/chain/actors/builtin/paych/v1.go @@ -0,0 +1,91 @@ +package paych + +import ( + "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" + "github.com/filecoin-project/specs-actors/v2/actors/builtin/paych" + adt1 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" +) + +var _ State = (*state1)(nil) + +type state1 struct { + paych.State + store adt.Store + lsAmt *adt1.Array +} + +// Channel owner, who has funded the actor +func (s *state1) From() address.Address { + return s.State.From +} + +// Recipient of payouts from channel +func (s *state1) To() address.Address { + return s.State.To +} + +// Height at which the channel can be `Collected` +func (s *state1) SettlingAt() abi.ChainEpoch { + return s.State.SettlingAt +} + +// Amount successfully redeemed through the payment channel, paid out on `Collect()` +func (s *state1) ToSend() abi.TokenAmount { + return s.State.ToSend +} + +func (s *state1) getOrLoadLsAmt() (*adt1.Array, error) { + if s.lsAmt != nil { + return s.lsAmt, nil + } + + // Get the lane state from the chain + lsamt, err := adt1.AsArray(s.store, s.State.LaneStates) + if err != nil { + return nil, err + } + + s.lsAmt = lsamt + return lsamt, nil +} + +// Get total number of lanes +func (s *state1) LaneCount() (uint64, error) { + lsamt, err := s.getOrLoadLsAmt() + if err != nil { + return 0, err + } + return lsamt.Length(), nil +} + +// Iterate lane states +func (s *state1) 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 paych.LaneState + return lsamt.ForEach(&ls, func(i int64) error { + return cb(uint64(i), &laneState1{ls}) + }) +} + +type laneState1 struct { + paych.LaneState +} + +func (ls *laneState1) Redeemed() big.Int { + return ls.LaneState.Redeemed +} + +func (ls *laneState1) Nonce() uint64 { + return ls.LaneState.Nonce +} diff --git a/chain/actors/builtin/power/v1.go b/chain/actors/builtin/power/v1.go new file mode 100644 index 000000000..85defd053 --- /dev/null +++ b/chain/actors/builtin/power/v1.go @@ -0,0 +1,85 @@ +package power + +import ( + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/specs-actors/actors/util/adt" + power1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/power" +) + +var _ State = (*state1)(nil) + +type state1 struct { + power1.State + store adt.Store +} + +func (s *state1) TotalLocked() (abi.TokenAmount, error) { + return s.TotalPledgeCollateral, nil +} + +func (s *state1) 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 *state1) TotalCommitted() (Claim, error) { + return Claim{ + RawBytePower: s.TotalBytesCommitted, + QualityAdjPower: s.TotalQABytesCommitted, + }, nil +} + +func (s *state1) MinerPower(addr address.Address) (Claim, bool, error) { + claims, err := adt.AsMap(s.store, s.Claims) + if err != nil { + return Claim{}, false, err + } + var claim power1.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 *state1) MinerNominalPowerMeetsConsensusMinimum(a address.Address) (bool, error) { + return s.State.MinerNominalPowerMeetsConsensusMinimum(s.store, a) +} + +func (s *state1) TotalPowerSmoothed() (builtin.FilterEstimate, error) { + return builtin.FromV1FilterEstimate(s.State.ThisEpochQAPowerSmoothed), nil +} + +func (s *state1) MinerCounts() (uint64, uint64, error) { + return uint64(s.State.MinerAboveMinPowerCount), uint64(s.State.MinerCount), nil +} + +func (s *state1) ListAllMiners() ([]address.Address, error) { + claims, err := adt.AsMap(s.store, 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 +} diff --git a/chain/actors/builtin/reward/reward.go b/chain/actors/builtin/reward/reward.go index cfa82c774..324bc95dd 100644 --- a/chain/actors/builtin/reward/reward.go +++ b/chain/actors/builtin/reward/reward.go @@ -7,6 +7,7 @@ import ( "github.com/filecoin-project/go-state-types/cbor" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" @@ -24,6 +25,13 @@ func Load(store adt.Store, act *types.Actor) (st State, err error) { return nil, err } return &out, nil + case builtin1.RewardActorCodeID: + out := state1{store: store} + err := store.Get(store.Context(), act.Head, &out) + if err != nil { + return nil, err + } + return &out, nil } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } diff --git a/chain/actors/builtin/reward/v1.go b/chain/actors/builtin/reward/v1.go new file mode 100644 index 000000000..162dc13a1 --- /dev/null +++ b/chain/actors/builtin/reward/v1.go @@ -0,0 +1,74 @@ +package reward + +import ( + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/specs-actors/actors/util/adt" + miner1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" + "github.com/filecoin-project/specs-actors/v2/actors/builtin/reward" + "github.com/filecoin-project/specs-actors/v2/actors/util/smoothing" +) + +var _ State = (*state1)(nil) + +type state1 struct { + reward.State + store adt.Store +} + +func (s *state1) ThisEpochReward() (abi.StoragePower, error) { + return s.State.ThisEpochReward, nil +} + +func (s *state1) ThisEpochRewardSmoothed() (builtin.FilterEstimate, error) { + return builtin.FilterEstimate{ + PositionEstimate: s.State.ThisEpochRewardSmoothed.PositionEstimate, + VelocityEstimate: s.State.ThisEpochRewardSmoothed.VelocityEstimate, + }, nil +} + +func (s *state1) ThisEpochBaselinePower() (abi.StoragePower, error) { + return s.State.ThisEpochBaselinePower, nil +} + +func (s *state1) TotalStoragePowerReward() (abi.TokenAmount, error) { + return s.State.TotalStoragePowerReward, nil +} + +func (s *state1) EffectiveBaselinePower() (abi.StoragePower, error) { + return s.State.EffectiveBaselinePower, nil +} + +func (s *state1) EffectiveNetworkTime() (abi.ChainEpoch, error) { + return s.State.EffectiveNetworkTime, nil +} + +func (s *state1) CumsumBaseline() (abi.StoragePower, error) { + return s.State.CumsumBaseline, nil +} + +func (s *state1) CumsumRealized() (abi.StoragePower, error) { + return s.State.CumsumBaseline, nil +} + +func (s *state1) InitialPledgeForPower(qaPower abi.StoragePower, networkTotalPledge abi.TokenAmount, networkQAPower *builtin.FilterEstimate, circSupply abi.TokenAmount) (abi.TokenAmount, error) { + return miner1.InitialPledgeForPower( + qaPower, + s.State.ThisEpochBaselinePower, + s.State.ThisEpochRewardSmoothed, + smoothing.FilterEstimate{ + PositionEstimate: networkQAPower.PositionEstimate, + VelocityEstimate: networkQAPower.VelocityEstimate, + }, + circSupply, + ), nil +} + +func (s *state1) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, sectorWeight abi.StoragePower) (abi.TokenAmount, error) { + return miner1.PreCommitDepositForPower(s.State.ThisEpochRewardSmoothed, + smoothing.FilterEstimate{ + PositionEstimate: networkQAPower.PositionEstimate, + VelocityEstimate: networkQAPower.VelocityEstimate, + }, + sectorWeight), nil +} diff --git a/chain/actors/builtin/verifreg/v1.go b/chain/actors/builtin/verifreg/v1.go new file mode 100644 index 000000000..4fb013e1b --- /dev/null +++ b/chain/actors/builtin/verifreg/v1.go @@ -0,0 +1,39 @@ +package verifreg + +import ( + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/big" + adt1 "github.com/filecoin-project/specs-actors/actors/util/adt" + verifreg1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/verifreg" + "golang.org/x/xerrors" + + "github.com/filecoin-project/lotus/chain/actors/adt" +) + +var _ State = (*state1)(nil) + +type state1 struct { + verifreg1.State + store adt.Store +} + +func (s *state1) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) { + if addr.Protocol() != address.ID { + return false, big.Zero(), xerrors.Errorf("can only look up ID addresses") + } + + vh, err := adt1.AsMap(s.store, s.VerifiedClients) + if err != nil { + return false, big.Zero(), xerrors.Errorf("loading verified clients: %w", err) + } + + var dcap abi.StoragePower + if found, err := vh.Get(abi.AddrKey(addr), &dcap); err != nil { + return false, big.Zero(), xerrors.Errorf("looking up verified clients: %w", err) + } else if !found { + return false, big.Zero(), nil + } + + return true, dcap, nil +} diff --git a/chain/actors/builtin/verifreg/verifreg.go b/chain/actors/builtin/verifreg/verifreg.go index c861f862f..4255e8855 100644 --- a/chain/actors/builtin/verifreg/verifreg.go +++ b/chain/actors/builtin/verifreg/verifreg.go @@ -7,6 +7,7 @@ import ( "github.com/filecoin-project/go-state-types/cbor" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/types" @@ -23,6 +24,13 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, err } return &out, nil + case builtin1.VerifiedRegistryActorCodeID: + out := state1{store: store} + err := store.Get(store.Context(), act.Head, &out) + if err != nil { + return nil, err + } + return &out, nil } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } diff --git a/chain/stmgr/utils.go b/chain/stmgr/utils.go index 3493afca3..3c0a895d3 100644 --- a/chain/stmgr/utils.go +++ b/chain/stmgr/utils.go @@ -31,6 +31,17 @@ import ( verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg" proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof" + builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + account1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/account" + init1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/init" + market1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market" + miner1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" + msig1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig" + paych1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/paych" + power1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/power" + reward1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/reward" + verifreg1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/verifreg" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init" @@ -545,6 +556,18 @@ func init() { builtin0.MultisigActorCodeID: {builtin0.MethodsMultisig, msig0.Actor{}}, builtin0.RewardActorCodeID: {builtin0.MethodsReward, reward0.Actor{}}, builtin0.VerifiedRegistryActorCodeID: {builtin0.MethodsVerifiedRegistry, verifreg0.Actor{}}, + + // builtin1.SystemActorCodeID: {builtin1.MethodsSystem, system.Actor{} }- apparently it doesn't have methods + builtin1.InitActorCodeID: {builtin1.MethodsInit, init1.Actor{}}, + builtin1.CronActorCodeID: {builtin1.MethodsCron, cron.Actor{}}, + builtin1.AccountActorCodeID: {builtin1.MethodsAccount, account1.Actor{}}, + builtin1.StoragePowerActorCodeID: {builtin1.MethodsPower, power1.Actor{}}, + builtin1.StorageMinerActorCodeID: {builtin1.MethodsMiner, miner1.Actor{}}, + builtin1.StorageMarketActorCodeID: {builtin1.MethodsMarket, market1.Actor{}}, + builtin1.PaymentChannelActorCodeID: {builtin1.MethodsPaych, paych1.Actor{}}, + builtin1.MultisigActorCodeID: {builtin1.MethodsMultisig, msig1.Actor{}}, + builtin1.RewardActorCodeID: {builtin1.MethodsReward, reward1.Actor{}}, + builtin1.VerifiedRegistryActorCodeID: {builtin1.MethodsVerifiedRegistry, verifreg1.Actor{}}, } for c, m := range cidToMethods { @@ -552,6 +575,7 @@ func init() { methods := make(map[abi.MethodNum]MethodMeta, len(exports)) // Explicitly add send, it's special. + // Note that builtin1.MethodSend = builtin0.MethodSend = 0. methods[builtin0.MethodSend] = MethodMeta{ Name: "Send", Params: reflect.TypeOf(new(abi.EmptyValue)), @@ -592,8 +616,10 @@ func init() { } switch abi.MethodNum(number) { + // Note that builtin1.MethodSend = builtin0.MethodSend = 0. case builtin0.MethodSend: panic("method 0 is reserved for Send") + // Note that builtin1.MethodConstructor = builtin0.MethodConstructor = 1. case builtin0.MethodConstructor: if fnName != "Constructor" { panic("method 1 is reserved for Constructor") diff --git a/chain/vm/invoker.go b/chain/vm/invoker.go index 0a83e273d..bf71a4f74 100644 --- a/chain/vm/invoker.go +++ b/chain/vm/invoker.go @@ -22,7 +22,20 @@ import ( reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward" system0 "github.com/filecoin-project/specs-actors/actors/builtin/system" verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg" + vmr "github.com/filecoin-project/specs-actors/actors/runtime" + builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + account1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/account" + cron1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/cron" + init1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/init" + market1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market" + miner1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" + msig1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig" + paych1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/paych" + power1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/power" + reward1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/reward" + system1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/system" + verifreg1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/verifreg" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/exitcode" @@ -45,7 +58,6 @@ func NewInvoker() *Invoker { } // add builtInCode using: register(cid, singleton) - // NETUPGRADE: register code IDs for v2, etc. inv.Register(builtin0.SystemActorCodeID, system0.Actor{}, abi.EmptyValue{}) inv.Register(builtin0.InitActorCodeID, init0.Actor{}, init0.State{}) inv.Register(builtin0.RewardActorCodeID, reward0.Actor{}, reward0.State{}) @@ -58,6 +70,18 @@ func NewInvoker() *Invoker { inv.Register(builtin0.VerifiedRegistryActorCodeID, verifreg0.Actor{}, verifreg0.State{}) inv.Register(builtin0.AccountActorCodeID, account0.Actor{}, account0.State{}) + inv.Register(builtin1.SystemActorCodeID, system1.Actor{}, abi.EmptyValue{}) + inv.Register(builtin1.InitActorCodeID, init1.Actor{}, init1.State{}) + inv.Register(builtin1.RewardActorCodeID, reward1.Actor{}, reward1.State{}) + inv.Register(builtin1.CronActorCodeID, cron1.Actor{}, cron1.State{}) + inv.Register(builtin1.StoragePowerActorCodeID, power1.Actor{}, power1.State{}) + inv.Register(builtin1.StorageMarketActorCodeID, market1.Actor{}, market1.State{}) + inv.Register(builtin1.StorageMinerActorCodeID, miner1.Actor{}, miner1.State{}) + inv.Register(builtin1.MultisigActorCodeID, msig1.Actor{}, msig1.State{}) + inv.Register(builtin1.PaymentChannelActorCodeID, paych1.Actor{}, paych1.State{}) + inv.Register(builtin1.VerifiedRegistryActorCodeID, verifreg1.Actor{}, verifreg1.State{}) + inv.Register(builtin1.AccountActorCodeID, account1.Actor{}, account1.State{}) + return inv } diff --git a/go.mod b/go.mod index cfdf4cb1d..b19f5c053 100644 --- a/go.mod +++ b/go.mod @@ -37,6 +37,7 @@ require ( github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b github.com/filecoin-project/specs-actors v0.9.10 + github.com/filecoin-project/specs-actors/v2 v2.0.0-20200918035954-4caac0a9b252 github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796 github.com/filecoin-project/test-vectors/schema v0.0.1 github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 diff --git a/go.sum b/go.sum index 3b31e6c3b..6f5ab862d 100644 --- a/go.sum +++ b/go.sum @@ -232,6 +232,8 @@ github.com/filecoin-project/go-hamt-ipld v0.1.5 h1:uoXrKbCQZ49OHpsTCkrThPNelC4W3 github.com/filecoin-project/go-hamt-ipld v0.1.5 h1:uoXrKbCQZ49OHpsTCkrThPNelC4W3LPEk0OrS/ytIBM= github.com/filecoin-project/go-hamt-ipld v0.1.5/go.mod h1:6Is+ONR5Cd5R6XZoCse1CWaXZc0Hdb/JeX+EQCQzX24= github.com/filecoin-project/go-hamt-ipld v0.1.5/go.mod h1:6Is+ONR5Cd5R6XZoCse1CWaXZc0Hdb/JeX+EQCQzX24= +github.com/filecoin-project/go-hamt-ipld/v2 v2.0.0 h1:b3UDemBYN2HNfk3KOXNuxgTTxlWi3xVvbQP0IT38fvM= +github.com/filecoin-project/go-hamt-ipld/v2 v2.0.0/go.mod h1:7aWZdaQ1b16BVoQUYR+eEvrDCGJoPLxFpDynFjYfBjI= github.com/filecoin-project/go-jsonrpc v0.1.2-0.20200822201400-474f4fdccc52 h1:FXtCp0ybqdQL9knb3OGDpkNTaBbPxgkqPeWKotUwkH0= github.com/filecoin-project/go-jsonrpc v0.1.2-0.20200822201400-474f4fdccc52/go.mod h1:XBBpuKIMaXIIzeqzO1iucq4GvbF8CxmXRFoezRh+Cx4= github.com/filecoin-project/go-multistore v0.0.3 h1:vaRBY4YiA2UZFPK57RNuewypB8u0DzzQwqsL0XarpnI= @@ -254,8 +256,11 @@ github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/go.mod h1:Q0GQOBtKf1oE10eSXSlhN45kDBdGvEcVOqMiffqX+N8= github.com/filecoin-project/specs-actors v0.9.4/go.mod h1:BStZQzx5x7TmCkLv0Bpa07U6cPKol6fd3w9KjMPZ6Z4= github.com/filecoin-project/specs-actors v0.9.7/go.mod h1:wM2z+kwqYgXn5Z7scV1YHLyd1Q1cy0R8HfTIWQ0BFGU= +github.com/filecoin-project/specs-actors v0.9.9/go.mod h1:czlvLQGEX0fjLLfdNHD7xLymy6L3n7aQzRWzsYGf+ys= github.com/filecoin-project/specs-actors v0.9.10 h1:gU0TrRhgkCsBEOP42sGDE7RQuR0Cov9hJhBqq+RJmjU= github.com/filecoin-project/specs-actors v0.9.10/go.mod h1:czlvLQGEX0fjLLfdNHD7xLymy6L3n7aQzRWzsYGf+ys= +github.com/filecoin-project/specs-actors/v2 v2.0.0-20200918035954-4caac0a9b252 h1:0vOZo6xlVDyPhuRS3ArrAy1fml7H2FEY65IFx6rwp3o= +github.com/filecoin-project/specs-actors/v2 v2.0.0-20200918035954-4caac0a9b252/go.mod h1:vV1UOOKlmdKg4dy3YKixtJtVf15WMuZsS6KgKRDxkWg= github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796 h1:dJsTPWpG2pcTeojO2pyn0c6l+x/3MZYCBgo/9d11JEk= github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796/go.mod h1:nJRRM7Aa9XVvygr3W9k6xGF46RWzr2zxF/iGoAIfA/g= github.com/filecoin-project/test-vectors/schema v0.0.1 h1:5fNF76nl4qolEvcIsjc0kUADlTMVHO73tW4kXXPnsus= @@ -1367,6 +1372,7 @@ github.com/whyrusleeping/cbor-gen v0.0.0-20200414195334-429a0b5e922e/go.mod h1:X github.com/whyrusleeping/cbor-gen v0.0.0-20200504204219-64967432584d/go.mod h1:W5MvapuoHRP8rz4vxjwCK1pDqF1aQcWsV5PZ+AHbqdg= github.com/whyrusleeping/cbor-gen v0.0.0-20200710004633-5379fc63235d/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/cbor-gen v0.0.0-20200715143311-227fab5a2377/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= +github.com/whyrusleeping/cbor-gen v0.0.0-20200806213330-63aa96ca5488/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/cbor-gen v0.0.0-20200810223238-211df3b9e24c/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/cbor-gen v0.0.0-20200812213548-958ddffe352c/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/cbor-gen v0.0.0-20200814224545-656e08ce49ee h1:U7zWWvvAjT76EiuWPSOiZlQDnaQYPxPoxugTtTAcJK0= From 35562bd2f9b884b21ed64172b8ae85a05770a194 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 23 Sep 2020 15:36:56 -0700 Subject: [PATCH 002/115] fixup v1 actors for new methods Also, correctly handle multiple ADT versions. --- chain/actors/adt/adt.go | 10 +++ chain/actors/builtin/builtin.go | 1 + chain/actors/builtin/init/v0.go | 3 +- chain/actors/builtin/init/v1.go | 19 +++++ chain/actors/builtin/market/v1.go | 25 +++--- chain/actors/builtin/miner/v1.go | 109 ++++++++++++-------------- chain/actors/builtin/multisig/v1.go | 45 +++++++++-- chain/actors/builtin/paych/v1.go | 24 +++--- chain/actors/builtin/power/v0.go | 8 +- chain/actors/builtin/power/v1.go | 8 +- chain/actors/builtin/reward/v0.go | 13 +-- chain/actors/builtin/reward/v1.go | 13 +-- chain/actors/builtin/verifreg/util.go | 46 +++++++++++ chain/actors/builtin/verifreg/v0.go | 51 ++---------- chain/actors/builtin/verifreg/v1.go | 37 ++++----- 15 files changed, 238 insertions(+), 174 deletions(-) create mode 100644 chain/actors/builtin/verifreg/util.go diff --git a/chain/actors/adt/adt.go b/chain/actors/adt/adt.go index 39dd5cebc..cf2ede0ae 100644 --- a/chain/actors/adt/adt.go +++ b/chain/actors/adt/adt.go @@ -8,7 +8,9 @@ import ( "github.com/filecoin-project/go-state-types/cbor" "github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/lotus/chain/actors/builtin" + adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" + adt1 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" ) type Map interface { @@ -25,6 +27,8 @@ func AsMap(store Store, root cid.Cid, version builtin.Version) (Map, error) { switch version { case builtin.Version0: return adt0.AsMap(store, root) + case builtin.Version1: + return adt1.AsMap(store, root) } return nil, xerrors.Errorf("unknown network version: %d", version) } @@ -33,6 +37,8 @@ func NewMap(store Store, version builtin.Version) (Map, error) { switch version { case builtin.Version0: return adt0.MakeEmptyMap(store), nil + case builtin.Version1: + return adt1.MakeEmptyMap(store), nil } return nil, xerrors.Errorf("unknown network version: %d", version) } @@ -52,6 +58,8 @@ func AsArray(store Store, root cid.Cid, version network.Version) (Array, error) switch builtin.VersionForNetwork(version) { case builtin.Version0: return adt0.AsArray(store, root) + case builtin.Version1: + return adt1.AsArray(store, root) } return nil, xerrors.Errorf("unknown network version: %d", version) } @@ -60,6 +68,8 @@ func NewArray(store Store, version builtin.Version) (Array, error) { switch version { case builtin.Version0: return adt0.MakeEmptyArray(store), nil + case builtin.Version1: + return adt1.MakeEmptyArray(store), nil } return nil, xerrors.Errorf("unknown network version: %d", version) } diff --git a/chain/actors/builtin/builtin.go b/chain/actors/builtin/builtin.go index e25cfcf36..ae007d731 100644 --- a/chain/actors/builtin/builtin.go +++ b/chain/actors/builtin/builtin.go @@ -17,6 +17,7 @@ type Version int const ( Version0 = iota + Version1 ) // Converts a network version into a specs-actors version. diff --git a/chain/actors/builtin/init/v0.go b/chain/actors/builtin/init/v0.go index 425ba654c..b82b85aee 100644 --- a/chain/actors/builtin/init/v0.go +++ b/chain/actors/builtin/init/v0.go @@ -6,11 +6,10 @@ import ( cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" - init_ "github.com/filecoin-project/specs-actors/actors/builtin/init" - "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/node/modules/dtypes" + init_ "github.com/filecoin-project/specs-actors/actors/builtin/init" adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" ) diff --git a/chain/actors/builtin/init/v1.go b/chain/actors/builtin/init/v1.go index d11071bdd..d65d5b89d 100644 --- a/chain/actors/builtin/init/v1.go +++ b/chain/actors/builtin/init/v1.go @@ -4,6 +4,7 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" 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" @@ -45,3 +46,21 @@ func (s *state1) ForEachActor(cb func(id abi.ActorID, address address.Address) e func (s *state1) NetworkName() (dtypes.NetworkName, error) { return dtypes.NetworkName(s.State.NetworkName), nil } + +func (s *state1) Remove(addrs ...address.Address) (err error) { + m, err := adt1.AsMap(s.store, s.State.AddressMap) + 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 +} diff --git a/chain/actors/builtin/market/v1.go b/chain/actors/builtin/market/v1.go index 8a634ddd2..dc84c2633 100644 --- a/chain/actors/builtin/market/v1.go +++ b/chain/actors/builtin/market/v1.go @@ -25,24 +25,24 @@ func (s *state1) TotalLocked() (abi.TokenAmount, error) { return fml, nil } -func (s *state1) BalancesChanged(otherState State) bool { +func (s *state1) BalancesChanged(otherState State) (bool, error) { otherState1, ok := otherState.(*state1) 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 + return true, nil } - return !s.State.EscrowTable.Equals(otherState1.State.EscrowTable) || !s.State.LockedTable.Equals(otherState1.State.LockedTable) + return !s.State.EscrowTable.Equals(otherState1.State.EscrowTable) || !s.State.LockedTable.Equals(otherState1.State.LockedTable), nil } -func (s *state1) StatesChanged(otherState State) bool { +func (s *state1) StatesChanged(otherState State) (bool, error) { otherState1, ok := otherState.(*state1) 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 + return true, nil } - return !s.State.States.Equals(otherState1.State.States) + return !s.State.States.Equals(otherState1.State.States), nil } func (s *state1) States() (DealStates, error) { @@ -53,14 +53,14 @@ func (s *state1) States() (DealStates, error) { return &dealStates1{stateArray}, nil } -func (s *state1) ProposalsChanged(otherState State) bool { +func (s *state1) ProposalsChanged(otherState State) (bool, error) { otherState1, ok := otherState.(*state1) 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 + return true, nil } - return !s.State.Proposals.Equals(otherState1.State.Proposals) + return !s.State.Proposals.Equals(otherState1.State.Proposals), nil } func (s *state1) Proposals() (DealProposals, error) { @@ -127,6 +127,13 @@ func (s *dealStates1) Get(dealID abi.DealID) (*DealState, bool, error) { return &deal, true, nil } +func (s *dealStates1) ForEach(cb func(dealID abi.DealID, ds DealState) error) error { + var ds1 market.DealState + return s.Array.ForEach(&ds1, func(idx int64) error { + return cb(abi.DealID(idx), fromV1DealState(ds1)) + }) +} + func (s *dealStates1) decode(val *cbg.Deferred) (*DealState, error) { var ds1 market.DealState if err := ds1.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { diff --git a/chain/actors/builtin/miner/v1.go b/chain/actors/builtin/miner/v1.go index 9c0486eb0..4c991b4f3 100644 --- a/chain/actors/builtin/miner/v1.go +++ b/chain/actors/builtin/miner/v1.go @@ -12,7 +12,6 @@ import ( adt1 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" "github.com/libp2p/go-libp2p-core/peer" cbg "github.com/whyrusleeping/cbor-gen" - "golang.org/x/xerrors" miner1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" ) @@ -79,6 +78,21 @@ func (s *state1) FindSector(num abi.SectorNumber) (*SectorLocation, error) { }, nil } +func (s *state1) 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 *miner1.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 isn't found or has already been terminated, this method returns @@ -162,60 +176,37 @@ func (s *state1) GetPrecommittedSector(num abi.SectorNumber) (*SectorPreCommitOn return &ret, nil } -func (s *state1) LoadSectorsFromSet(filter *bitfield.BitField, filterOut bool) (adt.Array, error) { - a, err := adt1.AsArray(s.store, s.State.Sectors) +func (s *state1) LoadSectors(snos *bitfield.BitField) ([]*SectorOnChainInfo, error) { + sectors, err := miner1.LoadSectors(s.store, s.State.Sectors) if err != nil { return nil, err } - ret := adt1.MakeEmptyArray(s.store) - var v cbg.Deferred - if err := a.ForEach(&v, func(i int64) error { - include := true - if filter != nil { - set, err := filter.IsSet(uint64(i)) - if err != nil { - return xerrors.Errorf("filter check error: %w", err) - } - if set == filterOut { - include = false - } + // If no sector numbers are specified, load all. + if snos == nil { + infos := make([]*SectorOnChainInfo, 0, sectors.Length()) + var info1 miner1.SectorOnChainInfo + if err := sectors.ForEach(&info1, func(_ int64) error { + info := fromV1SectorOnChainInfo(info1) + infos = append(infos, &info) + return nil + }); err != nil { + return nil, err } - - if include { - var oci miner1.SectorOnChainInfo - if err := oci.UnmarshalCBOR(bytes.NewReader(v.Raw)); err != nil { - return err - } - - noci := SectorOnChainInfo{ - SectorNumber: oci.SectorNumber, - SealProof: oci.SealProof, - SealedCID: oci.SealedCID, - DealIDs: oci.DealIDs, - Activation: oci.Activation, - Expiration: oci.Expiration, - DealWeight: oci.DealWeight, - VerifiedDealWeight: oci.VerifiedDealWeight, - InitialPledge: oci.InitialPledge, - ExpectedDayReward: oci.ExpectedDayReward, - ExpectedStoragePledge: oci.ExpectedStoragePledge, - } - - if err := ret.Set(uint64(i), &noci); err != nil { - return err - } - } - return nil - }); err != nil { - return nil, err + return infos, nil } - return ret, nil -} - -func (s *state1) LoadPreCommittedSectors() (adt.Map, error) { - return adt1.AsMap(s.store, s.State.PreCommittedSectors) + // Otherwise, load selected. + infos1, err := sectors.Load(*snos) + if err != nil { + return nil, err + } + infos := make([]*SectorOnChainInfo, len(infos1)) + for i, info1 := range infos1 { + info := fromV1SectorOnChainInfo(*info1) + infos[i] = &info + } + return infos, nil } func (s *state1) IsAllocated(num abi.SectorNumber) (bool, error) { @@ -253,14 +244,14 @@ func (s *state1) NumDeadlines() (uint64, error) { return miner1.WPoStPeriodDeadlines, nil } -func (s *state1) DeadlinesChanged(other State) bool { +func (s *state1) DeadlinesChanged(other State) (bool, error) { other1, ok := other.(*state1) if !ok { // treat an upgrade as a change, always - return true + return true, nil } - return s.State.Deadlines.Equals(other1.Deadlines) + return s.State.Deadlines.Equals(other1.Deadlines), nil } func (s *state1) Info() (MinerInfo, error) { @@ -297,8 +288,8 @@ func (s *state1) Info() (MinerInfo, error) { return mi, nil } -func (s *state1) DeadlineInfo(epoch abi.ChainEpoch) *dline.Info { - return s.State.DeadlineInfo(epoch) +func (s *state1) DeadlineInfo(epoch abi.ChainEpoch) (*dline.Info, error) { + return s.State.DeadlineInfo(epoch), nil } func (s *state1) sectors() (adt.Array, error) { @@ -312,8 +303,7 @@ func (s *state1) decodeSectorOnChainInfo(val *cbg.Deferred) (SectorOnChainInfo, return SectorOnChainInfo{}, err } - ret := fromV1SectorOnChainInfo(si) - return ret, nil + return fromV1SectorOnChainInfo(si), nil } func (s *state1) precommits() (adt.Map, error) { @@ -327,8 +317,7 @@ func (s *state1) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (SectorPreC return SectorPreCommitOnChainInfo{}, err } - ret := fromV1SectorPreCommitOnChainInfo(sp) - return ret, nil + return fromV1SectorPreCommitOnChainInfo(sp), nil } func (d *deadline1) LoadPartition(idx uint64) (Partition, error) { @@ -350,14 +339,14 @@ func (d *deadline1) ForEachPartition(cb func(uint64, Partition) error) error { }) } -func (d *deadline1) PartitionsChanged(other Deadline) bool { +func (d *deadline1) PartitionsChanged(other Deadline) (bool, error) { other1, ok := other.(*deadline1) if !ok { // treat an upgrade as a change, always - return true + return true, nil } - return d.Deadline.Partitions.Equals(other1.Deadline.Partitions) + return d.Deadline.Partitions.Equals(other1.Deadline.Partitions), nil } func (d *deadline1) PostSubmissions() (bitfield.BitField, error) { diff --git a/chain/actors/builtin/multisig/v1.go b/chain/actors/builtin/multisig/v1.go index cf2d67453..97b9ae4a3 100644 --- a/chain/actors/builtin/multisig/v1.go +++ b/chain/actors/builtin/multisig/v1.go @@ -1,15 +1,21 @@ package multisig import ( + "encoding/binary" + + "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/lotus/chain/actors/adt" - "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig" + "golang.org/x/xerrors" + + msig1 "github.com/filecoin-project/specs-actors/actors/builtin/multisig" + adt1 "github.com/filecoin-project/specs-actors/actors/util/adt" ) var _ State = (*state1)(nil) type state1 struct { - multisig.State + msig1.State store adt.Store } @@ -17,14 +23,37 @@ func (s *state1) LockedBalance(currEpoch abi.ChainEpoch) (abi.TokenAmount, error return s.State.AmountLocked(currEpoch - s.State.StartEpoch), nil } -func (s *state1) StartEpoch() abi.ChainEpoch { - return s.State.StartEpoch +func (s *state1) StartEpoch() (abi.ChainEpoch, error) { + return s.State.StartEpoch, nil } -func (s *state1) UnlockDuration() abi.ChainEpoch { - return s.State.UnlockDuration +func (s *state1) UnlockDuration() (abi.ChainEpoch, error) { + return s.State.UnlockDuration, nil } -func (s *state1) InitialBalance() abi.TokenAmount { - return s.State.InitialBalance +func (s *state1) InitialBalance() (abi.TokenAmount, error) { + return s.State.InitialBalance, nil +} + +func (s *state1) Threshold() (uint64, error) { + return s.State.NumApprovalsThreshold, nil +} + +func (s *state1) Signers() ([]address.Address, error) { + return s.State.Signers, nil +} + +func (s *state1) ForEachPendingTxn(cb func(id int64, txn Transaction) error) error { + arr, err := adt1.AsMap(s.store, s.State.PendingTxns) + if err != nil { + return err + } + var out msig1.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)) + }) } diff --git a/chain/actors/builtin/paych/v1.go b/chain/actors/builtin/paych/v1.go index bbe3bbebf..7a960067c 100644 --- a/chain/actors/builtin/paych/v1.go +++ b/chain/actors/builtin/paych/v1.go @@ -18,23 +18,23 @@ type state1 struct { } // Channel owner, who has funded the actor -func (s *state1) From() address.Address { - return s.State.From +func (s *state1) From() (address.Address, error) { + return s.State.From, nil } // Recipient of payouts from channel -func (s *state1) To() address.Address { - return s.State.To +func (s *state1) To() (address.Address, error) { + return s.State.To, nil } // Height at which the channel can be `Collected` -func (s *state1) SettlingAt() abi.ChainEpoch { - return s.State.SettlingAt +func (s *state1) SettlingAt() (abi.ChainEpoch, error) { + return s.State.SettlingAt, nil } // Amount successfully redeemed through the payment channel, paid out on `Collect()` -func (s *state1) ToSend() abi.TokenAmount { - return s.State.ToSend +func (s *state1) ToSend() (abi.TokenAmount, error) { + return s.State.ToSend, nil } func (s *state1) getOrLoadLsAmt() (*adt1.Array, error) { @@ -82,10 +82,10 @@ type laneState1 struct { paych.LaneState } -func (ls *laneState1) Redeemed() big.Int { - return ls.LaneState.Redeemed +func (ls *laneState1) Redeemed() (big.Int, error) { + return ls.LaneState.Redeemed, nil } -func (ls *laneState1) Nonce() uint64 { - return ls.LaneState.Nonce +func (ls *laneState1) Nonce() (uint64, error) { + return ls.LaneState.Nonce, nil } diff --git a/chain/actors/builtin/power/v0.go b/chain/actors/builtin/power/v0.go index f2fe96dad..657de7ed0 100644 --- a/chain/actors/builtin/power/v0.go +++ b/chain/actors/builtin/power/v0.go @@ -3,9 +3,11 @@ package power import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" + power0 "github.com/filecoin-project/specs-actors/actors/builtin/power" - "github.com/filecoin-project/specs-actors/actors/util/adt" + adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" ) var _ State = (*state0)(nil) @@ -35,7 +37,7 @@ func (s *state0) TotalCommitted() (Claim, error) { } func (s *state0) MinerPower(addr address.Address) (Claim, bool, error) { - claims, err := adt.AsMap(s.store, s.Claims) + claims, err := adt0.AsMap(s.store, s.Claims) if err != nil { return Claim{}, false, err } @@ -63,7 +65,7 @@ func (s *state0) MinerCounts() (uint64, uint64, error) { } func (s *state0) ListAllMiners() ([]address.Address, error) { - claims, err := adt.AsMap(s.store, s.Claims) + claims, err := adt0.AsMap(s.store, s.Claims) if err != nil { return nil, err } diff --git a/chain/actors/builtin/power/v1.go b/chain/actors/builtin/power/v1.go index 85defd053..8c1a052b3 100644 --- a/chain/actors/builtin/power/v1.go +++ b/chain/actors/builtin/power/v1.go @@ -3,8 +3,10 @@ package power import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" - "github.com/filecoin-project/specs-actors/actors/util/adt" + + adt1 "github.com/filecoin-project/specs-actors/actors/util/adt" power1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/power" ) @@ -35,7 +37,7 @@ func (s *state1) TotalCommitted() (Claim, error) { } func (s *state1) MinerPower(addr address.Address) (Claim, bool, error) { - claims, err := adt.AsMap(s.store, s.Claims) + claims, err := adt1.AsMap(s.store, s.Claims) if err != nil { return Claim{}, false, err } @@ -63,7 +65,7 @@ func (s *state1) MinerCounts() (uint64, uint64, error) { } func (s *state1) ListAllMiners() ([]address.Address, error) { - claims, err := adt.AsMap(s.store, s.Claims) + claims, err := adt1.AsMap(s.store, s.Claims) if err != nil { return nil, err } diff --git a/chain/actors/builtin/reward/v0.go b/chain/actors/builtin/reward/v0.go index df7117b67..57084899d 100644 --- a/chain/actors/builtin/reward/v0.go +++ b/chain/actors/builtin/reward/v0.go @@ -2,17 +2,18 @@ package reward import ( "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" + miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" - "github.com/filecoin-project/specs-actors/actors/builtin/reward" - "github.com/filecoin-project/specs-actors/actors/util/adt" - "github.com/filecoin-project/specs-actors/actors/util/smoothing" + reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward" + smoothing0 "github.com/filecoin-project/specs-actors/actors/util/smoothing" ) var _ State = (*state0)(nil) type state0 struct { - reward.State + reward0.State store adt.Store } @@ -54,7 +55,7 @@ func (s *state0) InitialPledgeForPower(sectorWeight abi.StoragePower, networkTot s.State.ThisEpochBaselinePower, networkTotalPledge, s.State.ThisEpochRewardSmoothed, - &smoothing.FilterEstimate{ + &smoothing0.FilterEstimate{ PositionEstimate: networkQAPower.PositionEstimate, VelocityEstimate: networkQAPower.VelocityEstimate, }, @@ -63,7 +64,7 @@ func (s *state0) InitialPledgeForPower(sectorWeight abi.StoragePower, networkTot func (s *state0) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, sectorWeight abi.StoragePower) (abi.TokenAmount, error) { return miner0.PreCommitDepositForPower(s.State.ThisEpochRewardSmoothed, - &smoothing.FilterEstimate{ + &smoothing0.FilterEstimate{ PositionEstimate: networkQAPower.PositionEstimate, VelocityEstimate: networkQAPower.VelocityEstimate, }, diff --git a/chain/actors/builtin/reward/v1.go b/chain/actors/builtin/reward/v1.go index 162dc13a1..f16256a00 100644 --- a/chain/actors/builtin/reward/v1.go +++ b/chain/actors/builtin/reward/v1.go @@ -2,17 +2,18 @@ package reward import ( "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" - "github.com/filecoin-project/specs-actors/actors/util/adt" + miner1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" - "github.com/filecoin-project/specs-actors/v2/actors/builtin/reward" - "github.com/filecoin-project/specs-actors/v2/actors/util/smoothing" + reward1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/reward" + smoothing1 "github.com/filecoin-project/specs-actors/v2/actors/util/smoothing" ) var _ State = (*state1)(nil) type state1 struct { - reward.State + reward1.State store adt.Store } @@ -56,7 +57,7 @@ func (s *state1) InitialPledgeForPower(qaPower abi.StoragePower, networkTotalPle qaPower, s.State.ThisEpochBaselinePower, s.State.ThisEpochRewardSmoothed, - smoothing.FilterEstimate{ + smoothing1.FilterEstimate{ PositionEstimate: networkQAPower.PositionEstimate, VelocityEstimate: networkQAPower.VelocityEstimate, }, @@ -66,7 +67,7 @@ func (s *state1) InitialPledgeForPower(qaPower abi.StoragePower, networkTotalPle func (s *state1) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, sectorWeight abi.StoragePower) (abi.TokenAmount, error) { return miner1.PreCommitDepositForPower(s.State.ThisEpochRewardSmoothed, - smoothing.FilterEstimate{ + smoothing1.FilterEstimate{ PositionEstimate: networkQAPower.PositionEstimate, VelocityEstimate: networkQAPower.VelocityEstimate, }, diff --git a/chain/actors/builtin/verifreg/util.go b/chain/actors/builtin/verifreg/util.go new file mode 100644 index 000000000..413a68a15 --- /dev/null +++ b/chain/actors/builtin/verifreg/util.go @@ -0,0 +1,46 @@ +package verifreg + +import ( + "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" + "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/ipfs/go-cid" + "golang.org/x/xerrors" +) + +func getDataCap(store adt.Store, ver builtin.Version, root cid.Cid, addr address.Address) (bool, abi.StoragePower, error) { + if addr.Protocol() != address.ID { + return false, big.Zero(), xerrors.Errorf("can only look up ID addresses") + } + + vh, err := adt.AsMap(store, root, ver) + if err != nil { + return false, big.Zero(), xerrors.Errorf("loading verifreg: %w", err) + } + + var dcap abi.StoragePower + if found, err := vh.Get(abi.AddrKey(addr), &dcap); err != nil { + return false, big.Zero(), xerrors.Errorf("looking up addr: %w", err) + } else if !found { + return false, big.Zero(), nil + } + + return true, dcap, nil +} + +func forEachCap(store adt.Store, ver builtin.Version, root cid.Cid, cb func(addr address.Address, dcap abi.StoragePower) error) error { + vh, err := adt.AsMap(store, root, ver) + if err != nil { + return xerrors.Errorf("loading verified clients: %w", err) + } + var dcap abi.StoragePower + return vh.ForEach(&dcap, func(key string) error { + a, err := address.NewFromBytes([]byte(key)) + if err != nil { + return err + } + return cb(a, dcap) + }) +} diff --git a/chain/actors/builtin/verifreg/v0.go b/chain/actors/builtin/verifreg/v0.go index c59a58811..33e6757e7 100644 --- a/chain/actors/builtin/verifreg/v0.go +++ b/chain/actors/builtin/verifreg/v0.go @@ -3,13 +3,11 @@ package verifreg import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/go-state-types/big" - verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg" - adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" - "github.com/ipfs/go-cid" - "golang.org/x/xerrors" "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin" + + verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg" ) var _ State = (*state0)(nil) @@ -19,53 +17,18 @@ type state0 struct { store adt.Store } -func getDataCap(store adt.Store, root cid.Cid, addr address.Address) (bool, abi.StoragePower, error) { - if addr.Protocol() != address.ID { - return false, big.Zero(), xerrors.Errorf("can only look up ID addresses") - } - - vh, err := adt0.AsMap(store, root) - if err != nil { - return false, big.Zero(), xerrors.Errorf("loading verifreg: %w", err) - } - - var dcap abi.StoragePower - if found, err := vh.Get(abi.AddrKey(addr), &dcap); err != nil { - return false, big.Zero(), xerrors.Errorf("looking up addr: %w", err) - } else if !found { - return false, big.Zero(), nil - } - - return true, dcap, nil -} - func (s *state0) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) { - return getDataCap(s.store, s.State.VerifiedClients, addr) + return getDataCap(s.store, builtin.Version0, s.State.VerifiedClients, addr) } func (s *state0) VerifierDataCap(addr address.Address) (bool, abi.StoragePower, error) { - return getDataCap(s.store, s.State.Verifiers, addr) -} - -func forEachCap(store adt.Store, root cid.Cid, cb func(addr address.Address, dcap abi.StoragePower) error) error { - vh, err := adt0.AsMap(store, root) - if err != nil { - return xerrors.Errorf("loading verified clients: %w", err) - } - var dcap abi.StoragePower - return vh.ForEach(&dcap, func(key string) error { - a, err := address.NewFromBytes([]byte(key)) - if err != nil { - return err - } - return cb(a, dcap) - }) + return getDataCap(s.store, builtin.Version0, s.State.Verifiers, addr) } func (s *state0) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error { - return forEachCap(s.store, s.State.Verifiers, cb) + return forEachCap(s.store, builtin.Version0, s.State.Verifiers, cb) } func (s *state0) ForEachClient(cb func(addr address.Address, dcap abi.StoragePower) error) error { - return forEachCap(s.store, s.State.VerifiedClients, cb) + return forEachCap(s.store, builtin.Version0, s.State.VerifiedClients, cb) } diff --git a/chain/actors/builtin/verifreg/v1.go b/chain/actors/builtin/verifreg/v1.go index 4fb013e1b..ae78e260b 100644 --- a/chain/actors/builtin/verifreg/v1.go +++ b/chain/actors/builtin/verifreg/v1.go @@ -3,12 +3,11 @@ package verifreg import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/go-state-types/big" - adt1 "github.com/filecoin-project/specs-actors/actors/util/adt" - verifreg1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/verifreg" - "golang.org/x/xerrors" "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin" + + verifreg1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/verifreg" ) var _ State = (*state1)(nil) @@ -19,21 +18,17 @@ type state1 struct { } func (s *state1) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) { - if addr.Protocol() != address.ID { - return false, big.Zero(), xerrors.Errorf("can only look up ID addresses") - } - - vh, err := adt1.AsMap(s.store, s.VerifiedClients) - if err != nil { - return false, big.Zero(), xerrors.Errorf("loading verified clients: %w", err) - } - - var dcap abi.StoragePower - if found, err := vh.Get(abi.AddrKey(addr), &dcap); err != nil { - return false, big.Zero(), xerrors.Errorf("looking up verified clients: %w", err) - } else if !found { - return false, big.Zero(), nil - } - - return true, dcap, nil + return getDataCap(s.store, builtin.Version1, s.State.VerifiedClients, addr) +} + +func (s *state1) VerifierDataCap(addr address.Address) (bool, abi.StoragePower, error) { + return getDataCap(s.store, builtin.Version1, s.State.Verifiers, addr) +} + +func (s *state1) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error { + return forEachCap(s.store, builtin.Version1, s.State.Verifiers, cb) +} + +func (s *state1) ForEachClient(cb func(addr address.Address, dcap abi.StoragePower) error) error { + return forEachCap(s.store, builtin.Version1, s.State.VerifiedClients, cb) } From 858f11992f93d037c53d7d895a8df9e47a5c830e Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 23 Sep 2020 16:02:17 -0700 Subject: [PATCH 003/115] compile fix --- chain/stmgr/utils.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/chain/stmgr/utils.go b/chain/stmgr/utils.go index 3c0a895d3..0d7be7adf 100644 --- a/chain/stmgr/utils.go +++ b/chain/stmgr/utils.go @@ -33,6 +33,7 @@ import ( builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" account1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/account" + cron1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/cron" init1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/init" market1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market" miner1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" @@ -559,7 +560,7 @@ func init() { // builtin1.SystemActorCodeID: {builtin1.MethodsSystem, system.Actor{} }- apparently it doesn't have methods builtin1.InitActorCodeID: {builtin1.MethodsInit, init1.Actor{}}, - builtin1.CronActorCodeID: {builtin1.MethodsCron, cron.Actor{}}, + builtin1.CronActorCodeID: {builtin1.MethodsCron, cron1.Actor{}}, builtin1.AccountActorCodeID: {builtin1.MethodsAccount, account1.Actor{}}, builtin1.StoragePowerActorCodeID: {builtin1.MethodsPower, power1.Actor{}}, builtin1.StorageMinerActorCodeID: {builtin1.MethodsMiner, miner1.Actor{}}, From 8806f2722045ff240a52a6301ec11ef900f73755 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 23 Sep 2020 16:15:37 -0700 Subject: [PATCH 004/115] fix runtime reflection for upgrade --- chain/vm/invoker.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/chain/vm/invoker.go b/chain/vm/invoker.go index bf71a4f74..7465074b4 100644 --- a/chain/vm/invoker.go +++ b/chain/vm/invoker.go @@ -23,7 +23,6 @@ import ( system0 "github.com/filecoin-project/specs-actors/actors/builtin/system" verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg" - vmr "github.com/filecoin-project/specs-actors/actors/runtime" builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" account1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/account" cron1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/cron" @@ -36,6 +35,7 @@ import ( reward1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/reward" system1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/system" verifreg1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/verifreg" + vmr "github.com/filecoin-project/specs-actors/v2/actors/runtime" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/exitcode" @@ -115,6 +115,7 @@ type Invokee interface { func (*Invoker) transform(instance Invokee) (nativeCode, error) { itype := reflect.TypeOf(instance) exports := instance.Exports() + runtimeType := reflect.TypeOf((*vmr.Runtime)(nil)).Elem() for i, m := range exports { i := i newErr := func(format string, args ...interface{}) error { @@ -135,7 +136,7 @@ func (*Invoker) transform(instance Invokee) (nativeCode, error) { return nil, newErr("wrong number of inputs should be: " + "vmr.Runtime, ") } - if t.In(0) != reflect.TypeOf((*vmr.Runtime)(nil)).Elem() { + if !runtimeType.Implements(t.In(0)) { return nil, newErr("first arguemnt should be vmr.Runtime") } if t.In(1).Kind() != reflect.Ptr { From edb31e606a05a7624c8bd3cde922b883cbbb93dc Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 23 Sep 2020 16:50:34 -0700 Subject: [PATCH 005/115] correctly load new actors --- chain/actors/builtin/miner/miner.go | 13 +++++++++++-- chain/actors/builtin/power/power.go | 11 ++++++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/chain/actors/builtin/miner/miner.go b/chain/actors/builtin/miner/miner.go index 1a4c466b9..11f65fd49 100644 --- a/chain/actors/builtin/miner/miner.go +++ b/chain/actors/builtin/miner/miner.go @@ -11,11 +11,13 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/cbor" "github.com/filecoin-project/go-state-types/dline" - builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/types" + + builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" + builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" ) // Unchanged between v0 and v1 actors @@ -32,6 +34,13 @@ func Load(store adt.Store, act *types.Actor) (st State, err error) { return nil, err } return &out, nil + case builtin1.StorageMinerActorCodeID: + out := state1{store: store} + err := store.Get(store.Context(), act.Head, &out) + if err != nil { + return nil, err + } + return &out, nil } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } diff --git a/chain/actors/builtin/power/power.go b/chain/actors/builtin/power/power.go index e4bb52d44..7aa86fe00 100644 --- a/chain/actors/builtin/power/power.go +++ b/chain/actors/builtin/power/power.go @@ -6,11 +6,13 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/cbor" - builtin0 "github.com/filecoin-project/specs-actors/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" + + builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" ) var Address = builtin0.StoragePowerActorAddr @@ -24,6 +26,13 @@ func Load(store adt.Store, act *types.Actor) (st State, err error) { return nil, err } return &out, nil + case builtin1.StoragePowerActorCodeID: + out := state1{store: store} + err := store.Get(store.Context(), act.Head, &out) + if err != nil { + return nil, err + } + return &out, nil } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } From 87351fa35cbd1be5796803d23ea1a1f9704d1bc4 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 23 Sep 2020 17:01:40 -0700 Subject: [PATCH 006/115] move version to actors, from builtin Otherwise, we're going to end up with an import cycle between the adt and this version. --- chain/actors/adt/adt.go | 27 ++++++++++++++------------- chain/actors/builtin/builtin.go | 21 --------------------- chain/actors/builtin/verifreg/util.go | 6 +++--- chain/actors/builtin/verifreg/v0.go | 10 +++++----- chain/actors/builtin/verifreg/v1.go | 10 +++++----- chain/actors/version.go | 24 ++++++++++++++++++++++++ chain/gen/genesis/genesis.go | 4 ++-- chain/state/statetree.go | 18 +++++++++--------- chain/state/statetree_test.go | 14 +++++++------- chain/stmgr/stmgr.go | 3 +-- 10 files changed, 70 insertions(+), 67 deletions(-) create mode 100644 chain/actors/version.go diff --git a/chain/actors/adt/adt.go b/chain/actors/adt/adt.go index cf2ede0ae..778ba9fcf 100644 --- a/chain/actors/adt/adt.go +++ b/chain/actors/adt/adt.go @@ -7,7 +7,8 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/cbor" "github.com/filecoin-project/go-state-types/network" - "github.com/filecoin-project/lotus/chain/actors/builtin" + + "github.com/filecoin-project/lotus/chain/actors" adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" adt1 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" @@ -23,21 +24,21 @@ type Map interface { ForEach(v cbor.Unmarshaler, fn func(key string) error) error } -func AsMap(store Store, root cid.Cid, version builtin.Version) (Map, error) { +func AsMap(store Store, root cid.Cid, version actors.Version) (Map, error) { switch version { - case builtin.Version0: + case actors.Version0: return adt0.AsMap(store, root) - case builtin.Version1: + case actors.Version1: return adt1.AsMap(store, root) } return nil, xerrors.Errorf("unknown network version: %d", version) } -func NewMap(store Store, version builtin.Version) (Map, error) { +func NewMap(store Store, version actors.Version) (Map, error) { switch version { - case builtin.Version0: + case actors.Version0: return adt0.MakeEmptyMap(store), nil - case builtin.Version1: + case actors.Version1: return adt1.MakeEmptyMap(store), nil } return nil, xerrors.Errorf("unknown network version: %d", version) @@ -55,20 +56,20 @@ type Array interface { } func AsArray(store Store, root cid.Cid, version network.Version) (Array, error) { - switch builtin.VersionForNetwork(version) { - case builtin.Version0: + switch actors.VersionForNetwork(version) { + case actors.Version0: return adt0.AsArray(store, root) - case builtin.Version1: + case actors.Version1: return adt1.AsArray(store, root) } return nil, xerrors.Errorf("unknown network version: %d", version) } -func NewArray(store Store, version builtin.Version) (Array, error) { +func NewArray(store Store, version actors.Version) (Array, error) { switch version { - case builtin.Version0: + case actors.Version0: return adt0.MakeEmptyArray(store), nil - case builtin.Version1: + case actors.Version1: return adt1.MakeEmptyArray(store), nil } return nil, xerrors.Errorf("unknown network version: %d", version) diff --git a/chain/actors/builtin/builtin.go b/chain/actors/builtin/builtin.go index ae007d731..53dfa8669 100644 --- a/chain/actors/builtin/builtin.go +++ b/chain/actors/builtin/builtin.go @@ -1,35 +1,14 @@ package builtin import ( - "fmt" - "github.com/filecoin-project/go-state-types/abi" miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof" smoothing0 "github.com/filecoin-project/specs-actors/actors/util/smoothing" smoothing1 "github.com/filecoin-project/specs-actors/v2/actors/util/smoothing" - - "github.com/filecoin-project/go-state-types/network" ) -type Version int - -const ( - Version0 = iota - Version1 -) - -// Converts a network version into a specs-actors version. -func VersionForNetwork(version network.Version) Version { - switch version { - case network.Version0, network.Version1, network.Version2: - return Version0 - default: - panic(fmt.Sprintf("unsupported network version %d", version)) - } -} - // TODO: Why does actors have 2 different versions of this? type SectorInfo = proof0.SectorInfo type PoStProof = proof0.PoStProof diff --git a/chain/actors/builtin/verifreg/util.go b/chain/actors/builtin/verifreg/util.go index 413a68a15..4136c0c30 100644 --- a/chain/actors/builtin/verifreg/util.go +++ b/chain/actors/builtin/verifreg/util.go @@ -4,13 +4,13 @@ import ( "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" "github.com/filecoin-project/lotus/chain/actors/adt" - "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/ipfs/go-cid" "golang.org/x/xerrors" ) -func getDataCap(store adt.Store, ver builtin.Version, root cid.Cid, addr address.Address) (bool, abi.StoragePower, error) { +func getDataCap(store adt.Store, ver actors.Version, root cid.Cid, addr address.Address) (bool, abi.StoragePower, error) { if addr.Protocol() != address.ID { return false, big.Zero(), xerrors.Errorf("can only look up ID addresses") } @@ -30,7 +30,7 @@ func getDataCap(store adt.Store, ver builtin.Version, root cid.Cid, addr address return true, dcap, nil } -func forEachCap(store adt.Store, ver builtin.Version, root cid.Cid, cb func(addr address.Address, dcap abi.StoragePower) error) error { +func forEachCap(store adt.Store, ver actors.Version, root cid.Cid, cb func(addr address.Address, dcap abi.StoragePower) error) error { vh, err := adt.AsMap(store, root, ver) if err != nil { return xerrors.Errorf("loading verified clients: %w", err) diff --git a/chain/actors/builtin/verifreg/v0.go b/chain/actors/builtin/verifreg/v0.go index 33e6757e7..5cb053c79 100644 --- a/chain/actors/builtin/verifreg/v0.go +++ b/chain/actors/builtin/verifreg/v0.go @@ -4,8 +4,8 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" - "github.com/filecoin-project/lotus/chain/actors/builtin" verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg" ) @@ -18,17 +18,17 @@ type state0 struct { } func (s *state0) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) { - return getDataCap(s.store, builtin.Version0, s.State.VerifiedClients, addr) + return getDataCap(s.store, actors.Version0, s.State.VerifiedClients, addr) } func (s *state0) VerifierDataCap(addr address.Address) (bool, abi.StoragePower, error) { - return getDataCap(s.store, builtin.Version0, s.State.Verifiers, addr) + return getDataCap(s.store, actors.Version0, s.State.Verifiers, addr) } func (s *state0) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error { - return forEachCap(s.store, builtin.Version0, s.State.Verifiers, cb) + return forEachCap(s.store, actors.Version0, s.State.Verifiers, cb) } func (s *state0) ForEachClient(cb func(addr address.Address, dcap abi.StoragePower) error) error { - return forEachCap(s.store, builtin.Version0, s.State.VerifiedClients, cb) + return forEachCap(s.store, actors.Version0, s.State.VerifiedClients, cb) } diff --git a/chain/actors/builtin/verifreg/v1.go b/chain/actors/builtin/verifreg/v1.go index ae78e260b..ec998f9e5 100644 --- a/chain/actors/builtin/verifreg/v1.go +++ b/chain/actors/builtin/verifreg/v1.go @@ -4,8 +4,8 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" - "github.com/filecoin-project/lotus/chain/actors/builtin" verifreg1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/verifreg" ) @@ -18,17 +18,17 @@ type state1 struct { } func (s *state1) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) { - return getDataCap(s.store, builtin.Version1, s.State.VerifiedClients, addr) + return getDataCap(s.store, actors.Version1, s.State.VerifiedClients, addr) } func (s *state1) VerifierDataCap(addr address.Address) (bool, abi.StoragePower, error) { - return getDataCap(s.store, builtin.Version1, s.State.Verifiers, addr) + return getDataCap(s.store, actors.Version1, s.State.Verifiers, addr) } func (s *state1) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error { - return forEachCap(s.store, builtin.Version1, s.State.Verifiers, cb) + return forEachCap(s.store, actors.Version1, s.State.Verifiers, cb) } func (s *state1) ForEachClient(cb func(addr address.Address, dcap abi.StoragePower) error) error { - return forEachCap(s.store, builtin.Version1, s.State.VerifiedClients, cb) + return forEachCap(s.store, actors.Version1, s.State.VerifiedClients, cb) } diff --git a/chain/actors/version.go b/chain/actors/version.go new file mode 100644 index 000000000..8d256cf7d --- /dev/null +++ b/chain/actors/version.go @@ -0,0 +1,24 @@ +package actors + +import ( + "fmt" + + "github.com/filecoin-project/go-state-types/network" +) + +type Version int + +const ( + Version0 = iota + Version1 +) + +// Converts a network version into an actors adt version. +func VersionForNetwork(version network.Version) Version { + switch version { + case network.Version0, network.Version1, network.Version2: + return Version0 + default: + panic(fmt.Sprintf("unsupported network version %d", version)) + } +} diff --git a/chain/gen/genesis/genesis.go b/chain/gen/genesis/genesis.go index 039e284cd..bb1056e2e 100644 --- a/chain/gen/genesis/genesis.go +++ b/chain/gen/genesis/genesis.go @@ -24,7 +24,7 @@ import ( adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" @@ -115,7 +115,7 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge return nil, nil, xerrors.Errorf("putting empty object: %w", err) } - state, err := state.NewStateTree(cst, builtin.Version0) + state, err := state.NewStateTree(cst, actors.Version0) if err != nil { return nil, nil, xerrors.Errorf("making new state tree: %w", err) } diff --git a/chain/state/statetree.go b/chain/state/statetree.go index fe932bfa1..acf67e977 100644 --- a/chain/state/statetree.go +++ b/chain/state/statetree.go @@ -13,7 +13,7 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors" init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init" cbg "github.com/whyrusleeping/cbor-gen" @@ -26,7 +26,7 @@ var log = logging.Logger("statetree") // StateTree stores actors state by their ID. type StateTree struct { root adt.Map - version builtin.Version // TODO + version actors.Version // TODO info cid.Cid Store cbor.IpldStore @@ -120,10 +120,10 @@ func (ss *stateSnaps) deleteActor(addr address.Address) { ss.layers[len(ss.layers)-1].actors[addr] = streeOp{Delete: true} } -func NewStateTree(cst cbor.IpldStore, version builtin.Version) (*StateTree, error) { +func NewStateTree(cst cbor.IpldStore, version actors.Version) (*StateTree, error) { var info cid.Cid switch version { - case builtin.Version0: + case actors.Version0: // info is undefined default: return nil, xerrors.Errorf("unsupported state tree version: %d", version) @@ -148,18 +148,18 @@ func LoadStateTree(cst cbor.IpldStore, c cid.Cid) (*StateTree, error) { if err := cst.Get(context.TODO(), c, &root); err != nil { // We failed to decode as the new version, must be an old version. root.Actors = c - root.Version = builtin.Version0 + root.Version = actors.Version0 } // If that fails, load as an old-style state-tree (direct hampt, version 0. - nd, err := adt.AsMap(adt.WrapStore(context.TODO(), cst), root.Actors, builtin.Version(root.Version)) + nd, err := adt.AsMap(adt.WrapStore(context.TODO(), cst), root.Actors, actors.Version(root.Version)) if err != nil { log.Errorf("loading hamt node %s failed: %s", c, err) return nil, err } switch root.Version { - case builtin.Version0: + case actors.Version0: // supported default: return nil, xerrors.Errorf("unsupported state tree version: %d", root.Version) @@ -168,7 +168,7 @@ func LoadStateTree(cst cbor.IpldStore, c cid.Cid) (*StateTree, error) { return &StateTree{ root: nd, info: root.Info, - version: builtin.Version(root.Version), + version: actors.Version(root.Version), Store: cst, snaps: newStateSnaps(), }, nil @@ -305,7 +305,7 @@ func (st *StateTree) Flush(ctx context.Context) (cid.Cid, error) { return cid.Undef, xerrors.Errorf("failed to flush state-tree hamt: %w", err) } // If we're version 0, return a raw tree. - if st.version == builtin.Version0 { + if st.version == actors.Version0 { return root, nil } // Otherwise, return a versioned tree. diff --git a/chain/state/statetree_test.go b/chain/state/statetree_test.go index 79ab20606..554ba2697 100644 --- a/chain/state/statetree_test.go +++ b/chain/state/statetree_test.go @@ -12,13 +12,13 @@ import ( "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/lotus/build" - builtin2 "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/types" ) func BenchmarkStateTreeSet(b *testing.B) { cst := cbor.NewMemCborStore() - st, err := NewStateTree(cst, builtin2.VersionForNetwork(build.NewestNetworkVersion)) + st, err := NewStateTree(cst, actors.VersionForNetwork(build.NewestNetworkVersion)) if err != nil { b.Fatal(err) } @@ -45,7 +45,7 @@ func BenchmarkStateTreeSet(b *testing.B) { func BenchmarkStateTreeSetFlush(b *testing.B) { cst := cbor.NewMemCborStore() - st, err := NewStateTree(cst, builtin2.VersionForNetwork(build.NewestNetworkVersion)) + st, err := NewStateTree(cst, actors.VersionForNetwork(build.NewestNetworkVersion)) if err != nil { b.Fatal(err) } @@ -75,7 +75,7 @@ func BenchmarkStateTreeSetFlush(b *testing.B) { func BenchmarkStateTree10kGetActor(b *testing.B) { cst := cbor.NewMemCborStore() - st, err := NewStateTree(cst, builtin2.VersionForNetwork(build.NewestNetworkVersion)) + st, err := NewStateTree(cst, actors.VersionForNetwork(build.NewestNetworkVersion)) if err != nil { b.Fatal(err) } @@ -117,7 +117,7 @@ func BenchmarkStateTree10kGetActor(b *testing.B) { func TestSetCache(t *testing.T) { cst := cbor.NewMemCborStore() - st, err := NewStateTree(cst, builtin2.VersionForNetwork(build.NewestNetworkVersion)) + st, err := NewStateTree(cst, actors.VersionForNetwork(build.NewestNetworkVersion)) if err != nil { t.Fatal(err) } @@ -154,7 +154,7 @@ func TestSetCache(t *testing.T) { func TestSnapshots(t *testing.T) { ctx := context.Background() cst := cbor.NewMemCborStore() - st, err := NewStateTree(cst, builtin2.VersionForNetwork(build.NewestNetworkVersion)) + st, err := NewStateTree(cst, actors.VersionForNetwork(build.NewestNetworkVersion)) if err != nil { t.Fatal(err) } @@ -237,7 +237,7 @@ func assertNotHas(t *testing.T, st *StateTree, addr address.Address) { func TestStateTreeConsistency(t *testing.T) { cst := cbor.NewMemCborStore() - st, err := NewStateTree(cst, builtin2.VersionForNetwork(build.NewestNetworkVersion)) + st, err := NewStateTree(cst, actors.VersionForNetwork(build.NewestNetworkVersion)) if err != nil { t.Fatal(err) } diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index eaf9215db..b93de3b07 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -24,7 +24,6 @@ import ( "github.com/filecoin-project/lotus/build" "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/actors/builtin/market" "github.com/filecoin-project/lotus/chain/actors/builtin/multisig" "github.com/filecoin-project/lotus/chain/actors/builtin/paych" @@ -291,7 +290,7 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp } // XXX: Is the height correct? Or should it be epoch-1? - rectarr, err := adt.NewArray(sm.cs.Store(ctx), builtin.VersionForNetwork(sm.GetNtwkVersion(ctx, epoch))) + rectarr, err := adt.NewArray(sm.cs.Store(ctx), actors.VersionForNetwork(sm.GetNtwkVersion(ctx, epoch))) if err != nil { return cid.Undef, cid.Undef, xerrors.Errorf("failed to create receipts amt: %w", err) } From d9656f5220a1744966417ac5d881378447c3861c Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 23 Sep 2020 17:40:29 -0700 Subject: [PATCH 007/115] add a generic load method for actor state This will make it easier to load arbitrary actors. We can: * Type switch (sort of unsafe, may want marker methods?) * Use this with `vm.MutateActorState`. --- chain/actors/builtin/account/account.go | 30 ++++++++++--------- chain/actors/builtin/account/v0.go | 16 ++++++++-- chain/actors/builtin/account/v1.go | 16 ++++++++-- chain/actors/builtin/builtin.go | 25 +++++++++++++++- chain/actors/builtin/init/init.go | 30 ++++++++++--------- chain/actors/builtin/init/v0.go | 14 +++++++-- chain/actors/builtin/init/v1.go | 14 +++++++-- chain/actors/builtin/market/market.go | 24 +++++++-------- chain/actors/builtin/market/v0.go | 36 +++++++++++++++-------- chain/actors/builtin/market/v1.go | 36 +++++++++++++++-------- chain/actors/builtin/miner/miner.go | 24 +++++++-------- chain/actors/builtin/miner/v0.go | 20 +++++++++---- chain/actors/builtin/miner/v1.go | 15 ++++++++-- chain/actors/builtin/multisig/multisig.go | 25 ++++++++-------- chain/actors/builtin/multisig/v0.go | 13 +++++++- chain/actors/builtin/multisig/v1.go | 13 +++++++- chain/actors/builtin/paych/paych.go | 25 ++++++++-------- chain/actors/builtin/paych/v0.go | 23 +++++++++++---- chain/actors/builtin/paych/v1.go | 21 ++++++++++--- chain/actors/builtin/power/power.go | 24 +++++++-------- chain/actors/builtin/power/v0.go | 11 +++++++ chain/actors/builtin/power/v1.go | 11 +++++++ chain/actors/builtin/reward/reward.go | 24 +++++++-------- chain/actors/builtin/reward/v0.go | 11 +++++++ chain/actors/builtin/reward/v1.go | 11 +++++++ chain/actors/builtin/verifreg/v0.go | 10 +++++++ chain/actors/builtin/verifreg/v1.go | 10 +++++++ chain/actors/builtin/verifreg/verifreg.go | 25 ++++++++-------- 28 files changed, 394 insertions(+), 163 deletions(-) diff --git a/chain/actors/builtin/account/account.go b/chain/actors/builtin/account/account.go index 07f4c4fc7..2754607e2 100644 --- a/chain/actors/builtin/account/account.go +++ b/chain/actors/builtin/account/account.go @@ -5,29 +5,31 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/cbor" - builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + "github.com/ipfs/go-cid" "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/types" + + builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" ) +func init() { + builtin.RegisterActorState(builtin0.AccountActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load0(store, root) + }) + builtin.RegisterActorState(builtin1.AccountActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load1(store, root) + }) +} + func Load(store adt.Store, act *types.Actor) (State, error) { switch act.Code { case builtin0.AccountActorCodeID: - out := state0{store: store} - err := store.Get(store.Context(), act.Head, &out) - if err != nil { - return nil, err - } - return &out, nil + return load0(store, act.Head) case builtin1.AccountActorCodeID: - out := state1{store: store} - err := store.Get(store.Context(), act.Head, &out) - if err != nil { - return nil, err - } - return &out, nil + return load1(store, act.Head) } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } diff --git a/chain/actors/builtin/account/v0.go b/chain/actors/builtin/account/v0.go index 30bafbfd3..67c555c5d 100644 --- a/chain/actors/builtin/account/v0.go +++ b/chain/actors/builtin/account/v0.go @@ -2,14 +2,26 @@ package account import ( "github.com/filecoin-project/go-address" + "github.com/ipfs/go-cid" + "github.com/filecoin-project/lotus/chain/actors/adt" - "github.com/filecoin-project/specs-actors/actors/builtin/account" + + account0 "github.com/filecoin-project/specs-actors/actors/builtin/account" ) var _ State = (*state0)(nil) +func load0(store adt.Store, root cid.Cid) (State, error) { + out := state0{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + type state0 struct { - account.State + account0.State store adt.Store } diff --git a/chain/actors/builtin/account/v1.go b/chain/actors/builtin/account/v1.go index ed0fb0104..993c0e397 100644 --- a/chain/actors/builtin/account/v1.go +++ b/chain/actors/builtin/account/v1.go @@ -2,14 +2,26 @@ package account import ( "github.com/filecoin-project/go-address" + "github.com/ipfs/go-cid" + "github.com/filecoin-project/lotus/chain/actors/adt" - "github.com/filecoin-project/specs-actors/v2/actors/builtin/account" + + account1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/account" ) var _ State = (*state1)(nil) +func load1(store adt.Store, root cid.Cid) (State, error) { + out := state1{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + type state1 struct { - account.State + account1.State store adt.Store } diff --git a/chain/actors/builtin/builtin.go b/chain/actors/builtin/builtin.go index 53dfa8669..49a07951b 100644 --- a/chain/actors/builtin/builtin.go +++ b/chain/actors/builtin/builtin.go @@ -1,10 +1,17 @@ package builtin import ( + "github.com/ipfs/go-cid" + "golang.org/x/xerrors" + "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" + miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof" - smoothing0 "github.com/filecoin-project/specs-actors/actors/util/smoothing" smoothing1 "github.com/filecoin-project/specs-actors/v2/actors/util/smoothing" ) @@ -26,3 +33,19 @@ func QAPowerForWeight(size abi.SectorSize, duration abi.ChainEpoch, dealWeight, func FromV1FilterEstimate(v1 smoothing1.FilterEstimate) FilterEstimate { return (FilterEstimate)(v1) } + +type ActorStateLoader func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) + +var ActorStateLoaders = make(map[cid.Cid]ActorStateLoader) + +func RegisterActorState(code cid.Cid, loader ActorStateLoader) { + ActorStateLoaders[code] = loader +} + +func Load(store adt.Store, act *types.Actor) (cbor.Marshaler, error) { + loader, found := ActorStateLoaders[act.Code] + if !found { + return nil, xerrors.Errorf("unknown actor code %s", act.Code) + } + return loader(store, act.Head) +} diff --git a/chain/actors/builtin/init/init.go b/chain/actors/builtin/init/init.go index a9fd25a1a..622921ee9 100644 --- a/chain/actors/builtin/init/init.go +++ b/chain/actors/builtin/init/init.go @@ -6,32 +6,34 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/cbor" - builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + "github.com/ipfs/go-cid" "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/node/modules/dtypes" + + builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" ) +func init() { + builtin.RegisterActorState(builtin0.InitActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load0(store, root) + }) + builtin.RegisterActorState(builtin1.InitActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load1(store, root) + }) +} + var Address = builtin0.InitActorAddr func Load(store adt.Store, act *types.Actor) (State, error) { switch act.Code { case builtin0.InitActorCodeID: - out := state0{store: store} - err := store.Get(store.Context(), act.Head, &out) - if err != nil { - return nil, err - } - return &out, nil + return load0(store, act.Head) case builtin1.InitActorCodeID: - out := state1{store: store} - err := store.Get(store.Context(), act.Head, &out) - if err != nil { - return nil, err - } - return &out, nil + return load1(store, act.Head) } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } diff --git a/chain/actors/builtin/init/v0.go b/chain/actors/builtin/init/v0.go index b82b85aee..de0d6c9e1 100644 --- a/chain/actors/builtin/init/v0.go +++ b/chain/actors/builtin/init/v0.go @@ -3,20 +3,30 @@ 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" - init_ "github.com/filecoin-project/specs-actors/actors/builtin/init" + init0 "github.com/filecoin-project/specs-actors/actors/builtin/init" adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" ) var _ State = (*state0)(nil) +func load0(store adt.Store, root cid.Cid) (State, error) { + out := state0{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + type state0 struct { - init_.State + init0.State store adt.Store } diff --git a/chain/actors/builtin/init/v1.go b/chain/actors/builtin/init/v1.go index d65d5b89d..dcaa5a9ed 100644 --- a/chain/actors/builtin/init/v1.go +++ b/chain/actors/builtin/init/v1.go @@ -3,20 +3,30 @@ 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" - init_ "github.com/filecoin-project/specs-actors/v2/actors/builtin/init" + init1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/init" adt1 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" ) var _ State = (*state1)(nil) +func load1(store adt.Store, root cid.Cid) (State, error) { + out := state1{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + type state1 struct { - init_.State + init1.State store adt.Store } diff --git a/chain/actors/builtin/market/market.go b/chain/actors/builtin/market/market.go index b1c9d7a7e..d0798560b 100644 --- a/chain/actors/builtin/market/market.go +++ b/chain/actors/builtin/market/market.go @@ -14,27 +14,27 @@ import ( builtin1 "github.com/filecoin-project/specs-actors/v2/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" ) +func init() { + builtin.RegisterActorState(builtin0.StorageMarketActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load0(store, root) + }) + builtin.RegisterActorState(builtin1.StorageMarketActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load1(store, root) + }) +} + var Address = builtin0.StorageMarketActorAddr func Load(store adt.Store, act *types.Actor) (st State, err error) { switch act.Code { case builtin0.StorageMarketActorCodeID: - out := state0{store: store} - err := store.Get(store.Context(), act.Head, &out) - if err != nil { - return nil, err - } - return &out, nil + return load0(store, act.Head) case builtin1.StorageMarketActorCodeID: - out := state1{store: store} - err := store.Get(store.Context(), act.Head, &out) - if err != nil { - return nil, err - } - return &out, nil + return load1(store, act.Head) } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } diff --git a/chain/actors/builtin/market/v0.go b/chain/actors/builtin/market/v0.go index 2727f513d..20d38b5f1 100644 --- a/chain/actors/builtin/market/v0.go +++ b/chain/actors/builtin/market/v0.go @@ -5,17 +5,29 @@ 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" + "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/specs-actors/actors/builtin/market" + + market0 "github.com/filecoin-project/specs-actors/actors/builtin/market" adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" - cbg "github.com/whyrusleeping/cbor-gen" ) var _ State = (*state0)(nil) +func load0(store adt.Store, root cid.Cid) (State, error) { + out := state0{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + type state0 struct { - market.State + market0.State store adt.Store } @@ -90,7 +102,7 @@ func (s *state0) LockedTable() (BalanceTable, error) { func (s *state0) VerifyDealsForActivation( minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch, ) (weight, verifiedWeight abi.DealWeight, err error) { - return market.ValidateDealsForActivation(&s.State, s.store, deals, minerAddr, sectorExpiry, currEpoch) + return market0.ValidateDealsForActivation(&s.State, s.store, deals, minerAddr, sectorExpiry, currEpoch) } type balanceTable0 struct { @@ -114,7 +126,7 @@ type dealStates0 struct { } func (s *dealStates0) Get(dealID abi.DealID) (*DealState, bool, error) { - var deal0 market.DealState + var deal0 market0.DealState found, err := s.Array.Get(uint64(dealID), &deal0) if err != nil { return nil, false, err @@ -127,14 +139,14 @@ func (s *dealStates0) Get(dealID abi.DealID) (*DealState, bool, error) { } func (s *dealStates0) ForEach(cb func(dealID abi.DealID, ds DealState) error) error { - var ds0 market.DealState + var ds0 market0.DealState return s.Array.ForEach(&ds0, func(idx int64) error { return cb(abi.DealID(idx), fromV0DealState(ds0)) }) } func (s *dealStates0) decode(val *cbg.Deferred) (*DealState, error) { - var ds0 market.DealState + var ds0 market0.DealState if err := ds0.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { return nil, err } @@ -146,7 +158,7 @@ func (s *dealStates0) array() adt.Array { return s.Array } -func fromV0DealState(v0 market.DealState) DealState { +func fromV0DealState(v0 market0.DealState) DealState { return (DealState)(v0) } @@ -155,7 +167,7 @@ type dealProposals0 struct { } func (s *dealProposals0) Get(dealID abi.DealID) (*DealProposal, bool, error) { - var proposal0 market.DealProposal + var proposal0 market0.DealProposal found, err := s.Array.Get(uint64(dealID), &proposal0) if err != nil { return nil, false, err @@ -168,14 +180,14 @@ func (s *dealProposals0) Get(dealID abi.DealID) (*DealProposal, bool, error) { } func (s *dealProposals0) ForEach(cb func(dealID abi.DealID, dp DealProposal) error) error { - var dp0 market.DealProposal + var dp0 market0.DealProposal return s.Array.ForEach(&dp0, func(idx int64) error { return cb(abi.DealID(idx), fromV0DealProposal(dp0)) }) } func (s *dealProposals0) decode(val *cbg.Deferred) (*DealProposal, error) { - var dp0 market.DealProposal + var dp0 market0.DealProposal if err := dp0.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { return nil, err } @@ -187,6 +199,6 @@ func (s *dealProposals0) array() adt.Array { return s.Array } -func fromV0DealProposal(v0 market.DealProposal) DealProposal { +func fromV0DealProposal(v0 market0.DealProposal) DealProposal { return (DealProposal)(v0) } diff --git a/chain/actors/builtin/market/v1.go b/chain/actors/builtin/market/v1.go index dc84c2633..3ad0cded6 100644 --- a/chain/actors/builtin/market/v1.go +++ b/chain/actors/builtin/market/v1.go @@ -5,17 +5,29 @@ 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" + "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/specs-actors/v2/actors/builtin/market" + + market1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market" adt1 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" - cbg "github.com/whyrusleeping/cbor-gen" ) var _ State = (*state1)(nil) +func load1(store adt.Store, root cid.Cid) (State, error) { + out := state1{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + type state1 struct { - market.State + market1.State store adt.Store } @@ -90,7 +102,7 @@ func (s *state1) LockedTable() (BalanceTable, error) { func (s *state1) VerifyDealsForActivation( minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch, ) (weight, verifiedWeight abi.DealWeight, err error) { - w, vw, _, err := market.ValidateDealsForActivation(&s.State, s.store, deals, minerAddr, sectorExpiry, currEpoch) + w, vw, _, err := market1.ValidateDealsForActivation(&s.State, s.store, deals, minerAddr, sectorExpiry, currEpoch) return w, vw, err } @@ -115,7 +127,7 @@ type dealStates1 struct { } func (s *dealStates1) Get(dealID abi.DealID) (*DealState, bool, error) { - var deal1 market.DealState + var deal1 market1.DealState found, err := s.Array.Get(uint64(dealID), &deal1) if err != nil { return nil, false, err @@ -128,14 +140,14 @@ func (s *dealStates1) Get(dealID abi.DealID) (*DealState, bool, error) { } func (s *dealStates1) ForEach(cb func(dealID abi.DealID, ds DealState) error) error { - var ds1 market.DealState + var ds1 market1.DealState return s.Array.ForEach(&ds1, func(idx int64) error { return cb(abi.DealID(idx), fromV1DealState(ds1)) }) } func (s *dealStates1) decode(val *cbg.Deferred) (*DealState, error) { - var ds1 market.DealState + var ds1 market1.DealState if err := ds1.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { return nil, err } @@ -147,7 +159,7 @@ func (s *dealStates1) array() adt.Array { return s.Array } -func fromV1DealState(v1 market.DealState) DealState { +func fromV1DealState(v1 market1.DealState) DealState { return (DealState)(v1) } @@ -156,7 +168,7 @@ type dealProposals1 struct { } func (s *dealProposals1) Get(dealID abi.DealID) (*DealProposal, bool, error) { - var proposal1 market.DealProposal + var proposal1 market1.DealProposal found, err := s.Array.Get(uint64(dealID), &proposal1) if err != nil { return nil, false, err @@ -169,14 +181,14 @@ func (s *dealProposals1) Get(dealID abi.DealID) (*DealProposal, bool, error) { } func (s *dealProposals1) ForEach(cb func(dealID abi.DealID, dp DealProposal) error) error { - var dp1 market.DealProposal + var dp1 market1.DealProposal return s.Array.ForEach(&dp1, func(idx int64) error { return cb(abi.DealID(idx), fromV1DealProposal(dp1)) }) } func (s *dealProposals1) decode(val *cbg.Deferred) (*DealProposal, error) { - var dp1 market.DealProposal + var dp1 market1.DealProposal if err := dp1.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { return nil, err } @@ -188,6 +200,6 @@ func (s *dealProposals1) array() adt.Array { return s.Array } -func fromV1DealProposal(v1 market.DealProposal) DealProposal { +func fromV1DealProposal(v1 market1.DealProposal) DealProposal { return (DealProposal)(v1) } diff --git a/chain/actors/builtin/miner/miner.go b/chain/actors/builtin/miner/miner.go index 11f65fd49..00687a76f 100644 --- a/chain/actors/builtin/miner/miner.go +++ b/chain/actors/builtin/miner/miner.go @@ -13,6 +13,7 @@ import ( "github.com/filecoin-project/go-state-types/dline" "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/types" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" @@ -20,6 +21,15 @@ import ( builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" ) +func init() { + builtin.RegisterActorState(builtin0.StorageMinerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load0(store, root) + }) + builtin.RegisterActorState(builtin1.StorageMinerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load1(store, root) + }) +} + // Unchanged between v0 and v1 actors var WPoStProvingPeriod = miner0.WPoStProvingPeriod @@ -28,19 +38,9 @@ const MinSectorExpiration = miner0.MinSectorExpiration func Load(store adt.Store, act *types.Actor) (st State, err error) { switch act.Code { case builtin0.StorageMinerActorCodeID: - out := state0{store: store} - err := store.Get(store.Context(), act.Head, &out) - if err != nil { - return nil, err - } - return &out, nil + return load0(store, act.Head) case builtin1.StorageMinerActorCodeID: - out := state1{store: store} - err := store.Get(store.Context(), act.Head, &out) - if err != nil { - return nil, err - } - return &out, nil + return load1(store, act.Head) } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } diff --git a/chain/actors/builtin/miner/v0.go b/chain/actors/builtin/miner/v0.go index 9cdfc25bc..c0bd6f5dc 100644 --- a/chain/actors/builtin/miner/v0.go +++ b/chain/actors/builtin/miner/v0.go @@ -4,21 +4,31 @@ import ( "bytes" "errors" - "github.com/libp2p/go-libp2p-core/peer" - cbg "github.com/whyrusleeping/cbor-gen" - "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-bitfield" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/dline" - miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" - adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" + "github.com/ipfs/go-cid" + "github.com/libp2p/go-libp2p-core/peer" + cbg "github.com/whyrusleeping/cbor-gen" "github.com/filecoin-project/lotus/chain/actors/adt" + + miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" + adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" ) var _ State = (*state0)(nil) +func load0(store adt.Store, root cid.Cid) (State, error) { + out := state0{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + type state0 struct { miner0.State store adt.Store diff --git a/chain/actors/builtin/miner/v1.go b/chain/actors/builtin/miner/v1.go index 4c991b4f3..9259353f3 100644 --- a/chain/actors/builtin/miner/v1.go +++ b/chain/actors/builtin/miner/v1.go @@ -8,16 +8,27 @@ import ( "github.com/filecoin-project/go-bitfield" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/dline" - "github.com/filecoin-project/lotus/chain/actors/adt" - adt1 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" + "github.com/ipfs/go-cid" "github.com/libp2p/go-libp2p-core/peer" cbg "github.com/whyrusleeping/cbor-gen" + "github.com/filecoin-project/lotus/chain/actors/adt" + miner1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" + adt1 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" ) var _ State = (*state1)(nil) +func load1(store adt.Store, root cid.Cid) (State, error) { + out := state1{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + type state1 struct { miner1.State store adt.Store diff --git a/chain/actors/builtin/multisig/multisig.go b/chain/actors/builtin/multisig/multisig.go index a30082824..022e7e2c5 100644 --- a/chain/actors/builtin/multisig/multisig.go +++ b/chain/actors/builtin/multisig/multisig.go @@ -6,31 +6,32 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/cbor" + "github.com/ipfs/go-cid" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig" builtin1 "github.com/filecoin-project/specs-actors/v2/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" ) +func init() { + builtin.RegisterActorState(builtin0.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load0(store, root) + }) + builtin.RegisterActorState(builtin1.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load1(store, root) + }) +} + func Load(store adt.Store, act *types.Actor) (State, error) { switch act.Code { case builtin0.MultisigActorCodeID: - out := state0{store: store} - err := store.Get(store.Context(), act.Head, &out) - if err != nil { - return nil, err - } - return &out, nil + return load0(store, act.Head) case builtin1.MultisigActorCodeID: - out := state1{store: store} - err := store.Get(store.Context(), act.Head, &out) - if err != nil { - return nil, err - } - return &out, nil + return load1(store, act.Head) } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } diff --git a/chain/actors/builtin/multisig/v0.go b/chain/actors/builtin/multisig/v0.go index ae0a7ac0e..c934343e7 100644 --- a/chain/actors/builtin/multisig/v0.go +++ b/chain/actors/builtin/multisig/v0.go @@ -5,15 +5,26 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/ipfs/go-cid" "golang.org/x/xerrors" + "github.com/filecoin-project/lotus/chain/actors/adt" + msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig" adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" ) var _ State = (*state0)(nil) +func load0(store adt.Store, root cid.Cid) (State, error) { + out := state0{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + type state0 struct { msig0.State store adt.Store diff --git a/chain/actors/builtin/multisig/v1.go b/chain/actors/builtin/multisig/v1.go index 97b9ae4a3..7bfde404a 100644 --- a/chain/actors/builtin/multisig/v1.go +++ b/chain/actors/builtin/multisig/v1.go @@ -5,15 +5,26 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/ipfs/go-cid" "golang.org/x/xerrors" + "github.com/filecoin-project/lotus/chain/actors/adt" + msig1 "github.com/filecoin-project/specs-actors/actors/builtin/multisig" adt1 "github.com/filecoin-project/specs-actors/actors/util/adt" ) var _ State = (*state1)(nil) +func load1(store adt.Store, root cid.Cid) (State, error) { + out := state1{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + type state1 struct { msig1.State store adt.Store diff --git a/chain/actors/builtin/paych/paych.go b/chain/actors/builtin/paych/paych.go index 36cf56e63..959968f22 100644 --- a/chain/actors/builtin/paych/paych.go +++ b/chain/actors/builtin/paych/paych.go @@ -7,32 +7,33 @@ import ( "github.com/filecoin-project/go-state-types/abi" big "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/cbor" + "github.com/ipfs/go-cid" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych" builtin1 "github.com/filecoin-project/specs-actors/v2/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" ) +func init() { + builtin.RegisterActorState(builtin0.PaymentChannelActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load0(store, root) + }) + builtin.RegisterActorState(builtin1.PaymentChannelActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load1(store, root) + }) +} + // Load returns an abstract copy of payment channel state, irregardless of actor version func Load(store adt.Store, act *types.Actor) (State, error) { switch act.Code { case builtin0.PaymentChannelActorCodeID: - out := state0{store: store} - err := store.Get(store.Context(), act.Head, &out) - if err != nil { - return nil, err - } - return &out, nil + return load0(store, act.Head) case builtin1.PaymentChannelActorCodeID: - out := state1{store: store} - err := store.Get(store.Context(), act.Head, &out) - if err != nil { - return nil, err - } - return &out, nil + return load1(store, act.Head) } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } diff --git a/chain/actors/builtin/paych/v0.go b/chain/actors/builtin/paych/v0.go index c0eea1000..8e0e3434e 100644 --- a/chain/actors/builtin/paych/v0.go +++ b/chain/actors/builtin/paych/v0.go @@ -1,18 +1,31 @@ package paych import ( + "github.com/ipfs/go-cid" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" - big "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/lotus/chain/actors/adt" - "github.com/filecoin-project/specs-actors/actors/builtin/paych" + + paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych" adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" ) var _ State = (*state0)(nil) +func load0(store adt.Store, root cid.Cid) (State, error) { + out := state0{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + type state0 struct { - paych.State + paych0.State store adt.Store lsAmt *adt0.Array } @@ -72,14 +85,14 @@ func (s *state0) ForEachLaneState(cb func(idx uint64, dl LaneState) error) error // 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 paych.LaneState + var ls paych0.LaneState return lsamt.ForEach(&ls, func(i int64) error { return cb(uint64(i), &laneState0{ls}) }) } type laneState0 struct { - paych.LaneState + paych0.LaneState } func (ls *laneState0) Redeemed() (big.Int, error) { diff --git a/chain/actors/builtin/paych/v1.go b/chain/actors/builtin/paych/v1.go index 7a960067c..c1b47c120 100644 --- a/chain/actors/builtin/paych/v1.go +++ b/chain/actors/builtin/paych/v1.go @@ -1,18 +1,31 @@ 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" - "github.com/filecoin-project/specs-actors/v2/actors/builtin/paych" + + paych1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/paych" adt1 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" ) var _ State = (*state1)(nil) +func load1(store adt.Store, root cid.Cid) (State, error) { + out := state1{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + type state1 struct { - paych.State + paych1.State store adt.Store lsAmt *adt1.Array } @@ -72,14 +85,14 @@ func (s *state1) ForEachLaneState(cb func(idx uint64, dl LaneState) error) error // 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 paych.LaneState + var ls paych1.LaneState return lsamt.ForEach(&ls, func(i int64) error { return cb(uint64(i), &laneState1{ls}) }) } type laneState1 struct { - paych.LaneState + paych1.LaneState } func (ls *laneState1) Redeemed() (big.Int, error) { diff --git a/chain/actors/builtin/power/power.go b/chain/actors/builtin/power/power.go index 7aa86fe00..9dd61c07e 100644 --- a/chain/actors/builtin/power/power.go +++ b/chain/actors/builtin/power/power.go @@ -2,6 +2,7 @@ package power import ( "github.com/filecoin-project/go-address" + "github.com/ipfs/go-cid" "golang.org/x/xerrors" "github.com/filecoin-project/go-state-types/abi" @@ -15,24 +16,23 @@ import ( builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" ) +func init() { + builtin.RegisterActorState(builtin0.StoragePowerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load0(store, root) + }) + builtin.RegisterActorState(builtin1.StoragePowerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load1(store, root) + }) +} + var Address = builtin0.StoragePowerActorAddr func Load(store adt.Store, act *types.Actor) (st State, err error) { switch act.Code { case builtin0.StoragePowerActorCodeID: - out := state0{store: store} - err := store.Get(store.Context(), act.Head, &out) - if err != nil { - return nil, err - } - return &out, nil + return load0(store, act.Head) case builtin1.StoragePowerActorCodeID: - out := state1{store: store} - err := store.Get(store.Context(), act.Head, &out) - if err != nil { - return nil, err - } - return &out, nil + return load1(store, act.Head) } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } diff --git a/chain/actors/builtin/power/v0.go b/chain/actors/builtin/power/v0.go index 657de7ed0..e2a9cf382 100644 --- a/chain/actors/builtin/power/v0.go +++ b/chain/actors/builtin/power/v0.go @@ -3,6 +3,8 @@ package power 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/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" @@ -12,6 +14,15 @@ import ( var _ State = (*state0)(nil) +func load0(store adt.Store, root cid.Cid) (State, error) { + out := state0{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + type state0 struct { power0.State store adt.Store diff --git a/chain/actors/builtin/power/v1.go b/chain/actors/builtin/power/v1.go index 8c1a052b3..38df11916 100644 --- a/chain/actors/builtin/power/v1.go +++ b/chain/actors/builtin/power/v1.go @@ -3,6 +3,8 @@ package power 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/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" @@ -12,6 +14,15 @@ import ( var _ State = (*state1)(nil) +func load1(store adt.Store, root cid.Cid) (State, error) { + out := state1{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + type state1 struct { power1.State store adt.Store diff --git a/chain/actors/builtin/reward/reward.go b/chain/actors/builtin/reward/reward.go index 324bc95dd..e6d05de46 100644 --- a/chain/actors/builtin/reward/reward.go +++ b/chain/actors/builtin/reward/reward.go @@ -3,6 +3,7 @@ package reward import ( "github.com/filecoin-project/go-state-types/abi" reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward" + "github.com/ipfs/go-cid" "golang.org/x/xerrors" "github.com/filecoin-project/go-state-types/cbor" @@ -14,24 +15,23 @@ import ( "github.com/filecoin-project/lotus/chain/types" ) +func init() { + builtin.RegisterActorState(builtin0.RewardActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load0(store, root) + }) + builtin.RegisterActorState(builtin1.RewardActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load1(store, root) + }) +} + var Address = builtin0.RewardActorAddr func Load(store adt.Store, act *types.Actor) (st State, err error) { switch act.Code { case builtin0.RewardActorCodeID: - out := state0{store: store} - err := store.Get(store.Context(), act.Head, &out) - if err != nil { - return nil, err - } - return &out, nil + return load0(store, act.Head) case builtin1.RewardActorCodeID: - out := state1{store: store} - err := store.Get(store.Context(), act.Head, &out) - if err != nil { - return nil, err - } - return &out, nil + return load1(store, act.Head) } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } diff --git a/chain/actors/builtin/reward/v0.go b/chain/actors/builtin/reward/v0.go index 57084899d..0efd0b482 100644 --- a/chain/actors/builtin/reward/v0.go +++ b/chain/actors/builtin/reward/v0.go @@ -2,6 +2,8 @@ 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" @@ -12,6 +14,15 @@ import ( var _ State = (*state0)(nil) +func load0(store adt.Store, root cid.Cid) (State, error) { + out := state0{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + type state0 struct { reward0.State store adt.Store diff --git a/chain/actors/builtin/reward/v1.go b/chain/actors/builtin/reward/v1.go index f16256a00..9f94bbf1d 100644 --- a/chain/actors/builtin/reward/v1.go +++ b/chain/actors/builtin/reward/v1.go @@ -2,6 +2,8 @@ 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" @@ -12,6 +14,15 @@ import ( var _ State = (*state1)(nil) +func load1(store adt.Store, root cid.Cid) (State, error) { + out := state1{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + type state1 struct { reward1.State store adt.Store diff --git a/chain/actors/builtin/verifreg/v0.go b/chain/actors/builtin/verifreg/v0.go index 5cb053c79..c203cef39 100644 --- a/chain/actors/builtin/verifreg/v0.go +++ b/chain/actors/builtin/verifreg/v0.go @@ -3,6 +3,7 @@ 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" @@ -12,6 +13,15 @@ import ( var _ State = (*state0)(nil) +func load0(store adt.Store, root cid.Cid) (State, error) { + out := state0{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + type state0 struct { verifreg0.State store adt.Store diff --git a/chain/actors/builtin/verifreg/v1.go b/chain/actors/builtin/verifreg/v1.go index ec998f9e5..0c9e1b139 100644 --- a/chain/actors/builtin/verifreg/v1.go +++ b/chain/actors/builtin/verifreg/v1.go @@ -3,6 +3,7 @@ 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" @@ -12,6 +13,15 @@ import ( var _ State = (*state1)(nil) +func load1(store adt.Store, root cid.Cid) (State, error) { + out := state1{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + type state1 struct { verifreg1.State store adt.Store diff --git a/chain/actors/builtin/verifreg/verifreg.go b/chain/actors/builtin/verifreg/verifreg.go index 4255e8855..86b1c5939 100644 --- a/chain/actors/builtin/verifreg/verifreg.go +++ b/chain/actors/builtin/verifreg/verifreg.go @@ -3,6 +3,7 @@ package verifreg import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + "github.com/ipfs/go-cid" "golang.org/x/xerrors" "github.com/filecoin-project/go-state-types/cbor" @@ -10,27 +11,27 @@ import ( builtin1 "github.com/filecoin-project/specs-actors/v2/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" ) +func init() { + builtin.RegisterActorState(builtin0.VerifiedRegistryActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load0(store, root) + }) + builtin.RegisterActorState(builtin1.VerifiedRegistryActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load1(store, root) + }) +} + var Address = builtin0.VerifiedRegistryActorAddr func Load(store adt.Store, act *types.Actor) (State, error) { switch act.Code { case builtin0.VerifiedRegistryActorCodeID: - out := state0{store: store} - err := store.Get(store.Context(), act.Head, &out) - if err != nil { - return nil, err - } - return &out, nil + return load0(store, act.Head) case builtin1.VerifiedRegistryActorCodeID: - out := state1{store: store} - err := store.Get(store.Context(), act.Head, &out) - if err != nil { - return nil, err - } - return &out, nil + return load1(store, act.Head) } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } From 8b35f480c4f4c3dc7379f1767e2af8eeee4559f9 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Thu, 24 Sep 2020 17:51:34 -0700 Subject: [PATCH 008/115] initial vm conversion We're probably going to want to change some of these design decisions down the road, but this is a good starting point. * We may want to use a more general test for "is actor valid at epoch". Maybe just a function? * I'd like to push some of the actor metadata down into the actor types themselves. Ideally, we'd be able to register actors with a simple `Register(validation, manyActors...)` call. --- chain/stmgr/forks_test.go | 4 +- chain/vm/gas.go | 3 +- chain/vm/gas_v0.go | 6 +- chain/vm/invoker.go | 126 ++++++++++++++++++++++++-------------- chain/vm/invoker_test.go | 2 +- chain/vm/mkactor.go | 40 ++++++------ chain/vm/runtime.go | 18 ++---- chain/vm/vm.go | 10 +-- conformance/driver.go | 5 +- node/impl/full/chain.go | 2 +- node/impl/full/state.go | 2 +- 11 files changed, 121 insertions(+), 97 deletions(-) diff --git a/chain/stmgr/forks_test.go b/chain/stmgr/forks_test.go index 516058a81..8ec00f95f 100644 --- a/chain/stmgr/forks_test.go +++ b/chain/stmgr/forks_test.go @@ -106,7 +106,7 @@ func TestForkHeightTriggers(t *testing.T) { sm := NewStateManager(cg.ChainStore()) - inv := vm.NewInvoker() + inv := vm.NewActorRegistry() // predicting the address here... may break if other assumptions change taddr, err := address.NewIDAddress(1002) @@ -143,7 +143,7 @@ func TestForkHeightTriggers(t *testing.T) { return nil } - inv.Register(builtin.PaymentChannelActorCodeID, &testActor{}, &testActorState{}) + inv.Register(actors.Version0, builtin.PaymentChannelActorCodeID, &testActor{}, &testActorState{}, false) sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (*vm.VM, error) { nvm, err := vm.NewVM(ctx, vmopt) if err != nil { diff --git a/chain/vm/gas.go b/chain/vm/gas.go index 12acf6a21..6802013e5 100644 --- a/chain/vm/gas.go +++ b/chain/vm/gas.go @@ -9,7 +9,6 @@ import ( addr "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/crypto" - "github.com/filecoin-project/specs-actors/actors/runtime" vmr "github.com/filecoin-project/specs-actors/actors/runtime" "github.com/ipfs/go-cid" ) @@ -210,7 +209,7 @@ func (ps pricedSyscalls) VerifyPoSt(vi proof.WindowPoStVerifyInfo) error { // the "parent grinding fault", in which case it must be the sibling of h1 (same parent tipset) and one of the // blocks in the parent of h2 (i.e. h2's grandparent). // Returns nil and an error if the headers don't prove a fault. -func (ps pricedSyscalls) VerifyConsensusFault(h1 []byte, h2 []byte, extra []byte) (*runtime.ConsensusFault, error) { +func (ps pricedSyscalls) VerifyConsensusFault(h1 []byte, h2 []byte, extra []byte) (*vmr.ConsensusFault, error) { ps.chargeGas(ps.pl.OnVerifyConsensusFault()) defer ps.chargeGas(gasOnActorExec) diff --git a/chain/vm/gas_v0.go b/chain/vm/gas_v0.go index e5ded440e..bfb49c345 100644 --- a/chain/vm/gas_v0.go +++ b/chain/vm/gas_v0.go @@ -8,7 +8,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/crypto" - "github.com/filecoin-project/specs-actors/actors/builtin" + builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" ) type scalingCost struct { @@ -112,14 +112,14 @@ func (pl *pricelistV0) OnMethodInvocation(value abi.TokenAmount, methodNum abi.M if big.Cmp(value, abi.NewTokenAmount(0)) != 0 { ret += pl.sendTransferFunds - if methodNum == builtin.MethodSend { + if methodNum == builtin0.MethodSend { // transfer only ret += pl.sendTransferOnlyPremium } extra += "t" } - if methodNum != builtin.MethodSend { + if methodNum != builtin0.MethodSend { extra += "i" // running actors is cheaper becase we hand over to actors ret += pl.sendInvokeMethod diff --git a/chain/vm/invoker.go b/chain/vm/invoker.go index 7465074b4..48a574f9d 100644 --- a/chain/vm/invoker.go +++ b/chain/vm/invoker.go @@ -40,79 +40,113 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/exitcode" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/aerrors" + "github.com/filecoin-project/lotus/chain/types" ) -type Invoker struct { - builtInCode map[cid.Cid]nativeCode - builtInState map[cid.Cid]reflect.Type +type ActorRegistry struct { + actors map[cid.Cid]*actorInfo } type invokeFunc func(rt vmr.Runtime, params []byte) ([]byte, aerrors.ActorError) type nativeCode []invokeFunc -func NewInvoker() *Invoker { - inv := &Invoker{ - builtInCode: make(map[cid.Cid]nativeCode), - builtInState: make(map[cid.Cid]reflect.Type), - } +type actorInfo struct { + methods nativeCode + stateType reflect.Type + // TODO: consider making this a network version range? + version actors.Version + singleton bool +} + +func NewActorRegistry() *ActorRegistry { + inv := &ActorRegistry{actors: make(map[cid.Cid]*actorInfo)} + + // TODO: define all these properties on the actors themselves, in specs-actors. // add builtInCode using: register(cid, singleton) - inv.Register(builtin0.SystemActorCodeID, system0.Actor{}, abi.EmptyValue{}) - inv.Register(builtin0.InitActorCodeID, init0.Actor{}, init0.State{}) - inv.Register(builtin0.RewardActorCodeID, reward0.Actor{}, reward0.State{}) - inv.Register(builtin0.CronActorCodeID, cron0.Actor{}, cron0.State{}) - inv.Register(builtin0.StoragePowerActorCodeID, power0.Actor{}, power0.State{}) - inv.Register(builtin0.StorageMarketActorCodeID, market0.Actor{}, market0.State{}) - inv.Register(builtin0.StorageMinerActorCodeID, miner0.Actor{}, miner0.State{}) - inv.Register(builtin0.MultisigActorCodeID, msig0.Actor{}, msig0.State{}) - inv.Register(builtin0.PaymentChannelActorCodeID, paych0.Actor{}, paych0.State{}) - inv.Register(builtin0.VerifiedRegistryActorCodeID, verifreg0.Actor{}, verifreg0.State{}) - inv.Register(builtin0.AccountActorCodeID, account0.Actor{}, account0.State{}) + inv.Register(actors.Version0, builtin0.SystemActorCodeID, system0.Actor{}, abi.EmptyValue{}, true) + inv.Register(actors.Version0, builtin0.InitActorCodeID, init0.Actor{}, init0.State{}, true) + inv.Register(actors.Version0, builtin0.RewardActorCodeID, reward0.Actor{}, reward0.State{}, true) + inv.Register(actors.Version0, builtin0.CronActorCodeID, cron0.Actor{}, cron0.State{}, true) + inv.Register(actors.Version0, builtin0.StoragePowerActorCodeID, power0.Actor{}, power0.State{}, true) + inv.Register(actors.Version0, builtin0.StorageMarketActorCodeID, market0.Actor{}, market0.State{}, true) + inv.Register(actors.Version0, builtin0.VerifiedRegistryActorCodeID, verifreg0.Actor{}, verifreg0.State{}, true) + inv.Register(actors.Version0, builtin0.StorageMinerActorCodeID, miner0.Actor{}, miner0.State{}, false) + inv.Register(actors.Version0, builtin0.MultisigActorCodeID, msig0.Actor{}, msig0.State{}, false) + inv.Register(actors.Version0, builtin0.PaymentChannelActorCodeID, paych0.Actor{}, paych0.State{}, false) + inv.Register(actors.Version0, builtin0.AccountActorCodeID, account0.Actor{}, account0.State{}, false) - inv.Register(builtin1.SystemActorCodeID, system1.Actor{}, abi.EmptyValue{}) - inv.Register(builtin1.InitActorCodeID, init1.Actor{}, init1.State{}) - inv.Register(builtin1.RewardActorCodeID, reward1.Actor{}, reward1.State{}) - inv.Register(builtin1.CronActorCodeID, cron1.Actor{}, cron1.State{}) - inv.Register(builtin1.StoragePowerActorCodeID, power1.Actor{}, power1.State{}) - inv.Register(builtin1.StorageMarketActorCodeID, market1.Actor{}, market1.State{}) - inv.Register(builtin1.StorageMinerActorCodeID, miner1.Actor{}, miner1.State{}) - inv.Register(builtin1.MultisigActorCodeID, msig1.Actor{}, msig1.State{}) - inv.Register(builtin1.PaymentChannelActorCodeID, paych1.Actor{}, paych1.State{}) - inv.Register(builtin1.VerifiedRegistryActorCodeID, verifreg1.Actor{}, verifreg1.State{}) - inv.Register(builtin1.AccountActorCodeID, account1.Actor{}, account1.State{}) + inv.Register(actors.Version0, builtin1.SystemActorCodeID, system1.Actor{}, abi.EmptyValue{}, true) + inv.Register(actors.Version0, builtin1.InitActorCodeID, init1.Actor{}, init1.State{}, true) + inv.Register(actors.Version0, builtin1.RewardActorCodeID, reward1.Actor{}, reward1.State{}, true) + inv.Register(actors.Version0, builtin1.CronActorCodeID, cron1.Actor{}, cron1.State{}, true) + inv.Register(actors.Version0, builtin1.StoragePowerActorCodeID, power1.Actor{}, power1.State{}, true) + inv.Register(actors.Version0, builtin1.StorageMarketActorCodeID, market1.Actor{}, market1.State{}, true) + inv.Register(actors.Version0, builtin1.VerifiedRegistryActorCodeID, verifreg1.Actor{}, verifreg1.State{}, true) + inv.Register(actors.Version0, builtin1.StorageMinerActorCodeID, miner1.Actor{}, miner1.State{}, false) + inv.Register(actors.Version0, builtin1.MultisigActorCodeID, msig1.Actor{}, msig1.State{}, false) + inv.Register(actors.Version0, builtin1.PaymentChannelActorCodeID, paych1.Actor{}, paych1.State{}, false) + inv.Register(actors.Version0, builtin1.AccountActorCodeID, account1.Actor{}, account1.State{}, false) return inv } -func (inv *Invoker) Invoke(codeCid cid.Cid, rt vmr.Runtime, method abi.MethodNum, params []byte) ([]byte, aerrors.ActorError) { - - code, ok := inv.builtInCode[codeCid] +func (ar *ActorRegistry) Invoke(codeCid cid.Cid, rt vmr.Runtime, method abi.MethodNum, params []byte) ([]byte, aerrors.ActorError) { + act, ok := ar.actors[codeCid] if !ok { log.Errorf("no code for actor %s (Addr: %s)", codeCid, rt.Receiver()) return nil, aerrors.Newf(exitcode.SysErrorIllegalActor, "no code for actor %s(%d)(%s)", codeCid, method, hex.EncodeToString(params)) } - if method >= abi.MethodNum(len(code)) || code[method] == nil { + if method >= abi.MethodNum(len(act.methods)) || act.methods[method] == nil { return nil, aerrors.Newf(exitcode.SysErrInvalidMethod, "no method %d on actor", method) } - return code[method](rt, params) + if curVer := actors.VersionForNetwork(rt.NetworkVersion()); curVer != act.version { + return nil, aerrors.Newf(exitcode.SysErrInvalidMethod, "unsupported actors code version %d, expected %d", act.version, curVer) + } + return act.methods[method](rt, params) } -func (inv *Invoker) Register(c cid.Cid, instance Invokee, state interface{}) { - code, err := inv.transform(instance) +func (ar *ActorRegistry) Register(version actors.Version, c cid.Cid, instance Invokee, state interface{}, singleton bool) { + code, err := ar.transform(instance) if err != nil { panic(xerrors.Errorf("%s: %w", string(c.Hash()), err)) } - inv.builtInCode[c] = code - inv.builtInState[c] = reflect.TypeOf(state) + ar.actors[c] = &actorInfo{ + methods: code, + version: version, + stateType: reflect.TypeOf(state), + singleton: singleton, + } +} + +func (ar *ActorRegistry) Create(codeCid cid.Cid, rt vmr.Runtime) (*types.Actor, aerrors.ActorError) { + act, ok := ar.actors[codeCid] + if !ok { + return nil, aerrors.Newf(exitcode.SysErrorIllegalArgument, "Can only create built-in actors.") + } + if version := actors.VersionForNetwork(rt.NetworkVersion()); act.version != version { + return nil, aerrors.Newf(exitcode.SysErrorIllegalArgument, "Can only create version %d actors, attempted to create version %d actor", version, act.version) + } + + if act.singleton { + return nil, aerrors.Newf(exitcode.SysErrorIllegalArgument, "Can only have one instance of singleton actors.") + } + return &types.Actor{ + Code: codeCid, + Head: EmptyObjectCid, + Nonce: 0, + Balance: abi.NewTokenAmount(0), + }, nil } type Invokee interface { Exports() []interface{} } -func (*Invoker) transform(instance Invokee) (nativeCode, error) { +func (*ActorRegistry) transform(instance Invokee) (nativeCode, error) { itype := reflect.TypeOf(instance) exports := instance.Exports() runtimeType := reflect.TypeOf((*vmr.Runtime)(nil)).Elem() @@ -201,19 +235,19 @@ func DecodeParams(b []byte, out interface{}) error { return um.UnmarshalCBOR(bytes.NewReader(b)) } -func DumpActorState(code cid.Cid, b []byte) (interface{}, error) { - if code == builtin0.AccountActorCodeID { // Account code special case +func DumpActorState(act *types.Actor, b []byte) (interface{}, error) { + if act.IsAccountActor() { // Account code special case return nil, nil } - i := NewInvoker() // TODO: register builtins in init block + i := NewActorRegistry() // TODO: register builtins in init block - typ, ok := i.builtInState[code] + actInfo, ok := i.actors[act.Code] if !ok { - return nil, xerrors.Errorf("state type for actor %s not found", code) + return nil, xerrors.Errorf("state type for actor %s not found", act.Code) } - rv := reflect.New(typ) + rv := reflect.New(actInfo.stateType) um, ok := rv.Interface().(cbg.CBORUnmarshaler) if !ok { return nil, xerrors.New("state type does not implement CBORUnmarshaler") diff --git a/chain/vm/invoker_test.go b/chain/vm/invoker_test.go index 3744aa8d2..4005dd42f 100644 --- a/chain/vm/invoker_test.go +++ b/chain/vm/invoker_test.go @@ -77,7 +77,7 @@ func (basicContract) InvokeSomething10(rt runtime.Runtime, params *basicParams) } func TestInvokerBasic(t *testing.T) { - inv := Invoker{} + inv := ActorRegistry{} code, err := inv.transform(basicContract{}) assert.NoError(t, err) diff --git a/chain/vm/mkactor.go b/chain/vm/mkactor.go index 43d2f9431..26e8c3ba1 100644 --- a/chain/vm/mkactor.go +++ b/chain/vm/mkactor.go @@ -6,11 +6,13 @@ import ( "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/exitcode" "github.com/filecoin-project/lotus/chain/actors" - "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/ipfs/go-cid" cbor "github.com/ipfs/go-ipld-cbor" + builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/lotus/chain/actors/aerrors" "github.com/filecoin-project/lotus/chain/types" @@ -39,7 +41,7 @@ func TryCreateAccountActor(rt *Runtime, addr address.Address) (*types.Actor, aer return nil, aerrors.Escalate(err, "registering actor address") } - act, aerr := makeActor(addr) + act, aerr := makeActor(actors.VersionForNetwork(rt.NetworkVersion()), addr) if aerr != nil { return nil, aerr } @@ -54,7 +56,7 @@ func TryCreateAccountActor(rt *Runtime, addr address.Address) (*types.Actor, aer } // call constructor on account - _, aerr = rt.internalSend(builtin.SystemActorAddr, addrID, builtin.MethodsAccount.Constructor, big.Zero(), p) + _, aerr = rt.internalSend(builtin0.SystemActorAddr, addrID, builtin0.MethodsAccount.Constructor, big.Zero(), p) if aerr != nil { return nil, aerrors.Wrap(aerr, "failed to invoke account constructor") } @@ -66,12 +68,10 @@ func TryCreateAccountActor(rt *Runtime, addr address.Address) (*types.Actor, aer return act, nil } -func makeActor(addr address.Address) (*types.Actor, aerrors.ActorError) { +func makeActor(ver actors.Version, addr address.Address) (*types.Actor, aerrors.ActorError) { switch addr.Protocol() { - case address.BLS: - return NewBLSAccountActor(), nil - case address.SECP256K1: - return NewSecp256k1AccountActor(), nil + case address.BLS, address.SECP256K1: + return newAccountActor(ver), nil case address.ID: return nil, aerrors.Newf(exitcode.SysErrInvalidReceiver, "no actor with given ID: %s", addr) case address.Actor: @@ -81,19 +81,19 @@ func makeActor(addr address.Address) (*types.Actor, aerrors.ActorError) { } } -func NewBLSAccountActor() *types.Actor { +func newAccountActor(ver actors.Version) *types.Actor { + // TODO: ActorsUpgrade use a global actor registry? + var code cid.Cid + switch ver { + case actors.Version0: + code = builtin0.AccountActorCodeID + case actors.Version1: + code = builtin1.AccountActorCodeID + default: + panic("unsupported actors version") + } nact := &types.Actor{ - Code: builtin.AccountActorCodeID, - Balance: types.NewInt(0), - Head: EmptyObjectCid, - } - - return nact -} - -func NewSecp256k1AccountActor() *types.Actor { - nact := &types.Actor{ - Code: builtin.AccountActorCodeID, + Code: code, Balance: types.NewInt(0), Head: EmptyObjectCid, } diff --git a/chain/vm/runtime.go b/chain/vm/runtime.go index 156d57282..3dcd269fa 100644 --- a/chain/vm/runtime.go +++ b/chain/vm/runtime.go @@ -10,13 +10,11 @@ import ( "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/go-state-types/cbor" "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/go-state-types/exitcode" "github.com/filecoin-project/go-state-types/network" rtt "github.com/filecoin-project/go-state-types/rt" - "github.com/filecoin-project/specs-actors/actors/builtin" rt0 "github.com/filecoin-project/specs-actors/actors/runtime" "github.com/ipfs/go-cid" ipldcbor "github.com/ipfs/go-ipld-cbor" @@ -216,12 +214,9 @@ func (rt *Runtime) NewActorAddress() address.Address { } func (rt *Runtime) CreateActor(codeID cid.Cid, address address.Address) { - if !builtin.IsBuiltinActor(codeID) { - rt.Abortf(exitcode.SysErrorIllegalArgument, "Can only create built-in actors.") - } - - if builtin.IsSingletonActor(codeID) { - rt.Abortf(exitcode.SysErrorIllegalArgument, "Can only have one instance of singleton actors.") + act, aerr := rt.vm.areg.Create(codeID, rt) + if aerr != nil { + rt.Abortf(aerr.RetCode(), aerr.Error()) } _, err := rt.state.GetActor(address) @@ -231,12 +226,7 @@ func (rt *Runtime) CreateActor(codeID cid.Cid, address address.Address) { rt.chargeGas(rt.Pricelist().OnCreateActor()) - err = rt.state.SetActor(address, &types.Actor{ - Code: codeID, - Head: EmptyObjectCid, - Nonce: 0, - Balance: big.Zero(), - }) + err = rt.state.SetActor(address, act) if err != nil { panic(aerrors.Fatalf("creating actor entry: %v", err)) } diff --git a/chain/vm/vm.go b/chain/vm/vm.go index 54ea47698..d92d16310 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -152,7 +152,7 @@ type VM struct { cst *cbor.BasicIpldStore buf *bufbstore.BufferedBS blockHeight abi.ChainEpoch - inv *Invoker + areg *ActorRegistry rand Rand circSupplyCalc CircSupplyCalculator ntwkVersion NtwkVersionGetter @@ -186,7 +186,7 @@ func NewVM(ctx context.Context, opts *VMOpts) (*VM, error) { cst: cst, buf: buf, blockHeight: opts.Epoch, - inv: NewInvoker(), + areg: NewActorRegistry(), rand: opts.Rand, // TODO: Probably should be a syscall circSupplyCalc: opts.CircSupplyCalc, ntwkVersion: opts.NtwkVersion, @@ -734,15 +734,15 @@ func (vm *VM) Invoke(act *types.Actor, rt *Runtime, method abi.MethodNum, params defer func() { rt.ctx = oldCtx }() - ret, err := vm.inv.Invoke(act.Code, rt, method, params) + ret, err := vm.areg.Invoke(act.Code, rt, method, params) if err != nil { return nil, err } return ret, nil } -func (vm *VM) SetInvoker(i *Invoker) { - vm.inv = i +func (vm *VM) SetInvoker(i *ActorRegistry) { + vm.areg = i } func (vm *VM) GetNtwkVersion(ctx context.Context, ce abi.ChainEpoch) network.Version { diff --git a/conformance/driver.go b/conformance/driver.go index f43a8739d..1a63aaff3 100644 --- a/conformance/driver.go +++ b/conformance/driver.go @@ -5,6 +5,7 @@ import ( "github.com/filecoin-project/go-state-types/crypto" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" @@ -140,11 +141,11 @@ func (d *Driver) ExecuteMessage(bs blockstore.Blockstore, preroot cid.Cid, epoch return nil, cid.Undef, err } - invoker := vm.NewInvoker() + invoker := vm.NewActorRegistry() // register the chaos actor if required by the vector. if chaosOn, ok := d.selector["chaos_actor"]; ok && chaosOn == "true" { - invoker.Register(chaos.ChaosActorCodeCID, chaos.Actor{}, chaos.State{}) + invoker.Register(actors.Version0, chaos.ChaosActorCodeCID, chaos.Actor{}, chaos.State{}, true) } lvm.SetInvoker(invoker) diff --git a/node/impl/full/chain.go b/node/impl/full/chain.go index 9606a023a..ea715c66a 100644 --- a/node/impl/full/chain.go +++ b/node/impl/full/chain.go @@ -422,7 +422,7 @@ func resolveOnce(bs blockstore.Blockstore) func(ctx context.Context, ds ipld.Nod return nil, nil, xerrors.Errorf("getting actor head for @state: %w", err) } - m, err := vm.DumpActorState(act.Code, head.RawData()) + m, err := vm.DumpActorState(&act, head.RawData()) if err != nil { return nil, nil, err } diff --git a/node/impl/full/state.go b/node/impl/full/state.go index f8bf92a92..d2bf5cf25 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -411,7 +411,7 @@ func (a *StateAPI) StateReadState(ctx context.Context, actor address.Address, ts return nil, xerrors.Errorf("getting actor head: %w", err) } - oif, err := vm.DumpActorState(act.Code, blk.RawData()) + oif, err := vm.DumpActorState(act, blk.RawData()) if err != nil { return nil, xerrors.Errorf("dumping actor state (a:%s): %w", actor, err) } From 7d3bd146e663674e449737acc70eaf6feda8bbf8 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Fri, 25 Sep 2020 12:51:02 -0700 Subject: [PATCH 009/115] rebase fixup --- chain/state/statetree.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chain/state/statetree.go b/chain/state/statetree.go index acf67e977..179e6dd02 100644 --- a/chain/state/statetree.go +++ b/chain/state/statetree.go @@ -396,7 +396,7 @@ func (st *StateTree) ForEach(f func(address.Address, *types.Actor) error) error } // Version returns the version of the StateTree data structure in use. -func (st *StateTree) Version() builtin.Version { +func (st *StateTree) Version() actors.Version { return st.version } From b8d9d7894fad1662ff29e12ac947ad89d0dc6ca0 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Fri, 25 Sep 2020 12:52:16 -0700 Subject: [PATCH 010/115] fix vm version --- chain/vm/invoker.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/chain/vm/invoker.go b/chain/vm/invoker.go index 48a574f9d..e137e71e4 100644 --- a/chain/vm/invoker.go +++ b/chain/vm/invoker.go @@ -78,17 +78,17 @@ func NewActorRegistry() *ActorRegistry { inv.Register(actors.Version0, builtin0.PaymentChannelActorCodeID, paych0.Actor{}, paych0.State{}, false) inv.Register(actors.Version0, builtin0.AccountActorCodeID, account0.Actor{}, account0.State{}, false) - inv.Register(actors.Version0, builtin1.SystemActorCodeID, system1.Actor{}, abi.EmptyValue{}, true) - inv.Register(actors.Version0, builtin1.InitActorCodeID, init1.Actor{}, init1.State{}, true) - inv.Register(actors.Version0, builtin1.RewardActorCodeID, reward1.Actor{}, reward1.State{}, true) - inv.Register(actors.Version0, builtin1.CronActorCodeID, cron1.Actor{}, cron1.State{}, true) - inv.Register(actors.Version0, builtin1.StoragePowerActorCodeID, power1.Actor{}, power1.State{}, true) - inv.Register(actors.Version0, builtin1.StorageMarketActorCodeID, market1.Actor{}, market1.State{}, true) - inv.Register(actors.Version0, builtin1.VerifiedRegistryActorCodeID, verifreg1.Actor{}, verifreg1.State{}, true) - inv.Register(actors.Version0, builtin1.StorageMinerActorCodeID, miner1.Actor{}, miner1.State{}, false) - inv.Register(actors.Version0, builtin1.MultisigActorCodeID, msig1.Actor{}, msig1.State{}, false) - inv.Register(actors.Version0, builtin1.PaymentChannelActorCodeID, paych1.Actor{}, paych1.State{}, false) - inv.Register(actors.Version0, builtin1.AccountActorCodeID, account1.Actor{}, account1.State{}, false) + inv.Register(actors.Version1, builtin1.SystemActorCodeID, system1.Actor{}, abi.EmptyValue{}, true) + inv.Register(actors.Version1, builtin1.InitActorCodeID, init1.Actor{}, init1.State{}, true) + inv.Register(actors.Version1, builtin1.RewardActorCodeID, reward1.Actor{}, reward1.State{}, true) + inv.Register(actors.Version1, builtin1.CronActorCodeID, cron1.Actor{}, cron1.State{}, true) + inv.Register(actors.Version1, builtin1.StoragePowerActorCodeID, power1.Actor{}, power1.State{}, true) + inv.Register(actors.Version1, builtin1.StorageMarketActorCodeID, market1.Actor{}, market1.State{}, true) + inv.Register(actors.Version1, builtin1.VerifiedRegistryActorCodeID, verifreg1.Actor{}, verifreg1.State{}, true) + inv.Register(actors.Version1, builtin1.StorageMinerActorCodeID, miner1.Actor{}, miner1.State{}, false) + inv.Register(actors.Version1, builtin1.MultisigActorCodeID, msig1.Actor{}, msig1.State{}, false) + inv.Register(actors.Version1, builtin1.PaymentChannelActorCodeID, paych1.Actor{}, paych1.State{}, false) + inv.Register(actors.Version1, builtin1.AccountActorCodeID, account1.Actor{}, account1.State{}, false) return inv } From 271ceb968a3b8d0d494ee8c867f102e0c6e5c3f4 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Fri, 25 Sep 2020 12:55:10 -0700 Subject: [PATCH 011/115] add v1 support to the state tree --- chain/state/statetree.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/chain/state/statetree.go b/chain/state/statetree.go index 179e6dd02..7a2e70cdc 100644 --- a/chain/state/statetree.go +++ b/chain/state/statetree.go @@ -125,6 +125,12 @@ func NewStateTree(cst cbor.IpldStore, version actors.Version) (*StateTree, error switch version { case actors.Version0: // info is undefined + case actors.Version1: + var err error + info, err = cst.Put(context.TODO(), new(types.StateInfo)) + if err != nil { + return nil, err + } default: return nil, xerrors.Errorf("unsupported state tree version: %d", version) } @@ -159,7 +165,7 @@ func LoadStateTree(cst cbor.IpldStore, c cid.Cid) (*StateTree, error) { } switch root.Version { - case actors.Version0: + case actors.Version0, actors.Version1: // supported default: return nil, xerrors.Errorf("unsupported state tree version: %d", root.Version) From 5f3160cf5bf3fd304882a6756e605131d35dfd6c Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 28 Sep 2020 12:48:08 -0700 Subject: [PATCH 012/115] continue expanding vm abstraction layer --- chain/actors/builtin/builtin.go | 17 +++ chain/stmgr/forks_test.go | 25 +++- chain/stmgr/utils.go | 88 +++---------- chain/vm/invoker.go | 119 +++++++----------- cli/state.go | 27 ++-- .../processor/common_actors.go | 25 ++-- conformance/chaos/actor.go | 8 +- conformance/driver.go | 3 +- go.mod | 6 +- go.sum | 10 +- 10 files changed, 135 insertions(+), 193 deletions(-) diff --git a/chain/actors/builtin/builtin.go b/chain/actors/builtin/builtin.go index 49a07951b..a0567dc27 100644 --- a/chain/actors/builtin/builtin.go +++ b/chain/actors/builtin/builtin.go @@ -10,9 +10,11 @@ import ( "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/types" + builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof" smoothing0 "github.com/filecoin-project/specs-actors/actors/util/smoothing" + builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" smoothing1 "github.com/filecoin-project/specs-actors/v2/actors/util/smoothing" ) @@ -49,3 +51,18 @@ func Load(store adt.Store, act *types.Actor) (cbor.Marshaler, error) { } return loader(store, act.Head) } + +func ActorNameByCode(c cid.Cid) string { + switch { + case builtin0.IsBuiltinActor(c): + return builtin0.ActorNameByCode(c) + case builtin1.IsBuiltinActor(c): + return builtin1.ActorNameByCode(c) + default: + return "" + } +} + +func IsBuiltinActor(c cid.Cid) bool { + return builtin0.IsBuiltinActor(c) || builtin1.IsBuiltinActor(c) +} diff --git a/chain/stmgr/forks_test.go b/chain/stmgr/forks_test.go index 8ec00f95f..d2ab74bc7 100644 --- a/chain/stmgr/forks_test.go +++ b/chain/stmgr/forks_test.go @@ -8,9 +8,11 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/cbor" "github.com/filecoin-project/specs-actors/actors/builtin" init_ "github.com/filecoin-project/specs-actors/actors/builtin/init" "github.com/filecoin-project/specs-actors/actors/runtime" + "github.com/multiformats/go-multihash" "golang.org/x/xerrors" "github.com/filecoin-project/lotus/chain/actors" @@ -25,7 +27,8 @@ import ( _ "github.com/filecoin-project/lotus/lib/sigs/bls" _ "github.com/filecoin-project/lotus/lib/sigs/secp" - cbor "github.com/ipfs/go-ipld-cbor" + "github.com/ipfs/go-cid" + ipldcbor "github.com/ipfs/go-ipld-cbor" logging "github.com/ipfs/go-log" cbg "github.com/whyrusleeping/cbor-gen" ) @@ -41,6 +44,18 @@ const testForkHeight = 40 type testActor struct { } +var testActorCodeID = func() cid.Cid { + builder := cid.V1Builder{Codec: cid.Raw, MhType: multihash.IDENTITY} + c, err := builder.Sum([]byte("fil/any/test")) + if err != nil { + panic(err) + } + return c +}() + +func (testActor) Code() cid.Cid { return testActorCodeID } +func (testActor) State() cbor.Er { return new(testActorState) } + type testActorState struct { HasUpgraded uint64 } @@ -61,7 +76,7 @@ func (tas *testActorState) UnmarshalCBOR(r io.Reader) error { return nil } -func (ta *testActor) Exports() []interface{} { +func (ta testActor) Exports() []interface{} { return []interface{}{ 1: ta.Constructor, 2: ta.TestMethod, @@ -115,7 +130,7 @@ func TestForkHeightTriggers(t *testing.T) { } stmgr.ForksAtHeight[testForkHeight] = func(ctx context.Context, sm *StateManager, st types.StateTree, ts *types.TipSet) error { - cst := cbor.NewCborStore(sm.ChainStore().Blockstore()) + cst := ipldcbor.NewCborStore(sm.ChainStore().Blockstore()) act, err := st.GetActor(taddr) if err != nil { @@ -143,7 +158,7 @@ func TestForkHeightTriggers(t *testing.T) { return nil } - inv.Register(actors.Version0, builtin.PaymentChannelActorCodeID, &testActor{}, &testActorState{}, false) + inv.Register(nil, testActor{}) sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (*vm.VM, error) { nvm, err := vm.NewVM(ctx, vmopt) if err != nil { @@ -157,7 +172,7 @@ func TestForkHeightTriggers(t *testing.T) { var msgs []*types.SignedMessage - enc, err := actors.SerializeParams(&init_.ExecParams{CodeCID: builtin.PaymentChannelActorCodeID}) + enc, err := actors.SerializeParams(&init_.ExecParams{CodeCID: (testActor{}).Code()}) if err != nil { t.Fatal(err) } diff --git a/chain/stmgr/utils.go b/chain/stmgr/utils.go index 0d7be7adf..aedd324c2 100644 --- a/chain/stmgr/utils.go +++ b/chain/stmgr/utils.go @@ -17,32 +17,13 @@ import ( "github.com/filecoin-project/go-bitfield" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/crypto" + "github.com/filecoin-project/go-state-types/rt" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - account0 "github.com/filecoin-project/specs-actors/actors/builtin/account" - cron0 "github.com/filecoin-project/specs-actors/actors/builtin/cron" - init0 "github.com/filecoin-project/specs-actors/actors/builtin/init" - market0 "github.com/filecoin-project/specs-actors/actors/builtin/market" - miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" - msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig" - paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych" - power0 "github.com/filecoin-project/specs-actors/actors/builtin/power" - reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward" - verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg" + exported0 "github.com/filecoin-project/specs-actors/actors/builtin/exported" + exported1 "github.com/filecoin-project/specs-actors/actors/builtin/exported" proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof" - builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" - account1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/account" - cron1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/cron" - init1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/init" - market1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market" - miner1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" - msig1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig" - paych1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/paych" - power1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/power" - reward1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/reward" - verifreg1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/verifreg" - "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init" @@ -545,34 +526,13 @@ type MethodMeta struct { var MethodsMap = map[cid.Cid]map[abi.MethodNum]MethodMeta{} func init() { - cidToMethods := map[cid.Cid][2]interface{}{ - // builtin.SystemActorCodeID: {builtin.MethodsSystem, system.Actor{} }- apparently it doesn't have methods - builtin0.InitActorCodeID: {builtin0.MethodsInit, init0.Actor{}}, - builtin0.CronActorCodeID: {builtin0.MethodsCron, cron0.Actor{}}, - builtin0.AccountActorCodeID: {builtin0.MethodsAccount, account0.Actor{}}, - builtin0.StoragePowerActorCodeID: {builtin0.MethodsPower, power0.Actor{}}, - builtin0.StorageMinerActorCodeID: {builtin0.MethodsMiner, miner0.Actor{}}, - builtin0.StorageMarketActorCodeID: {builtin0.MethodsMarket, market0.Actor{}}, - builtin0.PaymentChannelActorCodeID: {builtin0.MethodsPaych, paych0.Actor{}}, - builtin0.MultisigActorCodeID: {builtin0.MethodsMultisig, msig0.Actor{}}, - builtin0.RewardActorCodeID: {builtin0.MethodsReward, reward0.Actor{}}, - builtin0.VerifiedRegistryActorCodeID: {builtin0.MethodsVerifiedRegistry, verifreg0.Actor{}}, + // TODO: combine with the runtime actor registry. + var actors []rt.VMActor + actors = append(actors, exported0.BuiltinActors()...) + actors = append(actors, exported1.BuiltinActors()...) - // builtin1.SystemActorCodeID: {builtin1.MethodsSystem, system.Actor{} }- apparently it doesn't have methods - builtin1.InitActorCodeID: {builtin1.MethodsInit, init1.Actor{}}, - builtin1.CronActorCodeID: {builtin1.MethodsCron, cron1.Actor{}}, - builtin1.AccountActorCodeID: {builtin1.MethodsAccount, account1.Actor{}}, - builtin1.StoragePowerActorCodeID: {builtin1.MethodsPower, power1.Actor{}}, - builtin1.StorageMinerActorCodeID: {builtin1.MethodsMiner, miner1.Actor{}}, - builtin1.StorageMarketActorCodeID: {builtin1.MethodsMarket, market1.Actor{}}, - builtin1.PaymentChannelActorCodeID: {builtin1.MethodsPaych, paych1.Actor{}}, - builtin1.MultisigActorCodeID: {builtin1.MethodsMultisig, msig1.Actor{}}, - builtin1.RewardActorCodeID: {builtin1.MethodsReward, reward1.Actor{}}, - builtin1.VerifiedRegistryActorCodeID: {builtin1.MethodsVerifiedRegistry, verifreg1.Actor{}}, - } - - for c, m := range cidToMethods { - exports := m[1].(vm.Invokee).Exports() + for _, actor := range actors { + exports := actor.Exports() methods := make(map[abi.MethodNum]MethodMeta, len(exports)) // Explicitly add send, it's special. @@ -583,17 +543,6 @@ func init() { Ret: reflect.TypeOf(new(abi.EmptyValue)), } - // Learn method names from the builtin.Methods* structs. - rv := reflect.ValueOf(m[0]) - rt := rv.Type() - nf := rt.NumField() - methodToName := make([]string, len(exports)) - for i := 0; i < nf; i++ { - name := rt.Field(i).Name - number := rv.Field(i).Interface().(abi.MethodNum) - methodToName[number] = name - } - // Iterate over exported methods. Some of these _may_ be nil and // must be skipped. for number, export := range exports { @@ -604,24 +553,19 @@ func init() { ev := reflect.ValueOf(export) et := ev.Type() - // Make sure the method name is correct. - // This is just a nice sanity check. + // Extract the method names using reflection. These + // method names always match the field names in the + // `builtin.Method*` structs (tested in the specs-actors + // tests). fnName := runtime.FuncForPC(ev.Pointer()).Name() fnName = strings.TrimSuffix(fnName[strings.LastIndexByte(fnName, '.')+1:], "-fm") - mName := methodToName[number] - if mName != fnName { - panic(fmt.Sprintf( - "actor method name is %s but exported method name is %s", - fnName, mName, - )) - } switch abi.MethodNum(number) { - // Note that builtin1.MethodSend = builtin0.MethodSend = 0. case builtin0.MethodSend: + // Note that builtin1.MethodSend = builtin0.MethodSend = 0. panic("method 0 is reserved for Send") - // Note that builtin1.MethodConstructor = builtin0.MethodConstructor = 1. case builtin0.MethodConstructor: + // Note that builtin1.MethodConstructor = builtin0.MethodConstructor = 1. if fnName != "Constructor" { panic("method 1 is reserved for Constructor") } @@ -633,7 +577,7 @@ func init() { Ret: et.Out(0), } } - MethodsMap[c] = methods + MethodsMap[actor.Code()] = methods } } diff --git a/chain/vm/invoker.go b/chain/vm/invoker.go index e137e71e4..1f3db3ee9 100644 --- a/chain/vm/invoker.go +++ b/chain/vm/invoker.go @@ -10,35 +10,13 @@ import ( cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" - builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - account0 "github.com/filecoin-project/specs-actors/actors/builtin/account" - cron0 "github.com/filecoin-project/specs-actors/actors/builtin/cron" - init0 "github.com/filecoin-project/specs-actors/actors/builtin/init" - market0 "github.com/filecoin-project/specs-actors/actors/builtin/market" - miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" - msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig" - paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych" - power0 "github.com/filecoin-project/specs-actors/actors/builtin/power" - reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward" - system0 "github.com/filecoin-project/specs-actors/actors/builtin/system" - verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg" - - builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" - account1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/account" - cron1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/cron" - init1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/init" - market1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market" - miner1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" - msig1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig" - paych1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/paych" - power1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/power" - reward1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/reward" - system1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/system" - verifreg1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/verifreg" + exported0 "github.com/filecoin-project/specs-actors/actors/builtin/exported" + exported1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/exported" vmr "github.com/filecoin-project/specs-actors/v2/actors/runtime" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/exitcode" + rtt "github.com/filecoin-project/go-state-types/rt" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/aerrors" @@ -49,15 +27,27 @@ type ActorRegistry struct { actors map[cid.Cid]*actorInfo } +// An ActorPredicate returns an error if the given actor is not valid for the given runtime environment (e.g., chain height, version, etc.). +type ActorPredicate func(vmr.Runtime, rtt.VMActor) error + +func ActorsVersionPredicate(ver actors.Version) ActorPredicate { + return func(rt vmr.Runtime, v rtt.VMActor) error { + nver := actors.VersionForNetwork(rt.NetworkVersion()) + if nver != ver { + return xerrors.Errorf("actor %s is a version %d actor; chain only supports actor version %d at height %d", v.Code(), ver, nver, rt.CurrEpoch()) + } + return nil + } +} + type invokeFunc func(rt vmr.Runtime, params []byte) ([]byte, aerrors.ActorError) type nativeCode []invokeFunc type actorInfo struct { - methods nativeCode - stateType reflect.Type + methods nativeCode + vmActor rtt.VMActor // TODO: consider making this a network version range? - version actors.Version - singleton bool + predicate ActorPredicate } func NewActorRegistry() *ActorRegistry { @@ -66,29 +56,8 @@ func NewActorRegistry() *ActorRegistry { // TODO: define all these properties on the actors themselves, in specs-actors. // add builtInCode using: register(cid, singleton) - inv.Register(actors.Version0, builtin0.SystemActorCodeID, system0.Actor{}, abi.EmptyValue{}, true) - inv.Register(actors.Version0, builtin0.InitActorCodeID, init0.Actor{}, init0.State{}, true) - inv.Register(actors.Version0, builtin0.RewardActorCodeID, reward0.Actor{}, reward0.State{}, true) - inv.Register(actors.Version0, builtin0.CronActorCodeID, cron0.Actor{}, cron0.State{}, true) - inv.Register(actors.Version0, builtin0.StoragePowerActorCodeID, power0.Actor{}, power0.State{}, true) - inv.Register(actors.Version0, builtin0.StorageMarketActorCodeID, market0.Actor{}, market0.State{}, true) - inv.Register(actors.Version0, builtin0.VerifiedRegistryActorCodeID, verifreg0.Actor{}, verifreg0.State{}, true) - inv.Register(actors.Version0, builtin0.StorageMinerActorCodeID, miner0.Actor{}, miner0.State{}, false) - inv.Register(actors.Version0, builtin0.MultisigActorCodeID, msig0.Actor{}, msig0.State{}, false) - inv.Register(actors.Version0, builtin0.PaymentChannelActorCodeID, paych0.Actor{}, paych0.State{}, false) - inv.Register(actors.Version0, builtin0.AccountActorCodeID, account0.Actor{}, account0.State{}, false) - - inv.Register(actors.Version1, builtin1.SystemActorCodeID, system1.Actor{}, abi.EmptyValue{}, true) - inv.Register(actors.Version1, builtin1.InitActorCodeID, init1.Actor{}, init1.State{}, true) - inv.Register(actors.Version1, builtin1.RewardActorCodeID, reward1.Actor{}, reward1.State{}, true) - inv.Register(actors.Version1, builtin1.CronActorCodeID, cron1.Actor{}, cron1.State{}, true) - inv.Register(actors.Version1, builtin1.StoragePowerActorCodeID, power1.Actor{}, power1.State{}, true) - inv.Register(actors.Version1, builtin1.StorageMarketActorCodeID, market1.Actor{}, market1.State{}, true) - inv.Register(actors.Version1, builtin1.VerifiedRegistryActorCodeID, verifreg1.Actor{}, verifreg1.State{}, true) - inv.Register(actors.Version1, builtin1.StorageMinerActorCodeID, miner1.Actor{}, miner1.State{}, false) - inv.Register(actors.Version1, builtin1.MultisigActorCodeID, msig1.Actor{}, msig1.State{}, false) - inv.Register(actors.Version1, builtin1.PaymentChannelActorCodeID, paych1.Actor{}, paych1.State{}, false) - inv.Register(actors.Version1, builtin1.AccountActorCodeID, account1.Actor{}, account1.State{}, false) + inv.Register(ActorsVersionPredicate(actors.Version0), exported0.BuiltinActors()...) + inv.Register(ActorsVersionPredicate(actors.Version1), exported1.BuiltinActors()...) return inv } @@ -102,23 +71,27 @@ func (ar *ActorRegistry) Invoke(codeCid cid.Cid, rt vmr.Runtime, method abi.Meth if method >= abi.MethodNum(len(act.methods)) || act.methods[method] == nil { return nil, aerrors.Newf(exitcode.SysErrInvalidMethod, "no method %d on actor", method) } - if curVer := actors.VersionForNetwork(rt.NetworkVersion()); curVer != act.version { - return nil, aerrors.Newf(exitcode.SysErrInvalidMethod, "unsupported actors code version %d, expected %d", act.version, curVer) + if err := act.predicate(rt, act.vmActor); err != nil { + return nil, aerrors.Newf(exitcode.SysErrInvalidMethod, "unsupported actor: %s", err) } return act.methods[method](rt, params) } -func (ar *ActorRegistry) Register(version actors.Version, c cid.Cid, instance Invokee, state interface{}, singleton bool) { - code, err := ar.transform(instance) - if err != nil { - panic(xerrors.Errorf("%s: %w", string(c.Hash()), err)) +func (ar *ActorRegistry) Register(pred ActorPredicate, actors ...rtt.VMActor) { + if pred == nil { + pred = func(vmr.Runtime, rtt.VMActor) error { return nil } } - ar.actors[c] = &actorInfo{ - methods: code, - version: version, - stateType: reflect.TypeOf(state), - singleton: singleton, + for _, a := range actors { + code, err := ar.transform(a) + if err != nil { + panic(xerrors.Errorf("%s: %w", string(a.Code().Hash()), err)) + } + ar.actors[a.Code()] = &actorInfo{ + methods: code, + vmActor: a, + predicate: pred, + } } } @@ -127,11 +100,12 @@ func (ar *ActorRegistry) Create(codeCid cid.Cid, rt vmr.Runtime) (*types.Actor, if !ok { return nil, aerrors.Newf(exitcode.SysErrorIllegalArgument, "Can only create built-in actors.") } - if version := actors.VersionForNetwork(rt.NetworkVersion()); act.version != version { - return nil, aerrors.Newf(exitcode.SysErrorIllegalArgument, "Can only create version %d actors, attempted to create version %d actor", version, act.version) + + if err := act.predicate(rt, act.vmActor); err != nil { + return nil, aerrors.Newf(exitcode.SysErrorIllegalArgument, "Cannot create actor: %w", err) } - if act.singleton { + if rtt.IsSingletonActor(act.vmActor) { return nil, aerrors.Newf(exitcode.SysErrorIllegalArgument, "Can only have one instance of singleton actors.") } return &types.Actor{ @@ -142,11 +116,11 @@ func (ar *ActorRegistry) Create(codeCid cid.Cid, rt vmr.Runtime) (*types.Actor, }, nil } -type Invokee interface { +type invokee interface { Exports() []interface{} } -func (*ActorRegistry) transform(instance Invokee) (nativeCode, error) { +func (*ActorRegistry) transform(instance invokee) (nativeCode, error) { itype := reflect.TypeOf(instance) exports := instance.Exports() runtimeType := reflect.TypeOf((*vmr.Runtime)(nil)).Elem() @@ -247,15 +221,10 @@ func DumpActorState(act *types.Actor, b []byte) (interface{}, error) { return nil, xerrors.Errorf("state type for actor %s not found", act.Code) } - rv := reflect.New(actInfo.stateType) - um, ok := rv.Interface().(cbg.CBORUnmarshaler) - if !ok { - return nil, xerrors.New("state type does not implement CBORUnmarshaler") - } - + um := actInfo.vmActor.State() if err := um.UnmarshalCBOR(bytes.NewReader(b)); err != nil { return nil, xerrors.Errorf("unmarshaling actor state: %w", err) } - return rv.Elem().Interface(), nil + return um, nil } diff --git a/cli/state.go b/cli/state.go index d96c93c54..610fcac03 100644 --- a/cli/state.go +++ b/cli/state.go @@ -14,8 +14,6 @@ import ( "strings" "time" - "github.com/filecoin-project/specs-actors/actors/runtime" - "github.com/multiformats/go-multiaddr" "github.com/ipfs/go-cid" @@ -30,7 +28,6 @@ import ( "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/exitcode" "github.com/filecoin-project/specs-actors/actors/builtin" - "github.com/filecoin-project/specs-actors/actors/builtin/exported" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" @@ -1513,28 +1510,18 @@ func parseParamsForMethod(act cid.Cid, method uint64, args []string) ([]byte, er return nil, nil } - var target runtime.Invokee - for _, actor := range exported.BuiltinActors() { - if actor.Code() == act { - target = actor - } - } - if target == nil { + // TODO: consider moving this to a dedicated helper + actMeta, ok := stmgr.MethodsMap[act] + if !ok { return nil, fmt.Errorf("unknown actor %s", act) } - methods := target.Exports() - if uint64(len(methods)) <= method || methods[method] == nil { + + methodMeta, ok := actMeta[abi.MethodNum(method)] + if !ok { return nil, fmt.Errorf("unknown method %d for actor %s", method, act) } - f := methods[method] - - rf := reflect.TypeOf(f) - if rf.NumIn() != 2 { - return nil, fmt.Errorf("expected referenced method to have three arguments") - } - - paramObj := rf.In(1).Elem() + paramObj := methodMeta.Params if paramObj.NumField() != len(args) { return nil, fmt.Errorf("not enough arguments given to call that method (expecting %d)", paramObj.NumField()) } diff --git a/cmd/lotus-chainwatch/processor/common_actors.go b/cmd/lotus-chainwatch/processor/common_actors.go index 56520880c..4b8d124e2 100644 --- a/cmd/lotus-chainwatch/processor/common_actors.go +++ b/cmd/lotus-chainwatch/processor/common_actors.go @@ -9,12 +9,15 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + "github.com/ipfs/go-cid" + + builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + + "github.com/filecoin-project/lotus/chain/actors/builtin" _init "github.com/filecoin-project/lotus/chain/actors/builtin/init" "github.com/filecoin-project/lotus/chain/events/state" "github.com/filecoin-project/lotus/chain/types" cw_util "github.com/filecoin-project/lotus/cmd/lotus-chainwatch/util" - "github.com/filecoin-project/specs-actors/actors/builtin" - "github.com/ipfs/go-cid" ) func (p *Processor) setupCommonActors() error { @@ -135,15 +138,15 @@ func (p Processor) storeActorAddresses(ctx context.Context, actors map[cid.Cid]A addressToID := map[address.Address]address.Address{} // HACK until genesis storage is figured out: - addressToID[builtin.SystemActorAddr] = builtin.SystemActorAddr - addressToID[builtin.InitActorAddr] = builtin.InitActorAddr - addressToID[builtin.RewardActorAddr] = builtin.RewardActorAddr - addressToID[builtin.CronActorAddr] = builtin.CronActorAddr - addressToID[builtin.StoragePowerActorAddr] = builtin.StoragePowerActorAddr - addressToID[builtin.StorageMarketActorAddr] = builtin.StorageMarketActorAddr - addressToID[builtin.VerifiedRegistryActorAddr] = builtin.VerifiedRegistryActorAddr - addressToID[builtin.BurntFundsActorAddr] = builtin.BurntFundsActorAddr - initActor, err := p.node.StateGetActor(ctx, builtin.InitActorAddr, types.EmptyTSK) + addressToID[builtin1.SystemActorAddr] = builtin1.SystemActorAddr + addressToID[builtin1.InitActorAddr] = builtin1.InitActorAddr + addressToID[builtin1.RewardActorAddr] = builtin1.RewardActorAddr + addressToID[builtin1.CronActorAddr] = builtin1.CronActorAddr + addressToID[builtin1.StoragePowerActorAddr] = builtin1.StoragePowerActorAddr + addressToID[builtin1.StorageMarketActorAddr] = builtin1.StorageMarketActorAddr + addressToID[builtin1.VerifiedRegistryActorAddr] = builtin1.VerifiedRegistryActorAddr + addressToID[builtin1.BurntFundsActorAddr] = builtin1.BurntFundsActorAddr + initActor, err := p.node.StateGetActor(ctx, builtin1.InitActorAddr, types.EmptyTSK) if err != nil { return err } diff --git a/conformance/chaos/actor.go b/conformance/chaos/actor.go index 477204374..d5e0b4352 100644 --- a/conformance/chaos/actor.go +++ b/conformance/chaos/actor.go @@ -3,7 +3,9 @@ package chaos import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/cbor" "github.com/filecoin-project/go-state-types/exitcode" + "github.com/filecoin-project/go-state-types/rt" "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/specs-actors/actors/runtime" "github.com/ipfs/go-cid" @@ -86,7 +88,11 @@ func (a Actor) Exports() []interface{} { } } -var _ runtime.Invokee = Actor{} +func (a Actor) Code() cid.Cid { return ChaosActorCodeCID } +func (a Actor) State() cbor.Er { return new(State) } +func (a Actor) IsSingleton() bool { return true } + +var _ rt.VMActor = Actor{} // SendArgs are the arguments for the Send method. type SendArgs struct { diff --git a/conformance/driver.go b/conformance/driver.go index 1a63aaff3..7645e11c8 100644 --- a/conformance/driver.go +++ b/conformance/driver.go @@ -5,7 +5,6 @@ import ( "github.com/filecoin-project/go-state-types/crypto" - "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" @@ -145,7 +144,7 @@ func (d *Driver) ExecuteMessage(bs blockstore.Blockstore, preroot cid.Cid, epoch // register the chaos actor if required by the vector. if chaosOn, ok := d.selector["chaos_actor"]; ok && chaosOn == "true" { - invoker.Register(actors.Version0, chaos.ChaosActorCodeCID, chaos.Actor{}, chaos.State{}, true) + invoker.Register(nil, chaos.Actor{}) } lvm.SetInvoker(invoker) diff --git a/go.mod b/go.mod index b19f5c053..8212fa826 100644 --- a/go.mod +++ b/go.mod @@ -32,12 +32,12 @@ require ( github.com/filecoin-project/go-multistore v0.0.3 github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20 github.com/filecoin-project/go-paramfetch v0.0.2-0.20200701152213-3e0f0afdc261 - github.com/filecoin-project/go-state-types v0.0.0-20200911004822-964d6c679cfc + github.com/filecoin-project/go-state-types v0.0.0-20200928172055-2df22083d8ab github.com/filecoin-project/go-statemachine v0.0.0-20200813232949-df9b130df370 github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b - github.com/filecoin-project/specs-actors v0.9.10 - github.com/filecoin-project/specs-actors/v2 v2.0.0-20200918035954-4caac0a9b252 + github.com/filecoin-project/specs-actors v0.9.12-0.20200928180918-488a087c5add + github.com/filecoin-project/specs-actors/v2 v2.0.0-20200928175842-971c8d772684 github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796 github.com/filecoin-project/test-vectors/schema v0.0.1 github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 diff --git a/go.sum b/go.sum index 6f5ab862d..b96159c10 100644 --- a/go.sum +++ b/go.sum @@ -247,6 +247,8 @@ github.com/filecoin-project/go-state-types v0.0.0-20200904021452-1883f36ca2f4/go github.com/filecoin-project/go-state-types v0.0.0-20200905071437-95828685f9df/go.mod h1:IQ0MBPnonv35CJHtWSN3YY1Hz2gkPru1Q9qoaYLxx9I= github.com/filecoin-project/go-state-types v0.0.0-20200911004822-964d6c679cfc h1:1vr/LoqGq5m5g37Q3sNSAjfwF1uJY0zmiHcvnxY6hik= github.com/filecoin-project/go-state-types v0.0.0-20200911004822-964d6c679cfc/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g= +github.com/filecoin-project/go-state-types v0.0.0-20200928172055-2df22083d8ab h1:cEDC5Ei8UuT99hPWhCjA72SM9AuRtnpvdSTIYbnzN8I= +github.com/filecoin-project/go-state-types v0.0.0-20200928172055-2df22083d8ab/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g= github.com/filecoin-project/go-statemachine v0.0.0-20200714194326-a77c3ae20989/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= github.com/filecoin-project/go-statemachine v0.0.0-20200813232949-df9b130df370 h1:Jbburj7Ih2iaJ/o5Q9A+EAeTabME6YII7FLi9SKUf5c= github.com/filecoin-project/go-statemachine v0.0.0-20200813232949-df9b130df370/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= @@ -257,10 +259,10 @@ github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/ github.com/filecoin-project/specs-actors v0.9.4/go.mod h1:BStZQzx5x7TmCkLv0Bpa07U6cPKol6fd3w9KjMPZ6Z4= github.com/filecoin-project/specs-actors v0.9.7/go.mod h1:wM2z+kwqYgXn5Z7scV1YHLyd1Q1cy0R8HfTIWQ0BFGU= github.com/filecoin-project/specs-actors v0.9.9/go.mod h1:czlvLQGEX0fjLLfdNHD7xLymy6L3n7aQzRWzsYGf+ys= -github.com/filecoin-project/specs-actors v0.9.10 h1:gU0TrRhgkCsBEOP42sGDE7RQuR0Cov9hJhBqq+RJmjU= -github.com/filecoin-project/specs-actors v0.9.10/go.mod h1:czlvLQGEX0fjLLfdNHD7xLymy6L3n7aQzRWzsYGf+ys= -github.com/filecoin-project/specs-actors/v2 v2.0.0-20200918035954-4caac0a9b252 h1:0vOZo6xlVDyPhuRS3ArrAy1fml7H2FEY65IFx6rwp3o= -github.com/filecoin-project/specs-actors/v2 v2.0.0-20200918035954-4caac0a9b252/go.mod h1:vV1UOOKlmdKg4dy3YKixtJtVf15WMuZsS6KgKRDxkWg= +github.com/filecoin-project/specs-actors v0.9.12-0.20200928180918-488a087c5add h1:iXQOxr8uSyZ/qnTlOZf7ALp0io+jwLxmuWsNAk/YdoQ= +github.com/filecoin-project/specs-actors v0.9.12-0.20200928180918-488a087c5add/go.mod h1:TS1AW/7LbG+615j4NsjMK1qlpAwaFsG9w0V2tg2gSao= +github.com/filecoin-project/specs-actors/v2 v2.0.0-20200928175842-971c8d772684 h1:sjWZqblOOf1RaohI9w2R2AVp5uifNdzsusy7oVi5ioU= +github.com/filecoin-project/specs-actors/v2 v2.0.0-20200928175842-971c8d772684/go.mod h1:/2Zra1BhLtpRywUhm++QP+3I5Ir+hBk/W24TpYjj43E= github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796 h1:dJsTPWpG2pcTeojO2pyn0c6l+x/3MZYCBgo/9d11JEk= github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796/go.mod h1:nJRRM7Aa9XVvygr3W9k6xGF46RWzr2zxF/iGoAIfA/g= github.com/filecoin-project/test-vectors/schema v0.0.1 h1:5fNF76nl4qolEvcIsjc0kUADlTMVHO73tW4kXXPnsus= From 2049daa008b4029eaa551aaaf09a392c50a862d3 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 28 Sep 2020 13:12:41 -0700 Subject: [PATCH 013/115] fix actor imports --- chain/actors/builtin/multisig/v1.go | 4 ++-- chain/actors/builtin/power/v1.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/chain/actors/builtin/multisig/v1.go b/chain/actors/builtin/multisig/v1.go index 7bfde404a..56760cbba 100644 --- a/chain/actors/builtin/multisig/v1.go +++ b/chain/actors/builtin/multisig/v1.go @@ -10,8 +10,8 @@ import ( "github.com/filecoin-project/lotus/chain/actors/adt" - msig1 "github.com/filecoin-project/specs-actors/actors/builtin/multisig" - adt1 "github.com/filecoin-project/specs-actors/actors/util/adt" + msig1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig" + adt1 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" ) var _ State = (*state1)(nil) diff --git a/chain/actors/builtin/power/v1.go b/chain/actors/builtin/power/v1.go index 38df11916..63c9df547 100644 --- a/chain/actors/builtin/power/v1.go +++ b/chain/actors/builtin/power/v1.go @@ -8,8 +8,8 @@ import ( "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" - adt1 "github.com/filecoin-project/specs-actors/actors/util/adt" power1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/power" + adt1 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" ) var _ State = (*state1)(nil) From ca9448bc1171d02a365fe0a066c2568d826dd4dc Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 28 Sep 2020 13:13:18 -0700 Subject: [PATCH 014/115] rename actors v1 -> actors v2 The actual actors version is v2, not v1. Using Version1 internally was really confusing. --- chain/actors/adt/adt.go | 18 +- chain/actors/builtin/account/account.go | 10 +- chain/actors/builtin/account/{v1.go => v2.go} | 14 +- chain/actors/builtin/builtin.go | 12 +- chain/actors/builtin/init/init.go | 10 +- chain/actors/builtin/init/{v1.go => v2.go} | 28 +-- chain/actors/builtin/market/market.go | 10 +- chain/actors/builtin/market/v1.go | 205 ------------------ chain/actors/builtin/market/v2.go | 205 ++++++++++++++++++ chain/actors/builtin/miner/miner.go | 12 +- chain/actors/builtin/miner/{v1.go => v2.go} | 180 +++++++-------- chain/actors/builtin/multisig/multisig.go | 10 +- .../actors/builtin/multisig/{v1.go => v2.go} | 32 +-- chain/actors/builtin/paych/paych.go | 10 +- chain/actors/builtin/paych/{v1.go => v2.go} | 44 ++-- chain/actors/builtin/power/power.go | 10 +- chain/actors/builtin/power/{v1.go => v2.go} | 38 ++-- chain/actors/builtin/reward/reward.go | 10 +- chain/actors/builtin/reward/{v1.go => v2.go} | 44 ++-- chain/actors/builtin/verifreg/v1.go | 44 ---- chain/actors/builtin/verifreg/v2.go | 44 ++++ chain/actors/builtin/verifreg/verifreg.go | 10 +- chain/actors/version.go | 4 +- chain/state/statetree.go | 4 +- chain/stmgr/utils.go | 10 +- chain/vm/invoker.go | 4 +- chain/vm/mkactor.go | 6 +- .../processor/common_actors.go | 20 +- journal/registry_test.go | 10 +- journal/types.go | 2 +- 30 files changed, 530 insertions(+), 530 deletions(-) rename chain/actors/builtin/account/{v1.go => v2.go} (53%) rename chain/actors/builtin/init/{v1.go => v2.go} (65%) delete mode 100644 chain/actors/builtin/market/v1.go create mode 100644 chain/actors/builtin/market/v2.go rename chain/actors/builtin/miner/{v1.go => v2.go} (59%) rename chain/actors/builtin/multisig/{v1.go => v2.go} (55%) rename chain/actors/builtin/paych/{v1.go => v2.go} (61%) rename chain/actors/builtin/power/{v1.go => v2.go} (62%) rename chain/actors/builtin/reward/{v1.go => v2.go} (56%) delete mode 100644 chain/actors/builtin/verifreg/v1.go create mode 100644 chain/actors/builtin/verifreg/v2.go diff --git a/chain/actors/adt/adt.go b/chain/actors/adt/adt.go index 778ba9fcf..6a454ac26 100644 --- a/chain/actors/adt/adt.go +++ b/chain/actors/adt/adt.go @@ -11,7 +11,7 @@ import ( "github.com/filecoin-project/lotus/chain/actors" adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" - adt1 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" + adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" ) type Map interface { @@ -28,8 +28,8 @@ func AsMap(store Store, root cid.Cid, version actors.Version) (Map, error) { switch version { case actors.Version0: return adt0.AsMap(store, root) - case actors.Version1: - return adt1.AsMap(store, root) + case actors.Version2: + return adt2.AsMap(store, root) } return nil, xerrors.Errorf("unknown network version: %d", version) } @@ -38,8 +38,8 @@ func NewMap(store Store, version actors.Version) (Map, error) { switch version { case actors.Version0: return adt0.MakeEmptyMap(store), nil - case actors.Version1: - return adt1.MakeEmptyMap(store), nil + case actors.Version2: + return adt2.MakeEmptyMap(store), nil } return nil, xerrors.Errorf("unknown network version: %d", version) } @@ -59,8 +59,8 @@ func AsArray(store Store, root cid.Cid, version network.Version) (Array, error) switch actors.VersionForNetwork(version) { case actors.Version0: return adt0.AsArray(store, root) - case actors.Version1: - return adt1.AsArray(store, root) + case actors.Version2: + return adt2.AsArray(store, root) } return nil, xerrors.Errorf("unknown network version: %d", version) } @@ -69,8 +69,8 @@ func NewArray(store Store, version actors.Version) (Array, error) { switch version { case actors.Version0: return adt0.MakeEmptyArray(store), nil - case actors.Version1: - return adt1.MakeEmptyArray(store), nil + case actors.Version2: + return adt2.MakeEmptyArray(store), nil } return nil, xerrors.Errorf("unknown network version: %d", version) } diff --git a/chain/actors/builtin/account/account.go b/chain/actors/builtin/account/account.go index 2754607e2..7b1b2a792 100644 --- a/chain/actors/builtin/account/account.go +++ b/chain/actors/builtin/account/account.go @@ -12,15 +12,15 @@ import ( "github.com/filecoin-project/lotus/chain/types" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" ) func init() { builtin.RegisterActorState(builtin0.AccountActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load0(store, root) }) - builtin.RegisterActorState(builtin1.AccountActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { - return load1(store, root) + builtin.RegisterActorState(builtin2.AccountActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load2(store, root) }) } @@ -28,8 +28,8 @@ func Load(store adt.Store, act *types.Actor) (State, error) { switch act.Code { case builtin0.AccountActorCodeID: return load0(store, act.Head) - case builtin1.AccountActorCodeID: - return load1(store, act.Head) + case builtin2.AccountActorCodeID: + return load2(store, act.Head) } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } diff --git a/chain/actors/builtin/account/v1.go b/chain/actors/builtin/account/v2.go similarity index 53% rename from chain/actors/builtin/account/v1.go rename to chain/actors/builtin/account/v2.go index 993c0e397..2664631bc 100644 --- a/chain/actors/builtin/account/v1.go +++ b/chain/actors/builtin/account/v2.go @@ -6,13 +6,13 @@ import ( "github.com/filecoin-project/lotus/chain/actors/adt" - account1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/account" + account2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/account" ) -var _ State = (*state1)(nil) +var _ State = (*state2)(nil) -func load1(store adt.Store, root cid.Cid) (State, error) { - out := state1{store: store} +func load2(store adt.Store, root cid.Cid) (State, error) { + out := state2{store: store} err := store.Get(store.Context(), root, &out) if err != nil { return nil, err @@ -20,11 +20,11 @@ func load1(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -type state1 struct { - account1.State +type state2 struct { + account2.State store adt.Store } -func (s *state1) PubkeyAddress() (address.Address, error) { +func (s *state2) PubkeyAddress() (address.Address, error) { return s.Address, nil } diff --git a/chain/actors/builtin/builtin.go b/chain/actors/builtin/builtin.go index a0567dc27..784c004eb 100644 --- a/chain/actors/builtin/builtin.go +++ b/chain/actors/builtin/builtin.go @@ -14,8 +14,8 @@ import ( miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof" smoothing0 "github.com/filecoin-project/specs-actors/actors/util/smoothing" - builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" - smoothing1 "github.com/filecoin-project/specs-actors/v2/actors/util/smoothing" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + smoothing2 "github.com/filecoin-project/specs-actors/v2/actors/util/smoothing" ) // TODO: Why does actors have 2 different versions of this? @@ -32,7 +32,7 @@ func QAPowerForWeight(size abi.SectorSize, duration abi.ChainEpoch, dealWeight, return miner0.QAPowerForWeight(size, duration, dealWeight, verifiedWeight) } -func FromV1FilterEstimate(v1 smoothing1.FilterEstimate) FilterEstimate { +func FromV2FilterEstimate(v1 smoothing2.FilterEstimate) FilterEstimate { return (FilterEstimate)(v1) } @@ -56,13 +56,13 @@ func ActorNameByCode(c cid.Cid) string { switch { case builtin0.IsBuiltinActor(c): return builtin0.ActorNameByCode(c) - case builtin1.IsBuiltinActor(c): - return builtin1.ActorNameByCode(c) + case builtin2.IsBuiltinActor(c): + return builtin2.ActorNameByCode(c) default: return "" } } func IsBuiltinActor(c cid.Cid) bool { - return builtin0.IsBuiltinActor(c) || builtin1.IsBuiltinActor(c) + return builtin0.IsBuiltinActor(c) || builtin2.IsBuiltinActor(c) } diff --git a/chain/actors/builtin/init/init.go b/chain/actors/builtin/init/init.go index 622921ee9..d1a41b158 100644 --- a/chain/actors/builtin/init/init.go +++ b/chain/actors/builtin/init/init.go @@ -14,15 +14,15 @@ import ( "github.com/filecoin-project/lotus/node/modules/dtypes" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" ) func init() { builtin.RegisterActorState(builtin0.InitActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load0(store, root) }) - builtin.RegisterActorState(builtin1.InitActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { - return load1(store, root) + builtin.RegisterActorState(builtin2.InitActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load2(store, root) }) } @@ -32,8 +32,8 @@ func Load(store adt.Store, act *types.Actor) (State, error) { switch act.Code { case builtin0.InitActorCodeID: return load0(store, act.Head) - case builtin1.InitActorCodeID: - return load1(store, act.Head) + case builtin2.InitActorCodeID: + return load2(store, act.Head) } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } diff --git a/chain/actors/builtin/init/v1.go b/chain/actors/builtin/init/v2.go similarity index 65% rename from chain/actors/builtin/init/v1.go rename to chain/actors/builtin/init/v2.go index dcaa5a9ed..38b3099fd 100644 --- a/chain/actors/builtin/init/v1.go +++ b/chain/actors/builtin/init/v2.go @@ -10,14 +10,14 @@ import ( "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/node/modules/dtypes" - init1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/init" - adt1 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" + init2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/init" + adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" ) -var _ State = (*state1)(nil) +var _ State = (*state2)(nil) -func load1(store adt.Store, root cid.Cid) (State, error) { - out := state1{store: store} +func load2(store adt.Store, root cid.Cid) (State, error) { + out := state2{store: store} err := store.Get(store.Context(), root, &out) if err != nil { return nil, err @@ -25,21 +25,21 @@ func load1(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -type state1 struct { - init1.State +type state2 struct { + init2.State store adt.Store } -func (s *state1) ResolveAddress(address address.Address) (address.Address, bool, error) { +func (s *state2) ResolveAddress(address address.Address) (address.Address, bool, error) { return s.State.ResolveAddress(s.store, address) } -func (s *state1) MapAddressToNewID(address address.Address) (address.Address, error) { +func (s *state2) MapAddressToNewID(address address.Address) (address.Address, error) { return s.State.MapAddressToNewID(s.store, address) } -func (s *state1) ForEachActor(cb func(id abi.ActorID, address address.Address) error) error { - addrs, err := adt1.AsMap(s.store, s.State.AddressMap) +func (s *state2) ForEachActor(cb func(id abi.ActorID, address address.Address) error) error { + addrs, err := adt2.AsMap(s.store, s.State.AddressMap) if err != nil { return err } @@ -53,12 +53,12 @@ func (s *state1) ForEachActor(cb func(id abi.ActorID, address address.Address) e }) } -func (s *state1) NetworkName() (dtypes.NetworkName, error) { +func (s *state2) NetworkName() (dtypes.NetworkName, error) { return dtypes.NetworkName(s.State.NetworkName), nil } -func (s *state1) Remove(addrs ...address.Address) (err error) { - m, err := adt1.AsMap(s.store, s.State.AddressMap) +func (s *state2) Remove(addrs ...address.Address) (err error) { + m, err := adt2.AsMap(s.store, s.State.AddressMap) if err != nil { return err } diff --git a/chain/actors/builtin/market/market.go b/chain/actors/builtin/market/market.go index d0798560b..fd08a0119 100644 --- a/chain/actors/builtin/market/market.go +++ b/chain/actors/builtin/market/market.go @@ -11,7 +11,7 @@ import ( builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" market0 "github.com/filecoin-project/specs-actors/actors/builtin/market" - builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" @@ -22,8 +22,8 @@ func init() { builtin.RegisterActorState(builtin0.StorageMarketActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load0(store, root) }) - builtin.RegisterActorState(builtin1.StorageMarketActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { - return load1(store, root) + builtin.RegisterActorState(builtin2.StorageMarketActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load2(store, root) }) } @@ -33,8 +33,8 @@ func Load(store adt.Store, act *types.Actor) (st State, err error) { switch act.Code { case builtin0.StorageMarketActorCodeID: return load0(store, act.Head) - case builtin1.StorageMarketActorCodeID: - return load1(store, act.Head) + case builtin2.StorageMarketActorCodeID: + return load2(store, act.Head) } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } diff --git a/chain/actors/builtin/market/v1.go b/chain/actors/builtin/market/v1.go deleted file mode 100644 index 3ad0cded6..000000000 --- a/chain/actors/builtin/market/v1.go +++ /dev/null @@ -1,205 +0,0 @@ -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" - - "github.com/filecoin-project/lotus/chain/actors/adt" - "github.com/filecoin-project/lotus/chain/types" - - market1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market" - adt1 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" -) - -var _ State = (*state1)(nil) - -func load1(store adt.Store, root cid.Cid) (State, error) { - out := state1{store: store} - err := store.Get(store.Context(), root, &out) - if err != nil { - return nil, err - } - return &out, nil -} - -type state1 struct { - market1.State - store adt.Store -} - -func (s *state1) TotalLocked() (abi.TokenAmount, error) { - fml := types.BigAdd(s.TotalClientLockedCollateral, s.TotalProviderLockedCollateral) - fml = types.BigAdd(fml, s.TotalClientStorageFee) - return fml, nil -} - -func (s *state1) BalancesChanged(otherState State) (bool, error) { - otherState1, ok := otherState.(*state1) - 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(otherState1.State.EscrowTable) || !s.State.LockedTable.Equals(otherState1.State.LockedTable), nil -} - -func (s *state1) StatesChanged(otherState State) (bool, error) { - otherState1, ok := otherState.(*state1) - 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(otherState1.State.States), nil -} - -func (s *state1) States() (DealStates, error) { - stateArray, err := adt1.AsArray(s.store, s.State.States) - if err != nil { - return nil, err - } - return &dealStates1{stateArray}, nil -} - -func (s *state1) ProposalsChanged(otherState State) (bool, error) { - otherState1, ok := otherState.(*state1) - 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(otherState1.State.Proposals), nil -} - -func (s *state1) Proposals() (DealProposals, error) { - proposalArray, err := adt1.AsArray(s.store, s.State.Proposals) - if err != nil { - return nil, err - } - return &dealProposals1{proposalArray}, nil -} - -func (s *state1) EscrowTable() (BalanceTable, error) { - bt, err := adt1.AsBalanceTable(s.store, s.State.EscrowTable) - if err != nil { - return nil, err - } - return &balanceTable1{bt}, nil -} - -func (s *state1) LockedTable() (BalanceTable, error) { - bt, err := adt1.AsBalanceTable(s.store, s.State.LockedTable) - if err != nil { - return nil, err - } - return &balanceTable1{bt}, nil -} - -func (s *state1) VerifyDealsForActivation( - minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch, -) (weight, verifiedWeight abi.DealWeight, err error) { - w, vw, _, err := market1.ValidateDealsForActivation(&s.State, s.store, deals, minerAddr, sectorExpiry, currEpoch) - return w, vw, err -} - -type balanceTable1 struct { - *adt1.BalanceTable -} - -func (bt *balanceTable1) ForEach(cb func(address.Address, abi.TokenAmount) error) error { - asMap := (*adt1.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 dealStates1 struct { - adt.Array -} - -func (s *dealStates1) Get(dealID abi.DealID) (*DealState, bool, error) { - var deal1 market1.DealState - found, err := s.Array.Get(uint64(dealID), &deal1) - if err != nil { - return nil, false, err - } - if !found { - return nil, false, nil - } - deal := fromV1DealState(deal1) - return &deal, true, nil -} - -func (s *dealStates1) ForEach(cb func(dealID abi.DealID, ds DealState) error) error { - var ds1 market1.DealState - return s.Array.ForEach(&ds1, func(idx int64) error { - return cb(abi.DealID(idx), fromV1DealState(ds1)) - }) -} - -func (s *dealStates1) decode(val *cbg.Deferred) (*DealState, error) { - var ds1 market1.DealState - if err := ds1.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { - return nil, err - } - ds := fromV1DealState(ds1) - return &ds, nil -} - -func (s *dealStates1) array() adt.Array { - return s.Array -} - -func fromV1DealState(v1 market1.DealState) DealState { - return (DealState)(v1) -} - -type dealProposals1 struct { - adt.Array -} - -func (s *dealProposals1) Get(dealID abi.DealID) (*DealProposal, bool, error) { - var proposal1 market1.DealProposal - found, err := s.Array.Get(uint64(dealID), &proposal1) - if err != nil { - return nil, false, err - } - if !found { - return nil, false, nil - } - proposal := fromV1DealProposal(proposal1) - return &proposal, true, nil -} - -func (s *dealProposals1) ForEach(cb func(dealID abi.DealID, dp DealProposal) error) error { - var dp1 market1.DealProposal - return s.Array.ForEach(&dp1, func(idx int64) error { - return cb(abi.DealID(idx), fromV1DealProposal(dp1)) - }) -} - -func (s *dealProposals1) decode(val *cbg.Deferred) (*DealProposal, error) { - var dp1 market1.DealProposal - if err := dp1.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { - return nil, err - } - dp := fromV1DealProposal(dp1) - return &dp, nil -} - -func (s *dealProposals1) array() adt.Array { - return s.Array -} - -func fromV1DealProposal(v1 market1.DealProposal) DealProposal { - return (DealProposal)(v1) -} diff --git a/chain/actors/builtin/market/v2.go b/chain/actors/builtin/market/v2.go new file mode 100644 index 000000000..a5e5c7b45 --- /dev/null +++ b/chain/actors/builtin/market/v2.go @@ -0,0 +1,205 @@ +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" + + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/types" + + market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market" + adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" +) + +var _ State = (*state2)(nil) + +func load2(store adt.Store, root cid.Cid) (State, error) { + out := state2{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +type state2 struct { + market2.State + store adt.Store +} + +func (s *state2) TotalLocked() (abi.TokenAmount, error) { + fml := types.BigAdd(s.TotalClientLockedCollateral, s.TotalProviderLockedCollateral) + fml = types.BigAdd(fml, s.TotalClientStorageFee) + return fml, nil +} + +func (s *state2) BalancesChanged(otherState State) (bool, error) { + otherState2, ok := otherState.(*state2) + 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(otherState2.State.EscrowTable) || !s.State.LockedTable.Equals(otherState2.State.LockedTable), nil +} + +func (s *state2) StatesChanged(otherState State) (bool, error) { + otherState2, ok := otherState.(*state2) + 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(otherState2.State.States), nil +} + +func (s *state2) States() (DealStates, error) { + stateArray, err := adt2.AsArray(s.store, s.State.States) + if err != nil { + return nil, err + } + return &dealStates2{stateArray}, nil +} + +func (s *state2) ProposalsChanged(otherState State) (bool, error) { + otherState2, ok := otherState.(*state2) + 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(otherState2.State.Proposals), nil +} + +func (s *state2) Proposals() (DealProposals, error) { + proposalArray, err := adt2.AsArray(s.store, s.State.Proposals) + if err != nil { + return nil, err + } + return &dealProposals2{proposalArray}, nil +} + +func (s *state2) EscrowTable() (BalanceTable, error) { + bt, err := adt2.AsBalanceTable(s.store, s.State.EscrowTable) + if err != nil { + return nil, err + } + return &balanceTable2{bt}, nil +} + +func (s *state2) LockedTable() (BalanceTable, error) { + bt, err := adt2.AsBalanceTable(s.store, s.State.LockedTable) + if err != nil { + return nil, err + } + return &balanceTable2{bt}, nil +} + +func (s *state2) VerifyDealsForActivation( + minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch, +) (weight, verifiedWeight abi.DealWeight, err error) { + w, vw, _, err := market2.ValidateDealsForActivation(&s.State, s.store, deals, minerAddr, sectorExpiry, currEpoch) + return w, vw, err +} + +type balanceTable2 struct { + *adt2.BalanceTable +} + +func (bt *balanceTable2) ForEach(cb func(address.Address, abi.TokenAmount) error) error { + asMap := (*adt2.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 dealStates2 struct { + adt.Array +} + +func (s *dealStates2) Get(dealID abi.DealID) (*DealState, bool, error) { + var deal2 market2.DealState + found, err := s.Array.Get(uint64(dealID), &deal2) + if err != nil { + return nil, false, err + } + if !found { + return nil, false, nil + } + deal := fromV2DealState(deal2) + return &deal, true, nil +} + +func (s *dealStates2) ForEach(cb func(dealID abi.DealID, ds DealState) error) error { + var ds1 market2.DealState + return s.Array.ForEach(&ds1, func(idx int64) error { + return cb(abi.DealID(idx), fromV2DealState(ds1)) + }) +} + +func (s *dealStates2) decode(val *cbg.Deferred) (*DealState, error) { + var ds1 market2.DealState + if err := ds1.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { + return nil, err + } + ds := fromV2DealState(ds1) + return &ds, nil +} + +func (s *dealStates2) array() adt.Array { + return s.Array +} + +func fromV2DealState(v1 market2.DealState) DealState { + return (DealState)(v1) +} + +type dealProposals2 struct { + adt.Array +} + +func (s *dealProposals2) Get(dealID abi.DealID) (*DealProposal, bool, error) { + var proposal2 market2.DealProposal + found, err := s.Array.Get(uint64(dealID), &proposal2) + if err != nil { + return nil, false, err + } + if !found { + return nil, false, nil + } + proposal := fromV2DealProposal(proposal2) + return &proposal, true, nil +} + +func (s *dealProposals2) ForEach(cb func(dealID abi.DealID, dp DealProposal) error) error { + var dp1 market2.DealProposal + return s.Array.ForEach(&dp1, func(idx int64) error { + return cb(abi.DealID(idx), fromV2DealProposal(dp1)) + }) +} + +func (s *dealProposals2) decode(val *cbg.Deferred) (*DealProposal, error) { + var dp1 market2.DealProposal + if err := dp1.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { + return nil, err + } + dp := fromV2DealProposal(dp1) + return &dp, nil +} + +func (s *dealProposals2) array() adt.Array { + return s.Array +} + +func fromV2DealProposal(v1 market2.DealProposal) DealProposal { + return (DealProposal)(v1) +} diff --git a/chain/actors/builtin/miner/miner.go b/chain/actors/builtin/miner/miner.go index 00687a76f..66a157588 100644 --- a/chain/actors/builtin/miner/miner.go +++ b/chain/actors/builtin/miner/miner.go @@ -18,19 +18,19 @@ import ( builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" - builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" ) func init() { builtin.RegisterActorState(builtin0.StorageMinerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load0(store, root) }) - builtin.RegisterActorState(builtin1.StorageMinerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { - return load1(store, root) + builtin.RegisterActorState(builtin2.StorageMinerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load2(store, root) }) } -// Unchanged between v0 and v1 actors +// Unchanged between v0 and v2 actors var WPoStProvingPeriod = miner0.WPoStProvingPeriod const MinSectorExpiration = miner0.MinSectorExpiration @@ -39,8 +39,8 @@ func Load(store adt.Store, act *types.Actor) (st State, err error) { switch act.Code { case builtin0.StorageMinerActorCodeID: return load0(store, act.Head) - case builtin1.StorageMinerActorCodeID: - return load1(store, act.Head) + case builtin2.StorageMinerActorCodeID: + return load2(store, act.Head) } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } diff --git a/chain/actors/builtin/miner/v1.go b/chain/actors/builtin/miner/v2.go similarity index 59% rename from chain/actors/builtin/miner/v1.go rename to chain/actors/builtin/miner/v2.go index 9259353f3..6f496a51e 100644 --- a/chain/actors/builtin/miner/v1.go +++ b/chain/actors/builtin/miner/v2.go @@ -14,14 +14,14 @@ import ( "github.com/filecoin-project/lotus/chain/actors/adt" - miner1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" - adt1 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" + miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" + adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" ) -var _ State = (*state1)(nil) +var _ State = (*state2)(nil) -func load1(store adt.Store, root cid.Cid) (State, error) { - out := state1{store: store} +func load2(store adt.Store, root cid.Cid) (State, error) { + out := state2{store: store} err := store.Get(store.Context(), root, &out) if err != nil { return nil, err @@ -29,30 +29,30 @@ func load1(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -type state1 struct { - miner1.State +type state2 struct { + miner2.State store adt.Store } -type deadline1 struct { - miner1.Deadline +type deadline2 struct { + miner2.Deadline store adt.Store } -type partition1 struct { - miner1.Partition +type partition2 struct { + miner2.Partition store adt.Store } -func (s *state1) AvailableBalance(bal abi.TokenAmount) (abi.TokenAmount, error) { +func (s *state2) AvailableBalance(bal abi.TokenAmount) (abi.TokenAmount, error) { return s.GetAvailableBalance(bal), nil } -func (s *state1) VestedFunds(epoch abi.ChainEpoch) (abi.TokenAmount, error) { +func (s *state2) VestedFunds(epoch abi.ChainEpoch) (abi.TokenAmount, error) { return s.CheckVestedFunds(s.store, epoch) } -func (s *state1) LockedFunds() (LockedFunds, error) { +func (s *state2) LockedFunds() (LockedFunds, error) { return LockedFunds{ VestingFunds: s.State.LockedFunds, InitialPledgeRequirement: s.State.InitialPledge, @@ -60,25 +60,25 @@ func (s *state1) LockedFunds() (LockedFunds, error) { }, nil } -func (s *state1) InitialPledge() (abi.TokenAmount, error) { +func (s *state2) InitialPledge() (abi.TokenAmount, error) { return s.State.InitialPledge, nil } -func (s *state1) PreCommitDeposits() (abi.TokenAmount, error) { +func (s *state2) PreCommitDeposits() (abi.TokenAmount, error) { return s.State.PreCommitDeposits, nil } -func (s *state1) GetSector(num abi.SectorNumber) (*SectorOnChainInfo, error) { +func (s *state2) GetSector(num abi.SectorNumber) (*SectorOnChainInfo, error) { info, ok, err := s.State.GetSector(s.store, num) if !ok || err != nil { return nil, err } - ret := fromV1SectorOnChainInfo(*info) + ret := fromV2SectorOnChainInfo(*info) return &ret, nil } -func (s *state1) FindSector(num abi.SectorNumber) (*SectorLocation, error) { +func (s *state2) FindSector(num abi.SectorNumber) (*SectorLocation, error) { dlIdx, partIdx, err := s.State.FindSector(s.store, num) if err != nil { return nil, err @@ -89,13 +89,13 @@ func (s *state1) FindSector(num abi.SectorNumber) (*SectorLocation, error) { }, nil } -func (s *state1) NumLiveSectors() (uint64, error) { +func (s *state2) 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 *miner1.Deadline) error { + if err := dls.ForEach(s.store, func(dlIdx uint64, dl *miner2.Deadline) error { total += dl.LiveSectors return nil }); err != nil { @@ -109,7 +109,7 @@ func (s *state1) NumLiveSectors() (uint64, error) { // If the sector isn't found or has already been terminated, this method returns // nil and no error. If the sector does not expire early, the Early expiration // field is 0. -func (s *state1) GetSectorExpiration(num abi.SectorNumber) (*SectorExpiration, error) { +func (s *state2) GetSectorExpiration(num abi.SectorNumber) (*SectorExpiration, error) { dls, err := s.State.LoadDeadlines(s.store) if err != nil { return nil, err @@ -122,13 +122,13 @@ func (s *state1) GetSectorExpiration(num abi.SectorNumber) (*SectorExpiration, e // of the expiration queue. stopErr := errors.New("stop") out := SectorExpiration{} - err = dls.ForEach(s.store, func(dlIdx uint64, dl *miner1.Deadline) error { + err = dls.ForEach(s.store, func(dlIdx uint64, dl *miner2.Deadline) error { partitions, err := dl.PartitionsArray(s.store) if err != nil { return err } quant := s.State.QuantSpecForDeadline(dlIdx) - var part miner1.Partition + var part miner2.Partition return partitions.ForEach(&part, func(partIdx int64) error { if found, err := part.Sectors.IsSet(uint64(num)); err != nil { return err @@ -142,11 +142,11 @@ func (s *state1) GetSectorExpiration(num abi.SectorNumber) (*SectorExpiration, e return stopErr } - q, err := miner1.LoadExpirationQueue(s.store, part.ExpirationsEpochs, quant) + q, err := miner2.LoadExpirationQueue(s.store, part.ExpirationsEpochs, quant) if err != nil { return err } - var exp miner1.ExpirationSet + var exp miner2.ExpirationSet return q.ForEach(&exp, func(epoch int64) error { if early, err := exp.EarlySectors.IsSet(uint64(num)); err != nil { return err @@ -176,19 +176,19 @@ func (s *state1) GetSectorExpiration(num abi.SectorNumber) (*SectorExpiration, e return &out, nil } -func (s *state1) GetPrecommittedSector(num abi.SectorNumber) (*SectorPreCommitOnChainInfo, error) { +func (s *state2) GetPrecommittedSector(num abi.SectorNumber) (*SectorPreCommitOnChainInfo, error) { info, ok, err := s.State.GetPrecommittedSector(s.store, num) if !ok || err != nil { return nil, err } - ret := fromV1SectorPreCommitOnChainInfo(*info) + ret := fromV2SectorPreCommitOnChainInfo(*info) return &ret, nil } -func (s *state1) LoadSectors(snos *bitfield.BitField) ([]*SectorOnChainInfo, error) { - sectors, err := miner1.LoadSectors(s.store, s.State.Sectors) +func (s *state2) LoadSectors(snos *bitfield.BitField) ([]*SectorOnChainInfo, error) { + sectors, err := miner2.LoadSectors(s.store, s.State.Sectors) if err != nil { return nil, err } @@ -196,9 +196,9 @@ func (s *state1) LoadSectors(snos *bitfield.BitField) ([]*SectorOnChainInfo, err // If no sector numbers are specified, load all. if snos == nil { infos := make([]*SectorOnChainInfo, 0, sectors.Length()) - var info1 miner1.SectorOnChainInfo - if err := sectors.ForEach(&info1, func(_ int64) error { - info := fromV1SectorOnChainInfo(info1) + var info2 miner2.SectorOnChainInfo + if err := sectors.ForEach(&info2, func(_ int64) error { + info := fromV2SectorOnChainInfo(info2) infos = append(infos, &info) return nil }); err != nil { @@ -208,19 +208,19 @@ func (s *state1) LoadSectors(snos *bitfield.BitField) ([]*SectorOnChainInfo, err } // Otherwise, load selected. - infos1, err := sectors.Load(*snos) + infos2, err := sectors.Load(*snos) if err != nil { return nil, err } - infos := make([]*SectorOnChainInfo, len(infos1)) - for i, info1 := range infos1 { - info := fromV1SectorOnChainInfo(*info1) + infos := make([]*SectorOnChainInfo, len(infos2)) + for i, info2 := range infos2 { + info := fromV2SectorOnChainInfo(*info2) infos[i] = &info } return infos, nil } -func (s *state1) IsAllocated(num abi.SectorNumber) (bool, error) { +func (s *state2) IsAllocated(num abi.SectorNumber) (bool, error) { var allocatedSectors bitfield.BitField if err := s.store.Get(s.store.Context(), s.State.AllocatedSectors, &allocatedSectors); err != nil { return false, err @@ -229,7 +229,7 @@ func (s *state1) IsAllocated(num abi.SectorNumber) (bool, error) { return allocatedSectors.IsSet(uint64(num)) } -func (s *state1) LoadDeadline(idx uint64) (Deadline, error) { +func (s *state2) LoadDeadline(idx uint64) (Deadline, error) { dls, err := s.State.LoadDeadlines(s.store) if err != nil { return nil, err @@ -238,34 +238,34 @@ func (s *state1) LoadDeadline(idx uint64) (Deadline, error) { if err != nil { return nil, err } - return &deadline1{*dl, s.store}, nil + return &deadline2{*dl, s.store}, nil } -func (s *state1) ForEachDeadline(cb func(uint64, Deadline) error) error { +func (s *state2) 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 *miner1.Deadline) error { - return cb(i, &deadline1{*dl, s.store}) + return dls.ForEach(s.store, func(i uint64, dl *miner2.Deadline) error { + return cb(i, &deadline2{*dl, s.store}) }) } -func (s *state1) NumDeadlines() (uint64, error) { - return miner1.WPoStPeriodDeadlines, nil +func (s *state2) NumDeadlines() (uint64, error) { + return miner2.WPoStPeriodDeadlines, nil } -func (s *state1) DeadlinesChanged(other State) (bool, error) { - other1, ok := other.(*state1) +func (s *state2) DeadlinesChanged(other State) (bool, error) { + other2, ok := other.(*state2) if !ok { // treat an upgrade as a change, always return true, nil } - return s.State.Deadlines.Equals(other1.Deadlines), nil + return s.State.Deadlines.Equals(other2.Deadlines), nil } -func (s *state1) Info() (MinerInfo, error) { +func (s *state2) Info() (MinerInfo, error) { info, err := s.State.GetInfo(s.store) if err != nil { return MinerInfo{}, err @@ -299,105 +299,105 @@ func (s *state1) Info() (MinerInfo, error) { return mi, nil } -func (s *state1) DeadlineInfo(epoch abi.ChainEpoch) (*dline.Info, error) { +func (s *state2) DeadlineInfo(epoch abi.ChainEpoch) (*dline.Info, error) { return s.State.DeadlineInfo(epoch), nil } -func (s *state1) sectors() (adt.Array, error) { - return adt1.AsArray(s.store, s.Sectors) +func (s *state2) sectors() (adt.Array, error) { + return adt2.AsArray(s.store, s.Sectors) } -func (s *state1) decodeSectorOnChainInfo(val *cbg.Deferred) (SectorOnChainInfo, error) { - var si miner1.SectorOnChainInfo +func (s *state2) decodeSectorOnChainInfo(val *cbg.Deferred) (SectorOnChainInfo, error) { + var si miner2.SectorOnChainInfo err := si.UnmarshalCBOR(bytes.NewReader(val.Raw)) if err != nil { return SectorOnChainInfo{}, err } - return fromV1SectorOnChainInfo(si), nil + return fromV2SectorOnChainInfo(si), nil } -func (s *state1) precommits() (adt.Map, error) { - return adt1.AsMap(s.store, s.PreCommittedSectors) +func (s *state2) precommits() (adt.Map, error) { + return adt2.AsMap(s.store, s.PreCommittedSectors) } -func (s *state1) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (SectorPreCommitOnChainInfo, error) { - var sp miner1.SectorPreCommitOnChainInfo +func (s *state2) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (SectorPreCommitOnChainInfo, error) { + var sp miner2.SectorPreCommitOnChainInfo err := sp.UnmarshalCBOR(bytes.NewReader(val.Raw)) if err != nil { return SectorPreCommitOnChainInfo{}, err } - return fromV1SectorPreCommitOnChainInfo(sp), nil + return fromV2SectorPreCommitOnChainInfo(sp), nil } -func (d *deadline1) LoadPartition(idx uint64) (Partition, error) { +func (d *deadline2) LoadPartition(idx uint64) (Partition, error) { p, err := d.Deadline.LoadPartition(d.store, idx) if err != nil { return nil, err } - return &partition1{*p, d.store}, nil + return &partition2{*p, d.store}, nil } -func (d *deadline1) ForEachPartition(cb func(uint64, Partition) error) error { +func (d *deadline2) ForEachPartition(cb func(uint64, Partition) error) error { ps, err := d.Deadline.PartitionsArray(d.store) if err != nil { return err } - var part miner1.Partition + var part miner2.Partition return ps.ForEach(&part, func(i int64) error { - return cb(uint64(i), &partition1{part, d.store}) + return cb(uint64(i), &partition2{part, d.store}) }) } -func (d *deadline1) PartitionsChanged(other Deadline) (bool, error) { - other1, ok := other.(*deadline1) +func (d *deadline2) PartitionsChanged(other Deadline) (bool, error) { + other2, ok := other.(*deadline2) if !ok { // treat an upgrade as a change, always return true, nil } - return d.Deadline.Partitions.Equals(other1.Deadline.Partitions), nil + return d.Deadline.Partitions.Equals(other2.Deadline.Partitions), nil } -func (d *deadline1) PostSubmissions() (bitfield.BitField, error) { +func (d *deadline2) PostSubmissions() (bitfield.BitField, error) { return d.Deadline.PostSubmissions, nil } -func (p *partition1) AllSectors() (bitfield.BitField, error) { +func (p *partition2) AllSectors() (bitfield.BitField, error) { return p.Partition.Sectors, nil } -func (p *partition1) FaultySectors() (bitfield.BitField, error) { +func (p *partition2) FaultySectors() (bitfield.BitField, error) { return p.Partition.Faults, nil } -func (p *partition1) RecoveringSectors() (bitfield.BitField, error) { +func (p *partition2) RecoveringSectors() (bitfield.BitField, error) { return p.Partition.Recoveries, nil } -func fromV1SectorOnChainInfo(v1 miner1.SectorOnChainInfo) SectorOnChainInfo { +func fromV2SectorOnChainInfo(v2 miner2.SectorOnChainInfo) SectorOnChainInfo { return SectorOnChainInfo{ - SectorNumber: v1.SectorNumber, - SealProof: v1.SealProof, - SealedCID: v1.SealedCID, - DealIDs: v1.DealIDs, - Activation: v1.Activation, - Expiration: v1.Expiration, - DealWeight: v1.DealWeight, - VerifiedDealWeight: v1.VerifiedDealWeight, - InitialPledge: v1.InitialPledge, - ExpectedDayReward: v1.ExpectedDayReward, - ExpectedStoragePledge: v1.ExpectedStoragePledge, + SectorNumber: v2.SectorNumber, + SealProof: v2.SealProof, + SealedCID: v2.SealedCID, + DealIDs: v2.DealIDs, + Activation: v2.Activation, + Expiration: v2.Expiration, + DealWeight: v2.DealWeight, + VerifiedDealWeight: v2.VerifiedDealWeight, + InitialPledge: v2.InitialPledge, + ExpectedDayReward: v2.ExpectedDayReward, + ExpectedStoragePledge: v2.ExpectedStoragePledge, } } -func fromV1SectorPreCommitOnChainInfo(v1 miner1.SectorPreCommitOnChainInfo) SectorPreCommitOnChainInfo { +func fromV2SectorPreCommitOnChainInfo(v2 miner2.SectorPreCommitOnChainInfo) SectorPreCommitOnChainInfo { return SectorPreCommitOnChainInfo{ - Info: (SectorPreCommitInfo)(v1.Info), - PreCommitDeposit: v1.PreCommitDeposit, - PreCommitEpoch: v1.PreCommitEpoch, - DealWeight: v1.DealWeight, - VerifiedDealWeight: v1.VerifiedDealWeight, + Info: (SectorPreCommitInfo)(v2.Info), + PreCommitDeposit: v2.PreCommitDeposit, + PreCommitEpoch: v2.PreCommitEpoch, + DealWeight: v2.DealWeight, + VerifiedDealWeight: v2.VerifiedDealWeight, } } diff --git a/chain/actors/builtin/multisig/multisig.go b/chain/actors/builtin/multisig/multisig.go index 022e7e2c5..89a7eedad 100644 --- a/chain/actors/builtin/multisig/multisig.go +++ b/chain/actors/builtin/multisig/multisig.go @@ -10,7 +10,7 @@ import ( builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig" - builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" @@ -21,8 +21,8 @@ func init() { builtin.RegisterActorState(builtin0.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load0(store, root) }) - builtin.RegisterActorState(builtin1.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { - return load1(store, root) + builtin.RegisterActorState(builtin2.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load2(store, root) }) } @@ -30,8 +30,8 @@ func Load(store adt.Store, act *types.Actor) (State, error) { switch act.Code { case builtin0.MultisigActorCodeID: return load0(store, act.Head) - case builtin1.MultisigActorCodeID: - return load1(store, act.Head) + case builtin2.MultisigActorCodeID: + return load2(store, act.Head) } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } diff --git a/chain/actors/builtin/multisig/v1.go b/chain/actors/builtin/multisig/v2.go similarity index 55% rename from chain/actors/builtin/multisig/v1.go rename to chain/actors/builtin/multisig/v2.go index 56760cbba..a78b07d55 100644 --- a/chain/actors/builtin/multisig/v1.go +++ b/chain/actors/builtin/multisig/v2.go @@ -10,14 +10,14 @@ import ( "github.com/filecoin-project/lotus/chain/actors/adt" - msig1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig" - adt1 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" + msig2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig" + adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" ) -var _ State = (*state1)(nil) +var _ State = (*state2)(nil) -func load1(store adt.Store, root cid.Cid) (State, error) { - out := state1{store: store} +func load2(store adt.Store, root cid.Cid) (State, error) { + out := state2{store: store} err := store.Get(store.Context(), root, &out) if err != nil { return nil, err @@ -25,41 +25,41 @@ func load1(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -type state1 struct { - msig1.State +type state2 struct { + msig2.State store adt.Store } -func (s *state1) LockedBalance(currEpoch abi.ChainEpoch) (abi.TokenAmount, error) { +func (s *state2) LockedBalance(currEpoch abi.ChainEpoch) (abi.TokenAmount, error) { return s.State.AmountLocked(currEpoch - s.State.StartEpoch), nil } -func (s *state1) StartEpoch() (abi.ChainEpoch, error) { +func (s *state2) StartEpoch() (abi.ChainEpoch, error) { return s.State.StartEpoch, nil } -func (s *state1) UnlockDuration() (abi.ChainEpoch, error) { +func (s *state2) UnlockDuration() (abi.ChainEpoch, error) { return s.State.UnlockDuration, nil } -func (s *state1) InitialBalance() (abi.TokenAmount, error) { +func (s *state2) InitialBalance() (abi.TokenAmount, error) { return s.State.InitialBalance, nil } -func (s *state1) Threshold() (uint64, error) { +func (s *state2) Threshold() (uint64, error) { return s.State.NumApprovalsThreshold, nil } -func (s *state1) Signers() ([]address.Address, error) { +func (s *state2) Signers() ([]address.Address, error) { return s.State.Signers, nil } -func (s *state1) ForEachPendingTxn(cb func(id int64, txn Transaction) error) error { - arr, err := adt1.AsMap(s.store, s.State.PendingTxns) +func (s *state2) ForEachPendingTxn(cb func(id int64, txn Transaction) error) error { + arr, err := adt2.AsMap(s.store, s.State.PendingTxns) if err != nil { return err } - var out msig1.Transaction + var out msig2.Transaction return arr.ForEach(&out, func(key string) error { txid, n := binary.Varint([]byte(key)) if n <= 0 { diff --git a/chain/actors/builtin/paych/paych.go b/chain/actors/builtin/paych/paych.go index 959968f22..f462de6fd 100644 --- a/chain/actors/builtin/paych/paych.go +++ b/chain/actors/builtin/paych/paych.go @@ -11,7 +11,7 @@ import ( builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych" - builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" @@ -22,8 +22,8 @@ func init() { builtin.RegisterActorState(builtin0.PaymentChannelActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load0(store, root) }) - builtin.RegisterActorState(builtin1.PaymentChannelActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { - return load1(store, root) + builtin.RegisterActorState(builtin2.PaymentChannelActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load2(store, root) }) } @@ -32,8 +32,8 @@ func Load(store adt.Store, act *types.Actor) (State, error) { switch act.Code { case builtin0.PaymentChannelActorCodeID: return load0(store, act.Head) - case builtin1.PaymentChannelActorCodeID: - return load1(store, act.Head) + case builtin2.PaymentChannelActorCodeID: + return load2(store, act.Head) } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } diff --git a/chain/actors/builtin/paych/v1.go b/chain/actors/builtin/paych/v2.go similarity index 61% rename from chain/actors/builtin/paych/v1.go rename to chain/actors/builtin/paych/v2.go index c1b47c120..fbf4b9fde 100644 --- a/chain/actors/builtin/paych/v1.go +++ b/chain/actors/builtin/paych/v2.go @@ -9,14 +9,14 @@ import ( "github.com/filecoin-project/lotus/chain/actors/adt" - paych1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/paych" - adt1 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" + paych2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/paych" + adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" ) -var _ State = (*state1)(nil) +var _ State = (*state2)(nil) -func load1(store adt.Store, root cid.Cid) (State, error) { - out := state1{store: store} +func load2(store adt.Store, root cid.Cid) (State, error) { + out := state2{store: store} err := store.Get(store.Context(), root, &out) if err != nil { return nil, err @@ -24,39 +24,39 @@ func load1(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -type state1 struct { - paych1.State +type state2 struct { + paych2.State store adt.Store - lsAmt *adt1.Array + lsAmt *adt2.Array } // Channel owner, who has funded the actor -func (s *state1) From() (address.Address, error) { +func (s *state2) From() (address.Address, error) { return s.State.From, nil } // Recipient of payouts from channel -func (s *state1) To() (address.Address, error) { +func (s *state2) To() (address.Address, error) { return s.State.To, nil } // Height at which the channel can be `Collected` -func (s *state1) SettlingAt() (abi.ChainEpoch, error) { +func (s *state2) SettlingAt() (abi.ChainEpoch, error) { return s.State.SettlingAt, nil } // Amount successfully redeemed through the payment channel, paid out on `Collect()` -func (s *state1) ToSend() (abi.TokenAmount, error) { +func (s *state2) ToSend() (abi.TokenAmount, error) { return s.State.ToSend, nil } -func (s *state1) getOrLoadLsAmt() (*adt1.Array, error) { +func (s *state2) getOrLoadLsAmt() (*adt2.Array, error) { if s.lsAmt != nil { return s.lsAmt, nil } // Get the lane state from the chain - lsamt, err := adt1.AsArray(s.store, s.State.LaneStates) + lsamt, err := adt2.AsArray(s.store, s.State.LaneStates) if err != nil { return nil, err } @@ -66,7 +66,7 @@ func (s *state1) getOrLoadLsAmt() (*adt1.Array, error) { } // Get total number of lanes -func (s *state1) LaneCount() (uint64, error) { +func (s *state2) LaneCount() (uint64, error) { lsamt, err := s.getOrLoadLsAmt() if err != nil { return 0, err @@ -75,7 +75,7 @@ func (s *state1) LaneCount() (uint64, error) { } // Iterate lane states -func (s *state1) ForEachLaneState(cb func(idx uint64, dl LaneState) error) error { +func (s *state2) ForEachLaneState(cb func(idx uint64, dl LaneState) error) error { // Get the lane state from the chain lsamt, err := s.getOrLoadLsAmt() if err != nil { @@ -85,20 +85,20 @@ func (s *state1) ForEachLaneState(cb func(idx uint64, dl LaneState) error) error // 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 paych1.LaneState + var ls paych2.LaneState return lsamt.ForEach(&ls, func(i int64) error { - return cb(uint64(i), &laneState1{ls}) + return cb(uint64(i), &laneState2{ls}) }) } -type laneState1 struct { - paych1.LaneState +type laneState2 struct { + paych2.LaneState } -func (ls *laneState1) Redeemed() (big.Int, error) { +func (ls *laneState2) Redeemed() (big.Int, error) { return ls.LaneState.Redeemed, nil } -func (ls *laneState1) Nonce() (uint64, error) { +func (ls *laneState2) Nonce() (uint64, error) { return ls.LaneState.Nonce, nil } diff --git a/chain/actors/builtin/power/power.go b/chain/actors/builtin/power/power.go index 9dd61c07e..e683cfd96 100644 --- a/chain/actors/builtin/power/power.go +++ b/chain/actors/builtin/power/power.go @@ -13,15 +13,15 @@ import ( "github.com/filecoin-project/lotus/chain/types" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" ) func init() { builtin.RegisterActorState(builtin0.StoragePowerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load0(store, root) }) - builtin.RegisterActorState(builtin1.StoragePowerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { - return load1(store, root) + builtin.RegisterActorState(builtin2.StoragePowerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load2(store, root) }) } @@ -31,8 +31,8 @@ func Load(store adt.Store, act *types.Actor) (st State, err error) { switch act.Code { case builtin0.StoragePowerActorCodeID: return load0(store, act.Head) - case builtin1.StoragePowerActorCodeID: - return load1(store, act.Head) + case builtin2.StoragePowerActorCodeID: + return load2(store, act.Head) } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } diff --git a/chain/actors/builtin/power/v1.go b/chain/actors/builtin/power/v2.go similarity index 62% rename from chain/actors/builtin/power/v1.go rename to chain/actors/builtin/power/v2.go index 63c9df547..6346a09b6 100644 --- a/chain/actors/builtin/power/v1.go +++ b/chain/actors/builtin/power/v2.go @@ -8,14 +8,14 @@ import ( "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" - power1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/power" - adt1 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" + power2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/power" + adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" ) -var _ State = (*state1)(nil) +var _ State = (*state2)(nil) -func load1(store adt.Store, root cid.Cid) (State, error) { - out := state1{store: store} +func load2(store adt.Store, root cid.Cid) (State, error) { + out := state2{store: store} err := store.Get(store.Context(), root, &out) if err != nil { return nil, err @@ -23,16 +23,16 @@ func load1(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -type state1 struct { - power1.State +type state2 struct { + power2.State store adt.Store } -func (s *state1) TotalLocked() (abi.TokenAmount, error) { +func (s *state2) TotalLocked() (abi.TokenAmount, error) { return s.TotalPledgeCollateral, nil } -func (s *state1) TotalPower() (Claim, error) { +func (s *state2) TotalPower() (Claim, error) { return Claim{ RawBytePower: s.TotalRawBytePower, QualityAdjPower: s.TotalQualityAdjPower, @@ -40,19 +40,19 @@ func (s *state1) TotalPower() (Claim, error) { } // Committed power to the network. Includes miners below the minimum threshold. -func (s *state1) TotalCommitted() (Claim, error) { +func (s *state2) TotalCommitted() (Claim, error) { return Claim{ RawBytePower: s.TotalBytesCommitted, QualityAdjPower: s.TotalQABytesCommitted, }, nil } -func (s *state1) MinerPower(addr address.Address) (Claim, bool, error) { - claims, err := adt1.AsMap(s.store, s.Claims) +func (s *state2) MinerPower(addr address.Address) (Claim, bool, error) { + claims, err := adt2.AsMap(s.store, s.Claims) if err != nil { return Claim{}, false, err } - var claim power1.Claim + var claim power2.Claim ok, err := claims.Get(abi.AddrKey(addr), &claim) if err != nil { return Claim{}, false, err @@ -63,20 +63,20 @@ func (s *state1) MinerPower(addr address.Address) (Claim, bool, error) { }, ok, nil } -func (s *state1) MinerNominalPowerMeetsConsensusMinimum(a address.Address) (bool, error) { +func (s *state2) MinerNominalPowerMeetsConsensusMinimum(a address.Address) (bool, error) { return s.State.MinerNominalPowerMeetsConsensusMinimum(s.store, a) } -func (s *state1) TotalPowerSmoothed() (builtin.FilterEstimate, error) { - return builtin.FromV1FilterEstimate(s.State.ThisEpochQAPowerSmoothed), nil +func (s *state2) TotalPowerSmoothed() (builtin.FilterEstimate, error) { + return builtin.FromV2FilterEstimate(s.State.ThisEpochQAPowerSmoothed), nil } -func (s *state1) MinerCounts() (uint64, uint64, error) { +func (s *state2) MinerCounts() (uint64, uint64, error) { return uint64(s.State.MinerAboveMinPowerCount), uint64(s.State.MinerCount), nil } -func (s *state1) ListAllMiners() ([]address.Address, error) { - claims, err := adt1.AsMap(s.store, s.Claims) +func (s *state2) ListAllMiners() ([]address.Address, error) { + claims, err := adt2.AsMap(s.store, s.Claims) if err != nil { return nil, err } diff --git a/chain/actors/builtin/reward/reward.go b/chain/actors/builtin/reward/reward.go index e6d05de46..065f242e2 100644 --- a/chain/actors/builtin/reward/reward.go +++ b/chain/actors/builtin/reward/reward.go @@ -8,7 +8,7 @@ import ( "github.com/filecoin-project/go-state-types/cbor" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" @@ -19,8 +19,8 @@ func init() { builtin.RegisterActorState(builtin0.RewardActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load0(store, root) }) - builtin.RegisterActorState(builtin1.RewardActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { - return load1(store, root) + builtin.RegisterActorState(builtin2.RewardActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load2(store, root) }) } @@ -30,8 +30,8 @@ func Load(store adt.Store, act *types.Actor) (st State, err error) { switch act.Code { case builtin0.RewardActorCodeID: return load0(store, act.Head) - case builtin1.RewardActorCodeID: - return load1(store, act.Head) + case builtin2.RewardActorCodeID: + return load2(store, act.Head) } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } diff --git a/chain/actors/builtin/reward/v1.go b/chain/actors/builtin/reward/v2.go similarity index 56% rename from chain/actors/builtin/reward/v1.go rename to chain/actors/builtin/reward/v2.go index 9f94bbf1d..ec0709c39 100644 --- a/chain/actors/builtin/reward/v1.go +++ b/chain/actors/builtin/reward/v2.go @@ -7,15 +7,15 @@ import ( "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" - miner1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" - reward1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/reward" - smoothing1 "github.com/filecoin-project/specs-actors/v2/actors/util/smoothing" + miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" + reward2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/reward" + smoothing2 "github.com/filecoin-project/specs-actors/v2/actors/util/smoothing" ) -var _ State = (*state1)(nil) +var _ State = (*state2)(nil) -func load1(store adt.Store, root cid.Cid) (State, error) { - out := state1{store: store} +func load2(store adt.Store, root cid.Cid) (State, error) { + out := state2{store: store} err := store.Get(store.Context(), root, &out) if err != nil { return nil, err @@ -23,52 +23,52 @@ func load1(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -type state1 struct { - reward1.State +type state2 struct { + reward2.State store adt.Store } -func (s *state1) ThisEpochReward() (abi.StoragePower, error) { +func (s *state2) ThisEpochReward() (abi.StoragePower, error) { return s.State.ThisEpochReward, nil } -func (s *state1) ThisEpochRewardSmoothed() (builtin.FilterEstimate, error) { +func (s *state2) ThisEpochRewardSmoothed() (builtin.FilterEstimate, error) { return builtin.FilterEstimate{ PositionEstimate: s.State.ThisEpochRewardSmoothed.PositionEstimate, VelocityEstimate: s.State.ThisEpochRewardSmoothed.VelocityEstimate, }, nil } -func (s *state1) ThisEpochBaselinePower() (abi.StoragePower, error) { +func (s *state2) ThisEpochBaselinePower() (abi.StoragePower, error) { return s.State.ThisEpochBaselinePower, nil } -func (s *state1) TotalStoragePowerReward() (abi.TokenAmount, error) { +func (s *state2) TotalStoragePowerReward() (abi.TokenAmount, error) { return s.State.TotalStoragePowerReward, nil } -func (s *state1) EffectiveBaselinePower() (abi.StoragePower, error) { +func (s *state2) EffectiveBaselinePower() (abi.StoragePower, error) { return s.State.EffectiveBaselinePower, nil } -func (s *state1) EffectiveNetworkTime() (abi.ChainEpoch, error) { +func (s *state2) EffectiveNetworkTime() (abi.ChainEpoch, error) { return s.State.EffectiveNetworkTime, nil } -func (s *state1) CumsumBaseline() (abi.StoragePower, error) { +func (s *state2) CumsumBaseline() (abi.StoragePower, error) { return s.State.CumsumBaseline, nil } -func (s *state1) CumsumRealized() (abi.StoragePower, error) { +func (s *state2) CumsumRealized() (abi.StoragePower, error) { return s.State.CumsumBaseline, nil } -func (s *state1) InitialPledgeForPower(qaPower abi.StoragePower, networkTotalPledge abi.TokenAmount, networkQAPower *builtin.FilterEstimate, circSupply abi.TokenAmount) (abi.TokenAmount, error) { - return miner1.InitialPledgeForPower( +func (s *state2) InitialPledgeForPower(qaPower abi.StoragePower, networkTotalPledge abi.TokenAmount, networkQAPower *builtin.FilterEstimate, circSupply abi.TokenAmount) (abi.TokenAmount, error) { + return miner2.InitialPledgeForPower( qaPower, s.State.ThisEpochBaselinePower, s.State.ThisEpochRewardSmoothed, - smoothing1.FilterEstimate{ + smoothing2.FilterEstimate{ PositionEstimate: networkQAPower.PositionEstimate, VelocityEstimate: networkQAPower.VelocityEstimate, }, @@ -76,9 +76,9 @@ func (s *state1) InitialPledgeForPower(qaPower abi.StoragePower, networkTotalPle ), nil } -func (s *state1) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, sectorWeight abi.StoragePower) (abi.TokenAmount, error) { - return miner1.PreCommitDepositForPower(s.State.ThisEpochRewardSmoothed, - smoothing1.FilterEstimate{ +func (s *state2) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, sectorWeight abi.StoragePower) (abi.TokenAmount, error) { + return miner2.PreCommitDepositForPower(s.State.ThisEpochRewardSmoothed, + smoothing2.FilterEstimate{ PositionEstimate: networkQAPower.PositionEstimate, VelocityEstimate: networkQAPower.VelocityEstimate, }, diff --git a/chain/actors/builtin/verifreg/v1.go b/chain/actors/builtin/verifreg/v1.go deleted file mode 100644 index 0c9e1b139..000000000 --- a/chain/actors/builtin/verifreg/v1.go +++ /dev/null @@ -1,44 +0,0 @@ -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" - - verifreg1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/verifreg" -) - -var _ State = (*state1)(nil) - -func load1(store adt.Store, root cid.Cid) (State, error) { - out := state1{store: store} - err := store.Get(store.Context(), root, &out) - if err != nil { - return nil, err - } - return &out, nil -} - -type state1 struct { - verifreg1.State - store adt.Store -} - -func (s *state1) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) { - return getDataCap(s.store, actors.Version1, s.State.VerifiedClients, addr) -} - -func (s *state1) VerifierDataCap(addr address.Address) (bool, abi.StoragePower, error) { - return getDataCap(s.store, actors.Version1, s.State.Verifiers, addr) -} - -func (s *state1) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error { - return forEachCap(s.store, actors.Version1, s.State.Verifiers, cb) -} - -func (s *state1) ForEachClient(cb func(addr address.Address, dcap abi.StoragePower) error) error { - return forEachCap(s.store, actors.Version1, s.State.VerifiedClients, cb) -} diff --git a/chain/actors/builtin/verifreg/v2.go b/chain/actors/builtin/verifreg/v2.go new file mode 100644 index 000000000..72a781f26 --- /dev/null +++ b/chain/actors/builtin/verifreg/v2.go @@ -0,0 +1,44 @@ +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" + + verifreg2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/verifreg" +) + +var _ State = (*state2)(nil) + +func load2(store adt.Store, root cid.Cid) (State, error) { + out := state2{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +type state2 struct { + verifreg2.State + store adt.Store +} + +func (s *state2) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) { + return getDataCap(s.store, actors.Version2, s.State.VerifiedClients, addr) +} + +func (s *state2) VerifierDataCap(addr address.Address) (bool, abi.StoragePower, error) { + return getDataCap(s.store, actors.Version2, s.State.Verifiers, addr) +} + +func (s *state2) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error { + return forEachCap(s.store, actors.Version2, s.State.Verifiers, cb) +} + +func (s *state2) ForEachClient(cb func(addr address.Address, dcap abi.StoragePower) error) error { + return forEachCap(s.store, actors.Version2, s.State.VerifiedClients, cb) +} diff --git a/chain/actors/builtin/verifreg/verifreg.go b/chain/actors/builtin/verifreg/verifreg.go index 86b1c5939..00a492e95 100644 --- a/chain/actors/builtin/verifreg/verifreg.go +++ b/chain/actors/builtin/verifreg/verifreg.go @@ -8,7 +8,7 @@ import ( "github.com/filecoin-project/go-state-types/cbor" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" @@ -19,8 +19,8 @@ func init() { builtin.RegisterActorState(builtin0.VerifiedRegistryActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load0(store, root) }) - builtin.RegisterActorState(builtin1.VerifiedRegistryActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { - return load1(store, root) + builtin.RegisterActorState(builtin2.VerifiedRegistryActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load2(store, root) }) } @@ -30,8 +30,8 @@ func Load(store adt.Store, act *types.Actor) (State, error) { switch act.Code { case builtin0.VerifiedRegistryActorCodeID: return load0(store, act.Head) - case builtin1.VerifiedRegistryActorCodeID: - return load1(store, act.Head) + case builtin2.VerifiedRegistryActorCodeID: + return load2(store, act.Head) } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } diff --git a/chain/actors/version.go b/chain/actors/version.go index 6242ad738..2173a320d 100644 --- a/chain/actors/version.go +++ b/chain/actors/version.go @@ -9,8 +9,8 @@ import ( type Version int const ( - Version0 = iota - Version1 + Version0 = 0 + Version2 = 2 ) // Converts a network version into an actors adt version. diff --git a/chain/state/statetree.go b/chain/state/statetree.go index 7a2e70cdc..fcb7ffbaa 100644 --- a/chain/state/statetree.go +++ b/chain/state/statetree.go @@ -125,7 +125,7 @@ func NewStateTree(cst cbor.IpldStore, version actors.Version) (*StateTree, error switch version { case actors.Version0: // info is undefined - case actors.Version1: + case actors.Version2: var err error info, err = cst.Put(context.TODO(), new(types.StateInfo)) if err != nil { @@ -165,7 +165,7 @@ func LoadStateTree(cst cbor.IpldStore, c cid.Cid) (*StateTree, error) { } switch root.Version { - case actors.Version0, actors.Version1: + case actors.Version0, actors.Version2: // supported default: return nil, xerrors.Errorf("unsupported state tree version: %d", root.Version) diff --git a/chain/stmgr/utils.go b/chain/stmgr/utils.go index 19a3246a7..6ed94775b 100644 --- a/chain/stmgr/utils.go +++ b/chain/stmgr/utils.go @@ -21,7 +21,7 @@ import ( builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" exported0 "github.com/filecoin-project/specs-actors/actors/builtin/exported" - exported1 "github.com/filecoin-project/specs-actors/actors/builtin/exported" + exported2 "github.com/filecoin-project/specs-actors/actors/builtin/exported" proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof" "github.com/filecoin-project/lotus/api" @@ -530,14 +530,14 @@ func init() { // TODO: combine with the runtime actor registry. var actors []rt.VMActor actors = append(actors, exported0.BuiltinActors()...) - actors = append(actors, exported1.BuiltinActors()...) + actors = append(actors, exported2.BuiltinActors()...) for _, actor := range actors { exports := actor.Exports() methods := make(map[abi.MethodNum]MethodMeta, len(exports)) // Explicitly add send, it's special. - // Note that builtin1.MethodSend = builtin0.MethodSend = 0. + // Note that builtin2.MethodSend = builtin0.MethodSend = 0. methods[builtin0.MethodSend] = MethodMeta{ Name: "Send", Params: reflect.TypeOf(new(abi.EmptyValue)), @@ -563,10 +563,10 @@ func init() { switch abi.MethodNum(number) { case builtin0.MethodSend: - // Note that builtin1.MethodSend = builtin0.MethodSend = 0. + // Note that builtin2.MethodSend = builtin0.MethodSend = 0. panic("method 0 is reserved for Send") case builtin0.MethodConstructor: - // Note that builtin1.MethodConstructor = builtin0.MethodConstructor = 1. + // Note that builtin2.MethodConstructor = builtin0.MethodConstructor = 1. if fnName != "Constructor" { panic("method 1 is reserved for Constructor") } diff --git a/chain/vm/invoker.go b/chain/vm/invoker.go index 1f3db3ee9..65ef73cfc 100644 --- a/chain/vm/invoker.go +++ b/chain/vm/invoker.go @@ -11,7 +11,7 @@ import ( "golang.org/x/xerrors" exported0 "github.com/filecoin-project/specs-actors/actors/builtin/exported" - exported1 "github.com/filecoin-project/specs-actors/v2/actors/builtin/exported" + exported2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/exported" vmr "github.com/filecoin-project/specs-actors/v2/actors/runtime" "github.com/filecoin-project/go-state-types/abi" @@ -57,7 +57,7 @@ func NewActorRegistry() *ActorRegistry { // add builtInCode using: register(cid, singleton) inv.Register(ActorsVersionPredicate(actors.Version0), exported0.BuiltinActors()...) - inv.Register(ActorsVersionPredicate(actors.Version1), exported1.BuiltinActors()...) + inv.Register(ActorsVersionPredicate(actors.Version2), exported2.BuiltinActors()...) return inv } diff --git a/chain/vm/mkactor.go b/chain/vm/mkactor.go index 26e8c3ba1..33884368f 100644 --- a/chain/vm/mkactor.go +++ b/chain/vm/mkactor.go @@ -11,7 +11,7 @@ import ( cbor "github.com/ipfs/go-ipld-cbor" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" "github.com/filecoin-project/go-address" "github.com/filecoin-project/lotus/chain/actors/aerrors" @@ -87,8 +87,8 @@ func newAccountActor(ver actors.Version) *types.Actor { switch ver { case actors.Version0: code = builtin0.AccountActorCodeID - case actors.Version1: - code = builtin1.AccountActorCodeID + case actors.Version2: + code = builtin2.AccountActorCodeID default: panic("unsupported actors version") } diff --git a/cmd/lotus-chainwatch/processor/common_actors.go b/cmd/lotus-chainwatch/processor/common_actors.go index 4b8d124e2..0f2c0d2ea 100644 --- a/cmd/lotus-chainwatch/processor/common_actors.go +++ b/cmd/lotus-chainwatch/processor/common_actors.go @@ -11,7 +11,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/ipfs/go-cid" - builtin1 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/builtin" _init "github.com/filecoin-project/lotus/chain/actors/builtin/init" @@ -138,15 +138,15 @@ func (p Processor) storeActorAddresses(ctx context.Context, actors map[cid.Cid]A addressToID := map[address.Address]address.Address{} // HACK until genesis storage is figured out: - addressToID[builtin1.SystemActorAddr] = builtin1.SystemActorAddr - addressToID[builtin1.InitActorAddr] = builtin1.InitActorAddr - addressToID[builtin1.RewardActorAddr] = builtin1.RewardActorAddr - addressToID[builtin1.CronActorAddr] = builtin1.CronActorAddr - addressToID[builtin1.StoragePowerActorAddr] = builtin1.StoragePowerActorAddr - addressToID[builtin1.StorageMarketActorAddr] = builtin1.StorageMarketActorAddr - addressToID[builtin1.VerifiedRegistryActorAddr] = builtin1.VerifiedRegistryActorAddr - addressToID[builtin1.BurntFundsActorAddr] = builtin1.BurntFundsActorAddr - initActor, err := p.node.StateGetActor(ctx, builtin1.InitActorAddr, types.EmptyTSK) + addressToID[builtin2.SystemActorAddr] = builtin2.SystemActorAddr + addressToID[builtin2.InitActorAddr] = builtin2.InitActorAddr + addressToID[builtin2.RewardActorAddr] = builtin2.RewardActorAddr + addressToID[builtin2.CronActorAddr] = builtin2.CronActorAddr + addressToID[builtin2.StoragePowerActorAddr] = builtin2.StoragePowerActorAddr + addressToID[builtin2.StorageMarketActorAddr] = builtin2.StorageMarketActorAddr + addressToID[builtin2.VerifiedRegistryActorAddr] = builtin2.VerifiedRegistryActorAddr + addressToID[builtin2.BurntFundsActorAddr] = builtin2.BurntFundsActorAddr + initActor, err := p.node.StateGetActor(ctx, builtin2.InitActorAddr, types.EmptyTSK) if err != nil { return err } diff --git a/journal/registry_test.go b/journal/registry_test.go index 9d2085c12..bce3d3f17 100644 --- a/journal/registry_test.go +++ b/journal/registry_test.go @@ -14,7 +14,7 @@ func TestDisabledEvents(t *testing.T) { registry := NewEventTypeRegistry(dis) reg1 := registry.RegisterEventType("system1", "disabled1") - reg2 := registry.RegisterEventType("system2", "disabled2") + reg2 := registry.RegisterEventType("system1", "disabled2") req.False(reg1.Enabled()) req.False(reg2.Enabled()) @@ -29,21 +29,21 @@ func TestDisabledEvents(t *testing.T) { t.Run("direct", test(DisabledEvents{ EventType{System: "system1", Event: "disabled1"}, - EventType{System: "system2", Event: "disabled2"}, + EventType{System: "system1", Event: "disabled2"}, })) - dis, err := ParseDisabledEvents("system1:disabled1,system2:disabled2") + dis, err := ParseDisabledEvents("system1:disabled1,system1:disabled2") req.NoError(err) t.Run("parsed", test(dis)) - dis, err = ParseDisabledEvents(" system1:disabled1 , system2:disabled2 ") + dis, err = ParseDisabledEvents(" system1:disabled1 , system1:disabled2 ") req.NoError(err) t.Run("parsed_spaces", test(dis)) } func TestParseDisableEvents(t *testing.T) { - _, err := ParseDisabledEvents("system1:disabled1:failed,system2:disabled2") + _, err := ParseDisabledEvents("system1:disabled1:failed,system1:disabled2") require.Error(t, err) } diff --git a/journal/types.go b/journal/types.go index 56c7d4bc0..5b51ed4c8 100644 --- a/journal/types.go +++ b/journal/types.go @@ -22,7 +22,7 @@ var ( // DisabledEvents is the set of event types whose journaling is suppressed. type DisabledEvents []EventType -// ParseDisabledEvents parses a string of the form: "system1:event1,system2:event2[,...]" +// ParseDisabledEvents parses a string of the form: "system1:event1,system1:event2[,...]" // into a DisabledEvents object, returning an error if the string failed to parse. // // It sanitizes strings via strings.TrimSpace. From 6fcf57ed1f45ab8938ed3b12e65b2a3e176ff26d Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 28 Sep 2020 13:34:14 -0700 Subject: [PATCH 015/115] use actor state abstraction in payment channel test --- api/test/paych.go | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/api/test/paych.go b/api/test/paych.go index 36eb2c256..4c3bdba1b 100644 --- a/api/test/paych.go +++ b/api/test/paych.go @@ -8,17 +8,21 @@ import ( "testing" "time" - "github.com/filecoin-project/specs-actors/actors/builtin" + builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" - "github.com/filecoin-project/specs-actors/actors/builtin/paych" "github.com/ipfs/go-cid" "github.com/filecoin-project/go-address" + cbor "github.com/ipfs/go-ipld-cbor" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/apibstore" "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin/paych" "github.com/filecoin-project/lotus/chain/events" "github.com/filecoin-project/lotus/chain/events/state" "github.com/filecoin-project/lotus/chain/types" @@ -133,17 +137,26 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) { t.Fatal("Unable to settle payment channel") } + creatorStore := adt.WrapStore(ctx, cbor.NewCborStore(apibstore.NewAPIBlockstore(paymentCreator))) + // wait for the receiver to submit their vouchers ev := events.NewEvents(ctx, paymentCreator) preds := state.NewStatePredicates(paymentCreator) finished := make(chan struct{}) err = ev.StateChanged(func(ts *types.TipSet) (done bool, more bool, err error) { - act, err := paymentCreator.StateReadState(ctx, channel, ts.Key()) + act, err := paymentCreator.StateGetActor(ctx, channel, ts.Key()) if err != nil { return false, false, err } - state := act.State.(paych.State) - if state.ToSend.GreaterThanEqual(abi.NewTokenAmount(6000)) { + state, err := paych.Load(creatorStore, act) + if err != nil { + return false, false, err + } + toSend, err := state.ToSend() + if err != nil { + return false, false, err + } + if toSend.GreaterThanEqual(abi.NewTokenAmount(6000)) { return true, false, nil } return false, true, nil @@ -170,7 +183,7 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) { } // wait for the settlement period to pass before collecting - waitForBlocks(ctx, t, bm, paymentReceiver, receiverAddr, paych.SettleDelay) + waitForBlocks(ctx, t, bm, paymentReceiver, receiverAddr, paych0.SettleDelay) creatorPreCollectBalance, err := paymentCreator.WalletBalance(ctx, createrAddr) if err != nil { @@ -226,7 +239,7 @@ func waitForBlocks(ctx context.Context, t *testing.T, bm *BlockMiner, paymentRec // Add a real block m, err := paymentReceiver.MpoolPushMessage(ctx, &types.Message{ - To: builtin.BurntFundsActorAddr, + To: builtin0.BurntFundsActorAddr, From: receiverAddr, Value: types.NewInt(0), }, nil) From 1a7fb06dd9629f87be2f447fe0d7240944ee3749 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 28 Sep 2020 14:09:04 -0700 Subject: [PATCH 016/115] improve lotuspond There's still some work to do here, but it should now work better with the network upgrade. --- lotuspond/front/src/chain/methodgen.go | 38 ++++++++++---------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/lotuspond/front/src/chain/methodgen.go b/lotuspond/front/src/chain/methodgen.go index 3197803fe..5a00d5e6e 100644 --- a/lotuspond/front/src/chain/methodgen.go +++ b/lotuspond/front/src/chain/methodgen.go @@ -4,12 +4,11 @@ import ( "encoding/json" "io/ioutil" "os" - "reflect" - "github.com/ipfs/go-cid" "github.com/multiformats/go-multihash" - "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/chain/stmgr" ) func main() { @@ -17,6 +16,7 @@ func main() { panic(err) // note: must run in lotuspond/front/src/chain } + // TODO: ActorUpgrade: this is going to be a problem. names := map[string]string{ "system": "fil/1/system", "init": "fil/1/init", @@ -42,33 +42,25 @@ func main() { } } - methods := map[cid.Cid]interface{}{ - // builtin.SystemActorCodeID: builtin.MethodsSystem - apparently it doesn't have methods - builtin.InitActorCodeID: builtin.MethodsInit, - builtin.CronActorCodeID: builtin.MethodsCron, - builtin.AccountActorCodeID: builtin.MethodsAccount, - builtin.StoragePowerActorCodeID: builtin.MethodsPower, - builtin.StorageMinerActorCodeID: builtin.MethodsMiner, - builtin.StorageMarketActorCodeID: builtin.MethodsMarket, - builtin.PaymentChannelActorCodeID: builtin.MethodsPaych, - builtin.MultisigActorCodeID: builtin.MethodsMultisig, - builtin.RewardActorCodeID: builtin.MethodsReward, - builtin.VerifiedRegistryActorCodeID: builtin.MethodsVerifiedRegistry, - } - out := map[string][]string{} - for c, methods := range methods { + + for c, methods := range stmgr.MethodsMap { cmh, err := multihash.Decode(c.Hash()) if err != nil { panic(err) } - rt := reflect.TypeOf(methods) - nf := rt.NumField() + name := string(cmh.Digest) + remaining := len(methods) - out[string(cmh.Digest)] = append(out[string(cmh.Digest)], "Send") - for i := 0; i < nf; i++ { - out[string(cmh.Digest)] = append(out[string(cmh.Digest)], rt.Field(i).Name) + // iterate over actor methods in order. + for i := abi.MethodNum(0); remaining > 0; i++ { + m, ok := methods[i] + if !ok { + continue + } + out[name] = append(out[name], m.Name) + remaining-- } } From 52e064dabb0361cc063e97baa3f4934405ddb331 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 28 Sep 2020 14:09:46 -0700 Subject: [PATCH 017/115] add gas numbers for v2 --- chain/messagepool/gasguess/guessgas.go | 46 +++++++++++++++++--------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/chain/messagepool/gasguess/guessgas.go b/chain/messagepool/gasguess/guessgas.go index af58db7d2..1a6a21755 100644 --- a/chain/messagepool/gasguess/guessgas.go +++ b/chain/messagepool/gasguess/guessgas.go @@ -10,7 +10,9 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/specs-actors/actors/builtin" + + builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" ) type ActorLookup func(context.Context, address.Address, types.TipSetKey) (*types.Actor, error) @@ -27,19 +29,32 @@ type CostKey struct { } var Costs = map[CostKey]int64{ - {builtin.InitActorCodeID, 2}: 8916753, - {builtin.StorageMarketActorCodeID, 2}: 6955002, - {builtin.StorageMarketActorCodeID, 4}: 245436108, - {builtin.StorageMinerActorCodeID, 4}: 2315133, - {builtin.StorageMinerActorCodeID, 5}: 1600271356, - {builtin.StorageMinerActorCodeID, 6}: 22864493, - {builtin.StorageMinerActorCodeID, 7}: 142002419, - {builtin.StorageMinerActorCodeID, 10}: 23008274, - {builtin.StorageMinerActorCodeID, 11}: 19303178, - {builtin.StorageMinerActorCodeID, 14}: 566356835, - {builtin.StorageMinerActorCodeID, 16}: 5325185, - {builtin.StorageMinerActorCodeID, 18}: 2328637, - {builtin.StoragePowerActorCodeID, 2}: 23600956, + {builtin0.InitActorCodeID, 2}: 8916753, + {builtin0.StorageMarketActorCodeID, 2}: 6955002, + {builtin0.StorageMarketActorCodeID, 4}: 245436108, + {builtin0.StorageMinerActorCodeID, 4}: 2315133, + {builtin0.StorageMinerActorCodeID, 5}: 1600271356, + {builtin0.StorageMinerActorCodeID, 6}: 22864493, + {builtin0.StorageMinerActorCodeID, 7}: 142002419, + {builtin0.StorageMinerActorCodeID, 10}: 23008274, + {builtin0.StorageMinerActorCodeID, 11}: 19303178, + {builtin0.StorageMinerActorCodeID, 14}: 566356835, + {builtin0.StorageMinerActorCodeID, 16}: 5325185, + {builtin0.StorageMinerActorCodeID, 18}: 2328637, + {builtin0.StoragePowerActorCodeID, 2}: 23600956, + {builtin2.InitActorCodeID, 2}: 8916753, + {builtin2.StorageMarketActorCodeID, 2}: 6955002, + {builtin2.StorageMarketActorCodeID, 4}: 245436108, + {builtin2.StorageMinerActorCodeID, 4}: 2315133, + {builtin2.StorageMinerActorCodeID, 5}: 1600271356, + {builtin2.StorageMinerActorCodeID, 6}: 22864493, + {builtin2.StorageMinerActorCodeID, 7}: 142002419, + {builtin2.StorageMinerActorCodeID, 10}: 23008274, + {builtin2.StorageMinerActorCodeID, 11}: 19303178, + {builtin2.StorageMinerActorCodeID, 14}: 566356835, + {builtin2.StorageMinerActorCodeID, 16}: 5325185, + {builtin2.StorageMinerActorCodeID, 18}: 2328637, + {builtin2.StoragePowerActorCodeID, 2}: 23600956, } func failedGuess(msg *types.SignedMessage) int64 { @@ -51,7 +66,8 @@ func failedGuess(msg *types.SignedMessage) int64 { } func GuessGasUsed(ctx context.Context, tsk types.TipSetKey, msg *types.SignedMessage, al ActorLookup) (int64, error) { - if msg.Message.Method == builtin.MethodSend { + // MethodSend is the same in all versions. + if msg.Message.Method == builtin0.MethodSend { switch msg.Message.From.Protocol() { case address.BLS: return 1298450, nil From 233d8a9b7292a80ec51cf46be68d4373f9a82712 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 28 Sep 2020 14:25:58 -0700 Subject: [PATCH 018/115] update even more imports --- chain/actors/builtin/paych/paych.go | 18 ++++++++++++++++++ chain/stmgr/forks.go | 20 ++++++++------------ chain/store/store.go | 10 +++++++--- chain/sub/incoming.go | 10 ++++++---- chain/sync.go | 16 +++++++++------- chain/types/voucher.go | 22 ---------------------- cli/paych.go | 10 +++++----- extern/storage-sealing/states_failed.go | 6 +++--- extern/storage-sealing/types.go | 4 ++-- markets/retrievaladapter/client.go | 3 +-- markets/retrievaladapter/provider.go | 2 +- node/impl/full/chain.go | 2 ++ paychmgr/manager.go | 13 ++++++------- paychmgr/paych.go | 20 ++++++++++++-------- paychmgr/settler/settler.go | 10 +++++----- paychmgr/store.go | 15 +++++++-------- paychmgr/util.go | 10 +++++----- 17 files changed, 97 insertions(+), 94 deletions(-) delete mode 100644 chain/types/voucher.go diff --git a/chain/actors/builtin/paych/paych.go b/chain/actors/builtin/paych/paych.go index f462de6fd..20c7a74b7 100644 --- a/chain/actors/builtin/paych/paych.go +++ b/chain/actors/builtin/paych/paych.go @@ -1,6 +1,8 @@ package paych import ( + "encoding/base64" + "golang.org/x/xerrors" "github.com/filecoin-project/go-address" @@ -8,6 +10,7 @@ import ( big "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/cbor" "github.com/ipfs/go-cid" + ipldcbor "github.com/ipfs/go-ipld-cbor" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych" @@ -68,3 +71,18 @@ type LaneState interface { type SignedVoucher = paych0.SignedVoucher type ModVerifyParams = paych0.ModVerifyParams + +// DecodeSignedVoucher decodes base64 encoded signed voucher. +func DecodeSignedVoucher(s string) (*SignedVoucher, error) { + data, err := base64.RawURLEncoding.DecodeString(s) + if err != nil { + return nil, err + } + + var sv SignedVoucher + if err := ipldcbor.DecodeInto(data, &sv); err != nil { + return nil, err + } + + return &sv, nil +} diff --git a/chain/stmgr/forks.go b/chain/stmgr/forks.go index 252b731d7..9561e5ed9 100644 --- a/chain/stmgr/forks.go +++ b/chain/stmgr/forks.go @@ -6,31 +6,27 @@ import ( "encoding/binary" "math" - multisig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig" - - "github.com/filecoin-project/lotus/chain/actors/builtin/multisig" - - "github.com/filecoin-project/lotus/chain/state" - - "github.com/filecoin-project/specs-actors/actors/migration/nv3" - - "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/ipfs/go-cid" + cbor "github.com/ipfs/go-ipld-cbor" + "golang.org/x/xerrors" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" init0 "github.com/filecoin-project/specs-actors/actors/builtin/init" miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" + multisig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig" power0 "github.com/filecoin-project/specs-actors/actors/builtin/power" adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" + "github.com/filecoin-project/specs-actors/actors/migration/nv3" + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/actors/builtin/multisig" + "github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/vm" - cbor "github.com/ipfs/go-ipld-cbor" - "golang.org/x/xerrors" ) var ForksAtHeight = map[abi.ChainEpoch]func(context.Context, *StateManager, ExecCallback, cid.Cid, *types.TipSet) (cid.Cid, error){ diff --git a/chain/store/store.go b/chain/store/store.go index 6c93db7a0..ab732413b 100644 --- a/chain/store/store.go +++ b/chain/store/store.go @@ -17,11 +17,13 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/specs-actors/actors/builtin" - "github.com/filecoin-project/specs-actors/actors/util/adt" + adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/vm" "github.com/filecoin-project/lotus/journal" bstore "github.com/filecoin-project/lotus/lib/blockstore" @@ -747,7 +749,8 @@ func (cs *ChainStore) GetSignedMessage(c cid.Cid) (*types.SignedMessage, error) func (cs *ChainStore) readAMTCids(root cid.Cid) ([]cid.Cid, error) { ctx := context.TODO() - a, err := adt.AsArray(cs.Store(ctx), root) + // block headers use adt0, for now. + a, err := adt0.AsArray(cs.Store(ctx), root) if err != nil { return nil, xerrors.Errorf("amt load: %w", err) } @@ -940,7 +943,8 @@ func (cs *ChainStore) MessagesForBlock(b *types.BlockHeader) ([]*types.Message, func (cs *ChainStore) GetParentReceipt(b *types.BlockHeader, i int) (*types.MessageReceipt, error) { ctx := context.TODO() - a, err := adt.AsArray(cs.Store(ctx), b.ParentMessageReceipts) + // block headers use adt0, for now. + a, err := adt0.AsArray(cs.Store(ctx), b.ParentMessageReceipts) if err != nil { return nil, xerrors.Errorf("amt load: %w", err) } diff --git a/chain/sub/incoming.go b/chain/sub/incoming.go index c6e0c8b80..eb17b078d 100644 --- a/chain/sub/incoming.go +++ b/chain/sub/incoming.go @@ -10,7 +10,6 @@ import ( "golang.org/x/xerrors" address "github.com/filecoin-project/go-address" - "github.com/filecoin-project/specs-actors/actors/util/adt" lru "github.com/hashicorp/golang-lru" blocks "github.com/ipfs/go-block-format" bserv "github.com/ipfs/go-blockservice" @@ -24,6 +23,8 @@ import ( "go.opencensus.io/stats" "go.opencensus.io/tag" + adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" + "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" @@ -374,9 +375,10 @@ func (bv *BlockValidator) isChainNearSynced() bool { func (bv *BlockValidator) validateMsgMeta(ctx context.Context, msg *types.BlockMsg) error { // TODO there has to be a simpler way to do this without the blockstore dance - store := adt.WrapStore(ctx, cbor.NewCborStore(blockstore.NewTemporary())) - bmArr := adt.MakeEmptyArray(store) - smArr := adt.MakeEmptyArray(store) + // block headers use adt0 + store := adt0.WrapStore(ctx, cbor.NewCborStore(blockstore.NewTemporary())) + bmArr := adt0.MakeEmptyArray(store) + smArr := adt0.MakeEmptyArray(store) for i, m := range msg.BlsMessages { c := cbg.CborCid(m) diff --git a/chain/sync.go b/chain/sync.go index 9e098a57e..6abe43567 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -33,9 +33,10 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper" - "github.com/filecoin-project/specs-actors/actors/util/adt" blst "github.com/supranational/blst/bindings/go" + adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors/builtin/power" @@ -455,9 +456,10 @@ func zipTipSetAndMessages(bs cbor.IpldStore, ts *types.TipSet, allbmsgs []*types // computeMsgMeta computes the root CID of the combined arrays of message CIDs // of both types (BLS and Secpk). func computeMsgMeta(bs cbor.IpldStore, bmsgCids, smsgCids []cid.Cid) (cid.Cid, error) { - store := adt.WrapStore(context.TODO(), bs) - bmArr := adt.MakeEmptyArray(store) - smArr := adt.MakeEmptyArray(store) + // block headers use adt0 + store := adt0.WrapStore(context.TODO(), bs) + bmArr := adt0.MakeEmptyArray(store) + smArr := adt0.MakeEmptyArray(store) for i, m := range bmsgCids { c := cbg.CborCid(m) @@ -1092,9 +1094,9 @@ func (syncer *Syncer) checkBlockMessages(ctx context.Context, b *types.FullBlock return nil } - store := adt.WrapStore(ctx, cst) + store := adt0.WrapStore(ctx, cst) - bmArr := adt.MakeEmptyArray(store) + bmArr := adt0.MakeEmptyArray(store) for i, m := range b.BlsMessages { if err := checkMsg(m); err != nil { return xerrors.Errorf("block had invalid bls message at index %d: %w", i, err) @@ -1106,7 +1108,7 @@ func (syncer *Syncer) checkBlockMessages(ctx context.Context, b *types.FullBlock } } - smArr := adt.MakeEmptyArray(store) + smArr := adt0.MakeEmptyArray(store) for i, m := range b.SecpkMessages { if err := checkMsg(m); err != nil { return xerrors.Errorf("block had invalid secpk message at index %d: %w", i, err) diff --git a/chain/types/voucher.go b/chain/types/voucher.go deleted file mode 100644 index 687109c33..000000000 --- a/chain/types/voucher.go +++ /dev/null @@ -1,22 +0,0 @@ -package types - -import ( - "encoding/base64" - - "github.com/filecoin-project/specs-actors/actors/builtin/paych" - cbor "github.com/ipfs/go-ipld-cbor" -) - -func DecodeSignedVoucher(s string) (*paych.SignedVoucher, error) { - data, err := base64.RawURLEncoding.DecodeString(s) - if err != nil { - return nil, err - } - - var sv paych.SignedVoucher - if err := cbor.DecodeInto(data, &sv); err != nil { - return nil, err - } - - return &sv, nil -} diff --git a/cli/paych.go b/cli/paych.go index dc5b54c4a..1d5e304c3 100644 --- a/cli/paych.go +++ b/cli/paych.go @@ -14,10 +14,10 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/specs-actors/actors/builtin/paych" "github.com/urfave/cli/v2" - types "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/chain/actors/builtin/paych" + "github.com/filecoin-project/lotus/chain/types" ) var paychCmd = &cli.Command{ @@ -404,7 +404,7 @@ var paychVoucherCheckCmd = &cli.Command{ return err } - sv, err := types.DecodeSignedVoucher(cctx.Args().Get(1)) + sv, err := paych.DecodeSignedVoucher(cctx.Args().Get(1)) if err != nil { return err } @@ -440,7 +440,7 @@ var paychVoucherAddCmd = &cli.Command{ return err } - sv, err := types.DecodeSignedVoucher(cctx.Args().Get(1)) + sv, err := paych.DecodeSignedVoucher(cctx.Args().Get(1)) if err != nil { return err } @@ -598,7 +598,7 @@ var paychVoucherSubmitCmd = &cli.Command{ return err } - sv, err := types.DecodeSignedVoucher(cctx.Args().Get(1)) + sv, err := paych.DecodeSignedVoucher(cctx.Args().Get(1)) if err != nil { return err } diff --git a/extern/storage-sealing/states_failed.go b/extern/storage-sealing/states_failed.go index b026e70f9..63e64ca1b 100644 --- a/extern/storage-sealing/states_failed.go +++ b/extern/storage-sealing/states_failed.go @@ -4,14 +4,14 @@ import ( "bytes" "time" - "github.com/filecoin-project/lotus/chain/actors/builtin/miner" - "golang.org/x/xerrors" + "github.com/filecoin-project/lotus/chain/actors/builtin/market" + "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/exitcode" "github.com/filecoin-project/go-statemachine" - "github.com/filecoin-project/specs-actors/actors/builtin/market" "github.com/filecoin-project/lotus/extern/sector-storage/zerocomm" ) diff --git a/extern/storage-sealing/types.go b/extern/storage-sealing/types.go index c044defd3..046271a7f 100644 --- a/extern/storage-sealing/types.go +++ b/extern/storage-sealing/types.go @@ -9,7 +9,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/exitcode" - "github.com/filecoin-project/specs-actors/actors/builtin/miner" + miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" "github.com/filecoin-project/specs-storage/storage" sectorstorage "github.com/filecoin-project/lotus/extern/sector-storage" @@ -82,7 +82,7 @@ type SectorInfo struct { CommR *cid.Cid Proof []byte - PreCommitInfo *miner.SectorPreCommitInfo + PreCommitInfo *miner0.SectorPreCommitInfo PreCommitDeposit big.Int PreCommitMessage *cid.Cid PreCommitTipSet TipSetToken diff --git a/markets/retrievaladapter/client.go b/markets/retrievaladapter/client.go index ab81dd8c9..1bef23e12 100644 --- a/markets/retrievaladapter/client.go +++ b/markets/retrievaladapter/client.go @@ -3,8 +3,6 @@ package retrievaladapter import ( "context" - "github.com/filecoin-project/specs-actors/actors/builtin/paych" - "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-fil-markets/retrievalmarket" "github.com/filecoin-project/go-fil-markets/shared" @@ -12,6 +10,7 @@ import ( "github.com/ipfs/go-cid" "github.com/multiformats/go-multiaddr" + "github.com/filecoin-project/lotus/chain/actors/builtin/paych" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/node/impl/full" payapi "github.com/filecoin-project/lotus/node/impl/paych" diff --git a/markets/retrievaladapter/provider.go b/markets/retrievaladapter/provider.go index 443c4fb4a..674ec4793 100644 --- a/markets/retrievaladapter/provider.go +++ b/markets/retrievaladapter/provider.go @@ -5,6 +5,7 @@ import ( "io" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/actors/builtin/paych" "github.com/filecoin-project/lotus/chain/types" sectorstorage "github.com/filecoin-project/lotus/extern/sector-storage" "github.com/filecoin-project/lotus/extern/sector-storage/storiface" @@ -14,7 +15,6 @@ import ( "github.com/filecoin-project/go-fil-markets/retrievalmarket" "github.com/filecoin-project/go-fil-markets/shared" "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/specs-actors/actors/builtin/paych" "github.com/ipfs/go-cid" ) diff --git a/node/impl/full/chain.go b/node/impl/full/chain.go index ea715c66a..095e32ad2 100644 --- a/node/impl/full/chain.go +++ b/node/impl/full/chain.go @@ -285,6 +285,8 @@ func (s stringKey) Key() string { return (string)(s) } +// TODO: ActorUpgrade: this entire function is a problem (in theory) as we don't know the HAMT version. +// In practice, hamt v0 should work "just fine" for reading. func resolveOnce(bs blockstore.Blockstore) func(ctx context.Context, ds ipld.NodeGetter, nd ipld.Node, names []string) (*ipld.Link, []string, error) { return func(ctx context.Context, ds ipld.NodeGetter, nd ipld.Node, names []string) (*ipld.Link, []string, error) { store := adt.WrapStore(ctx, cbor.NewCborStore(bs)) diff --git a/paychmgr/manager.go b/paychmgr/manager.go index d9c568cbe..7ef1264c5 100644 --- a/paychmgr/manager.go +++ b/paychmgr/manager.go @@ -12,7 +12,6 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/crypto" - paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/actors/adt" @@ -221,7 +220,7 @@ func (pm *Manager) GetChannelInfo(addr address.Address) (*ChannelInfo, error) { return ca.getChannelInfo(addr) } -func (pm *Manager) CreateVoucher(ctx context.Context, ch address.Address, voucher paych0.SignedVoucher) (*api.VoucherCreateResult, error) { +func (pm *Manager) CreateVoucher(ctx context.Context, ch address.Address, voucher paych.SignedVoucher) (*api.VoucherCreateResult, error) { ca, err := pm.accessorByAddress(ch) if err != nil { return nil, err @@ -233,7 +232,7 @@ func (pm *Manager) CreateVoucher(ctx context.Context, ch address.Address, vouche // CheckVoucherValid checks if the given voucher is valid (is or could become spendable at some point). // If the channel is not in the store, fetches the channel from state (and checks that // the channel To address is owned by the wallet). -func (pm *Manager) CheckVoucherValid(ctx context.Context, ch address.Address, sv *paych0.SignedVoucher) error { +func (pm *Manager) CheckVoucherValid(ctx context.Context, ch address.Address, sv *paych.SignedVoucher) error { // Get an accessor for the channel, creating it from state if necessary ca, err := pm.inboundChannelAccessor(ctx, ch) if err != nil { @@ -245,7 +244,7 @@ func (pm *Manager) CheckVoucherValid(ctx context.Context, ch address.Address, sv } // CheckVoucherSpendable checks if the given voucher is currently spendable -func (pm *Manager) CheckVoucherSpendable(ctx context.Context, ch address.Address, sv *paych0.SignedVoucher, secret []byte, proof []byte) (bool, error) { +func (pm *Manager) CheckVoucherSpendable(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, secret []byte, proof []byte) (bool, error) { ca, err := pm.accessorByAddress(ch) if err != nil { return false, err @@ -256,7 +255,7 @@ func (pm *Manager) CheckVoucherSpendable(ctx context.Context, ch address.Address // AddVoucherOutbound adds a voucher for an outbound channel. // Returns an error if the channel is not already in the store. -func (pm *Manager) AddVoucherOutbound(ctx context.Context, ch address.Address, sv *paych0.SignedVoucher, proof []byte, minDelta types.BigInt) (types.BigInt, error) { +func (pm *Manager) AddVoucherOutbound(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, proof []byte, minDelta types.BigInt) (types.BigInt, error) { ca, err := pm.accessorByAddress(ch) if err != nil { return types.NewInt(0), err @@ -267,7 +266,7 @@ func (pm *Manager) AddVoucherOutbound(ctx context.Context, ch address.Address, s // AddVoucherInbound adds a voucher for an inbound channel. // If the channel is not in the store, fetches the channel from state (and checks that // the channel To address is owned by the wallet). -func (pm *Manager) AddVoucherInbound(ctx context.Context, ch address.Address, sv *paych0.SignedVoucher, proof []byte, minDelta types.BigInt) (types.BigInt, error) { +func (pm *Manager) AddVoucherInbound(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, proof []byte, minDelta types.BigInt) (types.BigInt, error) { // Get an accessor for the channel, creating it from state if necessary ca, err := pm.inboundChannelAccessor(ctx, ch) if err != nil { @@ -336,7 +335,7 @@ func (pm *Manager) trackInboundChannel(ctx context.Context, ch address.Address) return pm.store.TrackChannel(stateCi) } -func (pm *Manager) SubmitVoucher(ctx context.Context, ch address.Address, sv *paych0.SignedVoucher, secret []byte, proof []byte) (cid.Cid, error) { +func (pm *Manager) SubmitVoucher(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, secret []byte, proof []byte) (cid.Cid, error) { ca, err := pm.accessorByAddress(ch) if err != nil { return cid.Undef, err diff --git a/paychmgr/paych.go b/paychmgr/paych.go index f856b9890..ba96c5e40 100644 --- a/paychmgr/paych.go +++ b/paychmgr/paych.go @@ -103,7 +103,7 @@ func (ca *channelAccessor) outboundActiveByFromTo(from, to address.Address) (*Ch // nonce, signing the voucher and storing it in the local datastore. // If there are not enough funds in the channel to create the voucher, returns // the shortfall in funds. -func (ca *channelAccessor) createVoucher(ctx context.Context, ch address.Address, voucher paych0.SignedVoucher) (*api.VoucherCreateResult, error) { +func (ca *channelAccessor) createVoucher(ctx context.Context, ch address.Address, voucher paych.SignedVoucher) (*api.VoucherCreateResult, error) { ca.lk.Lock() defer ca.lk.Unlock() @@ -162,14 +162,14 @@ func (ca *channelAccessor) nextNonceForLane(ci *ChannelInfo, lane uint64) uint64 return maxnonce + 1 } -func (ca *channelAccessor) checkVoucherValid(ctx context.Context, ch address.Address, sv *paych0.SignedVoucher) (map[uint64]paych.LaneState, error) { +func (ca *channelAccessor) checkVoucherValid(ctx context.Context, ch address.Address, sv *paych.SignedVoucher) (map[uint64]paych.LaneState, error) { ca.lk.Lock() defer ca.lk.Unlock() return ca.checkVoucherValidUnlocked(ctx, ch, sv) } -func (ca *channelAccessor) checkVoucherValidUnlocked(ctx context.Context, ch address.Address, sv *paych0.SignedVoucher) (map[uint64]paych.LaneState, error) { +func (ca *channelAccessor) checkVoucherValidUnlocked(ctx context.Context, ch address.Address, sv *paych.SignedVoucher) (map[uint64]paych.LaneState, error) { if sv.ChannelAddr != ch { return nil, xerrors.Errorf("voucher ChannelAddr doesn't match channel address, got %s, expected %s", sv.ChannelAddr, ch) } @@ -272,7 +272,7 @@ func (ca *channelAccessor) checkVoucherValidUnlocked(ctx context.Context, ch add return laneStates, nil } -func (ca *channelAccessor) checkVoucherSpendable(ctx context.Context, ch address.Address, sv *paych0.SignedVoucher, secret []byte, proof []byte) (bool, error) { +func (ca *channelAccessor) checkVoucherSpendable(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, secret []byte, proof []byte) (bool, error) { ca.lk.Lock() defer ca.lk.Unlock() @@ -346,14 +346,14 @@ func (ca *channelAccessor) getPaychRecipient(ctx context.Context, ch address.Add return state.To() } -func (ca *channelAccessor) addVoucher(ctx context.Context, ch address.Address, sv *paych0.SignedVoucher, proof []byte, minDelta types.BigInt) (types.BigInt, error) { +func (ca *channelAccessor) addVoucher(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, proof []byte, minDelta types.BigInt) (types.BigInt, error) { ca.lk.Lock() defer ca.lk.Unlock() return ca.addVoucherUnlocked(ctx, ch, sv, proof, minDelta) } -func (ca *channelAccessor) addVoucherUnlocked(ctx context.Context, ch address.Address, sv *paych0.SignedVoucher, proof []byte, minDelta types.BigInt) (types.BigInt, error) { +func (ca *channelAccessor) addVoucherUnlocked(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, proof []byte, minDelta types.BigInt) (types.BigInt, error) { ci, err := ca.store.ByAddress(ch) if err != nil { return types.BigInt{}, err @@ -420,7 +420,7 @@ func (ca *channelAccessor) addVoucherUnlocked(ctx context.Context, ch address.Ad return delta, ca.store.putChannelInfo(ci) } -func (ca *channelAccessor) submitVoucher(ctx context.Context, ch address.Address, sv *paych0.SignedVoucher, secret []byte, proof []byte) (cid.Cid, error) { +func (ca *channelAccessor) submitVoucher(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, secret []byte, proof []byte) (cid.Cid, error) { ca.lk.Lock() defer ca.lk.Unlock() @@ -461,6 +461,10 @@ func (ca *channelAccessor) submitVoucher(ctx context.Context, ch address.Address } } + // TODO: ActorUpgrade + // The "proof" field is going away. We will need to abstract over the + // network version here. + // Alternatively, we'd need to support the "old" method on-chain. enc, err := actors.SerializeParams(&paych0.UpdateChannelStateParams{ Sv: *sv, Secret: secret, @@ -572,7 +576,7 @@ func (ca *channelAccessor) laneState(ctx context.Context, state paych.State, ch } // Get the total redeemed amount across all lanes, after applying the voucher -func (ca *channelAccessor) totalRedeemedWithVoucher(laneStates map[uint64]paych.LaneState, sv *paych0.SignedVoucher) (big.Int, error) { +func (ca *channelAccessor) totalRedeemedWithVoucher(laneStates map[uint64]paych.LaneState, sv *paych.SignedVoucher) (big.Int, error) { // TODO: merges if len(sv.Merges) != 0 { return big.Int{}, xerrors.Errorf("dont currently support paych lane merges") diff --git a/paychmgr/settler/settler.go b/paychmgr/settler/settler.go index 654ed66cc..02fe9256e 100644 --- a/paychmgr/settler/settler.go +++ b/paychmgr/settler/settler.go @@ -15,10 +15,10 @@ import ( "github.com/filecoin-project/go-state-types/abi" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/actors/builtin/paych" "github.com/filecoin-project/lotus/chain/events" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/node/impl/full" @@ -39,9 +39,9 @@ type API struct { type settlerAPI interface { PaychList(context.Context) ([]address.Address, error) PaychStatus(context.Context, address.Address) (*api.PaychStatus, error) - PaychVoucherCheckSpendable(context.Context, address.Address, *paych0.SignedVoucher, []byte, []byte) (bool, error) - PaychVoucherList(context.Context, address.Address) ([]*paych0.SignedVoucher, error) - PaychVoucherSubmit(context.Context, address.Address, *paych0.SignedVoucher, []byte, []byte) (cid.Cid, error) + PaychVoucherCheckSpendable(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (bool, error) + PaychVoucherList(context.Context, address.Address) ([]*paych.SignedVoucher, error) + PaychVoucherSubmit(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (cid.Cid, error) StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64) (*api.MsgLookup, error) } @@ -86,7 +86,7 @@ func (pcs *paymentChannelSettler) messageHandler(msg *types.Message, rec *types. if err != nil { return true, err } - go func(voucher *paych0.SignedVoucher, submitMessageCID cid.Cid) { + go func(voucher *paych.SignedVoucher, submitMessageCID cid.Cid) { defer wg.Done() msgLookup, err := pcs.api.StateWaitMsg(pcs.ctx, submitMessageCID, build.MessageConfidence) if err != nil { diff --git a/paychmgr/store.go b/paychmgr/store.go index 23916669e..dbd663832 100644 --- a/paychmgr/store.go +++ b/paychmgr/store.go @@ -17,11 +17,10 @@ import ( "github.com/ipfs/go-datastore/namespace" dsq "github.com/ipfs/go-datastore/query" - paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych" - "github.com/filecoin-project/go-address" cborrpc "github.com/filecoin-project/go-cbor-util" + "github.com/filecoin-project/lotus/chain/actors/builtin/paych" "github.com/filecoin-project/lotus/node/modules/dtypes" ) @@ -49,7 +48,7 @@ const ( ) type VoucherInfo struct { - Voucher *paych0.SignedVoucher + Voucher *paych.SignedVoucher Proof []byte Submitted bool } @@ -103,7 +102,7 @@ func (ci *ChannelInfo) to() address.Address { // infoForVoucher gets the VoucherInfo for the given voucher. // returns nil if the channel doesn't have the voucher. -func (ci *ChannelInfo) infoForVoucher(sv *paych0.SignedVoucher) (*VoucherInfo, error) { +func (ci *ChannelInfo) infoForVoucher(sv *paych.SignedVoucher) (*VoucherInfo, error) { for _, v := range ci.Vouchers { eq, err := cborutil.Equals(sv, v.Voucher) if err != nil { @@ -116,7 +115,7 @@ func (ci *ChannelInfo) infoForVoucher(sv *paych0.SignedVoucher) (*VoucherInfo, e return nil, nil } -func (ci *ChannelInfo) hasVoucher(sv *paych0.SignedVoucher) (bool, error) { +func (ci *ChannelInfo) hasVoucher(sv *paych.SignedVoucher) (bool, error) { vi, err := ci.infoForVoucher(sv) return vi != nil, err } @@ -124,7 +123,7 @@ func (ci *ChannelInfo) hasVoucher(sv *paych0.SignedVoucher) (bool, error) { // markVoucherSubmitted marks the voucher, and any vouchers of lower nonce // in the same lane, as being submitted. // Note: This method doesn't write anything to the store. -func (ci *ChannelInfo) markVoucherSubmitted(sv *paych0.SignedVoucher) error { +func (ci *ChannelInfo) markVoucherSubmitted(sv *paych.SignedVoucher) error { vi, err := ci.infoForVoucher(sv) if err != nil { return err @@ -148,7 +147,7 @@ func (ci *ChannelInfo) markVoucherSubmitted(sv *paych0.SignedVoucher) error { } // wasVoucherSubmitted returns true if the voucher has been submitted -func (ci *ChannelInfo) wasVoucherSubmitted(sv *paych0.SignedVoucher) (bool, error) { +func (ci *ChannelInfo) wasVoucherSubmitted(sv *paych.SignedVoucher) (bool, error) { vi, err := ci.infoForVoucher(sv) if err != nil { return false, err @@ -277,7 +276,7 @@ func (ps *Store) VouchersForPaych(ch address.Address) ([]*VoucherInfo, error) { return ci.Vouchers, nil } -func (ps *Store) MarkVoucherSubmitted(ci *ChannelInfo, sv *paych0.SignedVoucher) error { +func (ps *Store) MarkVoucherSubmitted(ci *ChannelInfo, sv *paych.SignedVoucher) error { err := ci.markVoucherSubmitted(sv) if err != nil { return err diff --git a/paychmgr/util.go b/paychmgr/util.go index 2a8181c15..8e5dd4fab 100644 --- a/paychmgr/util.go +++ b/paychmgr/util.go @@ -5,21 +5,21 @@ import ( "github.com/filecoin-project/go-address" - paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych" + "github.com/filecoin-project/lotus/chain/actors/builtin/paych" ) type BestSpendableAPI interface { - PaychVoucherList(context.Context, address.Address) ([]*paych0.SignedVoucher, error) - PaychVoucherCheckSpendable(context.Context, address.Address, *paych0.SignedVoucher, []byte, []byte) (bool, error) + PaychVoucherList(context.Context, address.Address) ([]*paych.SignedVoucher, error) + PaychVoucherCheckSpendable(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (bool, error) } -func BestSpendableByLane(ctx context.Context, api BestSpendableAPI, ch address.Address) (map[uint64]*paych0.SignedVoucher, error) { +func BestSpendableByLane(ctx context.Context, api BestSpendableAPI, ch address.Address) (map[uint64]*paych.SignedVoucher, error) { vouchers, err := api.PaychVoucherList(ctx, ch) if err != nil { return nil, err } - bestByLane := make(map[uint64]*paych0.SignedVoucher) + bestByLane := make(map[uint64]*paych.SignedVoucher) for _, voucher := range vouchers { spendable, err := api.PaychVoucherCheckSpendable(ctx, ch, voucher, nil, nil) if err != nil { From c88d124954221398c7bab5f524dccbaad095c997 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 28 Sep 2020 14:43:55 -0700 Subject: [PATCH 019/115] use built-in actor ID The init actor will not allow the account actor to exec an arbitrary actor. --- chain/stmgr/forks_test.go | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/chain/stmgr/forks_test.go b/chain/stmgr/forks_test.go index ee378c983..9db6a491a 100644 --- a/chain/stmgr/forks_test.go +++ b/chain/stmgr/forks_test.go @@ -12,7 +12,6 @@ import ( "github.com/filecoin-project/specs-actors/actors/builtin" init_ "github.com/filecoin-project/specs-actors/actors/builtin/init" "github.com/filecoin-project/specs-actors/actors/runtime" - "github.com/multiformats/go-multihash" "golang.org/x/xerrors" "github.com/filecoin-project/lotus/chain/actors" @@ -44,16 +43,8 @@ const testForkHeight = 40 type testActor struct { } -var testActorCodeID = func() cid.Cid { - builder := cid.V1Builder{Codec: cid.Raw, MhType: multihash.IDENTITY} - c, err := builder.Sum([]byte("fil/any/test")) - if err != nil { - panic(err) - } - return c -}() - -func (testActor) Code() cid.Cid { return testActorCodeID } +// must use existing actor that an account is allowed to exec. +func (testActor) Code() cid.Cid { return builtin.PaymentChannelActorCodeID } func (testActor) State() cbor.Er { return new(testActorState) } type testActorState struct { From d1000e38d715890c8d7853d4c604844f8957c221 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 28 Sep 2020 15:50:54 -0700 Subject: [PATCH 020/115] wire up network upgrade logic for v2 actors upgrade --- build/params_2k.go | 1 + build/params_testground.go | 1 + build/params_testnet.go | 2 ++ chain/stmgr/forks.go | 40 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 44 insertions(+) diff --git a/build/params_2k.go b/build/params_2k.go index 3682f7be1..4428da748 100644 --- a/build/params_2k.go +++ b/build/params_2k.go @@ -14,6 +14,7 @@ const BreezeGasTampingDuration = 0 const UpgradeSmokeHeight = -1 const UpgradeIgnitionHeight = -2 const UpgradeLiftoffHeight = -3 +const UpgradeActorsV2 = 10 var DrandSchedule = map[abi.ChainEpoch]DrandEnum{ 0: DrandMainnet, diff --git a/build/params_testground.go b/build/params_testground.go index 07cc88688..718e21d68 100644 --- a/build/params_testground.go +++ b/build/params_testground.go @@ -77,6 +77,7 @@ var ( UpgradeSmokeHeight abi.ChainEpoch = -1 UpgradeIgnitionHeight abi.ChainEpoch = -2 UpgradeLiftoffHeight abi.ChainEpoch = -3 + UpgradeActorsV2 abi.ChainEpoch = 10 DrandSchedule = map[abi.ChainEpoch]DrandEnum{ 0: DrandMainnet, diff --git a/build/params_testnet.go b/build/params_testnet.go index 960f3a9b6..66f30f869 100644 --- a/build/params_testnet.go +++ b/build/params_testnet.go @@ -23,6 +23,8 @@ const UpgradeSmokeHeight = 51000 const UpgradeIgnitionHeight = 94000 +const UpgradeActorsV2 = 128888 + // This signals our tentative epoch for mainnet launch. Can make it later, but not earlier. // Miners, clients, developers, custodians all need time to prepare. // We still have upgrades and state changes to do, but can happen after signaling timing here. diff --git a/chain/stmgr/forks.go b/chain/stmgr/forks.go index 9561e5ed9..c49d75370 100644 --- a/chain/stmgr/forks.go +++ b/chain/stmgr/forks.go @@ -21,8 +21,10 @@ import ( adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" "github.com/filecoin-project/specs-actors/actors/migration/nv3" + m2 "github.com/filecoin-project/specs-actors/v2/actors/migration" "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/builtin/multisig" "github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/types" @@ -32,6 +34,7 @@ import ( var ForksAtHeight = map[abi.ChainEpoch]func(context.Context, *StateManager, ExecCallback, cid.Cid, *types.TipSet) (cid.Cid, error){ build.UpgradeBreezeHeight: UpgradeFaucetBurnRecovery, build.UpgradeIgnitionHeight: UpgradeIgnition, + build.UpgradeActorsV2: UpgradeActorsV2, build.UpgradeLiftoffHeight: UpgradeLiftoff, } @@ -414,6 +417,43 @@ func UpgradeIgnition(ctx context.Context, sm *StateManager, cb ExecCallback, roo return tree.Flush(ctx) } +func UpgradeActorsV2(ctx context.Context, sm *StateManager, cb ExecCallback, root cid.Cid, ts *types.TipSet) (cid.Cid, error) { + store := sm.cs.Store(ctx) + + info, err := store.Put(ctx, new(types.StateInfo)) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to create new state info for actors v2: %w", err) + } + + newHamtRoot, err := m2.MigrateStateTree(ctx, store, root) + if err != nil { + return cid.Undef, xerrors.Errorf("upgrading to actors v2: %w", err) + } + + newRoot, err := store.Put(ctx, &types.StateRoot{ + // TODO: ActorUpgrade: should be state-tree specific, not just the actors version. + Version: actors.Version2, + Actors: newHamtRoot, + Info: info, + }) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to persist new state root: %w", err) + } + + // perform some basic sanity checks. + if newSm, err := state.LoadStateTree(store, newRoot); err != nil { + return cid.Undef, xerrors.Errorf("state tree sanity load failed: %w", err) + } else if newRoot2, err := newSm.Flush(ctx); err != nil { + return cid.Undef, xerrors.Errorf("state tree sanity flush failed: %w", err) + } else if newRoot2 != newRoot { + return cid.Undef, xerrors.Errorf("state-root mismatch: %s != %s", newRoot, newRoot2) + } else if _, err := newSm.GetActor(builtin0.InitActorAddr); err != nil { + return cid.Undef, xerrors.Errorf("failed to load init actor after upgrade: %w", err) + } + + return newRoot, nil +} + func UpgradeLiftoff(ctx context.Context, sm *StateManager, cb ExecCallback, root cid.Cid, ts *types.TipSet) (cid.Cid, error) { tree, err := sm.StateTree(root) if err != nil { From 3e6323a503e7a05ede45c3cf2a42cccc729bad0e Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 28 Sep 2020 15:54:48 -0700 Subject: [PATCH 021/115] make setNetworkName work with any actors version --- chain/actors/builtin/init/init.go | 3 +++ chain/actors/builtin/init/v0.go | 5 +++++ chain/actors/builtin/init/v2.go | 5 +++++ chain/stmgr/forks.go | 13 +++++++------ 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/chain/actors/builtin/init/init.go b/chain/actors/builtin/init/init.go index d1a41b158..5777bb890 100644 --- a/chain/actors/builtin/init/init.go +++ b/chain/actors/builtin/init/init.go @@ -51,4 +51,7 @@ type State interface { // It should not be used in production code, as init actor entries are // immutable. Remove(addrs ...address.Address) error + + // Sets the network's name. This should only be used on upgrade/fork. + SetNetworkName(name string) error } diff --git a/chain/actors/builtin/init/v0.go b/chain/actors/builtin/init/v0.go index de0d6c9e1..ceb87f970 100644 --- a/chain/actors/builtin/init/v0.go +++ b/chain/actors/builtin/init/v0.go @@ -57,6 +57,11 @@ func (s *state0) NetworkName() (dtypes.NetworkName, error) { return dtypes.NetworkName(s.State.NetworkName), nil } +func (s *state0) SetNetworkName(name string) error { + s.State.NetworkName = name + return nil +} + func (s *state0) Remove(addrs ...address.Address) (err error) { m, err := adt0.AsMap(s.store, s.State.AddressMap) if err != nil { diff --git a/chain/actors/builtin/init/v2.go b/chain/actors/builtin/init/v2.go index 38b3099fd..5aa0ddc18 100644 --- a/chain/actors/builtin/init/v2.go +++ b/chain/actors/builtin/init/v2.go @@ -57,6 +57,11 @@ func (s *state2) NetworkName() (dtypes.NetworkName, error) { return dtypes.NetworkName(s.State.NetworkName), nil } +func (s *state2) SetNetworkName(name string) error { + s.State.NetworkName = name + return nil +} + func (s *state2) Remove(addrs ...address.Address) (err error) { m, err := adt2.AsMap(s.store, s.State.AddressMap) if err != nil { diff --git a/chain/stmgr/forks.go b/chain/stmgr/forks.go index c49d75370..813557c04 100644 --- a/chain/stmgr/forks.go +++ b/chain/stmgr/forks.go @@ -14,7 +14,6 @@ import ( "golang.org/x/xerrors" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - init0 "github.com/filecoin-project/specs-actors/actors/builtin/init" miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" multisig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig" power0 "github.com/filecoin-project/specs-actors/actors/builtin/power" @@ -25,6 +24,8 @@ import ( "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/adt" + init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init" "github.com/filecoin-project/lotus/chain/actors/builtin/multisig" "github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/types" @@ -468,20 +469,20 @@ func UpgradeLiftoff(ctx context.Context, sm *StateManager, cb ExecCallback, root return tree.Flush(ctx) } -func setNetworkName(ctx context.Context, store adt0.Store, tree *state.StateTree, name string) error { +func setNetworkName(ctx context.Context, store adt.Store, tree *state.StateTree, name string) error { ia, err := tree.GetActor(builtin0.InitActorAddr) if err != nil { return xerrors.Errorf("getting init actor: %w", err) } - var initState init0.State - if err := store.Get(ctx, ia.Head, &initState); err != nil { + initState, err := init_.Load(store, ia) + if err != nil { return xerrors.Errorf("reading init state: %w", err) } - initState.NetworkName = name + initState.SetNetworkName(name) - ia.Head, err = store.Put(ctx, &initState) + ia.Head, err = store.Put(ctx, initState) if err != nil { return xerrors.Errorf("writing new init state: %w", err) } From c0b316fd9ca0b0fc6cfe9051cacb7ff83d817c55 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 28 Sep 2020 15:58:07 -0700 Subject: [PATCH 022/115] finish wiring up actors v2 --- build/params_shared_funcs.go | 2 +- build/params_shared_vals.go | 2 +- chain/stmgr/stmgr.go | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/build/params_shared_funcs.go b/build/params_shared_funcs.go index 28567d3d1..95daa45e7 100644 --- a/build/params_shared_funcs.go +++ b/build/params_shared_funcs.go @@ -41,7 +41,7 @@ func DhtProtocolName(netName dtypes.NetworkName) protocol.ID { func UseNewestNetwork() bool { // TODO: Put these in a container we can iterate over - if UpgradeBreezeHeight <= 0 && UpgradeSmokeHeight <= 0 { + if UpgradeBreezeHeight <= 0 && UpgradeSmokeHeight <= 0 && UpgradeActorsV2 <= 0 { return true } return false diff --git a/build/params_shared_vals.go b/build/params_shared_vals.go index 33828f954..9655711fb 100644 --- a/build/params_shared_vals.go +++ b/build/params_shared_vals.go @@ -25,7 +25,7 @@ const UnixfsLinksPerLevel = 1024 // Consensus / Network const AllowableClockDriftSecs = uint64(1) -const NewestNetworkVersion = network.Version3 +const NewestNetworkVersion = network.Version4 const ActorUpgradeNetworkVersion = network.Version4 // Epochs diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index 409b2de29..aa0439467 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -1275,6 +1275,10 @@ func (sm *StateManager) GetNtwkVersion(ctx context.Context, height abi.ChainEpoc return network.Version2 } + if height <= build.UpgradeActorsV2 { + return network.Version3 + } + return build.NewestNetworkVersion } From a314cfd2372e1a80e361a53910664c708ea303f4 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 28 Sep 2020 15:59:11 -0700 Subject: [PATCH 023/115] process error when setting network name --- chain/stmgr/forks.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/chain/stmgr/forks.go b/chain/stmgr/forks.go index 813557c04..772a1a9a3 100644 --- a/chain/stmgr/forks.go +++ b/chain/stmgr/forks.go @@ -480,7 +480,9 @@ func setNetworkName(ctx context.Context, store adt.Store, tree *state.StateTree, return xerrors.Errorf("reading init state: %w", err) } - initState.SetNetworkName(name) + if err := initState.SetNetworkName(name); err != nil { + return xerrors.Errorf("setting network name: %w", err) + } ia.Head, err = store.Put(ctx, initState) if err != nil { From b95b871943e39784a93d0c3d815f1035c3b5cd5d Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 28 Sep 2020 16:14:51 -0700 Subject: [PATCH 024/115] actually upgrade to actors v2 --- chain/actors/version.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/chain/actors/version.go b/chain/actors/version.go index 2173a320d..385ff592f 100644 --- a/chain/actors/version.go +++ b/chain/actors/version.go @@ -18,6 +18,8 @@ func VersionForNetwork(version network.Version) Version { switch version { case network.Version0, network.Version1, network.Version2, network.Version3: return Version0 + case network.Version4: + return Version2 default: panic(fmt.Sprintf("unsupported network version %d", version)) } From 01272f850d5fefc27925ce4e6d2c252b9dec60d8 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 28 Sep 2020 16:23:46 -0700 Subject: [PATCH 025/115] fix state test --- chain/state/statetree_test.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/chain/state/statetree_test.go b/chain/state/statetree_test.go index 554ba2697..3b08a4b53 100644 --- a/chain/state/statetree_test.go +++ b/chain/state/statetree_test.go @@ -9,6 +9,7 @@ import ( cbor "github.com/ipfs/go-ipld-cbor" address "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/lotus/build" @@ -237,7 +238,8 @@ func assertNotHas(t *testing.T, st *StateTree, addr address.Address) { func TestStateTreeConsistency(t *testing.T) { cst := cbor.NewMemCborStore() - st, err := NewStateTree(cst, actors.VersionForNetwork(build.NewestNetworkVersion)) + // TODO: ActorUpgrade: this test tests pre actors v2 + st, err := NewStateTree(cst, actors.VersionForNetwork(network.Version3)) if err != nil { t.Fatal(err) } From 9344bc4e9bd94c4505ce593f9cea0b5e2d707c91 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 28 Sep 2020 16:27:47 -0700 Subject: [PATCH 026/115] update api docs for new network version --- documentation/en/api-methods.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/en/api-methods.md b/documentation/en/api-methods.md index ed082ccbf..c39840382 100644 --- a/documentation/en/api-methods.md +++ b/documentation/en/api-methods.md @@ -3825,7 +3825,7 @@ Inputs: ] ``` -Response: `3` +Response: `4` ### StateReadState StateReadState returns the indicated actor's state. From 2315db161bed787776136c4f9ee30fef12ae80d5 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 28 Sep 2020 16:46:29 -0700 Subject: [PATCH 027/115] cleanup state-tree loading And remove incorrect comment. --- chain/state/statetree.go | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/chain/state/statetree.go b/chain/state/statetree.go index fcb7ffbaa..3f9597420 100644 --- a/chain/state/statetree.go +++ b/chain/state/statetree.go @@ -157,27 +157,25 @@ func LoadStateTree(cst cbor.IpldStore, c cid.Cid) (*StateTree, error) { root.Version = actors.Version0 } - // If that fails, load as an old-style state-tree (direct hampt, version 0. - nd, err := adt.AsMap(adt.WrapStore(context.TODO(), cst), root.Actors, actors.Version(root.Version)) - if err != nil { - log.Errorf("loading hamt node %s failed: %s", c, err) - return nil, err - } - switch root.Version { case actors.Version0, actors.Version2: - // supported + // Load the actual state-tree HAMT. + nd, err := adt.AsMap(adt.WrapStore(context.TODO(), cst), root.Actors, actors.Version(root.Version)) + if err != nil { + log.Errorf("loading hamt node %s failed: %s", c, err) + return nil, err + } + + return &StateTree{ + root: nd, + info: root.Info, + version: actors.Version(root.Version), + Store: cst, + snaps: newStateSnaps(), + }, nil default: return nil, xerrors.Errorf("unsupported state tree version: %d", root.Version) } - - return &StateTree{ - root: nd, - info: root.Info, - version: actors.Version(root.Version), - Store: cst, - snaps: newStateSnaps(), - }, nil } func (st *StateTree) SetActor(addr address.Address, act *types.Actor) error { From 1c0386285476cb6e51a451c5114f640688cd4c91 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 28 Sep 2020 17:28:16 -0700 Subject: [PATCH 028/115] fix policy for specs-actors update --- api/test/paych.go | 2 +- build/params_shared_vals.go | 13 ++++-------- build/params_testground.go | 9 ++++---- chain/actors/policy/policy.go | 27 ++++++++++++++++++++++++ chain/actors/policy/policy_test.go | 11 ++++++++++ extern/storage-sealing/checks.go | 16 ++++---------- extern/storage-sealing/constants.go | 7 ------ extern/storage-sealing/states_sealing.go | 13 +++--------- 8 files changed, 54 insertions(+), 44 deletions(-) diff --git a/api/test/paych.go b/api/test/paych.go index 4c3bdba1b..c13303593 100644 --- a/api/test/paych.go +++ b/api/test/paych.go @@ -169,7 +169,7 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) { return true, nil }, func(ctx context.Context, ts *types.TipSet) error { return nil - }, int(build.MessageConfidence)+1, build.SealRandomnessLookbackLimit, func(oldTs, newTs *types.TipSet) (bool, events.StateChange, error) { + }, int(build.MessageConfidence)+1, build.Finality, func(oldTs, newTs *types.TipSet) (bool, events.StateChange, error) { return preds.OnPaymentChannelActorChanged(channel, preds.OnToSendAmountChanges())(ctx, oldTs.Key(), newTs.Key()) }) if err != nil { diff --git a/build/params_shared_vals.go b/build/params_shared_vals.go index 9655711fb..4734a15ed 100644 --- a/build/params_shared_vals.go +++ b/build/params_shared_vals.go @@ -7,12 +7,12 @@ import ( "os" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/lotus/chain/actors/policy" "github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/specs-actors/actors/builtin" - miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" ) // ///// @@ -35,7 +35,7 @@ const ForkLengthThreshold = Finality var BlocksPerEpoch = uint64(builtin.ExpectedLeadersPerEpoch) // Epochs -const Finality = miner0.ChainFinality +const Finality = policy.ChainFinality const MessageConfidence = uint64(5) // constants for Weight calculation @@ -47,13 +47,8 @@ const WRatioDen = uint64(2) // Proofs // Epochs -const SealRandomnessLookback = Finality - -// Epochs -const SealRandomnessLookbackLimit = SealRandomnessLookback + 2000 // TODO: Get from spec specs-actors - -// Maximum lookback that randomness can be sourced from for a seal proof submission -const MaxSealLookback = SealRandomnessLookbackLimit + 2000 // TODO: Get from specs-actors +// TODO: unused +const SealRandomnessLookback = policy.SealRandomnessLookback // ///// // Mining diff --git a/build/params_testground.go b/build/params_testground.go index 718e21d68..975c26599 100644 --- a/build/params_testground.go +++ b/build/params_testground.go @@ -13,7 +13,8 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/specs-actors/actors/builtin" - miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" + + "github.com/filecoin-project/lotus/chain/actors/policy" ) var ( @@ -32,7 +33,7 @@ var ( AllowableClockDriftSecs = uint64(1) - Finality = miner0.ChainFinality + Finality = policy.ChainFinality ForkLengthThreshold = Finality SlashablePowerDelay = 20 @@ -47,9 +48,7 @@ var ( BlsSignatureCacheSize = 40000 VerifSigCacheSize = 32000 - SealRandomnessLookback = Finality - SealRandomnessLookbackLimit = SealRandomnessLookback + 2000 - MaxSealLookback = SealRandomnessLookbackLimit + 2000 + SealRandomnessLookback = policy.SealRandomnessLookback TicketRandomnessLookback = abi.ChainEpoch(1) WinningPoStSectorSetLookback = abi.ChainEpoch(10) diff --git a/chain/actors/policy/policy.go b/chain/actors/policy/policy.go index b8205177e..2101cfdcf 100644 --- a/chain/actors/policy/policy.go +++ b/chain/actors/policy/policy.go @@ -2,10 +2,19 @@ package policy import ( "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/chain/actors" miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" power0 "github.com/filecoin-project/specs-actors/actors/builtin/power" verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" + verifreg2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/verifreg" +) + +const ( + ChainFinality = miner0.ChainFinality + SealRandomnessLookback = ChainFinality ) // SetSupportedProofTypes sets supported proof types, across all actor versions. @@ -17,6 +26,7 @@ func SetSupportedProofTypes(types ...abi.RegisteredSealProof) { } // Set for all miner versions. miner0.SupportedProofTypes = newTypes + miner2.SupportedProofTypes = newTypes } // AddSupportedProofTypes sets supported proof types, across all actor versions. @@ -25,6 +35,7 @@ func AddSupportedProofTypes(types ...abi.RegisteredSealProof) { for _, t := range types { // Set for all miner versions. miner0.SupportedProofTypes[t] = struct{}{} + miner2.SupportedProofTypes[t] = struct{}{} } } @@ -33,6 +44,7 @@ func AddSupportedProofTypes(types ...abi.RegisteredSealProof) { func SetPreCommitChallengeDelay(delay abi.ChainEpoch) { // Set for all miner versions. miner0.PreCommitChallengeDelay = delay + miner2.PreCommitChallengeDelay = delay } // TODO: this function shouldn't really exist. Instead, the API should expose the precommit delay. @@ -45,10 +57,25 @@ func GetPreCommitChallengeDelay() abi.ChainEpoch { // for testing. func SetConsensusMinerMinPower(p abi.StoragePower) { power0.ConsensusMinerMinPower = p + for _, policy := range builtin2.SealProofPolicies { + policy.ConsensusMinerMinPower = p + } } // SetMinVerifiedDealSize sets the minimum size of a verified deal. This should // only be used for testing. func SetMinVerifiedDealSize(size abi.StoragePower) { verifreg0.MinVerifiedDealSize = size + verifreg2.MinVerifiedDealSize = size +} + +func GetMaxProveCommitDuration(ver actors.Version, t abi.RegisteredSealProof) abi.ChainEpoch { + switch ver { + case actors.Version0: + return miner0.MaxSealDuration[t] + case actors.Version2: + return miner2.MaxProveCommitDuration[t] + default: + panic("unsupported actors version") + } } diff --git a/chain/actors/policy/policy_test.go b/chain/actors/policy/policy_test.go index be64362a2..9ba5b4030 100644 --- a/chain/actors/policy/policy_test.go +++ b/chain/actors/policy/policy_test.go @@ -7,6 +7,9 @@ import ( "github.com/filecoin-project/go-state-types/abi" miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" + verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg" + miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" + verifreg2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/verifreg" ) func TestSupportedProofTypes(t *testing.T) { @@ -34,3 +37,11 @@ func TestSupportedProofTypes(t *testing.T) { }, ) } + +// Tests assumptions about policies being the same between actor versions. +func TestAssumptions(t *testing.T) { + require.EqualValues(t, miner0.SupportedProofTypes, miner2.SupportedProofTypes) + require.Equal(t, miner0.PreCommitChallengeDelay, miner2.PreCommitChallengeDelay) + require.Equal(t, miner0.ChainFinality, miner2.ChainFinality) + require.Equal(t, verifreg0.MinVerifiedDealSize, verifreg2.MinVerifiedDealSize) +} diff --git a/extern/storage-sealing/checks.go b/extern/storage-sealing/checks.go index 49994024f..1010d31b2 100644 --- a/extern/storage-sealing/checks.go +++ b/extern/storage-sealing/checks.go @@ -4,11 +4,9 @@ import ( "bytes" "context" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/policy" - "github.com/filecoin-project/lotus/build" - miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" - proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof" "golang.org/x/xerrors" @@ -102,16 +100,10 @@ func checkPrecommit(ctx context.Context, maddr address.Address, si SectorInfo, t return &ErrApi{xerrors.Errorf("calling StateNetworkVersion: %w", err)} } - var msd abi.ChainEpoch - if nv < build.ActorUpgradeNetworkVersion { - msd = miner0.MaxSealDuration[si.SectorType] - } else { - // TODO: ActorUpgrade(use MaxProveCommitDuration) - msd = 0 - } + msd := policy.GetMaxProveCommitDuration(actors.VersionForNetwork(nv), si.SectorType) - if height-(si.TicketEpoch+SealRandomnessLookback) > msd { - return &ErrExpiredTicket{xerrors.Errorf("ticket expired: seal height: %d, head: %d", si.TicketEpoch+SealRandomnessLookback, height)} + if height-(si.TicketEpoch+policy.SealRandomnessLookback) > msd { + return &ErrExpiredTicket{xerrors.Errorf("ticket expired: seal height: %d, head: %d", si.TicketEpoch+policy.SealRandomnessLookback, height)} } pci, err := api.StateSectorPreCommitInfo(ctx, maddr, si.SectorNumber, tok) diff --git a/extern/storage-sealing/constants.go b/extern/storage-sealing/constants.go index 8c7fa5abc..d6aba1814 100644 --- a/extern/storage-sealing/constants.go +++ b/extern/storage-sealing/constants.go @@ -1,11 +1,4 @@ package sealing -import ( - miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" -) - -// Epochs -const SealRandomnessLookback = miner0.ChainFinality - // Epochs const InteractivePoRepConfidence = 6 diff --git a/extern/storage-sealing/states_sealing.go b/extern/storage-sealing/states_sealing.go index a4e852454..96589bcd2 100644 --- a/extern/storage-sealing/states_sealing.go +++ b/extern/storage-sealing/states_sealing.go @@ -4,10 +4,9 @@ import ( "bytes" "context" - "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" "github.com/filecoin-project/lotus/chain/actors/policy" - miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" "golang.org/x/xerrors" @@ -60,7 +59,7 @@ func (m *Sealing) getTicket(ctx statemachine.Context, sector SectorInfo) (abi.Se return nil, 0, nil } - ticketEpoch := epoch - SealRandomnessLookback + ticketEpoch := epoch - policy.SealRandomnessLookback buf := new(bytes.Buffer) if err := m.maddr.MarshalCBOR(buf); err != nil { return nil, 0, err @@ -189,13 +188,7 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf return ctx.Send(SectorSealPreCommit1Failed{xerrors.Errorf("failed to get network version: %w", err)}) } - var msd abi.ChainEpoch - if nv < build.ActorUpgradeNetworkVersion { - msd = miner0.MaxSealDuration[sector.SectorType] - } else { - // TODO: ActorUpgrade(use MaxProveCommitDuration) - msd = 0 - } + msd := policy.GetMaxProveCommitDuration(actors.VersionForNetwork(nv), sector.SectorType) if minExpiration := height + msd + miner.MinSectorExpiration + 10; expiration < minExpiration { expiration = minExpiration From c0e190344d6e9df2a13d071ed0a571b50dd0e0cb Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 28 Sep 2020 17:42:29 -0700 Subject: [PATCH 029/115] check state invariants after upgrade --- chain/stmgr/forks.go | 16 +++++++++++++++- go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/chain/stmgr/forks.go b/chain/stmgr/forks.go index 772a1a9a3..96873b675 100644 --- a/chain/stmgr/forks.go +++ b/chain/stmgr/forks.go @@ -21,6 +21,7 @@ import ( "github.com/filecoin-project/specs-actors/actors/migration/nv3" m2 "github.com/filecoin-project/specs-actors/v2/actors/migration" + states2 "github.com/filecoin-project/specs-actors/v2/actors/states" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors" @@ -431,6 +432,19 @@ func UpgradeActorsV2(ctx context.Context, sm *StateManager, cb ExecCallback, roo return cid.Undef, xerrors.Errorf("upgrading to actors v2: %w", err) } + newStateTree, err := states2.LoadTree(store, newHamtRoot) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to load new state tree: %w", err) + } + + // Check all state-tree invariants. + if msgs, err := states2.CheckStateInvariants(newStateTree, types.TotalFilecoinInt); err != nil { + return cid.Undef, xerrors.Errorf("failed to check new state tree: %w", err) + } else if !msgs.IsEmpty() { + // This error is going to be really nasty. + return cid.Undef, xerrors.Errorf("network upgrade failed: %v", msgs.Messages()) + } + newRoot, err := store.Put(ctx, &types.StateRoot{ // TODO: ActorUpgrade: should be state-tree specific, not just the actors version. Version: actors.Version2, @@ -441,7 +455,7 @@ func UpgradeActorsV2(ctx context.Context, sm *StateManager, cb ExecCallback, roo return cid.Undef, xerrors.Errorf("failed to persist new state root: %w", err) } - // perform some basic sanity checks. + // perform some basic sanity checks to make sure everything still works. if newSm, err := state.LoadStateTree(store, newRoot); err != nil { return cid.Undef, xerrors.Errorf("state tree sanity load failed: %w", err) } else if newRoot2, err := newSm.Flush(ctx); err != nil { diff --git a/go.mod b/go.mod index 4908523fc..55f2fa308 100644 --- a/go.mod +++ b/go.mod @@ -37,7 +37,7 @@ require ( github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b github.com/filecoin-project/specs-actors v0.9.12-0.20200928180918-488a087c5add - github.com/filecoin-project/specs-actors/v2 v2.0.0-20200928175842-971c8d772684 + github.com/filecoin-project/specs-actors/v2 v2.0.0-20200929004132-ea2d270c9f47 github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796 github.com/filecoin-project/test-vectors/schema v0.0.1 github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 diff --git a/go.sum b/go.sum index 042b0d855..3413d730a 100644 --- a/go.sum +++ b/go.sum @@ -263,8 +263,8 @@ github.com/filecoin-project/specs-actors v0.9.7/go.mod h1:wM2z+kwqYgXn5Z7scV1YHL github.com/filecoin-project/specs-actors v0.9.9/go.mod h1:czlvLQGEX0fjLLfdNHD7xLymy6L3n7aQzRWzsYGf+ys= github.com/filecoin-project/specs-actors v0.9.12-0.20200928180918-488a087c5add h1:iXQOxr8uSyZ/qnTlOZf7ALp0io+jwLxmuWsNAk/YdoQ= github.com/filecoin-project/specs-actors v0.9.12-0.20200928180918-488a087c5add/go.mod h1:TS1AW/7LbG+615j4NsjMK1qlpAwaFsG9w0V2tg2gSao= -github.com/filecoin-project/specs-actors/v2 v2.0.0-20200928175842-971c8d772684 h1:sjWZqblOOf1RaohI9w2R2AVp5uifNdzsusy7oVi5ioU= -github.com/filecoin-project/specs-actors/v2 v2.0.0-20200928175842-971c8d772684/go.mod h1:/2Zra1BhLtpRywUhm++QP+3I5Ir+hBk/W24TpYjj43E= +github.com/filecoin-project/specs-actors/v2 v2.0.0-20200929004132-ea2d270c9f47 h1:bt/CdGbF1Rq5rDVaMV+XWfHBRCxN7IxZfw6lC1v6KQM= +github.com/filecoin-project/specs-actors/v2 v2.0.0-20200929004132-ea2d270c9f47/go.mod h1:/2Zra1BhLtpRywUhm++QP+3I5Ir+hBk/W24TpYjj43E= github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796 h1:dJsTPWpG2pcTeojO2pyn0c6l+x/3MZYCBgo/9d11JEk= github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796/go.mod h1:nJRRM7Aa9XVvygr3W9k6xGF46RWzr2zxF/iGoAIfA/g= github.com/filecoin-project/test-vectors/schema v0.0.1 h1:5fNF76nl4qolEvcIsjc0kUADlTMVHO73tW4kXXPnsus= From e658ab32872e7cf026287de127c0ee192d2aefa3 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 28 Sep 2020 17:44:34 -0700 Subject: [PATCH 030/115] fix policy test --- chain/actors/policy/policy_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chain/actors/policy/policy_test.go b/chain/actors/policy/policy_test.go index 9ba5b4030..8d6aac09f 100644 --- a/chain/actors/policy/policy_test.go +++ b/chain/actors/policy/policy_test.go @@ -43,5 +43,5 @@ func TestAssumptions(t *testing.T) { require.EqualValues(t, miner0.SupportedProofTypes, miner2.SupportedProofTypes) require.Equal(t, miner0.PreCommitChallengeDelay, miner2.PreCommitChallengeDelay) require.Equal(t, miner0.ChainFinality, miner2.ChainFinality) - require.Equal(t, verifreg0.MinVerifiedDealSize, verifreg2.MinVerifiedDealSize) + require.True(t, verifreg0.MinVerifiedDealSize.Equals(verifreg2.MinVerifiedDealSize)) } From dd65e57d4b6335d3882fda8ea8fb042e5813a63b Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 28 Sep 2020 17:53:11 -0700 Subject: [PATCH 031/115] set policy correctly from test vectors --- chain/vectors/gen/main.go | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/chain/vectors/gen/main.go b/chain/vectors/gen/main.go index 2b1c6f340..51d907648 100644 --- a/chain/vectors/gen/main.go +++ b/chain/vectors/gen/main.go @@ -6,28 +6,25 @@ import ( "math/rand" "os" - power0 "github.com/filecoin-project/specs-actors/actors/builtin/power" - "github.com/filecoin-project/go-address" "golang.org/x/xerrors" "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/crypto" + "github.com/filecoin-project/lotus/chain/actors/policy" "github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types/mock" "github.com/filecoin-project/lotus/chain/vectors" "github.com/filecoin-project/lotus/chain/wallet" - verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg" _ "github.com/filecoin-project/lotus/lib/sigs/bls" _ "github.com/filecoin-project/lotus/lib/sigs/secp" ) func init() { - verifreg0.MinVerifiedDealSize = big.NewInt(2048) - power0.ConsensusMinerMinPower = big.NewInt(2048) + policy.SetMinVerifiedDealSize(abi.NewStoragePower(2048)) + policy.SetConsensusMinerMinPower(abi.NewStoragePower(2048)) } func MakeHeaderVectors() []vectors.HeaderVector { From be9d23b32981b660d3b5fdc392b4e5d2cdd70458 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Tue, 29 Sep 2020 00:24:38 -0400 Subject: [PATCH 032/115] Centralize some params in builtin --- chain/actors/builtin/builtin.go | 20 ++++++++++++++++++++ chain/stmgr/stmgr.go | 6 ++++-- chain/sync.go | 4 +++- chain/types/actor.go | 18 ------------------ chain/vm/invoker.go | 4 +++- chain/vm/vm.go | 5 +++-- cli/multisig.go | 13 ++++++++----- cli/state.go | 3 ++- cmd/lotus-pcr/main.go | 10 ++++++---- cmd/lotus-shed/balances.go | 8 ++++---- cmd/lotus-shed/genesis-verify.go | 8 +++++--- cmd/lotus-shed/mempool-stats.go | 3 ++- node/impl/full/gas.go | 4 +++- 13 files changed, 63 insertions(+), 43 deletions(-) diff --git a/chain/actors/builtin/builtin.go b/chain/actors/builtin/builtin.go index 784c004eb..d49164486 100644 --- a/chain/actors/builtin/builtin.go +++ b/chain/actors/builtin/builtin.go @@ -18,6 +18,9 @@ import ( smoothing2 "github.com/filecoin-project/specs-actors/v2/actors/util/smoothing" ) +var SystemActorAddr = builtin0.SystemActorAddr +var BurntFundsActorAddr = builtin0.BurntFundsActorAddr + // TODO: Why does actors have 2 different versions of this? type SectorInfo = proof0.SectorInfo type PoStProof = proof0.PoStProof @@ -66,3 +69,20 @@ func ActorNameByCode(c cid.Cid) string { func IsBuiltinActor(c cid.Cid) bool { return builtin0.IsBuiltinActor(c) || builtin2.IsBuiltinActor(c) } + +func IsAccountActor(c cid.Cid) bool { + return c == builtin0.AccountActorCodeID || c == builtin2.AccountActorCodeID +} + +func IsStorageMinerActor(c cid.Cid) bool { + return c == builtin0.StorageMinerActorCodeID || c == builtin2.StorageMinerActorCodeID +} + +func IsMultisigActor(c cid.Cid) bool { + return c == builtin0.MultisigActorCodeID || c == builtin2.MultisigActorCodeID + +} + +func IsPaymentChannelActor(c cid.Cid) bool { + return c == builtin0.PaymentChannelActorCodeID || c == builtin2.PaymentChannelActorCodeID +} diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index aa0439467..c5968c4a4 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -5,6 +5,8 @@ import ( "fmt" "sync" + "github.com/filecoin-project/lotus/chain/actors/builtin" + builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig" @@ -858,7 +860,7 @@ func (sm *StateManager) setupGenesisActors(ctx context.Context) error { totalsByEpoch := make(map[abi.ChainEpoch]abi.TokenAmount) err = sTree.ForEach(func(kaddr address.Address, act *types.Actor) error { - if act.IsMultisigActor() { + if builtin.IsMultisigActor(act.Code) { s, err := multisig.Load(sm.cs.Store(ctx), act) if err != nil { return err @@ -890,7 +892,7 @@ func (sm *StateManager) setupGenesisActors(ctx context.Context) error { totalsByEpoch[ud] = ib } - } else if act.IsAccountActor() { + } else if builtin.IsAccountActor(act.Code) { // should exclude burnt funds actor and "remainder account actor" // should only ever be "faucet" accounts in testnets if kaddr == builtin0.BurntFundsActorAddr { diff --git a/chain/sync.go b/chain/sync.go index 6abe43567..eba10e95e 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -11,6 +11,8 @@ import ( "sync" "time" + "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/specs-actors/actors/runtime/proof" @@ -1080,7 +1082,7 @@ func (syncer *Syncer) checkBlockMessages(ctx context.Context, b *types.FullBlock return xerrors.Errorf("failed to get actor: %w", err) } - if !act.IsAccountActor() { + if !builtin.IsAccountActor(act.Code) { return xerrors.New("Sender must be an account actor") } nonces[m.From] = act.Nonce diff --git a/chain/types/actor.go b/chain/types/actor.go index eb8e05c49..a9974a01f 100644 --- a/chain/types/actor.go +++ b/chain/types/actor.go @@ -4,8 +4,6 @@ import ( "errors" "github.com/ipfs/go-cid" - - builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" ) var ErrActorNotFound = errors.New("actor not found") @@ -17,19 +15,3 @@ type Actor struct { Nonce uint64 Balance BigInt } - -func (a *Actor) IsAccountActor() bool { - return a.Code == builtin0.AccountActorCodeID -} - -func (a *Actor) IsStorageMinerActor() bool { - return a.Code == builtin0.StorageMinerActorCodeID -} - -func (a *Actor) IsMultisigActor() bool { - return a.Code == builtin0.MultisigActorCodeID -} - -func (a *Actor) IsPaymentChannelActor() bool { - return a.Code == builtin0.PaymentChannelActorCodeID -} diff --git a/chain/vm/invoker.go b/chain/vm/invoker.go index 65ef73cfc..1e9f04081 100644 --- a/chain/vm/invoker.go +++ b/chain/vm/invoker.go @@ -6,6 +6,8 @@ import ( "fmt" "reflect" + "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" @@ -210,7 +212,7 @@ func DecodeParams(b []byte, out interface{}) error { } func DumpActorState(act *types.Actor, b []byte) (interface{}, error) { - if act.IsAccountActor() { // Account code special case + if builtin.IsAccountActor(act.Code) { // Account code special case return nil, nil } diff --git a/chain/vm/vm.go b/chain/vm/vm.go index d92d16310..1161178ac 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -8,6 +8,8 @@ import ( "sync/atomic" "time" + "github.com/filecoin-project/lotus/chain/actors/builtin" + block "github.com/ipfs/go-block-format" cid "github.com/ipfs/go-cid" cbor "github.com/ipfs/go-ipld-cbor" @@ -23,7 +25,6 @@ import ( "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/go-state-types/exitcode" "github.com/filecoin-project/go-state-types/network" - "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors/adt" @@ -396,7 +397,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet, } // this should never happen, but is currently still exercised by some tests - if !fromActor.IsAccountActor() { + if !builtin.IsAccountActor(fromActor.Code) { gasOutputs := ZeroGasOutputs() gasOutputs.MinerPenalty = minerPenaltyAmount return &ApplyRet{ diff --git a/cli/multisig.go b/cli/multisig.go index 5b0977382..6b3867cb3 100644 --- a/cli/multisig.go +++ b/cli/multisig.go @@ -9,6 +9,10 @@ import ( "strconv" "text/tabwriter" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + + "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/go-state-types/big" @@ -20,7 +24,6 @@ import ( "github.com/urfave/cli/v2" "golang.org/x/xerrors" - "github.com/filecoin-project/specs-actors/actors/builtin" init0 "github.com/filecoin-project/specs-actors/actors/builtin/init" msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig" @@ -356,7 +359,7 @@ var msigProposeCmd = &cli.Command{ return fmt.Errorf("failed to look up multisig %s: %w", msig, err) } - if !act.IsMultisigActor() { + if !builtin.IsMultisigActor(act.Code) { return fmt.Errorf("actor %s is not a multisig actor", msig) } @@ -1029,7 +1032,7 @@ var msigLockProposeCmd = &cli.Command{ return actErr } - msgCid, err := api.MsigPropose(ctx, msig, msig, big.Zero(), from, uint64(builtin.MethodsMultisig.LockBalance), params) + msgCid, err := api.MsigPropose(ctx, msig, msig, big.Zero(), from, uint64(builtin2.MethodsMultisig.LockBalance), params) if err != nil { return err } @@ -1126,7 +1129,7 @@ var msigLockApproveCmd = &cli.Command{ return actErr } - msgCid, err := api.MsigApprove(ctx, msig, txid, prop, msig, big.Zero(), from, uint64(builtin.MethodsMultisig.LockBalance), params) + msgCid, err := api.MsigApprove(ctx, msig, txid, prop, msig, big.Zero(), from, uint64(builtin2.MethodsMultisig.LockBalance), params) if err != nil { return err } @@ -1218,7 +1221,7 @@ var msigLockCancelCmd = &cli.Command{ return actErr } - msgCid, err := api.MsigCancel(ctx, msig, txid, msig, big.Zero(), from, uint64(builtin.MethodsMultisig.LockBalance), params) + msgCid, err := api.MsigCancel(ctx, msig, txid, msig, big.Zero(), from, uint64(builtin2.MethodsMultisig.LockBalance), params) if err != nil { return err } diff --git a/cli/state.go b/cli/state.go index 94ffa63fe..cb1c974a7 100644 --- a/cli/state.go +++ b/cli/state.go @@ -14,6 +14,8 @@ import ( "strings" "time" + "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/multiformats/go-multiaddr" "github.com/ipfs/go-cid" @@ -28,7 +30,6 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/exitcode" - "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/apibstore" diff --git a/cmd/lotus-pcr/main.go b/cmd/lotus-pcr/main.go index 36961a663..8acaa3c71 100644 --- a/cmd/lotus-pcr/main.go +++ b/cmd/lotus-pcr/main.go @@ -12,7 +12,9 @@ import ( "strconv" "time" - "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors/builtin" + builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" "github.com/filecoin-project/go-state-types/network" @@ -375,14 +377,14 @@ func (r *refunder) ProcessTipset(ctx context.Context, tipset *types.TipSet, refu continue } - if !a.IsStorageMinerActor() { + if !builtin.IsStorageMinerActor(a.Code) { continue } var messageMethod string switch m.Method { - case builtin.MethodsMiner.ProveCommitSector: + case builtin0.MethodsMiner.ProveCommitSector: if !r.proveCommitEnabled { continue } @@ -429,7 +431,7 @@ func (r *refunder) ProcessTipset(ctx context.Context, tipset *types.TipSet, refu } refundValue = collateral - case builtin.MethodsMiner.PreCommitSector: + case builtin0.MethodsMiner.PreCommitSector: if !r.preCommitEnabled { continue } diff --git a/cmd/lotus-shed/balances.go b/cmd/lotus-shed/balances.go index 1c89a00cf..fba6d7724 100644 --- a/cmd/lotus-shed/balances.go +++ b/cmd/lotus-shed/balances.go @@ -6,7 +6,7 @@ import ( "strconv" "github.com/docker/go-units" - lotusbuiltin "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/builtin/power" "github.com/filecoin-project/lotus/chain/actors/builtin/reward" @@ -97,7 +97,7 @@ var chainBalanceCmd = &cli.Command{ Type: string(act.Code.Hash()[2:]), } - if act.IsStorageMinerActor() { + if builtin.IsStorageMinerActor(act.Code) { pow, err := api.StateMinerPower(ctx, addr, tsk) if err != nil { return xerrors.Errorf("failed to get power: %w", err) @@ -198,7 +198,7 @@ var chainBalanceStateCmd = &cli.Command{ PreCommits: types.FIL(big.NewInt(0)), } - if minerInfo && act.IsStorageMinerActor() { + if minerInfo && builtin.IsStorageMinerActor(act.Code) { pow, _, _, err := stmgr.GetPowerRaw(ctx, sm, sroot, addr) if err != nil { return xerrors.Errorf("failed to get power: %w", err) @@ -322,7 +322,7 @@ var chainPledgeCmd = &cli.Command{ } var ( - powerSmoothed lotusbuiltin.FilterEstimate + powerSmoothed builtin.FilterEstimate pledgeCollateral abi.TokenAmount ) if act, err := state.GetActor(power.Address); err != nil { diff --git a/cmd/lotus-shed/genesis-verify.go b/cmd/lotus-shed/genesis-verify.go index da2c82359..9a47d6561 100644 --- a/cmd/lotus-shed/genesis-verify.go +++ b/cmd/lotus-shed/genesis-verify.go @@ -6,6 +6,8 @@ import ( "os" "sort" + "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/fatih/color" "github.com/ipfs/go-datastore" cbor "github.com/ipfs/go-ipld-cbor" @@ -95,14 +97,14 @@ var genesisVerifyCmd = &cli.Command{ if err := stree.ForEach(func(addr address.Address, act *types.Actor) error { switch { - case act.IsStorageMinerActor(): + case builtin.IsStorageMinerActor(act.Code): _, err := miner.Load(store, act) if err != nil { return xerrors.Errorf("miner actor: %w", err) } // TODO: actually verify something here? kminers[addr] = minerInfo{} - case act.IsMultisigActor(): + case builtin.IsMultisigActor(act.Code): st, err := multisig.Load(store, act) if err != nil { return xerrors.Errorf("multisig actor: %w", err) @@ -123,7 +125,7 @@ var genesisVerifyCmd = &cli.Command{ Threshold: threshold, } msigAddrs = append(msigAddrs, addr) - case act.IsAccountActor(): + case builtin.IsAccountActor(act.Code): st, err := account.Load(store, act) if err != nil { // TODO: magik6k: this _used_ to log instead of failing, why? diff --git a/cmd/lotus-shed/mempool-stats.go b/cmd/lotus-shed/mempool-stats.go index 165c01432..d70cd4b71 100644 --- a/cmd/lotus-shed/mempool-stats.go +++ b/cmd/lotus-shed/mempool-stats.go @@ -18,6 +18,7 @@ import ( "github.com/filecoin-project/go-address" lapi "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" ) @@ -122,7 +123,7 @@ var mpoolStatsCmd = &cli.Command{ return false, err } - ism := act.IsStorageMinerActor() + ism := builtin.IsStorageMinerActor(act.Code) mcache[addr] = ism return ism, nil } diff --git a/node/impl/full/gas.go b/node/impl/full/gas.go index f03807c80..c912c7a8c 100644 --- a/node/impl/full/gas.go +++ b/node/impl/full/gas.go @@ -6,6 +6,8 @@ import ( "math/rand" "sort" + "github.com/filecoin-project/lotus/chain/actors/builtin" + "go.uber.org/fx" "golang.org/x/xerrors" @@ -182,7 +184,7 @@ func (a *GasAPI) GasEstimateGasLimit(ctx context.Context, msgIn *types.Message, return res.MsgRct.GasUsed, nil } - if !act.IsPaymentChannelActor() { + if !builtin.IsPaymentChannelActor(act.Code) { return res.MsgRct.GasUsed, nil } if msgIn.Method != builtin0.MethodsPaych.Collect { From 724306c1104ccbb0ffa49d16ddbaf4705e393c17 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 30 Sep 2020 09:23:04 -0700 Subject: [PATCH 033/115] update specs-actors --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index a2a2ab2ba..2cf9a81fe 100644 --- a/go.mod +++ b/go.mod @@ -37,8 +37,8 @@ require ( github.com/filecoin-project/go-statemachine v0.0.0-20200813232949-df9b130df370 github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b - github.com/filecoin-project/specs-actors v0.9.12-0.20200928180918-488a087c5add - github.com/filecoin-project/specs-actors/v2 v2.0.0-20200929004132-ea2d270c9f47 + github.com/filecoin-project/specs-actors v0.9.12-0.20200930015636-a6848b2dd741 + github.com/filecoin-project/specs-actors/v2 v2.0.0-20200930035834-7115a78cb9a1 github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796 github.com/filecoin-project/test-vectors/schema v0.0.3 github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 diff --git a/go.sum b/go.sum index 7ec9936e9..05960060e 100644 --- a/go.sum +++ b/go.sum @@ -273,10 +273,10 @@ github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/ github.com/filecoin-project/specs-actors v0.9.4/go.mod h1:BStZQzx5x7TmCkLv0Bpa07U6cPKol6fd3w9KjMPZ6Z4= github.com/filecoin-project/specs-actors v0.9.7/go.mod h1:wM2z+kwqYgXn5Z7scV1YHLyd1Q1cy0R8HfTIWQ0BFGU= github.com/filecoin-project/specs-actors v0.9.9/go.mod h1:czlvLQGEX0fjLLfdNHD7xLymy6L3n7aQzRWzsYGf+ys= -github.com/filecoin-project/specs-actors v0.9.12-0.20200928180918-488a087c5add h1:iXQOxr8uSyZ/qnTlOZf7ALp0io+jwLxmuWsNAk/YdoQ= -github.com/filecoin-project/specs-actors v0.9.12-0.20200928180918-488a087c5add/go.mod h1:TS1AW/7LbG+615j4NsjMK1qlpAwaFsG9w0V2tg2gSao= -github.com/filecoin-project/specs-actors/v2 v2.0.0-20200929004132-ea2d270c9f47 h1:bt/CdGbF1Rq5rDVaMV+XWfHBRCxN7IxZfw6lC1v6KQM= -github.com/filecoin-project/specs-actors/v2 v2.0.0-20200929004132-ea2d270c9f47/go.mod h1:/2Zra1BhLtpRywUhm++QP+3I5Ir+hBk/W24TpYjj43E= +github.com/filecoin-project/specs-actors v0.9.12-0.20200930015636-a6848b2dd741 h1:pqAfjHE+yLFj1mvtx68S3HKdd9LSy6Byziz2qRNh3fA= +github.com/filecoin-project/specs-actors v0.9.12-0.20200930015636-a6848b2dd741/go.mod h1:TS1AW/7LbG+615j4NsjMK1qlpAwaFsG9w0V2tg2gSao= +github.com/filecoin-project/specs-actors/v2 v2.0.0-20200930035834-7115a78cb9a1 h1:lNMXodbyskP3ZfTWL/t6M4NYI0hhcZQ2GAJCIVK8Y/E= +github.com/filecoin-project/specs-actors/v2 v2.0.0-20200930035834-7115a78cb9a1/go.mod h1:/2Zra1BhLtpRywUhm++QP+3I5Ir+hBk/W24TpYjj43E= github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796 h1:dJsTPWpG2pcTeojO2pyn0c6l+x/3MZYCBgo/9d11JEk= github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796/go.mod h1:nJRRM7Aa9XVvygr3W9k6xGF46RWzr2zxF/iGoAIfA/g= github.com/filecoin-project/test-vectors/schema v0.0.3 h1:1zuBo25B3016inbygYLgYFdpJ2m1BDTbAOCgABRleiU= From 23b729a0569a2b14d4de799d00fc2ca4b17789e5 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 30 Sep 2020 09:35:42 -0700 Subject: [PATCH 034/115] remove proof parameter from payment channels It never worked properly, and will be removed in actors v2. --- paychmgr/manager.go | 23 +++++++-- paychmgr/paych.go | 74 ++++----------------------- paychmgr/paych_test.go | 111 ++++------------------------------------- paychmgr/store.go | 2 +- 4 files changed, 42 insertions(+), 168 deletions(-) diff --git a/paychmgr/manager.go b/paychmgr/manager.go index 7ef1264c5..1b2acfd2f 100644 --- a/paychmgr/manager.go +++ b/paychmgr/manager.go @@ -2,6 +2,7 @@ package paychmgr import ( "context" + "errors" "sync" "github.com/ipfs/go-cid" @@ -24,6 +25,8 @@ import ( var log = logging.Logger("paych") +var errProofNotSupported = errors.New("payment channel proof parameter is not supported") + // PaychAPI is used by dependency injection to pass the consituent APIs to NewManager() type PaychAPI struct { fx.In @@ -245,34 +248,43 @@ func (pm *Manager) CheckVoucherValid(ctx context.Context, ch address.Address, sv // CheckVoucherSpendable checks if the given voucher is currently spendable func (pm *Manager) CheckVoucherSpendable(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, secret []byte, proof []byte) (bool, error) { + if len(proof) > 0 { + return false, errProofNotSupported + } ca, err := pm.accessorByAddress(ch) if err != nil { return false, err } - return ca.checkVoucherSpendable(ctx, ch, sv, secret, proof) + return ca.checkVoucherSpendable(ctx, ch, sv, secret) } // AddVoucherOutbound adds a voucher for an outbound channel. // Returns an error if the channel is not already in the store. func (pm *Manager) AddVoucherOutbound(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, proof []byte, minDelta types.BigInt) (types.BigInt, error) { + if len(proof) > 0 { + return types.NewInt(0), errProofNotSupported + } ca, err := pm.accessorByAddress(ch) if err != nil { return types.NewInt(0), err } - return ca.addVoucher(ctx, ch, sv, proof, minDelta) + return ca.addVoucher(ctx, ch, sv, minDelta) } // AddVoucherInbound adds a voucher for an inbound channel. // If the channel is not in the store, fetches the channel from state (and checks that // the channel To address is owned by the wallet). func (pm *Manager) AddVoucherInbound(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, proof []byte, minDelta types.BigInt) (types.BigInt, error) { + if len(proof) > 0 { + return types.NewInt(0), errProofNotSupported + } // Get an accessor for the channel, creating it from state if necessary ca, err := pm.inboundChannelAccessor(ctx, ch) if err != nil { return types.BigInt{}, err } - return ca.addVoucher(ctx, ch, sv, proof, minDelta) + return ca.addVoucher(ctx, ch, sv, minDelta) } // inboundChannelAccessor gets an accessor for the given channel. The channel @@ -336,11 +348,14 @@ func (pm *Manager) trackInboundChannel(ctx context.Context, ch address.Address) } func (pm *Manager) SubmitVoucher(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, secret []byte, proof []byte) (cid.Cid, error) { + if len(proof) > 0 { + return cid.Undef, errProofNotSupported + } ca, err := pm.accessorByAddress(ch) if err != nil { return cid.Undef, err } - return ca.submitVoucher(ctx, ch, sv, secret, proof) + return ca.submitVoucher(ctx, ch, sv, secret) } func (pm *Manager) AllocateLane(ch address.Address) (uint64, error) { diff --git a/paychmgr/paych.go b/paychmgr/paych.go index ba96c5e40..056140653 100644 --- a/paychmgr/paych.go +++ b/paychmgr/paych.go @@ -1,7 +1,6 @@ package paychmgr import ( - "bytes" "context" "fmt" @@ -133,7 +132,7 @@ func (ca *channelAccessor) createVoucher(ctx context.Context, ch address.Address sv.Signature = sig // Store the voucher - if _, err := ca.addVoucherUnlocked(ctx, ch, sv, nil, types.NewInt(0)); err != nil { + if _, err := ca.addVoucherUnlocked(ctx, ch, sv, types.NewInt(0)); err != nil { // If there are not enough funds in the channel to cover the voucher, // return a voucher create result with the shortfall var ife insufficientFundsErr @@ -272,7 +271,7 @@ func (ca *channelAccessor) checkVoucherValidUnlocked(ctx context.Context, ch add return laneStates, nil } -func (ca *channelAccessor) checkVoucherSpendable(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, secret []byte, proof []byte) (bool, error) { +func (ca *channelAccessor) checkVoucherSpendable(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, secret []byte) (bool, error) { ca.lk.Lock() defer ca.lk.Unlock() @@ -295,26 +294,9 @@ func (ca *channelAccessor) checkVoucherSpendable(ctx context.Context, ch address return false, nil } - // If proof is needed and wasn't supplied as a parameter, get it from the - // datastore - if sv.Extra != nil && proof == nil { - vi, err := ci.infoForVoucher(sv) - if err != nil { - return false, err - } - - if vi.Proof != nil { - log.Info("CheckVoucherSpendable: using stored proof") - proof = vi.Proof - } else { - log.Warn("CheckVoucherSpendable: nil proof for voucher with validation") - } - } - enc, err := actors.SerializeParams(&paych0.UpdateChannelStateParams{ Sv: *sv, Secret: secret, - Proof: proof, }) if err != nil { return false, err @@ -346,44 +328,31 @@ func (ca *channelAccessor) getPaychRecipient(ctx context.Context, ch address.Add return state.To() } -func (ca *channelAccessor) addVoucher(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, proof []byte, minDelta types.BigInt) (types.BigInt, error) { +func (ca *channelAccessor) addVoucher(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, minDelta types.BigInt) (types.BigInt, error) { ca.lk.Lock() defer ca.lk.Unlock() - return ca.addVoucherUnlocked(ctx, ch, sv, proof, minDelta) + return ca.addVoucherUnlocked(ctx, ch, sv, minDelta) } -func (ca *channelAccessor) addVoucherUnlocked(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, proof []byte, minDelta types.BigInt) (types.BigInt, error) { +func (ca *channelAccessor) addVoucherUnlocked(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, minDelta types.BigInt) (types.BigInt, error) { ci, err := ca.store.ByAddress(ch) if err != nil { return types.BigInt{}, err } // Check if the voucher has already been added - for i, v := range ci.Vouchers { + for _, v := range ci.Vouchers { eq, err := cborutil.Equals(sv, v.Voucher) if err != nil { return types.BigInt{}, err } - if !eq { - continue + if eq { + // Ignore the duplicate voucher. + log.Warnf("AddVoucher: voucher re-added") + return types.NewInt(0), nil } - // This is a duplicate voucher. - // Update the proof on the existing voucher - if len(proof) > 0 && !bytes.Equal(v.Proof, proof) { - log.Warnf("AddVoucher: adding proof to stored voucher") - ci.Vouchers[i] = &VoucherInfo{ - Voucher: v.Voucher, - Proof: proof, - } - - return types.NewInt(0), ca.store.putChannelInfo(ci) - } - - // Otherwise just ignore the duplicate voucher - log.Warnf("AddVoucher: voucher re-added with matching proof") - return types.NewInt(0), nil } // Check voucher validity @@ -410,7 +379,6 @@ func (ca *channelAccessor) addVoucherUnlocked(ctx context.Context, ch address.Ad ci.Vouchers = append(ci.Vouchers, &VoucherInfo{ Voucher: sv, - Proof: proof, }) if ci.NextLane <= sv.Lane { @@ -420,7 +388,7 @@ func (ca *channelAccessor) addVoucherUnlocked(ctx context.Context, ch address.Ad return delta, ca.store.putChannelInfo(ci) } -func (ca *channelAccessor) submitVoucher(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, secret []byte, proof []byte) (cid.Cid, error) { +func (ca *channelAccessor) submitVoucher(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, secret []byte) (cid.Cid, error) { ca.lk.Lock() defer ca.lk.Unlock() @@ -429,21 +397,6 @@ func (ca *channelAccessor) submitVoucher(ctx context.Context, ch address.Address return cid.Undef, err } - // If voucher needs proof, and none was supplied, check datastore for proof - if sv.Extra != nil && proof == nil { - vi, err := ci.infoForVoucher(sv) - if err != nil { - return cid.Undef, err - } - - if vi.Proof != nil { - log.Info("SubmitVoucher: using stored proof") - proof = vi.Proof - } else { - log.Warn("SubmitVoucher: nil proof for voucher with validation") - } - } - has, err := ci.hasVoucher(sv) if err != nil { return cid.Undef, err @@ -462,13 +415,9 @@ func (ca *channelAccessor) submitVoucher(ctx context.Context, ch address.Address } // TODO: ActorUpgrade - // The "proof" field is going away. We will need to abstract over the - // network version here. - // Alternatively, we'd need to support the "old" method on-chain. enc, err := actors.SerializeParams(&paych0.UpdateChannelStateParams{ Sv: *sv, Secret: secret, - Proof: proof, }) if err != nil { return cid.Undef, err @@ -492,7 +441,6 @@ func (ca *channelAccessor) submitVoucher(ctx context.Context, ch address.Address // Add the voucher to the channel ci.Vouchers = append(ci.Vouchers, &VoucherInfo{ Voucher: sv, - Proof: proof, }) } diff --git a/paychmgr/paych_test.go b/paychmgr/paych_test.go index b27b1e540..ff77f5512 100644 --- a/paychmgr/paych_test.go +++ b/paychmgr/paych_test.go @@ -555,53 +555,6 @@ func TestAllocateLaneWithExistingLaneState(t *testing.T) { require.EqualValues(t, 3, lane) } -func TestAddVoucherProof(t *testing.T) { - ctx := context.Background() - - // Set up a manager with a single payment channel - s := testSetupMgrWithChannel(ctx, t) - - nonce := uint64(1) - voucherAmount := big.NewInt(1) - minDelta := big.NewInt(0) - voucherAmount = big.NewInt(2) - voucherLane := uint64(1) - - // Add a voucher with no proof - var proof []byte - sv := createTestVoucher(t, s.ch, voucherLane, nonce, voucherAmount, s.fromKeyPrivate) - _, err := s.mgr.AddVoucherOutbound(ctx, s.ch, sv, nil, minDelta) - require.NoError(t, err) - - // Expect one voucher with no proof - ci, err := s.mgr.GetChannelInfo(s.ch) - require.NoError(t, err) - require.Len(t, ci.Vouchers, 1) - require.Len(t, ci.Vouchers[0].Proof, 0) - - // Add same voucher with no proof - voucherLane = uint64(1) - _, err = s.mgr.AddVoucherOutbound(ctx, s.ch, sv, proof, minDelta) - require.NoError(t, err) - - // Expect one voucher with no proof - ci, err = s.mgr.GetChannelInfo(s.ch) - require.NoError(t, err) - require.Len(t, ci.Vouchers, 1) - require.Len(t, ci.Vouchers[0].Proof, 0) - - // Add same voucher with proof - proof = []byte{1} - _, err = s.mgr.AddVoucherOutbound(ctx, s.ch, sv, proof, minDelta) - require.NoError(t, err) - - // Should add proof to existing voucher - ci, err = s.mgr.GetChannelInfo(s.ch) - require.NoError(t, err) - require.Len(t, ci.Vouchers, 1) - require.Len(t, ci.Vouchers[0].Proof, 1) -} - func TestAddVoucherInboundWalletKey(t *testing.T) { ctx := context.Background() @@ -748,10 +701,9 @@ func TestCheckSpendable(t *testing.T) { voucherAmount := big.NewInt(1) voucher := createTestVoucherWithExtra(t, s.ch, voucherLane, nonce, voucherAmount, s.fromKeyPrivate) - // Add voucher with proof + // Add voucher minDelta := big.NewInt(0) - proof := []byte("proof") - _, err := s.mgr.AddVoucherInbound(ctx, s.ch, voucher, proof, minDelta) + _, err := s.mgr.AddVoucherInbound(ctx, s.ch, voucher, nil, minDelta) require.NoError(t, err) // Return success exit code from VM call, which indicates that voucher is @@ -765,33 +717,17 @@ func TestCheckSpendable(t *testing.T) { // Check that spendable is true secret := []byte("secret") - otherProof := []byte("other proof") - spendable, err := s.mgr.CheckVoucherSpendable(ctx, s.ch, voucher, secret, otherProof) + spendable, err := s.mgr.CheckVoucherSpendable(ctx, s.ch, voucher, secret, nil) require.NoError(t, err) require.True(t, spendable) - // Check that the secret and proof were passed through correctly + // Check that the secret was passed through correctly lastCall := s.mock.getLastCall() var p paych0.UpdateChannelStateParams err = p.UnmarshalCBOR(bytes.NewReader(lastCall.Params)) require.NoError(t, err) - require.Equal(t, otherProof, p.Proof) require.Equal(t, secret, p.Secret) - // Check that if no proof is supplied, the proof supplied to add voucher - // above is used - secret2 := []byte("secret2") - spendable, err = s.mgr.CheckVoucherSpendable(ctx, s.ch, voucher, secret2, nil) - require.NoError(t, err) - require.True(t, spendable) - - lastCall = s.mock.getLastCall() - var p2 paych0.UpdateChannelStateParams - err = p2.UnmarshalCBOR(bytes.NewReader(lastCall.Params)) - require.NoError(t, err) - require.Equal(t, proof, p2.Proof) - require.Equal(t, secret2, p2.Secret) - // Check that if VM call returns non-success exit code, spendable is false s.mock.setCallResponse(&api.InvocResult{ MsgRct: &types.MessageReceipt{ @@ -829,73 +765,48 @@ func TestSubmitVoucher(t *testing.T) { voucherAmount := big.NewInt(1) voucher := createTestVoucherWithExtra(t, s.ch, voucherLane, nonce, voucherAmount, s.fromKeyPrivate) - // Add voucher with proof + // Add voucher minDelta := big.NewInt(0) - addVoucherProof := []byte("proof") - _, err := s.mgr.AddVoucherInbound(ctx, s.ch, voucher, addVoucherProof, minDelta) + _, err := s.mgr.AddVoucherInbound(ctx, s.ch, voucher, nil, minDelta) require.NoError(t, err) // Submit voucher secret := []byte("secret") - submitProof := []byte("submit proof") - submitCid, err := s.mgr.SubmitVoucher(ctx, s.ch, voucher, secret, submitProof) + submitCid, err := s.mgr.SubmitVoucher(ctx, s.ch, voucher, secret, nil) require.NoError(t, err) - // Check that the secret and proof were passed through correctly + // Check that the secret was passed through correctly msg := s.mock.pushedMessages(submitCid) var p paych0.UpdateChannelStateParams err = p.UnmarshalCBOR(bytes.NewReader(msg.Message.Params)) require.NoError(t, err) - require.Equal(t, submitProof, p.Proof) require.Equal(t, secret, p.Secret) - // Check that if no proof is supplied to submit voucher, the proof supplied - // to add voucher is used - nonce++ - voucherAmount = big.NewInt(2) - addVoucherProof2 := []byte("proof2") - secret2 := []byte("secret2") - voucher = createTestVoucherWithExtra(t, s.ch, voucherLane, nonce, voucherAmount, s.fromKeyPrivate) - _, err = s.mgr.AddVoucherInbound(ctx, s.ch, voucher, addVoucherProof2, minDelta) - require.NoError(t, err) - - submitCid, err = s.mgr.SubmitVoucher(ctx, s.ch, voucher, secret2, nil) - require.NoError(t, err) - - msg = s.mock.pushedMessages(submitCid) - var p2 paych0.UpdateChannelStateParams - err = p2.UnmarshalCBOR(bytes.NewReader(msg.Message.Params)) - require.NoError(t, err) - require.Equal(t, addVoucherProof2, p2.Proof) - require.Equal(t, secret2, p2.Secret) - // Submit a voucher without first adding it nonce++ voucherAmount = big.NewInt(3) secret3 := []byte("secret2") - proof3 := []byte("proof3") voucher = createTestVoucherWithExtra(t, s.ch, voucherLane, nonce, voucherAmount, s.fromKeyPrivate) - submitCid, err = s.mgr.SubmitVoucher(ctx, s.ch, voucher, secret3, proof3) + submitCid, err = s.mgr.SubmitVoucher(ctx, s.ch, voucher, secret3, nil) require.NoError(t, err) msg = s.mock.pushedMessages(submitCid) var p3 paych0.UpdateChannelStateParams err = p3.UnmarshalCBOR(bytes.NewReader(msg.Message.Params)) require.NoError(t, err) - require.Equal(t, proof3, p3.Proof) require.Equal(t, secret3, p3.Secret) // Verify that vouchers are marked as submitted vis, err := s.mgr.ListVouchers(ctx, s.ch) require.NoError(t, err) - require.Len(t, vis, 3) + require.Len(t, vis, 2) for _, vi := range vis { require.True(t, vi.Submitted) } // Attempting to submit the same voucher again should fail - _, err = s.mgr.SubmitVoucher(ctx, s.ch, voucher, secret2, nil) + _, err = s.mgr.SubmitVoucher(ctx, s.ch, voucher, secret3, nil) require.Error(t, err) } diff --git a/paychmgr/store.go b/paychmgr/store.go index dbd663832..a17ad1fcd 100644 --- a/paychmgr/store.go +++ b/paychmgr/store.go @@ -49,7 +49,7 @@ const ( type VoucherInfo struct { Voucher *paych.SignedVoucher - Proof []byte + Proof []byte // ignored Submitted bool } From 4c60d7b5ceb341feb3d66371bd34310b12f49769 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 30 Sep 2020 10:04:10 -0700 Subject: [PATCH 035/115] abstract over paych messages --- chain/actors/builtin/paych/message.go | 28 +++++++ chain/actors/builtin/paych/message0.go | 74 +++++++++++++++++++ chain/actors/builtin/paych/message2.go | 74 +++++++++++++++++++ .../builtin/paych/{paych.go => state.go} | 0 .../actors/builtin/paych/{v0.go => state0.go} | 0 .../actors/builtin/paych/{v2.go => state2.go} | 0 paychmgr/manager.go | 2 + paychmgr/mock_test.go | 6 ++ paychmgr/paych.go | 68 ++++++++--------- paychmgr/paychget_test.go | 6 +- paychmgr/simple.go | 36 +++------ 11 files changed, 234 insertions(+), 60 deletions(-) create mode 100644 chain/actors/builtin/paych/message.go create mode 100644 chain/actors/builtin/paych/message0.go create mode 100644 chain/actors/builtin/paych/message2.go rename chain/actors/builtin/paych/{paych.go => state.go} (100%) rename chain/actors/builtin/paych/{v0.go => state0.go} (100%) rename chain/actors/builtin/paych/{v2.go => state2.go} (100%) diff --git a/chain/actors/builtin/paych/message.go b/chain/actors/builtin/paych/message.go new file mode 100644 index 000000000..d19f0c38f --- /dev/null +++ b/chain/actors/builtin/paych/message.go @@ -0,0 +1,28 @@ +package paych + +import ( + "fmt" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/types" +) + +func Message(version actors.Version) MessageBuilder { + switch version { + case actors.Version0: + return message0{} + case actors.Version2: + return message2{} + default: + panic(fmt.Sprintf("unsupported actors version: %d", version)) + } +} + +type MessageBuilder interface { + Create(from, to address.Address, initialAmount abi.TokenAmount) (*types.Message, error) + Update(from, paych address.Address, voucher *SignedVoucher, secret []byte) (*types.Message, error) + Settle(from, paych address.Address) (*types.Message, error) + Collect(from, paych address.Address) (*types.Message, error) +} diff --git a/chain/actors/builtin/paych/message0.go b/chain/actors/builtin/paych/message0.go new file mode 100644 index 000000000..0e7bbff92 --- /dev/null +++ b/chain/actors/builtin/paych/message0.go @@ -0,0 +1,74 @@ +package paych + +import ( + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + + builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + init0 "github.com/filecoin-project/specs-actors/actors/builtin/init" + paych0 "github.com/filecoin-project/specs-actors/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 message0 struct{} + +func (message0) Create(from, to address.Address, initialAmount abi.TokenAmount) (*types.Message, error) { + params, aerr := actors.SerializeParams(&paych0.ConstructorParams{From: from, To: to}) + if aerr != nil { + return nil, aerr + } + enc, aerr := actors.SerializeParams(&init0.ExecParams{ + CodeCID: builtin0.PaymentChannelActorCodeID, + ConstructorParams: params, + }) + if aerr != nil { + return nil, aerr + } + + return &types.Message{ + To: init_.Address, + From: from, + Value: initialAmount, + Method: builtin0.MethodsInit.Exec, + Params: enc, + }, nil +} + +func (message0) Update(from, paych address.Address, sv *SignedVoucher, secret []byte) (*types.Message, error) { + params, aerr := actors.SerializeParams(&paych0.UpdateChannelStateParams{ + Sv: *sv, + Secret: secret, + }) + if aerr != nil { + return nil, aerr + } + + return &types.Message{ + To: paych, + From: from, + Value: abi.NewTokenAmount(0), + Method: builtin0.MethodsPaych.UpdateChannelState, + Params: params, + }, nil +} + +func (message0) Settle(from, paych address.Address) (*types.Message, error) { + return &types.Message{ + To: paych, + From: from, + Value: abi.NewTokenAmount(0), + Method: builtin0.MethodsPaych.Settle, + }, nil +} + +func (message0) Collect(from, paych address.Address) (*types.Message, error) { + return &types.Message{ + To: paych, + From: from, + Value: abi.NewTokenAmount(0), + Method: builtin0.MethodsPaych.Collect, + }, nil +} diff --git a/chain/actors/builtin/paych/message2.go b/chain/actors/builtin/paych/message2.go new file mode 100644 index 000000000..94538bc49 --- /dev/null +++ b/chain/actors/builtin/paych/message2.go @@ -0,0 +1,74 @@ +package paych + +import ( + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + + builtin2 "github.com/filecoin-project/specs-actors/actors/builtin" + init2 "github.com/filecoin-project/specs-actors/actors/builtin/init" + paych2 "github.com/filecoin-project/specs-actors/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 message2 struct{} + +func (message2) Create(from, to address.Address, initialAmount abi.TokenAmount) (*types.Message, error) { + params, aerr := actors.SerializeParams(&paych2.ConstructorParams{From: from, To: to}) + if aerr != nil { + return nil, aerr + } + enc, aerr := actors.SerializeParams(&init2.ExecParams{ + CodeCID: builtin2.PaymentChannelActorCodeID, + ConstructorParams: params, + }) + if aerr != nil { + return nil, aerr + } + + return &types.Message{ + To: init_.Address, + From: from, + Value: initialAmount, + Method: builtin2.MethodsInit.Exec, + Params: enc, + }, nil +} + +func (message2) Update(from, paych address.Address, sv *SignedVoucher, secret []byte) (*types.Message, error) { + params, aerr := actors.SerializeParams(&paych2.UpdateChannelStateParams{ + Sv: *sv, + Secret: secret, + }) + if aerr != nil { + return nil, aerr + } + + return &types.Message{ + To: paych, + From: from, + Value: abi.NewTokenAmount(0), + Method: builtin2.MethodsPaych.UpdateChannelState, + Params: params, + }, nil +} + +func (message2) Settle(from, paych address.Address) (*types.Message, error) { + return &types.Message{ + To: paych, + From: from, + Value: abi.NewTokenAmount(0), + Method: builtin2.MethodsPaych.Settle, + }, nil +} + +func (message2) Collect(from, paych address.Address) (*types.Message, error) { + return &types.Message{ + To: paych, + From: from, + Value: abi.NewTokenAmount(0), + Method: builtin2.MethodsPaych.Collect, + }, nil +} diff --git a/chain/actors/builtin/paych/paych.go b/chain/actors/builtin/paych/state.go similarity index 100% rename from chain/actors/builtin/paych/paych.go rename to chain/actors/builtin/paych/state.go diff --git a/chain/actors/builtin/paych/v0.go b/chain/actors/builtin/paych/state0.go similarity index 100% rename from chain/actors/builtin/paych/v0.go rename to chain/actors/builtin/paych/state0.go diff --git a/chain/actors/builtin/paych/v2.go b/chain/actors/builtin/paych/state2.go similarity index 100% rename from chain/actors/builtin/paych/v2.go rename to chain/actors/builtin/paych/state2.go diff --git a/paychmgr/manager.go b/paychmgr/manager.go index 1b2acfd2f..f2fc190c7 100644 --- a/paychmgr/manager.go +++ b/paychmgr/manager.go @@ -13,6 +13,7 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/crypto" + "github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/actors/adt" @@ -49,6 +50,7 @@ type paychAPI interface { MpoolPushMessage(ctx context.Context, msg *types.Message, maxFee *api.MessageSendSpec) (*types.SignedMessage, error) WalletHas(ctx context.Context, addr address.Address) (bool, error) WalletSign(ctx context.Context, k address.Address, msg []byte) (*crypto.Signature, error) + StateNetworkVersion(context.Context, types.TipSetKey) (network.Version, error) } // managerAPI defines all methods needed by the manager diff --git a/paychmgr/mock_test.go b/paychmgr/mock_test.go index c761221d2..3393a3072 100644 --- a/paychmgr/mock_test.go +++ b/paychmgr/mock_test.go @@ -9,8 +9,10 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/crypto" + "github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors/builtin/paych" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/lib/sigs" @@ -241,3 +243,7 @@ func (pchapi *mockPaychAPI) addSigningKey(key []byte) { pchapi.signingKey = key } + +func (pchapi *mockPaychAPI) StateNetworkVersion(ctx context.Context, tsk types.TipSetKey) (network.Version, error) { + return build.NewestNetworkVersion, nil +} diff --git a/paychmgr/paych.go b/paychmgr/paych.go index 056140653..96ba43543 100644 --- a/paychmgr/paych.go +++ b/paychmgr/paych.go @@ -10,8 +10,6 @@ import ( "github.com/filecoin-project/go-address" cborutil "github.com/filecoin-project/go-cbor-util" "github.com/filecoin-project/go-state-types/big" - "github.com/filecoin-project/specs-actors/actors/builtin" - paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/actors" @@ -84,6 +82,15 @@ func newChannelAccessor(pm *Manager, from address.Address, to address.Address) * } } +func (ca *channelAccessor) messageBuilder(ctx context.Context) (paych.MessageBuilder, error) { + nwVersion, err := ca.api.StateNetworkVersion(ctx, types.EmptyTSK) + if err != nil { + return nil, err + } + + return paych.Message(actors.VersionForNetwork(nwVersion)), nil +} + func (ca *channelAccessor) getChannelInfo(addr address.Address) (*ChannelInfo, error) { ca.lk.Lock() defer ca.lk.Unlock() @@ -294,20 +301,17 @@ func (ca *channelAccessor) checkVoucherSpendable(ctx context.Context, ch address return false, nil } - enc, err := actors.SerializeParams(&paych0.UpdateChannelStateParams{ - Sv: *sv, - Secret: secret, - }) + mb, err := ca.messageBuilder(ctx) if err != nil { return false, err } - ret, err := ca.api.Call(ctx, &types.Message{ - From: recipient, - To: ch, - Method: builtin.MethodsPaych.UpdateChannelState, - Params: enc, - }, nil) + mes, err := mb.Update(recipient, ch, sv, secret) + if err != nil { + return false, err + } + + ret, err := ca.api.Call(ctx, mes, nil) if err != nil { return false, err } @@ -414,21 +418,14 @@ func (ca *channelAccessor) submitVoucher(ctx context.Context, ch address.Address } } - // TODO: ActorUpgrade - enc, err := actors.SerializeParams(&paych0.UpdateChannelStateParams{ - Sv: *sv, - Secret: secret, - }) + mb, err := ca.messageBuilder(ctx) if err != nil { return cid.Undef, err } - msg := &types.Message{ - From: ci.Control, - To: ch, - Value: types.NewInt(0), - Method: builtin.MethodsPaych.UpdateChannelState, - Params: enc, + msg, err := mb.Update(ci.Control, ch, sv, secret) + if err != nil { + return cid.Undef, err } smsg, err := ca.api.MpoolPushMessage(ctx, msg, nil) @@ -577,11 +574,13 @@ func (ca *channelAccessor) settle(ctx context.Context, ch address.Address) (cid. return cid.Undef, err } - msg := &types.Message{ - To: ch, - From: ci.Control, - Value: types.NewInt(0), - Method: builtin.MethodsPaych.Settle, + mb, err := ca.messageBuilder(ctx) + if err != nil { + return cid.Undef, err + } + msg, err := mb.Settle(ci.Control, ch) + if err != nil { + return cid.Undef, err } smgs, err := ca.api.MpoolPushMessage(ctx, msg, nil) if err != nil { @@ -606,11 +605,14 @@ func (ca *channelAccessor) collect(ctx context.Context, ch address.Address) (cid return cid.Undef, err } - msg := &types.Message{ - To: ch, - From: ci.Control, - Value: types.NewInt(0), - Method: builtin.MethodsPaych.Collect, + mb, err := ca.messageBuilder(ctx) + if err != nil { + return cid.Undef, err + } + + msg, err := mb.Collect(ci.Control, ch) + if err != nil { + return cid.Undef, err } smsg, err := ca.api.MpoolPushMessage(ctx, msg, nil) diff --git a/paychmgr/paychget_test.go b/paychmgr/paychget_test.go index 430e66c67..28e2ac7e3 100644 --- a/paychmgr/paychget_test.go +++ b/paychmgr/paychget_test.go @@ -15,9 +15,9 @@ import ( "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/specs-actors/actors/builtin" - init_ "github.com/filecoin-project/specs-actors/actors/builtin/init" - tutils "github.com/filecoin-project/specs-actors/support/testing" + "github.com/filecoin-project/specs-actors/v2/actors/builtin" + init_ "github.com/filecoin-project/specs-actors/v2/actors/builtin/init" + tutils "github.com/filecoin-project/specs-actors/v2/support/testing" lotusinit "github.com/filecoin-project/lotus/chain/actors/builtin/init" "github.com/filecoin-project/lotus/chain/actors/builtin/paych" diff --git a/paychmgr/simple.go b/paychmgr/simple.go index d49ccafe6..38804b7ea 100644 --- a/paychmgr/simple.go +++ b/paychmgr/simple.go @@ -12,14 +12,11 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/big" - "github.com/filecoin-project/specs-actors/actors/builtin" - init0 "github.com/filecoin-project/specs-actors/actors/builtin/init" - paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych" + + init2 "github.com/filecoin-project/specs-actors/actors/builtin/init" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/lotus/chain/actors" - lotusinit "github.com/filecoin-project/lotus/chain/actors/builtin/init" "github.com/filecoin-project/lotus/chain/types" ) @@ -387,25 +384,13 @@ func (ca *channelAccessor) processTask(ctx context.Context, amt types.BigInt) *p // createPaych sends a message to create the channel and returns the message cid func (ca *channelAccessor) createPaych(ctx context.Context, amt types.BigInt) (cid.Cid, error) { - params, aerr := actors.SerializeParams(&paych0.ConstructorParams{From: ca.from, To: ca.to}) - if aerr != nil { - return cid.Undef, aerr + mb, err := ca.messageBuilder(ctx) + if err != nil { + return cid.Undef, err } - - enc, aerr := actors.SerializeParams(&init0.ExecParams{ - CodeCID: builtin.PaymentChannelActorCodeID, - ConstructorParams: params, - }) - if aerr != nil { - return cid.Undef, aerr - } - - msg := &types.Message{ - To: lotusinit.Address, - From: ca.from, - Value: amt, - Method: builtin.MethodsInit.Exec, - Params: enc, + msg, err := mb.Create(ca.from, ca.to, amt) + if err != nil { + return cid.Undef, err } smsg, err := ca.api.MpoolPushMessage(ctx, msg, nil) @@ -457,7 +442,10 @@ func (ca *channelAccessor) waitPaychCreateMsg(channelID string, mcid cid.Cid) er return err } - var decodedReturn init0.ExecReturn + // TODO: ActorUpgrade abstract over this. + // This "works" because it hasn't changed from v0 to v2, but we still + // need an abstraction here. + var decodedReturn init2.ExecReturn err = decodedReturn.UnmarshalCBOR(bytes.NewReader(mwait.Receipt.Return)) if err != nil { log.Error(err) From 5253c0d959ab16b4275f7f5a0ad702090c5430d2 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 30 Sep 2020 10:11:48 -0700 Subject: [PATCH 036/115] fix: import the correct v2 methods --- chain/stmgr/utils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chain/stmgr/utils.go b/chain/stmgr/utils.go index 6ed94775b..98f6bc5ac 100644 --- a/chain/stmgr/utils.go +++ b/chain/stmgr/utils.go @@ -21,8 +21,8 @@ import ( builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" exported0 "github.com/filecoin-project/specs-actors/actors/builtin/exported" - exported2 "github.com/filecoin-project/specs-actors/actors/builtin/exported" proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof" + exported2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/exported" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" From 2e9915ac28e803763462dc2d9aef1bf905a05b3a Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 30 Sep 2020 10:58:34 -0700 Subject: [PATCH 037/115] move common from message param into message builder constructor --- chain/actors/builtin/paych/message.go | 14 +++++++------- chain/actors/builtin/paych/message0.go | 20 ++++++++++---------- chain/actors/builtin/paych/message2.go | 20 ++++++++++---------- paychmgr/paych.go | 20 ++++++++++---------- paychmgr/simple.go | 4 ++-- 5 files changed, 39 insertions(+), 39 deletions(-) diff --git a/chain/actors/builtin/paych/message.go b/chain/actors/builtin/paych/message.go index d19f0c38f..23b360394 100644 --- a/chain/actors/builtin/paych/message.go +++ b/chain/actors/builtin/paych/message.go @@ -9,20 +9,20 @@ import ( "github.com/filecoin-project/lotus/chain/types" ) -func Message(version actors.Version) MessageBuilder { +func Message(version actors.Version, from address.Address) MessageBuilder { switch version { case actors.Version0: - return message0{} + return message0{from} case actors.Version2: - return message2{} + return message2{from} default: panic(fmt.Sprintf("unsupported actors version: %d", version)) } } type MessageBuilder interface { - Create(from, to address.Address, initialAmount abi.TokenAmount) (*types.Message, error) - Update(from, paych address.Address, voucher *SignedVoucher, secret []byte) (*types.Message, error) - Settle(from, paych address.Address) (*types.Message, error) - Collect(from, paych address.Address) (*types.Message, error) + Create(to address.Address, initialAmount abi.TokenAmount) (*types.Message, error) + Update(paych address.Address, voucher *SignedVoucher, secret []byte) (*types.Message, error) + Settle(paych address.Address) (*types.Message, error) + Collect(paych address.Address) (*types.Message, error) } diff --git a/chain/actors/builtin/paych/message0.go b/chain/actors/builtin/paych/message0.go index 0e7bbff92..bfeb2731e 100644 --- a/chain/actors/builtin/paych/message0.go +++ b/chain/actors/builtin/paych/message0.go @@ -13,10 +13,10 @@ import ( "github.com/filecoin-project/lotus/chain/types" ) -type message0 struct{} +type message0 struct{ from address.Address } -func (message0) Create(from, to address.Address, initialAmount abi.TokenAmount) (*types.Message, error) { - params, aerr := actors.SerializeParams(&paych0.ConstructorParams{From: from, To: to}) +func (m message0) Create(to address.Address, initialAmount abi.TokenAmount) (*types.Message, error) { + params, aerr := actors.SerializeParams(&paych0.ConstructorParams{From: m.from, To: to}) if aerr != nil { return nil, aerr } @@ -30,14 +30,14 @@ func (message0) Create(from, to address.Address, initialAmount abi.TokenAmount) return &types.Message{ To: init_.Address, - From: from, + From: m.from, Value: initialAmount, Method: builtin0.MethodsInit.Exec, Params: enc, }, nil } -func (message0) Update(from, paych address.Address, sv *SignedVoucher, secret []byte) (*types.Message, error) { +func (m message0) Update(paych address.Address, sv *SignedVoucher, secret []byte) (*types.Message, error) { params, aerr := actors.SerializeParams(&paych0.UpdateChannelStateParams{ Sv: *sv, Secret: secret, @@ -48,26 +48,26 @@ func (message0) Update(from, paych address.Address, sv *SignedVoucher, secret [] return &types.Message{ To: paych, - From: from, + From: m.from, Value: abi.NewTokenAmount(0), Method: builtin0.MethodsPaych.UpdateChannelState, Params: params, }, nil } -func (message0) Settle(from, paych address.Address) (*types.Message, error) { +func (m message0) Settle(paych address.Address) (*types.Message, error) { return &types.Message{ To: paych, - From: from, + From: m.from, Value: abi.NewTokenAmount(0), Method: builtin0.MethodsPaych.Settle, }, nil } -func (message0) Collect(from, paych address.Address) (*types.Message, error) { +func (m message0) Collect(paych address.Address) (*types.Message, error) { return &types.Message{ To: paych, - From: from, + From: m.from, Value: abi.NewTokenAmount(0), Method: builtin0.MethodsPaych.Collect, }, nil diff --git a/chain/actors/builtin/paych/message2.go b/chain/actors/builtin/paych/message2.go index 94538bc49..7d9d8d07c 100644 --- a/chain/actors/builtin/paych/message2.go +++ b/chain/actors/builtin/paych/message2.go @@ -13,10 +13,10 @@ import ( "github.com/filecoin-project/lotus/chain/types" ) -type message2 struct{} +type message2 struct{ from address.Address } -func (message2) Create(from, to address.Address, initialAmount abi.TokenAmount) (*types.Message, error) { - params, aerr := actors.SerializeParams(&paych2.ConstructorParams{From: from, To: to}) +func (m message2) Create(to address.Address, initialAmount abi.TokenAmount) (*types.Message, error) { + params, aerr := actors.SerializeParams(&paych2.ConstructorParams{From: m.from, To: to}) if aerr != nil { return nil, aerr } @@ -30,14 +30,14 @@ func (message2) Create(from, to address.Address, initialAmount abi.TokenAmount) return &types.Message{ To: init_.Address, - From: from, + From: m.from, Value: initialAmount, Method: builtin2.MethodsInit.Exec, Params: enc, }, nil } -func (message2) Update(from, paych address.Address, sv *SignedVoucher, secret []byte) (*types.Message, error) { +func (m message2) Update(paych address.Address, sv *SignedVoucher, secret []byte) (*types.Message, error) { params, aerr := actors.SerializeParams(&paych2.UpdateChannelStateParams{ Sv: *sv, Secret: secret, @@ -48,26 +48,26 @@ func (message2) Update(from, paych address.Address, sv *SignedVoucher, secret [] return &types.Message{ To: paych, - From: from, + From: m.from, Value: abi.NewTokenAmount(0), Method: builtin2.MethodsPaych.UpdateChannelState, Params: params, }, nil } -func (message2) Settle(from, paych address.Address) (*types.Message, error) { +func (m message2) Settle(paych address.Address) (*types.Message, error) { return &types.Message{ To: paych, - From: from, + From: m.from, Value: abi.NewTokenAmount(0), Method: builtin2.MethodsPaych.Settle, }, nil } -func (message2) Collect(from, paych address.Address) (*types.Message, error) { +func (m message2) Collect(paych address.Address) (*types.Message, error) { return &types.Message{ To: paych, - From: from, + From: m.from, Value: abi.NewTokenAmount(0), Method: builtin2.MethodsPaych.Collect, }, nil diff --git a/paychmgr/paych.go b/paychmgr/paych.go index 96ba43543..28563f17d 100644 --- a/paychmgr/paych.go +++ b/paychmgr/paych.go @@ -82,13 +82,13 @@ func newChannelAccessor(pm *Manager, from address.Address, to address.Address) * } } -func (ca *channelAccessor) messageBuilder(ctx context.Context) (paych.MessageBuilder, error) { +func (ca *channelAccessor) messageBuilder(ctx context.Context, from address.Address) (paych.MessageBuilder, error) { nwVersion, err := ca.api.StateNetworkVersion(ctx, types.EmptyTSK) if err != nil { return nil, err } - return paych.Message(actors.VersionForNetwork(nwVersion)), nil + return paych.Message(actors.VersionForNetwork(nwVersion), from), nil } func (ca *channelAccessor) getChannelInfo(addr address.Address) (*ChannelInfo, error) { @@ -301,12 +301,12 @@ func (ca *channelAccessor) checkVoucherSpendable(ctx context.Context, ch address return false, nil } - mb, err := ca.messageBuilder(ctx) + mb, err := ca.messageBuilder(ctx, recipient) if err != nil { return false, err } - mes, err := mb.Update(recipient, ch, sv, secret) + mes, err := mb.Update(ch, sv, secret) if err != nil { return false, err } @@ -418,12 +418,12 @@ func (ca *channelAccessor) submitVoucher(ctx context.Context, ch address.Address } } - mb, err := ca.messageBuilder(ctx) + mb, err := ca.messageBuilder(ctx, ci.Control) if err != nil { return cid.Undef, err } - msg, err := mb.Update(ci.Control, ch, sv, secret) + msg, err := mb.Update(ch, sv, secret) if err != nil { return cid.Undef, err } @@ -574,11 +574,11 @@ func (ca *channelAccessor) settle(ctx context.Context, ch address.Address) (cid. return cid.Undef, err } - mb, err := ca.messageBuilder(ctx) + mb, err := ca.messageBuilder(ctx, ci.Control) if err != nil { return cid.Undef, err } - msg, err := mb.Settle(ci.Control, ch) + msg, err := mb.Settle(ch) if err != nil { return cid.Undef, err } @@ -605,12 +605,12 @@ func (ca *channelAccessor) collect(ctx context.Context, ch address.Address) (cid return cid.Undef, err } - mb, err := ca.messageBuilder(ctx) + mb, err := ca.messageBuilder(ctx, ci.Control) if err != nil { return cid.Undef, err } - msg, err := mb.Collect(ci.Control, ch) + msg, err := mb.Collect(ch) if err != nil { return cid.Undef, err } diff --git a/paychmgr/simple.go b/paychmgr/simple.go index 38804b7ea..9f315da09 100644 --- a/paychmgr/simple.go +++ b/paychmgr/simple.go @@ -384,11 +384,11 @@ func (ca *channelAccessor) processTask(ctx context.Context, amt types.BigInt) *p // createPaych sends a message to create the channel and returns the message cid func (ca *channelAccessor) createPaych(ctx context.Context, amt types.BigInt) (cid.Cid, error) { - mb, err := ca.messageBuilder(ctx) + mb, err := ca.messageBuilder(ctx, ca.from) if err != nil { return cid.Undef, err } - msg, err := mb.Create(ca.from, ca.to, amt) + msg, err := mb.Create(ca.to, amt) if err != nil { return cid.Undef, err } From b01a1d457aced6ca0ac53dbf955b6ac8f492e310 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 30 Sep 2020 12:30:02 -0700 Subject: [PATCH 038/115] abstract multisig calls --- chain/actors/builtin/multisig/message.go | 70 +++++++++ chain/actors/builtin/multisig/message0.go | 142 +++++++++++++++++ chain/actors/builtin/multisig/message2.go | 71 +++++++++ .../multisig/{multisig.go => state.go} | 0 .../builtin/multisig/{v0.go => state0.go} | 0 .../builtin/multisig/{v2.go => state2.go} | 0 node/impl/full/multisig.go | 143 ++++-------------- 7 files changed, 314 insertions(+), 112 deletions(-) create mode 100644 chain/actors/builtin/multisig/message.go create mode 100644 chain/actors/builtin/multisig/message0.go create mode 100644 chain/actors/builtin/multisig/message2.go rename chain/actors/builtin/multisig/{multisig.go => state.go} (100%) rename chain/actors/builtin/multisig/{v0.go => state0.go} (100%) rename chain/actors/builtin/multisig/{v2.go => state2.go} (100%) diff --git a/chain/actors/builtin/multisig/message.go b/chain/actors/builtin/multisig/message.go new file mode 100644 index 000000000..b19287432 --- /dev/null +++ b/chain/actors/builtin/multisig/message.go @@ -0,0 +1,70 @@ +package multisig + +import ( + "fmt" + + "github.com/minio/blake2b-simd" + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + + multisig2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig" + + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/types" +) + +func Message(version actors.Version, from address.Address) MessageBuilder { + switch version { + case actors.Version0: + return message0{from} + case actors.Version2: + return message2{message0{from}} + default: + panic(fmt.Sprintf("unsupported actors version: %d", version)) + } +} + +type MessageBuilder interface { + // Create a new multisig with the specified parameters. + Create(signers []address.Address, threshold uint64, + vestingStart, vestingDuration abi.ChainEpoch, + initialAmount abi.TokenAmount) (*types.Message, error) + + // Propose a transaction to the given multisig. + Propose(msig, target address.Address, amt abi.TokenAmount, + method abi.MethodNum, params []byte) (*types.Message, error) + + // Approve a multisig transaction. The "hash" is optional. + Approve(msig address.Address, txID uint64, hash *ProposalHashData) (*types.Message, error) + + // Cancel a multisig transaction. The "hash" is optional. + Cancel(msig address.Address, txID uint64, hash *ProposalHashData) (*types.Message, error) +} + +// this type is the same between v0 and v2 +type ProposalHashData = multisig2.ProposalHashData + +func txnParams(id uint64, data *ProposalHashData) ([]byte, error) { + params := multisig2.TxnIDParams{ID: multisig2.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) + } + if data.Value.Sign() == -1 { + return nil, xerrors.Errorf("proposal value must be non-negative, was %s", data.Value) + } + if data.To == address.Undef { + return nil, xerrors.Errorf("proposed destination address must be set") + } + pser, err := data.Serialize() + if err != nil { + return nil, err + } + hash := blake2b.Sum256(pser) + params.ProposalHash = hash[:] + } + + return actors.SerializeParams(¶ms) +} diff --git a/chain/actors/builtin/multisig/message0.go b/chain/actors/builtin/multisig/message0.go new file mode 100644 index 000000000..dc43a9d5d --- /dev/null +++ b/chain/actors/builtin/multisig/message0.go @@ -0,0 +1,142 @@ +package multisig + +import ( + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + + builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + init0 "github.com/filecoin-project/specs-actors/actors/builtin/init" + multisig0 "github.com/filecoin-project/specs-actors/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 message0 struct{ from address.Address } + +func (m message0) 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") + } + + if unlockStart != 0 { + return nil, xerrors.Errorf("actors v0 does not support a non-zero vesting start time") + } + + // Set up constructor parameters for multisig + msigParams := &multisig0.ConstructorParams{ + Signers: signers, + NumApprovalsThreshold: threshold, + UnlockDuration: unlockDuration, + } + + 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 := &init0.ExecParams{ + CodeCID: builtin0.MultisigActorCodeID, + ConstructorParams: enc, + } + + enc, actErr = actors.SerializeParams(execParams) + if actErr != nil { + return nil, actErr + } + + return &types.Message{ + To: init_.Address, + From: m.from, + Method: builtin0.MethodsInit.Exec, + Params: enc, + Value: initialAmount, + }, nil +} + +func (m message0) Propose(msig, to address.Address, amt abi.TokenAmount, + method abi.MethodNum, params []byte) (*types.Message, error) { + + if msig == address.Undef { + return nil, xerrors.Errorf("must provide a multisig address for proposal") + } + + if to == address.Undef { + return nil, xerrors.Errorf("must provide a target address for proposal") + } + + if amt.Sign() == -1 { + return nil, xerrors.Errorf("must provide a non-negative amount for proposed send") + } + + if m.from == address.Undef { + return nil, xerrors.Errorf("must provide source address") + } + + enc, actErr := actors.SerializeParams(&multisig0.ProposeParams{ + To: to, + Value: amt, + Method: method, + Params: params, + }) + if actErr != nil { + return nil, xerrors.Errorf("failed to serialize parameters: %w", actErr) + } + + return &types.Message{ + To: msig, + From: m.from, + Value: abi.NewTokenAmount(0), + Method: builtin0.MethodsMultisig.Propose, + Params: enc, + }, nil +} + +func (m message0) Approve(msig address.Address, txID uint64, hashData *ProposalHashData) (*types.Message, error) { + enc, err := txnParams(txID, hashData) + if err != nil { + return nil, err + } + + return &types.Message{ + To: msig, + From: m.from, + Value: types.NewInt(0), + Method: builtin0.MethodsMultisig.Approve, + Params: enc, + }, nil +} + +func (m message0) Cancel(msig address.Address, txID uint64, hashData *ProposalHashData) (*types.Message, error) { + enc, err := txnParams(txID, hashData) + if err != nil { + return nil, err + } + + return &types.Message{ + To: msig, + From: m.from, + Value: types.NewInt(0), + Method: builtin0.MethodsMultisig.Cancel, + Params: enc, + }, nil +} diff --git a/chain/actors/builtin/multisig/message2.go b/chain/actors/builtin/multisig/message2.go new file mode 100644 index 000000000..da2700d06 --- /dev/null +++ b/chain/actors/builtin/multisig/message2.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" + + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + init2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/init" + multisig2 "github.com/filecoin-project/specs-actors/v2/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 message2 struct{ message0 } + +func (m message2) 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 := &multisig2.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 := &init2.ExecParams{ + CodeCID: builtin2.MultisigActorCodeID, + ConstructorParams: enc, + } + + enc, actErr = actors.SerializeParams(execParams) + if actErr != nil { + return nil, actErr + } + + return &types.Message{ + To: init_.Address, + From: m.from, + Method: builtin2.MethodsInit.Exec, + Params: enc, + Value: initialAmount, + }, nil +} diff --git a/chain/actors/builtin/multisig/multisig.go b/chain/actors/builtin/multisig/state.go similarity index 100% rename from chain/actors/builtin/multisig/multisig.go rename to chain/actors/builtin/multisig/state.go diff --git a/chain/actors/builtin/multisig/v0.go b/chain/actors/builtin/multisig/state0.go similarity index 100% rename from chain/actors/builtin/multisig/v0.go rename to chain/actors/builtin/multisig/state0.go diff --git a/chain/actors/builtin/multisig/v2.go b/chain/actors/builtin/multisig/state2.go similarity index 100% rename from chain/actors/builtin/multisig/v2.go rename to chain/actors/builtin/multisig/state2.go diff --git a/node/impl/full/multisig.go b/node/impl/full/multisig.go index 8c15a27be..715689edc 100644 --- a/node/impl/full/multisig.go +++ b/node/impl/full/multisig.go @@ -9,15 +9,13 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/actors" - init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init" + "github.com/filecoin-project/lotus/chain/actors/builtin/multisig" "github.com/filecoin-project/lotus/chain/types" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - init0 "github.com/filecoin-project/specs-actors/actors/builtin/init" multisig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig" "github.com/ipfs/go-cid" - "github.com/minio/blake2b-simd" "go.uber.org/fx" "golang.org/x/xerrors" ) @@ -30,58 +28,31 @@ type MsigAPI struct { MpoolAPI MpoolAPI } +func (a *MsigAPI) messageBuilder(ctx context.Context, from address.Address) (multisig.MessageBuilder, error) { + nver, err := a.StateAPI.StateNetworkVersion(ctx, types.EmptyTSK) + if err != nil { + return nil, err + } + + return multisig.Message(actors.VersionForNetwork(nver), from), nil +} + // TODO: remove gp (gasPrice) from arguments +// TODO: Add "vesting start" to arguments. func (a *MsigAPI) MsigCreate(ctx context.Context, req uint64, addrs []address.Address, duration abi.ChainEpoch, val types.BigInt, src address.Address, gp types.BigInt) (cid.Cid, error) { - lenAddrs := uint64(len(addrs)) - - if lenAddrs < req { - return cid.Undef, xerrors.Errorf("cannot require signing of more addresses than provided for multisig") + mb, err := a.messageBuilder(ctx, src) + if err != nil { + return cid.Undef, err } - if req == 0 { - req = lenAddrs - } - - if src == address.Undef { - return cid.Undef, xerrors.Errorf("must provide source address") - } - - // Set up constructor parameters for multisig - msigParams := &multisig0.ConstructorParams{ - Signers: addrs, - NumApprovalsThreshold: req, - UnlockDuration: duration, - } - - enc, actErr := actors.SerializeParams(msigParams) - if actErr != nil { - return cid.Undef, actErr - } - - // new actors are created by invoking 'exec' on the init actor with the constructor params - // TODO: network upgrade? - execParams := &init0.ExecParams{ - CodeCID: builtin0.MultisigActorCodeID, - ConstructorParams: enc, - } - - enc, actErr = actors.SerializeParams(execParams) - if actErr != nil { - return cid.Undef, actErr - } - - // now we create the message to send this with - msg := types.Message{ - To: init_.Address, - From: src, - Method: builtin0.MethodsInit.Exec, - Params: enc, - Value: val, + msg, err := mb.Create(addrs, req, 0, duration, val) + if err != nil { + return cid.Undef, err } // send the message out to the network - smsg, err := a.MpoolAPI.MpoolPushMessage(ctx, &msg, nil) + smsg, err := a.MpoolAPI.MpoolPushMessage(ctx, msg, nil) if err != nil { return cid.Undef, err } @@ -91,38 +62,14 @@ func (a *MsigAPI) MsigCreate(ctx context.Context, req uint64, addrs []address.Ad func (a *MsigAPI) MsigPropose(ctx context.Context, msig address.Address, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (cid.Cid, error) { - if msig == address.Undef { - return cid.Undef, xerrors.Errorf("must provide a multisig address for proposal") + mb, err := a.messageBuilder(ctx, src) + if err != nil { + return cid.Undef, err } - if to == address.Undef { - return cid.Undef, xerrors.Errorf("must provide a target address for proposal") - } - - if amt.Sign() == -1 { - return cid.Undef, xerrors.Errorf("must provide a positive amount for proposed send") - } - - if src == address.Undef { - return cid.Undef, xerrors.Errorf("must provide source address") - } - - enc, actErr := actors.SerializeParams(&multisig0.ProposeParams{ - To: to, - Value: amt, - Method: abi.MethodNum(method), - Params: params, - }) - if actErr != nil { - return cid.Undef, xerrors.Errorf("failed to serialize parameters: %w", actErr) - } - - msg := &types.Message{ - To: msig, - From: src, - Value: types.NewInt(0), - Method: builtin0.MethodsMultisig.Propose, - Params: enc, + msg, err := mb.Propose(msig, to, amt, abi.MethodNum(method), params) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to create proposal: %w", err) } smsg, err := a.MpoolAPI.MpoolPushMessage(ctx, msg, nil) @@ -200,14 +147,6 @@ func (a *MsigAPI) msigApproveOrCancel(ctx context.Context, operation api.MsigPro return cid.Undef, xerrors.Errorf("must provide multisig address") } - if to == address.Undef { - return cid.Undef, xerrors.Errorf("must provide proposed target address") - } - - if amt.Sign() == -1 { - return cid.Undef, xerrors.Errorf("must provide the positive amount that was proposed") - } - if src == address.Undef { return cid.Undef, xerrors.Errorf("must provide source address") } @@ -220,7 +159,7 @@ func (a *MsigAPI) msigApproveOrCancel(ctx context.Context, operation api.MsigPro proposer = proposerID } - p := multisig0.ProposalHashData{ + p := multisig.ProposalHashData{ Requester: proposer, To: to, Value: amt, @@ -228,42 +167,22 @@ func (a *MsigAPI) msigApproveOrCancel(ctx context.Context, operation api.MsigPro Params: params, } - pser, err := p.Serialize() - if err != nil { - return cid.Undef, err - } - phash := blake2b.Sum256(pser) - - enc, err := actors.SerializeParams(&multisig0.TxnIDParams{ - ID: multisig0.TxnID(txID), - ProposalHash: phash[:], - }) - + mb, err := a.messageBuilder(ctx, src) if err != nil { return cid.Undef, err } - var msigResponseMethod abi.MethodNum - - /* - We pass in a MsigProposeResponse instead of MethodNum to - tighten the possible inputs to just Approve and Cancel. - */ + var msg *types.Message switch operation { case api.MsigApprove: - msigResponseMethod = builtin0.MethodsMultisig.Approve + msg, err = mb.Approve(msig, txID, &p) case api.MsigCancel: - msigResponseMethod = builtin0.MethodsMultisig.Cancel + msg, err = mb.Cancel(msig, txID, &p) default: return cid.Undef, xerrors.Errorf("Invalid operation for msigApproveOrCancel") } - - msg := &types.Message{ - To: msig, - From: src, - Value: types.NewInt(0), - Method: msigResponseMethod, - Params: enc, + if err != nil { + return cid.Undef, err } smsg, err := a.MpoolAPI.MpoolPushMessage(ctx, msg, nil) From 99fe63716bb7147f856541442cf506e2ddeacce0 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 30 Sep 2020 13:12:17 -0700 Subject: [PATCH 039/115] regen lotuspond info --- lotuspond/front/src/chain/methods.json | 106 +++++++++++++++++++++++++ 1 file changed, 106 insertions(+) diff --git a/lotuspond/front/src/chain/methods.json b/lotuspond/front/src/chain/methods.json index ce4919cc4..5e15b053b 100644 --- a/lotuspond/front/src/chain/methods.json +++ b/lotuspond/front/src/chain/methods.json @@ -87,6 +87,10 @@ "SubmitPoRepForBulkVerify", "CurrentTotalPower" ], + "fil/1/system": [ + "Send", + "Constructor" + ], "fil/1/verifiedregistry": [ "Send", "Constructor", @@ -95,5 +99,107 @@ "AddVerifiedClient", "UseBytes", "RestoreBytes" + ], + "fil/2/account": [ + "Send", + "Constructor", + "PubkeyAddress" + ], + "fil/2/cron": [ + "Send", + "Constructor", + "EpochTick" + ], + "fil/2/init": [ + "Send", + "Constructor", + "Exec" + ], + "fil/2/multisig": [ + "Send", + "Constructor", + "Propose", + "Approve", + "Cancel", + "AddSigner", + "RemoveSigner", + "SwapSigner", + "ChangeNumApprovalsThreshold", + "LockBalance" + ], + "fil/2/paymentchannel": [ + "Send", + "Constructor", + "UpdateChannelState", + "Settle", + "Collect" + ], + "fil/2/reward": [ + "Send", + "Constructor", + "AwardBlockReward", + "ThisEpochReward", + "UpdateNetworkKPI" + ], + "fil/2/storagemarket": [ + "Send", + "Constructor", + "AddBalance", + "WithdrawBalance", + "PublishStorageDeals", + "VerifyDealsForActivation", + "ActivateDeals", + "OnMinerSectorsTerminate", + "ComputeDataCommitment", + "CronTick" + ], + "fil/2/storageminer": [ + "Send", + "Constructor", + "ControlAddresses", + "ChangeWorkerAddress", + "ChangePeerID", + "SubmitWindowedPoSt", + "PreCommitSector", + "ProveCommitSector", + "ExtendSectorExpiration", + "TerminateSectors", + "DeclareFaults", + "DeclareFaultsRecovered", + "OnDeferredCronEvent", + "CheckSectorProven", + "ApplyRewards", + "ReportConsensusFault", + "WithdrawBalance", + "ConfirmSectorProofsValid", + "ChangeMultiaddrs", + "CompactPartitions", + "CompactSectorNumbers", + "ConfirmUpdateWorkerKey", + "RepayDebt" + ], + "fil/2/storagepower": [ + "Send", + "Constructor", + "CreateMiner", + "UpdateClaimedPower", + "EnrollCronEvent", + "OnEpochTickEnd", + "UpdatePledgeTotal", + "SubmitPoRepForBulkVerify", + "CurrentTotalPower" + ], + "fil/2/system": [ + "Send", + "Constructor" + ], + "fil/2/verifiedregistry": [ + "Send", + "Constructor", + "AddVerifier", + "RemoveVerifier", + "AddVerifiedClient", + "UseBytes", + "RestoreBytes" ] } \ No newline at end of file From 35e606d39775fbbfb90801ba8218e7ba441cd1cc Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 30 Sep 2020 13:17:56 -0700 Subject: [PATCH 040/115] remove direct specs-actors miner access from expiration calculation --- node/impl/client/client.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/node/impl/client/client.go b/node/impl/client/client.go index 7cb087ec7..ece29bc65 100644 --- a/node/impl/client/client.go +++ b/node/impl/client/client.go @@ -42,7 +42,6 @@ import ( "github.com/filecoin-project/go-multistore" "github.com/filecoin-project/go-padreader" "github.com/filecoin-project/go-state-types/abi" - miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" "github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper" marketevents "github.com/filecoin-project/lotus/markets/loggers" @@ -88,7 +87,7 @@ func calcDealExpiration(minDuration uint64, md *dline.Info, startEpoch abi.Chain minExp := startEpoch + abi.ChainEpoch(minDuration) // Align on miners ProvingPeriodBoundary - return minExp + miner0.WPoStProvingPeriod - (minExp % miner0.WPoStProvingPeriod) + (md.PeriodStart % miner0.WPoStProvingPeriod) - 1 + return minExp + md.WPoStProvingPeriod - (minExp % md.WPoStProvingPeriod) + (md.PeriodStart % md.WPoStProvingPeriod) - 1 } func (a *API) imgr() *importmgr.Mgr { From 8dcbd525da9a65d713398f24d1e28bbae3a78464 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 30 Sep 2020 13:30:24 -0700 Subject: [PATCH 041/115] abstract over deal collateral --- chain/actors/policy/policy.go | 18 ++++++++++++++++++ node/impl/full/state.go | 22 ++++++++++------------ 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/chain/actors/policy/policy.go b/chain/actors/policy/policy.go index 2101cfdcf..8606119f0 100644 --- a/chain/actors/policy/policy.go +++ b/chain/actors/policy/policy.go @@ -2,12 +2,15 @@ package policy import ( "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/lotus/chain/actors" + market0 "github.com/filecoin-project/specs-actors/actors/builtin/market" miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" power0 "github.com/filecoin-project/specs-actors/actors/builtin/power" verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg" builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market" miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" verifreg2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/verifreg" ) @@ -79,3 +82,18 @@ func GetMaxProveCommitDuration(ver actors.Version, t abi.RegisteredSealProof) ab panic("unsupported actors version") } } + +func DealProviderCollateralBounds( + size abi.PaddedPieceSize, verified bool, + rawBytePower, qaPower, baselinePower abi.StoragePower, + circulatingFil abi.TokenAmount, nwVer network.Version, +) (min, max abi.TokenAmount) { + switch actors.VersionForNetwork(nwVer) { + case actors.Version0: + return market0.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil, nwVer) + case actors.Version2: + return market2.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil) + default: + panic("unsupported network version") + } +} diff --git a/node/impl/full/state.go b/node/impl/full/state.go index d2bf5cf25..fc30eb3bb 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -5,10 +5,8 @@ import ( "context" "strconv" - lotusbuiltin "github.com/filecoin-project/lotus/chain/actors/builtin" - - builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - market0 "github.com/filecoin-project/specs-actors/actors/builtin/market" + "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors/policy" "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg" @@ -883,10 +881,10 @@ func (a *StateAPI) StateMinerPreCommitDepositForPower(ctx context.Context, maddr } else { // NB: not exactly accurate, but should always lead us to *over* estimate, not under duration := pci.Expiration - ts.Height() - sectorWeight = lotusbuiltin.QAPowerForWeight(ssize, duration, w, vw) + sectorWeight = builtin.QAPowerForWeight(ssize, duration, w, vw) } - var powerSmoothed lotusbuiltin.FilterEstimate + var powerSmoothed builtin.FilterEstimate if act, err := state.GetActor(power.Address); err != nil { return types.EmptyInt, xerrors.Errorf("loading power actor: %w", err) } else if s, err := power.Load(store, act); err != nil { @@ -944,11 +942,11 @@ func (a *StateAPI) StateMinerInitialPledgeCollateral(ctx context.Context, maddr } else { // NB: not exactly accurate, but should always lead us to *over* estimate, not under duration := pci.Expiration - ts.Height() - sectorWeight = lotusbuiltin.QAPowerForWeight(ssize, duration, w, vw) + sectorWeight = builtin.QAPowerForWeight(ssize, duration, w, vw) } var ( - powerSmoothed lotusbuiltin.FilterEstimate + powerSmoothed builtin.FilterEstimate pledgeCollateral abi.TokenAmount ) if act, err := state.GetActor(power.Address); err != nil { @@ -1025,7 +1023,7 @@ func (a *StateAPI) StateMinerAvailableBalance(ctx context.Context, maddr address // Returns zero if there is no entry in the data cap table for the // address. func (a *StateAPI) StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) { - act, err := a.StateGetActor(ctx, builtin0.VerifiedRegistryActorAddr, tsk) + act, err := a.StateGetActor(ctx, verifreg.Address, tsk) if err != nil { return nil, err } @@ -1063,12 +1061,12 @@ func (a *StateAPI) StateDealProviderCollateralBounds(ctx context.Context, size a return api.DealCollateralBounds{}, xerrors.Errorf("loading tipset %s: %w", tsk, err) } - pact, err := a.StateGetActor(ctx, builtin0.StoragePowerActorAddr, tsk) + pact, err := a.StateGetActor(ctx, power.Address, tsk) if err != nil { return api.DealCollateralBounds{}, xerrors.Errorf("failed to load power actor: %w", err) } - ract, err := a.StateGetActor(ctx, builtin0.RewardActorAddr, tsk) + ract, err := a.StateGetActor(ctx, reward.Address, tsk) if err != nil { return api.DealCollateralBounds{}, xerrors.Errorf("failed to load reward actor: %w", err) } @@ -1098,7 +1096,7 @@ func (a *StateAPI) StateDealProviderCollateralBounds(ctx context.Context, size a return api.DealCollateralBounds{}, xerrors.Errorf("getting reward baseline power: %w", err) } - min, max := market0.DealProviderCollateralBounds(size, + min, max := policy.DealProviderCollateralBounds(size, verified, powClaim.RawBytePower, powClaim.QualityAdjPower, From 6825a485eb5f13f3900734780e8a2572cc1b7120 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 30 Sep 2020 14:28:25 -0700 Subject: [PATCH 042/115] update message extraction tool for specs-actors update --- cmd/tvx/actor_mapping.go | 44 ---------------------------------------- cmd/tvx/extract_many.go | 21 ++++++++++++++----- 2 files changed, 16 insertions(+), 49 deletions(-) delete mode 100644 cmd/tvx/actor_mapping.go diff --git a/cmd/tvx/actor_mapping.go b/cmd/tvx/actor_mapping.go deleted file mode 100644 index 8c306aca0..000000000 --- a/cmd/tvx/actor_mapping.go +++ /dev/null @@ -1,44 +0,0 @@ -package main - -import ( - "reflect" - - "github.com/filecoin-project/specs-actors/actors/builtin" - "github.com/ipfs/go-cid" - "github.com/multiformats/go-multihash" -) - -var ActorMethodTable = make(map[string][]string, 64) - -var Actors = map[cid.Cid]interface{}{ - builtin.InitActorCodeID: builtin.MethodsInit, - builtin.CronActorCodeID: builtin.MethodsCron, - builtin.AccountActorCodeID: builtin.MethodsAccount, - builtin.StoragePowerActorCodeID: builtin.MethodsPower, - builtin.StorageMinerActorCodeID: builtin.MethodsMiner, - builtin.StorageMarketActorCodeID: builtin.MethodsMarket, - builtin.PaymentChannelActorCodeID: builtin.MethodsPaych, - builtin.MultisigActorCodeID: builtin.MethodsMultisig, - builtin.RewardActorCodeID: builtin.MethodsReward, - builtin.VerifiedRegistryActorCodeID: builtin.MethodsVerifiedRegistry, -} - -func init() { - for code, methods := range Actors { - cmh, err := multihash.Decode(code.Hash()) // identity hash. - if err != nil { - panic(err) - } - - var ( - aname = string(cmh.Digest) - rt = reflect.TypeOf(methods) - nf = rt.NumField() - ) - - ActorMethodTable[aname] = append(ActorMethodTable[aname], "Send") - for i := 0; i < nf; i++ { - ActorMethodTable[aname] = append(ActorMethodTable[aname], rt.Field(i).Name) - } - } -} diff --git a/cmd/tvx/extract_many.go b/cmd/tvx/extract_many.go index 9679a1dbd..fe0ce6a6c 100644 --- a/cmd/tvx/extract_many.go +++ b/cmd/tvx/extract_many.go @@ -12,10 +12,14 @@ import ( "strings" "github.com/fatih/color" + "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/exitcode" "github.com/hashicorp/go-multierror" + "github.com/ipfs/go-cid" + "github.com/multiformats/go-multihash" "github.com/urfave/cli/v2" + "github.com/filecoin-project/lotus/chain/stmgr" lcli "github.com/filecoin-project/lotus/cli" ) @@ -118,6 +122,8 @@ func runExtractMany(c *cli.Context) error { log.Println(color.GreenString("csv sanity check succeeded; header contains fields: %v", header)) } + codeCidBuilder := cid.V1Builder{Codec: cid.Raw, MhType: multihash.IDENTITY} + var ( generated []string merr = new(multierror.Error) @@ -133,7 +139,7 @@ func runExtractMany(c *cli.Context) error { return fmt.Errorf("failed to read row: %w", err) } var ( - cid = row[0] + mcid = row[0] actorcode = row[1] methodnumstr = row[2] exitcodestr = row[3] @@ -155,13 +161,18 @@ func runExtractMany(c *cli.Context) error { return fmt.Errorf("invalid method number: %s", methodnumstr) } + codeCid, err := codeCidBuilder.Sum([]byte(actorcode)) + if err != nil { + return fmt.Errorf("failed to compute actor code CID") + } + // Lookup the method in actor method table. - if m, ok := ActorMethodTable[actorcode]; !ok { + if m, ok := stmgr.MethodsMap[codeCid]; !ok { return fmt.Errorf("unrecognized actor: %s", actorcode) } else if methodnum >= len(m) { return fmt.Errorf("unrecognized method number for actor %s: %d", actorcode, methodnum) } else { - methodname = m[methodnum] + methodname = m[abi.MethodNum(methodnum)].Name } // exitcode string representations are of kind ErrType(0); strip out @@ -181,14 +192,14 @@ func runExtractMany(c *cli.Context) error { id: id, block: block, class: "message", - cid: cid, + cid: mcid, file: file, retain: "accessed-cids", precursor: PrecursorSelectSender, } if err := doExtract(ctx, fapi, opts); err != nil { - log.Println(color.RedString("failed to extract vector for message %s: %s; queuing for 'canonical' precursor selection", cid, err)) + log.Println(color.RedString("failed to extract vector for message %s: %s; queuing for 'canonical' precursor selection", mcid, err)) retry = append(retry, opts) continue } From 486812e082ec85693e2d4dd33c2248cae7148aea Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 30 Sep 2020 14:55:50 -0700 Subject: [PATCH 043/115] name test networks Necessary to get upgrades to run. --- node/test/builder.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/node/test/builder.go b/node/test/builder.go index c496b1e4c..fb3aa71d4 100644 --- a/node/test/builder.go +++ b/node/test/builder.go @@ -198,6 +198,7 @@ func Builder(t *testing.T, nFull int, storage []test.StorageMiner) ([]test.TestN templ := &genesis.Template{ Accounts: genaccs, Miners: genms, + NetworkName: "test", Timestamp: uint64(time.Now().Unix() - 10000), // some time sufficiently far in the past VerifregRootKey: gen.DefaultVerifregRootkeyActor, RemainderAccount: gen.DefaultRemainderAccountActor, @@ -344,6 +345,7 @@ func MockSbBuilder(t *testing.T, nFull int, storage []test.StorageMiner) ([]test templ := &genesis.Template{ Accounts: genaccs, Miners: genms, + NetworkName: "test", Timestamp: uint64(time.Now().Unix()) - (build.BlockDelaySecs * 20000), VerifregRootKey: gen.DefaultVerifregRootkeyActor, RemainderAccount: gen.DefaultRemainderAccountActor, From 42d5d8d784ed1602725dc8878088ba46c764001b Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 30 Sep 2020 14:56:16 -0700 Subject: [PATCH 044/115] run upgrade logic on stmgr.Call --- chain/stmgr/call.go | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/chain/stmgr/call.go b/chain/stmgr/call.go index f4dfc7115..2f049cae3 100644 --- a/chain/stmgr/call.go +++ b/chain/stmgr/call.go @@ -5,7 +5,6 @@ import ( "fmt" "github.com/filecoin-project/go-address" - "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/crypto" "github.com/ipfs/go-cid" "go.opencensus.io/trace" @@ -18,14 +17,30 @@ import ( "github.com/filecoin-project/lotus/chain/vm" ) -func (sm *StateManager) CallRaw(ctx context.Context, msg *types.Message, bstate cid.Cid, r vm.Rand, bheight abi.ChainEpoch) (*api.InvocResult, error) { - ctx, span := trace.StartSpan(ctx, "statemanager.CallRaw") +func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types.TipSet) (*api.InvocResult, error) { + ctx, span := trace.StartSpan(ctx, "statemanager.Call") defer span.End() + if ts == nil { + ts = sm.cs.GetHeaviestTipSet() + } + + bstate := ts.ParentState() + bheight := ts.Height() + + newState, err := sm.handleStateForks(ctx, bstate, bheight-1, nil, ts) + if err != nil { + return nil, fmt.Errorf("failed to handle fork") + } + if newState != bstate { + fmt.Println("IT WORKED!") + } + bstate = newState + vmopt := &vm.VMOpts{ StateBase: bstate, Epoch: bheight, - Rand: r, + Rand: store.NewChainRand(sm.cs, ts.Cids()), Bstore: sm.cs.Blockstore(), Syscalls: sm.cs.VMSys(), CircSupplyCalc: sm.GetCirculatingSupply, @@ -89,18 +104,6 @@ func (sm *StateManager) CallRaw(ctx context.Context, msg *types.Message, bstate } -func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types.TipSet) (*api.InvocResult, error) { - if ts == nil { - ts = sm.cs.GetHeaviestTipSet() - } - - state := ts.ParentState() - - r := store.NewChainRand(sm.cs, ts.Cids()) - - return sm.CallRaw(ctx, msg, state, r, ts.Height()) -} - func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, priorMsgs []types.ChainMsg, ts *types.TipSet) (*api.InvocResult, error) { ctx, span := trace.StartSpan(ctx, "statemanager.CallWithGas") defer span.End() From 9d59635b427f4a2f827b5dc48d1ca99ef5931f0a Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 30 Sep 2020 15:04:16 -0700 Subject: [PATCH 045/115] fix error messages --- chain/stmgr/stmgr.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index c5968c4a4..2ce393378 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -280,7 +280,7 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp sysAct, actErr := vmi.StateTree().GetActor(builtin0.SystemActorAddr) if actErr != nil { - return cid.Undef, cid.Undef, xerrors.Errorf("failed to get system actor: %w", err) + return cid.Undef, cid.Undef, xerrors.Errorf("failed to get system actor: %w", actErr) } rwMsg := &types.Message{ @@ -296,7 +296,7 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp } ret, actErr := vmi.ApplyImplicitMessage(ctx, rwMsg) if actErr != nil { - return cid.Undef, cid.Undef, xerrors.Errorf("failed to apply reward message for miner %s: %w", b.Miner, err) + return cid.Undef, cid.Undef, xerrors.Errorf("failed to apply reward message for miner %s: %w", b.Miner, actErr) } if cb != nil { if err := cb(rwMsg.Cid(), rwMsg, ret); err != nil { From 9705b25bbdb349b8efb502ee53cfeb3406e99381 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 30 Sep 2020 15:15:34 -0700 Subject: [PATCH 046/115] fix testground actor versions --- build/params_testground.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/params_testground.go b/build/params_testground.go index 975c26599..de554f49e 100644 --- a/build/params_testground.go +++ b/build/params_testground.go @@ -82,8 +82,8 @@ var ( 0: DrandMainnet, } - NewestNetworkVersion = network.Version2 - ActorUpgradeNetworkVersion = network.Version3 + NewestNetworkVersion = network.Version4 + ActorUpgradeNetworkVersion = network.Version4 Devnet = true ) From 47a83b422e3500714dea2445123a05133a57322b Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 30 Sep 2020 15:51:11 -0700 Subject: [PATCH 047/115] handle state forks in gas estimation --- chain/stmgr/call.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/chain/stmgr/call.go b/chain/stmgr/call.go index 2f049cae3..15cbac53e 100644 --- a/chain/stmgr/call.go +++ b/chain/stmgr/call.go @@ -28,14 +28,10 @@ func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types. bstate := ts.ParentState() bheight := ts.Height() - newState, err := sm.handleStateForks(ctx, bstate, bheight-1, nil, ts) + bstate, err := sm.handleStateForks(ctx, bstate, bheight-1, nil, ts) if err != nil { - return nil, fmt.Errorf("failed to handle fork") + return nil, fmt.Errorf("failed to handle fork: %w", err) } - if newState != bstate { - fmt.Println("IT WORKED!") - } - bstate = newState vmopt := &vm.VMOpts{ StateBase: bstate, @@ -117,6 +113,11 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri return nil, xerrors.Errorf("computing tipset state: %w", err) } + state, err = sm.handleStateForks(ctx, state, ts.Height(), nil, ts) + if err != nil { + return nil, fmt.Errorf("failed to handle fork: %w", err) + } + r := store.NewChainRand(sm.cs, ts.Cids()) if span.IsRecordingEvents() { From 196bf3957462987767911eb6942a2b66d7b3828b Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 30 Sep 2020 17:33:20 -0700 Subject: [PATCH 048/115] use non-faulty sectors, instead of active, in post proof In actors v2, active doesn't include "new" (unproven) sectors. --- storage/wdpost_run.go | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/storage/wdpost_run.go b/storage/wdpost_run.go index 65dbd6e59..6aa3d5188 100644 --- a/storage/wdpost_run.go +++ b/storage/wdpost_run.go @@ -327,17 +327,22 @@ func (s *WindowPoStScheduler) checkNextFaults(ctx context.Context, dlIdx uint64, } for partIdx, partition := range partitions { - good, err := s.checkSectors(ctx, partition.ActiveSectors) + nonFaulty, err := bitfield.SubtractBitField(partition.LiveSectors, partition.FaultySectors) + if err != nil { + return nil, nil, xerrors.Errorf("determining non faulty sectors: %w", err) + } + + good, err := s.checkSectors(ctx, nonFaulty) if err != nil { return nil, nil, xerrors.Errorf("checking sectors: %w", err) } - faulty, err := bitfield.SubtractBitField(partition.ActiveSectors, good) + newFaulty, err := bitfield.SubtractBitField(nonFaulty, good) if err != nil { return nil, nil, xerrors.Errorf("calculating faulty sector set: %w", err) } - c, err := faulty.Count() + c, err := newFaulty.Count() if err != nil { return nil, nil, xerrors.Errorf("counting faulty sectors: %w", err) } @@ -351,7 +356,7 @@ func (s *WindowPoStScheduler) checkNextFaults(ctx context.Context, dlIdx uint64, params.Faults = append(params.Faults, miner.FaultDeclaration{ Deadline: dlIdx, Partition: uint64(partIdx), - Sectors: faulty, + Sectors: newFaulty, }) } @@ -509,7 +514,11 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di dline.Info, ts *ty var sinfos []proof.SectorInfo for partIdx, partition := range batch { // TODO: Can do this in parallel - toProve, err := bitfield.MergeBitFields(partition.ActiveSectors, partition.RecoveringSectors) + toProve, err := bitfield.SubtractBitField(partition.LiveSectors, partition.FaultySectors) + if err != nil { + return nil, xerrors.Errorf("removing faults from set of sectors to prove: %w", err) + } + toProve, err = bitfield.MergeBitFields(toProve, partition.RecoveringSectors) if err != nil { return nil, xerrors.Errorf("adding recoveries to set of sectors to prove: %w", err) } From 3d91633699634c720978069bfce4ae9fa5206c71 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Thu, 1 Oct 2020 04:58:13 -0400 Subject: [PATCH 049/115] Update to v2/actors master --- build/params_2k.go | 2 +- build/params_shared_funcs.go | 2 +- build/params_testground.go | 2 +- build/params_testnet.go | 2 +- chain/stmgr/forks.go | 4 ++-- chain/stmgr/stmgr.go | 2 +- go.mod | 4 ++-- go.sum | 11 ++++------- 8 files changed, 13 insertions(+), 16 deletions(-) diff --git a/build/params_2k.go b/build/params_2k.go index 4428da748..f4a17f724 100644 --- a/build/params_2k.go +++ b/build/params_2k.go @@ -14,7 +14,7 @@ const BreezeGasTampingDuration = 0 const UpgradeSmokeHeight = -1 const UpgradeIgnitionHeight = -2 const UpgradeLiftoffHeight = -3 -const UpgradeActorsV2 = 10 +const UpgradeActorsV2Height = 10 var DrandSchedule = map[abi.ChainEpoch]DrandEnum{ 0: DrandMainnet, diff --git a/build/params_shared_funcs.go b/build/params_shared_funcs.go index 95daa45e7..40ccca50b 100644 --- a/build/params_shared_funcs.go +++ b/build/params_shared_funcs.go @@ -41,7 +41,7 @@ func DhtProtocolName(netName dtypes.NetworkName) protocol.ID { func UseNewestNetwork() bool { // TODO: Put these in a container we can iterate over - if UpgradeBreezeHeight <= 0 && UpgradeSmokeHeight <= 0 && UpgradeActorsV2 <= 0 { + if UpgradeBreezeHeight <= 0 && UpgradeSmokeHeight <= 0 && UpgradeActorsV2Height <= 0 { return true } return false diff --git a/build/params_testground.go b/build/params_testground.go index de554f49e..6d51100e4 100644 --- a/build/params_testground.go +++ b/build/params_testground.go @@ -76,7 +76,7 @@ var ( UpgradeSmokeHeight abi.ChainEpoch = -1 UpgradeIgnitionHeight abi.ChainEpoch = -2 UpgradeLiftoffHeight abi.ChainEpoch = -3 - UpgradeActorsV2 abi.ChainEpoch = 10 + UpgradeActorsV2Height abi.ChainEpoch = 10 DrandSchedule = map[abi.ChainEpoch]DrandEnum{ 0: DrandMainnet, diff --git a/build/params_testnet.go b/build/params_testnet.go index 66f30f869..ab579fd10 100644 --- a/build/params_testnet.go +++ b/build/params_testnet.go @@ -23,7 +23,7 @@ const UpgradeSmokeHeight = 51000 const UpgradeIgnitionHeight = 94000 -const UpgradeActorsV2 = 128888 +const UpgradeActorsV2Height = 128888 // This signals our tentative epoch for mainnet launch. Can make it later, but not earlier. // Miners, clients, developers, custodians all need time to prepare. diff --git a/chain/stmgr/forks.go b/chain/stmgr/forks.go index 96873b675..7d1555114 100644 --- a/chain/stmgr/forks.go +++ b/chain/stmgr/forks.go @@ -36,7 +36,7 @@ import ( var ForksAtHeight = map[abi.ChainEpoch]func(context.Context, *StateManager, ExecCallback, cid.Cid, *types.TipSet) (cid.Cid, error){ build.UpgradeBreezeHeight: UpgradeFaucetBurnRecovery, build.UpgradeIgnitionHeight: UpgradeIgnition, - build.UpgradeActorsV2: UpgradeActorsV2, + build.UpgradeActorsV2Height: UpgradeActorsV2, build.UpgradeLiftoffHeight: UpgradeLiftoff, } @@ -427,7 +427,7 @@ func UpgradeActorsV2(ctx context.Context, sm *StateManager, cb ExecCallback, roo return cid.Undef, xerrors.Errorf("failed to create new state info for actors v2: %w", err) } - newHamtRoot, err := m2.MigrateStateTree(ctx, store, root) + newHamtRoot, err := m2.MigrateStateTree(ctx, store, root, build.UpgradeActorsV2Height, m2.DefaultConfig()) if err != nil { return cid.Undef, xerrors.Errorf("upgrading to actors v2: %w", err) } diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index 2ce393378..e7947cac3 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -1277,7 +1277,7 @@ func (sm *StateManager) GetNtwkVersion(ctx context.Context, height abi.ChainEpoc return network.Version2 } - if height <= build.UpgradeActorsV2 { + if height <= build.UpgradeActorsV2Height { return network.Version3 } diff --git a/go.mod b/go.mod index 1f8d043fa..ea33b810e 100644 --- a/go.mod +++ b/go.mod @@ -37,8 +37,8 @@ require ( github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b - github.com/filecoin-project/specs-actors v0.9.12-0.20200930015636-a6848b2dd741 - github.com/filecoin-project/specs-actors/v2 v2.0.0-20200930035834-7115a78cb9a1 + github.com/filecoin-project/specs-actors v0.9.12 + github.com/filecoin-project/specs-actors/v2 v2.0.0-20201001041506-c7ff44a3ce9b github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796 github.com/filecoin-project/test-vectors/schema v0.0.3 github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 diff --git a/go.sum b/go.sum index 3e16f9b74..6b3b00907 100644 --- a/go.sum +++ b/go.sum @@ -261,8 +261,6 @@ github.com/filecoin-project/go-paramfetch v0.0.2-0.20200701152213-3e0f0afdc261/g github.com/filecoin-project/go-state-types v0.0.0-20200903145444-247639ffa6ad/go.mod h1:IQ0MBPnonv35CJHtWSN3YY1Hz2gkPru1Q9qoaYLxx9I= github.com/filecoin-project/go-state-types v0.0.0-20200904021452-1883f36ca2f4/go.mod h1:IQ0MBPnonv35CJHtWSN3YY1Hz2gkPru1Q9qoaYLxx9I= github.com/filecoin-project/go-state-types v0.0.0-20200905071437-95828685f9df/go.mod h1:IQ0MBPnonv35CJHtWSN3YY1Hz2gkPru1Q9qoaYLxx9I= -github.com/filecoin-project/go-state-types v0.0.0-20200911004822-964d6c679cfc h1:1vr/LoqGq5m5g37Q3sNSAjfwF1uJY0zmiHcvnxY6hik= -github.com/filecoin-project/go-state-types v0.0.0-20200911004822-964d6c679cfc/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g= github.com/filecoin-project/go-state-types v0.0.0-20200928172055-2df22083d8ab h1:cEDC5Ei8UuT99hPWhCjA72SM9AuRtnpvdSTIYbnzN8I= github.com/filecoin-project/go-state-types v0.0.0-20200928172055-2df22083d8ab/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g= github.com/filecoin-project/go-statemachine v0.0.0-20200714194326-a77c3ae20989/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= @@ -274,11 +272,10 @@ github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/go.mod h1:Q0GQOBtKf1oE10eSXSlhN45kDBdGvEcVOqMiffqX+N8= github.com/filecoin-project/specs-actors v0.9.4/go.mod h1:BStZQzx5x7TmCkLv0Bpa07U6cPKol6fd3w9KjMPZ6Z4= github.com/filecoin-project/specs-actors v0.9.7/go.mod h1:wM2z+kwqYgXn5Z7scV1YHLyd1Q1cy0R8HfTIWQ0BFGU= -github.com/filecoin-project/specs-actors v0.9.9/go.mod h1:czlvLQGEX0fjLLfdNHD7xLymy6L3n7aQzRWzsYGf+ys= -github.com/filecoin-project/specs-actors v0.9.12-0.20200930015636-a6848b2dd741 h1:pqAfjHE+yLFj1mvtx68S3HKdd9LSy6Byziz2qRNh3fA= -github.com/filecoin-project/specs-actors v0.9.12-0.20200930015636-a6848b2dd741/go.mod h1:TS1AW/7LbG+615j4NsjMK1qlpAwaFsG9w0V2tg2gSao= -github.com/filecoin-project/specs-actors/v2 v2.0.0-20200930035834-7115a78cb9a1 h1:lNMXodbyskP3ZfTWL/t6M4NYI0hhcZQ2GAJCIVK8Y/E= -github.com/filecoin-project/specs-actors/v2 v2.0.0-20200930035834-7115a78cb9a1/go.mod h1:/2Zra1BhLtpRywUhm++QP+3I5Ir+hBk/W24TpYjj43E= +github.com/filecoin-project/specs-actors v0.9.12 h1:iIvk58tuMtmloFNHhAOQHG+4Gci6Lui0n7DYQGi3cJk= +github.com/filecoin-project/specs-actors v0.9.12/go.mod h1:TS1AW/7LbG+615j4NsjMK1qlpAwaFsG9w0V2tg2gSao= +github.com/filecoin-project/specs-actors/v2 v2.0.0-20201001041506-c7ff44a3ce9b h1:8JRxR0rKdiuCHIDKi7Zbs+/jiygr6eXEX47QXhjX+kA= +github.com/filecoin-project/specs-actors/v2 v2.0.0-20201001041506-c7ff44a3ce9b/go.mod h1:52FuQUNDXq2WDg+6+UOhkqBuNc2e62h9BCIB67Bluxg= github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796 h1:dJsTPWpG2pcTeojO2pyn0c6l+x/3MZYCBgo/9d11JEk= github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796/go.mod h1:nJRRM7Aa9XVvygr3W9k6xGF46RWzr2zxF/iGoAIfA/g= github.com/filecoin-project/test-vectors/schema v0.0.3 h1:1zuBo25B3016inbygYLgYFdpJ2m1BDTbAOCgABRleiU= From 1cc0f74744fd256dfc972d3f7518e95d55082d15 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Thu, 1 Oct 2020 15:02:40 -0700 Subject: [PATCH 050/115] make the upgrade schedule fully configurable This should help with testing. --- chain/stmgr/forks.go | 23 ++++++++++---- chain/stmgr/forks_test.go | 62 ++++++++++++++++++------------------ chain/stmgr/options.go | 23 ++++++++++++++ chain/stmgr/stmgr.go | 67 +++++++++++++++++++++++---------------- go.mod | 2 +- go.sum | 2 ++ 6 files changed, 115 insertions(+), 64 deletions(-) create mode 100644 chain/stmgr/options.go diff --git a/chain/stmgr/forks.go b/chain/stmgr/forks.go index 7d1555114..807f5666c 100644 --- a/chain/stmgr/forks.go +++ b/chain/stmgr/forks.go @@ -9,6 +9,7 @@ import ( "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/go-state-types/network" "github.com/ipfs/go-cid" cbor "github.com/ipfs/go-ipld-cbor" "golang.org/x/xerrors" @@ -33,17 +34,27 @@ import ( "github.com/filecoin-project/lotus/chain/vm" ) -var ForksAtHeight = map[abi.ChainEpoch]func(context.Context, *StateManager, ExecCallback, cid.Cid, *types.TipSet) (cid.Cid, error){ - build.UpgradeBreezeHeight: UpgradeFaucetBurnRecovery, - build.UpgradeIgnitionHeight: UpgradeIgnition, - build.UpgradeActorsV2Height: UpgradeActorsV2, - build.UpgradeLiftoffHeight: UpgradeLiftoff, +type UpgradeFunc func(context.Context, *StateManager, ExecCallback, cid.Cid, *types.TipSet) (cid.Cid, error) + +type Upgrade struct { + Height abi.ChainEpoch + Migration UpgradeFunc +} + +type UpgradeSchedule map[network.Version]Upgrade + +var DefaultUpgradeSchedule = UpgradeSchedule{ + network.Version1: {build.UpgradeBreezeHeight, UpgradeFaucetBurnRecovery}, + network.Version2: {build.UpgradeSmokeHeight, nil}, + network.Version3: {build.UpgradeIgnitionHeight, UpgradeIgnition}, + network.Version4: {build.UpgradeActorsV2Height, UpgradeActorsV2}, + network.Version5: {build.UpgradeLiftoffHeight, UpgradeLiftoff}, } func (sm *StateManager) handleStateForks(ctx context.Context, root cid.Cid, height abi.ChainEpoch, cb ExecCallback, ts *types.TipSet) (cid.Cid, error) { retCid := root var err error - f, ok := ForksAtHeight[height] + f, ok := sm.stateMigrations[height] if ok { retCid, err = f(ctx, sm, cb, root, ts) if err != nil { diff --git a/chain/stmgr/forks_test.go b/chain/stmgr/forks_test.go index 9db6a491a..1b794f31c 100644 --- a/chain/stmgr/forks_test.go +++ b/chain/stmgr/forks_test.go @@ -19,7 +19,6 @@ import ( lotusinit "github.com/filecoin-project/lotus/chain/actors/builtin/init" "github.com/filecoin-project/lotus/chain/actors/policy" "github.com/filecoin-project/lotus/chain/gen" - "github.com/filecoin-project/lotus/chain/stmgr" . "github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/vm" @@ -110,51 +109,54 @@ func TestForkHeightTriggers(t *testing.T) { t.Fatal(err) } - sm := NewStateManager(cg.ChainStore()) - - inv := vm.NewActorRegistry() - // predicting the address here... may break if other assumptions change taddr, err := address.NewIDAddress(1002) if err != nil { t.Fatal(err) } - stmgr.ForksAtHeight[testForkHeight] = func(ctx context.Context, sm *StateManager, cb ExecCallback, root cid.Cid, ts *types.TipSet) (cid.Cid, error) { - cst := ipldcbor.NewCborStore(sm.ChainStore().Blockstore()) + sm := NewStateManager(cg.ChainStore(), + WithUpgradeSchedule(UpgradeSchedule{ + 1: {Height: testForkHeight, Migration: func(ctx context.Context, sm *StateManager, cb ExecCallback, + root cid.Cid, ts *types.TipSet) (cid.Cid, error) { + cst := ipldcbor.NewCborStore(sm.ChainStore().Blockstore()) - st, err := sm.StateTree(root) - if err != nil { - return cid.Undef, xerrors.Errorf("getting state tree: %w", err) - } + st, err := sm.StateTree(root) + if err != nil { + return cid.Undef, xerrors.Errorf("getting state tree: %w", err) + } - act, err := st.GetActor(taddr) - if err != nil { - return cid.Undef, err - } + act, err := st.GetActor(taddr) + if err != nil { + return cid.Undef, err + } - var tas testActorState - if err := cst.Get(ctx, act.Head, &tas); err != nil { - return cid.Undef, xerrors.Errorf("in fork handler, failed to run get: %w", err) - } + var tas testActorState + if err := cst.Get(ctx, act.Head, &tas); err != nil { + return cid.Undef, xerrors.Errorf("in fork handler, failed to run get: %w", err) + } - tas.HasUpgraded = 55 + tas.HasUpgraded = 55 - ns, err := cst.Put(ctx, &tas) - if err != nil { - return cid.Undef, err - } + ns, err := cst.Put(ctx, &tas) + if err != nil { + return cid.Undef, err + } - act.Head = ns + act.Head = ns - if err := st.SetActor(taddr, act); err != nil { - return cid.Undef, err - } + if err := st.SetActor(taddr, act); err != nil { + return cid.Undef, err + } - return st.Flush(ctx) - } + return st.Flush(ctx) + }}, + }), + ) + inv := vm.NewActorRegistry() inv.Register(nil, testActor{}) + sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (*vm.VM, error) { nvm, err := vm.NewVM(ctx, vmopt) if err != nil { diff --git a/chain/stmgr/options.go b/chain/stmgr/options.go new file mode 100644 index 000000000..8c63149a1 --- /dev/null +++ b/chain/stmgr/options.go @@ -0,0 +1,23 @@ +package stmgr + +type Option func(*config) + +type config struct { + upgradeSchedule UpgradeSchedule +} + +func parseOptions(opts ...Option) *config { + cfg := &config{ + upgradeSchedule: DefaultUpgradeSchedule, + } + for _, opt := range opts { + opt(cfg) + } + return cfg +} + +func WithUpgradeSchedule(schedule UpgradeSchedule) Option { + return func(cfg *config) { + cfg.upgradeSchedule = schedule + } +} diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index e7947cac3..8560690ea 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -42,6 +42,12 @@ var log = logging.Logger("statemgr") type StateManager struct { cs *store.ChainStore + // Sorted network upgrade epochs (starting at version 1). + // -1 means the version is skipped. + networkVersions []abi.ChainEpoch + // Maps chain epochs to upgrade functions. + stateMigrations map[abi.ChainEpoch]UpgradeFunc + stCache map[string][]cid.Cid compWait map[string]chan struct{} stlk sync.Mutex @@ -51,12 +57,36 @@ type StateManager struct { postIgnitionGenInfos *genesisInfo } -func NewStateManager(cs *store.ChainStore) *StateManager { +func NewStateManager(cs *store.ChainStore, options ...Option) *StateManager { + cfg := parseOptions(options...) + stateMigrations := make(map[abi.ChainEpoch]UpgradeFunc, len(cfg.upgradeSchedule)) + networkVersions := make([]abi.ChainEpoch, 0, len(stateMigrations)) + + // Iterate version by version, to make sure we handle skipped version numbers. + // Always skip version 0. + for i, version := 0, network.Version(1); i < len(cfg.upgradeSchedule); version++ { + upgrade, ok := cfg.upgradeSchedule[version] + if ok { + // We've processed an upgrade. + i++ + } + + epoch := abi.ChainEpoch(-1) + if ok && upgrade.Height >= 0 { + epoch = upgrade.Height + stateMigrations[epoch] = upgrade.Migration + } + + networkVersions = append(networkVersions, epoch) + } + return &StateManager{ - newVM: vm.NewVM, - cs: cs, - stCache: make(map[string][]cid.Cid), - compWait: make(map[string]chan struct{}), + networkVersions: networkVersions, + stateMigrations: stateMigrations, + newVM: vm.NewVM, + cs: cs, + stCache: make(map[string][]cid.Cid), + compWait: make(map[string]chan struct{}), } } @@ -1259,29 +1289,12 @@ func (sm *StateManager) GetCirculatingSupply(ctx context.Context, height abi.Cha } func (sm *StateManager) GetNtwkVersion(ctx context.Context, height abi.ChainEpoch) network.Version { - // TODO: move hard fork epoch checks to a schedule defined in build/ - - if build.UseNewestNetwork() { - return build.NewestNetworkVersion + for v, epoch := range sm.networkVersions { + if epoch >= 0 && height <= epoch { + return network.Version(v + 1) // we've skipped version 0 + } } - - if height <= build.UpgradeBreezeHeight { - return network.Version0 - } - - if height <= build.UpgradeSmokeHeight { - return network.Version1 - } - - if height <= build.UpgradeIgnitionHeight { - return network.Version2 - } - - if height <= build.UpgradeActorsV2Height { - return network.Version3 - } - - return build.NewestNetworkVersion + return network.Version(len(sm.networkVersions)) } func (sm *StateManager) GetPaychState(ctx context.Context, addr address.Address, ts *types.TipSet) (*types.Actor, paych.State, error) { diff --git a/go.mod b/go.mod index ea33b810e..50e5aecc1 100644 --- a/go.mod +++ b/go.mod @@ -33,7 +33,7 @@ require ( github.com/filecoin-project/go-multistore v0.0.3 github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20 github.com/filecoin-project/go-paramfetch v0.0.2-0.20200701152213-3e0f0afdc261 - github.com/filecoin-project/go-state-types v0.0.0-20200928172055-2df22083d8ab + github.com/filecoin-project/go-state-types v0.0.0-20201001162932-93a412d8e9fa github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b diff --git a/go.sum b/go.sum index 6b3b00907..aa8e3f633 100644 --- a/go.sum +++ b/go.sum @@ -263,6 +263,8 @@ github.com/filecoin-project/go-state-types v0.0.0-20200904021452-1883f36ca2f4/go github.com/filecoin-project/go-state-types v0.0.0-20200905071437-95828685f9df/go.mod h1:IQ0MBPnonv35CJHtWSN3YY1Hz2gkPru1Q9qoaYLxx9I= github.com/filecoin-project/go-state-types v0.0.0-20200928172055-2df22083d8ab h1:cEDC5Ei8UuT99hPWhCjA72SM9AuRtnpvdSTIYbnzN8I= github.com/filecoin-project/go-state-types v0.0.0-20200928172055-2df22083d8ab/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g= +github.com/filecoin-project/go-state-types v0.0.0-20201001162932-93a412d8e9fa h1:WVxLrmc6w5naeX3QikfRvc1G7EFfBZbhXuzM8Lj2J+o= +github.com/filecoin-project/go-state-types v0.0.0-20201001162932-93a412d8e9fa/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g= github.com/filecoin-project/go-statemachine v0.0.0-20200714194326-a77c3ae20989/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe h1:dF8u+LEWeIcTcfUcCf3WFVlc81Fr2JKg8zPzIbBDKDw= github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= From e865ba0c645ada6b026cdc2263b24461befc32bd Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Thu, 1 Oct 2020 15:18:59 -0700 Subject: [PATCH 051/115] improve upgrade schedule configurable Unfortunately, it looks like functional ops cannot be passed in via lotus's di system. --- chain/stmgr/forks_test.go | 8 ++++---- chain/stmgr/options.go | 23 ----------------------- chain/stmgr/stmgr.go | 13 ++++++++----- node/builder.go | 3 ++- 4 files changed, 14 insertions(+), 33 deletions(-) delete mode 100644 chain/stmgr/options.go diff --git a/chain/stmgr/forks_test.go b/chain/stmgr/forks_test.go index 1b794f31c..db65d2485 100644 --- a/chain/stmgr/forks_test.go +++ b/chain/stmgr/forks_test.go @@ -115,8 +115,9 @@ func TestForkHeightTriggers(t *testing.T) { t.Fatal(err) } - sm := NewStateManager(cg.ChainStore(), - WithUpgradeSchedule(UpgradeSchedule{ + sm := NewStateManagerWithUpgradeSchedule( + cg.ChainStore(), + UpgradeSchedule{ 1: {Height: testForkHeight, Migration: func(ctx context.Context, sm *StateManager, cb ExecCallback, root cid.Cid, ts *types.TipSet) (cid.Cid, error) { cst := ipldcbor.NewCborStore(sm.ChainStore().Blockstore()) @@ -151,8 +152,7 @@ func TestForkHeightTriggers(t *testing.T) { return st.Flush(ctx) }}, - }), - ) + }) inv := vm.NewActorRegistry() inv.Register(nil, testActor{}) diff --git a/chain/stmgr/options.go b/chain/stmgr/options.go deleted file mode 100644 index 8c63149a1..000000000 --- a/chain/stmgr/options.go +++ /dev/null @@ -1,23 +0,0 @@ -package stmgr - -type Option func(*config) - -type config struct { - upgradeSchedule UpgradeSchedule -} - -func parseOptions(opts ...Option) *config { - cfg := &config{ - upgradeSchedule: DefaultUpgradeSchedule, - } - for _, opt := range opts { - opt(cfg) - } - return cfg -} - -func WithUpgradeSchedule(schedule UpgradeSchedule) Option { - return func(cfg *config) { - cfg.upgradeSchedule = schedule - } -} diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index 8560690ea..966049693 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -57,15 +57,18 @@ type StateManager struct { postIgnitionGenInfos *genesisInfo } -func NewStateManager(cs *store.ChainStore, options ...Option) *StateManager { - cfg := parseOptions(options...) - stateMigrations := make(map[abi.ChainEpoch]UpgradeFunc, len(cfg.upgradeSchedule)) +func NewStateManager(cs *store.ChainStore) *StateManager { + return NewStateManagerWithUpgradeSchedule(cs, DefaultUpgradeSchedule) +} + +func NewStateManagerWithUpgradeSchedule(cs *store.ChainStore, us UpgradeSchedule) *StateManager { + stateMigrations := make(map[abi.ChainEpoch]UpgradeFunc, len(us)) networkVersions := make([]abi.ChainEpoch, 0, len(stateMigrations)) // Iterate version by version, to make sure we handle skipped version numbers. // Always skip version 0. - for i, version := 0, network.Version(1); i < len(cfg.upgradeSchedule); version++ { - upgrade, ok := cfg.upgradeSchedule[version] + for i, version := 0, network.Version(1); i < len(us); version++ { + upgrade, ok := us[version] if ok { // We've processed an upgrade. i++ diff --git a/node/builder.go b/node/builder.go index 8512d0a0c..c738740ec 100644 --- a/node/builder.go +++ b/node/builder.go @@ -259,7 +259,8 @@ func Online() Option { Override(new(ffiwrapper.Verifier), ffiwrapper.ProofVerifier), Override(new(vm.SyscallBuilder), vm.Syscalls), Override(new(*store.ChainStore), modules.ChainStore), - Override(new(*stmgr.StateManager), stmgr.NewStateManager), + Override(new(stmgr.UpgradeSchedule), stmgr.DefaultUpgradeSchedule), + Override(new(*stmgr.StateManager), stmgr.NewStateManagerWithUpgradeSchedule), Override(new(*wallet.Wallet), wallet.NewWallet), Override(new(*messagesigner.MessageSigner), messagesigner.NewMessageSigner), From 8ad8a945fb688c0968af8fcb3c1e3d94b1615a76 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Thu, 1 Oct 2020 15:26:00 -0700 Subject: [PATCH 052/115] make it possible to override options when testing --- api/test/test.go | 3 ++- node/test/builder.go | 18 ++++++++++-------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/api/test/test.go b/api/test/test.go index 409274ff1..853267eff 100644 --- a/api/test/test.go +++ b/api/test/test.go @@ -12,6 +12,7 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/miner" + "github.com/filecoin-project/lotus/node" ) type TestNode struct { @@ -44,7 +45,7 @@ type StorageMiner struct { // // storage array defines storage nodes, numbers in the array specify full node // index the storage node 'belongs' to -type APIBuilder func(t *testing.T, nFull int, storage []StorageMiner) ([]TestNode, []TestStorageNode) +type APIBuilder func(t *testing.T, nFull int, storage []StorageMiner, opts ...node.Option) ([]TestNode, []TestStorageNode) type testSuite struct { makeNodes APIBuilder } diff --git a/node/test/builder.go b/node/test/builder.go index fb3aa71d4..a3455f376 100644 --- a/node/test/builder.go +++ b/node/test/builder.go @@ -137,7 +137,7 @@ func CreateTestStorageNode(ctx context.Context, t *testing.T, waddr address.Addr return test.TestStorageNode{StorageMiner: minerapi, MineOne: mineOne} } -func Builder(t *testing.T, nFull int, storage []test.StorageMiner) ([]test.TestNode, []test.TestStorageNode) { +func Builder(t *testing.T, nFull int, storage []test.StorageMiner, opts ...node.Option) ([]test.TestNode, []test.TestStorageNode) { ctx := context.Background() mn := mocknet.New(ctx) @@ -224,6 +224,7 @@ func Builder(t *testing.T, nFull int, storage []test.StorageMiner) ([]test.TestN node.Test(), genesis, + node.Options(opts...), ) if err != nil { t.Fatal(err) @@ -285,7 +286,7 @@ func Builder(t *testing.T, nFull int, storage []test.StorageMiner) ([]test.TestN return fulls, storers } -func MockSbBuilder(t *testing.T, nFull int, storage []test.StorageMiner) ([]test.TestNode, []test.TestStorageNode) { +func MockSbBuilder(t *testing.T, nFull int, storage []test.StorageMiner, options ...node.Option) ([]test.TestNode, []test.TestStorageNode) { ctx := context.Background() mn := mocknet.New(ctx) @@ -373,6 +374,7 @@ func MockSbBuilder(t *testing.T, nFull int, storage []test.StorageMiner) ([]test node.Override(new(ffiwrapper.Verifier), mock.MockVerifier), genesis, + node.Options(options...), ) if err != nil { t.Fatalf("%+v", err) @@ -435,16 +437,16 @@ func MockSbBuilder(t *testing.T, nFull int, storage []test.StorageMiner) ([]test return fulls, storers } -func RPCBuilder(t *testing.T, nFull int, storage []test.StorageMiner) ([]test.TestNode, []test.TestStorageNode) { - return rpcWithBuilder(t, Builder, nFull, storage) +func RPCBuilder(t *testing.T, nFull int, storage []test.StorageMiner, opts ...node.Option) ([]test.TestNode, []test.TestStorageNode) { + return rpcWithBuilder(t, Builder, nFull, storage, opts...) } -func RPCMockSbBuilder(t *testing.T, nFull int, storage []test.StorageMiner) ([]test.TestNode, []test.TestStorageNode) { - return rpcWithBuilder(t, MockSbBuilder, nFull, storage) +func RPCMockSbBuilder(t *testing.T, nFull int, storage []test.StorageMiner, opts ...node.Option) ([]test.TestNode, []test.TestStorageNode) { + return rpcWithBuilder(t, MockSbBuilder, nFull, storage, opts...) } -func rpcWithBuilder(t *testing.T, b test.APIBuilder, nFull int, storage []test.StorageMiner) ([]test.TestNode, []test.TestStorageNode) { - fullApis, storaApis := b(t, nFull, storage) +func rpcWithBuilder(t *testing.T, b test.APIBuilder, nFull int, storage []test.StorageMiner, opts ...node.Option) ([]test.TestNode, []test.TestStorageNode) { + fullApis, storaApis := b(t, nFull, storage, opts...) fulls := make([]test.TestNode, nFull) storers := make([]test.TestStorageNode, len(storage)) From 101d07f704c3f120829477219b9a7159ad546c55 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Thu, 1 Oct 2020 15:33:32 -0700 Subject: [PATCH 053/115] fix version off by one error --- chain/stmgr/stmgr.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index 966049693..3efe26f53 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -1292,9 +1292,12 @@ func (sm *StateManager) GetCirculatingSupply(ctx context.Context, height abi.Cha } func (sm *StateManager) GetNtwkVersion(ctx context.Context, height abi.ChainEpoch) network.Version { + // The epochs here are the _last_ epoch for every version, or -1 if the + // version is disabled. for v, epoch := range sm.networkVersions { if epoch >= 0 && height <= epoch { - return network.Version(v + 1) // we've skipped version 0 + // Use the _previous_ version + return network.Version(v) } } return network.Version(len(sm.networkVersions)) From ed86ac14a17f8d09d5a35e8f2311e2bef322ac79 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Thu, 1 Oct 2020 20:37:14 -0700 Subject: [PATCH 054/115] use upgrade epochs from upgrade schedule --- chain/stmgr/forks.go | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/chain/stmgr/forks.go b/chain/stmgr/forks.go index 807f5666c..ccb6221d7 100644 --- a/chain/stmgr/forks.go +++ b/chain/stmgr/forks.go @@ -382,7 +382,9 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, cb ExecCal func UpgradeIgnition(ctx context.Context, sm *StateManager, cb ExecCallback, root cid.Cid, ts *types.TipSet) (cid.Cid, error) { store := sm.cs.Store(ctx) - nst, err := nv3.MigrateStateTree(ctx, store, root, build.UpgradeIgnitionHeight) + epoch := ts.Height() - 1 + + nst, err := nv3.MigrateStateTree(ctx, store, root, epoch) if err != nil { return cid.Undef, xerrors.Errorf("migrating actors state: %w", err) } @@ -407,7 +409,7 @@ func UpgradeIgnition(ctx context.Context, sm *StateManager, cb ExecCallback, roo return cid.Undef, xerrors.Errorf("second split address: %w", err) } - err = resetGenesisMsigs(ctx, sm, store, tree) + err = resetGenesisMsigs(ctx, sm, store, tree, epoch) if err != nil { return cid.Undef, xerrors.Errorf("resetting genesis msig start epochs: %w", err) } @@ -422,7 +424,7 @@ func UpgradeIgnition(ctx context.Context, sm *StateManager, cb ExecCallback, roo return cid.Undef, xerrors.Errorf("splitting second msig: %w", err) } - err = nv3.CheckStateTree(ctx, store, nst, build.UpgradeIgnitionHeight, builtin0.TotalFilecoin) + err = nv3.CheckStateTree(ctx, store, nst, epoch, builtin0.TotalFilecoin) if err != nil { return cid.Undef, xerrors.Errorf("sanity check after ignition upgrade failed: %w", err) } @@ -433,12 +435,14 @@ func UpgradeIgnition(ctx context.Context, sm *StateManager, cb ExecCallback, roo func UpgradeActorsV2(ctx context.Context, sm *StateManager, cb ExecCallback, root cid.Cid, ts *types.TipSet) (cid.Cid, error) { store := sm.cs.Store(ctx) + epoch := ts.Height() - 1 + info, err := store.Put(ctx, new(types.StateInfo)) if err != nil { return cid.Undef, xerrors.Errorf("failed to create new state info for actors v2: %w", err) } - newHamtRoot, err := m2.MigrateStateTree(ctx, store, root, build.UpgradeActorsV2Height, m2.DefaultConfig()) + newHamtRoot, err := m2.MigrateStateTree(ctx, store, root, epoch, m2.DefaultConfig()) if err != nil { return cid.Undef, xerrors.Errorf("upgrading to actors v2: %w", err) } @@ -638,7 +642,7 @@ func makeKeyAddr(splitAddr address.Address, count uint64) (address.Address, erro return addr, nil } -func resetGenesisMsigs(ctx context.Context, sm *StateManager, store adt0.Store, tree *state.StateTree) error { +func resetGenesisMsigs(ctx context.Context, sm *StateManager, store adt0.Store, tree *state.StateTree, epoch abi.ChainEpoch) error { gb, err := sm.cs.GetGenesis() if err != nil { return xerrors.Errorf("getting genesis block: %w", err) @@ -667,7 +671,7 @@ func resetGenesisMsigs(ctx context.Context, sm *StateManager, store adt0.Store, return xerrors.Errorf("reading multisig state: %w", err) } - currState.StartEpoch = build.UpgradeLiftoffHeight + currState.StartEpoch = epoch currActor.Head, err = store.Put(ctx, &currState) if err != nil { From c5de617af61e54639c008fd006c8259ff019e264 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Fri, 2 Oct 2020 17:09:56 -0700 Subject: [PATCH 055/115] decouple network version and upgrades Not all upgrades require network version bumps. --- chain/stmgr/forks.go | 67 ++++++++++++++++++++++++++++++++---- chain/stmgr/forks_test.go | 15 +++++---- chain/stmgr/stmgr.go | 71 ++++++++++++++++++++++++--------------- go.mod | 4 +-- go.sum | 6 ++-- node/builder.go | 2 +- 6 files changed, 117 insertions(+), 48 deletions(-) diff --git a/chain/stmgr/forks.go b/chain/stmgr/forks.go index ccb6221d7..96cdd1f08 100644 --- a/chain/stmgr/forks.go +++ b/chain/stmgr/forks.go @@ -38,17 +38,70 @@ type UpgradeFunc func(context.Context, *StateManager, ExecCallback, cid.Cid, *ty type Upgrade struct { Height abi.ChainEpoch + Network network.Version Migration UpgradeFunc } -type UpgradeSchedule map[network.Version]Upgrade +type UpgradeSchedule []Upgrade -var DefaultUpgradeSchedule = UpgradeSchedule{ - network.Version1: {build.UpgradeBreezeHeight, UpgradeFaucetBurnRecovery}, - network.Version2: {build.UpgradeSmokeHeight, nil}, - network.Version3: {build.UpgradeIgnitionHeight, UpgradeIgnition}, - network.Version4: {build.UpgradeActorsV2Height, UpgradeActorsV2}, - network.Version5: {build.UpgradeLiftoffHeight, UpgradeLiftoff}, +func DefaultUpgradeSchedule() UpgradeSchedule { + var us UpgradeSchedule + + for _, u := range []Upgrade{{ + Height: build.UpgradeBreezeHeight, + Network: network.Version1, + Migration: UpgradeFaucetBurnRecovery, + }, { + Height: build.UpgradeSmokeHeight, + Network: network.Version2, + Migration: nil, + }, { + Height: build.UpgradeIgnitionHeight, + Network: network.Version3, + Migration: UpgradeIgnition, + }, { + Height: build.UpgradeActorsV2Height, + Network: network.Version4, + Migration: UpgradeActorsV2, + }, { + Height: build.UpgradeLiftoffHeight, + Network: network.Version4, + Migration: UpgradeLiftoff, + }} { + if u.Height < 0 { + // upgrade disabled + continue + } + us = append(us, u) + } + return us +} + +func (us UpgradeSchedule) Validate() error { + // Make sure we're not trying to upgrade to version 0. + for _, u := range us { + if u.Network <= 0 { + return xerrors.Errorf("cannot upgrade to version <= 0: %d", u.Network) + } + } + + // Make sure all the upgrades make sense. + for i := 1; i < len(us); i++ { + prev := &us[i-1] + curr := &us[i] + if !(prev.Network <= curr.Network) { + return xerrors.Errorf("cannot downgrade from version %d to version %d", prev.Network, curr.Network) + } + // Make sure the heights make sense. + if prev.Height < 0 { + // Previous upgrade was disabled. + continue + } + if !(prev.Height < curr.Height) { + return xerrors.Errorf("upgrade heights must be strictly increasing: upgrade %d was at height %d, followed by upgrade %d at height %d", i-1, prev.Height, i, curr.Height) + } + } + return nil } func (sm *StateManager) handleStateForks(ctx context.Context, root cid.Cid, height abi.ChainEpoch, cb ExecCallback, ts *types.TipSet) (cid.Cid, error) { diff --git a/chain/stmgr/forks_test.go b/chain/stmgr/forks_test.go index db65d2485..bb03f13b9 100644 --- a/chain/stmgr/forks_test.go +++ b/chain/stmgr/forks_test.go @@ -115,10 +115,11 @@ func TestForkHeightTriggers(t *testing.T) { t.Fatal(err) } - sm := NewStateManagerWithUpgradeSchedule( - cg.ChainStore(), - UpgradeSchedule{ - 1: {Height: testForkHeight, Migration: func(ctx context.Context, sm *StateManager, cb ExecCallback, + sm, err := NewStateManagerWithUpgradeSchedule( + cg.ChainStore(), UpgradeSchedule{{ + Network: 1, + Height: testForkHeight, + Migration: func(ctx context.Context, sm *StateManager, cb ExecCallback, root cid.Cid, ts *types.TipSet) (cid.Cid, error) { cst := ipldcbor.NewCborStore(sm.ChainStore().Blockstore()) @@ -151,8 +152,10 @@ func TestForkHeightTriggers(t *testing.T) { } return st.Flush(ctx) - }}, - }) + }}}) + if err != nil { + t.Fatal(err) + } inv := vm.NewActorRegistry() inv.Register(nil, testActor{}) diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index 3efe26f53..91109d9bd 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -39,12 +39,18 @@ import ( var log = logging.Logger("statemgr") +type versionSpec struct { + networkVersion network.Version + atOrBelow abi.ChainEpoch +} + type StateManager struct { cs *store.ChainStore - // Sorted network upgrade epochs (starting at version 1). - // -1 means the version is skipped. - networkVersions []abi.ChainEpoch + // Determines the network version at any given epoch. + networkVersions []versionSpec + latestVersion network.Version + // Maps chain epochs to upgrade functions. stateMigrations map[abi.ChainEpoch]UpgradeFunc @@ -58,39 +64,49 @@ type StateManager struct { } func NewStateManager(cs *store.ChainStore) *StateManager { - return NewStateManagerWithUpgradeSchedule(cs, DefaultUpgradeSchedule) + sm, err := NewStateManagerWithUpgradeSchedule(cs, DefaultUpgradeSchedule()) + if err != nil { + panic(fmt.Sprintf("default upgrade schedule is invalid: %s", err)) + } + return sm } -func NewStateManagerWithUpgradeSchedule(cs *store.ChainStore, us UpgradeSchedule) *StateManager { +func NewStateManagerWithUpgradeSchedule(cs *store.ChainStore, us UpgradeSchedule) (*StateManager, error) { + // If we have upgrades, make sure they're in-order and make sense. + if err := us.Validate(); err != nil { + return nil, err + } + stateMigrations := make(map[abi.ChainEpoch]UpgradeFunc, len(us)) - networkVersions := make([]abi.ChainEpoch, 0, len(stateMigrations)) - - // Iterate version by version, to make sure we handle skipped version numbers. - // Always skip version 0. - for i, version := 0, network.Version(1); i < len(us); version++ { - upgrade, ok := us[version] - if ok { - // We've processed an upgrade. - i++ + var networkVersions []versionSpec + lastVersion := network.Version0 + if len(us) > 0 { + // If we have any upgrades, process them and create a version + // schedule. + for _, upgrade := range us { + if upgrade.Migration != nil { + stateMigrations[upgrade.Height] = upgrade.Migration + } + networkVersions = append(networkVersions, versionSpec{ + networkVersion: lastVersion, + atOrBelow: upgrade.Height, + }) + lastVersion = upgrade.Network } - - epoch := abi.ChainEpoch(-1) - if ok && upgrade.Height >= 0 { - epoch = upgrade.Height - stateMigrations[epoch] = upgrade.Migration - } - - networkVersions = append(networkVersions, epoch) + } else { + // Otherwise, go directly to the latest version. + lastVersion = build.NewestNetworkVersion } return &StateManager{ networkVersions: networkVersions, + latestVersion: lastVersion, stateMigrations: stateMigrations, newVM: vm.NewVM, cs: cs, stCache: make(map[string][]cid.Cid), compWait: make(map[string]chan struct{}), - } + }, nil } func cidsToKey(cids []cid.Cid) string { @@ -1294,13 +1310,12 @@ func (sm *StateManager) GetCirculatingSupply(ctx context.Context, height abi.Cha func (sm *StateManager) GetNtwkVersion(ctx context.Context, height abi.ChainEpoch) network.Version { // The epochs here are the _last_ epoch for every version, or -1 if the // version is disabled. - for v, epoch := range sm.networkVersions { - if epoch >= 0 && height <= epoch { - // Use the _previous_ version - return network.Version(v) + for _, spec := range sm.networkVersions { + if height <= spec.atOrBelow { + return spec.networkVersion } } - return network.Version(len(sm.networkVersions)) + return sm.latestVersion } func (sm *StateManager) GetPaychState(ctx context.Context, addr address.Address, ts *types.TipSet) (*types.Actor, paych.State, error) { diff --git a/go.mod b/go.mod index 50e5aecc1..44dd4acfa 100644 --- a/go.mod +++ b/go.mod @@ -33,12 +33,12 @@ require ( github.com/filecoin-project/go-multistore v0.0.3 github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20 github.com/filecoin-project/go-paramfetch v0.0.2-0.20200701152213-3e0f0afdc261 - github.com/filecoin-project/go-state-types v0.0.0-20201001162932-93a412d8e9fa + github.com/filecoin-project/go-state-types v0.0.0-20200928172055-2df22083d8ab github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b github.com/filecoin-project/specs-actors v0.9.12 - github.com/filecoin-project/specs-actors/v2 v2.0.0-20201001041506-c7ff44a3ce9b + github.com/filecoin-project/specs-actors/v2 v2.0.0-20201002200957-bdd876b3bbe9 github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796 github.com/filecoin-project/test-vectors/schema v0.0.3 github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 diff --git a/go.sum b/go.sum index aa8e3f633..78daf3af2 100644 --- a/go.sum +++ b/go.sum @@ -263,8 +263,6 @@ github.com/filecoin-project/go-state-types v0.0.0-20200904021452-1883f36ca2f4/go github.com/filecoin-project/go-state-types v0.0.0-20200905071437-95828685f9df/go.mod h1:IQ0MBPnonv35CJHtWSN3YY1Hz2gkPru1Q9qoaYLxx9I= github.com/filecoin-project/go-state-types v0.0.0-20200928172055-2df22083d8ab h1:cEDC5Ei8UuT99hPWhCjA72SM9AuRtnpvdSTIYbnzN8I= github.com/filecoin-project/go-state-types v0.0.0-20200928172055-2df22083d8ab/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g= -github.com/filecoin-project/go-state-types v0.0.0-20201001162932-93a412d8e9fa h1:WVxLrmc6w5naeX3QikfRvc1G7EFfBZbhXuzM8Lj2J+o= -github.com/filecoin-project/go-state-types v0.0.0-20201001162932-93a412d8e9fa/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g= github.com/filecoin-project/go-statemachine v0.0.0-20200714194326-a77c3ae20989/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe h1:dF8u+LEWeIcTcfUcCf3WFVlc81Fr2JKg8zPzIbBDKDw= github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= @@ -276,8 +274,8 @@ github.com/filecoin-project/specs-actors v0.9.4/go.mod h1:BStZQzx5x7TmCkLv0Bpa07 github.com/filecoin-project/specs-actors v0.9.7/go.mod h1:wM2z+kwqYgXn5Z7scV1YHLyd1Q1cy0R8HfTIWQ0BFGU= github.com/filecoin-project/specs-actors v0.9.12 h1:iIvk58tuMtmloFNHhAOQHG+4Gci6Lui0n7DYQGi3cJk= github.com/filecoin-project/specs-actors v0.9.12/go.mod h1:TS1AW/7LbG+615j4NsjMK1qlpAwaFsG9w0V2tg2gSao= -github.com/filecoin-project/specs-actors/v2 v2.0.0-20201001041506-c7ff44a3ce9b h1:8JRxR0rKdiuCHIDKi7Zbs+/jiygr6eXEX47QXhjX+kA= -github.com/filecoin-project/specs-actors/v2 v2.0.0-20201001041506-c7ff44a3ce9b/go.mod h1:52FuQUNDXq2WDg+6+UOhkqBuNc2e62h9BCIB67Bluxg= +github.com/filecoin-project/specs-actors/v2 v2.0.0-20201002200957-bdd876b3bbe9 h1:UXVcGwUD9GJYNcgfGbf7ok790wrunvUhl5ZlgApGhGs= +github.com/filecoin-project/specs-actors/v2 v2.0.0-20201002200957-bdd876b3bbe9/go.mod h1:52FuQUNDXq2WDg+6+UOhkqBuNc2e62h9BCIB67Bluxg= github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796 h1:dJsTPWpG2pcTeojO2pyn0c6l+x/3MZYCBgo/9d11JEk= github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796/go.mod h1:nJRRM7Aa9XVvygr3W9k6xGF46RWzr2zxF/iGoAIfA/g= github.com/filecoin-project/test-vectors/schema v0.0.3 h1:1zuBo25B3016inbygYLgYFdpJ2m1BDTbAOCgABRleiU= diff --git a/node/builder.go b/node/builder.go index c738740ec..d267ac229 100644 --- a/node/builder.go +++ b/node/builder.go @@ -259,7 +259,7 @@ func Online() Option { Override(new(ffiwrapper.Verifier), ffiwrapper.ProofVerifier), Override(new(vm.SyscallBuilder), vm.Syscalls), Override(new(*store.ChainStore), modules.ChainStore), - Override(new(stmgr.UpgradeSchedule), stmgr.DefaultUpgradeSchedule), + Override(new(stmgr.UpgradeSchedule), stmgr.DefaultUpgradeSchedule()), Override(new(*stmgr.StateManager), stmgr.NewStateManagerWithUpgradeSchedule), Override(new(*wallet.Wallet), wallet.NewWallet), Override(new(*messagesigner.MessageSigner), messagesigner.NewMessageSigner), From a57288a4b919020d1ae82940e30c27db00127cc7 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Fri, 2 Oct 2020 17:15:31 -0700 Subject: [PATCH 056/115] run post before, while, and after upgrading --- api/test/window_post.go | 46 ++++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/api/test/window_post.go b/api/test/window_post.go index 958c91816..e77f25fe0 100644 --- a/api/test/window_post.go +++ b/api/test/window_post.go @@ -15,9 +15,11 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/lotus/extern/sector-storage/mock" sealing "github.com/filecoin-project/lotus/extern/storage-sealing" + "github.com/filecoin-project/lotus/node" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/types" bminer "github.com/filecoin-project/lotus/miner" "github.com/filecoin-project/lotus/node/impl" @@ -114,8 +116,29 @@ func pledgeSectors(t *testing.T, ctx context.Context, miner TestStorageNode, n, } func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSectors int) { - ctx := context.Background() - n, sn := b(t, 1, OneMiner) + for _, height := range []abi.ChainEpoch{ + 1, // before + 162, // while sealing + 3000, // while proving + 10_000, // after + } { + t.Run(fmt.Sprintf("upgrade-%d", height), func(t *testing.T) { + testWindowPostUpgrade(t, b, blocktime, nSectors, height) + }) + } + +} +func testWindowPostUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration, nSectors int, + upgradeHeight abi.ChainEpoch) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + n, sn := b(t, 1, OneMiner, node.Override(new(stmgr.UpgradeSchedule), stmgr.UpgradeSchedule{{ + Network: build.ActorUpgradeNetworkVersion, + Height: upgradeHeight, + Migration: stmgr.UpgradeActorsV2, + }})) + client := n[0].FullNode.(*impl.FullNodeAPI) miner := sn[0] @@ -129,17 +152,20 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector } build.Clock.Sleep(time.Second) - mine := true done := make(chan struct{}) go func() { defer close(done) - for mine { + for ctx.Err() == nil { build.Clock.Sleep(blocktime) if err := sn[0].MineOne(ctx, MineNext); err != nil { t.Error(err) } } }() + defer func() { + cancel() + <-done + }() pledgeSectors(t, ctx, miner, nSectors, 0, nil) @@ -159,7 +185,7 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector head, err := client.ChainHead(ctx) require.NoError(t, err) - if head.Height() > di.PeriodStart+(di.WPoStProvingPeriod)+2 { + if head.Height() > di.PeriodStart+di.WPoStProvingPeriod+2 { fmt.Printf("Now head.Height = %d\n", head.Height()) break } @@ -289,12 +315,11 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector pledgeSectors(t, ctx, miner, 1, nSectors, nil) { - // wait a bit more - - head, err := client.ChainHead(ctx) + // Wait until proven. + di, err = client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK) require.NoError(t, err) - waitUntil := head.Height() + 10 + waitUntil := di.PeriodStart + di.WPoStProvingPeriod + 2 fmt.Printf("End for head.Height > %d\n", waitUntil) for { @@ -315,7 +340,4 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector sectors = p.MinerPower.RawBytePower.Uint64() / uint64(ssz) require.Equal(t, nSectors+GenesisPreseals-2+1, int(sectors)) // -2 not recovered sectors + 1 just pledged - - mine = false - <-done } From f1e5e9fe72540bc52d131d2ff747df6883cb2aa8 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Fri, 2 Oct 2020 17:31:26 -0700 Subject: [PATCH 057/115] better upgrade test times --- api/test/window_post.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/api/test/window_post.go b/api/test/window_post.go index e77f25fe0..8f5c4db75 100644 --- a/api/test/window_post.go +++ b/api/test/window_post.go @@ -117,10 +117,9 @@ func pledgeSectors(t *testing.T, ctx context.Context, miner TestStorageNode, n, func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSectors int) { for _, height := range []abi.ChainEpoch{ - 1, // before - 162, // while sealing - 3000, // while proving - 10_000, // after + 1, // before + 162, // while sealing + 5000, // while proving } { t.Run(fmt.Sprintf("upgrade-%d", height), func(t *testing.T) { testWindowPostUpgrade(t, b, blocktime, nSectors, height) From 863a6ed38c526561cb8823106dacb97bd91e39d4 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Fri, 2 Oct 2020 17:45:01 -0700 Subject: [PATCH 058/115] fix lints --- api/test/window_post.go | 1 + 1 file changed, 1 insertion(+) diff --git a/api/test/window_post.go b/api/test/window_post.go index 8f5c4db75..a9a465b74 100644 --- a/api/test/window_post.go +++ b/api/test/window_post.go @@ -121,6 +121,7 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector 162, // while sealing 5000, // while proving } { + height := height // copy to satisfy lints t.Run(fmt.Sprintf("upgrade-%d", height), func(t *testing.T) { testWindowPostUpgrade(t, b, blocktime, nSectors, height) }) From 6aba3e3b94b6ad7df7146fa2505f535bde105565 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Fri, 2 Oct 2020 17:45:15 -0700 Subject: [PATCH 059/115] fix deal error message logging --- api/test/deals.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/api/test/deals.go b/api/test/deals.go index 12cd0607a..aa5bfa716 100644 --- a/api/test/deals.go +++ b/api/test/deals.go @@ -402,9 +402,12 @@ func testRetrieval(t *testing.T, ctx context.Context, client *impl.FullNodeAPI, IsCAR: carExport, } updates, err := client.ClientRetrieveWithEvents(ctx, offers[0].Order(caddr), ref) + if err != nil { + t.Fatal(err) + } for update := range updates { if update.Err != "" { - t.Fatalf("%v", err) + t.Fatalf("retrieval failed: %s", update.Err) } } From f6ccab1c6cc14bf685151e5b9130f2fff8b5a2a9 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Fri, 2 Oct 2020 17:47:01 -0700 Subject: [PATCH 060/115] ignore context canceled error in window post test --- api/test/window_post.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/api/test/window_post.go b/api/test/window_post.go index a9a465b74..eadcdbb05 100644 --- a/api/test/window_post.go +++ b/api/test/window_post.go @@ -158,6 +158,10 @@ func testWindowPostUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration, for ctx.Err() == nil { build.Clock.Sleep(blocktime) if err := sn[0].MineOne(ctx, MineNext); err != nil { + if ctx.Err() != nil { + // context was canceled, ignore the error. + return + } t.Error(err) } } From b9f8831aaffc138ecb6b1ee62cb79a3c9033b813 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 5 Oct 2020 09:51:04 -0700 Subject: [PATCH 061/115] fix specs-actors import in payment channel abstraction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Łukasz Magiera --- chain/actors/builtin/paych/message2.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/chain/actors/builtin/paych/message2.go b/chain/actors/builtin/paych/message2.go index 7d9d8d07c..2cf3ef22e 100644 --- a/chain/actors/builtin/paych/message2.go +++ b/chain/actors/builtin/paych/message2.go @@ -4,9 +4,9 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" - builtin2 "github.com/filecoin-project/specs-actors/actors/builtin" - init2 "github.com/filecoin-project/specs-actors/actors/builtin/init" - paych2 "github.com/filecoin-project/specs-actors/actors/builtin/paych" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + init2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/init" + paych2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/paych" "github.com/filecoin-project/lotus/chain/actors" init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init" From 420c44ed2cb9fc19c4aedb79f123e9f3e3f3b55d Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 5 Oct 2020 10:35:21 -0700 Subject: [PATCH 062/115] fix msig start height --- chain/stmgr/forks.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/chain/stmgr/forks.go b/chain/stmgr/forks.go index 96cdd1f08..d5d0dbf7e 100644 --- a/chain/stmgr/forks.go +++ b/chain/stmgr/forks.go @@ -437,6 +437,10 @@ func UpgradeIgnition(ctx context.Context, sm *StateManager, cb ExecCallback, roo epoch := ts.Height() - 1 + if build.UpgradeLiftoffHeight <= epoch { + return cid.Undef, xerrors.Errorf("liftoff height must be beyond ignition height") + } + nst, err := nv3.MigrateStateTree(ctx, store, root, epoch) if err != nil { return cid.Undef, xerrors.Errorf("migrating actors state: %w", err) @@ -462,7 +466,7 @@ func UpgradeIgnition(ctx context.Context, sm *StateManager, cb ExecCallback, roo return cid.Undef, xerrors.Errorf("second split address: %w", err) } - err = resetGenesisMsigs(ctx, sm, store, tree, epoch) + err = resetGenesisMsigs(ctx, sm, store, tree, build.UpgradeLiftoffHeight) if err != nil { return cid.Undef, xerrors.Errorf("resetting genesis msig start epochs: %w", err) } @@ -695,7 +699,7 @@ func makeKeyAddr(splitAddr address.Address, count uint64) (address.Address, erro return addr, nil } -func resetGenesisMsigs(ctx context.Context, sm *StateManager, store adt0.Store, tree *state.StateTree, epoch abi.ChainEpoch) error { +func resetGenesisMsigs(ctx context.Context, sm *StateManager, store adt0.Store, tree *state.StateTree, startEpoch abi.ChainEpoch) error { gb, err := sm.cs.GetGenesis() if err != nil { return xerrors.Errorf("getting genesis block: %w", err) @@ -724,7 +728,7 @@ func resetGenesisMsigs(ctx context.Context, sm *StateManager, store adt0.Store, return xerrors.Errorf("reading multisig state: %w", err) } - currState.StartEpoch = epoch + currState.StartEpoch = startEpoch currActor.Head, err = store.Put(ctx, &currState) if err != nil { From 8bcc201fc048271b0185321afd24fa4203eb3840 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 5 Oct 2020 10:52:32 -0700 Subject: [PATCH 063/115] fix v2 GetSectorExpiration --- chain/actors/builtin/miner/v2.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/chain/actors/builtin/miner/v2.go b/chain/actors/builtin/miner/v2.go index 6f496a51e..934554d23 100644 --- a/chain/actors/builtin/miner/v2.go +++ b/chain/actors/builtin/miner/v2.go @@ -11,6 +11,7 @@ import ( "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" @@ -106,9 +107,7 @@ func (s *state2) NumLiveSectors() (uint64, error) { // GetSectorExpiration returns the effective expiration of the given sector. // -// If the sector isn't found or has already been terminated, this method returns -// nil and no error. If the sector does not expire early, the Early expiration -// field is 0. +// If the sector does not expire early, the Early expiration field is 0. func (s *state2) GetSectorExpiration(num abi.SectorNumber) (*SectorExpiration, error) { dls, err := s.State.LoadDeadlines(s.store) if err != nil { @@ -171,7 +170,7 @@ func (s *state2) GetSectorExpiration(num abi.SectorNumber) (*SectorExpiration, e return nil, err } if out.Early == 0 && out.OnTime == 0 { - return nil, nil + return nil, xerrors.Errorf("failed to find sector %d", num) } return &out, nil } From 5a08b881d6fa2de17580c0b8220c4dba890e6575 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 5 Oct 2020 10:56:00 -0700 Subject: [PATCH 064/115] Test upgrade before/during/after cc upgrade --- api/test/ccupgrade.go | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/api/test/ccupgrade.go b/api/test/ccupgrade.go index f58f1ff6e..958d2b5aa 100644 --- a/api/test/ccupgrade.go +++ b/api/test/ccupgrade.go @@ -12,15 +12,35 @@ import ( "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/node" "github.com/filecoin-project/lotus/node/impl" ) func TestCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration) { _ = os.Setenv("BELLMAN_NO_GPU", "1") + for _, height := range []abi.ChainEpoch{ + 1, // before + 162, // while sealing + 520, // after upgrade deal + 5000, // after + } { + t.Run(fmt.Sprintf("upgrade-%d", height), func(t *testing.T) { + testCCUpgrade(t, b, blocktime, height) + }) + } +} + +func testCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration, upgradeHeight abi.ChainEpoch) { ctx := context.Background() - n, sn := b(t, 1, OneMiner) + n, sn := b(t, 1, OneMiner, node.Override(new(stmgr.UpgradeSchedule), stmgr.UpgradeSchedule{{ + Network: build.ActorUpgradeNetworkVersion, + Height: upgradeHeight, + Migration: stmgr.UpgradeActorsV2, + }})) client := n[0].FullNode.(*impl.FullNodeAPI) miner := sn[0] From f8b2022f82a51e7d899bd0b7eaaeed973f0115d4 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 5 Oct 2020 11:08:46 -0700 Subject: [PATCH 065/115] fix linters --- api/test/ccupgrade.go | 1 + 1 file changed, 1 insertion(+) diff --git a/api/test/ccupgrade.go b/api/test/ccupgrade.go index 958d2b5aa..97fb665ed 100644 --- a/api/test/ccupgrade.go +++ b/api/test/ccupgrade.go @@ -28,6 +28,7 @@ func TestCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration) { 520, // after upgrade deal 5000, // after } { + height := height // make linters happy by copying t.Run(fmt.Sprintf("upgrade-%d", height), func(t *testing.T) { testCCUpgrade(t, b, blocktime, height) }) From 9621dbb4f1d6a465ade8545a8939e334685bacdd Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 5 Oct 2020 13:27:34 -0700 Subject: [PATCH 066/115] fix tests to use v2 types --- paychmgr/paych_test.go | 32 ++++++++++++++++---------------- paychmgr/paychget_test.go | 4 ++-- paychmgr/simple.go | 2 +- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/paychmgr/paych_test.go b/paychmgr/paych_test.go index ea8a775b5..fcd3d50a8 100644 --- a/paychmgr/paych_test.go +++ b/paychmgr/paych_test.go @@ -15,8 +15,8 @@ import ( "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/specs-actors/actors/builtin" - paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych" tutils "github.com/filecoin-project/specs-actors/support/testing" + paych2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/paych" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/actors/builtin/paych" @@ -237,7 +237,7 @@ func TestCreateVoucher(t *testing.T) { // Create a voucher in lane 1 voucherLane1Amt := big.NewInt(5) - voucher := paych0.SignedVoucher{ + voucher := paych2.SignedVoucher{ Lane: 1, Amount: voucherLane1Amt, } @@ -252,7 +252,7 @@ func TestCreateVoucher(t *testing.T) { // Create a voucher in lane 1 again, with a higher amount voucherLane1Amt = big.NewInt(8) - voucher = paych0.SignedVoucher{ + voucher = paych2.SignedVoucher{ Lane: 1, Amount: voucherLane1Amt, } @@ -267,7 +267,7 @@ func TestCreateVoucher(t *testing.T) { // Create a voucher in lane 2 that covers all the remaining funds // in the channel voucherLane2Amt := big.Sub(s.amt, voucherLane1Amt) - voucher = paych0.SignedVoucher{ + voucher = paych2.SignedVoucher{ Lane: 2, Amount: voucherLane2Amt, } @@ -281,7 +281,7 @@ func TestCreateVoucher(t *testing.T) { // Create a voucher in lane 2 that exceeds the remaining funds in the // channel voucherLane2Amt = big.Add(voucherLane2Amt, big.NewInt(1)) - voucher = paych0.SignedVoucher{ + voucher = paych2.SignedVoucher{ Lane: 2, Amount: voucherLane2Amt, } @@ -619,7 +619,7 @@ func TestCheckSpendable(t *testing.T) { // Check that the secret was passed through correctly lastCall := s.mock.getLastCall() - var p paych0.UpdateChannelStateParams + var p paych2.UpdateChannelStateParams err = p.UnmarshalCBOR(bytes.NewReader(lastCall.Params)) require.NoError(t, err) require.Equal(t, secret, p.Secret) @@ -673,7 +673,7 @@ func TestSubmitVoucher(t *testing.T) { // Check that the secret was passed through correctly msg := s.mock.pushedMessages(submitCid) - var p paych0.UpdateChannelStateParams + var p paych2.UpdateChannelStateParams err = p.UnmarshalCBOR(bytes.NewReader(msg.Message.Params)) require.NoError(t, err) require.Equal(t, secret, p.Secret) @@ -687,7 +687,7 @@ func TestSubmitVoucher(t *testing.T) { require.NoError(t, err) msg = s.mock.pushedMessages(submitCid) - var p3 paych0.UpdateChannelStateParams + var p3 paych2.UpdateChannelStateParams err = p3.UnmarshalCBOR(bytes.NewReader(msg.Message.Params)) require.NoError(t, err) require.Equal(t, secret3, p3.Secret) @@ -773,8 +773,8 @@ func testGenerateKeyPair(t *testing.T) ([]byte, []byte) { return priv, pub } -func createTestVoucher(t *testing.T, ch address.Address, voucherLane uint64, nonce uint64, voucherAmount big.Int, key []byte) *paych0.SignedVoucher { - sv := &paych0.SignedVoucher{ +func createTestVoucher(t *testing.T, ch address.Address, voucherLane uint64, nonce uint64, voucherAmount big.Int, key []byte) *paych2.SignedVoucher { + sv := &paych2.SignedVoucher{ ChannelAddr: ch, Lane: voucherLane, Nonce: nonce, @@ -789,13 +789,13 @@ func createTestVoucher(t *testing.T, ch address.Address, voucherLane uint64, non return sv } -func createTestVoucherWithExtra(t *testing.T, ch address.Address, voucherLane uint64, nonce uint64, voucherAmount big.Int, key []byte) *paych0.SignedVoucher { - sv := &paych0.SignedVoucher{ +func createTestVoucherWithExtra(t *testing.T, ch address.Address, voucherLane uint64, nonce uint64, voucherAmount big.Int, key []byte) *paych2.SignedVoucher { + sv := &paych2.SignedVoucher{ ChannelAddr: ch, Lane: voucherLane, Nonce: nonce, Amount: voucherAmount, - Extra: &paych0.ModVerifyParams{ + Extra: &paych2.ModVerifyParams{ Actor: tutils.NewActorAddr(t, "act"), }, } @@ -813,13 +813,13 @@ type mockBestSpendableAPI struct { mgr *Manager } -func (m *mockBestSpendableAPI) PaychVoucherList(ctx context.Context, ch address.Address) ([]*paych0.SignedVoucher, error) { +func (m *mockBestSpendableAPI) PaychVoucherList(ctx context.Context, ch address.Address) ([]*paych2.SignedVoucher, error) { vi, err := m.mgr.ListVouchers(ctx, ch) if err != nil { return nil, err } - out := make([]*paych0.SignedVoucher, len(vi)) + out := make([]*paych2.SignedVoucher, len(vi)) for k, v := range vi { out[k] = v.Voucher } @@ -827,7 +827,7 @@ func (m *mockBestSpendableAPI) PaychVoucherList(ctx context.Context, ch address. return out, nil } -func (m *mockBestSpendableAPI) PaychVoucherCheckSpendable(ctx context.Context, ch address.Address, voucher *paych0.SignedVoucher, secret []byte, proof []byte) (bool, error) { +func (m *mockBestSpendableAPI) PaychVoucherCheckSpendable(ctx context.Context, ch address.Address, voucher *paych2.SignedVoucher, secret []byte, proof []byte) (bool, error) { return m.mgr.CheckVoucherSpendable(ctx, ch, voucher, secret, proof) } diff --git a/paychmgr/paychget_test.go b/paychmgr/paychget_test.go index dca660029..9f19dd13d 100644 --- a/paychmgr/paychget_test.go +++ b/paychmgr/paychget_test.go @@ -16,7 +16,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/specs-actors/v2/actors/builtin" - init_ "github.com/filecoin-project/specs-actors/v2/actors/builtin/init" + init2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/init" tutils "github.com/filecoin-project/specs-actors/v2/support/testing" lotusinit "github.com/filecoin-project/lotus/chain/actors/builtin/init" @@ -26,7 +26,7 @@ import ( ) func testChannelResponse(t *testing.T, ch address.Address) types.MessageReceipt { - createChannelRet := init_.ExecReturn{ + createChannelRet := init2.ExecReturn{ IDAddress: ch, RobustAddress: ch, } diff --git a/paychmgr/simple.go b/paychmgr/simple.go index cb3e3a102..253075604 100644 --- a/paychmgr/simple.go +++ b/paychmgr/simple.go @@ -13,7 +13,7 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/big" - init2 "github.com/filecoin-project/specs-actors/actors/builtin/init" + init2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/init" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" From 17846aad2f6f2d5828c9cb35baf8556d2317e1e0 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 5 Oct 2020 14:28:47 -0700 Subject: [PATCH 067/115] add some more policy toggles for testground --- chain/actors/policy/policy.go | 10 ++++++++++ chain/actors/policy/policy_test.go | 3 +++ extern/oni | 2 +- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/chain/actors/policy/policy.go b/chain/actors/policy/policy.go index 8606119f0..f29da9802 100644 --- a/chain/actors/policy/policy.go +++ b/chain/actors/policy/policy.go @@ -97,3 +97,13 @@ func DealProviderCollateralBounds( panic("unsupported network version") } } + +// Sets the challenge window and scales the proving period to match (such that +// there are always 48 challenge windows in a proving period). +func SetWPoStChallengeWindow(period abi.ChainEpoch) { + miner0.WPoStChallengeWindow = period + miner0.WPoStProvingPeriod = period * abi.ChainEpoch(miner0.WPoStPeriodDeadlines) + + miner2.WPoStChallengeWindow = period + miner2.WPoStProvingPeriod = period * abi.ChainEpoch(miner2.WPoStPeriodDeadlines) +} diff --git a/chain/actors/policy/policy_test.go b/chain/actors/policy/policy_test.go index 8d6aac09f..62e7f8964 100644 --- a/chain/actors/policy/policy_test.go +++ b/chain/actors/policy/policy_test.go @@ -43,5 +43,8 @@ func TestAssumptions(t *testing.T) { require.EqualValues(t, miner0.SupportedProofTypes, miner2.SupportedProofTypes) require.Equal(t, miner0.PreCommitChallengeDelay, miner2.PreCommitChallengeDelay) require.Equal(t, miner0.ChainFinality, miner2.ChainFinality) + require.Equal(t, miner0.WPoStChallengeWindow, miner2.WPoStChallengeWindow) + require.Equal(t, miner0.WPoStProvingPeriod, miner2.WPoStProvingPeriod) + require.Equal(t, miner0.WPoStPeriodDeadlines, miner2.WPoStPeriodDeadlines) require.True(t, verifreg0.MinVerifiedDealSize.Equals(verifreg2.MinVerifiedDealSize)) } diff --git a/extern/oni b/extern/oni index 9a0d5cd73..a5b57068d 160000 --- a/extern/oni +++ b/extern/oni @@ -1 +1 @@ -Subproject commit 9a0d5cd739de77b357589ac1fc8b756ed27299be +Subproject commit a5b57068d4c2ee0fda76f053edf9825613d1fe9b From 1e78cd21ec21d4ada6b732ec8be317b2fd287793 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 5 Oct 2020 14:34:13 -0700 Subject: [PATCH 068/115] fix lotus soup build --- extern/oni | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/oni b/extern/oni index a5b57068d..dbee44e4f 160000 --- a/extern/oni +++ b/extern/oni @@ -1 +1 @@ -Subproject commit a5b57068d4c2ee0fda76f053edf9825613d1fe9b +Subproject commit dbee44e4f940a502971f17116ccbba61ceaf2674 From 6d25f3d2ae190e8b162c6e21ca89dcbbe8b23f97 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Mon, 5 Oct 2020 18:39:39 -0400 Subject: [PATCH 069/115] Add some comments --- build/params_testnet.go | 1 + chain/messagepool/gasguess/guessgas.go | 1 + 2 files changed, 2 insertions(+) diff --git a/build/params_testnet.go b/build/params_testnet.go index ab579fd10..0aa77788b 100644 --- a/build/params_testnet.go +++ b/build/params_testnet.go @@ -23,6 +23,7 @@ const UpgradeSmokeHeight = 51000 const UpgradeIgnitionHeight = 94000 +// TODO: Actual epoch needs to be filled in const UpgradeActorsV2Height = 128888 // This signals our tentative epoch for mainnet launch. Can make it later, but not earlier. diff --git a/chain/messagepool/gasguess/guessgas.go b/chain/messagepool/gasguess/guessgas.go index 1a6a21755..607c7824a 100644 --- a/chain/messagepool/gasguess/guessgas.go +++ b/chain/messagepool/gasguess/guessgas.go @@ -42,6 +42,7 @@ var Costs = map[CostKey]int64{ {builtin0.StorageMinerActorCodeID, 16}: 5325185, {builtin0.StorageMinerActorCodeID, 18}: 2328637, {builtin0.StoragePowerActorCodeID, 2}: 23600956, + // TODO: Just reuse v0 values for now, this isn't actually used {builtin2.InitActorCodeID, 2}: 8916753, {builtin2.StorageMarketActorCodeID, 2}: 6955002, {builtin2.StorageMarketActorCodeID, 4}: 245436108, From 89b88c1e0d21272249ed9a45d844176cca60f94f Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 5 Oct 2020 17:02:11 -0700 Subject: [PATCH 070/115] fix conformance tests --- conformance/driver.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conformance/driver.go b/conformance/driver.go index 2e8d5a203..5648084ce 100644 --- a/conformance/driver.go +++ b/conformance/driver.go @@ -167,7 +167,7 @@ func (d *Driver) ExecuteMessage(bs blockstore.Blockstore, params ExecuteMessageP // dummy state manager; only to reference the GetNetworkVersion method, // which does not depend on state. - sm := new(stmgr.StateManager) + sm := stmgr.NewStateManager(nil) vmOpts := &vm.VMOpts{ StateBase: params.Preroot, From 16243b97aa8479e28d23c47c69d5fa5427f07bd1 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 5 Oct 2020 17:02:43 -0700 Subject: [PATCH 071/115] make state diffing work with partial state trees --- conformance/runner.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/conformance/runner.go b/conformance/runner.go index 2db53b3e4..626545b2b 100644 --- a/conformance/runner.go +++ b/conformance/runner.go @@ -233,7 +233,12 @@ func writeStateToTempCAR(bs blockstore.Blockstore, roots ...cid.Cid) (string, er if link.Cid.Prefix().Codec == cid.FilCommitmentSealed || link.Cid.Prefix().Codec == cid.FilCommitmentUnsealed { continue } - out = append(out, link) + // ignore things we don't have, the state tree is incomplete. + if has, err := bs.Has(link.Cid); err != nil { + return nil, err + } else if has { + out = append(out, link) + } } return out, nil } From f55b18eabeebc480ac3808dcc62443ed49bbce12 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Sun, 4 Oct 2020 21:38:52 -0400 Subject: [PATCH 072/115] Add funds that have left FilReserve to circ supply --- build/params_shared_vals.go | 5 +++++ build/params_testground.go | 8 ++++++++ chain/actors/builtin/builtin.go | 11 +++++++++++ chain/gen/genesis/genesis.go | 9 +++------ chain/stmgr/stmgr.go | 27 +++++++++++++++++++++++---- 5 files changed, 50 insertions(+), 10 deletions(-) diff --git a/build/params_shared_vals.go b/build/params_shared_vals.go index 4734a15ed..cc711b7bc 100644 --- a/build/params_shared_vals.go +++ b/build/params_shared_vals.go @@ -72,8 +72,10 @@ const FilBase = uint64(2_000_000_000) const FilAllocStorageMining = uint64(1_100_000_000) const FilecoinPrecision = uint64(1_000_000_000_000_000_000) +const FilReserved = uint64(300_000_000) var InitialRewardBalance *big.Int +var InitialFilReserved *big.Int // TODO: Move other important consts here @@ -81,6 +83,9 @@ func init() { InitialRewardBalance = big.NewInt(int64(FilAllocStorageMining)) InitialRewardBalance = InitialRewardBalance.Mul(InitialRewardBalance, big.NewInt(int64(FilecoinPrecision))) + InitialFilReserved = big.NewInt(int64(FilReserved)) + InitialFilReserved = InitialFilReserved.Mul(InitialFilReserved, big.NewInt(int64(FilecoinPrecision))) + if os.Getenv("LOTUS_ADDRESS_TYPE") == AddressMainnetEnvVar { SetAddressNetwork(address.Mainnet) } diff --git a/build/params_testground.go b/build/params_testground.go index 6d51100e4..162b3477c 100644 --- a/build/params_testground.go +++ b/build/params_testground.go @@ -55,6 +55,7 @@ var ( FilBase uint64 = 2_000_000_000 FilAllocStorageMining uint64 = 1_400_000_000 + FilReserved uint64 = 300_000_000 FilecoinPrecision uint64 = 1_000_000_000_000_000_000 @@ -63,6 +64,13 @@ var ( v = v.Mul(v, big.NewInt(int64(FilecoinPrecision))) return v }() + + InitialFilReserved = func() *big.Int { + v := big.NewInt(int64(FilReserved)) + v = v.Mul(v, big.NewInt(int64(FilecoinPrecision))) + return v + }() + // Actor consts // TODO: Pull from actors when its made not private MinDealDuration = abi.ChainEpoch(180 * builtin.EpochsInDay) diff --git a/chain/actors/builtin/builtin.go b/chain/actors/builtin/builtin.go index d49164486..7def78dcf 100644 --- a/chain/actors/builtin/builtin.go +++ b/chain/actors/builtin/builtin.go @@ -1,6 +1,7 @@ package builtin import ( + "github.com/filecoin-project/go-address" "github.com/ipfs/go-cid" "golang.org/x/xerrors" @@ -20,6 +21,7 @@ import ( var SystemActorAddr = builtin0.SystemActorAddr var BurntFundsActorAddr = builtin0.BurntFundsActorAddr +var ReserveAddress = makeAddress("t090") // TODO: Why does actors have 2 different versions of this? type SectorInfo = proof0.SectorInfo @@ -86,3 +88,12 @@ func IsMultisigActor(c cid.Cid) bool { func IsPaymentChannelActor(c cid.Cid) bool { return c == builtin0.PaymentChannelActorCodeID || c == builtin2.PaymentChannelActorCodeID } + +func makeAddress(addr string) address.Address { + ret, err := address.NewFromString(addr) + if err != nil { + panic(err) + } + + return ret +} diff --git a/chain/gen/genesis/genesis.go b/chain/gen/genesis/genesis.go index bb1056e2e..f532b9f5e 100644 --- a/chain/gen/genesis/genesis.go +++ b/chain/gen/genesis/genesis.go @@ -6,6 +6,8 @@ import ( "encoding/json" "fmt" + "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" cbor "github.com/ipfs/go-ipld-cbor" @@ -296,14 +298,9 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge return nil, nil, xerrors.Errorf("somehow overallocated filecoin (allocated = %s)", types.FIL(totalFilAllocated)) } - remAccKey, err := address.NewIDAddress(90) - if err != nil { - return nil, nil, err - } - template.RemainderAccount.Balance = remainingFil - if err := createMultisigAccount(ctx, bs, cst, state, remAccKey, template.RemainderAccount, keyIDs); err != nil { + if err := createMultisigAccount(ctx, bs, cst, state, builtin.ReserveAddress, template.RemainderAccount, keyIDs); err != nil { return nil, nil, xerrors.Errorf("failed to set up remainder account: %w", err) } diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index e371992e8..b27bed587 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -1171,14 +1171,27 @@ func (sm *StateManager) GetFilVested(ctx context.Context, height abi.ChainEpoch, } } - // continue to use preIgnitionGenInfos, nothing changed at the Ignition epoch - vf = big.Add(vf, sm.preIgnitionGenInfos.genesisPledge) - // continue to use preIgnitionGenInfos, nothing changed at the Ignition epoch - vf = big.Add(vf, sm.preIgnitionGenInfos.genesisMarketFunds) + // After UpgradeActorsV2Height these funds are accounted for in GetFilReserveDisbursed + if height <= build.UpgradeActorsV2Height { + // continue to use preIgnitionGenInfos, nothing changed at the Ignition epoch + vf = big.Add(vf, sm.preIgnitionGenInfos.genesisPledge) + // continue to use preIgnitionGenInfos, nothing changed at the Ignition epoch + vf = big.Add(vf, sm.preIgnitionGenInfos.genesisMarketFunds) + } return vf, nil } +func GetFilReserveDisbursed(ctx context.Context, st *state.StateTree) (abi.TokenAmount, error) { + ract, err := st.GetActor(builtin.ReserveAddress) + if err != nil { + return big.Zero(), xerrors.Errorf("failed to get reserve actor: %w", err) + } + + // If money enters the reserve actor, this could lead to a negative term + return big.Sub(big.NewFromGo(build.InitialFilReserved), ract.Balance), nil +} + func GetFilMined(ctx context.Context, st *state.StateTree) (abi.TokenAmount, error) { ractor, err := st.GetActor(reward.Address) if err != nil { @@ -1266,6 +1279,11 @@ func (sm *StateManager) GetCirculatingSupplyDetailed(ctx context.Context, height return api.CirculatingSupply{}, xerrors.Errorf("failed to calculate filVested: %w", err) } + filReserveDisbursed, err := GetFilReserveDisbursed(ctx, st) + if err != nil { + return api.CirculatingSupply{}, xerrors.Errorf("failed to calculate filReserveDisbursed: %w", err) + } + filMined, err := GetFilMined(ctx, st) if err != nil { return api.CirculatingSupply{}, xerrors.Errorf("failed to calculate filMined: %w", err) @@ -1282,6 +1300,7 @@ func (sm *StateManager) GetCirculatingSupplyDetailed(ctx context.Context, height } ret := types.BigAdd(filVested, filMined) + ret = types.BigAdd(ret, filReserveDisbursed) ret = types.BigSub(ret, filBurnt) ret = types.BigSub(ret, filLocked) From 14ad91c53ff0d159a94fd8f6ad4c3cd0cf565a54 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Tue, 6 Oct 2020 01:27:45 -0400 Subject: [PATCH 073/115] Add type assertion for v2 runtime --- chain/vm/runtime.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/chain/vm/runtime.go b/chain/vm/runtime.go index 20d79e378..472017a00 100644 --- a/chain/vm/runtime.go +++ b/chain/vm/runtime.go @@ -15,6 +15,7 @@ import ( "github.com/filecoin-project/go-state-types/network" rtt "github.com/filecoin-project/go-state-types/rt" rt0 "github.com/filecoin-project/specs-actors/actors/runtime" + rt2 "github.com/filecoin-project/specs-actors/v2/actors/runtime" "github.com/ipfs/go-cid" ipldcbor "github.com/ipfs/go-ipld-cbor" "go.opencensus.io/trace" @@ -108,6 +109,7 @@ func (rt *Runtime) StorePut(x cbor.Marshaler) cid.Cid { } var _ rt0.Runtime = (*Runtime)(nil) +var _ rt2.Runtime = (*Runtime)(nil) func (rt *Runtime) shimCall(f func() interface{}) (rval []byte, aerr aerrors.ActorError) { defer func() { From f8c886a611b83091f6d4b699493fb351ff27b6c3 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Tue, 6 Oct 2020 03:49:11 -0400 Subject: [PATCH 074/115] Rename MiningBaseInfo.HasMinPower to EligibleForMining --- api/api_full.go | 16 ++++++++-------- chain/stmgr/utils.go | 16 ++++++++-------- miner/miner.go | 2 +- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/api/api_full.go b/api/api_full.go index 5cbdde8e3..07b48a7eb 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -806,14 +806,14 @@ type CirculatingSupply struct { } type MiningBaseInfo struct { - MinerPower types.BigInt - NetworkPower types.BigInt - Sectors []builtin.SectorInfo - WorkerKey address.Address - SectorSize abi.SectorSize - PrevBeaconEntry types.BeaconEntry - BeaconEntries []types.BeaconEntry - HasMinPower bool + MinerPower types.BigInt + NetworkPower types.BigInt + Sectors []builtin.SectorInfo + WorkerKey address.Address + SectorSize abi.SectorSize + PrevBeaconEntry types.BeaconEntry + BeaconEntries []types.BeaconEntry + EligibleForMining bool } type BlockTemplate struct { diff --git a/chain/stmgr/utils.go b/chain/stmgr/utils.go index 98f6bc5ac..6b43303f0 100644 --- a/chain/stmgr/utils.go +++ b/chain/stmgr/utils.go @@ -506,14 +506,14 @@ func MinerGetBaseInfo(ctx context.Context, sm *StateManager, bcs beacon.Schedule } return &api.MiningBaseInfo{ - MinerPower: mpow.QualityAdjPower, - NetworkPower: tpow.QualityAdjPower, - Sectors: sectors, - WorkerKey: worker, - SectorSize: info.SectorSize, - PrevBeaconEntry: *prev, - BeaconEntries: entries, - HasMinPower: hmp, + MinerPower: mpow.QualityAdjPower, + NetworkPower: tpow.QualityAdjPower, + Sectors: sectors, + WorkerKey: worker, + SectorSize: info.SectorSize, + PrevBeaconEntry: *prev, + BeaconEntries: entries, + EligibleForMining: hmp, }, nil } diff --git a/miner/miner.go b/miner/miner.go index d4e7b2317..a256e8b3a 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -362,7 +362,7 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg, if mbi == nil { return nil, nil } - if !mbi.HasMinPower { + if !mbi.EligibleForMining { // slashed or just have no power yet return nil, nil } From 4a9155ba854d05f8acccde58ddb059543be7fdc5 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Tue, 6 Oct 2020 04:33:55 -0400 Subject: [PATCH 075/115] Use new MinerEligibleToMine method post-v2 actors --- chain/actors/builtin/miner/miner.go | 2 + chain/actors/builtin/miner/v0.go | 7 +++ chain/actors/builtin/miner/v2.go | 5 ++ chain/actors/policy/policy.go | 1 - chain/stmgr/utils.go | 80 +++++++++++++++++++++++++++-- chain/sub/incoming.go | 6 +-- chain/sync.go | 6 +-- 7 files changed, 97 insertions(+), 10 deletions(-) diff --git a/chain/actors/builtin/miner/miner.go b/chain/actors/builtin/miner/miner.go index 125d142d3..8649d4351 100644 --- a/chain/actors/builtin/miner/miner.go +++ b/chain/actors/builtin/miner/miner.go @@ -58,6 +58,7 @@ type State interface { VestedFunds(abi.ChainEpoch) (abi.TokenAmount, error) // Funds locked for various reasons. LockedFunds() (LockedFunds, error) + FeeDebt() (abi.TokenAmount, error) GetSector(abi.SectorNumber) (*SectorOnChainInfo, error) FindSector(abi.SectorNumber) (*SectorLocation, error) @@ -144,6 +145,7 @@ type MinerInfo struct { SealProofType abi.RegisteredSealProof SectorSize abi.SectorSize WindowPoStPartitionSectors uint64 + ConsensusFaultElapsed abi.ChainEpoch } type SectorExpiration struct { diff --git a/chain/actors/builtin/miner/v0.go b/chain/actors/builtin/miner/v0.go index 902ed20f2..7e71c7611 100644 --- a/chain/actors/builtin/miner/v0.go +++ b/chain/actors/builtin/miner/v0.go @@ -4,6 +4,8 @@ import ( "bytes" "errors" + "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-bitfield" "github.com/filecoin-project/go-state-types/abi" @@ -61,6 +63,10 @@ func (s *state0) LockedFunds() (LockedFunds, error) { }, nil } +func (s *state0) FeeDebt() (abi.TokenAmount, error) { + return big.Zero(), nil +} + func (s *state0) InitialPledge() (abi.TokenAmount, error) { return s.State.InitialPledgeRequirement, nil } @@ -287,6 +293,7 @@ func (s *state0) Info() (MinerInfo, error) { SealProofType: info.SealProofType, SectorSize: info.SectorSize, WindowPoStPartitionSectors: info.WindowPoStPartitionSectors, + ConsensusFaultElapsed: -1, } if info.PendingWorkerKey != nil { diff --git a/chain/actors/builtin/miner/v2.go b/chain/actors/builtin/miner/v2.go index 934554d23..e2b53e9a6 100644 --- a/chain/actors/builtin/miner/v2.go +++ b/chain/actors/builtin/miner/v2.go @@ -61,6 +61,10 @@ func (s *state2) LockedFunds() (LockedFunds, error) { }, nil } +func (s *state2) FeeDebt() (abi.TokenAmount, error) { + return s.State.FeeDebt, nil +} + func (s *state2) InitialPledge() (abi.TokenAmount, error) { return s.State.InitialPledge, nil } @@ -288,6 +292,7 @@ func (s *state2) Info() (MinerInfo, error) { SealProofType: info.SealProofType, SectorSize: info.SectorSize, WindowPoStPartitionSectors: info.WindowPoStPartitionSectors, + ConsensusFaultElapsed: info.ConsensusFaultElapsed, } if info.PendingWorkerKey != nil { diff --git a/chain/actors/policy/policy.go b/chain/actors/policy/policy.go index f29da9802..e7f213687 100644 --- a/chain/actors/policy/policy.go +++ b/chain/actors/policy/policy.go @@ -4,7 +4,6 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/lotus/chain/actors" - market0 "github.com/filecoin-project/specs-actors/actors/builtin/market" miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" power0 "github.com/filecoin-project/specs-actors/actors/builtin/power" diff --git a/chain/stmgr/utils.go b/chain/stmgr/utils.go index 6b43303f0..f2e2bfd19 100644 --- a/chain/stmgr/utils.go +++ b/chain/stmgr/utils.go @@ -9,6 +9,10 @@ import ( "runtime" "strings" + "github.com/filecoin-project/go-state-types/big" + + "github.com/filecoin-project/go-state-types/network" + cid "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" @@ -490,7 +494,7 @@ func MinerGetBaseInfo(ctx context.Context, sm *StateManager, bcs beacon.Schedule return nil, nil } - mpow, tpow, hmp, err := GetPowerRaw(ctx, sm, lbst, maddr) + mpow, tpow, _, err := GetPowerRaw(ctx, sm, lbst, maddr) if err != nil { return nil, xerrors.Errorf("failed to get power: %w", err) } @@ -505,6 +509,12 @@ func MinerGetBaseInfo(ctx context.Context, sm *StateManager, bcs beacon.Schedule return nil, xerrors.Errorf("resolving worker address: %w", err) } + // TODO: Not ideal performance...This method reloads miner and power state (already looked up here and in GetPowerRaw) + eligible, err := MinerEligibleToMine(ctx, sm, maddr, ts, lbts) + if err != nil { + return nil, xerrors.Errorf("determining miner eligibility: %w", err) + } + return &api.MiningBaseInfo{ MinerPower: mpow.QualityAdjPower, NetworkPower: tpow.QualityAdjPower, @@ -513,7 +523,7 @@ func MinerGetBaseInfo(ctx context.Context, sm *StateManager, bcs beacon.Schedule SectorSize: info.SectorSize, PrevBeaconEntry: *prev, BeaconEntries: entries, - EligibleForMining: hmp, + EligibleForMining: eligible, }, nil } @@ -595,7 +605,7 @@ func GetReturnType(ctx context.Context, sm *StateManager, to address.Address, me return reflect.New(m.Ret.Elem()).Interface().(cbg.CBORUnmarshaler), nil } -func MinerHasMinPower(ctx context.Context, sm *StateManager, addr address.Address, ts *types.TipSet) (bool, error) { +func minerHasMinPower(ctx context.Context, sm *StateManager, addr address.Address, ts *types.TipSet) (bool, error) { pact, err := sm.LoadActor(ctx, power.Address, ts) if err != nil { return false, xerrors.Errorf("loading power actor state: %w", err) @@ -609,6 +619,70 @@ func MinerHasMinPower(ctx context.Context, sm *StateManager, addr address.Addres return ps.MinerNominalPowerMeetsConsensusMinimum(addr) } +func MinerEligibleToMine(ctx context.Context, sm *StateManager, addr address.Address, baseTs *types.TipSet, lookbackTs *types.TipSet) (bool, error) { + hmp, err := minerHasMinPower(ctx, sm, addr, lookbackTs) + + // TODO: We're blurring the lines between a "runtime network version" and a "Lotus upgrade epoch", is that unavoidable? + if sm.GetNtwkVersion(ctx, baseTs.Height()) <= network.Version3 { + return hmp, err + } + + if err != nil { + return false, err + } + + if !hmp { + return false, nil + } + + // Post actors v2, also check MinerEligibleForElection with base ts + + pact, err := sm.LoadActor(ctx, power.Address, baseTs) + if err != nil { + return false, xerrors.Errorf("loading power actor state: %w", err) + } + + pstate, err := power.Load(sm.cs.Store(ctx), pact) + if err != nil { + return false, err + } + + mact, err := sm.LoadActor(ctx, addr, baseTs) + if err != nil { + return false, xerrors.Errorf("loading miner actor state: %w", err) + } + + mstate, err := miner.Load(sm.cs.Store(ctx), mact) + if err != nil { + return false, err + } + + // Non-empty power claim. + if claim, found, err := pstate.MinerPower(addr); err != nil { + return false, err + } else if !found { + return false, err + } else if claim.QualityAdjPower.LessThanEqual(big.Zero()) { + return false, err + } + + // No fee debt. + if debt, err := mstate.FeeDebt(); err != nil { + return false, err + } else if !debt.IsZero() { + return false, err + } + + // No active consensus faults. + if mInfo, err := mstate.Info(); err != nil { + return false, err + } else if baseTs.Height() <= mInfo.ConsensusFaultElapsed { + return false, nil + } + + return true, nil +} + func CheckTotalFIL(ctx context.Context, sm *StateManager, ts *types.TipSet) (abi.TokenAmount, error) { str, err := state.LoadStateTree(sm.ChainStore().Store(ctx), ts.ParentState()) if err != nil { diff --git a/chain/sub/incoming.go b/chain/sub/incoming.go index 53bc3d68e..07b3343d2 100644 --- a/chain/sub/incoming.go +++ b/chain/sub/incoming.go @@ -485,14 +485,14 @@ func (bv *BlockValidator) checkPowerAndGetWorkerKey(ctx context.Context, bh *typ return address.Undef, ErrSoftFailure } - hmp, err := stmgr.MinerHasMinPower(ctx, bv.stmgr, bh.Miner, lbts) + eligible, err := stmgr.MinerEligibleToMine(ctx, bv.stmgr, bh.Miner, baseTs, lbts) if err != nil { log.Warnf("failed to determine if incoming block's miner has minimum power: %s", err) return address.Undef, ErrSoftFailure } - if !hmp { - log.Warnf("incoming block's miner does not have minimum power") + if !eligible { + log.Warnf("incoming block's miner is ineligible") return address.Undef, ErrInsufficientPower } diff --git a/chain/sync.go b/chain/sync.go index 46d3934b1..655bb4a1d 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -827,13 +827,13 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock, use return xerrors.Errorf("block is not claiming to be a winner") } - hp, err := stmgr.MinerHasMinPower(ctx, syncer.sm, h.Miner, lbts) + eligible, err := stmgr.MinerEligibleToMine(ctx, syncer.sm, h.Miner, baseTs, lbts) if err != nil { return xerrors.Errorf("determining if miner has min power failed: %w", err) } - if !hp { - return xerrors.New("block's miner does not meet minimum power threshold") + if !eligible { + return xerrors.New("block's miner is ineligible to mine") } rBeacon := *prevBeacon From c53cef15267f8124587e313561aec12b1361af00 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Tue, 6 Oct 2020 04:47:00 -0400 Subject: [PATCH 076/115] Update docs --- documentation/en/api-methods.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/documentation/en/api-methods.md b/documentation/en/api-methods.md index 1bae2c1e6..518d38089 100644 --- a/documentation/en/api-methods.md +++ b/documentation/en/api-methods.md @@ -1611,7 +1611,7 @@ Response: "Data": "Ynl0ZSBhcnJheQ==" }, "BeaconEntries": null, - "HasMinPower": true + "EligibleForMining": true } ``` @@ -3531,7 +3531,8 @@ Response: "Multiaddrs": null, "SealProofType": 3, "SectorSize": 34359738368, - "WindowPoStPartitionSectors": 42 + "WindowPoStPartitionSectors": 42, + "ConsensusFaultElapsed": 10101 } ``` From 7a80e356decf0bd36ee976eacf00b43e984fd493 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Tue, 6 Oct 2020 05:05:39 -0400 Subject: [PATCH 077/115] Add a CLI command to set a miner's owner address --- cmd/lotus-storage-miner/actor.go | 118 +++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/cmd/lotus-storage-miner/actor.go b/cmd/lotus-storage-miner/actor.go index ea21aa90d..fa320289e 100644 --- a/cmd/lotus-storage-miner/actor.go +++ b/cmd/lotus-storage-miner/actor.go @@ -5,6 +5,9 @@ import ( "os" "strings" + "github.com/filecoin-project/lotus/build" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + "github.com/fatih/color" "github.com/libp2p/go-libp2p-core/peer" ma "github.com/multiformats/go-multiaddr" @@ -32,6 +35,7 @@ var actorCmd = &cli.Command{ actorSetAddrsCmd, actorWithdrawCmd, actorSetPeeridCmd, + actorSetOwnerCmd, actorControl, }, } @@ -478,3 +482,117 @@ var actorControlSet = &cli.Command{ return nil }, } + +var actorSetOwnerCmd = &cli.Command{ + Name: "set-owner", + Usage: "Set owner address", + ArgsUsage: "[address]", + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "really-do-it", + Usage: "Actually send transaction performing the action", + Value: false, + }, + }, + Action: func(cctx *cli.Context) error { + if !cctx.Bool("really-do-it") { + fmt.Println("Pass --really-do-it to actually execute this action") + return nil + } + + if !cctx.Args().Present() { + return fmt.Errorf("must pass address of new owner address") + } + + nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx) + if err != nil { + return err + } + defer closer() + + api, acloser, err := lcli.GetFullNodeAPI(cctx) + if err != nil { + return err + } + defer acloser() + + ctx := lcli.ReqContext(cctx) + + na, err := address.NewFromString(cctx.Args().First()) + if err != nil { + return err + } + + newAddr, err := api.StateLookupID(ctx, na, types.EmptyTSK) + if err != nil { + return err + } + + maddr, err := nodeApi.ActorAddress(ctx) + if err != nil { + return err + } + + mi, err := api.StateMinerInfo(ctx, maddr, types.EmptyTSK) + if err != nil { + return err + } + + sp, err := actors.SerializeParams(&newAddr) + if err != nil { + return xerrors.Errorf("serializing params: %w", err) + } + + smsg, err := api.MpoolPushMessage(ctx, &types.Message{ + From: mi.Owner, + To: maddr, + Method: builtin2.MethodsMiner.ChangeOwnerAddress, + Value: big.Zero(), + Params: sp, + }, nil) + if err != nil { + return xerrors.Errorf("mpool push: %w", err) + } + + fmt.Println("Propose Message CID:", smsg.Cid()) + + // wait for it to get mined into a block + wait, err := api.StateWaitMsg(ctx, smsg.Cid(), build.MessageConfidence) + if err != nil { + return err + } + + // check it executed successfully + if wait.Receipt.ExitCode != 0 { + fmt.Println("Propose owner change failed!") + return err + } + + smsg, err = api.MpoolPushMessage(ctx, &types.Message{ + From: newAddr, + To: maddr, + Method: builtin2.MethodsMiner.ChangeOwnerAddress, + Value: big.Zero(), + Params: sp, + }, nil) + if err != nil { + return xerrors.Errorf("mpool push: %w", err) + } + + fmt.Println("Approve Message CID:", smsg.Cid()) + + // wait for it to get mined into a block + wait, err = api.StateWaitMsg(ctx, smsg.Cid(), build.MessageConfidence) + if err != nil { + return err + } + + // check it executed successfully + if wait.Receipt.ExitCode != 0 { + fmt.Println("Approve owner change failed!") + return err + } + + return nil + }, +} From 7b556252db0597a3737a24216d495addc47b842d Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Tue, 6 Oct 2020 05:34:53 -0400 Subject: [PATCH 078/115] Use SysErrReserved1 in the event of an actors panic --- chain/vm/runtime.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/chain/vm/runtime.go b/chain/vm/runtime.go index 472017a00..52b2dcd2c 100644 --- a/chain/vm/runtime.go +++ b/chain/vm/runtime.go @@ -122,7 +122,11 @@ func (rt *Runtime) shimCall(f func() interface{}) (rval []byte, aerr aerrors.Act //log.Desugar().WithOptions(zap.AddStacktrace(zapcore.ErrorLevel)). //Sugar().Errorf("spec actors failure: %s", r) log.Errorf("spec actors failure: %s", r) - aerr = aerrors.Newf(1, "spec actors failure: %s", r) + if rt.NetworkVersion() <= network.Version3 { + aerr = aerrors.Newf(1, "spec actors failure: %s", r) + } else { + aerr = aerrors.Newf(exitcode.SysErrReserved1, "spec actors failure: %s", r) + } } }() From 15330396bba66dd18d94516a09807d3eed604298 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 6 Oct 2020 16:53:49 +0200 Subject: [PATCH 079/115] Fix circ supply before v2 upgrade epoch --- chain/stmgr/stmgr.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index b27bed587..ac01ebb61 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -1279,9 +1279,12 @@ func (sm *StateManager) GetCirculatingSupplyDetailed(ctx context.Context, height return api.CirculatingSupply{}, xerrors.Errorf("failed to calculate filVested: %w", err) } - filReserveDisbursed, err := GetFilReserveDisbursed(ctx, st) - if err != nil { - return api.CirculatingSupply{}, xerrors.Errorf("failed to calculate filReserveDisbursed: %w", err) + filReserveDisbursed := big.Zero() + if height > build.UpgradeActorsV2Height { + filReserveDisbursed, err = GetFilReserveDisbursed(ctx, st) + if err != nil { + return api.CirculatingSupply{}, xerrors.Errorf("failed to calculate filReserveDisbursed: %w", err) + } } filMined, err := GetFilMined(ctx, st) From 4a6e9c920dd566f6170beb70d6c30f1891de2137 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 6 Oct 2020 11:42:04 -0700 Subject: [PATCH 080/115] set genesis name in test --- chain/gen/gen.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/chain/gen/gen.go b/chain/gen/gen.go index d05165ab1..3ebd127f3 100644 --- a/chain/gen/gen.go +++ b/chain/gen/gen.go @@ -9,6 +9,7 @@ import ( "time" "github.com/filecoin-project/specs-actors/actors/runtime/proof" + "github.com/google/uuid" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" @@ -224,7 +225,7 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) { }, VerifregRootKey: DefaultVerifregRootkeyActor, RemainderAccount: DefaultRemainderAccountActor, - NetworkName: "", + NetworkName: uuid.New().String(), Timestamp: uint64(build.Clock.Now().Add(-500 * time.Duration(build.BlockDelaySecs) * time.Second).Unix()), } From 256be285ba7910dd2b59c3cf828622463d971d65 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 6 Oct 2020 13:00:06 -0700 Subject: [PATCH 081/115] only enable gas tampering if the breeze upgrade is enabled --- chain/store/basefee.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chain/store/basefee.go b/chain/store/basefee.go index 45785240e..33367abcc 100644 --- a/chain/store/basefee.go +++ b/chain/store/basefee.go @@ -46,7 +46,7 @@ func ComputeNextBaseFee(baseFee types.BigInt, gasLimitUsed int64, noOfBlocks int } func (cs *ChainStore) ComputeBaseFee(ctx context.Context, ts *types.TipSet) (abi.TokenAmount, error) { - if ts.Height() > build.UpgradeBreezeHeight && ts.Height() < build.UpgradeBreezeHeight+build.BreezeGasTampingDuration { + if build.UpgradeBreezeHeight >= 0 && ts.Height() > build.UpgradeBreezeHeight && ts.Height() < build.UpgradeBreezeHeight+build.BreezeGasTampingDuration { return abi.NewTokenAmount(100), nil } From b1818a10555c2962bd241eee2af5dde55b874d10 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 6 Oct 2020 13:12:16 -0700 Subject: [PATCH 082/115] fix base fee tests for different smoke heights --- chain/store/basefee_test.go | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/chain/store/basefee_test.go b/chain/store/basefee_test.go index b4757f70e..b3d414cf5 100644 --- a/chain/store/basefee_test.go +++ b/chain/store/basefee_test.go @@ -11,24 +11,27 @@ import ( func TestBaseFee(t *testing.T) { tests := []struct { - basefee uint64 - limitUsed int64 - noOfBlocks int - output uint64 + basefee uint64 + limitUsed int64 + noOfBlocks int + preSmoke, postSmoke uint64 }{ - {100e6, 0, 1, 87.5e6}, - {100e6, 0, 5, 87.5e6}, - {100e6, build.BlockGasTarget, 1, 103.125e6}, - {100e6, build.BlockGasTarget * 2, 2, 103.125e6}, - {100e6, build.BlockGasLimit * 2, 2, 112.5e6}, - {100e6, build.BlockGasLimit * 1.5, 2, 110937500}, + {100e6, 0, 1, 87.5e6, 87.5e6}, + {100e6, 0, 5, 87.5e6, 87.5e6}, + {100e6, build.BlockGasTarget, 1, 103.125e6, 100e6}, + {100e6, build.BlockGasTarget * 2, 2, 103.125e6, 100e6}, + {100e6, build.BlockGasLimit * 2, 2, 112.5e6, 112.5e6}, + {100e6, build.BlockGasLimit * 1.5, 2, 110937500, 106.250e6}, } for _, test := range tests { test := test t.Run(fmt.Sprintf("%v", test), func(t *testing.T) { - output := ComputeNextBaseFee(types.NewInt(test.basefee), test.limitUsed, test.noOfBlocks, 0) - assert.Equal(t, fmt.Sprintf("%d", test.output), output.String()) + preSmoke := ComputeNextBaseFee(types.NewInt(test.basefee), test.limitUsed, test.noOfBlocks, build.UpgradeSmokeHeight-1) + assert.Equal(t, fmt.Sprintf("%d", test.preSmoke), preSmoke.String()) + + postSmoke := ComputeNextBaseFee(types.NewInt(test.basefee), test.limitUsed, test.noOfBlocks, build.UpgradeSmokeHeight+1) + assert.Equal(t, fmt.Sprintf("%d", test.postSmoke), postSmoke.String()) }) } } From b71b7434200c56f40ace3ce22314171f3e1a0f18 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Sun, 6 Sep 2020 03:48:45 -0400 Subject: [PATCH 083/115] Bugfix: Runtime's Receiver() should only return ID addresses --- chain/vm/mkactor.go | 18 +++++++++--------- chain/vm/vm.go | 12 +++++++++++- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/chain/vm/mkactor.go b/chain/vm/mkactor.go index 33884368f..22a2acb8b 100644 --- a/chain/vm/mkactor.go +++ b/chain/vm/mkactor.go @@ -31,41 +31,41 @@ func init() { var EmptyObjectCid cid.Cid // TryCreateAccountActor creates account actors from only BLS/SECP256K1 addresses. -func TryCreateAccountActor(rt *Runtime, addr address.Address) (*types.Actor, aerrors.ActorError) { +func TryCreateAccountActor(rt *Runtime, addr address.Address) (*types.Actor, address.Address, aerrors.ActorError) { if err := rt.chargeGasSafe(PricelistByEpoch(rt.height).OnCreateActor()); err != nil { - return nil, err + return nil, address.Undef, err } addrID, err := rt.state.RegisterNewAddress(addr) if err != nil { - return nil, aerrors.Escalate(err, "registering actor address") + return nil, address.Undef, aerrors.Escalate(err, "registering actor address") } act, aerr := makeActor(actors.VersionForNetwork(rt.NetworkVersion()), addr) if aerr != nil { - return nil, aerr + return nil, address.Undef, aerr } if err := rt.state.SetActor(addrID, act); err != nil { - return nil, aerrors.Escalate(err, "creating new actor failed") + return nil, address.Undef, aerrors.Escalate(err, "creating new actor failed") } p, err := actors.SerializeParams(&addr) if err != nil { - return nil, aerrors.Escalate(err, "couldn't serialize params for actor construction") + return nil, address.Undef, aerrors.Escalate(err, "couldn't serialize params for actor construction") } // call constructor on account _, aerr = rt.internalSend(builtin0.SystemActorAddr, addrID, builtin0.MethodsAccount.Constructor, big.Zero(), p) if aerr != nil { - return nil, aerrors.Wrap(aerr, "failed to invoke account constructor") + return nil, address.Undef, aerrors.Wrap(aerr, "failed to invoke account constructor") } act, err = rt.state.GetActor(addrID) if err != nil { - return nil, aerrors.Escalate(err, "loading newly created actor failed") + return nil, address.Undef, aerrors.Escalate(err, "loading newly created actor failed") } - return act, nil + return act, addrID, nil } func makeActor(ver actors.Version, addr address.Address) (*types.Actor, aerrors.ActorError) { diff --git a/chain/vm/vm.go b/chain/vm/vm.go index 1361c6fbe..aec356fb4 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -131,6 +131,9 @@ func (vm *VM) makeRuntime(ctx context.Context, msg *types.Message, origin addres rt.Abortf(exitcode.SysErrInvalidReceiver, "resolve msg.From address failed") } vmm.From = resF + resT, _ := rt.ResolveAddress(msg.To) + // may be set to undef if recipient doesn't exist yet + vmm.To = resT rt.Message = vmm return rt @@ -257,11 +260,18 @@ func (vm *VM) send(ctx context.Context, msg *types.Message, parent *Runtime, toActor, err := st.GetActor(msg.To) if err != nil { if xerrors.Is(err, types.ErrActorNotFound) { - a, err := TryCreateAccountActor(rt, msg.To) + a, aid, err := TryCreateAccountActor(rt, msg.To) if err != nil { return nil, aerrors.Wrapf(err, "could not create account") } toActor = a + nmsg := types.Message{ + To: aid, + From: rt.vmsg.Caller(), + Value: rt.vmsg.ValueReceived(), + } + + rt.vmsg = &nmsg } else { return nil, aerrors.Escalate(err, "getting actor") } From 757aa1039fe65202cfedd6c3c6819b41bc2d0473 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Wed, 23 Sep 2020 22:45:53 -0400 Subject: [PATCH 084/115] Panic if runtime's Message has non-ID caller or receiver --- chain/vm/runtime.go | 24 +++++++++++++++++++++++- chain/vm/vm.go | 14 ++++++++------ 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/chain/vm/runtime.go b/chain/vm/runtime.go index 472017a00..4c6bf1848 100644 --- a/chain/vm/runtime.go +++ b/chain/vm/runtime.go @@ -27,8 +27,30 @@ import ( "github.com/filecoin-project/lotus/chain/types" ) +type Message struct { + msg types.Message +} + +func (m *Message) Caller() address.Address { + if m.msg.From.Protocol() != address.ID { + panic("runtime message has a non-ID caller") + } + return m.msg.From +} + +func (m *Message) Receiver() address.Address { + if m.msg.To != address.Undef && m.msg.To.Protocol() != address.ID { + panic("runtime message has a non-ID receiver") + } + return m.msg.To +} + +func (m *Message) ValueReceived() abi.TokenAmount { + return m.msg.Value +} + type Runtime struct { - types.Message + Message rt0.Syscalls ctx context.Context diff --git a/chain/vm/vm.go b/chain/vm/vm.go index aec356fb4..a5072f8c5 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -134,7 +134,7 @@ func (vm *VM) makeRuntime(ctx context.Context, msg *types.Message, origin addres resT, _ := rt.ResolveAddress(msg.To) // may be set to undef if recipient doesn't exist yet vmm.To = resT - rt.Message = vmm + rt.Message = Message{msg: vmm} return rt } @@ -265,13 +265,15 @@ func (vm *VM) send(ctx context.Context, msg *types.Message, parent *Runtime, return nil, aerrors.Wrapf(err, "could not create account") } toActor = a - nmsg := types.Message{ - To: aid, - From: rt.vmsg.Caller(), - Value: rt.vmsg.ValueReceived(), + nmsg := Message{ + msg: types.Message{ + To: aid, + From: rt.Message.Caller(), + Value: rt.Message.ValueReceived(), + }, } - rt.vmsg = &nmsg + rt.Message = nmsg } else { return nil, aerrors.Escalate(err, "getting actor") } From d9fad5fad09764504320e6aa82a7030b42b26a18 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Tue, 6 Oct 2020 01:25:55 -0400 Subject: [PATCH 085/115] Move rt.Message fixes behind fork logic --- chain/vm/runtime.go | 2 +- chain/vm/vm.go | 33 +++++++++++++++++++++------------ 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/chain/vm/runtime.go b/chain/vm/runtime.go index 4c6bf1848..530adfe95 100644 --- a/chain/vm/runtime.go +++ b/chain/vm/runtime.go @@ -50,7 +50,7 @@ func (m *Message) ValueReceived() abi.TokenAmount { } type Runtime struct { - Message + rt0.Message rt0.Syscalls ctx context.Context diff --git a/chain/vm/vm.go b/chain/vm/vm.go index a5072f8c5..bb20c14e9 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -131,10 +131,15 @@ func (vm *VM) makeRuntime(ctx context.Context, msg *types.Message, origin addres rt.Abortf(exitcode.SysErrInvalidReceiver, "resolve msg.From address failed") } vmm.From = resF - resT, _ := rt.ResolveAddress(msg.To) - // may be set to undef if recipient doesn't exist yet - vmm.To = resT - rt.Message = Message{msg: vmm} + + if vm.ntwkVersion(ctx, vm.blockHeight) <= network.Version3 { + rt.Message = &vmm + } else { + resT, _ := rt.ResolveAddress(msg.To) + // may be set to undef if recipient doesn't exist yet + vmm.To = resT + rt.Message = &Message{msg: vmm} + } return rt } @@ -265,15 +270,19 @@ func (vm *VM) send(ctx context.Context, msg *types.Message, parent *Runtime, return nil, aerrors.Wrapf(err, "could not create account") } toActor = a - nmsg := Message{ - msg: types.Message{ - To: aid, - From: rt.Message.Caller(), - Value: rt.Message.ValueReceived(), - }, - } + if vm.ntwkVersion(ctx, vm.blockHeight) <= network.Version3 { + // Leave the rt.Message as is + } else { + nmsg := Message{ + msg: types.Message{ + To: aid, + From: rt.Message.Caller(), + Value: rt.Message.ValueReceived(), + }, + } - rt.Message = nmsg + rt.Message = &nmsg + } } else { return nil, aerrors.Escalate(err, "getting actor") } From 4d6a0f7b8c510e83b862be4639804e8bec9c54bb Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Tue, 6 Oct 2020 05:26:25 -0400 Subject: [PATCH 086/115] Set WinningPoStSectorSetLookback to finality post-v2 actors --- build/params_shared_vals.go | 2 -- build/params_testground.go | 3 +-- chain/actors/policy/policy.go | 8 ++++++++ chain/stmgr/utils.go | 7 ++++--- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/build/params_shared_vals.go b/build/params_shared_vals.go index cc711b7bc..722590575 100644 --- a/build/params_shared_vals.go +++ b/build/params_shared_vals.go @@ -56,8 +56,6 @@ const SealRandomnessLookback = policy.SealRandomnessLookback // Epochs const TicketRandomnessLookback = abi.ChainEpoch(1) -const WinningPoStSectorSetLookback = abi.ChainEpoch(10) - // ///// // Address diff --git a/build/params_testground.go b/build/params_testground.go index 162b3477c..bd064b3d6 100644 --- a/build/params_testground.go +++ b/build/params_testground.go @@ -50,8 +50,7 @@ var ( SealRandomnessLookback = policy.SealRandomnessLookback - TicketRandomnessLookback = abi.ChainEpoch(1) - WinningPoStSectorSetLookback = abi.ChainEpoch(10) + TicketRandomnessLookback = abi.ChainEpoch(1) FilBase uint64 = 2_000_000_000 FilAllocStorageMining uint64 = 1_400_000_000 diff --git a/chain/actors/policy/policy.go b/chain/actors/policy/policy.go index e7f213687..ba09e4424 100644 --- a/chain/actors/policy/policy.go +++ b/chain/actors/policy/policy.go @@ -106,3 +106,11 @@ func SetWPoStChallengeWindow(period abi.ChainEpoch) { miner2.WPoStChallengeWindow = period miner2.WPoStProvingPeriod = period * abi.ChainEpoch(miner2.WPoStPeriodDeadlines) } + +func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch { + if nwVer <= network.Version3 { + return 10 + } + + return ChainFinality +} diff --git a/chain/stmgr/utils.go b/chain/stmgr/utils.go index f2e2bfd19..2c9c5ad94 100644 --- a/chain/stmgr/utils.go +++ b/chain/stmgr/utils.go @@ -12,6 +12,7 @@ import ( "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/network" + "github.com/filecoin-project/lotus/chain/actors/policy" cid "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -29,7 +30,6 @@ import ( exported2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/exported" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/build" init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init" "github.com/filecoin-project/lotus/chain/actors/builtin/market" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" @@ -413,8 +413,9 @@ func ComputeState(ctx context.Context, sm *StateManager, height abi.ChainEpoch, func GetLookbackTipSetForRound(ctx context.Context, sm *StateManager, ts *types.TipSet, round abi.ChainEpoch) (*types.TipSet, error) { var lbr abi.ChainEpoch - if round > build.WinningPoStSectorSetLookback { - lbr = round - build.WinningPoStSectorSetLookback + lb := policy.GetWinningPoStSectorSetLookback(sm.GetNtwkVersion(ctx, round)) + if round > lb { + lbr = round - lb } // more null blocks than our lookback From 00187d4aa8c66ae56ff77274698b773730a3a304 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 6 Oct 2020 11:51:32 -0700 Subject: [PATCH 087/115] update the AMT implementation This change ensures the bitmap is reset on flush. --- go.mod | 1 + go.sum | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index a160389b0..acafdc7c8 100644 --- a/go.mod +++ b/go.mod @@ -23,6 +23,7 @@ require ( github.com/fatih/color v1.8.0 github.com/filecoin-project/filecoin-ffi v0.30.4-0.20200716204036-cddc56607e1d github.com/filecoin-project/go-address v0.0.4 + github.com/filecoin-project/go-amt-ipld/v2 v2.1.1-0.20201006184820-924ee87a1349 // indirect github.com/filecoin-project/go-bitfield v0.2.1 github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 diff --git a/go.sum b/go.sum index 5a00fff77..708ad72c3 100644 --- a/go.sum +++ b/go.sum @@ -228,6 +228,8 @@ github.com/filecoin-project/go-address v0.0.4 h1:gSNMv0qWwH16fGQs7ycOUrDjY6YCSsg github.com/filecoin-project/go-address v0.0.4/go.mod h1:jr8JxKsYx+lQlQZmF5i2U0Z+cGQ59wMIps/8YW/lDj8= github.com/filecoin-project/go-amt-ipld/v2 v2.1.0 h1:t6qDiuGYYngDqaLc2ZUvdtAg4UNxPeOYaXhBWSNsVaM= github.com/filecoin-project/go-amt-ipld/v2 v2.1.0/go.mod h1:nfFPoGyX0CU9SkXX8EoCcSuHN1XcbN0c6KBh7yvP5fs= +github.com/filecoin-project/go-amt-ipld/v2 v2.1.1-0.20201006184820-924ee87a1349 h1:pIuR0dnMD0i+as8wNnjjHyQrnhP5O5bmba/lmgQeRgU= +github.com/filecoin-project/go-amt-ipld/v2 v2.1.1-0.20201006184820-924ee87a1349/go.mod h1:vgmwKBkx+ca5OIeEvstiQgzAZnb7R6QaqE1oEDSqa6g= github.com/filecoin-project/go-bitfield v0.2.0 h1:gCtLcjskIPtdg4NfN7gQZSQF9yrBQ7mkT0qCJxzGI2Q= github.com/filecoin-project/go-bitfield v0.2.0/go.mod h1:CNl9WG8hgR5mttCnUErjcQjGvuiZjRqK9rHVBsQF4oM= github.com/filecoin-project/go-bitfield v0.2.1 h1:S6Uuqcspqu81sWJ0He4OAfFLm1tSwPdVjtKTkl5m/xQ= @@ -1400,6 +1402,7 @@ github.com/whyrusleeping/cbor-gen v0.0.0-20200414195334-429a0b5e922e/go.mod h1:X github.com/whyrusleeping/cbor-gen v0.0.0-20200504204219-64967432584d/go.mod h1:W5MvapuoHRP8rz4vxjwCK1pDqF1aQcWsV5PZ+AHbqdg= github.com/whyrusleeping/cbor-gen v0.0.0-20200710004633-5379fc63235d/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/cbor-gen v0.0.0-20200715143311-227fab5a2377/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= +github.com/whyrusleeping/cbor-gen v0.0.0-20200723185710-6a3894a6352b/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/cbor-gen v0.0.0-20200806213330-63aa96ca5488/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/cbor-gen v0.0.0-20200810223238-211df3b9e24c/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/cbor-gen v0.0.0-20200812213548-958ddffe352c/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= @@ -1525,7 +1528,6 @@ golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm0 golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd h1:zkO/Lhoka23X63N9OSzpSeROEUQ5ODw47tM3YWjygbs= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200513190911-00229845015e h1:rMqLP+9XLy+LdbCXHjJHAmTfXCr93W7oruWA6Hq1Alc= golang.org/x/exp v0.0.0-20200513190911-00229845015e/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= From 15670942c36dd6ffc185ae80152c2cd3f0651eae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 6 Oct 2020 16:29:16 +0200 Subject: [PATCH 088/115] Fix pond --- cmd/lotus-storage-miner/run.go | 16 ++++++++-------- lotuspond/spawn.go | 12 +++++++----- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/cmd/lotus-storage-miner/run.go b/cmd/lotus-storage-miner/run.go index a5d996f78..98a9cfaba 100644 --- a/cmd/lotus-storage-miner/run.go +++ b/cmd/lotus-storage-miner/run.go @@ -33,7 +33,7 @@ var runCmd = &cli.Command{ Usage: "Start a lotus miner process", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "api", + Name: "miner-api", Usage: "2345", }, &cli.BoolFlag{ @@ -61,7 +61,7 @@ var runCmd = &cli.Command{ nodeApi, ncloser, err := lcli.GetFullNodeAPI(cctx) if err != nil { - return err + return xerrors.Errorf("getting full node api: %w", err) } defer ncloser() ctx := lcli.DaemonContext(cctx) @@ -112,29 +112,29 @@ var runCmd = &cli.Command{ node.Online(), node.Repo(r), - node.ApplyIf(func(s *node.Settings) bool { return cctx.IsSet("api") }, + node.ApplyIf(func(s *node.Settings) bool { return cctx.IsSet("miner-api") }, node.Override(new(dtypes.APIEndpoint), func() (dtypes.APIEndpoint, error) { - return multiaddr.NewMultiaddr("/ip4/127.0.0.1/tcp/" + cctx.String("api")) + return multiaddr.NewMultiaddr("/ip4/127.0.0.1/tcp/" + cctx.String("miner-api")) })), node.Override(new(api.FullNode), nodeApi), ) if err != nil { - return err + return xerrors.Errorf("creating node: %w", err) } endpoint, err := r.APIEndpoint() if err != nil { - return err + return xerrors.Errorf("getting API endpoint: %w", err) } // Bootstrap with full node remoteAddrs, err := nodeApi.NetAddrsListen(ctx) if err != nil { - return err + return xerrors.Errorf("getting full node libp2p address: %w", err) } if err := minerapi.NetConnect(ctx, remoteAddrs); err != nil { - return err + return xerrors.Errorf("connecting to full node (libp2p): %w", err) } log.Infof("Remote version %s", v) diff --git a/lotuspond/spawn.go b/lotuspond/spawn.go index 8b2e8661d..ce01b115e 100644 --- a/lotuspond/spawn.go +++ b/lotuspond/spawn.go @@ -11,16 +11,16 @@ import ( "sync/atomic" "time" - "github.com/filecoin-project/lotus/chain/actors/policy" - "github.com/filecoin-project/lotus/chain/types" - + "github.com/google/uuid" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" genesis2 "github.com/filecoin-project/lotus/chain/gen/genesis" + "github.com/filecoin-project/lotus/chain/actors/policy" "github.com/filecoin-project/lotus/chain/gen" + "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/cmd/lotus-seed/seed" "github.com/filecoin-project/lotus/genesis" ) @@ -69,6 +69,8 @@ func (api *api) Spawn() (nodeInfo, error) { Meta: (&genesis.AccountMeta{Owner: genm.Owner}).ActorMeta(), }) template.VerifregRootKey = gen.DefaultVerifregRootkeyActor + template.RemainderAccount = gen.DefaultRemainderAccountActor + template.NetworkName = "pond-" + uuid.New().String() tb, err := json.Marshal(&template) if err != nil { @@ -188,7 +190,7 @@ func (api *api) SpawnStorage(fullNodeRepo string) (nodeInfo, error) { mux := newWsMux() - cmd = exec.Command("./lotus-miner", "run", "--api", fmt.Sprintf("%d", 2500+id), "--nosync") + cmd = exec.Command("./lotus-miner", "run", "--miner-api", fmt.Sprintf("%d", 2500+id), "--nosync") cmd.Stderr = io.MultiWriter(os.Stderr, errlogfile, mux.errpw) cmd.Stdout = io.MultiWriter(os.Stdout, logfile, mux.outpw) cmd.Env = append(os.Environ(), "LOTUS_MINER_PATH="+dir, "LOTUS_PATH="+fullNodeRepo) @@ -248,7 +250,7 @@ func (api *api) RestartNode(id int32) (nodeInfo, error) { var cmd *exec.Cmd if nd.meta.Storage { - cmd = exec.Command("./lotus-miner", "run", "--api", fmt.Sprintf("%d", 2500+id), "--nosync") + cmd = exec.Command("./lotus-miner", "run", "--miner-api", fmt.Sprintf("%d", 2500+id), "--nosync") } else { cmd = exec.Command("./lotus", "daemon", "--api", fmt.Sprintf("%d", 2500+id)) } From 839d1121ce5845d0ba302bd1d1543376793ca10f Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Tue, 6 Oct 2020 18:56:42 -0400 Subject: [PATCH 089/115] Update to actors v2.0.1 --- chain/actors/builtin/miner/v2.go | 2 +- go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/chain/actors/builtin/miner/v2.go b/chain/actors/builtin/miner/v2.go index e2b53e9a6..eed82257f 100644 --- a/chain/actors/builtin/miner/v2.go +++ b/chain/actors/builtin/miner/v2.go @@ -46,7 +46,7 @@ type partition2 struct { } func (s *state2) AvailableBalance(bal abi.TokenAmount) (abi.TokenAmount, error) { - return s.GetAvailableBalance(bal), nil + return s.GetAvailableBalance(bal) } func (s *state2) VestedFunds(epoch abi.ChainEpoch) (abi.TokenAmount, error) { diff --git a/go.mod b/go.mod index 6f8a23a9d..8a25b3232 100644 --- a/go.mod +++ b/go.mod @@ -39,7 +39,7 @@ require ( github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b github.com/filecoin-project/specs-actors v0.9.12 - github.com/filecoin-project/specs-actors/v2 v2.0.0-20201002200957-bdd876b3bbe9 + github.com/filecoin-project/specs-actors/v2 v2.0.1 github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796 github.com/filecoin-project/test-vectors/schema v0.0.3 github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 diff --git a/go.sum b/go.sum index 708ad72c3..6062ee4ee 100644 --- a/go.sum +++ b/go.sum @@ -276,8 +276,8 @@ github.com/filecoin-project/specs-actors v0.9.4/go.mod h1:BStZQzx5x7TmCkLv0Bpa07 github.com/filecoin-project/specs-actors v0.9.7/go.mod h1:wM2z+kwqYgXn5Z7scV1YHLyd1Q1cy0R8HfTIWQ0BFGU= github.com/filecoin-project/specs-actors v0.9.12 h1:iIvk58tuMtmloFNHhAOQHG+4Gci6Lui0n7DYQGi3cJk= github.com/filecoin-project/specs-actors v0.9.12/go.mod h1:TS1AW/7LbG+615j4NsjMK1qlpAwaFsG9w0V2tg2gSao= -github.com/filecoin-project/specs-actors/v2 v2.0.0-20201002200957-bdd876b3bbe9 h1:UXVcGwUD9GJYNcgfGbf7ok790wrunvUhl5ZlgApGhGs= -github.com/filecoin-project/specs-actors/v2 v2.0.0-20201002200957-bdd876b3bbe9/go.mod h1:52FuQUNDXq2WDg+6+UOhkqBuNc2e62h9BCIB67Bluxg= +github.com/filecoin-project/specs-actors/v2 v2.0.1 h1:bf08x6tqCDfClzrv2q/rmt/A/UbBOy1KgaoogQEcLhU= +github.com/filecoin-project/specs-actors/v2 v2.0.1/go.mod h1:v2NZVYinNIKA9acEMBm5wWXxqv5+frFEbekBFemYghY= github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796 h1:dJsTPWpG2pcTeojO2pyn0c6l+x/3MZYCBgo/9d11JEk= github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796/go.mod h1:nJRRM7Aa9XVvygr3W9k6xGF46RWzr2zxF/iGoAIfA/g= github.com/filecoin-project/test-vectors/schema v0.0.3 h1:1zuBo25B3016inbygYLgYFdpJ2m1BDTbAOCgABRleiU= From c23f1623a1a3ef52b09291b6ec40e2560120355d Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Tue, 6 Oct 2020 20:48:00 -0400 Subject: [PATCH 090/115] Fix test --- cmd/lotus-storage-miner/allinfo_test.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cmd/lotus-storage-miner/allinfo_test.go b/cmd/lotus-storage-miner/allinfo_test.go index 562714fa0..8f744c4b3 100644 --- a/cmd/lotus-storage-miner/allinfo_test.go +++ b/cmd/lotus-storage-miner/allinfo_test.go @@ -5,6 +5,8 @@ import ( "testing" "time" + "github.com/filecoin-project/lotus/node" + logging "github.com/ipfs/go-log/v2" "github.com/stretchr/testify/require" "github.com/urfave/cli/v2" @@ -62,8 +64,8 @@ func TestMinerAllInfo(t *testing.T) { require.NoError(t, infoAllCmd.Action(cctx)) } - bp := func(t *testing.T, nFull int, storage []test.StorageMiner) ([]test.TestNode, []test.TestStorageNode) { - n, sn = builder.Builder(t, nFull, storage) + bp := func(t *testing.T, nFull int, storage []test.StorageMiner, opts ...node.Option) ([]test.TestNode, []test.TestStorageNode) { + n, sn = builder.Builder(t, nFull, storage, opts...) t.Run("pre-info-all", run) From b7c8f65af5c474310d988b59da0d036b9d252a26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 7 Oct 2020 01:15:19 +0200 Subject: [PATCH 091/115] stmgr: Make v2 upgrade faster --- chain/stmgr/forks.go | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/chain/stmgr/forks.go b/chain/stmgr/forks.go index d5d0dbf7e..8143524c0 100644 --- a/chain/stmgr/forks.go +++ b/chain/stmgr/forks.go @@ -4,6 +4,9 @@ import ( "bytes" "context" "encoding/binary" + "github.com/filecoin-project/lotus/chain/store" + bstore "github.com/filecoin-project/lotus/lib/blockstore" + "github.com/filecoin-project/lotus/lib/bufbstore" "math" "github.com/filecoin-project/go-address" @@ -490,7 +493,8 @@ func UpgradeIgnition(ctx context.Context, sm *StateManager, cb ExecCallback, roo } func UpgradeActorsV2(ctx context.Context, sm *StateManager, cb ExecCallback, root cid.Cid, ts *types.TipSet) (cid.Cid, error) { - store := sm.cs.Store(ctx) + buf := bufbstore.NewTieredBstore(sm.cs.Blockstore(), bstore.NewTemporarySync()) + store := store.ActorStore(ctx, buf) epoch := ts.Height() - 1 @@ -538,6 +542,15 @@ func UpgradeActorsV2(ctx context.Context, sm *StateManager, cb ExecCallback, roo return cid.Undef, xerrors.Errorf("failed to load init actor after upgrade: %w", err) } + { + 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 } From 3b12a9f425c81715bf9fe0ad8087b6b880aee437 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Tue, 6 Oct 2020 16:38:31 -0700 Subject: [PATCH 092/115] Add flag to accept previous output of compute-state as input --- cli/state.go | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/cli/state.go b/cli/state.go index cb1c974a7..b2beb8ffb 100644 --- a/cli/state.go +++ b/cli/state.go @@ -7,6 +7,7 @@ import ( "fmt" "html/template" "io" + "io/ioutil" "os" "reflect" "sort" @@ -32,6 +33,7 @@ import ( "github.com/filecoin-project/go-state-types/exitcode" "github.com/filecoin-project/lotus/api" + lapi "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/apibstore" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/state" @@ -823,6 +825,10 @@ var stateComputeStateCmd = &cli.Command{ Name: "json", Usage: "generate json output", }, + &cli.StringFlag{ + Name: "compute-state-output", + Usage: "a json file containing pre-existing compute-state output, to generate html reports without rerunning state changes", + }, }, Action: func(cctx *cli.Context) error { api, closer, err := GetFullNodeAPI(cctx) @@ -862,9 +868,26 @@ var stateComputeStateCmd = &cli.Command{ } } - stout, err := api.StateCompute(ctx, h, msgs, ts.Key()) - if err != nil { - return err + var stout *lapi.ComputeStateOutput + if csofile := cctx.String("compute-state-output"); csofile != "" { + data, err := ioutil.ReadFile(csofile) + if err != nil { + return err + } + + var o lapi.ComputeStateOutput + if err := json.Unmarshal(data, &o); err != nil { + return err + } + + stout = &o + } else { + o, err := api.StateCompute(ctx, h, msgs, ts.Key()) + if err != nil { + return err + } + + stout = o } if cctx.Bool("json") { From d6fa64497446d8f8337b16411e840bcdaa46ded4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 7 Oct 2020 14:10:23 +0200 Subject: [PATCH 093/115] Fix lint --- chain/stmgr/forks.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/chain/stmgr/forks.go b/chain/stmgr/forks.go index 8143524c0..2c2304a1f 100644 --- a/chain/stmgr/forks.go +++ b/chain/stmgr/forks.go @@ -4,9 +4,6 @@ import ( "bytes" "context" "encoding/binary" - "github.com/filecoin-project/lotus/chain/store" - bstore "github.com/filecoin-project/lotus/lib/blockstore" - "github.com/filecoin-project/lotus/lib/bufbstore" "math" "github.com/filecoin-project/go-address" @@ -33,8 +30,11 @@ import ( init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init" "github.com/filecoin-project/lotus/chain/actors/builtin/multisig" "github.com/filecoin-project/lotus/chain/state" + "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/vm" + bstore "github.com/filecoin-project/lotus/lib/blockstore" + "github.com/filecoin-project/lotus/lib/bufbstore" ) type UpgradeFunc func(context.Context, *StateManager, ExecCallback, cid.Cid, *types.TipSet) (cid.Cid, error) @@ -547,7 +547,7 @@ func UpgradeActorsV2(ctx context.Context, sm *StateManager, cb ExecCallback, roo to := buf.Read() if err := vm.Copy(ctx, from, to, newRoot); err != nil { - return cid.Undef, xerrors.Errorf("copying migrated tree: %w", err) + return cid.Undef, xerrors.Errorf("copying migrated tree: %w", err) } } From 0d34881a0ca3b3b823dfd3c16e84e66625b1c331 Mon Sep 17 00:00:00 2001 From: Travis Person Date: Wed, 7 Oct 2020 18:50:50 +0000 Subject: [PATCH 094/115] lotus-pcr: ignore all other messages --- cmd/lotus-pcr/main.go | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/cmd/lotus-pcr/main.go b/cmd/lotus-pcr/main.go index 14f4778c2..5b59ff03d 100644 --- a/cmd/lotus-pcr/main.go +++ b/cmd/lotus-pcr/main.go @@ -1037,29 +1037,22 @@ func (r *refunder) ProcessTipset(ctx context.Context, tipset *types.TipSet, refu } var messageMethod string + var processed bool if m.To == builtin.StorageMarketActorAddr { - var err error - var processed bool processed, messageMethod, refundValue, err = r.processTipsetStorageMarketActor(ctx, tipset, msg, recps[i]) - if err != nil { - continue - } - if !processed { - continue - } } if a.IsStorageMinerActor() { - var err error - var processed bool processed, messageMethod, refundValue, err = r.processTipsetStorageMinerActor(ctx, tipset, msg, recps[i]) - if err != nil { - continue - } - if !processed { - continue - } + } + + if err != nil { + log.Errorw("error while processing message", "cid", msg.Cid) + continue + } + if !processed { + continue } log.Debugw( From 5bd6a3cdadd47fc5f26027b522fd0e94724350df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Wed, 7 Oct 2020 19:52:37 +0100 Subject: [PATCH 095/115] conformance: record randomness in tvx; replay in driver. --- cmd/tvx/extract.go | 10 ++++- conformance/rand_record.go | 86 ++++++++++++++++++++++++++++++++++++++ conformance/rand_replay.go | 78 ++++++++++++++++++++++++++++++++++ conformance/runner.go | 1 + go.mod | 2 +- go.sum | 4 +- 6 files changed, 177 insertions(+), 4 deletions(-) create mode 100644 conformance/rand_record.go create mode 100644 conformance/rand_replay.go diff --git a/cmd/tvx/extract.go b/cmd/tvx/extract.go index afdeb9540..b0ed574df 100644 --- a/cmd/tvx/extract.go +++ b/cmd/tvx/extract.go @@ -200,6 +200,8 @@ func doExtract(ctx context.Context, fapi api.FullNode, opts extractOpts) error { Message: m, CircSupply: circSupplyDetail.FilCirculating, BaseFee: basefee, + // recorded randomness will be discarded. + Rand: conformance.NewRecordingRand(new(conformance.LogReporter), fapi), }) if err != nil { return fmt.Errorf("failed to execute precursor message: %w", err) @@ -212,6 +214,9 @@ func doExtract(ctx context.Context, fapi api.FullNode, opts extractOpts) error { applyret *vm.ApplyRet carWriter func(w io.Writer) error retention = opts.retain + + // recordingRand will record randomness so we can embed it in the test vector. + recordingRand = conformance.NewRecordingRand(new(conformance.LogReporter), fapi) ) log.Printf("using state retention strategy: %s", retention) @@ -231,6 +236,7 @@ func doExtract(ctx context.Context, fapi api.FullNode, opts extractOpts) error { Message: msg, CircSupply: circSupplyDetail.FilCirculating, BaseFee: basefee, + Rand: recordingRand, }) if err != nil { return fmt.Errorf("failed to execute message: %w", err) @@ -262,6 +268,7 @@ func doExtract(ctx context.Context, fapi api.FullNode, opts extractOpts) error { Message: msg, CircSupply: circSupplyDetail.FilCirculating, BaseFee: basefee, + Rand: recordingRand, }) if err != nil { return fmt.Errorf("failed to execute message: %w", err) @@ -356,7 +363,8 @@ func doExtract(ctx context.Context, fapi api.FullNode, opts extractOpts) error { {Source: fmt.Sprintf("execution_tipset:%s", execTs.Key().String())}, {Source: "github.com/filecoin-project/lotus", Version: version.String()}}, }, - CAR: out.Bytes(), + Randomness: recordingRand.Recorded(), + CAR: out.Bytes(), Pre: &schema.Preconditions{ Epoch: int64(execTs.Height()), CircSupply: circSupply.Int, diff --git a/conformance/rand_record.go b/conformance/rand_record.go new file mode 100644 index 000000000..2d3477c94 --- /dev/null +++ b/conformance/rand_record.go @@ -0,0 +1,86 @@ +package conformance + +import ( + "context" + "sync" + + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/crypto" + + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/chain/vm" + "github.com/filecoin-project/test-vectors/schema" +) + +type RecordingRand struct { + reporter Reporter + api api.FullNode + + lk sync.Mutex + recorded schema.Randomness +} + +var _ vm.Rand = (*RecordingRand)(nil) + +// NewRecordingRand returns a vm.Rand implementation that proxies calls to a +// full Lotus node via JSON-RPC, and records matching rules and responses so +// they can later be embedded in test vectors. +func NewRecordingRand(reporter Reporter, api api.FullNode) *RecordingRand { + return &RecordingRand{reporter: reporter, api: api} +} + +func (r *RecordingRand) GetChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) { + ret, err := r.api.ChainGetRandomnessFromTickets(ctx, types.EmptyTSK, pers, round, entropy) + if err != nil { + return ret, err + } + + r.reporter.Logf("fetched and recorded chain randomness for: dst=%d, epoch=%d, entropy=%x, result=%x", pers, round, entropy, ret) + + match := schema.RandomnessMatch{ + On: schema.RandomnessRule{ + Kind: schema.RandomnessChain, + DomainSeparationTag: int64(pers), + Epoch: int64(round), + Entropy: entropy, + }, + Return: []byte(ret), + } + r.lk.Lock() + r.recorded = append(r.recorded, match) + r.lk.Unlock() + + return ret, err +} + +func (r *RecordingRand) GetBeaconRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) { + ret, err := r.api.ChainGetRandomnessFromBeacon(ctx, types.EmptyTSK, pers, round, entropy) + if err != nil { + return ret, err + } + + r.reporter.Logf("fetched and recorded beacon randomness for: dst=%d, epoch=%d, entropy=%x, result=%x", pers, round, entropy, ret) + + match := schema.RandomnessMatch{ + On: schema.RandomnessRule{ + Kind: schema.RandomnessBeacon, + DomainSeparationTag: int64(pers), + Epoch: int64(round), + Entropy: entropy, + }, + Return: []byte(ret), + } + r.lk.Lock() + r.recorded = append(r.recorded, match) + r.lk.Unlock() + + return ret, err +} + +func (r *RecordingRand) Recorded() schema.Randomness { + r.lk.Lock() + defer r.lk.Unlock() + + return r.recorded +} diff --git a/conformance/rand_replay.go b/conformance/rand_replay.go new file mode 100644 index 000000000..b820b8ced --- /dev/null +++ b/conformance/rand_replay.go @@ -0,0 +1,78 @@ +package conformance + +import ( + "bytes" + "context" + + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/crypto" + + "github.com/filecoin-project/lotus/chain/vm" + "github.com/filecoin-project/test-vectors/schema" +) + +type ReplayingRand struct { + reporter Reporter + recorded schema.Randomness + fallback vm.Rand +} + +var _ vm.Rand = (*ReplayingRand)(nil) + +// NewReplayingRand replays recorded randomness when requested, falling back to +// fixed randomness if the value cannot be found; hence this is a safe +// backwards-compatible replacement for fixedRand. +func NewReplayingRand(reporter Reporter, recorded schema.Randomness) *ReplayingRand { + return &ReplayingRand{ + reporter: reporter, + recorded: recorded, + fallback: NewFixedRand(), + } +} + +func (r *ReplayingRand) match(requested schema.RandomnessRule) ([]byte, bool) { + for _, other := range r.recorded { + if other.On.Kind == requested.Kind && + other.On.Epoch == requested.Epoch && + other.On.DomainSeparationTag == requested.DomainSeparationTag && + bytes.Equal(other.On.Entropy, requested.Entropy) { + return other.Return, true + } + } + return nil, false +} + +func (r *ReplayingRand) GetChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) { + rule := schema.RandomnessRule{ + Kind: schema.RandomnessChain, + DomainSeparationTag: int64(pers), + Epoch: int64(round), + Entropy: entropy, + } + + if ret, ok := r.match(rule); ok { + r.reporter.Logf("returning saved chain randomness: dst=%d, epoch=%d, entropy=%x, result=%x", pers, round, entropy, ret) + return ret, nil + } + + r.reporter.Logf("returning fallback chain randomness: dst=%d, epoch=%d, entropy=%x", pers, round, entropy) + return r.fallback.GetChainRandomness(ctx, pers, round, entropy) +} + +func (r *ReplayingRand) GetBeaconRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) { + rule := schema.RandomnessRule{ + Kind: schema.RandomnessBeacon, + DomainSeparationTag: int64(pers), + Epoch: int64(round), + Entropy: entropy, + } + + if ret, ok := r.match(rule); ok { + r.reporter.Logf("returning saved beacon randomness: dst=%d, epoch=%d, entropy=%x, result=%x", pers, round, entropy, ret) + return ret, nil + } + + r.reporter.Logf("returning fallback beacon randomness: dst=%d, epoch=%d, entropy=%x", pers, round, entropy) + return r.fallback.GetBeaconRandomness(ctx, pers, round, entropy) + +} diff --git a/conformance/runner.go b/conformance/runner.go index a240c9067..3897ad853 100644 --- a/conformance/runner.go +++ b/conformance/runner.go @@ -66,6 +66,7 @@ func ExecuteMessageVector(r Reporter, vector *schema.TestVector) { Message: msg, BaseFee: BaseFeeOrDefault(vector.Pre.BaseFee), CircSupply: CircSupplyOrDefault(vector.Pre.CircSupply), + Rand: NewReplayingRand(r, vector.Randomness), }) if err != nil { r.Fatalf("fatal failure when executing message: %s", err) diff --git a/go.mod b/go.mod index 170dc3003..e401af36d 100644 --- a/go.mod +++ b/go.mod @@ -39,7 +39,7 @@ require ( github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b github.com/filecoin-project/specs-actors v0.9.11 github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796 - github.com/filecoin-project/test-vectors/schema v0.0.3 + github.com/filecoin-project/test-vectors/schema v0.0.4-0.20201007174510-548c9399aa6a github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 github.com/go-kit/kit v0.10.0 github.com/go-ole/go-ole v1.2.4 // indirect diff --git a/go.sum b/go.sum index e820ede3a..7d6c743ae 100644 --- a/go.sum +++ b/go.sum @@ -274,8 +274,8 @@ github.com/filecoin-project/specs-actors v0.9.11 h1:TnpG7HAeiUrfj0mJM7UaPW0P2137 github.com/filecoin-project/specs-actors v0.9.11/go.mod h1:czlvLQGEX0fjLLfdNHD7xLymy6L3n7aQzRWzsYGf+ys= github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796 h1:dJsTPWpG2pcTeojO2pyn0c6l+x/3MZYCBgo/9d11JEk= github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796/go.mod h1:nJRRM7Aa9XVvygr3W9k6xGF46RWzr2zxF/iGoAIfA/g= -github.com/filecoin-project/test-vectors/schema v0.0.3 h1:1zuBo25B3016inbygYLgYFdpJ2m1BDTbAOCgABRleiU= -github.com/filecoin-project/test-vectors/schema v0.0.3/go.mod h1:iQ9QXLpYWL3m7warwvK1JC/pTri8mnfEmKygNDqqY6E= +github.com/filecoin-project/test-vectors/schema v0.0.4-0.20201007174510-548c9399aa6a h1:2jRLaT3/sHyAinWR2asCAkvzcnOAIi13eTlWf3YEVvY= +github.com/filecoin-project/test-vectors/schema v0.0.4-0.20201007174510-548c9399aa6a/go.mod h1:iQ9QXLpYWL3m7warwvK1JC/pTri8mnfEmKygNDqqY6E= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6 h1:u/UEqS66A5ckRmS4yNpjmVH56sVtS/RfclBAYocb4as= github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6/go.mod h1:1i71OnUq3iUe1ma7Lr6yG6/rjvM3emb6yoL7xLFzcVQ= From e803cf151f1dd6df0dd30681a44665a07e7b4ef9 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 6 Oct 2020 15:22:54 -0700 Subject: [PATCH 096/115] introduce separate state-tree versions Instead of versioning the state tree along with the actors, version it separately. This structure may not upgrade every time we update actors. --- chain/gen/genesis/genesis.go | 3 +- chain/state/statetree.go | 56 ++++++++++++++++++-------- chain/state/statetree_test.go | 13 +++--- chain/stmgr/forks.go | 2 +- chain/types/cbor_gen.go | 16 ++++---- chain/types/state.go | 17 ++++++-- gen/main.go | 2 +- lotuspond/front/src/chain/methods.json | 3 +- 8 files changed, 73 insertions(+), 39 deletions(-) diff --git a/chain/gen/genesis/genesis.go b/chain/gen/genesis/genesis.go index f532b9f5e..9f15ecaed 100644 --- a/chain/gen/genesis/genesis.go +++ b/chain/gen/genesis/genesis.go @@ -26,7 +26,6 @@ import ( adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" @@ -117,7 +116,7 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge return nil, nil, xerrors.Errorf("putting empty object: %w", err) } - state, err := state.NewStateTree(cst, actors.Version0) + state, err := state.NewStateTree(cst, types.StateTreeVersion0) if err != nil { return nil, nil, xerrors.Errorf("making new state tree: %w", err) } diff --git a/chain/state/statetree.go b/chain/state/statetree.go index 3f9597420..e9b76ea77 100644 --- a/chain/state/statetree.go +++ b/chain/state/statetree.go @@ -13,6 +13,7 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/lotus/chain/actors" init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init" cbg "github.com/whyrusleeping/cbor-gen" @@ -26,7 +27,7 @@ var log = logging.Logger("statetree") // StateTree stores actors state by their ID. type StateTree struct { root adt.Map - version actors.Version // TODO + version types.StateTreeVersion info cid.Cid Store cbor.IpldStore @@ -120,21 +121,41 @@ func (ss *stateSnaps) deleteActor(addr address.Address) { ss.layers[len(ss.layers)-1].actors[addr] = streeOp{Delete: true} } -func NewStateTree(cst cbor.IpldStore, version actors.Version) (*StateTree, error) { +// VersionForNetwork returns the state tree version for the given network +// version. +func VersionForNetwork(ver network.Version) types.StateTreeVersion { + if actors.VersionForNetwork(ver) == actors.Version0 { + return types.StateTreeVersion0 + } + return types.StateTreeVersion1 +} + +func adtForSTVersion(ver types.StateTreeVersion) actors.Version { + switch ver { + case types.StateTreeVersion0: + return actors.Version0 + case types.StateTreeVersion1: + return actors.Version2 + default: + panic("unhandled state tree version") + } +} + +func NewStateTree(cst cbor.IpldStore, ver types.StateTreeVersion) (*StateTree, error) { var info cid.Cid - switch version { - case actors.Version0: + switch ver { + case types.StateTreeVersion0: // info is undefined - case actors.Version2: + case types.StateTreeVersion1: var err error - info, err = cst.Put(context.TODO(), new(types.StateInfo)) + info, err = cst.Put(context.TODO(), new(types.StateInfo0)) if err != nil { return nil, err } default: - return nil, xerrors.Errorf("unsupported state tree version: %d", version) + return nil, xerrors.Errorf("unsupported state tree version: %d", ver) } - root, err := adt.NewMap(adt.WrapStore(context.TODO(), cst), version) + root, err := adt.NewMap(adt.WrapStore(context.TODO(), cst), adtForSTVersion(ver)) if err != nil { return nil, err } @@ -142,7 +163,7 @@ func NewStateTree(cst cbor.IpldStore, version actors.Version) (*StateTree, error return &StateTree{ root: root, info: info, - version: version, + version: ver, Store: cst, snaps: newStateSnaps(), }, nil @@ -154,13 +175,16 @@ func LoadStateTree(cst cbor.IpldStore, c cid.Cid) (*StateTree, error) { if err := cst.Get(context.TODO(), c, &root); err != nil { // We failed to decode as the new version, must be an old version. root.Actors = c - root.Version = actors.Version0 + root.Version = types.StateTreeVersion0 } switch root.Version { - case actors.Version0, actors.Version2: + case types.StateTreeVersion0, types.StateTreeVersion1: // Load the actual state-tree HAMT. - nd, err := adt.AsMap(adt.WrapStore(context.TODO(), cst), root.Actors, actors.Version(root.Version)) + nd, err := adt.AsMap( + adt.WrapStore(context.TODO(), cst), root.Actors, + adtForSTVersion(root.Version), + ) if err != nil { log.Errorf("loading hamt node %s failed: %s", c, err) return nil, err @@ -169,7 +193,7 @@ func LoadStateTree(cst cbor.IpldStore, c cid.Cid) (*StateTree, error) { return &StateTree{ root: nd, info: root.Info, - version: actors.Version(root.Version), + version: root.Version, Store: cst, snaps: newStateSnaps(), }, nil @@ -309,11 +333,11 @@ func (st *StateTree) Flush(ctx context.Context) (cid.Cid, error) { return cid.Undef, xerrors.Errorf("failed to flush state-tree hamt: %w", err) } // If we're version 0, return a raw tree. - if st.version == actors.Version0 { + if st.version == types.StateTreeVersion0 { return root, nil } // Otherwise, return a versioned tree. - return st.Store.Put(ctx, &types.StateRoot{Version: uint64(st.version), Actors: root, Info: st.info}) + return st.Store.Put(ctx, &types.StateRoot{Version: st.version, Actors: root, Info: st.info}) } func (st *StateTree) Snapshot(ctx context.Context) error { @@ -400,7 +424,7 @@ func (st *StateTree) ForEach(f func(address.Address, *types.Actor) error) error } // Version returns the version of the StateTree data structure in use. -func (st *StateTree) Version() actors.Version { +func (st *StateTree) Version() types.StateTreeVersion { return st.version } diff --git a/chain/state/statetree_test.go b/chain/state/statetree_test.go index 3b08a4b53..ed1fb1889 100644 --- a/chain/state/statetree_test.go +++ b/chain/state/statetree_test.go @@ -13,13 +13,12 @@ import ( "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/types" ) func BenchmarkStateTreeSet(b *testing.B) { cst := cbor.NewMemCborStore() - st, err := NewStateTree(cst, actors.VersionForNetwork(build.NewestNetworkVersion)) + st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion)) if err != nil { b.Fatal(err) } @@ -46,7 +45,7 @@ func BenchmarkStateTreeSet(b *testing.B) { func BenchmarkStateTreeSetFlush(b *testing.B) { cst := cbor.NewMemCborStore() - st, err := NewStateTree(cst, actors.VersionForNetwork(build.NewestNetworkVersion)) + st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion)) if err != nil { b.Fatal(err) } @@ -76,7 +75,7 @@ func BenchmarkStateTreeSetFlush(b *testing.B) { func BenchmarkStateTree10kGetActor(b *testing.B) { cst := cbor.NewMemCborStore() - st, err := NewStateTree(cst, actors.VersionForNetwork(build.NewestNetworkVersion)) + st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion)) if err != nil { b.Fatal(err) } @@ -118,7 +117,7 @@ func BenchmarkStateTree10kGetActor(b *testing.B) { func TestSetCache(t *testing.T) { cst := cbor.NewMemCborStore() - st, err := NewStateTree(cst, actors.VersionForNetwork(build.NewestNetworkVersion)) + st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion)) if err != nil { t.Fatal(err) } @@ -155,7 +154,7 @@ func TestSetCache(t *testing.T) { func TestSnapshots(t *testing.T) { ctx := context.Background() cst := cbor.NewMemCborStore() - st, err := NewStateTree(cst, actors.VersionForNetwork(build.NewestNetworkVersion)) + st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion)) if err != nil { t.Fatal(err) } @@ -239,7 +238,7 @@ func assertNotHas(t *testing.T, st *StateTree, addr address.Address) { func TestStateTreeConsistency(t *testing.T) { cst := cbor.NewMemCborStore() // TODO: ActorUpgrade: this test tests pre actors v2 - st, err := NewStateTree(cst, actors.VersionForNetwork(network.Version3)) + st, err := NewStateTree(cst, VersionForNetwork(network.Version3)) if err != nil { t.Fatal(err) } diff --git a/chain/stmgr/forks.go b/chain/stmgr/forks.go index d5d0dbf7e..fd6058127 100644 --- a/chain/stmgr/forks.go +++ b/chain/stmgr/forks.go @@ -494,7 +494,7 @@ func UpgradeActorsV2(ctx context.Context, sm *StateManager, cb ExecCallback, roo epoch := ts.Height() - 1 - info, err := store.Put(ctx, new(types.StateInfo)) + info, err := store.Put(ctx, new(types.StateInfo0)) if err != nil { return cid.Undef, xerrors.Errorf("failed to create new state info for actors v2: %w", err) } diff --git a/chain/types/cbor_gen.go b/chain/types/cbor_gen.go index f95df33bc..d063ce8c9 100644 --- a/chain/types/cbor_gen.go +++ b/chain/types/cbor_gen.go @@ -1648,7 +1648,7 @@ func (t *StateRoot) MarshalCBOR(w io.Writer) error { scratch := make([]byte, 9) - // t.Version (uint64) (uint64) + // t.Version (types.StateTreeVersion) (uint64) if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajUnsignedInt, uint64(t.Version)); err != nil { return err @@ -1687,7 +1687,7 @@ func (t *StateRoot) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("cbor input had wrong number of fields") } - // t.Version (uint64) (uint64) + // t.Version (types.StateTreeVersion) (uint64) { @@ -1698,7 +1698,7 @@ func (t *StateRoot) UnmarshalCBOR(r io.Reader) error { if maj != cbg.MajUnsignedInt { return fmt.Errorf("wrong type for uint64 field") } - t.Version = uint64(extra) + t.Version = StateTreeVersion(extra) } // t.Actors (cid.Cid) (struct) @@ -1728,22 +1728,22 @@ func (t *StateRoot) UnmarshalCBOR(r io.Reader) error { return nil } -var lengthBufStateInfo = []byte{128} +var lengthBufStateInfo0 = []byte{128} -func (t *StateInfo) MarshalCBOR(w io.Writer) error { +func (t *StateInfo0) MarshalCBOR(w io.Writer) error { if t == nil { _, err := w.Write(cbg.CborNull) return err } - if _, err := w.Write(lengthBufStateInfo); err != nil { + if _, err := w.Write(lengthBufStateInfo0); err != nil { return err } return nil } -func (t *StateInfo) UnmarshalCBOR(r io.Reader) error { - *t = StateInfo{} +func (t *StateInfo0) UnmarshalCBOR(r io.Reader) error { + *t = StateInfo0{} br := cbg.GetPeeker(r) scratch := make([]byte, 8) diff --git a/chain/types/state.go b/chain/types/state.go index b99eb19c2..a96883604 100644 --- a/chain/types/state.go +++ b/chain/types/state.go @@ -2,9 +2,20 @@ package types import "github.com/ipfs/go-cid" +// StateTreeVersion is the version of the state tree itself, independent of the +// network version or the actors version. +type StateTreeVersion uint64 + +const ( + // StateTreeVersion0 corresponds to actors < v2. + StateTreeVersion0 StateTreeVersion = iota + // StateTreeVersion1 corresponds to actors >= v2. + StateTreeVersion1 +) + type StateRoot struct { - // State root version. Versioned along with actors (for now). - Version uint64 + // State tree version. + Version StateTreeVersion // Actors tree. The structure depends on the state root version. Actors cid.Cid // Info. The structure depends on the state root version. @@ -12,4 +23,4 @@ type StateRoot struct { } // TODO: version this. -type StateInfo struct{} +type StateInfo0 struct{} diff --git a/gen/main.go b/gen/main.go index bcb43a8f0..d5874af2c 100644 --- a/gen/main.go +++ b/gen/main.go @@ -27,7 +27,7 @@ func main() { types.ExpTipSet{}, types.BeaconEntry{}, types.StateRoot{}, - types.StateInfo{}, + types.StateInfo0{}, ) if err != nil { fmt.Println(err) diff --git a/lotuspond/front/src/chain/methods.json b/lotuspond/front/src/chain/methods.json index 5e15b053b..b271bfae5 100644 --- a/lotuspond/front/src/chain/methods.json +++ b/lotuspond/front/src/chain/methods.json @@ -176,7 +176,8 @@ "CompactPartitions", "CompactSectorNumbers", "ConfirmUpdateWorkerKey", - "RepayDebt" + "RepayDebt", + "ChangeOwnerAddress" ], "fil/2/storagepower": [ "Send", From c17fa4bc35d3a7847fcc50a967fce468b56993f9 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 6 Oct 2020 16:58:18 -0700 Subject: [PATCH 097/115] update test-vectors for StateManager constructor change --- extern/test-vectors | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/test-vectors b/extern/test-vectors index 3a6e0b5e0..56f0676eb 160000 --- a/extern/test-vectors +++ b/extern/test-vectors @@ -1 +1 @@ -Subproject commit 3a6e0b5e069b1452ce1a032aa315354d645f3ec4 +Subproject commit 56f0676eb3be4b1e1dea892eea330614de755177 From cca17f607898615ded848d89a5de27c139413f90 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 6 Oct 2020 17:51:43 -0700 Subject: [PATCH 098/115] fix state tree version in v2 upgrade --- chain/actors/version.go | 4 ++-- chain/stmgr/forks.go | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/chain/actors/version.go b/chain/actors/version.go index 385ff592f..17af8b08b 100644 --- a/chain/actors/version.go +++ b/chain/actors/version.go @@ -9,8 +9,8 @@ import ( type Version int const ( - Version0 = 0 - Version2 = 2 + Version0 Version = 0 + Version2 Version = 2 ) // Converts a network version into an actors adt version. diff --git a/chain/stmgr/forks.go b/chain/stmgr/forks.go index fd6058127..52c764ba2 100644 --- a/chain/stmgr/forks.go +++ b/chain/stmgr/forks.go @@ -25,7 +25,6 @@ import ( states2 "github.com/filecoin-project/specs-actors/v2/actors/states" "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init" "github.com/filecoin-project/lotus/chain/actors/builtin/multisig" @@ -518,8 +517,7 @@ func UpgradeActorsV2(ctx context.Context, sm *StateManager, cb ExecCallback, roo } newRoot, err := store.Put(ctx, &types.StateRoot{ - // TODO: ActorUpgrade: should be state-tree specific, not just the actors version. - Version: actors.Version2, + Version: types.StateTreeVersion1, Actors: newHamtRoot, Info: info, }) From c02daca9e973354a75660c18bf1cb921e4ff096e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Wed, 7 Oct 2020 20:12:35 +0100 Subject: [PATCH 099/115] work around #4223. --- conformance/rand_record.go | 23 ++++++++++++++++++++--- conformance/rand_replay.go | 3 ++- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/conformance/rand_record.go b/conformance/rand_record.go index 2d3477c94..6f6d064dc 100644 --- a/conformance/rand_record.go +++ b/conformance/rand_record.go @@ -2,21 +2,28 @@ package conformance import ( "context" + "fmt" "sync" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/crypto" + "github.com/filecoin-project/test-vectors/schema" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/vm" - "github.com/filecoin-project/test-vectors/schema" ) type RecordingRand struct { reporter Reporter api api.FullNode + // once guards the loading of the head tipset. + // can be removed when https://github.com/filecoin-project/lotus/issues/4223 + // is fixed. + once sync.Once + head types.TipSetKey lk sync.Mutex recorded schema.Randomness } @@ -30,8 +37,17 @@ func NewRecordingRand(reporter Reporter, api api.FullNode) *RecordingRand { return &RecordingRand{reporter: reporter, api: api} } +func (r *RecordingRand) loadHead() { + head, err := r.api.ChainHead(context.Background()) + if err != nil { + panic(fmt.Sprintf("could not fetch chain head while fetching randomness: %s", err)) + } + r.head = head.Key() +} + func (r *RecordingRand) GetChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) { - ret, err := r.api.ChainGetRandomnessFromTickets(ctx, types.EmptyTSK, pers, round, entropy) + r.once.Do(r.loadHead) + ret, err := r.api.ChainGetRandomnessFromTickets(ctx, r.head, pers, round, entropy) if err != nil { return ret, err } @@ -55,7 +71,8 @@ func (r *RecordingRand) GetChainRandomness(ctx context.Context, pers crypto.Doma } func (r *RecordingRand) GetBeaconRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) { - ret, err := r.api.ChainGetRandomnessFromBeacon(ctx, types.EmptyTSK, pers, round, entropy) + r.once.Do(r.loadHead) + ret, err := r.api.ChainGetRandomnessFromBeacon(ctx, r.head, pers, round, entropy) if err != nil { return ret, err } diff --git a/conformance/rand_replay.go b/conformance/rand_replay.go index b820b8ced..1b73e5a08 100644 --- a/conformance/rand_replay.go +++ b/conformance/rand_replay.go @@ -7,8 +7,9 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/crypto" - "github.com/filecoin-project/lotus/chain/vm" "github.com/filecoin-project/test-vectors/schema" + + "github.com/filecoin-project/lotus/chain/vm" ) type ReplayingRand struct { From 767c346cf82dd2a41d72926dd2b406707f049a0c Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 7 Oct 2020 12:17:32 -0700 Subject: [PATCH 100/115] update test-vectors --- extern/test-vectors | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/test-vectors b/extern/test-vectors index 56f0676eb..7471e2805 160000 --- a/extern/test-vectors +++ b/extern/test-vectors @@ -1 +1 @@ -Subproject commit 56f0676eb3be4b1e1dea892eea330614de755177 +Subproject commit 7471e2805fc3e459e4ee325775633e8ec76cb7c6 From ae3691e0a2ee49858ba2d2f7f8dda26f728462c9 Mon Sep 17 00:00:00 2001 From: Travis Person Date: Wed, 7 Oct 2020 21:53:56 +0000 Subject: [PATCH 101/115] lotus-pcr: zero refund --- cmd/lotus-pcr/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/lotus-pcr/main.go b/cmd/lotus-pcr/main.go index 5b59ff03d..a1406789e 100644 --- a/cmd/lotus-pcr/main.go +++ b/cmd/lotus-pcr/main.go @@ -1025,9 +1025,9 @@ func (r *refunder) ProcessTipset(ctx context.Context, tipset *types.TipSet, refu return nil, nil } - refundValue := types.NewInt(0) tipsetRefunds := NewMinersRefund() for i, msg := range msgs { + refundValue := types.NewInt(0) m := msg.Message a, err := r.api.StateGetActor(ctx, m.To, tipset.Key()) From 12cd478e11c5ee6e1eadab98392710c379f1f93a Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Wed, 7 Oct 2020 15:14:46 -0700 Subject: [PATCH 102/115] Add message counts to inspect chain output --- cli/chain.go | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/cli/chain.go b/cli/chain.go index 20a8b7797..763752f23 100644 --- a/cli/chain.go +++ b/cli/chain.go @@ -449,11 +449,16 @@ var chainInspectUsage = &cli.Command{ bySender := make(map[string]int64) byDest := make(map[string]int64) byMethod := make(map[string]int64) + bySenderC := make(map[string]int64) + byDestC := make(map[string]int64) + byMethodC := make(map[string]int64) var sum int64 for _, m := range msgs { bySender[m.Message.From.String()] += m.Message.GasLimit + bySenderC[m.Message.From.String()]++ byDest[m.Message.To.String()] += m.Message.GasLimit + byDestC[m.Message.To.String()]++ sum += m.Message.GasLimit code, err := lookupActorCode(m.Message.To) @@ -464,7 +469,7 @@ var chainInspectUsage = &cli.Command{ mm := stmgr.MethodsMap[code][m.Message.Method] byMethod[mm.Name] += m.Message.GasLimit - + byMethodC[mm.Name]++ } type keyGasPair struct { @@ -496,19 +501,19 @@ var chainInspectUsage = &cli.Command{ fmt.Printf("By Sender:\n") for i := 0; i < numRes && i < len(senderVals); i++ { sv := senderVals[i] - fmt.Printf("%s\t%0.2f%%\t(%d)\n", sv.Key, (100*float64(sv.Gas))/float64(sum), sv.Gas) + fmt.Printf("%s\t%0.2f%%\t(total: %d, count: %d)\n", sv.Key, (100*float64(sv.Gas))/float64(sum), sv.Gas, bySenderC[sv.Key]) } fmt.Println() fmt.Printf("By Receiver:\n") for i := 0; i < numRes && i < len(destVals); i++ { sv := destVals[i] - fmt.Printf("%s\t%0.2f%%\t(%d)\n", sv.Key, (100*float64(sv.Gas))/float64(sum), sv.Gas) + fmt.Printf("%s\t%0.2f%%\t(total: %d, count: %d)\n", sv.Key, (100*float64(sv.Gas))/float64(sum), sv.Gas, byDestC[sv.Key]) } fmt.Println() fmt.Printf("By Method:\n") for i := 0; i < numRes && i < len(methodVals); i++ { sv := methodVals[i] - fmt.Printf("%s\t%0.2f%%\t(%d)\n", sv.Key, (100*float64(sv.Gas))/float64(sum), sv.Gas) + fmt.Printf("%s\t%0.2f%%\t(total: %d, count: %d)\n", sv.Key, (100*float64(sv.Gas))/float64(sum), sv.Gas, byMethodC[sv.Key]) } return nil From fe912223bdfa000b008c143b21f2cca1c0ac7388 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 7 Oct 2020 13:56:38 -0700 Subject: [PATCH 103/115] pass an explicit upgrade height to migrations The tipset height may not be the correct one, given null blocks. --- chain/stmgr/forks.go | 23 +++++++++++++---------- chain/stmgr/forks_test.go | 2 +- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/chain/stmgr/forks.go b/chain/stmgr/forks.go index 52c764ba2..b897c86eb 100644 --- a/chain/stmgr/forks.go +++ b/chain/stmgr/forks.go @@ -33,7 +33,14 @@ import ( "github.com/filecoin-project/lotus/chain/vm" ) -type UpgradeFunc func(context.Context, *StateManager, ExecCallback, cid.Cid, *types.TipSet) (cid.Cid, error) +// UpgradeFunc is a migration function run ate very upgrade. +// +// - The oldState is the state produced by the upgrade epoch. +// - The returned newState is the new state that will be used by the next epoch. +// - The height is the upgrade epoch height (already executed). +// - The tipset is the tipset for the last non-null block before the upgrade. Do +// not assume that ts.Height() is the upgrade height. +type UpgradeFunc func(ctx context.Context, sm *StateManager, cb ExecCallback, oldState cid.Cid, height abi.ChainEpoch, ts *types.TipSet) (newState cid.Cid, err error) type Upgrade struct { Height abi.ChainEpoch @@ -108,7 +115,7 @@ func (sm *StateManager) handleStateForks(ctx context.Context, root cid.Cid, heig var err error f, ok := sm.stateMigrations[height] if ok { - retCid, err = f(ctx, sm, cb, root, ts) + retCid, err = f(ctx, sm, cb, root, height, ts) if err != nil { return cid.Undef, err } @@ -179,7 +186,7 @@ func doTransfer(cb ExecCallback, tree types.StateTree, from, to address.Address, return nil } -func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, cb ExecCallback, root cid.Cid, ts *types.TipSet) (cid.Cid, error) { +func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, cb ExecCallback, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { // Some initial parameters FundsForMiners := types.FromFil(1_000_000) LookbackEpoch := abi.ChainEpoch(32000) @@ -431,11 +438,9 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, cb ExecCal return tree.Flush(ctx) } -func UpgradeIgnition(ctx context.Context, sm *StateManager, cb ExecCallback, root cid.Cid, ts *types.TipSet) (cid.Cid, error) { +func UpgradeIgnition(ctx context.Context, sm *StateManager, cb ExecCallback, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { store := sm.cs.Store(ctx) - epoch := ts.Height() - 1 - if build.UpgradeLiftoffHeight <= epoch { return cid.Undef, xerrors.Errorf("liftoff height must be beyond ignition height") } @@ -488,11 +493,9 @@ func UpgradeIgnition(ctx context.Context, sm *StateManager, cb ExecCallback, roo return tree.Flush(ctx) } -func UpgradeActorsV2(ctx context.Context, sm *StateManager, cb ExecCallback, root cid.Cid, ts *types.TipSet) (cid.Cid, error) { +func UpgradeActorsV2(ctx context.Context, sm *StateManager, cb ExecCallback, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { store := sm.cs.Store(ctx) - epoch := ts.Height() - 1 - info, err := store.Put(ctx, new(types.StateInfo0)) if err != nil { return cid.Undef, xerrors.Errorf("failed to create new state info for actors v2: %w", err) @@ -539,7 +542,7 @@ func UpgradeActorsV2(ctx context.Context, sm *StateManager, cb ExecCallback, roo return newRoot, nil } -func UpgradeLiftoff(ctx context.Context, sm *StateManager, cb ExecCallback, root cid.Cid, ts *types.TipSet) (cid.Cid, error) { +func UpgradeLiftoff(ctx context.Context, sm *StateManager, cb ExecCallback, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { tree, err := sm.StateTree(root) if err != nil { return cid.Undef, xerrors.Errorf("getting state tree: %w", err) diff --git a/chain/stmgr/forks_test.go b/chain/stmgr/forks_test.go index bb03f13b9..daa39a8d6 100644 --- a/chain/stmgr/forks_test.go +++ b/chain/stmgr/forks_test.go @@ -120,7 +120,7 @@ func TestForkHeightTriggers(t *testing.T) { Network: 1, Height: testForkHeight, Migration: func(ctx context.Context, sm *StateManager, cb ExecCallback, - root cid.Cid, ts *types.TipSet) (cid.Cid, error) { + root cid.Cid, height abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { cst := ipldcbor.NewCborStore(sm.ChainStore().Blockstore()) st, err := sm.StateTree(root) From dab1107f5b86f6f6dbef8e630b92fc9d0b4efac7 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 7 Oct 2020 14:35:07 -0700 Subject: [PATCH 104/115] avoid estimating gas and explicitly calling blocks on fork tipsets These tipsets can be slow. --- chain/stmgr/call.go | 39 +++++++++++++++++++++++++++++++++++++++ chain/stmgr/forks.go | 5 +++++ node/impl/full/gas.go | 13 ++++++++++++- 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/chain/stmgr/call.go b/chain/stmgr/call.go index 15cbac53e..0497a20ed 100644 --- a/chain/stmgr/call.go +++ b/chain/stmgr/call.go @@ -2,6 +2,7 @@ package stmgr import ( "context" + "errors" "fmt" "github.com/filecoin-project/go-address" @@ -17,17 +18,37 @@ import ( "github.com/filecoin-project/lotus/chain/vm" ) +var ErrWouldFork = errors.New("refusing explicit call due to state fork at epoch") + func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types.TipSet) (*api.InvocResult, error) { ctx, span := trace.StartSpan(ctx, "statemanager.Call") defer span.End() + // If no tipset is provided, try to find one without a fork. if ts == nil { ts = sm.cs.GetHeaviestTipSet() + + // Search back till we find a height with no fork, or we reach the beginning. + for ts.Height() > 0 && sm.hasStateFork(ctx, ts.Height()-1) { + var err error + ts, err = sm.cs.GetTipSetFromKey(ts.Parents()) + if err != nil { + return nil, xerrors.Errorf("failed to find a non-forking epoch: %w", err) + } + } } bstate := ts.ParentState() bheight := ts.Height() + // If we have to run a migration, and we're not at genesis, return an + // error because the migration will take too long. + // + // We allow this at height 0 for at-genesis migrations (for testing). + if bheight-1 > 0 && sm.hasStateFork(ctx, bheight-1) { + return nil, ErrWouldFork + } + bstate, err := sm.handleStateForks(ctx, bstate, bheight-1, nil, ts) if err != nil { return nil, fmt.Errorf("failed to handle fork: %w", err) @@ -106,6 +127,24 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri if ts == nil { ts = sm.cs.GetHeaviestTipSet() + + // Search back till we find a height with no fork, or we reach the beginning. + // We need the _previous_ height to have no fork, because we'll + // run the fork logic in `sm.TipSetState`. We need the _current_ + // height to have no fork, because we'll run it inside this + // function before executing the given message. + for ts.Height() > 0 && (sm.hasStateFork(ctx, ts.Height()) || sm.hasStateFork(ctx, ts.Height()-1)) { + var err error + ts, err = sm.cs.GetTipSetFromKey(ts.Parents()) + if err != nil { + return nil, xerrors.Errorf("failed to find a non-forking epoch: %w", err) + } + } + } + + // When we're not at the genesis block, make sure we're at a migration height. + if ts.Height() > 0 && (sm.hasStateFork(ctx, ts.Height()) || sm.hasStateFork(ctx, ts.Height()-1)) { + return nil, ErrWouldFork } state, _, err := sm.TipSetState(ctx, ts) diff --git a/chain/stmgr/forks.go b/chain/stmgr/forks.go index b897c86eb..69159f0fe 100644 --- a/chain/stmgr/forks.go +++ b/chain/stmgr/forks.go @@ -124,6 +124,11 @@ func (sm *StateManager) handleStateForks(ctx context.Context, root cid.Cid, heig return retCid, nil } +func (sm *StateManager) hasStateFork(ctx context.Context, height abi.ChainEpoch) bool { + _, ok := sm.stateMigrations[height] + return ok +} + func doTransfer(cb ExecCallback, tree types.StateTree, from, to address.Address, amt abi.TokenAmount) error { fromAct, err := tree.GetActor(from) if err != nil { diff --git a/node/impl/full/gas.go b/node/impl/full/gas.go index c912c7a8c..1b07aa950 100644 --- a/node/impl/full/gas.go +++ b/node/impl/full/gas.go @@ -160,7 +160,18 @@ func (a *GasAPI) GasEstimateGasLimit(ctx context.Context, msgIn *types.Message, priorMsgs = append(priorMsgs, m) } - res, err := a.Stmgr.CallWithGas(ctx, &msg, priorMsgs, ts) + // Try calling until we find a height with no migration. + var res *api.InvocResult + for { + res, err = a.Stmgr.CallWithGas(ctx, &msg, priorMsgs, ts) + if err != stmgr.ErrWouldFork { + break + } + ts, err = a.Chain.GetTipSetFromKey(ts.Parents()) + if err != nil { + return -1, xerrors.Errorf("getting parent tipset: %w", err) + } + } if err != nil { return -1, xerrors.Errorf("CallWithGas failed: %w", err) } From 9b7b6146ebf6e3c18ecd421a0f148045d937325e Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 7 Oct 2020 15:26:08 -0700 Subject: [PATCH 105/115] construct the new vm with the state manager's vm constructor --- chain/stmgr/call.go | 4 ++-- chain/stmgr/utils.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/chain/stmgr/call.go b/chain/stmgr/call.go index 0497a20ed..14a4359c1 100644 --- a/chain/stmgr/call.go +++ b/chain/stmgr/call.go @@ -65,7 +65,7 @@ func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types. BaseFee: types.NewInt(0), } - vmi, err := vm.NewVM(ctx, vmopt) + vmi, err := sm.newVM(ctx, vmopt) if err != nil { return nil, xerrors.Errorf("failed to set up vm: %w", err) } @@ -177,7 +177,7 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri NtwkVersion: sm.GetNtwkVersion, BaseFee: ts.Blocks()[0].ParentBaseFee, } - vmi, err := vm.NewVM(ctx, vmopt) + vmi, err := sm.newVM(ctx, vmopt) if err != nil { return nil, xerrors.Errorf("failed to set up vm: %w", err) } diff --git a/chain/stmgr/utils.go b/chain/stmgr/utils.go index 2c9c5ad94..c0f0c4d2f 100644 --- a/chain/stmgr/utils.go +++ b/chain/stmgr/utils.go @@ -387,7 +387,7 @@ func ComputeState(ctx context.Context, sm *StateManager, height abi.ChainEpoch, NtwkVersion: sm.GetNtwkVersion, BaseFee: ts.Blocks()[0].ParentBaseFee, } - vmi, err := vm.NewVM(ctx, vmopt) + vmi, err := sm.newVM(ctx, vmopt) if err != nil { return cid.Undef, nil, err } From 1fea550ce5028997cbe7423b0e9347251dc5878f Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 7 Oct 2020 15:28:16 -0700 Subject: [PATCH 106/115] test that we refuse explicit calls at the migration epochs --- chain/stmgr/forks_test.go | 87 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 3 deletions(-) diff --git a/chain/stmgr/forks_test.go b/chain/stmgr/forks_test.go index daa39a8d6..bd3e960d0 100644 --- a/chain/stmgr/forks_test.go +++ b/chain/stmgr/forks_test.go @@ -10,8 +10,9 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/cbor" "github.com/filecoin-project/specs-actors/actors/builtin" - init_ "github.com/filecoin-project/specs-actors/actors/builtin/init" + init0 "github.com/filecoin-project/specs-actors/actors/builtin/init" "github.com/filecoin-project/specs-actors/actors/runtime" + "github.com/stretchr/testify/require" "golang.org/x/xerrors" "github.com/filecoin-project/lotus/chain/actors" @@ -76,7 +77,7 @@ func (ta testActor) Exports() []interface{} { func (ta *testActor) Constructor(rt runtime.Runtime, params *abi.EmptyValue) *abi.EmptyValue { rt.ValidateImmediateCallerAcceptAny() rt.StateCreate(&testActorState{11}) - fmt.Println("NEW ACTOR ADDRESS IS: ", rt.Receiver()) + //fmt.Println("NEW ACTOR ADDRESS IS: ", rt.Receiver()) return abi.Empty } @@ -173,7 +174,7 @@ func TestForkHeightTriggers(t *testing.T) { var msgs []*types.SignedMessage - enc, err := actors.SerializeParams(&init_.ExecParams{CodeCID: (testActor{}).Code()}) + enc, err := actors.SerializeParams(&init0.ExecParams{CodeCID: (testActor{}).Code()}) if err != nil { t.Fatal(err) } @@ -233,3 +234,83 @@ func TestForkHeightTriggers(t *testing.T) { } } } + +func TestForkRefuseCall(t *testing.T) { + logging.SetAllLoggers(logging.LevelInfo) + + ctx := context.TODO() + + cg, err := gen.NewGenerator() + if err != nil { + t.Fatal(err) + } + + sm, err := NewStateManagerWithUpgradeSchedule( + cg.ChainStore(), UpgradeSchedule{{ + Network: 1, + Height: testForkHeight, + Migration: func(ctx context.Context, sm *StateManager, cb ExecCallback, + root cid.Cid, height abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { + return root, nil + }}}) + if err != nil { + t.Fatal(err) + } + + inv := vm.NewActorRegistry() + inv.Register(nil, testActor{}) + + sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (*vm.VM, error) { + nvm, err := vm.NewVM(ctx, vmopt) + if err != nil { + return nil, err + } + nvm.SetInvoker(inv) + return nvm, nil + }) + + cg.SetStateManager(sm) + + enc, err := actors.SerializeParams(&init0.ExecParams{CodeCID: (testActor{}).Code()}) + if err != nil { + t.Fatal(err) + } + + m := &types.Message{ + From: cg.Banker(), + To: lotusinit.Address, + Method: builtin.MethodsInit.Exec, + Params: enc, + GasLimit: types.TestGasLimit, + Value: types.NewInt(0), + GasPremium: types.NewInt(0), + GasFeeCap: types.NewInt(0), + } + + for i := 0; i < 50; i++ { + ts, err := cg.NextTipSet() + if err != nil { + t.Fatal(err) + } + + ret, err := sm.CallWithGas(ctx, m, nil, ts.TipSet.TipSet()) + switch ts.TipSet.TipSet().Height() { + case testForkHeight, testForkHeight + 1: + // If I had a fork, or I _will_ have a fork, it should fail. + require.Equal(t, ErrWouldFork, err) + default: + require.NoError(t, err) + require.True(t, ret.MsgRct.ExitCode.IsSuccess()) + } + // Call just runs on the parent state for a tipset, so we only + // expect an error at the fork height. + ret, err = sm.Call(ctx, m, ts.TipSet.TipSet()) + switch ts.TipSet.TipSet().Height() { + case testForkHeight + 1: + require.Equal(t, ErrWouldFork, err) + default: + require.NoError(t, err) + require.True(t, ret.MsgRct.ExitCode.IsSuccess()) + } + } +} From b0bea5f14558f49a676d471c5c612d97c925158b Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 7 Oct 2020 15:46:56 -0700 Subject: [PATCH 107/115] return an illegal actor error when we see an unsupported actor version As far as the chain is concerned, this actor does not exist. --- chain/vm/invoker.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/chain/vm/invoker.go b/chain/vm/invoker.go index 1e9f04081..661e31178 100644 --- a/chain/vm/invoker.go +++ b/chain/vm/invoker.go @@ -70,12 +70,12 @@ func (ar *ActorRegistry) Invoke(codeCid cid.Cid, rt vmr.Runtime, method abi.Meth log.Errorf("no code for actor %s (Addr: %s)", codeCid, rt.Receiver()) return nil, aerrors.Newf(exitcode.SysErrorIllegalActor, "no code for actor %s(%d)(%s)", codeCid, method, hex.EncodeToString(params)) } + if err := act.predicate(rt, act.vmActor); err != nil { + return nil, aerrors.Newf(exitcode.SysErrorIllegalActor, "unsupported actor: %s", err) + } if method >= abi.MethodNum(len(act.methods)) || act.methods[method] == nil { return nil, aerrors.Newf(exitcode.SysErrInvalidMethod, "no method %d on actor", method) } - if err := act.predicate(rt, act.vmActor); err != nil { - return nil, aerrors.Newf(exitcode.SysErrInvalidMethod, "unsupported actor: %s", err) - } return act.methods[method](rt, params) } From a4e954197caf1c10ee67eb6487398640a96028b5 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 7 Oct 2020 16:03:42 -0700 Subject: [PATCH 108/115] retry StateCall at different height if we're at an expensive fork height --- node/impl/full/state.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/node/impl/full/state.go b/node/impl/full/state.go index 3a4390d03..0a5c856bd 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -307,12 +307,22 @@ func (a *StateAPI) StateMinerPower(ctx context.Context, addr address.Address, ts }, nil } -func (a *StateAPI) StateCall(ctx context.Context, msg *types.Message, tsk types.TipSetKey) (*api.InvocResult, error) { +func (a *StateAPI) StateCall(ctx context.Context, msg *types.Message, tsk types.TipSetKey) (res *api.InvocResult, err error) { ts, err := a.Chain.GetTipSetFromKey(tsk) if err != nil { return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err) } - return a.StateManager.Call(ctx, msg, ts) + for { + res, err = a.StateManager.Call(ctx, msg, ts) + if err != stmgr.ErrWouldFork { + break + } + ts, err = a.Chain.GetTipSetFromKey(ts.Parents()) + if err != nil { + return nil, xerrors.Errorf("getting parent tipset: %w", err) + } + } + return res, err } func (a *StateAPI) StateReplay(ctx context.Context, tsk types.TipSetKey, mc cid.Cid) (*api.InvocResult, error) { From e8253d22c6600d8b03733bf1d32fb1b508101fa3 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 7 Oct 2020 16:14:11 -0700 Subject: [PATCH 109/115] only forbid Call* at expensive forks --- chain/stmgr/call.go | 21 +++++++++++---------- chain/stmgr/forks.go | 6 ++++-- chain/stmgr/forks_test.go | 9 +++++---- chain/stmgr/stmgr.go | 23 ++++++++++++++++------- node/impl/full/gas.go | 2 +- node/impl/full/state.go | 2 +- 6 files changed, 38 insertions(+), 25 deletions(-) diff --git a/chain/stmgr/call.go b/chain/stmgr/call.go index 14a4359c1..df3bfa357 100644 --- a/chain/stmgr/call.go +++ b/chain/stmgr/call.go @@ -18,7 +18,7 @@ import ( "github.com/filecoin-project/lotus/chain/vm" ) -var ErrWouldFork = errors.New("refusing explicit call due to state fork at epoch") +var ErrExpensiveFork = errors.New("refusing explicit call due to state fork at epoch") func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types.TipSet) (*api.InvocResult, error) { ctx, span := trace.StartSpan(ctx, "statemanager.Call") @@ -29,7 +29,7 @@ func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types. ts = sm.cs.GetHeaviestTipSet() // Search back till we find a height with no fork, or we reach the beginning. - for ts.Height() > 0 && sm.hasStateFork(ctx, ts.Height()-1) { + for ts.Height() > 0 && sm.hasExpensiveFork(ctx, ts.Height()-1) { var err error ts, err = sm.cs.GetTipSetFromKey(ts.Parents()) if err != nil { @@ -41,14 +41,15 @@ func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types. bstate := ts.ParentState() bheight := ts.Height() - // If we have to run a migration, and we're not at genesis, return an - // error because the migration will take too long. + // If we have to run an expensive migration, and we're not at genesis, + // return an error because the migration will take too long. // // We allow this at height 0 for at-genesis migrations (for testing). - if bheight-1 > 0 && sm.hasStateFork(ctx, bheight-1) { - return nil, ErrWouldFork + if bheight-1 > 0 && sm.hasExpensiveFork(ctx, bheight-1) { + return nil, ErrExpensiveFork } + // Run the (not expensive) migration. bstate, err := sm.handleStateForks(ctx, bstate, bheight-1, nil, ts) if err != nil { return nil, fmt.Errorf("failed to handle fork: %w", err) @@ -133,7 +134,7 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri // run the fork logic in `sm.TipSetState`. We need the _current_ // height to have no fork, because we'll run it inside this // function before executing the given message. - for ts.Height() > 0 && (sm.hasStateFork(ctx, ts.Height()) || sm.hasStateFork(ctx, ts.Height()-1)) { + for ts.Height() > 0 && (sm.hasExpensiveFork(ctx, ts.Height()) || sm.hasExpensiveFork(ctx, ts.Height()-1)) { var err error ts, err = sm.cs.GetTipSetFromKey(ts.Parents()) if err != nil { @@ -142,9 +143,9 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri } } - // When we're not at the genesis block, make sure we're at a migration height. - if ts.Height() > 0 && (sm.hasStateFork(ctx, ts.Height()) || sm.hasStateFork(ctx, ts.Height()-1)) { - return nil, ErrWouldFork + // When we're not at the genesis block, make sure we don't have an expensive migration. + if ts.Height() > 0 && (sm.hasExpensiveFork(ctx, ts.Height()) || sm.hasExpensiveFork(ctx, ts.Height()-1)) { + return nil, ErrExpensiveFork } state, _, err := sm.TipSetState(ctx, ts) diff --git a/chain/stmgr/forks.go b/chain/stmgr/forks.go index 69159f0fe..6aa5e5d87 100644 --- a/chain/stmgr/forks.go +++ b/chain/stmgr/forks.go @@ -45,6 +45,7 @@ type UpgradeFunc func(ctx context.Context, sm *StateManager, cb ExecCallback, ol type Upgrade struct { Height abi.ChainEpoch Network network.Version + Expensive bool Migration UpgradeFunc } @@ -68,6 +69,7 @@ func DefaultUpgradeSchedule() UpgradeSchedule { }, { Height: build.UpgradeActorsV2Height, Network: network.Version4, + Expensive: true, Migration: UpgradeActorsV2, }, { Height: build.UpgradeLiftoffHeight, @@ -124,8 +126,8 @@ func (sm *StateManager) handleStateForks(ctx context.Context, root cid.Cid, heig return retCid, nil } -func (sm *StateManager) hasStateFork(ctx context.Context, height abi.ChainEpoch) bool { - _, ok := sm.stateMigrations[height] +func (sm *StateManager) hasExpensiveFork(ctx context.Context, height abi.ChainEpoch) bool { + _, ok := sm.expensiveUpgrades[height] return ok } diff --git a/chain/stmgr/forks_test.go b/chain/stmgr/forks_test.go index bd3e960d0..bf1c711e4 100644 --- a/chain/stmgr/forks_test.go +++ b/chain/stmgr/forks_test.go @@ -247,8 +247,9 @@ func TestForkRefuseCall(t *testing.T) { sm, err := NewStateManagerWithUpgradeSchedule( cg.ChainStore(), UpgradeSchedule{{ - Network: 1, - Height: testForkHeight, + Network: 1, + Expensive: true, + Height: testForkHeight, Migration: func(ctx context.Context, sm *StateManager, cb ExecCallback, root cid.Cid, height abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { return root, nil @@ -297,7 +298,7 @@ func TestForkRefuseCall(t *testing.T) { switch ts.TipSet.TipSet().Height() { case testForkHeight, testForkHeight + 1: // If I had a fork, or I _will_ have a fork, it should fail. - require.Equal(t, ErrWouldFork, err) + require.Equal(t, ErrExpensiveFork, err) default: require.NoError(t, err) require.True(t, ret.MsgRct.ExitCode.IsSuccess()) @@ -307,7 +308,7 @@ func TestForkRefuseCall(t *testing.T) { ret, err = sm.Call(ctx, m, ts.TipSet.TipSet()) switch ts.TipSet.TipSet().Height() { case testForkHeight + 1: - require.Equal(t, ErrWouldFork, err) + require.Equal(t, ErrExpensiveFork, err) default: require.NoError(t, err) require.True(t, ret.MsgRct.ExitCode.IsSuccess()) diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index ac01ebb61..d81cf1c72 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -53,6 +53,10 @@ type StateManager struct { // Maps chain epochs to upgrade functions. stateMigrations map[abi.ChainEpoch]UpgradeFunc + // A set of potentially expensive/time consuming upgrades. Explicit + // calls for, e.g., gas estimation fail against this epoch with + // ErrExpensiveFork. + expensiveUpgrades map[abi.ChainEpoch]struct{} stCache map[string][]cid.Cid compWait map[string]chan struct{} @@ -78,6 +82,7 @@ func NewStateManagerWithUpgradeSchedule(cs *store.ChainStore, us UpgradeSchedule } stateMigrations := make(map[abi.ChainEpoch]UpgradeFunc, len(us)) + expensiveUpgrades := make(map[abi.ChainEpoch]struct{}, len(us)) var networkVersions []versionSpec lastVersion := network.Version0 if len(us) > 0 { @@ -87,6 +92,9 @@ func NewStateManagerWithUpgradeSchedule(cs *store.ChainStore, us UpgradeSchedule if upgrade.Migration != nil { stateMigrations[upgrade.Height] = upgrade.Migration } + if upgrade.Expensive { + expensiveUpgrades[upgrade.Height] = struct{}{} + } networkVersions = append(networkVersions, versionSpec{ networkVersion: lastVersion, atOrBelow: upgrade.Height, @@ -99,13 +107,14 @@ func NewStateManagerWithUpgradeSchedule(cs *store.ChainStore, us UpgradeSchedule } return &StateManager{ - networkVersions: networkVersions, - latestVersion: lastVersion, - stateMigrations: stateMigrations, - newVM: vm.NewVM, - cs: cs, - stCache: make(map[string][]cid.Cid), - compWait: make(map[string]chan struct{}), + networkVersions: networkVersions, + latestVersion: lastVersion, + stateMigrations: stateMigrations, + expensiveUpgrades: expensiveUpgrades, + newVM: vm.NewVM, + cs: cs, + stCache: make(map[string][]cid.Cid), + compWait: make(map[string]chan struct{}), }, nil } diff --git a/node/impl/full/gas.go b/node/impl/full/gas.go index 1b07aa950..3580ca26d 100644 --- a/node/impl/full/gas.go +++ b/node/impl/full/gas.go @@ -164,7 +164,7 @@ func (a *GasAPI) GasEstimateGasLimit(ctx context.Context, msgIn *types.Message, var res *api.InvocResult for { res, err = a.Stmgr.CallWithGas(ctx, &msg, priorMsgs, ts) - if err != stmgr.ErrWouldFork { + if err != stmgr.ErrExpensiveFork { break } ts, err = a.Chain.GetTipSetFromKey(ts.Parents()) diff --git a/node/impl/full/state.go b/node/impl/full/state.go index 0a5c856bd..7d654985a 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -314,7 +314,7 @@ func (a *StateAPI) StateCall(ctx context.Context, msg *types.Message, tsk types. } for { res, err = a.StateManager.Call(ctx, msg, ts) - if err != stmgr.ErrWouldFork { + if err != stmgr.ErrExpensiveFork { break } ts, err = a.Chain.GetTipSetFromKey(ts.Parents()) From d97eb10349398e8fae800bf11b2bfc046d96d57e Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 7 Oct 2020 16:32:54 -0700 Subject: [PATCH 110/115] fix spelling nit --- chain/stmgr/forks.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chain/stmgr/forks.go b/chain/stmgr/forks.go index 6aa5e5d87..1888d1ee9 100644 --- a/chain/stmgr/forks.go +++ b/chain/stmgr/forks.go @@ -33,7 +33,7 @@ import ( "github.com/filecoin-project/lotus/chain/vm" ) -// UpgradeFunc is a migration function run ate very upgrade. +// UpgradeFunc is a migration function run at every upgrade. // // - The oldState is the state produced by the upgrade epoch. // - The returned newState is the new state that will be used by the next epoch. From d1555106a474bf75c2e5329df02579165ffcbff8 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Tue, 6 Oct 2020 17:47:03 -0400 Subject: [PATCH 111/115] Set actorsv2 upgrade epoch --- build/params_2k.go | 3 +- build/params_testground.go | 3 +- build/params_testnet.go | 5 +-- chain/actors/builtin/builtin.go | 1 + chain/stmgr/forks.go | 68 +++++++++++++++++++++++++++++++++ 5 files changed, 75 insertions(+), 5 deletions(-) diff --git a/build/params_2k.go b/build/params_2k.go index f4a17f724..a9277831d 100644 --- a/build/params_2k.go +++ b/build/params_2k.go @@ -13,8 +13,9 @@ const BreezeGasTampingDuration = 0 const UpgradeSmokeHeight = -1 const UpgradeIgnitionHeight = -2 -const UpgradeLiftoffHeight = -3 +const UpgradeRefuelHeight = -3 const UpgradeActorsV2Height = 10 +const UpgradeLiftoffHeight = -4 var DrandSchedule = map[abi.ChainEpoch]DrandEnum{ 0: DrandMainnet, diff --git a/build/params_testground.go b/build/params_testground.go index bd064b3d6..6109cbc04 100644 --- a/build/params_testground.go +++ b/build/params_testground.go @@ -82,8 +82,9 @@ var ( UpgradeSmokeHeight abi.ChainEpoch = -1 UpgradeIgnitionHeight abi.ChainEpoch = -2 - UpgradeLiftoffHeight abi.ChainEpoch = -3 + UpgradeRefuelHeight abi.ChainEpoch = -3 UpgradeActorsV2Height abi.ChainEpoch = 10 + UpgradeLiftoffHeight abi.ChainEpoch = -4 DrandSchedule = map[abi.ChainEpoch]DrandEnum{ 0: DrandMainnet, diff --git a/build/params_testnet.go b/build/params_testnet.go index 16de8ff75..aef3ff450 100644 --- a/build/params_testnet.go +++ b/build/params_testnet.go @@ -25,9 +25,8 @@ const BreezeGasTampingDuration = 120 const UpgradeSmokeHeight = 51000 const UpgradeIgnitionHeight = 94000 - -// TODO: Actual epoch needs to be filled in -const UpgradeActorsV2Height = 128888 +const UpgradeRefuelHeight = 130800 +const UpgradeActorsV2Height = 138720 // This signals our tentative epoch for mainnet launch. Can make it later, but not earlier. // Miners, clients, developers, custodians all need time to prepare. diff --git a/chain/actors/builtin/builtin.go b/chain/actors/builtin/builtin.go index 7def78dcf..cb24a2c33 100644 --- a/chain/actors/builtin/builtin.go +++ b/chain/actors/builtin/builtin.go @@ -22,6 +22,7 @@ import ( var SystemActorAddr = builtin0.SystemActorAddr var BurntFundsActorAddr = builtin0.BurntFundsActorAddr var ReserveAddress = makeAddress("t090") +var RootVerifierAddress = makeAddress("t080") // TODO: Why does actors have 2 different versions of this? type SectorInfo = proof0.SectorInfo diff --git a/chain/stmgr/forks.go b/chain/stmgr/forks.go index 1888d1ee9..989a94870 100644 --- a/chain/stmgr/forks.go +++ b/chain/stmgr/forks.go @@ -6,6 +6,8 @@ import ( "encoding/binary" "math" + "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" @@ -66,6 +68,10 @@ func DefaultUpgradeSchedule() UpgradeSchedule { Height: build.UpgradeIgnitionHeight, Network: network.Version3, Migration: UpgradeIgnition, + }, { + Height: build.UpgradeRefuelHeight, + Network: network.Version3, + Migration: UpgradeRefuel, }, { Height: build.UpgradeActorsV2Height, Network: network.Version4, @@ -500,6 +506,36 @@ func UpgradeIgnition(ctx context.Context, sm *StateManager, cb ExecCallback, roo return tree.Flush(ctx) } +func UpgradeRefuel(ctx context.Context, sm *StateManager, cb ExecCallback, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { + store := sm.cs.Store(ctx) + tree, err := sm.StateTree(root) + if err != nil { + return cid.Undef, xerrors.Errorf("getting state tree: %w", err) + } + + addr, err := address.NewFromString("t0122") + if err != nil { + return cid.Undef, xerrors.Errorf("getting address: %w", err) + } + + err = resetMultisigVesting(ctx, store, tree, addr, 0, 0, big.Zero()) + if err != nil { + return cid.Undef, xerrors.Errorf("tweaking msig vesting: %w", err) + } + + err = resetMultisigVesting(ctx, store, tree, builtin.ReserveAddress, 0, 0, big.Zero()) + if err != nil { + return cid.Undef, xerrors.Errorf("tweaking msig vesting: %w", err) + } + + err = resetMultisigVesting(ctx, store, tree, builtin.RootVerifierAddress, 0, 0, big.Zero()) + if err != nil { + return cid.Undef, xerrors.Errorf("tweaking msig vesting: %w", err) + } + + return tree.Flush(ctx) +} + func UpgradeActorsV2(ctx context.Context, sm *StateManager, cb ExecCallback, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { store := sm.cs.Store(ctx) @@ -707,6 +743,7 @@ func makeKeyAddr(splitAddr address.Address, count uint64) (address.Address, erro return addr, nil } +// TODO: After the Liftoff epoch, refactor this to use resetMultisigVesting func resetGenesisMsigs(ctx context.Context, sm *StateManager, store adt0.Store, tree *state.StateTree, startEpoch abi.ChainEpoch) error { gb, err := sm.cs.GetGenesis() if err != nil { @@ -756,3 +793,34 @@ func resetGenesisMsigs(ctx context.Context, sm *StateManager, store adt0.Store, return nil } + +func resetMultisigVesting(ctx context.Context, store adt0.Store, tree *state.StateTree, addr address.Address, startEpoch abi.ChainEpoch, duration abi.ChainEpoch, balance abi.TokenAmount) error { + act, err := tree.GetActor(addr) + if err != nil { + return xerrors.Errorf("getting actor: %w", err) + } + + if !builtin.IsMultisigActor(act.Code) { + return xerrors.Errorf("actor wasn't msig: %w", err) + } + + var msigState multisig0.State + if err := store.Get(ctx, act.Head, &msigState); err != nil { + return xerrors.Errorf("reading multisig state: %w", err) + } + + msigState.StartEpoch = startEpoch + msigState.UnlockDuration = duration + msigState.InitialBalance = balance + + act.Head, err = store.Put(ctx, &msigState) + if err != nil { + return xerrors.Errorf("writing new multisig state: %w", err) + } + + if err := tree.SetActor(addr, act); err != nil { + return xerrors.Errorf("setting multisig actor: %w", err) + } + + return nil +} From f9f54819d41d333e021b9d2c3b4d32c4d3dbd138 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 8 Oct 2020 00:17:24 +0200 Subject: [PATCH 112/115] Env var to control v2 actor migration Env var to control v2 actor migration --- build/params_2k.go | 13 +++++++++++-- build/params_testnet.go | 8 +++++++- chain/stmgr/forks.go | 30 ++++++++++++++++++++++++++++-- 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/build/params_2k.go b/build/params_2k.go index a9277831d..c6538dc08 100644 --- a/build/params_2k.go +++ b/build/params_2k.go @@ -3,6 +3,9 @@ package build import ( + "math" + "os" + "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/lotus/chain/actors/policy" @@ -14,8 +17,9 @@ const BreezeGasTampingDuration = 0 const UpgradeSmokeHeight = -1 const UpgradeIgnitionHeight = -2 const UpgradeRefuelHeight = -3 -const UpgradeActorsV2Height = 10 -const UpgradeLiftoffHeight = -4 + +var UpgradeActorsV2Height = abi.ChainEpoch(10) +var UpgradeLiftoffHeight = abi.ChainEpoch(-4) var DrandSchedule = map[abi.ChainEpoch]DrandEnum{ 0: DrandMainnet, @@ -26,6 +30,11 @@ func init() { policy.SetConsensusMinerMinPower(abi.NewStoragePower(2048)) policy.SetMinVerifiedDealSize(abi.NewStoragePower(256)) + if os.Getenv("LOTUS_DISABLE_V2_ACTOR_MIGRATION") == "1" { + UpgradeActorsV2Height = math.MaxInt64 + UpgradeLiftoffHeight = 11 + } + BuildType |= Build2k } diff --git a/build/params_testnet.go b/build/params_testnet.go index aef3ff450..fe70deaef 100644 --- a/build/params_testnet.go +++ b/build/params_testnet.go @@ -5,6 +5,7 @@ package build import ( + "math" "os" "github.com/filecoin-project/go-address" @@ -26,7 +27,8 @@ const UpgradeSmokeHeight = 51000 const UpgradeIgnitionHeight = 94000 const UpgradeRefuelHeight = 130800 -const UpgradeActorsV2Height = 138720 + +var UpgradeActorsV2Height = abi.ChainEpoch(138720) // This signals our tentative epoch for mainnet launch. Can make it later, but not earlier. // Miners, clients, developers, custodians all need time to prepare. @@ -44,6 +46,10 @@ func init() { SetAddressNetwork(address.Mainnet) } + if os.Getenv("LOTUS_DISABLE_V2_ACTOR_MIGRATION") == "1" { + UpgradeActorsV2Height = math.MaxInt64 + } + Devnet = false } diff --git a/chain/stmgr/forks.go b/chain/stmgr/forks.go index 989a94870..cbbc351f9 100644 --- a/chain/stmgr/forks.go +++ b/chain/stmgr/forks.go @@ -56,7 +56,7 @@ type UpgradeSchedule []Upgrade func DefaultUpgradeSchedule() UpgradeSchedule { var us UpgradeSchedule - for _, u := range []Upgrade{{ + updates := []Upgrade{{ Height: build.UpgradeBreezeHeight, Network: network.Version1, Migration: UpgradeFaucetBurnRecovery, @@ -81,7 +81,33 @@ func DefaultUpgradeSchedule() UpgradeSchedule { Height: build.UpgradeLiftoffHeight, Network: network.Version4, Migration: UpgradeLiftoff, - }} { + }} + + if build.UpgradeActorsV2Height == math.MaxInt64 { // disable actors upgrade + updates = []Upgrade{{ + Height: build.UpgradeBreezeHeight, + Network: network.Version1, + Migration: UpgradeFaucetBurnRecovery, + }, { + Height: build.UpgradeSmokeHeight, + Network: network.Version2, + Migration: nil, + }, { + Height: build.UpgradeIgnitionHeight, + Network: network.Version3, + Migration: UpgradeIgnition, + }, { + Height: build.UpgradeRefuelHeight, + Network: network.Version3, + Migration: UpgradeRefuel, + }, { + Height: build.UpgradeLiftoffHeight, + Network: network.Version3, + Migration: UpgradeLiftoff, + }} + } + + for _, u := range updates { if u.Height < 0 { // upgrade disabled continue From da34548a05782982b7a152efc0876cd59d8bc336 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Wed, 7 Oct 2020 21:45:41 -0400 Subject: [PATCH 113/115] Set head should unmark blocks as valid --- node/impl/full/chain.go | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/node/impl/full/chain.go b/node/impl/full/chain.go index b405fb3dc..aa2ae4df1 100644 --- a/node/impl/full/chain.go +++ b/node/impl/full/chain.go @@ -254,11 +254,31 @@ func (a *ChainAPI) ChainStatObj(ctx context.Context, obj cid.Cid, base cid.Cid) } func (a *ChainAPI) ChainSetHead(ctx context.Context, tsk types.TipSetKey) error { - ts, err := a.Chain.GetTipSetFromKey(tsk) + newHeadTs, err := a.Chain.GetTipSetFromKey(tsk) if err != nil { return xerrors.Errorf("loading tipset %s: %w", tsk, err) } - return a.Chain.SetHead(ts) + + currentTs, err := a.ChainHead(ctx) + if err != nil { + return xerrors.Errorf("getting head: %w", err) + } + + for currentTs.Height() >= newHeadTs.Height() { + for _, blk := range currentTs.Key().Cids() { + err = a.Chain.UnmarkBlockAsValidated(ctx, blk) + if err != nil { + return xerrors.Errorf("unmarking block as validated %s: %w", blk, err) + } + } + + currentTs, err = a.ChainGetTipSet(ctx, currentTs.Parents()) + if err != nil { + return xerrors.Errorf("loading tipset: %w", err) + } + } + + return a.Chain.SetHead(newHeadTs) } func (a *ChainAPI) ChainGetGenesis(ctx context.Context) (*types.TipSet, error) { From dea70426689002cd4fbba6004012e1567328ea8d Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Wed, 7 Oct 2020 19:00:56 -0400 Subject: [PATCH 114/115] Lotus version 0.9.0 --- CHANGELOG.md | 95 +++++++++++++++++++++++++++++++++++++++++++++++- build/version.go | 2 +- 2 files changed, 95 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6de6ddc2c..4f6f0b3a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,98 @@ # Lotus changelog +# 0.9.0 / 2020-10-07 + +This consensus-breaking release of Lotus upgrades the actors version to v2.0.0. This requires migrating actor state from v0 to v2. The changes that break consensus are: + +- Introducing v2 actors and its migration (https://github.com/filecoin-project/lotus/pull/3936) +- Runtime's Receiver() should only return ID addresses (https://github.com/filecoin-project/lotus/pull/3589) +- Update miner eligibility checks for v2 actors (https://github.com/filecoin-project/lotus/pull/4188) +- Add funds that have left FilReserve to circ supply (https://github.com/filecoin-project/lotus/pull/4160) +- Set WinningPoStSectorSetLookback to finality post-v2 actors (https://github.com/filecoin-project/lotus/pull/4190) +- fix: error when actor panics directly (https://github.com/filecoin-project/lotus/pull/3697) + +## Changes + +#### Dependencies + +- Update go-bitfield (https://github.com/filecoin-project/lotus/pull/4171) +- update the AMT implementation (https://github.com/filecoin-project/lotus/pull/4194) +- Update to actors v0.2.1 (https://github.com/filecoin-project/lotus/pull/4199) + +#### Core Lotus + +- Paych: fix voucher amount verification (https://github.com/filecoin-project/lotus/pull/3821) +- Cap market provider messages (https://github.com/filecoin-project/lotus/pull/4141) +- Run fork function after cron for null block safety (https://github.com/filecoin-project/lotus/pull/4114) +- use bitswap sessions when fetching messages, and cancel them (https://github.com/filecoin-project/lotus/pull/4142) +- relax pubsub IPColocationFactorThreshold to 5 (https://github.com/filecoin-project/lotus/pull/4183) +- Support addresses with mainnet prefixes (https://github.com/filecoin-project/lotus/pull/4186) +- fix: make message signer nonce generation transactional (https://github.com/filecoin-project/lotus/pull/4165) +- build: Env var to keep test address output (https://github.com/filecoin-project/lotus/pull/4213) +- make vm.EnableGasTracing public (https://github.com/filecoin-project/lotus/pull/4214) +- introduce separate state-tree versions (https://github.com/filecoin-project/lotus/pull/4197) +- reject explicit "calls" at the upgrade height (https://github.com/filecoin-project/lotus/pull/4231) +- return an illegal actor error when we see an unsupported actor version (https://github.com/filecoin-project/lotus/pull/4232) +- Set head should unmark blocks as valid (https://gist.github.com/travisperson/3c7cddd77a33979a519ccef4e6515f20) + +#### Mining + +- Increased ExpectedSealDuration and and WaitDealsDelay (https://github.com/filecoin-project/lotus/pull/3743) +- Miner backup/restore commands (https://github.com/filecoin-project/lotus/pull/4133) +- lotus-miner: add more help text to storage / attach (https://github.com/filecoin-project/lotus/pull/3961) +- Reject deals that are > 7 days in the future in the BasicDealFilter (https://github.com/filecoin-project/lotus/pull/4173) +- feat(miner): add miner deadline diffing logic (https://github.com/filecoin-project/lotus/pull/4178) + +#### UX + +- Improve the UX for replacing messages (https://github.com/filecoin-project/lotus/pull/4134) +- Add verified flag to interactive deal creation (https://github.com/filecoin-project/lotus/pull/4145) +- Add command to (slowly) prune lotus chain datastore (https://github.com/filecoin-project/lotus/pull/3876) +- Some helpers for verifreg work (https://github.com/filecoin-project/lotus/pull/4124) +- Always use default 720h for setask duration and hide the duration param option (https://github.com/filecoin-project/lotus/pull/4077) +- Convert ID addresses to key addresses before checking wallet (https://github.com/filecoin-project/lotus/pull/4122) +- add a command to view block space utilization (https://github.com/filecoin-project/lotus/pull/4176) +- allow usage inspection on a chain segment (https://github.com/filecoin-project/lotus/pull/4177) +- Add mpool stats for base fee (https://github.com/filecoin-project/lotus/pull/4170) +- Add verified status to api.DealInfo (https://github.com/filecoin-project/lotus/pull/4153) +- Add a CLI command to set a miner's owner address (https://github.com/filecoin-project/lotus/pull/4189) + +#### Tooling and validation + +- Lotus-pcr: add recover-miners command (https://github.com/filecoin-project/lotus/pull/3714) +- MpoolPushUntrusted API for gateway (https://github.com/filecoin-project/lotus/pull/3915) +- Test lotus-miner info all (https://github.com/filecoin-project/lotus/pull/4166) +- chain export: Error with unfinished exports (https://github.com/filecoin-project/lotus/pull/4179) +- add printf in TestWindowPost (https://github.com/filecoin-project/lotus/pull/4043) +- add trace wdpost (https://github.com/filecoin-project/lotus/pull/4020) +- Fix noncefix (https://github.com/filecoin-project/lotus/pull/4202) +- Lotus-pcr: Limit the fee cap of messages we will process, refund gas fees for windowed post and storage deals (https://github.com/filecoin-project/lotus/pull/4198) +- Fix pond (https://github.com/filecoin-project/lotus/pull/4203) +- allow manual setting of noncefix fee cap (https://github.com/filecoin-project/lotus/pull/4205) +- implement command to get execution traces of any message (https://github.com/filecoin-project/lotus/pull/4200) +- conformance: minor driver refactors (https://github.com/filecoin-project/lotus/pull/4211) +- lotus-pcr: ignore all other messages (https://github.com/filecoin-project/lotus/pull/4218) +- lotus-pcr: zero refund (https://github.com/filecoin-project/lotus/pull/4229) + +## Contributors + +The following contributors had 5 or more commits go into this release. +We are grateful for every contribution! + +| Contributor | Commits | Lines ± | +|--------------------|---------|---------------| +| Stebalien | 84 | +3425/-2287 | +| magik6k | 41 | +2121/-506 | +| arajasek | 39 | +2467/-424 | +| Kubuxu | 25 | +2344/-775 | +| raulk | 21 | +287/-196 | +| whyrusleeping | 13 | +727/-71 | +| hsanjuan | 13 | +5886/-7956 | +| dirkmc | 11 | +2634/-576 | +| travisperson | 8 | +923/-202 | +| ribasushi | 6 | +188/-128 | +| zgfzgf | 5 | +21/-17 | + # 0.8.1 / 2020-09-30 This optional release of Lotus introduces a new version of markets which switches to CBOR-map encodings, and allows datastore migrations. The release also introduces several improvements to the mining process, a few performance optimizations, and a battery of UX additions and enhancements. @@ -117,7 +210,7 @@ We are grateful for every contribution! | vyzo | 22 | +287/-196 | | alanshaw | 15 | +761/-146 | | whyrusleeping | 15 | +736/-52 | -| hannahhoward | 14 | +1237/837- | +| hannahhoward | 14 | +1237/-837 | | anton | 6 | +32/-8 | | travisperson | 5 | +502/-6 | | Frank | 5 | +78/-39 | diff --git a/build/version.go b/build/version.go index 0b317aa17..1602551e4 100644 --- a/build/version.go +++ b/build/version.go @@ -29,7 +29,7 @@ func buildType() string { } // BuildVersion is the local build version, set by build system -const BuildVersion = "0.8.1" +const BuildVersion = "0.9.0" func UserVersion() string { return BuildVersion + buildType() + CurrentCommit From 1f9446f91fc19473f51408680585035b4dc468ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Thu, 8 Oct 2020 15:00:35 +0100 Subject: [PATCH 115/115] upgrade to test vectors schema v0.0.4. --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index e401af36d..5473dbb59 100644 --- a/go.mod +++ b/go.mod @@ -39,7 +39,7 @@ require ( github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b github.com/filecoin-project/specs-actors v0.9.11 github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796 - github.com/filecoin-project/test-vectors/schema v0.0.4-0.20201007174510-548c9399aa6a + github.com/filecoin-project/test-vectors/schema v0.0.4 github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 github.com/go-kit/kit v0.10.0 github.com/go-ole/go-ole v1.2.4 // indirect diff --git a/go.sum b/go.sum index 7d6c743ae..45d20d118 100644 --- a/go.sum +++ b/go.sum @@ -274,8 +274,8 @@ github.com/filecoin-project/specs-actors v0.9.11 h1:TnpG7HAeiUrfj0mJM7UaPW0P2137 github.com/filecoin-project/specs-actors v0.9.11/go.mod h1:czlvLQGEX0fjLLfdNHD7xLymy6L3n7aQzRWzsYGf+ys= github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796 h1:dJsTPWpG2pcTeojO2pyn0c6l+x/3MZYCBgo/9d11JEk= github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796/go.mod h1:nJRRM7Aa9XVvygr3W9k6xGF46RWzr2zxF/iGoAIfA/g= -github.com/filecoin-project/test-vectors/schema v0.0.4-0.20201007174510-548c9399aa6a h1:2jRLaT3/sHyAinWR2asCAkvzcnOAIi13eTlWf3YEVvY= -github.com/filecoin-project/test-vectors/schema v0.0.4-0.20201007174510-548c9399aa6a/go.mod h1:iQ9QXLpYWL3m7warwvK1JC/pTri8mnfEmKygNDqqY6E= +github.com/filecoin-project/test-vectors/schema v0.0.4 h1:QTRd0gb/NP4ZOTM7Dib5U3xE1/ToGDKnYLfxkC3t/m8= +github.com/filecoin-project/test-vectors/schema v0.0.4/go.mod h1:iQ9QXLpYWL3m7warwvK1JC/pTri8mnfEmKygNDqqY6E= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6 h1:u/UEqS66A5ckRmS4yNpjmVH56sVtS/RfclBAYocb4as= github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6/go.mod h1:1i71OnUq3iUe1ma7Lr6yG6/rjvM3emb6yoL7xLFzcVQ=