Skip to content

Commit 47a1ce4

Browse files
sync: coreth PR #1324: Replace getValidatorSet (#1803)
1 parent 1e749f6 commit 47a1ce4

File tree

8 files changed

+121
-165
lines changed

8 files changed

+121
-165
lines changed

plugin/evm/vm_warp_test.go

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -365,22 +365,29 @@ func testWarpVMTransaction(t *testing.T, scheme string, unsignedMessage *avalanc
365365
GetSubnetIDF: func(context.Context, ids.ID) (ids.ID, error) {
366366
return ids.Empty, nil
367367
},
368-
GetValidatorSetF: func(_ context.Context, height uint64, _ ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) {
368+
GetWarpValidatorSetF: func(_ context.Context, height uint64, _ ids.ID) (validators.WarpSet, error) {
369369
if height < minimumValidPChainHeight {
370-
return nil, getValidatorSetTestErr
370+
return validators.WarpSet{}, getValidatorSetTestErr
371371
}
372-
return map[ids.NodeID]*validators.GetValidatorOutput{
373-
nodeID1: {
374-
NodeID: nodeID1,
375-
PublicKey: blsPublicKey1,
376-
Weight: 50,
372+
vdrs := validators.WarpSet{
373+
Validators: []*validators.Warp{
374+
{
375+
PublicKey: blsPublicKey1,
376+
PublicKeyBytes: bls.PublicKeyToUncompressedBytes(blsPublicKey1),
377+
Weight: 50,
378+
NodeIDs: []ids.NodeID{nodeID1},
379+
},
380+
{
381+
PublicKey: blsPublicKey2,
382+
PublicKeyBytes: bls.PublicKeyToUncompressedBytes(blsPublicKey2),
383+
Weight: 50,
384+
NodeIDs: []ids.NodeID{nodeID2},
385+
},
377386
},
378-
nodeID2: {
379-
NodeID: nodeID2,
380-
PublicKey: blsPublicKey2,
381-
Weight: 50,
382-
},
383-
}, nil
387+
TotalWeight: 100,
388+
}
389+
avagoUtils.Sort(vdrs.Validators)
390+
return vdrs, nil
384391
},
385392
}
386393

@@ -666,24 +673,28 @@ func testReceiveWarpMessage(
666673
}
667674
return vm.ctx.SubnetID, nil
668675
},
669-
GetValidatorSetF: func(_ context.Context, height uint64, subnetID ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) {
676+
GetWarpValidatorSetF: func(_ context.Context, height uint64, subnetID ids.ID) (validators.WarpSet, error) {
670677
if height < minimumValidPChainHeight {
671-
return nil, getValidatorSetTestErr
678+
return validators.WarpSet{}, getValidatorSetTestErr
672679
}
673680
signers := subnetSigners
674681
if subnetID == constants.PrimaryNetworkID {
675682
signers = primarySigners
676683
}
677684

678-
vdrOutput := make(map[ids.NodeID]*validators.GetValidatorOutput)
685+
vdrs := validators.WarpSet{}
679686
for _, s := range signers {
680-
vdrOutput[s.nodeID] = &validators.GetValidatorOutput{
681-
NodeID: s.nodeID,
682-
PublicKey: s.secret.PublicKey(),
683-
Weight: s.weight,
684-
}
687+
pk := s.secret.PublicKey()
688+
vdrs.Validators = append(vdrs.Validators, &validators.Warp{
689+
PublicKey: pk,
690+
PublicKeyBytes: bls.PublicKeyToUncompressedBytes(pk),
691+
Weight: s.weight,
692+
NodeIDs: []ids.NodeID{s.nodeID},
693+
})
694+
vdrs.TotalWeight += s.weight
685695
}
686-
return vdrOutput, nil
696+
avagoUtils.Sort(vdrs.Validators)
697+
return vdrs, nil
687698
},
688699
}
689700

precompile/contracts/warp/config.go

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"errors"
99
"fmt"
1010

11+
"github.com/ava-labs/avalanchego/utils/constants"
1112
"github.com/ava-labs/avalanchego/vms/evm/predicate"
1213
"github.com/ava-labs/avalanchego/vms/platformvm/warp"
1314
"github.com/ava-labs/avalanchego/vms/platformvm/warp/payload"
@@ -16,8 +17,6 @@ import (
1617
"github.com/ava-labs/libevm/log"
1718

1819
"github.com/ava-labs/subnet-evm/precompile/precompileconfig"
19-
20-
warpValidators "github.com/ava-labs/subnet-evm/warp/validators"
2120
)
2221

2322
const (
@@ -203,24 +202,48 @@ func (c *Config) VerifyPredicate(predicateContext *precompileconfig.PredicateCon
203202
quorumNumerator = c.QuorumNumerator
204203
}
205204

206-
log.Debug("verifying warp message", "warpMsg", warpMsg, "quorumNum", quorumNumerator, "quorumDenom", WarpQuorumDenominator)
205+
log.Debug("verifying warp message",
206+
"warpMsg", warpMsg,
207+
"quorumNum", quorumNumerator,
208+
"quorumDenom", WarpQuorumDenominator,
209+
)
207210

208-
// Wrap validators.State on the chain snow context to special case the Primary Network
209-
state := warpValidators.NewState(
210-
predicateContext.SnowCtx.ValidatorState,
211-
predicateContext.SnowCtx.SubnetID,
211+
sourceSubnetID, err := predicateContext.SnowCtx.ValidatorState.GetSubnetID(
212+
context.TODO(),
212213
warpMsg.SourceChainID,
213-
c.RequirePrimaryNetworkSigners,
214214
)
215+
if err != nil {
216+
log.Debug("failed to retrieve subnetID for chain",
217+
"msgID", warpMsg.ID(),
218+
"chainID", warpMsg.SourceChainID,
219+
"err", err,
220+
)
221+
return fmt.Errorf("%w: %w", errCannotRetrieveValidatorSet, err)
222+
}
223+
224+
if sourceSubnetID == constants.PrimaryNetworkID {
225+
// For the X-chain and the C-chain, chains can be configured not to
226+
// require the primary network validators to have signed the warp
227+
// message and to use the, likely smaller, local subnet's validator set.
228+
//
229+
// The primary network validator set is never required when verifying
230+
// messages from the P-chain because the P-chain is always synced.
231+
if !c.RequirePrimaryNetworkSigners || warpMsg.SourceChainID == constants.PlatformChainID {
232+
sourceSubnetID = predicateContext.SnowCtx.SubnetID
233+
}
234+
}
215235

216-
validatorSet, err := warp.GetCanonicalValidatorSetFromChainID(
217-
context.Background(),
218-
state,
236+
validatorSet, err := predicateContext.SnowCtx.ValidatorState.GetWarpValidatorSet(
237+
context.TODO(),
219238
predicateContext.ProposerVMBlockCtx.PChainHeight,
220-
warpMsg.UnsignedMessage.SourceChainID,
239+
sourceSubnetID,
221240
)
222241
if err != nil {
223-
log.Debug("failed to retrieve canonical validator set", "msgID", warpMsg.ID(), "err", err)
242+
log.Debug("failed to retrieve canonical validator set",
243+
"msgID", warpMsg.ID(),
244+
"subnetID", sourceSubnetID,
245+
"err", err,
246+
)
224247
return fmt.Errorf("%w: %w", errCannotRetrieveValidatorSet, err)
225248
}
226249

@@ -232,7 +255,10 @@ func (c *Config) VerifyPredicate(predicateContext *precompileconfig.PredicateCon
232255
WarpQuorumDenominator,
233256
)
234257
if err != nil {
235-
log.Debug("failed to verify warp signature", "msgID", warpMsg.ID(), "err", err)
258+
log.Debug("failed to verify warp signature",
259+
"msgID", warpMsg.ID(),
260+
"err", err,
261+
)
236262
return fmt.Errorf("%w: %w", errFailedVerification, err)
237263
}
238264

precompile/contracts/warp/predicate_test.go

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ type validatorRange struct {
188188

189189
// createSnowCtx creates a snow.Context instance with a validator state specified by the given validatorRanges
190190
func createSnowCtx(tb testing.TB, validatorRanges []validatorRange) *snow.Context {
191-
getValidatorsOutput := make(map[ids.NodeID]*validators.GetValidatorOutput)
191+
validatorSet := make(map[ids.NodeID]*validators.GetValidatorOutput)
192192

193193
for _, validatorRange := range validatorRanges {
194194
for i := validatorRange.start; i < validatorRange.end; i++ {
@@ -199,20 +199,19 @@ func createSnowCtx(tb testing.TB, validatorRanges []validatorRange) *snow.Contex
199199
if validatorRange.publicKey {
200200
validatorOutput.PublicKey = testVdrs[i].vdr.PublicKey
201201
}
202-
getValidatorsOutput[testVdrs[i].nodeID] = validatorOutput
202+
validatorSet[testVdrs[i].nodeID] = validatorOutput
203203
}
204204
}
205205

206206
snowCtx := utilstest.NewTestSnowContext(tb)
207-
state := &validatorstest.State{
207+
snowCtx.ValidatorState = &validatorstest.State{
208208
GetSubnetIDF: func(context.Context, ids.ID) (ids.ID, error) {
209209
return sourceSubnetID, nil
210210
},
211-
GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) {
212-
return getValidatorsOutput, nil
211+
GetWarpValidatorSetF: func(context.Context, uint64, ids.ID) (validators.WarpSet, error) {
212+
return validators.FlattenValidatorSet(validatorSet)
213213
},
214214
}
215-
snowCtx.ValidatorState = state
216215
return snowCtx
217216
}
218217

@@ -247,20 +246,29 @@ func testWarpMessageFromPrimaryNetwork(t *testing.T, requirePrimaryNetworkSigner
247246
unsignedMsg, err := avalancheWarp.NewUnsignedMessage(constants.UnitTestID, cChainID, addressedCall.Bytes())
248247
require.NoError(err)
249248

250-
getValidatorsOutput := make(map[ids.NodeID]*validators.GetValidatorOutput)
251-
blsSignatures := make([]*bls.Signature, 0, numKeys)
249+
var (
250+
warpValidators = validators.WarpSet{
251+
Validators: make([]*validators.Warp, 0, numKeys),
252+
TotalWeight: 20 * uint64(numKeys),
253+
}
254+
blsSignatures = make([]*bls.Signature, 0, numKeys)
255+
)
252256
for i := 0; i < numKeys; i++ {
253-
sig, err := testVdrs[i].sk.Sign(unsignedMsg.Bytes())
257+
vdr := testVdrs[i]
258+
sig, err := vdr.sk.Sign(unsignedMsg.Bytes())
254259
require.NoError(err)
255-
256-
validatorOutput := &validators.GetValidatorOutput{
257-
NodeID: testVdrs[i].nodeID,
258-
Weight: 20,
259-
PublicKey: testVdrs[i].vdr.PublicKey,
260-
}
261-
getValidatorsOutput[testVdrs[i].nodeID] = validatorOutput
262260
blsSignatures = append(blsSignatures, sig)
261+
262+
pk := vdr.sk.PublicKey()
263+
warpValidators.Validators = append(warpValidators.Validators, &validators.Warp{
264+
PublicKey: pk,
265+
PublicKeyBytes: bls.PublicKeyToUncompressedBytes(pk),
266+
Weight: 20,
267+
NodeIDs: []ids.NodeID{vdr.nodeID},
268+
})
263269
}
270+
agoUtils.Sort(warpValidators.Validators)
271+
264272
aggregateSignature, err := bls.AggregateSignatures(blsSignatures)
265273
require.NoError(err)
266274
bitSet := set.NewBits()
@@ -285,13 +293,13 @@ func testWarpMessageFromPrimaryNetwork(t *testing.T, requirePrimaryNetworkSigner
285293
require.Equal(chainID, cChainID)
286294
return constants.PrimaryNetworkID, nil // Return Primary Network SubnetID
287295
},
288-
GetValidatorSetF: func(_ context.Context, _ uint64, subnetID ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) {
296+
GetWarpValidatorSetF: func(_ context.Context, _ uint64, subnetID ids.ID) (validators.WarpSet, error) {
289297
expectedSubnetID := snowCtx.SubnetID
290298
if requirePrimaryNetworkSigners {
291299
expectedSubnetID = constants.PrimaryNetworkID
292300
}
293301
require.Equal(expectedSubnetID, subnetID)
294-
return getValidatorsOutput, nil
302+
return warpValidators, nil
295303
},
296304
}
297305

@@ -718,26 +726,27 @@ func makeWarpPredicateTests(tb testing.TB) map[string]precompiletest.PredicateTe
718726
testName := fmt.Sprintf("%d validators w/ %d signers/repeated PublicKeys", totalNodes, numSigners)
719727

720728
pred := createPredicate(numSigners)
721-
getValidatorsOutput := make(map[ids.NodeID]*validators.GetValidatorOutput, totalNodes)
729+
validatorSet := make(map[ids.NodeID]*validators.GetValidatorOutput, totalNodes)
722730
for i := 0; i < totalNodes; i++ {
723-
getValidatorsOutput[testVdrs[i].nodeID] = &validators.GetValidatorOutput{
731+
validatorSet[testVdrs[i].nodeID] = &validators.GetValidatorOutput{
724732
NodeID: testVdrs[i].nodeID,
725733
Weight: 20,
726734
PublicKey: testVdrs[i%numSigners].vdr.PublicKey,
727735
}
728736
}
737+
warpValidators, err := validators.FlattenValidatorSet(validatorSet)
738+
require.NoError(tb, err)
729739

730740
snowCtx := utilstest.NewTestSnowContext(tb)
731741

732-
state := &validatorstest.State{
742+
snowCtx.ValidatorState = &validatorstest.State{
733743
GetSubnetIDF: func(context.Context, ids.ID) (ids.ID, error) {
734744
return sourceSubnetID, nil
735745
},
736-
GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) {
737-
return getValidatorsOutput, nil
746+
GetWarpValidatorSetF: func(context.Context, uint64, ids.ID) (validators.WarpSet, error) {
747+
return warpValidators, nil
738748
},
739749
}
740-
snowCtx.ValidatorState = state
741750

742751
predicateTests[testName] = createValidPredicateTest(snowCtx, uint64(numSigners), pred)
743752
}

utils/utilstest/context.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ func NewTestValidatorState() *validatorstest.State {
4141
GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) {
4242
return map[ids.NodeID]*validators.GetValidatorOutput{}, nil
4343
},
44+
GetWarpValidatorSetsF: func(context.Context, uint64) (map[ids.ID]validators.WarpSet, error) {
45+
return nil, nil
46+
},
47+
GetWarpValidatorSetF: func(context.Context, uint64, ids.ID) (validators.WarpSet, error) {
48+
return validators.WarpSet{}, nil
49+
},
4450
GetCurrentValidatorSetF: func(context.Context, ids.ID) (map[ids.ID]*validators.GetCurrentValidatorOutput, uint64, error) {
4551
return map[ids.ID]*validators.GetCurrentValidatorOutput{}, 0, nil
4652
},

utils/utilstest/context_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ func TestNewTestSnowContext(t *testing.T) {
2525
require.NoError(t, err)
2626
require.NotNil(t, validators)
2727

28+
// Test that we can call GetWarpValidatorSetF without panicking
29+
_, err = validatorState.GetWarpValidatorSet(context.TODO(), 0, ids.Empty)
30+
require.NoError(t, err)
31+
32+
// Test that we can call GetWarpValidatorSetsF without panicking
33+
_, err = validatorState.GetWarpValidatorSets(context.TODO(), 0)
34+
require.NoError(t, err)
35+
2836
// Test that we can call GetCurrentValidatorSetF without panicking
2937
currentValidators, height, err := validatorState.GetCurrentValidatorSet(context.TODO(), ids.Empty)
3038
require.NoError(t, err)

warp/service.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ func (a *API) aggregateSignatures(ctx context.Context, unsignedMessage *warp.Uns
105105
return nil, err
106106
}
107107

108-
validatorSet, err := warp.GetCanonicalValidatorSetFromSubnetID(ctx, validatorState, pChainHeight, subnetID)
108+
validatorSet, err := validatorState.GetWarpValidatorSet(ctx, pChainHeight, subnetID)
109109
if err != nil {
110110
return nil, fmt.Errorf("failed to get validator set: %w", err)
111111
}

warp/validators/state.go

Lines changed: 0 additions & 55 deletions
This file was deleted.

0 commit comments

Comments
 (0)