-
Notifications
You must be signed in to change notification settings - Fork 129
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(parachain): Implement request and response message for /req_stat…
…ement/1 protocol (#3354) - Added `StatementFetchingRequest` and `StatementFetchingResponse` varying data types. - implemented 'network.Message` interface in `StatementFetchingRequest` and 'network.ResponseMessage` interface in `StatementFetchingResponse` as they will be passed into `func (rrp *RequestResponseProtocol) Do(to peer.ID, req Message, res ResponseMessage) error` function as `req` and `res`. - I didn't want to create a new YAML file here. so I decided to rename the YAML file name and variable(in which data of the YAML file getting unmarshalled) name so that I can use them in this PR.
- Loading branch information
1 parent
f2a2e30
commit 746ec00
Showing
6 changed files
with
243 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package parachain | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/ChainSafe/gossamer/lib/common" | ||
"github.com/ChainSafe/gossamer/pkg/scale" | ||
) | ||
|
||
// StatementFetchingRequest represents a request for fetching a large statement via request/response. | ||
type StatementFetchingRequest struct { | ||
// Data needed to locate and identify the needed statement. | ||
RelayParent common.Hash `scale:"1"` | ||
|
||
// Hash of candidate that was used create the `CommitedCandidateRecept`. | ||
CandidateHash CandidateHash `scale:"2"` | ||
} | ||
|
||
// Encode returns the SCALE encoding of the StatementFetchingRequest. | ||
func (s *StatementFetchingRequest) Encode() ([]byte, error) { | ||
return scale.Marshal(*s) | ||
} | ||
|
||
// StatementFetchingResponse represents the statement fetching response is | ||
// sent by nodes to the clients who issued a collation fetching request. | ||
// | ||
// Respond with found full statement. | ||
type StatementFetchingResponse scale.VaryingDataType | ||
|
||
// MissingDataInStatement represents the data missing to reconstruct the full signed statement. | ||
type MissingDataInStatement CommittedCandidateReceipt | ||
|
||
// Index returns the index of varying data type | ||
func (MissingDataInStatement) Index() uint { | ||
return 0 | ||
} | ||
|
||
// NewStatementFetchingResponse returns a new statement fetching response varying data type | ||
func NewStatementFetchingResponse() StatementFetchingResponse { | ||
vdt := scale.MustNewVaryingDataType(MissingDataInStatement{}) | ||
return StatementFetchingResponse(vdt) | ||
} | ||
|
||
// Set will set a value using the underlying varying data type | ||
func (s *StatementFetchingResponse) Set(val scale.VaryingDataTypeValue) (err error) { | ||
vdt := scale.VaryingDataType(*s) | ||
err = vdt.Set(val) | ||
if err != nil { | ||
return fmt.Errorf("setting value to varying data type: %w", err) | ||
} | ||
|
||
*s = StatementFetchingResponse(vdt) | ||
return nil | ||
} | ||
|
||
// Value returns the value from the underlying varying data type | ||
func (s *StatementFetchingResponse) Value() (scale.VaryingDataTypeValue, error) { | ||
vdt := scale.VaryingDataType(*s) | ||
return vdt.Value() | ||
} | ||
|
||
// Encode returns the SCALE encoding of the StatementFetchingResponse. | ||
func (s *StatementFetchingResponse) Encode() ([]byte, error) { | ||
return scale.Marshal(*s) | ||
} | ||
|
||
// Decode returns the SCALE decoding of the StatementFetchingResponse. | ||
func (s *StatementFetchingResponse) Decode(in []byte) (err error) { | ||
return scale.Unmarshal(in, s) | ||
} | ||
|
||
// String formats a StatementFetchingResponse as a string | ||
func (s *StatementFetchingResponse) String() string { | ||
if s == nil { | ||
return "StatementFetchingResponse=nil" | ||
} | ||
|
||
v, _ := s.Value() | ||
missingData := v.(MissingDataInStatement) | ||
return fmt.Sprintf("StatementFetchingResponse MissingDataInStatement=%+v", missingData) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
package parachain | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/ChainSafe/gossamer/lib/common" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestEncodeStatementFetchingRequest(t *testing.T) { | ||
t.Parallel() | ||
|
||
testCases := []struct { | ||
name string | ||
request StatementFetchingRequest | ||
expectedEncode []byte | ||
}{ | ||
{ | ||
// expected encoding is generated by running rust test code: | ||
// fn statement_request() { | ||
// let hash4 = Hash::repeat_byte(4); | ||
// let statement_fetching_request = StatementFetchingRequest{ | ||
// relay_parent: hash4, | ||
// candidate_hash: CandidateHash(hash4) | ||
// }; | ||
// println!( | ||
// "statement_fetching_request encode => {:?}\n\n", | ||
// statement_fetching_request.encode() | ||
// ); | ||
// } | ||
name: "all_4_in_hash", | ||
request: StatementFetchingRequest{ | ||
RelayParent: getDummyHash(4), | ||
CandidateHash: CandidateHash{Value: getDummyHash(4)}, | ||
}, | ||
expectedEncode: common.MustHexToBytes(testDataStatement["all4InCommonHash"]), | ||
}, | ||
{ | ||
name: "all_7_in_hash", | ||
request: StatementFetchingRequest{ | ||
RelayParent: getDummyHash(7), | ||
CandidateHash: CandidateHash{Value: getDummyHash(7)}, | ||
}, | ||
expectedEncode: common.MustHexToBytes(testDataStatement["all7InCommonHash"]), | ||
}, | ||
{ | ||
name: "random_hash", | ||
request: StatementFetchingRequest{ | ||
RelayParent: common.MustHexToHash("0x677811d2f3ded2489685468dbdb2e4fa280a249fba9356acceb2e823820e2c19"), | ||
CandidateHash: CandidateHash{ | ||
Value: common.MustHexToHash("0x677811d2f3ded2489685468dbdb2e4fa280a249fba9356acceb2e823820e2c19"), | ||
}, | ||
}, | ||
expectedEncode: common.MustHexToBytes(testDataStatement["hexOfStatementFetchingRequest"]), | ||
}, | ||
} | ||
|
||
for _, c := range testCases { | ||
c := c | ||
t.Run(c.name, func(t *testing.T) { | ||
t.Parallel() | ||
actualEncode, err := c.request.Encode() | ||
require.NoError(t, err) | ||
require.Equal(t, c.expectedEncode, actualEncode) | ||
}) | ||
} | ||
} | ||
|
||
func TestStatementFetchingResponse(t *testing.T) { | ||
t.Parallel() | ||
|
||
testHash := common.MustHexToHash("0x677811d2f3ded2489685468dbdb2e4fa280a249fba9356acceb2e823820e2c19") | ||
|
||
var collatorID CollatorID | ||
tempCollatID := common.MustHexToBytes("0x48215b9d322601e5b1a95164cea0dc4626f545f98343d07f1551eb9543c4b147") | ||
copy(collatorID[:], tempCollatID) | ||
|
||
var collatorSignature CollatorSignature | ||
tempSignature := common.MustHexToBytes(testDataStatement["collatorSignature"]) | ||
copy(collatorSignature[:], tempSignature) | ||
|
||
missingDataInStatement := MissingDataInStatement{ | ||
Descriptor: CandidateDescriptor{ | ||
ParaID: uint32(1), | ||
RelayParent: testHash, | ||
Collator: collatorID, | ||
PersistedValidationDataHash: testHash, | ||
PovHash: testHash, | ||
ErasureRoot: testHash, | ||
Signature: collatorSignature, | ||
ParaHead: testHash, | ||
ValidationCodeHash: ValidationCodeHash(testHash), | ||
}, | ||
Commitments: CandidateCommitments{ | ||
UpwardMessages: []UpwardMessage{{1, 2, 3}}, | ||
NewValidationCode: &ValidationCode{1, 2, 3}, | ||
HeadData: headData{1, 2, 3}, | ||
ProcessedDownwardMessages: uint32(5), | ||
HrmpWatermark: uint32(0), | ||
}, | ||
} | ||
|
||
encodedValue := common.MustHexToBytes(testDataStatement["hexOfStatementFetchingResponse"]) | ||
|
||
t.Run("encode_statement_fetching_response", func(t *testing.T) { | ||
t.Parallel() | ||
|
||
response := NewStatementFetchingResponse() | ||
err := response.Set(missingDataInStatement) | ||
require.NoError(t, err) | ||
|
||
actualEncode, err := response.Encode() | ||
require.NoError(t, err) | ||
|
||
require.Equal(t, encodedValue, actualEncode) | ||
}) | ||
|
||
t.Run("Decode_statement_fetching_response", func(t *testing.T) { | ||
t.Parallel() | ||
|
||
response := NewStatementFetchingResponse() | ||
err := response.Decode(encodedValue) | ||
require.NoError(t, err) | ||
|
||
actualData, err := response.Value() | ||
require.NoError(t, err) | ||
|
||
require.EqualValues(t, missingDataInStatement, actualData) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters