diff --git a/storage/sealer/commitment/commd.go b/storage/sealer/commitment/commd.go new file mode 100644 index 000000000..b7dc9998a --- /dev/null +++ b/storage/sealer/commitment/commd.go @@ -0,0 +1,34 @@ +package commitment + +import ( + "io" + "os" + "path/filepath" +) + +const treeDFile = "sc-02-data-tree-d.dat" + +// TreeDCommD reads CommD from tree-d +func TreeDCommD(cache string) ([32]byte, error) { + // Open the tree-d file for reading + file, err := os.Open(filepath.Join(cache, treeDFile)) + if err != nil { + return [32]byte{}, err + } + defer file.Close() // nolint:errcheck + + // Seek to 32 bytes from the end of the file + _, err = file.Seek(-32, io.SeekEnd) + if err != nil { + return [32]byte{}, err + } + + // Read the last 32 bytes + var commD [32]byte + _, err = file.Read(commD[:]) + if err != nil { + return [32]byte{}, err + } + + return commD, nil +} diff --git a/storage/sealer/commitment/commr.go b/storage/sealer/commitment/commr.go new file mode 100644 index 000000000..d5f5b0844 --- /dev/null +++ b/storage/sealer/commitment/commr.go @@ -0,0 +1,64 @@ +package commitment + +import ( + "math/big" + "os" + "path/filepath" + + "github.com/triplewz/poseidon" + ff "github.com/triplewz/poseidon/bls12_381" + "golang.org/x/xerrors" +) + +const pauxFile = "p_aux" + +func CommR(commC, commRLast [32]byte) ([32]byte, error) { + // reverse commC and commRLast so that endianness is correct + for i, j := 0, len(commC)-1; i < j; i, j = i+1, j-1 { + commC[i], commC[j] = commC[j], commC[i] + commRLast[i], commRLast[j] = commRLast[j], commRLast[i] + } + + input_a := new(big.Int) + input_a.SetBytes(commC[:]) + input_b := new(big.Int) + input_b.SetBytes(commRLast[:]) + input := []*big.Int{input_a, input_b} + + cons, err := poseidon.GenPoseidonConstants(3) + if err != nil { + return [32]byte{}, err + } + + h1, err := poseidon.Hash(input, cons, poseidon.OptimizedStatic) + if err != nil { + return [32]byte{}, err + } + + h1element := new(ff.Element).SetBigInt(h1).Bytes() + + // reverse the bytes so that endianness is correct + for i, j := 0, len(h1element)-1; i < j; i, j = i+1, j-1 { + h1element[i], h1element[j] = h1element[j], h1element[i] + } + + return h1element, nil +} + +// PAuxCommR reads p_aux and computes CommR +func PAuxCommR(cache string) ([32]byte, error) { + commCcommRLast, err := os.ReadFile(filepath.Join(cache, pauxFile)) + if err != nil { + return [32]byte{}, err + } + + if len(commCcommRLast) != 64 { + return [32]byte{}, xerrors.Errorf("invalid commCcommRLast length %d", len(commCcommRLast)) + } + + var commC, commRLast [32]byte + copy(commC[:], commCcommRLast[:32]) + copy(commRLast[:], commCcommRLast[32:]) + + return CommR(commC, commRLast) +} diff --git a/storage/sealer/commr/commr_test.go b/storage/sealer/commitment/commr_test.go similarity index 91% rename from storage/sealer/commr/commr_test.go rename to storage/sealer/commitment/commr_test.go index 987e6a13b..107f483d2 100644 --- a/storage/sealer/commr/commr_test.go +++ b/storage/sealer/commitment/commr_test.go @@ -1,4 +1,4 @@ -package commr +package commitment import ( "testing" @@ -21,7 +21,8 @@ func TestCommR(t *testing.T) { 0x26, 0xf8, 0x82, 0x68, 0x60, 0xf7, 0xe7, 0x68, } - res := CommR(commC, commRLast) + res, err := CommR(commC, commRLast) + require.NoError(t, err) var expected = [32]byte{ 0xe6, 0x74, 0xd1, 0x9e, 0x6c, 0xe7, 0xfc, 0xf3, diff --git a/storage/sealer/commr/commr.go b/storage/sealer/commr/commr.go deleted file mode 100644 index 44a93e52e..000000000 --- a/storage/sealer/commr/commr.go +++ /dev/null @@ -1,33 +0,0 @@ -package commr - -import ( - "math/big" - - "github.com/triplewz/poseidon" - ff "github.com/triplewz/poseidon/bls12_381" -) - -func CommR(commC, commRLast [32]byte) [32]byte { - // reverse commC and commRLast so that endianness is correct - for i, j := 0, len(commC)-1; i < j; i, j = i+1, j-1 { - commC[i], commC[j] = commC[j], commC[i] - commRLast[i], commRLast[j] = commRLast[j], commRLast[i] - } - - input_a := new(big.Int) - input_a.SetBytes(commC[:]) - input_b := new(big.Int) - input_b.SetBytes(commRLast[:]) - input := []*big.Int{input_a, input_b} - - cons, _ := poseidon.GenPoseidonConstants(3) - h1, _ := poseidon.Hash(input, cons, poseidon.OptimizedStatic) - h1element := new(ff.Element).SetBigInt(h1).Bytes() - - // reverse the bytes so that endianness is correct - for i, j := 0, len(h1element)-1; i < j; i, j = i+1, j-1 { - h1element[i], h1element[j] = h1element[j], h1element[i] - } - - return h1element -} diff --git a/storage/sealer/ffiwrapper/sealer_test.go b/storage/sealer/ffiwrapper/sealer_test.go index 745cc7375..720dc10ff 100644 --- a/storage/sealer/ffiwrapper/sealer_test.go +++ b/storage/sealer/ffiwrapper/sealer_test.go @@ -30,6 +30,7 @@ import ( "github.com/filecoin-project/lotus/chain/actors/policy" "github.com/filecoin-project/lotus/storage/pipeline/lib/nullreader" + "github.com/filecoin-project/lotus/storage/sealer/commitment" "github.com/filecoin-project/lotus/storage/sealer/ffiwrapper/basicfs" "github.com/filecoin-project/lotus/storage/sealer/storiface" ) @@ -1211,6 +1212,61 @@ func (c *closeAssertReader) Close() error { var _ io.Closer = &closeAssertReader{} +func TestSealCommDRInGo(t *testing.T) { + if testing.Short() { + t.Skip("skipping test in short mode") + } + + defer requireFDsClosed(t, openFDs(t)) + + cdir, err := os.MkdirTemp("", "sbtest-c-") + require.NoError(t, err) + miner := abi.ActorID(123) + + sp := &basicfs.Provider{ + Root: cdir, + } + sb, err := New(sp) + require.NoError(t, err) + + t.Cleanup(func() { + if t.Failed() { + fmt.Printf("not removing %s\n", cdir) + return + } + if err := os.RemoveAll(cdir); err != nil { + t.Error(err) + } + }) + + si := storiface.SectorRef{ + ID: abi.SectorID{Miner: miner, Number: 1}, + ProofType: sealProofType, + } + + s := seal{ref: si} + + s.precommit(t, sb, si, func() {}) + + p, _, err := sp.AcquireSector(context.Background(), si, storiface.FTCache, storiface.FTNone, storiface.PathStorage) + require.NoError(t, err) + + commr, err := commitment.PAuxCommR(p.Cache) + require.NoError(t, err) + + commd, err := commitment.TreeDCommD(p.Cache) + require.NoError(t, err) + + sealCid, err := commcid.ReplicaCommitmentV1ToCID(commr[:]) + require.NoError(t, err) + + unsealedCid, err := commcid.DataCommitmentV1ToCID(commd[:]) + require.NoError(t, err) + + require.Equal(t, s.cids.Sealed, sealCid) + require.Equal(t, s.cids.Unsealed, unsealedCid) +} + func TestGenerateSDR(t *testing.T) { d := t.TempDir()