diff --git a/api/api_full.go b/api/api_full.go index 8d62cb47b..0379b14c1 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -6,11 +6,13 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-fil-markets/storagemarket" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/abi/big" + "github.com/filecoin-project/specs-actors/actors/builtin/market" "github.com/ipfs/go-cid" "github.com/ipfs/go-filestore" "github.com/libp2p/go-libp2p-core/peer" - "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" ) @@ -19,6 +21,8 @@ import ( type FullNode interface { Common + // TODO: TipSetKeys + // chain // ChainNotify returns channel with chain head updates @@ -31,7 +35,7 @@ type FullNode interface { ChainGetBlockMessages(context.Context, cid.Cid) (*BlockMessages, error) ChainGetParentReceipts(context.Context, cid.Cid) ([]*types.MessageReceipt, error) ChainGetParentMessages(context.Context, cid.Cid) ([]Message, error) - ChainGetTipSetByHeight(context.Context, uint64, *types.TipSet) (*types.TipSet, error) + ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, *types.TipSet) (*types.TipSet, error) ChainReadObj(context.Context, cid.Cid) ([]byte, error) ChainHasObj(context.Context, cid.Cid) (bool, error) ChainSetHead(context.Context, *types.TipSet) error @@ -59,7 +63,7 @@ type FullNode interface { // miner - MinerCreateBlock(context.Context, address.Address, *types.TipSet, *types.Ticket, *types.EPostProof, []*types.SignedMessage, uint64, uint64) (*types.BlockMsg, error) + MinerCreateBlock(context.Context, address.Address, *types.TipSet, *types.Ticket, *types.EPostProof, []*types.SignedMessage, abi.ChainEpoch, uint64) (*types.BlockMsg, error) // // UX ? @@ -101,7 +105,7 @@ type FullNode interface { StateReplay(context.Context, *types.TipSet, cid.Cid) (*ReplayResults, error) StateGetActor(ctx context.Context, actor address.Address, ts *types.TipSet) (*types.Actor, error) StateReadState(ctx context.Context, act *types.Actor, ts *types.TipSet) (*ActorState, error) - StateListMessages(ctx context.Context, match *types.Message, ts *types.TipSet, toht uint64) ([]cid.Cid, error) + StateListMessages(ctx context.Context, match *types.Message, ts *types.TipSet, toht abi.ChainEpoch) ([]cid.Cid, error) StateMinerSectors(context.Context, address.Address, *types.TipSet) ([]*ChainSectorInfo, error) StateMinerProvingSet(context.Context, address.Address, *types.TipSet) ([]*ChainSectorInfo, error) @@ -109,21 +113,21 @@ type FullNode interface { StateMinerWorker(context.Context, address.Address, *types.TipSet) (address.Address, error) StateMinerPeerID(ctx context.Context, m address.Address, ts *types.TipSet) (peer.ID, error) StateMinerElectionPeriodStart(ctx context.Context, actor address.Address, ts *types.TipSet) (uint64, error) - StateMinerSectorSize(context.Context, address.Address, *types.TipSet) (uint64, error) + StateMinerSectorSize(context.Context, address.Address, *types.TipSet) (abi.SectorSize, error) StateMinerFaults(context.Context, address.Address, *types.TipSet) ([]uint64, error) StatePledgeCollateral(context.Context, *types.TipSet) (types.BigInt, error) StateWaitMsg(context.Context, cid.Cid) (*MsgWait, error) StateListMiners(context.Context, *types.TipSet) ([]address.Address, error) StateListActors(context.Context, *types.TipSet) ([]address.Address, error) - StateMarketBalance(context.Context, address.Address, *types.TipSet) (actors.StorageParticipantBalance, error) - StateMarketParticipants(context.Context, *types.TipSet) (map[string]actors.StorageParticipantBalance, error) - StateMarketDeals(context.Context, *types.TipSet) (map[string]actors.OnChainDeal, error) - StateMarketStorageDeal(context.Context, uint64, *types.TipSet) (*actors.OnChainDeal, error) + StateMarketBalance(context.Context, address.Address, *types.TipSet) (MarketBalance, error) + StateMarketParticipants(context.Context, *types.TipSet) (map[string]MarketBalance, error) + StateMarketDeals(context.Context, *types.TipSet) (map[string]market.DealProposal, error) + StateMarketStorageDeal(context.Context, abi.DealID, *types.TipSet) (*market.DealProposal, error) StateLookupID(context.Context, address.Address, *types.TipSet) (address.Address, error) StateChangedActors(context.Context, cid.Cid, cid.Cid) (map[string]types.Actor, error) StateGetReceipt(context.Context, cid.Cid, *types.TipSet) (*types.MessageReceipt, error) StateMinerSectorCount(context.Context, address.Address, *types.TipSet) (MinerSectors, error) - StateCompute(context.Context, uint64, []*types.Message, *types.TipSet) (cid.Cid, error) + StateCompute(context.Context, abi.ChainEpoch, []*types.Message, *types.TipSet) (cid.Cid, error) MsigGetAvailableBalance(context.Context, address.Address, *types.TipSet) (types.BigInt, error) @@ -260,6 +264,11 @@ func (o *QueryOffer) Order(client address.Address) RetrievalOrder { } } +type MarketBalance struct { + Escrow big.Int + Locked big.Int +} + type RetrievalOrder struct { // TODO: make this less unixfs specific Root cid.Cid @@ -289,7 +298,7 @@ type ActiveSync struct { Target *types.TipSet Stage SyncStateStage - Height uint64 + Height abi.ChainEpoch Start time.Time End time.Time diff --git a/api/api_storage.go b/api/api_storage.go index 5c4362929..a8187af8d 100644 --- a/api/api_storage.go +++ b/api/api_storage.go @@ -4,6 +4,8 @@ import ( "context" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/go-sectorbuilder" ) @@ -135,9 +137,9 @@ type SectorInfo struct { } type SealedRef struct { - SectorID uint64 + SectorID abi.SectorNumber Offset uint64 - Size uint64 + Size abi.UnpaddedPieceSize } type SealedRefs struct { diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 11808013d..6fa1376e3 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -4,14 +4,16 @@ import ( "context" sectorbuilder "github.com/filecoin-project/go-sectorbuilder" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin/market" "github.com/ipfs/go-cid" "github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/peer" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" ) @@ -48,7 +50,7 @@ type FullNodeStruct struct { ChainGetBlockMessages func(context.Context, cid.Cid) (*api.BlockMessages, error) `perm:"read"` ChainGetParentReceipts func(context.Context, cid.Cid) ([]*types.MessageReceipt, error) `perm:"read"` ChainGetParentMessages func(context.Context, cid.Cid) ([]api.Message, error) `perm:"read"` - ChainGetTipSetByHeight func(context.Context, uint64, *types.TipSet) (*types.TipSet, error) `perm:"read"` + ChainGetTipSetByHeight func(context.Context, abi.ChainEpoch, *types.TipSet) (*types.TipSet, error) `perm:"read"` ChainReadObj func(context.Context, cid.Cid) ([]byte, error) `perm:"read"` ChainHasObj func(context.Context, cid.Cid) (bool, error) `perm:"read"` ChainSetHead func(context.Context, *types.TipSet) error `perm:"admin"` @@ -70,7 +72,7 @@ type FullNodeStruct struct { MpoolGetNonce func(context.Context, address.Address) (uint64, error) `perm:"read"` MpoolSub func(context.Context) (<-chan api.MpoolUpdate, error) `perm:"read"` - MinerCreateBlock func(context.Context, address.Address, *types.TipSet, *types.Ticket, *types.EPostProof, []*types.SignedMessage, uint64, uint64) (*types.BlockMsg, error) `perm:"write"` + MinerCreateBlock func(context.Context, address.Address, *types.TipSet, *types.Ticket, *types.EPostProof, []*types.SignedMessage, abi.ChainEpoch, uint64) (*types.BlockMsg, error) `perm:"write"` WalletNew func(context.Context, string) (address.Address, error) `perm:"write"` WalletHas func(context.Context, address.Address) (bool, error) `perm:"write"` @@ -99,7 +101,7 @@ type FullNodeStruct struct { StateMinerWorker func(context.Context, address.Address, *types.TipSet) (address.Address, error) `perm:"read"` StateMinerPeerID func(ctx context.Context, m address.Address, ts *types.TipSet) (peer.ID, error) `perm:"read"` StateMinerElectionPeriodStart func(ctx context.Context, actor address.Address, ts *types.TipSet) (uint64, error) `perm:"read"` - StateMinerSectorSize func(context.Context, address.Address, *types.TipSet) (uint64, error) `perm:"read"` + StateMinerSectorSize func(context.Context, address.Address, *types.TipSet) (abi.SectorSize, error) `perm:"read"` StateMinerFaults func(context.Context, address.Address, *types.TipSet) ([]uint64, error) `perm:"read"` StateCall func(context.Context, *types.Message, *types.TipSet) (*api.MethodCall, error) `perm:"read"` StateReplay func(context.Context, *types.TipSet, cid.Cid) (*api.ReplayResults, error) `perm:"read"` @@ -109,16 +111,16 @@ type FullNodeStruct struct { StateWaitMsg func(context.Context, cid.Cid) (*api.MsgWait, error) `perm:"read"` StateListMiners func(context.Context, *types.TipSet) ([]address.Address, error) `perm:"read"` StateListActors func(context.Context, *types.TipSet) ([]address.Address, error) `perm:"read"` - StateMarketBalance func(context.Context, address.Address, *types.TipSet) (actors.StorageParticipantBalance, error) `perm:"read"` - StateMarketParticipants func(context.Context, *types.TipSet) (map[string]actors.StorageParticipantBalance, error) `perm:"read"` - StateMarketDeals func(context.Context, *types.TipSet) (map[string]actors.OnChainDeal, error) `perm:"read"` - StateMarketStorageDeal func(context.Context, uint64, *types.TipSet) (*actors.OnChainDeal, error) `perm:"read"` + StateMarketBalance func(context.Context, address.Address, *types.TipSet) (api.MarketBalance, error) `perm:"read"` + StateMarketParticipants func(context.Context, *types.TipSet) (map[string]api.MarketBalance, error) `perm:"read"` + StateMarketDeals func(context.Context, *types.TipSet) (map[string]market.DealProposal, error) `perm:"read"` + StateMarketStorageDeal func(context.Context, abi.DealID, *types.TipSet) (*market.DealProposal, error) `perm:"read"` StateLookupID func(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) `perm:"read"` StateChangedActors func(context.Context, cid.Cid, cid.Cid) (map[string]types.Actor, error) `perm:"read"` StateGetReceipt func(context.Context, cid.Cid, *types.TipSet) (*types.MessageReceipt, error) `perm:"read"` StateMinerSectorCount func(context.Context, address.Address, *types.TipSet) (api.MinerSectors, error) `perm:"read"` - StateListMessages func(ctx context.Context, match *types.Message, ts *types.TipSet, toht uint64) ([]cid.Cid, error) `perm:"read"` - StateCompute func(context.Context, uint64, []*types.Message, *types.TipSet) (cid.Cid, error) `perm:"read"` + StateListMessages func(ctx context.Context, match *types.Message, ts *types.TipSet, toht abi.ChainEpoch) ([]cid.Cid, error) `perm:"read"` + StateCompute func(context.Context, abi.ChainEpoch, []*types.Message, *types.TipSet) (cid.Cid, error) `perm:"read"` MsigGetAvailableBalance func(context.Context, address.Address, *types.TipSet) (types.BigInt, error) `perm:"read"` @@ -254,7 +256,7 @@ func (c *FullNodeStruct) MpoolSub(ctx context.Context) (<-chan api.MpoolUpdate, return c.Internal.MpoolSub(ctx) } -func (c *FullNodeStruct) MinerCreateBlock(ctx context.Context, addr address.Address, base *types.TipSet, ticket *types.Ticket, eproof *types.EPostProof, msgs []*types.SignedMessage, height, ts uint64) (*types.BlockMsg, error) { +func (c *FullNodeStruct) MinerCreateBlock(ctx context.Context, addr address.Address, base *types.TipSet, ticket *types.Ticket, eproof *types.EPostProof, msgs []*types.SignedMessage, height abi.ChainEpoch, ts uint64) (*types.BlockMsg, error) { return c.Internal.MinerCreateBlock(ctx, addr, base, ticket, eproof, msgs, height, ts) } @@ -266,7 +268,7 @@ func (c *FullNodeStruct) ChainGetRandomness(ctx context.Context, pts types.TipSe return c.Internal.ChainGetRandomness(ctx, pts, round) } -func (c *FullNodeStruct) ChainGetTipSetByHeight(ctx context.Context, h uint64, ts *types.TipSet) (*types.TipSet, error) { +func (c *FullNodeStruct) ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEpoch, ts *types.TipSet) (*types.TipSet, error) { return c.Internal.ChainGetTipSetByHeight(ctx, h, ts) } @@ -414,7 +416,7 @@ func (c *FullNodeStruct) StateMinerElectionPeriodStart(ctx context.Context, acto return c.Internal.StateMinerElectionPeriodStart(ctx, actor, ts) } -func (c *FullNodeStruct) StateMinerSectorSize(ctx context.Context, actor address.Address, ts *types.TipSet) (uint64, error) { +func (c *FullNodeStruct) StateMinerSectorSize(ctx context.Context, actor address.Address, ts *types.TipSet) (abi.SectorSize, error) { return c.Internal.StateMinerSectorSize(ctx, actor, ts) } @@ -453,19 +455,19 @@ func (c *FullNodeStruct) StateListActors(ctx context.Context, ts *types.TipSet) return c.Internal.StateListActors(ctx, ts) } -func (c *FullNodeStruct) StateMarketBalance(ctx context.Context, addr address.Address, ts *types.TipSet) (actors.StorageParticipantBalance, error) { +func (c *FullNodeStruct) StateMarketBalance(ctx context.Context, addr address.Address, ts *types.TipSet) (api.MarketBalance, error) { return c.Internal.StateMarketBalance(ctx, addr, ts) } -func (c *FullNodeStruct) StateMarketParticipants(ctx context.Context, ts *types.TipSet) (map[string]actors.StorageParticipantBalance, error) { +func (c *FullNodeStruct) StateMarketParticipants(ctx context.Context, ts *types.TipSet) (map[string]api.MarketBalance, error) { return c.Internal.StateMarketParticipants(ctx, ts) } -func (c *FullNodeStruct) StateMarketDeals(ctx context.Context, ts *types.TipSet) (map[string]actors.OnChainDeal, error) { +func (c *FullNodeStruct) StateMarketDeals(ctx context.Context, ts *types.TipSet) (map[string]market.DealProposal, error) { return c.Internal.StateMarketDeals(ctx, ts) } -func (c *FullNodeStruct) StateMarketStorageDeal(ctx context.Context, dealid uint64, ts *types.TipSet) (*actors.OnChainDeal, error) { +func (c *FullNodeStruct) StateMarketStorageDeal(ctx context.Context, dealid abi.DealID, ts *types.TipSet) (*market.DealProposal, error) { return c.Internal.StateMarketStorageDeal(ctx, dealid, ts) } @@ -481,11 +483,11 @@ func (c *FullNodeStruct) StateGetReceipt(ctx context.Context, msg cid.Cid, ts *t return c.Internal.StateGetReceipt(ctx, msg, ts) } -func (c *FullNodeStruct) StateListMessages(ctx context.Context, match *types.Message, ts *types.TipSet, toht uint64) ([]cid.Cid, error) { +func (c *FullNodeStruct) StateListMessages(ctx context.Context, match *types.Message, ts *types.TipSet, toht abi.ChainEpoch) ([]cid.Cid, error) { return c.Internal.StateListMessages(ctx, match, ts, toht) } -func (c *FullNodeStruct) StateCompute(ctx context.Context, height uint64, msgs []*types.Message, ts *types.TipSet) (cid.Cid, error) { +func (c *FullNodeStruct) StateCompute(ctx context.Context, height abi.ChainEpoch, msgs []*types.Message, ts *types.TipSet) (cid.Cid, error) { return c.Internal.StateCompute(ctx, height, msgs, ts) } diff --git a/api/cbor_gen.go b/api/cbor_gen.go index c9c9cac5a..b3201b3e7 100644 --- a/api/cbor_gen.go +++ b/api/cbor_gen.go @@ -286,7 +286,6 @@ func (t *SealedRef) UnmarshalCBOR(r io.Reader) error { if maj != cbg.MajUnsignedInt { return fmt.Errorf("wrong type for uint64 field") } - t.SectorID = uint64(extra) // t.Offset (uint64) (uint64) case "Offset": @@ -308,7 +307,6 @@ func (t *SealedRef) UnmarshalCBOR(r io.Reader) error { if maj != cbg.MajUnsignedInt { return fmt.Errorf("wrong type for uint64 field") } - t.Size = uint64(extra) default: return fmt.Errorf("unknown struct field %d: '%s'", i, name) diff --git a/build/version.go b/build/version.go index 21cb88a82..a0ee2aa93 100644 --- a/build/version.go +++ b/build/version.go @@ -5,7 +5,7 @@ import "fmt" var CurrentCommit string // BuildVersion is the local build version, set by build system -const BuildVersion = "0.2.7" +const BuildVersion = "0.3.0" var UserVersion = BuildVersion + CurrentCommit @@ -31,7 +31,7 @@ func (ve Version) EqMajorMinor(v2 Version) bool { } // APIVersion is a semver version of the rpc api exposed -var APIVersion Version = newVer(0, 1, 6) +var APIVersion Version = newVer(0, 2, 0) const ( majorMask = 0xff0000 diff --git a/chain/actors/actor_miner.go b/chain/actors/actor_miner.go index 254ef6624..a16b5d66d 100644 --- a/chain/actors/actor_miner.go +++ b/chain/actors/actor_miner.go @@ -10,6 +10,7 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-amt-ipld/v2" amt2 "github.com/filecoin-project/go-amt-ipld/v2" + "github.com/filecoin-project/specs-actors/actors/abi" "github.com/libp2p/go-libp2p-core/peer" "github.com/filecoin-project/go-sectorbuilder" @@ -93,6 +94,8 @@ type StorageMinerActorState struct { ElectionPeriodStart uint64 } +// 46356: + type MinerInfo struct { // Account that owns this miner. // - Income and returned collateral are paid to this address. @@ -109,7 +112,7 @@ type MinerInfo struct { PeerID peer.ID // Amount of space in each sector committed to the network by this miner. - SectorSize uint64 + SectorSize abi.SectorSize // SubsectorCount } @@ -122,12 +125,12 @@ type PreCommittedSector struct { type StorageMinerConstructorParams struct { Owner address.Address Worker address.Address - SectorSize uint64 + SectorSize abi.SectorSize PeerID peer.ID } type SectorPreCommitInfo struct { - SectorNumber uint64 + SectorNumber abi.SectorNumber CommR []byte // TODO: Spec says CID SealEpoch uint64 @@ -204,12 +207,12 @@ func (sma StorageMinerActor) PreCommitSector(act *types.Actor, vmctx types.VMCon return nil, err } - if params.SealEpoch >= vmctx.BlockHeight()+build.SealRandomnessLookback { + if params.SealEpoch >= uint64(vmctx.BlockHeight())+build.SealRandomnessLookback { return nil, aerrors.Newf(1, "sector commitment must be based off past randomness (%d >= %d)", params.SealEpoch, vmctx.BlockHeight()+build.SealRandomnessLookback) } - if vmctx.BlockHeight()-params.SealEpoch+build.SealRandomnessLookback > build.SealRandomnessLookbackLimit { - return nil, aerrors.Newf(2, "sector commitment must be recent enough (was %d)", vmctx.BlockHeight()-params.SealEpoch+build.SealRandomnessLookback) + if uint64(vmctx.BlockHeight())-params.SealEpoch+build.SealRandomnessLookback > build.SealRandomnessLookbackLimit { + return nil, aerrors.Newf(2, "sector commitment must be recent enough (was %d)", uint64(vmctx.BlockHeight())-params.SealEpoch+build.SealRandomnessLookback) } mi, err := loadMinerInfo(vmctx, self) @@ -222,7 +225,7 @@ func (sma StorageMinerActor) PreCommitSector(act *types.Actor, vmctx types.VMCon } // make sure the miner isnt trying to submit a pre-existing sector - unique, err := SectorIsUnique(ctx, vmctx.Ipld(), self.Sectors, params.SectorNumber) + unique, err := SectorIsUnique(ctx, vmctx.Ipld(), self.Sectors, uint64(params.SectorNumber)) if err != nil { return nil, err } @@ -231,7 +234,7 @@ func (sma StorageMinerActor) PreCommitSector(act *types.Actor, vmctx types.VMCon } // Power of the miner after adding this sector - futurePower := types.BigAdd(self.Power, types.NewInt(mi.SectorSize)) + futurePower := types.BigAdd(self.Power, types.NewInt(uint64(mi.SectorSize))) collateralRequired := CollateralForPower(futurePower) // TODO: grab from market? @@ -239,9 +242,9 @@ func (sma StorageMinerActor) PreCommitSector(act *types.Actor, vmctx types.VMCon return nil, aerrors.New(4, "not enough collateral") } - self.PreCommittedSectors[uintToStringKey(params.SectorNumber)] = &PreCommittedSector{ + self.PreCommittedSectors[uintToStringKey(uint64(params.SectorNumber))] = &PreCommittedSector{ Info: *params, - ReceivedEpoch: vmctx.BlockHeight(), + ReceivedEpoch: uint64(vmctx.BlockHeight()), } if len(self.PreCommittedSectors) > 4096 { @@ -275,41 +278,41 @@ func (sma StorageMinerActor) ProveCommitSector(act *types.Actor, vmctx types.VMC return nil, aerrors.New(1, "not authorized to submit sector proof for miner") } - us, ok := self.PreCommittedSectors[uintToStringKey(params.SectorID)] + us, ok := self.PreCommittedSectors[uintToStringKey(uint64(params.SectorID))] if !ok { return nil, aerrors.New(1, "no pre-commitment found for sector") } - if us.ReceivedEpoch+build.InteractivePoRepDelay >= vmctx.BlockHeight() { + if us.ReceivedEpoch+build.InteractivePoRepDelay >= uint64(vmctx.BlockHeight()){ return nil, aerrors.New(2, "too early for proof submission") } - delete(self.PreCommittedSectors, uintToStringKey(params.SectorID)) + delete(self.PreCommittedSectors, uintToStringKey(uint64(params.SectorID))) // TODO: ensure normalization to ID address maddr := vmctx.Message().To - if vmctx.BlockHeight()-us.Info.SealEpoch > build.MaxSealLookback { + if uint64(vmctx.BlockHeight())-us.Info.SealEpoch > build.MaxSealLookback { return nil, aerrors.Newf(5, "source randomness for sector SealEpoch too far in past (epoch %d)", us.Info.SealEpoch) } - if vmctx.BlockHeight()-us.ReceivedEpoch > build.MaxSealLookback { + if uint64(vmctx.BlockHeight())-us.ReceivedEpoch > build.MaxSealLookback { return nil, aerrors.Newf(6, "source randomness for sector ReceivedEpoch too far in past (epoch %d)", us.ReceivedEpoch) } - ticket, err := vmctx.GetRandomness(us.Info.SealEpoch - build.SealRandomnessLookback) + ticket, err := vmctx.GetRandomness(abi.ChainEpoch(0)) if err != nil { return nil, aerrors.Wrap(err, "failed to get ticket randomness") } - seed, err := vmctx.GetRandomness(us.ReceivedEpoch + build.InteractivePoRepDelay) + seed, err := vmctx.GetRandomness(abi.ChainEpoch(0)) if err != nil { return nil, aerrors.Wrap(err, "failed to get randomness for prove sector commitment") } enc, err := SerializeParams(&ComputeDataCommitmentParams{ DealIDs: params.DealIDs, - SectorSize: mi.SectorSize, + SectorSize: abi.SectorSize(mi.SectorSize), }) if err != nil { return nil, aerrors.Wrap(err, "failed to serialize ComputeDataCommitmentParams") @@ -329,7 +332,7 @@ func (sma StorageMinerActor) ProveCommitSector(act *types.Actor, vmctx types.VMC // Note: There must exist a unique index in the miner's sector set for each // sector ID. The `faults`, `recovered`, and `done` parameters of the // SubmitPoSt method express indices into this sector set. - nssroot, err := AddToSectorSet2(ctx, vmctx.Ipld(), self.Sectors, params.SectorID, us.Info.CommR, commD) + nssroot, err := AddToSectorSet2(ctx, vmctx.Ipld(), self.Sectors, uint64(params.SectorID), us.Info.CommR, commD) if err != nil { return nil, err } @@ -352,7 +355,7 @@ func (sma StorageMinerActor) ProveCommitSector(act *types.Actor, vmctx types.VMC self.ProvingSet = self.Sectors // TODO: probably want to wait until the miner is above a certain // threshold before starting this - self.ElectionPeriodStart = vmctx.BlockHeight() + self.ElectionPeriodStart = uint64(vmctx.BlockHeight()) } nstate, err := vmctx.Storage().Put(self) @@ -364,7 +367,7 @@ func (sma StorageMinerActor) ProveCommitSector(act *types.Actor, vmctx types.VMC } activateParams, err := SerializeParams(&ActivateStorageDealsParams{ - Deals: params.DealIDs, + DealIDs: params.DealIDs, }) if err != nil { return nil, err @@ -408,12 +411,12 @@ func (sma StorageMinerActor) SubmitFallbackPoSt(act *types.Actor, vmctx types.VM var seed [sectorbuilder.CommLen]byte { randHeight := self.ElectionPeriodStart + build.FallbackPoStDelay - if vmctx.BlockHeight() <= randHeight { + if uint64(vmctx.BlockHeight()) <= randHeight { // TODO: spec, retcode return nil, aerrors.Newf(1, "submit fallback PoSt called too early (%d < %d)", vmctx.BlockHeight(), randHeight) } - rand, err := vmctx.GetRandomness(randHeight) + rand, err := vmctx.GetRandomness(0) if err != nil { return nil, aerrors.Wrap(err, "could not get randomness for PoST") @@ -690,7 +693,7 @@ func (sma StorageMinerActor) GetSectorSize(act *types.Actor, vmctx types.VMConte return nil, err } - return types.NewInt(mi.SectorSize).Bytes(), nil + return types.NewInt(uint64(mi.SectorSize)).Bytes(), nil } func (sma StorageMinerActor) IsSlashed(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) { @@ -713,7 +716,7 @@ func (sma StorageMinerActor) CheckMiner(act *types.Actor, vmctx types.VMContext, return nil, err } - if !isLate(vmctx.BlockHeight(), self) { + if !isLate(uint64(vmctx.BlockHeight()), self) { // Everything's fine return nil, nil } @@ -732,7 +735,7 @@ func (sma StorageMinerActor) CheckMiner(act *types.Actor, vmctx types.VMContext, // Slash for being late - self.SlashedAt = vmctx.BlockHeight() + self.SlashedAt = uint64(vmctx.BlockHeight()) oldPower := self.Power self.Power = types.NewInt(0) @@ -787,7 +790,7 @@ func (sma StorageMinerActor) DeclareFaults(act *types.Actor, vmctx types.VMConte self.FaultSet = nfaults - self.LastFaultSubmission = vmctx.BlockHeight() + self.LastFaultSubmission = uint64(vmctx.BlockHeight()) nstate, aerr := vmctx.Storage().Put(self) if aerr != nil { @@ -814,7 +817,7 @@ func (sma StorageMinerActor) SlashConsensusFault(act *types.Actor, vmctx types.V // GROWTH_RATE determines how fast the slasher share of slashed collateral will increase as block elapses // current GROWTH_RATE results in SLASHER_SHARE reaches 1 after 30 blocks // TODO: define arithmetic precision and rounding for this operation - blockElapsed := vmctx.BlockHeight() - params.AtHeight + blockElapsed := uint64(vmctx.BlockHeight()) - uint64(params.AtHeight) slasherShare := slasherShare(params.SlashedCollateral, blockElapsed) @@ -946,7 +949,7 @@ func onSuccessfulPoSt2(self *StorageMinerActorState, vmctx types.VMContext, acti self.FaultSet = types.NewBitField() oldPower := self.Power - newPower := types.BigMul(types.NewInt(pss.Count-activeFaults), types.NewInt(mi.SectorSize)) + newPower := types.BigMul(types.NewInt(pss.Count-activeFaults), types.NewInt(uint64(mi.SectorSize))) // If below the minimum size requirement, miners have zero power if newPower.LessThan(types.NewInt(build.MinimumMinerPower)) { @@ -970,7 +973,7 @@ func onSuccessfulPoSt2(self *StorageMinerActorState, vmctx types.VMContext, acti if !(oldPower.IsZero() && newPower.IsZero()) { enc, err := SerializeParams(&UpdateStorageParams{ Delta: delta, - NextSlashDeadline: vmctx.BlockHeight() + build.SlashablePowerDelay, + NextSlashDeadline: uint64(vmctx.BlockHeight())+ build.SlashablePowerDelay, PreviousSlashDeadline: prevSlashingDeadline, }) if err != nil { @@ -982,7 +985,7 @@ func onSuccessfulPoSt2(self *StorageMinerActorState, vmctx types.VMContext, acti return aerrors.Wrap(err, "updating storage failed") } - self.ElectionPeriodStart = vmctx.BlockHeight() + self.ElectionPeriodStart = uint64(vmctx.BlockHeight()) } var ncid cid.Cid @@ -1033,7 +1036,7 @@ func GetFromSectorSet(ctx context.Context, cst cbor.IpldStore, ss cid.Cid, secto return true, comms[0], comms[1], nil } -func AddToSectorSet(ctx context.Context, blks cbor.IpldStore, ss cid.Cid, sectorID uint64, commR, commD []byte) (cid.Cid, ActorError) { +func AddToSectorSet(ctx context.Context, blks cbor.IpldStore, ss cid.Cid, sectorID abi.SectorNumber, commR, commD []byte) (cid.Cid, ActorError) { if sectorID >= build.MinerMaxSectors { return cid.Undef, aerrors.Newf(25, "sector ID out of range: %d", sectorID) } @@ -1044,7 +1047,7 @@ func AddToSectorSet(ctx context.Context, blks cbor.IpldStore, ss cid.Cid, sector // TODO: Spec says to use SealCommitment, and construct commD from deals each time, // but that would make SubmitPoSt way, way more expensive - if err := ssr.Set(ctx, sectorID, [][]byte{commR, commD}); err != nil { + if err := ssr.Set(ctx, uint64(sectorID), [][]byte{commR, commD}); err != nil { return cid.Undef, aerrors.HandleExternalError(err, "failed to set commitment in sector set") } @@ -1083,8 +1086,8 @@ func uintToStringKey(i uint64) string { type SectorProveCommitInfo struct { Proof []byte - SectorID uint64 - DealIDs []uint64 + SectorID abi.SectorNumber + DealIDs []abi.DealID } func truncateHexPrint(b []byte) string { @@ -1131,7 +1134,7 @@ type DeclareFaultsParams struct { type MinerSlashConsensusFault struct { Slasher address.Address - AtHeight uint64 + AtHeight abi.ChainEpoch SlashedCollateral types.BigInt } diff --git a/chain/actors/actor_paych.go b/chain/actors/actor_paych.go index 05d9a9913..d7a07eee3 100644 --- a/chain/actors/actor_paych.go +++ b/chain/actors/actor_paych.go @@ -123,7 +123,7 @@ func (pca PaymentChannelActor) UpdateChannelState(act *types.Actor, vmctx types. return nil, err } - if vmctx.BlockHeight() < sv.TimeLock { + if uint64(vmctx.BlockHeight()) < sv.TimeLock { return nil, aerrors.New(2, "cannot use this voucher yet!") } @@ -228,7 +228,7 @@ func (pca PaymentChannelActor) Close(act *types.Actor, vmctx types.VMContext, pa return nil, aerrors.New(2, "channel already closing") } - self.ClosingAt = vmctx.BlockHeight() + build.PaymentChannelClosingDelay + self.ClosingAt = uint64(vmctx.BlockHeight()) + build.PaymentChannelClosingDelay if self.ClosingAt < self.MinCloseHeight { self.ClosingAt = self.MinCloseHeight } @@ -256,7 +256,7 @@ func (pca PaymentChannelActor) Collect(act *types.Actor, vmctx types.VMContext, return nil, aerrors.New(1, "payment channel not closing or closed") } - if vmctx.BlockHeight() < self.ClosingAt { + if uint64(vmctx.BlockHeight()) < self.ClosingAt { return nil, aerrors.New(2, "payment channel not closed yet") } _, err := vmctx.Send(self.From, 0, types.BigSub(act.Balance, self.ToSend), nil) diff --git a/chain/actors/actor_storagemarket.go b/chain/actors/actor_storagemarket.go index 383b63fef..d02820b4e 100644 --- a/chain/actors/actor_storagemarket.go +++ b/chain/actors/actor_storagemarket.go @@ -1,28 +1,9 @@ package actors import ( - "bytes" - "context" - "sort" - - "go.opencensus.io/trace" - "golang.org/x/xerrors" - - "github.com/filecoin-project/go-amt-ipld/v2" - "github.com/ipfs/go-cid" - "github.com/ipfs/go-hamt-ipld" - cbor "github.com/ipfs/go-ipld-cbor" - - "github.com/filecoin-project/go-address" - cborutil "github.com/filecoin-project/go-cbor-util" - "github.com/filecoin-project/go-sectorbuilder" - "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/lotus/chain/actors/aerrors" - "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/lib/sigs" + "github.com/filecoin-project/specs-actors/actors/builtin/market" ) -type StorageMarketActor struct{} type smaMethods struct { Constructor uint64 @@ -41,33 +22,7 @@ type smaMethods struct { var SMAMethods = smaMethods{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12} -func (sma StorageMarketActor) Exports() []interface{} { - return []interface{}{ - 2: sma.WithdrawBalance, - 3: sma.AddBalance, - // 4: sma.CheckLockedBalance, - 5: sma.PublishStorageDeals, - // 6: sma.HandleCronAction, - // 7: sma.SettleExpiredDeals, - // 8: sma.ProcessStorageDealsPayment, - // 9: sma.SlashStorageDealCollateral, - // 10: sma.GetLastExpirationFromDealIDs, - 11: sma.ActivateStorageDeals, // TODO: move under PublishStorageDeals after specs team approves - 12: sma.ComputeDataCommitment, - } -} - -type StorageParticipantBalance struct { - Locked types.BigInt - Available types.BigInt -} - -type StorageMarketState struct { - Balances cid.Cid // hamt - Deals cid.Cid // amt - - NextDealID uint64 // TODO: spec -} +type StorageMarketState = market.State // TODO: Drop in favour of car storage type SerializationMode = uint64 @@ -77,590 +32,18 @@ const ( // IPLD / car ) -type StorageDealProposal struct { - PieceRef []byte // cid bytes // TODO: spec says to use cid.Cid, probably not a good idea - PieceSize uint64 +type StorageDealProposal = market.DealProposal - Client address.Address - Provider address.Address +type WithdrawBalanceParams = market.WithdrawBalanceParams - ProposalExpiration uint64 - Duration uint64 // TODO: spec +type PublishStorageDealsParams = market.PublishStorageDealsParams - StoragePricePerEpoch types.BigInt - StorageCollateral types.BigInt +type PublishStorageDealResponse = market.PublishStorageDealsReturn - ProposerSignature *types.Signature -} +type ActivateStorageDealsParams = market.VerifyDealsOnSectorProveCommitParams -func (sdp *StorageDealProposal) TotalStoragePrice() types.BigInt { - return types.BigMul(sdp.StoragePricePerEpoch, types.NewInt(sdp.Duration)) -} +type ComputeDataCommitmentParams = market.ComputeDataCommitmentParams -type SignFunc = func(context.Context, []byte) (*types.Signature, error) - -func (sdp *StorageDealProposal) Sign(ctx context.Context, sign SignFunc) error { - if sdp.ProposerSignature != nil { - return xerrors.New("signature already present in StorageDealProposal") - } - var buf bytes.Buffer - if err := sdp.MarshalCBOR(&buf); err != nil { - return err - } - sig, err := sign(ctx, buf.Bytes()) - if err != nil { - return err - } - sdp.ProposerSignature = sig - return nil -} - -func (sdp *StorageDealProposal) Cid() (cid.Cid, error) { - nd, err := cborutil.AsIpld(sdp) - if err != nil { - return cid.Undef, err - } - - return nd.Cid(), nil -} - -func (sdp *StorageDealProposal) Verify(worker address.Address) error { - if sdp.Client != worker || worker == address.Undef { - unsigned := *sdp - unsigned.ProposerSignature = nil - var buf bytes.Buffer - if err := unsigned.MarshalCBOR(&buf); err != nil { - return err - } - - if err := sigs.Verify(sdp.ProposerSignature, sdp.Client, buf.Bytes()); err != nil { - return err - } - } - - return nil -} - -type OnChainDeal struct { - PieceRef []byte // cid bytes // TODO: spec says to use cid.Cid, probably not a good idea - PieceSize uint64 - - Client address.Address - Provider address.Address - - ProposalExpiration uint64 - Duration uint64 // TODO: spec - - StoragePricePerEpoch types.BigInt - StorageCollateral types.BigInt - ActivationEpoch uint64 // 0 = inactive -} - -type WithdrawBalanceParams struct { - Balance types.BigInt -} - -func (sma StorageMarketActor) WithdrawBalance(act *types.Actor, vmctx types.VMContext, params *WithdrawBalanceParams) ([]byte, ActorError) { - // TODO: (spec) this should be 2-stage - - var self StorageMarketState - old := vmctx.Storage().GetHead() - if err := vmctx.Storage().Get(old, &self); err != nil { - return nil, err - } - - b, bnd, err := GetMarketBalances(vmctx.Context(), vmctx.Ipld(), self.Balances, vmctx.Message().From) - if err != nil { - return nil, aerrors.Wrap(err, "could not get balance") - } - - balance := b[0] - - if balance.Available.LessThan(params.Balance) { - return nil, aerrors.Newf(1, "can not withdraw more funds than available: %s > %s", params.Balance, b[0].Available) - } - - balance.Available = types.BigSub(balance.Available, params.Balance) - - _, err = vmctx.Send(vmctx.Message().From, 0, params.Balance, nil) - if err != nil { - return nil, aerrors.Wrap(err, "sending funds failed") - } - - bcid, err := setMarketBalances(vmctx, bnd, map[address.Address]StorageParticipantBalance{ - vmctx.Message().From: balance, - }) - if err != nil { - return nil, err - } - - self.Balances = bcid - - nroot, err := vmctx.Storage().Put(&self) - if err != nil { - return nil, err - } - - return nil, vmctx.Storage().Commit(old, nroot) -} - -func (sma StorageMarketActor) AddBalance(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) { - var self StorageMarketState - old := vmctx.Storage().GetHead() - if err := vmctx.Storage().Get(old, &self); err != nil { - return nil, err - } - - b, bnd, err := GetMarketBalances(vmctx.Context(), vmctx.Ipld(), self.Balances, vmctx.Message().From) - if err != nil { - return nil, aerrors.Wrap(err, "could not get balance") - } - - balance := b[0] - - balance.Available = types.BigAdd(balance.Available, vmctx.Message().Value) - - bcid, err := setMarketBalances(vmctx, bnd, map[address.Address]StorageParticipantBalance{ - vmctx.Message().From: balance, - }) - if err != nil { - return nil, err - } - - self.Balances = bcid - - nroot, err := vmctx.Storage().Put(&self) - if err != nil { - return nil, err - } - - return nil, vmctx.Storage().Commit(old, nroot) -} - -func setMarketBalances(vmctx types.VMContext, nd *hamt.Node, set map[address.Address]StorageParticipantBalance) (cid.Cid, ActorError) { - keys := make([]address.Address, 0, len(set)) - for k := range set { - keys = append(keys, k) - } - sort.Slice(keys, func(i, j int) bool { - return bytes.Compare(keys[i].Bytes(), keys[j].Bytes()) < 0 - }) - for _, addr := range keys { - balance := set[addr] - if err := nd.Set(vmctx.Context(), string(addr.Bytes()), &balance); err != nil { - return cid.Undef, aerrors.HandleExternalError(err, "setting new balance") - } - } - if err := nd.Flush(vmctx.Context()); err != nil { - return cid.Undef, aerrors.HandleExternalError(err, "flushing balance hamt") - } - - c, err := vmctx.Ipld().Put(vmctx.Context(), nd) - if err != nil { - return cid.Undef, aerrors.HandleExternalError(err, "failed to balances storage") - } - return c, nil -} - -func GetMarketBalances(ctx context.Context, store cbor.IpldStore, rcid cid.Cid, addrs ...address.Address) ([]StorageParticipantBalance, *hamt.Node, ActorError) { - ctx, span := trace.StartSpan(ctx, "GetMarketBalances") - defer span.End() - - nd, err := hamt.LoadNode(ctx, store, rcid) - if err != nil { - return nil, nil, aerrors.HandleExternalError(err, "failed to load miner set") - } - - out := make([]StorageParticipantBalance, len(addrs)) - - for i, a := range addrs { - var balance StorageParticipantBalance - err = nd.Find(ctx, string(a.Bytes()), &balance) - switch err { - case hamt.ErrNotFound: - out[i] = StorageParticipantBalance{ - Locked: types.NewInt(0), - Available: types.NewInt(0), - } - case nil: - out[i] = balance - default: - return nil, nil, aerrors.HandleExternalError(err, "failed to do set lookup") - } - - } - - return out, nd, nil -} - -/* -func (sma StorageMarketActor) CheckLockedBalance(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) { - -} -*/ - -type PublishStorageDealsParams struct { - Deals []StorageDealProposal -} - -type PublishStorageDealResponse struct { - DealIDs []uint64 -} - -func (sma StorageMarketActor) PublishStorageDeals(act *types.Actor, vmctx types.VMContext, params *PublishStorageDealsParams) ([]byte, ActorError) { - var self StorageMarketState - old := vmctx.Storage().GetHead() - if err := vmctx.Storage().Get(old, &self); err != nil { - return nil, err - } - - deals, err := amt.LoadAMT(vmctx.Context(), vmctx.Ipld(), self.Deals) - if err != nil { - return nil, aerrors.HandleExternalError(err, "loading deals amt") - } - - // todo: handle duplicate deals - - if len(params.Deals) == 0 { - return nil, aerrors.New(1, "no storage deals in params.Deals") - } - - out := PublishStorageDealResponse{ - DealIDs: make([]uint64, len(params.Deals)), - } - - workerBytes, aerr := vmctx.Send(params.Deals[0].Provider, MAMethods.GetWorkerAddr, types.NewInt(0), nil) - if aerr != nil { - return nil, aerr - } - providerWorker, err := address.NewFromBytes(workerBytes) - if err != nil { - return nil, aerrors.HandleExternalError(err, "parsing provider worker address bytes") - } - - // TODO: REVIEW: Do we want to check if provider exists in the power actor? - - for i, deal := range params.Deals { - if err := self.validateDeal(vmctx, deal, providerWorker); err != nil { - return nil, err - } - - err := deals.Set(vmctx.Context(), self.NextDealID, &OnChainDeal{ - PieceRef: deal.PieceRef, - PieceSize: deal.PieceSize, - - Client: deal.Client, - Provider: deal.Provider, - - ProposalExpiration: deal.ProposalExpiration, - Duration: deal.Duration, - - StoragePricePerEpoch: deal.StoragePricePerEpoch, - StorageCollateral: deal.StorageCollateral, - ActivationEpoch: 0, - }) - if err != nil { - return nil, aerrors.HandleExternalError(err, "setting deal in deal AMT") - } - out.DealIDs[i] = self.NextDealID - - self.NextDealID++ - } - - dealsCid, err := deals.Flush(vmctx.Context()) - if err != nil { - return nil, aerrors.HandleExternalError(err, "saving deals AMT") - } - - self.Deals = dealsCid - - nroot, err := vmctx.Storage().Put(&self) - if err != nil { - return nil, aerrors.HandleExternalError(err, "storing state failed") - } - - aerr = vmctx.Storage().Commit(old, nroot) - if aerr != nil { - return nil, aerr - } - - var outBuf bytes.Buffer - if err := out.MarshalCBOR(&outBuf); err != nil { - return nil, aerrors.HandleExternalError(err, "serialising output") - } - - return outBuf.Bytes(), nil -} - -func (st *StorageMarketState) validateDeal(vmctx types.VMContext, deal StorageDealProposal, providerWorker address.Address) aerrors.ActorError { - ctx, span := trace.StartSpan(vmctx.Context(), "validateDeal") - defer span.End() - - if vmctx.BlockHeight() > deal.ProposalExpiration { - return aerrors.New(1, "deal proposal already expired") - } - - if vmctx.Message().From != providerWorker { - return aerrors.New(2, "Deals must be submitted by the miner worker") - } - - if err := deal.Verify(providerWorker); err != nil { - return aerrors.Absorb(err, 3, "verifying proposer signature") - } - - // TODO: do some caching (changes gas so needs to be in spec too) - b, bnd, aerr := GetMarketBalances(ctx, vmctx.Ipld(), st.Balances, deal.Client, providerWorker) - if aerr != nil { - return aerrors.Wrap(aerr, "getting client, and provider balances") - } - clientBalance := b[0] - providerBalance := b[1] - - totalPrice := deal.TotalStoragePrice() - - if clientBalance.Available.LessThan(totalPrice) { - return aerrors.Newf(5, "client doesn't have enough available funds to cover storage price; %d < %d", clientBalance.Available, totalPrice) - } - - clientBalance = lockFunds(clientBalance, totalPrice) - - // TODO: REVIEW: Not clear who pays for this - if providerBalance.Available.LessThan(deal.StorageCollateral) { - return aerrors.Newf(6, "provider doesn't have enough available funds to cover StorageCollateral; %d < %d", providerBalance.Available, deal.StorageCollateral) - } - - providerBalance = lockFunds(providerBalance, deal.StorageCollateral) - - // TODO: piece checks (e.g. size > sectorSize)? - - bcid, aerr := setMarketBalances(vmctx, bnd, map[address.Address]StorageParticipantBalance{ - deal.Client: clientBalance, - providerWorker: providerBalance, - }) - if aerr != nil { - return aerr - } - - st.Balances = bcid - - return nil -} - -type ActivateStorageDealsParams struct { - Deals []uint64 -} - -func (sma StorageMarketActor) ActivateStorageDeals(act *types.Actor, vmctx types.VMContext, params *ActivateStorageDealsParams) ([]byte, ActorError) { - ctx := vmctx.Context() - var self StorageMarketState - old := vmctx.Storage().GetHead() - if err := vmctx.Storage().Get(old, &self); err != nil { - return nil, err - } - - deals, err := amt.LoadAMT(ctx, vmctx.Ipld(), self.Deals) - if err != nil { - return nil, aerrors.HandleExternalError(err, "loading deals amt") - } - - for _, deal := range params.Deals { - var dealInfo OnChainDeal - if err := deals.Get(ctx, deal, &dealInfo); err != nil { - if _, is := err.(*amt.ErrNotFound); is { - return nil, aerrors.New(3, "deal not found") - } - return nil, aerrors.HandleExternalError(err, "getting deal info failed") - } - - if vmctx.Message().From != dealInfo.Provider { - return nil, aerrors.New(1, "ActivateStorageDeals can only be called by the deal provider") - } - - if vmctx.BlockHeight() > dealInfo.ProposalExpiration { - return nil, aerrors.New(2, "deal cannot be activated: proposal expired") - } - - if dealInfo.ActivationEpoch > 0 { - // this probably can't happen in practice - return nil, aerrors.New(3, "deal already active") - } - - dealInfo.ActivationEpoch = vmctx.BlockHeight() - - if err := deals.Set(ctx, deal, &dealInfo); err != nil { - return nil, aerrors.HandleExternalError(err, "setting deal info in AMT failed") - } - } - - dealsCid, err := deals.Flush(ctx) - if err != nil { - return nil, aerrors.HandleExternalError(err, "saving deals AMT") - } - - self.Deals = dealsCid - - nroot, err := vmctx.Storage().Put(&self) - if err != nil { - return nil, aerrors.HandleExternalError(err, "storing state failed") - } - - aerr := vmctx.Storage().Commit(old, nroot) - if aerr != nil { - return nil, aerr - } - - return nil, nil -} - -type ProcessStorageDealsPaymentParams struct { - DealIDs []uint64 -} - -func (sma StorageMarketActor) ProcessStorageDealsPayment(act *types.Actor, vmctx types.VMContext, params *ProcessStorageDealsPaymentParams) ([]byte, ActorError) { - ctx := vmctx.Context() - var self StorageMarketState - old := vmctx.Storage().GetHead() - if err := vmctx.Storage().Get(old, &self); err != nil { - return nil, err - } - - deals, err := amt.LoadAMT(ctx, vmctx.Ipld(), self.Deals) - if err != nil { - return nil, aerrors.HandleExternalError(err, "loading deals amt") - } - - // TODO: Would be nice if send could assert actor type - workerBytes, aerr := vmctx.Send(vmctx.Message().From, MAMethods.GetWorkerAddr, types.NewInt(0), nil) - if aerr != nil { - return nil, aerr - } - providerWorker, err := address.NewFromBytes(workerBytes) - if err != nil { - return nil, aerrors.HandleExternalError(err, "parsing provider worker address bytes") - } - - for _, deal := range params.DealIDs { - var dealInfo OnChainDeal - if err := deals.Get(ctx, deal, &dealInfo); err != nil { - if _, is := err.(*amt.ErrNotFound); is { - return nil, aerrors.New(2, "deal not found") - } - return nil, aerrors.HandleExternalError(err, "getting deal info failed") - } - - if dealInfo.Provider != vmctx.Message().From { - return nil, aerrors.New(3, "ProcessStorageDealsPayment can only be called by deal provider") - } - - if vmctx.BlockHeight() < dealInfo.ActivationEpoch { - // TODO: This is probably fatal - return nil, aerrors.New(4, "ActivationEpoch lower than block height") - } - - if vmctx.BlockHeight() > dealInfo.ActivationEpoch+dealInfo.Duration { - // Deal expired, miner should drop it - // TODO: process payment for the remainder of last proving period - return nil, nil - } - - toPay := types.BigMul(dealInfo.StoragePricePerEpoch, types.NewInt(build.SlashablePowerDelay)) - - b, bnd, aerr := GetMarketBalances(vmctx.Context(), vmctx.Ipld(), self.Balances, dealInfo.Client, providerWorker) - if aerr != nil { - return nil, aerr - } - clientBal := b[0] - providerBal := b[1] - - clientBal.Locked, providerBal.Available = transferFunds(clientBal.Locked, providerBal.Available, toPay) - - // TODO: call set once - bcid, aerr := setMarketBalances(vmctx, bnd, map[address.Address]StorageParticipantBalance{ - dealInfo.Client: clientBal, - providerWorker: providerBal, - }) - if aerr != nil { - return nil, aerr - } - - self.Balances = bcid - } - - nroot, err := vmctx.Storage().Put(&self) - if err != nil { - return nil, aerrors.HandleExternalError(err, "storing state failed") - } - - aerr = vmctx.Storage().Commit(old, nroot) - if aerr != nil { - return nil, aerr - } - - return nil, nil -} - -func lockFunds(p StorageParticipantBalance, amt types.BigInt) StorageParticipantBalance { - p.Available, p.Locked = transferFunds(p.Available, p.Locked, amt) - return p -} - -func transferFunds(from, to, amt types.BigInt) (types.BigInt, types.BigInt) { - // TODO: some asserts - return types.BigSub(from, amt), types.BigAdd(to, amt) -} - -type ComputeDataCommitmentParams struct { - DealIDs []uint64 - SectorSize uint64 -} - -func (sma StorageMarketActor) ComputeDataCommitment(act *types.Actor, vmctx types.VMContext, params *ComputeDataCommitmentParams) ([]byte, ActorError) { - ctx := vmctx.Context() - var self StorageMarketState - old := vmctx.Storage().GetHead() - if err := vmctx.Storage().Get(old, &self); err != nil { - return nil, err - } - - deals, err := amt.LoadAMT(ctx, vmctx.Ipld(), self.Deals) - if err != nil { - return nil, aerrors.HandleExternalError(err, "loading deals amt") - } - - if len(params.DealIDs) == 0 { - return nil, aerrors.New(3, "no deal IDs") - } - - var pieces []sectorbuilder.PublicPieceInfo - for _, deal := range params.DealIDs { - var dealInfo OnChainDeal - if err := deals.Get(ctx, deal, &dealInfo); err != nil { - if _, is := err.(*amt.ErrNotFound); is { - return nil, aerrors.New(4, "deal not found") - } - return nil, aerrors.HandleExternalError(err, "getting deal info failed") - } - - if dealInfo.Provider != vmctx.Message().From { - return nil, aerrors.New(5, "referenced deal was not from caller") - } - - var commP [32]byte - copy(commP[:], dealInfo.PieceRef) - - pieces = append(pieces, sectorbuilder.PublicPieceInfo{ - Size: dealInfo.PieceSize, - CommP: commP, - }) - } - - commd, err := sectorbuilder.GenerateDataCommitment(params.SectorSize, pieces) - if err != nil { - return nil, aerrors.Absorb(err, 6, "failed to generate data commitment from pieces") - } - - return commd[:], nil -} /* func (sma StorageMarketActor) HandleCronAction(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) { diff --git a/chain/actors/actor_storagepower.go b/chain/actors/actor_storagepower.go index 78213998e..33bfde49e 100644 --- a/chain/actors/actor_storagepower.go +++ b/chain/actors/actor_storagepower.go @@ -6,6 +6,7 @@ import ( "io" "github.com/filecoin-project/go-amt-ipld/v2" + "github.com/filecoin-project/specs-actors/actors/abi" cid "github.com/ipfs/go-cid" hamt "github.com/ipfs/go-hamt-ipld" cbor "github.com/ipfs/go-ipld-cbor" @@ -63,12 +64,12 @@ type StoragePowerState struct { type CreateStorageMinerParams struct { Owner address.Address Worker address.Address - SectorSize uint64 + SectorSize abi.SectorSize PeerID peer.ID } func (spa StoragePowerActor) CreateStorageMiner(act *types.Actor, vmctx types.VMContext, params *CreateStorageMinerParams) ([]byte, ActorError) { - if !build.SupportedSectorSize(params.SectorSize) { + if !build.SupportedSectorSize(uint64(params.SectorSize)) { return nil, aerrors.Newf(1, "Unsupported sector size: %d", params.SectorSize) } @@ -593,7 +594,7 @@ func (spa StoragePowerActor) CheckProofSubmissions(act *types.Actor, vmctx types return nil, err } - for i := self.LastMinerCheck; i < vmctx.BlockHeight(); i++ { + for i := self.LastMinerCheck; i < uint64(vmctx.BlockHeight()); i++ { height := i + 1 err := checkProofSubmissionsAtH(vmctx, &self, height) @@ -602,7 +603,7 @@ func (spa StoragePowerActor) CheckProofSubmissions(act *types.Actor, vmctx types } } - self.LastMinerCheck = vmctx.BlockHeight() + self.LastMinerCheck = uint64(vmctx.BlockHeight()) nroot, aerr := vmctx.Storage().Put(&self) if aerr != nil { diff --git a/chain/actors/cbor_gen.go b/chain/actors/cbor_gen.go index e77b548f0..9b27dffb2 100644 --- a/chain/actors/cbor_gen.go +++ b/chain/actors/cbor_gen.go @@ -501,61 +501,6 @@ func (t *StorageMinerConstructorParams) MarshalCBOR(w io.Writer) error { return nil } -func (t *StorageMinerConstructorParams) UnmarshalCBOR(r io.Reader) error { - br := cbg.GetPeeker(r) - - maj, extra, err := cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajArray { - return fmt.Errorf("cbor input should be of type array") - } - - if extra != 4 { - return fmt.Errorf("cbor input had wrong number of fields") - } - - // t.Owner (address.Address) (struct) - - { - - if err := t.Owner.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.Worker (address.Address) (struct) - - { - - if err := t.Worker.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.SectorSize (uint64) (uint64) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.SectorSize = uint64(extra) - // t.PeerID (peer.ID) (string) - - { - sval, err := cbg.ReadString(br) - if err != nil { - return err - } - - t.PeerID = peer.ID(sval) - } - return nil -} func (t *SectorPreCommitInfo) MarshalCBOR(w io.Writer) error { if t == nil { @@ -603,6 +548,9 @@ func (t *SectorPreCommitInfo) MarshalCBOR(w io.Writer) error { } return nil } +func (i IsValidMinerParam) MarshalCBOR(io.Writer) error { + panic("implement me") +} func (t *SectorPreCommitInfo) UnmarshalCBOR(r io.Reader) error { br := cbg.GetPeeker(r) @@ -628,7 +576,6 @@ func (t *SectorPreCommitInfo) UnmarshalCBOR(r io.Reader) error { if maj != cbg.MajUnsignedInt { return fmt.Errorf("wrong type for uint64 field") } - t.SectorNumber = uint64(extra) // t.CommR ([]uint8) (slice) maj, extra, err = cbg.CborReadHeader(br) @@ -838,7 +785,6 @@ func (t *MinerInfo) UnmarshalCBOR(r io.Reader) error { if maj != cbg.MajUnsignedInt { return fmt.Errorf("wrong type for uint64 field") } - t.SectorSize = uint64(extra) return nil } @@ -1817,104 +1763,6 @@ func (t *CreateStorageMinerParams) MarshalCBOR(w io.Writer) error { return nil } -func (t *CreateStorageMinerParams) UnmarshalCBOR(r io.Reader) error { - br := cbg.GetPeeker(r) - - maj, extra, err := cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajArray { - return fmt.Errorf("cbor input should be of type array") - } - - if extra != 4 { - return fmt.Errorf("cbor input had wrong number of fields") - } - - // t.Owner (address.Address) (struct) - - { - - if err := t.Owner.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.Worker (address.Address) (struct) - - { - - if err := t.Worker.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.SectorSize (uint64) (uint64) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.SectorSize = uint64(extra) - // t.PeerID (peer.ID) (string) - - { - sval, err := cbg.ReadString(br) - if err != nil { - return err - } - - t.PeerID = peer.ID(sval) - } - return nil -} - -func (t *IsValidMinerParam) MarshalCBOR(w io.Writer) error { - if t == nil { - _, err := w.Write(cbg.CborNull) - return err - } - if _, err := w.Write([]byte{129}); err != nil { - return err - } - - // t.Addr (address.Address) (struct) - if err := t.Addr.MarshalCBOR(w); err != nil { - return err - } - return nil -} - -func (t *IsValidMinerParam) UnmarshalCBOR(r io.Reader) error { - br := cbg.GetPeeker(r) - - maj, extra, err := cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajArray { - return fmt.Errorf("cbor input should be of type array") - } - - if extra != 1 { - return fmt.Errorf("cbor input had wrong number of fields") - } - - // t.Addr (address.Address) (struct) - - { - - if err := t.Addr.UnmarshalCBOR(br); err != nil { - return err - } - - } - return nil -} func (t *PowerLookupParams) MarshalCBOR(w io.Writer) error { if t == nil { @@ -2208,14 +2056,7 @@ func (t *MinerSlashConsensusFault) UnmarshalCBOR(r io.Reader) error { } // t.AtHeight (uint64) (uint64) - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.AtHeight = uint64(extra) + // t.SlashedCollateral (types.BigInt) (struct) { @@ -2227,1045 +2068,6 @@ func (t *MinerSlashConsensusFault) UnmarshalCBOR(r io.Reader) error { } return nil } - -func (t *StorageParticipantBalance) MarshalCBOR(w io.Writer) error { - if t == nil { - _, err := w.Write(cbg.CborNull) - return err - } - if _, err := w.Write([]byte{130}); err != nil { - return err - } - - // t.Locked (types.BigInt) (struct) - if err := t.Locked.MarshalCBOR(w); err != nil { - return err - } - - // t.Available (types.BigInt) (struct) - if err := t.Available.MarshalCBOR(w); err != nil { - return err - } - return nil -} - -func (t *StorageParticipantBalance) UnmarshalCBOR(r io.Reader) error { - br := cbg.GetPeeker(r) - - maj, extra, err := cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajArray { - return fmt.Errorf("cbor input should be of type array") - } - - if extra != 2 { - return fmt.Errorf("cbor input had wrong number of fields") - } - - // t.Locked (types.BigInt) (struct) - - { - - if err := t.Locked.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.Available (types.BigInt) (struct) - - { - - if err := t.Available.UnmarshalCBOR(br); err != nil { - return err - } - - } - return nil -} - -func (t *StorageMarketState) MarshalCBOR(w io.Writer) error { - if t == nil { - _, err := w.Write(cbg.CborNull) - return err - } - if _, err := w.Write([]byte{131}); err != nil { - return err - } - - // t.Balances (cid.Cid) (struct) - - if err := cbg.WriteCid(w, t.Balances); err != nil { - return xerrors.Errorf("failed to write cid field t.Balances: %w", err) - } - - // t.Deals (cid.Cid) (struct) - - if err := cbg.WriteCid(w, t.Deals); err != nil { - return xerrors.Errorf("failed to write cid field t.Deals: %w", err) - } - - // t.NextDealID (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.NextDealID))); err != nil { - return err - } - return nil -} - -func (t *StorageMarketState) UnmarshalCBOR(r io.Reader) error { - br := cbg.GetPeeker(r) - - maj, extra, err := cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajArray { - return fmt.Errorf("cbor input should be of type array") - } - - if extra != 3 { - return fmt.Errorf("cbor input had wrong number of fields") - } - - // t.Balances (cid.Cid) (struct) - - { - - c, err := cbg.ReadCid(br) - if err != nil { - return xerrors.Errorf("failed to read cid field t.Balances: %w", err) - } - - t.Balances = c - - } - // t.Deals (cid.Cid) (struct) - - { - - c, err := cbg.ReadCid(br) - if err != nil { - return xerrors.Errorf("failed to read cid field t.Deals: %w", err) - } - - t.Deals = c - - } - // t.NextDealID (uint64) (uint64) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.NextDealID = uint64(extra) - return nil -} - -func (t *WithdrawBalanceParams) MarshalCBOR(w io.Writer) error { - if t == nil { - _, err := w.Write(cbg.CborNull) - return err - } - if _, err := w.Write([]byte{129}); err != nil { - return err - } - - // t.Balance (types.BigInt) (struct) - if err := t.Balance.MarshalCBOR(w); err != nil { - return err - } - return nil -} - -func (t *WithdrawBalanceParams) UnmarshalCBOR(r io.Reader) error { - br := cbg.GetPeeker(r) - - maj, extra, err := cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajArray { - return fmt.Errorf("cbor input should be of type array") - } - - if extra != 1 { - return fmt.Errorf("cbor input had wrong number of fields") - } - - // t.Balance (types.BigInt) (struct) - - { - - if err := t.Balance.UnmarshalCBOR(br); err != nil { - return err - } - - } - return nil -} - -func (t *StorageDealProposal) MarshalCBOR(w io.Writer) error { - if t == nil { - _, err := w.Write(cbg.CborNull) - return err - } - if _, err := w.Write([]byte{137}); err != nil { - return err - } - - // t.PieceRef ([]uint8) (slice) - if len(t.PieceRef) > cbg.ByteArrayMaxLen { - return xerrors.Errorf("Byte array in field t.PieceRef was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.PieceRef)))); err != nil { - return err - } - if _, err := w.Write(t.PieceRef); err != nil { - return err - } - - // t.PieceSize (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.PieceSize))); err != nil { - return err - } - - // t.Client (address.Address) (struct) - if err := t.Client.MarshalCBOR(w); err != nil { - return err - } - - // t.Provider (address.Address) (struct) - if err := t.Provider.MarshalCBOR(w); err != nil { - return err - } - - // t.ProposalExpiration (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.ProposalExpiration))); err != nil { - return err - } - - // t.Duration (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Duration))); err != nil { - return err - } - - // t.StoragePricePerEpoch (types.BigInt) (struct) - if err := t.StoragePricePerEpoch.MarshalCBOR(w); err != nil { - return err - } - - // t.StorageCollateral (types.BigInt) (struct) - if err := t.StorageCollateral.MarshalCBOR(w); err != nil { - return err - } - - // t.ProposerSignature (types.Signature) (struct) - if err := t.ProposerSignature.MarshalCBOR(w); err != nil { - return err - } - return nil -} - -func (t *StorageDealProposal) UnmarshalCBOR(r io.Reader) error { - br := cbg.GetPeeker(r) - - maj, extra, err := cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajArray { - return fmt.Errorf("cbor input should be of type array") - } - - if extra != 9 { - return fmt.Errorf("cbor input had wrong number of fields") - } - - // t.PieceRef ([]uint8) (slice) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.ByteArrayMaxLen { - return fmt.Errorf("t.PieceRef: byte array too large (%d)", extra) - } - if maj != cbg.MajByteString { - return fmt.Errorf("expected byte array") - } - t.PieceRef = make([]byte, extra) - if _, err := io.ReadFull(br, t.PieceRef); err != nil { - return err - } - // t.PieceSize (uint64) (uint64) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.PieceSize = uint64(extra) - // t.Client (address.Address) (struct) - - { - - if err := t.Client.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.Provider (address.Address) (struct) - - { - - if err := t.Provider.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.ProposalExpiration (uint64) (uint64) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.ProposalExpiration = uint64(extra) - // t.Duration (uint64) (uint64) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.Duration = uint64(extra) - // t.StoragePricePerEpoch (types.BigInt) (struct) - - { - - if err := t.StoragePricePerEpoch.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.StorageCollateral (types.BigInt) (struct) - - { - - if err := t.StorageCollateral.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.ProposerSignature (types.Signature) (struct) - - { - - pb, err := br.PeekByte() - if err != nil { - return err - } - if pb == cbg.CborNull[0] { - var nbuf [1]byte - if _, err := br.Read(nbuf[:]); err != nil { - return err - } - } else { - t.ProposerSignature = new(types.Signature) - if err := t.ProposerSignature.UnmarshalCBOR(br); err != nil { - return err - } - } - - } - return nil -} - -func (t *PublishStorageDealsParams) MarshalCBOR(w io.Writer) error { - if t == nil { - _, err := w.Write(cbg.CborNull) - return err - } - if _, err := w.Write([]byte{129}); err != nil { - return err - } - - // t.Deals ([]actors.StorageDealProposal) (slice) - if len(t.Deals) > cbg.MaxLength { - return xerrors.Errorf("Slice value in field t.Deals was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Deals)))); err != nil { - return err - } - for _, v := range t.Deals { - if err := v.MarshalCBOR(w); err != nil { - return err - } - } - return nil -} - -func (t *PublishStorageDealsParams) UnmarshalCBOR(r io.Reader) error { - br := cbg.GetPeeker(r) - - maj, extra, err := cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajArray { - return fmt.Errorf("cbor input should be of type array") - } - - if extra != 1 { - return fmt.Errorf("cbor input had wrong number of fields") - } - - // t.Deals ([]actors.StorageDealProposal) (slice) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.MaxLength { - return fmt.Errorf("t.Deals: array too large (%d)", extra) - } - - if maj != cbg.MajArray { - return fmt.Errorf("expected cbor array") - } - if extra > 0 { - t.Deals = make([]StorageDealProposal, extra) - } - for i := 0; i < int(extra); i++ { - - var v StorageDealProposal - if err := v.UnmarshalCBOR(br); err != nil { - return err - } - - t.Deals[i] = v - } - - return nil -} - -func (t *PublishStorageDealResponse) MarshalCBOR(w io.Writer) error { - if t == nil { - _, err := w.Write(cbg.CborNull) - return err - } - if _, err := w.Write([]byte{129}); err != nil { - return err - } - - // t.DealIDs ([]uint64) (slice) - if len(t.DealIDs) > cbg.MaxLength { - return xerrors.Errorf("Slice value in field t.DealIDs was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.DealIDs)))); err != nil { - return err - } - for _, v := range t.DealIDs { - if err := cbg.CborWriteHeader(w, cbg.MajUnsignedInt, v); err != nil { - return err - } - } - return nil -} - -func (t *PublishStorageDealResponse) UnmarshalCBOR(r io.Reader) error { - br := cbg.GetPeeker(r) - - maj, extra, err := cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajArray { - return fmt.Errorf("cbor input should be of type array") - } - - if extra != 1 { - return fmt.Errorf("cbor input had wrong number of fields") - } - - // t.DealIDs ([]uint64) (slice) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.MaxLength { - return fmt.Errorf("t.DealIDs: array too large (%d)", extra) - } - - if maj != cbg.MajArray { - return fmt.Errorf("expected cbor array") - } - if extra > 0 { - t.DealIDs = make([]uint64, extra) - } - for i := 0; i < int(extra); i++ { - - maj, val, err := cbg.CborReadHeader(br) - if err != nil { - return xerrors.Errorf("failed to read uint64 for t.DealIDs slice: %w", err) - } - - if maj != cbg.MajUnsignedInt { - return xerrors.Errorf("value read for array t.DealIDs was not a uint, instead got %d", maj) - } - - t.DealIDs[i] = val - } - - return nil -} - -func (t *ActivateStorageDealsParams) MarshalCBOR(w io.Writer) error { - if t == nil { - _, err := w.Write(cbg.CborNull) - return err - } - if _, err := w.Write([]byte{129}); err != nil { - return err - } - - // t.Deals ([]uint64) (slice) - if len(t.Deals) > cbg.MaxLength { - return xerrors.Errorf("Slice value in field t.Deals was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Deals)))); err != nil { - return err - } - for _, v := range t.Deals { - if err := cbg.CborWriteHeader(w, cbg.MajUnsignedInt, v); err != nil { - return err - } - } - return nil -} - -func (t *ActivateStorageDealsParams) UnmarshalCBOR(r io.Reader) error { - br := cbg.GetPeeker(r) - - maj, extra, err := cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajArray { - return fmt.Errorf("cbor input should be of type array") - } - - if extra != 1 { - return fmt.Errorf("cbor input had wrong number of fields") - } - - // t.Deals ([]uint64) (slice) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.MaxLength { - return fmt.Errorf("t.Deals: array too large (%d)", extra) - } - - if maj != cbg.MajArray { - return fmt.Errorf("expected cbor array") - } - if extra > 0 { - t.Deals = make([]uint64, extra) - } - for i := 0; i < int(extra); i++ { - - maj, val, err := cbg.CborReadHeader(br) - if err != nil { - return xerrors.Errorf("failed to read uint64 for t.Deals slice: %w", err) - } - - if maj != cbg.MajUnsignedInt { - return xerrors.Errorf("value read for array t.Deals was not a uint, instead got %d", maj) - } - - t.Deals[i] = val - } - - return nil -} - -func (t *ProcessStorageDealsPaymentParams) MarshalCBOR(w io.Writer) error { - if t == nil { - _, err := w.Write(cbg.CborNull) - return err - } - if _, err := w.Write([]byte{129}); err != nil { - return err - } - - // t.DealIDs ([]uint64) (slice) - if len(t.DealIDs) > cbg.MaxLength { - return xerrors.Errorf("Slice value in field t.DealIDs was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.DealIDs)))); err != nil { - return err - } - for _, v := range t.DealIDs { - if err := cbg.CborWriteHeader(w, cbg.MajUnsignedInt, v); err != nil { - return err - } - } - return nil -} - -func (t *ProcessStorageDealsPaymentParams) UnmarshalCBOR(r io.Reader) error { - br := cbg.GetPeeker(r) - - maj, extra, err := cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajArray { - return fmt.Errorf("cbor input should be of type array") - } - - if extra != 1 { - return fmt.Errorf("cbor input had wrong number of fields") - } - - // t.DealIDs ([]uint64) (slice) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.MaxLength { - return fmt.Errorf("t.DealIDs: array too large (%d)", extra) - } - - if maj != cbg.MajArray { - return fmt.Errorf("expected cbor array") - } - if extra > 0 { - t.DealIDs = make([]uint64, extra) - } - for i := 0; i < int(extra); i++ { - - maj, val, err := cbg.CborReadHeader(br) - if err != nil { - return xerrors.Errorf("failed to read uint64 for t.DealIDs slice: %w", err) - } - - if maj != cbg.MajUnsignedInt { - return xerrors.Errorf("value read for array t.DealIDs was not a uint, instead got %d", maj) - } - - t.DealIDs[i] = val - } - - return nil -} - -func (t *OnChainDeal) MarshalCBOR(w io.Writer) error { - if t == nil { - _, err := w.Write(cbg.CborNull) - return err - } - if _, err := w.Write([]byte{137}); err != nil { - return err - } - - // t.PieceRef ([]uint8) (slice) - if len(t.PieceRef) > cbg.ByteArrayMaxLen { - return xerrors.Errorf("Byte array in field t.PieceRef was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.PieceRef)))); err != nil { - return err - } - if _, err := w.Write(t.PieceRef); err != nil { - return err - } - - // t.PieceSize (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.PieceSize))); err != nil { - return err - } - - // t.Client (address.Address) (struct) - if err := t.Client.MarshalCBOR(w); err != nil { - return err - } - - // t.Provider (address.Address) (struct) - if err := t.Provider.MarshalCBOR(w); err != nil { - return err - } - - // t.ProposalExpiration (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.ProposalExpiration))); err != nil { - return err - } - - // t.Duration (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Duration))); err != nil { - return err - } - - // t.StoragePricePerEpoch (types.BigInt) (struct) - if err := t.StoragePricePerEpoch.MarshalCBOR(w); err != nil { - return err - } - - // t.StorageCollateral (types.BigInt) (struct) - if err := t.StorageCollateral.MarshalCBOR(w); err != nil { - return err - } - - // t.ActivationEpoch (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.ActivationEpoch))); err != nil { - return err - } - return nil -} - -func (t *OnChainDeal) UnmarshalCBOR(r io.Reader) error { - br := cbg.GetPeeker(r) - - maj, extra, err := cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajArray { - return fmt.Errorf("cbor input should be of type array") - } - - if extra != 9 { - return fmt.Errorf("cbor input had wrong number of fields") - } - - // t.PieceRef ([]uint8) (slice) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.ByteArrayMaxLen { - return fmt.Errorf("t.PieceRef: byte array too large (%d)", extra) - } - if maj != cbg.MajByteString { - return fmt.Errorf("expected byte array") - } - t.PieceRef = make([]byte, extra) - if _, err := io.ReadFull(br, t.PieceRef); err != nil { - return err - } - // t.PieceSize (uint64) (uint64) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.PieceSize = uint64(extra) - // t.Client (address.Address) (struct) - - { - - if err := t.Client.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.Provider (address.Address) (struct) - - { - - if err := t.Provider.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.ProposalExpiration (uint64) (uint64) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.ProposalExpiration = uint64(extra) - // t.Duration (uint64) (uint64) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.Duration = uint64(extra) - // t.StoragePricePerEpoch (types.BigInt) (struct) - - { - - if err := t.StoragePricePerEpoch.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.StorageCollateral (types.BigInt) (struct) - - { - - if err := t.StorageCollateral.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.ActivationEpoch (uint64) (uint64) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.ActivationEpoch = uint64(extra) - return nil -} - -func (t *ComputeDataCommitmentParams) MarshalCBOR(w io.Writer) error { - if t == nil { - _, err := w.Write(cbg.CborNull) - return err - } - if _, err := w.Write([]byte{130}); err != nil { - return err - } - - // t.DealIDs ([]uint64) (slice) - if len(t.DealIDs) > cbg.MaxLength { - return xerrors.Errorf("Slice value in field t.DealIDs was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.DealIDs)))); err != nil { - return err - } - for _, v := range t.DealIDs { - if err := cbg.CborWriteHeader(w, cbg.MajUnsignedInt, v); err != nil { - return err - } - } - - // t.SectorSize (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SectorSize))); err != nil { - return err - } - return nil -} - -func (t *ComputeDataCommitmentParams) UnmarshalCBOR(r io.Reader) error { - br := cbg.GetPeeker(r) - - maj, extra, err := cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajArray { - return fmt.Errorf("cbor input should be of type array") - } - - if extra != 2 { - return fmt.Errorf("cbor input had wrong number of fields") - } - - // t.DealIDs ([]uint64) (slice) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.MaxLength { - return fmt.Errorf("t.DealIDs: array too large (%d)", extra) - } - - if maj != cbg.MajArray { - return fmt.Errorf("expected cbor array") - } - if extra > 0 { - t.DealIDs = make([]uint64, extra) - } - for i := 0; i < int(extra); i++ { - - maj, val, err := cbg.CborReadHeader(br) - if err != nil { - return xerrors.Errorf("failed to read uint64 for t.DealIDs slice: %w", err) - } - - if maj != cbg.MajUnsignedInt { - return xerrors.Errorf("value read for array t.DealIDs was not a uint, instead got %d", maj) - } - - t.DealIDs[i] = val - } - - // t.SectorSize (uint64) (uint64) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.SectorSize = uint64(extra) - return nil -} - -func (t *SectorProveCommitInfo) MarshalCBOR(w io.Writer) error { - if t == nil { - _, err := w.Write(cbg.CborNull) - return err - } - if _, err := w.Write([]byte{131}); err != nil { - return err - } - - // t.Proof ([]uint8) (slice) - if len(t.Proof) > cbg.ByteArrayMaxLen { - return xerrors.Errorf("Byte array in field t.Proof was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Proof)))); err != nil { - return err - } - if _, err := w.Write(t.Proof); err != nil { - return err - } - - // t.SectorID (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SectorID))); err != nil { - return err - } - - // t.DealIDs ([]uint64) (slice) - if len(t.DealIDs) > cbg.MaxLength { - return xerrors.Errorf("Slice value in field t.DealIDs was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.DealIDs)))); err != nil { - return err - } - for _, v := range t.DealIDs { - if err := cbg.CborWriteHeader(w, cbg.MajUnsignedInt, v); err != nil { - return err - } - } - return nil -} - -func (t *SectorProveCommitInfo) UnmarshalCBOR(r io.Reader) error { - br := cbg.GetPeeker(r) - - maj, extra, err := cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajArray { - return fmt.Errorf("cbor input should be of type array") - } - - if extra != 3 { - return fmt.Errorf("cbor input had wrong number of fields") - } - - // t.Proof ([]uint8) (slice) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.ByteArrayMaxLen { - return fmt.Errorf("t.Proof: byte array too large (%d)", extra) - } - if maj != cbg.MajByteString { - return fmt.Errorf("expected byte array") - } - t.Proof = make([]byte, extra) - if _, err := io.ReadFull(br, t.Proof); err != nil { - return err - } - // t.SectorID (uint64) (uint64) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.SectorID = uint64(extra) - // t.DealIDs ([]uint64) (slice) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.MaxLength { - return fmt.Errorf("t.DealIDs: array too large (%d)", extra) - } - - if maj != cbg.MajArray { - return fmt.Errorf("expected cbor array") - } - if extra > 0 { - t.DealIDs = make([]uint64, extra) - } - for i := 0; i < int(extra); i++ { - - maj, val, err := cbg.CborReadHeader(br) - if err != nil { - return xerrors.Errorf("failed to read uint64 for t.DealIDs slice: %w", err) - } - - if maj != cbg.MajUnsignedInt { - return xerrors.Errorf("value read for array t.DealIDs was not a uint, instead got %d", maj) - } - - t.DealIDs[i] = val - } - - return nil -} - func (t *CheckMinerParams) MarshalCBOR(w io.Writer) error { if t == nil { _, err := w.Write(cbg.CborNull) diff --git a/chain/actors/forks.go b/chain/actors/forks.go index 3cc5d5b74..60be370ef 100644 --- a/chain/actors/forks.go +++ b/chain/actors/forks.go @@ -26,7 +26,7 @@ func withUpdates(updates ...update) interface{} { vmctx := args[1].Interface().(types.VMContext) for _, u := range updates { - if vmctx.BlockHeight() > u.start { + if uint64(vmctx.BlockHeight()) > u.start { return reflect.ValueOf(u.method).Call(args) } } diff --git a/chain/events/events.go b/chain/events/events.go index 8a860c5ad..8baa142b3 100644 --- a/chain/events/events.go +++ b/chain/events/events.go @@ -5,6 +5,7 @@ import ( "sync" "time" + "github.com/filecoin-project/specs-actors/actors/abi" "github.com/ipfs/go-cid" logging "github.com/ipfs/go-log/v2" "golang.org/x/xerrors" @@ -19,7 +20,7 @@ import ( var log = logging.Logger("events") // `curH`-`ts.Height` = `confidence` -type HeightHandler func(ctx context.Context, ts *types.TipSet, curH uint64) error +type HeightHandler func(ctx context.Context, ts *types.TipSet, curH abi.ChainEpoch) error type RevertHandler func(ctx context.Context, ts *types.TipSet) error type heightHandler struct { @@ -33,7 +34,7 @@ type heightHandler struct { type eventApi interface { ChainNotify(context.Context) (<-chan []*store.HeadChange, error) ChainGetBlockMessages(context.Context, cid.Cid) (*api.BlockMessages, error) - ChainGetTipSetByHeight(context.Context, uint64, *types.TipSet) (*types.TipSet, error) + ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, *types.TipSet) (*types.TipSet, error) StateGetReceipt(context.Context, cid.Cid, *types.TipSet) (*types.MessageReceipt, error) StateGetActor(ctx context.Context, actor address.Address, ts *types.TipSet) (*types.Actor, error) // optional / for CalledMsg @@ -65,11 +66,11 @@ func NewEvents(ctx context.Context, api eventApi) *Events { heightEvents: heightEvents{ tsc: tsc, ctx: ctx, - gcConfidence: uint64(gcConfidence), + gcConfidence: abi.ChainEpoch(gcConfidence), heightTriggers: map[uint64]*heightHandler{}, - htTriggerHeights: map[uint64][]uint64{}, - htHeights: map[uint64][]uint64{}, + htTriggerHeights: map[abi.ChainEpoch][]uint64{}, + htHeights: map[abi.ChainEpoch][]uint64{}, }, calledEvents: calledEvents{ @@ -82,7 +83,7 @@ func NewEvents(ctx context.Context, api eventApi) *Events { revertQueue: map[msgH][]triggerH{}, triggers: map[triggerId]*callHandler{}, matchers: map[triggerId][]MatchFunc{}, - timeouts: map[uint64]map[triggerId]int{}, + timeouts: map[abi.ChainEpoch]map[triggerId]int{}, }, } diff --git a/chain/events/events_called.go b/chain/events/events_called.go index 106251b81..ce353f765 100644 --- a/chain/events/events_called.go +++ b/chain/events/events_called.go @@ -5,6 +5,7 @@ import ( "math" "sync" + "github.com/filecoin-project/specs-actors/actors/abi" "github.com/ipfs/go-cid" "golang.org/x/xerrors" @@ -12,20 +13,20 @@ import ( "github.com/filecoin-project/lotus/chain/types" ) -const NoTimeout = math.MaxUint64 +const NoTimeout = math.MaxInt64 type triggerId = uint64 // msgH is the block height at which a message was present / event has happened -type msgH = uint64 +type msgH = abi.ChainEpoch // triggerH is the block height at which the listener will be notified about the // message (msgH+confidence) -type triggerH = uint64 +type triggerH = abi.ChainEpoch // `ts` is the tipset, in which the `msg` is included. // `curH`-`ts.Height` = `confidence` -type CalledHandler func(msg *types.Message, rec *types.MessageReceipt, ts *types.TipSet, curH uint64) (more bool, err error) +type CalledHandler func(msg *types.Message, rec *types.MessageReceipt, ts *types.TipSet, curH abi.ChainEpoch) (more bool, err error) // CheckFunc is used for atomicity guarantees. If the condition the callbacks // wait for has already happened in tipset `ts` @@ -39,7 +40,7 @@ type MatchFunc func(msg *types.Message) (bool, error) type callHandler struct { confidence int - timeout uint64 + timeout abi.ChainEpoch disabled bool // TODO: GC after gcConfidence reached @@ -50,7 +51,7 @@ type callHandler struct { type queuedEvent struct { trigger triggerId - h uint64 + h abi.ChainEpoch msg *types.Message called bool @@ -77,7 +78,7 @@ type calledEvents struct { revertQueue map[msgH][]triggerH // [timeoutH+confidence][triggerId]{calls} - timeouts map[uint64]map[triggerId]int + timeouts map[abi.ChainEpoch]map[triggerId]int } func (e *calledEvents) headChangeCalled(rev, app []*types.TipSet) error { @@ -153,11 +154,11 @@ func (e *calledEvents) queueForConfidence(triggerId uint64, msg *types.Message, // messages are not applied in the tipset they are included in appliedH := ts.Height() + 1 - triggerH := appliedH + uint64(trigger.confidence) + triggerH := appliedH + abi.ChainEpoch(trigger.confidence) byOrigH, ok := e.confQueue[triggerH] if !ok { - byOrigH = map[uint64][]*queuedEvent{} + byOrigH = map[abi.ChainEpoch][]*queuedEvent{} e.confQueue[triggerH] = byOrigH } @@ -231,9 +232,9 @@ func (e *calledEvents) applyTimeouts(ts *types.TipSet) { continue } - timeoutTs, err := e.tsc.get(ts.Height() - uint64(trigger.confidence)) + timeoutTs, err := e.tsc.get(ts.Height() - abi.ChainEpoch(trigger.confidence)) if err != nil { - log.Errorf("events: applyTimeouts didn't find tipset for event; wanted %d; current %d", ts.Height()-uint64(trigger.confidence), ts.Height()) + log.Errorf("events: applyTimeouts didn't find tipset for event; wanted %d; current %d", ts.Height()-abi.ChainEpoch(trigger.confidence), ts.Height()) } more, err := trigger.handle(nil, nil, timeoutTs, ts.Height()) @@ -304,7 +305,7 @@ func (e *calledEvents) messagesForTs(ts *types.TipSet, consume func(*types.Messa // containing the message. The tipset passed as the argument is the tipset // that is being dropped. Note that the message dropped may be re-applied // in a different tipset in small amount of time. -func (e *calledEvents) Called(check CheckFunc, hnd CalledHandler, rev RevertHandler, confidence int, timeout uint64, mf MatchFunc) error { +func (e *calledEvents) Called(check CheckFunc, hnd CalledHandler, rev RevertHandler, confidence int, timeout abi.ChainEpoch, mf MatchFunc) error { e.lk.Lock() defer e.lk.Unlock() @@ -322,7 +323,7 @@ func (e *calledEvents) Called(check CheckFunc, hnd CalledHandler, rev RevertHand e.triggers[id] = &callHandler{ confidence: confidence, - timeout: timeout + uint64(confidence), + timeout: timeout + abi.ChainEpoch(confidence), disabled: !more, @@ -333,15 +334,15 @@ func (e *calledEvents) Called(check CheckFunc, hnd CalledHandler, rev RevertHand e.matchers[id] = append(e.matchers[id], mf) if timeout != NoTimeout { - if e.timeouts[timeout+uint64(confidence)] == nil { - e.timeouts[timeout+uint64(confidence)] = map[uint64]int{} + if e.timeouts[timeout+abi.ChainEpoch(confidence)] == nil { + e.timeouts[timeout+abi.ChainEpoch(confidence)] = map[uint64]int{} } - e.timeouts[timeout+uint64(confidence)][id] = 0 + e.timeouts[timeout+abi.ChainEpoch(confidence)][id] = 0 } return nil } -func (e *calledEvents) CalledMsg(ctx context.Context, hnd CalledHandler, rev RevertHandler, confidence int, timeout uint64, msg store.ChainMsg) error { +func (e *calledEvents) CalledMsg(ctx context.Context, hnd CalledHandler, rev RevertHandler, confidence int, timeout abi.ChainEpoch, msg store.ChainMsg) error { return e.Called(e.CheckMsg(ctx, msg, hnd), hnd, rev, confidence, timeout, e.MatchMsg(msg.VMMessage())) } diff --git a/chain/events/events_height.go b/chain/events/events_height.go index a407d167a..1b89e7bd7 100644 --- a/chain/events/events_height.go +++ b/chain/events/events_height.go @@ -4,6 +4,7 @@ import ( "context" "sync" + "github.com/filecoin-project/specs-actors/actors/abi" "go.opencensus.io/trace" "github.com/filecoin-project/lotus/chain/types" @@ -12,7 +13,7 @@ import ( type heightEvents struct { lk sync.Mutex tsc *tipSetCache - gcConfidence uint64 + gcConfidence abi.ChainEpoch ctr triggerId @@ -35,7 +36,7 @@ func (e *heightEvents) headChangeAt(rev, app []*types.TipSet) error { // TODO: log error if h below gcconfidence // revert height-based triggers - revert := func(h uint64, ts *types.TipSet) { + revert := func(h abi.ChainEpoch, ts *types.TipSet) { for _, tid := range e.htHeights[h] { ctx, span := trace.StartSpan(ctx, "events.HeightRevert") @@ -80,7 +81,7 @@ func (e *heightEvents) headChangeAt(rev, app []*types.TipSet) error { // height triggers - apply := func(h uint64, ts *types.TipSet) error { + apply := func(h abi.ChainEpoch, ts *types.TipSet) error { for _, tid := range e.htTriggerHeights[h] { hnd := e.heightTriggers[tid] if hnd.called { @@ -88,7 +89,7 @@ func (e *heightEvents) headChangeAt(rev, app []*types.TipSet) error { } hnd.called = true - triggerH := h - uint64(hnd.confidence) + triggerH := h - abi.ChainEpoch(hnd.confidence) incTs, err := e.tsc.getNonNull(triggerH) if err != nil { @@ -139,13 +140,13 @@ func (e *heightEvents) headChangeAt(rev, app []*types.TipSet) error { // specified height, `RevertHandler` will be called. // // ts passed to handlers is the tipset at the specified, or above, if lower tipsets were null -func (e *heightEvents) ChainAt(hnd HeightHandler, rev RevertHandler, confidence int, h uint64) error { +func (e *heightEvents) ChainAt(hnd HeightHandler, rev RevertHandler, confidence int, h abi.ChainEpoch) error { e.lk.Lock() // Tricky locking, check your locks if you modify this function! bestH := e.tsc.best().Height() - if bestH >= h+uint64(confidence) { + if bestH >= h+abi.ChainEpoch(confidence) { ts, err := e.tsc.getNonNull(h) if err != nil { log.Warnf("events.ChainAt: calling HandleFunc with nil tipset, not found in cache: %s", err) @@ -168,11 +169,11 @@ func (e *heightEvents) ChainAt(hnd HeightHandler, rev RevertHandler, confidence defer e.lk.Unlock() - if bestH >= h+uint64(confidence)+e.gcConfidence { + if bestH >= h+abi.ChainEpoch(confidence)+e.gcConfidence { return nil } - triggerAt := h + uint64(confidence) + triggerAt := h + abi.ChainEpoch(confidence) id := e.ctr e.ctr++ diff --git a/chain/events/tscache.go b/chain/events/tscache.go index 2e58a3f5b..f8dd05366 100644 --- a/chain/events/tscache.go +++ b/chain/events/tscache.go @@ -3,12 +3,13 @@ package events import ( "context" + "github.com/filecoin-project/specs-actors/actors/abi" "golang.org/x/xerrors" "github.com/filecoin-project/lotus/chain/types" ) -type tsByHFunc func(context.Context, uint64, *types.TipSet) (*types.TipSet, error) +type tsByHFunc func(context.Context, abi.ChainEpoch, *types.TipSet) (*types.TipSet, error) // tipSetCache implements a simple ring-buffer cache to keep track of recent // tipsets @@ -77,7 +78,7 @@ func (tsc *tipSetCache) revert(ts *types.TipSet) error { return nil } -func (tsc *tipSetCache) getNonNull(height uint64) (*types.TipSet, error) { +func (tsc *tipSetCache) getNonNull(height abi.ChainEpoch) (*types.TipSet, error) { for { ts, err := tsc.get(height) if err != nil { @@ -90,7 +91,7 @@ func (tsc *tipSetCache) getNonNull(height uint64) (*types.TipSet, error) { } } -func (tsc *tipSetCache) get(height uint64) (*types.TipSet, error) { +func (tsc *tipSetCache) get(height abi.ChainEpoch) (*types.TipSet, error) { if tsc.len == 0 { log.Warnf("tipSetCache.get: cache is empty, requesting from storage (h=%d)", height) return tsc.storage(context.TODO(), height, nil) diff --git a/chain/gen/gen.go b/chain/gen/gen.go index 8486056ff..53b194278 100644 --- a/chain/gen/gen.go +++ b/chain/gen/gen.go @@ -9,6 +9,7 @@ import ( "io/ioutil" "sync/atomic" + "github.com/filecoin-project/specs-actors/actors/abi" block "github.com/ipfs/go-block-format" "github.com/ipfs/go-blockservice" "github.com/ipfs/go-car" @@ -54,7 +55,7 @@ type ChainGen struct { genesis *types.BlockHeader CurTipset *store.FullTipSet - Timestamper func(*types.TipSet, uint64) uint64 + Timestamper func(*types.TipSet, abi.ChainEpoch) uint64 GetMessages func(*ChainGen) ([]*types.SignedMessage, error) @@ -319,7 +320,7 @@ func (cg *ChainGen) NextTipSetFromMiners(base *types.TipSet, miners []address.Ad } if proof != nil { - fblk, err := cg.makeBlock(base, m, proof, t, uint64(round), msgs) + fblk, err := cg.makeBlock(base, m, proof, t, abi.ChainEpoch(round), msgs) if err != nil { return nil, xerrors.Errorf("making a block for next tipset failed: %w", err) } @@ -341,13 +342,13 @@ func (cg *ChainGen) NextTipSetFromMiners(base *types.TipSet, miners []address.Ad }, nil } -func (cg *ChainGen) makeBlock(parents *types.TipSet, m address.Address, eproof *types.EPostProof, ticket *types.Ticket, height uint64, msgs []*types.SignedMessage) (*types.FullBlock, error) { +func (cg *ChainGen) makeBlock(parents *types.TipSet, m address.Address, eproof *types.EPostProof, ticket *types.Ticket, height abi.ChainEpoch, msgs []*types.SignedMessage) (*types.FullBlock, error) { var ts uint64 if cg.Timestamper != nil { ts = cg.Timestamper(parents, height-parents.Height()) } else { - ts = parents.MinTimestamp() + ((height - parents.Height()) * build.BlockDelay) + ts = parents.MinTimestamp() + uint64((height - parents.Height()) * build.BlockDelay) } fblk, err := MinerCreateBlock(context.TODO(), cg.sm, cg.w, m, parents, ticket, eproof, msgs, height, ts) @@ -423,7 +424,7 @@ type MiningCheckAPI interface { StateMinerWorker(context.Context, address.Address, *types.TipSet) (address.Address, error) - StateMinerSectorSize(context.Context, address.Address, *types.TipSet) (uint64, error) + StateMinerSectorSize(context.Context, address.Address, *types.TipSet) (abi.SectorSize, error) StateMinerProvingSet(context.Context, address.Address, *types.TipSet) ([]*api.ChainSectorInfo, error) @@ -455,7 +456,7 @@ func (mca mca) StateMinerWorker(ctx context.Context, maddr address.Address, ts * return stmgr.GetMinerWorkerRaw(ctx, mca.sm, ts.ParentState(), maddr) } -func (mca mca) StateMinerSectorSize(ctx context.Context, maddr address.Address, ts *types.TipSet) (uint64, error) { +func (mca mca) StateMinerSectorSize(ctx context.Context, maddr address.Address, ts *types.TipSet) (abi.SectorSize, error) { return stmgr.GetMinerSectorSize(ctx, mca.sm, ts, maddr) } diff --git a/chain/gen/mining.go b/chain/gen/mining.go index dd5939d7a..d63d7f500 100644 --- a/chain/gen/mining.go +++ b/chain/gen/mining.go @@ -5,6 +5,7 @@ import ( bls "github.com/filecoin-project/filecoin-ffi" amt "github.com/filecoin-project/go-amt-ipld/v2" + "github.com/filecoin-project/specs-actors/actors/abi" cid "github.com/ipfs/go-cid" cbor "github.com/ipfs/go-ipld-cbor" cbg "github.com/whyrusleeping/cbor-gen" @@ -18,7 +19,7 @@ import ( "github.com/filecoin-project/lotus/chain/wallet" ) -func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w *wallet.Wallet, miner address.Address, parents *types.TipSet, ticket *types.Ticket, proof *types.EPostProof, msgs []*types.SignedMessage, height, timestamp uint64) (*types.FullBlock, error) { +func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w *wallet.Wallet, miner address.Address, parents *types.TipSet, ticket *types.Ticket, proof *types.EPostProof, msgs []*types.SignedMessage, height abi.ChainEpoch, timestamp uint64) (*types.FullBlock, error) { st, recpts, err := sm.TipSetState(ctx, parents) if err != nil { return nil, xerrors.Errorf("failed to load tipset state: %w", err) diff --git a/chain/gen/utils.go b/chain/gen/utils.go index e790af641..cca18d9f5 100644 --- a/chain/gen/utils.go +++ b/chain/gen/utils.go @@ -6,6 +6,7 @@ import ( "fmt" amt "github.com/filecoin-project/go-amt-ipld/v2" + "github.com/filecoin-project/specs-actors/actors/builtin/market" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" hamt "github.com/ipfs/go-hamt-ipld" @@ -17,6 +18,7 @@ import ( "golang.org/x/xerrors" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/lotus/build" actors "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/state" @@ -202,24 +204,26 @@ func SetupStoragePowerActor(bs bstore.Blockstore) (*types.Actor, error) { func SetupStorageMarketActor(bs bstore.Blockstore, sroot cid.Cid, deals []actors.StorageDealProposal) (cid.Cid, error) { ctx := context.TODO() cst := cbor.NewCborStore(bs) - nd := hamt.NewNode(cst) - emptyHAMT, err := cst.Put(ctx, nd) - if err != nil { - return cid.Undef, err - } + ast := store.ActorStore(context.TODO(), bs) cdeals := make([]cbg.CBORMarshaler, len(deals)) + sdeals := make([]cbg.CBORMarshaler, len(deals)) for i, deal := range deals { - cdeals[i] = &actors.OnChainDeal{ - PieceRef: deal.PieceRef, + cdeals[i] = &market.DealProposal{ + PieceCID: deal.PieceCID, PieceSize: deal.PieceSize, Client: deal.Client, Provider: deal.Provider, - ProposalExpiration: deal.ProposalExpiration, - Duration: deal.Duration, + StartEpoch: deal.StartEpoch, + EndEpoch: deal.EndEpoch, StoragePricePerEpoch: deal.StoragePricePerEpoch, - StorageCollateral: deal.StorageCollateral, - ActivationEpoch: 1, + ProviderCollateral: deal.ProviderCollateral, + ClientCollateral: deal.ClientCollateral, + } + sdeals[i] = &market.DealState{ + SectorStartEpoch: 1, + LastUpdatedEpoch: -1, + SlashEpoch: -1, } } @@ -228,17 +232,26 @@ func SetupStorageMarketActor(bs bstore.Blockstore, sroot cid.Cid, deals []actors return cid.Undef, xerrors.Errorf("amt build failed: %w", err) } - sms := &actors.StorageMarketState{ - Balances: emptyHAMT, - Deals: dealAmt, - NextDealID: uint64(len(deals)), + stateAmt, err := amt.FromArray(ctx, cst, sdeals) + if err != nil { + return cid.Undef, xerrors.Errorf("amt build failed: %w", err) } + sms, err := market.ConstructState(ast) + if err != nil { + return cid.Cid{}, err + } + + sms.Proposals = dealAmt + sms.States = stateAmt + stcid, err := cst.Put(context.TODO(), sms) if err != nil { return cid.Undef, err } + // TODO: MARKET BALANCES!!!!!!111 + act := &types.Actor{ Code: actors.StorageMarketCodeCid, Head: stcid, @@ -328,7 +341,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid return cid.Undef, nil, err } - power := types.BigMul(types.NewInt(minerParams.SectorSize), types.NewInt(uint64(len(ps.Sectors)))) + power := types.BigMul(types.NewInt(uint64(minerParams.SectorSize)), types.NewInt(uint64(len(ps.Sectors)))) params = mustEnc(&actors.UpdateStorageParams{Delta: power}) @@ -352,7 +365,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid if err := cst.Get(ctx, mact.Head, &mstate); err != nil { return cid.Undef, nil, xerrors.Errorf("getting miner actor state failed: %w", err) } - mstate.Power = types.BigMul(types.NewInt(ps.SectorSize), types.NewInt(uint64(len(ps.Sectors)))) + mstate.Power = types.BigMul(types.NewInt(uint64(ps.SectorSize)), types.NewInt(uint64(len(ps.Sectors)))) for _, s := range ps.Sectors { nssroot, err := actors.AddToSectorSet(ctx, cst, mstate.Sectors, s.SectorID, s.CommR[:], s.CommD[:]) diff --git a/chain/market/fundmgr.go b/chain/market/fundmgr.go index 1500a78a5..e859da3b1 100644 --- a/chain/market/fundmgr.go +++ b/chain/market/fundmgr.go @@ -40,7 +40,7 @@ func (fm *FundMgr) EnsureAvailable(ctx context.Context, addr address.Address, am return err } - avail = bal.Available + avail = types.BigSub(bal.Escrow, bal.Locked) } toAdd := types.NewInt(0) diff --git a/chain/metrics/consensus.go b/chain/metrics/consensus.go index 0635b08fd..f78bc0c03 100644 --- a/chain/metrics/consensus.go +++ b/chain/metrics/consensus.go @@ -5,6 +5,7 @@ import ( "encoding/json" "time" + "github.com/filecoin-project/specs-actors/actors/abi" "github.com/ipfs/go-cid" logging "github.com/ipfs/go-log/v2" pubsub "github.com/libp2p/go-libp2p-pubsub" @@ -68,7 +69,7 @@ type message struct { // TipSet Cids []cid.Cid Blocks []*types.BlockHeader - Height uint64 + Height abi.ChainEpoch Weight types.BigInt Time uint64 Nonce uint64 diff --git a/chain/stmgr/call.go b/chain/stmgr/call.go index d8d46212a..17b0b79c9 100644 --- a/chain/stmgr/call.go +++ b/chain/stmgr/call.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + "github.com/filecoin-project/specs-actors/actors/abi" "github.com/ipfs/go-cid" "go.opencensus.io/trace" "golang.org/x/xerrors" @@ -15,7 +16,7 @@ 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 uint64) (*api.MethodCall, error) { +func (sm *StateManager) CallRaw(ctx context.Context, msg *types.Message, bstate cid.Cid, r vm.Rand, bheight abi.ChainEpoch) (*api.MethodCall, error) { ctx, span := trace.StartSpan(ctx, "statemanager.CallRaw") defer span.End() diff --git a/chain/stmgr/forks.go b/chain/stmgr/forks.go index f318adf15..7f8dc579b 100644 --- a/chain/stmgr/forks.go +++ b/chain/stmgr/forks.go @@ -3,12 +3,13 @@ package stmgr import ( "context" + "github.com/filecoin-project/specs-actors/actors/abi" "github.com/ipfs/go-cid" ) -var ForksAtHeight = map[uint64]func(context.Context, *StateManager, cid.Cid) (cid.Cid, error){} +var ForksAtHeight = map[abi.ChainEpoch]func(context.Context, *StateManager, cid.Cid) (cid.Cid, error){} -func (sm *StateManager) handleStateForks(ctx context.Context, pstate cid.Cid, height, parentH uint64) (_ cid.Cid, err error) { +func (sm *StateManager) handleStateForks(ctx context.Context, pstate cid.Cid, height, parentH abi.ChainEpoch) (_ cid.Cid, err error) { for i := parentH; i < height; i++ { f, ok := ForksAtHeight[i] if ok { diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index a8185f159..d1a93589c 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -7,11 +7,14 @@ import ( "github.com/filecoin-project/go-address" amt "github.com/filecoin-project/go-amt-ipld/v2" + "github.com/filecoin-project/lotus/api" "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" "github.com/filecoin-project/lotus/chain/vm" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/util/adt" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" @@ -32,7 +35,7 @@ type StateManager struct { stCache map[string][]cid.Cid compWait map[string]chan struct{} stlk sync.Mutex - newVM func(cid.Cid, uint64, vm.Rand, address.Address, blockstore.Blockstore, *types.VMSyscalls) (*vm.VM, error) + newVM func(cid.Cid, abi.ChainEpoch, vm.Rand, address.Address, blockstore.Blockstore, *types.VMSyscalls) (*vm.VM, error) } func NewStateManager(cs *store.ChainStore) *StateManager { @@ -598,18 +601,25 @@ func (sm *StateManager) ListAllActors(ctx context.Context, ts *types.TipSet) ([] return out, nil } -func (sm *StateManager) MarketBalance(ctx context.Context, addr address.Address, ts *types.TipSet) (actors.StorageParticipantBalance, error) { +func (sm *StateManager) MarketBalance(ctx context.Context, addr address.Address, ts *types.TipSet) (api.MarketBalance, error) { var state actors.StorageMarketState - if _, err := sm.LoadActorState(ctx, actors.StorageMarketAddress, &state, ts); err != nil { - return actors.StorageParticipantBalance{}, err - } - cst := cbor.NewCborStore(sm.cs.Blockstore()) - b, _, err := actors.GetMarketBalances(ctx, cst, state.Balances, addr) + _, err := sm.LoadActorState(ctx, actors.StorageMarketAddress, &state, ts) if err != nil { - return actors.StorageParticipantBalance{}, err + return api.MarketBalance{}, err } - return b[0], nil + var out api.MarketBalance + out.Escrow, err = adt.AsBalanceTable(sm.cs.Store(ctx), state.EscrowTable).Get(addr) + if err != nil { + return api.MarketBalance{}, xerrors.Errorf("getting escrow balance: %w", err) + } + + out.Locked, err = adt.AsBalanceTable(sm.cs.Store(ctx), state.LockedTable).Get(addr) + if err != nil { + return api.MarketBalance{}, xerrors.Errorf("getting locked balance: %w", err) + } + + return out, nil } func (sm *StateManager) ValidateChain(ctx context.Context, ts *types.TipSet) error { @@ -641,6 +651,6 @@ func (sm *StateManager) ValidateChain(ctx context.Context, ts *types.TipSet) err return nil } -func (sm *StateManager) SetVMConstructor(nvm func(cid.Cid, uint64, vm.Rand, address.Address, blockstore.Blockstore, *types.VMSyscalls) (*vm.VM, error)) { +func (sm *StateManager) SetVMConstructor(nvm func(cid.Cid, abi.ChainEpoch, vm.Rand, address.Address, blockstore.Blockstore, *types.VMSyscalls) (*vm.VM, error)) { sm.newVM = nvm } diff --git a/chain/stmgr/utils.go b/chain/stmgr/utils.go index 6ab4044ba..685469f3e 100644 --- a/chain/stmgr/utils.go +++ b/chain/stmgr/utils.go @@ -4,6 +4,9 @@ import ( "context" amt "github.com/filecoin-project/go-amt-ipld/v2" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin/market" + "github.com/filecoin-project/lotus/chain/actors/aerrors" ffi "github.com/filecoin-project/filecoin-ffi" @@ -228,7 +231,7 @@ func GetSectorsForElectionPost(ctx context.Context, sm *StateManager, ts *types. return &ssi, nil } -func GetMinerSectorSize(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (uint64, error) { +func GetMinerSectorSize(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (abi.SectorSize, error) { var mas actors.StorageMinerActorState _, err := sm.LoadActorState(ctx, maddr, &mas, ts) if err != nil { @@ -269,18 +272,18 @@ func GetMinerFaults(ctx context.Context, sm *StateManager, ts *types.TipSet, mad return mas.FaultSet.All(2 * ss.Count) } -func GetStorageDeal(ctx context.Context, sm *StateManager, dealId uint64, ts *types.TipSet) (*actors.OnChainDeal, error) { +func GetStorageDeal(ctx context.Context, sm *StateManager, dealId uint64, ts *types.TipSet) (*market.DealProposal, error) { var state actors.StorageMarketState if _, err := sm.LoadActorState(ctx, actors.StorageMarketAddress, &state, ts); err != nil { return nil, err } - da, err := amt.LoadAMT(ctx, cbor.NewCborStore(sm.ChainStore().Blockstore()), state.Deals) + da, err := amt.LoadAMT(ctx, cbor.NewCborStore(sm.ChainStore().Blockstore()), state.Proposals) if err != nil { return nil, err } - var ocd actors.OnChainDeal + var ocd market.DealProposal if err := da.Get(ctx, dealId, &ocd); err != nil { return nil, err } @@ -328,7 +331,7 @@ func LoadSectorsFromSet(ctx context.Context, bs blockstore.Blockstore, ssc cid.C return sset, nil } -func ComputeState(ctx context.Context, sm *StateManager, height uint64, msgs []*types.Message, ts *types.TipSet) (cid.Cid, error) { +func ComputeState(ctx context.Context, sm *StateManager, height abi.ChainEpoch, msgs []*types.Message, ts *types.TipSet) (cid.Cid, error) { if ts == nil { ts = sm.cs.GetHeaviestTipSet() } diff --git a/chain/store/store.go b/chain/store/store.go index 393528a22..3d0375c8b 100644 --- a/chain/store/store.go +++ b/chain/store/store.go @@ -10,13 +10,17 @@ import ( "sync" "github.com/filecoin-project/go-address" - "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/lotus/chain/state" - "github.com/filecoin-project/lotus/chain/vm" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/util/adt" "go.opencensus.io/trace" "go.uber.org/multierr" + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/state" + "github.com/filecoin-project/lotus/chain/vm" + amt "github.com/filecoin-project/go-amt-ipld/v2" + "github.com/filecoin-project/lotus/chain/types" lru "github.com/hashicorp/golang-lru" @@ -51,7 +55,7 @@ type ChainStore struct { pubLk sync.Mutex tstLk sync.Mutex - tipsets map[uint64][]cid.Cid + tipsets map[abi.ChainEpoch][]cid.Cid reorgCh chan<- reorg headChangeNotifs []func(rev, app []*types.TipSet) error @@ -69,7 +73,7 @@ func NewChainStore(bs bstore.Blockstore, ds dstore.Batching, vmcalls *types.VMSy bs: bs, ds: ds, bestTips: pubsub.New(64), - tipsets: make(map[uint64][]cid.Cid), + tipsets: make(map[abi.ChainEpoch][]cid.Cid), mmCache: c, tsCache: tsc, vmcalls: vmcalls, @@ -829,6 +833,34 @@ func (cs *ChainStore) Blockstore() bstore.Blockstore { return cs.bs } +func ActorStore(ctx context.Context, bs blockstore.Blockstore) adt.Store { + return &astore{ + cst: cbor.NewCborStore(bs), + ctx: ctx, + } +} + +type astore struct { + cst cbor.IpldStore + ctx context.Context +} + +func (a *astore) Context() context.Context { + return a.ctx +} + +func (a *astore) Get(ctx context.Context, c cid.Cid, out interface{}) error { + return a.cst.Get(ctx, c, out) +} + +func (a *astore) Put(ctx context.Context, v interface{}) (cid.Cid, error) { + return a.cst.Put(ctx, v) +} + +func (cs *ChainStore) Store(ctx context.Context) adt.Store { + return ActorStore(ctx, cs.bs) +} + func (cs *ChainStore) VMSys() *types.VMSyscalls { return cs.vmcalls } @@ -899,7 +931,7 @@ func (cs *ChainStore) GetRandomness(ctx context.Context, blks []cid.Cid, round i } } -func (cs *ChainStore) GetTipsetByHeight(ctx context.Context, h uint64, ts *types.TipSet) (*types.TipSet, error) { +func (cs *ChainStore) GetTipsetByHeight(ctx context.Context, h abi.ChainEpoch, ts *types.TipSet) (*types.TipSet, error) { if ts == nil { ts = cs.GetHeaviestTipSet() } @@ -1007,10 +1039,10 @@ func (cs *ChainStore) Import(r io.Reader) (*types.TipSet, error) { type chainRand struct { cs *ChainStore blks []cid.Cid - bh uint64 + bh abi.ChainEpoch } -func NewChainRand(cs *ChainStore, blks []cid.Cid, bheight uint64) vm.Rand { +func NewChainRand(cs *ChainStore, blks []cid.Cid, bheight abi.ChainEpoch) vm.Rand { return &chainRand{ cs: cs, blks: blks, diff --git a/chain/sync.go b/chain/sync.go index fee9a0e14..bce41279c 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -516,7 +516,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err log.Warn("Got block from the future, but within threshold", h.Timestamp, time.Now().Unix()) } - if h.Timestamp < baseTs.MinTimestamp()+(build.BlockDelay*(h.Height-baseTs.Height())) { + if h.Timestamp < baseTs.MinTimestamp()+(build.BlockDelay*uint64(h.Height-baseTs.Height())) { log.Warn("timestamp funtimes: ", h.Timestamp, baseTs.MinTimestamp(), h.Height, baseTs.Height()) return xerrors.Errorf("block was generated too soon (h.ts:%d < base.mints:%d + BLOCK_DELAY:%d * deltaH:%d)", h.Timestamp, baseTs.MinTimestamp(), build.BlockDelay, h.Height-baseTs.Height()) } @@ -541,7 +541,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err return xerrors.Errorf("failed to get sector size for block miner: %w", err) } - snum := types.BigDiv(mpow, types.NewInt(ssize)) + snum := types.BigDiv(mpow, types.NewInt(uint64(ssize))) if len(h.EPostProof.Candidates) == 0 { return xerrors.Errorf("no candidates") diff --git a/chain/syncstate.go b/chain/syncstate.go index 622598193..b213c7483 100644 --- a/chain/syncstate.go +++ b/chain/syncstate.go @@ -5,6 +5,8 @@ import ( "sync" "time" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/types" ) @@ -31,7 +33,7 @@ type SyncerState struct { Target *types.TipSet Base *types.TipSet Stage api.SyncStateStage - Height uint64 + Height abi.ChainEpoch Message string Start time.Time End time.Time @@ -66,7 +68,7 @@ func (ss *SyncerState) Init(base, target *types.TipSet) { ss.End = time.Time{} } -func (ss *SyncerState) SetHeight(h uint64) { +func (ss *SyncerState) SetHeight(h abi.ChainEpoch) { if ss == nil { return } diff --git a/chain/types/bigint.go b/chain/types/bigint.go index 99fb7c0fb..d8f5e0c7b 100644 --- a/chain/types/bigint.go +++ b/chain/types/bigint.go @@ -1,41 +1,21 @@ package types import ( - "encoding/json" "fmt" - "io" "math/big" - "github.com/filecoin-project/lotus/build" - cbor "github.com/ipfs/go-ipld-cbor" - "github.com/polydawn/refmt/obj/atlas" + big2 "github.com/filecoin-project/specs-actors/actors/abi/big" - cbg "github.com/whyrusleeping/cbor-gen" - "golang.org/x/xerrors" + "github.com/filecoin-project/lotus/build" ) const BigIntMaxSerializedLen = 128 // is this big enough? or too big? var TotalFilecoinInt = FromFil(build.TotalFilecoin) -func init() { - cbor.RegisterCborType(atlas.BuildEntry(BigInt{}).Transform(). - TransformMarshal(atlas.MakeMarshalTransformFunc( - func(i BigInt) ([]byte, error) { - return i.cborBytes(), nil - })). - TransformUnmarshal(atlas.MakeUnmarshalTransformFunc( - func(x []byte) (BigInt, error) { - return fromCborBytes(x) - })). - Complete()) -} - var EmptyInt = BigInt{} -type BigInt struct { - *big.Int -} +type BigInt = big2.Int func NewInt(i uint64) BigInt { return BigInt{big.NewInt(0).SetUint64(i)} @@ -83,50 +63,9 @@ func BigCmp(a, b BigInt) int { return a.Int.Cmp(b.Int) } -func (bi BigInt) Nil() bool { - return bi.Int == nil -} - -// LessThan returns true if bi < o -func (bi BigInt) LessThan(o BigInt) bool { - return BigCmp(bi, o) < 0 -} - -// GreaterThan returns true if bi > o -func (bi BigInt) GreaterThan(o BigInt) bool { - return BigCmp(bi, o) > 0 -} - -// Equals returns true if bi == o -func (bi BigInt) Equals(o BigInt) bool { - return BigCmp(bi, o) == 0 -} - -func (bi *BigInt) MarshalJSON() ([]byte, error) { - return json.Marshal(bi.String()) -} - -func (bi *BigInt) UnmarshalJSON(b []byte) error { - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - - i, ok := big.NewInt(0).SetString(s, 10) - if !ok { - if string(s) == "" { - return nil - } - return xerrors.Errorf("failed to parse bigint string: '%s'", string(b)) - } - - bi.Int = i - return nil -} - var sizeUnits = []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB"} -func (bi BigInt) SizeStr() string { +func SizeStr(bi BigInt) string { r := new(big.Rat).SetInt(bi.Int) den := big.NewRat(1, 1024) @@ -139,121 +78,3 @@ func (bi BigInt) SizeStr() string { f, _ := r.Float64() return fmt.Sprintf("%.3g %s", f, sizeUnits[i]) } - -func (bi *BigInt) Scan(value interface{}) error { - switch value := value.(type) { - case string: - i, ok := big.NewInt(0).SetString(value, 10) - if !ok { - if value == "" { - return nil - } - return xerrors.Errorf("failed to parse bigint string: '%s'", value) - } - - bi.Int = i - - return nil - case int64: - bi.Int = big.NewInt(value) - return nil - default: - return xerrors.Errorf("non-string types unsupported: %T", value) - } -} - -func (bi *BigInt) cborBytes() []byte { - if bi.Int == nil { - return []byte{} - } - - switch { - case bi.Sign() > 0: - return append([]byte{0}, bi.Bytes()...) - case bi.Sign() < 0: - return append([]byte{1}, bi.Bytes()...) - default: // bi.Sign() == 0: - return []byte{} - } -} - -func fromCborBytes(buf []byte) (BigInt, error) { - if len(buf) == 0 { - return NewInt(0), nil - } - - var negative bool - switch buf[0] { - case 0: - negative = false - case 1: - negative = true - default: - return EmptyInt, fmt.Errorf("big int prefix should be either 0 or 1, got %d", buf[0]) - } - - i := big.NewInt(0).SetBytes(buf[1:]) - if negative { - i.Neg(i) - } - - return BigInt{i}, nil -} - -func (bi *BigInt) MarshalCBOR(w io.Writer) error { - if bi.Int == nil { - zero := NewInt(0) - return zero.MarshalCBOR(w) - } - - enc := bi.cborBytes() - - header := cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(enc))) - if _, err := w.Write(header); err != nil { - return err - } - - if _, err := w.Write(enc); err != nil { - return err - } - - return nil -} - -func (bi *BigInt) UnmarshalCBOR(br io.Reader) error { - maj, extra, err := cbg.CborReadHeader(br) - if err != nil { - return err - } - - if maj != cbg.MajByteString { - return fmt.Errorf("cbor input for fil big int was not a byte string (%x)", maj) - } - - if extra == 0 { - bi.Int = big.NewInt(0) - return nil - } - - if extra > BigIntMaxSerializedLen { - return fmt.Errorf("big integer byte array too long") - } - - buf := make([]byte, extra) - if _, err := io.ReadFull(br, buf); err != nil { - return err - } - - i, err := fromCborBytes(buf) - if err != nil { - return err - } - - *bi = i - - return nil -} - -func (bi *BigInt) IsZero() bool { - return bi.Int.Sign() == 0 -} diff --git a/chain/types/blockheader.go b/chain/types/blockheader.go index 87e994fc5..8a5070b0f 100644 --- a/chain/types/blockheader.go +++ b/chain/types/blockheader.go @@ -5,6 +5,7 @@ import ( "math/big" "github.com/filecoin-project/go-sectorbuilder" + "github.com/filecoin-project/specs-actors/actors/abi" block "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" @@ -44,7 +45,7 @@ type BlockHeader struct { ParentWeight BigInt // 4 - Height uint64 // 5 + Height abi.ChainEpoch // 5 ParentStateRoot cid.Cid // 6 @@ -165,8 +166,8 @@ var blocksPerEpoch = NewInt(build.BlocksPerEpoch) const sha256bits = 256 -func IsTicketWinner(partialTicket []byte, ssizeI uint64, snum uint64, totpow BigInt) bool { - ssize := NewInt(ssizeI) +func IsTicketWinner(partialTicket []byte, ssizeI abi.SectorSize, snum uint64, totpow BigInt) bool { + ssize := NewInt(uint64(ssizeI)) ssampled := ElectionPostChallengeCount(snum, 0) // TODO: faults in epost? /* Need to check that diff --git a/chain/types/cbor_gen.go b/chain/types/cbor_gen.go index f606955c7..8024eb533 100644 --- a/chain/types/cbor_gen.go +++ b/chain/types/cbor_gen.go @@ -193,26 +193,7 @@ func (t *BlockHeader) UnmarshalCBOR(r io.Reader) error { } // t.Height (uint64) (uint64) - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.Height = uint64(extra) - // t.ParentStateRoot (cid.Cid) (struct) - { - - c, err := cbg.ReadCid(br) - if err != nil { - return xerrors.Errorf("failed to read cid field t.ParentStateRoot: %w", err) - } - - t.ParentStateRoot = c - - } // t.ParentMessageReceipts (cid.Cid) (struct) { @@ -1845,15 +1826,5 @@ func (t *ExpTipSet) UnmarshalCBOR(r io.Reader) error { t.Blocks[i] = &v } - // t.Height (uint64) (uint64) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.Height = uint64(extra) return nil } diff --git a/chain/types/tipset.go b/chain/types/tipset.go index b320f3e30..b840dcbdf 100644 --- a/chain/types/tipset.go +++ b/chain/types/tipset.go @@ -7,6 +7,7 @@ import ( "io" "sort" + "github.com/filecoin-project/specs-actors/actors/abi" "github.com/ipfs/go-cid" logging "github.com/ipfs/go-log/v2" cbg "github.com/whyrusleeping/cbor-gen" @@ -18,7 +19,7 @@ var log = logging.Logger("types") type TipSet struct { cids []cid.Cid blks []*BlockHeader - height uint64 + height abi.ChainEpoch } // why didnt i just export the fields? Because the struct has methods with the @@ -26,7 +27,7 @@ type TipSet struct { type ExpTipSet struct { Cids []cid.Cid Blocks []*BlockHeader - Height uint64 + Height abi.ChainEpoch } func (ts *TipSet) MarshalJSON() ([]byte, error) { @@ -132,7 +133,7 @@ func (ts *TipSet) Key() TipSetKey { return NewTipSetKey(ts.cids...) } -func (ts *TipSet) Height() uint64 { +func (ts *TipSet) Height() abi.ChainEpoch { return ts.height } diff --git a/chain/types/vmcontext.go b/chain/types/vmcontext.go index 1a9a87941..fbd1f2cc3 100644 --- a/chain/types/vmcontext.go +++ b/chain/types/vmcontext.go @@ -4,6 +4,7 @@ import ( "context" "github.com/filecoin-project/go-sectorbuilder" + "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/go-address" "github.com/filecoin-project/lotus/chain/actors/aerrors" @@ -33,13 +34,13 @@ type VMContext interface { Origin() address.Address Ipld() cbor.IpldStore Send(to address.Address, method uint64, value BigInt, params []byte) ([]byte, aerrors.ActorError) - BlockHeight() uint64 + BlockHeight() abi.ChainEpoch GasUsed() BigInt Storage() Storage StateTree() (StateTree, aerrors.ActorError) VerifySignature(sig *Signature, from address.Address, data []byte) aerrors.ActorError ChargeGas(uint64) aerrors.ActorError - GetRandomness(height uint64) ([]byte, aerrors.ActorError) + GetRandomness(height abi.ChainEpoch) ([]byte, aerrors.ActorError) GetBalance(address.Address) (BigInt, aerrors.ActorError) Sys() *VMSyscalls @@ -47,9 +48,9 @@ type VMContext interface { } type VMSyscalls struct { - ValidatePoRep func(context.Context, address.Address, uint64, []byte, []byte, []byte, []byte, []byte, uint64) (bool, aerrors.ActorError) + ValidatePoRep func(context.Context, address.Address, abi.SectorSize, []byte, []byte, []byte, []byte, []byte, abi.SectorNumber) (bool, aerrors.ActorError) VerifyFallbackPost func(ctx context.Context, - sectorSize uint64, + sectorSize abi.SectorSize, sectorInfo sectorbuilder.SortedPublicSectorInfo, challengeSeed []byte, proof []byte, diff --git a/chain/vm/invoker.go b/chain/vm/invoker.go index 709212ab3..04709ce39 100644 --- a/chain/vm/invoker.go +++ b/chain/vm/invoker.go @@ -11,11 +11,14 @@ import ( cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" + "github.com/filecoin-project/specs-actors/actors/builtin/multisig" + vmr "github.com/filecoin-project/specs-actors/actors/runtime" + + "github.com/filecoin-project/specs-actors/actors/builtin/market" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/aerrors" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/specs-actors/actors/builtin/multisig" - vmr "github.com/filecoin-project/specs-actors/actors/runtime" ) type invoker struct { @@ -36,9 +39,9 @@ func NewInvoker() *invoker { inv.Register(actors.InitCodeCid, actors.InitActor{}, actors.InitActorState{}) inv.Register(actors.CronCodeCid, actors.CronActor{}, actors.CronActorState{}) inv.Register(actors.StoragePowerCodeCid, actors.StoragePowerActor{}, actors.StoragePowerState{}) - inv.Register(actors.StorageMarketCodeCid, actors.StorageMarketActor{}, actors.StorageMarketState{}) + inv.Register(actors.StorageMarketCodeCid, market.Actor{}, market.State{}) inv.Register(actors.StorageMinerCodeCid, actors.StorageMinerActor{}, actors.StorageMinerActorState{}) - inv.Register(actors.MultisigCodeCid, multisig.MultiSigActor{}, multisig.MultiSigActorState{}) + inv.Register(actors.MultisigCodeCid, multisig.Actor{}, multisig.State{}) inv.Register(actors.PaymentChannelCodeCid, actors.PaymentChannelActor{}, actors.PaymentChannelActorState{}) return inv diff --git a/chain/vm/syscalls.go b/chain/vm/syscalls.go index fa3ea18c9..4d8351f57 100644 --- a/chain/vm/syscalls.go +++ b/chain/vm/syscalls.go @@ -7,6 +7,7 @@ import ( "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/aerrors" "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/specs-actors/actors/abi" "go.opencensus.io/trace" ) @@ -14,7 +15,7 @@ import ( func Syscalls(verifier sectorbuilder.Verifier) *types.VMSyscalls { return &types.VMSyscalls{ - ValidatePoRep: func(ctx context.Context, maddr address.Address, ssize uint64, commD, commR, ticket, proof, seed []byte, sectorID uint64) (bool, actors.ActorError) { + ValidatePoRep: func(ctx context.Context, maddr address.Address, ssize abi.SectorSize, commD, commR, ticket, proof, seed []byte, sectorID abi.SectorNumber) (bool, actors.ActorError) { _, span := trace.StartSpan(ctx, "ValidatePoRep") defer span.End() ok, err := verifier.VerifySeal(ssize, commR, commD, maddr, ticket, seed, sectorID, proof) diff --git a/chain/vm/vm.go b/chain/vm/vm.go index b6e6496f7..86199bb11 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -6,6 +6,7 @@ import ( "fmt" "math/big" + "github.com/filecoin-project/specs-actors/actors/abi" block "github.com/ipfs/go-block-format" cid "github.com/ipfs/go-cid" hamt "github.com/ipfs/go-hamt-ipld" @@ -50,7 +51,7 @@ type VMContext struct { vm *VM state *state.StateTree msg *types.Message - height uint64 + height abi.ChainEpoch cst cbor.IpldStore gasAvailable types.BigInt @@ -70,7 +71,7 @@ func (vmc *VMContext) Message() *types.Message { return vmc.msg } -func (vmc *VMContext) GetRandomness(height uint64) ([]byte, aerrors.ActorError) { +func (vmc *VMContext) GetRandomness(height abi.ChainEpoch) ([]byte, aerrors.ActorError) { res, err := vmc.vm.rand.GetRandomness(vmc.ctx, int64(height)) if err != nil { @@ -158,7 +159,7 @@ func (vmc *VMContext) Send(to address.Address, method uint64, value types.BigInt } // BlockHeight returns the height of the block this message was added to the chain in -func (vmc *VMContext) BlockHeight() uint64 { +func (vmc *VMContext) BlockHeight() abi.ChainEpoch { return vmc.height } @@ -301,7 +302,7 @@ type VM struct { base cid.Cid cst *cbor.BasicIpldStore buf *bufbstore.BufferedBS - blockHeight uint64 + blockHeight abi.ChainEpoch blockMiner address.Address inv *invoker rand Rand @@ -309,7 +310,7 @@ type VM struct { Syscalls *types.VMSyscalls } -func NewVM(base cid.Cid, height uint64, r Rand, maddr address.Address, cbs blockstore.Blockstore, syscalls *types.VMSyscalls) (*VM, error) { +func NewVM(base cid.Cid, height abi.ChainEpoch, r Rand, maddr address.Address, cbs blockstore.Blockstore, syscalls *types.VMSyscalls) (*VM, error) { buf := bufbstore.NewBufferedBstore(cbs) cst := cbor.NewCborStore(buf) state, err := state.LoadStateTree(cst, base) @@ -622,7 +623,7 @@ func (vm *VM) StateTree() types.StateTree { return vm.cstate } -func (vm *VM) SetBlockHeight(h uint64) { +func (vm *VM) SetBlockHeight(h abi.ChainEpoch) { vm.blockHeight = h } diff --git a/cli/chain.go b/cli/chain.go index 6f691edee..bd476b35a 100644 --- a/cli/chain.go +++ b/cli/chain.go @@ -11,6 +11,7 @@ import ( "strings" "time" + "github.com/filecoin-project/specs-actors/actors/abi" cid "github.com/ipfs/go-cid" "golang.org/x/xerrors" "gopkg.in/urfave/cli.v2" @@ -250,7 +251,7 @@ var chainSetHeadCmd = &cli.Command{ ts, err = api.ChainGetGenesis(ctx) } if ts == nil && cctx.IsSet("epoch") { - ts, err = api.ChainGetTipSetByHeight(ctx, cctx.Uint64("epoch"), nil) + ts, err = api.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(cctx.Uint64("epoch")), nil) } if ts == nil { ts, err = parseTipSet(api, ctx, cctx.Args().Slice()) @@ -313,7 +314,7 @@ var chainListCmd = &cli.Command{ var head *types.TipSet if cctx.IsSet("height") { - head, err = api.ChainGetTipSetByHeight(ctx, cctx.Uint64("height"), nil) + head, err = api.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(cctx.Uint64("height")), nil) } else { head, err = api.ChainHead(ctx) } @@ -446,7 +447,7 @@ var chainBisectCmd = &cli.Command{ subPath := cctx.Args().Get(2) - highest, err := api.ChainGetTipSetByHeight(ctx, end, nil) + highest, err := api.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(end), nil) if err != nil { return err } @@ -460,7 +461,7 @@ var chainBisectCmd = &cli.Command{ start = end } - midTs, err := api.ChainGetTipSetByHeight(ctx, mid, highest) + midTs, err := api.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(mid), highest) if err != nil { return err } @@ -506,7 +507,7 @@ var chainBisectCmd = &cli.Command{ return nil } - prev = mid + prev = abi.ChainEpoch(mid) } }, } diff --git a/cli/multisig.go b/cli/multisig.go index 85a716cd9..844c0ce35 100644 --- a/cli/multisig.go +++ b/cli/multisig.go @@ -186,7 +186,7 @@ var msigInspectCmd = &cli.Command{ return err } - var mstate samsig.MultiSigActorState + var mstate samsig.State if err := mstate.UnmarshalCBOR(bytes.NewReader(obj)); err != nil { return err } @@ -226,7 +226,7 @@ var msigInspectCmd = &cli.Command{ }, } -func GetMultisigPending(ctx context.Context, lapi api.FullNode, hroot cid.Cid) (map[int64]*samsig.MultiSigTransaction, error) { +func GetMultisigPending(ctx context.Context, lapi api.FullNode, hroot cid.Cid) (map[int64]*samsig.Transaction, error) { bs := apibstore.NewAPIBlockstore(lapi) cst := cbor.NewCborStore(bs) @@ -235,10 +235,10 @@ func GetMultisigPending(ctx context.Context, lapi api.FullNode, hroot cid.Cid) ( return nil, err } - txs := make(map[int64]*samsig.MultiSigTransaction) + txs := make(map[int64]*samsig.Transaction) err = nd.ForEach(ctx, func(k string, val interface{}) error { d := val.(*cbg.Deferred) - var tx samsig.MultiSigTransaction + var tx samsig.Transaction if err := tx.UnmarshalCBOR(bytes.NewReader(d.Raw)); err != nil { return err } @@ -255,7 +255,7 @@ func GetMultisigPending(ctx context.Context, lapi api.FullNode, hroot cid.Cid) ( return txs, nil } -func state(tx *samsig.MultiSigTransaction) string { +func state(tx *samsig.Transaction) string { /* // TODO(why): I strongly disagree with not having these... but i need to move forward if tx.Complete { return "done" diff --git a/cli/state.go b/cli/state.go index 229a8a7c4..fee7decb7 100644 --- a/cli/state.go +++ b/cli/state.go @@ -10,13 +10,16 @@ import ( "strings" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin/market" + samsig "github.com/filecoin-project/specs-actors/actors/builtin/multisig" + "github.com/libp2p/go-libp2p-core/peer" + "golang.org/x/xerrors" + "github.com/filecoin-project/lotus/api" actors "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/miner" - samsig "github.com/filecoin-project/specs-actors/actors/builtin/multisig" - "github.com/libp2p/go-libp2p-core/peer" - "golang.org/x/xerrors" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -124,9 +127,9 @@ var statePowerCmd = &cli.Command{ if cctx.Args().Present() { mp := power.MinerPower percI := types.BigDiv(types.BigMul(mp, types.NewInt(1000000)), tp) - fmt.Printf("%s(%s) / %s(%s) ~= %0.4f%%\n", mp.String(), mp.SizeStr(), tp.String(), tp.SizeStr(), float64(percI.Int64())/10000) + fmt.Printf("%s(%s) / %s(%s) ~= %0.4f%%\n", mp.String(), types.SizeStr(mp), tp.String(), types.SizeStr(tp), float64(percI.Int64())/10000) } else { - fmt.Printf("%s(%s)\n", tp.String(), tp.SizeStr()) + fmt.Printf("%s(%s)\n", tp.String(), types.SizeStr(tp)) } return nil @@ -330,7 +333,7 @@ var stateGetDealSetCmd = &cli.Command{ return err } - deal, err := api.StateMarketStorageDeal(ctx, dealid, ts) + deal, err := api.StateMarketStorageDeal(ctx, abi.DealID(dealid), ts) if err != nil { return err } @@ -619,7 +622,7 @@ var stateListMessagesCmd = &cli.Command{ return err } - msgs, err := api.StateListMessages(ctx, &types.Message{To: toa, From: froma}, ts, toh) + msgs, err := api.StateListMessages(ctx, &types.Message{To: toa, From: froma}, ts, abi.ChainEpoch(toh)) if err != nil { return err } @@ -672,7 +675,7 @@ var stateComputeStateCmd = &cli.Command{ return err } - h := cctx.Uint64("height") + h := abi.ChainEpoch(cctx.Uint64("height")) if h == 0 { if ts == nil { head, err := api.ChainHead(ctx) @@ -860,13 +863,13 @@ func parseParamsForMethod(act cid.Cid, method uint64, args []string) ([]byte, er var f interface{} switch act { case actors.StorageMarketCodeCid: - f = actors.StorageMarketActor{}.Exports()[method] + f = market.Actor{}.Exports()[method] case actors.StorageMinerCodeCid: f = actors.StorageMinerActor{}.Exports()[method] case actors.StoragePowerCodeCid: f = actors.StoragePowerActor{}.Exports()[method] case actors.MultisigCodeCid: - f = samsig.MultiSigActor{}.Exports()[method] + f = samsig.Actor{}.Exports()[method] case actors.PaymentChannelCodeCid: f = actors.PaymentChannelActor{}.Exports()[method] default: diff --git a/cli/sync.go b/cli/sync.go index d3d425967..d0aa11805 100644 --- a/cli/sync.go +++ b/cli/sync.go @@ -5,6 +5,7 @@ import ( "fmt" "time" + "github.com/filecoin-project/specs-actors/actors/abi" cid "github.com/ipfs/go-cid" "gopkg.in/urfave/cli.v2" @@ -44,7 +45,7 @@ var syncStatusCmd = &cli.Command{ fmt.Printf("worker %d:\n", i) var base, target []cid.Cid var heightDiff int64 - var theight uint64 + var theight abi.ChainEpoch if ss.Base != nil { base = ss.Base.Cids() heightDiff = int64(ss.Base.Height()) diff --git a/cmd/lotus-seed/seed/seed.go b/cmd/lotus-seed/seed/seed.go index 57fbd9e19..29391ea46 100644 --- a/cmd/lotus-seed/seed/seed.go +++ b/cmd/lotus-seed/seed/seed.go @@ -10,16 +10,21 @@ import ( "os" "path/filepath" - sectorbuilder "github.com/filecoin-project/go-sectorbuilder" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/abi/big" + "github.com/filecoin-project/specs-actors/actors/builtin/market" + "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/namespace" badger "github.com/ipfs/go-ds-badger2" logging "github.com/ipfs/go-log/v2" + "github.com/multiformats/go-multihash" "golang.org/x/xerrors" + sectorbuilder "github.com/filecoin-project/go-sectorbuilder" + "github.com/filecoin-project/go-address" - "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/wallet" "github.com/filecoin-project/lotus/genesis" @@ -27,7 +32,7 @@ import ( var log = logging.Logger("preseal") -func PreSeal(maddr address.Address, ssize uint64, offset uint64, sectors int, sbroot string, preimage []byte) (*genesis.GenesisMiner, error) { +func PreSeal(maddr address.Address, ssize abi.SectorSize, offset uint64, sectors int, sbroot string, preimage []byte) (*genesis.GenesisMiner, error) { cfg := §orbuilder.Config{ Miner: maddr, SectorSize: ssize, @@ -50,8 +55,6 @@ func PreSeal(maddr address.Address, ssize uint64, offset uint64, sectors int, sb return nil, err } - size := sectorbuilder.UserBytesForSectorSize(ssize) - var sealedSectors []*genesis.PreSeal for i := 0; i < sectors; i++ { sid, err := sb.AcquireSectorId() @@ -59,7 +62,7 @@ func PreSeal(maddr address.Address, ssize uint64, offset uint64, sectors int, sb return nil, err } - pi, err := sb.AddPiece(context.TODO(), size, sid, rand.Reader, nil) + pi, err := sb.AddPiece(context.TODO(), abi.PaddedPieceSize(ssize).Unpadded(), sid, rand.Reader, nil) if err != nil { return nil, err } @@ -104,7 +107,7 @@ func PreSeal(maddr address.Address, ssize uint64, offset uint64, sectors int, sb Key: minerAddr.KeyInfo, } - if err := createDeals(miner, minerAddr, maddr, ssize); err != nil { + if err := createDeals(miner, minerAddr, maddr, abi.SectorSize(ssize)); err != nil { return nil, xerrors.Errorf("creating deals: %w", err) } @@ -132,25 +135,33 @@ func WriteGenesisMiner(maddr address.Address, sbroot string, gm *genesis.Genesis return nil } -func createDeals(m *genesis.GenesisMiner, k *wallet.Key, maddr address.Address, ssize uint64) error { +func commDCID(commd []byte) cid.Cid { + d, err := cid.Prefix{ + Version: 1, + Codec: cid.Raw, + MhType: multihash.IDENTITY, + MhLength: len(commd), + }.Sum(commd) + if err != nil { + panic(err) + } + return d +} + +func createDeals(m *genesis.GenesisMiner, k *wallet.Key, maddr address.Address, ssize abi.SectorSize) error { for _, sector := range m.Sectors { pref := make([]byte, len(sector.CommD)) copy(pref, sector.CommD[:]) - proposal := &actors.StorageDealProposal{ - PieceRef: pref, // just one deal so this == CommP - PieceSize: sectorbuilder.UserBytesForSectorSize(ssize), + proposal := &market.DealProposal{ + PieceCID: commDCID(pref), // just one deal so this == CommP + PieceSize: abi.PaddedPieceSize(ssize), Client: k.Address, Provider: maddr, - ProposalExpiration: 9000, // TODO: allow setting - Duration: 9000, - StoragePricePerEpoch: types.NewInt(0), - StorageCollateral: types.NewInt(0), - ProposerSignature: nil, - } - - // TODO: pretty sure we don't even need to sign this - if err := api.SignWith(context.TODO(), wallet.KeyWallet(k).Sign, k.Address, proposal); err != nil { - return err + StartEpoch: 1, // TODO: allow setting + EndEpoch: 9001, + StoragePricePerEpoch: big.Zero(), + ProviderCollateral: big.Zero(), + ClientCollateral: big.Zero(), } sector.Deal = *proposal diff --git a/genesis/types.go b/genesis/types.go index 27eabea4a..9a9a34448 100644 --- a/genesis/types.go +++ b/genesis/types.go @@ -2,6 +2,8 @@ package genesis import ( "github.com/filecoin-project/go-address" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/types" ) @@ -9,7 +11,7 @@ import ( type PreSeal struct { CommR [32]byte CommD [32]byte - SectorID uint64 + SectorID abi.SectorNumber Deal actors.StorageDealProposal } @@ -17,7 +19,7 @@ type GenesisMiner struct { Owner address.Address Worker address.Address - SectorSize uint64 + SectorSize abi.SectorSize Sectors []*PreSeal diff --git a/go.mod b/go.mod index 60bbf4c55..6f5bed0bf 100644 --- a/go.mod +++ b/go.mod @@ -17,11 +17,12 @@ require ( github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 github.com/filecoin-project/go-data-transfer v0.0.0-20191219005021-4accf56bd2ce + github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5 github.com/filecoin-project/go-fil-markets v0.0.0-20200206024724-973498b060e3 github.com/filecoin-project/go-paramfetch v0.0.1 github.com/filecoin-project/go-sectorbuilder v0.0.2-0.20200203173614-42d67726bb62 github.com/filecoin-project/go-statestore v0.1.0 - github.com/filecoin-project/specs-actors v0.0.0-20200206185502-20fc70907293 + github.com/filecoin-project/specs-actors v0.0.0-20200207231150-6c4532d56ffd github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 github.com/go-ole/go-ole v1.2.4 // indirect github.com/gorilla/mux v1.7.3 @@ -33,7 +34,7 @@ require ( github.com/ipfs/go-block-format v0.0.2 github.com/ipfs/go-blockservice v0.1.3-0.20190908200855-f22eea50656c github.com/ipfs/go-car v0.0.3-0.20200131220434-3f68f6ebd093 - github.com/ipfs/go-cid v0.0.4 + github.com/ipfs/go-cid v0.0.5 github.com/ipfs/go-datastore v0.3.1 github.com/ipfs/go-ds-badger2 v0.0.0-20200123200730-d75eb2678a5d github.com/ipfs/go-filestore v0.0.2 @@ -79,14 +80,14 @@ require ( github.com/multiformats/go-multiaddr v0.2.0 github.com/multiformats/go-multiaddr-dns v0.2.0 github.com/multiformats/go-multiaddr-net v0.1.1 - github.com/multiformats/go-multihash v0.0.10 - github.com/multiformats/go-varint v0.0.2 + github.com/multiformats/go-multihash v0.0.13 + github.com/multiformats/go-varint v0.0.5 github.com/opentracing/opentracing-go v1.1.0 github.com/polydawn/refmt v0.0.0-20190809202753-05966cbd336a github.com/prometheus/common v0.4.0 github.com/stretchr/testify v1.4.0 github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba - github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158 + github.com/whyrusleeping/cbor-gen v0.0.0-20200206220010-03c9665e2a66 github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 github.com/whyrusleeping/pubsub v0.0.0-20131020042734-02de8aa2db3d go.opencensus.io v0.22.2 @@ -113,3 +114,7 @@ replace github.com/golangci/golangci-lint => github.com/golangci/golangci-lint v replace github.com/filecoin-project/filecoin-ffi => ./extern/filecoin-ffi replace github.com/coreos/go-systemd => github.com/coreos/go-systemd/v22 v22.0.0 + +replace github.com/filecoin-project/go-sectorbuilder => /home/magik6k/gohack/github.com/filecoin-project/go-sectorbuilder + +replace github.com/filecoin-project/go-fil-markets => /home/magik6k/gohack/github.com/filecoin-project/go-fil-markets diff --git a/go.sum b/go.sum index 7470c18b1..efc500afc 100644 --- a/go.sum +++ b/go.sum @@ -111,6 +111,8 @@ github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 h1:2pMX github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03/go.mod h1:+viYnvGtUTgJRdy6oaeF4MTFKAfatX071MPDPBL11EQ= github.com/filecoin-project/go-data-transfer v0.0.0-20191219005021-4accf56bd2ce h1:Jdejrx6XVSTRy2PiX08HCU5y68p3wx2hNMJJc/J7kZY= github.com/filecoin-project/go-data-transfer v0.0.0-20191219005021-4accf56bd2ce/go.mod h1:b14UWxhxVCAjrQUYvVGrQRRsjAh79wXYejw9RbUcAww= +github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5 h1:yvQJCW9mmi9zy+51xA01Ea2X7/dL7r8eKDPuGUjRmbo= +github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5/go.mod h1:JbkIgFF/Z9BDlvrJO1FuKkaWsH673/UdFaiVS6uIHlA= github.com/filecoin-project/go-fil-markets v0.0.0-20200206024724-973498b060e3 h1:fsHA5wFvO78+imT4VJiq2MLZGr8WmKVgjhnvVyqKOck= github.com/filecoin-project/go-fil-markets v0.0.0-20200206024724-973498b060e3/go.mod h1:0d8NAXL4ecTLvxCpoc0cZd1XbRq9UtFT14BkITidVkc= github.com/filecoin-project/go-padreader v0.0.0-20200130212543-892867c4edf9 h1:CQsjS+oWG96rk5YbeKpPw84fhbgc5H6/BGvrlPgd63A= @@ -125,6 +127,14 @@ github.com/filecoin-project/go-statestore v0.1.0 h1:t56reH59843TwXHkMcwyuayStBIi github.com/filecoin-project/go-statestore v0.1.0/go.mod h1:LFc9hD+fRxPqiHiaqUEZOinUJB4WARkRfNl10O7kTnI= github.com/filecoin-project/specs-actors v0.0.0-20200206185502-20fc70907293 h1:k/xtj90OknHTVOJikJ9mnf81UN2BaflS3R83OUg3BJM= github.com/filecoin-project/specs-actors v0.0.0-20200206185502-20fc70907293/go.mod h1:gx4vDpIVf3AfF23iyVn9PNQhKy7wGQDrhxNyCHDzG8I= +github.com/filecoin-project/specs-actors v0.0.0-20200206220134-acceaa425e32 h1:gSrOU90zdvaLF41X11mWldrRdTLPEntPnTaYNR/UHgQ= +github.com/filecoin-project/specs-actors v0.0.0-20200206220134-acceaa425e32/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= +github.com/filecoin-project/specs-actors v0.0.0-20200207002225-301c089ba033 h1:W/51r7T3vb8tFkRa5hnYCpzZBA1iIziCseI26pLXR6c= +github.com/filecoin-project/specs-actors v0.0.0-20200207002225-301c089ba033/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= +github.com/filecoin-project/specs-actors v0.0.0-20200207015621-48d5262d247f h1:3a+S7GyE2hRsKvqa4EMoPrdfs50toKZoM+VRHAgq4Bg= +github.com/filecoin-project/specs-actors v0.0.0-20200207015621-48d5262d247f/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= +github.com/filecoin-project/specs-actors v0.0.0-20200207231150-6c4532d56ffd h1:jR9qzUElb3J6UxDgDA1tlZ0AnL35dMZz7/bN/2z8Agk= +github.com/filecoin-project/specs-actors v0.0.0-20200207231150-6c4532d56ffd/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 h1:EzDjxMg43q1tA2c0MV3tNbaontnHLplHyFF6M5KiVP0= @@ -227,6 +237,8 @@ github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUP github.com/ipfs/go-cid v0.0.4-0.20191112011718-79e75dffeb10/go.mod h1:/BYOuUoxkE+0f6tGzlzMvycuN+5l35VOR4Bpg2sCmds= github.com/ipfs/go-cid v0.0.4 h1:UlfXKrZx1DjZoBhQHmNHLC1fK1dUJDN20Y28A7s+gJ8= github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= +github.com/ipfs/go-cid v0.0.5 h1:o0Ix8e/ql7Zb5UVUJEUfjsWCIY8t48++9lR8qi6oiJU= +github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= github.com/ipfs/go-datastore v0.0.5/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= github.com/ipfs/go-datastore v0.1.0/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= @@ -628,6 +640,8 @@ github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa github.com/multiformats/go-multihash v0.0.9/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= github.com/multiformats/go-multihash v0.0.10 h1:lMoNbh2Ssd9PUF74Nz008KGzGPlfeV6wH3rit5IIGCM= github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= +github.com/multiformats/go-multihash v0.0.13 h1:06x+mk/zj1FoMsgNejLpy6QTvJqlSt/BhLEy87zidlc= +github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= github.com/multiformats/go-multistream v0.0.1/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= github.com/multiformats/go-multistream v0.0.4/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= github.com/multiformats/go-multistream v0.1.0 h1:UpO6jrsjqs46mqAK3n6wKRYFhugss9ArzbyUzU+4wkQ= @@ -635,6 +649,8 @@ github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wS github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.2 h1:6sUvyh2YHpJCb8RZ6eYzj6iJQ4+chWYmyIHxszqlPTA= github.com/multiformats/go-varint v0.0.2/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/multiformats/go-varint v0.0.5 h1:XVZwSo04Cs3j/jS0uAEPpT3JY6DzMcVLLoWOSnCxOjg= +github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229 h1:E2B8qYyeSgv5MXpmzZXRNp8IAQ4vjxIjhpAf5hv/tAg= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= @@ -745,6 +761,8 @@ github.com/whyrusleeping/cbor-gen v0.0.0-20191212224538-d370462a7e8a/go.mod h1:x github.com/whyrusleeping/cbor-gen v0.0.0-20191216205031-b047b6acb3c0/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY= github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158 h1:WXhVOwj2USAXB5oMDwRl3piOux2XMV9TANaYxXHdkoE= github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= +github.com/whyrusleeping/cbor-gen v0.0.0-20200206220010-03c9665e2a66 h1:LolR9FiEfQNn5U031bAhn/46po2JgWHKadYbcWFIJ+0= +github.com/whyrusleeping/cbor-gen v0.0.0-20200206220010-03c9665e2a66/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= diff --git a/markets/utils/converters.go b/markets/utils/converters.go index 58080896f..c29987f58 100644 --- a/markets/utils/converters.go +++ b/markets/utils/converters.go @@ -3,6 +3,9 @@ package utils import ( "bytes" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/abi/big" + "github.com/filecoin-project/specs-actors/actors/builtin/market" peer "github.com/libp2p/go-libp2p-peer" "github.com/filecoin-project/go-address" @@ -17,7 +20,7 @@ func FromSharedTokenAmount(in sharedamount.TokenAmount) types.BigInt { return types.BigInt{Int: in.Int} } -func ToSharedTokenAmount(in types.BigInt) sharedamount.TokenAmount { +func ToSharedTokenAmount(in abi.TokenAmount) sharedamount.TokenAmount { return sharedamount.TokenAmount{Int: in.Int} } @@ -105,43 +108,31 @@ func FromSignedStorageAsk(in *sharedtypes.SignedStorageAsk) (*types.SignedStorag return &out, nil } -func NewStorageProviderInfo(address address.Address, miner address.Address, sectorSize uint64, peer peer.ID) storagemarket.StorageProviderInfo { +func NewStorageProviderInfo(address address.Address, miner address.Address, sectorSize abi.SectorSize, peer peer.ID) storagemarket.StorageProviderInfo { return storagemarket.StorageProviderInfo{ Address: address, Worker: miner, - SectorSize: sectorSize, + SectorSize: uint64(sectorSize), PeerID: peer, } } -func FromOnChainDeal(deal actors.OnChainDeal) storagemarket.StorageDeal { +func FromOnChainDeal(proposal market.DealProposal, state market.DealState) storagemarket.StorageDeal { return storagemarket.StorageDeal{ - PieceRef: deal.PieceRef, - PieceSize: deal.PieceSize, - Client: deal.Client, - Provider: deal.Provider, - StoragePricePerEpoch: ToSharedTokenAmount(deal.StoragePricePerEpoch), - StorageCollateral: ToSharedTokenAmount(deal.StorageCollateral), - ActivationEpoch: deal.ActivationEpoch, + PieceRef: proposal.PieceCID.Bytes(), + PieceSize: uint64(proposal.PieceSize.Unpadded()), + Client: proposal.Client, + Provider: proposal.Provider, + StoragePricePerEpoch: ToSharedTokenAmount(proposal.StoragePricePerEpoch), + StorageCollateral: ToSharedTokenAmount(proposal.ProviderCollateral), + ActivationEpoch: uint64(state.SectorStartEpoch), } } -func ToOnChainDeal(deal storagemarket.StorageDeal) actors.OnChainDeal { - return actors.OnChainDeal{ - PieceRef: deal.PieceRef, - PieceSize: deal.PieceSize, - Client: deal.Client, - Provider: deal.Provider, - StoragePricePerEpoch: FromSharedTokenAmount(deal.StoragePricePerEpoch), - StorageCollateral: FromSharedTokenAmount(deal.StorageCollateral), - ActivationEpoch: deal.ActivationEpoch, - } -} - -func ToSharedBalance(balance actors.StorageParticipantBalance) storagemarket.Balance { +func ToSharedBalance(escrow, locked abi.TokenAmount) storagemarket.Balance { return storagemarket.Balance{ - Locked: ToSharedTokenAmount(balance.Locked), - Available: ToSharedTokenAmount(balance.Available), + Locked: ToSharedTokenAmount(locked), + Available: ToSharedTokenAmount(big.Sub(escrow, locked)), } } diff --git a/miner/miner.go b/miner/miner.go index 0395165fa..49935517a 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -12,6 +12,7 @@ import ( "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/specs-actors/actors/abi" lru "github.com/hashicorp/golang-lru" logging "github.com/ipfs/go-log/v2" @@ -243,7 +244,7 @@ eventLoop: type MiningBase struct { ts *types.TipSet - nullRounds uint64 + nullRounds abi.ChainEpoch } func (m *Miner) GetBestMiningCandidate(ctx context.Context) (*MiningBase, error) { diff --git a/node/impl/full/chain.go b/node/impl/full/chain.go index 4b7441989..8abe991e3 100644 --- a/node/impl/full/chain.go +++ b/node/impl/full/chain.go @@ -8,6 +8,7 @@ import ( "strings" "github.com/filecoin-project/go-amt-ipld/v2" + "github.com/filecoin-project/specs-actors/actors/abi" "github.com/ipfs/go-blockservice" "github.com/ipfs/go-cid" "github.com/ipfs/go-hamt-ipld" @@ -157,7 +158,7 @@ func (a *ChainAPI) ChainGetParentReceipts(ctx context.Context, bcid cid.Cid) ([] return out, nil } -func (a *ChainAPI) ChainGetTipSetByHeight(ctx context.Context, h uint64, ts *types.TipSet) (*types.TipSet, error) { +func (a *ChainAPI) ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEpoch, ts *types.TipSet) (*types.TipSet, error) { return a.Chain.GetTipsetByHeight(ctx, h, ts) } diff --git a/node/impl/full/state.go b/node/impl/full/state.go index d380c4cfc..c7993bb88 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -7,8 +7,9 @@ import ( "strconv" "github.com/filecoin-project/go-amt-ipld/v2" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin/market" samsig "github.com/filecoin-project/specs-actors/actors/builtin/multisig" - cid "github.com/ipfs/go-cid" "github.com/ipfs/go-hamt-ipld" cbor "github.com/ipfs/go-ipld-cbor" @@ -18,6 +19,7 @@ import ( "golang.org/x/xerrors" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/gen" @@ -83,7 +85,7 @@ func (a *StateAPI) StateMinerElectionPeriodStart(ctx context.Context, actor addr return stmgr.GetMinerElectionPeriodStart(ctx, a.StateManager, ts, actor) } -func (a *StateAPI) StateMinerSectorSize(ctx context.Context, actor address.Address, ts *types.TipSet) (uint64, error) { +func (a *StateAPI) StateMinerSectorSize(ctx context.Context, actor address.Address, ts *types.TipSet) (abi.SectorSize, error) { return stmgr.GetMinerSectorSize(ctx, a.StateManager, ts, actor) } @@ -193,7 +195,7 @@ func (a *StateAPI) StateReadState(ctx context.Context, act *types.Actor, ts *typ } // This is on StateAPI because miner.Miner requires this, and MinerAPI requires miner.Miner -func (a *StateAPI) MinerCreateBlock(ctx context.Context, addr address.Address, parents *types.TipSet, ticket *types.Ticket, proof *types.EPostProof, msgs []*types.SignedMessage, height, ts uint64) (*types.BlockMsg, error) { +func (a *StateAPI) MinerCreateBlock(ctx context.Context, addr address.Address, parents *types.TipSet, ticket *types.Ticket, proof *types.EPostProof, msgs []*types.SignedMessage, height abi.ChainEpoch, ts uint64) (*types.BlockMsg, error) { fblk, err := gen.MinerCreateBlock(ctx, a.StateManager, a.Wallet, addr, parents, ticket, proof, msgs, height, ts) if err != nil { return nil, err @@ -237,34 +239,47 @@ func (a *StateAPI) StateListActors(ctx context.Context, ts *types.TipSet) ([]add return a.StateManager.ListAllActors(ctx, ts) } -func (a *StateAPI) StateMarketBalance(ctx context.Context, addr address.Address, ts *types.TipSet) (actors.StorageParticipantBalance, error) { +func (a *StateAPI) StateMarketBalance(ctx context.Context, addr address.Address, ts *types.TipSet) (api.MarketBalance, error) { return a.StateManager.MarketBalance(ctx, addr, ts) } -func (a *StateAPI) StateMarketParticipants(ctx context.Context, ts *types.TipSet) (map[string]actors.StorageParticipantBalance, error) { - out := map[string]actors.StorageParticipantBalance{} +func (a *StateAPI) StateMarketParticipants(ctx context.Context, ts *types.TipSet) (map[string]api.MarketBalance, error) { + out := map[string]api.MarketBalance{} var state actors.StorageMarketState if _, err := a.StateManager.LoadActorState(ctx, actors.StorageMarketAddress, &state, ts); err != nil { return nil, err } cst := cbor.NewCborStore(a.StateManager.ChainStore().Blockstore()) - nd, err := hamt.LoadNode(ctx, cst, state.Balances) + escrow, err := hamt.LoadNode(ctx, cst, state.EscrowTable) + if err != nil { + return nil, err + } + locked, err := hamt.LoadNode(ctx, cst, state.EscrowTable) if err != nil { return nil, err } - err = nd.ForEach(ctx, func(k string, val interface{}) error { + err = escrow.ForEach(ctx, func(k string, val interface{}) error { cv := val.(*cbg.Deferred) a, err := address.NewFromBytes([]byte(k)) if err != nil { return err } - var b actors.StorageParticipantBalance - if err := b.UnmarshalCBOR(bytes.NewReader(cv.Raw)); err != nil { + + var es abi.TokenAmount + if err := es.UnmarshalCBOR(bytes.NewReader(cv.Raw)); err != nil { return err } - out[a.String()] = b + var lk abi.TokenAmount + if err := locked.Find(ctx, k, &es); err != nil { + return err + } + + out[a.String()] = api.MarketBalance{ + Escrow: es, + Locked: lk, + } return nil }) if err != nil { @@ -273,8 +288,8 @@ func (a *StateAPI) StateMarketParticipants(ctx context.Context, ts *types.TipSet return out, nil } -func (a *StateAPI) StateMarketDeals(ctx context.Context, ts *types.TipSet) (map[string]actors.OnChainDeal, error) { - out := map[string]actors.OnChainDeal{} +func (a *StateAPI) StateMarketDeals(ctx context.Context, ts *types.TipSet) (map[string]market.DealProposal, error) { + out := map[string]market.DealProposal{} var state actors.StorageMarketState if _, err := a.StateManager.LoadActorState(ctx, actors.StorageMarketAddress, &state, ts); err != nil { @@ -282,13 +297,13 @@ func (a *StateAPI) StateMarketDeals(ctx context.Context, ts *types.TipSet) (map[ } blks := cbor.NewCborStore(a.StateManager.ChainStore().Blockstore()) - da, err := amt.LoadAMT(ctx, blks, state.Deals) + da, err := amt.LoadAMT(ctx, blks, state.Proposals) if err != nil { return nil, err } if err := da.ForEach(ctx, func(i uint64, v *cbg.Deferred) error { - var d actors.OnChainDeal + var d market.DealProposal if err := d.UnmarshalCBOR(bytes.NewReader(v.Raw)); err != nil { return err } @@ -300,7 +315,7 @@ func (a *StateAPI) StateMarketDeals(ctx context.Context, ts *types.TipSet) (map[ return out, nil } -func (a *StateAPI) StateMarketStorageDeal(ctx context.Context, dealId uint64, ts *types.TipSet) (*actors.OnChainDeal, error) { +func (a *StateAPI) StateMarketStorageDeal(ctx context.Context, dealId uint64, ts *types.TipSet) (*market.DealProposal, error) { return stmgr.GetStorageDeal(ctx, a.StateManager, dealId, ts) } @@ -359,7 +374,7 @@ func (a *StateAPI) StateMinerSectorCount(ctx context.Context, addr address.Addre return stmgr.SectorSetSizes(ctx, a.StateManager, addr, ts) } -func (a *StateAPI) StateListMessages(ctx context.Context, match *types.Message, ts *types.TipSet, toheight uint64) ([]cid.Cid, error) { +func (a *StateAPI) StateListMessages(ctx context.Context, match *types.Message, ts *types.TipSet, toheight abi.ChainEpoch) ([]cid.Cid, error) { if ts == nil { ts = a.Chain.GetHeaviestTipSet() } @@ -408,7 +423,7 @@ func (a *StateAPI) StateListMessages(ctx context.Context, match *types.Message, return out, nil } -func (a *StateAPI) StateCompute(ctx context.Context, height uint64, msgs []*types.Message, ts *types.TipSet) (cid.Cid, error) { +func (a *StateAPI) StateCompute(ctx context.Context, height abi.ChainEpoch, msgs []*types.Message, ts *types.TipSet) (cid.Cid, error) { return stmgr.ComputeState(ctx, a.StateManager, height, msgs, ts) } @@ -417,7 +432,7 @@ func (a *StateAPI) MsigGetAvailableBalance(ctx context.Context, addr address.Add ts = a.Chain.GetHeaviestTipSet() } - var st samsig.MultiSigActorState + var st samsig.State act, err := a.StateManager.LoadActorState(ctx, addr, &st, ts) if err != nil { return types.EmptyInt, xerrors.Errorf("failed to load multisig actor state: %w", err) @@ -431,12 +446,12 @@ func (a *StateAPI) MsigGetAvailableBalance(ctx context.Context, addr address.Add return act.Balance, nil } - offset := ts.Height() - uint64(st.StartEpoch) - if offset > uint64(st.UnlockDuration) { + offset := ts.Height() - st.StartEpoch + if offset > st.UnlockDuration { return act.Balance, nil } minBalance := types.BigDiv(types.BigInt(st.InitialBalance), types.NewInt(uint64(st.UnlockDuration))) - minBalance = types.BigMul(minBalance, types.NewInt(offset)) + minBalance = types.BigMul(minBalance, types.NewInt(uint64(offset))) return types.BigSub(act.Balance, minBalance), nil } diff --git a/storage/fpost_run.go b/storage/fpost_run.go index 5cd711c7b..69cbcddbd 100644 --- a/storage/fpost_run.go +++ b/storage/fpost_run.go @@ -6,6 +6,7 @@ import ( ffi "github.com/filecoin-project/filecoin-ffi" sectorbuilder "github.com/filecoin-project/go-sectorbuilder" + "github.com/filecoin-project/specs-actors/actors/abi" "go.opencensus.io/trace" "golang.org/x/xerrors" @@ -14,7 +15,7 @@ import ( "github.com/filecoin-project/lotus/chain/types" ) -func (s *FPoStScheduler) failPost(eps uint64) { +func (s *FPoStScheduler) failPost(eps abi.ChainEpoch) { s.failLk.Lock() if eps > s.failed { s.failed = eps @@ -22,7 +23,7 @@ func (s *FPoStScheduler) failPost(eps uint64) { s.failLk.Unlock() } -func (s *FPoStScheduler) doPost(ctx context.Context, eps uint64, ts *types.TipSet) { +func (s *FPoStScheduler) doPost(ctx context.Context, eps abi.ChainEpoch, ts *types.TipSet) { ctx, abort := context.WithCancel(ctx) s.abort = abort @@ -86,10 +87,10 @@ func (s *FPoStScheduler) declareFaults(ctx context.Context, fc uint64, params *a return nil } -func (s *FPoStScheduler) checkFaults(ctx context.Context, ssi sectorbuilder.SortedPublicSectorInfo) ([]uint64, error) { +func (s *FPoStScheduler) checkFaults(ctx context.Context, ssi sectorbuilder.SortedPublicSectorInfo) ([]abi.SectorNumber, error) { faults := s.sb.Scrub(ssi) - declaredFaults := map[uint64]struct{}{} + declaredFaults := map[abi.SectorNumber]struct{}{} { chainFaults, err := s.api.StateMinerFaults(ctx, s.actor, nil) @@ -106,12 +107,12 @@ func (s *FPoStScheduler) checkFaults(ctx context.Context, ssi sectorbuilder.Sort params := &actors.DeclareFaultsParams{Faults: types.NewBitField()} for _, fault := range faults { - if _, ok := declaredFaults[fault.SectorID]; ok { + if _, ok := declaredFaults[abi.SectorNumber(fault.SectorID)]; ok { continue } log.Warnf("new fault detected: sector %d: %s", fault.SectorID, fault.Err) - declaredFaults[fault.SectorID] = struct{}{} + declaredFaults[abi.SectorNumber(fault.SectorID)] = struct{}{} params.Faults.Set(fault.SectorID) } @@ -126,15 +127,15 @@ func (s *FPoStScheduler) checkFaults(ctx context.Context, ssi sectorbuilder.Sort } } - faultIDs := make([]uint64, 0, len(declaredFaults)) + faultIDs := make([]abi.SectorNumber, 0, len(declaredFaults)) for fault := range declaredFaults { - faultIDs = append(faultIDs, fault) + faultIDs = append(faultIDs, abi.SectorNumber(fault)) } return faultIDs, nil } -func (s *FPoStScheduler) runPost(ctx context.Context, eps uint64, ts *types.TipSet) (*actors.SubmitFallbackPoStParams, error) { +func (s *FPoStScheduler) runPost(ctx context.Context, eps abi.ChainEpoch, ts *types.TipSet) (*actors.SubmitFallbackPoStParams, error) { ctx, span := trace.StartSpan(ctx, "storage.runPost") defer span.End() diff --git a/storage/fpost_sched.go b/storage/fpost_sched.go index 9fa427677..ad976abdf 100644 --- a/storage/fpost_sched.go +++ b/storage/fpost_sched.go @@ -4,6 +4,7 @@ import ( "context" "sync" + "github.com/filecoin-project/specs-actors/actors/abi" "go.opencensus.io/trace" "golang.org/x/xerrors" @@ -29,10 +30,10 @@ type FPoStScheduler struct { cur *types.TipSet // if a post is in progress, this indicates for which ElectionPeriodStart - activeEPS uint64 + activeEPS abi.ChainEpoch abort context.CancelFunc - failed uint64 // eps + failed abi.ChainEpoch // eps failLk sync.Mutex } @@ -161,7 +162,7 @@ func (s *FPoStScheduler) abortActivePoSt() { s.abort = nil } -func (s *FPoStScheduler) shouldFallbackPost(ctx context.Context, ts *types.TipSet) (uint64, bool, error) { +func (s *FPoStScheduler) shouldFallbackPost(ctx context.Context, ts *types.TipSet) (abi.ChainEpoch, bool, error) { eps, err := s.api.StateMinerElectionPeriodStart(ctx, s.actor, ts) if err != nil { return 0, false, xerrors.Errorf("getting ElectionPeriodStart: %w", err) diff --git a/storage/miner.go b/storage/miner.go index 110d93565..84adfa66a 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -6,16 +6,18 @@ import ( "time" "github.com/filecoin-project/go-address" - "github.com/filecoin-project/go-sectorbuilder" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin/market" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" logging "github.com/ipfs/go-log/v2" "github.com/libp2p/go-libp2p-core/host" "golang.org/x/xerrors" + "github.com/filecoin-project/go-sectorbuilder" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/events" "github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/store" @@ -42,22 +44,22 @@ type storageMinerApi interface { // Call a read only method on actors (no interaction with the chain required) StateCall(context.Context, *types.Message, *types.TipSet) (*api.MethodCall, error) StateMinerWorker(context.Context, address.Address, *types.TipSet) (address.Address, error) - StateMinerElectionPeriodStart(ctx context.Context, actor address.Address, ts *types.TipSet) (uint64, error) + StateMinerElectionPeriodStart(ctx context.Context, actor address.Address, ts *types.TipSet) (abi.ChainEpoch, error) StateMinerSectors(context.Context, address.Address, *types.TipSet) ([]*api.ChainSectorInfo, error) StateMinerProvingSet(context.Context, address.Address, *types.TipSet) ([]*api.ChainSectorInfo, error) - StateMinerSectorSize(context.Context, address.Address, *types.TipSet) (uint64, error) + StateMinerSectorSize(context.Context, address.Address, *types.TipSet) (abi.SectorSize, error) StateWaitMsg(context.Context, cid.Cid) (*api.MsgWait, error) // TODO: removeme eventually StateGetActor(ctx context.Context, actor address.Address, ts *types.TipSet) (*types.Actor, error) StateGetReceipt(context.Context, cid.Cid, *types.TipSet) (*types.MessageReceipt, error) - StateMarketStorageDeal(context.Context, uint64, *types.TipSet) (*actors.OnChainDeal, error) - StateMinerFaults(context.Context, address.Address, *types.TipSet) ([]uint64, error) + StateMarketStorageDeal(context.Context, abi.DealID, *types.TipSet) (*market.DealProposal, error) + StateMinerFaults(context.Context, address.Address, *types.TipSet) ([]abi.SectorNumber, error) MpoolPushMessage(context.Context, *types.Message) (*types.SignedMessage, error) ChainHead(context.Context) (*types.TipSet, error) ChainNotify(context.Context) (<-chan []*store.HeadChange, error) ChainGetRandomness(context.Context, types.TipSetKey, int64) ([]byte, error) - ChainGetTipSetByHeight(context.Context, uint64, *types.TipSet) (*types.TipSet, error) + ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, *types.TipSet) (*types.TipSet, error) ChainGetBlockMessages(context.Context, cid.Cid) (*api.BlockMessages, error) ChainReadObj(context.Context, cid.Cid) ([]byte, error) @@ -125,7 +127,7 @@ var _ gen.ElectionPoStProver = (*SectorBuilderEpp)(nil) func (epp *SectorBuilderEpp) GenerateCandidates(ctx context.Context, ssi sectorbuilder.SortedPublicSectorInfo, rand []byte) ([]sectorbuilder.EPostCandidate, error) { start := time.Now() - var faults []uint64 // TODO + var faults []abi.SectorNumber // TODO var randbuf [32]byte copy(randbuf[:], rand) diff --git a/storage/sealing.go b/storage/sealing.go index d6d27b429..5ede41996 100644 --- a/storage/sealing.go +++ b/storage/sealing.go @@ -4,17 +4,19 @@ import ( "context" "io" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/storage/sealing" ) // TODO: refactor this to be direct somehow -func (m *Miner) AllocatePiece(size uint64) (sectorID uint64, offset uint64, err error) { +func (m *Miner) AllocatePiece(size uint64) (sectorID abi.SectorNumber, offset uint64, err error) { return m.sealing.AllocatePiece(size) } -func (m *Miner) SealPiece(ctx context.Context, size uint64, r io.Reader, sectorID uint64, dealID uint64) error { +func (m *Miner) SealPiece(ctx context.Context, size abi.UnpaddedPieceSize, r io.Reader, sectorID abi.SectorNumber, dealID abi.DealID) error { return m.sealing.SealPiece(ctx, size, r, sectorID, dealID) } diff --git a/storage/sealing/cbor_gen.go b/storage/sealing/cbor_gen.go index af1a18da2..21e60741f 100644 --- a/storage/sealing/cbor_gen.go +++ b/storage/sealing/cbor_gen.go @@ -218,9 +218,7 @@ func (t *SealSeed) UnmarshalCBOR(r io.Reader) error { } if maj != cbg.MajUnsignedInt { return fmt.Errorf("wrong type for uint64 field") - } - t.BlockHeight = uint64(extra) - // t.TicketBytes ([]uint8) (slice) + } // t.TicketBytes ([]uint8) (slice) case "TicketBytes": maj, extra, err = cbg.CborReadHeader(br) @@ -352,18 +350,9 @@ func (t *Piece) UnmarshalCBOR(r io.Reader) error { if maj != cbg.MajUnsignedInt { return fmt.Errorf("wrong type for uint64 field") } - t.DealID = uint64(extra) // t.Size (uint64) (uint64) case "Size": - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.Size = uint64(extra) // t.CommP ([]uint8) (slice) case "CommP": @@ -740,7 +729,6 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { if maj != cbg.MajUnsignedInt { return fmt.Errorf("wrong type for uint64 field") } - t.SectorID = uint64(extra) // t.Nonce (uint64) (uint64) case "Nonce": diff --git a/storage/sealing/checks.go b/storage/sealing/checks.go index 9baf2d993..a94cd20da 100644 --- a/storage/sealing/checks.go +++ b/storage/sealing/checks.go @@ -3,6 +3,7 @@ package sealing import ( "context" + "github.com/multiformats/go-multihash" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" @@ -39,16 +40,21 @@ func checkPieces(ctx context.Context, si SectorInfo, api sealingApi) error { return &ErrApi{xerrors.Errorf("getting deal %d for piece %d: %w", piece.DealID, i, err)} } - if string(deal.PieceRef) != string(piece.CommP) { - return &ErrInvalidDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers deal %d with wrong CommP: %x != %x", i, len(si.Pieces), si.SectorID, piece.DealID, piece.CommP, deal.PieceRef)} + h, err := multihash.Decode(deal.PieceCID.Hash()) + if err != nil { + return &ErrInvalidDeals{xerrors.Errorf("decoding piece CID: %w", err)} } - if piece.Size != deal.PieceSize { + if string(h.Digest) != string(piece.CommP) { + return &ErrInvalidDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers deal %d with wrong CommP: %x != %x", i, len(si.Pieces), si.SectorID, piece.DealID, piece.CommP, h.Digest)} + } + + if piece.Size != deal.PieceSize.Unpadded() { return &ErrInvalidDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers deal %d with different size: %d != %d", i, len(si.Pieces), si.SectorID, piece.DealID, piece.Size, deal.PieceSize)} } - if head.Height() >= deal.ProposalExpiration { - return &ErrExpiredDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers expired deal %d - expires %d, head %d", i, len(si.Pieces), si.SectorID, piece.DealID, deal.ProposalExpiration, head.Height())} + if head.Height() >= deal.StartEpoch { + return &ErrExpiredDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers expired deal %d - should start at %d, head %d", i, len(si.Pieces), si.SectorID, piece.DealID, deal.StartEpoch, head.Height())} } } diff --git a/storage/sealing/fsm_events.go b/storage/sealing/fsm_events.go index 84b1120c8..528da1234 100644 --- a/storage/sealing/fsm_events.go +++ b/storage/sealing/fsm_events.go @@ -1,6 +1,7 @@ package sealing import ( + "github.com/filecoin-project/specs-actors/actors/abi" "github.com/ipfs/go-cid" "github.com/filecoin-project/lotus/api" @@ -45,7 +46,7 @@ func (evt SectorForceState) applyGlobal(state *SectorInfo) bool { // Normal path type SectorStart struct { - id uint64 + id abi.SectorNumber pieces []Piece } diff --git a/storage/sealing/garbage.go b/storage/sealing/garbage.go index ca8c1e454..52f2eb9cb 100644 --- a/storage/sealing/garbage.go +++ b/storage/sealing/garbage.go @@ -8,20 +8,22 @@ import ( "math/bits" "math/rand" - sectorbuilder "github.com/filecoin-project/go-sectorbuilder" + commcid "github.com/filecoin-project/go-fil-commcid" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin/market" "golang.org/x/xerrors" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/types" ) -func (m *Sealing) pledgeReader(size uint64, parts uint64) io.Reader { +func (m *Sealing) pledgeReader(size abi.UnpaddedPieceSize, parts uint64) io.Reader { parts = 1 << bits.Len64(parts) // round down to nearest power of 2 - if size/parts < 127 { - parts = size / 127 + if uint64(size)/parts < 127 { + parts = uint64(size) / 127 } - piece := sectorbuilder.UserBytesForSectorSize((size/127 + size) / parts) + piece := abi.PaddedPieceSize(uint64(size.Padded()) / parts).Unpadded() readers := make([]io.Reader, parts) for i := range readers { @@ -31,33 +33,34 @@ func (m *Sealing) pledgeReader(size uint64, parts uint64) io.Reader { return io.MultiReader(readers...) } -func (m *Sealing) pledgeSector(ctx context.Context, sectorID uint64, existingPieceSizes []uint64, sizes ...uint64) ([]Piece, error) { +func (m *Sealing) pledgeSector(ctx context.Context, sectorID abi.SectorNumber, existingPieceSizes []abi.UnpaddedPieceSize, sizes ...abi.UnpaddedPieceSize) ([]Piece, error) { if len(sizes) == 0 { return nil, nil } log.Infof("Pledge %d, contains %+v", sectorID, existingPieceSizes) - deals := make([]actors.StorageDealProposal, len(sizes)) + deals := make([]market.ClientDealProposal, len(sizes)) for i, size := range sizes { commP, err := m.fastPledgeCommitment(size, uint64(1)) if err != nil { return nil, err } - sdp := actors.StorageDealProposal{ - PieceRef: commP[:], - PieceSize: size, + sdp := market.DealProposal{ + PieceCID: commcid.PieceCommitmentV1ToCID(commP[:]), + PieceSize: size.Padded(), Client: m.worker, Provider: m.maddr, - ProposalExpiration: math.MaxUint64, - Duration: math.MaxUint64 / 2, // /2 because overflows + StartEpoch: math.MaxInt64, + EndEpoch: math.MaxInt64, StoragePricePerEpoch: types.NewInt(0), - StorageCollateral: types.NewInt(0), - ProposerSignature: nil, // nil because self dealing + ProviderCollateral: types.NewInt(0), } - deals[i] = sdp + deals[i] = market.ClientDealProposal{ + Proposal: sdp, + } } log.Infof("Publishing deals for %d", sectorID) @@ -92,11 +95,11 @@ func (m *Sealing) pledgeSector(ctx context.Context, sectorID uint64, existingPie if err := resp.UnmarshalCBOR(bytes.NewReader(r.Receipt.Return)); err != nil { return nil, err } - if len(resp.DealIDs) != len(sizes) { + if len(resp.IDs) != len(sizes) { return nil, xerrors.New("got unexpected number of DealIDs from PublishStorageDeals") } - log.Infof("Deals for sector %d: %+v", sectorID, resp.DealIDs) + log.Infof("Deals for sector %d: %+v", sectorID, resp.IDs) out := make([]Piece, len(sizes)) for i, size := range sizes { @@ -108,8 +111,8 @@ func (m *Sealing) pledgeSector(ctx context.Context, sectorID uint64, existingPie existingPieceSizes = append(existingPieceSizes, size) out[i] = Piece{ - DealID: resp.DealIDs[i], - Size: ppi.Size, + DealID: resp.IDs[i], + Size: abi.UnpaddedPieceSize(ppi.Size), CommP: ppi.CommP[:], } } @@ -123,7 +126,7 @@ func (m *Sealing) PledgeSector() error { // this, as we run everything here async, and it's cancelled when the // command exits - size := sectorbuilder.UserBytesForSectorSize(m.sb.SectorSize()) + size := abi.PaddedPieceSize(m.sb.SectorSize()).Unpadded() sid, err := m.sb.AcquireSectorId() if err != nil { @@ -131,7 +134,7 @@ func (m *Sealing) PledgeSector() error { return } - pieces, err := m.pledgeSector(ctx, sid, []uint64{}, size) + pieces, err := m.pledgeSector(ctx, sid, []abi.UnpaddedPieceSize{}, abi.UnpaddedPieceSize(size)) if err != nil { log.Errorf("%+v", err) return diff --git a/storage/sealing/sealing.go b/storage/sealing/sealing.go index 6e562001d..a9e080328 100644 --- a/storage/sealing/sealing.go +++ b/storage/sealing/sealing.go @@ -6,6 +6,8 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-sectorbuilder" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin/market" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/namespace" @@ -13,7 +15,6 @@ import ( "golang.org/x/xerrors" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/events" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" @@ -31,21 +32,21 @@ type sealingApi interface { // TODO: trim down // Call a read only method on actors (no interaction with the chain required) StateCall(context.Context, *types.Message, *types.TipSet) (*api.MethodCall, error) StateMinerWorker(context.Context, address.Address, *types.TipSet) (address.Address, error) - StateMinerElectionPeriodStart(ctx context.Context, actor address.Address, ts *types.TipSet) (uint64, error) + StateMinerElectionPeriodStart(ctx context.Context, actor address.Address, ts *types.TipSet) (abi.ChainEpoch, error) StateMinerSectors(context.Context, address.Address, *types.TipSet) ([]*api.ChainSectorInfo, error) StateMinerProvingSet(context.Context, address.Address, *types.TipSet) ([]*api.ChainSectorInfo, error) - StateMinerSectorSize(context.Context, address.Address, *types.TipSet) (uint64, error) + StateMinerSectorSize(context.Context, address.Address, *types.TipSet) (abi.SectorSize, error) StateWaitMsg(context.Context, cid.Cid) (*api.MsgWait, error) // TODO: removeme eventually StateGetActor(ctx context.Context, actor address.Address, ts *types.TipSet) (*types.Actor, error) StateGetReceipt(context.Context, cid.Cid, *types.TipSet) (*types.MessageReceipt, error) - StateMarketStorageDeal(context.Context, uint64, *types.TipSet) (*actors.OnChainDeal, error) + StateMarketStorageDeal(context.Context, abi.DealID, *types.TipSet) (*market.DealProposal, error) MpoolPushMessage(context.Context, *types.Message) (*types.SignedMessage, error) ChainHead(context.Context) (*types.TipSet, error) ChainNotify(context.Context) (<-chan []*store.HeadChange, error) ChainGetRandomness(context.Context, types.TipSetKey, int64) ([]byte, error) - ChainGetTipSetByHeight(context.Context, uint64, *types.TipSet) (*types.TipSet, error) + ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, *types.TipSet) (*types.TipSet, error) ChainGetBlockMessages(context.Context, cid.Cid) (*api.BlockMessages, error) ChainReadObj(context.Context, cid.Cid) ([]byte, error) @@ -95,7 +96,7 @@ func (m *Sealing) Stop(ctx context.Context) error { return m.sectors.Stop(ctx) } -func (m *Sealing) AllocatePiece(size uint64) (sectorID uint64, offset uint64, err error) { +func (m *Sealing) AllocatePiece(size uint64) (sectorID abi.SectorNumber, offset uint64, err error) { if padreader.PaddedSize(size) != size { return 0, 0, xerrors.Errorf("cannot allocate unpadded piece") } @@ -109,10 +110,10 @@ func (m *Sealing) AllocatePiece(size uint64) (sectorID uint64, offset uint64, er return sid, 0, nil } -func (m *Sealing) SealPiece(ctx context.Context, size uint64, r io.Reader, sectorID uint64, dealID uint64) error { +func (m *Sealing) SealPiece(ctx context.Context, size abi.UnpaddedPieceSize, r io.Reader, sectorID abi.SectorNumber, dealID abi.DealID) error { log.Infof("Seal piece for deal %d", dealID) - ppi, err := m.sb.AddPiece(ctx, size, sectorID, r, []uint64{}) + ppi, err := m.sb.AddPiece(ctx, size, sectorID, r, []abi.UnpaddedPieceSize{}) if err != nil { return xerrors.Errorf("adding piece to sector: %w", err) } @@ -120,7 +121,7 @@ func (m *Sealing) SealPiece(ctx context.Context, size uint64, r io.Reader, secto return m.newSector(ctx, sectorID, dealID, ppi) } -func (m *Sealing) newSector(ctx context.Context, sid uint64, dealID uint64, ppi sectorbuilder.PublicPieceInfo) error { +func (m *Sealing) newSector(ctx context.Context, sid abi.SectorNumber, dealID abi.DealID, ppi sectorbuilder.PublicPieceInfo) error { log.Infof("Start sealing %d", sid) return m.sectors.Send(sid, SectorStart{ id: sid, @@ -128,7 +129,7 @@ func (m *Sealing) newSector(ctx context.Context, sid uint64, dealID uint64, ppi { DealID: dealID, - Size: ppi.Size, + Size: abi.UnpaddedPieceSize(ppi.Size), CommP: ppi.CommP[:], }, }, diff --git a/storage/sealing/states.go b/storage/sealing/states.go index 723a2d843..7288770cc 100644 --- a/storage/sealing/states.go +++ b/storage/sealing/states.go @@ -3,8 +3,8 @@ package sealing import ( "context" - sectorbuilder "github.com/filecoin-project/go-sectorbuilder" "github.com/filecoin-project/go-sectorbuilder/fs" + "github.com/filecoin-project/specs-actors/actors/abi" "golang.org/x/xerrors" "github.com/filecoin-project/lotus/build" @@ -16,12 +16,12 @@ import ( func (m *Sealing) handlePacking(ctx statemachine.Context, sector SectorInfo) error { log.Infow("performing filling up rest of the sector...", "sector", sector.SectorID) - var allocated uint64 + var allocated abi.UnpaddedPieceSize for _, piece := range sector.Pieces { allocated += piece.Size } - ubytes := sectorbuilder.UserBytesForSectorSize(m.sb.SectorSize()) + ubytes := abi.PaddedPieceSize(m.sb.SectorSize()).Unpadded() if allocated > ubytes { return xerrors.Errorf("too much data in sector: %d > %d", allocated, ubytes) @@ -100,7 +100,7 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf CommR: sector.CommR, SealEpoch: sector.Ticket.BlockHeight, - DealIDs: sector.deals(), + DealIDs: nil, // sector.deals(), // TODO: REFACTOR } enc, aerr := actors.SerializeParams(params) if aerr != nil { @@ -144,7 +144,7 @@ func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) er randHeight := mw.TipSet.Height() + build.InteractivePoRepDelay - 1 // -1 because of how the messages are applied log.Infof("precommit for sector %d made it on chain, will start proof computation at height %d", sector.SectorID, randHeight) - err = m.events.ChainAt(func(ectx context.Context, ts *types.TipSet, curH uint64) error { + err = m.events.ChainAt(func(ectx context.Context, ts *types.TipSet, curH abi.ChainEpoch) error { rand, err := m.api.ChainGetRandomness(ectx, ts.Key(), int64(randHeight)) if err != nil { err = xerrors.Errorf("failed to get randomness for computing seal proof: %w", err) @@ -181,13 +181,13 @@ func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo) // TODO: Consider splitting states and persist proof for faster recovery - params := &actors.SectorProveCommitInfo{ + /*params := &actors.SectorProveCommitInfo{ Proof: proof, SectorID: sector.SectorID, DealIDs: sector.deals(), - } + }*/ - enc, aerr := actors.SerializeParams(params) + enc, aerr := actors.SerializeParams(nil) // TODO: REFACTOR: Fix if aerr != nil { return ctx.Send(SectorCommitFailed{xerrors.Errorf("could not serialize commit sector parameters: %w", aerr)}) } @@ -255,7 +255,7 @@ func (m *Sealing) handleFaulty(ctx statemachine.Context, sector SectorInfo) erro // TODO: coalesce faulty sector reporting bf := types.NewBitField() - bf.Set(sector.SectorID) + bf.Set(uint64(sector.SectorID)) enc, aerr := actors.SerializeParams(&actors.DeclareFaultsParams{bf}) if aerr != nil { diff --git a/storage/sealing/types.go b/storage/sealing/types.go index f0fbe09a4..ebec1ee1c 100644 --- a/storage/sealing/types.go +++ b/storage/sealing/types.go @@ -3,6 +3,7 @@ package sealing import ( sectorbuilder "github.com/filecoin-project/go-sectorbuilder" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/specs-actors/actors/abi" "github.com/ipfs/go-cid" ) @@ -18,12 +19,12 @@ func (t *SealTicket) SB() sectorbuilder.SealTicket { } type SealSeed struct { - BlockHeight uint64 + BlockHeight abi.ChainEpoch TicketBytes []byte } func (t *SealSeed) SB() sectorbuilder.SealSeed { - out := sectorbuilder.SealSeed{BlockHeight: t.BlockHeight} + out := sectorbuilder.SealSeed{BlockHeight: uint64(t.BlockHeight)} copy(out.TicketBytes[:], t.TicketBytes) return out } @@ -33,14 +34,14 @@ func (t *SealSeed) Equals(o *SealSeed) bool { } type Piece struct { - DealID uint64 + DealID abi.DealID - Size uint64 + Size abi.UnpaddedPieceSize CommP []byte } func (p *Piece) ppi() (out sectorbuilder.PublicPieceInfo) { - out.Size = p.Size + out.Size = uint64(p.Size) copy(out.CommP[:], p.CommP) return out } @@ -57,7 +58,7 @@ type Log struct { type SectorInfo struct { State api.SectorState - SectorID uint64 + SectorID abi.SectorNumber Nonce uint64 // TODO: remove // Packing @@ -95,16 +96,16 @@ func (t *SectorInfo) pieceInfos() []sectorbuilder.PublicPieceInfo { return out } -func (t *SectorInfo) deals() []uint64 { - out := make([]uint64, len(t.Pieces)) +func (t *SectorInfo) deals() []abi.DealID { + out := make([]abi.DealID, len(t.Pieces)) for i, piece := range t.Pieces { out[i] = piece.DealID } return out } -func (t *SectorInfo) existingPieces() []uint64 { - out := make([]uint64, len(t.Pieces)) +func (t *SectorInfo) existingPieces() []abi.UnpaddedPieceSize { + out := make([]abi.UnpaddedPieceSize, len(t.Pieces)) for i, piece := range t.Pieces { out[i] = piece.Size } diff --git a/storage/sealing/utils.go b/storage/sealing/utils.go index b2221b278..d03393405 100644 --- a/storage/sealing/utils.go +++ b/storage/sealing/utils.go @@ -6,12 +6,13 @@ import ( "math/rand" "sync" + "github.com/filecoin-project/specs-actors/actors/abi" "github.com/hashicorp/go-multierror" sectorbuilder "github.com/filecoin-project/go-sectorbuilder" ) -func fillersFromRem(toFill uint64) ([]uint64, error) { +func fillersFromRem(in abi.UnpaddedPieceSize) ([]abi.UnpaddedPieceSize, error) { // Convert to in-sector bytes for easier math: // // Sector size to user bytes ratio is constant, e.g. for 1024B we have 1016B @@ -24,13 +25,13 @@ func fillersFromRem(toFill uint64) ([]uint64, error) { // // (we convert to sector bytes as they are nice round binary numbers) - toFill += toFill / 127 + toFill := uint64(in + (in / 127)) // We need to fill the sector with pieces that are powers of 2. Conveniently // computers store numbers in binary, which means we can look at 1s to get // all the piece sizes we need to fill the sector. It also means that number // of pieces is the number of 1s in the number of remaining bytes to fill - out := make([]uint64, bits.OnesCount64(toFill)) + out := make([]abi.UnpaddedPieceSize, bits.OnesCount64(toFill)) for i := range out { // Extract the next lowest non-zero bit next := bits.TrailingZeros64(toFill) @@ -42,18 +43,18 @@ func fillersFromRem(toFill uint64) ([]uint64, error) { toFill ^= psize // Add the piece size to the list of pieces we need to create - out[i] = sectorbuilder.UserBytesForSectorSize(psize) + out[i] = abi.PaddedPieceSize(psize).Unpadded() } return out, nil } -func (m *Sealing) fastPledgeCommitment(size uint64, parts uint64) (commP [sectorbuilder.CommLen]byte, err error) { +func (m *Sealing) fastPledgeCommitment(size abi.UnpaddedPieceSize, parts uint64) (commP [sectorbuilder.CommLen]byte, err error) { parts = 1 << bits.Len64(parts) // round down to nearest power of 2 - if size/parts < 127 { - parts = size / 127 + if uint64(size)/parts < 127 { + parts = uint64(size) / 127 } - piece := sectorbuilder.UserBytesForSectorSize((size + size/127) / parts) + piece := abi.PaddedPieceSize(uint64(size.Padded()) / parts).Unpadded() out := make([]sectorbuilder.PublicPieceInfo, parts) var lk sync.Mutex @@ -70,7 +71,7 @@ func (m *Sealing) fastPledgeCommitment(size uint64, parts uint64) (commP [sector err = multierror.Append(err, perr) } out[i] = sectorbuilder.PublicPieceInfo{ - Size: piece, + Size: uint64(piece), CommP: commP, } lk.Unlock() diff --git a/storage/sectorblocks/blocks.go b/storage/sectorblocks/blocks.go index 363043dd0..0421ce989 100644 --- a/storage/sectorblocks/blocks.go +++ b/storage/sectorblocks/blocks.go @@ -9,6 +9,7 @@ import ( "sync" sectorbuilder "github.com/filecoin-project/go-sectorbuilder" + "github.com/filecoin-project/specs-actors/actors/abi" "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/namespace" "github.com/ipfs/go-datastore/query" @@ -32,9 +33,9 @@ var dsPrefix = datastore.NewKey("/sealedblocks") var ErrNotFound = errors.New("not found") -func DealIDToDsKey(dealID uint64) datastore.Key { +func DealIDToDsKey(dealID abi.DealID) datastore.Key { buf := make([]byte, binary.MaxVarintLen64) - size := binary.PutUvarint(buf, dealID) + size := binary.PutUvarint(buf, uint64(dealID)) return dshelp.NewKeyFromBinary(buf[:size]) } @@ -65,7 +66,7 @@ func NewSectorBlocks(miner *storage.Miner, ds dtypes.MetadataDS, sb sectorbuilde return sbc } -func (st *SectorBlocks) writeRef(dealID uint64, sectorID uint64, offset uint64, size uint64) error { +func (st *SectorBlocks) writeRef(dealID abi.DealID, sectorID abi.SectorNumber, offset uint64, size abi.UnpaddedPieceSize) error { st.keyLk.Lock() // TODO: make this multithreaded defer st.keyLk.Unlock() @@ -97,8 +98,7 @@ func (st *SectorBlocks) writeRef(dealID uint64, sectorID uint64, offset uint64, return st.keys.Put(DealIDToDsKey(dealID), newRef) // TODO: batch somehow } -func (st *SectorBlocks) AddPiece(ctx context.Context, size uint64, r io.Reader, dealID uint64) (sectorID uint64, err error) { - +func (st *SectorBlocks) AddPiece(ctx context.Context, size abi.UnpaddedPieceSize, r io.Reader, dealID abi.DealID) (sectorID abi.SectorNumber, err error) { sectorID, pieceOffset, err := st.Miner.AllocatePiece(padreader.PaddedSize(uint64(size))) if err != nil { return 0, err @@ -141,7 +141,7 @@ func (st *SectorBlocks) List() (map[uint64][]api.SealedRef, error) { return out, nil } -func (st *SectorBlocks) GetRefs(dealID uint64) ([]api.SealedRef, error) { // TODO: track local sectors +func (st *SectorBlocks) GetRefs(dealID abi.DealID) ([]api.SealedRef, error) { // TODO: track local sectors ent, err := st.keys.Get(DealIDToDsKey(dealID)) if err == datastore.ErrNotFound { err = ErrNotFound @@ -158,7 +158,7 @@ func (st *SectorBlocks) GetRefs(dealID uint64) ([]api.SealedRef, error) { // TOD return refs.Refs, nil } -func (st *SectorBlocks) GetSize(dealID uint64) (uint64, error) { +func (st *SectorBlocks) GetSize(dealID abi.DealID) (uint64, error) { refs, err := st.GetRefs(dealID) if err != nil { return 0, err @@ -167,7 +167,7 @@ func (st *SectorBlocks) GetSize(dealID uint64) (uint64, error) { return uint64(refs[0].Size), nil } -func (st *SectorBlocks) Has(dealID uint64) (bool, error) { +func (st *SectorBlocks) Has(dealID abi.DealID) (bool, error) { // TODO: ensure sector is still there return st.keys.Has(DealIDToDsKey(dealID)) }