2020-01-20 22:03:50 +00:00
package sealing
import (
"context"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
2020-01-23 14:05:44 +00:00
"github.com/filecoin-project/lotus/build"
2020-01-20 22:03:50 +00:00
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/types"
)
2020-01-23 15:38:01 +00:00
// TODO: For now we handle this by halting state execution, when we get jsonrpc reconnecting
// We should implement some wait-for-api logic
2020-01-23 12:17:45 +00:00
type ErrApi error
type ErrInvalidDeals error
type ErrExpiredDeals error
2020-01-23 14:05:44 +00:00
type ErrBadCommD error
type ErrExpiredTicket error
2020-01-22 19:47:29 +00:00
func checkPieces ( ctx context . Context , si SectorInfo , api sealingApi ) error {
2020-01-23 12:17:45 +00:00
head , err := api . ChainHead ( ctx )
if err != nil {
return ErrApi ( xerrors . Errorf ( "getting chain head: %w" , err ) )
}
2020-01-20 22:03:50 +00:00
for i , piece := range si . Pieces {
deal , err := api . StateMarketStorageDeal ( ctx , piece . DealID , nil )
if err != nil {
2020-01-23 12:17:45 +00:00
return ErrApi ( xerrors . Errorf ( "getting deal %d for piece %d: %w" , piece . DealID , i , err ) )
2020-01-20 22:03:50 +00:00
}
if string ( deal . PieceRef ) != string ( piece . CommP ) {
2020-01-23 12:17:45 +00:00
return ErrInvalidDeals ( xerrors . Errorf ( "piece %d of sector %d refers deal %d with wrong CommP: %x != %x" , i , si . SectorID , piece . DealID , piece . CommP , deal . PieceRef ) )
2020-01-20 22:03:50 +00:00
}
if piece . Size != deal . PieceSize {
2020-01-23 12:17:45 +00:00
return ErrInvalidDeals ( xerrors . Errorf ( "piece %d of sector %d refers deal %d with different size: %d != %d" , i , si . SectorID , piece . DealID , piece . Size , deal . PieceSize ) )
}
if head . Height ( ) >= deal . ProposalExpiration {
return ErrExpiredDeals ( xerrors . Errorf ( "piece %d of sector %d refers expired deal %d - expires %d, head %d" , i , si . SectorID , piece . DealID , deal . ProposalExpiration , head . Height ( ) ) )
2020-01-20 22:03:50 +00:00
}
}
return nil
}
2020-01-22 19:47:29 +00:00
func checkSeal ( ctx context . Context , maddr address . Address , si SectorInfo , api sealingApi ) ( err error ) {
2020-01-23 14:05:44 +00:00
head , err := api . ChainHead ( ctx )
2020-01-20 22:03:50 +00:00
if err != nil {
2020-01-23 14:05:44 +00:00
return ErrApi ( xerrors . Errorf ( "getting chain head: %w" , err ) )
}
ssize , err := api . StateMinerSectorSize ( ctx , maddr , head )
if err != nil {
return ErrApi ( err )
2020-01-20 22:03:50 +00:00
}
ccparams , err := actors . SerializeParams ( & actors . ComputeDataCommitmentParams {
DealIDs : si . deals ( ) ,
SectorSize : ssize ,
} )
if err != nil {
return xerrors . Errorf ( "computing params for ComputeDataCommitment: %w" , err )
}
ccmt := & types . Message {
To : actors . StorageMarketAddress ,
2020-01-22 19:47:29 +00:00
From : maddr ,
2020-01-20 22:03:50 +00:00
Value : types . NewInt ( 0 ) ,
GasPrice : types . NewInt ( 0 ) ,
GasLimit : types . NewInt ( 9999999999 ) ,
Method : actors . SMAMethods . ComputeDataCommitment ,
Params : ccparams ,
}
r , err := api . StateCall ( ctx , ccmt , nil )
if err != nil {
2020-01-23 15:38:01 +00:00
return ErrApi ( xerrors . Errorf ( "calling ComputeDataCommitment: %w" , err ) )
2020-01-20 22:03:50 +00:00
}
if r . ExitCode != 0 {
2020-01-23 14:05:44 +00:00
return ErrBadCommD ( xerrors . Errorf ( "receipt for ComputeDataCommitment had exit code %d" , r . ExitCode ) )
2020-01-20 22:03:50 +00:00
}
if string ( r . Return ) != string ( si . CommD ) {
2020-01-23 14:05:44 +00:00
return ErrBadCommD ( xerrors . Errorf ( "on chain CommD differs from sector: %x != %x" , r . Return , si . CommD ) )
}
2020-01-23 14:18:05 +00:00
if int64 ( head . Height ( ) ) - int64 ( si . Ticket . BlockHeight + build . SealRandomnessLookback ) > build . SealRandomnessLookbackLimit {
return ErrExpiredTicket ( xerrors . Errorf ( "ticket expired: seal height: %d, head: %d" , si . Ticket . BlockHeight + build . SealRandomnessLookback , head . Height ( ) ) )
2020-01-20 22:03:50 +00:00
}
return nil
}