Skip to content

Commit 88022a2

Browse files
authored
Merge pull request #642 from pastelnetwork/PSL-928_broadcastingStorageChallengeResult
[PSL-928] implement storage challenge broadcasting
2 parents 9b010b5 + 05af2e4 commit 88022a2

File tree

16 files changed

+811
-189
lines changed

16 files changed

+811
-189
lines changed

common/types/storage_challenge.go

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package types
22

33
import (
4-
"github.com/pastelnetwork/gonode/common/errors"
54
"time"
5+
6+
"github.com/pastelnetwork/gonode/common/errors"
67
)
78

89
// MessageType represents the type of message
@@ -17,6 +18,8 @@ const (
1718
EvaluationMessageType
1819
// AffirmationMessageType represents the affirmation message
1920
AffirmationMessageType
21+
//BroadcastMessageType represents the message that needs to be broadcast
22+
BroadcastMessageType
2023
)
2124

2225
// String returns the message string
@@ -51,15 +54,23 @@ func MessageTypeFromString(str string) (MessageType, error) {
5154
}
5255
}
5356

57+
// StorageChallengeSignatures represents the signature struct for broadcasting
58+
type StorageChallengeSignatures struct {
59+
Challenger map[string]string `json:"challenger,omitempty"`
60+
Recipient map[string]string `json:"recipient,omitempty"`
61+
Obs map[string]string `json:"obs,omitempty"`
62+
}
63+
5464
// Message represents the storage challenge message
5565
type Message struct {
56-
MessageType MessageType `json:"message_type"`
57-
ChallengeID string `json:"challenge_id"`
58-
Data MessageData `json:"data"`
59-
Sender string `json:"sender"`
60-
SenderSignature []byte `json:"sender_signature"`
61-
CreatedAt time.Time `json:"created_at"`
62-
UpdatedAt time.Time `json:"updated_at"`
66+
MessageType MessageType `json:"message_type"`
67+
ChallengeID string `json:"challenge_id"`
68+
Data MessageData `json:"data"`
69+
Sender string `json:"sender"`
70+
SenderSignature []byte `json:"sender_signature"`
71+
StorageChallengeSignatures StorageChallengeStatus
72+
CreatedAt time.Time `json:"created_at"`
73+
UpdatedAt time.Time `json:"updated_at"`
6374
}
6475

6576
// MessageData represents the storage challenge message data

proto/supernode/protobuf/storage_challenge.proto

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ service StorageChallenge {
1414
rpc ProcessStorageChallenge(ProcessStorageChallengeRequest) returns (ProcessStorageChallengeReply);
1515
rpc VerifyStorageChallenge(VerifyStorageChallengeRequest) returns (VerifyStorageChallengeReply);
1616
rpc VerifyEvaluationResult(VerifyEvaluationResultRequest) returns (VerifyEvaluationResultReply);
17-
17+
rpc BroadcastStorageChallengeResult(BroadcastStorageChallengeRequest) returns (BroadcastStorageChallengeResponse);
1818
}
1919

2020
message StorageChallengeData {
@@ -77,6 +77,17 @@ message VerifyEvaluationResultReply {
7777
StorageChallengeMessage data = 1;
7878
}
7979

80+
message BroadcastStorageChallengeRequest {
81+
StorageChallengeMessage data = 1;
82+
map<string, bytes> challenger = 2;
83+
map<string, bytes> recipient = 3;
84+
map<string, bytes> obs = 4;
85+
}
86+
87+
message BroadcastStorageChallengeResponse {
88+
StorageChallengeMessage data = 1;
89+
}
90+
8091

8192
message StorageChallengeMessage {
8293
enum messageType {

proto/supernode/storage_challenge.pb.go

Lines changed: 186 additions & 68 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

proto/supernode/storage_challenge_grpc.pb.go

Lines changed: 36 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

supernode/node/grpc/client/storage_challenge.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ package client
33
import (
44
"context"
55
"encoding/json"
6-
"github.com/pastelnetwork/gonode/common/types"
76
"io"
87

98
"github.com/pastelnetwork/gonode/common/errors"
109
"github.com/pastelnetwork/gonode/common/log"
10+
"github.com/pastelnetwork/gonode/common/types"
1111
pb "github.com/pastelnetwork/gonode/proto/supernode"
1212
"github.com/pastelnetwork/gonode/supernode/node"
1313
"google.golang.org/grpc/codes"
@@ -120,6 +120,19 @@ func (service *storageChallengeGRPCClient) VerifyEvaluationResult(ctx context.Co
120120
return msg, nil
121121
}
122122

123+
// BroadcastStorageChallengeResult broadcast the result to the entire network
124+
func (service *storageChallengeGRPCClient) BroadcastStorageChallengeResult(ctx context.Context, req *pb.BroadcastStorageChallengeRequest) error {
125+
ctx = contextWithLogPrefix(ctx, service.conn.id)
126+
ctx = contextWithMDSessID(ctx, service.sessID)
127+
128+
_, err := service.client.BroadcastStorageChallengeResult(ctx, req)
129+
if err != nil {
130+
return err
131+
}
132+
133+
return nil
134+
}
135+
123136
func newStorageChallengeGRPCClient(conn *clientConn) node.StorageChallengeInterface {
124137
return &storageChallengeGRPCClient{
125138
conn: conn,

supernode/node/grpc/server/services/supernode/storage_challenge.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ package supernode
33
import (
44
"context"
55
"encoding/json"
6-
"github.com/pastelnetwork/gonode/common/types"
76
"io"
87

98
"github.com/pastelnetwork/gonode/common/errors"
109
"github.com/pastelnetwork/gonode/common/log"
10+
"github.com/pastelnetwork/gonode/common/types"
1111
pb "github.com/pastelnetwork/gonode/proto/supernode"
1212
"github.com/pastelnetwork/gonode/supernode/node/grpc/server/services/common"
1313
"github.com/pastelnetwork/gonode/supernode/services/storagechallenge"
@@ -179,6 +179,27 @@ func (service *StorageChallengeGRPC) VerifyEvaluationResult(ctx context.Context,
179179
}}, nil
180180
}
181181

182+
// BroadcastStorageChallengeResult broadcast the message to the entire network
183+
func (service *StorageChallengeGRPC) BroadcastStorageChallengeResult(ctx context.Context, scRequest *pb.BroadcastStorageChallengeRequest) (*pb.BroadcastStorageChallengeResponse, error) {
184+
log.WithContext(ctx).WithField("req", scRequest).Debugf("broadcast storage challenge result request received from gRpc client")
185+
task := service.NewSCTask()
186+
187+
msg := types.Message{
188+
ChallengeID: scRequest.Data.ChallengeId,
189+
MessageType: types.MessageType(scRequest.Data.MessageType),
190+
Sender: scRequest.Data.SenderId,
191+
SenderSignature: scRequest.Data.SenderSignature,
192+
}
193+
194+
_, err := task.BroadcastStorageChallengeResult(ctx, msg)
195+
if err != nil {
196+
log.WithContext(ctx).WithError(err).Error("Error verifying evaluation result")
197+
return nil, errors.Errorf("error verifying evaluation report")
198+
}
199+
200+
return nil, err
201+
}
202+
182203
// NewStorageChallengeGRPC returns a new StorageChallenge instance.
183204
func NewStorageChallengeGRPC(service *storagechallenge.SCService) *StorageChallengeGRPC {
184205
return &StorageChallengeGRPC{

supernode/node/node_client_interface.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ package node
1212

1313
import (
1414
"context"
15-
"github.com/pastelnetwork/gonode/common/types"
1615

1716
"github.com/pastelnetwork/gonode/common/service/userdata"
17+
"github.com/pastelnetwork/gonode/common/types"
1818
pb "github.com/pastelnetwork/gonode/proto/supernode"
1919
)
2020

@@ -109,6 +109,9 @@ type StorageChallengeInterface interface {
109109

110110
//VerifyEvaluationResult verifies the evaluation report by challenger
111111
VerifyEvaluationResult(ctx context.Context, challengeMessage *pb.StorageChallengeMessage) (types.Message, error)
112+
113+
//BroadcastStorageChallengeResult broadcast the result to all SNs
114+
BroadcastStorageChallengeResult(ctx context.Context, req *pb.BroadcastStorageChallengeRequest) error
112115
}
113116

114117
// SelfHealingChallengeInterface represents an interaction stream with supernodes for self-healing challenge communications

supernode/node/test/storage_challenge/mock_client.go

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package test
22

33
import (
4-
pb "github.com/pastelnetwork/gonode/proto/supernode"
54
"testing"
65

6+
"github.com/pastelnetwork/gonode/common/types"
77
"github.com/pastelnetwork/gonode/supernode/node/mocks"
88
"github.com/stretchr/testify/mock"
99
)
@@ -36,8 +36,14 @@ const (
3636
//VerifyStorageChallengeMethod intercepts the VerifyStorageChallenge method
3737
VerifyStorageChallengeMethod = "VerifyStorageChallenge"
3838

39+
//VerifyEvaluationResultMethod intercepts the VerifyEvaluationResult Method
40+
VerifyEvaluationResultMethod = "VerifyEvaluationResult"
41+
3942
//StorageChallengeInterfaceMethod intercepts the StorageChallenge interface
4043
StorageChallengeInterfaceMethod = "StorageChallenge"
44+
45+
//BroadcastStorageChallengeResultMethod intercepts the BroadcastStorageChallengeResult Method
46+
BroadcastStorageChallengeResultMethod = "BroadcastStorageChallengeResult"
4147
)
4248

4349
// Client implementing node.Client mock for testing purpose
@@ -83,8 +89,22 @@ func (client *Client) ListenOnProcessStorageChallengeFunc(returnErr error) *Clie
8389
}
8490

8591
// ListenOnVerifyStorageChallengeFunc returns returnErr
86-
func (client *Client) ListenOnVerifyStorageChallengeFunc(data *pb.StorageChallengeData, returnErr error) *Client {
87-
client.StorageChallengeInterface.On(VerifyStorageChallengeMethod, mock.Anything, mock.Anything).Return(data, returnErr)
92+
func (client *Client) ListenOnVerifyStorageChallengeFunc(returnErr error) *Client {
93+
client.StorageChallengeInterface.On(VerifyStorageChallengeMethod, mock.Anything, mock.Anything).Return(returnErr)
94+
95+
return client
96+
}
97+
98+
// ListenOnVerifyEvaluationResultFunc returns affirmations & returnErr
99+
func (client *Client) ListenOnVerifyEvaluationResultFunc(data types.Message, returnErr error) *Client {
100+
client.StorageChallengeInterface.On(VerifyEvaluationResultMethod, mock.Anything, mock.Anything).Return(data, returnErr)
101+
102+
return client
103+
}
104+
105+
// ListenOnBroadcastStorageChallengeResultFunc returns error
106+
func (client *Client) ListenOnBroadcastStorageChallengeResultFunc(returnErr error) *Client {
107+
client.StorageChallengeInterface.On(BroadcastStorageChallengeResultMethod, mock.Anything, mock.Anything).Return(returnErr)
88108

89109
return client
90110
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package storagechallenge
2+
3+
import (
4+
"context"
5+
"github.com/pastelnetwork/gonode/common/log"
6+
7+
"github.com/pastelnetwork/gonode/common/types"
8+
)
9+
10+
// BroadcastStorageChallengeResult receives and process the storage challenge result
11+
func (task *SCTask) BroadcastStorageChallengeResult(ctx context.Context, incomingEvaluationResult types.Message) (types.Message, error) {
12+
log.WithContext(ctx).WithField("method", "BroadcastStorageChallengeResult").
13+
WithField("challengeID", incomingEvaluationResult.ChallengeID).
14+
Debug("Start processing broadcasting message") // Incoming challenge message validation
15+
return types.Message{}, nil
16+
}

supernode/services/storagechallenge/config.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ const (
1616

1717
// ChallengeFailuresThreshold is a threshold which when exceeds will send the challenge for self-healing
1818
defaultChallengeFailuresThreshold = 5
19+
20+
// SuccessfulEvaluationThreshold is the affirmation threshold required for broadcasting
21+
SuccessfulEvaluationThreshold = 2
1922
)
2023

2124
// Config storage challenge config
@@ -26,9 +29,10 @@ type Config struct {
2629
NumberOfVerifyingNodes int `mapstructure:"number_of_verifying_nodes" json:"number_of_verifying_nodes"`
2730

2831
// raptorq service
29-
RaptorQServiceAddress string `mapstructure:"-" json:"-"`
30-
RqFilesDir string
31-
ChallengeFailuresThreshold int
32+
RaptorQServiceAddress string `mapstructure:"-" json:"-"`
33+
RqFilesDir string
34+
ChallengeFailuresThreshold int
35+
SuccessfulEvaluationThreshold int
3236
}
3337

3438
// NewConfig returns a new Config instance.
@@ -44,5 +48,6 @@ func NewConfig() *Config {
4448
NumberOfChallengeReplicas: defaultNumberOfChallengeReplicas,
4549
NumberOfVerifyingNodes: defaultNumberOfVerifyingNodes,
4650
ChallengeFailuresThreshold: challengeFailuresThreshold,
51+
SuccessfulEvaluationThreshold: SuccessfulEvaluationThreshold,
4752
}
4853
}

0 commit comments

Comments
 (0)