2019-11-27 02:47:08 +00:00
package main
import (
2019-11-28 01:43:36 +00:00
"context"
2019-12-10 13:22:39 +00:00
"encoding/json"
2019-11-27 02:47:08 +00:00
"fmt"
"io/ioutil"
2019-12-10 19:53:39 +00:00
"math/big"
2019-11-27 02:47:08 +00:00
"math/rand"
"os"
"path/filepath"
"time"
2019-12-16 13:49:58 +00:00
"github.com/docker/go-units"
2020-01-08 19:10:57 +00:00
logging "github.com/ipfs/go-log/v2"
2020-05-07 23:44:12 +00:00
"github.com/minio/blake2b-simd"
2019-11-27 02:47:08 +00:00
"github.com/mitchellh/go-homedir"
2020-06-02 18:12:53 +00:00
"github.com/urfave/cli/v2"
2020-06-05 22:59:01 +00:00
"golang.org/x/xerrors"
2019-11-27 02:47:08 +00:00
2019-12-19 20:13:17 +00:00
"github.com/filecoin-project/go-address"
2020-03-15 17:48:27 +00:00
paramfetch "github.com/filecoin-project/go-paramfetch"
2020-06-05 17:19:33 +00:00
lcli "github.com/filecoin-project/lotus/cli"
2020-05-12 17:58:12 +00:00
"github.com/filecoin-project/sector-storage/ffiwrapper"
"github.com/filecoin-project/sector-storage/ffiwrapper/basicfs"
2020-05-07 23:44:12 +00:00
"github.com/filecoin-project/sector-storage/stores"
2020-03-15 17:48:27 +00:00
"github.com/filecoin-project/specs-actors/actors/abi"
2020-05-12 17:58:12 +00:00
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
2020-03-15 17:48:27 +00:00
"github.com/filecoin-project/specs-storage/storage"
2020-02-28 18:06:59 +00:00
2020-02-27 22:23:05 +00:00
lapi "github.com/filecoin-project/lotus/api"
2019-11-27 02:47:08 +00:00
"github.com/filecoin-project/lotus/build"
2019-12-10 19:53:39 +00:00
"github.com/filecoin-project/lotus/chain/types"
2019-12-10 13:22:39 +00:00
"github.com/filecoin-project/lotus/genesis"
2019-11-27 02:47:08 +00:00
)
var log = logging . Logger ( "lotus-bench" )
type BenchResults struct {
2020-02-10 19:16:36 +00:00
SectorSize abi . SectorSize
2019-11-27 02:47:08 +00:00
SealingResults [ ] SealingResult
PostGenerateCandidates time . Duration
2020-04-13 22:13:34 +00:00
PostWinningProofCold time . Duration
PostWinningProofHot time . Duration
VerifyWinningPostCold time . Duration
VerifyWinningPostHot time . Duration
PostWindowProofCold time . Duration
PostWindowProofHot time . Duration
VerifyWindowPostCold time . Duration
VerifyWindowPostHot time . Duration
2019-11-27 02:47:08 +00:00
}
type SealingResult struct {
2020-02-28 18:06:59 +00:00
AddPiece time . Duration
PreCommit1 time . Duration
PreCommit2 time . Duration
Commit1 time . Duration
Commit2 time . Duration
Verify time . Duration
Unseal time . Duration
2019-11-27 02:47:08 +00:00
}
2020-02-29 02:31:25 +00:00
type Commit2In struct {
2020-03-01 02:52:23 +00:00
SectorNum int64
Phase1Out [ ] byte
SectorSize uint64
2020-02-29 02:31:25 +00:00
}
2019-11-27 02:47:08 +00:00
func main ( ) {
logging . SetLogLevel ( "*" , "INFO" )
log . Info ( "Starting lotus-bench" )
2020-06-15 16:30:49 +00:00
miner . SupportedProofTypes [ abi . RegisteredSealProof_StackedDrg2KiBV1 ] = struct { } { }
2019-12-17 19:59:14 +00:00
2019-11-27 02:47:08 +00:00
app := & cli . App {
Name : "lotus-bench" ,
Usage : "Benchmark performance of lotus on your hardware" ,
2020-06-01 18:43:51 +00:00
Version : build . UserVersion ( ) ,
2020-03-01 02:52:23 +00:00
Commands : [ ] * cli . Command {
proveCmd ,
2020-04-02 21:18:57 +00:00
sealBenchCmd ,
importBenchCmd ,
2020-03-01 02:52:23 +00:00
} ,
2020-04-02 21:18:57 +00:00
}
2019-11-27 02:47:08 +00:00
2020-04-02 21:18:57 +00:00
if err := app . Run ( os . Args ) ; err != nil {
log . Warnf ( "%+v" , err )
return
}
}
2019-12-10 13:01:17 +00:00
2020-04-02 21:18:57 +00:00
var sealBenchCmd = & cli . Command {
Name : "sealing" ,
Flags : [ ] cli . Flag {
& cli . StringFlag {
Name : "storage-dir" ,
Value : "~/.lotus-bench" ,
Usage : "Path to the storage directory that will store sectors long term" ,
} ,
& cli . StringFlag {
Name : "sector-size" ,
Value : "512MiB" ,
Usage : "size of the sectors in bytes, i.e. 32GiB" ,
} ,
& cli . BoolFlag {
Name : "no-gpu" ,
Usage : "disable gpu usage for the benchmark run" ,
} ,
& cli . StringFlag {
Name : "miner-addr" ,
Usage : "pass miner address (only necessary if using existing sectorbuilder)" ,
Value : "t01000" ,
} ,
& cli . StringFlag {
Name : "benchmark-existing-sectorbuilder" ,
2020-04-10 22:20:48 +00:00
Usage : "pass a directory to run post timings on an existing sectorbuilder" ,
2020-04-02 21:18:57 +00:00
} ,
& cli . BoolFlag {
Name : "json-out" ,
Usage : "output results in json format" ,
} ,
& cli . BoolFlag {
Name : "skip-commit2" ,
Usage : "skip the commit2 (snark) portion of the benchmark" ,
} ,
& cli . BoolFlag {
Name : "skip-unseal" ,
Usage : "skip the unseal portion of the benchmark" ,
} ,
& cli . StringFlag {
Name : "save-commit2-input" ,
Usage : "Save commit2 input to a file" ,
} ,
2020-04-21 19:47:07 +00:00
& cli . IntFlag {
2020-04-21 21:38:26 +00:00
Name : "num-sectors" ,
2020-04-21 19:47:07 +00:00
Value : 1 ,
} ,
2020-06-17 00:39:51 +00:00
& cli . IntFlag {
Name : "parallel" ,
Value : 1 ,
} ,
2020-04-02 21:18:57 +00:00
} ,
Action : func ( c * cli . Context ) error {
if c . Bool ( "no-gpu" ) {
2020-05-27 20:53:20 +00:00
err := os . Setenv ( "BELLMAN_NO_GPU" , "1" )
if err != nil {
return xerrors . Errorf ( "setting no-gpu flag: %w" , err )
}
2020-04-02 21:18:57 +00:00
}
2019-12-10 13:01:17 +00:00
2020-04-02 21:18:57 +00:00
robench := c . String ( "benchmark-existing-sectorbuilder" )
2019-12-10 13:01:17 +00:00
2020-04-02 21:18:57 +00:00
var sbdir string
2019-11-27 02:47:08 +00:00
2020-04-02 21:18:57 +00:00
if robench == "" {
sdir , err := homedir . Expand ( c . String ( "storage-dir" ) )
2019-11-27 02:47:08 +00:00
if err != nil {
return err
}
2020-05-27 23:15:19 +00:00
err = os . MkdirAll ( sdir , 0775 ) //nolint:gosec
2020-05-27 20:53:20 +00:00
if err != nil {
return xerrors . Errorf ( "creating sectorbuilder dir: %w" , err )
}
2020-04-02 21:18:57 +00:00
tsdir , err := ioutil . TempDir ( sdir , "bench" )
2019-12-11 02:06:28 +00:00
if err != nil {
return err
}
2020-04-02 21:18:57 +00:00
defer func ( ) {
if err := os . RemoveAll ( tsdir ) ; err != nil {
log . Warn ( "remove all: " , err )
}
} ( )
2020-04-22 19:47:20 +00:00
// TODO: pretty sure this isnt even needed?
if err := os . MkdirAll ( tsdir , 0775 ) ; err != nil {
return err
}
2020-04-02 21:18:57 +00:00
sbdir = tsdir
} else {
exp , err := homedir . Expand ( robench )
2020-02-27 22:23:05 +00:00
if err != nil {
return err
}
2020-04-02 21:18:57 +00:00
sbdir = exp
}
2020-02-27 22:23:05 +00:00
2020-04-22 19:47:20 +00:00
// miner address
2020-04-02 21:18:57 +00:00
maddr , err := address . NewFromString ( c . String ( "miner-addr" ) )
if err != nil {
return err
}
2020-04-22 19:47:20 +00:00
amid , err := address . IDFromAddress ( maddr )
if err != nil {
return err
}
mid := abi . ActorID ( amid )
2019-12-10 13:01:17 +00:00
2020-04-22 19:47:20 +00:00
// sector size
2020-04-02 21:18:57 +00:00
sectorSizeInt , err := units . RAMInBytes ( c . String ( "sector-size" ) )
if err != nil {
return err
}
sectorSize := abi . SectorSize ( sectorSizeInt )
2019-11-27 02:47:08 +00:00
2020-04-10 22:20:48 +00:00
spt , err := ffiwrapper . SealProofTypeFromSectorSize ( sectorSize )
2020-04-02 21:18:57 +00:00
if err != nil {
return err
}
2020-02-28 18:06:59 +00:00
2020-04-02 21:18:57 +00:00
cfg := & ffiwrapper . Config {
SealProofType : spt ,
}
2020-02-28 18:06:59 +00:00
2020-04-22 19:47:20 +00:00
// Only fetch parameters if actually needed
2020-04-02 21:18:57 +00:00
if ! c . Bool ( "skip-commit2" ) {
2020-06-05 22:58:24 +00:00
if err := paramfetch . GetParams ( lcli . ReqContext ( c ) , build . ParametersJSON ( ) , uint64 ( sectorSize ) ) ; err != nil {
2020-04-02 21:18:57 +00:00
return xerrors . Errorf ( "getting params: %w" , err )
2020-02-27 22:23:05 +00:00
}
2020-04-02 21:18:57 +00:00
}
sbfs := & basicfs . Provider {
Root : sbdir ,
}
2020-02-27 22:23:05 +00:00
2020-04-02 21:18:57 +00:00
sb , err := ffiwrapper . New ( sbfs , cfg )
if err != nil {
return err
}
2020-02-27 22:23:05 +00:00
2020-04-02 21:18:57 +00:00
var sealTimings [ ] SealingResult
var sealedSectors [ ] abi . SectorInfo
2019-11-27 02:47:08 +00:00
2020-04-22 19:47:20 +00:00
if robench == "" {
var err error
2020-06-17 18:02:48 +00:00
parCfg := ParCfg {
PreCommit1 : c . Int ( "parallel" ) ,
PreCommit2 : 1 ,
Commit : 1 ,
}
sealTimings , sealedSectors , err = runSeals ( sb , sbfs , c . Int ( "num-sectors" ) , parCfg , mid , sectorSize , [ ] byte ( c . String ( "ticket-preimage" ) ) , c . String ( "save-commit2-input" ) , c . Bool ( "skip-commit2" ) , c . Bool ( "skip-unseal" ) )
2020-04-02 21:18:57 +00:00
if err != nil {
2020-04-22 19:47:20 +00:00
return xerrors . Errorf ( "failed to run seals: %w" , err )
2020-04-02 21:18:57 +00:00
}
}
2019-12-10 13:22:39 +00:00
2020-04-02 21:18:57 +00:00
beforePost := time . Now ( )
var challenge [ 32 ] byte
rand . Read ( challenge [ : ] )
if robench != "" {
2020-04-22 20:01:09 +00:00
// TODO: implement sbfs.List() and use that for all cases (preexisting sectorbuilder or not)
2020-04-02 21:18:57 +00:00
// TODO: this assumes we only ever benchmark a preseal
// sectorbuilder directory... we need a better way to handle
// this in other cases
fdata , err := ioutil . ReadFile ( filepath . Join ( sbdir , "pre-seal-" + maddr . String ( ) + ".json" ) )
if err != nil {
return err
2019-12-10 13:22:39 +00:00
}
2020-04-02 21:18:57 +00:00
var genmm map [ string ] genesis . Miner
if err := json . Unmarshal ( fdata , & genmm ) ; err != nil {
return err
2019-11-27 02:47:08 +00:00
}
2020-04-02 21:18:57 +00:00
genm , ok := genmm [ maddr . String ( ) ]
if ! ok {
return xerrors . Errorf ( "preseal file didnt have expected miner in it" )
}
2020-02-27 22:23:05 +00:00
2020-04-02 21:18:57 +00:00
for _ , s := range genm . Sectors {
sealedSectors = append ( sealedSectors , abi . SectorInfo {
2020-06-15 16:30:49 +00:00
SealedCID : s . CommR ,
SectorNumber : s . SectorID ,
SealProof : s . ProofType ,
2020-04-02 21:18:57 +00:00
} )
}
}
2019-11-27 02:47:08 +00:00
2020-04-02 21:18:57 +00:00
bo := BenchResults {
SectorSize : sectorSize ,
SealingResults : sealTimings ,
}
2019-11-29 18:48:07 +00:00
2020-04-02 21:18:57 +00:00
if ! c . Bool ( "skip-commit2" ) {
2020-04-10 12:19:06 +00:00
log . Info ( "generating winning post candidates" )
2020-06-15 17:53:21 +00:00
wipt , err := spt . RegisteredWinningPoStProof ( )
2020-06-15 16:30:49 +00:00
if err != nil {
return err
}
2020-06-15 17:53:21 +00:00
fcandidates , err := ffiwrapper . ProofVerifier . GenerateWinningPoStSectorChallenge ( context . TODO ( ) , wipt , mid , challenge [ : ] , uint64 ( len ( sealedSectors ) ) )
2020-04-02 21:18:57 +00:00
if err != nil {
return err
}
2019-11-29 18:48:07 +00:00
2020-04-10 12:19:06 +00:00
candidates := make ( [ ] abi . SectorInfo , len ( fcandidates ) )
for i , fcandidate := range fcandidates {
2020-04-13 22:13:34 +00:00
candidates [ i ] = sealedSectors [ fcandidate ]
2020-04-02 21:18:57 +00:00
}
2019-11-27 02:47:08 +00:00
2020-04-02 21:18:57 +00:00
gencandidates := time . Now ( )
2019-11-27 02:47:08 +00:00
2020-04-10 12:19:06 +00:00
log . Info ( "computing winning post snark (cold)" )
proof1 , err := sb . GenerateWinningPoSt ( context . TODO ( ) , mid , candidates , challenge [ : ] )
2020-04-02 21:18:57 +00:00
if err != nil {
return err
}
2019-11-29 18:48:07 +00:00
2020-06-17 19:49:23 +00:00
winningpost1 := time . Now ( )
2019-11-28 01:43:36 +00:00
2020-04-10 12:19:06 +00:00
log . Info ( "computing winning post snark (hot)" )
proof2 , err := sb . GenerateWinningPoSt ( context . TODO ( ) , mid , candidates , challenge [ : ] )
2020-04-02 21:18:57 +00:00
if err != nil {
return err
}
2019-11-29 18:48:07 +00:00
2020-04-13 22:13:34 +00:00
winnningpost2 := time . Now ( )
2020-02-27 22:23:05 +00:00
2020-04-10 12:19:06 +00:00
pvi1 := abi . WinningPoStVerifyInfo {
2020-04-10 21:07:18 +00:00
Randomness : abi . PoStRandomness ( challenge [ : ] ) ,
Proofs : proof1 ,
2020-04-10 12:19:06 +00:00
ChallengedSectors : candidates ,
2020-04-10 21:07:18 +00:00
Prover : mid ,
2020-04-02 21:18:57 +00:00
}
2020-04-10 12:19:06 +00:00
ok , err := ffiwrapper . ProofVerifier . VerifyWinningPoSt ( context . TODO ( ) , pvi1 )
2020-04-02 21:18:57 +00:00
if err != nil {
return err
}
if ! ok {
log . Error ( "post verification failed" )
}
2020-03-15 17:48:27 +00:00
2020-06-17 19:49:23 +00:00
verifyWinningPost1 := time . Now ( )
2020-04-02 21:18:57 +00:00
2020-04-10 12:19:06 +00:00
pvi2 := abi . WinningPoStVerifyInfo {
2020-04-10 21:07:18 +00:00
Randomness : abi . PoStRandomness ( challenge [ : ] ) ,
Proofs : proof2 ,
2020-04-10 12:19:06 +00:00
ChallengedSectors : candidates ,
2020-04-10 21:07:18 +00:00
Prover : mid ,
2020-03-15 17:48:27 +00:00
}
2019-11-27 02:47:08 +00:00
2020-04-10 12:19:06 +00:00
ok , err = ffiwrapper . ProofVerifier . VerifyWinningPoSt ( context . TODO ( ) , pvi2 )
2020-04-02 21:18:57 +00:00
if err != nil {
return err
}
if ! ok {
log . Error ( "post verification failed" )
}
2020-04-13 22:13:34 +00:00
verifyWinningPost2 := time . Now ( )
log . Info ( "computing window post snark (cold)" )
2020-06-08 18:20:58 +00:00
wproof1 , _ , err := sb . GenerateWindowPoSt ( context . TODO ( ) , mid , sealedSectors , challenge [ : ] )
2020-04-13 22:13:34 +00:00
if err != nil {
return err
}
windowpost1 := time . Now ( )
log . Info ( "computing window post snark (hot)" )
2020-06-08 18:20:58 +00:00
wproof2 , _ , err := sb . GenerateWindowPoSt ( context . TODO ( ) , mid , sealedSectors , challenge [ : ] )
2020-04-13 22:13:34 +00:00
if err != nil {
return err
}
windowpost2 := time . Now ( )
wpvi1 := abi . WindowPoStVerifyInfo {
Randomness : challenge [ : ] ,
Proofs : wproof1 ,
ChallengedSectors : sealedSectors ,
Prover : mid ,
}
ok , err = ffiwrapper . ProofVerifier . VerifyWindowPoSt ( context . TODO ( ) , wpvi1 )
if err != nil {
return err
}
if ! ok {
log . Error ( "post verification failed" )
}
verifyWindowpost1 := time . Now ( )
wpvi2 := abi . WindowPoStVerifyInfo {
Randomness : challenge [ : ] ,
Proofs : wproof2 ,
ChallengedSectors : sealedSectors ,
Prover : mid ,
}
ok , err = ffiwrapper . ProofVerifier . VerifyWindowPoSt ( context . TODO ( ) , wpvi2 )
if err != nil {
return err
}
if ! ok {
log . Error ( "post verification failed" )
}
verifyWindowpost2 := time . Now ( )
2019-12-10 14:05:41 +00:00
2020-04-02 21:18:57 +00:00
bo . PostGenerateCandidates = gencandidates . Sub ( beforePost )
2020-06-17 19:49:23 +00:00
bo . PostWinningProofCold = winningpost1 . Sub ( gencandidates )
bo . PostWinningProofHot = winnningpost2 . Sub ( winningpost1 )
bo . VerifyWinningPostCold = verifyWinningPost1 . Sub ( winnningpost2 )
bo . VerifyWinningPostHot = verifyWinningPost2 . Sub ( verifyWinningPost1 )
2020-04-13 22:13:34 +00:00
bo . PostWindowProofCold = windowpost1 . Sub ( verifyWinningPost2 )
bo . PostWindowProofHot = windowpost2 . Sub ( windowpost1 )
bo . VerifyWindowPostCold = verifyWindowpost1 . Sub ( windowpost2 )
bo . VerifyWindowPostHot = verifyWindowpost2 . Sub ( verifyWindowpost1 )
2020-04-02 21:18:57 +00:00
}
if c . Bool ( "json-out" ) {
data , err := json . MarshalIndent ( bo , "" , " " )
if err != nil {
return err
2019-12-10 13:01:17 +00:00
}
2019-11-27 02:47:08 +00:00
2020-04-02 21:18:57 +00:00
fmt . Println ( string ( data ) )
} else {
2020-06-08 21:25:49 +00:00
fmt . Printf ( "----\nresults (v27) (%d)\n" , sectorSize )
2020-04-02 21:18:57 +00:00
if robench == "" {
fmt . Printf ( "seal: addPiece: %s (%s)\n" , bo . SealingResults [ 0 ] . AddPiece , bps ( bo . SectorSize , bo . SealingResults [ 0 ] . AddPiece ) ) // TODO: average across multiple sealings
fmt . Printf ( "seal: preCommit phase 1: %s (%s)\n" , bo . SealingResults [ 0 ] . PreCommit1 , bps ( bo . SectorSize , bo . SealingResults [ 0 ] . PreCommit1 ) )
fmt . Printf ( "seal: preCommit phase 2: %s (%s)\n" , bo . SealingResults [ 0 ] . PreCommit2 , bps ( bo . SectorSize , bo . SealingResults [ 0 ] . PreCommit2 ) )
fmt . Printf ( "seal: commit phase 1: %s (%s)\n" , bo . SealingResults [ 0 ] . Commit1 , bps ( bo . SectorSize , bo . SealingResults [ 0 ] . Commit1 ) )
fmt . Printf ( "seal: commit phase 2: %s (%s)\n" , bo . SealingResults [ 0 ] . Commit2 , bps ( bo . SectorSize , bo . SealingResults [ 0 ] . Commit2 ) )
fmt . Printf ( "seal: verify: %s\n" , bo . SealingResults [ 0 ] . Verify )
if ! c . Bool ( "skip-unseal" ) {
fmt . Printf ( "unseal: %s (%s)\n" , bo . SealingResults [ 0 ] . Unseal , bps ( bo . SectorSize , bo . SealingResults [ 0 ] . Unseal ) )
}
2020-04-13 22:13:34 +00:00
fmt . Println ( "" )
2020-04-02 21:18:57 +00:00
}
if ! c . Bool ( "skip-commit2" ) {
fmt . Printf ( "generate candidates: %s (%s)\n" , bo . PostGenerateCandidates , bps ( bo . SectorSize * abi . SectorSize ( len ( bo . SealingResults ) ) , bo . PostGenerateCandidates ) )
2020-06-17 19:49:23 +00:00
fmt . Printf ( "compute winning post proof (cold): %s\n" , bo . PostWinningProofCold )
fmt . Printf ( "compute winning post proof (hot): %s\n" , bo . PostWinningProofHot )
fmt . Printf ( "verify winning post proof (cold): %s\n" , bo . VerifyWinningPostCold )
fmt . Printf ( "verify winning post proof (hot): %s\n\n" , bo . VerifyWinningPostHot )
2020-04-13 22:13:34 +00:00
fmt . Printf ( "compute window post proof (cold): %s\n" , bo . PostWindowProofCold )
fmt . Printf ( "compute window post proof (hot): %s\n" , bo . PostWindowProofHot )
fmt . Printf ( "verify window post proof (cold): %s\n" , bo . VerifyWindowPostCold )
fmt . Printf ( "verify window post proof (hot): %s\n" , bo . VerifyWindowPostHot )
2020-04-02 21:18:57 +00:00
}
}
return nil
} ,
2019-11-27 02:47:08 +00:00
}
2019-12-10 18:04:13 +00:00
2020-06-17 18:02:48 +00:00
type ParCfg struct {
PreCommit1 int
PreCommit2 int
Commit int
}
func runSeals ( sb * ffiwrapper . Sealer , sbfs * basicfs . Provider , numSectors int , par ParCfg , mid abi . ActorID , sectorSize abi . SectorSize , ticketPreimage [ ] byte , saveC2inp string , skipc2 , skipunseal bool ) ( [ ] SealingResult , [ ] abi . SectorInfo , error ) {
2020-06-17 00:39:51 +00:00
var pieces [ ] abi . PieceInfo
sealTimings := make ( [ ] SealingResult , numSectors )
sealedSectors := make ( [ ] abi . SectorInfo , numSectors )
2020-06-17 18:02:48 +00:00
preCommit2Sema := make ( chan struct { } , par . PreCommit2 )
commitSema := make ( chan struct { } , par . Commit )
if numSectors % par . PreCommit1 != 0 {
2020-06-17 00:39:51 +00:00
return nil , nil , fmt . Errorf ( "parallelism factor must cleanly divide numSectors" )
}
2020-04-22 19:47:20 +00:00
for i := abi . SectorNumber ( 1 ) ; i <= abi . SectorNumber ( numSectors ) ; i ++ {
sid := abi . SectorID {
Miner : mid ,
Number : i ,
}
start := time . Now ( )
2020-06-17 00:39:51 +00:00
log . Infof ( "[%d] Writing piece into sector..." , i )
2020-04-22 19:47:20 +00:00
r := rand . New ( rand . NewSource ( 100 + int64 ( i ) ) )
pi , err := sb . AddPiece ( context . TODO ( ) , sid , nil , abi . PaddedPieceSize ( sectorSize ) . Unpadded ( ) , r )
if err != nil {
return nil , nil , err
}
2020-06-17 00:39:51 +00:00
pieces = append ( pieces , pi )
2020-04-22 19:47:20 +00:00
2020-06-17 00:39:51 +00:00
sealTimings [ i - 1 ] . AddPiece = time . Since ( start )
}
2020-05-07 23:44:12 +00:00
2020-06-17 18:02:48 +00:00
sectorsPerWorker := numSectors / par . PreCommit1
2020-06-17 00:39:51 +00:00
2020-06-17 18:02:48 +00:00
errs := make ( chan error , par . PreCommit1 )
for wid := 0 ; wid < par . PreCommit1 ; wid ++ {
2020-06-17 00:39:51 +00:00
go func ( worker int ) {
sealerr := func ( ) error {
start := 1 + ( worker * sectorsPerWorker )
end := start + sectorsPerWorker
for i := abi . SectorNumber ( start ) ; i < abi . SectorNumber ( end ) ; i ++ {
ix := int ( i - 1 )
sid := abi . SectorID {
Miner : mid ,
Number : i ,
}
start := time . Now ( )
trand := blake2b . Sum256 ( ticketPreimage )
ticket := abi . SealRandomness ( trand [ : ] )
log . Infof ( "[%d] Running replication(1)..." , i )
pieces := [ ] abi . PieceInfo { pieces [ ix ] }
pc1o , err := sb . SealPreCommit1 ( context . TODO ( ) , sid , ticket , pieces )
if err != nil {
return xerrors . Errorf ( "commit: %w" , err )
}
precommit1 := time . Now ( )
2020-06-17 18:02:48 +00:00
preCommit2Sema <- struct { } { }
pc2Start := time . Now ( )
2020-06-17 00:39:51 +00:00
log . Infof ( "[%d] Running replication(2)..." , i )
cids , err := sb . SealPreCommit2 ( context . TODO ( ) , sid , pc1o )
if err != nil {
return xerrors . Errorf ( "commit: %w" , err )
}
precommit2 := time . Now ( )
2020-06-17 18:02:48 +00:00
<- preCommit2Sema
2020-06-17 00:39:51 +00:00
sealedSectors [ ix ] = abi . SectorInfo {
SealProof : sb . SealProofType ( ) ,
SectorNumber : i ,
SealedCID : cids . Sealed ,
}
seed := lapi . SealSeed {
Epoch : 101 ,
Value : [ ] byte { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 , 31 , 255 } ,
}
2020-06-17 18:02:48 +00:00
commitSema <- struct { } { }
commitStart := time . Now ( )
2020-06-17 00:39:51 +00:00
log . Infof ( "[%d] Generating PoRep for sector (1)" , i )
c1o , err := sb . SealCommit1 ( context . TODO ( ) , sid , ticket , seed . Value , pieces , cids )
if err != nil {
return err
}
sealcommit1 := time . Now ( )
log . Infof ( "[%d] Generating PoRep for sector (2)" , i )
if saveC2inp != "" {
c2in := Commit2In {
SectorNum : int64 ( i ) ,
Phase1Out : c1o ,
SectorSize : uint64 ( sectorSize ) ,
}
b , err := json . Marshal ( & c2in )
if err != nil {
return err
}
if err := ioutil . WriteFile ( saveC2inp , b , 0664 ) ; err != nil {
log . Warnf ( "%+v" , err )
}
}
var proof storage . Proof
if ! skipc2 {
proof , err = sb . SealCommit2 ( context . TODO ( ) , sid , c1o )
if err != nil {
return err
}
}
sealcommit2 := time . Now ( )
2020-06-17 18:02:48 +00:00
<- commitSema
2020-06-17 00:39:51 +00:00
if ! skipc2 {
svi := abi . SealVerifyInfo {
SectorID : abi . SectorID { Miner : mid , Number : i } ,
SealedCID : cids . Sealed ,
SealProof : sb . SealProofType ( ) ,
Proof : proof ,
DealIDs : nil ,
Randomness : ticket ,
InteractiveRandomness : seed . Value ,
UnsealedCID : cids . Unsealed ,
}
ok , err := ffiwrapper . ProofVerifier . VerifySeal ( svi )
if err != nil {
return err
}
if ! ok {
return xerrors . Errorf ( "porep proof for sector %d was invalid" , i )
}
}
verifySeal := time . Now ( )
if ! skipunseal {
log . Infof ( "[%d] Unsealing sector" , i )
{
2020-07-08 15:23:27 +00:00
p , done , err := sbfs . AcquireSector ( context . TODO ( ) , abi . SectorID { Miner : mid , Number : 1 } , stores . FTUnsealed , stores . FTNone , stores . PathSealing )
2020-06-17 00:39:51 +00:00
if err != nil {
return xerrors . Errorf ( "acquire unsealed sector for removing: %w" , err )
}
done ( )
if err := os . Remove ( p . Unsealed ) ; err != nil {
return xerrors . Errorf ( "removing unsealed sector: %w" , err )
}
}
err := sb . UnsealPiece ( context . TODO ( ) , abi . SectorID { Miner : mid , Number : 1 } , 0 , abi . PaddedPieceSize ( sectorSize ) . Unpadded ( ) , ticket , cids . Unsealed )
if err != nil {
return err
}
}
unseal := time . Now ( )
sealTimings [ ix ] . PreCommit1 = precommit1 . Sub ( start )
2020-06-17 18:02:48 +00:00
sealTimings [ ix ] . PreCommit2 = precommit2 . Sub ( pc2Start )
sealTimings [ ix ] . Commit1 = sealcommit1 . Sub ( commitStart )
2020-06-17 00:39:51 +00:00
sealTimings [ ix ] . Commit2 = sealcommit2 . Sub ( sealcommit1 )
sealTimings [ ix ] . Verify = verifySeal . Sub ( sealcommit2 )
sealTimings [ ix ] . Unseal = unseal . Sub ( verifySeal )
2020-05-07 23:44:12 +00:00
}
2020-06-17 00:39:51 +00:00
return nil
} ( )
if sealerr != nil {
errs <- sealerr
return
2020-05-07 23:44:12 +00:00
}
2020-06-17 00:39:51 +00:00
errs <- nil
} ( wid )
}
2020-05-07 23:44:12 +00:00
2020-06-17 18:02:48 +00:00
for i := 0 ; i < par . PreCommit1 ; i ++ {
2020-06-17 00:39:51 +00:00
err := <- errs
if err != nil {
return nil , nil , err
2020-04-22 19:47:20 +00:00
}
}
return sealTimings , sealedSectors , nil
}
2020-03-01 02:52:23 +00:00
var proveCmd = & cli . Command {
Name : "prove" ,
Usage : "Benchmark a proof computation" ,
Flags : [ ] cli . Flag {
& cli . BoolFlag {
Name : "no-gpu" ,
Usage : "disable gpu usage for the benchmark run" ,
} ,
2020-06-11 08:35:46 +00:00
& cli . StringFlag {
Name : "miner-addr" ,
Usage : "pass miner address (only necessary if using existing sectorbuilder)" ,
Value : "t01000" ,
} ,
2020-03-01 02:52:23 +00:00
} ,
Action : func ( c * cli . Context ) error {
if c . Bool ( "no-gpu" ) {
2020-05-27 20:53:20 +00:00
err := os . Setenv ( "BELLMAN_NO_GPU" , "1" )
if err != nil {
return xerrors . Errorf ( "setting no-gpu flag: %w" , err )
}
2020-03-01 02:52:23 +00:00
}
if ! c . Args ( ) . Present ( ) {
return xerrors . Errorf ( "Usage: lotus-bench prove [input.json]" )
}
inb , err := ioutil . ReadFile ( c . Args ( ) . First ( ) )
if err != nil {
return xerrors . Errorf ( "reading input file: %w" , err )
}
var c2in Commit2In
if err := json . Unmarshal ( inb , & c2in ) ; err != nil {
return xerrors . Errorf ( "unmarshalling input file: %w" , err )
}
2020-06-05 22:58:24 +00:00
if err := paramfetch . GetParams ( lcli . ReqContext ( c ) , build . ParametersJSON ( ) , c2in . SectorSize ) ; err != nil {
2020-03-01 02:52:23 +00:00
return xerrors . Errorf ( "getting params: %w" , err )
}
maddr , err := address . NewFromString ( c . String ( "miner-addr" ) )
if err != nil {
return err
}
2020-03-18 01:08:11 +00:00
mid , err := address . IDFromAddress ( maddr )
if err != nil {
return err
}
2020-03-01 02:52:23 +00:00
2020-04-10 22:20:48 +00:00
spt , err := ffiwrapper . SealProofTypeFromSectorSize ( abi . SectorSize ( c2in . SectorSize ) )
2020-03-01 02:52:23 +00:00
if err != nil {
return err
}
2020-03-26 02:50:56 +00:00
cfg := & ffiwrapper . Config {
2020-03-01 02:52:23 +00:00
SealProofType : spt ,
}
2020-03-26 02:50:56 +00:00
sb , err := ffiwrapper . New ( nil , cfg )
2020-03-01 02:52:23 +00:00
if err != nil {
return err
}
start := time . Now ( )
2020-03-18 01:08:11 +00:00
proof , err := sb . SealCommit2 ( context . TODO ( ) , abi . SectorID { Miner : abi . ActorID ( mid ) , Number : abi . SectorNumber ( c2in . SectorNum ) } , c2in . Phase1Out )
2020-03-01 02:52:23 +00:00
if err != nil {
return err
}
sealCommit2 := time . Now ( )
fmt . Printf ( "proof: %x\n" , proof )
2020-06-11 08:35:46 +00:00
fmt . Printf ( "----\nresults (v27) (%d)\n" , c2in . SectorSize )
2020-03-01 02:52:23 +00:00
dur := sealCommit2 . Sub ( start )
fmt . Printf ( "seal: commit phase 2: %s (%s)\n" , dur , bps ( abi . SectorSize ( c2in . SectorSize ) , dur ) )
return nil
} ,
}
2020-02-10 19:16:36 +00:00
func bps ( data abi . SectorSize , d time . Duration ) string {
bdata := new ( big . Int ) . SetUint64 ( uint64 ( data ) )
2019-12-10 19:53:39 +00:00
bdata = bdata . Mul ( bdata , big . NewInt ( time . Second . Nanoseconds ( ) ) )
bps := bdata . Div ( bdata , big . NewInt ( d . Nanoseconds ( ) ) )
2020-08-12 19:05:09 +00:00
return types . SizeStr ( types . BigInt { Int : bps } ) + "/s"
2019-12-10 18:04:13 +00:00
}