diff --git a/pkg/api/rchash.go b/pkg/api/rchash.go index b38e63ef601..64b11e34472 100644 --- a/pkg/api/rchash.go +++ b/pkg/api/rchash.go @@ -6,13 +6,104 @@ package api import ( "encoding/hex" "net/http" + "time" "github.com/ethersphere/bee/pkg/jsonhttp" - "github.com/ethersphere/bee/pkg/storageincentives" + "github.com/ethersphere/bee/pkg/storageincentives/redistribution" + "github.com/ethersphere/bee/pkg/swarm" "github.com/gorilla/mux" ) -type RCHashResponse storageincentives.SampleWithProofs +type RCHashResponse struct { + Hash swarm.Address `json:"hash"` + Proofs ChunkInclusionProofs `json:"proofs"` + Duration time.Duration `json:"duration"` +} + +type ChunkInclusionProofs struct { + A ChunkInclusionProof `json:"proof1"` + B ChunkInclusionProof `json:"proof2"` + C ChunkInclusionProof `json:"proofLast"` +} + +// ChunkInclusionProof structure must exactly match +// corresponding structure (of the same name) in Redistribution.sol smart contract. +// github.com/ethersphere/storage-incentives/blob/ph_f2/src/Redistribution.sol +// github.com/ethersphere/storage-incentives/blob/master/src/Redistribution.sol (when merged to master) +type ChunkInclusionProof struct { + ProofSegments []string `json:"proofSegments"` + ProveSegment string `json:"proveSegment"` + ProofSegments2 []string `json:"proofSegments2"` + ProveSegment2 string `json:"proveSegment2"` + ChunkSpan uint64 `json:"chunkSpan"` + ProofSegments3 []string `json:"proofSegments3"` + PostageProof PostageProof `json:"postageProof"` + SocProof []SOCProof `json:"socProof"` +} + +// SOCProof structure must exactly match +// corresponding structure (of the same name) in Redistribution.sol smart contract. +type PostageProof struct { + Signature string `json:"signature"` + PostageId string `json:"postageId"` + Index string `json:"index"` + TimeStamp string `json:"timeStamp"` +} + +// SOCProof structure must exactly match +// corresponding structure (of the same name) in Redistribution.sol smart contract. +type SOCProof struct { + Signer string `json:"signer"` + Signature string `json:"signature"` + Identifier string `json:"identifier"` + ChunkAddr string `json:"chunkAddr"` +} + +func renderChunkInclusionProofs(proofs redistribution.ChunkInclusionProofs) ChunkInclusionProofs { + return ChunkInclusionProofs{ + A: renderChunkInclusionProof(proofs.A), + B: renderChunkInclusionProof(proofs.B), + C: renderChunkInclusionProof(proofs.C), + } +} + +func renderChunkInclusionProof(proof redistribution.ChunkInclusionProof) ChunkInclusionProof { + var socProof []SOCProof + if len(proof.SocProof) == 1 { + socProof = []SOCProof{ + SOCProof{ + Signer: toHexString(proof.SocProof[0].Signer)[0], + Signature: toHexString(proof.SocProof[0].Signature)[0], + Identifier: toHexString(proof.SocProof[0].Identifier)[0], + ChunkAddr: toHexString(proof.SocProof[0].ChunkAddr)[0], + }, + } + } + + return ChunkInclusionProof{ + ProveSegment: toHexString(proof.ProveSegment)[0], + ProofSegments: toHexString(proof.ProofSegments...), + ProveSegment2: toHexString(proof.ProveSegment2)[0], + ProofSegments2: toHexString(proof.ProofSegments2...), + ProofSegments3: toHexString(proof.ProofSegments3...), + ChunkSpan: proof.ChunkSpan, + PostageProof: PostageProof{ + Signature: toHexString(proof.PostageProof.Signature)[0], + PostageId: toHexString(proof.PostageProof.PostageId)[0], + Index: toHexString(proof.PostageProof.Index)[0], + TimeStamp: toHexString(proof.PostageProof.TimeStamp)[0], + }, + SocProof: socProof, + } +} + +func toHexString(proofSegments ...[]byte) []string { + output := make([]string, len(proofSegments)) + for i, s := range proofSegments { + output[i] = hex.EncodeToString(s) + } + return output +} // This API is kept for testing the sampler. As a result, no documentation or tests are added here. func (s *Service) rchash(w http.ResponseWriter, r *http.Request) { @@ -42,12 +133,18 @@ func (s *Service) rchash(w http.ResponseWriter, r *http.Request) { return } - resp, err := s.redistributionAgent.SampleWithProofs(r.Context(), anchor1, anchor2, paths.Depth) + swp, err := s.redistributionAgent.SampleWithProofs(r.Context(), anchor1, anchor2, paths.Depth) if err != nil { logger.Error(err, "failed making sample with proofs") jsonhttp.InternalServerError(w, "failed making sample with proofs") return } + resp := RCHashResponse{ + Hash: swp.Hash, + Duration: swp.Duration, + Proofs: renderChunkInclusionProofs(swp.Proofs), + } + jsonhttp.OK(w, RCHashResponse(resp)) } diff --git a/pkg/storageincentives/redistribution/inclusionproof.go b/pkg/storageincentives/redistribution/inclusionproof.go index 2c07a645483..27e0807c38b 100644 --- a/pkg/storageincentives/redistribution/inclusionproof.go +++ b/pkg/storageincentives/redistribution/inclusionproof.go @@ -8,7 +8,6 @@ package redistribution import ( "encoding/binary" - "encoding/hex" "github.com/ethersphere/bee/pkg/bmt" "github.com/ethersphere/bee/pkg/soc" @@ -27,57 +26,53 @@ type ChunkInclusionProofs struct { // github.com/ethersphere/storage-incentives/blob/ph_f2/src/Redistribution.sol // github.com/ethersphere/storage-incentives/blob/master/src/Redistribution.sol (when merged to master) type ChunkInclusionProof struct { - ProofSegments []string `json:"proofSegments"` - ProveSegment string `json:"proveSegment"` - ProofSegments2 []string `json:"proofSegments2"` - ProveSegment2 string `json:"proveSegment2"` - ChunkSpan uint64 `json:"chunkSpan"` - ProofSegments3 []string `json:"proofSegments3"` - PostageProof PostageProof `json:"postageProof"` - SocProof []SOCProof `json:"socProof"` + ProveSegment []byte + ProofSegments [][]byte + ProofSegments2 [][]byte + ProveSegment2 []byte + ChunkSpan uint64 + ProofSegments3 [][]byte + PostageProof PostageProof + SocProof []SOCProof } // SOCProof structure must exactly match // corresponding structure (of the same name) in Redistribution.sol smart contract. type PostageProof struct { - Signature string `json:"signature"` - PostageId string `json:"postageId"` - Index string `json:"index"` - TimeStamp string `json:"timeStamp"` + Signature []byte + PostageId []byte + Index []byte + TimeStamp []byte } // SOCProof structure must exactly match // corresponding structure (of the same name) in Redistribution.sol smart contract. type SOCProof struct { - Signer string `json:"signer"` - Signature string `json:"signature"` - Identifier string `json:"identifier"` - ChunkAddr string `json:"chunkAddr"` + Signer []byte + Signature []byte + Identifier []byte + ChunkAddr []byte } // Transforms arguments to ChunkInclusionProof object func NewChunkInclusionProof(proofp1, proofp2 bmt.Proof, proofp3 bmt.Proof, sampleItem storer.SampleItem) (ChunkInclusionProof, error) { - proofp1Hex := newHexProofs(proofp1) - proofp2Hex := newHexProofs(proofp2) - proofp3Hex := newHexProofs(proofp3) - socProof, err := makeSOCProof(sampleItem) if err != nil { return ChunkInclusionProof{}, err } return ChunkInclusionProof{ - ProofSegments: proofp1Hex.ProofSegments, - ProveSegment: proofp1Hex.ProveSegment, - ProofSegments2: proofp2Hex.ProofSegments, - ProveSegment2: proofp2Hex.ProveSegment, + ProofSegments: proofp1.ProofSegments, + ProveSegment: proofp1.ProveSegment, + ProofSegments2: proofp2.ProofSegments, + ProveSegment2: proofp2.ProveSegment, ChunkSpan: binary.LittleEndian.Uint64(proofp2.Span[:swarm.SpanSize]), // should be uint64 on the other size; copied from pkg/api/bytes.go - ProofSegments3: proofp3Hex.ProofSegments, + ProofSegments3: proofp3.ProofSegments, PostageProof: PostageProof{ - Signature: hex.EncodeToString(sampleItem.Stamp.Sig()), - PostageId: hex.EncodeToString(sampleItem.Stamp.BatchID()), - Index: hex.EncodeToString(sampleItem.Stamp.Index()), - TimeStamp: hex.EncodeToString(sampleItem.Stamp.Timestamp()), + Signature: sampleItem.Stamp.Sig(), + PostageId: sampleItem.Stamp.BatchID(), + Index: sampleItem.Stamp.Index(), + TimeStamp: sampleItem.Stamp.Timestamp(), }, SocProof: socProof, }, nil @@ -96,27 +91,9 @@ func makeSOCProof(sampleItem storer.SampleItem) ([]SOCProof, error) { } return []SOCProof{{ - Signer: hex.EncodeToString(socCh.OwnerAddress()), - Signature: hex.EncodeToString(socCh.Signature()), - Identifier: hex.EncodeToString(socCh.ID()), - ChunkAddr: hex.EncodeToString(socCh.WrappedChunk().Address().Bytes()), + Signer: socCh.OwnerAddress(), + Signature: socCh.Signature(), + Identifier: socCh.ID(), + ChunkAddr: socCh.WrappedChunk().Address().Bytes(), }}, nil } - -type hexProof struct { - ProofSegments []string - ProveSegment string -} - -// Transforms proof object to its hexadecimal representation -func newHexProofs(proof bmt.Proof) hexProof { - proofSegments := make([]string, len(proof.ProofSegments)) - for i := 0; i < len(proof.ProofSegments); i++ { - proofSegments[i] = hex.EncodeToString(proof.ProofSegments[i]) - } - - return hexProof{ - ProveSegment: hex.EncodeToString(proof.ProveSegment), - ProofSegments: proofSegments, - } -} diff --git a/pkg/storageincentives/redistribution/redistribution_test.go b/pkg/storageincentives/redistribution/redistribution_test.go index b0174ec74a9..63863ec49d9 100644 --- a/pkg/storageincentives/redistribution/redistribution_test.go +++ b/pkg/storageincentives/redistribution/redistribution_test.go @@ -7,13 +7,10 @@ package redistribution_test import ( "bytes" "context" - "encoding/hex" "errors" "fmt" "math/big" - "strconv" "testing" - "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" @@ -35,18 +32,19 @@ func randChunkInclusionProof(t *testing.T) redistribution.ChunkInclusionProof { t.Helper() return redistribution.ChunkInclusionProof{ - ProofSegments: []string{hex.EncodeToString(testutil.RandBytes(t, 32))}, - ProveSegment: hex.EncodeToString(testutil.RandBytes(t, 32)), - ProofSegments2: []string{hex.EncodeToString(testutil.RandBytes(t, 32))}, - ProveSegment2: hex.EncodeToString(testutil.RandBytes(t, 32)), - ProofSegments3: []string{hex.EncodeToString(testutil.RandBytes(t, 32))}, + ProofSegments: [][]byte{testutil.RandBytes(t, 32)}, + ProveSegment: testutil.RandBytes(t, 32), + ProofSegments2: [][]byte{testutil.RandBytes(t, 32)}, + ProveSegment2: testutil.RandBytes(t, 32), + ProofSegments3: [][]byte{testutil.RandBytes(t, 32)}, PostageProof: redistribution.PostageProof{ - Signature: string(testutil.RandBytes(t, 32)), - PostageId: hex.EncodeToString(testutil.RandBytes(t, 32)), - Index: hex.EncodeToString(testutil.RandBytes(t, 32)), - TimeStamp: strconv.Itoa(time.Now().Nanosecond()), + Signature: testutil.RandBytes(t, 32), + PostageId: testutil.RandBytes(t, 32), + Index: testutil.RandBytes(t, 32), + TimeStamp: testutil.RandBytes(t, 8), }, ChunkSpan: 1, + SocProof: []redistribution.SOCProof{}, } }