github.com/ethersphere/bee/v2@v2.2.0/pkg/storageincentives/redistribution/inclusionproof.go (about)

     1  // Copyright 2023 The Swarm Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package redistribution
     6  
     7  import (
     8  	"encoding/binary"
     9  
    10  	"github.com/ethereum/go-ethereum/common"
    11  	"github.com/ethersphere/bee/v2/pkg/bmt"
    12  	"github.com/ethersphere/bee/v2/pkg/soc"
    13  	"github.com/ethersphere/bee/v2/pkg/storer"
    14  	"github.com/ethersphere/bee/v2/pkg/swarm"
    15  )
    16  
    17  type ChunkInclusionProofs struct {
    18  	A ChunkInclusionProof `json:"proof1"`
    19  	B ChunkInclusionProof `json:"proof2"`
    20  	C ChunkInclusionProof `json:"proofLast"`
    21  }
    22  
    23  // ChunkInclusionProof structure must exactly match
    24  // corresponding structure (of the same name) in Redistribution.sol smart contract.
    25  // github.com/ethersphere/storage-incentives/blob/ph_f2/src/Redistribution.sol
    26  // github.com/ethersphere/storage-incentives/blob/master/src/Redistribution.sol (when merged to master)
    27  type ChunkInclusionProof struct {
    28  	ProofSegments  []common.Hash `json:"proofSegments"`
    29  	ProveSegment   common.Hash   `json:"proveSegment"`
    30  	ProofSegments2 []common.Hash `json:"proofSegments2"`
    31  	ProveSegment2  common.Hash   `json:"proveSegment2"`
    32  	ChunkSpan      uint64        `json:"chunkSpan"`
    33  	ProofSegments3 []common.Hash `json:"proofSegments3"`
    34  	PostageProof   PostageProof  `json:"postageProof"`
    35  	SocProof       []SOCProof    `json:"socProof"`
    36  }
    37  
    38  // SOCProof structure must exactly match
    39  // corresponding structure (of the same name) in Redistribution.sol smart contract.
    40  type PostageProof struct {
    41  	Signature []byte      `json:"signature"`
    42  	PostageId common.Hash `json:"postageId"`
    43  	Index     uint64      `json:"index"`
    44  	TimeStamp uint64      `json:"timeStamp"`
    45  }
    46  
    47  // SOCProof structure must exactly match
    48  // corresponding structure (of the same name) in Redistribution.sol smart contract.
    49  type SOCProof struct {
    50  	Signer     common.Address `json:"signer"`
    51  	Signature  []byte         `json:"signature"`
    52  	Identifier common.Hash    `json:"identifier"`
    53  	ChunkAddr  common.Hash    `json:"chunkAddr"`
    54  }
    55  
    56  // NewChunkInclusionProof transforms arguments to ChunkInclusionProof object
    57  func NewChunkInclusionProof(proofp1, proofp2, proofp3 bmt.Proof, sampleItem storer.SampleItem) (ChunkInclusionProof, error) {
    58  	socProof, err := makeSOCProof(sampleItem)
    59  	if err != nil {
    60  		return ChunkInclusionProof{}, err
    61  	}
    62  
    63  	return ChunkInclusionProof{
    64  		ProofSegments:  toCommonHash(proofp1.ProofSegments),
    65  		ProveSegment:   common.BytesToHash(proofp1.ProveSegment),
    66  		ProofSegments2: toCommonHash(proofp2.ProofSegments),
    67  		ProveSegment2:  common.BytesToHash(proofp2.ProveSegment),
    68  		ChunkSpan:      binary.LittleEndian.Uint64(proofp2.Span[:swarm.SpanSize]), // should be uint64 on the other size; copied from pkg/api/bytes.go
    69  		ProofSegments3: toCommonHash(proofp3.ProofSegments),
    70  		PostageProof: PostageProof{
    71  			Signature: sampleItem.Stamp.Sig(),
    72  			PostageId: common.BytesToHash(sampleItem.Stamp.BatchID()),
    73  			Index:     binary.BigEndian.Uint64(sampleItem.Stamp.Index()),
    74  			TimeStamp: binary.BigEndian.Uint64(sampleItem.Stamp.Timestamp()),
    75  		},
    76  		SocProof: socProof,
    77  	}, nil
    78  }
    79  
    80  func toCommonHash(hashes [][]byte) []common.Hash {
    81  	output := make([]common.Hash, len(hashes))
    82  	for i, s := range hashes {
    83  		output[i] = common.BytesToHash(s)
    84  	}
    85  	return output
    86  }
    87  
    88  func makeSOCProof(sampleItem storer.SampleItem) ([]SOCProof, error) {
    89  	ch := swarm.NewChunk(sampleItem.ChunkAddress, sampleItem.ChunkData)
    90  	if !soc.Valid(ch) {
    91  		return []SOCProof{}, nil
    92  	}
    93  
    94  	socCh, err := soc.FromChunk(ch)
    95  	if err != nil {
    96  		return []SOCProof{}, err
    97  	}
    98  
    99  	return []SOCProof{{
   100  		Signer:     common.BytesToAddress(socCh.OwnerAddress()),
   101  		Signature:  socCh.Signature(),
   102  		Identifier: common.BytesToHash(socCh.ID()),
   103  		ChunkAddr:  common.BytesToHash(socCh.WrappedChunk().Address().Bytes()),
   104  	}}, nil
   105  }