diff --git a/api/api_full.go b/api/api_full.go index 4912c72be..9d6ae9a52 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -6,11 +6,16 @@ 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/filecoin-project/specs-actors/actors/builtin/miner" + "github.com/filecoin-project/specs-actors/actors/builtin/paych" + "github.com/filecoin-project/specs-actors/actors/crypto" "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,19 +24,21 @@ import ( type FullNode interface { Common + // TODO: TipSetKeys + // chain // ChainNotify returns channel with chain head updates // First message is guaranteed to be of len == 1, and type == 'current' ChainNotify(context.Context) (<-chan []*store.HeadChange, error) ChainHead(context.Context) (*types.TipSet, error) - ChainGetRandomness(context.Context, types.TipSetKey, int64) ([]byte, error) + ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) ChainGetBlock(context.Context, cid.Cid) (*types.BlockHeader, error) ChainGetTipSet(context.Context, types.TipSetKey) (*types.TipSet, error) 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.TipSetKey) (*types.TipSet, error) + ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error) ChainReadObj(context.Context, cid.Cid) ([]byte, error) ChainHasObj(context.Context, cid.Cid) (bool, error) ChainSetHead(context.Context, types.TipSetKey) error @@ -60,17 +67,17 @@ type FullNode interface { // miner - MinerCreateBlock(context.Context, address.Address, types.TipSetKey, *types.Ticket, *types.EPostProof, []*types.SignedMessage, uint64, uint64) (*types.BlockMsg, error) + MinerCreateBlock(context.Context, address.Address, types.TipSetKey, *types.Ticket, *types.EPostProof, []*types.SignedMessage, abi.ChainEpoch, uint64) (*types.BlockMsg, error) // // UX ? // wallet - WalletNew(context.Context, string) (address.Address, error) + WalletNew(context.Context, crypto.SigType) (address.Address, error) WalletHas(context.Context, address.Address) (bool, error) WalletList(context.Context) ([]address.Address, error) WalletBalance(context.Context, address.Address) (types.BigInt, error) - WalletSign(context.Context, address.Address, []byte) (*types.Signature, error) + WalletSign(context.Context, address.Address, []byte) (*crypto.Signature, error) WalletSignMessage(context.Context, address.Address, *types.Message) (*types.SignedMessage, error) WalletDefaultAddress(context.Context) (address.Address, error) WalletSetDefault(context.Context, address.Address) error @@ -87,7 +94,7 @@ type FullNode interface { ClientHasLocal(ctx context.Context, root cid.Cid) (bool, error) ClientFindData(ctx context.Context, root cid.Cid) ([]QueryOffer, error) ClientRetrieve(ctx context.Context, order RetrievalOrder, path string) error - ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*types.SignedStorageAsk, error) + ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.SignedStorageAsk, error) // ClientUnimport removes references to the specified file from filestore //ClientUnimport(path string) @@ -102,29 +109,29 @@ type FullNode interface { StateReplay(context.Context, types.TipSetKey, cid.Cid) (*ReplayResults, error) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) StateReadState(ctx context.Context, act *types.Actor, tsk types.TipSetKey) (*ActorState, error) - StateListMessages(ctx context.Context, match *types.Message, tsk types.TipSetKey, toht uint64) ([]cid.Cid, error) + StateListMessages(ctx context.Context, match *types.Message, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error) StateMinerSectors(context.Context, address.Address, types.TipSetKey) ([]*ChainSectorInfo, error) StateMinerProvingSet(context.Context, address.Address, types.TipSetKey) ([]*ChainSectorInfo, error) StateMinerPower(context.Context, address.Address, types.TipSetKey) (MinerPower, error) StateMinerWorker(context.Context, address.Address, types.TipSetKey) (address.Address, error) StateMinerPeerID(ctx context.Context, m address.Address, tsk types.TipSetKey) (peer.ID, error) - StateMinerElectionPeriodStart(ctx context.Context, actor address.Address, tsk types.TipSetKey) (uint64, error) - StateMinerSectorSize(context.Context, address.Address, types.TipSetKey) (uint64, error) - StateMinerFaults(context.Context, address.Address, types.TipSetKey) ([]uint64, error) + StateMinerPostState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*miner.PoStState, error) + StateMinerSectorSize(context.Context, address.Address, types.TipSetKey) (abi.SectorSize, error) + StateMinerFaults(context.Context, address.Address, types.TipSetKey) ([]abi.SectorNumber, error) StatePledgeCollateral(context.Context, types.TipSetKey) (types.BigInt, error) StateWaitMsg(context.Context, cid.Cid) (*MsgWait, error) StateListMiners(context.Context, types.TipSetKey) ([]address.Address, error) StateListActors(context.Context, types.TipSetKey) ([]address.Address, error) - StateMarketBalance(context.Context, address.Address, types.TipSetKey) (actors.StorageParticipantBalance, error) - StateMarketParticipants(context.Context, types.TipSetKey) (map[string]actors.StorageParticipantBalance, error) - StateMarketDeals(context.Context, types.TipSetKey) (map[string]actors.OnChainDeal, error) - StateMarketStorageDeal(context.Context, uint64, types.TipSetKey) (*actors.OnChainDeal, error) + StateMarketBalance(context.Context, address.Address, types.TipSetKey) (MarketBalance, error) + StateMarketParticipants(context.Context, types.TipSetKey) (map[string]MarketBalance, error) + StateMarketDeals(context.Context, types.TipSetKey) (map[string]MarketDeal, error) + StateMarketStorageDeal(context.Context, abi.DealID, types.TipSetKey) (*MarketDeal, error) StateLookupID(context.Context, address.Address, types.TipSetKey) (address.Address, error) StateChangedActors(context.Context, cid.Cid, cid.Cid) (map[string]types.Actor, error) StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) StateMinerSectorCount(context.Context, address.Address, types.TipSetKey) (MinerSectors, error) - StateCompute(context.Context, uint64, []*types.Message, types.TipSetKey) (cid.Cid, error) + StateCompute(context.Context, abi.ChainEpoch, []*types.Message, types.TipSetKey) (cid.Cid, error) MsigGetAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) @@ -137,12 +144,12 @@ type FullNode interface { PaychClose(context.Context, address.Address) (cid.Cid, error) PaychAllocateLane(ctx context.Context, ch address.Address) (uint64, error) PaychNewPayment(ctx context.Context, from, to address.Address, vouchers []VoucherSpec) (*PaymentInfo, error) - PaychVoucherCheckValid(context.Context, address.Address, *types.SignedVoucher) error - PaychVoucherCheckSpendable(context.Context, address.Address, *types.SignedVoucher, []byte, []byte) (bool, error) - PaychVoucherCreate(context.Context, address.Address, types.BigInt, uint64) (*types.SignedVoucher, error) - PaychVoucherAdd(context.Context, address.Address, *types.SignedVoucher, []byte, types.BigInt) (types.BigInt, error) - PaychVoucherList(context.Context, address.Address) ([]*types.SignedVoucher, error) - PaychVoucherSubmit(context.Context, address.Address, *types.SignedVoucher) (cid.Cid, error) + PaychVoucherCheckValid(context.Context, address.Address, *paych.SignedVoucher) error + PaychVoucherCheckSpendable(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (bool, error) + PaychVoucherCreate(context.Context, address.Address, types.BigInt, uint64) (*paych.SignedVoucher, error) + PaychVoucherAdd(context.Context, address.Address, *paych.SignedVoucher, []byte, types.BigInt) (types.BigInt, error) + PaychVoucherList(context.Context, address.Address) ([]*paych.SignedVoucher, error) + PaychVoucherSubmit(context.Context, address.Address, *paych.SignedVoucher) (cid.Cid, error) } type MinerSectors struct { @@ -187,9 +194,8 @@ type Message struct { } type ChainSectorInfo struct { - SectorID uint64 - CommD []byte - CommR []byte + Info miner.SectorOnChainInfo + ID abi.SectorNumber } type ActorState struct { @@ -218,15 +224,15 @@ type ChannelInfo struct { type PaymentInfo struct { Channel address.Address ChannelMessage *cid.Cid - Vouchers []*types.SignedVoucher + Vouchers []*paych.SignedVoucher } type VoucherSpec struct { - Amount types.BigInt - TimeLock uint64 - MinClose uint64 + Amount types.BigInt + TimeLock abi.ChainEpoch + MinSettle abi.ChainEpoch - Extra *types.ModVerifyParams + Extra *paych.ModVerifyParams } type MinerPower struct { @@ -261,6 +267,16 @@ func (o *QueryOffer) Order(client address.Address) RetrievalOrder { } } +type MarketBalance struct { + Escrow big.Int + Locked big.Int +} + +type MarketDeal struct { + Proposal market.DealProposal + State market.DealState +} + type RetrievalOrder struct { // TODO: make this less unixfs specific Root cid.Cid @@ -290,7 +306,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..81f3a33a0 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" ) @@ -86,20 +88,20 @@ type StorageMiner interface { ActorAddress(context.Context) (address.Address, error) - ActorSectorSize(context.Context, address.Address) (uint64, error) + ActorSectorSize(context.Context, address.Address) (abi.SectorSize, error) // Temp api for testing PledgeSector(context.Context) error // Get the status of a given sector by ID - SectorsStatus(context.Context, uint64) (SectorInfo, error) + SectorsStatus(context.Context, abi.SectorNumber) (SectorInfo, error) // List all staged sectors - SectorsList(context.Context) ([]uint64, error) + SectorsList(context.Context) ([]abi.SectorNumber, error) SectorsRefs(context.Context) (map[string][]SealedRef, error) - SectorsUpdate(context.Context, uint64, SectorState) error + SectorsUpdate(context.Context, abi.SectorNumber, SectorState) error WorkerStats(context.Context) (sectorbuilder.WorkerStats, error) @@ -119,12 +121,12 @@ type SectorLog struct { } type SectorInfo struct { - SectorID uint64 + SectorID abi.SectorNumber State SectorState CommD []byte CommR []byte Proof []byte - Deals []uint64 + Deals []abi.DealID Ticket sectorbuilder.SealTicket Seed sectorbuilder.SealSeed Retries uint64 @@ -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 52b862be9..c53619990 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -3,15 +3,20 @@ package apistruct import ( "context" - sectorbuilder "github.com/filecoin-project/go-sectorbuilder" - "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/go-fil-markets/storagemarket" + 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/miner" + "github.com/filecoin-project/specs-actors/actors/builtin/paych" + "github.com/filecoin-project/specs-actors/actors/crypto" + "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" ) @@ -44,24 +49,24 @@ type FullNodeStruct struct { CommonStruct Internal struct { - ChainNotify func(context.Context) (<-chan []*store.HeadChange, error) `perm:"read"` - ChainHead func(context.Context) (*types.TipSet, error) `perm:"read"` - ChainGetRandomness func(context.Context, types.TipSetKey, int64) ([]byte, error) `perm:"read"` - ChainGetBlock func(context.Context, cid.Cid) (*types.BlockHeader, error) `perm:"read"` - ChainGetTipSet func(context.Context, types.TipSetKey) (*types.TipSet, error) `perm:"read"` - 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.TipSetKey) (*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.TipSetKey) error `perm:"admin"` - ChainGetGenesis func(context.Context) (*types.TipSet, error) `perm:"read"` - ChainTipSetWeight func(context.Context, types.TipSetKey) (types.BigInt, error) `perm:"read"` - ChainGetNode func(ctx context.Context, p string) (interface{}, error) `perm:"read"` - ChainGetMessage func(context.Context, cid.Cid) (*types.Message, error) `perm:"read"` - ChainGetPath func(context.Context, types.TipSetKey, types.TipSetKey) ([]*store.HeadChange, error) `perm:"read"` - ChainExport func(context.Context, types.TipSetKey) (<-chan []byte, error) `perm:"read"` + ChainNotify func(context.Context) (<-chan []*store.HeadChange, error) `perm:"read"` + ChainHead func(context.Context) (*types.TipSet, error) `perm:"read"` + ChainGetRandomness func(context.Context, types.TipSetKey, crypto.DomainSeparationTag, abi.ChainEpoch, []byte) (abi.Randomness, error) `perm:"read"` + ChainGetBlock func(context.Context, cid.Cid) (*types.BlockHeader, error) `perm:"read"` + ChainGetTipSet func(context.Context, types.TipSetKey) (*types.TipSet, error) `perm:"read"` + 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, abi.ChainEpoch, types.TipSetKey) (*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.TipSetKey) error `perm:"admin"` + ChainGetGenesis func(context.Context) (*types.TipSet, error) `perm:"read"` + ChainTipSetWeight func(context.Context, types.TipSetKey) (types.BigInt, error) `perm:"read"` + ChainGetNode func(ctx context.Context, p string) (interface{}, error) `perm:"read"` + ChainGetMessage func(context.Context, cid.Cid) (*types.Message, error) `perm:"read"` + ChainGetPath func(context.Context, types.TipSetKey, types.TipSetKey) ([]*store.HeadChange, error) `perm:"read"` + ChainExport func(context.Context, types.TipSetKey) (<-chan []byte, error) `perm:"read"` SyncState func(context.Context) (*api.SyncState, error) `perm:"read"` SyncSubmitBlock func(ctx context.Context, blk *types.BlockMsg) error `perm:"write"` @@ -70,18 +75,18 @@ type FullNodeStruct struct { SyncCheckBad func(ctx context.Context, bcid cid.Cid) (string, error) `perm:"read"` MpoolPending func(context.Context, types.TipSetKey) ([]*types.SignedMessage, error) `perm:"read"` - MpoolPush func(context.Context, *types.SignedMessage) (cid.Cid, error) `perm:"write"` - MpoolPushMessage func(context.Context, *types.Message) (*types.SignedMessage, error) `perm:"sign"` - MpoolGetNonce func(context.Context, address.Address) (uint64, error) `perm:"read"` - MpoolSub func(context.Context) (<-chan api.MpoolUpdate, error) `perm:"read"` + MpoolPush func(context.Context, *types.SignedMessage) (cid.Cid, error) `perm:"write"` + MpoolPushMessage func(context.Context, *types.Message) (*types.SignedMessage, error) `perm:"sign"` + 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.TipSetKey, *types.Ticket, *types.EPostProof, []*types.SignedMessage, uint64, uint64) (*types.BlockMsg, error) `perm:"write"` + MinerCreateBlock func(context.Context, address.Address, types.TipSetKey, *types.Ticket, *types.EPostProof, []*types.SignedMessage, abi.ChainEpoch, uint64) (*types.BlockMsg, error) `perm:"write"` - WalletNew func(context.Context, string) (address.Address, error) `perm:"write"` + WalletNew func(context.Context, crypto.SigType) (address.Address, error) `perm:"write"` WalletHas func(context.Context, address.Address) (bool, error) `perm:"write"` WalletList func(context.Context) ([]address.Address, error) `perm:"write"` WalletBalance func(context.Context, address.Address) (types.BigInt, error) `perm:"read"` - WalletSign func(context.Context, address.Address, []byte) (*types.Signature, error) `perm:"sign"` + WalletSign func(context.Context, address.Address, []byte) (*crypto.Signature, error) `perm:"sign"` WalletSignMessage func(context.Context, address.Address, *types.Message) (*types.SignedMessage, error) `perm:"sign"` WalletDefaultAddress func(context.Context) (address.Address, error) `perm:"write"` WalletSetDefault func(context.Context, address.Address) error `perm:"admin"` @@ -96,34 +101,34 @@ type FullNodeStruct struct { ClientGetDealInfo func(context.Context, cid.Cid) (*api.DealInfo, error) `perm:"read"` ClientListDeals func(ctx context.Context) ([]api.DealInfo, error) `perm:"write"` ClientRetrieve func(ctx context.Context, order api.RetrievalOrder, path string) error `perm:"admin"` - ClientQueryAsk func(ctx context.Context, p peer.ID, miner address.Address) (*types.SignedStorageAsk, error) `perm:"read"` + ClientQueryAsk func(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.SignedStorageAsk, error) `perm:"read"` - StateMinerSectors func(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) `perm:"read"` - StateMinerProvingSet func(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) `perm:"read"` - StateMinerPower func(context.Context, address.Address, types.TipSetKey) (api.MinerPower, error) `perm:"read"` - StateMinerWorker func(context.Context, address.Address, types.TipSetKey) (address.Address, error) `perm:"read"` - StateMinerPeerID func(ctx context.Context, m address.Address, tsk types.TipSetKey) (peer.ID, error) `perm:"read"` - StateMinerElectionPeriodStart func(ctx context.Context, actor address.Address, tsk types.TipSetKey) (uint64, error) `perm:"read"` - StateMinerSectorSize func(context.Context, address.Address, types.TipSetKey) (uint64, error) `perm:"read"` - StateMinerFaults func(context.Context, address.Address, types.TipSetKey) ([]uint64, error) `perm:"read"` - StateCall func(context.Context, *types.Message, types.TipSetKey) (*api.MethodCall, error) `perm:"read"` - StateReplay func(context.Context, types.TipSetKey, cid.Cid) (*api.ReplayResults, error) `perm:"read"` - StateGetActor func(context.Context, address.Address, types.TipSetKey) (*types.Actor, error) `perm:"read"` - StateReadState func(context.Context, *types.Actor, types.TipSetKey) (*api.ActorState, error) `perm:"read"` - StatePledgeCollateral func(context.Context, types.TipSetKey) (types.BigInt, error) `perm:"read"` - StateWaitMsg func(context.Context, cid.Cid) (*api.MsgWait, error) `perm:"read"` - StateListMiners func(context.Context, types.TipSetKey) ([]address.Address, error) `perm:"read"` - StateListActors func(context.Context, types.TipSetKey) ([]address.Address, error) `perm:"read"` - StateMarketBalance func(context.Context, address.Address, types.TipSetKey) (actors.StorageParticipantBalance, error) `perm:"read"` - StateMarketParticipants func(context.Context, types.TipSetKey) (map[string]actors.StorageParticipantBalance, error) `perm:"read"` - StateMarketDeals func(context.Context, types.TipSetKey) (map[string]actors.OnChainDeal, error) `perm:"read"` - StateMarketStorageDeal func(context.Context, uint64, types.TipSetKey) (*actors.OnChainDeal, error) `perm:"read"` - StateLookupID func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (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.TipSetKey) (*types.MessageReceipt, error) `perm:"read"` - StateMinerSectorCount func(context.Context, address.Address, types.TipSetKey) (api.MinerSectors, error) `perm:"read"` - StateListMessages func(ctx context.Context, match *types.Message, tsk types.TipSetKey, toht uint64) ([]cid.Cid, error) `perm:"read"` - StateCompute func(context.Context, uint64, []*types.Message, types.TipSetKey) (cid.Cid, error) `perm:"read"` + StateMinerSectors func(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) `perm:"read"` + StateMinerProvingSet func(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) `perm:"read"` + StateMinerPower func(context.Context, address.Address, types.TipSetKey) (api.MinerPower, error) `perm:"read"` + StateMinerWorker func(context.Context, address.Address, types.TipSetKey) (address.Address, error) `perm:"read"` + StateMinerPeerID func(ctx context.Context, m address.Address, tsk types.TipSetKey) (peer.ID, error) `perm:"read"` + StateMinerPostState func(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*miner.PoStState, error) `perm:"read"` + StateMinerSectorSize func(context.Context, address.Address, types.TipSetKey) (abi.SectorSize, error) `perm:"read"` + StateMinerFaults func(context.Context, address.Address, types.TipSetKey) ([]abi.SectorNumber, error) `perm:"read"` + StateCall func(context.Context, *types.Message, types.TipSetKey) (*api.MethodCall, error) `perm:"read"` + StateReplay func(context.Context, types.TipSetKey, cid.Cid) (*api.ReplayResults, error) `perm:"read"` + StateGetActor func(context.Context, address.Address, types.TipSetKey) (*types.Actor, error) `perm:"read"` + StateReadState func(context.Context, *types.Actor, types.TipSetKey) (*api.ActorState, error) `perm:"read"` + StatePledgeCollateral func(context.Context, types.TipSetKey) (types.BigInt, error) `perm:"read"` + StateWaitMsg func(context.Context, cid.Cid) (*api.MsgWait, error) `perm:"read"` + StateListMiners func(context.Context, types.TipSetKey) ([]address.Address, error) `perm:"read"` + StateListActors func(context.Context, types.TipSetKey) ([]address.Address, error) `perm:"read"` + StateMarketBalance func(context.Context, address.Address, types.TipSetKey) (api.MarketBalance, error) `perm:"read"` + StateMarketParticipants func(context.Context, types.TipSetKey) (map[string]api.MarketBalance, error) `perm:"read"` + StateMarketDeals func(context.Context, types.TipSetKey) (map[string]api.MarketDeal, error) `perm:"read"` + StateMarketStorageDeal func(context.Context, abi.DealID, types.TipSetKey) (*api.MarketDeal, error) `perm:"read"` + StateLookupID func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (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.TipSetKey) (*types.MessageReceipt, error) `perm:"read"` + StateMinerSectorCount func(context.Context, address.Address, types.TipSetKey) (api.MinerSectors, error) `perm:"read"` + StateListMessages func(ctx context.Context, match *types.Message, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error) `perm:"read"` + StateCompute func(context.Context, abi.ChainEpoch, []*types.Message, types.TipSetKey) (cid.Cid, error) `perm:"read"` MsigGetAvailableBalance func(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) `perm:"read"` @@ -135,13 +140,13 @@ type FullNodeStruct struct { PaychClose func(context.Context, address.Address) (cid.Cid, error) `perm:"sign"` PaychAllocateLane func(context.Context, address.Address) (uint64, error) `perm:"sign"` PaychNewPayment func(ctx context.Context, from, to address.Address, vouchers []api.VoucherSpec) (*api.PaymentInfo, error) `perm:"sign"` - PaychVoucherCheck func(context.Context, *types.SignedVoucher) error `perm:"read"` - PaychVoucherCheckValid func(context.Context, address.Address, *types.SignedVoucher) error `perm:"read"` - PaychVoucherCheckSpendable func(context.Context, address.Address, *types.SignedVoucher, []byte, []byte) (bool, error) `perm:"read"` - PaychVoucherAdd func(context.Context, address.Address, *types.SignedVoucher, []byte, types.BigInt) (types.BigInt, error) `perm:"write"` - PaychVoucherCreate func(context.Context, address.Address, types.BigInt, uint64) (*types.SignedVoucher, error) `perm:"sign"` - PaychVoucherList func(context.Context, address.Address) ([]*types.SignedVoucher, error) `perm:"write"` - PaychVoucherSubmit func(context.Context, address.Address, *types.SignedVoucher) (cid.Cid, error) `perm:"sign"` + PaychVoucherCheck func(context.Context, *paych.SignedVoucher) error `perm:"read"` + PaychVoucherCheckValid func(context.Context, address.Address, *paych.SignedVoucher) error `perm:"read"` + PaychVoucherCheckSpendable func(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (bool, error) `perm:"read"` + PaychVoucherAdd func(context.Context, address.Address, *paych.SignedVoucher, []byte, types.BigInt) (types.BigInt, error) `perm:"write"` + PaychVoucherCreate func(context.Context, address.Address, big.Int, uint64) (*paych.SignedVoucher, error) `perm:"sign"` + PaychVoucherList func(context.Context, address.Address) ([]*paych.SignedVoucher, error) `perm:"write"` + PaychVoucherSubmit func(context.Context, address.Address, *paych.SignedVoucher) (cid.Cid, error) `perm:"sign"` } } @@ -153,15 +158,15 @@ type StorageMinerStruct struct { CommonStruct Internal struct { - ActorAddress func(context.Context) (address.Address, error) `perm:"read"` - ActorSectorSize func(context.Context, address.Address) (uint64, error) `perm:"read"` + ActorAddress func(context.Context) (address.Address, error) `perm:"read"` + ActorSectorSize func(context.Context, address.Address) (abi.SectorSize, error) `perm:"read"` PledgeSector func(context.Context) error `perm:"write"` - SectorsStatus func(context.Context, uint64) (api.SectorInfo, error) `perm:"read"` - SectorsList func(context.Context) ([]uint64, error) `perm:"read"` - SectorsRefs func(context.Context) (map[string][]api.SealedRef, error) `perm:"read"` - SectorsUpdate func(context.Context, uint64, api.SectorState) error `perm:"write"` + SectorsStatus func(context.Context, abi.SectorNumber) (api.SectorInfo, error) `perm:"read"` + SectorsList func(context.Context) ([]abi.SectorNumber, error) `perm:"read"` + SectorsRefs func(context.Context) (map[string][]api.SealedRef, error) `perm:"read"` + SectorsUpdate func(context.Context, abi.SectorNumber, api.SectorState) error `perm:"write"` WorkerStats func(context.Context) (sectorbuilder.WorkerStats, error) `perm:"read"` @@ -251,7 +256,7 @@ func (c *FullNodeStruct) ClientRetrieve(ctx context.Context, order api.Retrieval return c.Internal.ClientRetrieve(ctx, order, path) } -func (c *FullNodeStruct) ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*types.SignedStorageAsk, error) { +func (c *FullNodeStruct) ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.SignedStorageAsk, error) { return c.Internal.ClientQueryAsk(ctx, p, miner) } @@ -271,7 +276,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.TipSetKey, 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.TipSetKey, 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) } @@ -279,15 +284,15 @@ func (c *FullNodeStruct) ChainHead(ctx context.Context) (*types.TipSet, error) { return c.Internal.ChainHead(ctx) } -func (c *FullNodeStruct) ChainGetRandomness(ctx context.Context, pts types.TipSetKey, round int64) ([]byte, error) { - return c.Internal.ChainGetRandomness(ctx, pts, round) +func (c *FullNodeStruct) ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) { + return c.Internal.ChainGetRandomness(ctx, tsk, personalization, randEpoch, entropy) } -func (c *FullNodeStruct) ChainGetTipSetByHeight(ctx context.Context, h uint64, tsk types.TipSetKey) (*types.TipSet, error) { +func (c *FullNodeStruct) ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) (*types.TipSet, error) { return c.Internal.ChainGetTipSetByHeight(ctx, h, tsk) } -func (c *FullNodeStruct) WalletNew(ctx context.Context, typ string) (address.Address, error) { +func (c *FullNodeStruct) WalletNew(ctx context.Context, typ crypto.SigType) (address.Address, error) { return c.Internal.WalletNew(ctx, typ) } @@ -303,7 +308,7 @@ func (c *FullNodeStruct) WalletBalance(ctx context.Context, a address.Address) ( return c.Internal.WalletBalance(ctx, a) } -func (c *FullNodeStruct) WalletSign(ctx context.Context, k address.Address, msg []byte) (*types.Signature, error) { +func (c *FullNodeStruct) WalletSign(ctx context.Context, k address.Address, msg []byte) (*crypto.Signature, error) { return c.Internal.WalletSign(ctx, k, msg) } @@ -431,15 +436,15 @@ func (c *FullNodeStruct) StateMinerPeerID(ctx context.Context, m address.Address return c.Internal.StateMinerPeerID(ctx, m, tsk) } -func (c *FullNodeStruct) StateMinerElectionPeriodStart(ctx context.Context, actor address.Address, tsk types.TipSetKey) (uint64, error) { - return c.Internal.StateMinerElectionPeriodStart(ctx, actor, tsk) +func (c *FullNodeStruct) StateMinerPostState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*miner.PoStState, error) { + return c.Internal.StateMinerPostState(ctx, actor, tsk) } -func (c *FullNodeStruct) StateMinerSectorSize(ctx context.Context, actor address.Address, tsk types.TipSetKey) (uint64, error) { +func (c *FullNodeStruct) StateMinerSectorSize(ctx context.Context, actor address.Address, tsk types.TipSetKey) (abi.SectorSize, error) { return c.Internal.StateMinerSectorSize(ctx, actor, tsk) } -func (c *FullNodeStruct) StateMinerFaults(ctx context.Context, actor address.Address, tsk types.TipSetKey) ([]uint64, error) { +func (c *FullNodeStruct) StateMinerFaults(ctx context.Context, actor address.Address, tsk types.TipSetKey) ([]abi.SectorNumber, error) { return c.Internal.StateMinerFaults(ctx, actor, tsk) } @@ -474,19 +479,19 @@ func (c *FullNodeStruct) StateListActors(ctx context.Context, tsk types.TipSetKe return c.Internal.StateListActors(ctx, tsk) } -func (c *FullNodeStruct) StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (actors.StorageParticipantBalance, error) { +func (c *FullNodeStruct) StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MarketBalance, error) { return c.Internal.StateMarketBalance(ctx, addr, tsk) } -func (c *FullNodeStruct) StateMarketParticipants(ctx context.Context, tsk types.TipSetKey) (map[string]actors.StorageParticipantBalance, error) { +func (c *FullNodeStruct) StateMarketParticipants(ctx context.Context, tsk types.TipSetKey) (map[string]api.MarketBalance, error) { return c.Internal.StateMarketParticipants(ctx, tsk) } -func (c *FullNodeStruct) StateMarketDeals(ctx context.Context, tsk types.TipSetKey) (map[string]actors.OnChainDeal, error) { +func (c *FullNodeStruct) StateMarketDeals(ctx context.Context, tsk types.TipSetKey) (map[string]api.MarketDeal, error) { return c.Internal.StateMarketDeals(ctx, tsk) } -func (c *FullNodeStruct) StateMarketStorageDeal(ctx context.Context, dealid uint64, tsk types.TipSetKey) (*actors.OnChainDeal, error) { +func (c *FullNodeStruct) StateMarketStorageDeal(ctx context.Context, dealid abi.DealID, tsk types.TipSetKey) (*api.MarketDeal, error) { return c.Internal.StateMarketStorageDeal(ctx, dealid, tsk) } @@ -502,11 +507,11 @@ func (c *FullNodeStruct) StateGetReceipt(ctx context.Context, msg cid.Cid, tsk t return c.Internal.StateGetReceipt(ctx, msg, tsk) } -func (c *FullNodeStruct) StateListMessages(ctx context.Context, match *types.Message, tsk types.TipSetKey, toht uint64) ([]cid.Cid, error) { +func (c *FullNodeStruct) StateListMessages(ctx context.Context, match *types.Message, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error) { return c.Internal.StateListMessages(ctx, match, tsk, toht) } -func (c *FullNodeStruct) StateCompute(ctx context.Context, height uint64, msgs []*types.Message, tsk types.TipSetKey) (cid.Cid, error) { +func (c *FullNodeStruct) StateCompute(ctx context.Context, height abi.ChainEpoch, msgs []*types.Message, tsk types.TipSetKey) (cid.Cid, error) { return c.Internal.StateCompute(ctx, height, msgs, tsk) } @@ -530,23 +535,23 @@ func (c *FullNodeStruct) PaychStatus(ctx context.Context, pch address.Address) ( return c.Internal.PaychStatus(ctx, pch) } -func (c *FullNodeStruct) PaychVoucherCheckValid(ctx context.Context, addr address.Address, sv *types.SignedVoucher) error { +func (c *FullNodeStruct) PaychVoucherCheckValid(ctx context.Context, addr address.Address, sv *paych.SignedVoucher) error { return c.Internal.PaychVoucherCheckValid(ctx, addr, sv) } -func (c *FullNodeStruct) PaychVoucherCheckSpendable(ctx context.Context, addr address.Address, sv *types.SignedVoucher, secret []byte, proof []byte) (bool, error) { +func (c *FullNodeStruct) PaychVoucherCheckSpendable(ctx context.Context, addr address.Address, sv *paych.SignedVoucher, secret []byte, proof []byte) (bool, error) { return c.Internal.PaychVoucherCheckSpendable(ctx, addr, sv, secret, proof) } -func (c *FullNodeStruct) PaychVoucherAdd(ctx context.Context, addr address.Address, sv *types.SignedVoucher, proof []byte, minDelta types.BigInt) (types.BigInt, error) { +func (c *FullNodeStruct) PaychVoucherAdd(ctx context.Context, addr address.Address, sv *paych.SignedVoucher, proof []byte, minDelta types.BigInt) (types.BigInt, error) { return c.Internal.PaychVoucherAdd(ctx, addr, sv, proof, minDelta) } -func (c *FullNodeStruct) PaychVoucherCreate(ctx context.Context, pch address.Address, amt types.BigInt, lane uint64) (*types.SignedVoucher, error) { +func (c *FullNodeStruct) PaychVoucherCreate(ctx context.Context, pch address.Address, amt types.BigInt, lane uint64) (*paych.SignedVoucher, error) { return c.Internal.PaychVoucherCreate(ctx, pch, amt, lane) } -func (c *FullNodeStruct) PaychVoucherList(ctx context.Context, pch address.Address) ([]*types.SignedVoucher, error) { +func (c *FullNodeStruct) PaychVoucherList(ctx context.Context, pch address.Address) ([]*paych.SignedVoucher, error) { return c.Internal.PaychVoucherList(ctx, pch) } @@ -562,7 +567,7 @@ func (c *FullNodeStruct) PaychNewPayment(ctx context.Context, from, to address.A return c.Internal.PaychNewPayment(ctx, from, to, vouchers) } -func (c *FullNodeStruct) PaychVoucherSubmit(ctx context.Context, ch address.Address, sv *types.SignedVoucher) (cid.Cid, error) { +func (c *FullNodeStruct) PaychVoucherSubmit(ctx context.Context, ch address.Address, sv *paych.SignedVoucher) (cid.Cid, error) { return c.Internal.PaychVoucherSubmit(ctx, ch, sv) } @@ -570,7 +575,7 @@ func (c *StorageMinerStruct) ActorAddress(ctx context.Context) (address.Address, return c.Internal.ActorAddress(ctx) } -func (c *StorageMinerStruct) ActorSectorSize(ctx context.Context, addr address.Address) (uint64, error) { +func (c *StorageMinerStruct) ActorSectorSize(ctx context.Context, addr address.Address) (abi.SectorSize, error) { return c.Internal.ActorSectorSize(ctx, addr) } @@ -579,12 +584,12 @@ func (c *StorageMinerStruct) PledgeSector(ctx context.Context) error { } // Get the status of a given sector by ID -func (c *StorageMinerStruct) SectorsStatus(ctx context.Context, sid uint64) (api.SectorInfo, error) { +func (c *StorageMinerStruct) SectorsStatus(ctx context.Context, sid abi.SectorNumber) (api.SectorInfo, error) { return c.Internal.SectorsStatus(ctx, sid) } // List all staged sectors -func (c *StorageMinerStruct) SectorsList(ctx context.Context) ([]uint64, error) { +func (c *StorageMinerStruct) SectorsList(ctx context.Context) ([]abi.SectorNumber, error) { return c.Internal.SectorsList(ctx) } @@ -592,7 +597,7 @@ func (c *StorageMinerStruct) SectorsRefs(ctx context.Context) (map[string][]api. return c.Internal.SectorsRefs(ctx) } -func (c *StorageMinerStruct) SectorsUpdate(ctx context.Context, id uint64, state api.SectorState) error { +func (c *StorageMinerStruct) SectorsUpdate(ctx context.Context, id abi.SectorNumber, state api.SectorState) error { return c.Internal.SectorsUpdate(ctx, id, state) } diff --git a/api/cbor_gen.go b/api/cbor_gen.go index c9c9cac5a..71c551ebe 100644 --- a/api/cbor_gen.go +++ b/api/cbor_gen.go @@ -6,7 +6,8 @@ import ( "fmt" "io" - "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin/paych" cbg "github.com/whyrusleeping/cbor-gen" xerrors "golang.org/x/xerrors" ) @@ -60,7 +61,7 @@ func (t *PaymentInfo) MarshalCBOR(w io.Writer) error { } } - // t.Vouchers ([]*types.SignedVoucher) (slice) + // t.Vouchers ([]*paych.SignedVoucher) (slice) if len("Vouchers") > cbg.MaxLength { return xerrors.Errorf("Value in field \"Vouchers\" was too long") } @@ -152,7 +153,7 @@ func (t *PaymentInfo) UnmarshalCBOR(r io.Reader) error { } } - // t.Vouchers ([]*types.SignedVoucher) (slice) + // t.Vouchers ([]*paych.SignedVoucher) (slice) case "Vouchers": maj, extra, err = cbg.CborReadHeader(br) @@ -168,11 +169,11 @@ func (t *PaymentInfo) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("expected cbor array") } if extra > 0 { - t.Vouchers = make([]*types.SignedVoucher, extra) + t.Vouchers = make([]*paych.SignedVoucher, extra) } for i := 0; i < int(extra); i++ { - var v types.SignedVoucher + var v paych.SignedVoucher if err := v.UnmarshalCBOR(br); err != nil { return err } @@ -196,7 +197,7 @@ func (t *SealedRef) MarshalCBOR(w io.Writer) error { return err } - // t.SectorID (uint64) (uint64) + // t.SectorID (abi.SectorNumber) (uint64) if len("SectorID") > cbg.MaxLength { return xerrors.Errorf("Value in field \"SectorID\" was too long") } @@ -228,7 +229,7 @@ func (t *SealedRef) MarshalCBOR(w io.Writer) error { return err } - // t.Size (uint64) (uint64) + // t.Size (abi.UnpaddedPieceSize) (uint64) if len("Size") > cbg.MaxLength { return xerrors.Errorf("Value in field \"Size\" was too long") } @@ -243,6 +244,7 @@ func (t *SealedRef) MarshalCBOR(w io.Writer) error { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Size))); err != nil { return err } + return nil } @@ -276,39 +278,51 @@ func (t *SealedRef) UnmarshalCBOR(r io.Reader) error { } switch name { - // t.SectorID (uint64) (uint64) + // t.SectorID (abi.SectorNumber) (uint64) case "SectorID": - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err + { + + 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 = abi.SectorNumber(extra) + } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.SectorID = uint64(extra) // t.Offset (uint64) (uint64) case "Offset": - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err + { + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.Offset = uint64(extra) + } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.Offset = uint64(extra) - // t.Size (uint64) (uint64) + // t.Size (abi.UnpaddedPieceSize) (uint64) case "Size": - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err + { + + 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 = abi.UnpaddedPieceSize(extra) + } - 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/api/test/deals.go b/api/test/deals.go index 8ddbb0cbe..82bf85235 100644 --- a/api/test/deals.go +++ b/api/test/deals.go @@ -74,9 +74,9 @@ func TestDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration) { if err != nil { t.Fatal(err) } - deal, err := client.ClientStartDeal(ctx, fcid, addr, maddr, types.NewInt(40000000), 100) + deal, err := client.ClientStartDeal(ctx, fcid, addr, maddr, types.NewInt(1000000), 100) if err != nil { - t.Fatal(err) + t.Fatalf("%+v", err) } // TODO: this sleep is only necessary because deals don't immediately get logged in the dealstore, we should fix this diff --git a/api/utils.go b/api/utils.go index 0576ad1d4..13d5c92cb 100644 --- a/api/utils.go +++ b/api/utils.go @@ -4,12 +4,12 @@ import ( "context" "github.com/filecoin-project/go-address" - "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/specs-actors/actors/crypto" ) -type SignFunc = func(context.Context, []byte) (*types.Signature, error) +type SignFunc = func(context.Context, []byte) (*crypto.Signature, error) -type Signer func(context.Context, address.Address, []byte) (*types.Signature, error) +type Signer func(context.Context, address.Address, []byte) (*crypto.Signature, error) type Signable interface { Sign(context.Context, SignFunc) error @@ -17,7 +17,7 @@ type Signable interface { func SignWith(ctx context.Context, signer Signer, addr address.Address, signable ...Signable) error { for _, s := range signable { - err := s.Sign(ctx, func(ctx context.Context, b []byte) (*types.Signature, error) { + err := s.Sign(ctx, func(ctx context.Context, b []byte) (*crypto.Signature, error) { return signer(ctx, addr, b) }) if err != nil { diff --git a/bin/dist_get b/bin/dist_get deleted file mode 100755 index 39320443a..000000000 --- a/bin/dist_get +++ /dev/null @@ -1,177 +0,0 @@ -#!/bin/sh - -GOCC=${GOCC=go} - -die() { - echo "$@" >&2 - exit 1 -} - -have_binary() { - type "$1" > /dev/null 2> /dev/null -} - -check_writable() { - printf "" > "$1" && rm "$1" -} - -try_download() { - url="$1" - output="$2" - command="$3" - util_name="$(set -- $command; echo "$1")" - - if ! have_binary "$util_name"; then - return 1 - fi - - printf '==> Using %s to download "%s" to "%s"\n' "$util_name" "$url" "$output" - if eval "$command"; then - echo "==> Download complete!" - return - else - echo "error: couldn't download with $util_name ($?)" - return 1 - fi -} - -download() { - dl_url="$1" - dl_output="$2" - - test "$#" -eq "2" || die "download requires exactly two arguments, was given $@" - - if ! check_writable "$dl_output"; then - die "download error: cannot write to $dl_output" - fi - - try_download "$dl_url" "$dl_output" "wget '$dl_url' -O '$dl_output'" && return - try_download "$dl_url" "$dl_output" "curl --silent --fail --output '$dl_output' '$dl_url'" && return - try_download "$dl_url" "$dl_output" "fetch '$dl_url' -o '$dl_output'" && return - try_download "$dl_url" "$dl_output" "http '$dl_url' > '$dl_output'" && return - try_download "$dl_url" "$dl_output" "ftp -o '$dl_output' '$dl_url'" && return - - die "Unable to download $dl_url. exiting." -} - -unarchive() { - ua_archivetype="$1" - ua_infile="$2" - ua_outfile="$3" - ua_distname="$4" - ua_binpostfix="" - ua_os=$(uname -o) - - if [ "$ua_os" = "Msys" ] || [ "$ua_os" = "Cygwin" ] ; then - ua_binpostfix=".exe" - fi - ua_outfile="$ua_outfile$ua_binpostfix" - - if ! check_writable "$ua_outfile"; then - die "unarchive error: cannot write to $ua_outfile" - fi - - case "$ua_archivetype" in - tar.gz) - if have_binary tar; then - echo "==> using 'tar' to extract binary from archive" - < "$ua_infile" tar -Ozxf - "$ua_distname/$ua_distname$ua_binpostfix" > "$ua_outfile" \ - || die "tar has failed" - else - die "no binary on system for extracting tar files" - fi - ;; - zip) - if have_binary unzip; then - echo "==> using 'unzip' to extract binary from archive" - unzip -p "$ua_infile" "$ua_distname/$ua_distname$ua_binpostfix" > "$ua_outfile" \ - || die "unzip has failed" - else - die "no installed method for extracting .zip archives" - fi - ;; - *) - die "unrecognized archive type '$ua_archivetype'" - esac - - chmod +x "$ua_outfile" || die "chmod has failed" -} - -get_go_vars() { - if [ ! -z "$GOOS" ] && [ ! -z "$GOARCH" ]; then - printf "%s-%s" "$GOOS" "$GOARCH" - elif have_binary go; then - printf "%s-%s" "$($GOCC env GOOS)" "$($GOCC env GOARCH)" - else - die "no way of determining system GOOS and GOARCH\nPlease manually set GOOS and GOARCH then retry." - fi -} - -mkurl() { - m_root="$1" - m_name="$2" - m_vers="$3" - m_archive="$4" - m_govars=$(get_go_vars) || die "could not get go env vars" - - echo "https://ipfs.io$m_root/$m_name/$m_vers/${m_name}_${m_vers}_$m_govars.$m_archive" -} - -distroot="$1" -distname="$2" -outpath="$3" -version="$4" - -if [ -z "$distroot" ] || [ -z "$distname" ] || [ -z "$outpath" ] || [ -z "$version" ]; then - die "usage: dist_get " -fi - -case $version in - v*) - # correct input - ;; - *) - echo "invalid version '$version'" >&2 - die "versions must begin with 'v', for example: v0.4.0" - ;; -esac - -# TODO: don't depend on the go tool being installed to detect this -goenv=$(get_go_vars) || die "could not get go env vars" - -case $goenv in - linux-*) - archive="tar.gz" - ;; - darwin-*) - archive="tar.gz" - ;; - windows-*) - archive="zip" - ;; - freebsd-*) - archive="tar.gz" - ;; - openbsd-*) - archive="tar.gz" - ;; - *) - echo "unrecognized system environment: $goenv" >&2 - die "currently only linux, darwin, windows and freebsd are supported by this script" -esac - - -mkdir -p bin/tmp - -url=$(mkurl "$distroot" "$distname" "$version" "$archive") -tmpfi="bin/tmp/$distname.$archive" - -download "$url" "$tmpfi" -if [ $? -ne 0 ]; then - die "failed to download $url to $tmpfi" -fi - -unarchive "$archive" "$tmpfi" "$outpath" "$distname" -if [ $? -ne 0 ]; then - die "failed to extract archive $tmpfi" -fi diff --git a/build/params_debug.go b/build/params_debug.go index 2b0c8e22b..ac9efbbe6 100644 --- a/build/params_debug.go +++ b/build/params_debug.go @@ -2,11 +2,15 @@ package build +import ( + "github.com/filecoin-project/specs-actors/actors/abi" +) + func init() { InsecurePoStValidation = true } -var SectorSizes = []uint64{1024} +var SectorSizes = []abi.SectorSize{1024} // Seconds const BlockDelay = 6 diff --git a/build/params_shared.go b/build/params_shared.go index ad23b314a..b202c5925 100644 --- a/build/params_shared.go +++ b/build/params_shared.go @@ -2,6 +2,8 @@ package build import ( "math/big" + + "github.com/filecoin-project/specs-actors/actors/abi" ) // Core network constants @@ -12,7 +14,7 @@ import ( const UnixfsChunkSize uint64 = 1 << 20 const UnixfsLinksPerLevel = 1024 -func SupportedSectorSize(ssize uint64) bool { +func SupportedSectorSize(ssize abi.SectorSize) bool { for _, ss := range SectorSizes { if ssize == ss { return true diff --git a/build/params_testnet.go b/build/params_testnet.go index 016109770..17c2bf5ed 100644 --- a/build/params_testnet.go +++ b/build/params_testnet.go @@ -2,7 +2,12 @@ package build -var SectorSizes = []uint64{ +import ( + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin/miner" +) + +var SectorSizes = []abi.SectorSize{ 32 << 30, } @@ -15,16 +20,13 @@ const PropagationDelay = 6 // ElectionPeriodStart before starting fallback post computation // // Epochs -const FallbackPoStDelay = 30 +const FallbackPoStDelay = miner.ProvingPeriod // SlashablePowerDelay is the number of epochs after ElectionPeriodStart, after // which the miner is slashed // // Epochs -const SlashablePowerDelay = 200 - -// Epochs -const InteractivePoRepDelay = 8 +const SlashablePowerDelay = miner.ProvingPeriod * 3 // TODO: remove // Epochs const InteractivePoRepConfidence = 6 diff --git a/build/version.go b/build/version.go index 789edf1fc..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.8" +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_cron.go b/chain/actors/actor_cron.go deleted file mode 100644 index f0be6a439..000000000 --- a/chain/actors/actor_cron.go +++ /dev/null @@ -1,48 +0,0 @@ -package actors - -import ( - "github.com/filecoin-project/go-address" - "github.com/filecoin-project/lotus/chain/actors/aerrors" - "github.com/filecoin-project/lotus/chain/types" -) - -type CronActor struct{} - -type callTuple struct { - addr address.Address - method uint64 -} - -var CronActors = []callTuple{ - {StoragePowerAddress, SPAMethods.CheckProofSubmissions}, -} - -type CronActorState struct{} - -type cAMethods struct { - EpochTick uint64 -} - -var CAMethods = cAMethods{2} - -func (ca CronActor) Exports() []interface{} { - return []interface{}{ - 1: nil, - 2: ca.EpochTick, - } -} - -func (ca CronActor) EpochTick(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) { - if vmctx.Message().From != CronAddress { - return nil, aerrors.New(1, "EpochTick is only callable as a part of tipset state computation") - } - - for _, call := range CronActors { - _, err := vmctx.Send(call.addr, call.method, types.NewInt(0), nil) - if err != nil { - return nil, err // todo: this very bad? - } - } - - return nil, nil -} diff --git a/chain/actors/actor_init.go b/chain/actors/actor_init.go deleted file mode 100644 index f7c2fb6d4..000000000 --- a/chain/actors/actor_init.go +++ /dev/null @@ -1,239 +0,0 @@ -package actors - -import ( - "bytes" - "context" - "encoding/binary" - "fmt" - - "github.com/filecoin-project/go-address" - "github.com/filecoin-project/lotus/chain/actors/aerrors" - "github.com/filecoin-project/lotus/chain/types" - cbg "github.com/whyrusleeping/cbor-gen" - "golang.org/x/xerrors" - - "github.com/ipfs/go-cid" - "github.com/ipfs/go-hamt-ipld" - cbor "github.com/ipfs/go-ipld-cbor" - logging "github.com/ipfs/go-log/v2" - mh "github.com/multiformats/go-multihash" -) - -var log = logging.Logger("actors") - -var EmptyCBOR cid.Cid - -const ( - GasCreateActor = 100 -) - -var BuiltInActors map[cid.Cid]bool - -func init() { - - n, err := cbor.WrapObject(map[string]string{}, mh.SHA2_256, -1) - if err != nil { - panic(err) // ok - } - - EmptyCBOR = n.Cid() -} - -type InitActor struct{} - -type InitActorState struct { - AddressMap cid.Cid - - NextID uint64 -} - -type iAMethods struct { - Exec uint64 -} - -var IAMethods = iAMethods{2} - -func (ia InitActor) Exports() []interface{} { - return []interface{}{ - 1: nil, - 2: ia.Exec, - } -} - -type ExecParams struct { - Code cid.Cid - Params []byte -} - -func CreateExecParams(act cid.Cid, obj cbg.CBORMarshaler) ([]byte, aerrors.ActorError) { - encparams, err := SerializeParams(obj) - if err != nil { - return nil, aerrors.Wrap(err, "creating ExecParams") - } - - return SerializeParams(&ExecParams{ - Code: act, - Params: encparams, - }) -} - -func (ia InitActor) Exec(act *types.Actor, vmctx types.VMContext, p *ExecParams) ([]byte, aerrors.ActorError) { - beginState := vmctx.Storage().GetHead() - - var self InitActorState - if err := vmctx.Storage().Get(beginState, &self); err != nil { - return nil, err - } - - if err := vmctx.ChargeGas(GasCreateActor); err != nil { - return nil, aerrors.Wrap(err, "run out of gas") - } - - // Make sure that only the actors defined in the spec can be launched. - if !IsBuiltinActor(p.Code) { - return nil, aerrors.New(1, - "cannot launch actor instance that is not a builtin actor") - } - - // Ensure that singletons can be only launched once. - // TODO: do we want to enforce this? If so how should actors be marked as such? - if IsSingletonActor(p.Code) { - return nil, aerrors.New(1, "cannot launch another actor of this type") - } - - // This generates a unique address for this actor that is stable across message - // reordering - creator := vmctx.Message().From - nonce := vmctx.Message().Nonce - addr, err := ComputeActorAddress(creator, nonce) - if err != nil { - return nil, err - } - - // Set up the actor itself - actor := types.Actor{ - Code: p.Code, - Balance: types.NewInt(0), - Head: EmptyCBOR, - Nonce: 0, - } - - // The call to the actors constructor will set up the initial state - // from the given parameters, setting `actor.Head` to a new value when successful. - // TODO: can constructors fail? - //actor.Constructor(p.Params) - - // Store the mapping of address to actor ID. - idAddr, nerr := self.AddActor(vmctx.Ipld(), addr) - if nerr != nil { - return nil, aerrors.Escalate(err, "adding new actor mapping") - } - - // NOTE: This is a privileged call that only the init actor is allowed to make - // FIXME: Had to comment this because state is not in interface - state, err := vmctx.StateTree() - if err != nil { - return nil, err - } - - if err := state.SetActor(idAddr, &actor); err != nil { - if xerrors.Is(err, types.ErrActorNotFound) { - return nil, aerrors.Absorb(err, 1, "SetActor, actor not found") - } - return nil, aerrors.Escalate(err, "inserting new actor into state tree") - } - - // '1' is reserved for constructor methods - _, err = vmctx.Send(idAddr, 1, vmctx.Message().Value, p.Params) - if err != nil { - return nil, err - } - - c, err := vmctx.Storage().Put(&self) - if err != nil { - return nil, err - } - - if err := vmctx.Storage().Commit(beginState, c); err != nil { - return nil, err - } - - return idAddr.Bytes(), nil -} - -func IsBuiltinActor(code cid.Cid) bool { - return BuiltInActors[code] -} - -func IsSingletonActor(code cid.Cid) bool { - return code == StoragePowerCodeCid || code == StorageMarketCodeCid || code == InitCodeCid || code == CronCodeCid -} - -func (ias *InitActorState) AddActor(cst cbor.IpldStore, addr address.Address) (address.Address, error) { - nid := ias.NextID - - amap, err := hamt.LoadNode(context.TODO(), cst, ias.AddressMap) - if err != nil { - return address.Undef, err - } - - if err := amap.Set(context.TODO(), string(addr.Bytes()), nid); err != nil { - return address.Undef, err - } - - if err := amap.Flush(context.TODO()); err != nil { - return address.Undef, err - } - - ncid, err := cst.Put(context.TODO(), amap) - if err != nil { - return address.Undef, err - } - ias.AddressMap = ncid - ias.NextID++ - - return NewIDAddress(nid) -} - -func (ias *InitActorState) Lookup(cst cbor.IpldStore, addr address.Address) (address.Address, error) { - amap, err := hamt.LoadNode(context.TODO(), cst, ias.AddressMap) - if err != nil { - return address.Undef, xerrors.Errorf("ias lookup failed loading hamt node: %w", err) - } - - var val interface{} - err = amap.Find(context.TODO(), string(addr.Bytes()), &val) - if err != nil { - return address.Undef, xerrors.Errorf("ias lookup failed to do find: %w", err) - } - - ival, ok := val.(uint64) - if !ok { - return address.Undef, fmt.Errorf("invalid value in init actor state, expected uint64, got %T", val) - } - - return address.NewIDAddress(ival) -} - -type AccountActorState struct { - Address address.Address -} - -func ComputeActorAddress(creator address.Address, nonce uint64) (address.Address, ActorError) { - buf := new(bytes.Buffer) - _, err := buf.Write(creator.Bytes()) - if err != nil { - return address.Undef, aerrors.Escalate(err, "could not write address") - } - - err = binary.Write(buf, binary.BigEndian, nonce) - if err != nil { - return address.Undef, aerrors.Escalate(err, "could not write nonce") - } - - addr, err := address.NewActorAddress(buf.Bytes()) - if err != nil { - return address.Undef, aerrors.Escalate(err, "could not create address") - } - return addr, nil -} diff --git a/chain/actors/actor_miner.go b/chain/actors/actor_miner.go deleted file mode 100644 index 4f102f092..000000000 --- a/chain/actors/actor_miner.go +++ /dev/null @@ -1,1156 +0,0 @@ -package actors - -import ( - "bytes" - "context" - "encoding/binary" - "fmt" - - "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/libp2p/go-libp2p-core/peer" - - "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/ipfs/go-cid" - cbor "github.com/ipfs/go-ipld-cbor" - cbg "github.com/whyrusleeping/cbor-gen" - "golang.org/x/xerrors" -) - -type StorageMinerActor struct{} - -func (sma StorageMinerActor) Exports() []interface{} { - return []interface{}{ - 1: sma.StorageMinerConstructor, - 2: sma.PreCommitSector, - 3: sma.ProveCommitSector, - 4: sma.SubmitFallbackPoSt, - //5: sma.SlashStorageFault, - //6: sma.GetCurrentProvingSet, - //7: sma.ArbitrateDeal, - //8: sma.DePledge, - 9: sma.GetOwner, - 10: sma.GetWorkerAddr, - 11: sma.GetPower, - 12: sma.GetPeerID, - 13: sma.GetSectorSize, - 14: sma.UpdatePeerID, - //15: sma.ChangeWorker, - 16: sma.IsSlashed, - 17: sma.CheckMiner, - 18: sma.DeclareFaults, - 19: sma.SlashConsensusFault, - 20: sma.SubmitElectionPoSt, - } -} - -type StorageMinerActorState struct { - // PreCommittedSectors is the set of sectors that have been committed to but not - // yet had their proofs submitted - PreCommittedSectors map[string]*PreCommittedSector - - // All sectors this miner has committed. - // - // AMT[sectorID]ffi.PublicSectorInfo - Sectors cid.Cid - - // TODO: Spec says 'StagedCommittedSectors', which one is it? - - // Sectors this miner is currently mining. It is only updated - // when a PoSt is submitted (not as each new sector commitment is added). - // - // AMT[sectorID]ffi.PublicSectorInfo - ProvingSet cid.Cid - - // TODO: these: - // SectorTable - // SectorExpirationQueue - // ChallengeStatus - - // Contains mostly static info about this miner - Info cid.Cid - - // Faulty sectors reported since last SubmitPost - FaultSet types.BitField - - LastFaultSubmission uint64 - - // Amount of power this miner has. - Power types.BigInt - - // Active is set to true after the miner has submitted their first PoSt - Active bool - - // The height at which this miner was slashed at. - SlashedAt uint64 - - ElectionPeriodStart uint64 -} - -type MinerInfo struct { - // Account that owns this miner. - // - Income and returned collateral are paid to this address. - // - This address is also allowed to change the worker address for the miner. - Owner address.Address - - // Worker account for this miner. - // This will be the key that is used to sign blocks created by this miner, and - // sign messages sent on behalf of this miner to commit sectors, submit PoSts, and - // other day to day miner activities. - Worker address.Address - - // Libp2p identity that should be used when connecting to this miner. - PeerID peer.ID - - // Amount of space in each sector committed to the network by this miner. - SectorSize uint64 - - // SubsectorCount -} - -type PreCommittedSector struct { - Info SectorPreCommitInfo - ReceivedEpoch uint64 -} - -type StorageMinerConstructorParams struct { - Owner address.Address - Worker address.Address - SectorSize uint64 - PeerID peer.ID -} - -type SectorPreCommitInfo struct { - SectorNumber uint64 - - CommR []byte // TODO: Spec says CID - SealEpoch uint64 - DealIDs []uint64 -} - -type maMethods struct { - Constructor uint64 - PreCommitSector uint64 - ProveCommitSector uint64 - SubmitFallbackPoSt uint64 - SlashStorageFault uint64 - GetCurrentProvingSet uint64 - ArbitrateDeal uint64 - DePledge uint64 - GetOwner uint64 - GetWorkerAddr uint64 - GetPower uint64 - GetPeerID uint64 - GetSectorSize uint64 - UpdatePeerID uint64 - ChangeWorker uint64 - IsSlashed uint64 - CheckMiner uint64 - DeclareFaults uint64 - SlashConsensusFault uint64 - SubmitElectionPoSt uint64 -} - -var MAMethods = maMethods{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20} - -func (sma StorageMinerActor) StorageMinerConstructor(act *types.Actor, vmctx types.VMContext, params *StorageMinerConstructorParams) ([]byte, ActorError) { - minerInfo := &MinerInfo{ - Owner: params.Owner, - Worker: params.Worker, - PeerID: params.PeerID, - SectorSize: params.SectorSize, - } - - minfocid, err := vmctx.Storage().Put(minerInfo) - if err != nil { - return nil, err - } - - var self StorageMinerActorState - sectors := amt2.NewAMT(vmctx.Ipld()) - scid, serr := sectors.Flush(context.TODO()) - if serr != nil { - return nil, aerrors.HandleExternalError(serr, "initializing AMT") - } - - self.Sectors = scid - self.ProvingSet = scid - self.Info = minfocid - - storage := vmctx.Storage() - c, err := storage.Put(&self) - if err != nil { - return nil, err - } - - if err := storage.Commit(EmptyCBOR, c); err != nil { - return nil, err - } - - return nil, nil -} - -func (sma StorageMinerActor) PreCommitSector(act *types.Actor, vmctx types.VMContext, params *SectorPreCommitInfo) ([]byte, ActorError) { - - ctx := vmctx.Context() - oldstate, self, err := loadState(vmctx) - if err != nil { - return nil, err - } - - if params.SealEpoch >= 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) - } - - mi, err := loadMinerInfo(vmctx, self) - if err != nil { - return nil, err - } - - if vmctx.Message().From != mi.Worker { - return nil, aerrors.New(1, "not authorized to precommit sector for miner") - } - - // make sure the miner isnt trying to submit a pre-existing sector - unique, err := SectorIsUnique(ctx, vmctx.Ipld(), self.Sectors, params.SectorNumber) - if err != nil { - return nil, err - } - if !unique { - return nil, aerrors.New(3, "sector already committed!") - } - - // Power of the miner after adding this sector - futurePower := types.BigAdd(self.Power, types.NewInt(mi.SectorSize)) - collateralRequired := CollateralForPower(futurePower) - - // TODO: grab from market? - if act.Balance.LessThan(collateralRequired) { - return nil, aerrors.New(4, "not enough collateral") - } - - self.PreCommittedSectors[uintToStringKey(params.SectorNumber)] = &PreCommittedSector{ - Info: *params, - ReceivedEpoch: vmctx.BlockHeight(), - } - - if len(self.PreCommittedSectors) > 4096 { - return nil, aerrors.New(5, "too many precommitted sectors") - } - - nstate, err := vmctx.Storage().Put(self) - if err != nil { - return nil, err - } - if err := vmctx.Storage().Commit(oldstate, nstate); err != nil { - return nil, err - } - - return nil, nil -} - -func (sma StorageMinerActor) ProveCommitSector(act *types.Actor, vmctx types.VMContext, params *SectorProveCommitInfo) ([]byte, ActorError) { - ctx := vmctx.Context() - oldstate, self, err := loadState(vmctx) - if err != nil { - return nil, err - } - - mi, err := loadMinerInfo(vmctx, self) - if err != nil { - return nil, err - } - - if vmctx.Message().From != mi.Worker { - return nil, aerrors.New(1, "not authorized to submit sector proof for miner") - } - - us, ok := self.PreCommittedSectors[uintToStringKey(params.SectorID)] - if !ok { - return nil, aerrors.New(1, "no pre-commitment found for sector") - } - - if us.ReceivedEpoch+build.InteractivePoRepDelay >= vmctx.BlockHeight() { - return nil, aerrors.New(2, "too early for proof submission") - } - - delete(self.PreCommittedSectors, uintToStringKey(params.SectorID)) - - // TODO: ensure normalization to ID address - maddr := vmctx.Message().To - - if 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 { - 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) - if err != nil { - return nil, aerrors.Wrap(err, "failed to get ticket randomness") - } - - seed, err := vmctx.GetRandomness(us.ReceivedEpoch + build.InteractivePoRepDelay) - 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, - }) - if err != nil { - return nil, aerrors.Wrap(err, "failed to serialize ComputeDataCommitmentParams") - } - - commD, err := vmctx.Send(StorageMarketAddress, SMAMethods.ComputeDataCommitment, types.NewInt(0), enc) - if err != nil { - return nil, aerrors.Wrapf(err, "failed to compute data commitment (sector %d, deals: %v)", params.SectorID, params.DealIDs) - } - - if ok, err := vmctx.Sys().ValidatePoRep(ctx, maddr, mi.SectorSize, commD, us.Info.CommR, ticket, params.Proof, seed, params.SectorID); err != nil { - return nil, err - } else if !ok { - return nil, aerrors.Newf(2, "porep proof was invalid (t:%x; s:%x(%d); p:%s)", ticket, seed, us.ReceivedEpoch+build.InteractivePoRepDelay, truncateHexPrint(params.Proof)) - } - - // 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) - if err != nil { - return nil, err - } - self.Sectors = nssroot - - // if miner is not mining, start their proving period now - // Note: As written here, every miners first PoSt will only be over one sector. - // We could set up a 'grace period' for starting mining that would allow miners - // to submit several sectors for their first proving period. Alternatively, we - // could simply make the 'PreCommitSector' call take multiple sectors at a time. - // - // Note: Proving period is a function of sector size; small sectors take less - // time to prove than large sectors do. Sector size is selected when pledging. - pss, lerr := amt2.LoadAMT(vmctx.Context(), vmctx.Ipld(), self.ProvingSet) - if lerr != nil { - return nil, aerrors.HandleExternalError(lerr, "could not load proving set node") - } - - if pss.Count == 0 && !self.Active { - self.ProvingSet = self.Sectors - // TODO: probably want to wait until the miner is above a certain - // threshold before starting this - self.ElectionPeriodStart = vmctx.BlockHeight() - } - - nstate, err := vmctx.Storage().Put(self) - if err != nil { - return nil, err - } - if err := vmctx.Storage().Commit(oldstate, nstate); err != nil { - return nil, err - } - - activateParams, err := SerializeParams(&ActivateStorageDealsParams{ - Deals: params.DealIDs, - }) - if err != nil { - return nil, err - } - - _, err = vmctx.Send(StorageMarketAddress, SMAMethods.ActivateStorageDeals, types.NewInt(0), activateParams) - return nil, aerrors.Wrapf(err, "calling ActivateStorageDeals failed") -} - -func (sma StorageMinerActor) SubmitFallbackPoSt(act *types.Actor, vmctx types.VMContext, params *SubmitFallbackPoStParams) ([]byte, ActorError) { - oldstate, self, err := loadState(vmctx) - if err != nil { - return nil, err - } - - mi, err := loadMinerInfo(vmctx, self) - if err != nil { - return nil, err - } - - if vmctx.Message().From != mi.Worker { - return nil, aerrors.New(1, "not authorized to submit post for miner") - } - - /* - // TODO: handle fees - msgVal := vmctx.Message().Value - if msgVal.LessThan(feesRequired) { - return nil, aerrors.New(2, "not enough funds to pay post submission fees") - } - - if msgVal.GreaterThan(feesRequired) { - _, err := vmctx.Send(vmctx.Message().From, 0, - types.BigSub(msgVal, feesRequired), nil) - if err != nil { - return nil, aerrors.Wrap(err, "could not refund excess fees") - } - } - */ - - var seed [sectorbuilder.CommLen]byte - { - randHeight := self.ElectionPeriodStart + build.FallbackPoStDelay - if 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) - - if err != nil { - return nil, aerrors.Wrap(err, "could not get randomness for PoST") - } - if len(rand) < len(seed) { - return nil, aerrors.Escalate(fmt.Errorf("randomness too small (%d < %d)", - len(rand), len(seed)), "improper randomness") - } - copy(seed[:], rand) - } - - pss, lerr := amt2.LoadAMT(vmctx.Context(), vmctx.Ipld(), self.ProvingSet) - if lerr != nil { - return nil, aerrors.HandleExternalError(lerr, "could not load proving set node") - } - - ss, lerr := amt2.LoadAMT(vmctx.Context(), vmctx.Ipld(), self.Sectors) - if lerr != nil { - return nil, aerrors.HandleExternalError(lerr, "could not load proving set node") - } - - faults, nerr := self.FaultSet.AllMap(2 * ss.Count) - if nerr != nil { - return nil, aerrors.Absorb(err, 5, "RLE+ invalid") - } - - activeFaults := uint64(0) - var sectorInfos []types.PublicSectorInfo - if err := pss.ForEach(vmctx.Context(), func(id uint64, v *cbg.Deferred) error { - if faults[id] { - activeFaults++ - return nil - } - - var comms [][]byte - if err := cbor.DecodeInto(v.Raw, &comms); err != nil { - return xerrors.New("could not decode comms") - } - si := types.PublicSectorInfo{ - SectorID: id, - } - commR := comms[0] - if len(commR) != len(si.CommR) { - return xerrors.Errorf("commR length is wrong: %d", len(commR)) - } - copy(si.CommR[:], commR) - - sectorInfos = append(sectorInfos, si) - - return nil - }); err != nil { - return nil, aerrors.Absorb(err, 3, "could not decode sectorset") - } - - proverID := vmctx.Message().To // TODO: normalize to ID address - - var candidates []types.Candidate - for _, t := range params.Candidates { - var partial [32]byte - copy(partial[:], t.Partial) - candidates = append(candidates, types.Candidate{ - PartialTicket: partial, - SectorID: t.SectorID, - SectorChallengeIndex: t.ChallengeIndex, - }) - } - - if ok, lerr := vmctx.Sys().VerifyFallbackPost(vmctx.Context(), mi.SectorSize, - sectorInfos, seed[:], params.Proof, candidates, proverID, activeFaults); !ok || lerr != nil { - if lerr != nil { - // TODO: study PoST errors - return nil, aerrors.Absorb(lerr, 4, "PoST error") - } - if !ok { - return nil, aerrors.New(4, "PoST invalid") - } - } - - // Post submission is successful! - if err := onSuccessfulPoSt2(self, vmctx, activeFaults); err != nil { - return nil, err - } - - c, err := vmctx.Storage().Put(self) - if err != nil { - return nil, err - } - - if err := vmctx.Storage().Commit(oldstate, c); err != nil { - return nil, err - } - - return nil, nil -} - -func (sma StorageMinerActor) GetPower(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) { - _, self, err := loadState(vmctx) - if err != nil { - return nil, err - } - - if self.SlashedAt != 0 { - return types.NewInt(0).Bytes(), nil - } - - return self.Power.Bytes(), nil -} - -func SectorIsUnique2(ctx context.Context, s cbor.IpldStore, sroot cid.Cid, sid uint64) (bool, ActorError) { - found, _, _, err := GetFromSectorSet2(ctx, s, sroot, sid) - if err != nil { - return false, err - } - - return !found, nil -} - -func AddToSectorSet2(ctx context.Context, blks cbor.IpldStore, ss cid.Cid, sectorID uint64, commR, commD []byte) (cid.Cid, ActorError) { - if sectorID >= build.MinerMaxSectors { - return cid.Undef, aerrors.Newf(25, "sector ID out of range: %d", sectorID) - } - ssr, err := amt2.LoadAMT(ctx, blks, ss) - if err != nil { - return cid.Undef, aerrors.HandleExternalError(err, "could not load sector set node") - } - - // 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 { - return cid.Undef, aerrors.HandleExternalError(err, "failed to set commitment in sector set") - } - - ncid, err := ssr.Flush(ctx) - if err != nil { - return cid.Undef, aerrors.HandleExternalError(err, "failed to flush sector set") - } - - return ncid, nil -} - -func GetFromSectorSet2(ctx context.Context, cst cbor.IpldStore, ss cid.Cid, sectorID uint64) (bool, []byte, []byte, ActorError) { - if sectorID >= build.MinerMaxSectors { - return false, nil, nil, aerrors.Newf(25, "sector ID out of range: %d", sectorID) - } - - ssr, err := amt2.LoadAMT(ctx, cst, ss) - if err != nil { - return false, nil, nil, aerrors.HandleExternalError(err, "could not load sector set node") - } - - var comms [][]byte - err = ssr.Get(ctx, sectorID, &comms) - if err != nil { - if _, ok := err.(*amt2.ErrNotFound); ok { - return false, nil, nil, nil - } - return false, nil, nil, aerrors.HandleExternalError(err, "failed to find sector in sector set") - } - - if len(comms) != 2 { - return false, nil, nil, aerrors.Newf(20, "sector set entry should only have 2 elements") - } - - return true, comms[0], comms[1], nil -} - -func RemoveFromSectorSet2(ctx context.Context, cst cbor.IpldStore, ss cid.Cid, ids []uint64) (cid.Cid, aerrors.ActorError) { - - ssr, err := amt2.LoadAMT(ctx, cst, ss) - if err != nil { - return cid.Undef, aerrors.HandleExternalError(err, "could not load sector set node") - } - - for _, id := range ids { - if err := ssr.Delete(ctx, id); err != nil { - log.Warnf("failed to delete sector %d from set: %s", id, err) - } - } - - ncid, err := ssr.Flush(ctx) - if err != nil { - return cid.Undef, aerrors.HandleExternalError(err, "failed to flush sector set") - } - - return ncid, nil -} - -func (sma StorageMinerActor) GetWorkerAddr(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) { - _, self, err := loadState(vmctx) - if err != nil { - return nil, err - } - - mi, err := loadMinerInfo(vmctx, self) - if err != nil { - return nil, err - } - - return mi.Worker.Bytes(), nil -} - -func (sma StorageMinerActor) GetOwner(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) { - _, self, err := loadState(vmctx) - if err != nil { - return nil, err - } - - mi, err := loadMinerInfo(vmctx, self) - if err != nil { - return nil, err - } - - return mi.Owner.Bytes(), nil -} - -func (sma StorageMinerActor) GetPeerID(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) { - _, self, err := loadState(vmctx) - if err != nil { - return nil, err - } - - mi, err := loadMinerInfo(vmctx, self) - if err != nil { - return nil, err - } - - return []byte(mi.PeerID), nil -} - -func (sma StorageMinerActor) UpdatePeerID(act *types.Actor, vmctx types.VMContext, params *UpdatePeerIDParams) ([]byte, ActorError) { - oldstate, self, err := loadState(vmctx) - if err != nil { - return nil, err - } - - mi, err := loadMinerInfo(vmctx, self) - if err != nil { - return nil, err - } - - if vmctx.Message().From != mi.Worker { - return nil, aerrors.New(2, "only the mine worker may update the peer ID") - } - - mi.PeerID = params.PeerID - - mic, err := vmctx.Storage().Put(mi) - if err != nil { - return nil, err - } - - self.Info = mic - - c, err := vmctx.Storage().Put(self) - if err != nil { - return nil, err - } - - if err := vmctx.Storage().Commit(oldstate, c); err != nil { - return nil, err - } - - return nil, nil -} - -func (sma StorageMinerActor) GetSectorSize(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) { - _, self, err := loadState(vmctx) - if err != nil { - return nil, err - } - - mi, err := loadMinerInfo(vmctx, self) - if err != nil { - return nil, err - } - - return types.NewInt(mi.SectorSize).Bytes(), nil -} - -func (sma StorageMinerActor) IsSlashed(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) { - _, self, err := loadState(vmctx) - if err != nil { - return nil, err - } - - return cbg.EncodeBool(self.SlashedAt != 0), nil -} - -// TODO: better name -func (sma StorageMinerActor) CheckMiner(act *types.Actor, vmctx types.VMContext, params *CheckMinerParams) ([]byte, ActorError) { - if vmctx.Message().From != StoragePowerAddress { - return nil, aerrors.New(2, "only the storage power actor can check miner") - } - - oldstate, self, err := loadState(vmctx) - if err != nil { - return nil, err - } - - if !isLate(vmctx.BlockHeight(), self) { - // Everything's fine - return nil, nil - } - - if self.SlashedAt != 0 { - // Don't slash more than necessary - return nil, nil - } - - if params.NetworkPower.Equals(self.Power) { - // Don't break the network when there's only one miner left - - log.Warnf("can't slash miner %s for missed PoSt, no power would be left in the network", vmctx.Message().To) - return nil, nil - } - - // Slash for being late - - self.SlashedAt = vmctx.BlockHeight() - oldPower := self.Power - self.Power = types.NewInt(0) - - nstate, err := vmctx.Storage().Put(self) - if err != nil { - return nil, err - } - if err := vmctx.Storage().Commit(oldstate, nstate); err != nil { - return nil, err - } - - var out bytes.Buffer - if err := oldPower.MarshalCBOR(&out); err != nil { - return nil, aerrors.HandleExternalError(err, "marshaling return value") - } - return out.Bytes(), nil -} - -func (sma StorageMinerActor) DeclareFaults(act *types.Actor, vmctx types.VMContext, params *DeclareFaultsParams) ([]byte, ActorError) { - oldstate, self, aerr := loadState(vmctx) - if aerr != nil { - return nil, aerr - } - - mi, aerr := loadMinerInfo(vmctx, self) - if aerr != nil { - return nil, aerr - } - - if vmctx.Message().From != mi.Worker { - return nil, aerrors.New(1, "not authorized to declare faults for miner") - } - - nfaults, err := types.MergeBitFields(params.Faults, self.FaultSet) - if err != nil { - return nil, aerrors.Absorb(err, 1, "failed to merge bitfields") - } - - ss, nerr := amt2.LoadAMT(vmctx.Context(), vmctx.Ipld(), self.Sectors) - if nerr != nil { - return nil, aerrors.HandleExternalError(nerr, "failed to load sector set") - } - - cf, nerr := nfaults.Count() - if nerr != nil { - return nil, aerrors.Absorb(nerr, 2, "could not decode RLE+") - } - - if cf > 2*ss.Count { - return nil, aerrors.Newf(3, "too many declared faults: %d > %d", cf, 2*ss.Count) - } - - self.FaultSet = nfaults - - self.LastFaultSubmission = vmctx.BlockHeight() - - nstate, aerr := vmctx.Storage().Put(self) - if aerr != nil { - return nil, aerr - } - if err := vmctx.Storage().Commit(oldstate, nstate); err != nil { - return nil, err - } - - return nil, nil -} - -func (sma StorageMinerActor) SlashConsensusFault(act *types.Actor, vmctx types.VMContext, params *MinerSlashConsensusFault) ([]byte, ActorError) { - if vmctx.Message().From != StoragePowerAddress { - return nil, aerrors.New(1, "SlashConsensusFault may only be called by the storage market actor") - } - - slashedCollateral := params.SlashedCollateral - if slashedCollateral.LessThan(act.Balance) { - slashedCollateral = act.Balance - } - - // Some of the slashed collateral should be paid to the slasher - // 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 - - slasherShare := slasherShare(params.SlashedCollateral, blockElapsed) - - burnPortion := types.BigSub(slashedCollateral, slasherShare) - - _, err := vmctx.Send(vmctx.Message().From, 0, slasherShare, nil) - if err != nil { - return nil, aerrors.Wrap(err, "failed to pay slasher") - } - - _, err = vmctx.Send(BurntFundsAddress, 0, burnPortion, nil) - if err != nil { - return nil, aerrors.Wrap(err, "failed to burn funds") - } - - oldstate, self, err := loadState(vmctx) - if err != nil { - return nil, aerrors.Wrap(err, "failed to load state for slashing") - } - - self.Power = types.NewInt(0) - - ncid, err := vmctx.Storage().Put(self) - if err != nil { - return nil, err - } - if err := vmctx.Storage().Commit(oldstate, ncid); err != nil { - return nil, err - } - - // TODO: this still allows the miner to commit sectors and submit posts, - // their users could potentially be unaffected, but the miner will never be - // able to mine a block again - // One potential issue: the miner will have to pay back the slashed - // collateral to continue submitting PoSts, which includes pledge - // collateral that they no longer really 'need' - - return nil, nil -} - -func (sma StorageMinerActor) SubmitElectionPoSt(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, aerrors.ActorError) { - ctx := vmctx.Context() - - if vmctx.Message().From != NetworkAddress { - return nil, aerrors.Newf(1, "submit election post can only be called by the storage power actor") - } - - oldstate, self, aerr := loadState(vmctx) - if aerr != nil { - return nil, aerr - } - - if self.SlashedAt != 0 { - return nil, aerrors.New(1, "slashed miners can't perform election PoSt") - } - - pss, nerr := amt2.LoadAMT(ctx, vmctx.Ipld(), self.ProvingSet) - if nerr != nil { - return nil, aerrors.HandleExternalError(nerr, "failed to load proving set") - } - - ss, nerr := amt2.LoadAMT(ctx, vmctx.Ipld(), self.Sectors) - if nerr != nil { - return nil, aerrors.HandleExternalError(nerr, "failed to load proving set") - } - - faults, nerr := self.FaultSet.AllMap(2 * ss.Count) - if nerr != nil { - return nil, aerrors.Absorb(nerr, 1, "invalid bitfield (fatal?)") - } - - activeFaults := uint64(0) - for f := range faults { - if f > amt2.MaxIndex { - continue - } - - var comms [][]byte - err := pss.Get(ctx, f, &comms) - if err != nil { - var notfound *amt2.ErrNotFound - if !xerrors.As(err, ¬found) { - return nil, aerrors.HandleExternalError(err, "failed to find sector in sector set") - } - continue - } - - activeFaults++ - } - - if err := onSuccessfulPoSt2(self, vmctx, activeFaults); err != nil { // TODO - return nil, err - } - - ncid, err := vmctx.Storage().Put(self) - if err != nil { - return nil, err - } - if err := vmctx.Storage().Commit(oldstate, ncid); err != nil { - return nil, err - } - - return nil, nil -} - -func onSuccessfulPoSt2(self *StorageMinerActorState, vmctx types.VMContext, activeFaults uint64) aerrors.ActorError { - ctx := vmctx.Context() - - var mi MinerInfo - if err := vmctx.Storage().Get(self.Info, &mi); err != nil { - return err - } - - pss, nerr := amt2.LoadAMT(ctx, vmctx.Ipld(), self.ProvingSet) - if nerr != nil { - return aerrors.HandleExternalError(nerr, "failed to load proving set") - } - - ss, nerr := amt2.LoadAMT(ctx, vmctx.Ipld(), self.Sectors) - if nerr != nil { - return aerrors.HandleExternalError(nerr, "failed to load sector set") - } - - faults, nerr := self.FaultSet.All(2 * ss.Count) - if nerr != nil { - return aerrors.Absorb(nerr, 1, "invalid bitfield (fatal?)") - } - - self.FaultSet = types.NewBitField() - - oldPower := self.Power - newPower := types.BigMul(types.NewInt(pss.Count-activeFaults), types.NewInt(mi.SectorSize)) - - // If below the minimum size requirement, miners have zero power - if newPower.LessThan(types.NewInt(build.MinimumMinerPower)) { - newPower = types.NewInt(0) - } - - self.Power = newPower - - delta := types.BigSub(self.Power, oldPower) - if self.SlashedAt != 0 { - self.SlashedAt = 0 - delta = self.Power - } - - prevSlashingDeadline := self.ElectionPeriodStart + build.SlashablePowerDelay - if !self.Active && newPower.GreaterThan(types.NewInt(0)) { - self.Active = true - prevSlashingDeadline = 0 - } - - if !(oldPower.IsZero() && newPower.IsZero()) { - enc, err := SerializeParams(&UpdateStorageParams{ - Delta: delta, - NextSlashDeadline: vmctx.BlockHeight() + build.SlashablePowerDelay, - PreviousSlashDeadline: prevSlashingDeadline, - }) - if err != nil { - return err - } - - _, err = vmctx.Send(StoragePowerAddress, SPAMethods.UpdateStorage, types.NewInt(0), enc) - if err != nil { - return aerrors.Wrap(err, "updating storage failed") - } - - self.ElectionPeriodStart = vmctx.BlockHeight() - } - - var ncid cid.Cid - var err aerrors.ActorError - - ncid, err = RemoveFromSectorSet2(ctx, vmctx.Ipld(), self.Sectors, faults) - if err != nil { - return err - } - - self.Sectors = ncid - self.ProvingSet = ncid - return nil -} - -func SectorIsUnique(ctx context.Context, cst cbor.IpldStore, sroot cid.Cid, sid uint64) (bool, ActorError) { - found, _, _, err := GetFromSectorSet(ctx, cst, sroot, sid) - if err != nil { - return false, err - } - - return !found, nil -} - -func GetFromSectorSet(ctx context.Context, cst cbor.IpldStore, ss cid.Cid, sectorID uint64) (bool, []byte, []byte, ActorError) { - if sectorID >= build.MinerMaxSectors { - return false, nil, nil, aerrors.Newf(25, "sector ID out of range: %d", sectorID) - } - - ssr, err := amt.LoadAMT(ctx, cst, ss) - if err != nil { - return false, nil, nil, aerrors.HandleExternalError(err, "could not load sector set node") - } - - var comms [][]byte - err = ssr.Get(ctx, sectorID, &comms) - if err != nil { - if _, ok := err.(*amt.ErrNotFound); ok { - return false, nil, nil, nil - } - return false, nil, nil, aerrors.HandleExternalError(err, "failed to find sector in sector set") - } - - if len(comms) != 2 { - return false, nil, nil, aerrors.Newf(20, "sector set entry should only have 2 elements") - } - - 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) { - if sectorID >= build.MinerMaxSectors { - return cid.Undef, aerrors.Newf(25, "sector ID out of range: %d", sectorID) - } - ssr, err := amt.LoadAMT(ctx, blks, ss) - if err != nil { - return cid.Undef, aerrors.HandleExternalError(err, "could not load sector set node") - } - - // 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 { - return cid.Undef, aerrors.HandleExternalError(err, "failed to set commitment in sector set") - } - - ncid, err := ssr.Flush(ctx) - if err != nil { - return cid.Undef, aerrors.HandleExternalError(err, "failed to flush sector set") - } - - return ncid, nil -} - -func loadState(vmctx types.VMContext) (cid.Cid, *StorageMinerActorState, ActorError) { - var self StorageMinerActorState - oldstate := vmctx.Storage().GetHead() - if err := vmctx.Storage().Get(oldstate, &self); err != nil { - return cid.Undef, nil, err - } - - return oldstate, &self, nil -} - -func loadMinerInfo(vmctx types.VMContext, m *StorageMinerActorState) (*MinerInfo, ActorError) { - var mi MinerInfo - if err := vmctx.Storage().Get(m.Info, &mi); err != nil { - return nil, err - } - - return &mi, nil -} - -func uintToStringKey(i uint64) string { - buf := make([]byte, 10) - n := binary.PutUvarint(buf, i) - return string(buf[:n]) -} - -type SectorProveCommitInfo struct { - Proof []byte - SectorID uint64 - DealIDs []uint64 -} - -func truncateHexPrint(b []byte) string { - s := fmt.Sprintf("%x", b) - if len(s) > 60 { - return s[:20] + "..." + s[len(s)-20:] - } - return s -} - -type SubmitFallbackPoStParams struct { - Proof []byte - Candidates []types.EPostTicket -} - -func CollateralForPower(power types.BigInt) types.BigInt { - return types.BigMul(power, types.NewInt(10)) - /* TODO: this - availableFil = FakeGlobalMethods.GetAvailableFil() - totalNetworkPower = StorageMinerActor.GetTotalStorage() - numMiners = StorageMarket.GetMinerCount() - powerCollateral = availableFil * NetworkConstants.POWER_COLLATERAL_PROPORTION * power / totalNetworkPower - perCapitaCollateral = availableFil * NetworkConstants.PER_CAPITA_COLLATERAL_PROPORTION / numMiners - collateralRequired = math.Ceil(minerPowerCollateral + minerPerCapitaCollateral) - return collateralRequired - */ -} - -type UpdatePeerIDParams struct { - PeerID peer.ID -} - -func isLate(height uint64, self *StorageMinerActorState) bool { - return self.ElectionPeriodStart > 0 && height >= self.ElectionPeriodStart+build.SlashablePowerDelay -} - -type CheckMinerParams struct { - NetworkPower types.BigInt -} - -type DeclareFaultsParams struct { - Faults types.BitField -} - -type MinerSlashConsensusFault struct { - Slasher address.Address - AtHeight uint64 - SlashedCollateral types.BigInt -} - -func slasherShare(total types.BigInt, elapsed uint64) types.BigInt { - // [int(pow(1.26, n) * 10) for n in range(30)] - fracs := []uint64{10, 12, 15, 20, 25, 31, 40, 50, 63, 80, 100, 127, 160, 201, 254, 320, 403, 508, 640, 807, 1017, 1281, 1614, 2034, 2563, 3230, 4070, 5128, 6462, 8142} - const precision = 10000 - - var frac uint64 - if elapsed >= uint64(len(fracs)) { - return total - } else { - frac = fracs[elapsed] - } - - return types.BigDiv( - types.BigMul( - types.NewInt(frac), - total, - ), - types.NewInt(precision), - ) -} diff --git a/chain/actors/actor_miner_test.go b/chain/actors/actor_miner_test.go deleted file mode 100644 index c80519276..000000000 --- a/chain/actors/actor_miner_test.go +++ /dev/null @@ -1,281 +0,0 @@ -package actors_test - -import ( - "bytes" - "context" - "math" - "math/rand" - "testing" - - "github.com/filecoin-project/go-address" - "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/actors/aerrors" - "github.com/filecoin-project/lotus/chain/stmgr" - "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/lib/rlepluslazy" - blockstore "github.com/ipfs/go-ipfs-blockstore" - cbor "github.com/ipfs/go-ipld-cbor" - "github.com/stretchr/testify/assert" - cbg "github.com/whyrusleeping/cbor-gen" -) - -func TestMinerCommitSectors(t *testing.T) { - var worker, client address.Address - var minerAddr address.Address - opts := []HarnessOpt{ - HarnessAddr(&worker, 1000000), - HarnessAddr(&client, 1000000), - HarnessActor(&minerAddr, &worker, actors.StorageMinerCodeCid, - func() cbg.CBORMarshaler { - return &actors.StorageMinerConstructorParams{ - Owner: worker, - Worker: worker, - SectorSize: 1024, - PeerID: "fakepeerid", - } - }), - } - - h := NewHarness(t, opts...) - h.vm.Syscalls.ValidatePoRep = func(ctx context.Context, maddr address.Address, ssize uint64, commD, commR, ticket, proof, seed []byte, sectorID uint64) (bool, aerrors.ActorError) { - // all proofs are valid - return true, nil - } - - ret, _ := h.SendFunds(t, worker, minerAddr, types.NewInt(100000)) - ApplyOK(t, ret) - - ret, _ = h.InvokeWithValue(t, client, actors.StorageMarketAddress, actors.SMAMethods.AddBalance, types.NewInt(2000), nil) - ApplyOK(t, ret) - - addSectorToMiner(h, t, minerAddr, worker, client, 1) - - assertSectorIDs(h, t, minerAddr, []uint64{1}) - -} - -type badRuns struct { - done bool -} - -func (br *badRuns) HasNext() bool { - return !br.done -} - -func (br *badRuns) NextRun() (rlepluslazy.Run, error) { - br.done = true - return rlepluslazy.Run{true, math.MaxInt64}, nil -} - -var _ rlepluslazy.RunIterator = (*badRuns)(nil) - -func TestMinerSubmitBadFault(t *testing.T) { - oldSS, oldMin := build.SectorSizes, build.MinimumMinerPower - build.SectorSizes, build.MinimumMinerPower = []uint64{1024}, 1024 - defer func() { - build.SectorSizes, build.MinimumMinerPower = oldSS, oldMin - }() - - var worker, client address.Address - var minerAddr address.Address - opts := []HarnessOpt{ - HarnessAddr(&worker, 1000000), - HarnessAddr(&client, 1000000), - HarnessAddMiner(&minerAddr, &worker), - } - - h := NewHarness(t, opts...) - h.vm.Syscalls.ValidatePoRep = func(ctx context.Context, maddr address.Address, ssize uint64, commD, commR, ticket, proof, seed []byte, sectorID uint64) (bool, aerrors.ActorError) { - // all proofs are valid - return true, nil - } - - ret, _ := h.SendFunds(t, worker, minerAddr, types.NewInt(100000)) - ApplyOK(t, ret) - - ret, _ = h.InvokeWithValue(t, client, actors.StorageMarketAddress, actors.SMAMethods.AddBalance, types.NewInt(2000), nil) - ApplyOK(t, ret) - - addSectorToMiner(h, t, minerAddr, worker, client, 1) - - assertSectorIDs(h, t, minerAddr, []uint64{1}) - - bf := types.NewBitField() - bf.Set(6) - ret, _ = h.Invoke(t, worker, minerAddr, actors.MAMethods.DeclareFaults, &actors.DeclareFaultsParams{bf}) - ApplyOK(t, ret) - - ret, _ = h.Invoke(t, actors.NetworkAddress, minerAddr, actors.MAMethods.SubmitElectionPoSt, nil) - ApplyOK(t, ret) - assertSectorIDs(h, t, minerAddr, []uint64{1}) - - st, err := getMinerState(context.TODO(), h.vm.StateTree(), h.bs, minerAddr) - assert.NoError(t, err) - expectedPower := st.Power - if types.BigCmp(expectedPower, types.NewInt(1024)) != 0 { - t.Errorf("Expected power of 1024, got %s", expectedPower) - } - - badnum := uint64(0) - badnum-- - bf = types.NewBitField() - bf.Set(badnum) - bf.Set(badnum - 1) - ret, _ = h.Invoke(t, worker, minerAddr, actors.MAMethods.DeclareFaults, &actors.DeclareFaultsParams{bf}) - ApplyOK(t, ret) - - ret, _ = h.Invoke(t, actors.NetworkAddress, minerAddr, actors.MAMethods.SubmitElectionPoSt, nil) - - ApplyOK(t, ret) - assertSectorIDs(h, t, minerAddr, []uint64{1}) - - st, err = getMinerState(context.TODO(), h.vm.StateTree(), h.bs, minerAddr) - assert.NoError(t, err) - currentPower := st.Power - if types.BigCmp(expectedPower, currentPower) != 0 { - t.Errorf("power changed and shouldn't have: %s != %s", expectedPower, currentPower) - } - - bf.Set(badnum - 2) - ret, _ = h.Invoke(t, worker, minerAddr, actors.MAMethods.DeclareFaults, &actors.DeclareFaultsParams{bf}) - if ret.ExitCode != 3 { - t.Errorf("expected exit code 3, got %d: %+v", ret.ExitCode, ret.ActorErr) - } - assertSectorIDs(h, t, minerAddr, []uint64{1}) - - rle, err := rlepluslazy.EncodeRuns(&badRuns{}, []byte{}) - assert.NoError(t, err) - - bf, err = types.NewBitFieldFromBytes(rle) - assert.NoError(t, err) - ret, _ = h.Invoke(t, worker, minerAddr, actors.MAMethods.DeclareFaults, &actors.DeclareFaultsParams{bf}) - if ret.ExitCode != 3 { - t.Errorf("expected exit code 3, got %d: %+v", ret.ExitCode, ret.ActorErr) - } - assertSectorIDs(h, t, minerAddr, []uint64{1}) - - bf = types.NewBitField() - bf.Set(1) - ret, _ = h.Invoke(t, worker, minerAddr, actors.MAMethods.DeclareFaults, &actors.DeclareFaultsParams{bf}) - ApplyOK(t, ret) - - ret, _ = h.Invoke(t, actors.NetworkAddress, minerAddr, actors.MAMethods.SubmitElectionPoSt, nil) - ApplyOK(t, ret) - - assertSectorIDs(h, t, minerAddr, []uint64{}) - -} - -func addSectorToMiner(h *Harness, t *testing.T, minerAddr, worker, client address.Address, sid uint64) { - t.Helper() - s := sectorbuilder.UserBytesForSectorSize(1024) - deal := h.makeFakeDeal(t, minerAddr, worker, client, s) - ret, _ := h.Invoke(t, worker, actors.StorageMarketAddress, actors.SMAMethods.PublishStorageDeals, - &actors.PublishStorageDealsParams{ - Deals: []actors.StorageDealProposal{*deal}, - }) - ApplyOK(t, ret) - var dealIds actors.PublishStorageDealResponse - if err := dealIds.UnmarshalCBOR(bytes.NewReader(ret.Return)); err != nil { - t.Fatal(err) - } - - dealid := dealIds.DealIDs[0] - - ret, _ = h.Invoke(t, worker, minerAddr, actors.MAMethods.PreCommitSector, - &actors.SectorPreCommitInfo{ - SectorNumber: sid, - CommR: []byte("cats"), - SealEpoch: 10, - DealIDs: []uint64{dealid}, - }) - ApplyOK(t, ret) - - h.BlockHeight += 100 - ret, _ = h.Invoke(t, worker, minerAddr, actors.MAMethods.ProveCommitSector, - &actors.SectorProveCommitInfo{ - Proof: []byte("prooofy"), - SectorID: sid, - DealIDs: []uint64{dealid}, // TODO: weird that i have to pass this again - }) - ApplyOK(t, ret) -} - -func assertSectorIDs(h *Harness, t *testing.T, maddr address.Address, ids []uint64) { - t.Helper() - sectors, err := getMinerSectorSet(context.TODO(), h.vm.StateTree(), h.bs, maddr) - if err != nil { - t.Fatal(err) - } - - if len(sectors) != len(ids) { - t.Fatal("miner has wrong number of sectors in their sector set") - } - - all := make(map[uint64]bool) - for _, s := range sectors { - all[s.SectorID] = true - } - - for _, id := range ids { - if !all[id] { - t.Fatal("expected to find sector ID: ", id) - } - } -} - -func getMinerState(ctx context.Context, st types.StateTree, bs blockstore.Blockstore, maddr address.Address) (*actors.StorageMinerActorState, error) { - mact, err := st.GetActor(maddr) - if err != nil { - return nil, err - } - - cst := cbor.NewCborStore(bs) - - var mstate actors.StorageMinerActorState - if err := cst.Get(ctx, mact.Head, &mstate); err != nil { - return nil, err - } - return &mstate, nil -} - -func getMinerSectorSet(ctx context.Context, st types.StateTree, bs blockstore.Blockstore, maddr address.Address) ([]*api.ChainSectorInfo, error) { - mstate, err := getMinerState(ctx, st, bs, maddr) - if err != nil { - return nil, err - } - - return stmgr.LoadSectorsFromSet(ctx, bs, mstate.Sectors) -} - -func (h *Harness) makeFakeDeal(t *testing.T, miner, worker, client address.Address, size uint64) *actors.StorageDealProposal { - data := make([]byte, size) - rand.Read(data) - commP, err := sectorbuilder.GeneratePieceCommitment(bytes.NewReader(data), size) - if err != nil { - t.Fatal(err) - } - - prop := actors.StorageDealProposal{ - PieceRef: commP[:], - PieceSize: size, - - Client: client, - Provider: miner, - - ProposalExpiration: 10000, - Duration: 150, - - StoragePricePerEpoch: types.NewInt(1), - StorageCollateral: types.NewInt(0), - } - - if err := api.SignWith(context.TODO(), h.w.Sign, client, &prop); err != nil { - t.Fatal(err) - } - - return &prop -} diff --git a/chain/actors/actor_paych.go b/chain/actors/actor_paych.go deleted file mode 100644 index 05d9a9913..000000000 --- a/chain/actors/actor_paych.go +++ /dev/null @@ -1,302 +0,0 @@ -package actors - -import ( - "bytes" - "fmt" - - "github.com/ipfs/go-cid" - "github.com/minio/blake2b-simd" - - "github.com/filecoin-project/go-address" - "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/lotus/chain/actors/aerrors" - "github.com/filecoin-project/lotus/chain/types" -) - -type PaymentChannelActor struct{} - -type PaymentInfo struct { - PayChActor address.Address - Payer address.Address - ChannelMessage *cid.Cid - - Vouchers []*types.SignedVoucher -} - -type LaneState struct { - Closed bool - Redeemed types.BigInt - Nonce uint64 -} - -type PaymentChannelActorState struct { - From address.Address - To address.Address - - ToSend types.BigInt - - ClosingAt uint64 - MinCloseHeight uint64 - - // TODO: needs to be map[uint64]*laneState - // waiting on refmt#35 to be fixed - LaneStates map[string]*LaneState -} - -func (pca PaymentChannelActor) Exports() []interface{} { - return []interface{}{ - 1: pca.Constructor, - 2: pca.UpdateChannelState, - 3: pca.Close, - 4: pca.Collect, - 5: pca.GetOwner, - 6: pca.GetToSend, - } -} - -type pcaMethods struct { - Constructor uint64 - UpdateChannelState uint64 - Close uint64 - Collect uint64 - GetOwner uint64 - GetToSend uint64 -} - -var PCAMethods = pcaMethods{1, 2, 3, 4, 5, 6} - -type PCAConstructorParams struct { - To address.Address -} - -func (pca PaymentChannelActor) Constructor(act *types.Actor, vmctx types.VMContext, params *PCAConstructorParams) ([]byte, ActorError) { - var self PaymentChannelActorState - self.From = vmctx.Origin() - self.To = params.To - self.LaneStates = make(map[string]*LaneState) - - storage := vmctx.Storage() - c, err := storage.Put(&self) - if err != nil { - return nil, err - } - - if err := storage.Commit(EmptyCBOR, c); err != nil { - return nil, err - } - - return nil, nil -} - -type PCAUpdateChannelStateParams struct { - Sv types.SignedVoucher - Secret []byte - Proof []byte -} - -func hash(b []byte) []byte { - s := blake2b.Sum256(b) - return s[:] -} - -type PaymentVerifyParams struct { - Extra []byte - Proof []byte -} - -func (pca PaymentChannelActor) UpdateChannelState(act *types.Actor, vmctx types.VMContext, params *PCAUpdateChannelStateParams) ([]byte, ActorError) { - var self PaymentChannelActorState - oldstate := vmctx.Storage().GetHead() - storage := vmctx.Storage() - if err := storage.Get(oldstate, &self); err != nil { - return nil, err - } - - sv := params.Sv - - vb, nerr := sv.SigningBytes() - if nerr != nil { - return nil, aerrors.Absorb(nerr, 1, "failed to serialize signedvoucher") - } - - if err := vmctx.VerifySignature(sv.Signature, self.From, vb); err != nil { - return nil, err - } - - if vmctx.BlockHeight() < sv.TimeLock { - return nil, aerrors.New(2, "cannot use this voucher yet!") - } - - if len(sv.SecretPreimage) > 0 { - if !bytes.Equal(hash(params.Secret), sv.SecretPreimage) { - return nil, aerrors.New(3, "incorrect secret!") - } - } - - if sv.Extra != nil { - encoded, err := SerializeParams(&PaymentVerifyParams{sv.Extra.Data, params.Proof}) - if err != nil { - return nil, err - } - - _, err = vmctx.Send(sv.Extra.Actor, sv.Extra.Method, types.NewInt(0), encoded) - if err != nil { - return nil, aerrors.Newf(4, "spend voucher verification failed: %s", err) - } - } - - ls, ok := self.LaneStates[fmt.Sprint(sv.Lane)] - if !ok { - ls = new(LaneState) - ls.Redeemed = types.NewInt(0) // TODO: kinda annoying that this doesnt default to a usable value - self.LaneStates[fmt.Sprint(sv.Lane)] = ls - } - if ls.Closed { - return nil, aerrors.New(5, "cannot redeem a voucher on a closed lane") - } - - if ls.Nonce > sv.Nonce { - return nil, aerrors.New(6, "voucher has an outdated nonce, cannot redeem") - } - - mergeValue := types.NewInt(0) - for _, merge := range sv.Merges { - if merge.Lane == sv.Lane { - return nil, aerrors.New(7, "voucher cannot merge its own lane") - } - - ols := self.LaneStates[fmt.Sprint(merge.Lane)] - - if ols.Nonce >= merge.Nonce { - return nil, aerrors.New(8, "merge in voucher has outdated nonce, cannot redeem") - } - - mergeValue = types.BigAdd(mergeValue, ols.Redeemed) - ols.Nonce = merge.Nonce - } - - ls.Nonce = sv.Nonce - balanceDelta := types.BigSub(sv.Amount, types.BigAdd(mergeValue, ls.Redeemed)) - ls.Redeemed = sv.Amount - - newSendBalance := types.BigAdd(self.ToSend, balanceDelta) - if newSendBalance.LessThan(types.NewInt(0)) { - // TODO: is this impossible? - return nil, aerrors.New(9, "voucher would leave channel balance negative") - } - - if newSendBalance.GreaterThan(act.Balance) { - return nil, aerrors.New(10, "not enough funds in channel to cover voucher") - } - - log.Info("vals: ", newSendBalance, sv.Amount, balanceDelta, mergeValue, ls.Redeemed) - self.ToSend = newSendBalance - - if sv.MinCloseHeight != 0 { - if self.ClosingAt != 0 && self.ClosingAt < sv.MinCloseHeight { - self.ClosingAt = sv.MinCloseHeight - } - if self.MinCloseHeight < sv.MinCloseHeight { - self.MinCloseHeight = sv.MinCloseHeight - } - } - - ncid, err := storage.Put(&self) - if err != nil { - return nil, err - } - if err := storage.Commit(oldstate, ncid); err != nil { - return nil, err - } - - return nil, nil -} - -func (pca PaymentChannelActor) Close(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, aerrors.ActorError) { - var self PaymentChannelActorState - storage := vmctx.Storage() - oldstate := storage.GetHead() - if err := storage.Get(oldstate, &self); err != nil { - return nil, err - } - - if vmctx.Message().From != self.From && vmctx.Message().From != self.To { - return nil, aerrors.New(1, "not authorized to close channel") - } - - if self.ClosingAt != 0 { - return nil, aerrors.New(2, "channel already closing") - } - - self.ClosingAt = vmctx.BlockHeight() + build.PaymentChannelClosingDelay - if self.ClosingAt < self.MinCloseHeight { - self.ClosingAt = self.MinCloseHeight - } - - ncid, err := storage.Put(&self) - if err != nil { - return nil, err - } - if err := storage.Commit(oldstate, ncid); err != nil { - return nil, err - } - - return nil, nil -} - -func (pca PaymentChannelActor) Collect(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, aerrors.ActorError) { - var self PaymentChannelActorState - storage := vmctx.Storage() - oldstate := storage.GetHead() - if err := storage.Get(oldstate, &self); err != nil { - return nil, err - } - - if self.ClosingAt == 0 { - return nil, aerrors.New(1, "payment channel not closing or closed") - } - - if 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) - if err != nil { - return nil, err - } - _, err = vmctx.Send(self.To, 0, self.ToSend, nil) - if err != nil { - return nil, err - } - - self.ToSend = types.NewInt(0) - - ncid, err := storage.Put(&self) - if err != nil { - return nil, err - } - if err := storage.Commit(oldstate, ncid); err != nil { - return nil, err - } - - return nil, nil -} - -func (pca PaymentChannelActor) GetOwner(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, aerrors.ActorError) { - var self PaymentChannelActorState - storage := vmctx.Storage() - if err := storage.Get(storage.GetHead(), &self); err != nil { - return nil, err - } - - return self.From.Bytes(), nil -} - -func (pca PaymentChannelActor) GetToSend(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, aerrors.ActorError) { - var self PaymentChannelActorState - storage := vmctx.Storage() - if err := storage.Get(storage.GetHead(), &self); err != nil { - return nil, err - } - - return self.ToSend.Bytes(), nil -} diff --git a/chain/actors/actor_storagemarket.go b/chain/actors/actor_storagemarket.go deleted file mode 100644 index 383b63fef..000000000 --- a/chain/actors/actor_storagemarket.go +++ /dev/null @@ -1,681 +0,0 @@ -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" -) - -type StorageMarketActor struct{} - -type smaMethods struct { - Constructor uint64 - WithdrawBalance uint64 - AddBalance uint64 - CheckLockedBalance uint64 - PublishStorageDeals uint64 - HandleCronAction uint64 - SettleExpiredDeals uint64 - ProcessStorageDealsPayment uint64 - SlashStorageDealCollateral uint64 - GetLastExpirationFromDealIDs uint64 - ActivateStorageDeals uint64 - ComputeDataCommitment uint64 -} - -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 -} - -// TODO: Drop in favour of car storage -type SerializationMode = uint64 - -const ( - SerializationUnixFSv0 = iota - // IPLD / car -) - -type StorageDealProposal 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 - - ProposerSignature *types.Signature -} - -func (sdp *StorageDealProposal) TotalStoragePrice() types.BigInt { - return types.BigMul(sdp.StoragePricePerEpoch, types.NewInt(sdp.Duration)) -} - -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) { - -} - -func (sma StorageMarketActor) SettleExpiredDeals(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) { - -} - -func (sma StorageMarketActor) SlashStorageDealCollateral(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) { - -} - -func (sma StorageMarketActor) GetLastExpirationFromDealIDs(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) { - -} -*/ diff --git a/chain/actors/actor_storagepower.go b/chain/actors/actor_storagepower.go deleted file mode 100644 index 78213998e..000000000 --- a/chain/actors/actor_storagepower.go +++ /dev/null @@ -1,845 +0,0 @@ -package actors - -import ( - "bytes" - "context" - "io" - - "github.com/filecoin-project/go-amt-ipld/v2" - cid "github.com/ipfs/go-cid" - hamt "github.com/ipfs/go-hamt-ipld" - cbor "github.com/ipfs/go-ipld-cbor" - "github.com/libp2p/go-libp2p-core/peer" - cbg "github.com/whyrusleeping/cbor-gen" - "go.opencensus.io/trace" - xerrors "golang.org/x/xerrors" - - "github.com/filecoin-project/go-address" - "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" -) - -type StoragePowerActor struct{} - -type spaMethods struct { - Constructor uint64 - CreateStorageMiner uint64 - ArbitrateConsensusFault uint64 - UpdateStorage uint64 - GetTotalStorage uint64 - PowerLookup uint64 - IsValidMiner uint64 - PledgeCollateralForSize uint64 - CheckProofSubmissions uint64 -} - -var SPAMethods = spaMethods{1, 2, 3, 4, 5, 6, 7, 8, 9} - -func (spa StoragePowerActor) Exports() []interface{} { - return []interface{}{ - //1: spa.StoragePowerConstructor, - 2: spa.CreateStorageMiner, - 3: spa.ArbitrateConsensusFault, - 4: spa.UpdateStorage, - 5: spa.GetTotalStorage, - 6: spa.PowerLookup, - 7: spa.IsValidMiner, - 8: spa.PledgeCollateralForSize, - 9: spa.CheckProofSubmissions, - } -} - -type StoragePowerState struct { - Miners cid.Cid - ProvingBuckets cid.Cid // amt[ProvingPeriodBucket]hamt[minerAddress]struct{} - MinerCount uint64 - LastMinerCheck uint64 - - TotalStorage types.BigInt -} - -type CreateStorageMinerParams struct { - Owner address.Address - Worker address.Address - SectorSize uint64 - PeerID peer.ID -} - -func (spa StoragePowerActor) CreateStorageMiner(act *types.Actor, vmctx types.VMContext, params *CreateStorageMinerParams) ([]byte, ActorError) { - if !build.SupportedSectorSize(params.SectorSize) { - return nil, aerrors.Newf(1, "Unsupported sector size: %d", params.SectorSize) - } - - var self StoragePowerState - old := vmctx.Storage().GetHead() - if err := vmctx.Storage().Get(old, &self); err != nil { - return nil, err - } - - reqColl, err := pledgeCollateralForSize(vmctx, types.NewInt(0), self.TotalStorage, self.MinerCount+1) - if err != nil { - return nil, err - } - - if vmctx.Message().Value.LessThan(reqColl) { - return nil, aerrors.Newf(1, "not enough funds passed to cover required miner collateral (needed %s, got %s)", reqColl, vmctx.Message().Value) - } - - minerCid := StorageMinerCodeCid - - encoded, err := CreateExecParams(minerCid, &StorageMinerConstructorParams{ - Owner: params.Owner, - Worker: params.Worker, - SectorSize: params.SectorSize, - PeerID: params.PeerID, - }) - if err != nil { - return nil, err - } - - ret, err := vmctx.Send(InitAddress, IAMethods.Exec, vmctx.Message().Value, encoded) - if err != nil { - return nil, err - } - - naddr, nerr := address.NewFromBytes(ret) - if nerr != nil { - return nil, aerrors.Absorb(nerr, 2, "could not read address of new actor") - } - - ncid, err := MinerSetAdd(context.TODO(), vmctx, self.Miners, naddr) - if err != nil { - return nil, err - } - self.Miners = ncid - self.MinerCount++ - - nroot, err := vmctx.Storage().Put(&self) - if err != nil { - return nil, err - } - - if err := vmctx.Storage().Commit(old, nroot); err != nil { - return nil, err - } - - return naddr.Bytes(), nil -} - -type ArbitrateConsensusFaultParams struct { - Block1 *types.BlockHeader - Block2 *types.BlockHeader -} - -func (spa StoragePowerActor) ArbitrateConsensusFault(act *types.Actor, vmctx types.VMContext, params *ArbitrateConsensusFaultParams) ([]byte, ActorError) { - if params == nil || params.Block1 == nil || params.Block2 == nil { - return nil, aerrors.New(1, "failed to parse params") - } - - if params.Block1.Miner != params.Block2.Miner { - return nil, aerrors.New(2, "blocks must be from the same miner") - } - - if params.Block1.Cid() == params.Block2.Cid() { - return nil, aerrors.New(3, "blocks must be different") - } - - rval, err := vmctx.Send(params.Block1.Miner, MAMethods.GetWorkerAddr, types.NewInt(0), nil) - if err != nil { - return nil, aerrors.Wrap(err, "failed to get miner worker") - } - - worker, oerr := address.NewFromBytes(rval) - if oerr != nil { - // REVIEW: should this be fatal? i can't think of a real situation that would get us here - return nil, aerrors.Absorb(oerr, 3, "response from 'GetWorkerAddr' was not a valid address") - } - - if err := sigs.CheckBlockSignature(params.Block1, vmctx.Context(), worker); err != nil { - return nil, aerrors.Absorb(err, 4, "block1 did not have valid signature") - } - - if err := sigs.CheckBlockSignature(params.Block2, vmctx.Context(), worker); err != nil { - return nil, aerrors.Absorb(err, 5, "block2 did not have valid signature") - } - - // see the "Consensus Faults" section of the faults spec (faults.md) - // for details on these slashing conditions. - if !shouldSlash(params.Block1, params.Block2) { - return nil, aerrors.New(6, "blocks do not prove a slashable offense") - } - - var self StoragePowerState - old := vmctx.Storage().GetHead() - if err := vmctx.Storage().Get(old, &self); err != nil { - return nil, err - } - - if types.BigCmp(self.TotalStorage, types.NewInt(0)) == 0 { - return nil, aerrors.Fatal("invalid state, storage power actor has zero total storage") - } - - miner := params.Block1.Miner - if has, err := MinerSetHas(vmctx, self.Miners, miner); err != nil { - return nil, aerrors.Wrapf(err, "failed to check miner in set") - } else if !has { - return nil, aerrors.New(7, "either already slashed or not a miner") - } - - minerPower, err := powerLookup(context.TODO(), vmctx, &self, miner) - if err != nil { - return nil, err - } - - slashedCollateral, err := pledgeCollateralForSize(vmctx, minerPower, self.TotalStorage, self.MinerCount) - if err != nil { - return nil, err - } - - enc, err := SerializeParams(&MinerSlashConsensusFault{ - Slasher: vmctx.Message().From, - AtHeight: params.Block1.Height, - SlashedCollateral: slashedCollateral, - }) - if err != nil { - return nil, err - } - - _, err = vmctx.Send(miner, MAMethods.SlashConsensusFault, types.NewInt(0), enc) - if err != nil { - return nil, err - } - - // Remove the miner from the list of network miners - ncid, err := MinerSetRemove(context.TODO(), vmctx, self.Miners, miner) - if err != nil { - return nil, err - } - self.Miners = ncid - self.MinerCount-- - - self.TotalStorage = types.BigSub(self.TotalStorage, minerPower) - - nroot, err := vmctx.Storage().Put(&self) - if err != nil { - return nil, err - } - - if err := vmctx.Storage().Commit(old, nroot); err != nil { - return nil, err - } - - return nil, nil -} - -func cidArrContains(a []cid.Cid, b cid.Cid) bool { - for _, c := range a { - if b == c { - return true - } - } - - return false -} - -func shouldSlash(block1, block2 *types.BlockHeader) bool { - // First slashing condition, blocks have the same ticket round - if block1.Height == block2.Height { - return true - } - - /* Second slashing condition requires having access to the parent tipset blocks - // This might not always be available, needs some thought on the best way to deal with this - - - // Second slashing condition, miner ignored own block when mining - // Case A: block2 could have been in block1's parent set but is not - b1ParentHeight := block1.Height - len(block1.Tickets) - - block1ParentTipSet := block1.Parents - if !cidArrContains(block1.Parents, block2.Cid()) && - b1ParentHeight == block2.Height && - block1ParentTipSet.ParentCids == block2.ParentCids { - return true - } - - // Case B: block1 could have been in block2's parent set but is not - block2ParentTipSet := parentOf(block2) - if !block2Parent.contains(block1) && - block2ParentTipSet.Height == block1.Height && - block2ParentTipSet.ParentCids == block1.ParentCids { - return true - } - - */ - - return false -} - -type UpdateStorageParams struct { - Delta types.BigInt - NextSlashDeadline uint64 - PreviousSlashDeadline uint64 -} - -func (spa StoragePowerActor) UpdateStorage(act *types.Actor, vmctx types.VMContext, params *UpdateStorageParams) ([]byte, ActorError) { - ctx := vmctx.Context() - var self StoragePowerState - old := vmctx.Storage().GetHead() - if err := vmctx.Storage().Get(old, &self); err != nil { - return nil, err - } - - has, err := MinerSetHas(vmctx, self.Miners, vmctx.Message().From) - if err != nil { - return nil, err - } - if !has { - return nil, aerrors.New(1, "update storage must only be called by a miner actor") - } - - self.TotalStorage = types.BigAdd(self.TotalStorage, params.Delta) - - previousBucket := params.PreviousSlashDeadline % build.SlashablePowerDelay - nextBucket := params.NextSlashDeadline % build.SlashablePowerDelay - - if previousBucket == nextBucket && params.PreviousSlashDeadline != 0 { - nroot, err := vmctx.Storage().Put(&self) - if err != nil { - return nil, err - } - - if err := vmctx.Storage().Commit(old, nroot); err != nil { - return nil, err - } - - return nil, nil // Nothing to do - } - - buckets, eerr := amt.LoadAMT(ctx, vmctx.Ipld(), self.ProvingBuckets) - if eerr != nil { - return nil, aerrors.HandleExternalError(eerr, "loading proving buckets amt") - } - - if params.PreviousSlashDeadline != 0 { // delete from previous bucket - err := deleteMinerFromBucket(vmctx, buckets, previousBucket) - if err != nil { - return nil, aerrors.Wrapf(err, "delete from bucket %d, next %d", previousBucket, nextBucket) - } - } - - err = addMinerToBucket(vmctx, buckets, nextBucket) - if err != nil { - return nil, err - } - - self.ProvingBuckets, eerr = buckets.Flush(ctx) - if eerr != nil { - return nil, aerrors.HandleExternalError(eerr, "flushing proving buckets") - } - - nroot, err := vmctx.Storage().Put(&self) - if err != nil { - return nil, err - } - - if err := vmctx.Storage().Commit(old, nroot); err != nil { - return nil, err - } - - return nil, nil -} - -func deleteMinerFromBucket(vmctx types.VMContext, buckets *amt.Root, previousBucket uint64) aerrors.ActorError { - ctx := vmctx.Context() - var bucket cid.Cid - err := buckets.Get(ctx, previousBucket, &bucket) - switch err.(type) { - case *amt.ErrNotFound: - return aerrors.HandleExternalError(err, "proving bucket missing") - case nil: // noop - default: - return aerrors.HandleExternalError(err, "getting proving bucket") - } - - bhamt, err := hamt.LoadNode(vmctx.Context(), vmctx.Ipld(), bucket) - if err != nil { - return aerrors.HandleExternalError(err, "failed to load proving bucket") - } - err = bhamt.Delete(vmctx.Context(), string(vmctx.Message().From.Bytes())) - if err != nil { - return aerrors.HandleExternalError(err, "deleting miner from proving bucket") - } - - err = bhamt.Flush(vmctx.Context()) - if err != nil { - return aerrors.HandleExternalError(err, "flushing previous proving bucket") - } - - bucket, err = vmctx.Ipld().Put(vmctx.Context(), bhamt) - if err != nil { - return aerrors.HandleExternalError(err, "putting previous proving bucket hamt") - } - - err = buckets.Set(ctx, previousBucket, bucket) - if err != nil { - return aerrors.HandleExternalError(err, "setting previous proving bucket cid in amt") - } - - return nil -} - -func addMinerToBucket(vmctx types.VMContext, buckets *amt.Root, nextBucket uint64) aerrors.ActorError { - ctx := vmctx.Context() - var bhamt *hamt.Node - var bucket cid.Cid - err := buckets.Get(ctx, nextBucket, &bucket) - switch err.(type) { - case *amt.ErrNotFound: - bhamt = hamt.NewNode(vmctx.Ipld()) - case nil: - bhamt, err = hamt.LoadNode(vmctx.Context(), vmctx.Ipld(), bucket) - if err != nil { - return aerrors.HandleExternalError(err, "failed to load proving bucket") - } - default: - return aerrors.HandleExternalError(err, "getting proving bucket") - } - - err = bhamt.Set(vmctx.Context(), string(vmctx.Message().From.Bytes()), CborNull) - if err != nil { - return aerrors.HandleExternalError(err, "setting miner in proving bucket") - } - - err = bhamt.Flush(vmctx.Context()) - if err != nil { - return aerrors.HandleExternalError(err, "flushing previous proving bucket") - } - - bucket, err = vmctx.Ipld().Put(vmctx.Context(), bhamt) - if err != nil { - return aerrors.HandleExternalError(err, "putting previous proving bucket hamt") - } - - err = buckets.Set(ctx, nextBucket, bucket) - if err != nil { - return aerrors.HandleExternalError(err, "setting previous proving bucket cid in amt") - } - return nil -} - -func (spa StoragePowerActor) GetTotalStorage(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) { - var self StoragePowerState - if err := vmctx.Storage().Get(vmctx.Storage().GetHead(), &self); err != nil { - return nil, err - } - - return self.TotalStorage.Bytes(), nil -} - -type PowerLookupParams struct { - Miner address.Address -} - -func (spa StoragePowerActor) PowerLookup(act *types.Actor, vmctx types.VMContext, params *PowerLookupParams) ([]byte, ActorError) { - var self StoragePowerState - if err := vmctx.Storage().Get(vmctx.Storage().GetHead(), &self); err != nil { - return nil, aerrors.Wrap(err, "getting head") - } - - pow, err := powerLookup(context.TODO(), vmctx, &self, params.Miner) - if err != nil { - return nil, err - } - - return pow.Bytes(), nil -} - -func powerLookup(ctx context.Context, vmctx types.VMContext, self *StoragePowerState, miner address.Address) (types.BigInt, ActorError) { - has, err := MinerSetHas(vmctx, self.Miners, miner) - if err != nil { - return types.EmptyInt, err - } - - if !has { - // A miner could be registered with storage power actor, but removed for some reasons, e.g. consensus fault - return types.EmptyInt, aerrors.New(1, "miner not registered with storage power actor, or removed already") - } - - // TODO: Use local amt - ret, err := vmctx.Send(miner, MAMethods.GetPower, types.NewInt(0), nil) - if err != nil { - return types.EmptyInt, aerrors.Wrap(err, "invoke Miner.GetPower") - } - - return types.BigFromBytes(ret), nil -} - -type IsValidMinerParam struct { - Addr address.Address -} - -func (spa StoragePowerActor) IsValidMiner(act *types.Actor, vmctx types.VMContext, param *IsValidMinerParam) ([]byte, ActorError) { - var self StoragePowerState - if err := vmctx.Storage().Get(vmctx.Storage().GetHead(), &self); err != nil { - return nil, err - } - - has, err := MinerSetHas(vmctx, self.Miners, param.Addr) - if err != nil { - return nil, err - } - - if !has { - log.Warnf("Miner INVALID: not in set: %s", param.Addr) - - return cbg.CborBoolFalse, nil - } - - ret, err := vmctx.Send(param.Addr, MAMethods.IsSlashed, types.NewInt(0), nil) - if err != nil { - return nil, err - } - - slashed := bytes.Equal(ret, cbg.CborBoolTrue) - - if slashed { - log.Warnf("Miner INVALID: /SLASHED/ : %s", param.Addr) - } - - return cbg.EncodeBool(!slashed), nil -} - -type PledgeCollateralParams struct { - Size types.BigInt -} - -func (spa StoragePowerActor) PledgeCollateralForSize(act *types.Actor, vmctx types.VMContext, param *PledgeCollateralParams) ([]byte, ActorError) { - var self StoragePowerState - if err := vmctx.Storage().Get(vmctx.Storage().GetHead(), &self); err != nil { - return nil, err - } - - totalCollateral, err := pledgeCollateralForSize(vmctx, param.Size, self.TotalStorage, self.MinerCount) - if err != nil { - return nil, err - } - - return totalCollateral.Bytes(), nil -} - -func pledgeCollateralForSize(vmctx types.VMContext, size, totalStorage types.BigInt, minerCount uint64) (types.BigInt, aerrors.ActorError) { - netBalance, err := vmctx.GetBalance(NetworkAddress) - if err != nil { - return types.EmptyInt, err - } - - // TODO: the spec says to also grab 'total vested filecoin' and include it as available - // If we don't factor that in, we effectively assume all of the locked up filecoin is 'available' - // the blocker on that right now is that its hard to tell how much filecoin is unlocked - - availableFilecoin := types.BigSub( - types.BigMul(types.NewInt(build.TotalFilecoin), types.NewInt(build.FilecoinPrecision)), - netBalance, - ) - - totalPowerCollateral := types.BigDiv( - types.BigMul( - availableFilecoin, - types.NewInt(build.PowerCollateralProportion), - ), - types.NewInt(build.CollateralPrecision), - ) - - totalPerCapitaCollateral := types.BigDiv( - types.BigMul( - availableFilecoin, - types.NewInt(build.PerCapitaCollateralProportion), - ), - types.NewInt(build.CollateralPrecision), - ) - - // REVIEW: for bootstrapping purposes, we skip the power portion of the - // collateral if there is no collateral in the network yet - powerCollateral := types.NewInt(0) - if types.BigCmp(totalStorage, types.NewInt(0)) != 0 { - powerCollateral = types.BigDiv( - types.BigMul( - totalPowerCollateral, - size, - ), - totalStorage, - ) - } - - perCapCollateral := types.BigDiv( - totalPerCapitaCollateral, - types.NewInt(minerCount), - ) - - return types.BigAdd(powerCollateral, perCapCollateral), nil -} - -func (spa StoragePowerActor) CheckProofSubmissions(act *types.Actor, vmctx types.VMContext, param *struct{}) ([]byte, ActorError) { - if vmctx.Message().From != CronAddress { - return nil, aerrors.New(1, "CheckProofSubmissions is only callable from the cron actor") - } - - var self StoragePowerState - old := vmctx.Storage().GetHead() - if err := vmctx.Storage().Get(old, &self); err != nil { - return nil, err - } - - for i := self.LastMinerCheck; i < vmctx.BlockHeight(); i++ { - height := i + 1 - - err := checkProofSubmissionsAtH(vmctx, &self, height) - if err != nil { - return nil, err - } - } - - self.LastMinerCheck = vmctx.BlockHeight() - - nroot, aerr := vmctx.Storage().Put(&self) - if aerr != nil { - return nil, aerr - } - - if err := vmctx.Storage().Commit(old, nroot); err != nil { - return nil, err - } - - return nil, nil -} - -func checkProofSubmissionsAtH(vmctx types.VMContext, self *StoragePowerState, height uint64) aerrors.ActorError { - ctx := vmctx.Context() - bucketID := height % build.SlashablePowerDelay - - buckets, eerr := amt.LoadAMT(ctx, vmctx.Ipld(), self.ProvingBuckets) - if eerr != nil { - return aerrors.HandleExternalError(eerr, "loading proving buckets amt") - } - - var bucket cid.Cid - err := buckets.Get(ctx, bucketID, &bucket) - switch err.(type) { - case *amt.ErrNotFound: - return nil // nothing to do - case nil: - default: - return aerrors.HandleExternalError(err, "getting proving bucket") - } - - bhamt, err := hamt.LoadNode(vmctx.Context(), vmctx.Ipld(), bucket) - if err != nil { - return aerrors.HandleExternalError(err, "failed to load proving bucket") - } - - forRemoval := make([]address.Address, 0) - - err = bhamt.ForEach(vmctx.Context(), func(k string, val interface{}) error { - _, span := trace.StartSpan(vmctx.Context(), "StoragePowerActor.CheckProofSubmissions.loop") - defer span.End() - - maddr, err := address.NewFromBytes([]byte(k)) - if err != nil { - return aerrors.Escalate(err, "parsing miner address") - } - - has, aerr := MinerSetHas(vmctx, self.Miners, maddr) - if aerr != nil { - return aerr - } - - if !has { - forRemoval = append(forRemoval, maddr) - } - - span.AddAttributes(trace.StringAttribute("miner", maddr.String())) - - params, err := SerializeParams(&CheckMinerParams{NetworkPower: self.TotalStorage}) - if err != nil { - return err - } - - ret, err := vmctx.Send(maddr, MAMethods.CheckMiner, types.NewInt(0), params) - if err != nil { - return err - } - - if len(ret) == 0 { - return nil // miner is fine - } - - var power types.BigInt - if err := power.UnmarshalCBOR(bytes.NewReader(ret)); err != nil { - return xerrors.Errorf("unmarshaling CheckMiner response (%x): %w", ret, err) - } - - if power.GreaterThan(types.NewInt(0)) { - log.Warnf("slashing miner %s for missed PoSt (%s B, H: %d, Bucket: %d)", maddr, power, height, bucketID) - - self.TotalStorage = types.BigSub(self.TotalStorage, power) - } - return nil - }) - - if err != nil { - return aerrors.HandleExternalError(err, "iterating miners in proving bucket") - } - - if len(forRemoval) > 0 { - nBucket, err := MinerSetRemove(vmctx.Context(), vmctx, bucket, forRemoval...) - - if err != nil { - return aerrors.Wrap(err, "could not remove miners from set") - } - - eerr := buckets.Set(ctx, bucketID, nBucket) - if err != nil { - return aerrors.HandleExternalError(eerr, "could not set the bucket") - } - ncid, eerr := buckets.Flush(ctx) - if err != nil { - return aerrors.HandleExternalError(eerr, "could not flush buckets") - } - self.ProvingBuckets = ncid - } - - return nil -} - -func MinerSetHas(vmctx types.VMContext, rcid cid.Cid, maddr address.Address) (bool, aerrors.ActorError) { - nd, err := hamt.LoadNode(vmctx.Context(), vmctx.Ipld(), rcid) - if err != nil { - return false, aerrors.HandleExternalError(err, "failed to load miner set") - } - - err = nd.Find(vmctx.Context(), string(maddr.Bytes()), nil) - switch err { - case hamt.ErrNotFound: - return false, nil - case nil: - return true, nil - default: - return false, aerrors.HandleExternalError(err, "failed to do set lookup") - } -} - -func MinerSetList(ctx context.Context, cst cbor.IpldStore, rcid cid.Cid) ([]address.Address, error) { - nd, err := hamt.LoadNode(ctx, cst, rcid) - if err != nil { - return nil, xerrors.Errorf("failed to load miner set: %w", err) - } - - var out []address.Address - err = nd.ForEach(ctx, func(k string, val interface{}) error { - addr, err := address.NewFromBytes([]byte(k)) - if err != nil { - return err - } - out = append(out, addr) - return nil - }) - if err != nil { - return nil, err - } - - return out, nil -} - -func MinerSetAdd(ctx context.Context, vmctx types.VMContext, rcid cid.Cid, maddr address.Address) (cid.Cid, aerrors.ActorError) { - nd, err := hamt.LoadNode(ctx, vmctx.Ipld(), rcid) - if err != nil { - return cid.Undef, aerrors.HandleExternalError(err, "failed to load miner set") - } - - mkey := string(maddr.Bytes()) - err = nd.Find(ctx, mkey, nil) - if err == nil { - return cid.Undef, aerrors.New(20, "miner already in set") - } - - if !xerrors.Is(err, hamt.ErrNotFound) { - return cid.Undef, aerrors.HandleExternalError(err, "failed to do miner set check") - } - - if err := nd.Set(ctx, mkey, uint64(1)); err != nil { - return cid.Undef, aerrors.HandleExternalError(err, "adding miner address to set failed") - } - - if err := nd.Flush(ctx); err != nil { - return cid.Undef, aerrors.HandleExternalError(err, "failed to flush miner set") - } - - c, err := vmctx.Ipld().Put(ctx, nd) - if err != nil { - return cid.Undef, aerrors.HandleExternalError(err, "failed to persist miner set to storage") - } - - return c, nil -} - -func MinerSetRemove(ctx context.Context, vmctx types.VMContext, rcid cid.Cid, maddrs ...address.Address) (cid.Cid, aerrors.ActorError) { - nd, err := hamt.LoadNode(ctx, vmctx.Ipld(), rcid) - if err != nil { - return cid.Undef, aerrors.HandleExternalError(err, "failed to load miner set") - } - - for _, maddr := range maddrs { - mkey := string(maddr.Bytes()) - switch nd.Delete(ctx, mkey) { - default: - return cid.Undef, aerrors.HandleExternalError(err, "failed to delete miner from set") - case hamt.ErrNotFound: - return cid.Undef, aerrors.New(1, "miner not found in set on delete") - case nil: - } - } - - if err := nd.Flush(ctx); err != nil { - return cid.Undef, aerrors.HandleExternalError(err, "failed to flush miner set") - } - - c, err := vmctx.Ipld().Put(ctx, nd) - if err != nil { - return cid.Undef, aerrors.HandleExternalError(err, "failed to persist miner set to storage") - } - - return c, nil -} - -type cbgNull struct{} - -var CborNull = &cbgNull{} - -func (cbgNull) MarshalCBOR(w io.Writer) error { - n, err := w.Write(cbg.CborNull) - if err != nil { - return err - } - if n != 1 { - return xerrors.New("expected to write 1 byte") - } - return nil -} - -func (cbgNull) UnmarshalCBOR(r io.Reader) error { - b := [1]byte{} - n, err := r.Read(b[:]) - if err != nil { - return err - } - if n != 1 { - return xerrors.New("expected 1 byte") - } - if !bytes.Equal(b[:], cbg.CborNull) { - return xerrors.New("expected cbor null") - } - return nil -} diff --git a/chain/actors/actors.go b/chain/actors/actors.go deleted file mode 100644 index 3203980f2..000000000 --- a/chain/actors/actors.go +++ /dev/null @@ -1,66 +0,0 @@ -package actors - -import ( - "github.com/filecoin-project/go-address" - - "github.com/ipfs/go-cid" - mh "github.com/multiformats/go-multihash" -) - -var AccountCodeCid cid.Cid -var CronCodeCid cid.Cid -var StoragePowerCodeCid cid.Cid -var StorageMarketCodeCid cid.Cid -var StorageMinerCodeCid cid.Cid -var MultisigCodeCid cid.Cid -var InitCodeCid cid.Cid -var PaymentChannelCodeCid cid.Cid - -var SystemAddress = mustIDAddress(0) -var InitAddress = mustIDAddress(1) -var RewardActor = mustIDAddress(2) -var CronAddress = mustIDAddress(3) -var StoragePowerAddress = mustIDAddress(4) -var StorageMarketAddress = mustIDAddress(5) - -var NetworkAddress = mustIDAddress(17) // TODO: needs to be removed in favor of reward actor - -var BurntFundsAddress = mustIDAddress(99) - -func mustIDAddress(i uint64) address.Address { - a, err := address.NewIDAddress(i) - if err != nil { - panic(err) // ok - } - return a -} - -func init() { - pref := cid.NewPrefixV1(cid.Raw, mh.IDENTITY) - mustSum := func(s string) cid.Cid { - c, err := pref.Sum([]byte(s)) - if err != nil { - panic(err) // ok - } - return c - } - - AccountCodeCid = mustSum("fil/1/account") // TODO: spec - CronCodeCid = mustSum("fil/1/cron") - StoragePowerCodeCid = mustSum("fil/1/power") - StorageMarketCodeCid = mustSum("fil/1/market") - StorageMinerCodeCid = mustSum("fil/1/miner") - MultisigCodeCid = mustSum("fil/1/multisig") - InitCodeCid = mustSum("fil/1/init") - PaymentChannelCodeCid = mustSum("fil/1/paych") - - BuiltInActors = map[cid.Cid]bool{ - StorageMarketCodeCid: true, - StoragePowerCodeCid: true, - StorageMinerCodeCid: true, - AccountCodeCid: true, - InitCodeCid: true, - MultisigCodeCid: true, - PaymentChannelCodeCid: true, - } -} diff --git a/chain/actors/actors_test.go b/chain/actors/actors_test.go index 30f7b702e..6e832d0da 100644 --- a/chain/actors/actors_test.go +++ b/chain/actors/actors_test.go @@ -7,15 +7,16 @@ import ( "testing" "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/gen/genesis" "github.com/filecoin-project/go-address" + dstore "github.com/ipfs/go-datastore" + bstore "github.com/ipfs/go-ipfs-blockstore" + . "github.com/filecoin-project/lotus/chain/actors" - "github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/vm" - dstore "github.com/ipfs/go-datastore" - bstore "github.com/ipfs/go-ipfs-blockstore" ) func blsaddr(n uint64) address.Address { @@ -40,7 +41,7 @@ func setupVMTestEnv(t *testing.T) (*vm.VM, []address.Address, bstore.Blockstore) from: types.NewInt(1000000), maddr: types.NewInt(0), } - st, err := gen.MakeInitialStateTree(bs, actors) + st, err := genesis.MakeInitialStateTree(bs, actors) if err != nil { t.Fatal(err) } diff --git a/chain/actors/address.go b/chain/actors/address.go deleted file mode 100644 index eb3bcbff3..000000000 --- a/chain/actors/address.go +++ /dev/null @@ -1,14 +0,0 @@ -package actors - -import ( - "github.com/filecoin-project/go-address" - "github.com/filecoin-project/lotus/chain/actors/aerrors" -) - -func NewIDAddress(id uint64) (address.Address, ActorError) { - a, err := address.NewIDAddress(id) - if err != nil { - return address.Undef, aerrors.Escalate(err, "could not create ID Address") - } - return a, nil -} diff --git a/chain/actors/aerrors/wrap.go b/chain/actors/aerrors/wrap.go index 928d3fb70..324eeb4e1 100644 --- a/chain/actors/aerrors/wrap.go +++ b/chain/actors/aerrors/wrap.go @@ -48,6 +48,26 @@ func Newf(retCode uint8, format string, args ...interface{}) ActorError { } } +// todo: bit hacky +func NewfSkip(skip int, retCode uint8, format string, args ...interface{}) ActorError { + if retCode == 0 { + return &actorError{ + fatal: true, + retCode: 0, + + msg: "tried creating an error and setting RetCode to 0", + frame: xerrors.Caller(skip), + err: fmt.Errorf(format, args...), + } + } + return &actorError{ + retCode: retCode, + + msg: fmt.Sprintf(format, args...), + frame: xerrors.Caller(skip), + } +} + func Fatal(message string, args ...interface{}) ActorError { return &actorError{ fatal: true, diff --git a/chain/actors/cbor_gen.go b/chain/actors/cbor_gen.go deleted file mode 100644 index 10c04c778..000000000 --- a/chain/actors/cbor_gen.go +++ /dev/null @@ -1,3339 +0,0 @@ -// Code generated by github.com/whyrusleeping/cbor-gen. DO NOT EDIT. - -package actors - -import ( - "fmt" - "io" - "sort" - - "github.com/filecoin-project/lotus/chain/types" - "github.com/libp2p/go-libp2p-core/peer" - cbg "github.com/whyrusleeping/cbor-gen" - xerrors "golang.org/x/xerrors" -) - -var _ = xerrors.Errorf - -func (t *InitActorState) 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.AddressMap (cid.Cid) (struct) - - if err := cbg.WriteCid(w, t.AddressMap); err != nil { - return xerrors.Errorf("failed to write cid field t.AddressMap: %w", err) - } - - // t.NextID (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.NextID))); err != nil { - return err - } - return nil -} - -func (t *InitActorState) 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.AddressMap (cid.Cid) (struct) - - { - - c, err := cbg.ReadCid(br) - if err != nil { - return xerrors.Errorf("failed to read cid field t.AddressMap: %w", err) - } - - t.AddressMap = c - - } - // t.NextID (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.NextID = uint64(extra) - return nil -} - -func (t *ExecParams) 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.Code (cid.Cid) (struct) - - if err := cbg.WriteCid(w, t.Code); err != nil { - return xerrors.Errorf("failed to write cid field t.Code: %w", err) - } - - // t.Params ([]uint8) (slice) - if len(t.Params) > cbg.ByteArrayMaxLen { - return xerrors.Errorf("Byte array in field t.Params was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Params)))); err != nil { - return err - } - if _, err := w.Write(t.Params); err != nil { - return err - } - return nil -} - -func (t *ExecParams) 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.Code (cid.Cid) (struct) - - { - - c, err := cbg.ReadCid(br) - if err != nil { - return xerrors.Errorf("failed to read cid field t.Code: %w", err) - } - - t.Code = c - - } - // t.Params ([]uint8) (slice) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.ByteArrayMaxLen { - return fmt.Errorf("t.Params: byte array too large (%d)", extra) - } - if maj != cbg.MajByteString { - return fmt.Errorf("expected byte array") - } - t.Params = make([]byte, extra) - if _, err := io.ReadFull(br, t.Params); err != nil { - return err - } - return nil -} - -func (t *AccountActorState) 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.Address (address.Address) (struct) - if err := t.Address.MarshalCBOR(w); err != nil { - return err - } - return nil -} - -func (t *AccountActorState) 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.Address (address.Address) (struct) - - { - - if err := t.Address.UnmarshalCBOR(br); err != nil { - return err - } - - } - return nil -} - -func (t *StorageMinerActorState) MarshalCBOR(w io.Writer) error { - if t == nil { - _, err := w.Write(cbg.CborNull) - return err - } - if _, err := w.Write([]byte{138}); err != nil { - return err - } - - // t.PreCommittedSectors (map[string]*actors.PreCommittedSector) (map) - { - if len(t.PreCommittedSectors) > 4096 { - return xerrors.Errorf("cannot marshal t.PreCommittedSectors map too large") - } - - if err := cbg.CborWriteHeader(w, cbg.MajMap, uint64(len(t.PreCommittedSectors))); err != nil { - return err - } - - keys := make([]string, 0, len(t.PreCommittedSectors)) - for k := range t.PreCommittedSectors { - keys = append(keys, k) - } - sort.Strings(keys) - for _, k := range keys { - v := t.PreCommittedSectors[k] - - if len(k) > cbg.MaxLength { - return xerrors.Errorf("Value in field k was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(k)))); err != nil { - return err - } - if _, err := w.Write([]byte(k)); err != nil { - return err - } - - if err := v.MarshalCBOR(w); err != nil { - return err - } - - } - } - - // t.Sectors (cid.Cid) (struct) - - if err := cbg.WriteCid(w, t.Sectors); err != nil { - return xerrors.Errorf("failed to write cid field t.Sectors: %w", err) - } - - // t.ProvingSet (cid.Cid) (struct) - - if err := cbg.WriteCid(w, t.ProvingSet); err != nil { - return xerrors.Errorf("failed to write cid field t.ProvingSet: %w", err) - } - - // t.Info (cid.Cid) (struct) - - if err := cbg.WriteCid(w, t.Info); err != nil { - return xerrors.Errorf("failed to write cid field t.Info: %w", err) - } - - // t.FaultSet (types.BitField) (struct) - if err := t.FaultSet.MarshalCBOR(w); err != nil { - return err - } - - // t.LastFaultSubmission (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.LastFaultSubmission))); err != nil { - return err - } - - // t.Power (types.BigInt) (struct) - if err := t.Power.MarshalCBOR(w); err != nil { - return err - } - - // t.Active (bool) (bool) - if err := cbg.WriteBool(w, t.Active); err != nil { - return err - } - - // t.SlashedAt (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SlashedAt))); err != nil { - return err - } - - // t.ElectionPeriodStart (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.ElectionPeriodStart))); err != nil { - return err - } - return nil -} - -func (t *StorageMinerActorState) 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 != 10 { - return fmt.Errorf("cbor input had wrong number of fields") - } - - // t.PreCommittedSectors (map[string]*actors.PreCommittedSector) (map) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajMap { - return fmt.Errorf("expected a map (major type 5)") - } - if extra > 4096 { - return fmt.Errorf("t.PreCommittedSectors: map too large") - } - - t.PreCommittedSectors = make(map[string]*PreCommittedSector, extra) - - for i, l := 0, int(extra); i < l; i++ { - - var k string - - { - sval, err := cbg.ReadString(br) - if err != nil { - return err - } - - k = string(sval) - } - - var v *PreCommittedSector - - { - - 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 { - v = new(PreCommittedSector) - if err := v.UnmarshalCBOR(br); err != nil { - return err - } - } - - } - - t.PreCommittedSectors[k] = v - - } - // t.Sectors (cid.Cid) (struct) - - { - - c, err := cbg.ReadCid(br) - if err != nil { - return xerrors.Errorf("failed to read cid field t.Sectors: %w", err) - } - - t.Sectors = c - - } - // t.ProvingSet (cid.Cid) (struct) - - { - - c, err := cbg.ReadCid(br) - if err != nil { - return xerrors.Errorf("failed to read cid field t.ProvingSet: %w", err) - } - - t.ProvingSet = c - - } - // t.Info (cid.Cid) (struct) - - { - - c, err := cbg.ReadCid(br) - if err != nil { - return xerrors.Errorf("failed to read cid field t.Info: %w", err) - } - - t.Info = c - - } - // t.FaultSet (types.BitField) (struct) - - { - - if err := t.FaultSet.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.LastFaultSubmission (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.LastFaultSubmission = uint64(extra) - // t.Power (types.BigInt) (struct) - - { - - if err := t.Power.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.Active (bool) (bool) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajOther { - return fmt.Errorf("booleans must be major type 7") - } - switch extra { - case 20: - t.Active = false - case 21: - t.Active = true - default: - return fmt.Errorf("booleans are either major type 7, value 20 or 21 (got %d)", extra) - } - // t.SlashedAt (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.SlashedAt = uint64(extra) - // t.ElectionPeriodStart (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.ElectionPeriodStart = uint64(extra) - return nil -} - -func (t *StorageMinerConstructorParams) MarshalCBOR(w io.Writer) error { - if t == nil { - _, err := w.Write(cbg.CborNull) - return err - } - if _, err := w.Write([]byte{132}); err != nil { - return err - } - - // t.Owner (address.Address) (struct) - if err := t.Owner.MarshalCBOR(w); err != nil { - return err - } - - // t.Worker (address.Address) (struct) - if err := t.Worker.MarshalCBOR(w); err != nil { - return err - } - - // t.SectorSize (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SectorSize))); err != nil { - return err - } - - // t.PeerID (peer.ID) (string) - if len(t.PeerID) > cbg.MaxLength { - return xerrors.Errorf("Value in field t.PeerID was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.PeerID)))); err != nil { - return err - } - if _, err := w.Write([]byte(t.PeerID)); err != nil { - return err - } - 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 { - _, err := w.Write(cbg.CborNull) - return err - } - if _, err := w.Write([]byte{132}); err != nil { - return err - } - - // t.SectorNumber (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SectorNumber))); err != nil { - return err - } - - // t.CommR ([]uint8) (slice) - if len(t.CommR) > cbg.ByteArrayMaxLen { - return xerrors.Errorf("Byte array in field t.CommR was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.CommR)))); err != nil { - return err - } - if _, err := w.Write(t.CommR); err != nil { - return err - } - - // t.SealEpoch (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SealEpoch))); 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, uint64(v)); err != nil { - return err - } - } - return nil -} - -func (t *SectorPreCommitInfo) 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.SectorNumber (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.SectorNumber = uint64(extra) - // t.CommR ([]uint8) (slice) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.ByteArrayMaxLen { - return fmt.Errorf("t.CommR: byte array too large (%d)", extra) - } - if maj != cbg.MajByteString { - return fmt.Errorf("expected byte array") - } - t.CommR = make([]byte, extra) - if _, err := io.ReadFull(br, t.CommR); err != nil { - return err - } - // t.SealEpoch (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.SealEpoch = 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] = uint64(val) - } - - return nil -} - -func (t *PreCommittedSector) 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.Info (actors.SectorPreCommitInfo) (struct) - if err := t.Info.MarshalCBOR(w); err != nil { - return err - } - - // t.ReceivedEpoch (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.ReceivedEpoch))); err != nil { - return err - } - return nil -} - -func (t *PreCommittedSector) 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.Info (actors.SectorPreCommitInfo) (struct) - - { - - if err := t.Info.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.ReceivedEpoch (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.ReceivedEpoch = uint64(extra) - return nil -} - -func (t *MinerInfo) MarshalCBOR(w io.Writer) error { - if t == nil { - _, err := w.Write(cbg.CborNull) - return err - } - if _, err := w.Write([]byte{132}); err != nil { - return err - } - - // t.Owner (address.Address) (struct) - if err := t.Owner.MarshalCBOR(w); err != nil { - return err - } - - // t.Worker (address.Address) (struct) - if err := t.Worker.MarshalCBOR(w); err != nil { - return err - } - - // t.PeerID (peer.ID) (string) - if len(t.PeerID) > cbg.MaxLength { - return xerrors.Errorf("Value in field t.PeerID was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.PeerID)))); err != nil { - return err - } - if _, err := w.Write([]byte(t.PeerID)); 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 *MinerInfo) 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.PeerID (peer.ID) (string) - - { - sval, err := cbg.ReadString(br) - if err != nil { - return err - } - - t.PeerID = peer.ID(sval) - } - // 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 *SubmitFallbackPoStParams) 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.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.Candidates ([]types.EPostTicket) (slice) - if len(t.Candidates) > cbg.MaxLength { - return xerrors.Errorf("Slice value in field t.Candidates was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Candidates)))); err != nil { - return err - } - for _, v := range t.Candidates { - if err := v.MarshalCBOR(w); err != nil { - return err - } - } - return nil -} - -func (t *SubmitFallbackPoStParams) 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.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.Candidates ([]types.EPostTicket) (slice) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.MaxLength { - return fmt.Errorf("t.Candidates: array too large (%d)", extra) - } - - if maj != cbg.MajArray { - return fmt.Errorf("expected cbor array") - } - if extra > 0 { - t.Candidates = make([]types.EPostTicket, extra) - } - for i := 0; i < int(extra); i++ { - - var v types.EPostTicket - if err := v.UnmarshalCBOR(br); err != nil { - return err - } - - t.Candidates[i] = v - } - - return nil -} - -func (t *PaymentVerifyParams) 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.Extra ([]uint8) (slice) - if len(t.Extra) > cbg.ByteArrayMaxLen { - return xerrors.Errorf("Byte array in field t.Extra was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Extra)))); err != nil { - return err - } - if _, err := w.Write(t.Extra); 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 - } - return nil -} - -func (t *PaymentVerifyParams) 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.Extra ([]uint8) (slice) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.ByteArrayMaxLen { - return fmt.Errorf("t.Extra: byte array too large (%d)", extra) - } - if maj != cbg.MajByteString { - return fmt.Errorf("expected byte array") - } - t.Extra = make([]byte, extra) - if _, err := io.ReadFull(br, t.Extra); err != nil { - return err - } - // 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 - } - return nil -} - -func (t *UpdatePeerIDParams) 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.PeerID (peer.ID) (string) - if len(t.PeerID) > cbg.MaxLength { - return xerrors.Errorf("Value in field t.PeerID was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.PeerID)))); err != nil { - return err - } - if _, err := w.Write([]byte(t.PeerID)); err != nil { - return err - } - return nil -} - -func (t *UpdatePeerIDParams) 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.PeerID (peer.ID) (string) - - { - sval, err := cbg.ReadString(br) - if err != nil { - return err - } - - t.PeerID = peer.ID(sval) - } - return nil -} - -func (t *DeclareFaultsParams) 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.Faults (types.BitField) (struct) - if err := t.Faults.MarshalCBOR(w); err != nil { - return err - } - return nil -} - -func (t *DeclareFaultsParams) 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.Faults (types.BitField) (struct) - - { - - if err := t.Faults.UnmarshalCBOR(br); err != nil { - return err - } - - } - return nil -} - -func (t *PaymentChannelActorState) MarshalCBOR(w io.Writer) error { - if t == nil { - _, err := w.Write(cbg.CborNull) - return err - } - if _, err := w.Write([]byte{134}); err != nil { - return err - } - - // t.From (address.Address) (struct) - if err := t.From.MarshalCBOR(w); err != nil { - return err - } - - // t.To (address.Address) (struct) - if err := t.To.MarshalCBOR(w); err != nil { - return err - } - - // t.ToSend (types.BigInt) (struct) - if err := t.ToSend.MarshalCBOR(w); err != nil { - return err - } - - // t.ClosingAt (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.ClosingAt))); err != nil { - return err - } - - // t.MinCloseHeight (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.MinCloseHeight))); err != nil { - return err - } - - // t.LaneStates (map[string]*actors.LaneState) (map) - { - if len(t.LaneStates) > 4096 { - return xerrors.Errorf("cannot marshal t.LaneStates map too large") - } - - if err := cbg.CborWriteHeader(w, cbg.MajMap, uint64(len(t.LaneStates))); err != nil { - return err - } - - keys := make([]string, 0, len(t.LaneStates)) - for k := range t.LaneStates { - keys = append(keys, k) - } - sort.Strings(keys) - for _, k := range keys { - v := t.LaneStates[k] - - if len(k) > cbg.MaxLength { - return xerrors.Errorf("Value in field k was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(k)))); err != nil { - return err - } - if _, err := w.Write([]byte(k)); err != nil { - return err - } - - if err := v.MarshalCBOR(w); err != nil { - return err - } - - } - } - return nil -} - -func (t *PaymentChannelActorState) 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 != 6 { - return fmt.Errorf("cbor input had wrong number of fields") - } - - // t.From (address.Address) (struct) - - { - - if err := t.From.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.To (address.Address) (struct) - - { - - if err := t.To.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.ToSend (types.BigInt) (struct) - - { - - if err := t.ToSend.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.ClosingAt (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.ClosingAt = uint64(extra) - // t.MinCloseHeight (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.MinCloseHeight = uint64(extra) - // t.LaneStates (map[string]*actors.LaneState) (map) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajMap { - return fmt.Errorf("expected a map (major type 5)") - } - if extra > 4096 { - return fmt.Errorf("t.LaneStates: map too large") - } - - t.LaneStates = make(map[string]*LaneState, extra) - - for i, l := 0, int(extra); i < l; i++ { - - var k string - - { - sval, err := cbg.ReadString(br) - if err != nil { - return err - } - - k = string(sval) - } - - var v *LaneState - - { - - 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 { - v = new(LaneState) - if err := v.UnmarshalCBOR(br); err != nil { - return err - } - } - - } - - t.LaneStates[k] = v - - } - return nil -} - -func (t *PCAConstructorParams) 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.To (address.Address) (struct) - if err := t.To.MarshalCBOR(w); err != nil { - return err - } - return nil -} - -func (t *PCAConstructorParams) 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.To (address.Address) (struct) - - { - - if err := t.To.UnmarshalCBOR(br); err != nil { - return err - } - - } - return nil -} - -func (t *LaneState) 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.Closed (bool) (bool) - if err := cbg.WriteBool(w, t.Closed); err != nil { - return err - } - - // t.Redeemed (types.BigInt) (struct) - if err := t.Redeemed.MarshalCBOR(w); err != nil { - return err - } - - // t.Nonce (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Nonce))); err != nil { - return err - } - return nil -} - -func (t *LaneState) 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.Closed (bool) (bool) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajOther { - return fmt.Errorf("booleans must be major type 7") - } - switch extra { - case 20: - t.Closed = false - case 21: - t.Closed = true - default: - return fmt.Errorf("booleans are either major type 7, value 20 or 21 (got %d)", extra) - } - // t.Redeemed (types.BigInt) (struct) - - { - - if err := t.Redeemed.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.Nonce (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.Nonce = uint64(extra) - return nil -} - -func (t *PCAUpdateChannelStateParams) 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.Sv (types.SignedVoucher) (struct) - if err := t.Sv.MarshalCBOR(w); err != nil { - return err - } - - // t.Secret ([]uint8) (slice) - if len(t.Secret) > cbg.ByteArrayMaxLen { - return xerrors.Errorf("Byte array in field t.Secret was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Secret)))); err != nil { - return err - } - if _, err := w.Write(t.Secret); 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 - } - return nil -} - -func (t *PCAUpdateChannelStateParams) 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.Sv (types.SignedVoucher) (struct) - - { - - if err := t.Sv.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.Secret ([]uint8) (slice) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.ByteArrayMaxLen { - return fmt.Errorf("t.Secret: byte array too large (%d)", extra) - } - if maj != cbg.MajByteString { - return fmt.Errorf("expected byte array") - } - t.Secret = make([]byte, extra) - if _, err := io.ReadFull(br, t.Secret); err != nil { - return err - } - // 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 - } - return nil -} - -func (t *PaymentInfo) MarshalCBOR(w io.Writer) error { - if t == nil { - _, err := w.Write(cbg.CborNull) - return err - } - if _, err := w.Write([]byte{132}); err != nil { - return err - } - - // t.PayChActor (address.Address) (struct) - if err := t.PayChActor.MarshalCBOR(w); err != nil { - return err - } - - // t.Payer (address.Address) (struct) - if err := t.Payer.MarshalCBOR(w); err != nil { - return err - } - - // t.ChannelMessage (cid.Cid) (struct) - - if t.ChannelMessage == nil { - if _, err := w.Write(cbg.CborNull); err != nil { - return err - } - } else { - if err := cbg.WriteCid(w, *t.ChannelMessage); err != nil { - return xerrors.Errorf("failed to write cid field t.ChannelMessage: %w", err) - } - } - - // t.Vouchers ([]*types.SignedVoucher) (slice) - if len(t.Vouchers) > cbg.MaxLength { - return xerrors.Errorf("Slice value in field t.Vouchers was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Vouchers)))); err != nil { - return err - } - for _, v := range t.Vouchers { - if err := v.MarshalCBOR(w); err != nil { - return err - } - } - return nil -} - -func (t *PaymentInfo) 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.PayChActor (address.Address) (struct) - - { - - if err := t.PayChActor.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.Payer (address.Address) (struct) - - { - - if err := t.Payer.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.ChannelMessage (cid.Cid) (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 { - - c, err := cbg.ReadCid(br) - if err != nil { - return xerrors.Errorf("failed to read cid field t.ChannelMessage: %w", err) - } - - t.ChannelMessage = &c - } - - } - // t.Vouchers ([]*types.SignedVoucher) (slice) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.MaxLength { - return fmt.Errorf("t.Vouchers: array too large (%d)", extra) - } - - if maj != cbg.MajArray { - return fmt.Errorf("expected cbor array") - } - if extra > 0 { - t.Vouchers = make([]*types.SignedVoucher, extra) - } - for i := 0; i < int(extra); i++ { - - var v types.SignedVoucher - if err := v.UnmarshalCBOR(br); err != nil { - return err - } - - t.Vouchers[i] = &v - } - - return nil -} - -func (t *StoragePowerState) MarshalCBOR(w io.Writer) error { - if t == nil { - _, err := w.Write(cbg.CborNull) - return err - } - if _, err := w.Write([]byte{133}); err != nil { - return err - } - - // t.Miners (cid.Cid) (struct) - - if err := cbg.WriteCid(w, t.Miners); err != nil { - return xerrors.Errorf("failed to write cid field t.Miners: %w", err) - } - - // t.ProvingBuckets (cid.Cid) (struct) - - if err := cbg.WriteCid(w, t.ProvingBuckets); err != nil { - return xerrors.Errorf("failed to write cid field t.ProvingBuckets: %w", err) - } - - // t.MinerCount (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.MinerCount))); err != nil { - return err - } - - // t.LastMinerCheck (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.LastMinerCheck))); err != nil { - return err - } - - // t.TotalStorage (types.BigInt) (struct) - if err := t.TotalStorage.MarshalCBOR(w); err != nil { - return err - } - return nil -} - -func (t *StoragePowerState) 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 != 5 { - return fmt.Errorf("cbor input had wrong number of fields") - } - - // t.Miners (cid.Cid) (struct) - - { - - c, err := cbg.ReadCid(br) - if err != nil { - return xerrors.Errorf("failed to read cid field t.Miners: %w", err) - } - - t.Miners = c - - } - // t.ProvingBuckets (cid.Cid) (struct) - - { - - c, err := cbg.ReadCid(br) - if err != nil { - return xerrors.Errorf("failed to read cid field t.ProvingBuckets: %w", err) - } - - t.ProvingBuckets = c - - } - // t.MinerCount (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.MinerCount = uint64(extra) - // t.LastMinerCheck (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.LastMinerCheck = uint64(extra) - // t.TotalStorage (types.BigInt) (struct) - - { - - if err := t.TotalStorage.UnmarshalCBOR(br); err != nil { - return err - } - - } - return nil -} - -func (t *CreateStorageMinerParams) MarshalCBOR(w io.Writer) error { - if t == nil { - _, err := w.Write(cbg.CborNull) - return err - } - if _, err := w.Write([]byte{132}); err != nil { - return err - } - - // t.Owner (address.Address) (struct) - if err := t.Owner.MarshalCBOR(w); err != nil { - return err - } - - // t.Worker (address.Address) (struct) - if err := t.Worker.MarshalCBOR(w); err != nil { - return err - } - - // t.SectorSize (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SectorSize))); err != nil { - return err - } - - // t.PeerID (peer.ID) (string) - if len(t.PeerID) > cbg.MaxLength { - return xerrors.Errorf("Value in field t.PeerID was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.PeerID)))); err != nil { - return err - } - if _, err := w.Write([]byte(t.PeerID)); err != nil { - return err - } - 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 { - _, err := w.Write(cbg.CborNull) - return err - } - if _, err := w.Write([]byte{129}); err != nil { - return err - } - - // t.Miner (address.Address) (struct) - if err := t.Miner.MarshalCBOR(w); err != nil { - return err - } - return nil -} - -func (t *PowerLookupParams) 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.Miner (address.Address) (struct) - - { - - if err := t.Miner.UnmarshalCBOR(br); err != nil { - return err - } - - } - return nil -} - -func (t *UpdateStorageParams) 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.Delta (types.BigInt) (struct) - if err := t.Delta.MarshalCBOR(w); err != nil { - return err - } - - // t.NextSlashDeadline (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.NextSlashDeadline))); err != nil { - return err - } - - // t.PreviousSlashDeadline (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.PreviousSlashDeadline))); err != nil { - return err - } - return nil -} - -func (t *UpdateStorageParams) 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.Delta (types.BigInt) (struct) - - { - - if err := t.Delta.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.NextSlashDeadline (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.NextSlashDeadline = uint64(extra) - // t.PreviousSlashDeadline (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.PreviousSlashDeadline = uint64(extra) - return nil -} - -func (t *ArbitrateConsensusFaultParams) 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.Block1 (types.BlockHeader) (struct) - if err := t.Block1.MarshalCBOR(w); err != nil { - return err - } - - // t.Block2 (types.BlockHeader) (struct) - if err := t.Block2.MarshalCBOR(w); err != nil { - return err - } - return nil -} - -func (t *ArbitrateConsensusFaultParams) 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.Block1 (types.BlockHeader) (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.Block1 = new(types.BlockHeader) - if err := t.Block1.UnmarshalCBOR(br); err != nil { - return err - } - } - - } - // t.Block2 (types.BlockHeader) (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.Block2 = new(types.BlockHeader) - if err := t.Block2.UnmarshalCBOR(br); err != nil { - return err - } - } - - } - return nil -} - -func (t *PledgeCollateralParams) 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.Size (types.BigInt) (struct) - if err := t.Size.MarshalCBOR(w); err != nil { - return err - } - return nil -} - -func (t *PledgeCollateralParams) 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.Size (types.BigInt) (struct) - - { - - if err := t.Size.UnmarshalCBOR(br); err != nil { - return err - } - - } - return nil -} - -func (t *MinerSlashConsensusFault) 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.Slasher (address.Address) (struct) - if err := t.Slasher.MarshalCBOR(w); err != nil { - return err - } - - // t.AtHeight (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.AtHeight))); err != nil { - return err - } - - // t.SlashedCollateral (types.BigInt) (struct) - if err := t.SlashedCollateral.MarshalCBOR(w); err != nil { - return err - } - return nil -} - -func (t *MinerSlashConsensusFault) 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.Slasher (address.Address) (struct) - - { - - if err := t.Slasher.UnmarshalCBOR(br); err != nil { - return err - } - - } - // 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) - - { - - if err := t.SlashedCollateral.UnmarshalCBOR(br); err != nil { - return err - } - - } - 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, uint64(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] = uint64(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, uint64(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] = uint64(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, uint64(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] = uint64(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, uint64(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] = uint64(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, uint64(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] = uint64(val) - } - - return nil -} - -func (t *CheckMinerParams) 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.NetworkPower (types.BigInt) (struct) - if err := t.NetworkPower.MarshalCBOR(w); err != nil { - return err - } - return nil -} - -func (t *CheckMinerParams) 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.NetworkPower (types.BigInt) (struct) - - { - - if err := t.NetworkPower.UnmarshalCBOR(br); err != nil { - return err - } - - } - return nil -} - -func (t *CronActorState) MarshalCBOR(w io.Writer) error { - if t == nil { - _, err := w.Write(cbg.CborNull) - return err - } - if _, err := w.Write([]byte{128}); err != nil { - return err - } - return nil -} - -func (t *CronActorState) 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 != 0 { - return fmt.Errorf("cbor input had wrong number of fields") - } - - return nil -} diff --git a/chain/actors/error.go b/chain/actors/error.go deleted file mode 100644 index a24f952da..000000000 --- a/chain/actors/error.go +++ /dev/null @@ -1,5 +0,0 @@ -package actors - -import "github.com/filecoin-project/lotus/chain/actors/aerrors" - -type ActorError = aerrors.ActorError diff --git a/chain/actors/forks.go b/chain/actors/forks.go deleted file mode 100644 index 3cc5d5b74..000000000 --- a/chain/actors/forks.go +++ /dev/null @@ -1,46 +0,0 @@ -package actors - -import ( - "reflect" - "sort" - - "github.com/filecoin-project/lotus/chain/actors/aerrors" - "github.com/filecoin-project/lotus/chain/types" -) - -type update struct { - start uint64 - method interface{} -} - -func withUpdates(updates ...update) interface{} { - sort.Slice(updates, func(i, j int) bool { // so we iterate from newest below - return updates[i].start > updates[j].start - }) - - // -} - -func notFound(vmctx types.VMContext) func() ([]byte, ActorError) { - return func() ([]byte, ActorError) { - return nil, aerrors.Fatal("no code for method %d at height %d", vmctx.Message().Method, vmctx.BlockHeight()) - } -} diff --git a/chain/actors/harness2_test.go b/chain/actors/harness2_test.go index a75f69172..f9739f4a6 100644 --- a/chain/actors/harness2_test.go +++ b/chain/actors/harness2_test.go @@ -6,6 +6,8 @@ import ( "math/rand" "testing" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/go-sectorbuilder" "github.com/ipfs/go-cid" @@ -17,8 +19,9 @@ import ( "golang.org/x/xerrors" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/lotus/chain/actors" - "github.com/filecoin-project/lotus/chain/gen" + "github.com/filecoin-project/lotus/chain/gen/genesis" "github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" @@ -49,7 +52,7 @@ type Harness struct { Nonces map[address.Address]uint64 GasCharges map[address.Address]types.BigInt Rand vm.Rand - BlockHeight uint64 + BlockHeight abi.ChainEpoch lastBalanceCheck map[address.Address]types.BigInt @@ -181,7 +184,7 @@ func NewHarness(t *testing.T, options ...HarnessOpt) *Harness { } } - st, err := gen.MakeInitialStateTree(h.bs, h.HI.Addrs) + st, err := genesis.MakeInitialStateTree(h.bs, h.HI.Addrs) if err != nil { t.Fatal(err) } @@ -191,7 +194,7 @@ func NewHarness(t *testing.T, options ...HarnessOpt) *Harness { t.Fatal(err) } - stateroot, err = gen.SetupStorageMarketActor(h.bs, stateroot, nil) + stateroot, err = genesis.SetupStorageMarketActor(h.bs, stateroot, nil) if err != nil { t.Fatal(err) } diff --git a/chain/actors/params.go b/chain/actors/params.go index c713167ce..e14dcafc9 100644 --- a/chain/actors/params.go +++ b/chain/actors/params.go @@ -7,10 +7,6 @@ import ( cbg "github.com/whyrusleeping/cbor-gen" ) -var ( - EmptyStructCBOR = []byte{0xa0} -) - func SerializeParams(i cbg.CBORMarshaler) ([]byte, aerrors.ActorError) { buf := new(bytes.Buffer) if err := i.MarshalCBOR(buf); err != nil { diff --git a/chain/blocksync/blocksync_client.go b/chain/blocksync/blocksync_client.go index 4b5fd2ddf..69cd5ec7c 100644 --- a/chain/blocksync/blocksync_client.go +++ b/chain/blocksync/blocksync_client.go @@ -22,8 +22,8 @@ import ( "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" incrt "github.com/filecoin-project/lotus/lib/increadtimeout" + "github.com/filecoin-project/lotus/lib/peermgr" "github.com/filecoin-project/lotus/node/modules/dtypes" - "github.com/filecoin-project/lotus/peermgr" ) type BlockSync struct { diff --git a/chain/blocksync/cbor_gen.go b/chain/blocksync/cbor_gen.go index 1e569a3ae..6668eb3a6 100644 --- a/chain/blocksync/cbor_gen.go +++ b/chain/blocksync/cbor_gen.go @@ -7,7 +7,7 @@ import ( "io" "github.com/filecoin-project/lotus/chain/types" - "github.com/ipfs/go-cid" + cid "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" xerrors "golang.org/x/xerrors" ) @@ -38,14 +38,17 @@ func (t *BlockSyncRequest) MarshalCBOR(w io.Writer) error { } // t.RequestLength (uint64) (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.RequestLength))); err != nil { return err } // t.Options (uint64) (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Options))); err != nil { return err } + return nil } @@ -92,24 +95,32 @@ func (t *BlockSyncRequest) UnmarshalCBOR(r io.Reader) error { // t.RequestLength (uint64) (uint64) - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err + { + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.RequestLength = uint64(extra) + } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.RequestLength = uint64(extra) // t.Options (uint64) (uint64) - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err + { + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.Options = uint64(extra) + } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.Options = uint64(extra) return nil } @@ -137,6 +148,7 @@ func (t *BlockSyncResponse) MarshalCBOR(w io.Writer) error { } // t.Status (uint64) (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Status))); err != nil { return err } @@ -199,14 +211,18 @@ func (t *BlockSyncResponse) UnmarshalCBOR(r io.Reader) error { // t.Status (uint64) (uint64) - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err + { + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.Status = uint64(extra) + } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.Status = uint64(extra) // t.Message (string) (string) { diff --git a/chain/events/events.go b/chain/events/events.go index 693aaf113..217b6fb30 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.TipSetKey) (*types.TipSet, error) + ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error) StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*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 99e5ce195..3b1d86123 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 { @@ -129,7 +130,7 @@ func (e *calledEvents) checkNewCalls(ts *types.TipSet) { for _, matchFn := range matchFns { ok, err := matchFn(msg) if err != nil { - log.Warnf("event matcher failed: %s") + log.Warnf("event matcher failed: %s", err) continue } matched = ok @@ -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/events_test.go b/chain/events/events_test.go index 8c5dbdc10..eaddad69b 100644 --- a/chain/events/events_test.go +++ b/chain/events/events_test.go @@ -6,6 +6,9 @@ import ( "testing" "time" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/crypto" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/store" @@ -31,7 +34,7 @@ type fakeMsg struct { type fakeCS struct { t *testing.T - h uint64 + h abi.ChainEpoch tsc *tipSetCache msgs map[cid.Cid]fakeMsg @@ -48,11 +51,11 @@ func (fcs *fakeCS) StateGetActor(ctx context.Context, actor address.Address, tsk panic("Not Implemented") } -func (fcs *fakeCS) ChainGetTipSetByHeight(context.Context, uint64, types.TipSetKey) (*types.TipSet, error) { +func (fcs *fakeCS) ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error) { panic("Not Implemented") } -func makeTs(t *testing.T, h uint64, msgcid cid.Cid) *types.TipSet { +func makeTs(t *testing.T, h abi.ChainEpoch, msgcid cid.Cid) *types.TipSet { a, _ := address.NewFromString("t00") b, _ := address.NewFromString("t02") var ts, err = types.NewTipSet([]*types.BlockHeader{ @@ -66,8 +69,8 @@ func makeTs(t *testing.T, h uint64, msgcid cid.Cid) *types.TipSet { Messages: msgcid, ParentMessageReceipts: dummyCid, - BlockSig: &types.Signature{Type: types.KTBLS}, - BLSAggregate: types.Signature{Type: types.KTBLS}, + BlockSig: &crypto.Signature{Type: crypto.SigTypeBLS}, + BLSAggregate: crypto.Signature{Type: crypto.SigTypeBLS}, }, { Height: h, @@ -79,8 +82,8 @@ func makeTs(t *testing.T, h uint64, msgcid cid.Cid) *types.TipSet { Messages: msgcid, ParentMessageReceipts: dummyCid, - BlockSig: &types.Signature{Type: types.KTBLS}, - BLSAggregate: types.Signature{Type: types.KTBLS}, + BlockSig: &crypto.Signature{Type: crypto.SigTypeBLS}, + BLSAggregate: crypto.Signature{Type: crypto.SigTypeBLS}, }, }) @@ -206,7 +209,7 @@ func TestAt(t *testing.T) { var applied bool var reverted bool - err := events.ChainAt(func(_ context.Context, ts *types.TipSet, curH uint64) error { + err := events.ChainAt(func(_ context.Context, ts *types.TipSet, curH abi.ChainEpoch) error { require.Equal(t, 5, int(ts.Height())) require.Equal(t, 8, int(curH)) applied = true @@ -271,7 +274,7 @@ func TestAtDoubleTrigger(t *testing.T) { var applied bool var reverted bool - err := events.ChainAt(func(_ context.Context, ts *types.TipSet, curH uint64) error { + err := events.ChainAt(func(_ context.Context, ts *types.TipSet, curH abi.ChainEpoch) error { require.Equal(t, 5, int(ts.Height())) require.Equal(t, 8, int(curH)) applied = true @@ -313,8 +316,8 @@ func TestAtNullTrigger(t *testing.T) { var applied bool var reverted bool - err := events.ChainAt(func(_ context.Context, ts *types.TipSet, curH uint64) error { - require.Equal(t, uint64(6), ts.Height()) + err := events.ChainAt(func(_ context.Context, ts *types.TipSet, curH abi.ChainEpoch) error { + require.Equal(t, abi.ChainEpoch(6), ts.Height()) require.Equal(t, 8, int(curH)) applied = true return nil @@ -347,7 +350,7 @@ func TestAtNullConf(t *testing.T) { var applied bool var reverted bool - err := events.ChainAt(func(_ context.Context, ts *types.TipSet, curH uint64) error { + err := events.ChainAt(func(_ context.Context, ts *types.TipSet, curH abi.ChainEpoch) error { require.Equal(t, 5, int(ts.Height())) require.Equal(t, 8, int(curH)) applied = true @@ -388,7 +391,7 @@ func TestAtStart(t *testing.T) { var applied bool var reverted bool - err := events.ChainAt(func(_ context.Context, ts *types.TipSet, curH uint64) error { + err := events.ChainAt(func(_ context.Context, ts *types.TipSet, curH abi.ChainEpoch) error { require.Equal(t, 5, int(ts.Height())) require.Equal(t, 8, int(curH)) applied = true @@ -422,7 +425,7 @@ func TestAtStartConfidence(t *testing.T) { var applied bool var reverted bool - err := events.ChainAt(func(_ context.Context, ts *types.TipSet, curH uint64) error { + err := events.ChainAt(func(_ context.Context, ts *types.TipSet, curH abi.ChainEpoch) error { require.Equal(t, 5, int(ts.Height())) require.Equal(t, 11, int(curH)) applied = true @@ -450,8 +453,8 @@ func TestAtChained(t *testing.T) { var applied bool var reverted bool - err := events.ChainAt(func(_ context.Context, ts *types.TipSet, curH uint64) error { - return events.ChainAt(func(_ context.Context, ts *types.TipSet, curH uint64) error { + err := events.ChainAt(func(_ context.Context, ts *types.TipSet, curH abi.ChainEpoch) error { + return events.ChainAt(func(_ context.Context, ts *types.TipSet, curH abi.ChainEpoch) error { require.Equal(t, 10, int(ts.Height())) applied = true return nil @@ -486,8 +489,8 @@ func TestAtChainedConfidence(t *testing.T) { var applied bool var reverted bool - err := events.ChainAt(func(_ context.Context, ts *types.TipSet, curH uint64) error { - return events.ChainAt(func(_ context.Context, ts *types.TipSet, curH uint64) error { + err := events.ChainAt(func(_ context.Context, ts *types.TipSet, curH abi.ChainEpoch) error { + return events.ChainAt(func(_ context.Context, ts *types.TipSet, curH abi.ChainEpoch) error { require.Equal(t, 10, int(ts.Height())) applied = true return nil @@ -520,7 +523,7 @@ func TestAtChainedConfidenceNull(t *testing.T) { var applied bool var reverted bool - err := events.ChainAt(func(_ context.Context, ts *types.TipSet, curH uint64) error { + err := events.ChainAt(func(_ context.Context, ts *types.TipSet, curH abi.ChainEpoch) error { applied = true require.Equal(t, 6, int(ts.Height())) return nil @@ -534,7 +537,7 @@ func TestAtChainedConfidenceNull(t *testing.T) { require.Equal(t, false, reverted) } -func matchAddrMethod(to address.Address, m uint64) func(msg *types.Message) (bool, error) { +func matchAddrMethod(to address.Address, m abi.MethodNum) func(msg *types.Message) (bool, error) { return func(msg *types.Message) (bool, error) { return to == msg.To && m == msg.Method, nil } @@ -560,11 +563,11 @@ func TestCalled(t *testing.T) { var applied, reverted bool var appliedMsg *types.Message var appliedTs *types.TipSet - var appliedH uint64 + var appliedH abi.ChainEpoch err = events.Called(func(ts *types.TipSet) (d bool, m bool, e error) { return false, true, nil - }, func(msg *types.Message, rec *types.MessageReceipt, ts *types.TipSet, curH uint64) (bool, error) { + }, func(msg *types.Message, rec *types.MessageReceipt, ts *types.TipSet, curH abi.ChainEpoch) (bool, error) { require.Equal(t, false, applied) applied = true appliedMsg = msg @@ -610,12 +613,12 @@ func TestCalled(t *testing.T) { require.Equal(t, false, applied) require.Equal(t, false, reverted) - require.Equal(t, uint64(7), appliedTs.Height()) + require.Equal(t, abi.ChainEpoch(7), appliedTs.Height()) require.Equal(t, "bafkqaaa", appliedTs.Blocks()[0].Messages.String()) - require.Equal(t, uint64(10), appliedH) + require.Equal(t, abi.ChainEpoch(10), appliedH) require.Equal(t, t0123, appliedMsg.To) require.Equal(t, uint64(1), appliedMsg.Nonce) - require.Equal(t, uint64(5), appliedMsg.Method) + require.Equal(t, abi.MethodNum(5), appliedMsg.Method) // revert some blocks, keep the message @@ -647,12 +650,12 @@ func TestCalled(t *testing.T) { require.Equal(t, false, reverted) applied = false - require.Equal(t, uint64(9), appliedTs.Height()) + require.Equal(t, abi.ChainEpoch(9), appliedTs.Height()) require.Equal(t, "bafkqaaa", appliedTs.Blocks()[0].Messages.String()) - require.Equal(t, uint64(12), appliedH) + require.Equal(t, abi.ChainEpoch(12), appliedH) require.Equal(t, t0123, appliedMsg.To) require.Equal(t, uint64(2), appliedMsg.Nonce) - require.Equal(t, uint64(5), appliedMsg.Method) + require.Equal(t, abi.MethodNum(5), appliedMsg.Method) // revert and apply at different height @@ -668,12 +671,12 @@ func TestCalled(t *testing.T) { reverted = false applied = false - require.Equal(t, uint64(11), appliedTs.Height()) + require.Equal(t, abi.ChainEpoch(11), appliedTs.Height()) require.Equal(t, "bafkqaaa", appliedTs.Blocks()[0].Messages.String()) - require.Equal(t, uint64(14), appliedH) + require.Equal(t, abi.ChainEpoch(14), appliedH) require.Equal(t, t0123, appliedMsg.To) require.Equal(t, uint64(2), appliedMsg.Nonce) - require.Equal(t, uint64(5), appliedMsg.Method) + require.Equal(t, abi.MethodNum(5), appliedMsg.Method) // call method again @@ -765,11 +768,11 @@ func TestCalledTimeout(t *testing.T) { err = events.Called(func(ts *types.TipSet) (d bool, m bool, e error) { return false, true, nil - }, func(msg *types.Message, rec *types.MessageReceipt, ts *types.TipSet, curH uint64) (bool, error) { + }, func(msg *types.Message, rec *types.MessageReceipt, ts *types.TipSet, curH abi.ChainEpoch) (bool, error) { called = true require.Nil(t, msg) - require.Equal(t, uint64(20), ts.Height()) - require.Equal(t, uint64(23), curH) + require.Equal(t, abi.ChainEpoch(20), ts.Height()) + require.Equal(t, abi.ChainEpoch(23), curH) return false, nil }, func(_ context.Context, ts *types.TipSet) error { t.Fatal("revert on timeout") @@ -800,11 +803,11 @@ func TestCalledTimeout(t *testing.T) { err = events.Called(func(ts *types.TipSet) (d bool, m bool, e error) { return true, true, nil - }, func(msg *types.Message, rec *types.MessageReceipt, ts *types.TipSet, curH uint64) (bool, error) { + }, func(msg *types.Message, rec *types.MessageReceipt, ts *types.TipSet, curH abi.ChainEpoch) (bool, error) { called = true require.Nil(t, msg) - require.Equal(t, uint64(20), ts.Height()) - require.Equal(t, uint64(23), curH) + require.Equal(t, abi.ChainEpoch(20), ts.Height()) + require.Equal(t, abi.ChainEpoch(23), curH) return false, nil }, func(_ context.Context, ts *types.TipSet) error { t.Fatal("revert on timeout") @@ -839,14 +842,14 @@ func TestCalledOrder(t *testing.T) { err = events.Called(func(ts *types.TipSet) (d bool, m bool, e error) { return false, true, nil - }, func(msg *types.Message, rec *types.MessageReceipt, ts *types.TipSet, curH uint64) (bool, error) { + }, func(msg *types.Message, rec *types.MessageReceipt, ts *types.TipSet, curH abi.ChainEpoch) (bool, error) { switch at { case 0: require.Equal(t, uint64(1), msg.Nonce) - require.Equal(t, uint64(4), ts.Height()) + require.Equal(t, abi.ChainEpoch(4), ts.Height()) case 1: require.Equal(t, uint64(2), msg.Nonce) - require.Equal(t, uint64(5), ts.Height()) + require.Equal(t, abi.ChainEpoch(5), ts.Height()) default: t.Fatal("apply should only get called twice, at: ", at) } @@ -855,9 +858,9 @@ func TestCalledOrder(t *testing.T) { }, func(_ context.Context, ts *types.TipSet) error { switch at { case 2: - require.Equal(t, uint64(5), ts.Height()) + require.Equal(t, abi.ChainEpoch(5), ts.Height()) case 3: - require.Equal(t, uint64(4), ts.Height()) + require.Equal(t, abi.ChainEpoch(4), ts.Height()) default: t.Fatal("revert should only get called twice, at: ", at) } diff --git a/chain/events/tscache.go b/chain/events/tscache.go index beeba3fa0..7fc0e8f57 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.TipSetKey) (*types.TipSet, error) +type tsByHFunc func(context.Context, abi.ChainEpoch, types.TipSetKey) (*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, types.EmptyTSK) diff --git a/chain/events/tscache_test.go b/chain/events/tscache_test.go index fb0942bb9..66aa87f66 100644 --- a/chain/events/tscache_test.go +++ b/chain/events/tscache_test.go @@ -4,6 +4,8 @@ import ( "context" "testing" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/crypto" "github.com/stretchr/testify/require" "github.com/filecoin-project/go-address" @@ -11,12 +13,12 @@ import ( ) func TestTsCache(t *testing.T) { - tsc := newTSCache(50, func(context.Context, uint64, types.TipSetKey) (*types.TipSet, error) { + tsc := newTSCache(50, func(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error) { t.Fatal("storage call") return &types.TipSet{}, nil }) - h := uint64(75) + h := abi.ChainEpoch(75) a, _ := address.NewFromString("t00") @@ -27,8 +29,8 @@ func TestTsCache(t *testing.T) { ParentStateRoot: dummyCid, Messages: dummyCid, ParentMessageReceipts: dummyCid, - BlockSig: &types.Signature{Type: types.KTBLS}, - BLSAggregate: types.Signature{Type: types.KTBLS}, + BlockSig: &types.Signature{Type: crypto.SigTypeBLS}, + BLSAggregate: types.Signature{Type: crypto.SigTypeBLS}, }}) if err != nil { t.Fatal(err) @@ -54,12 +56,12 @@ func TestTsCache(t *testing.T) { } func TestTsCacheNulls(t *testing.T) { - tsc := newTSCache(50, func(context.Context, uint64, types.TipSetKey) (*types.TipSet, error) { + tsc := newTSCache(50, func(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error) { t.Fatal("storage call") return &types.TipSet{}, nil }) - h := uint64(75) + h := abi.ChainEpoch(75) a, _ := address.NewFromString("t00") add := func() { @@ -69,8 +71,8 @@ func TestTsCacheNulls(t *testing.T) { ParentStateRoot: dummyCid, Messages: dummyCid, ParentMessageReceipts: dummyCid, - BlockSig: &types.Signature{Type: types.KTBLS}, - BLSAggregate: types.Signature{Type: types.KTBLS}, + BlockSig: &types.Signature{Type: crypto.SigTypeBLS}, + BLSAggregate: types.Signature{Type: crypto.SigTypeBLS}, }}) if err != nil { t.Fatal(err) diff --git a/chain/gen/gen.go b/chain/gen/gen.go index 1b0b02c65..b8720c5e4 100644 --- a/chain/gen/gen.go +++ b/chain/gen/gen.go @@ -4,26 +4,29 @@ import ( "bytes" "context" "crypto/sha256" - "encoding/binary" "fmt" "io/ioutil" "sync/atomic" + "github.com/filecoin-project/go-address" + commcid "github.com/filecoin-project/go-fil-commcid" + sectorbuilder "github.com/filecoin-project/go-sectorbuilder" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/crypto" block "github.com/ipfs/go-block-format" "github.com/ipfs/go-blockservice" "github.com/ipfs/go-car" "github.com/ipfs/go-cid" blockstore "github.com/ipfs/go-ipfs-blockstore" offline "github.com/ipfs/go-ipfs-exchange-offline" + format "github.com/ipfs/go-ipld-format" logging "github.com/ipfs/go-log/v2" "github.com/ipfs/go-merkledag" - peer "github.com/libp2p/go-libp2p-core/peer" ffi "github.com/filecoin-project/filecoin-ffi" - "github.com/filecoin-project/go-address" - sectorbuilder "github.com/filecoin-project/go-sectorbuilder" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" + genesis2 "github.com/filecoin-project/lotus/chain/gen/genesis" "github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" @@ -33,6 +36,7 @@ import ( "github.com/filecoin-project/lotus/genesis" "github.com/filecoin-project/lotus/lib/sigs" "github.com/filecoin-project/lotus/node/repo" + "github.com/filecoin-project/lotus/storage/sbmock" "go.opencensus.io/trace" "golang.org/x/xerrors" @@ -54,7 +58,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) @@ -112,74 +116,81 @@ func NewGenerator() (*ChainGen, error) { return nil, xerrors.Errorf("creating memrepo wallet failed: %w", err) } - banker, err := w.GenerateKey(types.KTSecp256k1) + banker, err := w.GenerateKey(crypto.SigTypeSecp256k1) if err != nil { return nil, xerrors.Errorf("failed to generate banker key: %w", err) } receievers := make([]address.Address, msgsPerBlock) for r := range receievers { - receievers[r], err = w.GenerateKey(types.KTBLS) + receievers[r], err = w.GenerateKey(crypto.SigTypeBLS) if err != nil { return nil, xerrors.Errorf("failed to generate receiver key: %w", err) } } - maddr1, err := address.NewFromString("t0300") - if err != nil { - return nil, err - } + maddr1 := genesis2.MinerAddress(0) m1temp, err := ioutil.TempDir("", "preseal") if err != nil { return nil, err } - genm1, err := seed.PreSeal(maddr1, 1024, 0, 1, m1temp, []byte("some randomness")) + genm1, k1, err := seed.PreSeal(maddr1, 1024, 0, 1, m1temp, []byte("some randomness"), nil) if err != nil { return nil, err } - maddr2, err := address.NewFromString("t0301") - if err != nil { - return nil, err - } + maddr2 := genesis2.MinerAddress(1) m2temp, err := ioutil.TempDir("", "preseal") if err != nil { return nil, err } - genm2, err := seed.PreSeal(maddr2, 1024, 0, 1, m2temp, []byte("some randomness")) + genm2, k2, err := seed.PreSeal(maddr2, 1024, 0, 1, m2temp, []byte("some randomness"), nil) if err != nil { return nil, err } - mk1, err := w.Import(&genm1.Key) + mk1, err := w.Import(k1) if err != nil { return nil, err } - mk2, err := w.Import(&genm2.Key) + mk2, err := w.Import(k2) if err != nil { return nil, err } - minercfg := &GenMinerCfg{ - PeerIDs: []peer.ID{"peerID1", "peerID2"}, - PreSeals: map[string]genesis.GenesisMiner{ - maddr1.String(): *genm1, - maddr2.String(): *genm2, + sys := vm.Syscalls(&genFakeVerifier{}) + + tpl := genesis.Template{ + Accounts: []genesis.Actor{ + { + Type: genesis.TAccount, + Balance: types.FromFil(40000), + Meta: (&genesis.AccountMeta{Owner: mk1}).ActorMeta(), + }, + { + Type: genesis.TAccount, + Balance: types.FromFil(40000), + Meta: (&genesis.AccountMeta{Owner: mk2}).ActorMeta(), + }, + { + Type: genesis.TAccount, + Balance: types.FromFil(50000), + Meta: (&genesis.AccountMeta{Owner: banker}).ActorMeta(), + }, }, - MinerAddrs: []address.Address{maddr1, maddr2}, + Miners: []genesis.Miner{ + *genm1, + *genm2, + }, + NetworkName: "", + Timestamp: 100000, } - sys := vm.Syscalls(sectorbuilder.ProofVerifier) - - genb, err := MakeGenesisBlock(bs, sys, map[address.Address]types.BigInt{ - mk1: types.FromFil(40000), - mk2: types.FromFil(40000), - banker: types.FromFil(50000), - }, minercfg, 100000) + genb, err := genesis2.MakeGenesisBlock(context.TODO(), bs, sys, tpl) if err != nil { return nil, xerrors.Errorf("make genesis block failed: %w", err) } @@ -193,17 +204,15 @@ func NewGenerator() (*ChainGen, error) { return nil, xerrors.Errorf("set genesis failed: %w", err) } - if len(minercfg.MinerAddrs) == 0 { - return nil, xerrors.Errorf("MakeGenesisBlock failed to set miner address") - } - mgen := make(map[address.Address]ElectionPoStProver) - for _, m := range minercfg.MinerAddrs { - mgen[m] = &eppProvider{} + for i := range tpl.Miners { + mgen[genesis2.MinerAddress(uint64(i))] = &eppProvider{} } sm := stmgr.NewStateManager(cs) + miners := []address.Address{maddr1, maddr2} + gen := &ChainGen{ bs: bs, cs: cs, @@ -213,7 +222,7 @@ func NewGenerator() (*ChainGen, error) { w: w, GetMessages: getRandomMessages, - Miners: minercfg.MinerAddrs, + Miners: miners, eppProvs: mgen, banker: banker, receivers: receievers, @@ -246,16 +255,32 @@ func (cg *ChainGen) GenesisCar() ([]byte, error) { out := new(bytes.Buffer) - if err := car.WriteCar(context.TODO(), dserv, []cid.Cid{cg.Genesis().Cid()}, out); err != nil { + if err := car.WriteCarWithWalker(context.TODO(), dserv, []cid.Cid{cg.Genesis().Cid()}, out, CarWalkFunc); err != nil { return nil, xerrors.Errorf("genesis car write car failed: %w", err) } return out.Bytes(), nil } -func (cg *ChainGen) nextBlockProof(ctx context.Context, pts *types.TipSet, m address.Address, round int64) (*types.EPostProof, *types.Ticket, error) { +func CarWalkFunc(nd format.Node) (out []*format.Link, err error) { + for _, link := range nd.Links() { + if link.Cid.Prefix().MhType == uint64(commcid.FC_SEALED_V1) || link.Cid.Prefix().MhType == uint64(commcid.FC_UNSEALED_V1) { + continue + } + out = append(out, link) + } - lastTicket := pts.MinTicket() + return out, nil +} + +func (cg *ChainGen) nextBlockProof(ctx context.Context, pts *types.TipSet, m address.Address, round int64) (*types.EPostProof, *types.Ticket, error) { + mc := &mca{w: cg.w, sm: cg.sm} + + // TODO: REVIEW: Am I doing this correctly? + ticketRand, err := mc.ChainGetRandomness(ctx, pts.Key(), crypto.DomainSeparationTag_TicketProduction, pts.Height(), m.Bytes()) + if err != nil { + return nil, nil, err + } st := pts.ParentState() @@ -264,7 +289,7 @@ func (cg *ChainGen) nextBlockProof(ctx context.Context, pts *types.TipSet, m add return nil, nil, xerrors.Errorf("get miner worker: %w", err) } - vrfout, err := ComputeVRF(ctx, cg.w.Sign, worker, m, DSepTicket, lastTicket.VRFProof) + vrfout, err := ComputeVRF(ctx, cg.w.Sign, worker, ticketRand) if err != nil { return nil, nil, xerrors.Errorf("compute VRF: %w", err) } @@ -273,7 +298,7 @@ func (cg *ChainGen) nextBlockProof(ctx context.Context, pts *types.TipSet, m add VRFProof: vrfout, } - eproofin, err := IsRoundWinner(ctx, pts, round, m, cg.eppProvs[m], &mca{w: cg.w, sm: cg.sm}) + eproofin, err := IsRoundWinner(ctx, pts, round, m, cg.eppProvs[m], mc) if err != nil { return nil, nil, xerrors.Errorf("checking round winner failed: %w", err) } @@ -319,7 +344,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 +366,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) @@ -417,17 +442,17 @@ func (cg *ChainGen) YieldRepo() (repo.Repo, error) { } type MiningCheckAPI interface { - ChainGetRandomness(context.Context, types.TipSetKey, int64) ([]byte, error) + ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) StateMinerPower(context.Context, address.Address, types.TipSetKey) (api.MinerPower, error) StateMinerWorker(context.Context, address.Address, types.TipSetKey) (address.Address, error) - StateMinerSectorSize(context.Context, address.Address, types.TipSetKey) (uint64, error) + StateMinerSectorSize(context.Context, address.Address, types.TipSetKey) (abi.SectorSize, error) StateMinerProvingSet(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) - WalletSign(context.Context, address.Address, []byte) (*types.Signature, error) + WalletSign(context.Context, address.Address, []byte) (*crypto.Signature, error) } type mca struct { @@ -435,8 +460,13 @@ type mca struct { sm *stmgr.StateManager } -func (mca mca) ChainGetRandomness(ctx context.Context, pts types.TipSetKey, lb int64) ([]byte, error) { - return mca.sm.ChainStore().GetRandomness(ctx, pts.Cids(), int64(lb)) +func (mca mca) ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) { + pts, err := mca.sm.ChainStore().LoadTipSet(tsk) + if err != nil { + return nil, xerrors.Errorf("loading tipset key: %w", err) + } + + return mca.sm.ChainStore().GetRandomness(ctx, pts.Cids(), personalization, int64(randEpoch), entropy) } func (mca mca) StateMinerPower(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (api.MinerPower, error) { @@ -463,7 +493,7 @@ func (mca mca) StateMinerWorker(ctx context.Context, maddr address.Address, tsk return stmgr.GetMinerWorkerRaw(ctx, mca.sm, ts.ParentState(), maddr) } -func (mca mca) StateMinerSectorSize(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (uint64, error) { +func (mca mca) StateMinerSectorSize(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (abi.SectorSize, error) { ts, err := mca.sm.ChainStore().LoadTipSet(tsk) if err != nil { return 0, xerrors.Errorf("loading tipset %s: %w", tsk, err) @@ -479,7 +509,7 @@ func (mca mca) StateMinerProvingSet(ctx context.Context, maddr address.Address, return stmgr.GetMinerProvingSet(ctx, mca.sm, ts, maddr) } -func (mca mca) WalletSign(ctx context.Context, a address.Address, v []byte) (*types.Signature, error) { +func (mca mca) WalletSign(ctx context.Context, a address.Address, v []byte) (*crypto.Signature, error) { return mca.w.Sign(ctx, a, v) } @@ -493,7 +523,7 @@ type eppProvider struct{} func (epp *eppProvider) GenerateCandidates(ctx context.Context, _ sectorbuilder.SortedPublicSectorInfo, eprand []byte) ([]sectorbuilder.EPostCandidate, error) { return []sectorbuilder.EPostCandidate{ { - SectorID: 1, + SectorNum: 1, PartialTicket: [32]byte{}, Ticket: [32]byte{}, SectorChallengeIndex: 1, @@ -514,7 +544,7 @@ type ProofInput struct { } func IsRoundWinner(ctx context.Context, ts *types.TipSet, round int64, miner address.Address, epp ElectionPoStProver, a MiningCheckAPI) (*ProofInput, error) { - r, err := a.ChainGetRandomness(ctx, ts.Key(), round-build.EcRandomnessLookback) + epostRand, err := a.ChainGetRandomness(ctx, ts.Key(), crypto.DomainSeparationTag_ElectionPoStChallengeSeed, abi.ChainEpoch(round-build.EcRandomnessLookback), miner.Bytes()) if err != nil { return nil, xerrors.Errorf("chain get randomness: %w", err) } @@ -524,7 +554,7 @@ func IsRoundWinner(ctx context.Context, ts *types.TipSet, round int64, miner add return nil, xerrors.Errorf("failed to get miner worker: %w", err) } - vrfout, err := ComputeVRF(ctx, a.WalletSign, mworker, miner, DSepElectionPost, r) + vrfout, err := ComputeVRF(ctx, a.WalletSign, mworker, epostRand) if err != nil { return nil, xerrors.Errorf("failed to compute VRF: %w", err) } @@ -539,11 +569,15 @@ func IsRoundWinner(ctx context.Context, ts *types.TipSet, round int64, miner add var sinfos []ffi.PublicSectorInfo for _, s := range pset { + cr, err := commcid.CIDToReplicaCommitmentV1(s.Info.Info.SealedCID) + if err != nil { + return nil, xerrors.Errorf("get sealed cid: %w", err) + } var commRa [32]byte - copy(commRa[:], s.CommR) + copy(commRa[:], cr) sinfos = append(sinfos, ffi.PublicSectorInfo{ - SectorID: s.SectorID, - CommR: commRa, + SectorNum: s.ID, + CommR: commRa, }) } sectors := sectorbuilder.NewSortedPublicSectorInfo(sinfos) @@ -599,7 +633,7 @@ func ComputeProof(ctx context.Context, epp ElectionPoStProver, pi *ProofInput) ( copy(part, win.PartialTicket[:]) ept.Candidates = append(ept.Candidates, types.EPostTicket{ Partial: part, - SectorID: win.SectorID, + SectorID: win.SectorNum, ChallengeIndex: win.SectorChallengeIndex, }) } @@ -607,42 +641,14 @@ func ComputeProof(ctx context.Context, epp ElectionPoStProver, pi *ProofInput) ( return &ept, nil } -type SignFunc func(context.Context, address.Address, []byte) (*types.Signature, error) +type SignFunc func(context.Context, address.Address, []byte) (*crypto.Signature, error) -const ( - DSepTicket = 1 - DSepElectionPost = 2 -) - -func hashVRFBase(personalization uint64, miner address.Address, input []byte) ([]byte, error) { - if miner.Protocol() != address.ID { - return nil, xerrors.Errorf("miner address for compute VRF must be an ID address") - } - - var persbuf [8]byte - binary.LittleEndian.PutUint64(persbuf[:], personalization) - - h := sha256.New() - h.Write(persbuf[:]) - h.Write([]byte{0}) - h.Write(input) - h.Write([]byte{0}) - h.Write(miner.Bytes()) - - return h.Sum(nil), nil -} - -func VerifyVRF(ctx context.Context, worker, miner address.Address, p uint64, input, vrfproof []byte) error { +func VerifyVRF(ctx context.Context, worker address.Address, vrfBase, vrfproof []byte) error { _, span := trace.StartSpan(ctx, "VerifyVRF") defer span.End() - vrfBase, err := hashVRFBase(p, miner, input) - if err != nil { - return xerrors.Errorf("computing vrf base failed: %w", err) - } - - sig := &types.Signature{ - Type: types.KTBLS, + sig := &crypto.Signature{ + Type: crypto.SigTypeBLS, Data: vrfproof, } @@ -653,20 +659,34 @@ func VerifyVRF(ctx context.Context, worker, miner address.Address, p uint64, inp return nil } -func ComputeVRF(ctx context.Context, sign SignFunc, worker, miner address.Address, p uint64, input []byte) ([]byte, error) { - sigInput, err := hashVRFBase(p, miner, input) - if err != nil { - return nil, err - } - +func ComputeVRF(ctx context.Context, sign SignFunc, worker address.Address, sigInput []byte) ([]byte, error) { sig, err := sign(ctx, worker, sigInput) if err != nil { return nil, err } - if sig.Type != types.KTBLS { + if sig.Type != crypto.SigTypeBLS { return nil, fmt.Errorf("miner worker address was not a BLS key") } return sig.Data, nil } + +type genFakeVerifier struct{} + +var _ sectorbuilder.Verifier = (*genFakeVerifier)(nil) + +func (m genFakeVerifier) VerifyElectionPost(ctx context.Context, sectorSize abi.SectorSize, sectorInfo sectorbuilder.SortedPublicSectorInfo, challengeSeed []byte, proof []byte, candidates []sectorbuilder.EPostCandidate, proverID address.Address) (bool, error) { + panic("nyi") +} +func (m genFakeVerifier) GenerateDataCommitment(ssize abi.PaddedPieceSize, pieces []ffi.PublicPieceInfo) ([sectorbuilder.CommLen]byte, error) { + return sbmock.MockVerifier.GenerateDataCommitment(ssize, pieces) +} + +func (m genFakeVerifier) VerifySeal(sectorSize abi.SectorSize, commR, commD []byte, proverID address.Address, ticket []byte, seed []byte, sectorID abi.SectorNumber, proof []byte) (bool, error) { + return true, nil +} + +func (m genFakeVerifier) VerifyFallbackPost(ctx context.Context, sectorSize abi.SectorSize, sectorInfo sectorbuilder.SortedPublicSectorInfo, challengeSeed []byte, proof []byte, candidates []sectorbuilder.EPostCandidate, proverID address.Address, faults uint64) (bool, error) { + panic("nyi") +} diff --git a/chain/gen/gen_test.go b/chain/gen/gen_test.go index 340a695e7..e8f926ad5 100644 --- a/chain/gen/gen_test.go +++ b/chain/gen/gen_test.go @@ -3,20 +3,25 @@ package gen import ( "testing" + "github.com/filecoin-project/specs-actors/actors/abi" + + _ "github.com/filecoin-project/lotus/lib/sigs/bls" + _ "github.com/filecoin-project/lotus/lib/sigs/secp" + "github.com/filecoin-project/lotus/build" _ "github.com/filecoin-project/lotus/lib/sigs/bls" _ "github.com/filecoin-project/lotus/lib/sigs/secp" ) func init() { - build.SectorSizes = []uint64{1024} + build.SectorSizes = []abi.SectorSize{1024} build.MinimumMinerPower = 1024 } func testGeneration(t testing.TB, n int, msgs int) { g, err := NewGenerator() if err != nil { - t.Fatal(err) + t.Fatalf("%+v", err) } g.msgsPerBlock = msgs @@ -24,7 +29,7 @@ func testGeneration(t testing.TB, n int, msgs int) { for i := 0; i < n; i++ { mts, err := g.NextTipSet() if err != nil { - t.Fatalf("error at H:%d, %s", i, err) + t.Fatalf("error at H:%d, %+v", i, err) } _ = mts } diff --git a/chain/gen/genesis/genesis.go b/chain/gen/genesis/genesis.go new file mode 100644 index 000000000..7d82fcceb --- /dev/null +++ b/chain/gen/genesis/genesis.go @@ -0,0 +1,286 @@ +package genesis + +import ( + "context" + "encoding/json" + + "github.com/filecoin-project/go-amt-ipld/v2" + "github.com/filecoin-project/specs-actors/actors/abi/big" + "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/filecoin-project/specs-actors/actors/builtin/account" + "github.com/filecoin-project/specs-actors/actors/crypto" + "github.com/filecoin-project/specs-actors/actors/runtime" + "github.com/ipfs/go-cid" + "github.com/ipfs/go-datastore" + bstore "github.com/ipfs/go-ipfs-blockstore" + cbor "github.com/ipfs/go-ipld-cbor" + logging "github.com/ipfs/go-log/v2" + "golang.org/x/xerrors" + + "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/store" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/genesis" +) + +const AccountStart = 100 +const MinerStart = 1000 +const MaxAccounts = MinerStart - AccountStart + +var log = logging.Logger("genesis") + +type GenesisBootstrap struct { + Genesis *types.BlockHeader +} + +/* +From a list of parameters, create a genesis block / initial state + +The process: +- Bootstrap state (MakeInitialStateTree) + - Create empty state + - Create system actor + - Make init actor + - Create accounts mappings + - Set NextID to MinerStart + - Setup Reward (1.4B fil) + - Setup Cron + - Create empty power actor + - Create empty market + - Setup burnt fund address + - Initialize account / msig balances +- Instantiate early vm with genesis syscalls + - Create miners + - Each: + - power.CreateMiner, set msg value to PowerBalance + - market.AddFunds with correct value + - market.PublishDeals for related sectors + - Set precommits + - Commit presealed sectors + +Data Types: + +PreSeal :{ + CommR CID + CommD CID + SectorID SectorNumber + Deal market.DealProposal # Start at 0, self-deal! +} + +Genesis: { + Accounts: [ # non-miner, non-singleton actors, max len = MaxAccounts + { + Type: "account" / "multisig", + Value: "attofil", + [Meta: {msig settings, account key..}] + },... + ], + Miners: [ + { + Owner, Worker Addr # ID + MarketBalance, PowerBalance TokenAmount + SectorSize uint64 + PreSeals []PreSeal + },... + ], +} + +*/ + +func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template genesis.Template) (*state.StateTree, error) { + // Create empty state tree + + cst := cbor.NewCborStore(bs) + _, err := cst.Put(context.TODO(), []struct{}{}) + if err != nil { + return nil, xerrors.Errorf("putting empty object: %w", err) + } + + state, err := state.NewStateTree(cst) + if err != nil { + return nil, xerrors.Errorf("making new state tree: %w", err) + } + + emptyobject, err := cst.Put(context.TODO(), []struct{}{}) + if err != nil { + return nil, xerrors.Errorf("failed putting empty object: %w", err) + } + + // Create system actor + + sysact, err := SetupSystemActor(bs) + if err != nil { + return nil, xerrors.Errorf("setup init actor: %w", err) + } + if err := state.SetActor(builtin.SystemActorAddr, sysact); err != nil { + return nil, xerrors.Errorf("set init actor: %w", err) + } + + // Create init actor + + initact, err := SetupInitActor(bs, template.NetworkName, template.Accounts) + if err != nil { + return nil, xerrors.Errorf("setup init actor: %w", err) + } + if err := state.SetActor(builtin.InitActorAddr, initact); err != nil { + return nil, xerrors.Errorf("set init actor: %w", err) + } + + // Setup reward + err = state.SetActor(builtin.RewardActorAddr, &types.Actor{ + Code: builtin.RewardActorCodeID, + Balance: big.Int{Int: build.InitialReward}, + Head: emptyobject, // TODO ? + }) + if err != nil { + return nil, xerrors.Errorf("set network account actor: %w", err) + } + + // Setup cron + cronact, err := SetupCronActor(bs) + if err != nil { + return nil, xerrors.Errorf("setup cron actor: %w", err) + } + if err := state.SetActor(builtin.CronActorAddr, cronact); err != nil { + return nil, xerrors.Errorf("set cron actor: %w", err) + } + + // Create empty power actor + spact, err := SetupStoragePowerActor(bs) + if err != nil { + return nil, xerrors.Errorf("setup storage market actor: %w", err) + } + if err := state.SetActor(builtin.StoragePowerActorAddr, spact); err != nil { + return nil, xerrors.Errorf("set storage market actor: %w", err) + } + + // Create empty market actor + marketact, err := SetupStorageMarketActor(bs) + if err != nil { + return nil, xerrors.Errorf("setup storage market actor: %w", err) + } + if err := state.SetActor(builtin.StorageMarketActorAddr, marketact); err != nil { + return nil, xerrors.Errorf("set market actor: %w", err) + } + + // Setup burnt-funds + err = state.SetActor(builtin.BurntFundsActorAddr, &types.Actor{ + Code: builtin.AccountActorCodeID, + Balance: types.NewInt(0), + Head: emptyobject, + }) + if err != nil { + return nil, xerrors.Errorf("set burnt funds account actor: %w", err) + } + + // Create accounts + for id, info := range template.Accounts { + if info.Type != genesis.TAccount { + return nil, xerrors.New("unsupported account type") // TODO: msigs + } + + ida, err := address.NewIDAddress(uint64(AccountStart + id)) + if err != nil { + return nil, err + } + + var ainfo genesis.AccountMeta + if err := json.Unmarshal(info.Meta, &ainfo); err != nil { + return nil, xerrors.Errorf("unmarshaling account meta: %w", err) + } + + st, err := cst.Put(ctx, &account.State{Address: ainfo.Owner}) + if err != nil { + return nil, err + } + + err = state.SetActor(ida, &types.Actor{ + Code: builtin.AccountActorCodeID, + Balance: info.Balance, + Head: st, + }) + if err != nil { + return nil, xerrors.Errorf("setting account from actmap: %w", err) + } + } + + return state, nil +} + +func MakeGenesisBlock(ctx context.Context, bs bstore.Blockstore, sys runtime.Syscalls, template genesis.Template) (*GenesisBootstrap, error) { + st, err := MakeInitialStateTree(ctx, bs, template) + if err != nil { + return nil, xerrors.Errorf("make initial state tree failed: %w", err) + } + + stateroot, err := st.Flush(ctx) + if err != nil { + return nil, xerrors.Errorf("flush state tree failed: %w", err) + } + + // temp chainstore + cs := store.NewChainStore(bs, datastore.NewMapDatastore(), sys) + stateroot, err = SetupStorageMiners(ctx, cs, stateroot, template.Miners) + if err != nil { + return nil, xerrors.Errorf("setup storage miners failed: %w", err) + } + + cst := cbor.NewCborStore(bs) + + emptyroot, err := amt.FromArray(ctx, cst, nil) + if err != nil { + return nil, xerrors.Errorf("amt build failed: %w", err) + } + + mm := &types.MsgMeta{ + BlsMessages: emptyroot, + SecpkMessages: emptyroot, + } + mmb, err := mm.ToStorageBlock() + if err != nil { + return nil, xerrors.Errorf("serializing msgmeta failed: %w", err) + } + if err := bs.Put(mmb); err != nil { + return nil, xerrors.Errorf("putting msgmeta block to blockstore: %w", err) + } + + log.Infof("Empty Genesis root: %s", emptyroot) + + genesisticket := &types.Ticket{ + VRFProof: []byte("vrf proof0000000vrf proof0000000"), + } + + b := &types.BlockHeader{ + Miner: builtin.InitActorAddr, + Ticket: genesisticket, + EPostProof: types.EPostProof{ + Proof: []byte("not a real proof"), + PostRand: []byte("i guess this is kinda random"), + }, + Parents: []cid.Cid{}, + Height: 0, + ParentWeight: types.NewInt(0), + ParentStateRoot: stateroot, + Messages: mmb.Cid(), + ParentMessageReceipts: emptyroot, + BLSAggregate: crypto.Signature{Type: crypto.SigTypeBLS, Data: []byte("signatureeee")}, + BlockSig: &crypto.Signature{Type: crypto.SigTypeBLS, Data: []byte("block signatureeee")}, + Timestamp: template.Timestamp, + } + + sb, err := b.ToStorageBlock() + if err != nil { + return nil, xerrors.Errorf("serializing block header failed: %w", err) + } + + if err := bs.Put(sb); err != nil { + return nil, xerrors.Errorf("putting header to blockstore: %w", err) + } + + return &GenesisBootstrap{ + Genesis: b, + }, nil +} diff --git a/chain/gen/genesis/miners.go b/chain/gen/genesis/miners.go new file mode 100644 index 000000000..277b77523 --- /dev/null +++ b/chain/gen/genesis/miners.go @@ -0,0 +1,266 @@ +package genesis + +import ( + "bytes" + "context" + "fmt" + "math/rand" + + cborutil "github.com/filecoin-project/go-cbor-util" + commcid "github.com/filecoin-project/go-fil-commcid" + "github.com/filecoin-project/specs-actors/actors/builtin/power" + cbor "github.com/ipfs/go-ipld-cbor" + + "github.com/filecoin-project/go-address" + "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" + "github.com/filecoin-project/specs-actors/actors/builtin/market" + "github.com/filecoin-project/specs-actors/actors/builtin/miner" + "github.com/filecoin-project/specs-actors/actors/crypto" + "github.com/ipfs/go-cid" + "golang.org/x/xerrors" + + "github.com/filecoin-project/lotus/chain/state" + "github.com/filecoin-project/lotus/chain/store" + "github.com/filecoin-project/lotus/chain/vm" + "github.com/filecoin-project/lotus/genesis" +) + +func MinerAddress(genesisIndex uint64) address.Address { + maddr, err := address.NewIDAddress(MinerStart + genesisIndex) + if err != nil { + panic(err) + } + + return maddr +} + +func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid, miners []genesis.Miner) (cid.Cid, error) { + networkPower := big.Zero() + for _, m := range miners { + networkPower = big.Add(networkPower, big.NewInt(int64(m.SectorSize)*int64(len(m.Sectors)))) + } + + vm, err := vm.NewVM(sroot, 0, &fakeRand{}, builtin.SystemActorAddr, cs.Blockstore(), cs.VMSys()) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to create NewVM: %w", err) + } + + err = vm.MutateState(ctx, builtin.StoragePowerActorAddr, func(cst cbor.IpldStore, st *power.State) error { + st.TotalNetworkPower = networkPower + return nil + }) + + if len(miners) == 0 { + return cid.Undef, xerrors.New("no genesis miners") + } + + for i, m := range miners { + // Create miner through power actor + + var maddr address.Address + { + constructorParams := &power.CreateMinerParams{ + Worker: m.Worker, + SectorSize: m.SectorSize, + Peer: m.PeerId, + } + + params := mustEnc(constructorParams) + rval, err := doExecValue(ctx, vm, builtin.StoragePowerActorAddr, m.Owner, m.PowerBalance, builtin.MethodsPower.CreateMiner, params) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to create genesis miner: %w", err) + } + + var ma power.CreateMinerReturn + if err := ma.UnmarshalCBOR(bytes.NewReader(rval)); err != nil { + return cid.Undef, err + } + + expma := MinerAddress(uint64(i)) + if ma.IDAddress != expma { + return cid.Undef, xerrors.Errorf("miner assigned wrong address: %s != %s", ma.IDAddress, expma) + } + maddr = ma.IDAddress + } + + // Add market funds + + { + params := mustEnc(&maddr) + _, err := doExecValue(ctx, vm, builtin.StorageMarketActorAddr, m.Worker, m.MarketBalance, builtin.MethodsMarket.AddBalance, params) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to create genesis miner: %w", err) + } + } + { + params := mustEnc(&m.Worker) + _, err := doExecValue(ctx, vm, builtin.StorageMarketActorAddr, m.Worker, big.Zero(), builtin.MethodsMarket.AddBalance, params) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to create genesis miner: %w", err) + } + } + + // Publish preseal deals + + var dealIDs []abi.DealID + { + params := &market.PublishStorageDealsParams{} + for _, preseal := range m.Sectors { + + params.Deals = append(params.Deals, market.ClientDealProposal{ + Proposal: preseal.Deal, + ClientSignature: crypto.Signature{Type: crypto.SigTypeBLS}, // TODO: do we want to sign these? Or do we want to fake signatures for genesis setup? + }) + fmt.Printf("calling publish storage deals on miner %s with worker %s\n", preseal.Deal.Provider, m.Worker) + } + + ret, err := doExecValue(ctx, vm, builtin.StorageMarketActorAddr, m.Worker, big.Zero(), builtin.MethodsMarket.PublishStorageDeals, mustEnc(params)) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to create genesis miner: %w", err) + } + var ids market.PublishStorageDealsReturn + if err := ids.UnmarshalCBOR(bytes.NewReader(ret)); err != nil { + return cid.Undef, err + } + + dealIDs = ids.IDs + } + + // setup windowed post + { + err = vm.MutateState(ctx, maddr, func(cst cbor.IpldStore, st *miner.State) error { + // TODO: Randomize so all genesis miners don't fall on the same epoch + st.PoStState.ProvingPeriodStart = miner.ProvingPeriod + return nil + }) + + payload, err := cborutil.Dump(&miner.CronEventPayload{ + EventType: miner.CronEventWindowedPoStExpiration, + }) + if err != nil { + return cid.Undef, err + } + params := &power.EnrollCronEventParams{ + EventEpoch: miner.ProvingPeriod, + Payload: payload, + } + + _, err = doExecValue(ctx, vm, builtin.StoragePowerActorAddr, maddr, big.Zero(), builtin.MethodsPower.EnrollCronEvent, mustEnc(params)) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to verify preseal deals miner: %w", err) + } + } + + // Commit sectors + for pi, preseal := range m.Sectors { + // TODO: Maybe check seal (Can just be snark inputs, doesn't go into the genesis file) + + // check deals, get dealWeight + dealWeight := big.Zero() + { + params := &market.VerifyDealsOnSectorProveCommitParams{ + DealIDs: []abi.DealID{dealIDs[pi]}, + SectorExpiry: preseal.Deal.EndEpoch, + } + + ret, err := doExecValue(ctx, vm, builtin.StorageMarketActorAddr, maddr, big.Zero(), builtin.MethodsMarket.VerifyDealsOnSectorProveCommit, mustEnc(params)) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to verify preseal deals miner: %w", err) + } + if err := dealWeight.UnmarshalCBOR(bytes.NewReader(ret)); err != nil { + return cid.Undef, err + } + } + + // update power claims + pledge := big.Zero() + { + err = vm.MutateState(ctx, builtin.StoragePowerActorAddr, func(cst cbor.IpldStore, st *power.State) error { + weight := &power.SectorStorageWeightDesc{ + SectorSize: m.SectorSize, + Duration: preseal.Deal.Duration(), + DealWeight: dealWeight, + } + + spower := power.ConsensusPowerForWeight(weight) + pledge = power.PledgeForWeight(weight, big.Sub(st.TotalNetworkPower, spower)) + err := st.AddToClaim(&state.AdtStore{cst}, maddr, spower, pledge) + if err != nil { + return xerrors.Errorf("add to claim: %w", err) + } + return nil + }) + if err != nil { + return cid.Undef, xerrors.Errorf("register power claim in power actor: %w", err) + } + } + + // Put sectors to miner sector sets + { + newSectorInfo := &miner.SectorOnChainInfo{ + Info: miner.SectorPreCommitInfo{ + SectorNumber: preseal.SectorID, + SealedCID: commcid.ReplicaCommitmentV1ToCID(preseal.CommR[:]), + SealRandEpoch: 0, + DealIDs: []abi.DealID{dealIDs[pi]}, + Expiration: preseal.Deal.EndEpoch, + }, + ActivationEpoch: 0, + DealWeight: dealWeight, + PledgeRequirement: pledge, + } + + err = vm.MutateState(ctx, maddr, func(cst cbor.IpldStore, st *miner.State) error { + store := &state.AdtStore{cst} + + if err = st.PutSector(store, newSectorInfo); err != nil { + return xerrors.Errorf("failed to prove commit: %v", err) + } + + st.ProvingSet = st.Sectors + return nil + }) + if err != nil { + return cid.Cid{}, xerrors.Errorf("put to sset: %w", err) + } + } + + { + sectorBf := abi.NewBitField() + sectorBf.Set(uint64(preseal.SectorID)) + + payload, err := cborutil.Dump(&miner.CronEventPayload{ + EventType: miner.CronEventSectorExpiry, + Sectors: §orBf, + }) + if err != nil { + return cid.Undef, err + } + params := &power.EnrollCronEventParams{ + EventEpoch: preseal.Deal.EndEpoch, + Payload: payload, + } + + _, err = doExecValue(ctx, vm, builtin.StoragePowerActorAddr, maddr, big.Zero(), builtin.MethodsPower.EnrollCronEvent, mustEnc(params)) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to verify preseal deals miner: %w", err) + } + } + } + + } + + c, err := vm.Flush(ctx) + return c, err +} + +// TODO: copied from actors test harness, deduplicate or remove from here +type fakeRand struct{} + +func (fr *fakeRand) GetRandomness(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch int64, entropy []byte) ([]byte, error) { + out := make([]byte, 32) + rand.New(rand.NewSource(randEpoch)).Read(out) + return out, nil +} diff --git a/chain/gen/genesis/t00_system.go b/chain/gen/genesis/t00_system.go new file mode 100644 index 000000000..c506b4982 --- /dev/null +++ b/chain/gen/genesis/t00_system.go @@ -0,0 +1,28 @@ +package genesis + +import ( + "context" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/filecoin-project/specs-actors/actors/util/adt" + bstore "github.com/ipfs/go-ipfs-blockstore" + cbor "github.com/ipfs/go-ipld-cbor" +) + +func SetupSystemActor(bs bstore.Blockstore) (*types.Actor, error) { + var st adt.EmptyValue + + cst := cbor.NewCborStore(bs) + + statecid, err := cst.Put(context.TODO(), &st) + if err != nil { + return nil, err + } + + act := &types.Actor{ + Code: builtin.SystemActorCodeID, + Head: statecid, + } + + return act, nil +} diff --git a/chain/gen/genesis/t01_init.go b/chain/gen/genesis/t01_init.go new file mode 100644 index 000000000..1402f7a69 --- /dev/null +++ b/chain/gen/genesis/t01_init.go @@ -0,0 +1,69 @@ +package genesis + +import ( + "context" + "encoding/json" + "fmt" + "github.com/filecoin-project/specs-actors/actors/builtin" + + init_ "github.com/filecoin-project/specs-actors/actors/builtin/init" + "github.com/ipfs/go-hamt-ipld" + bstore "github.com/ipfs/go-ipfs-blockstore" + cbor "github.com/ipfs/go-ipld-cbor" + "golang.org/x/xerrors" + + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/genesis" +) + +func SetupInitActor(bs bstore.Blockstore, netname string, initialActors []genesis.Actor) (*types.Actor, error) { + if len(initialActors) > MaxAccounts { + return nil, xerrors.New("too many initial actors") + } + + var ias init_.State + ias.NextID = MinerStart + ias.NetworkName = netname + + cst := cbor.NewCborStore(bs) + amap := hamt.NewNode(cst, hamt.UseTreeBitWidth(5)) // TODO: use spec adt map + + for i, a := range initialActors { + if a.Type != genesis.TAccount { + return nil, xerrors.Errorf("unsupported account type: %s", a.Type) // TODO: Support msig (skip here) + } + + var ainfo genesis.AccountMeta + if err := json.Unmarshal(a.Meta, &ainfo); err != nil { + return nil, xerrors.Errorf("unmarshaling account meta: %w", err) + } + + fmt.Printf("init set %s t0%d\n", ainfo.Owner, AccountStart+uint64(i)) + + if err := amap.Set(context.TODO(), string(ainfo.Owner.Bytes()), AccountStart+uint64(i)); err != nil { + return nil, err + } + } + + if err := amap.Flush(context.TODO()); err != nil { + return nil, err + } + amapcid, err := cst.Put(context.TODO(), amap) + if err != nil { + return nil, err + } + + ias.AddressMap = amapcid + + statecid, err := cst.Put(context.TODO(), &ias) + if err != nil { + return nil, err + } + + act := &types.Actor{ + Code: builtin.InitActorCodeID, + Head: statecid, + } + + return act, nil +} diff --git a/chain/gen/genesis/t02_reward.go b/chain/gen/genesis/t02_reward.go new file mode 100644 index 000000000..d215223ac --- /dev/null +++ b/chain/gen/genesis/t02_reward.go @@ -0,0 +1 @@ +package genesis diff --git a/chain/gen/genesis/t03_cron.go b/chain/gen/genesis/t03_cron.go new file mode 100644 index 000000000..3c300d7e9 --- /dev/null +++ b/chain/gen/genesis/t03_cron.go @@ -0,0 +1,33 @@ +package genesis + +import ( + "context" + + "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/filecoin-project/specs-actors/actors/builtin/cron" + bstore "github.com/ipfs/go-ipfs-blockstore" + cbor "github.com/ipfs/go-ipld-cbor" + + "github.com/filecoin-project/lotus/chain/types" +) + +func SetupCronActor(bs bstore.Blockstore) (*types.Actor, error) { + cst := cbor.NewCborStore(bs) + cas := &cron.State{Entries: []cron.Entry{{ + Receiver: builtin.StoragePowerActorAddr, + MethodNum: builtin.MethodsPower.OnEpochTickEnd, + }, + }} + + stcid, err := cst.Put(context.TODO(), cas) + if err != nil { + return nil, err + } + + return &types.Actor{ + Code: builtin.CronActorCodeID, + Head: stcid, + Nonce: 0, + Balance: types.NewInt(0), + }, nil +} diff --git a/chain/gen/genesis/t04_power.go b/chain/gen/genesis/t04_power.go new file mode 100644 index 000000000..49bc5aa4d --- /dev/null +++ b/chain/gen/genesis/t04_power.go @@ -0,0 +1,46 @@ +package genesis + +import ( + "context" + "github.com/filecoin-project/specs-actors/actors/builtin" + + "github.com/filecoin-project/specs-actors/actors/abi/big" + "github.com/filecoin-project/specs-actors/actors/builtin/power" + "github.com/ipfs/go-hamt-ipld" + bstore "github.com/ipfs/go-ipfs-blockstore" + cbor "github.com/ipfs/go-ipld-cbor" + + "github.com/filecoin-project/lotus/chain/types" +) + +func SetupStoragePowerActor(bs bstore.Blockstore) (*types.Actor, error) { + ctx := context.TODO() + cst := cbor.NewCborStore(bs) + nd := hamt.NewNode(cst, hamt.UseTreeBitWidth(5)) + emptyhamt, err := cst.Put(ctx, nd) + if err != nil { + return nil, err + } + + sms := &power.State{ + TotalNetworkPower: big.NewInt(1), + MinerCount: 0, + EscrowTable: emptyhamt, + CronEventQueue: emptyhamt, + PoStDetectedFaultMiners: emptyhamt, + Claims: emptyhamt, + NumMinersMeetingMinPower: 0, + } + + stcid, err := cst.Put(ctx, sms) + if err != nil { + return nil, err + } + + return &types.Actor{ + Code: builtin.StoragePowerActorCodeID, + Head: stcid, + Nonce: 0, + Balance: types.NewInt(0), + }, nil +} diff --git a/chain/gen/genesis/t05_market.go b/chain/gen/genesis/t05_market.go new file mode 100644 index 000000000..9c55dff19 --- /dev/null +++ b/chain/gen/genesis/t05_market.go @@ -0,0 +1,42 @@ +package genesis + +import ( + "context" + "github.com/ipfs/go-hamt-ipld" + + "github.com/filecoin-project/go-amt-ipld/v2" + "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/filecoin-project/specs-actors/actors/builtin/market" + bstore "github.com/ipfs/go-ipfs-blockstore" + cbor "github.com/ipfs/go-ipld-cbor" + + "github.com/filecoin-project/lotus/chain/types" +) + +func SetupStorageMarketActor(bs bstore.Blockstore) (*types.Actor, error) { + cst := cbor.NewCborStore(bs) + + a, err := amt.NewAMT(cst).Flush(context.TODO()) + if err != nil { + return nil, err + } + h, err := cst.Put(context.TODO(), hamt.NewNode(cst, hamt.UseTreeBitWidth(5))) + if err != nil { + return nil, err + } + + sms := market.ConstructState(a, h, h) + + stcid, err := cst.Put(context.TODO(), sms) + if err != nil { + return nil, err + } + + act := &types.Actor{ + Code: builtin.StorageMarketActorCodeID, + Head: stcid, + Balance: types.NewInt(0), + } + + return act, nil +} diff --git a/chain/gen/genesis/util.go b/chain/gen/genesis/util.go new file mode 100644 index 000000000..22cb7c33d --- /dev/null +++ b/chain/gen/genesis/util.go @@ -0,0 +1,53 @@ +package genesis + +import ( + "context" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/specs-actors/actors/abi" + cbg "github.com/whyrusleeping/cbor-gen" + "golang.org/x/xerrors" + + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/chain/vm" +) + +func mustEnc(i cbg.CBORMarshaler) []byte { + enc, err := actors.SerializeParams(i) + if err != nil { + panic(err) // ok + } + return enc +} + +func doExec(ctx context.Context, vm *vm.VM, to, from address.Address, method abi.MethodNum, params []byte) ([]byte, error) { + return doExecValue(ctx, vm, to, from, types.NewInt(0), method, params) +} + +func doExecValue(ctx context.Context, vm *vm.VM, to, from address.Address, value types.BigInt, method abi.MethodNum, params []byte) ([]byte, error) { + act, err := vm.StateTree().GetActor(from) + if err != nil { + return nil, xerrors.Errorf("doExec failed to get from actor: %w", err) + } + + ret, err := vm.ApplyMessage(ctx, &types.Message{ + To: to, + From: from, + Method: method, + Params: params, + GasLimit: types.NewInt(1000000), + GasPrice: types.NewInt(0), + Value: value, + Nonce: act.Nonce, + }) + if err != nil { + return nil, xerrors.Errorf("doExec apply message failed: %w", err) + } + + if ret.ExitCode != 0 { + return nil, xerrors.Errorf("failed to call method: %w", ret.ActorErr) + } + + return ret.Return, nil +} diff --git a/chain/gen/mining.go b/chain/gen/mining.go index dd5939d7a..5b8bafa85 100644 --- a/chain/gen/mining.go +++ b/chain/gen/mining.go @@ -5,6 +5,8 @@ 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" + "github.com/filecoin-project/specs-actors/actors/crypto" cid "github.com/ipfs/go-cid" cbor "github.com/ipfs/go-ipld-cbor" cbg "github.com/whyrusleeping/cbor-gen" @@ -18,7 +20,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) @@ -44,9 +46,9 @@ func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w *wallet.Wal var secpkMessages []*types.SignedMessage var blsMsgCids, secpkMsgCids []cid.Cid - var blsSigs []types.Signature + var blsSigs []crypto.Signature for _, msg := range msgs { - if msg.Signature.TypeCode() == types.IKTBLS { + if msg.Signature.Type == crypto.SigTypeBLS { blsSigs = append(blsSigs, msg.Signature) blsMessages = append(blsMessages, &msg.Message) @@ -131,7 +133,7 @@ func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w *wallet.Wal return fullBlock, nil } -func aggregateSignatures(sigs []types.Signature) (types.Signature, error) { +func aggregateSignatures(sigs []crypto.Signature) (crypto.Signature, error) { var blsSigs []bls.Signature for _, s := range sigs { var bsig bls.Signature @@ -140,8 +142,8 @@ func aggregateSignatures(sigs []types.Signature) (types.Signature, error) { } aggSig := bls.Aggregate(blsSigs) - return types.Signature{ - Type: types.KTBLS, + return crypto.Signature{ + Type: crypto.SigTypeBLS, Data: aggSig[:], }, nil } diff --git a/chain/gen/utils.go b/chain/gen/utils.go deleted file mode 100644 index e790af641..000000000 --- a/chain/gen/utils.go +++ /dev/null @@ -1,676 +0,0 @@ -package gen - -import ( - "bytes" - "context" - "fmt" - - amt "github.com/filecoin-project/go-amt-ipld/v2" - "github.com/ipfs/go-cid" - "github.com/ipfs/go-datastore" - hamt "github.com/ipfs/go-hamt-ipld" - blockstore "github.com/ipfs/go-ipfs-blockstore" - bstore "github.com/ipfs/go-ipfs-blockstore" - cbor "github.com/ipfs/go-ipld-cbor" - peer "github.com/libp2p/go-libp2p-core/peer" - cbg "github.com/whyrusleeping/cbor-gen" - "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" - "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/lotus/genesis" -) - -type GenesisBootstrap struct { - Genesis *types.BlockHeader -} - -func SetupInitActor(bs bstore.Blockstore, addrs []address.Address) (*types.Actor, error) { - var ias actors.InitActorState - ias.NextID = 100 - - cst := cbor.NewCborStore(bs) - amap := hamt.NewNode(cst) - - for i, a := range addrs { - if err := amap.Set(context.TODO(), string(a.Bytes()), 100+uint64(i)); err != nil { - return nil, err - } - } - - ias.NextID += uint64(len(addrs)) - if err := amap.Flush(context.TODO()); err != nil { - return nil, err - } - amapcid, err := cst.Put(context.TODO(), amap) - if err != nil { - return nil, err - } - - ias.AddressMap = amapcid - - statecid, err := cst.Put(context.TODO(), &ias) - if err != nil { - return nil, err - } - - act := &types.Actor{ - Code: actors.InitCodeCid, - Head: statecid, - } - - return act, nil -} - -func MakeInitialStateTree(bs bstore.Blockstore, actmap map[address.Address]types.BigInt) (*state.StateTree, error) { - cst := cbor.NewCborStore(bs) - state, err := state.NewStateTree(cst) - if err != nil { - return nil, xerrors.Errorf("making new state tree: %w", err) - } - - emptyobject, err := cst.Put(context.TODO(), map[string]string{}) - if err != nil { - return nil, xerrors.Errorf("failed putting empty object: %w", err) - } - - var addrs []address.Address - for a := range actmap { - addrs = append(addrs, a) - } - - initact, err := SetupInitActor(bs, addrs) - if err != nil { - return nil, xerrors.Errorf("setup init actor: %w", err) - } - - if err := state.SetActor(actors.InitAddress, initact); err != nil { - return nil, xerrors.Errorf("set init actor: %w", err) - } - - cronact, err := SetupCronActor(bs) - if err != nil { - return nil, xerrors.Errorf("setup cron actor: %w", err) - } - - if err := state.SetActor(actors.CronAddress, cronact); err != nil { - return nil, xerrors.Errorf("set cron actor: %w", err) - } - - spact, err := SetupStoragePowerActor(bs) - if err != nil { - return nil, xerrors.Errorf("setup storage market actor: %w", err) - } - - if err := state.SetActor(actors.StoragePowerAddress, spact); err != nil { - return nil, xerrors.Errorf("set storage market actor: %w", err) - } - - netAmt := types.FromFil(build.TotalFilecoin) - for _, amt := range actmap { - netAmt = types.BigSub(netAmt, amt) - } - - err = state.SetActor(actors.NetworkAddress, &types.Actor{ - Code: actors.AccountCodeCid, - Balance: netAmt, - Head: emptyobject, - }) - if err != nil { - return nil, xerrors.Errorf("set network account actor: %w", err) - } - - err = state.SetActor(actors.BurntFundsAddress, &types.Actor{ - Code: actors.AccountCodeCid, - Balance: types.NewInt(0), - Head: emptyobject, - }) - if err != nil { - return nil, xerrors.Errorf("set burnt funds account actor: %w", err) - } - - for a, v := range actmap { - err = state.SetActor(a, &types.Actor{ - Code: actors.AccountCodeCid, - Balance: v, - Head: emptyobject, - }) - if err != nil { - return nil, xerrors.Errorf("setting account from actmap: %w", err) - } - } - - return state, nil -} - -func SetupCronActor(bs bstore.Blockstore) (*types.Actor, error) { - cst := cbor.NewCborStore(bs) - cas := &actors.CronActorState{} - - stcid, err := cst.Put(context.TODO(), cas) - if err != nil { - return nil, err - } - - return &types.Actor{ - Code: actors.CronCodeCid, - Head: stcid, - Nonce: 0, - Balance: types.NewInt(0), - }, nil -} - -func SetupStoragePowerActor(bs bstore.Blockstore) (*types.Actor, error) { - ctx := context.TODO() - cst := cbor.NewCborStore(bs) - nd := hamt.NewNode(cst) - emptyhamt, err := cst.Put(ctx, nd) - if err != nil { - return nil, err - } - - blks := cbor.NewCborStore(bs) - emptyamt, err := amt.FromArray(ctx, blks, nil) - if err != nil { - return nil, xerrors.Errorf("amt build failed: %w", err) - } - - sms := &actors.StoragePowerState{ - Miners: emptyhamt, - ProvingBuckets: emptyamt, - TotalStorage: types.NewInt(0), - } - - stcid, err := cst.Put(ctx, sms) - if err != nil { - return nil, err - } - - return &types.Actor{ - Code: actors.StoragePowerCodeCid, - Head: stcid, - Nonce: 0, - Balance: types.NewInt(0), - }, nil -} - -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 - } - - cdeals := make([]cbg.CBORMarshaler, len(deals)) - for i, deal := range deals { - cdeals[i] = &actors.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: 1, - } - } - - dealAmt, err := amt.FromArray(ctx, cst, cdeals) - if err != nil { - return cid.Undef, xerrors.Errorf("amt build failed: %w", err) - } - - sms := &actors.StorageMarketState{ - Balances: emptyHAMT, - Deals: dealAmt, - NextDealID: uint64(len(deals)), - } - - stcid, err := cst.Put(context.TODO(), sms) - if err != nil { - return cid.Undef, err - } - - act := &types.Actor{ - Code: actors.StorageMarketCodeCid, - Head: stcid, - Nonce: 0, - Balance: types.NewInt(0), - } - - state, err := state.LoadStateTree(cst, sroot) - if err != nil { - return cid.Undef, xerrors.Errorf("making new state tree: %w", err) - } - - if err := state.SetActor(actors.StorageMarketAddress, act); err != nil { - return cid.Undef, xerrors.Errorf("set storage market actor: %w", err) - } - - return state.Flush(context.TODO()) -} - -type GenMinerCfg struct { - PreSeals map[string]genesis.GenesisMiner - - // The addresses of the created miner, this is set by the genesis setup - MinerAddrs []address.Address - - PeerIDs []peer.ID -} - -func mustEnc(i cbg.CBORMarshaler) []byte { - enc, err := actors.SerializeParams(i) - if err != nil { - panic(err) // ok - } - return enc -} - -func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid, gmcfg *GenMinerCfg) (cid.Cid, []actors.StorageDealProposal, error) { - vm, err := vm.NewVM(sroot, 0, nil, actors.NetworkAddress, cs.Blockstore(), cs.VMSys()) - if err != nil { - return cid.Undef, nil, xerrors.Errorf("failed to create NewVM: %w", err) - } - - if len(gmcfg.MinerAddrs) == 0 { - return cid.Undef, nil, xerrors.New("no genesis miners") - } - - if len(gmcfg.MinerAddrs) != len(gmcfg.PreSeals) { - return cid.Undef, nil, xerrors.Errorf("miner address list, and preseal count doesn't match (%d != %d)", len(gmcfg.MinerAddrs), len(gmcfg.PreSeals)) - } - - var deals []actors.StorageDealProposal - - for i, maddr := range gmcfg.MinerAddrs { - ps, psok := gmcfg.PreSeals[maddr.String()] - if !psok { - return cid.Undef, nil, xerrors.Errorf("no preseal for miner %s", maddr) - } - - minerParams := &actors.CreateStorageMinerParams{ - Owner: ps.Owner, - Worker: ps.Worker, - SectorSize: ps.SectorSize, - PeerID: gmcfg.PeerIDs[i], // TODO: grab from preseal too - } - - params := mustEnc(minerParams) - - // TODO: hardcoding 6500 here is a little fragile, it changes any - // time anyone changes the initial account allocations - rval, err := doExecValue(ctx, vm, actors.StoragePowerAddress, ps.Worker, types.FromFil(6500), actors.SPAMethods.CreateStorageMiner, params) - if err != nil { - return cid.Undef, nil, xerrors.Errorf("failed to create genesis miner: %w", err) - } - - maddrret, err := address.NewFromBytes(rval) - if err != nil { - return cid.Undef, nil, err - } - - _, err = vm.Flush(ctx) - if err != nil { - return cid.Undef, nil, err - } - - cst := cbor.NewCborStore(cs.Blockstore()) - if err := reassignMinerActorAddress(vm, cst, maddrret, maddr); err != nil { - return cid.Undef, nil, err - } - - power := types.BigMul(types.NewInt(minerParams.SectorSize), types.NewInt(uint64(len(ps.Sectors)))) - - params = mustEnc(&actors.UpdateStorageParams{Delta: power}) - - _, err = doExec(ctx, vm, actors.StoragePowerAddress, maddr, actors.SPAMethods.UpdateStorage, params) - if err != nil { - return cid.Undef, nil, xerrors.Errorf("failed to update total storage: %w", err) - } - - // we have to flush the vm here because it buffers stuff internally for perf reasons - if _, err := vm.Flush(ctx); err != nil { - return cid.Undef, nil, xerrors.Errorf("vm.Flush failed: %w", err) - } - - st := vm.StateTree() - mact, err := st.GetActor(maddr) - if err != nil { - return cid.Undef, nil, xerrors.Errorf("get miner actor failed: %w", err) - } - - var mstate actors.StorageMinerActorState - 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)))) - - for _, s := range ps.Sectors { - nssroot, err := actors.AddToSectorSet(ctx, cst, mstate.Sectors, s.SectorID, s.CommR[:], s.CommD[:]) - if err != nil { - return cid.Undef, nil, xerrors.Errorf("failed to add fake sector to sector set: %w", err) - } - mstate.Sectors = nssroot - mstate.ProvingSet = nssroot - - deals = append(deals, s.Deal) - } - - nstate, err := cst.Put(ctx, &mstate) - if err != nil { - return cid.Undef, nil, err - } - - mact.Head = nstate - if err := st.SetActor(maddr, mact); err != nil { - return cid.Undef, nil, err - } - } - - c, err := vm.Flush(ctx) - return c, deals, err -} - -func reassignMinerActorAddress(vm *vm.VM, cst cbor.IpldStore, from, to address.Address) error { - if from == to { - return nil - } - act, err := vm.StateTree().GetActor(from) - if err != nil { - return xerrors.Errorf("reassign: failed to get 'from' actor: %w", err) - } - - _, err = vm.StateTree().GetActor(to) - if err == nil { - return xerrors.Errorf("cannot reassign actor, target address taken") - } - if err := vm.StateTree().SetActor(to, act); err != nil { - return xerrors.Errorf("failed to reassign actor: %w", err) - } - - if err := adjustStorageMarketTracking(vm, cst, from, to); err != nil { - return xerrors.Errorf("adjusting storage market tracking: %w", err) - } - - // Now, adjust the tracking in the init actor - return initActorReassign(vm, cst, from, to) -} - -func adjustStorageMarketTracking(vm *vm.VM, cst cbor.IpldStore, from, to address.Address) error { - ctx := context.TODO() - act, err := vm.StateTree().GetActor(actors.StoragePowerAddress) - if err != nil { - return xerrors.Errorf("loading storage power actor: %w", err) - } - - var spst actors.StoragePowerState - if err := cst.Get(ctx, act.Head, &spst); err != nil { - return xerrors.Errorf("loading storage power actor state: %w", err) - } - - miners, err := hamt.LoadNode(ctx, cst, spst.Miners) - if err != nil { - return xerrors.Errorf("loading miner set: %w", err) - } - - if err := miners.Delete(ctx, string(from.Bytes())); err != nil { - return xerrors.Errorf("deleting from spa set: %w", err) - } - - if err := miners.Set(ctx, string(to.Bytes()), uint64(1)); err != nil { - return xerrors.Errorf("failed setting miner: %w", err) - } - - if err := miners.Flush(ctx); err != nil { - return err - } - - nminerscid, err := cst.Put(ctx, miners) - if err != nil { - return err - } - spst.Miners = nminerscid - - nhead, err := cst.Put(ctx, &spst) - if err != nil { - return err - } - - act.Head = nhead - - return nil -} - -func initActorReassign(vm *vm.VM, cst cbor.IpldStore, from, to address.Address) error { - ctx := context.TODO() - initact, err := vm.StateTree().GetActor(actors.InitAddress) - if err != nil { - return xerrors.Errorf("couldnt get init actor: %w", err) - } - - var st actors.InitActorState - if err := cst.Get(ctx, initact.Head, &st); err != nil { - return xerrors.Errorf("reassign loading init actor state: %w", err) - } - - amap, err := hamt.LoadNode(ctx, cst, st.AddressMap) - if err != nil { - return xerrors.Errorf("failed to load init actor map: %w", err) - } - - target, err := address.IDFromAddress(from) - if err != nil { - return xerrors.Errorf("failed to extract ID: %w", err) - } - - var out string - halt := xerrors.Errorf("halt") - err = amap.ForEach(ctx, func(k string, v interface{}) error { - _, val, err := cbg.CborReadHeader(bytes.NewReader(v.(*cbg.Deferred).Raw)) - if err != nil { - return xerrors.Errorf("parsing int in map failed: %w", err) - } - - if val == target { - out = k - return halt - } - return nil - }) - - if err == nil { - return xerrors.Errorf("could not find from address in init ID map") - } - if !xerrors.Is(err, halt) { - return xerrors.Errorf("finding address in ID map failed: %w", err) - } - - if err := amap.Delete(ctx, out); err != nil { - return xerrors.Errorf("deleting 'from' entry in amap: %w", err) - } - - if err := amap.Set(ctx, out, target); err != nil { - return xerrors.Errorf("setting 'to' entry in amap: %w", err) - } - - if err := amap.Flush(ctx); err != nil { - return xerrors.Errorf("failed to flush amap: %w", err) - } - - ncid, err := cst.Put(ctx, amap) - if err != nil { - return err - } - - st.AddressMap = ncid - - nacthead, err := cst.Put(ctx, &st) - if err != nil { - return err - } - - initact.Head = nacthead - - return nil -} - -func doExec(ctx context.Context, vm *vm.VM, to, from address.Address, method uint64, params []byte) ([]byte, error) { - return doExecValue(ctx, vm, to, from, types.NewInt(0), method, params) -} - -func doExecValue(ctx context.Context, vm *vm.VM, to, from address.Address, value types.BigInt, method uint64, params []byte) ([]byte, error) { - act, err := vm.StateTree().GetActor(from) - if err != nil { - return nil, xerrors.Errorf("doExec failed to get from actor: %w", err) - } - - ret, err := vm.ApplyMessage(context.TODO(), &types.Message{ - To: to, - From: from, - Method: method, - Params: params, - GasLimit: types.NewInt(1000000), - GasPrice: types.NewInt(0), - Value: value, - Nonce: act.Nonce, - }) - if err != nil { - return nil, xerrors.Errorf("doExec apply message failed: %w", err) - } - - if ret.ExitCode != 0 { - return nil, fmt.Errorf("failed to call method: %s", ret.ActorErr) - } - - return ret.Return, nil -} - -func MakeGenesisBlock(bs bstore.Blockstore, sys *types.VMSyscalls, balances map[address.Address]types.BigInt, gmcfg *GenMinerCfg, ts uint64) (*GenesisBootstrap, error) { - ctx := context.TODO() - - state, err := MakeInitialStateTree(bs, balances) - if err != nil { - return nil, xerrors.Errorf("make initial state tree failed: %w", err) - } - - stateroot, err := state.Flush(ctx) - if err != nil { - return nil, xerrors.Errorf("flush state tree failed: %w", err) - } - - // temp chainstore - cs := store.NewChainStore(bs, datastore.NewMapDatastore(), sys) - stateroot, deals, err := SetupStorageMiners(ctx, cs, stateroot, gmcfg) - if err != nil { - return nil, xerrors.Errorf("setup storage miners failed: %w", err) - } - - stateroot, err = SetupStorageMarketActor(bs, stateroot, deals) - if err != nil { - return nil, xerrors.Errorf("setup storage market actor: %w", err) - } - - stateroot, err = AdjustInitActorStartID(ctx, bs, stateroot, 1000) - if err != nil { - return nil, xerrors.Errorf("failed to adjust init actor start ID: %w", err) - } - - cst := cbor.NewCborStore(bs) - - emptyroot, err := amt.FromArray(ctx, cst, nil) - if err != nil { - return nil, xerrors.Errorf("amt build failed: %w", err) - } - - mm := &types.MsgMeta{ - BlsMessages: emptyroot, - SecpkMessages: emptyroot, - } - mmb, err := mm.ToStorageBlock() - if err != nil { - return nil, xerrors.Errorf("serializing msgmeta failed: %w", err) - } - if err := bs.Put(mmb); err != nil { - return nil, xerrors.Errorf("putting msgmeta block to blockstore: %w", err) - } - - log.Infof("Empty Genesis root: %s", emptyroot) - - genesisticket := &types.Ticket{ - VRFProof: []byte("vrf proof0000000vrf proof0000000"), - } - - b := &types.BlockHeader{ - Miner: actors.InitAddress, - Ticket: genesisticket, - EPostProof: types.EPostProof{ - Proof: []byte("not a real proof"), - PostRand: []byte("i guess this is kinda random"), - }, - Parents: []cid.Cid{}, - Height: 0, - ParentWeight: types.NewInt(0), - ParentStateRoot: stateroot, - Messages: mmb.Cid(), - ParentMessageReceipts: emptyroot, - BLSAggregate: types.Signature{Type: types.KTBLS, Data: []byte("signatureeee")}, - BlockSig: &types.Signature{Type: types.KTBLS, Data: []byte("block signatureeee")}, - Timestamp: ts, - } - - sb, err := b.ToStorageBlock() - if err != nil { - return nil, xerrors.Errorf("serializing block header failed: %w", err) - } - - if err := bs.Put(sb); err != nil { - return nil, xerrors.Errorf("putting header to blockstore: %w", err) - } - - return &GenesisBootstrap{ - Genesis: b, - }, nil -} - -func AdjustInitActorStartID(ctx context.Context, bs blockstore.Blockstore, stateroot cid.Cid, val uint64) (cid.Cid, error) { - cst := cbor.NewCborStore(bs) - - tree, err := state.LoadStateTree(cst, stateroot) - if err != nil { - return cid.Undef, err - } - - act, err := tree.GetActor(actors.InitAddress) - if err != nil { - return cid.Undef, err - } - - var st actors.InitActorState - if err := cst.Get(ctx, act.Head, &st); err != nil { - return cid.Undef, err - } - - st.NextID = val - - nstate, err := cst.Put(ctx, &st) - if err != nil { - return cid.Undef, err - } - - act.Head = nstate - - if err := tree.SetActor(actors.InitAddress, act); err != nil { - return cid.Undef, err - } - - return tree.Flush(ctx) -} diff --git a/chain/market/fundmgr.go b/chain/market/fundmgr.go index 1500a78a5..e43dbfa79 100644 --- a/chain/market/fundmgr.go +++ b/chain/market/fundmgr.go @@ -4,6 +4,7 @@ import ( "context" "sync" + "github.com/filecoin-project/specs-actors/actors/builtin" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" @@ -40,7 +41,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) @@ -55,13 +56,20 @@ func (fm *FundMgr) EnsureAvailable(ctx context.Context, addr address.Address, am fm.lk.Unlock() + var err error + params, err := actors.SerializeParams(&addr) + if err != nil { + return err + } + smsg, err := fm.mpool.MpoolPushMessage(ctx, &types.Message{ - To: actors.StorageMarketAddress, + To: builtin.StorageMarketActorAddr, From: addr, Value: toAdd, GasPrice: types.NewInt(0), GasLimit: types.NewInt(1000000), - Method: actors.SMAMethods.AddBalance, + Method: builtin.MethodsMarket.AddBalance, + Params: params, }) if err != nil { return err diff --git a/chain/messagepool/messagepool.go b/chain/messagepool/messagepool.go index 5a9deb569..7cd1aaa26 100644 --- a/chain/messagepool/messagepool.go +++ b/chain/messagepool/messagepool.go @@ -8,6 +8,7 @@ import ( "sync" "time" + "github.com/filecoin-project/specs-actors/actors/crypto" lru "github.com/hashicorp/golang-lru" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" @@ -342,7 +343,7 @@ func (mp *MessagePool) addSkipChecks(m *types.SignedMessage) error { func (mp *MessagePool) addLocked(m *types.SignedMessage) error { log.Debugf("mpooladd: %s %s", m.Message.From, m.Message.Nonce) - if m.Signature.Type == types.KTBLS { + if m.Signature.Type == crypto.SigTypeBLS { mp.blsSigCache.Add(m.Cid(), m.Signature) } @@ -656,7 +657,7 @@ func (mp *MessagePool) RecoverSig(msg *types.Message) *types.SignedMessage { if !ok { return nil } - sig, ok := val.(types.Signature) + sig, ok := val.(crypto.Signature) if !ok { log.Errorf("value in signature cache was not a signature (got %T)", val) return nil diff --git a/chain/messagepool/messagepool_test.go b/chain/messagepool/messagepool_test.go index e0b1022ab..5dfa79158 100644 --- a/chain/messagepool/messagepool_test.go +++ b/chain/messagepool/messagepool_test.go @@ -11,6 +11,7 @@ import ( "github.com/filecoin-project/lotus/chain/wallet" _ "github.com/filecoin-project/lotus/lib/sigs/bls" _ "github.com/filecoin-project/lotus/lib/sigs/secp" + "github.com/filecoin-project/specs-actors/actors/crypto" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" ) @@ -146,7 +147,7 @@ func TestMessagePool(t *testing.T) { a := mock.MkBlock(nil, 1, 1) - sender, err := w.GenerateKey(types.KTBLS) + sender, err := w.GenerateKey(crypto.SigTypeBLS) if err != nil { t.Fatal(err) } @@ -188,7 +189,7 @@ func TestRevertMessages(t *testing.T) { a := mock.MkBlock(nil, 1, 1) b := mock.MkBlock(mock.TipSet(a), 1, 1) - sender, err := w.GenerateKey(types.KTBLS) + sender, err := w.GenerateKey(crypto.SigTypeBLS) if err != nil { t.Fatal(err) } diff --git a/chain/metrics/consensus.go b/chain/metrics/consensus.go index 68584d5d5..bc7e019d2 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/state/statetree.go b/chain/state/statetree.go index 6e33aeb3e..4637540c4 100644 --- a/chain/state/statetree.go +++ b/chain/state/statetree.go @@ -3,7 +3,10 @@ package state import ( "context" "fmt" + "github.com/filecoin-project/specs-actors/actors/builtin" + init_ "github.com/filecoin-project/specs-actors/actors/builtin/init" + "github.com/filecoin-project/specs-actors/actors/util/adt" "github.com/ipfs/go-cid" hamt "github.com/ipfs/go-hamt-ipld" cbor "github.com/ipfs/go-ipld-cbor" @@ -12,7 +15,6 @@ import ( "golang.org/x/xerrors" "github.com/filecoin-project/go-address" - "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/types" ) @@ -28,14 +30,14 @@ type StateTree struct { func NewStateTree(cst cbor.IpldStore) (*StateTree, error) { return &StateTree{ - root: hamt.NewNode(cst), + root: hamt.NewNode(cst, hamt.UseTreeBitWidth(5)), Store: cst, actorcache: make(map[address.Address]*types.Actor), }, nil } func LoadStateTree(cst cbor.IpldStore, c cid.Cid) (*StateTree, error) { - nd, err := hamt.LoadNode(context.Background(), cst, c) + nd, err := hamt.LoadNode(context.Background(), cst, c, hamt.UseTreeBitWidth(5)) if err != nil { log.Errorf("loading hamt node %s failed: %s", c, err) return nil, err @@ -72,17 +74,21 @@ func (st *StateTree) LookupID(addr address.Address) (address.Address, error) { return addr, nil } - act, err := st.GetActor(actors.InitAddress) + act, err := st.GetActor(builtin.InitActorAddr) if err != nil { return address.Undef, xerrors.Errorf("getting init actor: %w", err) } - var ias actors.InitActorState + var ias init_.State if err := st.Store.Get(context.TODO(), act.Head, &ias); err != nil { return address.Undef, xerrors.Errorf("loading init actor state: %w", err) } - return ias.Lookup(st.Store, addr) + a, err := ias.ResolveAddress(&AdtStore{st.Store}, addr) + if err != nil { + return address.Undef, xerrors.Errorf("resolve address %s: %w", addr, err) + } + return a, nil } func (st *StateTree) GetActor(addr address.Address) (*types.Actor, error) { @@ -92,8 +98,8 @@ func (st *StateTree) GetActor(addr address.Address) (*types.Actor, error) { iaddr, err := st.LookupID(addr) if err != nil { - if xerrors.Is(err, hamt.ErrNotFound) { - return nil, xerrors.Errorf("resolution lookup failed (%s): %w", addr, types.ErrActorNotFound) + if xerrors.Is(err, init_.ErrAddressNotFound) { + return nil, xerrors.Errorf("resolution lookup failed (%s): %w", addr, err) } return nil, xerrors.Errorf("address resolution: %w", err) } @@ -151,13 +157,13 @@ func (st *StateTree) Snapshot(ctx context.Context) error { func (st *StateTree) RegisterNewAddress(addr address.Address, act *types.Actor) (address.Address, error) { var out address.Address - err := st.MutateActor(actors.InitAddress, func(initact *types.Actor) error { - var ias actors.InitActorState + err := st.MutateActor(builtin.InitActorAddr, func(initact *types.Actor) error { + var ias init_.State if err := st.Store.Get(context.TODO(), initact.Head, &ias); err != nil { return err } - oaddr, err := ias.AddActor(st.Store, addr) + oaddr, err := ias.MapAddressToNewID(&AdtStore{st.Store}, addr) if err != nil { return err } @@ -182,8 +188,16 @@ func (st *StateTree) RegisterNewAddress(addr address.Address, act *types.Actor) return out, nil } +type AdtStore struct{ cbor.IpldStore } + +func (a *AdtStore) Context() context.Context { + return context.TODO() +} + +var _ adt.Store = (*AdtStore)(nil) + func (st *StateTree) Revert() error { - nd, err := hamt.LoadNode(context.Background(), st.Store, st.snapshot) + nd, err := hamt.LoadNode(context.Background(), st.Store, st.snapshot, hamt.UseTreeBitWidth(5)) if err != nil { return err } diff --git a/chain/state/statetree_test.go b/chain/state/statetree_test.go index 66864f034..3231e36eb 100644 --- a/chain/state/statetree_test.go +++ b/chain/state/statetree_test.go @@ -2,10 +2,10 @@ package state import ( "context" + "github.com/filecoin-project/specs-actors/actors/builtin" "testing" address "github.com/filecoin-project/go-address" - actors "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/types" cbor "github.com/ipfs/go-ipld-cbor" ) @@ -27,8 +27,8 @@ func BenchmarkStateTreeSet(b *testing.B) { } err = st.SetActor(a, &types.Actor{ Balance: types.NewInt(1258812523), - Code: actors.StorageMinerCodeCid, - Head: actors.AccountCodeCid, + Code: builtin.StorageMinerActorCodeID, + Head: builtin.AccountActorCodeID, Nonce: uint64(i), }) if err != nil { @@ -54,8 +54,8 @@ func BenchmarkStateTreeSetFlush(b *testing.B) { } err = st.SetActor(a, &types.Actor{ Balance: types.NewInt(1258812523), - Code: actors.StorageMinerCodeCid, - Head: actors.AccountCodeCid, + Code: builtin.StorageMinerActorCodeID, + Head: builtin.AccountActorCodeID, Nonce: uint64(i), }) if err != nil { @@ -80,8 +80,8 @@ func BenchmarkStateTree10kGetActor(b *testing.B) { } err = st.SetActor(a, &types.Actor{ Balance: types.NewInt(1258812523 + uint64(i)), - Code: actors.StorageMinerCodeCid, - Head: actors.AccountCodeCid, + Code: builtin.StorageMinerActorCodeID, + Head: builtin.AccountActorCodeID, Nonce: uint64(i), }) if err != nil { @@ -123,8 +123,8 @@ func TestSetCache(t *testing.T) { act := &types.Actor{ Balance: types.NewInt(0), - Code: actors.StorageMinerCodeCid, - Head: actors.AccountCodeCid, + Code: builtin.StorageMinerActorCodeID, + Head: builtin.AccountActorCodeID, Nonce: 0, } diff --git a/chain/stmgr/call.go b/chain/stmgr/call.go index d8d46212a..720781842 100644 --- a/chain/stmgr/call.go +++ b/chain/stmgr/call.go @@ -3,23 +3,24 @@ package stmgr import ( "context" "fmt" + "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/filecoin-project/specs-actors/actors/abi" "github.com/ipfs/go-cid" "go.opencensus.io/trace" "golang.org/x/xerrors" "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" "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() - vmi, err := vm.NewVM(bstate, bheight, r, actors.NetworkAddress, sm.cs.Blockstore(), sm.cs.VMSys()) + vmi, err := vm.NewVM(bstate, bheight, r, builtin.SystemActorAddr, sm.cs.Blockstore(), sm.cs.VMSys()) if err != nil { return nil, xerrors.Errorf("failed to set up vm: %w", err) } 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/forks_test.go b/chain/stmgr/forks_test.go index 903b6e526..9357e0b8b 100644 --- a/chain/stmgr/forks_test.go +++ b/chain/stmgr/forks_test.go @@ -7,6 +7,12 @@ import ( "testing" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin" + init_ "github.com/filecoin-project/specs-actors/actors/builtin/init" + "github.com/filecoin-project/specs-actors/actors/runtime" + "github.com/filecoin-project/specs-actors/actors/util/adt" + "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/aerrors" @@ -28,7 +34,7 @@ import ( ) func init() { - build.SectorSizes = []uint64{1024} + build.SectorSizes = []abi.SectorSize{1024} build.MinimumMinerPower = 1024 } @@ -69,10 +75,14 @@ func (ta *testActor) Constructor(act *types.Actor, vmctx types.VMContext, params if err != nil { return nil, err } + empty, err := vmctx.Storage().Put(&adt.EmptyValue{}) + if err != nil { + return nil, err + } fmt.Println("NEW ACTOR ADDRESS IS: ", vmctx.Message().To.String()) - return nil, vmctx.Storage().Commit(actors.EmptyCBOR, c) + return nil, vmctx.Storage().Commit(empty, c) } func (ta *testActor) TestMethod(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, aerrors.ActorError) { @@ -114,8 +124,6 @@ func TestForkHeightTriggers(t *testing.T) { t.Fatal(err) } - actors.BuiltInActors[actcid] = true - // predicting the address here... may break if other assumptions change taddr, err := address.NewIDAddress(1000) if err != nil { @@ -156,7 +164,7 @@ func TestForkHeightTriggers(t *testing.T) { } inv.Register(actcid, &testActor{}, &testActorState{}) - sm.SetVMConstructor(func(c cid.Cid, h uint64, r vm.Rand, a address.Address, b blockstore.Blockstore, s *types.VMSyscalls) (*vm.VM, error) { + sm.SetVMConstructor(func(c cid.Cid, h abi.ChainEpoch, r vm.Rand, a address.Address, b blockstore.Blockstore, s runtime.Syscalls) (*vm.VM, error) { nvm, err := vm.NewVM(c, h, r, a, b, s) if err != nil { return nil, err @@ -169,15 +177,15 @@ func TestForkHeightTriggers(t *testing.T) { var msgs []*types.SignedMessage - enc, err := actors.SerializeParams(&actors.ExecParams{Code: actcid}) + enc, err := actors.SerializeParams(&init_.ExecParams{CodeCID: actcid}) if err != nil { t.Fatal(err) } m := &types.Message{ From: cg.Banker(), - To: actors.InitAddress, - Method: actors.IAMethods.Exec, + To: builtin.InitActorAddr, + Method: builtin.MethodsInit.Exec, Params: enc, GasLimit: types.NewInt(10000), GasPrice: types.NewInt(0), diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index a8185f159..91794aaae 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -7,11 +7,17 @@ import ( "github.com/filecoin-project/go-address" amt "github.com/filecoin-project/go-amt-ipld/v2" - "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/api" "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/abi/big" + "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/filecoin-project/specs-actors/actors/builtin/market" + "github.com/filecoin-project/specs-actors/actors/runtime" + "github.com/filecoin-project/specs-actors/actors/util/adt" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" @@ -32,7 +38,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, runtime.Syscalls) (*vm.VM, error) } func NewStateManager(cs *store.ChainStore) *StateManager { @@ -148,13 +154,13 @@ func (sm *StateManager) computeTipSetState(ctx context.Context, blks []*types.Bl return cid.Undef, cid.Undef, xerrors.Errorf("instantiating VM failed: %w", err) } - netact, err := vmi.StateTree().GetActor(actors.NetworkAddress) + rewardActor, err := vmi.StateTree().GetActor(builtin.RewardActorAddr) if err != nil { return cid.Undef, cid.Undef, xerrors.Errorf("failed to get network actor: %w", err) } - reward := vm.MiningReward(netact.Balance) - for tsi, b := range blks { - netact, err = vmi.StateTree().GetActor(actors.NetworkAddress) + reward := vm.MiningReward(rewardActor.Balance) + for _, b := range blks { + rewardActor, err = vmi.StateTree().GetActor(builtin.RewardActorAddr) if err != nil { return cid.Undef, cid.Undef, xerrors.Errorf("failed to get network actor: %w", err) } @@ -170,27 +176,9 @@ func (sm *StateManager) computeTipSetState(ctx context.Context, blks []*types.Bl return cid.Undef, cid.Undef, xerrors.Errorf("failed to get miner owner actor") } - if err := vm.Transfer(netact, act, reward); err != nil { + if err := vm.Transfer(rewardActor, act, reward); err != nil { return cid.Undef, cid.Undef, xerrors.Errorf("failed to deduct funds from network actor: %w", err) } - - // all block miners created a valid post, go update the actor state - postSubmitMsg := &types.Message{ - From: actors.NetworkAddress, - Nonce: netact.Nonce, - To: b.Miner, - Method: actors.MAMethods.SubmitElectionPoSt, - GasPrice: types.NewInt(0), - GasLimit: types.NewInt(10000000000), - Value: types.NewInt(0), - } - ret, err := vmi.ApplyMessage(ctx, postSubmitMsg) - if err != nil { - return cid.Undef, cid.Undef, xerrors.Errorf("submit election post message for block %s (miner %s) invocation failed: %w", b.Cid(), b.Miner, err) - } - if ret.ExitCode != 0 { - return cid.Undef, cid.Undef, xerrors.Errorf("submit election post invocation returned nonzero exit code: %d (err = %s, block = %s, miner = %s, tsi = %d)", ret.ExitCode, ret.ActorErr, b.Cid(), b.Miner, tsi) - } } // TODO: can't use method from chainstore because it doesnt let us know who the block miners were @@ -259,19 +247,19 @@ func (sm *StateManager) computeTipSetState(ctx context.Context, blks []*types.Bl } // TODO: this nonce-getting is a tiny bit ugly - ca, err := vmi.StateTree().GetActor(actors.CronAddress) + ca, err := vmi.StateTree().GetActor(builtin.SystemActorAddr) if err != nil { return cid.Undef, cid.Undef, err } ret, err := vmi.ApplyMessage(ctx, &types.Message{ - To: actors.CronAddress, - From: actors.CronAddress, + To: builtin.CronActorAddr, + From: builtin.SystemActorAddr, Nonce: ca.Nonce, Value: types.NewInt(0), GasPrice: types.NewInt(0), GasLimit: types.NewInt(1 << 30), // Make super sure this is never too little - Method: actors.CAMethods.EpochTick, + Method: builtin.MethodsCron.EpochTick, Params: nil, }) if err != nil { @@ -295,15 +283,27 @@ func (sm *StateManager) computeTipSetState(ctx context.Context, blks []*types.Bl return st, rectroot, nil } -func (sm *StateManager) GetActor(addr address.Address, ts *types.TipSet) (*types.Actor, error) { +func (sm *StateManager) parentState(ts *types.TipSet) cid.Cid { if ts == nil { ts = sm.cs.GetHeaviestTipSet() } - stcid := ts.ParentState() + return ts.ParentState() +} +func (sm *StateManager) GetActor(addr address.Address, ts *types.TipSet) (*types.Actor, error) { cst := cbor.NewCborStore(sm.cs.Blockstore()) - state, err := state.LoadStateTree(cst, stcid) + state, err := state.LoadStateTree(cst, sm.parentState(ts)) + if err != nil { + return nil, xerrors.Errorf("load state tree: %w", err) + } + + return state.GetActor(addr) +} + +func (sm *StateManager) getActorRaw(addr address.Address, st cid.Cid) (*types.Actor, error) { + cst := cbor.NewCborStore(sm.cs.Blockstore()) + state, err := state.LoadStateTree(cst, st) if err != nil { return nil, xerrors.Errorf("load state tree: %w", err) } @@ -335,11 +335,30 @@ func (sm *StateManager) LoadActorState(ctx context.Context, a address.Address, o cst := cbor.NewCborStore(sm.cs.Blockstore()) if err := cst.Get(ctx, act.Head, out); err != nil { + var r cbg.Deferred + cst.Get(ctx, act.Head, &r) + fmt.Printf("badhead %x\n", r.Raw) + return nil, err } return act, nil } + +func (sm *StateManager) LoadActorStateRaw(ctx context.Context, a address.Address, out interface{}, st cid.Cid) (*types.Actor, error) { + act, err := sm.getActorRaw(a, st) + if err != nil { + return nil, err + } + + cst := cbor.NewCborStore(sm.cs.Blockstore()) + if err := cst.Get(ctx, act.Head, out); err != nil { + return nil, err + } + + return act, nil +} + func (sm *StateManager) ResolveToKeyAddress(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) { switch addr.Protocol() { case address.BLS, address.SECP256K1: @@ -381,6 +400,15 @@ func (sm *StateManager) GetBlsPublicKey(ctx context.Context, addr address.Addres return pubk, nil } +func (sm *StateManager) LookupID(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) { + cst := cbor.NewCborStore(sm.cs.Blockstore()) + state, err := state.LoadStateTree(cst, sm.parentState(ts)) + if err != nil { + return address.Undef, xerrors.Errorf("load state tree: %w", err) + } + return state.LookupID(addr) +} + func (sm *StateManager) GetReceipt(ctx context.Context, msg cid.Cid, ts *types.TipSet) (*types.MessageReceipt, error) { m, err := sm.cs.GetCMessage(msg) if err != nil { @@ -577,7 +605,7 @@ func (sm *StateManager) ListAllActors(ctx context.Context, ts *types.TipSet) ([] } cst := cbor.NewCborStore(sm.cs.Blockstore()) - r, err := hamt.LoadNode(ctx, cst, st) + r, err := hamt.LoadNode(ctx, cst, st, hamt.UseTreeBitWidth(5)) if err != nil { return nil, err } @@ -598,18 +626,49 @@ 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) { - 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) +func (sm *StateManager) MarketBalance(ctx context.Context, addr address.Address, ts *types.TipSet) (api.MarketBalance, error) { + var state market.State + _, err := sm.LoadActorState(ctx, builtin.StorageMarketActorAddr, &state, ts) if err != nil { - return actors.StorageParticipantBalance{}, err + return api.MarketBalance{}, err } - return b[0], nil + addr, err = sm.LookupID(ctx, addr, ts) + if err != nil { + return api.MarketBalance{}, err + } + + var out api.MarketBalance + + et := adt.AsBalanceTable(sm.cs.Store(ctx), state.EscrowTable) + ehas, err := et.Has(addr) + if err != nil { + return api.MarketBalance{}, err + } + if ehas { + out.Escrow, err = et.Get(addr) + if err != nil { + return api.MarketBalance{}, xerrors.Errorf("getting escrow balance: %w", err) + } + } else { + out.Escrow = big.Zero() + } + + lt := adt.AsBalanceTable(sm.cs.Store(ctx), state.LockedTable) + lhas, err := lt.Has(addr) + if err != nil { + return api.MarketBalance{}, err + } + if lhas { + out.Locked, err = lt.Get(addr) + if err != nil { + return api.MarketBalance{}, xerrors.Errorf("getting locked balance: %w", err) + } + } else { + out.Locked = big.Zero() + } + + return out, nil } func (sm *StateManager) ValidateChain(ctx context.Context, ts *types.TipSet) error { @@ -641,6 +700,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, runtime.Syscalls) (*vm.VM, error)) { sm.newVM = nvm } diff --git a/chain/stmgr/utils.go b/chain/stmgr/utils.go index 6ab4044ba..2f99cd9f1 100644 --- a/chain/stmgr/utils.go +++ b/chain/stmgr/utils.go @@ -2,17 +2,27 @@ package stmgr import ( "context" + "github.com/filecoin-project/lotus/chain/state" amt "github.com/filecoin-project/go-amt-ipld/v2" + commcid "github.com/filecoin-project/go-fil-commcid" + "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" + "github.com/filecoin-project/specs-actors/actors/builtin/market" + "github.com/filecoin-project/specs-actors/actors/builtin/miner" + "github.com/filecoin-project/specs-actors/actors/builtin/power" + "github.com/filecoin-project/specs-actors/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors/aerrors" - ffi "github.com/filecoin-project/filecoin-ffi" sectorbuilder "github.com/filecoin-project/go-sectorbuilder" + ffi "github.com/filecoin-project/filecoin-ffi" + "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" "github.com/filecoin-project/lotus/chain/vm" @@ -26,146 +36,83 @@ import ( ) func GetMinerWorkerRaw(ctx context.Context, sm *StateManager, st cid.Cid, maddr address.Address) (address.Address, error) { - recp, err := sm.CallRaw(ctx, &types.Message{ - To: maddr, - From: maddr, - Method: actors.MAMethods.GetWorkerAddr, - }, st, nil, 0) + var mas miner.State + _, err := sm.LoadActorStateRaw(ctx, maddr, &mas, st) if err != nil { - return address.Undef, xerrors.Errorf("callRaw failed: %w", err) + return address.Undef, xerrors.Errorf("(get sset) failed to load miner actor state: %w", err) } - if recp.ExitCode != 0 { - return address.Undef, xerrors.Errorf("getting miner worker addr failed (exit code %d)", recp.ExitCode) - } - - worker, err := address.NewFromBytes(recp.Return) + cst := cbor.NewCborStore(sm.cs.Blockstore()) + state, err := state.LoadStateTree(cst, st) if err != nil { - return address.Undef, err + return address.Undef, xerrors.Errorf("load state tree: %w", err) } - if worker.Protocol() == address.ID { - return address.Undef, xerrors.Errorf("need to resolve worker address to a pubkeyaddr") - } - - return worker, nil + return vm.ResolveToKeyAddr(state, cst, mas.Info.Worker) } func GetMinerOwner(ctx context.Context, sm *StateManager, st cid.Cid, maddr address.Address) (address.Address, error) { - recp, err := sm.CallRaw(ctx, &types.Message{ - To: maddr, - From: maddr, - Method: actors.MAMethods.GetOwner, - }, st, nil, 0) + var mas miner.State + _, err := sm.LoadActorStateRaw(ctx, maddr, &mas, st) if err != nil { - return address.Undef, xerrors.Errorf("callRaw failed: %w", err) + return address.Undef, xerrors.Errorf("(get sset) failed to load miner actor state: %w", err) } - if recp.ExitCode != 0 { - return address.Undef, xerrors.Errorf("getting miner owner addr failed (exit code %d)", recp.ExitCode) - } - - owner, err := address.NewFromBytes(recp.Return) + cst := cbor.NewCborStore(sm.cs.Blockstore()) + state, err := state.LoadStateTree(cst, st) if err != nil { - return address.Undef, err + return address.Undef, xerrors.Errorf("load state tree: %w", err) } - if owner.Protocol() == address.ID { - return address.Undef, xerrors.Errorf("need to resolve owner address to a pubkeyaddr") - } - - return owner, nil + return vm.ResolveToKeyAddr(state, cst, mas.Info.Owner) } func GetPower(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (types.BigInt, types.BigInt, error) { - var err error - - var mpow types.BigInt - - if maddr != address.Undef { - enc, aerr := actors.SerializeParams(&actors.PowerLookupParams{maddr}) - if aerr != nil { - return types.EmptyInt, types.EmptyInt, aerr - } - ret, err := sm.Call(ctx, &types.Message{ - From: maddr, - To: actors.StoragePowerAddress, - Method: actors.SPAMethods.PowerLookup, - Params: enc, - }, ts) - if err != nil { - return types.EmptyInt, types.EmptyInt, xerrors.Errorf("failed to get miner power from chain: %w", err) - } - if ret.ExitCode != 0 { - return types.EmptyInt, types.EmptyInt, xerrors.Errorf("failed to get miner power from chain (exit code %d)", ret.ExitCode) - } - - mpow = types.BigFromBytes(ret.Return) - } - - ret, err := sm.Call(ctx, &types.Message{ - From: actors.StoragePowerAddress, - To: actors.StoragePowerAddress, - Method: actors.SPAMethods.GetTotalStorage, - }, ts) + var ps power.State + _, err := sm.LoadActorState(ctx, builtin.StoragePowerActorAddr, &ps, ts) if err != nil { - return types.EmptyInt, types.EmptyInt, xerrors.Errorf("failed to get total power from chain: %w", err) - } - if ret.ExitCode != 0 { - return types.EmptyInt, types.EmptyInt, xerrors.Errorf("failed to get total power from chain (exit code %d)", ret.ExitCode) + return big.Zero(), big.Zero(), xerrors.Errorf("(get sset) failed to load power actor state: %w", err) } - tpow := types.BigFromBytes(ret.Return) + var mpow big.Int + if maddr != address.Undef { + var claim power.Claim + if _, err := adt.AsMap(sm.cs.Store(ctx), ps.Claims).Get(adt.AddrKey(maddr), &claim); err != nil { + return big.Zero(), big.Zero(), err + } - return mpow, tpow, nil + mpow = claim.Power + } + + return mpow, ps.TotalNetworkPower, nil } func GetMinerPeerID(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (peer.ID, error) { - recp, err := sm.Call(ctx, &types.Message{ - To: maddr, - From: maddr, - Method: actors.MAMethods.GetPeerID, - }, ts) + var mas miner.State + _, err := sm.LoadActorState(ctx, maddr, &mas, ts) if err != nil { - return "", xerrors.Errorf("call failed: %w", err) + return "", xerrors.Errorf("(get sset) failed to load miner actor state: %w", err) } - if recp.ExitCode != 0 { - return "", xerrors.Errorf("getting miner peer ID failed (exit code %d)", recp.ExitCode) - } - - return peer.IDFromBytes(recp.Return) + return mas.Info.PeerId, nil } func GetMinerWorker(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (address.Address, error) { - recp, err := sm.Call(ctx, &types.Message{ - To: maddr, - From: maddr, - Method: actors.MAMethods.GetWorkerAddr, - }, ts) - if err != nil { - return address.Undef, xerrors.Errorf("call failed: %w", err) - } - - if recp.ExitCode != 0 { - return address.Undef, xerrors.Errorf("getting miner peer ID failed (exit code %d)", recp.ExitCode) - } - - return address.NewFromBytes(recp.Return) + return GetMinerWorkerRaw(ctx, sm, sm.parentState(ts), maddr) } -func GetMinerElectionPeriodStart(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (uint64, error) { - var mas actors.StorageMinerActorState +func GetMinerPostState(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (*miner.PoStState, error) { + var mas miner.State _, err := sm.LoadActorState(ctx, maddr, &mas, ts) if err != nil { - return 0, xerrors.Errorf("(get eps) failed to load miner actor state: %w", err) + return nil, xerrors.Errorf("(get eps) failed to load miner actor state: %w", err) } - return mas.ElectionPeriodStart, nil + return &mas.PoStState, nil } func SectorSetSizes(ctx context.Context, sm *StateManager, maddr address.Address, ts *types.TipSet) (api.MinerSectors, error) { - var mas actors.StorageMinerActorState + var mas miner.State _, err := sm.LoadActorState(ctx, maddr, &mas, ts) if err != nil { return api.MinerSectors{}, xerrors.Errorf("(get sset) failed to load miner actor state: %w", err) @@ -189,7 +136,7 @@ func SectorSetSizes(ctx context.Context, sm *StateManager, maddr address.Address } func GetMinerProvingSet(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) ([]*api.ChainSectorInfo, error) { - var mas actors.StorageMinerActorState + var mas miner.State _, err := sm.LoadActorState(ctx, maddr, &mas, ts) if err != nil { return nil, xerrors.Errorf("(get pset) failed to load miner actor state: %w", err) @@ -199,7 +146,7 @@ func GetMinerProvingSet(ctx context.Context, sm *StateManager, ts *types.TipSet, } func GetMinerSectorSet(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) ([]*api.ChainSectorInfo, error) { - var mas actors.StorageMinerActorState + var mas miner.State _, err := sm.LoadActorState(ctx, maddr, &mas, ts) if err != nil { return nil, xerrors.Errorf("(get sset) failed to load miner actor state: %w", err) @@ -216,11 +163,15 @@ func GetSectorsForElectionPost(ctx context.Context, sm *StateManager, ts *types. var uselessOtherArray []ffi.PublicSectorInfo for _, s := range sectors { + cr, err := commcid.CIDToReplicaCommitmentV1(s.Info.Info.SealedCID) + if err != nil { + return nil, err + } var uselessBuffer [32]byte - copy(uselessBuffer[:], s.CommR) + copy(uselessBuffer[:], cr) uselessOtherArray = append(uselessOtherArray, ffi.PublicSectorInfo{ - SectorID: s.SectorID, - CommR: uselessBuffer, + SectorNum: s.ID, + CommR: uselessBuffer, }) } @@ -228,34 +179,23 @@ 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) { - var mas actors.StorageMinerActorState +func GetMinerSectorSize(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (abi.SectorSize, error) { + var mas miner.State _, err := sm.LoadActorState(ctx, maddr, &mas, ts) if err != nil { return 0, xerrors.Errorf("(get ssize) failed to load miner actor state: %w", err) } - cst := cbor.NewCborStore(sm.cs.Blockstore()) - var minfo actors.MinerInfo - if err := cst.Get(ctx, mas.Info, &minfo); err != nil { - return 0, xerrors.Errorf("failed to read miner info: %w", err) - } - - return minfo.SectorSize, nil + return mas.Info.SectorSize, nil } func GetMinerSlashed(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (uint64, error) { - var mas actors.StorageMinerActorState - _, err := sm.LoadActorState(ctx, maddr, &mas, ts) - if err != nil { - return 0, xerrors.Errorf("(get mslash) failed to load miner actor state: %w", err) - } - - return mas.SlashedAt, nil + log.Warn("stub GetMinerSlashed") + return 0, nil } -func GetMinerFaults(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) ([]uint64, error) { - var mas actors.StorageMinerActorState +func GetMinerFaults(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) ([]abi.SectorNumber, error) { + var mas miner.State _, err := sm.LoadActorState(ctx, maddr, &mas, ts) if err != nil { return nil, xerrors.Errorf("(get ssize) failed to load miner actor state: %w", err) @@ -266,36 +206,62 @@ func GetMinerFaults(ctx context.Context, sm *StateManager, ts *types.TipSet, mad return nil, aerrors.HandleExternalError(lerr, "could not load proving set node") } - return mas.FaultSet.All(2 * ss.Count) + faults, err := mas.FaultSet.All(2 * ss.Count) + if err != nil { + return nil, xerrors.Errorf("reading fault bit set: %w", err) + } + + out := make([]abi.SectorNumber, len(faults)) + for i, fault := range faults { + out[i] = abi.SectorNumber(fault) + } + + return out, nil } -func GetStorageDeal(ctx context.Context, sm *StateManager, dealId uint64, ts *types.TipSet) (*actors.OnChainDeal, error) { - var state actors.StorageMarketState - if _, err := sm.LoadActorState(ctx, actors.StorageMarketAddress, &state, ts); err != nil { +func GetStorageDeal(ctx context.Context, sm *StateManager, dealId abi.DealID, ts *types.TipSet) (*api.MarketDeal, error) { + var state market.State + if _, err := sm.LoadActorState(ctx, builtin.StorageMarketActorAddr, &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 - if err := da.Get(ctx, dealId, &ocd); err != nil { + var dp market.DealProposal + if err := da.Get(ctx, uint64(dealId), &dp); err != nil { return nil, err } - return &ocd, nil + sa := market.AsDealStateArray(sm.ChainStore().Store(ctx), state.States) + st, err := sa.Get(dealId) + if err != nil { + return nil, err + } + + return &api.MarketDeal{ + Proposal: dp, + State: *st, + }, nil } func ListMinerActors(ctx context.Context, sm *StateManager, ts *types.TipSet) ([]address.Address, error) { - var state actors.StoragePowerState - if _, err := sm.LoadActorState(ctx, actors.StoragePowerAddress, &state, ts); err != nil { + var state power.State + if _, err := sm.LoadActorState(ctx, builtin.StoragePowerActorAddr, &state, ts); err != nil { return nil, err } - cst := cbor.NewCborStore(sm.ChainStore().Blockstore()) - miners, err := actors.MinerSetList(ctx, cst, state.Miners) + var miners []address.Address + err := adt.AsMap(sm.cs.Store(ctx), state.Claims).ForEach(nil, func(k string) error { + a, err := address.NewFromBytes([]byte(k)) + if err != nil { + return err + } + miners = append(miners, a) + return nil + }) if err != nil { return nil, err } @@ -311,14 +277,13 @@ func LoadSectorsFromSet(ctx context.Context, bs blockstore.Blockstore, ssc cid.C var sset []*api.ChainSectorInfo if err := a.ForEach(ctx, func(i uint64, v *cbg.Deferred) error { - var comms [][]byte - if err := cbor.DecodeInto(v.Raw, &comms); err != nil { + var oci miner.SectorOnChainInfo + if err := cbor.DecodeInto(v.Raw, &oci); err != nil { return err } sset = append(sset, &api.ChainSectorInfo{ - SectorID: i, - CommR: comms[0], - CommD: comms[1], + Info: oci, + ID: abi.SectorNumber(i), }) return nil }); err != nil { @@ -328,7 +293,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() } @@ -344,7 +309,7 @@ func ComputeState(ctx context.Context, sm *StateManager, height uint64, msgs []* } r := store.NewChainRand(sm.cs, ts.Cids(), height) - vmi, err := vm.NewVM(fstate, height, r, actors.NetworkAddress, sm.cs.Blockstore(), sm.cs.VMSys()) + vmi, err := vm.NewVM(fstate, height, r, builtin.SystemActorAddr, sm.cs.Blockstore(), sm.cs.VMSys()) if err != nil { return cid.Undef, err } diff --git a/chain/store/store.go b/chain/store/store.go index a04b036a6..ff40b6da1 100644 --- a/chain/store/store.go +++ b/chain/store/store.go @@ -3,20 +3,26 @@ package store import ( "bytes" "context" - "crypto/sha256" "encoding/binary" "encoding/json" + "github.com/filecoin-project/specs-actors/actors/crypto" + "github.com/minio/blake2b-simd" "io" "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/runtime" + "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 +57,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 @@ -59,17 +65,17 @@ type ChainStore struct { mmCache *lru.ARCCache tsCache *lru.ARCCache - vmcalls *types.VMSyscalls + vmcalls runtime.Syscalls } -func NewChainStore(bs bstore.Blockstore, ds dstore.Batching, vmcalls *types.VMSyscalls) *ChainStore { +func NewChainStore(bs bstore.Blockstore, ds dstore.Batching, vmcalls runtime.Syscalls) *ChainStore { c, _ := lru.NewARC(2048) tsc, _ := lru.NewARC(4096) cs := &ChainStore{ 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,7 +835,35 @@ func (cs *ChainStore) Blockstore() bstore.Blockstore { return cs.bs } -func (cs *ChainStore) VMSys() *types.VMSyscalls { +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() runtime.Syscalls { return cs.vmcalls } @@ -855,22 +889,30 @@ func (cs *ChainStore) TryFillTipSet(ts *types.TipSet) (*FullTipSet, error) { return NewFullTipSet(out), nil } -func drawRandomness(t *types.Ticket, round int64) []byte { - h := sha256.New() - var buf [8]byte - binary.LittleEndian.PutUint64(buf[:], uint64(round)) - +func drawRandomness(t *types.Ticket, pers crypto.DomainSeparationTag, round int64, entropy []byte) ([]byte, error) { + // TODO: Make this spec compliant + h := blake2b.New256() + if err := binary.Write(h, binary.BigEndian, int64(pers)); err != nil { + return nil, xerrors.Errorf("deriving randomness: %w", err) + } h.Write(t.VRFProof) - h.Write(buf[:]) + if err := binary.Write(h, binary.BigEndian, round); err != nil { + return nil, xerrors.Errorf("deriving randomness: %w", err) + } + h.Write(entropy) - return h.Sum(nil) + return h.Sum(nil), nil } -func (cs *ChainStore) GetRandomness(ctx context.Context, blks []cid.Cid, round int64) ([]byte, error) { +func (cs *ChainStore) GetRandomness(ctx context.Context, blks []cid.Cid, pers crypto.DomainSeparationTag, round int64, entropy []byte) (out []byte, err error) { _, span := trace.StartSpan(ctx, "store.GetRandomness") defer span.End() span.AddAttributes(trace.Int64Attribute("round", round)) + defer func() { + log.Infof("getRand %v %d %d %x -> %x", blks, pers, round, entropy, out) + }() + for { nts, err := cs.LoadTipSet(types.NewTipSetKey(blks...)) if err != nil { @@ -880,7 +922,7 @@ func (cs *ChainStore) GetRandomness(ctx context.Context, blks []cid.Cid, round i mtb := nts.MinTicketBlock() if int64(nts.Height()) <= round { - return drawRandomness(nts.MinTicketBlock().Ticket, round), nil + return drawRandomness(nts.MinTicketBlock().Ticket, pers, round, entropy) } // special case for lookback behind genesis block @@ -888,10 +930,13 @@ func (cs *ChainStore) GetRandomness(ctx context.Context, blks []cid.Cid, round i if mtb.Height == 0 { // round is negative - thash := drawRandomness(mtb.Ticket, round*-1) + thash, err := drawRandomness(mtb.Ticket, pers, round*-1, entropy) + if err != nil { + return nil, err + } // for negative lookbacks, just use the hash of the positive tickethash value - h := sha256.Sum256(thash) + h := blake2b.Sum256(thash) return h[:], nil } @@ -899,7 +944,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 +1052,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, @@ -1018,8 +1063,8 @@ func NewChainRand(cs *ChainStore, blks []cid.Cid, bheight uint64) vm.Rand { } } -func (cr *chainRand) GetRandomness(ctx context.Context, round int64) ([]byte, error) { - return cr.cs.GetRandomness(ctx, cr.blks, round) +func (cr *chainRand) GetRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round int64, entropy []byte) ([]byte, error) { + return cr.cs.GetRandomness(ctx, cr.blks, pers, round, entropy) } func (cs *ChainStore) GetTipSetFromKey(tsk types.TipSetKey) (*types.TipSet, error) { diff --git a/chain/store/store_test.go b/chain/store/store_test.go index c3c7a2ef4..e1d0deb29 100644 --- a/chain/store/store_test.go +++ b/chain/store/store_test.go @@ -9,11 +9,12 @@ import ( "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/node/repo" + "github.com/filecoin-project/specs-actors/actors/abi" blockstore "github.com/ipfs/go-ipfs-blockstore" ) func init() { - build.SectorSizes = []uint64{1024} + build.SectorSizes = []abi.SectorSize{1024} build.MinimumMinerPower = 1024 } diff --git a/chain/store/weight.go b/chain/store/weight.go index 49ef9ef26..d4005bb3d 100644 --- a/chain/store/weight.go +++ b/chain/store/weight.go @@ -5,9 +5,13 @@ import ( "math/big" "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/vm" + big2 "github.com/filecoin-project/specs-actors/actors/abi/big" + "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/filecoin-project/specs-actors/actors/builtin/power" + cbor "github.com/ipfs/go-ipld-cbor" "golang.org/x/xerrors" ) @@ -23,19 +27,27 @@ func (cs *ChainStore) Weight(ctx context.Context, ts *types.TipSet) (types.BigIn // >>> wFunction(totalPowerAtTipset(ts)) * 2^8 <<< + (wFunction(totalPowerAtTipset(ts)) * len(ts.blocks) * wRatio_num * 2^8) / (e * wRatio_den) - ret, err := cs.call(ctx, &types.Message{ - From: actors.StoragePowerAddress, - To: actors.StoragePowerAddress, - Method: actors.SPAMethods.GetTotalStorage, - }, ts) - if err != nil { - return types.EmptyInt, xerrors.Errorf("failed to get total power from chain: %w", err) - } - if ret.ExitCode != 0 { - return types.EmptyInt, xerrors.Errorf("failed to get total power from chain (exit code %d)", ret.ExitCode) + tpow := big2.Zero() + { + cst := cbor.NewCborStore(cs.Blockstore()) + state, err := state.LoadStateTree(cst, ts.ParentState()) + if err != nil { + return types.NewInt(0), xerrors.Errorf("load state tree: %w", err) + } + + act, err := state.GetActor(builtin.StoragePowerActorAddr) + if err != nil { + return types.NewInt(0), xerrors.Errorf("get power actor: %w", err) + } + + var st power.State + if err := cst.Get(ctx, act.Head, &st); err != nil { + return types.NewInt(0), xerrors.Errorf("get power actor head: %w", err) + } + tpow = st.TotalNetworkPower } + log2P := int64(0) - tpow := types.BigFromBytes(ret.Return) if tpow.GreaterThan(zero) { log2P = int64(tpow.BitLen() - 1) } else { @@ -60,7 +72,7 @@ func (cs *ChainStore) call(ctx context.Context, msg *types.Message, ts *types.Ti r := NewChainRand(cs, ts.Cids(), ts.Height()) - vmi, err := vm.NewVM(bstate, ts.Height(), r, actors.NetworkAddress, cs.bs, cs.vmcalls) + vmi, err := vm.NewVM(bstate, ts.Height(), r, builtin.SystemActorAddr, cs.bs, cs.vmcalls) if err != nil { return nil, xerrors.Errorf("failed to set up vm: %w", err) } diff --git a/chain/sync.go b/chain/sync.go index 014889e93..1229e754b 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -1,18 +1,20 @@ package chain import ( - "bytes" "context" "crypto/sha256" "errors" "fmt" + "github.com/filecoin-project/specs-actors/actors/builtin" "sync" "time" "github.com/Gurpartap/async" - bls "github.com/filecoin-project/filecoin-ffi" amt "github.com/filecoin-project/go-amt-ipld/v2" sectorbuilder "github.com/filecoin-project/go-sectorbuilder" + "github.com/filecoin-project/specs-actors/actors/builtin/power" + "github.com/filecoin-project/specs-actors/actors/crypto" + "github.com/filecoin-project/specs-actors/actors/util/adt" "github.com/hashicorp/go-multierror" "github.com/ipfs/go-cid" dstore "github.com/ipfs/go-datastore" @@ -26,11 +28,12 @@ import ( "go.opencensus.io/trace" "golang.org/x/xerrors" + bls "github.com/filecoin-project/filecoin-ffi" + "github.com/filecoin-project/go-address" "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/blocksync" "github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/state" @@ -464,30 +467,21 @@ func (syncer *Syncer) ValidateTipSet(ctx context.Context, fts *store.FullTipSet) } func (syncer *Syncer) minerIsValid(ctx context.Context, maddr address.Address, baseTs *types.TipSet) error { - var err error - enc, err := actors.SerializeParams(&actors.IsValidMinerParam{Addr: maddr}) + var spast power.State + + _, err := syncer.sm.LoadActorState(ctx, builtin.StoragePowerActorAddr, &spast, baseTs) if err != nil { return err } - ret, err := syncer.sm.Call(ctx, &types.Message{ - To: actors.StoragePowerAddress, - From: maddr, - Method: actors.SPAMethods.IsValidMiner, - Params: enc, - }, baseTs) + var claim power.Claim + exist, err := adt.AsMap(syncer.store.Store(ctx), spast.Claims).Get(adt.AddrKey(maddr), &claim) if err != nil { - return xerrors.Errorf("checking if block miner is valid failed: %w", err) + return err } - - if ret.ExitCode != 0 { - return xerrors.Errorf("StorageMarket.IsValidMiner check failed (exit code %d)", ret.ExitCode) - } - - if !bytes.Equal(ret.Return, cbg.CborBoolTrue) { + if !exist { return xerrors.New("miner isn't valid") } - return nil } @@ -520,9 +514,11 @@ 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()) + diff := (baseTs.MinTimestamp() + (build.BlockDelay * uint64(h.Height-baseTs.Height()))) - h.Timestamp + + return xerrors.Errorf("block was generated too soon (h.ts:%d < base.mints:%d + BLOCK_DELAY:%d * deltaH:%d; diff %d)", h.Timestamp, baseTs.MinTimestamp(), build.BlockDelay, h.Height-baseTs.Height(), diff) } winnerCheck := async.Err(func() error { @@ -545,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") @@ -617,10 +613,12 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err }) tktsCheck := async.Err(func() error { - vrfBase := baseTs.MinTicket().VRFProof - - err := gen.VerifyVRF(ctx, waddr, h.Miner, gen.DSepTicket, vrfBase, h.Ticket.VRFProof) + vrfBase, err := syncer.sm.ChainStore().GetRandomness(ctx, baseTs.Cids(), crypto.DomainSeparationTag_TicketProduction, int64(baseTs.Height()), h.Miner.Bytes()) + if err != nil { + return xerrors.Errorf("failed to get randomness for verifying election proof: %w", err) + } + err = gen.VerifyVRF(ctx, waddr, vrfBase, h.Ticket.VRFProof) if err != nil { return xerrors.Errorf("validating block tickets failed: %w", err) } @@ -654,12 +652,12 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err } func (syncer *Syncer) VerifyElectionPoStProof(ctx context.Context, h *types.BlockHeader, baseTs *types.TipSet, waddr address.Address) error { - rand, err := syncer.sm.ChainStore().GetRandomness(ctx, baseTs.Cids(), int64(h.Height-build.EcRandomnessLookback)) + rand, err := syncer.sm.ChainStore().GetRandomness(ctx, baseTs.Cids(), crypto.DomainSeparationTag_ElectionPoStChallengeSeed, int64(h.Height-build.EcRandomnessLookback), h.Miner.Bytes()) if err != nil { return xerrors.Errorf("failed to get randomness for verifying election proof: %w", err) } - if err := VerifyElectionPoStVRF(ctx, h.EPostProof.PostRand, rand, waddr, h.Miner); err != nil { + if err := VerifyElectionPoStVRF(ctx, h.EPostProof.PostRand, rand, waddr); err != nil { return xerrors.Errorf("checking eproof failed: %w", err) } @@ -674,7 +672,7 @@ func (syncer *Syncer) VerifyElectionPoStProof(ctx context.Context, h *types.Bloc copy(partial[:], t.Partial) winners = append(winners, sectorbuilder.EPostCandidate{ PartialTicket: partial, - SectorID: t.SectorID, + SectorNum: t.SectorID, SectorChallengeIndex: t.ChallengeIndex, }) } @@ -825,7 +823,7 @@ func (syncer *Syncer) checkBlockMessages(ctx context.Context, b *types.FullBlock return nil } -func (syncer *Syncer) verifyBlsAggregate(ctx context.Context, sig types.Signature, msgs []cid.Cid, pubks []bls.PublicKey) error { +func (syncer *Syncer) verifyBlsAggregate(ctx context.Context, sig crypto.Signature, msgs []cid.Cid, pubks []bls.PublicKey) error { _, span := trace.StartSpan(ctx, "syncer.verifyBlsAggregate") defer span.End() span.AddAttributes( @@ -1119,8 +1117,8 @@ func persistMessages(bs bstore.Blockstore, bst *blocksync.BSTipSet) error { } } for _, m := range bst.SecpkMessages { - if m.Signature.Type != types.KTSecp256k1 { - return xerrors.Errorf("unknown signature type on message %s: %q", m.Cid(), m.Signature.TypeCode) + if m.Signature.Type != crypto.SigTypeSecp256k1 { + return xerrors.Errorf("unknown signature type on message %s: %q", m.Cid(), m.Signature.Type) } //log.Infof("putting secp256k1 message: %s", m.Cid()) if _, err := store.PutMessage(bs, m); err != nil { @@ -1178,8 +1176,8 @@ func (syncer *Syncer) collectChain(ctx context.Context, ts *types.TipSet) error return nil } -func VerifyElectionPoStVRF(ctx context.Context, evrf []byte, rand []byte, worker, miner address.Address) error { - if err := gen.VerifyVRF(ctx, worker, miner, gen.DSepElectionPost, rand, evrf); err != nil { +func VerifyElectionPoStVRF(ctx context.Context, evrf []byte, rand []byte, worker address.Address) error { + if err := gen.VerifyVRF(ctx, worker, rand, evrf); err != nil { return xerrors.Errorf("failed to verify post_randomness vrf: %w", err) } diff --git a/chain/sync_test.go b/chain/sync_test.go index 5964d18c8..f1979f4e7 100644 --- a/chain/sync_test.go +++ b/chain/sync_test.go @@ -7,6 +7,7 @@ import ( "testing" "time" + "github.com/filecoin-project/specs-actors/actors/abi" logging "github.com/ipfs/go-log/v2" "github.com/libp2p/go-libp2p-core/peer" mocknet "github.com/libp2p/go-libp2p/p2p/net/mock" @@ -27,7 +28,7 @@ import ( func init() { build.InsecurePoStValidation = true os.Setenv("TRUST_PARAMS", "1") - build.SectorSizes = []uint64{1024} + build.SectorSizes = []abi.SectorSize{1024} build.MinimumMinerPower = 1024 } @@ -158,7 +159,6 @@ func (tu *syncTestUtil) pushTsExpectErr(to int, fts *store.FullTipSet, experr bo require.NoError(tu.t, err) } } - } func (tu *syncTestUtil) mineOnBlock(blk *store.FullTipSet, src int, miners []int, wait, fail bool) *store.FullTipSet { @@ -398,7 +398,7 @@ func TestSyncBadTimestamp(t *testing.T) { tu.waitUntilSync(0, client) base := tu.g.CurTipset - tu.g.Timestamper = func(pts *types.TipSet, tl uint64) uint64 { + tu.g.Timestamper = func(pts *types.TipSet, tl abi.ChainEpoch) uint64 { return pts.MinTimestamp() + (build.BlockDelay / 2) } 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/actor.go b/chain/types/actor.go index a3a4418c1..30661a74c 100644 --- a/chain/types/actor.go +++ b/chain/types/actor.go @@ -1,12 +1,12 @@ package types import ( - "fmt" - "github.com/ipfs/go-cid" + + init_ "github.com/filecoin-project/specs-actors/actors/builtin/init" ) -var ErrActorNotFound = fmt.Errorf("actor not found") +var ErrActorNotFound = init_.ErrAddressNotFound type Actor struct { Code cid.Cid diff --git a/chain/types/ask.go b/chain/types/ask.go deleted file mode 100644 index 42265c9dc..000000000 --- a/chain/types/ask.go +++ /dev/null @@ -1,27 +0,0 @@ -package types - -import ( - "github.com/filecoin-project/go-address" - cbor "github.com/ipfs/go-ipld-cbor" -) - -func init() { - cbor.RegisterCborType(SignedStorageAsk{}) - cbor.RegisterCborType(StorageAsk{}) -} - -type SignedStorageAsk struct { - Ask *StorageAsk - Signature *Signature -} - -type StorageAsk struct { - // Price per GiB / Epoch - Price BigInt - - MinPieceSize uint64 - Miner address.Address - Timestamp uint64 - Expiry uint64 - SeqNo uint64 -} 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/bigint_test.go b/chain/types/bigint_test.go index be77acbde..2f632d1d7 100644 --- a/chain/types/bigint_test.go +++ b/chain/types/bigint_test.go @@ -67,7 +67,7 @@ func TestSizeStr(t *testing.T) { } for _, c := range cases { - assert.Equal(t, c.out, NewInt(c.in).SizeStr(), "input %+v, produced wrong result", c) + assert.Equal(t, c.out, SizeStr(NewInt(c.in)), "input %+v, produced wrong result", c) } } @@ -75,6 +75,6 @@ func TestSizeStrBig(t *testing.T) { ZiB := big.NewInt(50000) ZiB = ZiB.Lsh(ZiB, 70) - assert.Equal(t, "5e+04 ZiB", BigInt{Int: ZiB}.SizeStr(), "inout %+v, produced wrong result", ZiB) + assert.Equal(t, "5e+04 ZiB", SizeStr(BigInt{Int: ZiB}), "inout %+v, produced wrong result", ZiB) } diff --git a/chain/types/bitfield.go b/chain/types/bitfield.go deleted file mode 100644 index 81031085b..000000000 --- a/chain/types/bitfield.go +++ /dev/null @@ -1,226 +0,0 @@ -package types - -import ( - "errors" - "fmt" - "io" - - rlepluslazy "github.com/filecoin-project/lotus/lib/rlepluslazy" - cbg "github.com/whyrusleeping/cbor-gen" - "golang.org/x/xerrors" -) - -var ErrBitFieldTooMany = errors.New("to many items in RLE") - -type BitField struct { - rle rlepluslazy.RLE - - bits map[uint64]struct{} -} - -func NewBitField() BitField { - bf, err := NewBitFieldFromBytes([]byte{}) - if err != nil { - panic(fmt.Sprintf("creating empty rle: %+v", err)) - } - return bf -} - -func NewBitFieldFromBytes(rle []byte) (BitField, error) { - bf := BitField{} - rlep, err := rlepluslazy.FromBuf(rle) - if err != nil { - return BitField{}, xerrors.Errorf("could not decode rle+: %w", err) - } - bf.rle = rlep - bf.bits = make(map[uint64]struct{}) - return bf, nil - -} - -func BitFieldFromSet(setBits []uint64) BitField { - res := BitField{bits: make(map[uint64]struct{})} - for _, b := range setBits { - res.bits[b] = struct{}{} - } - return res -} - -func MergeBitFields(a, b BitField) (BitField, error) { - ra, err := a.rle.RunIterator() - if err != nil { - return BitField{}, err - } - - rb, err := b.rle.RunIterator() - if err != nil { - return BitField{}, err - } - - merge, err := rlepluslazy.Sum(ra, rb) - if err != nil { - return BitField{}, err - } - - mergebytes, err := rlepluslazy.EncodeRuns(merge, nil) - if err != nil { - return BitField{}, err - } - - rle, err := rlepluslazy.FromBuf(mergebytes) - if err != nil { - return BitField{}, err - } - - return BitField{ - rle: rle, - bits: make(map[uint64]struct{}), - }, nil -} - -func (bf BitField) sum() (rlepluslazy.RunIterator, error) { - if len(bf.bits) == 0 { - return bf.rle.RunIterator() - } - - a, err := bf.rle.RunIterator() - if err != nil { - return nil, err - } - slc := make([]uint64, 0, len(bf.bits)) - for b := range bf.bits { - slc = append(slc, b) - } - - b, err := rlepluslazy.RunsFromSlice(slc) - if err != nil { - return nil, err - } - - res, err := rlepluslazy.Sum(a, b) - if err != nil { - return nil, err - } - return res, nil -} - -// Set ...s bit in the BitField -func (bf BitField) Set(bit uint64) { - bf.bits[bit] = struct{}{} -} - -func (bf BitField) Count() (uint64, error) { - s, err := bf.sum() - if err != nil { - return 0, err - } - return rlepluslazy.Count(s) -} - -// All returns all set bits -func (bf BitField) All(max uint64) ([]uint64, error) { - c, err := bf.Count() - if err != nil { - return nil, xerrors.Errorf("count errror: %w", err) - } - if c > max { - return nil, xerrors.Errorf("expected %d, got %d: %w", max, c, ErrBitFieldTooMany) - } - - runs, err := bf.sum() - if err != nil { - return nil, err - } - - res, err := rlepluslazy.SliceFromRuns(runs) - if err != nil { - return nil, err - } - - return res, nil -} - -func (bf BitField) AllMap(max uint64) (map[uint64]bool, error) { - c, err := bf.Count() - if err != nil { - return nil, xerrors.Errorf("count errror: %w", err) - } - if c > max { - return nil, xerrors.Errorf("expected %d, got %d: %w", max, c, ErrBitFieldTooMany) - } - - runs, err := bf.sum() - if err != nil { - return nil, err - } - - res, err := rlepluslazy.SliceFromRuns(runs) - if err != nil { - return nil, err - } - - out := make(map[uint64]bool) - for _, i := range res { - out[i] = true - } - return out, nil -} - -func (bf BitField) MarshalCBOR(w io.Writer) error { - ints := make([]uint64, 0, len(bf.bits)) - for i := range bf.bits { - ints = append(ints, i) - } - - s, err := bf.sum() - if err != nil { - return err - } - - rle, err := rlepluslazy.EncodeRuns(s, []byte{}) - if err != nil { - return err - } - - if len(rle) > 8192 { - return xerrors.Errorf("encoded bitfield was too large (%d)", len(rle)) - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(rle)))); err != nil { - return err - } - if _, err = w.Write(rle); err != nil { - return xerrors.Errorf("writing rle: %w", err) - } - return nil -} - -func (bf *BitField) UnmarshalCBOR(r io.Reader) error { - br := cbg.GetPeeker(r) - - maj, extra, err := cbg.CborReadHeader(br) - if err != nil { - return err - } - if extra > 8192 { - return fmt.Errorf("array too large") - } - - if maj != cbg.MajByteString { - return fmt.Errorf("expected byte array") - } - - buf := make([]byte, extra) - if _, err := io.ReadFull(br, buf); err != nil { - return err - } - - rle, err := rlepluslazy.FromBuf(buf) - if err != nil { - return xerrors.Errorf("could not decode rle+: %w", err) - } - bf.rle = rle - bf.bits = make(map[uint64]struct{}) - - return nil -} diff --git a/chain/types/blockheader.go b/chain/types/blockheader.go index 2dca1f99d..dd21612df 100644 --- a/chain/types/blockheader.go +++ b/chain/types/blockheader.go @@ -4,6 +4,9 @@ import ( "bytes" "math/big" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/crypto" + block "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" "github.com/minio/sha256-simd" @@ -21,7 +24,7 @@ type Ticket struct { type EPostTicket struct { Partial []byte - SectorID uint64 + SectorID abi.SectorNumber ChallengeIndex uint64 } @@ -42,7 +45,7 @@ type BlockHeader struct { ParentWeight BigInt // 4 - Height uint64 // 5 + Height abi.ChainEpoch // 5 ParentStateRoot cid.Cid // 6 @@ -50,11 +53,11 @@ type BlockHeader struct { Messages cid.Cid // 8 - BLSAggregate Signature // 9 + BLSAggregate crypto.Signature // 9 Timestamp uint64 // 10 - BlockSig *Signature // 11 + BlockSig *crypto.Signature // 11 ForkSignaling uint64 // 12 } @@ -163,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/blockheader_test.go b/chain/types/blockheader_test.go index ee9ca8192..196a91744 100644 --- a/chain/types/blockheader_test.go +++ b/chain/types/blockheader_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/specs-actors/actors/crypto" cid "github.com/ipfs/go-cid" ) @@ -34,12 +35,12 @@ func testBlockHeader(t testing.TB) *BlockHeader { }, Parents: []cid.Cid{c, c}, ParentMessageReceipts: c, - BLSAggregate: Signature{Type: KTBLS, Data: []byte("boo! im a signature")}, + BLSAggregate: crypto.Signature{Type: crypto.SigTypeBLS, Data: []byte("boo! im a signature")}, ParentWeight: NewInt(123125126212), Messages: c, Height: 85919298723, ParentStateRoot: c, - BlockSig: &Signature{Type: KTBLS, Data: []byte("boo! im a signature")}, + BlockSig: &crypto.Signature{Type: crypto.SigTypeBLS, Data: []byte("boo! im a signature")}, } } diff --git a/chain/types/cbor_gen.go b/chain/types/cbor_gen.go index f606955c7..05183a904 100644 --- a/chain/types/cbor_gen.go +++ b/chain/types/cbor_gen.go @@ -7,7 +7,9 @@ import ( "io" "math" - "github.com/ipfs/go-cid" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/crypto" + cid "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" xerrors "golang.org/x/xerrors" ) @@ -52,14 +54,20 @@ func (t *BlockHeader) MarshalCBOR(w io.Writer) error { } } - // t.ParentWeight (types.BigInt) (struct) + // t.ParentWeight (big.Int) (struct) if err := t.ParentWeight.MarshalCBOR(w); err != nil { return err } - // t.Height (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Height))); err != nil { - return err + // t.Height (abi.ChainEpoch) (int64) + if t.Height >= 0 { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Height))); err != nil { + return err + } + } else { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajNegativeInt, uint64(-t.Height)-1)); err != nil { + return err + } } // t.ParentStateRoot (cid.Cid) (struct) @@ -80,25 +88,28 @@ func (t *BlockHeader) MarshalCBOR(w io.Writer) error { return xerrors.Errorf("failed to write cid field t.Messages: %w", err) } - // t.BLSAggregate (types.Signature) (struct) + // t.BLSAggregate (crypto.Signature) (struct) if err := t.BLSAggregate.MarshalCBOR(w); err != nil { return err } // t.Timestamp (uint64) (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Timestamp))); err != nil { return err } - // t.BlockSig (types.Signature) (struct) + // t.BlockSig (crypto.Signature) (struct) if err := t.BlockSig.MarshalCBOR(w); err != nil { return err } // t.ForkSignaling (uint64) (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.ForkSignaling))); err != nil { return err } + return nil } @@ -182,7 +193,7 @@ func (t *BlockHeader) UnmarshalCBOR(r io.Reader) error { t.Parents[i] = c } - // t.ParentWeight (types.BigInt) (struct) + // t.ParentWeight (big.Int) (struct) { @@ -191,16 +202,31 @@ func (t *BlockHeader) UnmarshalCBOR(r io.Reader) error { } } - // t.Height (uint64) (uint64) + // t.Height (abi.ChainEpoch) (int64) + { + maj, extra, err := cbg.CborReadHeader(br) + var extraI int64 + if err != nil { + return err + } + switch maj { + case cbg.MajUnsignedInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 positive overflow") + } + case cbg.MajNegativeInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 negative oveflow") + } + extraI = -1 - extraI + default: + return fmt.Errorf("wrong type for int64 field: %d", maj) + } - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err + t.Height = abi.ChainEpoch(extraI) } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.Height = uint64(extra) // t.ParentStateRoot (cid.Cid) (struct) { @@ -237,7 +263,7 @@ func (t *BlockHeader) UnmarshalCBOR(r io.Reader) error { t.Messages = c } - // t.BLSAggregate (types.Signature) (struct) + // t.BLSAggregate (crypto.Signature) (struct) { @@ -248,15 +274,19 @@ func (t *BlockHeader) UnmarshalCBOR(r io.Reader) error { } // t.Timestamp (uint64) (uint64) - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err + { + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.Timestamp = uint64(extra) + } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.Timestamp = uint64(extra) - // t.BlockSig (types.Signature) (struct) + // t.BlockSig (crypto.Signature) (struct) { @@ -270,7 +300,7 @@ func (t *BlockHeader) UnmarshalCBOR(r io.Reader) error { return err } } else { - t.BlockSig = new(Signature) + t.BlockSig = new(crypto.Signature) if err := t.BlockSig.UnmarshalCBOR(br); err != nil { return err } @@ -279,14 +309,18 @@ func (t *BlockHeader) UnmarshalCBOR(r io.Reader) error { } // t.ForkSignaling (uint64) (uint64) - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err + { + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.ForkSignaling = uint64(extra) + } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.ForkSignaling = uint64(extra) return nil } @@ -497,15 +531,18 @@ func (t *EPostTicket) MarshalCBOR(w io.Writer) error { return err } - // t.SectorID (uint64) (uint64) + // t.SectorID (abi.SectorNumber) (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SectorID))); err != nil { return err } // t.ChallengeIndex (uint64) (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.ChallengeIndex))); err != nil { return err } + return nil } @@ -541,26 +578,34 @@ func (t *EPostTicket) UnmarshalCBOR(r io.Reader) error { if _, err := io.ReadFull(br, t.Partial); err != nil { return err } - // t.SectorID (uint64) (uint64) + // t.SectorID (abi.SectorNumber) (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 = abi.SectorNumber(extra) - 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.ChallengeIndex (uint64) (uint64) - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err + { + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.ChallengeIndex = uint64(extra) + } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.ChallengeIndex = uint64(extra) return nil } @@ -584,26 +629,28 @@ func (t *Message) MarshalCBOR(w io.Writer) error { } // t.Nonce (uint64) (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Nonce))); err != nil { return err } - // t.Value (types.BigInt) (struct) + // t.Value (big.Int) (struct) if err := t.Value.MarshalCBOR(w); err != nil { return err } - // t.GasPrice (types.BigInt) (struct) + // t.GasPrice (big.Int) (struct) if err := t.GasPrice.MarshalCBOR(w); err != nil { return err } - // t.GasLimit (types.BigInt) (struct) + // t.GasLimit (big.Int) (struct) if err := t.GasLimit.MarshalCBOR(w); err != nil { return err } - // t.Method (uint64) (uint64) + // t.Method (abi.MethodNum) (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Method))); err != nil { return err } @@ -657,15 +704,19 @@ func (t *Message) UnmarshalCBOR(r io.Reader) error { } // t.Nonce (uint64) (uint64) - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err + { + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.Nonce = uint64(extra) + } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.Nonce = uint64(extra) - // t.Value (types.BigInt) (struct) + // t.Value (big.Int) (struct) { @@ -674,7 +725,7 @@ func (t *Message) UnmarshalCBOR(r io.Reader) error { } } - // t.GasPrice (types.BigInt) (struct) + // t.GasPrice (big.Int) (struct) { @@ -683,7 +734,7 @@ func (t *Message) UnmarshalCBOR(r io.Reader) error { } } - // t.GasLimit (types.BigInt) (struct) + // t.GasLimit (big.Int) (struct) { @@ -692,16 +743,20 @@ func (t *Message) UnmarshalCBOR(r io.Reader) error { } } - // t.Method (uint64) (uint64) + // t.Method (abi.MethodNum) (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.Method = abi.MethodNum(extra) - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.Method = uint64(extra) // t.Params ([]uint8) (slice) maj, extra, err = cbg.CborReadHeader(br) @@ -736,7 +791,7 @@ func (t *SignedMessage) MarshalCBOR(w io.Writer) error { return err } - // t.Signature (types.Signature) (struct) + // t.Signature (crypto.Signature) (struct) if err := t.Signature.MarshalCBOR(w); err != nil { return err } @@ -767,7 +822,7 @@ func (t *SignedMessage) UnmarshalCBOR(r io.Reader) error { } } - // t.Signature (types.Signature) (struct) + // t.Signature (crypto.Signature) (struct) { @@ -845,377 +900,6 @@ func (t *MsgMeta) UnmarshalCBOR(r io.Reader) error { return nil } -func (t *SignedVoucher) 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.TimeLock (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.TimeLock))); err != nil { - return err - } - - // t.SecretPreimage ([]uint8) (slice) - if len(t.SecretPreimage) > cbg.ByteArrayMaxLen { - return xerrors.Errorf("Byte array in field t.SecretPreimage was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.SecretPreimage)))); err != nil { - return err - } - if _, err := w.Write(t.SecretPreimage); err != nil { - return err - } - - // t.Extra (types.ModVerifyParams) (struct) - if err := t.Extra.MarshalCBOR(w); err != nil { - return err - } - - // t.Lane (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Lane))); err != nil { - return err - } - - // t.Nonce (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Nonce))); err != nil { - return err - } - - // t.Amount (types.BigInt) (struct) - if err := t.Amount.MarshalCBOR(w); err != nil { - return err - } - - // t.MinCloseHeight (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.MinCloseHeight))); err != nil { - return err - } - - // t.Merges ([]types.Merge) (slice) - if len(t.Merges) > cbg.MaxLength { - return xerrors.Errorf("Slice value in field t.Merges was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Merges)))); err != nil { - return err - } - for _, v := range t.Merges { - if err := v.MarshalCBOR(w); err != nil { - return err - } - } - - // t.Signature (types.Signature) (struct) - if err := t.Signature.MarshalCBOR(w); err != nil { - return err - } - return nil -} - -func (t *SignedVoucher) 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.TimeLock (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.TimeLock = uint64(extra) - // t.SecretPreimage ([]uint8) (slice) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.ByteArrayMaxLen { - return fmt.Errorf("t.SecretPreimage: byte array too large (%d)", extra) - } - if maj != cbg.MajByteString { - return fmt.Errorf("expected byte array") - } - t.SecretPreimage = make([]byte, extra) - if _, err := io.ReadFull(br, t.SecretPreimage); err != nil { - return err - } - // t.Extra (types.ModVerifyParams) (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.Extra = new(ModVerifyParams) - if err := t.Extra.UnmarshalCBOR(br); err != nil { - return err - } - } - - } - // t.Lane (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.Lane = uint64(extra) - // t.Nonce (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.Nonce = uint64(extra) - // t.Amount (types.BigInt) (struct) - - { - - if err := t.Amount.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.MinCloseHeight (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.MinCloseHeight = uint64(extra) - // t.Merges ([]types.Merge) (slice) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.MaxLength { - return fmt.Errorf("t.Merges: array too large (%d)", extra) - } - - if maj != cbg.MajArray { - return fmt.Errorf("expected cbor array") - } - if extra > 0 { - t.Merges = make([]Merge, extra) - } - for i := 0; i < int(extra); i++ { - - var v Merge - if err := v.UnmarshalCBOR(br); err != nil { - return err - } - - t.Merges[i] = v - } - - // t.Signature (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.Signature = new(Signature) - if err := t.Signature.UnmarshalCBOR(br); err != nil { - return err - } - } - - } - return nil -} - -func (t *ModVerifyParams) 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.Actor (address.Address) (struct) - if err := t.Actor.MarshalCBOR(w); err != nil { - return err - } - - // t.Method (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Method))); err != nil { - return err - } - - // t.Data ([]uint8) (slice) - if len(t.Data) > cbg.ByteArrayMaxLen { - return xerrors.Errorf("Byte array in field t.Data was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Data)))); err != nil { - return err - } - if _, err := w.Write(t.Data); err != nil { - return err - } - return nil -} - -func (t *ModVerifyParams) 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.Actor (address.Address) (struct) - - { - - if err := t.Actor.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.Method (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.Method = uint64(extra) - // t.Data ([]uint8) (slice) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.ByteArrayMaxLen { - return fmt.Errorf("t.Data: byte array too large (%d)", extra) - } - if maj != cbg.MajByteString { - return fmt.Errorf("expected byte array") - } - t.Data = make([]byte, extra) - if _, err := io.ReadFull(br, t.Data); err != nil { - return err - } - return nil -} - -func (t *Merge) 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.Lane (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Lane))); err != nil { - return err - } - - // t.Nonce (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Nonce))); err != nil { - return err - } - return nil -} - -func (t *Merge) 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.Lane (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.Lane = uint64(extra) - // t.Nonce (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.Nonce = uint64(extra) - return nil -} - func (t *Actor) MarshalCBOR(w io.Writer) error { if t == nil { _, err := w.Write(cbg.CborNull) @@ -1238,11 +922,12 @@ func (t *Actor) MarshalCBOR(w io.Writer) error { } // t.Nonce (uint64) (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Nonce))); err != nil { return err } - // t.Balance (types.BigInt) (struct) + // t.Balance (big.Int) (struct) if err := t.Balance.MarshalCBOR(w); err != nil { return err } @@ -1290,15 +975,19 @@ func (t *Actor) UnmarshalCBOR(r io.Reader) error { } // t.Nonce (uint64) (uint64) - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err + { + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.Nonce = uint64(extra) + } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.Nonce = uint64(extra) - // t.Balance (types.BigInt) (struct) + // t.Balance (big.Int) (struct) { @@ -1336,7 +1025,7 @@ func (t *MessageReceipt) MarshalCBOR(w io.Writer) error { return err } - // t.GasUsed (types.BigInt) (struct) + // t.GasUsed (big.Int) (struct) if err := t.GasUsed.MarshalCBOR(w); err != nil { return err } @@ -1388,7 +1077,7 @@ func (t *MessageReceipt) UnmarshalCBOR(r io.Reader) error { if _, err := io.ReadFull(br, t.Return); err != nil { return err } - // t.GasUsed (types.BigInt) (struct) + // t.GasUsed (big.Int) (struct) { @@ -1535,204 +1224,6 @@ func (t *BlockMsg) UnmarshalCBOR(r io.Reader) error { return nil } -func (t *SignedStorageAsk) 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.Ask (types.StorageAsk) (struct) - if err := t.Ask.MarshalCBOR(w); err != nil { - return err - } - - // t.Signature (types.Signature) (struct) - if err := t.Signature.MarshalCBOR(w); err != nil { - return err - } - return nil -} - -func (t *SignedStorageAsk) 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.Ask (types.StorageAsk) (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.Ask = new(StorageAsk) - if err := t.Ask.UnmarshalCBOR(br); err != nil { - return err - } - } - - } - // t.Signature (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.Signature = new(Signature) - if err := t.Signature.UnmarshalCBOR(br); err != nil { - return err - } - } - - } - return nil -} - -func (t *StorageAsk) MarshalCBOR(w io.Writer) error { - if t == nil { - _, err := w.Write(cbg.CborNull) - return err - } - if _, err := w.Write([]byte{134}); err != nil { - return err - } - - // t.Price (types.BigInt) (struct) - if err := t.Price.MarshalCBOR(w); err != nil { - return err - } - - // t.MinPieceSize (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.MinPieceSize))); err != nil { - return err - } - - // t.Miner (address.Address) (struct) - if err := t.Miner.MarshalCBOR(w); err != nil { - return err - } - - // t.Timestamp (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Timestamp))); err != nil { - return err - } - - // t.Expiry (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Expiry))); err != nil { - return err - } - - // t.SeqNo (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SeqNo))); err != nil { - return err - } - return nil -} - -func (t *StorageAsk) 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 != 6 { - return fmt.Errorf("cbor input had wrong number of fields") - } - - // t.Price (types.BigInt) (struct) - - { - - if err := t.Price.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.MinPieceSize (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.MinPieceSize = uint64(extra) - // t.Miner (address.Address) (struct) - - { - - if err := t.Miner.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.Timestamp (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.Timestamp = uint64(extra) - // t.Expiry (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.Expiry = uint64(extra) - // t.SeqNo (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.SeqNo = uint64(extra) - return nil -} - func (t *ExpTipSet) MarshalCBOR(w io.Writer) error { if t == nil { _, err := w.Write(cbg.CborNull) @@ -1770,9 +1261,15 @@ func (t *ExpTipSet) MarshalCBOR(w io.Writer) error { } } - // t.Height (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Height))); err != nil { - return err + // t.Height (abi.ChainEpoch) (int64) + if t.Height >= 0 { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Height))); err != nil { + return err + } + } else { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajNegativeInt, uint64(-t.Height)-1)); err != nil { + return err + } } return nil } @@ -1845,15 +1342,30 @@ func (t *ExpTipSet) UnmarshalCBOR(r io.Reader) error { t.Blocks[i] = &v } - // t.Height (uint64) (uint64) + // t.Height (abi.ChainEpoch) (int64) + { + maj, extra, err := cbg.CborReadHeader(br) + var extraI int64 + if err != nil { + return err + } + switch maj { + case cbg.MajUnsignedInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 positive overflow") + } + case cbg.MajNegativeInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 negative oveflow") + } + extraI = -1 - extraI + default: + return fmt.Errorf("wrong type for int64 field: %d", maj) + } - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err + t.Height = abi.ChainEpoch(extraI) } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.Height = uint64(extra) return nil } diff --git a/chain/types/message.go b/chain/types/message.go index 4ed940b67..7d41c8379 100644 --- a/chain/types/message.go +++ b/chain/types/message.go @@ -4,6 +4,7 @@ import ( "bytes" "fmt" + "github.com/filecoin-project/specs-actors/actors/abi" block "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" "github.com/multiformats/go-multihash" @@ -22,10 +23,26 @@ type Message struct { GasPrice BigInt GasLimit BigInt - Method uint64 // TODO: decide + Method abi.MethodNum Params []byte } +func (t *Message) BlockMiner() address.Address { + panic("implement me") +} + +func (t *Message) Caller() address.Address { + return t.From +} + +func (t *Message) Receiver() address.Address { + return t.To +} + +func (t *Message) ValueReceived() abi.TokenAmount { + return t.Value +} + func DecodeMessage(b []byte) (*Message, error) { var msg Message if err := msg.UnmarshalCBOR(bytes.NewReader(b)); err != nil { diff --git a/chain/types/mock/chain.go b/chain/types/mock/chain.go index 55fe8c11d..f4780bbb3 100644 --- a/chain/types/mock/chain.go +++ b/chain/types/mock/chain.go @@ -5,9 +5,12 @@ import ( "fmt" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/crypto" + "github.com/ipfs/go-cid" + "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/wallet" - "github.com/ipfs/go-cid" ) func Address(i uint64) address.Address { @@ -47,7 +50,7 @@ func MkBlock(parents *types.TipSet, weightInc uint64, ticketNonce uint64) *types } var pcids []cid.Cid - var height uint64 + var height abi.ChainEpoch weight := types.NewInt(weightInc) if parents != nil { pcids = parents.Cids() @@ -65,12 +68,12 @@ func MkBlock(parents *types.TipSet, weightInc uint64, ticketNonce uint64) *types }, Parents: pcids, ParentMessageReceipts: c, - BLSAggregate: types.Signature{Type: types.KTBLS, Data: []byte("boo! im a signature")}, + BLSAggregate: crypto.Signature{Type: crypto.SigTypeBLS, Data: []byte("boo! im a signature")}, ParentWeight: weight, Messages: c, Height: height, ParentStateRoot: c, - BlockSig: &types.Signature{Type: types.KTBLS, Data: []byte("boo! im a signature")}, + BlockSig: &crypto.Signature{Type: crypto.SigTypeBLS, Data: []byte("boo! im a signature")}, } } diff --git a/chain/types/signature.go b/chain/types/signature.go deleted file mode 100644 index 3b0862206..000000000 --- a/chain/types/signature.go +++ /dev/null @@ -1,123 +0,0 @@ -package types - -import ( - "bytes" - "encoding/binary" - "fmt" - "io" - - cbg "github.com/whyrusleeping/cbor-gen" -) - -const SignatureMaxLength = 200 - -const ( - KTSecp256k1 = "secp256k1" - KTBLS = "bls" -) - -const ( - IKTUnknown = -1 - - IKTSecp256k1 = iota - IKTBLS -) - -type Signature struct { - Type string - Data []byte -} - -func SignatureFromBytes(x []byte) (Signature, error) { - val, nr := binary.Uvarint(x) - if nr != 1 { - return Signature{}, fmt.Errorf("signatures with type field longer than one byte are invalid") - } - var ts string - switch val { - case IKTSecp256k1: - ts = KTSecp256k1 - case IKTBLS: - ts = KTBLS - default: - return Signature{}, fmt.Errorf("unsupported signature type: %d", val) - } - - return Signature{ - Type: ts, - Data: x[1:], - }, nil -} - -func (s *Signature) TypeCode() int { - switch s.Type { - case KTSecp256k1: - return IKTSecp256k1 - case KTBLS: - return IKTBLS - default: - return IKTUnknown - } -} - -func (s *Signature) MarshalCBOR(w io.Writer) error { - if s == nil { - _, err := w.Write(cbg.CborNull) - return err - } - - header := cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(s.Data)+1)) - - if _, err := w.Write(header); err != nil { - return err - } - - if _, err := w.Write([]byte{byte(s.TypeCode())}); err != nil { - return err - } - - if _, err := w.Write(s.Data); err != nil { - return err - } - - return nil -} - -func (s *Signature) UnmarshalCBOR(br io.Reader) error { - maj, l, err := cbg.CborReadHeader(br) - if err != nil { - return err - } - - if maj != cbg.MajByteString { - return fmt.Errorf("cbor input for signature was not a byte string") - } - - if l > SignatureMaxLength { - return fmt.Errorf("cbor byte array for signature was too long") - } - - buf := make([]byte, l) - if _, err := io.ReadFull(br, buf); err != nil { - return err - } - - switch buf[0] { - default: - return fmt.Errorf("invalid signature type in cbor input: %d", buf[0]) - case IKTSecp256k1: - s.Type = KTSecp256k1 - case IKTBLS: - s.Type = KTBLS - } - s.Data = buf[1:] - - return nil -} - -func (s *Signature) Equals(o *Signature) bool { - if s == nil || o == nil { - return s == o - } - return s.Type == o.Type && bytes.Equal(s.Data, o.Data) -} diff --git a/chain/types/signature_test.go b/chain/types/signature_test.go index b45024b29..751f55252 100644 --- a/chain/types/signature_test.go +++ b/chain/types/signature_test.go @@ -3,12 +3,14 @@ package types import ( "bytes" "testing" + + "github.com/filecoin-project/specs-actors/actors/crypto" ) func TestSignatureSerializeRoundTrip(t *testing.T) { - s := &Signature{ + s := &crypto.Signature{ Data: []byte("foo bar cat dog"), - Type: KTBLS, + Type: crypto.SigTypeBLS, } buf := new(bytes.Buffer) @@ -16,7 +18,7 @@ func TestSignatureSerializeRoundTrip(t *testing.T) { t.Fatal(err) } - var outs Signature + var outs crypto.Signature if err := outs.UnmarshalCBOR(buf); err != nil { t.Fatal(err) } diff --git a/chain/types/signedmessage.go b/chain/types/signedmessage.go index 0ede20a4f..9e3d45f0c 100644 --- a/chain/types/signedmessage.go +++ b/chain/types/signedmessage.go @@ -3,13 +3,14 @@ package types import ( "bytes" + "github.com/filecoin-project/specs-actors/actors/crypto" block "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" "github.com/multiformats/go-multihash" ) func (m *SignedMessage) ToStorageBlock() (block.Block, error) { - if m.Signature.Type == KTBLS { + if m.Signature.Type == crypto.SigTypeBLS { return m.Message.ToStorageBlock() } @@ -28,7 +29,7 @@ func (m *SignedMessage) ToStorageBlock() (block.Block, error) { } func (m *SignedMessage) Cid() cid.Cid { - if m.Signature.Type == KTBLS { + if m.Signature.Type == crypto.SigTypeBLS { return m.Message.Cid() } @@ -42,7 +43,7 @@ func (m *SignedMessage) Cid() cid.Cid { type SignedMessage struct { Message Message - Signature Signature + Signature crypto.Signature } func DecodeSignedMessage(data []byte) (*SignedMessage, error) { diff --git a/chain/types/tipset.go b/chain/types/tipset.go index f3f5e25cb..a92b27fcf 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) { @@ -135,7 +136,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 0f64b6cc4..639032358 100644 --- a/chain/types/vmcontext.go +++ b/chain/types/vmcontext.go @@ -3,6 +3,10 @@ package types import ( "context" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/crypto" + "github.com/filecoin-project/specs-actors/actors/runtime" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/lotus/chain/actors/aerrors" @@ -31,46 +35,22 @@ type VMContext interface { Message() *Message Origin() address.Address Ipld() cbor.IpldStore - Send(to address.Address, method uint64, value BigInt, params []byte) ([]byte, aerrors.ActorError) - BlockHeight() uint64 + Send(to address.Address, method abi.MethodNum, value BigInt, params []byte) ([]byte, aerrors.ActorError) + BlockHeight() abi.ChainEpoch GasUsed() BigInt Storage() Storage StateTree() (StateTree, aerrors.ActorError) - VerifySignature(sig *Signature, from address.Address, data []byte) aerrors.ActorError + ActorCodeCID(address.Address) (cid.Cid, error) + LookupID(address.Address) (address.Address, error) + VerifySignature(sig *crypto.Signature, from address.Address, data []byte) aerrors.ActorError ChargeGas(uint64) aerrors.ActorError - GetRandomness(height uint64) ([]byte, aerrors.ActorError) + GetRandomness(personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, aerrors.ActorError) GetBalance(address.Address) (BigInt, aerrors.ActorError) - Sys() *VMSyscalls + Sys() runtime.Syscalls Context() context.Context } -const CommitmentBytesLen = 32 - -type PublicSectorInfo struct { - SectorID uint64 - CommR [CommitmentBytesLen]byte -} - -type Candidate struct { - SectorID uint64 - PartialTicket [32]byte - Ticket [32]byte - SectorChallengeIndex uint64 -} - -type VMSyscalls struct { - ValidatePoRep func(context.Context, address.Address, uint64, []byte, []byte, []byte, []byte, []byte, uint64) (bool, aerrors.ActorError) - VerifyFallbackPost func(ctx context.Context, - sectorSize uint64, - sectorInfo []PublicSectorInfo, - challengeSeed []byte, - proof []byte, - candidates []Candidate, - proverID address.Address, - faults uint64) (bool, error) -} - type storageWrapper struct { s Storage } diff --git a/chain/types/voucher.go b/chain/types/voucher.go index ba2bab6ec..bbf7e1ed0 100644 --- a/chain/types/voucher.go +++ b/chain/types/voucher.go @@ -1,88 +1,22 @@ package types -import ( - "bytes" +import( "encoding/base64" - "github.com/filecoin-project/go-address" - cborrpc "github.com/filecoin-project/go-cbor-util" + "github.com/filecoin-project/specs-actors/actors/builtin/paych" cbor "github.com/ipfs/go-ipld-cbor" ) -type SignedVoucher struct { - TimeLock uint64 - SecretPreimage []byte - Extra *ModVerifyParams - Lane uint64 - Nonce uint64 - Amount BigInt - MinCloseHeight uint64 - - Merges []Merge - - Signature *Signature -} - -func (sv *SignedVoucher) SigningBytes() ([]byte, error) { - osv := *sv - osv.Signature = nil - - buf := new(bytes.Buffer) - if err := osv.MarshalCBOR(buf); err != nil { - return nil, err - } - - return buf.Bytes(), nil -} - -func (sv *SignedVoucher) EncodedString() (string, error) { - buf := new(bytes.Buffer) - if err := sv.MarshalCBOR(buf); err != nil { - return "", err - } - - return base64.RawURLEncoding.EncodeToString(buf.Bytes()), nil -} - -func (sv *SignedVoucher) Equals(other *SignedVoucher) bool { - // TODO: make this less bad - - selfB, err := cborrpc.Dump(sv) - if err != nil { - log.Errorf("SignedVoucher.Equals: dump self: %s", err) - return false - } - - otherB, err := cborrpc.Dump(other) - if err != nil { - log.Errorf("SignedVoucher.Equals: dump other: %s", err) - return false - } - - return bytes.Equal(selfB, otherB) -} - -func DecodeSignedVoucher(s string) (*SignedVoucher, error) { +func DecodeSignedVoucher(s string) (*paych.SignedVoucher, error) { data, err := base64.RawURLEncoding.DecodeString(s) if err != nil { return nil, err } - var sv SignedVoucher + var sv paych.SignedVoucher if err := cbor.DecodeInto(data, &sv); err != nil { return nil, err } return &sv, nil } - -type Merge struct { - Lane uint64 - Nonce uint64 -} - -type ModVerifyParams struct { - Actor address.Address - Method uint64 - Data []byte -} diff --git a/chain/validation/applier.go b/chain/validation/applier.go index 8caf1b2dd..38f48d6cd 100644 --- a/chain/validation/applier.go +++ b/chain/validation/applier.go @@ -2,6 +2,9 @@ package validation import ( "context" + + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/go-sectorbuilder" vchain "github.com/filecoin-project/chain-validation/pkg/chain" @@ -33,7 +36,7 @@ func (a *Applier) ApplyMessage(eCtx *vchain.ExecutionContext, state vstate.Wrapp if err != nil { return vchain.MessageReceipt{}, err } - lotusVM, err := vm.NewVM(base, eCtx.Epoch, randSrc, minerAddr, st.bs, vm.Syscalls(sectorbuilder.ProofVerifier)) + lotusVM, err := vm.NewVM(base, abi.ChainEpoch(eCtx.Epoch), randSrc, minerAddr, st.bs, vm.Syscalls(sectorbuilder.ProofVerifier)) if err != nil { return vchain.MessageReceipt{}, err } diff --git a/chain/validation/message.go b/chain/validation/message.go index d0f6201ea..3b1c2c12a 100644 --- a/chain/validation/message.go +++ b/chain/validation/message.go @@ -2,6 +2,7 @@ package validation import ( "context" + "github.com/ipfs/go-cid" "golang.org/x/xerrors" @@ -10,15 +11,16 @@ import ( vaddress "github.com/filecoin-project/chain-validation/pkg/state/address" vtypes "github.com/filecoin-project/chain-validation/pkg/state/types" - "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/filecoin-project/specs-actors/actors/crypto" - "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/types" ) type Signer interface { - Sign(ctx context.Context, addr vaddress.Address, msg []byte) (*types.Signature, error) + Sign(ctx context.Context, addr vaddress.Address, msg []byte) (*crypto.Signature, error) } type MessageFactory struct { @@ -53,7 +55,7 @@ func (mf *MessageFactory) MakeMessage(from, to vaddress.Address, method vchain.M valueDec, types.BigInt{gasPrice.Int}, types.NewInt(uint64(gasLimit)), - methodId, + abi.MethodNum(methodId), params, } @@ -72,18 +74,17 @@ func (mf *MessageFactory) FromActorCodeCid(code vactors.ActorCodeID) cid.Cid { // This will change to a mapping to method ids when method dispatch is updated to use integers. var methods = []uint64{ vchain.NoMethod: 0, - vchain.InitExec: actors.IAMethods.Exec, + vchain.InitExec: uint64(builtin.MethodsInit.Exec), - vchain.StoragePowerConstructor: actors.SPAMethods.Constructor, - vchain.StoragePowerCreateStorageMiner: actors.SPAMethods.CreateStorageMiner, - vchain.StoragePowerUpdatePower: actors.SPAMethods.UpdateStorage, + vchain.StoragePowerConstructor: uint64(builtin.MethodsPower.Constructor), + vchain.StoragePowerCreateStorageMiner: uint64(builtin.MethodsPower.CreateMiner), - vchain.StorageMinerUpdatePeerID: actors.MAMethods.UpdatePeerID, - vchain.StorageMinerGetOwner: actors.MAMethods.GetOwner, - vchain.StorageMinerGetPower: actors.MAMethods.GetPower, - vchain.StorageMinerGetWorkerAddr: actors.MAMethods.GetWorkerAddr, - vchain.StorageMinerGetPeerID: actors.MAMethods.GetPeerID, - vchain.StorageMinerGetSectorSize: actors.MAMethods.GetSectorSize, + vchain.StorageMinerUpdatePeerID: 0, //actors.MAMethods.UpdatePeerID, + vchain.StorageMinerGetOwner: 0, //actors.MAMethods.GetOwner, + vchain.StorageMinerGetPower: 0, //actors.MAMethods.GetPower, + vchain.StorageMinerGetWorkerAddr: 0, //actors.MAMethods.GetWorkerAddr, + vchain.StorageMinerGetPeerID: 0, //actors.MAMethods.GetPeerID, + vchain.StorageMinerGetSectorSize: 0, //actors.MAMethods.GetSectorSize, vchain.MultiSigConstructor: uint64(builtin.MethodsMultisig.Constructor), vchain.MultiSigPropose: uint64(builtin.MethodsMultisig.Propose), diff --git a/chain/validation/state.go b/chain/validation/state.go index 8ea8521aa..1c0f87383 100644 --- a/chain/validation/state.go +++ b/chain/validation/state.go @@ -20,8 +20,9 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-crypto" + "github.com/filecoin-project/lotus/chain/actors" - "github.com/filecoin-project/lotus/chain/gen" + "github.com/filecoin-project/lotus/chain/gen/genesis" "github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/vm" @@ -132,7 +133,7 @@ func (s *StateWrapper) SetSingletonActor(addr vactors.SingletonActorID, balance switch lotusAddr { case actors.InitAddress: - initact, err := gen.SetupInitActor(s.bs, nil) + initact, err := genesis.SetupInitActor(s.bs, "testing", nil) if err != nil { return nil, nil, err } @@ -142,7 +143,7 @@ func (s *StateWrapper) SetSingletonActor(addr vactors.SingletonActorID, balance return &actorWrapper{*initact}, s.storage, s.flush(tree) case actors.StorageMarketAddress: - nsroot, err := gen.SetupStorageMarketActor(s.bs, s.stateRoot, nil) + nsroot, err := genesis.SetupStorageMarketActor(s.bs) if err != nil { return nil, nil, err } @@ -158,7 +159,7 @@ func (s *StateWrapper) SetSingletonActor(addr vactors.SingletonActorID, balance } return &actorWrapper{*smact}, s.storage, s.flush(tree) case actors.StoragePowerAddress: - spact, err := gen.SetupStoragePowerActor(s.bs) + spact, err := genesis.SetupStoragePowerActor(s.bs) if err != nil { return nil, nil, err } diff --git a/chain/vm/invoker.go b/chain/vm/invoker.go index 709212ab3..70a7011e5 100644 --- a/chain/vm/invoker.go +++ b/chain/vm/invoker.go @@ -11,11 +11,21 @@ import ( cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" - "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/filecoin-project/specs-actors/actors/builtin/cron" + init_ "github.com/filecoin-project/specs-actors/actors/builtin/init" + "github.com/filecoin-project/specs-actors/actors/builtin/market" + "github.com/filecoin-project/specs-actors/actors/builtin/miner" + "github.com/filecoin-project/specs-actors/actors/builtin/multisig" + "github.com/filecoin-project/specs-actors/actors/builtin/paych" + "github.com/filecoin-project/specs-actors/actors/builtin/power" + "github.com/filecoin-project/specs-actors/actors/builtin/system" + vmr "github.com/filecoin-project/specs-actors/actors/runtime" + "github.com/filecoin-project/specs-actors/actors/util/adt" + "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 { @@ -33,20 +43,21 @@ func NewInvoker() *invoker { } // add builtInCode using: register(cid, singleton) - 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.StorageMinerCodeCid, actors.StorageMinerActor{}, actors.StorageMinerActorState{}) - inv.Register(actors.MultisigCodeCid, multisig.MultiSigActor{}, multisig.MultiSigActorState{}) - inv.Register(actors.PaymentChannelCodeCid, actors.PaymentChannelActor{}, actors.PaymentChannelActorState{}) + inv.Register(builtin.SystemActorCodeID, system.Actor{}, adt.EmptyValue{}) + inv.Register(builtin.InitActorCodeID, init_.Actor{}, init_.State{}) + inv.Register(builtin.CronActorCodeID, cron.Actor{}, cron.State{}) + inv.Register(builtin.StoragePowerActorCodeID, power.Actor{}, power.State{}) + inv.Register(builtin.StorageMarketActorCodeID, market.Actor{}, market.State{}) + inv.Register(builtin.StorageMinerActorCodeID, miner.Actor{}, miner.State{}) + inv.Register(builtin.MultisigActorCodeID, multisig.Actor{}, multisig.State{}) + inv.Register(builtin.PaymentChannelActorCodeID, paych.Actor{}, paych.State{}) return inv } -func (inv *invoker) Invoke(act *types.Actor, vmctx types.VMContext, method uint64, params []byte) ([]byte, aerrors.ActorError) { +func (inv *invoker) Invoke(act *types.Actor, vmctx types.VMContext, method abi.MethodNum, params []byte) ([]byte, aerrors.ActorError) { - if act.Code == actors.AccountCodeCid { + if act.Code == builtin.AccountActorCodeID { return nil, aerrors.Newf(254, "cannot invoke methods on account actors") } @@ -55,7 +66,7 @@ func (inv *invoker) Invoke(act *types.Actor, vmctx types.VMContext, method uint6 log.Errorf("no code for actor %s (Addr: %s)", act.Code, vmctx.Message().To) return nil, aerrors.Newf(255, "no code for actor %s(%d)(%s)", act.Code, method, hex.EncodeToString(params)) } - if method >= uint64(len(code)) || code[method] == nil { + if method >= abi.MethodNum(len(code)) || code[method] == nil { return nil, aerrors.Newf(255, "no method %d on actor", method) } return code[method](act, vmctx, params) @@ -252,7 +263,7 @@ func DecodeParams(b []byte, out interface{}) error { } func DumpActorState(code cid.Cid, b []byte) (interface{}, error) { - if code == actors.AccountCodeCid { // Account code special case + if code == builtin.AccountActorCodeID { // Account code special case return nil, nil } diff --git a/chain/vm/mkactor.go b/chain/vm/mkactor.go index ae1c9277c..df3f235dd 100644 --- a/chain/vm/mkactor.go +++ b/chain/vm/mkactor.go @@ -2,12 +2,13 @@ package vm import ( "context" + "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/filecoin-project/specs-actors/actors/builtin/account" "github.com/ipfs/go-cid" cbor "github.com/ipfs/go-ipld-cbor" "github.com/filecoin-project/go-address" - "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/aerrors" "github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/types" @@ -15,7 +16,7 @@ import ( func init() { cst := cbor.NewMemCborStore() - emptyobject, err := cst.Put(context.TODO(), map[string]string{}) + emptyobject, err := cst.Put(context.TODO(), []struct{}{}) if err != nil { panic(err) } @@ -54,7 +55,7 @@ func makeActor(st *state.StateTree, addr address.Address) (*types.Actor, aerrors } func NewBLSAccountActor(st *state.StateTree, addr address.Address) (*types.Actor, aerrors.ActorError) { - var acstate actors.AccountActorState + var acstate account.State acstate.Address = addr c, err := st.Store.Put(context.TODO(), &acstate) @@ -63,7 +64,7 @@ func NewBLSAccountActor(st *state.StateTree, addr address.Address) (*types.Actor } nact := &types.Actor{ - Code: actors.AccountCodeCid, + Code: builtin.AccountActorCodeID, Balance: types.NewInt(0), Head: c, } @@ -73,7 +74,7 @@ func NewBLSAccountActor(st *state.StateTree, addr address.Address) (*types.Actor func NewSecp256k1AccountActor(st *state.StateTree, addr address.Address) (*types.Actor, aerrors.ActorError) { nact := &types.Actor{ - Code: actors.AccountCodeCid, + Code: builtin.AccountActorCodeID, Balance: types.NewInt(0), Head: EmptyObjectCid, } diff --git a/chain/vm/spec_shim.go b/chain/vm/spec_shim.go index 8067d75f6..1cadde826 100644 --- a/chain/vm/spec_shim.go +++ b/chain/vm/spec_shim.go @@ -3,36 +3,62 @@ package vm import ( "bytes" "context" - "fmt" + "encoding/binary" "runtime/debug" "github.com/filecoin-project/go-address" - "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" - "github.com/filecoin-project/specs-actors/actors/runtime" + "github.com/filecoin-project/specs-actors/actors/abi/big" + "github.com/filecoin-project/specs-actors/actors/crypto" vmr "github.com/filecoin-project/specs-actors/actors/runtime" "github.com/filecoin-project/specs-actors/actors/runtime/exitcode" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" + + "github.com/filecoin-project/lotus/chain/actors/aerrors" + "github.com/filecoin-project/lotus/chain/types" ) type runtimeShim struct { vmctx types.VMContext - vmr.Runtime } -var _ runtime.Runtime = (*runtimeShim)(nil) +func (rs *runtimeShim) ResolveAddress(address address.Address) (ret address.Address, ok bool) { + r, err := rs.vmctx.LookupID(address) + if err != nil { // TODO: check notfound + rs.Abortf(exitcode.ErrPlaceholder, "resolve address: %v", err) + } + return r, true +} + +func (rs *runtimeShim) Get(c cid.Cid, o vmr.CBORUnmarshaler) bool { + err := rs.vmctx.Storage().Get(c, o) + if err != nil { // todo: not found + rs.Abortf(exitcode.ErrPlaceholder, "storage get: %v", err) + } + return true +} + +func (rs *runtimeShim) Put(x vmr.CBORMarshaler) cid.Cid { + c, err := rs.vmctx.Storage().Put(x) + if err != nil { + rs.Abortf(exitcode.ErrPlaceholder, "storage put: %v", err) // todo: spec code? + } + return c +} + +var _ vmr.Runtime = (*runtimeShim)(nil) func (rs *runtimeShim) shimCall(f func() interface{}) (rval []byte, aerr aerrors.ActorError) { defer func() { if r := recover(); r != nil { if ar, ok := r.(aerrors.ActorError); ok { + log.Warn("VM.Call failure: ", ar) + debug.PrintStack() aerr = ar return } - fmt.Println("caught one of those actor errors: ", r) + log.Warn("caught one of those actor errors: ", r) debug.PrintStack() log.Errorf("ERROR") aerr = aerrors.Newf(1, "generic spec actors failure") @@ -56,14 +82,132 @@ func (rs *runtimeShim) shimCall(f func() interface{}) (rval []byte, aerr aerrors } } +func (rs *runtimeShim) Message() vmr.Message { + var err error + + rawm := *rs.vmctx.Message() // TODO: normalize addresses earlier + rawm.From, err = rs.vmctx.LookupID(rawm.From) + if err != nil { + rs.Abortf(exitcode.ErrPlaceholder, "resolve from address: %v", err) + } + + rawm.To, err = rs.vmctx.LookupID(rawm.To) + if err != nil { + rs.Abortf(exitcode.ErrPlaceholder, "resolve to address: %v", err) + } + + return &rawm +} + +func (rs *runtimeShim) ValidateImmediateCallerAcceptAny() { + return +} + +func (rs *runtimeShim) CurrentBalance() abi.TokenAmount { + b, err := rs.vmctx.GetBalance(rs.vmctx.Message().To) + if err != nil { + rs.Abortf(exitcode.ExitCode(err.RetCode()), "get current balance: %v", err) + } + return b +} + +func (rs *runtimeShim) GetActorCodeCID(addr address.Address) (ret cid.Cid, ok bool) { + ret, err := rs.vmctx.ActorCodeCID(addr) + if err != nil { + // todo: notfound + rs.Abortf(exitcode.ErrPlaceholder, "%v", err) + } + + return ret, true +} + +func (rs *runtimeShim) GetRandomness(personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) abi.Randomness { + r, err := rs.vmctx.GetRandomness(personalization, randEpoch, entropy) + if err != nil { + rs.Abortf(exitcode.SysErrInternal, "getting randomness: %v", err) + } + + return r +} + +func (rs *runtimeShim) Store() vmr.Store { + return rs +} + +func (rs *runtimeShim) NewActorAddress() address.Address { + var b bytes.Buffer + if err := rs.ImmediateCaller().MarshalCBOR(&b); err != nil { // todo: spec says cbor; why not just bytes? + rs.Abortf(exitcode.ErrSerialization, "writing caller address into a buffer: %v", err) + } + + var err error + st, err := rs.vmctx.StateTree() + if err != nil { + rs.Abortf(exitcode.SysErrInternal, "getting statetree: %v", err) + } + act, err := st.GetActor(rs.vmctx.Origin()) + if err != nil { + rs.Abortf(exitcode.SysErrInternal, "getting top level actor: %v", err) + } + + if err := binary.Write(&b, binary.BigEndian, act.Nonce); err != nil { + rs.Abortf(exitcode.ErrSerialization, "writing nonce address into a buffer: %v", err) + } + if err := binary.Write(&b, binary.BigEndian, uint64(0)); err != nil { // TODO: expose on vm + rs.Abortf(exitcode.ErrSerialization, "writing callSeqNum address into a buffer: %v", err) + } + addr, err := address.NewActorAddress(b.Bytes()) + if err != nil { + rs.Abortf(exitcode.ErrSerialization, "create actor address: %v", err) + } + + return addr +} + +func (rs *runtimeShim) CreateActor(codeId cid.Cid, address address.Address) { + var err error + st, err := rs.vmctx.StateTree() + if err != nil { + rs.Abortf(exitcode.SysErrInternal, "getting statetree: %v", err) + } + + err = st.SetActor(address, &types.Actor{ + Code: codeId, + Head: EmptyObjectCid, + Nonce: 0, + Balance: big.Zero(), + }) + if err != nil { + rs.Abortf(exitcode.SysErrInternal, "creating actor entry: %v", err) + } + + return +} + +func (rs *runtimeShim) DeleteActor() { + panic("implement me") +} + +func (rs *runtimeShim) Syscalls() vmr.Syscalls { + return rs.vmctx.Sys() +} + +func (rs *runtimeShim) StartSpan(name string) vmr.TraceSpan { + panic("implement me") +} + func (rs *runtimeShim) ValidateImmediateCallerIs(as ...address.Address) { + imm, err := rs.vmctx.LookupID(rs.vmctx.Message().From) + if err != nil { + rs.Abortf(exitcode.ErrIllegalState, "couldn't resolve immediate caller") + } + for _, a := range as { - if rs.vmctx.Message().From == a { + if imm == a { return } } - fmt.Println("Caller: ", rs.vmctx.Message().From, as) - panic("we like to panic when people call the wrong methods") + rs.Abortf(exitcode.ErrForbidden, "caller %s is not one of %s", rs.vmctx.Message().From, as) } func (rs *runtimeShim) ImmediateCaller() address.Address { @@ -74,44 +218,20 @@ func (rs *runtimeShim) Context() context.Context { return rs.vmctx.Context() } -func (rs *runtimeShim) IpldGet(c cid.Cid, o vmr.CBORUnmarshaler) bool { - if err := rs.vmctx.Storage().Get(c, o); err != nil { - panic(err) // y o o o o o l l l l o o o o o - } - return true -} - -func (rs *runtimeShim) IpldPut(o vmr.CBORMarshaler) cid.Cid { - c, err := rs.vmctx.Storage().Put(o) - if err != nil { - panic(err) - } - return c -} - -func (rs *runtimeShim) Abort(code exitcode.ExitCode, msg string, args ...interface{}) { - panic(aerrors.Newf(uint8(code), msg, args...)) +func (rs *runtimeShim) Abortf(code exitcode.ExitCode, msg string, args ...interface{}) { + panic(aerrors.NewfSkip(2, uint8(code), msg, args...)) } func (rs *runtimeShim) AbortStateMsg(msg string) { - rs.Abort(101, msg) + panic(aerrors.NewfSkip(3, 101, msg)) } func (rs *runtimeShim) ValidateImmediateCallerType(...cid.Cid) { log.Info("validate caller type is dumb") } -func (rs *runtimeShim) CurrentBalance() abi.TokenAmount { - b, err := rs.vmctx.GetBalance(rs.vmctx.Message().From) - if err != nil { - rs.Abort(1, err.Error()) - } - - return abi.TokenAmount(b) -} - func (rs *runtimeShim) CurrEpoch() abi.ChainEpoch { - return abi.ChainEpoch(rs.vmctx.BlockHeight()) + return rs.vmctx.BlockHeight() } type dumbWrapperType struct { @@ -122,13 +242,17 @@ func (dwt *dumbWrapperType) Into(um vmr.CBORUnmarshaler) error { return um.UnmarshalCBOR(bytes.NewReader(dwt.val)) } -func (rs *runtimeShim) Send(to address.Address, method abi.MethodNum, m runtime.CBORMarshaler, value abi.TokenAmount) (vmr.SendReturn, exitcode.ExitCode) { - buf := new(bytes.Buffer) - if err := m.MarshalCBOR(buf); err != nil { - rs.Abort(exitcode.SysErrInvalidParameters, "failed to marshal input parameters: %s", err) +func (rs *runtimeShim) Send(to address.Address, method abi.MethodNum, m vmr.CBORMarshaler, value abi.TokenAmount) (vmr.SendReturn, exitcode.ExitCode) { + var params []byte + if m != nil { + buf := new(bytes.Buffer) + if err := m.MarshalCBOR(buf); err != nil { + rs.Abortf(exitcode.SysErrInvalidParameters, "failed to marshal input parameters: %s", err) + } + params = buf.Bytes() } - ret, err := rs.vmctx.Send(to, uint64(method), types.BigInt(value), buf.Bytes()) + ret, err := rs.vmctx.Send(to, method, types.BigInt(value), params) if err != nil { if err.IsFatal() { panic(err) @@ -146,6 +270,16 @@ type shimStateHandle struct { rs *runtimeShim } +func (ssh *shimStateHandle) Create(obj vmr.CBORMarshaler) { + c, err := ssh.rs.vmctx.Storage().Put(obj) + if err != nil { + panic(err) + } + if err := ssh.rs.vmctx.Storage().Commit(EmptyObjectCid, c); err != nil { + panic(err) + } +} + func (ssh *shimStateHandle) Readonly(obj vmr.CBORUnmarshaler) { if err := ssh.rs.vmctx.Storage().Get(ssh.rs.vmctx.Storage().GetHead(), obj); err != nil { panic(err) @@ -170,15 +304,3 @@ func (ssh *shimStateHandle) Transaction(obj vmr.CBORer, f func() interface{}) in return out } - -func (ssh *shimStateHandle) Construct(f func() vmr.CBORMarshaler) { - out := f() - - c, err := ssh.rs.vmctx.Storage().Put(out) - if err != nil { - panic(err) - } - if err := ssh.rs.vmctx.Storage().Commit(actors.EmptyCBOR, c); err != nil { - panic(err) - } -} diff --git a/chain/vm/syscalls.go b/chain/vm/syscalls.go index be6dc76bd..8fca1939a 100644 --- a/chain/vm/syscalls.go +++ b/chain/vm/syscalls.go @@ -1,69 +1,131 @@ package vm import ( - "context" - ffi "github.com/filecoin-project/filecoin-ffi" "github.com/filecoin-project/go-address" + commcid "github.com/filecoin-project/go-fil-commcid" "github.com/filecoin-project/go-sectorbuilder" - "github.com/filecoin-project/lotus/chain/actors" - "github.com/filecoin-project/lotus/chain/actors/aerrors" - "github.com/filecoin-project/lotus/chain/types" - "go.opencensus.io/trace" + "github.com/filecoin-project/lotus/lib/zerocomm" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/crypto" + "github.com/filecoin-project/specs-actors/actors/runtime" + "github.com/ipfs/go-cid" + mh "github.com/multiformats/go-multihash" + "golang.org/x/xerrors" + "math/bits" ) +func init() { + mh.Codes[0xf104] = "filecoin" +} + // Actual type is defined in chain/types/vmcontext.go because the VMContext interface is there -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) { - _, span := trace.StartSpan(ctx, "ValidatePoRep") - defer span.End() - ok, err := verifier.VerifySeal(ssize, commR, commD, maddr, ticket, seed, sectorID, proof) - if err != nil { - return false, aerrors.Absorb(err, 25, "verify seal failed") - } - - return ok, nil - }, - VerifyFallbackPost: func(ctx context.Context, - sectorSize uint64, - sectorInfo []types.PublicSectorInfo, - challengeSeed []byte, - proof []byte, - candidates []types.Candidate, - proverID address.Address, - faults uint64) (bool, error) { - - sI := make([]ffi.PublicSectorInfo, len(sectorInfo)) - for i, v := range sectorInfo { - sI[i] = ffi.PublicSectorInfo{ - SectorID: v.SectorID, - CommR: v.CommR, - } - } - - cand := make([]sectorbuilder.EPostCandidate, len(candidates)) - for i, v := range candidates { - cand[i] = sectorbuilder.EPostCandidate{ - SectorID: v.SectorID, - PartialTicket: v.PartialTicket, - Ticket: v.Ticket, - SectorChallengeIndex: v.SectorChallengeIndex, - } - } - - return verifier.VerifyFallbackPost( - ctx, - sectorSize, - sectorbuilder.NewSortedPublicSectorInfo(sI), - challengeSeed, - proof, - cand, - proverID, - faults, - ) - - }, - } +func Syscalls(verifier sectorbuilder.Verifier) runtime.Syscalls { + return &syscallShim{verifier} +} + +type syscallShim struct { + verifier sectorbuilder.Verifier +} + +func (ss *syscallShim) ComputeUnsealedSectorCID(ssize abi.SectorSize, pieces []abi.PieceInfo) (cid.Cid, error) { + // TODO: does this pull in unwanted dependencies? + var ffipieces []ffi.PublicPieceInfo + var sum abi.PaddedPieceSize + for _, p := range pieces { + ffipieces = append(ffipieces, ffi.PublicPieceInfo{ + Size: p.Size.Unpadded(), + CommP: cidToCommD(p.PieceCID), + }) + sum += p.Size + } + + { + // pad remaining space with 0 CommPs + toFill := uint64(abi.PaddedPieceSize(ssize) - sum) + n := bits.OnesCount64(toFill) + for i := 0; i < n; i++ { + next := bits.TrailingZeros64(toFill) + psize := uint64(1) << next + toFill ^= psize + + unpadded := abi.PaddedPieceSize(psize).Unpadded() + ffipieces = append(ffipieces, ffi.PublicPieceInfo{ + Size: unpadded, + CommP: zerocomm.ForSize(unpadded), + }) + } + } + + commd, err := sectorbuilder.GenerateDataCommitment(ssize, ffipieces) + if err != nil { + log.Errorf("generate data commitment failed: %s", err) + return cid.Undef, err + } + + return commcid.DataCommitmentV1ToCID(commd[:]), nil +} + +func (ss *syscallShim) HashBlake2b(data []byte) [32]byte { + panic("NYI") +} + +func (ss *syscallShim) VerifyConsensusFault(a, b []byte) bool { + panic("NYI") +} + +func (ss *syscallShim) VerifyPoSt(ssize abi.SectorSize, proof abi.PoStVerifyInfo) (bool, error) { + panic("NYI") +} + +func cidToCommD(c cid.Cid) [32]byte { + b := c.Bytes() + var out [32]byte + copy(out[:], b[len(b)-32:]) + return out +} + +func cidToCommR(c cid.Cid) [32]byte { + b := c.Bytes() + var out [32]byte + copy(out[:], b[len(b)-32:]) + return out +} + +func (ss *syscallShim) VerifySeal(ssize abi.SectorSize, info abi.SealVerifyInfo) (bool, error) { + //_, span := trace.StartSpan(ctx, "ValidatePoRep") + //defer span.End() + + commD := cidToCommD(info.UnsealedCID) + commR := cidToCommR(info.OnChain.SealedCID) + + miner, err := address.NewIDAddress(uint64(info.Miner)) + if err != nil { + return false, xerrors.Errorf("weirdly failed to construct address: %w", err) + } + + ticket := []byte(info.Randomness) + proof := []byte(info.OnChain.Proof) + seed := []byte(info.InteractiveRandomness) + + log.Infof("Werif %d r:%x; d:%x; m:%s; t:%x; s:%x; N:%d; p:%x", ssize, commR, commD, miner, ticket, seed, info.SectorID.Number, proof) + + //func(ctx context.Context, maddr address.Address, ssize abi.SectorSize, commD, commR, ticket, proof, seed []byte, sectorID abi.SectorNumber) + ok, err := ss.verifier.VerifySeal(ssize, commR[:], commD[:], miner, ticket, seed, info.SectorID.Number, proof) + if err != nil { + return false, xerrors.Errorf("failed to validate PoRep: %w", err) + } + + return ok, nil +} + +func (ss *syscallShim) VerifySignature(sig crypto.Signature, addr address.Address, input []byte) bool { + return true + /* // TODO: in genesis setup, we are currently faking signatures + if err := ss.rt.vmctx.VerifySignature(&sig, addr, input); err != nil { + return false + } + return true + */ } diff --git a/chain/vm/vm.go b/chain/vm/vm.go index b6e6496f7..c74f2cafe 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -4,7 +4,9 @@ import ( "bytes" "context" "fmt" + "github.com/filecoin-project/specs-actors/actors/builtin" "math/big" + "reflect" block "github.com/ipfs/go-block-format" cid "github.com/ipfs/go-cid" @@ -12,13 +14,20 @@ import ( blockstore "github.com/ipfs/go-ipfs-blockstore" cbor "github.com/ipfs/go-ipld-cbor" logging "github.com/ipfs/go-log/v2" + mh "github.com/multiformats/go-multihash" cbg "github.com/whyrusleeping/cbor-gen" "go.opencensus.io/trace" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" + commcid "github.com/filecoin-project/go-fil-commcid" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin/account" + init_ "github.com/filecoin-project/specs-actors/actors/builtin/init" + "github.com/filecoin-project/specs-actors/actors/crypto" + "github.com/filecoin-project/specs-actors/actors/runtime" + "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/aerrors" "github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/types" @@ -50,13 +59,13 @@ type VMContext struct { vm *VM state *state.StateTree msg *types.Message - height uint64 + height abi.ChainEpoch cst cbor.IpldStore gasAvailable types.BigInt gasUsed types.BigInt - sys *types.VMSyscalls + sys runtime.Syscalls // root cid of the state of the actor this invocation will be on sroot cid.Cid @@ -70,16 +79,15 @@ func (vmc *VMContext) Message() *types.Message { return vmc.msg } -func (vmc *VMContext) GetRandomness(height uint64) ([]byte, aerrors.ActorError) { - - res, err := vmc.vm.rand.GetRandomness(vmc.ctx, int64(height)) +func (vmc *VMContext) GetRandomness(personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, aerrors.ActorError) { + res, err := vmc.vm.rand.GetRandomness(vmc.ctx, personalization, int64(randEpoch), entropy) if err != nil { return nil, aerrors.Escalate(err, "could not get randomness") } return res, nil } -func (vmc *VMContext) Sys() *types.VMSyscalls { +func (vmc *VMContext) Sys() runtime.Syscalls { return vmc.sys } @@ -133,7 +141,7 @@ func (vmc *VMContext) Origin() address.Address { } // Send allows the current execution context to invoke methods on other actors in the system -func (vmc *VMContext) Send(to address.Address, method uint64, value types.BigInt, params []byte) ([]byte, aerrors.ActorError) { +func (vmc *VMContext) Send(to address.Address, method abi.MethodNum, value types.BigInt, params []byte) ([]byte, aerrors.ActorError) { ctx, span := trace.StartSpan(vmc.ctx, "vmc.Send") defer span.End() if span.IsRecordingEvents() { @@ -158,7 +166,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 } @@ -176,16 +184,28 @@ func (vmc *VMContext) ChargeGas(amount uint64) aerrors.ActorError { } func (vmc *VMContext) StateTree() (types.StateTree, aerrors.ActorError) { - if vmc.msg.To != actors.InitAddress { + if vmc.msg.To != builtin.InitActorAddr { return nil, aerrors.Escalate(fmt.Errorf("only init actor can access state tree directly"), "invalid use of StateTree") } return vmc.state, nil } +func (vmc *VMContext) ActorCodeCID(addr address.Address) (ret cid.Cid, err error) { + act, err := vmc.state.GetActor(addr) + if err != nil { + return cid.Undef, err + } + return act.Code, nil +} + +func (vmc *VMContext) LookupID(a address.Address) (address.Address, error) { + return vmc.state.LookupID(a) +} + const GasVerifySignature = 50 -func (vmctx *VMContext) VerifySignature(sig *types.Signature, act address.Address, data []byte) aerrors.ActorError { +func (vmctx *VMContext) VerifySignature(sig *crypto.Signature, act address.Address, data []byte) aerrors.ActorError { if err := vmctx.ChargeGas(GasVerifySignature); err != nil { return err } @@ -215,11 +235,11 @@ func ResolveToKeyAddr(state types.StateTree, cst cbor.IpldStore, addr address.Ad return address.Undef, aerrors.Newf(1, "failed to find actor: %s", addr) } - if act.Code != actors.AccountCodeCid { + if act.Code != builtin.AccountActorCodeID { return address.Undef, aerrors.New(1, "address was not for an account actor") } - var aast actors.AccountActorState + var aast account.State if err := cst.Get(context.TODO(), act.Head, &aast); err != nil { return address.Undef, aerrors.Escalate(err, fmt.Sprintf("failed to get account actor state for %s", addr)) } @@ -301,15 +321,15 @@ type VM struct { base cid.Cid cst *cbor.BasicIpldStore buf *bufbstore.BufferedBS - blockHeight uint64 + blockHeight abi.ChainEpoch blockMiner address.Address inv *invoker rand Rand - Syscalls *types.VMSyscalls + Syscalls runtime.Syscalls } -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 runtime.Syscalls) (*VM, error) { buf := bufbstore.NewBufferedBstore(cbs) cst := cbor.NewCborStore(buf) state, err := state.LoadStateTree(cst, base) @@ -331,7 +351,7 @@ func NewVM(base cid.Cid, height uint64, r Rand, maddr address.Address, cbs block } type Rand interface { - GetRandomness(ctx context.Context, h int64) ([]byte, error) + GetRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round int64, entropy []byte) ([]byte, error) } type ApplyRet struct { @@ -350,7 +370,7 @@ func (vm *VM) send(ctx context.Context, msg *types.Message, parent *VMContext, toActor, err := st.GetActor(msg.To) if err != nil { - if xerrors.Is(err, types.ErrActorNotFound) { + if xerrors.Is(err, init_.ErrAddressNotFound) { a, err := TryCreateAccountActor(st, msg.To) if err != nil { return nil, aerrors.Absorb(err, 1, "could not create account"), nil @@ -543,6 +563,37 @@ func (vm *VM) Flush(ctx context.Context) (cid.Cid, error) { return root, nil } +// vm.MutateState(idAddr, func(cst cbor.IpldStore, st *ActorStateType) error {...}) +func (vm *VM) MutateState(ctx context.Context, addr address.Address, fn interface{}) error { + act, err := vm.cstate.GetActor(addr) + if err != nil { + return xerrors.Errorf("actor not found: %w", err) + } + + st := reflect.New(reflect.TypeOf(fn).In(1).Elem()) + if err := vm.cst.Get(ctx, act.Head, st.Interface()); err != nil { + return xerrors.Errorf("read actor head: %w", err) + } + + out := reflect.ValueOf(fn).Call([]reflect.Value{reflect.ValueOf(vm.cst), st}) + if !out[0].IsNil() && out[0].Interface().(error) != nil { + return out[0].Interface().(error) + } + + head, err := vm.cst.Put(ctx, st.Interface()) + if err != nil { + return xerrors.Errorf("put new actor head: %w", err) + } + + act.Head = head + + if err := vm.cstate.SetActor(addr, act); err != nil { + return xerrors.Errorf("set actor: %w", err) + } + + return nil +} + func linksForObj(blk block.Block) ([]cid.Cid, error) { switch blk.Cid().Prefix().Codec { case cid.DagCBOR: @@ -595,7 +646,7 @@ func copyRec(from, to blockstore.Blockstore, root cid.Cid, cp func(block.Block) } for _, link := range links { - if link.Prefix().MhType == 0 { + if link.Prefix().MhType == mh.IDENTITY || link.Prefix().MhType == uint64(commcid.FC_SEALED_V1) || link.Prefix().MhType == uint64(commcid.FC_UNSEALED_V1) { continue } @@ -622,11 +673,11 @@ 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 } -func (vm *VM) Invoke(act *types.Actor, vmctx *VMContext, method uint64, params []byte) ([]byte, aerrors.ActorError) { +func (vm *VM) Invoke(act *types.Actor, vmctx *VMContext, method abi.MethodNum, params []byte) ([]byte, aerrors.ActorError) { ctx, span := trace.StartSpan(vmctx.ctx, "vm.Invoke") defer span.End() if span.IsRecordingEvents() { diff --git a/chain/wallet/wallet.go b/chain/wallet/wallet.go index df860b045..54587e1b5 100644 --- a/chain/wallet/wallet.go +++ b/chain/wallet/wallet.go @@ -6,6 +6,7 @@ import ( "strings" "sync" + "github.com/filecoin-project/specs-actors/actors/crypto" logging "github.com/ipfs/go-log/v2" "golang.org/x/xerrors" @@ -23,6 +24,8 @@ var log = logging.Logger("wallet") const ( KNamePrefix = "wallet-" KDefault = "default" + KTBLS = "bls" + KTSecp256k1 = "secp256k1" ) type Wallet struct { @@ -52,7 +55,7 @@ func KeyWallet(keys ...*Key) *Wallet { } } -func (w *Wallet) Sign(ctx context.Context, addr address.Address, msg []byte) (*types.Signature, error) { +func (w *Wallet) Sign(ctx context.Context, addr address.Address, msg []byte) (*crypto.Signature, error) { ki, err := w.findKey(addr) if err != nil { return nil, err @@ -61,7 +64,7 @@ func (w *Wallet) Sign(ctx context.Context, addr address.Address, msg []byte) (*t return nil, xerrors.Errorf("signing using key '%s': %w", addr.String(), types.ErrKeyInfoNotFound) } - return sigs.Sign(ki.Type, ki.PrivateKey, msg) + return sigs.Sign(ActSigType(ki.Type), ki.PrivateKey, msg) } func (w *Wallet) findKey(addr address.Address) (*Key, error) { @@ -179,19 +182,19 @@ func (w *Wallet) SetDefault(a address.Address) error { return nil } -func GenerateKey(typ string) (*Key, error) { +func GenerateKey(typ crypto.SigType) (*Key, error) { pk, err := sigs.Generate(typ) if err != nil { return nil, err } ki := types.KeyInfo{ - Type: typ, + Type: kstoreSigType(typ), PrivateKey: pk, } return NewKey(ki) } -func (w *Wallet) GenerateKey(typ string) (address.Address, error) { +func (w *Wallet) GenerateKey(typ crypto.SigType) (address.Address, error) { w.lk.Lock() defer w.lk.Unlock() @@ -240,18 +243,18 @@ func NewKey(keyinfo types.KeyInfo) (*Key, error) { } var err error - k.PublicKey, err = sigs.ToPublic(k.Type, k.PrivateKey) + k.PublicKey, err = sigs.ToPublic(ActSigType(k.Type), k.PrivateKey) if err != nil { return nil, err } switch k.Type { - case types.KTSecp256k1: + case KTSecp256k1: k.Address, err = address.NewSecp256k1Address(k.PublicKey) if err != nil { return nil, xerrors.Errorf("converting Secp256k1 to address: %w", err) } - case types.KTBLS: + case KTBLS: k.Address, err = address.NewBLSAddress(k.PublicKey) if err != nil { return nil, xerrors.Errorf("converting BLS to address: %w", err) @@ -262,3 +265,25 @@ func NewKey(keyinfo types.KeyInfo) (*Key, error) { return k, nil } + +func kstoreSigType(typ crypto.SigType) string { + switch typ { + case crypto.SigTypeBLS: + return KTBLS + case crypto.SigTypeSecp256k1: + return KTSecp256k1 + default: + return "" + } +} + +func ActSigType(typ string) crypto.SigType { + switch typ { + case KTBLS: + return crypto.SigTypeBLS + case KTSecp256k1: + return crypto.SigTypeSecp256k1 + default: + return 0 + } +} diff --git a/cli/chain.go b/cli/chain.go index 6de22ed3a..1bebc78e9 100644 --- a/cli/chain.go +++ b/cli/chain.go @@ -11,6 +11,11 @@ import ( "strings" "time" + "github.com/filecoin-project/go-address" + cborutil "github.com/filecoin-project/go-cbor-util" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/filecoin-project/specs-actors/actors/builtin/power" cid "github.com/ipfs/go-cid" "golang.org/x/xerrors" "gopkg.in/urfave/cli.v2" @@ -250,7 +255,7 @@ var chainSetHeadCmd = &cli.Command{ ts, err = api.ChainGetGenesis(ctx) } if ts == nil && cctx.IsSet("epoch") { - ts, err = api.ChainGetTipSetByHeight(ctx, cctx.Uint64("epoch"), types.EmptyTSK) + ts, err = api.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(cctx.Uint64("epoch")), types.EmptyTSK) } if ts == nil { ts, err = parseTipSet(api, ctx, cctx.Args().Slice()) @@ -313,7 +318,7 @@ var chainListCmd = &cli.Command{ var head *types.TipSet if cctx.IsSet("height") { - head, err = api.ChainGetTipSetByHeight(ctx, cctx.Uint64("height"), types.EmptyTSK) + head, err = api.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(cctx.Uint64("height")), types.EmptyTSK) } else { head, err = api.ChainHead(ctx) } @@ -446,7 +451,7 @@ var chainBisectCmd = &cli.Command{ subPath := cctx.Args().Get(2) - highest, err := api.ChainGetTipSetByHeight(ctx, end, types.EmptyTSK) + highest, err := api.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(end), types.EmptyTSK) if err != nil { return err } @@ -460,7 +465,7 @@ var chainBisectCmd = &cli.Command{ start = end } - midTs, err := api.ChainGetTipSetByHeight(ctx, mid, highest.Key()) + midTs, err := api.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(mid), highest.Key()) if err != nil { return err } @@ -506,7 +511,7 @@ var chainBisectCmd = &cli.Command{ return nil } - prev = mid + prev = abi.ChainEpoch(mid) } }, } @@ -594,18 +599,31 @@ var slashConsensusFault = &cli.Command{ return err } - params, err := actors.SerializeParams(&actors.ArbitrateConsensusFaultParams{ - Block1: b1, - Block2: b2, + bh1, err := cborutil.Dump(b1) + if err != nil { + return err + } + + bh2, err := cborutil.Dump(b2) + if err != nil { + return err + } + + params, err := actors.SerializeParams(&power.ReportConsensusFaultParams{ + BlockHeader1: bh1, + BlockHeader2: bh2, + Target: address.Address{}, + FaultEpoch: 0, + FaultType: 0, }) msg := &types.Message{ - To: actors.StoragePowerAddress, + To: builtin.StoragePowerActorAddr, From: def, Value: types.NewInt(0), GasPrice: types.NewInt(1), GasLimit: types.NewInt(10000000), - Method: actors.SPAMethods.ArbitrateConsensusFault, + Method: builtin.MethodsPower.ReportConsensusFault, Params: params, } diff --git a/cli/client.go b/cli/client.go index 078d7ad07..c680ce645 100644 --- a/cli/client.go +++ b/cli/client.go @@ -14,7 +14,7 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-fil-markets/storagemarket" - actors "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/types" ) @@ -291,27 +291,15 @@ var clientQueryAskCmd = &cli.Command{ } pid = p } else { - ret, err := api.StateCall(ctx, &types.Message{ - To: maddr, - From: maddr, - Method: actors.MAMethods.GetPeerID, - }, types.EmptyTSK) + p, err := api.StateMinerPeerID(ctx, maddr, types.EmptyTSK) if err != nil { return xerrors.Errorf("failed to get peerID for miner: %w", err) } - if ret.ExitCode != 0 { - return fmt.Errorf("call to GetPeerID was unsuccesful (exit code %d)", ret.ExitCode) - } - if peer.ID(ret.Return) == peer.ID("SETME") { + if p == peer.ID("SETME") { return fmt.Errorf("the miner hasn't initialized yet") } - p, err := peer.IDFromBytes(ret.Return) - if err != nil { - return err - } - pid = p } diff --git a/cli/multisig.go b/cli/multisig.go index d1c0ecd13..91959d6b3 100644 --- a/cli/multisig.go +++ b/cli/multisig.go @@ -14,6 +14,7 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/builtin" + init_ "github.com/filecoin-project/specs-actors/actors/builtin/init" samsig "github.com/filecoin-project/specs-actors/actors/builtin/multisig" cid "github.com/ipfs/go-cid" "github.com/ipfs/go-hamt-ipld" @@ -104,9 +105,9 @@ var msigCreateCmd = &cli.Command{ } // new actors are created by invoking 'exec' on the init actor with the constructor params - execParams := &actors.ExecParams{ - Code: actors.MultisigCodeCid, - Params: enc, + execParams := &init_.ExecParams{ + CodeCID: builtin.MultisigActorCodeID, + ConstructorParams: enc, } enc, err = actors.SerializeParams(execParams) @@ -116,9 +117,9 @@ var msigCreateCmd = &cli.Command{ // now we create the message to send this with msg := types.Message{ - To: actors.InitAddress, + To: builtin.InitActorAddr, From: sendAddr, - Method: actors.IAMethods.Exec, + Method: builtin.MethodsInit.Exec, Params: enc, GasPrice: types.NewInt(1), GasLimit: types.NewInt(1000000), @@ -186,7 +187,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,19 +227,19 @@ 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) - nd, err := hamt.LoadNode(ctx, cst, hroot) + nd, err := hamt.LoadNode(ctx, cst, hroot, hamt.UseTreeBitWidth(5)) if err != nil { 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 +256,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" @@ -347,7 +348,7 @@ var msigProposeCmd = &cli.Command{ To: msig, From: from, Value: types.NewInt(0), - Method: uint64(builtin.MethodsMultisig.Propose), + Method: builtin.MethodsMultisig.Propose, Params: enc, GasLimit: types.NewInt(100000), GasPrice: types.NewInt(1), @@ -432,7 +433,7 @@ var msigApproveCmd = &cli.Command{ To: msig, From: from, Value: types.NewInt(0), - Method: uint64(builtin.MethodsMultisig.Approve), + Method: builtin.MethodsMultisig.Approve, Params: enc, GasLimit: types.NewInt(100000), GasPrice: types.NewInt(1), diff --git a/cli/paych.go b/cli/paych.go index a41211e31..5d42a0ea5 100644 --- a/cli/paych.go +++ b/cli/paych.go @@ -1,11 +1,15 @@ package cli import ( + "bytes" + "encoding/base64" "fmt" "github.com/filecoin-project/go-address" - types "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/specs-actors/actors/builtin/paych" "gopkg.in/urfave/cli.v2" + + types "github.com/filecoin-project/lotus/chain/types" ) var paychCmd = &cli.Command{ @@ -136,7 +140,7 @@ var paychVoucherCreateCmd = &cli.Command{ return err } - enc, err := sv.EncodedString() + enc, err := EncodedString(sv) if err != nil { return err } @@ -250,7 +254,7 @@ var paychVoucherListCmd = &cli.Command{ for _, v := range vouchers { if cctx.Bool("export") { - enc, err := v.EncodedString() + enc, err := EncodedString(v) if err != nil { return err } @@ -291,7 +295,7 @@ var paychVoucherBestSpendableCmd = &cli.Command{ return err } - var best *types.SignedVoucher + var best *paych.SignedVoucher for _, v := range vouchers { spendable, err := api.PaychVoucherCheckSpendable(ctx, ch, v, nil, nil) if err != nil { @@ -308,7 +312,7 @@ var paychVoucherBestSpendableCmd = &cli.Command{ return fmt.Errorf("No spendable vouchers for that channel") } - enc, err := best.EncodedString() + enc, err := EncodedString(best) if err != nil { return err } @@ -364,3 +368,12 @@ var paychVoucherSubmitCmd = &cli.Command{ return nil }, } + +func EncodedString(sv *paych.SignedVoucher) (string, error) { + buf := new(bytes.Buffer) + if err := sv.MarshalCBOR(buf); err != nil { + return "", err + } + + return base64.RawURLEncoding.EncodeToString(buf.Bytes()), nil +} diff --git a/cli/state.go b/cli/state.go index 919613ce7..5e489ed7c 100644 --- a/cli/state.go +++ b/cli/state.go @@ -5,19 +5,25 @@ import ( "context" "encoding/json" "fmt" + "github.com/filecoin-project/specs-actors/actors/builtin" "reflect" "strconv" "strings" "github.com/filecoin-project/go-address" - "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" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin/market" + miner2 "github.com/filecoin-project/specs-actors/actors/builtin/miner" samsig "github.com/filecoin-project/specs-actors/actors/builtin/multisig" + "github.com/filecoin-project/specs-actors/actors/builtin/paych" + "github.com/filecoin-project/specs-actors/actors/builtin/power" "github.com/libp2p/go-libp2p-core/peer" "golang.org/x/xerrors" + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/miner" + "github.com/docker/go-units" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -90,24 +96,16 @@ var stateMinerInfo = &cli.Command{ return err } - var mst actors.StorageMinerActorState + var mst miner2.State if err := mst.UnmarshalCBOR(bytes.NewReader(aso)); err != nil { return err } - mio, err := api.ChainReadObj(ctx, mst.Info) - if err != nil { - return err - } - - var mi actors.MinerInfo - if err := mi.UnmarshalCBOR(bytes.NewReader(mio)); err != nil { - return err - } + mi := mst.Info fmt.Printf("Owner:\t%s\n", mi.Owner) fmt.Printf("Worker:\t%s\n", mi.Worker) - fmt.Printf("PeerID:\t%s\n", mi.PeerID) + fmt.Printf("PeerID:\t%s\n", mi.PeerId) fmt.Printf("SectorSize:\t%s (%d)\n", units.BytesSize(float64(mi.SectorSize)), mi.SectorSize) return nil @@ -187,9 +185,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 @@ -228,7 +226,7 @@ var stateSectorsCmd = &cli.Command{ } for _, s := range sectors { - fmt.Printf("%d: %x %x\n", s.SectorID, s.CommR, s.CommD) + fmt.Printf("%d: %x\n", s.Info.Info.SectorNumber, s.Info.Info.SealedCID) } return nil @@ -267,7 +265,7 @@ var stateProvingSetCmd = &cli.Command{ } for _, s := range sectors { - fmt.Printf("%d: %x %x\n", s.SectorID, s.CommR, s.CommD) + fmt.Printf("%d: %x\n", s.Info.Info.SectorNumber, s.Info.Info.SealedCID) } return nil @@ -278,8 +276,8 @@ var stateReplaySetCmd = &cli.Command{ Name: "replay", Usage: "Replay a particular message within a tipset", Action: func(cctx *cli.Context) error { - if cctx.Args().Len() < 2 { - fmt.Println("usage: ") + if cctx.Args().Len() < 1 { + fmt.Println("usage: [tipset] ") fmt.Println("The last cid passed will be used as the message CID") fmt.Println("All preceding ones will be used as the tipset") return nil @@ -291,15 +289,6 @@ var stateReplaySetCmd = &cli.Command{ return fmt.Errorf("message cid was invalid: %s", err) } - var tscids []cid.Cid - for _, s := range args[:len(args)-1] { - c, err := cid.Decode(s) - if err != nil { - return fmt.Errorf("tipset cid was invalid: %s", err) - } - tscids = append(tscids, c) - } - api, closer, err := GetFullNodeAPI(cctx) if err != nil { return err @@ -308,19 +297,41 @@ var stateReplaySetCmd = &cli.Command{ ctx := ReqContext(cctx) - var headers []*types.BlockHeader - for _, c := range tscids { - h, err := api.ChainGetBlock(ctx, c) + var ts *types.TipSet + { + var tscids []cid.Cid + for _, s := range args[:len(args)-1] { + c, err := cid.Decode(s) + if err != nil { + return fmt.Errorf("tipset cid was invalid: %s", err) + } + tscids = append(tscids, c) + } + + if len(tscids) > 0 { + var headers []*types.BlockHeader + for _, c := range tscids { + h, err := api.ChainGetBlock(ctx, c) + if err != nil { + return err + } + + headers = append(headers, h) + } + + ts, err = types.NewTipSet(headers) + } else { + r, err := api.StateWaitMsg(ctx, mcid) + if err != nil { + return xerrors.Errorf("finding message in chain: %w", err) + } + + ts, err = api.ChainGetTipSet(ctx, r.TipSet.Parents()) + } if err != nil { return err } - headers = append(headers, h) - } - - ts, err := types.NewTipSet(headers) - if err != nil { - return err } res, err := api.StateReplay(ctx, ts.Key(), mcid) @@ -393,7 +404,7 @@ var stateGetDealSetCmd = &cli.Command{ return err } - deal, err := api.StateMarketStorageDeal(ctx, dealid, ts.Key()) + deal, err := api.StateMarketStorageDeal(ctx, abi.DealID(dealid), ts.Key()) if err != nil { return err } @@ -682,7 +693,7 @@ var stateListMessagesCmd = &cli.Command{ return err } - msgs, err := api.StateListMessages(ctx, &types.Message{To: toa, From: froma}, ts.Key(), toh) + msgs, err := api.StateListMessages(ctx, &types.Message{To: toa, From: froma}, ts.Key(), abi.ChainEpoch(toh)) if err != nil { return err } @@ -735,7 +746,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) @@ -821,7 +832,7 @@ var stateCallCmd = &cli.Command{ &cli.StringFlag{ Name: "from", Usage: "", - Value: actors.NetworkAddress.String(), + Value: builtin.SystemActorAddr.String(), }, &cli.StringFlag{ Name: "value", @@ -888,7 +899,7 @@ var stateCallCmd = &cli.Command{ Value: types.BigInt(value), GasLimit: types.NewInt(10000000000), GasPrice: types.NewInt(0), - Method: method, + Method: abi.MethodNum(method), Params: params, }, ts.Key()) if err != nil { @@ -962,16 +973,16 @@ func parseParamsForMethod(act cid.Cid, method uint64, args []string) ([]byte, er var f interface{} switch act { - case actors.StorageMarketCodeCid: - f = actors.StorageMarketActor{}.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] - case actors.PaymentChannelCodeCid: - f = actors.PaymentChannelActor{}.Exports()[method] + case builtin.StorageMarketActorCodeID: + f = market.Actor{}.Exports()[method] + case builtin.StorageMinerActorCodeID: + f = miner2.Actor{}.Exports()[method] + case builtin.StoragePowerActorCodeID: + f = power.Actor{}.Exports()[method] + case builtin.MultisigActorCodeID: + f = samsig.Actor{}.Exports()[method] + case builtin.PaymentChannelActorCodeID: + f = paych.Actor{}.Exports()[method] default: return nil, fmt.Errorf("the lazy devs didnt add support for that actor to this call yet") } diff --git a/cli/sync.go b/cli/sync.go index 64c27d5ae..588fcf91e 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" @@ -45,7 +46,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/cli/wallet.go b/cli/wallet.go index ad600eadf..2548deb21 100644 --- a/cli/wallet.go +++ b/cli/wallet.go @@ -10,6 +10,8 @@ import ( "github.com/filecoin-project/go-address" types "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/chain/wallet" + "gopkg.in/urfave/cli.v2" ) @@ -44,7 +46,7 @@ var walletNew = &cli.Command{ t = "secp256k1" } - nk, err := api.WalletNew(ctx, t) + nk, err := api.WalletNew(ctx, wallet.ActSigType(t)) if err != nil { return err } diff --git a/cmd/chain-noise/main.go b/cmd/chain-noise/main.go index ae187b116..23440335c 100644 --- a/cmd/chain-noise/main.go +++ b/cmd/chain-noise/main.go @@ -3,6 +3,7 @@ package main import ( "context" "fmt" + "github.com/filecoin-project/specs-actors/actors/crypto" "math/rand" "os" "time" @@ -59,7 +60,7 @@ var runCmd = &cli.Command{ func sendSmallFundsTxs(ctx context.Context, api api.FullNode, from address.Address, rate int) error { var sendSet []address.Address for i := 0; i < 20; i++ { - naddr, err := api.WalletNew(ctx, "bls") + naddr, err := api.WalletNew(ctx, crypto.SigTypeSecp256k1) if err != nil { return err } diff --git a/cmd/lotus-bench/main.go b/cmd/lotus-bench/main.go index cd222c800..a86c2e47c 100644 --- a/cmd/lotus-bench/main.go +++ b/cmd/lotus-bench/main.go @@ -16,6 +16,7 @@ import ( "github.com/docker/go-units" ffi "github.com/filecoin-project/filecoin-ffi" paramfetch "github.com/filecoin-project/go-paramfetch" + "github.com/filecoin-project/specs-actors/actors/abi" "github.com/ipfs/go-datastore" logging "github.com/ipfs/go-log/v2" "github.com/mitchellh/go-homedir" @@ -32,7 +33,7 @@ import ( var log = logging.Logger("lotus-bench") type BenchResults struct { - SectorSize uint64 + SectorSize abi.SectorSize SealingResults []SealingResult @@ -139,7 +140,7 @@ func main() { if err != nil { return err } - sectorSize := uint64(sectorSizeInt) + sectorSize := abi.SectorSize(sectorSizeInt) mds := datastore.NewMapDatastore() cfg := §orbuilder.Config{ @@ -155,7 +156,7 @@ func main() { } } - if err := paramfetch.GetParams(build.ParametersJson(), sectorSize); err != nil { + if err := paramfetch.GetParams(build.ParametersJson(), uint64(sectorSize)); err != nil { return xerrors.Errorf("getting params: %w", err) } sb, err := sectorbuilder.New(cfg, mds) @@ -163,18 +164,16 @@ func main() { return err } - dataSize := sectorbuilder.UserBytesForSectorSize(sectorSize) - var sealTimings []SealingResult var sealedSectors []ffi.PublicSectorInfo - numSectors := uint64(1) - for i := uint64(1); i <= numSectors && robench == ""; i++ { + numSectors := abi.SectorNumber(1) + for i := abi.SectorNumber(1); i <= numSectors && robench == ""; i++ { start := time.Now() log.Info("Writing piece into sector...") r := rand.New(rand.NewSource(100 + int64(i))) - pi, err := sb.AddPiece(context.TODO(), dataSize, i, r, nil) + pi, err := sb.AddPiece(context.TODO(), abi.UnpaddedPieceSize(sectorSize), i, r, nil) if err != nil { return err } @@ -196,8 +195,8 @@ func main() { precommit := time.Now() sealedSectors = append(sealedSectors, ffi.PublicSectorInfo{ - CommR: pco.CommR, - SectorID: i, + CommR: pco.CommR, + SectorNum: i, }) seed := sectorbuilder.SealSeed{ @@ -225,7 +224,7 @@ func main() { if !c.Bool("skip-unseal") { log.Info("Unsealing sector") - rc, err := sb.ReadPieceFromSealedSector(context.TODO(), 1, 0, dataSize, ticket.TicketBytes[:], commD[:]) + rc, err := sb.ReadPieceFromSealedSector(context.TODO(), 1, 0, abi.UnpaddedPieceSize(sectorSize), ticket.TicketBytes[:], commD[:]) if err != nil { return err } @@ -260,7 +259,7 @@ func main() { return err } - var genmm map[string]genesis.GenesisMiner + var genmm map[string]genesis.Miner if err := json.Unmarshal(fdata, &genmm); err != nil { return err } @@ -272,15 +271,15 @@ func main() { for _, s := range genm.Sectors { sealedSectors = append(sealedSectors, ffi.PublicSectorInfo{ - CommR: s.CommR, - SectorID: s.SectorID, + CommR: s.CommR, + SectorNum: s.SectorID, }) } } log.Info("generating election post candidates") sinfos := sectorbuilder.NewSortedPublicSectorInfo(sealedSectors) - candidates, err := sb.GenerateEPostCandidates(sinfos, challenge, []uint64{}) + candidates, err := sb.GenerateEPostCandidates(sinfos, challenge, []abi.SectorNumber{}) if err != nil { return err } @@ -355,7 +354,7 @@ func main() { fmt.Printf("unseal: %s (%s)\n", bo.SealingResults[0].Unseal, bps(bo.SectorSize, bo.SealingResults[0].Unseal)) } } - fmt.Printf("generate candidates: %s (%s)\n", bo.PostGenerateCandidates, bps(bo.SectorSize*uint64(len(bo.SealingResults)), bo.PostGenerateCandidates)) + fmt.Printf("generate candidates: %s (%s)\n", bo.PostGenerateCandidates, bps(bo.SectorSize*abi.SectorSize(len(bo.SealingResults)), bo.PostGenerateCandidates)) fmt.Printf("compute epost proof (cold): %s\n", bo.PostEProofCold) fmt.Printf("compute epost proof (hot): %s\n", bo.PostEProofHot) fmt.Printf("verify epost proof (cold): %s\n", bo.VerifyEPostCold) @@ -371,9 +370,9 @@ func main() { } } -func bps(data uint64, d time.Duration) string { - bdata := new(big.Int).SetUint64(data) +func bps(data abi.SectorSize, d time.Duration) string { + bdata := new(big.Int).SetUint64(uint64(data)) bdata = bdata.Mul(bdata, big.NewInt(time.Second.Nanoseconds())) bps := bdata.Div(bdata, big.NewInt(d.Nanoseconds())) - return (types.BigInt{bps}).SizeStr() + "/s" + return types.SizeStr(types.BigInt{bps}) + "/s" } diff --git a/cmd/lotus-chainwatch/storage.go b/cmd/lotus-chainwatch/storage.go index cc1b9e0b7..befdc288f 100644 --- a/cmd/lotus-chainwatch/storage.go +++ b/cmd/lotus-chainwatch/storage.go @@ -2,7 +2,6 @@ package main import ( "database/sql" - "encoding/hex" "fmt" "sync" "time" @@ -13,7 +12,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/types" ) @@ -267,8 +265,8 @@ create table if not exists deals pieceSize bigint not null, client text not null, provider text not null, - expiration decimal not null, - duration decimal not null, + start decimal not null, + end decimal not null, epochPrice decimal not null, collateral decimal not null, constraint deals_pk @@ -473,11 +471,11 @@ create temp table mh (like miner_heads excluding constraints) on commit drop; fmt.Sprint(i.psize), i.info.Owner.String(), i.info.Worker.String(), - i.info.PeerID.String(), + i.info.PeerId.String(), i.info.SectorSize, - i.state.Power.String(), + i.state.Power.String(), // TODO: SPA i.state.Active, - i.state.ElectionPeriodStart, + i.state.PoStState.ProvingPeriodStart, i.state.SlashedAt, ); err != nil { return err @@ -842,7 +840,7 @@ func (st *storage) storeMpoolInclusions(msgs []api.MpoolUpdate) error { return tx.Commit() } -func (st *storage) storeDeals(deals map[string]actors.OnChainDeal) error { +func (st *storage) storeDeals(deals map[string]api.MarketDeal) error { tx, err := st.db.Begin() if err != nil { return err @@ -854,7 +852,7 @@ func (st *storage) storeDeals(deals map[string]actors.OnChainDeal) error { return xerrors.Errorf("prep temp: %w", err) } - stmt, err := tx.Prepare(`copy d (id, pieceref, piecesize, client, "provider", expiration, duration, epochprice, collateral) from stdin `) + stmt, err := tx.Prepare(`copy d (id, pieceref, piecesize, client, "provider", "start", "end", epochprice, collateral) from stdin `) if err != nil { return err } @@ -862,20 +860,20 @@ func (st *storage) storeDeals(deals map[string]actors.OnChainDeal) error { var bloat uint64 for id, deal := range deals { - if len(deal.PieceRef) > 40 { - bloat += uint64(len(deal.PieceRef)) + if len(deal.Proposal.PieceCID.String()) > 100 { + bloat += uint64(len(deal.Proposal.PieceCID.String())) continue } if _, err := stmt.Exec( id, - hex.EncodeToString(deal.PieceRef), - deal.PieceSize, - deal.Client.String(), - deal.Provider.String(), - fmt.Sprint(deal.ProposalExpiration), - fmt.Sprint(deal.Duration), - deal.StoragePricePerEpoch.String(), - deal.StorageCollateral.String(), + deal.Proposal.PieceCID.String(), + deal.Proposal.PieceSize, + deal.Proposal.Client.String(), + deal.Proposal.Provider.String(), + fmt.Sprint(deal.Proposal.StartEpoch), + fmt.Sprint(deal.Proposal.EndEpoch), + deal.Proposal.StoragePricePerEpoch.String(), + deal.Proposal.ProviderCollateral.String(), ); err != nil { return err } @@ -915,12 +913,12 @@ func (st *storage) storeDeals(deals map[string]actors.OnChainDeal) error { } for id, deal := range deals { - if deal.ActivationEpoch == 0 { + if deal.State.SectorStartEpoch <= 0 { continue } if _, err := stmt.Exec( id, - deal.ActivationEpoch, + deal.State.SectorStartEpoch, ); err != nil { return err } diff --git a/cmd/lotus-chainwatch/sync.go b/cmd/lotus-chainwatch/sync.go index 8d2a814b6..d3292ce9e 100644 --- a/cmd/lotus-chainwatch/sync.go +++ b/cmd/lotus-chainwatch/sync.go @@ -5,11 +5,13 @@ import ( "container/list" "context" "encoding/json" + "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/filecoin-project/specs-actors/actors/builtin/miner" "math" "sync" "github.com/filecoin-project/go-address" - actors2 "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/specs-actors/actors/abi" "github.com/ipfs/go-cid" @@ -51,8 +53,8 @@ type minerKey struct { } type minerInfo struct { - state actors2.StorageMinerActorState - info actors2.MinerInfo + state miner.State + info miner.MinerInfo ssize uint64 psize uint64 @@ -111,7 +113,7 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS for len(allToSync) > 0 { actors := map[address.Address]map[types.Actor]actorInfo{} addresses := map[address.Address]address.Address{} - minH := uint64(math.MaxUint64) + minH := abi.ChainEpoch(math.MaxUint64) for _, header := range allToSync { if header.Height < minH { @@ -251,7 +253,7 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS for addr, m := range actors { for actor, c := range m { - if actor.Code != actors2.StorageMinerCodeCid { + if actor.Code != builtin.StorageMinerActorCodeID { continue } @@ -285,16 +287,7 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS return } - ib, err := api.ChainReadObj(ctx, info.state.Info) - if err != nil { - log.Error(err) - return - } - - if err := info.info.UnmarshalCBOR(bytes.NewReader(ib)); err != nil { - log.Error(err) - return - } + info.info = info.state.Info }) log.Info("Getting receipts") diff --git a/cmd/lotus-fountain/main.go b/cmd/lotus-fountain/main.go index dda2eb257..2df186225 100644 --- a/cmd/lotus-fountain/main.go +++ b/cmd/lotus-fountain/main.go @@ -10,6 +10,9 @@ import ( "time" rice "github.com/GeertJohan/go.rice" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/filecoin-project/specs-actors/actors/builtin/power" "github.com/ipfs/go-cid" logging "github.com/ipfs/go-log/v2" peer "github.com/libp2p/go-libp2p-peer" @@ -261,11 +264,11 @@ func (h *handler) mkminer(w http.ResponseWriter, r *http.Request) { } log.Infof("%s: push funds %s", owner, smsg.Cid()) - params, err := actors.SerializeParams(&actors.CreateStorageMinerParams{ - Owner: owner, + params, err := actors.SerializeParams(&power.CreateMinerParams{ + Owner: owner, // TODO: That is useful Worker: owner, - SectorSize: uint64(ssize), - PeerID: peer.ID("SETME"), + SectorSize: abi.SectorSize(ssize), + Peer: peer.ID("SETME"), }) if err != nil { w.WriteHeader(400) @@ -274,11 +277,11 @@ func (h *handler) mkminer(w http.ResponseWriter, r *http.Request) { } createStorageMinerMsg := &types.Message{ - To: actors.StoragePowerAddress, + To: builtin.StoragePowerActorAddr, From: h.from, Value: types.BigAdd(collateral, types.BigDiv(collateral, types.NewInt(100))), - Method: actors.SPAMethods.CreateStorageMiner, + Method: builtin.MethodsPower.CreateMiner, Params: params, GasLimit: types.NewInt(10000000), diff --git a/cmd/lotus-seal-worker/main.go b/cmd/lotus-seal-worker/main.go index 208d64eb5..1551bb07f 100644 --- a/cmd/lotus-seal-worker/main.go +++ b/cmd/lotus-seal-worker/main.go @@ -134,7 +134,7 @@ var runCmd = &cli.Command{ return err } - if err := paramfetch.GetParams(build.ParametersJson(), ssize); err != nil { + if err := paramfetch.GetParams(build.ParametersJson(), uint64(ssize)); err != nil { return xerrors.Errorf("get params: %w", err) } diff --git a/cmd/lotus-seal-worker/sub.go b/cmd/lotus-seal-worker/sub.go index 0c2d233de..d57b3cb39 100644 --- a/cmd/lotus-seal-worker/sub.go +++ b/cmd/lotus-seal-worker/sub.go @@ -45,7 +45,7 @@ loop: select { case task := <-tasks: - log.Infof("New task: %d, sector %d, action: %d", task.TaskID, task.SectorID, task.Type) + log.Infof("New task: %d, sector %d, action: %d", task.TaskID, task.SectorNum, task.Type) res := w.processTask(ctx, task) @@ -71,7 +71,7 @@ func (w *worker) processTask(ctx context.Context, task sectorbuilder.WorkerTask) return errRes(xerrors.Errorf("unknown task type %d", task.Type)) } - if err := w.fetchSector(task.SectorID, task.Type); err != nil { + if err := w.fetchSector(task.SectorNum, task.Type); err != nil { return errRes(xerrors.Errorf("fetching sector: %w", err)) } @@ -82,7 +82,7 @@ func (w *worker) processTask(ctx context.Context, task sectorbuilder.WorkerTask) switch task.Type { case sectorbuilder.WorkerPreCommit: w.limiter.workLimit <- struct{}{} - rspco, err := w.sb.SealPreCommit(ctx, task.SectorID, task.SealTicket, task.Pieces) + rspco, err := w.sb.SealPreCommit(ctx, task.SectorNum, task.SealTicket, task.Pieces) <-w.limiter.workLimit if err != nil { @@ -90,20 +90,20 @@ func (w *worker) processTask(ctx context.Context, task sectorbuilder.WorkerTask) } res.Rspco = rspco.ToJson() - if err := w.push("sealed", task.SectorID); err != nil { + if err := w.push("sealed", task.SectorNum); err != nil { return errRes(xerrors.Errorf("pushing precommited data: %w", err)) } - if err := w.push("cache", task.SectorID); err != nil { + if err := w.push("cache", task.SectorNum); err != nil { return errRes(xerrors.Errorf("pushing precommited data: %w", err)) } - if err := w.remove("staging", task.SectorID); err != nil { + if err := w.remove("staging", task.SectorNum); err != nil { return errRes(xerrors.Errorf("cleaning up staged sector: %w", err)) } case sectorbuilder.WorkerCommit: w.limiter.workLimit <- struct{}{} - proof, err := w.sb.SealCommit(ctx, task.SectorID, task.SealTicket, task.SealSeed, task.Pieces, task.Rspco) + proof, err := w.sb.SealCommit(ctx, task.SectorNum, task.SealTicket, task.SealSeed, task.Pieces, task.Rspco) <-w.limiter.workLimit if err != nil { @@ -112,11 +112,11 @@ func (w *worker) processTask(ctx context.Context, task sectorbuilder.WorkerTask) res.Proof = proof - if err := w.push("cache", task.SectorID); err != nil { + if err := w.push("cache", task.SectorNum); err != nil { return errRes(xerrors.Errorf("pushing precommited data: %w", err)) } - if err := w.remove("sealed", task.SectorID); err != nil { + if err := w.remove("sealed", task.SectorNum); err != nil { return errRes(xerrors.Errorf("cleaning up sealed sector: %w", err)) } } diff --git a/cmd/lotus-seal-worker/transfer.go b/cmd/lotus-seal-worker/transfer.go index 6091a628f..683071b5f 100644 --- a/cmd/lotus-seal-worker/transfer.go +++ b/cmd/lotus-seal-worker/transfer.go @@ -9,6 +9,7 @@ import ( sectorbuilder "github.com/filecoin-project/go-sectorbuilder" "github.com/filecoin-project/go-sectorbuilder/fs" + "github.com/filecoin-project/specs-actors/actors/abi" files "github.com/ipfs/go-ipfs-files" "golang.org/x/xerrors" "gopkg.in/cheggaaa/pb.v1" @@ -25,7 +26,7 @@ func (w *worker) sizeForType(typ string) int64 { return size } -func (w *worker) fetch(typ string, sectorID uint64) error { +func (w *worker) fetch(typ string, sectorID abi.SectorNumber) error { outname := filepath.Join(w.repo, typ, w.sb.SectorName(sectorID)) url := w.minerEndpoint + "/remote/" + typ + "/" + fmt.Sprint(sectorID) @@ -77,7 +78,7 @@ func (w *worker) fetch(typ string, sectorID uint64) error { } -func (w *worker) push(typ string, sectorID uint64) error { +func (w *worker) push(typ string, sectorID abi.SectorNumber) error { w.limiter.transferLimit <- struct{}{} defer func() { <-w.limiter.transferLimit @@ -146,12 +147,12 @@ func (w *worker) push(typ string, sectorID uint64) error { return w.remove(typ, sectorID) } -func (w *worker) remove(typ string, sectorID uint64) error { +func (w *worker) remove(typ string, sectorID abi.SectorNumber) error { filename := filepath.Join(w.repo, typ, w.sb.SectorName(sectorID)) return os.RemoveAll(filename) } -func (w *worker) fetchSector(sectorID uint64, typ sectorbuilder.WorkerTaskType) error { +func (w *worker) fetchSector(sectorID abi.SectorNumber, typ sectorbuilder.WorkerTaskType) error { w.limiter.transferLimit <- struct{}{} defer func() { <-w.limiter.transferLimit diff --git a/cmd/lotus-seed/genesis.go b/cmd/lotus-seed/genesis.go new file mode 100644 index 000000000..187f5b499 --- /dev/null +++ b/cmd/lotus-seed/genesis.go @@ -0,0 +1,142 @@ +package main + +import ( + "encoding/json" + "io/ioutil" + + "github.com/google/uuid" + "github.com/mitchellh/go-homedir" + "golang.org/x/xerrors" + "gopkg.in/urfave/cli.v2" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/specs-actors/actors/abi/big" + + genesis2 "github.com/filecoin-project/lotus/chain/gen/genesis" + "github.com/filecoin-project/lotus/genesis" +) + +var genesisCmd = &cli.Command{ + Name: "genesis", + Description: "manipulate lotus genesis template", + Subcommands: []*cli.Command{ + genesisNewCmd, + genesisAddMinerCmd, + }, +} + +var genesisNewCmd = &cli.Command{ + Name: "new", + Description: "create new genesis template", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "network-name", + }, + }, + Action: func(cctx *cli.Context) error { + if !cctx.Args().Present() { + return xerrors.New("seed genesis new [genesis.json]") + } + + out := genesis.Template{ + Accounts: []genesis.Actor{}, + Miners: []genesis.Miner{}, + NetworkName: cctx.String("network-name"), + } + if out.NetworkName == "" { + out.NetworkName = "localnet-" + uuid.New().String() + } + + genb, err := json.MarshalIndent(&out, "", " ") + if err != nil { + return err + } + + genf, err := homedir.Expand(cctx.Args().First()) + if err != nil { + return err + } + + if err := ioutil.WriteFile(genf, genb, 0644); err != nil { + return err + } + + return nil + }, +} + +var genesisAddMinerCmd = &cli.Command{ + Name: "add-miner", + Description: "add genesis miner", + Flags: []cli.Flag{}, + Action: func(cctx *cli.Context) error { + if cctx.Args().Len() != 2 { + return xerrors.New("seed genesis add-miner [genesis.json] [preseal.json]") + } + + genf, err := homedir.Expand(cctx.Args().First()) + if err != nil { + return err + } + + var template genesis.Template + genb, err := ioutil.ReadFile(genf) + if err != nil { + return xerrors.Errorf("read genesis template: %w", err) + } + + if err := json.Unmarshal(genb, &template); err != nil { + return xerrors.Errorf("unmarshal genesis template: %w", err) + } + + minf, err := homedir.Expand(cctx.Args().Get(1)) + if err != nil { + return xerrors.Errorf("expand preseal file path: %w", err) + } + miners := map[string]genesis.Miner{} + minb, err := ioutil.ReadFile(minf) + if err != nil { + return xerrors.Errorf("read preseal file: %w", err) + } + if err := json.Unmarshal(minb, &miners); err != nil { + return xerrors.Errorf("unmarshal miner info: %w", err) + } + + for mn, miner := range miners { + log.Infof("Adding miner %s to genesis template", mn) + { + id := uint64(genesis2.MinerStart) + uint64(len(template.Miners)) + maddr, err := address.NewFromString(mn) + if err != nil { + return xerrors.Errorf("parsing miner address: %w", err) + } + mid, err := address.IDFromAddress(maddr) + if err != nil { + return xerrors.Errorf("getting miner id from address: %w", err) + } + if mid != id { + return xerrors.Errorf("tried to set miner t0%d as t0%d", mid, id) + } + } + + template.Miners = append(template.Miners, miner) + log.Infof("Giving %s some initial balance", miner.Owner) + template.Accounts = append(template.Accounts, genesis.Actor{ + Type: genesis.TAccount, + Balance: big.NewInt(100000000000000), + Meta: (&genesis.AccountMeta{Owner: miner.Owner}).ActorMeta(), + }) + } + + genb, err = json.MarshalIndent(&template, "", " ") + if err != nil { + return err + } + + if err := ioutil.WriteFile(genf, genb, 0644); err != nil { + return err + } + + return nil + }, +} diff --git a/cmd/lotus-seed/main.go b/cmd/lotus-seed/main.go index 3480619d7..ded25ebf9 100644 --- a/cmd/lotus-seed/main.go +++ b/cmd/lotus-seed/main.go @@ -1,13 +1,13 @@ package main import ( + "encoding/hex" "encoding/json" "fmt" + "io/ioutil" "os" "path/filepath" - sectorbuilder "github.com/filecoin-project/go-sectorbuilder" - "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/namespace" badger "github.com/ipfs/go-ds-badger2" @@ -17,8 +17,12 @@ import ( "gopkg.in/urfave/cli.v2" "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/abi/big" "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/cmd/lotus-seed/seed" "github.com/filecoin-project/lotus/genesis" ) @@ -28,9 +32,9 @@ var log = logging.Logger("lotus-seed") func main() { logging.SetLogLevel("*", "INFO") - log.Info("Starting seed") - local := []*cli.Command{ + genesisCmd, + preSealCmd, aggregateManifestsCmd, aggregateSectorDirsCmd, @@ -52,7 +56,7 @@ func main() { if err := app.Run(os.Args); err != nil { log.Warn(err) - return + os.Exit(1) } } @@ -61,12 +65,12 @@ var preSealCmd = &cli.Command{ Flags: []cli.Flag{ &cli.StringFlag{ Name: "miner-addr", - Value: "t0101", + Value: "t01000", Usage: "specify the future address of your miner", }, &cli.Uint64Flag{ Name: "sector-size", - Value: build.SectorSizes[0], + Value: uint64(build.SectorSizes[0]), Usage: "specify size of sectors to pre-seal", }, &cli.StringFlag{ @@ -84,6 +88,11 @@ var preSealCmd = &cli.Command{ Value: 0, Usage: "how many sector ids to skip when starting to seal", }, + &cli.StringFlag{ + Name: "key", + Value: "", + Usage: "(optional) Key to use for signing / owner/worker addresses", + }, }, Action: func(c *cli.Context) error { sdir := c.String("sectorbuilder-dir") @@ -97,12 +106,25 @@ var preSealCmd = &cli.Command{ return err } - gm, err := seed.PreSeal(maddr, c.Uint64("sector-size"), c.Uint64("sector-offset"), c.Int("num-sectors"), sbroot, []byte(c.String("ticket-preimage"))) + var k *types.KeyInfo + if c.String("key") != "" { + k = new(types.KeyInfo) + kh, err := ioutil.ReadFile(c.String("key")) + if err != nil { + return err + } + kb, err := hex.DecodeString(string(kh)) + if err := json.Unmarshal(kb, k); err != nil { + return err + } + } + + gm, key, err := seed.PreSeal(maddr, abi.SectorSize(c.Uint64("sector-size")), abi.SectorNumber(c.Uint64("sector-offset")), c.Int("num-sectors"), sbroot, []byte(c.String("ticket-preimage")), k) if err != nil { return err } - return seed.WriteGenesisMiner(maddr, sbroot, gm) + return seed.WriteGenesisMiner(maddr, sbroot, gm, key) }, } @@ -110,14 +132,14 @@ var aggregateManifestsCmd = &cli.Command{ Name: "aggregate-manifests", Usage: "aggregate a set of preseal manifests into a single file", Action: func(cctx *cli.Context) error { - var inputs []map[string]genesis.GenesisMiner + var inputs []map[string]genesis.Miner for _, infi := range cctx.Args().Slice() { fi, err := os.Open(infi) if err != nil { return err } defer fi.Close() - var val map[string]genesis.GenesisMiner + var val map[string]genesis.Miner if err := json.NewDecoder(fi).Decode(&val); err != nil { return err } @@ -125,7 +147,7 @@ var aggregateManifestsCmd = &cli.Command{ inputs = append(inputs, val) } - output := make(map[string]genesis.GenesisMiner) + output := make(map[string]genesis.Miner) for _, in := range inputs { for maddr, val := range in { if gm, ok := output[maddr]; ok { @@ -192,7 +214,7 @@ var aggregateSectorDirsCmd = &cli.Command{ } defer agmds.Close() - ssize := cctx.Uint64("sector-size") + ssize := abi.SectorSize(cctx.Uint64("sector-size")) agsb, err := sectorbuilder.New(§orbuilder.Config{ Miner: maddr, @@ -204,8 +226,8 @@ var aggregateSectorDirsCmd = &cli.Command{ return err } - var aggrGenMiner genesis.GenesisMiner - var highestSectorID uint64 + var aggrGenMiner genesis.Miner + var highestSectorID abi.SectorNumber for _, dir := range cctx.Args().Slice() { dir, err := homedir.Expand(dir) if err != nil { @@ -225,7 +247,7 @@ var aggregateSectorDirsCmd = &cli.Command{ return err } - var genmm map[string]genesis.GenesisMiner + var genmm map[string]genesis.Miner if err := json.NewDecoder(fi).Decode(&genmm); err != nil { return err } @@ -270,11 +292,11 @@ var aggregateSectorDirsCmd = &cli.Command{ } } - if err := agsb.SetLastSectorID(highestSectorID); err != nil { + if err := agsb.SetLastSectorNum(highestSectorID); err != nil { return err } - if err := seed.WriteGenesisMiner(maddr, destdir, &aggrGenMiner); err != nil { + if err := seed.WriteGenesisMiner(maddr, destdir, &aggrGenMiner, nil); err != nil { return err } @@ -282,16 +304,18 @@ var aggregateSectorDirsCmd = &cli.Command{ }, } -func mergeGenMiners(a, b genesis.GenesisMiner) genesis.GenesisMiner { +func mergeGenMiners(a, b genesis.Miner) genesis.Miner { if a.SectorSize != b.SectorSize { panic("sector sizes mismatch") } - return genesis.GenesisMiner{ - Owner: a.Owner, - Worker: a.Worker, - SectorSize: a.SectorSize, - Key: a.Key, - Sectors: append(a.Sectors, b.Sectors...), + return genesis.Miner{ + Owner: a.Owner, + Worker: a.Worker, + PeerId: "", + MarketBalance: big.Zero(), + PowerBalance: big.Zero(), + SectorSize: a.SectorSize, + Sectors: append(a.Sectors, b.Sectors...), } } diff --git a/cmd/lotus-seed/seed/seed.go b/cmd/lotus-seed/seed/seed.go index 57fbd9e19..247454ac4 100644 --- a/cmd/lotus-seed/seed/seed.go +++ b/cmd/lotus-seed/seed/seed.go @@ -4,22 +4,29 @@ import ( "context" "crypto/rand" "crypto/sha256" + "encoding/hex" "encoding/json" "fmt" "io/ioutil" "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/filecoin-project/specs-actors/actors/crypto" + "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,41 +34,39 @@ 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 abi.SectorNumber, sectors int, sbroot string, preimage []byte, key *types.KeyInfo) (*genesis.Miner, *types.KeyInfo, error) { cfg := §orbuilder.Config{ - Miner: maddr, - SectorSize: ssize, - FallbackLastID: offset, - Paths: sectorbuilder.SimplePath(sbroot), - WorkerThreads: 2, + Miner: maddr, + SectorSize: ssize, + FallbackLastNum: offset, + Paths: sectorbuilder.SimplePath(sbroot), + WorkerThreads: 2, } if err := os.MkdirAll(sbroot, 0775); err != nil { - return nil, err + return nil, nil, err } mds, err := badger.NewDatastore(filepath.Join(sbroot, "badger"), nil) if err != nil { - return nil, err + return nil, nil, err } sb, err := sectorbuilder.New(cfg, namespace.Wrap(mds, datastore.NewKey("/sectorbuilder"))) if err != nil { - return nil, err + return nil, nil, err } - size := sectorbuilder.UserBytesForSectorSize(ssize) - var sealedSectors []*genesis.PreSeal for i := 0; i < sectors; i++ { - sid, err := sb.AcquireSectorId() + sid, err := sb.AcquireSectorNumber() if err != nil { - return nil, err + return nil, 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 + return nil, nil, err } trand := sha256.Sum256(preimage) @@ -69,15 +74,15 @@ func PreSeal(maddr address.Address, ssize uint64, offset uint64, sectors int, sb TicketBytes: trand, } - fmt.Printf("sector-id: %d, piece info: %v", sid, pi) + fmt.Printf("sector-id: %d, piece info: %v\n", sid, pi) pco, err := sb.SealPreCommit(context.TODO(), sid, ticket, []sectorbuilder.PublicPieceInfo{pi}) if err != nil { - return nil, xerrors.Errorf("commit: %w", err) + return nil, nil, xerrors.Errorf("commit: %w", err) } if err := sb.TrimCache(context.TODO(), sid); err != nil { - return nil, xerrors.Errorf("trim cache: %w", err) + return nil, nil, xerrors.Errorf("trim cache: %w", err) } log.Warn("PreCommitOutput: ", sid, pco) @@ -88,35 +93,41 @@ func PreSeal(maddr address.Address, ssize uint64, offset uint64, sectors int, sb }) } - minerAddr, err := wallet.GenerateKey(types.KTBLS) - if err != nil { - return nil, err + var minerAddr *wallet.Key + if key != nil { + minerAddr, err = wallet.NewKey(*key) + if err != nil { + return nil, nil, err + } + } else { + minerAddr, err = wallet.GenerateKey(crypto.SigTypeBLS) + if err != nil { + return nil, nil, err + } } - miner := &genesis.GenesisMiner{ - Owner: minerAddr.Address, - Worker: minerAddr.Address, - - SectorSize: ssize, - - Sectors: sealedSectors, - - Key: minerAddr.KeyInfo, + miner := &genesis.Miner{ + Owner: minerAddr.Address, + Worker: minerAddr.Address, + MarketBalance: big.Zero(), + PowerBalance: big.Zero(), + SectorSize: ssize, + Sectors: sealedSectors, } if err := createDeals(miner, minerAddr, maddr, ssize); err != nil { - return nil, xerrors.Errorf("creating deals: %w", err) + return nil, nil, xerrors.Errorf("creating deals: %w", err) } if err := mds.Close(); err != nil { - return nil, xerrors.Errorf("closing datastore: %w", err) + return nil, nil, xerrors.Errorf("closing datastore: %w", err) } - return miner, nil + return miner, &minerAddr.KeyInfo, nil } -func WriteGenesisMiner(maddr address.Address, sbroot string, gm *genesis.GenesisMiner) error { - output := map[string]genesis.GenesisMiner{ +func WriteGenesisMiner(maddr address.Address, sbroot string, gm *genesis.Miner, key *types.KeyInfo) error { + output := map[string]genesis.Miner{ maddr.String(): *gm, } @@ -125,32 +136,54 @@ func WriteGenesisMiner(maddr address.Address, sbroot string, gm *genesis.Genesis return err } + log.Infof("Writing preseal manifest to %s", filepath.Join(sbroot, "pre-seal-"+maddr.String()+".json")) + if err := ioutil.WriteFile(filepath.Join(sbroot, "pre-seal-"+maddr.String()+".json"), out, 0664); err != nil { return err } + if key != nil { + b, err := json.Marshal(key) + if err != nil { + return err + } + + // TODO: allow providing key + if err := ioutil.WriteFile(filepath.Join(sbroot, "pre-seal-"+maddr.String()+".key"), []byte(hex.EncodeToString(b)), 0664); err != nil { + return err + } + } + 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.Miner, 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: 0, + EndEpoch: 9001, + StoragePricePerEpoch: big.Zero(), + ProviderCollateral: big.Zero(), + ClientCollateral: big.Zero(), } sector.Deal = *proposal diff --git a/cmd/lotus-storage-miner/info.go b/cmd/lotus-storage-miner/info.go index 6cbc3ee41..711234529 100644 --- a/cmd/lotus-storage-miner/info.go +++ b/cmd/lotus-storage-miner/info.go @@ -43,7 +43,7 @@ var infoCmd = &cli.Command{ return err } - fmt.Printf("Sector Size: %s\n", types.NewInt(sizeByte).SizeStr()) + fmt.Printf("Sector Size: %s\n", types.SizeStr(types.NewInt(uint64(sizeByte)))) pow, err := api.StateMinerPower(ctx, maddr, types.EmptyTSK) if err != nil { @@ -51,7 +51,7 @@ var infoCmd = &cli.Command{ } percI := types.BigDiv(types.BigMul(pow.MinerPower, types.NewInt(1000000)), pow.TotalPower) - fmt.Printf("Power: %s / %s (%0.4f%%)\n", pow.MinerPower.SizeStr(), pow.TotalPower.SizeStr(), float64(percI.Int64())/10000) + fmt.Printf("Power: %s / %s (%0.4f%%)\n", types.SizeStr(pow.MinerPower), types.SizeStr(pow.TotalPower), float64(percI.Int64())/10000) secCounts, err := api.StateMinerSectorCount(ctx, maddr, types.EmptyTSK) if err != nil { @@ -62,13 +62,13 @@ var infoCmd = &cli.Command{ return err } - fmt.Printf("\tCommitted: %s\n", types.BigMul(types.NewInt(secCounts.Sset), types.NewInt(sizeByte)).SizeStr()) + fmt.Printf("\tCommitted: %s\n", types.SizeStr(types.BigMul(types.NewInt(secCounts.Sset), types.NewInt(uint64(sizeByte))))) if len(faults) == 0 { - fmt.Printf("\tProving: %s\n", types.BigMul(types.NewInt(secCounts.Pset), types.NewInt(sizeByte)).SizeStr()) + fmt.Printf("\tProving: %s\n", types.SizeStr(types.BigMul(types.NewInt(secCounts.Pset), types.NewInt(uint64(sizeByte))))) } else { fmt.Printf("\tProving: %s (%s Faulty, %.2f%%)\n", - types.BigMul(types.NewInt(secCounts.Pset-uint64(len(faults))), types.NewInt(sizeByte)).SizeStr(), - types.BigMul(types.NewInt(uint64(len(faults))), types.NewInt(sizeByte)).SizeStr(), + types.SizeStr(types.BigMul(types.NewInt(secCounts.Pset-uint64(len(faults))), types.NewInt(uint64(sizeByte)))), + types.SizeStr(types.BigMul(types.NewInt(uint64(len(faults))), types.NewInt(uint64(sizeByte)))), float64(10000*uint64(len(faults))/secCounts.Pset)/100.) } @@ -88,16 +88,16 @@ var infoCmd = &cli.Command{ fmt.Printf("\tCommit: %d\n", wstat.CommitWait) fmt.Printf("\tUnseal: %d\n", wstat.UnsealWait) - eps, err := api.StateMinerElectionPeriodStart(ctx, maddr, types.EmptyTSK) + ps, err := api.StateMinerPostState(ctx, maddr, types.EmptyTSK) if err != nil { return err } - if eps != 0 { + if ps.ProvingPeriodStart != 0 { head, err := api.ChainHead(ctx) if err != nil { return err } - lastEps := int64(head.Height() - eps) + lastEps := int64(head.Height() - ps.ProvingPeriodStart) lastEpsS := lastEps * build.BlockDelay fallback := lastEps + build.FallbackPoStDelay @@ -107,10 +107,10 @@ var infoCmd = &cli.Command{ nextS := next * build.BlockDelay fmt.Printf("PoSt Submissions:\n") - fmt.Printf("\tPrevious: Epoch %d (%d block(s), ~%dm %ds ago)\n", eps, lastEps, lastEpsS/60, lastEpsS%60) - fmt.Printf("\tFallback: Epoch %d (in %d blocks, ~%dm %ds)\n", eps+build.FallbackPoStDelay, fallback, fallbackS/60, fallbackS%60) - fmt.Printf("\tDeadline: Epoch %d (in %d blocks, ~%dm %ds)\n", eps+build.SlashablePowerDelay, next, nextS/60, nextS%60) - + fmt.Printf("\tPrevious: Epoch %d (%d block(s), ~%dm %ds ago)\n", ps.ProvingPeriodStart, lastEps, lastEpsS/60, lastEpsS%60) + fmt.Printf("\tFallback: Epoch %d (in %d blocks, ~%dm %ds)\n", ps.ProvingPeriodStart+build.FallbackPoStDelay, fallback, fallbackS/60, fallbackS%60) + fmt.Printf("\tDeadline: Epoch %d (in %d blocks, ~%dm %ds)\n", ps.ProvingPeriodStart+build.SlashablePowerDelay, next, nextS/60, nextS%60) + fmt.Printf("\tConsecutive Failures: %d\n", ps.NumConsecutiveFailures) } else { fmt.Printf("Proving Period: Not Proving\n") } diff --git a/cmd/lotus-storage-miner/init.go b/cmd/lotus-storage-miner/init.go index e83da3c12..07ea75f61 100644 --- a/cmd/lotus-storage-miner/init.go +++ b/cmd/lotus-storage-miner/init.go @@ -1,11 +1,15 @@ package main import ( - "bytes" "context" "crypto/rand" "encoding/json" "fmt" + "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/filecoin-project/specs-actors/actors/builtin/market" + miner2 "github.com/filecoin-project/specs-actors/actors/builtin/miner" + "github.com/filecoin-project/specs-actors/actors/builtin/power" + crypto2 "github.com/filecoin-project/specs-actors/actors/crypto" "io/ioutil" "os" "path/filepath" @@ -13,10 +17,9 @@ import ( "github.com/filecoin-project/go-address" cborutil "github.com/filecoin-project/go-cbor-util" - "github.com/filecoin-project/go-fil-markets/storagemarket" - deals "github.com/filecoin-project/go-fil-markets/storagemarket/impl" paramfetch "github.com/filecoin-project/go-paramfetch" "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" badger "github.com/ipfs/go-ds-badger2" @@ -32,7 +35,6 @@ import ( "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" "github.com/filecoin-project/lotus/genesis" - "github.com/filecoin-project/lotus/markets/utils" "github.com/filecoin-project/lotus/miner" "github.com/filecoin-project/lotus/node/config" "github.com/filecoin-project/lotus/node/modules" @@ -72,7 +74,7 @@ var initCmd = &cli.Command{ &cli.Uint64Flag{ Name: "sector-size", Usage: "specify sector size to use", - Value: build.SectorSizes[0], + Value: uint64(build.SectorSizes[0]), }, &cli.StringFlag{ Name: "pre-sealed-sectors", @@ -94,7 +96,7 @@ var initCmd = &cli.Command{ Action: func(cctx *cli.Context) error { log.Info("Initializing lotus storage miner") - ssize := cctx.Uint64("sector-size") + ssize := abi.SectorSize(cctx.Uint64("sector-size")) symlink := cctx.Bool("symlink-imported-sectors") if symlink { @@ -102,7 +104,7 @@ var initCmd = &cli.Command{ } log.Info("Checking proof parameters") - if err := paramfetch.GetParams(build.ParametersJson(), ssize); err != nil { + if err := paramfetch.GetParams(build.ParametersJson(), uint64(ssize)); err != nil { return xerrors.Errorf("fetching proof parameters: %w", err) } @@ -236,17 +238,11 @@ func migratePreSealMeta(ctx context.Context, api lapi.FullNode, metadata string, return xerrors.Errorf("reading preseal metadata: %w", err) } - preseals := map[string]genesis.GenesisMiner{} - - if err := json.Unmarshal(b, &preseals); err != nil { + meta := genesis.Miner{} + if err := json.Unmarshal(b, &meta); err != nil { return xerrors.Errorf("unmarshaling preseal metadata: %w", err) } - meta, ok := preseals[maddr.String()] - if !ok { - return xerrors.New("got wrong preseal info") - } - for _, sector := range meta.Sectors { sectorKey := datastore.NewKey(sealing.SectorStorePrefix).ChildString(fmt.Sprint(sector.SectorID)) @@ -260,8 +256,8 @@ func migratePreSealMeta(ctx context.Context, api lapi.FullNode, metadata string, SectorID: sector.SectorID, Pieces: []sealing.Piece{ { - DealID: dealID, - Size: meta.SectorSize, + DealID: &dealID, + Size: abi.PaddedPieceSize(meta.SectorSize).Unpadded(), CommP: sector.CommD[:], }, }, @@ -283,26 +279,20 @@ func migratePreSealMeta(ctx context.Context, api lapi.FullNode, metadata string, return err } - proposalCid, err := sector.Deal.Cid() + /* // TODO: Import deals into market + pnd, err := cborutil.AsIpld(sector.Deal) if err != nil { return err } - dealKey := datastore.NewKey(deals.ProviderDsPrefix).ChildString(proposalCid.String()) + dealKey := datastore.NewKey(deals.ProviderDsPrefix).ChildString(pnd.Cid().String()) - proposal, err := utils.ToSharedStorageDealProposal(§or.Deal) - if err != nil { - return err - } deal := &deals.MinerDeal{ MinerDeal: storagemarket.MinerDeal{ - Proposal: *proposal, - ProposalCid: proposalCid, + ClientDealProposal: sector.Deal, + ProposalCid: pnd.Cid(), State: storagemarket.StorageDealActive, - Ref: proposalCid, // TODO: This is super wrong, but there - // are no params for CommP CIDs, we can't recover unixfs cid easily, - // and this isn't even used after the deal enters Complete state - DealID: dealID, + DealID: sector., }, } @@ -313,13 +303,13 @@ func migratePreSealMeta(ctx context.Context, api lapi.FullNode, metadata string, if err := mds.Put(dealKey, b); err != nil { return err - } + }*/ } return nil } -func findMarketDealID(ctx context.Context, api lapi.FullNode, deal actors.StorageDealProposal) (uint64, error) { +func findMarketDealID(ctx context.Context, api lapi.FullNode, deal market.DealProposal) (abi.DealID, error) { // TODO: find a better way // (this is only used by genesis miners) @@ -329,8 +319,9 @@ func findMarketDealID(ctx context.Context, api lapi.FullNode, deal actors.Storag } for k, v := range deals { - if bytes.Equal(v.PieceRef, deal.PieceRef) { - return strconv.ParseUint(k, 10, 64) + if v.Proposal.PieceCID.Equals(deal.PieceCID) { + id, err := strconv.ParseUint(k, 10, 64) + return abi.DealID(id), err } } @@ -480,26 +471,12 @@ func makeHostKey(lr repo.LockedRepo) (crypto.PrivKey, error) { } func configureStorageMiner(ctx context.Context, api lapi.FullNode, addr address.Address, peerid peer.ID) error { - // This really just needs to be an api call at this point... - recp, err := api.StateCall(ctx, &types.Message{ - To: addr, - From: addr, - Method: actors.MAMethods.GetWorkerAddr, - }, types.EmptyTSK) - if err != nil { - return xerrors.Errorf("failed to get worker address: %w", err) - } - - if recp.ExitCode != 0 { - return xerrors.Errorf("getWorkerAddr returned exit code %d", recp.ExitCode) - } - - waddr, err := address.NewFromBytes(recp.Return) + waddr, err := api.StateMinerWorker(ctx, addr, types.EmptyTSK) if err != nil { return xerrors.Errorf("getWorkerAddr returned bad address: %w", err) } - enc, err := actors.SerializeParams(&actors.UpdatePeerIDParams{PeerID: peerid}) + enc, err := actors.SerializeParams(&miner2.ChangePeerIDParams{NewID: peerid}) if err != nil { return err } @@ -507,7 +484,7 @@ func configureStorageMiner(ctx context.Context, api lapi.FullNode, addr address. msg := &types.Message{ To: addr, From: waddr, - Method: actors.MAMethods.UpdatePeerID, + Method: builtin.MethodsMiner.ChangePeerID, Params: enc, Value: types.NewInt(0), GasPrice: types.NewInt(0), @@ -551,7 +528,7 @@ func createStorageMiner(ctx context.Context, api lapi.FullNode, peerid peer.ID, if cctx.String("worker") != "" { worker, err = address.NewFromString(cctx.String("worker")) } else if cctx.Bool("create-worker-key") { // TODO: Do we need to force this if owner is Secpk? - worker, err = api.WalletNew(ctx, types.KTBLS) + worker, err = api.WalletNew(ctx, crypto2.SigTypeBLS) } // TODO: Transfer some initial funds to worker if err != nil { @@ -563,22 +540,21 @@ func createStorageMiner(ctx context.Context, api lapi.FullNode, peerid peer.ID, return address.Undef, err } - params, err := actors.SerializeParams(&actors.CreateStorageMinerParams{ - Owner: owner, + params, err := actors.SerializeParams(&power.CreateMinerParams{ Worker: worker, - SectorSize: ssize, - PeerID: peerid, + SectorSize: abi.SectorSize(ssize), + Peer: peerid, }) if err != nil { return address.Undef, err } createStorageMinerMsg := &types.Message{ - To: actors.StoragePowerAddress, + To: builtin.StoragePowerActorAddr, From: owner, Value: types.BigAdd(collateral, types.BigDiv(collateral, types.NewInt(100))), - Method: actors.SPAMethods.CreateStorageMiner, + Method: builtin.MethodsPower.CreateMiner, Params: params, GasLimit: types.NewInt(10000000), diff --git a/cmd/lotus-storage-miner/main.go b/cmd/lotus-storage-miner/main.go index ec91a7f4a..addcb9094 100644 --- a/cmd/lotus-storage-miner/main.go +++ b/cmd/lotus-storage-miner/main.go @@ -10,8 +10,8 @@ import ( "github.com/filecoin-project/lotus/build" lcli "github.com/filecoin-project/lotus/cli" "github.com/filecoin-project/lotus/lib/lotuslog" + "github.com/filecoin-project/lotus/lib/tracing" "github.com/filecoin-project/lotus/node/repo" - "github.com/filecoin-project/lotus/tracing" ) var log = logging.Logger("main") diff --git a/cmd/lotus-storage-miner/sectors.go b/cmd/lotus-storage-miner/sectors.go index eebcf8fb2..4e0a6310b 100644 --- a/cmd/lotus-storage-miner/sectors.go +++ b/cmd/lotus-storage-miner/sectors.go @@ -9,6 +9,7 @@ import ( "text/tabwriter" "time" + "github.com/filecoin-project/specs-actors/actors/abi" "golang.org/x/xerrors" "gopkg.in/urfave/cli.v2" @@ -68,7 +69,7 @@ var sectorsStatusCmd = &cli.Command{ return err } - status, err := nodeApi.SectorsStatus(ctx, id) + status, err := nodeApi.SectorsStatus(ctx, abi.SectorNumber(id)) if err != nil { return err } @@ -134,18 +135,18 @@ var sectorsListCmd = &cli.Command{ if err != nil { return err } - provingIDs := make(map[uint64]struct{}, len(pset)) + provingIDs := make(map[abi.SectorNumber]struct{}, len(pset)) for _, info := range pset { - provingIDs[info.SectorID] = struct{}{} + provingIDs[info.ID] = struct{}{} } sset, err := fullApi.StateMinerSectors(ctx, maddr, types.EmptyTSK) if err != nil { return err } - commitedIDs := make(map[uint64]struct{}, len(pset)) + commitedIDs := make(map[abi.SectorNumber]struct{}, len(pset)) for _, info := range sset { - commitedIDs[info.SectorID] = struct{}{} + commitedIDs[info.ID] = struct{}{} } sort.Slice(list, func(i, j int) bool { @@ -240,7 +241,7 @@ var sectorsUpdateCmd = &cli.Command{ } } - return nodeApi.SectorsUpdate(ctx, id, st) + return nodeApi.SectorsUpdate(ctx, abi.SectorNumber(id), st) }, } diff --git a/cmd/lotus/daemon.go b/cmd/lotus/daemon.go index 2cc1fcbdb..82ffdf45e 100644 --- a/cmd/lotus/daemon.go +++ b/cmd/lotus/daemon.go @@ -4,9 +4,13 @@ package main import ( "context" + "encoding/hex" + "encoding/json" + "github.com/filecoin-project/lotus/chain/types" "io/ioutil" "os" "runtime/pprof" + "strings" paramfetch "github.com/filecoin-project/go-paramfetch" "github.com/filecoin-project/go-sectorbuilder" @@ -23,16 +27,16 @@ import ( "github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/vm" + "github.com/filecoin-project/lotus/lib/peermgr" "github.com/filecoin-project/lotus/node" "github.com/filecoin-project/lotus/node/modules" "github.com/filecoin-project/lotus/node/modules/testing" "github.com/filecoin-project/lotus/node/repo" - "github.com/filecoin-project/lotus/peermgr" ) const ( - makeGenFlag = "lotus-make-random-genesis" - preSealedSectorsFlag = "genesis-presealed-sectors" + makeGenFlag = "lotus-make-genesis" + preTemplateFlag = "genesis-template" ) // DaemonCmd is the `go-lotus daemon` command @@ -50,18 +54,18 @@ var DaemonCmd = &cli.Command{ Hidden: true, }, &cli.StringFlag{ - Name: preSealedSectorsFlag, + Name: preTemplateFlag, + Hidden: true, + }, + &cli.StringFlag{ + Name: "import-key", + Usage: "on first run, import a default key from a given file", Hidden: true, }, &cli.StringFlag{ Name: "genesis", Usage: "genesis file to use for first node run", }, - &cli.StringFlag{ - Name: "genesis-timestamp", - Hidden: true, - Usage: "set the timestamp for the genesis block that will be created", - }, &cli.BoolFlag{ Name: "bootstrap", Value: true, @@ -139,10 +143,10 @@ var DaemonCmd = &cli.Command{ genesis = node.Override(new(modules.Genesis), modules.LoadGenesis(genBytes)) } if cctx.String(makeGenFlag) != "" { - if cctx.String(preSealedSectorsFlag) == "" { - return xerrors.Errorf("must also pass file with miner preseal info to `--%s`", preSealedSectorsFlag) + if cctx.String(preTemplateFlag) == "" { + return xerrors.Errorf("must also pass file with genesis template to `--%s`", preTemplateFlag) } - genesis = node.Override(new(modules.Genesis), testing.MakeGenesis(cctx.String(makeGenFlag), cctx.String(preSealedSectorsFlag), cctx.String("genesis-timestamp"))) + genesis = node.Override(new(modules.Genesis), testing.MakeGenesis(cctx.String(makeGenFlag), cctx.String(preTemplateFlag))) } var api api.FullNode @@ -173,6 +177,12 @@ var DaemonCmd = &cli.Command{ return xerrors.Errorf("initializing node: %w", err) } + if cctx.String("import-key") != "" { + if err := importKey(ctx, api, cctx.String("import-key")); err != nil { + log.Errorf("importing key failed: %+v", err) + } + } + // Add lotus version info to prometheus metrics var lotusInfoMetric = promauto.NewGaugeVec(prometheus.GaugeOpts{ Name: "lotus_info", @@ -194,6 +204,40 @@ var DaemonCmd = &cli.Command{ }, } +func importKey(ctx context.Context, api api.FullNode, f string) error { + f, err := homedir.Expand(f) + if err != nil { + return err + } + + hexdata, err := ioutil.ReadFile(f) + if err != nil { + return err + } + + data, err := hex.DecodeString(strings.TrimSpace(string(hexdata))) + if err != nil { + return err + } + + var ki types.KeyInfo + if err := json.Unmarshal(data, &ki); err != nil { + return err + } + + addr, err := api.WalletImport(ctx, &ki) + if err != nil { + return err + } + + if err := api.WalletSetDefault(ctx, addr); err != nil { + return err + } + + log.Info("successfully imported key for %s", addr) + return nil +} + func ImportChain(r repo.Repo, fname string) error { fi, err := os.Open(fname) if err != nil { diff --git a/cmd/lotus/debug_advance.go b/cmd/lotus/debug_advance.go index 37590f26f..dbe45ce2f 100644 --- a/cmd/lotus/debug_advance.go +++ b/cmd/lotus/debug_advance.go @@ -5,11 +5,11 @@ package main import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" "github.com/filecoin-project/lotus/miner" + "github.com/filecoin-project/specs-actors/actors/crypto" "golang.org/x/xerrors" "gopkg.in/urfave/cli.v2" @@ -44,28 +44,20 @@ func init() { msgs = msgs[:build.BlockMessageLimit] } - addr, _ := address.NewIDAddress(101) + addr, _ := address.NewIDAddress(1000) var ticket *types.Ticket { - vrfBase := head.MinTicket().VRFProof - ret, err := api.StateCall(ctx, &types.Message{ - From: addr, - To: addr, - Method: actors.MAMethods.GetWorkerAddr, - }, head.Key()) + w, err := api.StateMinerWorker(ctx, addr, head.Key()) if err != nil { - return xerrors.Errorf("failed to get miner worker addr: %w", err) + return xerrors.Errorf("StateMinerWorker: %w", err) } - if ret.ExitCode != 0 { - return xerrors.Errorf("failed to get miner worker addr (exit code %d)", ret.ExitCode) + rand, err := api.ChainGetRandomness(ctx, head.Key(), crypto.DomainSeparationTag_TicketProduction, head.Height(), addr.Bytes()) + if err != nil { + return xerrors.Errorf("failed to get randomness: %w", err) } - w, err := address.NewFromBytes(ret.Return) - if err != nil { - return xerrors.Errorf("GetWorkerAddr returned malformed address: %w", err) - } - t, err := gen.ComputeVRF(ctx, api.WalletSign, w, addr, gen.DSepTicket, vrfBase) + t, err := gen.ComputeVRF(ctx, api.WalletSign, w, rand) if err != nil { return xerrors.Errorf("compute vrf failed: %w", err) } @@ -86,7 +78,7 @@ func init() { } { - r, err := api.ChainGetRandomness(ctx, head.Key(), int64(head.Height()+1)-build.EcRandomnessLookback) + r, err := api.ChainGetRandomness(ctx, head.Key(), crypto.DomainSeparationTag_ElectionPoStChallengeSeed, (head.Height()+1)-build.EcRandomnessLookback, addr.Bytes()) if err != nil { return xerrors.Errorf("chain get randomness: %w", err) } @@ -95,7 +87,7 @@ func init() { return xerrors.Errorf("failed to get miner worker: %w", err) } - vrfout, err := gen.ComputeVRF(ctx, api.WalletSign, mworker, addr, gen.DSepElectionPost, r) + vrfout, err := gen.ComputeVRF(ctx, api.WalletSign, mworker, r) if err != nil { return xerrors.Errorf("failed to compute VRF: %w", err) } diff --git a/cmd/lotus/main.go b/cmd/lotus/main.go index e040d397e..da003fb1c 100644 --- a/cmd/lotus/main.go +++ b/cmd/lotus/main.go @@ -10,8 +10,8 @@ import ( "github.com/filecoin-project/lotus/build" lcli "github.com/filecoin-project/lotus/cli" "github.com/filecoin-project/lotus/lib/lotuslog" + "github.com/filecoin-project/lotus/lib/tracing" "github.com/filecoin-project/lotus/node/repo" - "github.com/filecoin-project/lotus/tracing" ) var AdvanceBlockCmd *cli.Command diff --git a/documentation/en/local-dev-net.md b/documentation/en/local-dev-net.md index 4418daaf6..2bf2b35c3 100644 --- a/documentation/en/local-dev-net.md +++ b/documentation/en/local-dev-net.md @@ -20,13 +20,21 @@ Pre-seal some sectors: Create the genesis block and start up the first node: ```sh -./lotus daemon --lotus-make-random-genesis=dev.gen --genesis-presealed-sectors=~/.genesis-sectors/pre-seal-t0101.json --bootstrap=false +./lotus-seed genesis new localnet.json +./lotus-seed genesis add-miner localnet.json ~/.genesis-sectors/pre-seal-t01000.json +./lotus daemon --lotus-make-genesis=dev.gen --genesis-template=localnet.json --bootstrap=false +``` + +Then, in another console, import the genesis miner key: + +```sh +./lotus wallet import ~/.genesis-sectors/pre-seal-t01000.key ``` Set up the genesis miner: ```sh -./lotus-storage-miner init --genesis-miner --actor=t0101 --sector-size=1024 --pre-sealed-sectors=~/.genesis-sectors --pre-sealed-metadata=~/.genesis-sectors/pre-seal-t0101.json --nosync +./lotus-storage-miner init --genesis-miner --actor=t01000 --sector-size=1024 --pre-sealed-sectors=~/.genesis-sectors --pre-sealed-metadata=~/.genesis-sectors/pre-seal-t0101.json --nosync ``` Now, finally, start up the miner: diff --git a/extern/filecoin-ffi b/extern/filecoin-ffi index 58761d3dc..cb6019e08 160000 --- a/extern/filecoin-ffi +++ b/extern/filecoin-ffi @@ -1 +1 @@ -Subproject commit 58761d3dca0f3617023240eb8b7f8b324db75b2a +Subproject commit cb6019e085428c845dc29c95b9e70569019e619f diff --git a/gen/main.go b/gen/main.go index 997d2704f..f8e830852 100644 --- a/gen/main.go +++ b/gen/main.go @@ -7,12 +7,11 @@ import ( gen "github.com/whyrusleeping/cbor-gen" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/blocksync" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/lib/statemachine" "github.com/filecoin-project/lotus/node/hello" - "github.com/filecoin-project/lotus/paych" + "github.com/filecoin-project/lotus/paychmgr" "github.com/filecoin-project/lotus/storage/sealing" ) @@ -25,14 +24,9 @@ func main() { types.Message{}, types.SignedMessage{}, types.MsgMeta{}, - types.SignedVoucher{}, - types.ModVerifyParams{}, - types.Merge{}, types.Actor{}, types.MessageReceipt{}, types.BlockMsg{}, - types.SignedStorageAsk{}, - types.StorageAsk{}, types.ExpTipSet{}, ) if err != nil { @@ -40,9 +34,9 @@ func main() { os.Exit(1) } - err = gen.WriteTupleEncodersToFile("./paych/cbor_gen.go", "paych", - paych.VoucherInfo{}, - paych.ChannelInfo{}, + err = gen.WriteMapEncodersToFile("./paychmgr/cbor_gen.go", "paychmgr", + paychmgr.VoucherInfo{}, + paychmgr.ChannelInfo{}, ) if err != nil { fmt.Println(err) @@ -78,51 +72,6 @@ func main() { os.Exit(1) } - err = gen.WriteTupleEncodersToFile("./chain/actors/cbor_gen.go", "actors", - actors.InitActorState{}, - actors.ExecParams{}, - actors.AccountActorState{}, - actors.StorageMinerActorState{}, - actors.StorageMinerConstructorParams{}, - actors.SectorPreCommitInfo{}, - actors.PreCommittedSector{}, - actors.MinerInfo{}, - actors.SubmitFallbackPoStParams{}, - actors.PaymentVerifyParams{}, - actors.UpdatePeerIDParams{}, - actors.DeclareFaultsParams{}, - actors.PaymentChannelActorState{}, - actors.PCAConstructorParams{}, - actors.LaneState{}, - actors.PCAUpdateChannelStateParams{}, - actors.PaymentInfo{}, - actors.StoragePowerState{}, - actors.CreateStorageMinerParams{}, - actors.IsValidMinerParam{}, - actors.PowerLookupParams{}, - actors.UpdateStorageParams{}, - actors.ArbitrateConsensusFaultParams{}, - actors.PledgeCollateralParams{}, - actors.MinerSlashConsensusFault{}, - actors.StorageParticipantBalance{}, - actors.StorageMarketState{}, - actors.WithdrawBalanceParams{}, - actors.StorageDealProposal{}, - actors.PublishStorageDealsParams{}, - actors.PublishStorageDealResponse{}, - actors.ActivateStorageDealsParams{}, - actors.ProcessStorageDealsPaymentParams{}, - actors.OnChainDeal{}, - actors.ComputeDataCommitmentParams{}, - actors.SectorProveCommitInfo{}, - actors.CheckMinerParams{}, - actors.CronActorState{}, - ) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - err = gen.WriteMapEncodersToFile("./storage/sealing/cbor_gen.go", "sealing", sealing.SealTicket{}, sealing.SealSeed{}, diff --git a/genesis/types.go b/genesis/types.go index 27eabea4a..f699a28b0 100644 --- a/genesis/types.go +++ b/genesis/types.go @@ -1,25 +1,68 @@ package genesis import ( + "encoding/json" + "github.com/filecoin-project/go-address" - "github.com/filecoin-project/lotus/chain/actors" - "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin/market" + "github.com/libp2p/go-libp2p-core/peer" +) + +type ActorType string + +const ( + TAccount ActorType = "account" + TMultisig ActorType = "multisig" ) type PreSeal struct { CommR [32]byte CommD [32]byte - SectorID uint64 - Deal actors.StorageDealProposal + SectorID abi.SectorNumber + Deal market.DealProposal } -type GenesisMiner struct { +type Miner struct { Owner address.Address Worker address.Address + PeerId peer.ID `json:",omitempty"` - SectorSize uint64 + MarketBalance abi.TokenAmount + PowerBalance abi.TokenAmount + + SectorSize abi.SectorSize Sectors []*PreSeal - - Key types.KeyInfo // TODO: separate file +} + +type AccountMeta struct { + Owner address.Address // bls / secpk +} + +func (am *AccountMeta) ActorMeta() json.RawMessage { + out, err := json.Marshal(am) + if err != nil { + panic(err) + } + return out +} + +type MultisigMeta struct { + // TODO +} + +type Actor struct { + Type ActorType + Balance abi.TokenAmount + + Meta json.RawMessage +} + +type Template struct { + Accounts []Actor + Miners []Miner + + NetworkName string + Timestamp uint64 `json:",omitempty"` } diff --git a/go.mod b/go.mod index 0f0a94d44..ccfe3a99a 100644 --- a/go.mod +++ b/go.mod @@ -12,18 +12,21 @@ require ( github.com/docker/go-units v0.4.0 github.com/filecoin-project/chain-validation v0.0.3 github.com/filecoin-project/filecoin-ffi v0.0.0-20191219131535-bb699517a590 - github.com/filecoin-project/go-address v0.0.0-20200107215422-da8eea2842b5 + github.com/filecoin-project/go-address v0.0.2-0.20200218010043-eb9bb40ed5be github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200131012142-05d80eeccc5e 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-markets v0.0.0-20200206024724-973498b060e3 + github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5 + github.com/filecoin-project/go-fil-markets v0.0.0-20200223154807-f7afd8e927f9 + github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6 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-sectorbuilder v0.0.2-0.20200210220012-eb75ec747d6b 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-20200223194852-39976038b18d github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 github.com/go-ole/go-ole v1.2.4 // indirect + github.com/google/uuid v1.1.1 github.com/gorilla/mux v1.7.3 github.com/gorilla/websocket v1.4.1 github.com/hashicorp/go-multierror v1.0.0 @@ -32,8 +35,8 @@ require ( github.com/ipfs/go-bitswap v0.1.8 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-car v0.0.3-0.20200221191037-3762780fa84e + 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,15 +82,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/client_golang v0.9.3-0.20190127221311-3c4408c8b829 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-20200206220010-03c9665e2a66 + github.com/whyrusleeping/cbor-gen v0.0.0-20200222160900-51052a1e8191 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 diff --git a/go.sum b/go.sum index 800ad910c..083504ec4 100644 --- a/go.sum +++ b/go.sum @@ -100,10 +100,10 @@ github.com/fatih/color v1.8.0/go.mod h1:3l45GVGkyrnYNl9HoIjnp2NnNWvh6hLAqD8yTfGj github.com/fd/go-nat v1.0.0/go.mod h1:BTBu/CKvMmOMUPkKVef1pngt2WFH/lg7E6yQnulfp6E= github.com/filecoin-project/chain-validation v0.0.3 h1:luT/8kJ0WdMIqQ9Bm31W4JkuYCW0wUb26AvnD4WK59M= github.com/filecoin-project/chain-validation v0.0.3/go.mod h1:NCEGFjcWRjb8akWFSOXvU6n2efkWIqAeOKU6o5WBGQw= -github.com/filecoin-project/go-address v0.0.0-20191219011437-af739c490b4f h1:L2jaVU8TvWTx7iZPhlYvUE8vkoOnj778XuKavz8W36g= -github.com/filecoin-project/go-address v0.0.0-20191219011437-af739c490b4f/go.mod h1:rCbpXPva2NKF9/J4X6sr7hbKBgQCxyFtRj7KOZqoIms= github.com/filecoin-project/go-address v0.0.0-20200107215422-da8eea2842b5 h1:/MmWluswvDIbuPvBct4q6HeQgVm62O2DzWYTB38kt4A= github.com/filecoin-project/go-address v0.0.0-20200107215422-da8eea2842b5/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0= +github.com/filecoin-project/go-address v0.0.2-0.20200218010043-eb9bb40ed5be h1:TooKBwR/g8jG0hZ3lqe9S5sy2vTUcLOZLlz3M5wGn2E= +github.com/filecoin-project/go-address v0.0.2-0.20200218010043-eb9bb40ed5be/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0= github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200131012142-05d80eeccc5e h1:IOoff6yAZSJ5zHCPY2jzGNwQYQU6ygsRVe/cSnJrY+o= github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200131012142-05d80eeccc5e/go.mod h1:boRtQhzmxNocrMxOXo1NYn4oUc1NGvR8tEa79wApNXg= github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 h1:av5fw6wmm58FYMgJeoB/lK9XXrgdugYiTqkdxjTy9k8= @@ -112,20 +112,24 @@ 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-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= -github.com/filecoin-project/go-padreader v0.0.0-20200130212543-892867c4edf9/go.mod h1:r0gyD7zvnqyRKSY8stil5G/LF0kXFgNzW/yR4vjga+Y= +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-20200223154807-f7afd8e927f9 h1:uFS5r3K3AgIuR7cGBYY8k+vgwn/UXhin9NR2yCXVe7o= +github.com/filecoin-project/go-fil-markets v0.0.0-20200223154807-f7afd8e927f9/go.mod h1:ftsiBbjLjNLAZ52FVDigkdCp73ltdcvAzAXav6drSLA= +github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6 h1:92PET+sx1Hb4W/8CgFwGuxaKbttwY+UNspYZTvXY0vs= +github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6/go.mod h1:0HgYnrkeSU4lu1p+LEOeDpFsNBssa0OGGriWdA4hvaE= github.com/filecoin-project/go-paramfetch v0.0.0-20200102181131-b20d579f2878/go.mod h1:40kI2Gv16mwcRsHptI3OAV4nlOEU7wVDc4RgMylNFjU= github.com/filecoin-project/go-paramfetch v0.0.1 h1:gV7bs5YaqlgpGFMiLxInGK2L1FyCXUE0rimz4L7ghoE= github.com/filecoin-project/go-paramfetch v0.0.1/go.mod h1:fZzmf4tftbwf9S37XRifoJlz7nCjRdIrMGLR07dKLCc= -github.com/filecoin-project/go-sectorbuilder v0.0.1/go.mod h1:3OZ4E3B2OuwhJjtxR4r7hPU9bCfB+A+hm4alLEsaeDc= -github.com/filecoin-project/go-sectorbuilder v0.0.2-0.20200203173614-42d67726bb62 h1:/+xdjMkIdiRs6vA2lJU56iqtEcl9BQgYXi8b2KuuYCg= -github.com/filecoin-project/go-sectorbuilder v0.0.2-0.20200203173614-42d67726bb62/go.mod h1:jNGVCDihkMFnraYVLH1xl4ceZQVxx/u4dOORrTKeRi0= +github.com/filecoin-project/go-sectorbuilder v0.0.2-0.20200210220012-eb75ec747d6b h1:ds4TQay8wuV+2ucC6ENAeSYQDdl9CWYXnX0gvxzGKHg= +github.com/filecoin-project/go-sectorbuilder v0.0.2-0.20200210220012-eb75ec747d6b/go.mod h1:qsuPYsbKTHH2phNk81aUF9VJIilUxFrnxxnryJh4FOM= github.com/filecoin-project/go-statestore v0.1.0 h1:t56reH59843TwXHkMcwyuayStBIiWBRilQjQ+5IiwdQ= 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-20200210130641-2d1fbd8672cf h1:fbxBG12yrxilPFV1EG2lYqpUyAlRZWkvtqjk2svSeXY= +github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= +github.com/filecoin-project/specs-actors v0.0.0-20200220011005-b2a2fbf40362/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= +github.com/filecoin-project/specs-actors v0.0.0-20200223194852-39976038b18d h1:vukVHqbLQnXc+ZfhK+Cor3kaQx9SQbSZISqSeGjhYcE= +github.com/filecoin-project/specs-actors v0.0.0-20200223194852-39976038b18d/go.mod h1:0HAWYrvajFHDgRaKbF0rl+IybVLZL5z4gQ8koCMPhoU= 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= @@ -224,12 +228,16 @@ github.com/ipfs/go-blockservice v0.1.3-0.20190908200855-f22eea50656c h1:lN5IQA07 github.com/ipfs/go-blockservice v0.1.3-0.20190908200855-f22eea50656c/go.mod h1:t+411r7psEUhLueM8C7aPA7cxCclv4O3VsUVxt9kz2I= github.com/ipfs/go-car v0.0.3-0.20200131220434-3f68f6ebd093 h1:mYq7vJKGUzxIkkYfqXfO0uEO8gOmV9F38Tcpvi/p8P8= github.com/ipfs/go-car v0.0.3-0.20200131220434-3f68f6ebd093/go.mod h1:rEkw0S1sHd5kHL3rUSGEhwNanYqTwwNhjtpp0rwjrr4= +github.com/ipfs/go-car v0.0.3-0.20200221191037-3762780fa84e h1:+wPt/tQHMOl00ekuf+5+ekWpyGQ6JOnF9vzEXjW7LtA= +github.com/ipfs/go-car v0.0.3-0.20200221191037-3762780fa84e/go.mod h1:rEkw0S1sHd5kHL3rUSGEhwNanYqTwwNhjtpp0rwjrr4= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= 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= @@ -384,11 +392,9 @@ github.com/libp2p/go-eventbus v0.1.0/go.mod h1:vROgu5cs5T7cv7POWlWxBaVLxfSegC5UG github.com/libp2p/go-flow-metrics v0.0.1 h1:0gxuFd2GuK7IIP5pKljLwps6TvcuYgvG7Atqi3INF5s= github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= github.com/libp2p/go-flow-metrics v0.0.3 h1:8tAs/hSdNvUiLgtlSy3mxwxWP4I9y/jlkPFT7epKdeM= -github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= -github.com/libp2p/go-flow-metrics v0.0.2 h1:U5TvqfoyR6GVRM+bC15Ux1ltar1kbj6Zw6xOVR02CZs= -github.com/libp2p/go-flow-metrics v0.0.2/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.0.3 h1:8tAs/hSdNvUiLgtlSy3mxwxWP4I9y/jlkPFT7epKdeM= github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= +github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-libp2p v0.0.30/go.mod h1:XWT8FGHlhptAv1+3V/+J5mEpzyui/5bvFsNuWYs611A= github.com/libp2p/go-libp2p v0.1.0/go.mod h1:6D/2OBauqLUoqcADOJpn9WbKqvaM07tDw68qHM0BxUM= github.com/libp2p/go-libp2p v0.1.1/go.mod h1:I00BRo1UuUSdpuc8Q2mN7yDF/oTUTRAX6JWpTiK9Rp8= @@ -423,11 +429,9 @@ github.com/libp2p/go-libp2p-core v0.2.2/go.mod h1:8fcwTbsG2B+lTgRJ1ICZtiM5GWCWZV github.com/libp2p/go-libp2p-core v0.2.4 h1:Et6ykkTwI6PU44tr8qUF9k43vP0aduMNniShAbUJJw8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= github.com/libp2p/go-libp2p-core v0.3.0 h1:F7PqduvrztDtFsAa/bcheQ3azmNo+Nq7m8hQY5GiUW8= -github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw= -github.com/libp2p/go-libp2p-core v0.2.5 h1:iP1PIiIrlRrGbE1fYq2918yBc5NlCH3pFuIPSWU9hds= -github.com/libp2p/go-libp2p-core v0.2.5/go.mod h1:6+5zJmKhsf7yHn1RbmYDu08qDUpIUxGdqHuEZckmZOA= github.com/libp2p/go-libp2p-core v0.3.0 h1:F7PqduvrztDtFsAa/bcheQ3azmNo+Nq7m8hQY5GiUW8= github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw= +github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw= github.com/libp2p/go-libp2p-crypto v0.0.1/go.mod h1:yJkNyDmO341d5wwXxDUGO0LykUVT72ImHNUqh5D/dBE= github.com/libp2p/go-libp2p-crypto v0.0.2/go.mod h1:eETI5OUfBnvARGOHrJz2eWNyTUxEGZnBxMcbUjfIj4I= github.com/libp2p/go-libp2p-crypto v0.1.0 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ= @@ -640,6 +644,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= @@ -649,6 +655,8 @@ github.com/multiformats/go-multistream v0.1.1/go.mod h1:KmHZ40hzVxiaiwlj3MEbYgK9 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= @@ -699,6 +707,7 @@ github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1 h1:/K3IL0Z1quvmJ7X0A1AwNEK7CRkVK3YwfOU/QAL4WGg= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rogpeppe/go-internal v1.3.0 h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= @@ -763,7 +772,11 @@ github.com/whyrusleeping/cbor-gen v0.0.0-20191216205031-b047b6acb3c0/go.mod h1:x 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 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/cbor-gen v0.0.0-20200206220010-03c9665e2a66/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= +github.com/whyrusleeping/cbor-gen v0.0.0-20200222160900-51052a1e8191 h1:TeuxLwKwQy612jEhfVhGJTqLsM2EwMi1eJE052ug+NY= +github.com/whyrusleeping/cbor-gen v0.0.0-20200222160900-51052a1e8191/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/lib/padreader/padreader.go b/lib/padreader/padreader.go deleted file mode 100644 index 179ae305b..000000000 --- a/lib/padreader/padreader.go +++ /dev/null @@ -1,38 +0,0 @@ -package padreader - -import ( - "io" - "math/bits" - - sectorbuilder "github.com/filecoin-project/filecoin-ffi" -) - -func PaddedSize(size uint64) uint64 { - logv := 64 - bits.LeadingZeros64(size) - - sectSize := uint64(1 << logv) - bound := sectorbuilder.GetMaxUserBytesPerStagedSector(sectSize) - if size <= bound { - return bound - } - - return sectorbuilder.GetMaxUserBytesPerStagedSector(1 << (logv + 1)) -} - -type nullReader struct{} - -func (nr nullReader) Read(b []byte) (int, error) { - for i := range b { - b[i] = 0 - } - return len(b), nil -} - -func New(r io.Reader, size uint64) (io.Reader, uint64) { - padSize := PaddedSize(size) - - return io.MultiReader( - io.LimitReader(r, int64(size)), - io.LimitReader(nullReader{}, int64(padSize-size)), - ), padSize -} diff --git a/lib/padreader/padreader_test.go b/lib/padreader/padreader_test.go deleted file mode 100644 index 712317e11..000000000 --- a/lib/padreader/padreader_test.go +++ /dev/null @@ -1,19 +0,0 @@ -package padreader - -import ( - "testing" - - "gotest.tools/assert" -) - -func TestComputePaddedSize(t *testing.T) { - assert.Equal(t, uint64(1040384), PaddedSize(1000000)) - - assert.Equal(t, uint64(1016), PaddedSize(548)) - assert.Equal(t, uint64(1016), PaddedSize(1015)) - assert.Equal(t, uint64(1016), PaddedSize(1016)) - assert.Equal(t, uint64(2032), PaddedSize(1017)) - - assert.Equal(t, uint64(2032), PaddedSize(1024)) - assert.Equal(t, uint64(4064), PaddedSize(2048)) -} diff --git a/peermgr/peermgr.go b/lib/peermgr/peermgr.go similarity index 100% rename from peermgr/peermgr.go rename to lib/peermgr/peermgr.go diff --git a/lib/sigs/bls/init.go b/lib/sigs/bls/init.go index 1c22202c8..fe916c446 100644 --- a/lib/sigs/bls/init.go +++ b/lib/sigs/bls/init.go @@ -3,9 +3,11 @@ package bls import ( "fmt" - ffi "github.com/filecoin-project/filecoin-ffi" "github.com/filecoin-project/go-address" - "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/specs-actors/actors/crypto" + + ffi "github.com/filecoin-project/filecoin-ffi" + "github.com/filecoin-project/lotus/lib/sigs" ) @@ -48,5 +50,5 @@ func (blsSigner) Verify(sig []byte, a address.Address, msg []byte) error { } func init() { - sigs.RegisterSignature(types.KTBLS, blsSigner{}) + sigs.RegisterSignature(crypto.SigTypeBLS, blsSigner{}) } diff --git a/lib/sigs/secp/init.go b/lib/sigs/secp/init.go index 84680ac81..1285b19b6 100644 --- a/lib/sigs/secp/init.go +++ b/lib/sigs/secp/init.go @@ -5,9 +5,10 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-crypto" - "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/lib/sigs" + crypto2 "github.com/filecoin-project/specs-actors/actors/crypto" "github.com/minio/blake2b-simd" + + "github.com/filecoin-project/lotus/lib/sigs" ) type secpSigner struct{} @@ -54,5 +55,5 @@ func (secpSigner) Verify(sig []byte, a address.Address, msg []byte) error { } func init() { - sigs.RegisterSignature(types.KTSecp256k1, secpSigner{}) + sigs.RegisterSignature(crypto2.SigTypeSecp256k1, secpSigner{}) } diff --git a/lib/sigs/sigs.go b/lib/sigs/sigs.go index 9d1bc4b6d..5b304542d 100644 --- a/lib/sigs/sigs.go +++ b/lib/sigs/sigs.go @@ -5,31 +5,33 @@ import ( "fmt" "github.com/filecoin-project/go-address" - "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/specs-actors/actors/crypto" "go.opencensus.io/trace" "golang.org/x/xerrors" + + "github.com/filecoin-project/lotus/chain/types" ) // Sign takes in signature type, private key and message. Returns a signature for that message. // Valid sigTypes are: "secp256k1" and "bls" -func Sign(sigType string, privkey []byte, msg []byte) (*types.Signature, error) { +func Sign(sigType crypto.SigType, privkey []byte, msg []byte) (*crypto.Signature, error) { sv, ok := sigs[sigType] if !ok { - return nil, fmt.Errorf("cannot sign message with signature of unsupported type: %s", sigType) + return nil, fmt.Errorf("cannot sign message with signature of unsupported type: %v", sigType) } sb, err := sv.Sign(privkey, msg) if err != nil { return nil, err } - return &types.Signature{ + return &crypto.Signature{ Type: sigType, Data: sb, }, nil } // Verify verifies signatures -func Verify(sig *types.Signature, addr address.Address, msg []byte) error { +func Verify(sig *crypto.Signature, addr address.Address, msg []byte) error { if sig == nil { return xerrors.Errorf("signature is nil") } @@ -40,27 +42,27 @@ func Verify(sig *types.Signature, addr address.Address, msg []byte) error { sv, ok := sigs[sig.Type] if !ok { - return fmt.Errorf("cannot verify signature of unsupported type: %s", sig.Type) + return fmt.Errorf("cannot verify signature of unsupported type: %v", sig.Type) } return sv.Verify(sig.Data, addr, msg) } // Generate generates private key of given type -func Generate(sigType string) ([]byte, error) { +func Generate(sigType crypto.SigType) ([]byte, error) { sv, ok := sigs[sigType] if !ok { - return nil, fmt.Errorf("cannot generate private key of unsupported type: %s", sigType) + return nil, fmt.Errorf("cannot generate private key of unsupported type: %v", sigType) } return sv.GenPrivate() } // ToPublic converts private key to public key -func ToPublic(sigType string, pk []byte) ([]byte, error) { +func ToPublic(sigType crypto.SigType, pk []byte) ([]byte, error) { sv, ok := sigs[sigType] if !ok { - return nil, fmt.Errorf("cannot generate public key of unsupported type: %s", sigType) + return nil, fmt.Errorf("cannot generate public key of unsupported type: %v", sigType) } return sv.ToPublic(pk) @@ -91,12 +93,12 @@ type SigShim interface { Verify(sig []byte, a address.Address, msg []byte) error } -var sigs map[string]SigShim +var sigs map[crypto.SigType]SigShim // RegisterSig should be only used during init -func RegisterSignature(name string, vs SigShim) { +func RegisterSignature(typ crypto.SigType, vs SigShim) { if sigs == nil { - sigs = make(map[string]SigShim) + sigs = make(map[crypto.SigType]SigShim) } - sigs[name] = vs + sigs[typ] = vs } diff --git a/lib/statemachine/cbor_gen.go b/lib/statemachine/cbor_gen.go index bf187e209..4bebe01d0 100644 --- a/lib/statemachine/cbor_gen.go +++ b/lib/statemachine/cbor_gen.go @@ -52,6 +52,7 @@ func (t *TestState) MarshalCBOR(w io.Writer) error { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.B))); err != nil { return err } + return nil } @@ -88,25 +89,33 @@ func (t *TestState) UnmarshalCBOR(r io.Reader) error { // t.A (uint64) (uint64) case "A": - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err + { + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.A = uint64(extra) + } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.A = uint64(extra) // t.B (uint64) (uint64) case "B": - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err + { + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.B = uint64(extra) + } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.B = uint64(extra) default: return fmt.Errorf("unknown struct field %d: '%s'", i, name) @@ -162,6 +171,7 @@ func (t *TestEvent) MarshalCBOR(w io.Writer) error { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Val))); err != nil { return err } + return nil } @@ -209,14 +219,18 @@ func (t *TestEvent) UnmarshalCBOR(r io.Reader) error { // t.Val (uint64) (uint64) case "Val": - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err + { + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.Val = uint64(extra) + } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.Val = uint64(extra) default: return fmt.Errorf("unknown struct field %d: '%s'", i, name) diff --git a/tracing/setup.go b/lib/tracing/setup.go similarity index 100% rename from tracing/setup.go rename to lib/tracing/setup.go diff --git a/lib/zerocomm/zerocomm.go b/lib/zerocomm/zerocomm.go new file mode 100644 index 000000000..40dff3ede --- /dev/null +++ b/lib/zerocomm/zerocomm.go @@ -0,0 +1,53 @@ +package zerocomm + +import ( + "math/bits" + + "github.com/filecoin-project/specs-actors/actors/abi" +) + +const levels = 37 +const skip = 2 // can't generate for 32, 64b + +var pieceComms = [levels - skip][32]byte{ + {0x37, 0x31, 0xbb, 0x99, 0xac, 0x68, 0x9f, 0x66, 0xee, 0xf5, 0x97, 0x3e, 0x4a, 0x94, 0xda, 0x18, 0x8f, 0x4d, 0xdc, 0xae, 0x58, 0x7, 0x24, 0xfc, 0x6f, 0x3f, 0xd6, 0xd, 0xfd, 0x48, 0x83, 0x33}, + {0x64, 0x2a, 0x60, 0x7e, 0xf8, 0x86, 0xb0, 0x4, 0xbf, 0x2c, 0x19, 0x78, 0x46, 0x3a, 0xe1, 0xd4, 0x69, 0x3a, 0xc0, 0xf4, 0x10, 0xeb, 0x2d, 0x1b, 0x7a, 0x47, 0xfe, 0x20, 0x5e, 0x5e, 0x75, 0xf}, + {0x57, 0xa2, 0x38, 0x1a, 0x28, 0x65, 0x2b, 0xf4, 0x7f, 0x6b, 0xef, 0x7a, 0xca, 0x67, 0x9b, 0xe4, 0xae, 0xde, 0x58, 0x71, 0xab, 0x5c, 0xf3, 0xeb, 0x2c, 0x8, 0x11, 0x44, 0x88, 0xcb, 0x85, 0x26}, + {0x1f, 0x7a, 0xc9, 0x59, 0x55, 0x10, 0xe0, 0x9e, 0xa4, 0x1c, 0x46, 0xb, 0x17, 0x64, 0x30, 0xbb, 0x32, 0x2c, 0xd6, 0xfb, 0x41, 0x2e, 0xc5, 0x7c, 0xb1, 0x7d, 0x98, 0x9a, 0x43, 0x10, 0x37, 0x2f}, + {0xfc, 0x7e, 0x92, 0x82, 0x96, 0xe5, 0x16, 0xfa, 0xad, 0xe9, 0x86, 0xb2, 0x8f, 0x92, 0xd4, 0x4a, 0x4f, 0x24, 0xb9, 0x35, 0x48, 0x52, 0x23, 0x37, 0x6a, 0x79, 0x90, 0x27, 0xbc, 0x18, 0xf8, 0x33}, + {0x8, 0xc4, 0x7b, 0x38, 0xee, 0x13, 0xbc, 0x43, 0xf4, 0x1b, 0x91, 0x5c, 0xe, 0xed, 0x99, 0x11, 0xa2, 0x60, 0x86, 0xb3, 0xed, 0x62, 0x40, 0x1b, 0xf9, 0xd5, 0x8b, 0x8d, 0x19, 0xdf, 0xf6, 0x24}, + {0xb2, 0xe4, 0x7b, 0xfb, 0x11, 0xfa, 0xcd, 0x94, 0x1f, 0x62, 0xaf, 0x5c, 0x75, 0xf, 0x3e, 0xa5, 0xcc, 0x4d, 0xf5, 0x17, 0xd5, 0xc4, 0xf1, 0x6d, 0xb2, 0xb4, 0xd7, 0x7b, 0xae, 0xc1, 0xa3, 0x2f}, + {0xf9, 0x22, 0x61, 0x60, 0xc8, 0xf9, 0x27, 0xbf, 0xdc, 0xc4, 0x18, 0xcd, 0xf2, 0x3, 0x49, 0x31, 0x46, 0x0, 0x8e, 0xae, 0xfb, 0x7d, 0x2, 0x19, 0x4d, 0x5e, 0x54, 0x81, 0x89, 0x0, 0x51, 0x8}, + {0x2c, 0x1a, 0x96, 0x4b, 0xb9, 0xb, 0x59, 0xeb, 0xfe, 0xf, 0x6d, 0xa2, 0x9a, 0xd6, 0x5a, 0xe3, 0xe4, 0x17, 0x72, 0x4a, 0x8f, 0x7c, 0x11, 0x74, 0x5a, 0x40, 0xca, 0xc1, 0xe5, 0xe7, 0x40, 0x11}, + {0xfe, 0xe3, 0x78, 0xce, 0xf1, 0x64, 0x4, 0xb1, 0x99, 0xed, 0xe0, 0xb1, 0x3e, 0x11, 0xb6, 0x24, 0xff, 0x9d, 0x78, 0x4f, 0xbb, 0xed, 0x87, 0x8d, 0x83, 0x29, 0x7e, 0x79, 0x5e, 0x2, 0x4f, 0x2}, + {0x8e, 0x9e, 0x24, 0x3, 0xfa, 0x88, 0x4c, 0xf6, 0x23, 0x7f, 0x60, 0xdf, 0x25, 0xf8, 0x3e, 0xe4, 0xd, 0xca, 0x9e, 0xd8, 0x79, 0xeb, 0x6f, 0x63, 0x52, 0xd1, 0x50, 0x84, 0xf5, 0xad, 0xd, 0x3f}, + {0x75, 0x2d, 0x96, 0x93, 0xfa, 0x16, 0x75, 0x24, 0x39, 0x54, 0x76, 0xe3, 0x17, 0xa9, 0x85, 0x80, 0xf0, 0x9, 0x47, 0xaf, 0xb7, 0xa3, 0x5, 0x40, 0xd6, 0x25, 0xa9, 0x29, 0x1c, 0xc1, 0x2a, 0x7}, + {0x70, 0x22, 0xf6, 0xf, 0x7e, 0xf6, 0xad, 0xfa, 0x17, 0x11, 0x7a, 0x52, 0x61, 0x9e, 0x30, 0xce, 0xa8, 0x2c, 0x68, 0x7, 0x5a, 0xdf, 0x1c, 0x66, 0x77, 0x86, 0xec, 0x50, 0x6e, 0xef, 0x2d, 0x19}, + {0xd9, 0x98, 0x87, 0xb9, 0x73, 0x57, 0x3a, 0x96, 0xe1, 0x13, 0x93, 0x64, 0x52, 0x36, 0xc1, 0x7b, 0x1f, 0x4c, 0x70, 0x34, 0xd7, 0x23, 0xc7, 0xa9, 0x9f, 0x70, 0x9b, 0xb4, 0xda, 0x61, 0x16, 0x2b}, + {0xd0, 0xb5, 0x30, 0xdb, 0xb0, 0xb4, 0xf2, 0x5c, 0x5d, 0x2f, 0x2a, 0x28, 0xdf, 0xee, 0x80, 0x8b, 0x53, 0x41, 0x2a, 0x2, 0x93, 0x1f, 0x18, 0xc4, 0x99, 0xf5, 0xa2, 0x54, 0x8, 0x6b, 0x13, 0x26}, + {0x84, 0xc0, 0x42, 0x1b, 0xa0, 0x68, 0x5a, 0x1, 0xbf, 0x79, 0x5a, 0x23, 0x44, 0x6, 0x4f, 0xe4, 0x24, 0xbd, 0x52, 0xa9, 0xd2, 0x43, 0x77, 0xb3, 0x94, 0xff, 0x4c, 0x4b, 0x45, 0x68, 0xe8, 0x11}, + {0x65, 0xf2, 0x9e, 0x5d, 0x98, 0xd2, 0x46, 0xc3, 0x8b, 0x38, 0x8c, 0xfc, 0x6, 0xdb, 0x1f, 0x6b, 0x2, 0x13, 0x3, 0xc5, 0xa2, 0x89, 0x0, 0xb, 0xdc, 0xe8, 0x32, 0xa9, 0xc3, 0xec, 0x42, 0x1c}, + {0xa2, 0x24, 0x75, 0x8, 0x28, 0x58, 0x50, 0x96, 0x5b, 0x7e, 0x33, 0x4b, 0x31, 0x27, 0xb0, 0xc0, 0x42, 0xb1, 0xd0, 0x46, 0xdc, 0x54, 0x40, 0x21, 0x37, 0x62, 0x7c, 0xd8, 0x79, 0x9c, 0xe1, 0x3a}, + {0xda, 0xfd, 0xab, 0x6d, 0xa9, 0x36, 0x44, 0x53, 0xc2, 0x6d, 0x33, 0x72, 0x6b, 0x9f, 0xef, 0xe3, 0x43, 0xbe, 0x8f, 0x81, 0x64, 0x9e, 0xc0, 0x9, 0xaa, 0xd3, 0xfa, 0xff, 0x50, 0x61, 0x75, 0x8}, + {0xd9, 0x41, 0xd5, 0xe0, 0xd6, 0x31, 0x4a, 0x99, 0x5c, 0x33, 0xff, 0xbd, 0x4f, 0xbe, 0x69, 0x11, 0x8d, 0x73, 0xd4, 0xe5, 0xfd, 0x2c, 0xd3, 0x1f, 0xf, 0x7c, 0x86, 0xeb, 0xdd, 0x14, 0xe7, 0x6}, + {0x51, 0x4c, 0x43, 0x5c, 0x3d, 0x4, 0xd3, 0x49, 0xa5, 0x36, 0x5f, 0xbd, 0x59, 0xff, 0xc7, 0x13, 0x62, 0x91, 0x11, 0x78, 0x59, 0x91, 0xc1, 0xa3, 0xc5, 0x3a, 0xf2, 0x20, 0x79, 0x74, 0x1a, 0x2f}, + {0xad, 0x6, 0x85, 0x39, 0x69, 0xd3, 0x7d, 0x34, 0xff, 0x8, 0xe0, 0x9f, 0x56, 0x93, 0xa, 0x4a, 0xd1, 0x9a, 0x89, 0xde, 0xf6, 0xc, 0xbf, 0xee, 0x7e, 0x1d, 0x33, 0x81, 0xc1, 0xe7, 0x1c, 0x37}, + {0x39, 0x56, 0xe, 0x7b, 0x13, 0xa9, 0x3b, 0x7, 0xa2, 0x43, 0xfd, 0x27, 0x20, 0xff, 0xa7, 0xcb, 0x3e, 0x1d, 0x2e, 0x50, 0x5a, 0xb3, 0x62, 0x9e, 0x79, 0xf4, 0x63, 0x13, 0x51, 0x2c, 0xda, 0x6}, + {0xcc, 0xc3, 0xc0, 0x12, 0xf5, 0xb0, 0x5e, 0x81, 0x1a, 0x2b, 0xbf, 0xdd, 0xf, 0x68, 0x33, 0xb8, 0x42, 0x75, 0xb4, 0x7b, 0xf2, 0x29, 0xc0, 0x5, 0x2a, 0x82, 0x48, 0x4f, 0x3c, 0x1a, 0x5b, 0x3d}, + {0x7d, 0xf2, 0x9b, 0x69, 0x77, 0x31, 0x99, 0xe8, 0xf2, 0xb4, 0xb, 0x77, 0x91, 0x9d, 0x4, 0x85, 0x9, 0xee, 0xd7, 0x68, 0xe2, 0xc7, 0x29, 0x7b, 0x1f, 0x14, 0x37, 0x3, 0x4f, 0xc3, 0xc6, 0x2c}, + {0x66, 0xce, 0x5, 0xa3, 0x66, 0x75, 0x52, 0xcf, 0x45, 0xc0, 0x2b, 0xcc, 0x4e, 0x83, 0x92, 0x91, 0x9b, 0xde, 0xac, 0x35, 0xde, 0x2f, 0xf5, 0x62, 0x71, 0x84, 0x8e, 0x9f, 0x7b, 0x67, 0x51, 0x7}, + {0xd8, 0x61, 0x2, 0x18, 0x42, 0x5a, 0xb5, 0xe9, 0x5b, 0x1c, 0xa6, 0x23, 0x9d, 0x29, 0xa2, 0xe4, 0x20, 0xd7, 0x6, 0xa9, 0x6f, 0x37, 0x3e, 0x2f, 0x9c, 0x9a, 0x91, 0xd7, 0x59, 0xd1, 0x9b, 0x1}, + {0x6d, 0x36, 0x4b, 0x1e, 0xf8, 0x46, 0x44, 0x1a, 0x5a, 0x4a, 0x68, 0x86, 0x23, 0x14, 0xac, 0xc0, 0xa4, 0x6f, 0x1, 0x67, 0x17, 0xe5, 0x34, 0x43, 0xe8, 0x39, 0xee, 0xdf, 0x83, 0xc2, 0x85, 0x3c}, + {0x7, 0x7e, 0x5f, 0xde, 0x35, 0xc5, 0xa, 0x93, 0x3, 0xa5, 0x50, 0x9, 0xe3, 0x49, 0x8a, 0x4e, 0xbe, 0xdf, 0xf3, 0x9c, 0x42, 0xb7, 0x10, 0xb7, 0x30, 0xd8, 0xec, 0x7a, 0xc7, 0xaf, 0xa6, 0x3e}, + {0xe6, 0x40, 0x5, 0xa6, 0xbf, 0xe3, 0x77, 0x79, 0x53, 0xb8, 0xad, 0x6e, 0xf9, 0x3f, 0xf, 0xca, 0x10, 0x49, 0xb2, 0x4, 0x16, 0x54, 0xf2, 0xa4, 0x11, 0xf7, 0x70, 0x27, 0x99, 0xce, 0xce, 0x2}, + {0x25, 0x9d, 0x3d, 0x6b, 0x1f, 0x4d, 0x87, 0x6d, 0x11, 0x85, 0xe1, 0x12, 0x3a, 0xf6, 0xf5, 0x50, 0x1a, 0xf0, 0xf6, 0x7c, 0xf1, 0x5b, 0x52, 0x16, 0x25, 0x5b, 0x7b, 0x17, 0x8d, 0x12, 0x5, 0x1d}, + {0x3f, 0x9a, 0x4d, 0x41, 0x1d, 0xa4, 0xef, 0x1b, 0x36, 0xf3, 0x5f, 0xf0, 0xa1, 0x95, 0xae, 0x39, 0x2a, 0xb2, 0x3f, 0xee, 0x79, 0x67, 0xb7, 0xc4, 0x1b, 0x3, 0xd1, 0x61, 0x3f, 0xc2, 0x92, 0x39}, + {0xfe, 0x4e, 0xf3, 0x28, 0xc6, 0x1a, 0xa3, 0x9c, 0xfd, 0xb2, 0x48, 0x4e, 0xaa, 0x32, 0xa1, 0x51, 0xb1, 0xfe, 0x3d, 0xfd, 0x1f, 0x96, 0xdd, 0x8c, 0x97, 0x11, 0xfd, 0x86, 0xd6, 0xc5, 0x81, 0x13}, + {0xf5, 0x5d, 0x68, 0x90, 0xe, 0x2d, 0x83, 0x81, 0xec, 0xcb, 0x81, 0x64, 0xcb, 0x99, 0x76, 0xf2, 0x4b, 0x2d, 0xe0, 0xdd, 0x61, 0xa3, 0x1b, 0x97, 0xce, 0x6e, 0xb2, 0x38, 0x50, 0xd5, 0xe8, 0x19}, + {0xaa, 0xaa, 0x8c, 0x4c, 0xb4, 0xa, 0xac, 0xee, 0x1e, 0x2, 0xdc, 0x65, 0x42, 0x4b, 0x2a, 0x6c, 0x8e, 0x99, 0xf8, 0x3, 0xb7, 0x2f, 0x79, 0x29, 0xc4, 0x10, 0x1d, 0x7f, 0xae, 0x6b, 0xff, 0x32}, +} + +func ForSize(sz abi.UnpaddedPieceSize) [32]byte { + level := bits.TrailingZeros64(uint64(sz.Padded())) - skip - 5 // 2^5 = 32 + return pieceComms[level] +} diff --git a/lib/zerocomm/zerocomm_test.go b/lib/zerocomm/zerocomm_test.go new file mode 100644 index 000000000..5648d4f8f --- /dev/null +++ b/lib/zerocomm/zerocomm_test.go @@ -0,0 +1,60 @@ +package zerocomm + +import ( + "bytes" + "fmt" + "testing" + + "github.com/filecoin-project/go-sectorbuilder" +) + +func TestComms(t *testing.T) { + var expPieceComms [levels - skip][32]byte + + { + l2, err := sectorbuilder.GeneratePieceCommitment(bytes.NewReader(make([]byte, 127)), 127) + if err != nil { + return + } + expPieceComms[0] = l2 + } + + for i := 1; i < levels-2; i++ { + var err error + expPieceComms[i], err = sectorbuilder.GenerateDataCommitment(128< 0 { + if sd.Proposal.StartEpoch > 0 { cb(nil) return true, false, nil } @@ -235,7 +242,7 @@ func (c *ClientNodeAdapter) OnDealSectorCommitted(ctx context.Context, provider return false, true, nil } - called := func(msg *types.Message, rec *types.MessageReceipt, ts *types.TipSet, curH uint64) (more bool, err error) { + called := func(msg *types.Message, rec *types.MessageReceipt, ts *types.TipSet, curH abi.ChainEpoch) (more bool, err error) { defer func() { if err != nil { cb(xerrors.Errorf("handling applied event: %w", err)) @@ -247,16 +254,16 @@ func (c *ClientNodeAdapter) OnDealSectorCommitted(ctx context.Context, provider return false, nil } - sd, err := stmgr.GetStorageDeal(ctx, c.StateManager, dealId, ts) + sd, err := stmgr.GetStorageDeal(ctx, c.StateManager, abi.DealID(dealId), ts) if err != nil { return false, xerrors.Errorf("failed to look up deal on chain: %w", err) } - if sd.ActivationEpoch == 0 { + if sd.Proposal.StartEpoch == 0 { return false, xerrors.Errorf("deal wasn't active: deal=%d, parentState=%s, h=%d", dealId, ts.ParentState(), ts.Height()) } - log.Infof("Storage deal %d activated at epoch %d", dealId, sd.ActivationEpoch) + log.Infof("Storage deal %d activated at epoch %d", dealId, sd.State.SectorStartEpoch) cb(nil) @@ -274,18 +281,18 @@ func (c *ClientNodeAdapter) OnDealSectorCommitted(ctx context.Context, provider return false, nil } - if msg.Method != actors.MAMethods.ProveCommitSector { + if msg.Method != builtin.MethodsMiner.ProveCommitSector { return false, nil } - var params actors.SectorProveCommitInfo + var params miner.SectorPreCommitInfo if err := params.UnmarshalCBOR(bytes.NewReader(msg.Params)); err != nil { return false, err } var found bool for _, dealID := range params.DealIDs { - if dealID == dealId { + if uint64(dealID) == dealId { found = true break } @@ -295,27 +302,22 @@ func (c *ClientNodeAdapter) OnDealSectorCommitted(ctx context.Context, provider } if err := c.ev.Called(checkFunc, called, revert, 3, build.SealRandomnessLookbackLimit, matchEvent); err != nil { - return xerrors.Errorf("failed to set up called handler") + return xerrors.Errorf("failed to set up called handler: %w", err) } return nil } -func (n *ClientNodeAdapter) SignProposal(ctx context.Context, signer address.Address, proposal *storagemarket.StorageDealProposal) error { - localProposal, err := utils.FromSharedStorageDealProposal(proposal) - if err != nil { - return err - } - err = api.SignWith(ctx, n.Wallet.Sign, signer, localProposal) - if err != nil { - return err - } - signature, err := utils.ToSharedSignature(localProposal.ProposerSignature) - if err != nil { - return err - } - proposal.ProposerSignature = signature - return nil +func (n *ClientNodeAdapter) SignProposal(ctx context.Context, signer address.Address, proposal samarket.DealProposal) (*samarket.ClientDealProposal, error) { + // TODO: output spec signed proposal + log.Warn("TODO: stub SignProposal") + return &samarket.ClientDealProposal{ + Proposal: proposal, + ClientSignature: crypto.Signature{ + Type: crypto.SigTypeBLS, + Data: []byte{}, + }, + }, nil } func (n *ClientNodeAdapter) GetDefaultWalletAddress(ctx context.Context) (address.Address, error) { @@ -323,7 +325,7 @@ func (n *ClientNodeAdapter) GetDefaultWalletAddress(ctx context.Context) (addres return addr, err } -func (n *ClientNodeAdapter) ValidateAskSignature(ask *sharedtypes.SignedStorageAsk) error { +func (n *ClientNodeAdapter) ValidateAskSignature(ask *storagemarket.SignedStorageAsk) error { tss := n.cs.GetHeaviestTipSet().ParentState() w, err := stmgr.GetMinerWorkerRaw(context.TODO(), n.StateManager, tss, ask.Ask.Miner) @@ -336,7 +338,9 @@ func (n *ClientNodeAdapter) ValidateAskSignature(ask *sharedtypes.SignedStorageA return xerrors.Errorf("failed to re-serialize ask") } - return ask.Signature.Verify(w, sigb) + _ = w + _ = sigb + panic("verify signature") } var _ storagemarket.StorageClientNode = &ClientNodeAdapter{} diff --git a/markets/storageadapter/provider.go b/markets/storageadapter/provider.go index b09f5a0e9..c7837894d 100644 --- a/markets/storageadapter/provider.go +++ b/markets/storageadapter/provider.go @@ -7,13 +7,16 @@ import ( "context" "io" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/filecoin-project/specs-actors/actors/builtin/market" + "github.com/filecoin-project/specs-actors/actors/builtin/miner" + "github.com/filecoin-project/specs-actors/actors/crypto" "github.com/ipfs/go-cid" logging "github.com/ipfs/go-log" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" - "github.com/filecoin-project/go-fil-markets/shared/tokenamount" - sharedtypes "github.com/filecoin-project/go-fil-markets/shared/types" "github.com/filecoin-project/go-fil-markets/storagemarket" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" @@ -55,12 +58,8 @@ func (n *ProviderNodeAdapter) PublishDeals(ctx context.Context, deal storagemark return 0, cid.Undef, err } - localProposal, err := utils.FromSharedStorageDealProposal(&deal.Proposal) - if err != nil { - return 0, cid.Undef, err - } - params, err := actors.SerializeParams(&actors.PublishStorageDealsParams{ - Deals: []actors.StorageDealProposal{*localProposal}, + params, err := actors.SerializeParams(&market.PublishStorageDealsParams{ + Deals: []market.ClientDealProposal{deal.ClientDealProposal}, }) if err != nil { @@ -69,12 +68,12 @@ func (n *ProviderNodeAdapter) PublishDeals(ctx context.Context, deal storagemark // TODO: We may want this to happen after fetching data smsg, err := n.MpoolPushMessage(ctx, &types.Message{ - To: actors.StorageMarketAddress, + To: builtin.StorageMarketActorAddr, From: worker, Value: types.NewInt(0), GasPrice: types.NewInt(0), GasLimit: types.NewInt(1000000), - Method: actors.SMAMethods.PublishStorageDeals, + Method: builtin.MethodsMarket.PublishStorageDeals, Params: params, }) if err != nil { @@ -87,20 +86,20 @@ func (n *ProviderNodeAdapter) PublishDeals(ctx context.Context, deal storagemark if r.Receipt.ExitCode != 0 { return 0, cid.Undef, xerrors.Errorf("publishing deal failed: exit %d", r.Receipt.ExitCode) } - var resp actors.PublishStorageDealResponse + var resp market.PublishStorageDealsReturn if err := resp.UnmarshalCBOR(bytes.NewReader(r.Receipt.Return)); err != nil { return 0, cid.Undef, err } - if len(resp.DealIDs) != 1 { + if len(resp.IDs) != 1 { return 0, cid.Undef, xerrors.Errorf("got unexpected number of DealIDs from") } - return storagemarket.DealID(resp.DealIDs[0]), smsg.Cid(), nil + // TODO: bad types here + return storagemarket.DealID(resp.IDs[0]), smsg.Cid(), nil } -func (n *ProviderNodeAdapter) OnDealComplete(ctx context.Context, deal storagemarket.MinerDeal, pieceSize uint64, pieceData io.Reader) error { - - _, err := n.secb.AddPiece(ctx, pieceSize, pieceData, deal.DealID) +func (n *ProviderNodeAdapter) OnDealComplete(ctx context.Context, deal storagemarket.MinerDeal, pieceSize abi.UnpaddedPieceSize, pieceData io.Reader) error { + _, err := n.secb.AddPiece(ctx, abi.UnpaddedPieceSize(pieceSize), pieceData, abi.DealID(deal.DealID)) if err != nil { return xerrors.Errorf("AddPiece failed: %s", err) } @@ -109,6 +108,11 @@ func (n *ProviderNodeAdapter) OnDealComplete(ctx context.Context, deal storagema return nil } +func (n *ProviderNodeAdapter) VerifySignature(sig crypto.Signature, addr address.Address, input []byte) bool { + log.Warn("stub VerifySignature") + return true +} + func (n *ProviderNodeAdapter) ListProviderDeals(ctx context.Context, addr address.Address) ([]storagemarket.StorageDeal, error) { allDeals, err := n.StateMarketDeals(ctx, types.EmptyTSK) if err != nil { @@ -118,7 +122,7 @@ func (n *ProviderNodeAdapter) ListProviderDeals(ctx context.Context, addr addres var out []storagemarket.StorageDeal for _, deal := range allDeals { - sharedDeal := utils.FromOnChainDeal(deal) + sharedDeal := utils.FromOnChainDeal(deal.Proposal, deal.State) if sharedDeal.Provider == addr { out = append(out, sharedDeal) } @@ -132,16 +136,16 @@ func (n *ProviderNodeAdapter) GetMinerWorker(ctx context.Context, miner address. return addr, err } -func (n *ProviderNodeAdapter) SignBytes(ctx context.Context, signer address.Address, b []byte) (*sharedtypes.Signature, error) { +func (n *ProviderNodeAdapter) SignBytes(ctx context.Context, signer address.Address, b []byte) (*crypto.Signature, error) { localSignature, err := n.WalletSign(ctx, signer, b) if err != nil { return nil, err } - return utils.ToSharedSignature(localSignature) + return localSignature, nil } -func (n *ProviderNodeAdapter) EnsureFunds(ctx context.Context, addr address.Address, amt tokenamount.TokenAmount) error { - return n.MarketEnsureAvailable(ctx, addr, utils.FromSharedTokenAmount(amt)) +func (n *ProviderNodeAdapter) EnsureFunds(ctx context.Context, addr address.Address, amt abi.TokenAmount) error { + return n.MarketEnsureAvailable(ctx, addr, amt) } func (n *ProviderNodeAdapter) MostRecentStateId(ctx context.Context) (storagemarket.StateKey, error) { @@ -149,15 +153,15 @@ func (n *ProviderNodeAdapter) MostRecentStateId(ctx context.Context) (storagemar } // Adds funds with the StorageMinerActor for a storage participant. Used by both providers and clients. -func (n *ProviderNodeAdapter) AddFunds(ctx context.Context, addr address.Address, amount tokenamount.TokenAmount) error { +func (n *ProviderNodeAdapter) AddFunds(ctx context.Context, addr address.Address, amount abi.TokenAmount) error { // (Provider Node API) smsg, err := n.MpoolPushMessage(ctx, &types.Message{ - To: actors.StorageMarketAddress, + To: builtin.StorageMarketActorAddr, From: addr, - Value: utils.FromSharedTokenAmount(amount), + Value: amount, GasPrice: types.NewInt(0), GasLimit: types.NewInt(1000000), - Method: actors.SMAMethods.AddBalance, + Method: builtin.MethodsMarket.AddBalance, }) if err != nil { return err @@ -186,7 +190,7 @@ func (n *ProviderNodeAdapter) GetBalance(ctx context.Context, addr address.Addre func (n *ProviderNodeAdapter) LocatePieceForDealWithinSector(ctx context.Context, dealID uint64) (sectorID uint64, offset uint64, length uint64, err error) { - refs, err := n.secb.GetRefs(dealID) + refs, err := n.secb.GetRefs(abi.DealID(dealID)) if err != nil { return 0, 0, 0, err } @@ -211,19 +215,19 @@ func (n *ProviderNodeAdapter) LocatePieceForDealWithinSector(ctx context.Context if bestSi.State == api.UndefinedSectorState { return 0, 0, 0, xerrors.New("no sealed sector found") } - return best.SectorID, best.Offset, best.Size, nil + return uint64(best.SectorID), best.Offset, uint64(best.Size), nil } func (n *ProviderNodeAdapter) OnDealSectorCommitted(ctx context.Context, provider address.Address, dealID uint64, cb storagemarket.DealSectorCommittedCallback) error { checkFunc := func(ts *types.TipSet) (done bool, more bool, err error) { - sd, err := n.StateMarketStorageDeal(ctx, dealID, ts.Key()) + sd, err := n.StateMarketStorageDeal(ctx, abi.DealID(dealID), ts.Key()) if err != nil { // TODO: This may be fine for some errors return false, false, xerrors.Errorf("failed to look up deal on chain: %w", err) } - if sd.ActivationEpoch > 0 { + if sd.State.SectorStartEpoch > 0 { cb(nil) return true, false, nil } @@ -231,7 +235,7 @@ func (n *ProviderNodeAdapter) OnDealSectorCommitted(ctx context.Context, provide return false, true, nil } - called := func(msg *types.Message, rec *types.MessageReceipt, ts *types.TipSet, curH uint64) (more bool, err error) { + called := func(msg *types.Message, rec *types.MessageReceipt, ts *types.TipSet, curH abi.ChainEpoch) (more bool, err error) { defer func() { if err != nil { cb(xerrors.Errorf("handling applied event: %w", err)) @@ -243,16 +247,16 @@ func (n *ProviderNodeAdapter) OnDealSectorCommitted(ctx context.Context, provide return false, nil } - sd, err := n.StateMarketStorageDeal(ctx, dealID, ts.Key()) + sd, err := n.StateMarketStorageDeal(ctx, abi.DealID(dealID), ts.Key()) if err != nil { return false, xerrors.Errorf("failed to look up deal on chain: %w", err) } - if sd.ActivationEpoch == 0 { + if sd.State.SectorStartEpoch < 1 { return false, xerrors.Errorf("deal wasn't active: deal=%d, parentState=%s, h=%d", dealID, ts.ParentState(), ts.Height()) } - log.Infof("Storage deal %d activated at epoch %d", dealID, sd.ActivationEpoch) + log.Infof("Storage deal %d activated at epoch %d", dealID, sd.State.SectorStartEpoch) cb(nil) @@ -270,18 +274,18 @@ func (n *ProviderNodeAdapter) OnDealSectorCommitted(ctx context.Context, provide return false, nil } - if msg.Method != actors.MAMethods.ProveCommitSector { + if msg.Method != builtin.MethodsMiner.ProveCommitSector { return false, nil } - var params actors.SectorProveCommitInfo + var params miner.SectorPreCommitInfo if err := params.UnmarshalCBOR(bytes.NewReader(msg.Params)); err != nil { return false, err } var found bool for _, did := range params.DealIDs { - if did == dealID { + if did == abi.DealID(dealID) { found = true break } @@ -291,7 +295,7 @@ func (n *ProviderNodeAdapter) OnDealSectorCommitted(ctx context.Context, provide } if err := n.ev.Called(checkFunc, called, revert, 3, build.SealRandomnessLookbackLimit, matchEvent); err != nil { - return xerrors.Errorf("failed to set up called handler") + return xerrors.Errorf("failed to set up called handler: %w", err) } return nil diff --git a/markets/utils/converters.go b/markets/utils/converters.go index 58080896f..91a1ff8fc 100644 --- a/markets/utils/converters.go +++ b/markets/utils/converters.go @@ -1,174 +1,35 @@ package utils import ( - "bytes" - + "github.com/filecoin-project/lotus/api" + "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" - sharedamount "github.com/filecoin-project/go-fil-markets/shared/tokenamount" - sharedtypes "github.com/filecoin-project/go-fil-markets/shared/types" "github.com/filecoin-project/go-fil-markets/storagemarket" - "github.com/filecoin-project/lotus/chain/actors" - "github.com/filecoin-project/lotus/chain/types" ) -func FromSharedTokenAmount(in sharedamount.TokenAmount) types.BigInt { - return types.BigInt{Int: in.Int} -} - -func ToSharedTokenAmount(in types.BigInt) sharedamount.TokenAmount { - return sharedamount.TokenAmount{Int: in.Int} -} - -func ToSharedSignedVoucher(in *types.SignedVoucher) (*sharedtypes.SignedVoucher, error) { - var encoded bytes.Buffer - err := in.MarshalCBOR(&encoded) - if err != nil { - return nil, err - } - var out sharedtypes.SignedVoucher - err = out.UnmarshalCBOR(&encoded) - if err != nil { - return nil, err - } - return &out, nil -} - -func FromSharedSignedVoucher(in *sharedtypes.SignedVoucher) (*types.SignedVoucher, error) { - var encoded bytes.Buffer - err := in.MarshalCBOR(&encoded) - if err != nil { - return nil, err - } - var out types.SignedVoucher - err = out.UnmarshalCBOR(&encoded) - if err != nil { - return nil, err - } - return &out, nil -} - -func ToSharedSignature(in *types.Signature) (*sharedtypes.Signature, error) { - var encoded bytes.Buffer - err := in.MarshalCBOR(&encoded) - if err != nil { - return nil, err - } - var out sharedtypes.Signature - err = out.UnmarshalCBOR(&encoded) - if err != nil { - return nil, err - } - return &out, nil -} - -func FromSharedSignature(in *sharedtypes.Signature) (*types.Signature, error) { - var encoded bytes.Buffer - err := in.MarshalCBOR(&encoded) - if err != nil { - return nil, err - } - var out types.Signature - err = out.UnmarshalCBOR(&encoded) - if err != nil { - return nil, err - } - return &out, nil -} - -func ToSharedStorageAsk(in *types.SignedStorageAsk) (*sharedtypes.SignedStorageAsk, error) { - var encoded bytes.Buffer - err := in.MarshalCBOR(&encoded) - if err != nil { - return nil, err - } - var out sharedtypes.SignedStorageAsk - err = out.UnmarshalCBOR(&encoded) - if err != nil { - return nil, err - } - return &out, nil -} - -func FromSignedStorageAsk(in *sharedtypes.SignedStorageAsk) (*types.SignedStorageAsk, error) { - var encoded bytes.Buffer - err := in.MarshalCBOR(&encoded) - if err != nil { - return nil, err - } - var out types.SignedStorageAsk - err = out.UnmarshalCBOR(&encoded) - if err != nil { - return nil, err - } - 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(prop 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, + DealProposal: prop, + DealState: state, } } -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(bal api.MarketBalance) storagemarket.Balance { return storagemarket.Balance{ - Locked: ToSharedTokenAmount(balance.Locked), - Available: ToSharedTokenAmount(balance.Available), + Locked: bal.Locked, + Available: big.Sub(bal.Escrow, bal.Locked), } } - -func ToSharedStorageDealProposal(proposal *actors.StorageDealProposal) (*storagemarket.StorageDealProposal, error) { - var encoded bytes.Buffer - err := proposal.MarshalCBOR(&encoded) - if err != nil { - return nil, err - } - var out storagemarket.StorageDealProposal - err = out.UnmarshalCBOR(&encoded) - if err != nil { - return nil, err - } - return &out, nil -} - -func FromSharedStorageDealProposal(proposal *storagemarket.StorageDealProposal) (*actors.StorageDealProposal, error) { - var encoded bytes.Buffer - err := proposal.MarshalCBOR(&encoded) - if err != nil { - return nil, err - } - var out actors.StorageDealProposal - err = out.UnmarshalCBOR(&encoded) - if err != nil { - return nil, err - } - return &out, nil -} diff --git a/miner/miner.go b/miner/miner.go index 064e8a14d..25025304a 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -7,12 +7,14 @@ import ( "time" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/crypto" + lru "github.com/hashicorp/golang-lru" + "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/gen" "github.com/filecoin-project/lotus/chain/types" - lru "github.com/hashicorp/golang-lru" logging "github.com/ipfs/go-log/v2" "go.opencensus.io/trace" @@ -243,7 +245,7 @@ eventLoop: type MiningBase struct { ts *types.TipSet - nullRounds uint64 + nullRounds abi.ChainEpoch } func (m *Miner) GetBestMiningCandidate(ctx context.Context) (*MiningBase, error) { @@ -340,42 +342,18 @@ func (m *Miner) mineOne(ctx context.Context, addr address.Address, base *MiningB return b, nil } -func (m *Miner) computeVRF(ctx context.Context, addr address.Address, input []byte) ([]byte, error) { - w, err := m.getMinerWorker(ctx, addr, types.EmptyTSK) +func (m *Miner) computeTicket(ctx context.Context, addr address.Address, base *MiningBase) (*types.Ticket, error) { + w, err := m.api.StateMinerWorker(ctx, addr, types.EmptyTSK) if err != nil { return nil, err } - return gen.ComputeVRF(ctx, m.api.WalletSign, w, addr, gen.DSepTicket, input) -} - -func (m *Miner) getMinerWorker(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) { - ret, err := m.api.StateCall(ctx, &types.Message{ - From: addr, - To: addr, - Method: actors.MAMethods.GetWorkerAddr, - }, tsk) + input, err := m.api.ChainGetRandomness(ctx, base.ts.Key(), crypto.DomainSeparationTag_TicketProduction, base.ts.Height(), addr.Bytes()) if err != nil { - return address.Undef, xerrors.Errorf("failed to get miner worker addr: %w", err) + return nil, err } - if ret.ExitCode != 0 { - return address.Undef, xerrors.Errorf("failed to get miner worker addr (exit code %d)", ret.ExitCode) - } - - w, err := address.NewFromBytes(ret.Return) - if err != nil { - return address.Undef, xerrors.Errorf("GetWorkerAddr returned malformed address: %w", err) - } - - return w, nil -} - -func (m *Miner) computeTicket(ctx context.Context, addr address.Address, base *MiningBase) (*types.Ticket, error) { - - vrfBase := base.ts.MinTicket().VRFProof - - vrfOut, err := m.computeVRF(ctx, addr, vrfBase) + vrfOut, err := gen.ComputeVRF(ctx, m.api.WalletSign, w, input) if err != nil { return nil, err } diff --git a/node/builder.go b/node/builder.go index 8214819d7..919169f40 100644 --- a/node/builder.go +++ b/node/builder.go @@ -3,6 +3,7 @@ package node import ( "context" "errors" + "github.com/filecoin-project/specs-actors/actors/runtime" "time" sectorbuilder "github.com/filecoin-project/go-sectorbuilder" @@ -37,6 +38,7 @@ import ( "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/vm" "github.com/filecoin-project/lotus/chain/wallet" + "github.com/filecoin-project/lotus/lib/peermgr" _ "github.com/filecoin-project/lotus/lib/sigs/bls" _ "github.com/filecoin-project/lotus/lib/sigs/secp" "github.com/filecoin-project/lotus/markets/storageadapter" @@ -50,8 +52,7 @@ import ( "github.com/filecoin-project/lotus/node/modules/lp2p" "github.com/filecoin-project/lotus/node/modules/testing" "github.com/filecoin-project/lotus/node/repo" - "github.com/filecoin-project/lotus/paych" - "github.com/filecoin-project/lotus/peermgr" + "github.com/filecoin-project/lotus/paychmgr" "github.com/filecoin-project/lotus/storage" "github.com/filecoin-project/lotus/storage/sealing" "github.com/filecoin-project/lotus/storage/sectorblocks" @@ -203,7 +204,7 @@ func Online() Option { Override(HandleIncomingMessagesKey, modules.HandleIncomingMessages), Override(new(sectorbuilder.Verifier), sectorbuilder.ProofVerifier), - Override(new(*types.VMSyscalls), vm.Syscalls), + Override(new(runtime.Syscalls), vm.Syscalls), Override(new(*store.ChainStore), modules.ChainStore), Override(new(*stmgr.StateManager), stmgr.NewStateManager), Override(new(*wallet.Wallet), wallet.NewWallet), @@ -244,8 +245,8 @@ func Online() Option { Override(RegisterClientValidatorKey, modules.RegisterClientValidator), Override(RunDealClientKey, modules.RunDealClient), - Override(new(*paych.Store), paych.NewStore), - Override(new(*paych.Manager), paych.NewManager), + Override(new(*paychmgr.Store), paychmgr.NewStore), + Override(new(*paychmgr.Manager), paychmgr.NewManager), Override(new(*market.FundMgr), market.NewFundMgr), ), diff --git a/node/hello/cbor_gen.go b/node/hello/cbor_gen.go index 05992ea01..da4bf0c00 100644 --- a/node/hello/cbor_gen.go +++ b/node/hello/cbor_gen.go @@ -6,7 +6,8 @@ import ( "fmt" "io" - "github.com/ipfs/go-cid" + "github.com/filecoin-project/specs-actors/actors/abi" + cid "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" xerrors "golang.org/x/xerrors" ) @@ -36,12 +37,18 @@ func (t *HelloMessage) MarshalCBOR(w io.Writer) error { } } - // t.HeaviestTipSetHeight (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.HeaviestTipSetHeight))); err != nil { - return err + // t.HeaviestTipSetHeight (abi.ChainEpoch) (int64) + if t.HeaviestTipSetHeight >= 0 { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.HeaviestTipSetHeight))); err != nil { + return err + } + } else { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajNegativeInt, uint64(-t.HeaviestTipSetHeight)-1)); err != nil { + return err + } } - // t.HeaviestTipSetWeight (types.BigInt) (struct) + // t.HeaviestTipSetWeight (big.Int) (struct) if err := t.HeaviestTipSetWeight.MarshalCBOR(w); err != nil { return err } @@ -96,17 +103,32 @@ func (t *HelloMessage) UnmarshalCBOR(r io.Reader) error { t.HeaviestTipSet[i] = c } - // t.HeaviestTipSetHeight (uint64) (uint64) + // t.HeaviestTipSetHeight (abi.ChainEpoch) (int64) + { + maj, extra, err := cbg.CborReadHeader(br) + var extraI int64 + if err != nil { + return err + } + switch maj { + case cbg.MajUnsignedInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 positive overflow") + } + case cbg.MajNegativeInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 negative oveflow") + } + extraI = -1 - extraI + default: + return fmt.Errorf("wrong type for int64 field: %d", maj) + } - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err + t.HeaviestTipSetHeight = abi.ChainEpoch(extraI) } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.HeaviestTipSetHeight = uint64(extra) - // t.HeaviestTipSetWeight (types.BigInt) (struct) + // t.HeaviestTipSetWeight (big.Int) (struct) { diff --git a/node/hello/hello.go b/node/hello/hello.go index d0aa16d67..c1802f7cb 100644 --- a/node/hello/hello.go +++ b/node/hello/hello.go @@ -2,8 +2,10 @@ package hello import ( "context" + "github.com/filecoin-project/specs-actors/actors/abi" "time" + "github.com/filecoin-project/specs-actors/actors/abi/big" "github.com/ipfs/go-cid" logging "github.com/ipfs/go-log/v2" "github.com/libp2p/go-libp2p-core/host" @@ -15,7 +17,7 @@ import ( "github.com/filecoin-project/lotus/chain" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/peermgr" + "github.com/filecoin-project/lotus/lib/peermgr" ) const ProtocolID = "/fil/hello/1.0.0" @@ -24,8 +26,8 @@ var log = logging.Logger("hello") type HelloMessage struct { HeaviestTipSet []cid.Cid - HeaviestTipSetHeight uint64 - HeaviestTipSetWeight types.BigInt + HeaviestTipSetHeight abi.ChainEpoch + HeaviestTipSetWeight big.Int GenesisHash cid.Cid } type LatencyMessage struct { diff --git a/node/impl/client/client.go b/node/impl/client/client.go index fda3e2a8a..b6a838ed9 100644 --- a/node/impl/client/client.go +++ b/node/impl/client/client.go @@ -4,9 +4,9 @@ import ( "context" "errors" "io" - "math" "os" + "github.com/filecoin-project/specs-actors/actors/abi/big" "golang.org/x/xerrors" "github.com/ipfs/go-blockservice" @@ -25,8 +25,9 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-fil-markets/retrievalmarket" - "github.com/filecoin-project/go-fil-markets/shared/tokenamount" "github.com/filecoin-project/go-fil-markets/storagemarket" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/store" @@ -37,6 +38,8 @@ import ( "github.com/filecoin-project/lotus/node/modules/dtypes" ) +const dealStartBuffer abi.ChainEpoch = 10000 // TODO: allow setting + type API struct { fx.In @@ -74,15 +77,22 @@ func (a *API) ClientStartDeal(ctx context.Context, data cid.Cid, addr address.Ad return nil, xerrors.Errorf("failed getting miner worker: %w", err) } providerInfo := utils.NewStorageProviderInfo(miner, mw, 0, pid) + ts, err := a.ChainHead(ctx) + if err != nil { + return nil, xerrors.Errorf("failed getting chain height: %w", err) + } result, err := a.SMDealClient.ProposeStorageDeal( ctx, addr, &providerInfo, - data, - storagemarket.Epoch(math.MaxUint64), - storagemarket.Epoch(blocksDuration), - utils.ToSharedTokenAmount(epochPrice), - tokenamount.Empty) + &storagemarket.DataRef{ + TransferType: storagemarket.TTGraphsync, + Root: data, + }, + ts.Height()+dealStartBuffer, + ts.Height()+dealStartBuffer+abi.ChainEpoch(blocksDuration), + epochPrice, + big.Zero()) if err != nil { return nil, xerrors.Errorf("failed to start deal: %w", err) @@ -104,11 +114,11 @@ func (a *API) ClientListDeals(ctx context.Context) ([]api.DealInfo, error) { State: v.State, Provider: v.Proposal.Provider, - PieceRef: v.Proposal.PieceRef, - Size: v.Proposal.PieceSize, + PieceRef: v.Proposal.PieceCID.Bytes(), + Size: uint64(v.Proposal.PieceSize.Unpadded()), - PricePerEpoch: utils.FromSharedTokenAmount(v.Proposal.StoragePricePerEpoch), - Duration: v.Proposal.Duration, + PricePerEpoch: v.Proposal.StoragePricePerEpoch, + Duration: uint64(v.Proposal.Duration()), } } @@ -125,10 +135,10 @@ func (a *API) ClientGetDealInfo(ctx context.Context, d cid.Cid) (*api.DealInfo, ProposalCid: v.ProposalCid, State: v.State, Provider: v.Proposal.Provider, - PieceRef: v.Proposal.PieceRef, - Size: v.Proposal.PieceSize, - PricePerEpoch: utils.FromSharedTokenAmount(v.Proposal.StoragePricePerEpoch), - Duration: v.Proposal.Duration, + PieceRef: v.Proposal.PieceCID.Bytes(), + Size: uint64(v.Proposal.PieceSize.Unpadded()), + PricePerEpoch: v.Proposal.StoragePricePerEpoch, + Duration: uint64(v.Proposal.Duration()), }, nil } @@ -161,7 +171,7 @@ func (a *API) ClientFindData(ctx context.Context, root cid.Cid) ([]api.QueryOffe out[k] = api.QueryOffer{ Root: root, Size: queryResponse.Size, - MinPrice: utils.FromSharedTokenAmount(queryResponse.PieceRetrievalPrice()), + MinPrice: queryResponse.PieceRetrievalPrice(), PaymentInterval: queryResponse.MaxPaymentInterval, PaymentIntervalIncrease: queryResponse.MaxPaymentIntervalIncrease, Miner: p.Address, // TODO: check @@ -293,8 +303,8 @@ func (a *API) ClientRetrieve(ctx context.Context, order api.RetrievalOrder, path a.Retrieval.Retrieve( ctx, order.Root, - retrievalmarket.NewParamsV0(types.BigDiv(order.Total, types.NewInt(order.Size)).Int, order.PaymentInterval, order.PaymentIntervalIncrease), - utils.ToSharedTokenAmount(order.Total), + retrievalmarket.NewParamsV0(types.BigDiv(order.Total, types.NewInt(order.Size)), order.PaymentInterval, order.PaymentIntervalIncrease), + order.Total, order.MinerPeerID, order.Client, order.Miner) @@ -320,11 +330,11 @@ func (a *API) ClientRetrieve(ctx context.Context, order api.RetrievalOrder, path return files.WriteTo(file, path) } -func (a *API) ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*types.SignedStorageAsk, error) { +func (a *API) ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.SignedStorageAsk, error) { info := utils.NewStorageProviderInfo(miner, address.Undef, 0, p) signedAsk, err := a.SMDealClient.GetAsk(ctx, info) if err != nil { return nil, err } - return utils.FromSignedStorageAsk(signedAsk) + return signedAsk, nil } diff --git a/node/impl/full/chain.go b/node/impl/full/chain.go index 6ec97a5be..e88b39d9f 100644 --- a/node/impl/full/chain.go +++ b/node/impl/full/chain.go @@ -8,6 +8,8 @@ import ( "strings" "github.com/filecoin-project/go-amt-ipld/v2" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/crypto" "github.com/ipfs/go-blockservice" "github.com/ipfs/go-cid" "github.com/ipfs/go-hamt-ipld" @@ -46,8 +48,13 @@ func (a *ChainAPI) ChainHead(context.Context) (*types.TipSet, error) { return a.Chain.GetHeaviestTipSet(), nil } -func (a *ChainAPI) ChainGetRandomness(ctx context.Context, pts types.TipSetKey, round int64) ([]byte, error) { - return a.Chain.GetRandomness(ctx, pts.Cids(), round) +func (a *ChainAPI) ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) { + pts, err := a.Chain.LoadTipSet(tsk) + if err != nil { + return nil, xerrors.Errorf("loading tipset key: %w", err) + } + + return a.Chain.GetRandomness(ctx, pts.Cids(), personalization, int64(randEpoch), entropy) } func (a *ChainAPI) ChainGetBlock(ctx context.Context, msg cid.Cid) (*types.BlockHeader, error) { @@ -157,7 +164,7 @@ func (a *ChainAPI) ChainGetParentReceipts(ctx context.Context, bcid cid.Cid) ([] return out, nil } -func (a *ChainAPI) ChainGetTipSetByHeight(ctx context.Context, h uint64, tsk types.TipSetKey) (*types.TipSet, error) { +func (a *ChainAPI) ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) (*types.TipSet, error) { ts, err := a.Chain.GetTipSetFromKey(tsk) if err != nil { return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err) @@ -217,7 +224,7 @@ func resolveOnce(bs blockstore.Blockstore) func(ctx context.Context, ds ipld.Nod if strings.HasPrefix(names[0], "@H:") { cst := cbor.NewCborStore(bs) - h, err := hamt.LoadNode(ctx, cst, nd.Cid()) + h, err := hamt.LoadNode(ctx, cst, nd.Cid(), hamt.UseTreeBitWidth(5)) if err != nil { return nil, nil, xerrors.Errorf("resolving hamt link: %w", err) } diff --git a/node/impl/full/state.go b/node/impl/full/state.go index c03a94153..9fb2e4933 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -6,20 +6,25 @@ import ( "fmt" "strconv" - "github.com/filecoin-project/go-amt-ipld/v2" - 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" "github.com/libp2p/go-libp2p-core/peer" + "github.com/prometheus/common/log" cbg "github.com/whyrusleeping/cbor-gen" "go.uber.org/fx" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-amt-ipld/v2" + "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" + "github.com/filecoin-project/specs-actors/actors/builtin/market" + "github.com/filecoin-project/specs-actors/actors/builtin/miner" + samsig "github.com/filecoin-project/specs-actors/actors/builtin/multisig" + "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/stmgr" @@ -99,15 +104,15 @@ func (a *StateAPI) StateMinerPeerID(ctx context.Context, m address.Address, tsk return stmgr.GetMinerPeerID(ctx, a.StateManager, ts, m) } -func (a *StateAPI) StateMinerElectionPeriodStart(ctx context.Context, actor address.Address, tsk types.TipSetKey) (uint64, error) { +func (a *StateAPI) StateMinerPostState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*miner.PoStState, error) { ts, err := a.Chain.GetTipSetFromKey(tsk) if err != nil { - return 0, xerrors.Errorf("loading tipset %s: %w", tsk, err) + return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err) } - return stmgr.GetMinerElectionPeriodStart(ctx, a.StateManager, ts, actor) + return stmgr.GetMinerPostState(ctx, a.StateManager, ts, actor) } -func (a *StateAPI) StateMinerSectorSize(ctx context.Context, actor address.Address, tsk types.TipSetKey) (uint64, error) { +func (a *StateAPI) StateMinerSectorSize(ctx context.Context, actor address.Address, tsk types.TipSetKey) (abi.SectorSize, error) { ts, err := a.Chain.GetTipSetFromKey(tsk) if err != nil { return 0, xerrors.Errorf("loading tipset %s: %w", tsk, err) @@ -115,7 +120,7 @@ func (a *StateAPI) StateMinerSectorSize(ctx context.Context, actor address.Addre return stmgr.GetMinerSectorSize(ctx, a.StateManager, ts, actor) } -func (a *StateAPI) StateMinerFaults(ctx context.Context, addr address.Address, tsk types.TipSetKey) ([]uint64, error) { +func (a *StateAPI) StateMinerFaults(ctx context.Context, addr address.Address, tsk types.TipSetKey) ([]abi.SectorNumber, error) { ts, err := a.Chain.GetTipSetFromKey(tsk) if err != nil { return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err) @@ -124,7 +129,7 @@ func (a *StateAPI) StateMinerFaults(ctx context.Context, addr address.Address, t } func (a *StateAPI) StatePledgeCollateral(ctx context.Context, tsk types.TipSetKey) (types.BigInt, error) { - ts, err := a.Chain.GetTipSetFromKey(tsk) + /*ts, err := a.Chain.GetTipSetFromKey(tsk) if err != nil { return types.EmptyInt, xerrors.Errorf("loading tipset %s: %w", tsk, err) } @@ -149,7 +154,9 @@ func (a *StateAPI) StatePledgeCollateral(ctx context.Context, tsk types.TipSetKe return types.NewInt(0), xerrors.Errorf("failed to get miner worker addr (exit code %d)", ret.ExitCode) } - return types.BigFromBytes(ret.Return), nil + return types.BigFromBytes(ret.Return), nil*/ + log.Error("TODO StatePledgeCollateral") + return big.Zero(), nil } func (a *StateAPI) StateCall(ctx context.Context, msg *types.Message, tsk types.TipSetKey) (*api.MethodCall, error) { @@ -250,7 +257,7 @@ func (a *StateAPI) StateReadState(ctx context.Context, act *types.Actor, tsk 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, parentsTSK types.TipSetKey, 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, parentsTSK types.TipSetKey, ticket *types.Ticket, proof *types.EPostProof, msgs []*types.SignedMessage, height abi.ChainEpoch, ts uint64) (*types.BlockMsg, error) { parents, err := a.Chain.GetTipSetFromKey(parentsTSK) if err != nil { return nil, xerrors.Errorf("loading tipset %s: %w", parentsTSK, err) @@ -310,42 +317,55 @@ func (a *StateAPI) StateListActors(ctx context.Context, tsk types.TipSetKey) ([] return a.StateManager.ListAllActors(ctx, ts) } -func (a *StateAPI) StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (actors.StorageParticipantBalance, error) { +func (a *StateAPI) StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MarketBalance, error) { ts, err := a.Chain.GetTipSetFromKey(tsk) if err != nil { - return actors.StorageParticipantBalance{}, xerrors.Errorf("loading tipset %s: %w", tsk, err) + return api.MarketBalance{}, xerrors.Errorf("loading tipset %s: %w", tsk, err) } return a.StateManager.MarketBalance(ctx, addr, ts) } -func (a *StateAPI) StateMarketParticipants(ctx context.Context, tsk types.TipSetKey) (map[string]actors.StorageParticipantBalance, error) { - out := map[string]actors.StorageParticipantBalance{} +func (a *StateAPI) StateMarketParticipants(ctx context.Context, tsk types.TipSetKey) (map[string]api.MarketBalance, error) { + out := map[string]api.MarketBalance{} - var state actors.StorageMarketState + var state market.State ts, err := a.Chain.GetTipSetFromKey(tsk) if err != nil { return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err) } - if _, err := a.StateManager.LoadActorState(ctx, actors.StorageMarketAddress, &state, ts); err != nil { + if _, err := a.StateManager.LoadActorState(ctx, builtin.StorageMarketActorAddr, &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, hamt.UseTreeBitWidth(5)) // todo: adt map + if err != nil { + return nil, err + } + locked, err := hamt.LoadNode(ctx, cst, state.EscrowTable, hamt.UseTreeBitWidth(5)) 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 { @@ -354,30 +374,43 @@ func (a *StateAPI) StateMarketParticipants(ctx context.Context, tsk types.TipSet return out, nil } -func (a *StateAPI) StateMarketDeals(ctx context.Context, tsk types.TipSetKey) (map[string]actors.OnChainDeal, error) { - out := map[string]actors.OnChainDeal{} +func (a *StateAPI) StateMarketDeals(ctx context.Context, tsk types.TipSetKey) (map[string]api.MarketDeal, error) { + out := map[string]api.MarketDeal{} - var state actors.StorageMarketState + var state market.State ts, err := a.Chain.GetTipSetFromKey(tsk) if err != nil { return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err) } - if _, err := a.StateManager.LoadActorState(ctx, actors.StorageMarketAddress, &state, ts); err != nil { + if _, err := a.StateManager.LoadActorState(ctx, builtin.StorageMarketActorAddr, &state, ts); err != nil { return nil, err } 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 + } + + sa, err := amt.LoadAMT(ctx, blks, state.States) 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 } - out[strconv.FormatInt(int64(i), 10)] = d + + var s market.DealState + if err := sa.Get(ctx, i, &s); err != nil { + return err + } + out[strconv.FormatInt(int64(i), 10)] = api.MarketDeal{ + Proposal: d, + State: s, + } return nil }); err != nil { return nil, err @@ -385,7 +418,7 @@ func (a *StateAPI) StateMarketDeals(ctx context.Context, tsk types.TipSetKey) (m return out, nil } -func (a *StateAPI) StateMarketStorageDeal(ctx context.Context, dealId uint64, tsk types.TipSetKey) (*actors.OnChainDeal, error) { +func (a *StateAPI) StateMarketStorageDeal(ctx context.Context, dealId abi.DealID, tsk types.TipSetKey) (*api.MarketDeal, error) { ts, err := a.Chain.GetTipSetFromKey(tsk) if err != nil { return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err) @@ -396,12 +429,12 @@ func (a *StateAPI) StateMarketStorageDeal(ctx context.Context, dealId uint64, ts func (a *StateAPI) StateChangedActors(ctx context.Context, old cid.Cid, new cid.Cid) (map[string]types.Actor, error) { cst := cbor.NewCborStore(a.Chain.Blockstore()) - nh, err := hamt.LoadNode(ctx, cst, new) + nh, err := hamt.LoadNode(ctx, cst, new, hamt.UseTreeBitWidth(5)) if err != nil { return nil, err } - oh, err := hamt.LoadNode(ctx, cst, old) + oh, err := hamt.LoadNode(ctx, cst, old, hamt.UseTreeBitWidth(5)) if err != nil { return nil, err } @@ -452,7 +485,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, tsk types.TipSetKey, toheight uint64) ([]cid.Cid, error) { +func (a *StateAPI) StateListMessages(ctx context.Context, match *types.Message, tsk types.TipSetKey, toheight abi.ChainEpoch) ([]cid.Cid, error) { ts, err := a.Chain.GetTipSetFromKey(tsk) if err != nil { return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err) @@ -505,7 +538,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, tsk types.TipSetKey) (cid.Cid, error) { +func (a *StateAPI) StateCompute(ctx context.Context, height abi.ChainEpoch, msgs []*types.Message, tsk types.TipSetKey) (cid.Cid, error) { ts, err := a.Chain.GetTipSetFromKey(tsk) if err != nil { return cid.Undef, xerrors.Errorf("loading tipset %s: %w", tsk, err) @@ -519,13 +552,13 @@ func (a *StateAPI) MsigGetAvailableBalance(ctx context.Context, addr address.Add return types.EmptyInt, xerrors.Errorf("loading tipset %s: %w", tsk, err) } - 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) } - if act.Code != actors.MultisigCodeCid { + if act.Code != builtin.MultisigActorCodeID { return types.EmptyInt, fmt.Errorf("given actor was not a multisig") } @@ -533,12 +566,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/node/impl/full/wallet.go b/node/impl/full/wallet.go index b30a55f38..e9266c788 100644 --- a/node/impl/full/wallet.go +++ b/node/impl/full/wallet.go @@ -4,6 +4,8 @@ import ( "context" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/specs-actors/actors/crypto" + "github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/wallet" @@ -19,7 +21,7 @@ type WalletAPI struct { Wallet *wallet.Wallet } -func (a *WalletAPI) WalletNew(ctx context.Context, typ string) (address.Address, error) { +func (a *WalletAPI) WalletNew(ctx context.Context, typ crypto.SigType) (address.Address, error) { return a.Wallet.GenerateKey(typ) } @@ -35,7 +37,7 @@ func (a *WalletAPI) WalletBalance(ctx context.Context, addr address.Address) (ty return a.StateManager.GetBalance(addr, nil) } -func (a *WalletAPI) WalletSign(ctx context.Context, k address.Address, msg []byte) (*types.Signature, error) { +func (a *WalletAPI) WalletSign(ctx context.Context, k address.Address, msg []byte) (*crypto.Signature, error) { return a.Wallet.Sign(ctx, k, msg) } diff --git a/node/impl/paych/paych.go b/node/impl/paych/paych.go index 92ffdd9f5..17464f231 100644 --- a/node/impl/paych/paych.go +++ b/node/impl/paych/paych.go @@ -4,6 +4,8 @@ import ( "context" "fmt" + "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/filecoin-project/specs-actors/actors/builtin/paych" "github.com/ipfs/go-cid" "go.uber.org/fx" "golang.org/x/xerrors" @@ -13,7 +15,7 @@ import ( "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/types" full "github.com/filecoin-project/lotus/node/impl/full" - "github.com/filecoin-project/lotus/paych" + "github.com/filecoin-project/lotus/paychmgr" ) type PaychAPI struct { @@ -23,7 +25,7 @@ type PaychAPI struct { full.WalletAPI full.ChainAPI - PaychMgr *paych.Manager + PaychMgr *paychmgr.Manager } func (a *PaychAPI) PaychGet(ctx context.Context, from, to address.Address, ensureFunds types.BigInt) (*api.ChannelInfo, error) { @@ -57,16 +59,16 @@ func (a *PaychAPI) PaychNewPayment(ctx context.Context, from, to address.Address return nil, err } - svs := make([]*types.SignedVoucher, len(vouchers)) + svs := make([]*paych.SignedVoucher, len(vouchers)) for i, v := range vouchers { - sv, err := a.paychVoucherCreate(ctx, ch.Channel, types.SignedVoucher{ + sv, err := a.paychVoucherCreate(ctx, ch.Channel, paych.SignedVoucher{ Amount: v.Amount, - Lane: lane, + Lane: uint64(lane), - Extra: v.Extra, - TimeLock: v.TimeLock, - MinCloseHeight: v.MinClose, + Extra: v.Extra, + TimeLock: v.TimeLock, + MinSettleHeight: v.MinSettle, }) if err != nil { return nil, err @@ -103,6 +105,8 @@ func (a *PaychAPI) PaychStatus(ctx context.Context, pch address.Address) (*api.P } func (a *PaychAPI) PaychClose(ctx context.Context, addr address.Address) (cid.Cid, error) { + panic("TODO Settle logic") + ci, err := a.PaychMgr.GetChannelInfo(addr) if err != nil { return cid.Undef, err @@ -117,7 +121,7 @@ func (a *PaychAPI) PaychClose(ctx context.Context, addr address.Address) (cid.Ci To: addr, From: ci.Control, Value: types.NewInt(0), - Method: actors.PCAMethods.Close, + Method: builtin.MethodsPaych.Settle, Nonce: nonce, GasLimit: types.NewInt(500), @@ -136,15 +140,15 @@ func (a *PaychAPI) PaychClose(ctx context.Context, addr address.Address) (cid.Ci return smsg.Cid(), nil } -func (a *PaychAPI) PaychVoucherCheckValid(ctx context.Context, ch address.Address, sv *types.SignedVoucher) error { +func (a *PaychAPI) PaychVoucherCheckValid(ctx context.Context, ch address.Address, sv *paych.SignedVoucher) error { return a.PaychMgr.CheckVoucherValid(ctx, ch, sv) } -func (a *PaychAPI) PaychVoucherCheckSpendable(ctx context.Context, ch address.Address, sv *types.SignedVoucher, secret []byte, proof []byte) (bool, error) { +func (a *PaychAPI) PaychVoucherCheckSpendable(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, secret []byte, proof []byte) (bool, error) { return a.PaychMgr.CheckVoucherSpendable(ctx, ch, sv, secret, proof) } -func (a *PaychAPI) PaychVoucherAdd(ctx context.Context, ch address.Address, sv *types.SignedVoucher, proof []byte, minDelta types.BigInt) (types.BigInt, error) { +func (a *PaychAPI) PaychVoucherAdd(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, proof []byte, minDelta types.BigInt) (types.BigInt, error) { _ = a.PaychMgr.TrackInboundChannel(ctx, ch) // TODO: expose those calls return a.PaychMgr.AddVoucher(ctx, ch, sv, proof, minDelta) @@ -155,11 +159,11 @@ func (a *PaychAPI) PaychVoucherAdd(ctx context.Context, ch address.Address, sv * // that will be used to create the voucher, so if previous vouchers exist, the // actual additional value of this voucher will only be the difference between // the two. -func (a *PaychAPI) PaychVoucherCreate(ctx context.Context, pch address.Address, amt types.BigInt, lane uint64) (*types.SignedVoucher, error) { - return a.paychVoucherCreate(ctx, pch, types.SignedVoucher{Amount: amt, Lane: lane}) +func (a *PaychAPI) PaychVoucherCreate(ctx context.Context, pch address.Address, amt types.BigInt, lane uint64) (*paych.SignedVoucher, error) { + return a.paychVoucherCreate(ctx, pch, paych.SignedVoucher{Amount: amt, Lane: lane}) } -func (a *PaychAPI) paychVoucherCreate(ctx context.Context, pch address.Address, voucher types.SignedVoucher) (*types.SignedVoucher, error) { +func (a *PaychAPI) paychVoucherCreate(ctx context.Context, pch address.Address, voucher paych.SignedVoucher) (*paych.SignedVoucher, error) { ci, err := a.PaychMgr.GetChannelInfo(pch) if err != nil { return nil, xerrors.Errorf("get channel info: %w", err) @@ -192,13 +196,13 @@ func (a *PaychAPI) paychVoucherCreate(ctx context.Context, pch address.Address, return sv, nil } -func (a *PaychAPI) PaychVoucherList(ctx context.Context, pch address.Address) ([]*types.SignedVoucher, error) { +func (a *PaychAPI) PaychVoucherList(ctx context.Context, pch address.Address) ([]*paych.SignedVoucher, error) { vi, err := a.PaychMgr.ListVouchers(ctx, pch) if err != nil { return nil, err } - out := make([]*types.SignedVoucher, len(vi)) + out := make([]*paych.SignedVoucher, len(vi)) for k, v := range vi { out[k] = v.Voucher } @@ -206,7 +210,7 @@ func (a *PaychAPI) PaychVoucherList(ctx context.Context, pch address.Address) ([ return out, nil } -func (a *PaychAPI) PaychVoucherSubmit(ctx context.Context, ch address.Address, sv *types.SignedVoucher) (cid.Cid, error) { +func (a *PaychAPI) PaychVoucherSubmit(ctx context.Context, ch address.Address, sv *paych.SignedVoucher) (cid.Cid, error) { ci, err := a.PaychMgr.GetChannelInfo(ch) if err != nil { return cid.Undef, err @@ -221,7 +225,7 @@ func (a *PaychAPI) PaychVoucherSubmit(ctx context.Context, ch address.Address, s return cid.Undef, fmt.Errorf("cant handle more advanced payment channel stuff yet") } - enc, err := actors.SerializeParams(&actors.PCAUpdateChannelStateParams{ + enc, err := actors.SerializeParams(&paych.UpdateChannelStateParams{ Sv: *sv, }) if err != nil { @@ -233,7 +237,7 @@ func (a *PaychAPI) PaychVoucherSubmit(ctx context.Context, ch address.Address, s To: ch, Value: types.NewInt(0), Nonce: nonce, - Method: actors.PCAMethods.UpdateChannelState, + Method: builtin.MethodsPaych.UpdateChannelState, Params: enc, GasLimit: types.NewInt(100000), GasPrice: types.NewInt(0), diff --git a/node/impl/storminer.go b/node/impl/storminer.go index 6f075a58f..f4847eade 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -10,6 +10,7 @@ import ( "os" "strconv" + "github.com/filecoin-project/specs-actors/actors/abi" "github.com/gorilla/mux" files "github.com/ipfs/go-ipfs-files" @@ -64,7 +65,7 @@ func (sm *StorageMinerAPI) remoteGetSector(w http.ResponseWriter, r *http.Reques return } - path, err := sm.SectorBuilder.SectorPath(fs.DataType(vars["type"]), id) + path, err := sm.SectorBuilder.SectorPath(fs.DataType(vars["type"]), abi.SectorNumber(id)) if err != nil { log.Error(err) w.WriteHeader(500) @@ -111,7 +112,7 @@ func (sm *StorageMinerAPI) remotePutSector(w http.ResponseWriter, r *http.Reques // This is going to get better with worker-to-worker transfers - path, err := sm.SectorBuilder.SectorPath(fs.DataType(vars["type"]), id) + path, err := sm.SectorBuilder.SectorPath(fs.DataType(vars["type"]), abi.SectorNumber(id)) if err != nil { if err != fs.ErrNotFound { log.Error(err) @@ -119,7 +120,7 @@ func (sm *StorageMinerAPI) remotePutSector(w http.ResponseWriter, r *http.Reques return } - path, err = sm.SectorBuilder.AllocSectorPath(fs.DataType(vars["type"]), id, true) + path, err = sm.SectorBuilder.AllocSectorPath(fs.DataType(vars["type"]), abi.SectorNumber(id), true) if err != nil { log.Error(err) w.WriteHeader(500) @@ -169,7 +170,7 @@ func (sm *StorageMinerAPI) ActorAddress(context.Context) (address.Address, error return sm.SectorBuilderConfig.Miner, nil } -func (sm *StorageMinerAPI) ActorSectorSize(ctx context.Context, addr address.Address) (uint64, error) { +func (sm *StorageMinerAPI) ActorSectorSize(ctx context.Context, addr address.Address) (abi.SectorSize, error) { return sm.Full.StateMinerSectorSize(ctx, addr, types.EmptyTSK) } @@ -177,15 +178,18 @@ func (sm *StorageMinerAPI) PledgeSector(ctx context.Context) error { return sm.Miner.PledgeSector() } -func (sm *StorageMinerAPI) SectorsStatus(ctx context.Context, sid uint64) (api.SectorInfo, error) { +func (sm *StorageMinerAPI) SectorsStatus(ctx context.Context, sid abi.SectorNumber) (api.SectorInfo, error) { info, err := sm.Miner.GetSectorInfo(sid) if err != nil { return api.SectorInfo{}, err } - deals := make([]uint64, len(info.Pieces)) + deals := make([]abi.DealID, len(info.Pieces)) for i, piece := range info.Pieces { - deals[i] = piece.DealID + if piece.DealID == nil { + continue + } + deals[i] = *piece.DealID } log := make([]api.SectorLog, len(info.Log)) @@ -215,13 +219,13 @@ func (sm *StorageMinerAPI) SectorsStatus(ctx context.Context, sid uint64) (api.S } // List all staged sectors -func (sm *StorageMinerAPI) SectorsList(context.Context) ([]uint64, error) { +func (sm *StorageMinerAPI) SectorsList(context.Context) ([]abi.SectorNumber, error) { sectors, err := sm.Miner.ListSectors() if err != nil { return nil, err } - out := make([]uint64, len(sectors)) + out := make([]abi.SectorNumber, len(sectors)) for i, sector := range sectors { out[i] = sector.SectorID } @@ -244,7 +248,7 @@ func (sm *StorageMinerAPI) SectorsRefs(context.Context) (map[string][]api.Sealed return out, nil } -func (sm *StorageMinerAPI) SectorsUpdate(ctx context.Context, id uint64, state api.SectorState) error { +func (sm *StorageMinerAPI) SectorsUpdate(ctx context.Context, id abi.SectorNumber, state api.SectorState) error { return sm.Miner.ForceSectorState(ctx, id, state) } diff --git a/node/modules/chain.go b/node/modules/chain.go index 24104425e..e466b2bf5 100644 --- a/node/modules/chain.go +++ b/node/modules/chain.go @@ -3,6 +3,7 @@ package modules import ( "bytes" "context" + "github.com/filecoin-project/specs-actors/actors/runtime" "github.com/ipfs/go-bitswap" "github.com/ipfs/go-bitswap/network" @@ -86,7 +87,7 @@ func ChainGraphsync(mctx helpers.MetricsCtx, lc fx.Lifecycle, ibs dtypes.ChainGC return gs } -func ChainStore(lc fx.Lifecycle, bs dtypes.ChainBlockstore, ds dtypes.MetadataDS, syscalls *types.VMSyscalls) *store.ChainStore { +func ChainStore(lc fx.Lifecycle, bs dtypes.ChainBlockstore, ds dtypes.MetadataDS, syscalls runtime.Syscalls) *store.ChainStore { chain := store.NewChainStore(bs, ds, syscalls) if err := chain.Load(); err != nil { diff --git a/node/modules/client.go b/node/modules/client.go index 22b6bdab9..8fa27163e 100644 --- a/node/modules/client.go +++ b/node/modules/client.go @@ -36,7 +36,7 @@ import ( "github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/node/modules/helpers" "github.com/filecoin-project/lotus/node/repo" - "github.com/filecoin-project/lotus/paych" + "github.com/filecoin-project/lotus/paychmgr" ) func ClientFstore(r repo.LockedRepo) (dtypes.ClientFilestore, error) { @@ -117,7 +117,7 @@ func StorageClient(h host.Host, ibs dtypes.ClientBlockstore, r repo.LockedRepo, } // RetrievalClient creates a new retrieval client attached to the client blockstore -func RetrievalClient(h host.Host, bs dtypes.ClientBlockstore, pmgr *paych.Manager, payapi payapi.PaychAPI, resolver retrievalmarket.PeerResolver) retrievalmarket.RetrievalClient { +func RetrievalClient(h host.Host, bs dtypes.ClientBlockstore, pmgr *paychmgr.Manager, payapi payapi.PaychAPI, resolver retrievalmarket.PeerResolver) retrievalmarket.RetrievalClient { adapter := retrievaladapter.NewRetrievalClientNode(pmgr, payapi) network := rmnet.NewFromLibp2pHost(h) return retrievalimpl.NewClient(network, bs, adapter, resolver) diff --git a/node/modules/services.go b/node/modules/services.go index 0ae6d98f0..d87058b5d 100644 --- a/node/modules/services.go +++ b/node/modules/services.go @@ -17,10 +17,10 @@ import ( "github.com/filecoin-project/lotus/chain/messagepool" "github.com/filecoin-project/lotus/chain/sub" "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/lib/peermgr" "github.com/filecoin-project/lotus/node/hello" "github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/node/modules/helpers" - "github.com/filecoin-project/lotus/peermgr" ) const BlocksTopic = "/fil/blocks" diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index f40645e62..3deb7bc98 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -21,6 +21,7 @@ import ( "github.com/filecoin-project/go-sectorbuilder" "github.com/filecoin-project/go-sectorbuilder/fs" "github.com/filecoin-project/go-statestore" + "github.com/filecoin-project/specs-actors/actors/crypto" "github.com/ipfs/go-bitswap" "github.com/ipfs/go-bitswap/network" "github.com/ipfs/go-blockservice" @@ -60,7 +61,7 @@ func minerAddrFromDS(ds dtypes.MetadataDS) (address.Address, error) { } func GetParams(sbc *sectorbuilder.Config) error { - if err := paramfetch.GetParams(build.ParametersJson(), sbc.SectorSize); err != nil { + if err := paramfetch.GetParams(build.ParametersJson(), uint64(sbc.SectorSize)); err != nil { return xerrors.Errorf("fetching proof parameters: %w", err) } @@ -273,7 +274,7 @@ func SealTicketGen(api api.FullNode) sealing.TicketFn { return nil, xerrors.Errorf("getting head ts for SealTicket failed: %w", err) } - r, err := api.ChainGetRandomness(ctx, ts.Key(), int64(ts.Height())-build.SealRandomnessLookback) + r, err := api.ChainGetRandomness(ctx, ts.Key(), crypto.DomainSeparationTag_SealRandomness, ts.Height()-build.SealRandomnessLookback, nil) if err != nil { return nil, xerrors.Errorf("getting randomness for SealTicket failed: %w", err) } @@ -284,7 +285,7 @@ func SealTicketGen(api api.FullNode) sealing.TicketFn { } return §orbuilder.SealTicket{ - BlockHeight: ts.Height(), + BlockHeight: uint64(ts.Height() - build.SealRandomnessLookback), TicketBytes: tkt, }, nil } diff --git a/node/modules/testing/genesis.go b/node/modules/testing/genesis.go index a5cc2e68b..e51f1b2c4 100644 --- a/node/modules/testing/genesis.go +++ b/node/modules/testing/genesis.go @@ -15,14 +15,14 @@ import ( offline "github.com/ipfs/go-ipfs-exchange-offline" logging "github.com/ipfs/go-log/v2" "github.com/ipfs/go-merkledag" - "github.com/libp2p/go-libp2p-core/peer" "github.com/mitchellh/go-homedir" "golang.org/x/xerrors" - "github.com/filecoin-project/go-address" + "github.com/filecoin-project/specs-actors/actors/runtime" + "github.com/filecoin-project/lotus/chain/gen" + genesis2 "github.com/filecoin-project/lotus/chain/gen/genesis" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/chain/wallet" "github.com/filecoin-project/lotus/genesis" "github.com/filecoin-project/lotus/node/modules" "github.com/filecoin-project/lotus/node/modules/dtypes" @@ -30,28 +30,11 @@ import ( var glog = logging.Logger("genesis") -func MakeGenesisMem(out io.Writer, gmc *gen.GenMinerCfg) func(bs dtypes.ChainBlockstore, w *wallet.Wallet, syscalls *types.VMSyscalls) modules.Genesis { - return func(bs dtypes.ChainBlockstore, w *wallet.Wallet, syscalls *types.VMSyscalls) modules.Genesis { +func MakeGenesisMem(out io.Writer, template genesis.Template) func(bs dtypes.ChainBlockstore, syscalls runtime.Syscalls) modules.Genesis { + return func(bs dtypes.ChainBlockstore, syscalls runtime.Syscalls) modules.Genesis { return func() (*types.BlockHeader, error) { glog.Warn("Generating new random genesis block, note that this SHOULD NOT happen unless you are setting up new network") - defk, err := w.GenerateKey(types.KTBLS) - if err != nil { - return nil, err - } - - alloc := map[address.Address]types.BigInt{ - defk: types.FromFil(1000), - } - - for _, genm := range gmc.PreSeals { - waddr, err := w.Import(&genm.Key) - if err != nil { - return nil, err - } - alloc[waddr] = types.FromFil(10000) - } - - b, err := gen.MakeGenesisBlock(bs, syscalls, alloc, gmc, 100000) + b, err := genesis2.MakeGenesisBlock(context.TODO(), bs, syscalls, template) if err != nil { return nil, err } @@ -59,7 +42,7 @@ func MakeGenesisMem(out io.Writer, gmc *gen.GenMinerCfg) func(bs dtypes.ChainBlo blkserv := blockservice.New(bs, offl) dserv := merkledag.NewDAGService(blkserv) - if err := car.WriteCar(context.TODO(), dserv, []cid.Cid{b.Genesis.Cid()}, out); err != nil { + if err := car.WriteCarWithWalker(context.TODO(), dserv, []cid.Cid{b.Genesis.Cid()}, out, gen.CarWalkFunc); err != nil { return nil, err } @@ -68,74 +51,35 @@ func MakeGenesisMem(out io.Writer, gmc *gen.GenMinerCfg) func(bs dtypes.ChainBlo } } -func MakeGenesis(outFile, presealInfo, timestamp string) func(bs dtypes.ChainBlockstore, w *wallet.Wallet, syscalls *types.VMSyscalls) modules.Genesis { - return func(bs dtypes.ChainBlockstore, w *wallet.Wallet, syscalls *types.VMSyscalls) modules.Genesis { +func MakeGenesis(outFile, genesisTemplate string) func(bs dtypes.ChainBlockstore, syscalls runtime.Syscalls) modules.Genesis { + return func(bs dtypes.ChainBlockstore, syscalls runtime.Syscalls) modules.Genesis { return func() (*types.BlockHeader, error) { glog.Warn("Generating new random genesis block, note that this SHOULD NOT happen unless you are setting up new network") - presealInfo, err := homedir.Expand(presealInfo) + genesisTemplate, err := homedir.Expand(genesisTemplate) if err != nil { return nil, err } - fdata, err := ioutil.ReadFile(presealInfo) + fdata, err := ioutil.ReadFile(genesisTemplate) if err != nil { return nil, xerrors.Errorf("reading preseals json: %w", err) } - var preseals map[string]genesis.GenesisMiner - if err := json.Unmarshal(fdata, &preseals); err != nil { + var template genesis.Template + if err := json.Unmarshal(fdata, &template); err != nil { return nil, err } - var fakePeerIDs []peer.ID - minerAddresses := make([]address.Address, 0, len(preseals)) - for s := range preseals { - a, err := address.NewFromString(s) - if err != nil { - return nil, err - } - if a.Protocol() != address.ID { - return nil, xerrors.New("expected ID address") - } - minerAddresses = append(minerAddresses, a) - fakePeerIDs = append(fakePeerIDs, peer.ID("peer"+a.String())) + if template.Timestamp == 0 { + template.Timestamp = uint64(time.Now().Unix()) } - gmc := &gen.GenMinerCfg{ - PeerIDs: fakePeerIDs, - PreSeals: preseals, - MinerAddrs: minerAddresses, - } - - addrs := map[address.Address]types.BigInt{} - - for _, miner := range preseals { - if _, err := w.Import(&miner.Key); err != nil { - return nil, xerrors.Errorf("importing miner key: %w", err) - } - - _ = w.SetDefault(miner.Worker) - - addrs[miner.Worker] = types.FromFil(100000) - } - - ts := uint64(time.Now().Unix()) - if timestamp != "" { - t, err := time.Parse(time.RFC3339, timestamp) - if err != nil { - return nil, xerrors.Errorf("parsing input genesis timestamp: %w", err) - } - - glog.Infof("will use %s as the genesis timestamp", t) - ts = uint64(t.Unix()) - } - - b, err := gen.MakeGenesisBlock(bs, syscalls, addrs, gmc, ts) + b, err := genesis2.MakeGenesisBlock(context.TODO(), bs, syscalls, template) if err != nil { - return nil, err + return nil, xerrors.Errorf("make genesis block: %w", err) } - fmt.Println("GENESIS MINER ADDRESS: ", gmc.MinerAddrs[0].String()) + fmt.Printf("GENESIS MINER ADDRESS: t0%d\n", genesis2.MinerStart) f, err := os.OpenFile(outFile, os.O_CREATE|os.O_WRONLY, 0644) if err != nil { @@ -146,7 +90,7 @@ func MakeGenesis(outFile, presealInfo, timestamp string) func(bs dtypes.ChainBlo blkserv := blockservice.New(bs, offl) dserv := merkledag.NewDAGService(blkserv) - if err := car.WriteCar(context.TODO(), dserv, []cid.Cid{b.Genesis.Cid()}, f); err != nil { + if err := car.WriteCarWithWalker(context.TODO(), dserv, []cid.Cid{b.Genesis.Cid()}, f, gen.CarWalkFunc); err != nil { return nil, err } diff --git a/node/node_test.go b/node/node_test.go index 0ac3a17ab..f2e542fa3 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -10,9 +10,6 @@ import ( "testing" "time" - "github.com/filecoin-project/go-address" - sectorbuilder "github.com/filecoin-project/go-sectorbuilder" - "github.com/filecoin-project/lotus/build" "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/namespace" badger "github.com/ipfs/go-ds-badger2" @@ -22,14 +19,23 @@ import ( mocknet "github.com/libp2p/go-libp2p/p2p/net/mock" "github.com/stretchr/testify/require" + "github.com/filecoin-project/go-address" + 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" + saminer "github.com/filecoin-project/specs-actors/actors/builtin/miner" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/client" "github.com/filecoin-project/lotus/api/test" + "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors" - "github.com/filecoin-project/lotus/chain/gen" + genesis2 "github.com/filecoin-project/lotus/chain/gen/genesis" "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/chain/wallet" "github.com/filecoin-project/lotus/cmd/lotus-seed/seed" - "github.com/filecoin-project/lotus/genesis" + genesis "github.com/filecoin-project/lotus/genesis" "github.com/filecoin-project/lotus/lib/jsonrpc" "github.com/filecoin-project/lotus/miner" "github.com/filecoin-project/lotus/node" @@ -43,7 +49,7 @@ import ( func init() { _ = logging.SetLogLevel("*", "INFO") - build.SectorSizes = []uint64{1024} + build.SectorSizes = []abi.SectorSize{1024} build.MinimumMinerPower = 1024 } @@ -76,13 +82,13 @@ func testStorageNode(ctx context.Context, t *testing.T, waddr address.Address, a peerid, err := peer.IDFromPrivateKey(pk) require.NoError(t, err) - enc, err := actors.SerializeParams(&actors.UpdatePeerIDParams{PeerID: peerid}) + enc, err := actors.SerializeParams(&saminer.ChangePeerIDParams{NewID: peerid}) require.NoError(t, err) msg := &types.Message{ To: act, From: waddr, - Method: actors.MAMethods.UpdatePeerID, + Method: builtin.MethodsMiner.ChangePeerID, Params: enc, Value: types.NewInt(0), GasPrice: types.NewInt(0), @@ -152,14 +158,15 @@ func builder(t *testing.T, nFull int, storage []int) ([]test.TestNode, []test.Te } // PRESEAL SECTION, TRY TO REPLACE WITH BETTER IN THE FUTURE // TODO: would be great if there was a better way to fake the preseals - gmc := &gen.GenMinerCfg{ - PeerIDs: []peer.ID{minerPid}, // TODO: if we have more miners, need more peer IDs - PreSeals: map[string]genesis.GenesisMiner{}, - } + + var genms []genesis.Miner + var maddrs []address.Address + var genaccs []genesis.Actor + var keys []*wallet.Key var presealDirs []string for i := 0; i < len(storage); i++ { - maddr, err := address.NewIDAddress(300 + uint64(i)) + maddr, err := address.NewIDAddress(genesis2.MinerStart + uint64(i)) if err != nil { t.Fatal(err) } @@ -167,14 +174,32 @@ func builder(t *testing.T, nFull int, storage []int) ([]test.TestNode, []test.Te if err != nil { t.Fatal(err) } - genm, err := seed.PreSeal(maddr, 1024, 0, 1, tdir, []byte("make genesis mem random")) + genm, k, err := seed.PreSeal(maddr, 1024, 0, 2, tdir, []byte("make genesis mem random"), nil) if err != nil { t.Fatal(err) } + genm.PeerId = minerPid + wk, err := wallet.NewKey(*k) + if err != nil { + return nil, nil + } + + genaccs = append(genaccs, genesis.Actor{ + Type: genesis.TAccount, + Balance: big.NewInt(40000000000), + Meta: (&genesis.AccountMeta{Owner: wk.Address}).ActorMeta(), + }) + + keys = append(keys, wk) presealDirs = append(presealDirs, tdir) - gmc.MinerAddrs = append(gmc.MinerAddrs, maddr) - gmc.PreSeals[maddr.String()] = *genm + maddrs = append(maddrs, maddr) + genms = append(genms, *genm) + } + + templ := &genesis.Template{ + Accounts: genaccs, + Miners: genms, } // END PRESEAL SECTION @@ -182,7 +207,7 @@ func builder(t *testing.T, nFull int, storage []int) ([]test.TestNode, []test.Te for i := 0; i < nFull; i++ { var genesis node.Option if i == 0 { - genesis = node.Override(new(modules.Genesis), modtest.MakeGenesisMem(&genbuf, gmc)) + genesis = node.Override(new(modules.Genesis), modtest.MakeGenesisMem(&genbuf, *templ)) } else { genesis = node.Override(new(modules.Genesis), modules.LoadGenesis(genbuf.Bytes())) } @@ -214,9 +239,15 @@ func builder(t *testing.T, nFull int, storage []int) ([]test.TestNode, []test.Te } f := fulls[full] + if _, err := f.FullNode.WalletImport(ctx, &keys[i].KeyInfo); err != nil { + return nil, nil + } + if err := f.FullNode.WalletSetDefault(ctx, keys[i].Address); err != nil { + return nil, nil + } - genMiner := gmc.MinerAddrs[i] - wa := gmc.PreSeals[genMiner.String()].Worker + genMiner := maddrs[i] + wa := genms[i].Worker storers[i] = testStorageNode(ctx, t, wa, genMiner, pk, f, mn, node.Options()) @@ -271,14 +302,14 @@ func mockSbBuilder(t *testing.T, nFull int, storage []int) ([]test.TestNode, []t } // PRESEAL SECTION, TRY TO REPLACE WITH BETTER IN THE FUTURE // TODO: would be great if there was a better way to fake the preseals - gmc := &gen.GenMinerCfg{ - PeerIDs: []peer.ID{minerPid}, // TODO: if we have more miners, need more peer IDs - PreSeals: map[string]genesis.GenesisMiner{}, - } + var genms []genesis.Miner + var genaccs []genesis.Actor + var maddrs []address.Address var presealDirs []string + var keys []*wallet.Key for i := 0; i < len(storage); i++ { - maddr, err := address.NewIDAddress(300 + uint64(i)) + maddr, err := address.NewIDAddress(genesis2.MinerStart + uint64(i)) if err != nil { t.Fatal(err) } @@ -286,14 +317,31 @@ func mockSbBuilder(t *testing.T, nFull int, storage []int) ([]test.TestNode, []t if err != nil { t.Fatal(err) } - genm, err := sbmock.PreSeal(1024, maddr, 1) + genm, k, err := sbmock.PreSeal(1024, maddr, 2) if err != nil { t.Fatal(err) } + genm.PeerId = minerPid + wk, err := wallet.NewKey(*k) + if err != nil { + return nil, nil + } + + genaccs = append(genaccs, genesis.Actor{ + Type: genesis.TAccount, + Balance: big.NewInt(40000000000), + Meta: (&genesis.AccountMeta{Owner: wk.Address}).ActorMeta(), + }) + + keys = append(keys, wk) presealDirs = append(presealDirs, tdir) - gmc.MinerAddrs = append(gmc.MinerAddrs, maddr) - gmc.PreSeals[maddr.String()] = *genm + maddrs = append(maddrs, maddr) + genms = append(genms, *genm) + } + templ := &genesis.Template{ + Accounts: genaccs, + Miners: genms, } // END PRESEAL SECTION @@ -301,7 +349,7 @@ func mockSbBuilder(t *testing.T, nFull int, storage []int) ([]test.TestNode, []t for i := 0; i < nFull; i++ { var genesis node.Option if i == 0 { - genesis = node.Override(new(modules.Genesis), modtest.MakeGenesisMem(&genbuf, gmc)) + genesis = node.Override(new(modules.Genesis), modtest.MakeGenesisMem(&genbuf, *templ)) } else { genesis = node.Override(new(modules.Genesis), modules.LoadGenesis(genbuf.Bytes())) } @@ -320,9 +368,8 @@ func mockSbBuilder(t *testing.T, nFull int, storage []int) ([]test.TestNode, []t genesis, ) if err != nil { - t.Fatal(err) + t.Fatalf("%+v", err) } - } for i, full := range storage { @@ -335,9 +382,15 @@ func mockSbBuilder(t *testing.T, nFull int, storage []int) ([]test.TestNode, []t } f := fulls[full] + if _, err := f.FullNode.WalletImport(ctx, &keys[i].KeyInfo); err != nil { + return nil, nil + } + if err := f.FullNode.WalletSetDefault(ctx, keys[i].Address); err != nil { + return nil, nil + } - genMiner := gmc.MinerAddrs[i] - wa := gmc.PreSeals[genMiner.String()].Worker + genMiner := maddrs[i] + wa := genms[i].Worker storers[i] = testStorageNode(ctx, t, wa, genMiner, pk, f, mn, node.Options( node.Override(new(sectorbuilder.Interface), sbmock.NewMockSectorBuilder(5, build.SectorSizes[0])), @@ -394,7 +447,7 @@ func TestAPIRPC(t *testing.T) { func TestAPIDealFlow(t *testing.T) { logging.SetLogLevel("miner", "ERROR") - logging.SetLogLevel("chainstore", "ERROR") + //logging.SetLogLevel("chainstore", "ERROR") logging.SetLogLevel("chain", "ERROR") logging.SetLogLevel("sub", "ERROR") logging.SetLogLevel("storageminer", "ERROR") diff --git a/paych/cbor_gen.go b/paych/cbor_gen.go deleted file mode 100644 index b2c2c34d0..000000000 --- a/paych/cbor_gen.go +++ /dev/null @@ -1,240 +0,0 @@ -// Code generated by github.com/whyrusleeping/cbor-gen. DO NOT EDIT. - -package paych - -import ( - "fmt" - "io" - - "github.com/filecoin-project/lotus/chain/types" - cbg "github.com/whyrusleeping/cbor-gen" - xerrors "golang.org/x/xerrors" -) - -var _ = xerrors.Errorf - -func (t *VoucherInfo) 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.Voucher (types.SignedVoucher) (struct) - if err := t.Voucher.MarshalCBOR(w); 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 - } - return nil -} - -func (t *VoucherInfo) 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.Voucher (types.SignedVoucher) (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.Voucher = new(types.SignedVoucher) - if err := t.Voucher.UnmarshalCBOR(br); err != nil { - return err - } - } - - } - // 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 - } - return nil -} - -func (t *ChannelInfo) MarshalCBOR(w io.Writer) error { - if t == nil { - _, err := w.Write(cbg.CborNull) - return err - } - if _, err := w.Write([]byte{134}); err != nil { - return err - } - - // t.Channel (address.Address) (struct) - if err := t.Channel.MarshalCBOR(w); err != nil { - return err - } - - // t.Control (address.Address) (struct) - if err := t.Control.MarshalCBOR(w); err != nil { - return err - } - - // t.Target (address.Address) (struct) - if err := t.Target.MarshalCBOR(w); err != nil { - return err - } - - // t.Direction (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Direction))); err != nil { - return err - } - - // t.Vouchers ([]*paych.VoucherInfo) (slice) - if len(t.Vouchers) > cbg.MaxLength { - return xerrors.Errorf("Slice value in field t.Vouchers was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Vouchers)))); err != nil { - return err - } - for _, v := range t.Vouchers { - if err := v.MarshalCBOR(w); err != nil { - return err - } - } - - // t.NextLane (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.NextLane))); err != nil { - return err - } - return nil -} - -func (t *ChannelInfo) 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 != 6 { - return fmt.Errorf("cbor input had wrong number of fields") - } - - // t.Channel (address.Address) (struct) - - { - - if err := t.Channel.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.Control (address.Address) (struct) - - { - - if err := t.Control.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.Target (address.Address) (struct) - - { - - if err := t.Target.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.Direction (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.Direction = uint64(extra) - // t.Vouchers ([]*paych.VoucherInfo) (slice) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.MaxLength { - return fmt.Errorf("t.Vouchers: array too large (%d)", extra) - } - - if maj != cbg.MajArray { - return fmt.Errorf("expected cbor array") - } - if extra > 0 { - t.Vouchers = make([]*VoucherInfo, extra) - } - for i := 0; i < int(extra); i++ { - - var v VoucherInfo - if err := v.UnmarshalCBOR(br); err != nil { - return err - } - - t.Vouchers[i] = &v - } - - // t.NextLane (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.NextLane = uint64(extra) - return nil -} diff --git a/paychmgr/cbor_gen.go b/paychmgr/cbor_gen.go new file mode 100644 index 000000000..158fd5912 --- /dev/null +++ b/paychmgr/cbor_gen.go @@ -0,0 +1,386 @@ +// Code generated by github.com/whyrusleeping/cbor-gen. DO NOT EDIT. + +package paychmgr + +import ( + "fmt" + "io" + + "github.com/filecoin-project/specs-actors/actors/builtin/paych" + cbg "github.com/whyrusleeping/cbor-gen" + xerrors "golang.org/x/xerrors" +) + +var _ = xerrors.Errorf + +func (t *VoucherInfo) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + if _, err := w.Write([]byte{162}); err != nil { + return err + } + + // t.Voucher (paych.SignedVoucher) (struct) + if len("Voucher") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"Voucher\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Voucher")))); err != nil { + return err + } + if _, err := w.Write([]byte("Voucher")); err != nil { + return err + } + + if err := t.Voucher.MarshalCBOR(w); err != nil { + return err + } + + // t.Proof ([]uint8) (slice) + if len("Proof") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"Proof\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Proof")))); err != nil { + return err + } + if _, err := w.Write([]byte("Proof")); err != nil { + return err + } + + 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 + } + return nil +} + +func (t *VoucherInfo) UnmarshalCBOR(r io.Reader) error { + br := cbg.GetPeeker(r) + + maj, extra, err := cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra > cbg.MaxLength { + return fmt.Errorf("VoucherInfo: map struct too large (%d)", extra) + } + + var name string + n := extra + + for i := uint64(0); i < n; i++ { + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + name = string(sval) + } + + switch name { + // t.Voucher (paych.SignedVoucher) (struct) + case "Voucher": + + { + + 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.Voucher = new(paych.SignedVoucher) + if err := t.Voucher.UnmarshalCBOR(br); err != nil { + return err + } + } + + } + // t.Proof ([]uint8) (slice) + case "Proof": + + 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 + } + + default: + return fmt.Errorf("unknown struct field %d: '%s'", i, name) + } + } + + return nil +} +func (t *ChannelInfo) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + if _, err := w.Write([]byte{166}); err != nil { + return err + } + + // t.Channel (address.Address) (struct) + if len("Channel") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"Channel\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Channel")))); err != nil { + return err + } + if _, err := w.Write([]byte("Channel")); err != nil { + return err + } + + if err := t.Channel.MarshalCBOR(w); err != nil { + return err + } + + // t.Control (address.Address) (struct) + if len("Control") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"Control\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Control")))); err != nil { + return err + } + if _, err := w.Write([]byte("Control")); err != nil { + return err + } + + if err := t.Control.MarshalCBOR(w); err != nil { + return err + } + + // t.Target (address.Address) (struct) + if len("Target") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"Target\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Target")))); err != nil { + return err + } + if _, err := w.Write([]byte("Target")); err != nil { + return err + } + + if err := t.Target.MarshalCBOR(w); err != nil { + return err + } + + // t.Direction (uint64) (uint64) + if len("Direction") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"Direction\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Direction")))); err != nil { + return err + } + if _, err := w.Write([]byte("Direction")); err != nil { + return err + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Direction))); err != nil { + return err + } + + // t.Vouchers ([]*paychmgr.VoucherInfo) (slice) + if len("Vouchers") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"Vouchers\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Vouchers")))); err != nil { + return err + } + if _, err := w.Write([]byte("Vouchers")); err != nil { + return err + } + + if len(t.Vouchers) > cbg.MaxLength { + return xerrors.Errorf("Slice value in field t.Vouchers was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Vouchers)))); err != nil { + return err + } + for _, v := range t.Vouchers { + if err := v.MarshalCBOR(w); err != nil { + return err + } + } + + // t.NextLane (uint64) (uint64) + if len("NextLane") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"NextLane\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("NextLane")))); err != nil { + return err + } + if _, err := w.Write([]byte("NextLane")); err != nil { + return err + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.NextLane))); err != nil { + return err + } + + return nil +} + +func (t *ChannelInfo) UnmarshalCBOR(r io.Reader) error { + br := cbg.GetPeeker(r) + + maj, extra, err := cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra > cbg.MaxLength { + return fmt.Errorf("ChannelInfo: map struct too large (%d)", extra) + } + + var name string + n := extra + + for i := uint64(0); i < n; i++ { + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + name = string(sval) + } + + switch name { + // t.Channel (address.Address) (struct) + case "Channel": + + { + + if err := t.Channel.UnmarshalCBOR(br); err != nil { + return err + } + + } + // t.Control (address.Address) (struct) + case "Control": + + { + + if err := t.Control.UnmarshalCBOR(br); err != nil { + return err + } + + } + // t.Target (address.Address) (struct) + case "Target": + + { + + if err := t.Target.UnmarshalCBOR(br); err != nil { + return err + } + + } + // t.Direction (uint64) (uint64) + case "Direction": + + { + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.Direction = uint64(extra) + + } + // t.Vouchers ([]*paychmgr.VoucherInfo) (slice) + case "Vouchers": + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + + if extra > cbg.MaxLength { + return fmt.Errorf("t.Vouchers: array too large (%d)", extra) + } + + if maj != cbg.MajArray { + return fmt.Errorf("expected cbor array") + } + if extra > 0 { + t.Vouchers = make([]*VoucherInfo, extra) + } + for i := 0; i < int(extra); i++ { + + var v VoucherInfo + if err := v.UnmarshalCBOR(br); err != nil { + return err + } + + t.Vouchers[i] = &v + } + + // t.NextLane (uint64) (uint64) + case "NextLane": + + { + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.NextLane = uint64(extra) + + } + + default: + return fmt.Errorf("unknown struct field %d: '%s'", i, name) + } + } + + return nil +} diff --git a/paych/paych.go b/paychmgr/paych.go similarity index 82% rename from paych/paych.go rename to paychmgr/paych.go index 375fe7395..24aa51842 100644 --- a/paych/paych.go +++ b/paychmgr/paych.go @@ -1,18 +1,21 @@ -package paych +package paychmgr import ( "bytes" "context" "fmt" "math" - "strconv" + cborutil "github.com/filecoin-project/go-cbor-util" + "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/filecoin-project/specs-actors/actors/builtin/paych" "golang.org/x/xerrors" logging "github.com/ipfs/go-log/v2" "go.uber.org/fx" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/types" @@ -50,15 +53,11 @@ func NewManager(sm *stmgr.StateManager, pchstore *Store, api ManagerApi) *Manage } } -func maxLaneFromState(st *actors.PaymentChannelActorState) (uint64, error) { - maxLane := uint64(math.MaxUint64) - for lane := range st.LaneStates { - ilane, err := strconv.ParseUint(lane, 10, 64) - if err != nil { - return 0, err - } - if ilane+1 > maxLane+1 { - maxLane = ilane +func maxLaneFromState(st *paych.State) (uint64, error) { + maxLane := uint64(math.MaxInt64) + for _, state := range st.LaneStates { + if (state.ID)+1 > maxLane+1 { + maxLane = state.ID } } return maxLane, nil @@ -124,7 +123,7 @@ func (pm *Manager) GetChannelInfo(addr address.Address) (*ChannelInfo, error) { } // checks if the given voucher is valid (is or could become spendable at some point) -func (pm *Manager) CheckVoucherValid(ctx context.Context, ch address.Address, sv *types.SignedVoucher) error { +func (pm *Manager) CheckVoucherValid(ctx context.Context, ch address.Address, sv *paych.SignedVoucher) error { act, pca, err := pm.loadPaychState(ctx, ch) if err != nil { return err @@ -148,13 +147,10 @@ func (pm *Manager) CheckVoucherValid(ctx context.Context, ch address.Address, sv // now check the lane state // TODO: should check against vouchers in our local store too // there might be something conflicting - ls, ok := pca.LaneStates[fmt.Sprint(sv.Lane)] - if !ok { + ls := findLane(pca.LaneStates, uint64(sv.Lane)) + if ls == nil { } else { - if ls.Closed { - return fmt.Errorf("voucher is on a closed lane") - } - if ls.Nonce >= sv.Nonce { + if (ls.Nonce) >= sv.Nonce { return fmt.Errorf("nonce too low") } @@ -175,7 +171,7 @@ func (pm *Manager) CheckVoucherValid(ctx context.Context, ch address.Address, sv } // checks if the given voucher is currently spendable -func (pm *Manager) CheckVoucherSpendable(ctx context.Context, ch address.Address, sv *types.SignedVoucher, secret []byte, proof []byte) (bool, error) { +func (pm *Manager) CheckVoucherSpendable(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, secret []byte, proof []byte) (bool, error) { owner, err := pm.getPaychOwner(ctx, ch) if err != nil { return false, err @@ -188,7 +184,11 @@ func (pm *Manager) CheckVoucherSpendable(ctx context.Context, ch address.Address } for _, v := range known { - if v.Proof != nil && v.Voucher.Equals(sv) { + eq, err := cborutil.Equals(v.Voucher, sv) + if err != nil { + return false, err + } + if v.Proof != nil && eq { log.Info("CheckVoucherSpendable: using stored proof") proof = v.Proof break @@ -199,7 +199,7 @@ func (pm *Manager) CheckVoucherSpendable(ctx context.Context, ch address.Address } } - enc, err := actors.SerializeParams(&actors.PCAUpdateChannelStateParams{ + enc, err := actors.SerializeParams(&paych.UpdateChannelStateParams{ Sv: *sv, Secret: secret, Proof: proof, @@ -211,7 +211,7 @@ func (pm *Manager) CheckVoucherSpendable(ctx context.Context, ch address.Address ret, err := pm.sm.Call(ctx, &types.Message{ From: owner, To: ch, - Method: actors.PCAMethods.UpdateChannelState, + Method: builtin.MethodsPaych.UpdateChannelState, Params: enc, }, nil) if err != nil { @@ -226,23 +226,15 @@ func (pm *Manager) CheckVoucherSpendable(ctx context.Context, ch address.Address } func (pm *Manager) getPaychOwner(ctx context.Context, ch address.Address) (address.Address, error) { - ret, err := pm.sm.Call(ctx, &types.Message{ - From: ch, - To: ch, - Method: actors.PCAMethods.GetOwner, - }, nil) - if err != nil { - return address.Undef, err + var state paych.State + if _, err := pm.sm.LoadActorState(ctx, ch, &state, nil); err != nil { + return address.Address{}, err } - if ret.ExitCode != 0 { - return address.Undef, fmt.Errorf("failed to get payment channel owner (exit code %d)", ret.ExitCode) - } - - return address.NewFromBytes(ret.Return) + return state.From, nil } -func (pm *Manager) AddVoucher(ctx context.Context, ch address.Address, sv *types.SignedVoucher, proof []byte, minDelta types.BigInt) (types.BigInt, error) { +func (pm *Manager) AddVoucher(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, proof []byte, minDelta types.BigInt) (types.BigInt, error) { if err := pm.CheckVoucherValid(ctx, ch, sv); err != nil { return types.NewInt(0), err } @@ -255,22 +247,22 @@ func (pm *Manager) AddVoucher(ctx context.Context, ch address.Address, sv *types return types.NewInt(0), err } - laneState, err := pm.laneState(ctx, ch, sv.Lane) + laneState, err := pm.laneState(ctx, ch, uint64(sv.Lane)) if err != nil { return types.NewInt(0), err } - if laneState.Closed { - return types.NewInt(0), xerrors.New("lane closed") - } - if minDelta.GreaterThan(types.NewInt(0)) && laneState.Nonce > sv.Nonce { return types.NewInt(0), xerrors.Errorf("already storing voucher with higher nonce; %d > %d", laneState.Nonce, sv.Nonce) } // look for duplicates for i, v := range ci.Vouchers { - if !sv.Equals(v.Voucher) { + eq, err := cborutil.Equals(sv, v) + if err != nil { + return types.BigInt{}, err + } + if !eq { continue } if v.Proof != nil { @@ -301,7 +293,7 @@ func (pm *Manager) AddVoucher(ctx context.Context, ch address.Address, sv *types Proof: proof, }) - if ci.NextLane <= sv.Lane { + if ci.NextLane <= (sv.Lane) { ci.NextLane = sv.Lane + 1 } @@ -338,9 +330,9 @@ func (pm *Manager) NextNonceForLane(ctx context.Context, ch address.Address, lan var maxnonce uint64 for _, v := range vouchers { - if v.Voucher.Lane == lane { - if v.Voucher.Nonce > maxnonce { - maxnonce = v.Voucher.Nonce + if uint64(v.Voucher.Lane) == lane { + if uint64(v.Voucher.Nonce) > maxnonce { + maxnonce = uint64(v.Voucher.Nonce) } } } diff --git a/paych/simple.go b/paychmgr/simple.go similarity index 85% rename from paych/simple.go rename to paychmgr/simple.go index 0c5844545..1370865ed 100644 --- a/paych/simple.go +++ b/paychmgr/simple.go @@ -1,36 +1,40 @@ -package paych +package paychmgr import ( "context" "fmt" + "github.com/filecoin-project/specs-actors/actors/builtin" + init_ "github.com/filecoin-project/specs-actors/actors/builtin/init" + "github.com/filecoin-project/specs-actors/actors/builtin/paych" "github.com/ipfs/go-cid" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/types" ) func (pm *Manager) createPaych(ctx context.Context, from, to address.Address, amt types.BigInt) (address.Address, cid.Cid, error) { - params, aerr := actors.SerializeParams(&actors.PCAConstructorParams{To: to}) + params, aerr := actors.SerializeParams(&paych.ConstructorParams{To: to}) if aerr != nil { return address.Undef, cid.Undef, aerr } - enc, aerr := actors.SerializeParams(&actors.ExecParams{ - Params: params, - Code: actors.PaymentChannelCodeCid, + enc, aerr := actors.SerializeParams(&init_.ExecParams{ + CodeCID: builtin.PaymentChannelActorCodeID, + ConstructorParams: params, }) if aerr != nil { return address.Undef, cid.Undef, aerr } msg := &types.Message{ - To: actors.InitAddress, + To: builtin.InitActorAddr, From: from, Value: amt, - Method: actors.IAMethods.Exec, + Method: builtin.MethodsInit.Exec, Params: enc, GasLimit: types.NewInt(1000000), GasPrice: types.NewInt(0), diff --git a/paych/state.go b/paychmgr/state.go similarity index 64% rename from paych/state.go rename to paychmgr/state.go index bd9521864..6aff6bd9e 100644 --- a/paych/state.go +++ b/paychmgr/state.go @@ -1,17 +1,17 @@ -package paych +package paychmgr import ( "context" - "fmt" "github.com/filecoin-project/go-address" - "github.com/filecoin-project/lotus/chain/actors" - "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/specs-actors/actors/builtin/paych" xerrors "golang.org/x/xerrors" + + "github.com/filecoin-project/lotus/chain/types" ) -func (pm *Manager) loadPaychState(ctx context.Context, ch address.Address) (*types.Actor, *actors.PaymentChannelActorState, error) { - var pcast actors.PaymentChannelActorState +func (pm *Manager) loadPaychState(ctx context.Context, ch address.Address) (*types.Actor, *paych.State, error) { + var pcast paych.State act, err := pm.sm.LoadActorState(ctx, ch, &pcast, nil) if err != nil { return nil, nil, err @@ -20,40 +20,47 @@ func (pm *Manager) loadPaychState(ctx context.Context, ch address.Address) (*typ return act, &pcast, nil } -func (pm *Manager) laneState(ctx context.Context, ch address.Address, lane uint64) (actors.LaneState, error) { +func findLane(states []*paych.LaneState, lane uint64) *paych.LaneState { + var ls *paych.LaneState + for _, laneState := range states { + if uint64(laneState.ID) == lane { + ls = laneState + break + } + } + return ls +} + +func (pm *Manager) laneState(ctx context.Context, ch address.Address, lane uint64) (paych.LaneState, error) { _, state, err := pm.loadPaychState(ctx, ch) if err != nil { - return actors.LaneState{}, err + return paych.LaneState{}, err } // TODO: we probably want to call UpdateChannelState with all vouchers to be fully correct // (but technically dont't need to) // TODO: make sure this is correct - ls, ok := state.LaneStates[fmt.Sprintf("%d", lane)] - if !ok { - ls = &actors.LaneState{ - Closed: false, + ls := findLane(state.LaneStates, lane) + if ls == nil { + ls = &paych.LaneState{ + ID: lane, Redeemed: types.NewInt(0), Nonce: 0, } } - if ls.Closed { - return *ls, nil - } - vouchers, err := pm.store.VouchersForPaych(ch) if err != nil { if err == ErrChannelNotTracked { return *ls, nil } - return actors.LaneState{}, err + return paych.LaneState{}, err } for _, v := range vouchers { for range v.Voucher.Merges { - return actors.LaneState{}, xerrors.Errorf("paych merges not handled yet") + return paych.LaneState{}, xerrors.Errorf("paych merges not handled yet") } if v.Voucher.Lane != lane { diff --git a/paych/store.go b/paychmgr/store.go similarity index 97% rename from paych/store.go rename to paychmgr/store.go index f5e74b843..3a425c4fc 100644 --- a/paych/store.go +++ b/paychmgr/store.go @@ -1,4 +1,4 @@ -package paych +package paychmgr import ( "bytes" @@ -7,6 +7,7 @@ import ( "strings" "sync" + "github.com/filecoin-project/specs-actors/actors/builtin/paych" "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/namespace" dsq "github.com/ipfs/go-datastore/query" @@ -14,7 +15,7 @@ import ( "github.com/filecoin-project/go-address" cborrpc "github.com/filecoin-project/go-cbor-util" - "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/node/modules/dtypes" ) @@ -39,7 +40,7 @@ const ( ) type VoucherInfo struct { - Voucher *types.SignedVoucher + Voucher *paych.SignedVoucher Proof []byte } diff --git a/storage/fpost_run.go b/storage/fpost_run.go index 79cf8aca0..6e712360c 100644 --- a/storage/fpost_run.go +++ b/storage/fpost_run.go @@ -2,10 +2,15 @@ package storage import ( "context" + "github.com/filecoin-project/specs-actors/actors/crypto" "time" ffi "github.com/filecoin-project/filecoin-ffi" + "github.com/filecoin-project/go-address" sectorbuilder "github.com/filecoin-project/go-sectorbuilder" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/filecoin-project/specs-actors/actors/builtin/miner" "go.opencensus.io/trace" "golang.org/x/xerrors" @@ -14,7 +19,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 +27,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 @@ -50,7 +55,7 @@ func (s *FPoStScheduler) doPost(ctx context.Context, eps uint64, ts *types.TipSe }() } -func (s *FPoStScheduler) declareFaults(ctx context.Context, fc uint64, params *actors.DeclareFaultsParams) error { +func (s *FPoStScheduler) declareFaults(ctx context.Context, fc uint64, params *miner.DeclareTemporaryFaultsParams) error { log.Warnf("DECLARING %d FAULTS", fc) enc, aerr := actors.SerializeParams(params) @@ -61,7 +66,7 @@ func (s *FPoStScheduler) declareFaults(ctx context.Context, fc uint64, params *a msg := &types.Message{ To: s.actor, From: s.worker, - Method: actors.MAMethods.DeclareFaults, + Method: builtin.MethodsMiner.DeclareTemporaryFaults, Params: enc, Value: types.NewInt(0), GasLimit: types.NewInt(10000000), // i dont know help @@ -86,10 +91,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, types.EmptyTSK) @@ -102,45 +107,45 @@ func (s *FPoStScheduler) checkFaults(ctx context.Context, ssi sectorbuilder.Sort } } + var faultIDs []abi.SectorNumber if len(faults) > 0 { - params := &actors.DeclareFaultsParams{Faults: types.NewBitField()} + params := &miner.DeclareTemporaryFaultsParams{ + Duration: 900, // TODO: duration is annoying + SectorNumbers: abi.NewBitField(), + } for _, fault := range faults { - if _, ok := declaredFaults[fault.SectorID]; ok { + if _, ok := declaredFaults[(fault.SectorNum)]; ok { continue } - log.Warnf("new fault detected: sector %d: %s", fault.SectorID, fault.Err) - declaredFaults[fault.SectorID] = struct{}{} - params.Faults.Set(fault.SectorID) + log.Warnf("new fault detected: sector %d: %s", fault.SectorNum, fault.Err) + declaredFaults[fault.SectorNum] = struct{}{} } - pc, err := params.Faults.Count() - if err != nil { - return nil, xerrors.Errorf("counting faults: %w", err) + faultIDs = make([]abi.SectorNumber, 0, len(declaredFaults)) + for fault := range declaredFaults { + faultIDs = append(faultIDs, fault) + params.SectorNumbers.Set(uint64(fault)) } - if pc > 0 { - if err := s.declareFaults(ctx, pc, params); err != nil { + + if len(faultIDs) > 0 { + if err := s.declareFaults(ctx, uint64(len(faultIDs)), params); err != nil { return nil, err } } } - faultIDs := make([]uint64, 0, len(declaredFaults)) - for fault := range declaredFaults { - faultIDs = append(faultIDs, 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) (*abi.OnChainPoStVerifyInfo, error) { ctx, span := trace.StartSpan(ctx, "storage.runPost") defer span.End() - challengeRound := int64(eps + build.FallbackPoStDelay) + challengeRound := eps + build.FallbackPoStDelay - rand, err := s.api.ChainGetRandomness(ctx, ts.Key(), challengeRound) + rand, err := s.api.ChainGetRandomness(ctx, ts.Key(), crypto.DomainSeparationTag_WindowedPoStChallengeSeed, challengeRound, s.actor.Bytes()) if err != nil { return nil, xerrors.Errorf("failed to get chain randomness for fpost (ts=%d; eps=%d): %w", ts.Height(), eps, err) } @@ -177,19 +182,29 @@ func (s *FPoStScheduler) runPost(ctx context.Context, eps uint64, ts *types.TipS elapsed := time.Since(tsStart) log.Infow("submitting PoSt", "pLen", len(proof), "elapsed", elapsed) - candidates := make([]types.EPostTicket, len(scandidates)) + mid, err := address.IDFromAddress(s.actor) + if err != nil { + return nil, err + } + + candidates := make([]abi.PoStCandidate, len(scandidates)) for i, sc := range scandidates { part := make([]byte, 32) copy(part, sc.PartialTicket[:]) - candidates[i] = types.EPostTicket{ - Partial: part, - SectorID: sc.SectorID, - ChallengeIndex: sc.SectorChallengeIndex, + candidates[i] = abi.PoStCandidate{ + RegisteredProof: abi.RegisteredProof_StackedDRG32GiBPoSt, // TODO: build setting + PartialTicket: part, + SectorID: abi.SectorID{ + Miner: abi.ActorID(mid), + Number: sc.SectorNum, + }, + ChallengeIndex: int64(sc.SectorChallengeIndex), // TODO: fix spec } } - return &actors.SubmitFallbackPoStParams{ - Proof: proof, + return &abi.OnChainPoStVerifyInfo{ + ProofType: abi.RegisteredProof_StackedDRG32GiBPoSt, // TODO: build setting + Proofs: []abi.PoStProof{{proof}}, Candidates: candidates, }, nil } @@ -206,18 +221,19 @@ func (s *FPoStScheduler) sortedSectorInfo(ctx context.Context, ts *types.TipSet) sbsi := make([]ffi.PublicSectorInfo, len(sset)) for k, sector := range sset { var commR [sectorbuilder.CommLen]byte - copy(commR[:], sector.CommR) + scid := sector.Info.Info.SealedCID.Bytes() + copy(commR[:], scid[len(scid)-32:]) sbsi[k] = ffi.PublicSectorInfo{ - SectorID: sector.SectorID, - CommR: commR, + SectorNum: sector.Info.Info.SectorNumber, + CommR: commR, } } return sectorbuilder.NewSortedPublicSectorInfo(sbsi), nil } -func (s *FPoStScheduler) submitPost(ctx context.Context, proof *actors.SubmitFallbackPoStParams) error { +func (s *FPoStScheduler) submitPost(ctx context.Context, proof *abi.OnChainPoStVerifyInfo) error { ctx, span := trace.StartSpan(ctx, "storage.commitPost") defer span.End() @@ -229,7 +245,7 @@ func (s *FPoStScheduler) submitPost(ctx context.Context, proof *actors.SubmitFal msg := &types.Message{ To: s.actor, From: s.worker, - Method: actors.MAMethods.SubmitFallbackPoSt, + Method: builtin.MethodsMiner.SubmitWindowedPoSt, Params: enc, Value: types.NewInt(1000), // currently hard-coded late fee in actor, returned if not late GasLimit: types.NewInt(10000000), // i dont know help diff --git a/storage/fpost_sched.go b/storage/fpost_sched.go index e0f0a6a6c..27eb7eb11 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,14 +162,14 @@ func (s *FPoStScheduler) abortActivePoSt() { s.abort = nil } -func (s *FPoStScheduler) shouldFallbackPost(ctx context.Context, ts *types.TipSet) (uint64, bool, error) { - eps, err := s.api.StateMinerElectionPeriodStart(ctx, s.actor, ts.Key()) +func (s *FPoStScheduler) shouldFallbackPost(ctx context.Context, ts *types.TipSet) (abi.ChainEpoch, bool, error) { + ps, err := s.api.StateMinerPostState(ctx, s.actor, ts.Key()) if err != nil { return 0, false, xerrors.Errorf("getting ElectionPeriodStart: %w", err) } - if ts.Height() >= eps+build.FallbackPoStDelay { - return eps, ts.Height() >= eps+build.FallbackPoStDelay+StartConfidence, nil + if ts.Height() >= ps.ProvingPeriodStart+build.FallbackPoStDelay { + return ps.ProvingPeriodStart, ts.Height() >= ps.ProvingPeriodStart+build.FallbackPoStDelay+StartConfidence, nil } return 0, false, nil } diff --git a/storage/miner.go b/storage/miner.go index ae423a877..fde9378a5 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -6,16 +6,19 @@ import ( "time" "github.com/filecoin-project/go-address" - "github.com/filecoin-project/go-sectorbuilder" "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/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin/miner" + "github.com/filecoin-project/specs-actors/actors/crypto" + "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,26 +45,27 @@ type storageMinerApi interface { // Call a read only method on actors (no interaction with the chain required) StateCall(context.Context, *types.Message, types.TipSetKey) (*api.MethodCall, error) StateMinerWorker(context.Context, address.Address, types.TipSetKey) (address.Address, error) - StateMinerElectionPeriodStart(ctx context.Context, actor address.Address, tsk types.TipSetKey) (uint64, error) + StateMinerPostState(ctx context.Context, actor address.Address, ts types.TipSetKey) (*miner.PoStState, error) StateMinerSectors(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) StateMinerProvingSet(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) - StateMinerSectorSize(context.Context, address.Address, types.TipSetKey) (uint64, error) + StateMinerSectorSize(context.Context, address.Address, types.TipSetKey) (abi.SectorSize, error) StateWaitMsg(context.Context, cid.Cid) (*api.MsgWait, error) // TODO: removeme eventually - StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) + StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error) StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) - StateMarketStorageDeal(context.Context, uint64, types.TipSetKey) (*actors.OnChainDeal, error) - StateMinerFaults(context.Context, address.Address, types.TipSetKey) ([]uint64, error) + StateMarketStorageDeal(context.Context, abi.DealID, types.TipSetKey) (*api.MarketDeal, error) + StateMinerFaults(context.Context, address.Address, types.TipSetKey) ([]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.TipSetKey) (*types.TipSet, error) + ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) + ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error) ChainGetBlockMessages(context.Context, cid.Cid) (*api.BlockMessages, error) ChainReadObj(context.Context, cid.Cid) ([]byte, error) + ChainHasObj(context.Context, cid.Cid) (bool, error) - WalletSign(context.Context, address.Address, []byte) (*types.Signature, error) + WalletSign(context.Context, address.Address, []byte) (*crypto.Signature, error) WalletBalance(context.Context, address.Address) (types.BigInt, error) WalletHas(context.Context, address.Address) (bool, error) } @@ -125,7 +129,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/sbmock/preseal.go b/storage/sbmock/preseal.go index ad4fc4f63..22326482a 100644 --- a/storage/sbmock/preseal.go +++ b/storage/sbmock/preseal.go @@ -1,52 +1,54 @@ package sbmock import ( - "math" - "github.com/filecoin-project/go-address" - "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/abi/big" + "github.com/filecoin-project/specs-actors/actors/builtin/market" + "github.com/filecoin-project/specs-actors/actors/crypto" - "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" ) -func PreSeal(ssize uint64, maddr address.Address, sectors int) (*genesis.GenesisMiner, error) { - k, err := wallet.GenerateKey(types.KTBLS) +func PreSeal(ssize abi.SectorSize, maddr address.Address, sectors int) (*genesis.Miner, *types.KeyInfo, error) { + k, err := wallet.GenerateKey(crypto.SigTypeBLS) if err != nil { - return nil, err + return nil, nil, err } - genm := &genesis.GenesisMiner{ - Owner: k.Address, - Worker: k.Address, - SectorSize: ssize, - Sectors: make([]*genesis.PreSeal, sectors), - Key: k.KeyInfo, + genm := &genesis.Miner{ + Owner: k.Address, + Worker: k.Address, + MarketBalance: big.NewInt(0), + PowerBalance: big.NewInt(0), + SectorSize: ssize, + Sectors: make([]*genesis.PreSeal, sectors), } for i := range genm.Sectors { preseal := &genesis.PreSeal{} - sdata := randB(sectorbuilder.UserBytesForSectorSize(ssize)) + sdata := randB(uint64(abi.PaddedPieceSize(ssize).Unpadded())) preseal.CommD = commD(sdata) preseal.CommR = commDR(preseal.CommD[:]) - preseal.SectorID = uint64(i + 1) - preseal.Deal = actors.StorageDealProposal{ - PieceRef: preseal.CommD[:], - PieceSize: sectorbuilder.UserBytesForSectorSize(ssize), + preseal.SectorID = abi.SectorNumber(i + 1) + preseal.Deal = market.DealProposal{ + PieceCID: commcid.PieceCommitmentV1ToCID(preseal.CommD[:]), + PieceSize: abi.PaddedPieceSize(ssize), Client: maddr, Provider: maddr, - ProposalExpiration: math.MaxUint64, - Duration: math.MaxUint64, - StoragePricePerEpoch: types.NewInt(0), - StorageCollateral: types.NewInt(0), - ProposerSignature: nil, + StartEpoch: 1, + EndEpoch: 10000, + StoragePricePerEpoch: big.Zero(), + ProviderCollateral: big.Zero(), + ClientCollateral: big.Zero(), } genm.Sectors[i] = preseal } - return genm, nil + return genm, &k.KeyInfo, nil } diff --git a/storage/sbmock/sbmock.go b/storage/sbmock/sbmock.go index 4d88853f5..ae74cc887 100644 --- a/storage/sbmock/sbmock.go +++ b/storage/sbmock/sbmock.go @@ -14,13 +14,14 @@ import ( "github.com/filecoin-project/go-address" "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" ) type SBMock struct { - sectors map[uint64]*sectorState - sectorSize uint64 - nextSectorID uint64 + sectors map[abi.SectorNumber]*sectorState + sectorSize abi.SectorSize + nextSectorID abi.SectorNumber rateLimit chan struct{} lk sync.Mutex @@ -28,9 +29,9 @@ type SBMock struct { type mockVerif struct{} -func NewMockSectorBuilder(threads int, ssize uint64) *SBMock { +func NewMockSectorBuilder(threads int, ssize abi.SectorSize) *SBMock { return &SBMock{ - sectors: make(map[uint64]*sectorState), + sectors: make(map[abi.SectorNumber]*sectorState), sectorSize: ssize, nextSectorID: 5, rateLimit: make(chan struct{}, threads), @@ -61,7 +62,7 @@ func (sb *SBMock) RateLimit() func() { } } -func (sb *SBMock) AddPiece(ctx context.Context, size uint64, sectorId uint64, r io.Reader, existingPieces []uint64) (sectorbuilder.PublicPieceInfo, error) { +func (sb *SBMock) AddPiece(ctx context.Context, size abi.UnpaddedPieceSize, sectorId abi.SectorNumber, r io.Reader, existingPieces []abi.UnpaddedPieceSize) (sectorbuilder.PublicPieceInfo, error) { sb.lk.Lock() ss, ok := sb.sectors[sectorId] if !ok { @@ -86,11 +87,11 @@ func (sb *SBMock) AddPiece(ctx context.Context, size uint64, sectorId uint64, r }, nil } -func (sb *SBMock) SectorSize() uint64 { +func (sb *SBMock) SectorSize() abi.SectorSize { return sb.sectorSize } -func (sb *SBMock) AcquireSectorId() (uint64, error) { +func (sb *SBMock) AcquireSectorNumber() (abi.SectorNumber, error) { sb.lk.Lock() defer sb.lk.Unlock() id := sb.nextSectorID @@ -100,7 +101,7 @@ func (sb *SBMock) AcquireSectorId() (uint64, error) { func (sb *SBMock) Scrub(sectorbuilder.SortedPublicSectorInfo) []*sectorbuilder.Fault { sb.lk.Lock() - mcopy := make(map[uint64]*sectorState) + mcopy := make(map[abi.SectorNumber]*sectorState) for k, v := range sb.sectors { mcopy[k] = v } @@ -111,8 +112,8 @@ func (sb *SBMock) Scrub(sectorbuilder.SortedPublicSectorInfo) []*sectorbuilder.F ss.lk.Lock() if ss.failed { out = append(out, §orbuilder.Fault{ - SectorID: sid, - Err: fmt.Errorf("mock sector failed"), + SectorNum: sid, + Err: fmt.Errorf("mock sector failed"), }) } @@ -122,11 +123,11 @@ func (sb *SBMock) Scrub(sectorbuilder.SortedPublicSectorInfo) []*sectorbuilder.F return out } -func (sb *SBMock) GenerateFallbackPoSt(sectorbuilder.SortedPublicSectorInfo, [sectorbuilder.CommLen]byte, []uint64) ([]sectorbuilder.EPostCandidate, []byte, error) { +func (sb *SBMock) GenerateFallbackPoSt(sectorbuilder.SortedPublicSectorInfo, [sectorbuilder.CommLen]byte, []abi.SectorNumber) ([]sectorbuilder.EPostCandidate, []byte, error) { panic("NYI") } -func (sb *SBMock) SealPreCommit(ctx context.Context, sid uint64, ticket sectorbuilder.SealTicket, pieces []sectorbuilder.PublicPieceInfo) (sectorbuilder.RawSealPreCommitOutput, error) { +func (sb *SBMock) SealPreCommit(ctx context.Context, sid abi.SectorNumber, ticket sectorbuilder.SealTicket, pieces []sectorbuilder.PublicPieceInfo) (sectorbuilder.RawSealPreCommitOutput, error) { sb.lk.Lock() ss, ok := sb.sectors[sid] sb.lk.Unlock() @@ -137,11 +138,11 @@ func (sb *SBMock) SealPreCommit(ctx context.Context, sid uint64, ticket sectorbu ss.lk.Lock() defer ss.lk.Unlock() - ussize := sectorbuilder.UserBytesForSectorSize(sb.sectorSize) + ussize := abi.PaddedPieceSize(sb.sectorSize).Unpadded() // TODO: verify pieces in sinfo.pieces match passed in pieces - var sum uint64 + var sum abi.UnpaddedPieceSize for _, p := range pieces { sum += p.Size } @@ -161,12 +162,12 @@ func (sb *SBMock) SealPreCommit(ctx context.Context, sid uint64, ticket sectorbu pis := make([]ffi.PublicPieceInfo, len(ss.pieces)) for i, piece := range ss.pieces { pis[i] = ffi.PublicPieceInfo{ - Size: uint64(len(piece)), + Size: abi.UnpaddedPieceSize(len(piece)), CommP: commD(piece), } } - commd, err := MockVerifier.GenerateDataCommitment(sb.sectorSize, pis) + commd, err := MockVerifier.GenerateDataCommitment(abi.PaddedPieceSize(sb.sectorSize), pis) if err != nil { return sectorbuilder.RawSealPreCommitOutput{}, err } @@ -177,7 +178,7 @@ func (sb *SBMock) SealPreCommit(ctx context.Context, sid uint64, ticket sectorbu }, nil } -func (sb *SBMock) SealCommit(ctx context.Context, sid uint64, ticket sectorbuilder.SealTicket, seed sectorbuilder.SealSeed, pieces []sectorbuilder.PublicPieceInfo, precommit sectorbuilder.RawSealPreCommitOutput) ([]byte, error) { +func (sb *SBMock) SealCommit(ctx context.Context, sid abi.SectorNumber, ticket sectorbuilder.SealTicket, seed sectorbuilder.SealSeed, pieces []sectorbuilder.PublicPieceInfo, precommit sectorbuilder.RawSealPreCommitOutput) ([]byte, error) { sb.lk.Lock() ss, ok := sb.sectors[sid] sb.lk.Unlock() @@ -208,7 +209,7 @@ func (sb *SBMock) GetPath(string, string) (string, error) { panic("nyi") } -func (sb *SBMock) CanCommit(sectorID uint64) (bool, error) { +func (sb *SBMock) CanCommit(sectorID abi.SectorNumber) (bool, error) { return true, nil } @@ -226,7 +227,7 @@ func (sb *SBMock) TaskDone(context.Context, uint64, sectorbuilder.SealRes) error // Test Instrumentation Methods -func (sb *SBMock) FailSector(sid uint64) error { +func (sb *SBMock) FailSector(sid abi.SectorNumber) error { sb.lk.Lock() defer sb.lk.Unlock() ss, ok := sb.sectors[sid] @@ -258,7 +259,7 @@ func (sb *SBMock) ComputeElectionPoSt(sectorInfo sectorbuilder.SortedPublicSecto panic("implement me") } -func (sb *SBMock) GenerateEPostCandidates(sectorInfo sectorbuilder.SortedPublicSectorInfo, challengeSeed [sectorbuilder.CommLen]byte, faults []uint64) ([]sectorbuilder.EPostCandidate, error) { +func (sb *SBMock) GenerateEPostCandidates(sectorInfo sectorbuilder.SortedPublicSectorInfo, challengeSeed [sectorbuilder.CommLen]byte, faults []abi.SectorNumber) ([]sectorbuilder.EPostCandidate, error) { if len(faults) > 0 { panic("todo") } @@ -275,7 +276,7 @@ func (sb *SBMock) GenerateEPostCandidates(sectorInfo sectorbuilder.SortedPublicS for i := range out { out[i] = sectorbuilder.EPostCandidate{ - SectorID: uint64((int(start) + i) % len(sectorInfo.Values())), + SectorNum: abi.SectorNumber((int(start) + i) % len(sectorInfo.Values())), PartialTicket: challengeSeed, Ticket: commDR(challengeSeed[:]), SectorChallengeIndex: 0, @@ -285,16 +286,16 @@ func (sb *SBMock) GenerateEPostCandidates(sectorInfo sectorbuilder.SortedPublicS return out, nil } -func (sb *SBMock) ReadPieceFromSealedSector(ctx context.Context, sectorID uint64, offset uint64, size uint64, ticket []byte, commD []byte) (io.ReadCloser, error) { +func (sb *SBMock) ReadPieceFromSealedSector(ctx context.Context, sectorID abi.SectorNumber, offset sectorbuilder.UnpaddedByteIndex, size abi.UnpaddedPieceSize, ticket []byte, commD []byte) (io.ReadCloser, error) { if len(sb.sectors[sectorID].pieces) > 1 { panic("implme") } return ioutil.NopCloser(io.LimitReader(bytes.NewReader(sb.sectors[sectorID].pieces[0][offset:]), int64(size))), nil } -func (sb *SBMock) StageFakeData() (uint64, []sectorbuilder.PublicPieceInfo, error) { - usize := sectorbuilder.UserBytesForSectorSize(sb.sectorSize) - sid, err := sb.AcquireSectorId() +func (sb *SBMock) StageFakeData() (abi.SectorNumber, []sectorbuilder.PublicPieceInfo, error) { + usize := abi.PaddedPieceSize(sb.sectorSize).Unpadded() + sid, err := sb.AcquireSectorNumber() if err != nil { return 0, nil, err } @@ -310,19 +311,19 @@ func (sb *SBMock) StageFakeData() (uint64, []sectorbuilder.PublicPieceInfo, erro return sid, []sectorbuilder.PublicPieceInfo{pi}, nil } -func (sb *SBMock) FinalizeSector(context.Context, uint64) error { +func (sb *SBMock) FinalizeSector(context.Context, abi.SectorNumber) error { return nil } -func (sb *SBMock) DropStaged(context.Context, uint64) error { +func (sb *SBMock) DropStaged(context.Context, abi.SectorNumber) error { return nil } -func (sb *SBMock) SectorPath(typ fs.DataType, sectorID uint64) (fs.SectorPath, error) { +func (sb *SBMock) SectorPath(typ fs.DataType, sectorID abi.SectorNumber) (fs.SectorPath, error) { panic("implement me") } -func (sb *SBMock) AllocSectorPath(typ fs.DataType, sectorID uint64, cache bool) (fs.SectorPath, error) { +func (sb *SBMock) AllocSectorPath(typ fs.DataType, sectorID abi.SectorNumber, cache bool) (fs.SectorPath, error) { panic("implement me") } @@ -330,15 +331,15 @@ func (sb *SBMock) ReleaseSector(fs.DataType, fs.SectorPath) { panic("implement me") } -func (m mockVerif) VerifyElectionPost(ctx context.Context, sectorSize uint64, sectorInfo sectorbuilder.SortedPublicSectorInfo, challengeSeed []byte, proof []byte, candidates []sectorbuilder.EPostCandidate, proverID address.Address) (bool, error) { +func (m mockVerif) VerifyElectionPost(ctx context.Context, sectorSize abi.SectorSize, sectorInfo sectorbuilder.SortedPublicSectorInfo, challengeSeed []byte, proof []byte, candidates []sectorbuilder.EPostCandidate, proverID address.Address) (bool, error) { panic("implement me") } -func (m mockVerif) VerifyFallbackPost(ctx context.Context, sectorSize uint64, sectorInfo sectorbuilder.SortedPublicSectorInfo, challengeSeed []byte, proof []byte, candidates []sectorbuilder.EPostCandidate, proverID address.Address, faults uint64) (bool, error) { +func (m mockVerif) VerifyFallbackPost(ctx context.Context, sectorSize abi.SectorSize, sectorInfo sectorbuilder.SortedPublicSectorInfo, challengeSeed []byte, proof []byte, candidates []sectorbuilder.EPostCandidate, proverID address.Address, faults uint64) (bool, error) { panic("implement me") } -func (m mockVerif) VerifySeal(sectorSize uint64, commR, commD []byte, proverID address.Address, ticket []byte, seed []byte, sectorID uint64, proof []byte) (bool, error) { +func (m mockVerif) VerifySeal(sectorSize abi.SectorSize, commR, commD []byte, proverID address.Address, ticket []byte, seed []byte, sectorID abi.SectorNumber, proof []byte) (bool, error) { if len(proof) != 32 { // Real ones are longer, but this should be fine return false, nil } @@ -352,11 +353,11 @@ func (m mockVerif) VerifySeal(sectorSize uint64, commR, commD []byte, proverID a return true, nil } -func (m mockVerif) GenerateDataCommitment(ssize uint64, pieces []ffi.PublicPieceInfo) ([sectorbuilder.CommLen]byte, error) { +func (m mockVerif) GenerateDataCommitment(ssize abi.PaddedPieceSize, pieces []ffi.PublicPieceInfo) ([sectorbuilder.CommLen]byte, error) { if len(pieces) != 1 { panic("todo") } - if pieces[0].Size != sectorbuilder.UserBytesForSectorSize(ssize) { + if pieces[0].Size != ssize.Unpadded() { panic("todo") } return pieces[0].CommP, nil diff --git a/storage/sbmock/util.go b/storage/sbmock/util.go index 1fb5206e7..5a4232d86 100644 --- a/storage/sbmock/util.go +++ b/storage/sbmock/util.go @@ -6,6 +6,8 @@ import ( "io" "io/ioutil" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/go-sectorbuilder" ) @@ -26,7 +28,7 @@ func commDR(in []byte) (out [32]byte) { } func commD(b []byte) [32]byte { - c, err := sectorbuilder.GeneratePieceCommitment(bytes.NewReader(b), uint64(len(b))) + c, err := sectorbuilder.GeneratePieceCommitment(bytes.NewReader(b), abi.UnpaddedPieceSize(len(b))) if err != nil { panic(err) } diff --git a/storage/sealing.go b/storage/sealing.go index d6d27b429..cb7cfb5a3 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 abi.UnpaddedPieceSize) (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) } @@ -22,7 +24,7 @@ func (m *Miner) ListSectors() ([]sealing.SectorInfo, error) { return m.sealing.ListSectors() } -func (m *Miner) GetSectorInfo(sid uint64) (sealing.SectorInfo, error) { +func (m *Miner) GetSectorInfo(sid abi.SectorNumber) (sealing.SectorInfo, error) { return m.sealing.GetSectorInfo(sid) } @@ -30,6 +32,6 @@ func (m *Miner) PledgeSector() error { return m.sealing.PledgeSector() } -func (m *Miner) ForceSectorState(ctx context.Context, id uint64, state api.SectorState) error { +func (m *Miner) ForceSectorState(ctx context.Context, id abi.SectorNumber, state api.SectorState) error { return m.sealing.ForceSectorState(ctx, id, state) } diff --git a/storage/sealing/cbor_gen.go b/storage/sealing/cbor_gen.go index af1a18da2..3cd9b6451 100644 --- a/storage/sealing/cbor_gen.go +++ b/storage/sealing/cbor_gen.go @@ -6,6 +6,7 @@ import ( "fmt" "io" + "github.com/filecoin-project/specs-actors/actors/abi" cbg "github.com/whyrusleeping/cbor-gen" xerrors "golang.org/x/xerrors" ) @@ -21,7 +22,7 @@ func (t *SealTicket) MarshalCBOR(w io.Writer) error { return err } - // t.BlockHeight (uint64) (uint64) + // t.BlockHeight (abi.ChainEpoch) (int64) if len("BlockHeight") > cbg.MaxLength { return xerrors.Errorf("Value in field \"BlockHeight\" was too long") } @@ -33,8 +34,14 @@ func (t *SealTicket) MarshalCBOR(w io.Writer) error { return err } - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.BlockHeight))); err != nil { - return err + if t.BlockHeight >= 0 { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.BlockHeight))); err != nil { + return err + } + } else { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajNegativeInt, uint64(-t.BlockHeight)-1)); err != nil { + return err + } } // t.TicketBytes ([]uint8) (slice) @@ -92,17 +99,32 @@ func (t *SealTicket) UnmarshalCBOR(r io.Reader) error { } switch name { - // t.BlockHeight (uint64) (uint64) + // t.BlockHeight (abi.ChainEpoch) (int64) case "BlockHeight": + { + maj, extra, err := cbg.CborReadHeader(br) + var extraI int64 + if err != nil { + return err + } + switch maj { + case cbg.MajUnsignedInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 positive overflow") + } + case cbg.MajNegativeInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 negative oveflow") + } + extraI = -1 - extraI + default: + return fmt.Errorf("wrong type for int64 field: %d", maj) + } - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err + t.BlockHeight = abi.ChainEpoch(extraI) } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.BlockHeight = uint64(extra) // t.TicketBytes ([]uint8) (slice) case "TicketBytes": @@ -138,7 +160,7 @@ func (t *SealSeed) MarshalCBOR(w io.Writer) error { return err } - // t.BlockHeight (uint64) (uint64) + // t.BlockHeight (abi.ChainEpoch) (int64) if len("BlockHeight") > cbg.MaxLength { return xerrors.Errorf("Value in field \"BlockHeight\" was too long") } @@ -150,8 +172,14 @@ func (t *SealSeed) MarshalCBOR(w io.Writer) error { return err } - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.BlockHeight))); err != nil { - return err + if t.BlockHeight >= 0 { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.BlockHeight))); err != nil { + return err + } + } else { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajNegativeInt, uint64(-t.BlockHeight)-1)); err != nil { + return err + } } // t.TicketBytes ([]uint8) (slice) @@ -209,17 +237,32 @@ func (t *SealSeed) UnmarshalCBOR(r io.Reader) error { } switch name { - // t.BlockHeight (uint64) (uint64) + // t.BlockHeight (abi.ChainEpoch) (int64) case "BlockHeight": + { + maj, extra, err := cbg.CborReadHeader(br) + var extraI int64 + if err != nil { + return err + } + switch maj { + case cbg.MajUnsignedInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 positive overflow") + } + case cbg.MajNegativeInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 negative oveflow") + } + extraI = -1 - extraI + default: + return fmt.Errorf("wrong type for int64 field: %d", maj) + } - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err + t.BlockHeight = abi.ChainEpoch(extraI) } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.BlockHeight = uint64(extra) // t.TicketBytes ([]uint8) (slice) case "TicketBytes": @@ -255,7 +298,7 @@ func (t *Piece) MarshalCBOR(w io.Writer) error { return err } - // t.DealID (uint64) (uint64) + // t.DealID (abi.DealID) (uint64) if len("DealID") > cbg.MaxLength { return xerrors.Errorf("Value in field \"DealID\" was too long") } @@ -267,11 +310,17 @@ func (t *Piece) MarshalCBOR(w io.Writer) error { return err } - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.DealID))); err != nil { - return err + if t.DealID == nil { + if _, err := w.Write(cbg.CborNull); err != nil { + return err + } + } else { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(*t.DealID))); err != nil { + return err + } } - // t.Size (uint64) (uint64) + // t.Size (abi.UnpaddedPieceSize) (uint64) if len("Size") > cbg.MaxLength { return xerrors.Errorf("Value in field \"Size\" was too long") } @@ -342,28 +391,48 @@ func (t *Piece) UnmarshalCBOR(r io.Reader) error { } switch name { - // t.DealID (uint64) (uint64) + // t.DealID (abi.DealID) (uint64) case "DealID": - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err + { + + 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 { + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + typed := abi.DealID(extra) + t.DealID = &typed + } + } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.DealID = uint64(extra) - // t.Size (uint64) (uint64) + // t.Size (abi.UnpaddedPieceSize) (uint64) case "Size": - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err + { + + 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 = abi.UnpaddedPieceSize(extra) + } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.Size = uint64(extra) // t.CommP ([]uint8) (slice) case "CommP": @@ -415,7 +484,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { return err } - // t.SectorID (uint64) (uint64) + // t.SectorID (abi.SectorNumber) (uint64) if len("SectorID") > cbg.MaxLength { return xerrors.Errorf("Value in field \"SectorID\" was too long") } @@ -722,36 +791,48 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { // t.State (uint64) (uint64) case "State": - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err + { + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.State = uint64(extra) + } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.State = uint64(extra) - // t.SectorID (uint64) (uint64) + // t.SectorID (abi.SectorNumber) (uint64) case "SectorID": - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err + { + + 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 = abi.SectorNumber(extra) + } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.SectorID = uint64(extra) // t.Nonce (uint64) (uint64) case "Nonce": - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err + { + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.Nonce = uint64(extra) + } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.Nonce = uint64(extra) // t.Pieces ([]sealing.Piece) (slice) case "Pieces": @@ -1104,14 +1185,18 @@ func (t *Log) UnmarshalCBOR(r io.Reader) error { // t.Timestamp (uint64) (uint64) case "Timestamp": - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err + { + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.Timestamp = uint64(extra) + } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.Timestamp = uint64(extra) // t.Trace (string) (string) case "Trace": diff --git a/storage/sealing/checks.go b/storage/sealing/checks.go index cbcbca8fc..b45966d9f 100644 --- a/storage/sealing/checks.go +++ b/storage/sealing/checks.go @@ -1,15 +1,23 @@ package sealing import ( + "bytes" "context" + "github.com/ipfs/go-cid" + "github.com/multiformats/go-multihash" + cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" + commcid "github.com/filecoin-project/go-fil-commcid" + "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/filecoin-project/specs-actors/actors/builtin/market" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/lib/zerocomm" ) // TODO: For now we handle this by halting state execution, when we get jsonrpc reconnecting @@ -17,6 +25,7 @@ import ( type ErrApi struct{ error } type ErrInvalidDeals struct{ error } +type ErrInvalidPiece struct{ error } type ErrExpiredDeals struct{ error } type ErrBadCommD struct{ error } @@ -34,21 +43,33 @@ func checkPieces(ctx context.Context, si SectorInfo, api sealingApi) error { } for i, piece := range si.Pieces { - deal, err := api.StateMarketStorageDeal(ctx, piece.DealID, types.EmptyTSK) + if piece.DealID == nil { + exp := zerocomm.ForSize(piece.Size) + if string(piece.CommP) != string(exp[:]) { + return &ErrInvalidPiece{xerrors.Errorf("deal %d piece %d had non-zero CommP %+v", piece.DealID, i, piece.CommP)} + } + continue + } + deal, err := api.StateMarketStorageDeal(ctx, *piece.DealID, types.EmptyTSK) if err != nil { 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.Proposal.PieceCID.Hash()) + if err != nil { + return &ErrInvalidDeals{xerrors.Errorf("decoding piece CID: %w", err)} } - if piece.Size != deal.PieceSize { - 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 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 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 piece.Size != deal.Proposal.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.Proposal.PieceSize)} + } + + if head.Height() >= deal.Proposal.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.Proposal.StartEpoch, head.Height())} } } @@ -68,7 +89,7 @@ func checkSeal(ctx context.Context, maddr address.Address, si SectorInfo, api se return &ErrApi{err} } - ccparams, err := actors.SerializeParams(&actors.ComputeDataCommitmentParams{ + ccparams, err := actors.SerializeParams(&market.ComputeDataCommitmentParams{ DealIDs: si.deals(), SectorSize: ssize, }) @@ -77,12 +98,12 @@ func checkSeal(ctx context.Context, maddr address.Address, si SectorInfo, api se } ccmt := &types.Message{ - To: actors.StorageMarketAddress, + To: builtin.StorageMarketActorAddr, From: maddr, Value: types.NewInt(0), GasPrice: types.NewInt(0), GasLimit: types.NewInt(9999999999), - Method: actors.SMAMethods.ComputeDataCommitment, + Method: builtin.MethodsMarket.ComputeDataCommitment, Params: ccparams, } r, err := api.StateCall(ctx, ccmt, types.EmptyTSK) @@ -92,7 +113,17 @@ func checkSeal(ctx context.Context, maddr address.Address, si SectorInfo, api se if r.ExitCode != 0 { return &ErrBadCommD{xerrors.Errorf("receipt for ComputeDataCommitment had exit code %d", r.ExitCode)} } - if string(r.Return) != string(si.CommD) { + + var c cbg.CborCid + if err := c.UnmarshalCBOR(bytes.NewReader(r.Return)); err != nil { + return err + } + cd, err := commcid.CIDToDataCommitmentV1(cid.Cid(c)) + if err != nil { + return err + } + + if string(cd) != string(si.CommD) { return &ErrBadCommD{xerrors.Errorf("on chain CommD differs from sector: %x != %x", r.Return, si.CommD)} } diff --git a/storage/sealing/fsm.go b/storage/sealing/fsm.go index 6ed5c0cfc..06ba11354 100644 --- a/storage/sealing/fsm.go +++ b/storage/sealing/fsm.go @@ -6,6 +6,7 @@ import ( "reflect" "time" + "github.com/filecoin-project/specs-actors/actors/abi" "golang.org/x/xerrors" "github.com/filecoin-project/lotus/api" @@ -227,7 +228,7 @@ func (m *Sealing) restartSectors(ctx context.Context) error { } for _, sector := range trackedSectors { - if err := m.sectors.Send(sector.SectorID, SectorRestart{}); err != nil { + if err := m.sectors.Send(uint64(sector.SectorID), SectorRestart{}); err != nil { log.Errorf("restarting sector %d: %+v", sector.SectorID, err) } } @@ -237,7 +238,7 @@ func (m *Sealing) restartSectors(ctx context.Context) error { return nil } -func (m *Sealing) ForceSectorState(ctx context.Context, id uint64, state api.SectorState) error { +func (m *Sealing) ForceSectorState(ctx context.Context, id abi.SectorNumber, state api.SectorState) error { return m.sectors.Send(id, SectorForceState{state}) } 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..0a7b33324 100644 --- a/storage/sealing/garbage.go +++ b/storage/sealing/garbage.go @@ -1,106 +1,37 @@ package sealing import ( - "bytes" "context" "io" - "math" - "math/bits" - "math/rand" - sectorbuilder "github.com/filecoin-project/go-sectorbuilder" "golang.org/x/xerrors" - "github.com/filecoin-project/lotus/chain/actors" - "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/specs-actors/actors/abi" ) -func (m *Sealing) pledgeReader(size uint64, parts uint64) io.Reader { - parts = 1 << bits.Len64(parts) // round down to nearest power of 2 - if size/parts < 127 { - parts = size / 127 +type nullReader struct{} + +func (nullReader) Read(out []byte) (int, error) { + for i := range out { + out[i] = 0 } - - piece := sectorbuilder.UserBytesForSectorSize((size/127 + size) / parts) - - readers := make([]io.Reader, parts) - for i := range readers { - readers[i] = io.LimitReader(rand.New(rand.NewSource(42+int64(i))), int64(piece)) - } - - return io.MultiReader(readers...) + return len(out), nil } -func (m *Sealing) pledgeSector(ctx context.Context, sectorID uint64, existingPieceSizes []uint64, sizes ...uint64) ([]Piece, error) { +func (m *Sealing) pledgeReader(size abi.UnpaddedPieceSize) io.Reader { + return io.LimitReader(&nullReader{}, int64(size)) +} + +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)) - 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, - Client: m.worker, - Provider: m.maddr, - ProposalExpiration: math.MaxUint64, - Duration: math.MaxUint64 / 2, // /2 because overflows - StoragePricePerEpoch: types.NewInt(0), - StorageCollateral: types.NewInt(0), - ProposerSignature: nil, // nil because self dealing - } - - deals[i] = sdp - } - - log.Infof("Publishing deals for %d", sectorID) - - params, aerr := actors.SerializeParams(&actors.PublishStorageDealsParams{ - Deals: deals, - }) - if aerr != nil { - return nil, xerrors.Errorf("serializing PublishStorageDeals params failed: ", aerr) - } - - smsg, err := m.api.MpoolPushMessage(ctx, &types.Message{ - To: actors.StorageMarketAddress, - From: m.worker, - Value: types.NewInt(0), - GasPrice: types.NewInt(0), - GasLimit: types.NewInt(1000000), - Method: actors.SMAMethods.PublishStorageDeals, - Params: params, - }) - if err != nil { - return nil, err - } - r, err := m.api.StateWaitMsg(ctx, smsg.Cid()) // TODO: more finality - if err != nil { - return nil, err - } - if r.Receipt.ExitCode != 0 { - log.Error(xerrors.Errorf("publishing deal failed: exit %d", r.Receipt.ExitCode)) - } - var resp actors.PublishStorageDealResponse - if err := resp.UnmarshalCBOR(bytes.NewReader(r.Receipt.Return)); err != nil { - return nil, err - } - if len(resp.DealIDs) != len(sizes) { - return nil, xerrors.New("got unexpected number of DealIDs from PublishStorageDeals") - } - - log.Infof("Deals for sector %d: %+v", sectorID, resp.DealIDs) - out := make([]Piece, len(sizes)) for i, size := range sizes { - ppi, err := m.sb.AddPiece(ctx, size, sectorID, m.pledgeReader(size, uint64(1)), existingPieceSizes) + ppi, err := m.sb.AddPiece(ctx, size, sectorID, m.pledgeReader(size), existingPieceSizes) if err != nil { return nil, xerrors.Errorf("add piece: %w", err) } @@ -108,9 +39,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, - CommP: ppi.CommP[:], + Size: ppi.Size, + CommP: ppi.CommP[:], } } @@ -123,21 +53,21 @@ 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() + sid, err := m.sb.AcquireSectorNumber() if err != nil { log.Errorf("%+v", err) return } - pieces, err := m.pledgeSector(ctx, sid, []uint64{}, size) + pieces, err := m.pledgeSector(ctx, sid, []abi.UnpaddedPieceSize{}, size) if err != nil { log.Errorf("%+v", err) return } - if err := m.newSector(context.TODO(), sid, pieces[0].DealID, pieces[0].ppi()); err != nil { + if err := m.newSector(sid, pieces); err != nil { log.Errorf("%+v", err) return } diff --git a/storage/sealing/sealing.go b/storage/sealing/sealing.go index c39b98257..9851d77a9 100644 --- a/storage/sealing/sealing.go +++ b/storage/sealing/sealing.go @@ -5,19 +5,22 @@ import ( "io" "github.com/filecoin-project/go-address" - "github.com/filecoin-project/go-sectorbuilder" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/namespace" logging "github.com/ipfs/go-log/v2" "golang.org/x/xerrors" + "github.com/filecoin-project/go-padreader" + "github.com/filecoin-project/go-sectorbuilder" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin/miner" + "github.com/filecoin-project/specs-actors/actors/crypto" + "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" - "github.com/filecoin-project/lotus/lib/padreader" "github.com/filecoin-project/lotus/lib/statemachine" ) @@ -31,25 +34,26 @@ 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.TipSetKey) (*api.MethodCall, error) StateMinerWorker(context.Context, address.Address, types.TipSetKey) (address.Address, error) - StateMinerElectionPeriodStart(ctx context.Context, actor address.Address, tsk types.TipSetKey) (uint64, error) + StateMinerPostState(ctx context.Context, actor address.Address, ts types.TipSetKey) (*miner.PoStState, error) StateMinerSectors(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) StateMinerProvingSet(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) - StateMinerSectorSize(context.Context, address.Address, types.TipSetKey) (uint64, error) + StateMinerSectorSize(context.Context, address.Address, types.TipSetKey) (abi.SectorSize, error) StateWaitMsg(context.Context, cid.Cid) (*api.MsgWait, error) // TODO: removeme eventually - StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) + StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error) StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) - StateMarketStorageDeal(context.Context, uint64, types.TipSetKey) (*actors.OnChainDeal, error) + StateMarketStorageDeal(context.Context, abi.DealID, types.TipSetKey) (*api.MarketDeal, 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.TipSetKey) (*types.TipSet, error) + ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) + ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error) ChainGetBlockMessages(context.Context, cid.Cid) (*api.BlockMessages, error) ChainReadObj(context.Context, cid.Cid) ([]byte, error) + ChainHasObj(context.Context, cid.Cid) (bool, error) - WalletSign(context.Context, address.Address, []byte) (*types.Signature, error) + WalletSign(context.Context, address.Address, []byte) (*crypto.Signature, error) WalletBalance(context.Context, address.Address) (types.BigInt, error) WalletHas(context.Context, address.Address) (bool, error) } @@ -95,12 +99,12 @@ 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) { - if padreader.PaddedSize(size) != size { +func (m *Sealing) AllocatePiece(size abi.UnpaddedPieceSize) (sectorID abi.SectorNumber, offset uint64, err error) { + if (padreader.PaddedSize(uint64(size))) != size { return 0, 0, xerrors.Errorf("cannot allocate unpadded piece") } - sid, err := m.sb.AcquireSectorId() // TODO: Put more than one thing in a sector + sid, err := m.sb.AcquireSectorNumber() // TODO: Put more than one thing in a sector if err != nil { return 0, 0, xerrors.Errorf("acquiring sector ID: %w", err) } @@ -109,28 +113,28 @@ 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) } - return m.newSector(ctx, sectorID, dealID, ppi) -} + return m.newSector(sectorID, []Piece{ + { + DealID: &dealID, -func (m *Sealing) newSector(ctx context.Context, sid uint64, dealID uint64, ppi sectorbuilder.PublicPieceInfo) error { - log.Infof("Start sealing %d", sid) - return m.sectors.Send(sid, SectorStart{ - id: sid, - pieces: []Piece{ - { - DealID: dealID, - - Size: ppi.Size, - CommP: ppi.CommP[:], - }, + Size: ppi.Size, + CommP: ppi.CommP[:], }, }) } + +func (m *Sealing) newSector(sid abi.SectorNumber, pieces []Piece) error { + log.Infof("Start sealing %d", sid) + return m.sectors.Send(uint64(sid), SectorStart{ + id: sid, + pieces: pieces, + }) +} diff --git a/storage/sealing/states.go b/storage/sealing/states.go index 723a2d843..a23647502 100644 --- a/storage/sealing/states.go +++ b/storage/sealing/states.go @@ -2,9 +2,13 @@ package sealing import ( "context" + "github.com/filecoin-project/specs-actors/actors/crypto" - sectorbuilder "github.com/filecoin-project/go-sectorbuilder" + commcid "github.com/filecoin-project/go-fil-commcid" "github.com/filecoin-project/go-sectorbuilder/fs" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/filecoin-project/specs-actors/actors/builtin/miner" "golang.org/x/xerrors" "github.com/filecoin-project/lotus/build" @@ -16,12 +20,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) @@ -74,7 +78,7 @@ func (m *Sealing) handleUnsealed(ctx statemachine.Context, sector SectorInfo) er commD: rspco.CommD[:], commR: rspco.CommR[:], ticket: SealTicket{ - BlockHeight: ticket.BlockHeight, + BlockHeight: abi.ChainEpoch(ticket.BlockHeight), TicketBytes: ticket.TicketBytes[:], }, }) @@ -95,12 +99,14 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf } } - params := &actors.SectorPreCommitInfo{ - SectorNumber: sector.SectorID, + params := &miner.SectorPreCommitInfo{ + Expiration: 10000000, // TODO: implement + SectorNumber: sector.SectorID, + RegisteredProof: abi.RegisteredProof_StackedDRG32GiBSeal, - CommR: sector.CommR, - SealEpoch: sector.Ticket.BlockHeight, - DealIDs: sector.deals(), + SealedCID: commcid.ReplicaCommitmentV1ToCID(sector.CommR), + SealRandEpoch: sector.Ticket.BlockHeight, + DealIDs: sector.deals(), } enc, aerr := actors.SerializeParams(params) if aerr != nil { @@ -110,7 +116,7 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf msg := &types.Message{ To: m.maddr, From: m.worker, - Method: actors.MAMethods.PreCommitSector, + Method: builtin.MethodsMiner.PreCommitSector, Params: enc, Value: types.NewInt(0), // TODO: need to ensure sufficient collateral GasLimit: types.NewInt(1000000 /* i dont know help */), @@ -141,11 +147,11 @@ func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) er } log.Info("precommit message landed on chain: ", sector.SectorID) - randHeight := mw.TipSet.Height() + build.InteractivePoRepDelay - 1 // -1 because of how the messages are applied + randHeight := mw.TipSet.Height() + miner.PreCommitChallengeDelay - 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 { - rand, err := m.api.ChainGetRandomness(ectx, ts.Key(), int64(randHeight)) + err = m.events.ChainAt(func(ectx context.Context, ts *types.TipSet, curH abi.ChainEpoch) error { + rand, err := m.api.ChainGetRandomness(ectx, ts.Key(), crypto.DomainSeparationTag_InteractiveSealChallengeSeed, randHeight, nil) if err != nil { err = xerrors.Errorf("failed to get randomness for computing seal proof: %w", err) @@ -163,7 +169,7 @@ func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) er log.Warn("revert in interactive commit sector step") // TODO: need to cancel running process and restart... return nil - }, build.InteractivePoRepConfidence, mw.TipSet.Height()+build.InteractivePoRepDelay) + }, build.InteractivePoRepConfidence, mw.TipSet.Height()+miner.PreCommitChallengeDelay) if err != nil { log.Warn("waitForPreCommitMessage ChainAt errored: ", err) } @@ -174,6 +180,8 @@ func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) er func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo) error { log.Info("scheduling seal proof computation...") + log.Infof("KOMIT %d %x(%d); %x(%d); %v; r:%x; d:%x", sector.SectorID, sector.Ticket.TicketBytes, sector.Ticket.BlockHeight, sector.Seed.TicketBytes, sector.Seed.BlockHeight, sector.pieceInfos(), sector.CommR, sector.CommD) + proof, err := m.sb.SealCommit(ctx.Context(), sector.SectorID, sector.Ticket.SB(), sector.Seed.SB(), sector.pieceInfos(), sector.rspco()) if err != nil { return ctx.Send(SectorComputeProofFailed{xerrors.Errorf("computing seal proof failed: %w", err)}) @@ -181,10 +189,9 @@ func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo) // TODO: Consider splitting states and persist proof for faster recovery - params := &actors.SectorProveCommitInfo{ - Proof: proof, - SectorID: sector.SectorID, - DealIDs: sector.deals(), + params := &miner.ProveCommitSectorParams{ + SectorNumber: sector.SectorID, + Proof: proof, } enc, aerr := actors.SerializeParams(params) @@ -195,7 +202,7 @@ func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo) msg := &types.Message{ To: m.maddr, From: m.worker, - Method: actors.MAMethods.ProveCommitSector, + Method: builtin.MethodsMiner.ProveCommitSector, Params: enc, Value: types.NewInt(0), // TODO: need to ensure sufficient collateral GasLimit: types.NewInt(1000000 /* i dont know help */), @@ -254,10 +261,13 @@ func (m *Sealing) handleFaulty(ctx statemachine.Context, sector SectorInfo) erro // TODO: check if the fault has already been reported, and that this sector is even valid // TODO: coalesce faulty sector reporting - bf := types.NewBitField() - bf.Set(sector.SectorID) + bf := abi.NewBitField() + bf.Set(uint64(sector.SectorID)) - enc, aerr := actors.SerializeParams(&actors.DeclareFaultsParams{bf}) + enc, aerr := actors.SerializeParams(&miner.DeclareTemporaryFaultsParams{ + SectorNumbers: bf, + Duration: 99999999, // TODO: This is very unlikely to be the correct number + }) if aerr != nil { return xerrors.Errorf("failed to serialize declare fault params: %w", aerr) } @@ -265,7 +275,7 @@ func (m *Sealing) handleFaulty(ctx statemachine.Context, sector SectorInfo) erro msg := &types.Message{ To: m.maddr, From: m.worker, - Method: actors.MAMethods.DeclareFaults, + Method: builtin.MethodsMiner.DeclareTemporaryFaults, Params: enc, Value: types.NewInt(0), // TODO: need to ensure sufficient collateral GasLimit: types.NewInt(1000000 /* i dont know help */), diff --git a/storage/sealing/states_failed.go b/storage/sealing/states_failed.go index 642469dd6..aaffe8b43 100644 --- a/storage/sealing/states_failed.go +++ b/storage/sealing/states_failed.go @@ -2,14 +2,17 @@ package sealing import ( "bytes" - "fmt" - "github.com/filecoin-project/lotus/chain/types" "time" + commcid "github.com/filecoin-project/go-fil-commcid" + "github.com/filecoin-project/specs-actors/actors/builtin/miner" + "github.com/filecoin-project/specs-actors/actors/util/adt" "golang.org/x/xerrors" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/api/apibstore" + "github.com/filecoin-project/lotus/chain/store" + "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/lib/statemachine" ) @@ -29,7 +32,7 @@ func failedCooldown(ctx statemachine.Context, sector SectorInfo) error { return nil } -func (m *Sealing) checkPreCommitted(ctx statemachine.Context, sector SectorInfo) (*actors.PreCommittedSector, bool) { +func (m *Sealing) checkPreCommitted(ctx statemachine.Context, sector SectorInfo) (*miner.SectorPreCommitOnChainInfo, bool) { act, err := m.api.StateGetActor(ctx.Context(), m.maddr, types.EmptyTSK) if err != nil { log.Errorf("handleSealFailed(%d): temp error: %+v", sector.SectorID, err) @@ -42,20 +45,20 @@ func (m *Sealing) checkPreCommitted(ctx statemachine.Context, sector SectorInfo) return nil, true } - var state actors.StorageMinerActorState + var state miner.State if err := state.UnmarshalCBOR(bytes.NewReader(st)); err != nil { log.Errorf("handleSealFailed(%d): temp error: unmarshaling miner state: %+v", sector.SectorID, err) return nil, true } - pci, found := state.PreCommittedSectors[fmt.Sprint(sector.SectorID)] - if found { - // TODO: If not expired yet, we can just try reusing sealticket - log.Warnf("sector %d found in miner preseal array", sector.SectorID) - return pci, true + var pci miner.SectorPreCommitOnChainInfo + precommits := adt.AsMap(store.ActorStore(ctx.Context(), apibstore.NewAPIBlockstore(m.api)), state.PreCommittedSectors) + if _, err := precommits.Get(adt.UIntKey(uint64(sector.SectorID)), &pci); err != nil { + log.Error(err) + return nil, true } - return nil, false + return &pci, false } func (m *Sealing) handleSealFailed(ctx statemachine.Context, sector SectorInfo) error { @@ -93,8 +96,13 @@ func (m *Sealing) handlePreCommitFailed(ctx statemachine.Context, sector SectorI return nil // TODO: SeedWait needs this currently } - if string(pci.Info.CommR) != string(sector.CommR) { - log.Warn("sector %d is precommitted on chain, with different CommR: %x != %x", sector.SectorID, pci.Info.CommR, sector.CommR) + pciR, err := commcid.CIDToReplicaCommitmentV1(pci.Info.SealedCID) + if err != nil { + return err + } + + if string(pciR) != string(sector.CommR) { + log.Warn("sector %d is precommitted on chain, with different CommR: %x != %x", sector.SectorID, pciR, sector.CommR) return nil // TODO: remove when the actor allows re-precommit } diff --git a/storage/sealing/types.go b/storage/sealing/types.go index f0fbe09a4..e2a2c049d 100644 --- a/storage/sealing/types.go +++ b/storage/sealing/types.go @@ -3,27 +3,28 @@ 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" ) type SealTicket struct { - BlockHeight uint64 + BlockHeight abi.ChainEpoch TicketBytes []byte } func (t *SealTicket) SB() sectorbuilder.SealTicket { - out := sectorbuilder.SealTicket{BlockHeight: t.BlockHeight} + out := sectorbuilder.SealTicket{BlockHeight: uint64(t.BlockHeight)} copy(out.TicketBytes[:], t.TicketBytes) return out } 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,9 +34,9 @@ func (t *SealSeed) Equals(o *SealSeed) bool { } type Piece struct { - DealID uint64 + DealID *abi.DealID - Size uint64 + Size abi.UnpaddedPieceSize CommP []byte } @@ -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,19 @@ func (t *SectorInfo) pieceInfos() []sectorbuilder.PublicPieceInfo { return out } -func (t *SectorInfo) deals() []uint64 { - out := make([]uint64, len(t.Pieces)) - for i, piece := range t.Pieces { - out[i] = piece.DealID +func (t *SectorInfo) deals() []abi.DealID { + out := make([]abi.DealID, 0, len(t.Pieces)) + for _, piece := range t.Pieces { + if piece.DealID == nil { + continue + } + out = append(out, *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..cfc17734c 100644 --- a/storage/sealing/utils.go +++ b/storage/sealing/utils.go @@ -1,17 +1,11 @@ package sealing import ( - "io" + "github.com/filecoin-project/specs-actors/actors/abi" "math/bits" - "math/rand" - "sync" - - "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 +18,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,49 +36,11 @@ 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) { - parts = 1 << bits.Len64(parts) // round down to nearest power of 2 - if size/parts < 127 { - parts = size / 127 - } - - piece := sectorbuilder.UserBytesForSectorSize((size + size/127) / parts) - out := make([]sectorbuilder.PublicPieceInfo, parts) - var lk sync.Mutex - - var wg sync.WaitGroup - wg.Add(int(parts)) - for i := uint64(0); i < parts; i++ { - go func(i uint64) { - defer wg.Done() - - commP, perr := sectorbuilder.GeneratePieceCommitment(io.LimitReader(rand.New(rand.NewSource(42+int64(i))), int64(piece)), piece) - - lk.Lock() - if perr != nil { - err = multierror.Append(err, perr) - } - out[i] = sectorbuilder.PublicPieceInfo{ - Size: piece, - CommP: commP, - } - lk.Unlock() - }(i) - } - wg.Wait() - - if err != nil { - return [32]byte{}, err - } - - return sectorbuilder.GenerateDataCommitment(m.sb.SectorSize(), out) -} - func (m *Sealing) ListSectors() ([]SectorInfo, error) { var sectors []SectorInfo if err := m.sectors.List(§ors); err != nil { @@ -93,8 +49,8 @@ func (m *Sealing) ListSectors() ([]SectorInfo, error) { return sectors, nil } -func (m *Sealing) GetSectorInfo(sid uint64) (SectorInfo, error) { +func (m *Sealing) GetSectorInfo(sid abi.SectorNumber) (SectorInfo, error) { var out SectorInfo - err := m.sectors.Get(sid).Get(&out) + err := m.sectors.Get(uint64(sid)).Get(&out) return out, err } diff --git a/storage/sealing/utils_test.go b/storage/sealing/utils_test.go index 94bf858c1..a5287fd87 100644 --- a/storage/sealing/utils_test.go +++ b/storage/sealing/utils_test.go @@ -1,20 +1,21 @@ package sealing import ( - "github.com/filecoin-project/lotus/storage/sbmock" "testing" - "github.com/stretchr/testify/assert" + "github.com/filecoin-project/specs-actors/actors/abi" - sectorbuilder "github.com/filecoin-project/go-sectorbuilder" + "github.com/filecoin-project/lotus/storage/sbmock" + + "github.com/stretchr/testify/assert" ) -func testFill(t *testing.T, n uint64, exp []uint64) { +func testFill(t *testing.T, n abi.UnpaddedPieceSize, exp []abi.UnpaddedPieceSize) { f, err := fillersFromRem(n) assert.NoError(t, err) assert.Equal(t, exp, f) - var sum uint64 + var sum abi.UnpaddedPieceSize for _, u := range f { sum += u } @@ -24,39 +25,39 @@ func testFill(t *testing.T, n uint64, exp []uint64) { func TestFillersFromRem(t *testing.T) { for i := 8; i < 32; i++ { // single - ub := sectorbuilder.UserBytesForSectorSize(uint64(1) << i) - testFill(t, ub, []uint64{ub}) + ub := abi.PaddedPieceSize(uint64(1) << i).Unpadded() + testFill(t, ub, []abi.UnpaddedPieceSize{ub}) // 2 - ub = sectorbuilder.UserBytesForSectorSize(uint64(5) << i) - ub1 := sectorbuilder.UserBytesForSectorSize(uint64(1) << i) - ub3 := sectorbuilder.UserBytesForSectorSize(uint64(4) << i) - testFill(t, ub, []uint64{ub1, ub3}) + ub = abi.PaddedPieceSize(uint64(5) << i).Unpadded() + ub1 := abi.PaddedPieceSize(uint64(1) << i).Unpadded() + ub3 := abi.PaddedPieceSize(uint64(4) << i).Unpadded() + testFill(t, ub, []abi.UnpaddedPieceSize{ub1, ub3}) // 4 - ub = sectorbuilder.UserBytesForSectorSize(uint64(15) << i) - ub2 := sectorbuilder.UserBytesForSectorSize(uint64(2) << i) - ub4 := sectorbuilder.UserBytesForSectorSize(uint64(8) << i) - testFill(t, ub, []uint64{ub1, ub2, ub3, ub4}) + ub = abi.PaddedPieceSize(uint64(15) << i).Unpadded() + ub2 := abi.PaddedPieceSize(uint64(2) << i).Unpadded() + ub4 := abi.PaddedPieceSize(uint64(8) << i).Unpadded() + testFill(t, ub, []abi.UnpaddedPieceSize{ub1, ub2, ub3, ub4}) // different 2 - ub = sectorbuilder.UserBytesForSectorSize(uint64(9) << i) - testFill(t, ub, []uint64{ub1, ub4}) + ub = abi.PaddedPieceSize(uint64(9) << i).Unpadded() + testFill(t, ub, []abi.UnpaddedPieceSize{ub1, ub4}) } } func TestFastPledge(t *testing.T) { - sz := uint64(16 << 20) + sz := abi.PaddedPieceSize(16 << 20) - s := Sealing{sb: sbmock.NewMockSectorBuilder(0, sz)} - if _, err := s.fastPledgeCommitment(sectorbuilder.UserBytesForSectorSize(sz), 5); err != nil { + s := Sealing{sb: sbmock.NewMockSectorBuilder(0, abi.SectorSize(sz))} + if _, err := s.fastPledgeCommitment(sz.Unpadded(), 5); err != nil { t.Fatalf("%+v", err) } - sz = uint64(1024) + sz = abi.PaddedPieceSize(1024) - s = Sealing{sb: sbmock.NewMockSectorBuilder(0, sz)} - if _, err := s.fastPledgeCommitment(sectorbuilder.UserBytesForSectorSize(sz), 64); err != nil { + s = Sealing{sb: sbmock.NewMockSectorBuilder(0, abi.SectorSize(sz))} + if _, err := s.fastPledgeCommitment(sz.Unpadded(), 64); err != nil { t.Fatalf("%+v", err) } } diff --git a/storage/sectorblocks/blocks.go b/storage/sectorblocks/blocks.go index 363043dd0..f485e2860 100644 --- a/storage/sectorblocks/blocks.go +++ b/storage/sectorblocks/blocks.go @@ -8,7 +8,9 @@ import ( "io" "sync" + "github.com/filecoin-project/go-padreader" 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" @@ -16,8 +18,8 @@ import ( "golang.org/x/xerrors" cborutil "github.com/filecoin-project/go-cbor-util" + "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/lib/padreader" "github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/storage" ) @@ -32,9 +34,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 +67,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 +99,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 +142,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 +159,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 +168,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)) } diff --git a/tools/stats/main.go b/tools/stats/main.go index fb383e8e1..bd84f3193 100644 --- a/tools/stats/main.go +++ b/tools/stats/main.go @@ -6,6 +6,7 @@ import ( "os" "time" + "github.com/filecoin-project/specs-actors/actors/abi" logging "github.com/ipfs/go-log/v2" ) @@ -66,7 +67,7 @@ func main() { log.Fatal(err) } - tipsetsCh, err := GetTips(ctx, api, uint64(height)) + tipsetsCh, err := GetTips(ctx, api, abi.ChainEpoch(height)) if err != nil { log.Fatal(err) } diff --git a/tools/stats/metrics.go b/tools/stats/metrics.go index 8154e74f1..c46b9313a 100644 --- a/tools/stats/metrics.go +++ b/tools/stats/metrics.go @@ -11,8 +11,8 @@ import ( "github.com/filecoin-project/go-address" "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/types" + "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/ipfs/go-cid" "github.com/multiformats/go-multihash" @@ -149,7 +149,7 @@ func RecordTipsetStatePoints(ctx context.Context, api api.FullNode, pl *PointLis p := NewPoint("chain.pledge_collateral", pcFilFloat) pl.AddPoint(p) - netBal, err := api.WalletBalance(ctx, actors.NetworkAddress) + netBal, err := api.WalletBalance(ctx, builtin.RewardActorAddr) if err != nil { return err } @@ -229,7 +229,7 @@ func RecordTipsetMessagesPoints(ctx context.Context, api api.FullNode, pl *Point } tag := msgTag{ actor: string(dm.Digest), - method: msg.Message.Method, + method: uint64(msg.Message.Method), exitcode: recp[i].ExitCode, } diff --git a/tools/stats/rpc.go b/tools/stats/rpc.go index 860ffc95f..b1f51381b 100644 --- a/tools/stats/rpc.go +++ b/tools/stats/rpc.go @@ -5,6 +5,7 @@ import ( "net/http" "time" + "github.com/filecoin-project/specs-actors/actors/abi" manet "github.com/multiformats/go-multiaddr-net" "golang.org/x/xerrors" @@ -120,7 +121,7 @@ sync_complete: } } -func GetTips(ctx context.Context, api api.FullNode, lastHeight uint64) (<-chan *types.TipSet, error) { +func GetTips(ctx context.Context, api api.FullNode, lastHeight abi.ChainEpoch) (<-chan *types.TipSet, error) { chmain := make(chan *types.TipSet) notif, err := api.ChainNotify(ctx) @@ -175,7 +176,7 @@ func GetTips(ctx context.Context, api api.FullNode, lastHeight uint64) (<-chan * return chmain, nil } -func loadTipsets(ctx context.Context, api api.FullNode, curr *types.TipSet, lowestHeight uint64) ([]*types.TipSet, error) { +func loadTipsets(ctx context.Context, api api.FullNode, curr *types.TipSet, lowestHeight abi.ChainEpoch) ([]*types.TipSet, error) { tipsets := []*types.TipSet{} for { if curr.Height() == 0 {