@@ -12,50 +12,65 @@ import (
1212 sha256simd "github.com/minio/sha256-simd"
1313)
1414
15- func GenerateUnsealedCID (proofType abi.RegisteredSealProof , pieces []abi.PieceInfo ) (cid.Cid , error ) {
15+ type stackFrame struct {
16+ size uint64
17+ commP []byte
18+ }
19+
20+ func GenerateUnsealedCID (proofType abi.RegisteredSealProof , pieceInfos []abi.PieceInfo ) (cid.Cid , error ) {
1621 spi , found := abi .SealProofInfos [proofType ]
1722 if ! found {
1823 return cid .Undef , fmt .Errorf ("unknown seal proof type %d" , proofType )
1924 }
20- if len (pieces ) == 0 {
25+ if len (pieceInfos ) == 0 {
2126 return cid .Undef , errors .New ("no pieces provided" )
2227 }
2328
24- maxSize := abi .PaddedPieceSize (spi .SectorSize )
29+ maxSize := uint64 (spi .SectorSize )
30+
31+ todo := make ([]stackFrame , len (pieceInfos ))
2532
2633 // sancheck everything
27- for i , p := range pieces {
34+ for i , p := range pieceInfos {
2835 if p .Size < 128 {
2936 return cid .Undef , fmt .Errorf ("invalid Size of PieceInfo %d: value %d is too small" , i , p .Size )
3037 }
31- if pieces [ i ] .Size > maxSize {
38+ if uint64 ( p .Size ) > maxSize {
3239 return cid .Undef , fmt .Errorf ("invalid Size of PieceInfo %d: value %d is larger than sector size of SealProofType %d" , i , p .Size , proofType )
3340 }
3441 if bits .OnesCount64 (uint64 (p .Size )) != 1 {
3542 return cid .Undef , fmt .Errorf ("invalid Size of PieceInfo %d: value %d is not a power of 2" , i , p .Size )
3643 }
37- if _ , err := commcid .CIDToPieceCommitmentV1 (p .PieceCID ); err != nil {
44+
45+ cp , err := commcid .CIDToPieceCommitmentV1 (p .PieceCID )
46+ if err != nil {
3847 return cid .Undef , fmt .Errorf ("invalid PieceCid for PieceInfo %d: %w" , i , err )
3948 }
49+ todo [i ] = stackFrame {size : uint64 (p .Size ), commP : cp }
4050 }
4151
4252 // reimplement https://github.com/filecoin-project/rust-fil-proofs/blob/380d6437c2/filecoin-proofs/src/pieces.rs#L85-L145
4353 stack := append (
44- make ([]abi.PieceInfo , 0 , 32 ),
45- pieces [0 ],
54+ make (
55+ []stackFrame ,
56+ 0 ,
57+ 32 ,
58+ ),
59+ todo [0 ],
4660 )
4761
48- for i := 1 ; i < len ( pieces ); i ++ {
62+ for _ , f := range todo [ 1 :] {
4963
50- for stack [len (stack )- 1 ].Size < pieces [i ].Size {
51- lastSize := stack [len (stack )- 1 ].Size
64+ // pre-pad if needed to balance the left limb
65+ for stack [len (stack )- 1 ].size < f .size {
66+ lastSize := stack [len (stack )- 1 ].size
5267
5368 stack = reduceStack (
5469 append (
5570 stack ,
56- abi. PieceInfo {
57- Size : lastSize ,
58- PieceCID : zerocomm . ZeroPieceCommitment (lastSize . Unpadded () ),
71+ stackFrame {
72+ size : lastSize ,
73+ commP : zeroCommForSize (lastSize ),
5974 },
6075 ),
6176 )
@@ -64,51 +79,47 @@ func GenerateUnsealedCID(proofType abi.RegisteredSealProof, pieces []abi.PieceIn
6479 stack = reduceStack (
6580 append (
6681 stack ,
67- pieces [ i ] ,
82+ f ,
6883 ),
6984 )
7085 }
7186
7287 for len (stack ) > 1 {
73- lastSize := stack [len (stack )- 1 ].Size
88+ lastSize := stack [len (stack )- 1 ].size
7489 stack = reduceStack (
7590 append (
7691 stack ,
77- abi. PieceInfo {
78- Size : lastSize ,
79- PieceCID : zerocomm . ZeroPieceCommitment (lastSize . Unpadded () ),
92+ stackFrame {
93+ size : lastSize ,
94+ commP : zeroCommForSize (lastSize ),
8095 },
8196 ),
8297 )
8398 }
8499
85- if stack [0 ].Size > maxSize {
86- return cid .Undef , fmt .Errorf ("provided pieces sum up to %d bytes, which is larger than sector size of SealProofType %d" , stack [0 ].Size , proofType )
100+ if stack [0 ].size > maxSize {
101+ return cid .Undef , fmt .Errorf ("provided pieces sum up to %d bytes, which is larger than sector size of SealProofType %d" , stack [0 ].size , proofType )
87102 }
88103
89- return stack [0 ].PieceCID , nil
104+ return commcid . PieceCommitmentV1ToCID ( stack [0 ].commP )
90105}
91106
92107var s256 = sha256simd .New ()
93108
94- func reduceStack (s []abi.PieceInfo ) []abi.PieceInfo {
95- for {
96- if len (s ) < 2 || s [len (s )- 2 ].Size != s [len (s )- 1 ].Size {
97- break
98- }
109+ func zeroCommForSize (s uint64 ) []byte { return zerocomm .PieceComms [bits .TrailingZeros64 (s )- 7 ][:] }
110+
111+ func reduceStack (s []stackFrame ) []stackFrame {
112+ for len (s ) > 1 && s [len (s )- 2 ].size == s [len (s )- 1 ].size {
99113
100- l , _ := commcid .CIDToPieceCommitmentV1 (s [len (s )- 2 ].PieceCID )
101- r , _ := commcid .CIDToPieceCommitmentV1 (s [len (s )- 1 ].PieceCID )
102114 s256 .Reset ()
103- s256 .Write (l )
104- s256 .Write (r )
115+ s256 .Write (s [ len ( s ) - 2 ]. commP )
116+ s256 .Write (s [ len ( s ) - 1 ]. commP )
105117 d := s256 .Sum (make ([]byte , 0 , 32 ))
106118 d [31 ] &= 0b00111111
107- newPiece , _ := commcid .PieceCommitmentV1ToCID (d )
108119
109- s [len (s )- 2 ] = abi. PieceInfo {
110- Size : 2 * s [len (s )- 2 ].Size ,
111- PieceCID : newPiece ,
120+ s [len (s )- 2 ] = stackFrame {
121+ size : 2 * s [len (s )- 2 ].size ,
122+ commP : d ,
112123 }
113124
114125 s = s [:len (s )- 1 ]
0 commit comments