Skip to content

Commit

Permalink
feat(prospective-parachains): handle GetMinimumRelayParents signal (#…
Browse files Browse the repository at this point in the history
…4363)

Co-authored-by: EclesioMeloJunior <[email protected]>
  • Loading branch information
DanielDDHM and EclesioMeloJunior authored Jan 14, 2025
1 parent 074f958 commit 84c3df0
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 2 deletions.
27 changes: 26 additions & 1 deletion dot/parachain/prospective-parachains/prospective-parachains.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ func (pp *ProspectiveParachains) processMessage(msg any) {
case GetHypotheticalMembership:
panic("not implemented yet: see issue #4311")
case GetMinimumRelayParents:
panic("not implemented yet: see issue #4312")
// Directly use the msg since it's already of type GetMinimumRelayParents
pp.getMinimumRelayParents(msg.RelayChainBlockHash, msg.Sender)
case GetProspectiveValidationData:
panic("not implemented yet: see issue #4313")
default:
Expand All @@ -92,6 +93,30 @@ func (*ProspectiveParachains) ProcessBlockFinalizedSignal(parachaintypes.BlockFi
return nil
}

func (pp *ProspectiveParachains) getMinimumRelayParents(
relayChainBlockHash common.Hash,
sender chan []ParaIDBlockNumber,
) {
var result []ParaIDBlockNumber

// Check if the relayChainBlockHash exists in active_leaves
if exists := pp.View.activeLeaves[relayChainBlockHash]; exists {
// Retrieve data associated with the relayChainBlockHash
if leafData, found := pp.View.perRelayParent[relayChainBlockHash]; found {
// Iterate over fragment_chains and collect the data
for paraID, fragmentChain := range leafData.fragmentChains {
result = append(result, ParaIDBlockNumber{
ParaId: paraID,
BlockNumber: fragmentChain.scope.relayParent.Number,
})
}
}
}

// Send the result through the sender channel
sender <- result
}

func (pp *ProspectiveParachains) getBackableCandidates(
msg GetBackableCandidates,
) {
Expand Down
107 changes: 106 additions & 1 deletion dot/parachain/prospective-parachains/prospective_parachains_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func makeCandidate(
commitmentsHash := commitments.Hash()

candidate := dummyCandidateReceiptBadSig(relayParent, &commitmentsHash)
candidate.CommitmentsHash = commitmentsHash
candidate.CommitmentsHash = commitments.Hash()
candidate.Descriptor.ParaID = paraID

pvdh, err := pvd.Hash()
Expand All @@ -92,6 +92,111 @@ func makeCandidate(
return result
}

func padTo32Bytes(input []byte) common.Hash {
var hash common.Hash
copy(hash[:], input)
return hash
}

// TestGetMinimumRelayParents ensures that getMinimumRelayParents
// processes the relay parent hash and correctly sends the output via the channel
func TestGetMinimumRelayParents(t *testing.T) {
// Setup a mock View with active leaves and relay parent data

mockRelayParent := relayChainBlockInfo{
Hash: padTo32Bytes([]byte("active_hash")),
Number: 10,
}

ancestors := []relayChainBlockInfo{
{
Hash: padTo32Bytes([]byte("active_hash_7")),
Number: 9,
},
{
Hash: padTo32Bytes([]byte("active_hash_8")),
Number: 8,
},
{
Hash: padTo32Bytes([]byte("active_hash_9")),
Number: 7,
},
}

baseConstraints := &parachaintypes.Constraints{
MinRelayParentNumber: 5,
}

mockScope, err := newScopeWithAncestors(mockRelayParent, baseConstraints, nil, 10, ancestors)
assert.NoError(t, err)

mockScope2, err := newScopeWithAncestors(mockRelayParent, baseConstraints, nil, 10, nil)
assert.NoError(t, err)

mockView := &view{
activeLeaves: map[common.Hash]bool{
common.BytesToHash([]byte("active_hash")): true,
},
perRelayParent: map[common.Hash]*relayParentData{
common.BytesToHash([]byte("active_hash")): {
fragmentChains: map[parachaintypes.ParaID]*fragmentChain{
parachaintypes.ParaID(1): newFragmentChain(mockScope, newCandidateStorage()),
parachaintypes.ParaID(2): newFragmentChain(mockScope2, newCandidateStorage()),
},
},
},
}

// Initialize ProspectiveParachains with the mock view
pp := &ProspectiveParachains{
View: mockView,
}

// Create a channel to capture the output
sender := make(chan []ParaIDBlockNumber, 1)

// Execute the method under test
pp.getMinimumRelayParents(common.BytesToHash([]byte("active_hash")), sender)

expected := []ParaIDBlockNumber{
{
ParaId: 1,
BlockNumber: 10,
},
{
ParaId: 2,
BlockNumber: 10,
},
}
// Validate the results
result := <-sender
assert.Len(t, result, 2)
assert.Equal(t, expected, result)
}

// TestGetMinimumRelayParents_NoActiveLeaves ensures that getMinimumRelayParents
// correctly handles the case where there are no active leaves.
func TestGetMinimumRelayParents_NoActiveLeaves(t *testing.T) {
mockView := &view{
activeLeaves: map[common.Hash]bool{},
perRelayParent: map[common.Hash]*relayParentData{},
}

// Initialize ProspectiveParachains with the mock view
pp := &ProspectiveParachains{
View: mockView,
}

// Create a channel to capture the output
sender := make(chan []ParaIDBlockNumber, 1)

// Execute the method under test
pp.getMinimumRelayParents(common.BytesToHash([]byte("active_hash")), sender)
// Validate the results
result := <-sender
assert.Empty(t, result, "Expected result to be empty when no active leaves are present")
}

func TestGetBackableCandidates(t *testing.T) {
candidateRelayParent1 := common.Hash{0x01}
candidateRelayParent2 := common.Hash{0x02}
Expand Down

0 comments on commit 84c3df0

Please sign in to comment.