Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: bump storage-incentives abi to v0.6.0-rc3 #4348

Merged
merged 14 commits into from
Sep 27, 2023
Merged
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ require (
github.com/coreos/go-semver v0.3.0
github.com/ethereum/go-ethereum v1.12.2
github.com/ethersphere/go-price-oracle-abi v0.1.0
github.com/ethersphere/go-storage-incentives-abi v0.5.0
github.com/ethersphere/go-storage-incentives-abi v0.6.0-rc3
github.com/ethersphere/go-sw3-abi v0.4.0
github.com/ethersphere/langos v1.0.0
github.com/go-playground/validator/v10 v10.11.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,8 @@ github.com/ethereum/go-ethereum v1.12.2 h1:eGHJ4ij7oyVqUQn48LBz3B7pvQ8sV0wGJiIE6
github.com/ethereum/go-ethereum v1.12.2/go.mod h1:1cRAEV+rp/xX0zraSCBnu9Py3HQ+geRMj3HdR+k0wfI=
github.com/ethersphere/go-price-oracle-abi v0.1.0 h1:yg/hK8nETNvk+GEBASlbakMFv/CVp7HXiycrHw1pRV8=
github.com/ethersphere/go-price-oracle-abi v0.1.0/go.mod h1:sI/Qj4/zJ23/b1enzwMMv0/hLTpPNVNacEwCWjo6yBk=
github.com/ethersphere/go-storage-incentives-abi v0.5.0 h1:dd01OZmPraCjOIiSX5FsCfFFwUR2b9PuTO/LDcYxS+s=
github.com/ethersphere/go-storage-incentives-abi v0.5.0/go.mod h1:SXvJVtM4sEsaSKD0jc1ClpDLw8ErPoROZDme4Wrc/Nc=
github.com/ethersphere/go-storage-incentives-abi v0.6.0-rc3 h1:tXux2FnhuU6DbrY+Z4nVQMGp63JkJPq7pKb5Xi2Sjxo=
github.com/ethersphere/go-storage-incentives-abi v0.6.0-rc3/go.mod h1:SXvJVtM4sEsaSKD0jc1ClpDLw8ErPoROZDme4Wrc/Nc=
github.com/ethersphere/go-sw3-abi v0.4.0 h1:T3ANY+ktWrPAwe2U0tZi+DILpkHzto5ym/XwV/Bbz8g=
github.com/ethersphere/go-sw3-abi v0.4.0/go.mod h1:BmpsvJ8idQZdYEtWnvxA8POYQ8Rl/NhyCdF0zLMOOJU=
github.com/ethersphere/langos v1.0.0 h1:NBtNKzXTTRSue95uOlzPN4py7Aofs0xWPzyj4AI1Vcc=
Expand Down
2 changes: 1 addition & 1 deletion pkg/api/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -783,7 +783,7 @@ func (m *mockContract) Claim(context.Context, redistribution.ChunkInclusionProof
return common.Hash{}, nil
}

func (m *mockContract) Commit(context.Context, []byte, *big.Int) (common.Hash, error) {
func (m *mockContract) Commit(context.Context, []byte, uint32) (common.Hash, error) {
m.mtx.Lock()
defer m.mtx.Unlock()
m.callsList = append(m.callsList, commitCall)
Expand Down
106 changes: 102 additions & 4 deletions pkg/api/rchash.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,106 @@
package api

import (
"encoding/hex"
"net/http"
"strconv"
"time"

"github.com/ethereum/go-ethereum/common"
"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{{
Signer: hex.EncodeToString(proof.SocProof[0].Signer.Bytes()),
Signature: hex.EncodeToString(proof.SocProof[0].Signature[:]),
Identifier: hex.EncodeToString(proof.SocProof[0].Identifier.Bytes()),
ChunkAddr: hex.EncodeToString(proof.SocProof[0].ChunkAddr.Bytes()),
}}
}

return ChunkInclusionProof{
ProveSegment: hex.EncodeToString(proof.ProveSegment.Bytes()),
ProofSegments: renderCommonHash(proof.ProofSegments),
ProveSegment2: hex.EncodeToString(proof.ProveSegment2.Bytes()),
ProofSegments2: renderCommonHash(proof.ProofSegments2),
ProofSegments3: renderCommonHash(proof.ProofSegments3),
ChunkSpan: proof.ChunkSpan,
PostageProof: PostageProof{
Signature: hex.EncodeToString(proof.PostageProof.Signature[:]),
PostageId: hex.EncodeToString(proof.PostageProof.PostageId[:]),
Index: strconv.FormatUint(proof.PostageProof.Index, 16),
TimeStamp: strconv.FormatUint(proof.PostageProof.TimeStamp, 16),
},
SocProof: socProof,
}
}

func renderCommonHash(proofSegments []common.Hash) []string {
output := make([]string, len(proofSegments))
for i, s := range proofSegments {
output[i] = hex.EncodeToString(s.Bytes())
}
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) {
Expand All @@ -31,12 +123,18 @@ func (s *Service) rchash(w http.ResponseWriter, r *http.Request) {

anchor2 := []byte(paths.Anchor2)

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
}

jsonhttp.OK(w, RCHashResponse(resp))
resp := RCHashResponse{
Hash: swp.Hash,
Duration: swp.Duration,
Proofs: renderChunkInclusionProofs(swp.Proofs),
}

jsonhttp.OK(w, resp)
}
6 changes: 3 additions & 3 deletions pkg/config/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ var (
SwarmTokenSymbol: "gBZZ",

StakingAddress: common.HexToAddress(abi.TestnetStakingAddress),
PostageStampAddress: common.HexToAddress(abi.TestnetPostageStampStampAddress),
PostageStampAddress: common.HexToAddress(abi.TestnetPostageStampAddress),
RedistributionAddress: common.HexToAddress(abi.TestnetRedistributionAddress),
SwapPriceOracleAddress: common.HexToAddress("0x0c9de531dcb38b758fe8a2c163444a5e54ee0db2"),
CurrentFactoryAddress: common.HexToAddress("0x73c412512E1cA0be3b89b77aB3466dA6A1B9d273"),
Expand All @@ -51,7 +51,7 @@ var (
},

StakingABI: abi.TestnetStakingABI,
PostageStampABI: abi.TestnetPostageStampStampABI,
PostageStampABI: abi.TestnetPostageStampABI,
RedistributionABI: abi.TestnetRedistributionABI,
}

Expand Down Expand Up @@ -84,7 +84,7 @@ func GetByChainID(chainID int64) (ChainConfig, bool) {
NativeTokenSymbol: Testnet.NativeTokenSymbol,
SwarmTokenSymbol: Testnet.SwarmTokenSymbol,
StakingABI: abi.TestnetStakingABI,
PostageStampABI: abi.TestnetPostageStampStampABI,
PostageStampABI: abi.TestnetPostageStampABI,
RedistributionABI: abi.TestnetRedistributionABI,
}, false
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/storageincentives/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,7 @@ func (a *Agent) commit(ctx context.Context, sample SampleData, round uint64) err
return err
}

txHash, err := a.contract.Commit(ctx, obfuscatedHash, big.NewInt(int64(round)))
txHash, err := a.contract.Commit(ctx, obfuscatedHash, uint32(round))
if err != nil {
a.metrics.ErrCommit.Inc()
return err
Expand Down
2 changes: 1 addition & 1 deletion pkg/storageincentives/agent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ func (m *mockContract) Claim(context.Context, redistribution.ChunkInclusionProof
return common.Hash{}, nil
}

func (m *mockContract) Commit(context.Context, []byte, *big.Int) (common.Hash, error) {
func (m *mockContract) Commit(context.Context, []byte, uint32) (common.Hash, error) {
m.mtx.Lock()
defer m.mtx.Unlock()
m.callsList = append(m.callsList, commitCall)
Expand Down
1 change: 0 additions & 1 deletion pkg/storageincentives/proof.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ func makeInclusionProofs(
require2++
}

// TODO: refactor, make it global / anchor (cleanup?)
prefixHasherFactory := func() hash.Hash {
return swarm.NewPrefixHasher(anchor1)
}
Expand Down
13 changes: 9 additions & 4 deletions pkg/storageincentives/proof_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ package storageincentives_test

import (
"bytes"
_ "embed"
"encoding/json"
"fmt"
"math/big"
"os"
"testing"

"github.com/ethersphere/bee/pkg/cac"
Expand Down Expand Up @@ -38,6 +38,9 @@ func TestMakeInclusionProofs(t *testing.T) {
}
}

//go:embed testdata/inclusion-proofs.json
var testData []byte

// Test asserts that MakeInclusionProofs will generate the same
// output for given sample.
func TestMakeInclusionProofsRegression(t *testing.T) {
Expand Down Expand Up @@ -111,10 +114,12 @@ func TestMakeInclusionProofsRegression(t *testing.T) {
t.Fatal(err)
}

expectedProofs := redistribution.ChunkInclusionProofs{}
var expectedProofs redistribution.ChunkInclusionProofs

data, _ := os.ReadFile("testdata/inclusion-proofs.json")
_ = json.Unmarshal(data, &expectedProofs)
err = json.Unmarshal(testData, &expectedProofs)
if err != nil {
t.Fatal(err)
}

if diff := cmp.Diff(proofs, expectedProofs); diff != "" {
t.Fatalf("unexpected inclusion proofs (-want +have):\n%s", diff)
Expand Down
99 changes: 42 additions & 57 deletions pkg/storageincentives/redistribution/inclusionproof.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ package redistribution

import (
"encoding/binary"
"encoding/hex"

"github.com/ethereum/go-ethereum/common"
"github.com/ethersphere/bee/pkg/bmt"
"github.com/ethersphere/bee/pkg/soc"
"github.com/ethersphere/bee/pkg/storer"
Expand All @@ -25,96 +25,81 @@ 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"`
ProofSegments []common.Hash `json:"proofSegments"`
ProveSegment common.Hash `json:"proveSegment"`
ProofSegments2 []common.Hash `json:"proofSegments2"`
ProveSegment2 common.Hash `json:"proveSegment2"`
ChunkSpan uint64 `json:"chunkSpan"`
ProofSegments3 []common.Hash `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"`
Signature []byte `json:"signature"`
PostageId common.Hash `json:"postageId"`
Index uint64 `json:"index"`
TimeStamp uint64 `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"`
Signer common.Address `json:"signer"`
Signature []byte `json:"signature"`
Identifier common.Hash `json:"identifier"`
ChunkAddr common.Hash `json:"chunkAddr"`
}

// NewChunkInclusionProof transforms arguments to ChunkInclusionProof object
func NewChunkInclusionProof(proofp1, proofp2, proofp3 bmt.Proof, sampleItem storer.SampleItem) (ChunkInclusionProof, error) {
proofp1Hex := newHexProofs(proofp1)
proofp2Hex := newHexProofs(proofp2)
proofp3Hex := newHexProofs(proofp3)

// Transforms arguments to ChunkInclusionProof object
func NewChunkInclusionProof(proofp1, proofp2 bmt.Proof, proofp3 bmt.Proof, sampleItem storer.SampleItem) (ChunkInclusionProof, error) {
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: toCommonHash(proofp1.ProofSegments),
ProveSegment: common.BytesToHash(proofp1.ProveSegment),
ProofSegments2: toCommonHash(proofp2.ProofSegments),
ProveSegment2: common.BytesToHash(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: toCommonHash(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: common.BytesToHash(sampleItem.Stamp.BatchID()),
Index: binary.BigEndian.Uint64(sampleItem.Stamp.Index()),
TimeStamp: binary.BigEndian.Uint64(sampleItem.Stamp.Timestamp()),
},
SocProof: socProof,
}, nil
}

func toCommonHash(hashes [][]byte) []common.Hash {
output := make([]common.Hash, len(hashes))
for i, s := range hashes {
output[i] = common.BytesToHash(s)
}
return output
}

func makeSOCProof(sampleItem storer.SampleItem) ([]SOCProof, error) {
var emptySOCProof = make([]SOCProof, 0)
ch := swarm.NewChunk(sampleItem.ChunkAddress, sampleItem.ChunkData)
if !soc.Valid(ch) {
return emptySOCProof, nil
return []SOCProof{}, nil
}

socCh, err := soc.FromChunk(ch)
if err != nil {
return emptySOCProof, err
return []SOCProof{}, err
}

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: common.BytesToAddress(socCh.OwnerAddress()),
Signature: socCh.Signature(),
Identifier: common.BytesToHash(socCh.ID()),
ChunkAddr: common.BytesToHash(socCh.WrappedChunk().Address().Bytes()),
}}, nil
}

type hexProof struct {
ProofSegments []string
ProveSegment string
}

// newHexProofs 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,
}
}
Loading
Loading