Skip to content

Commit 2880150

Browse files
Replace getValidatorSet (#1324)
1 parent cd63620 commit 2880150

File tree

6 files changed

+107
-165
lines changed

6 files changed

+107
-165
lines changed

plugin/evm/vm_warp_test.go

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -343,22 +343,29 @@ func testWarpVMTransaction(t *testing.T, scheme string, unsignedMessage *avalanc
343343
GetSubnetIDF: func(context.Context, ids.ID) (ids.ID, error) {
344344
return ids.Empty, nil
345345
},
346-
GetValidatorSetF: func(_ context.Context, height uint64, _ ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) {
346+
GetWarpValidatorSetF: func(_ context.Context, height uint64, _ ids.ID) (validators.WarpSet, error) {
347347
if height < minimumValidPChainHeight {
348-
return nil, getValidatorSetTestErr
348+
return validators.WarpSet{}, getValidatorSetTestErr
349349
}
350-
return map[ids.NodeID]*validators.GetValidatorOutput{
351-
nodeID1: {
352-
NodeID: nodeID1,
353-
PublicKey: blsPublicKey1,
354-
Weight: 50,
350+
vdrs := validators.WarpSet{
351+
Validators: []*validators.Warp{
352+
{
353+
PublicKey: blsPublicKey1,
354+
PublicKeyBytes: bls.PublicKeyToUncompressedBytes(blsPublicKey1),
355+
Weight: 50,
356+
NodeIDs: []ids.NodeID{nodeID1},
357+
},
358+
{
359+
PublicKey: blsPublicKey2,
360+
PublicKeyBytes: bls.PublicKeyToUncompressedBytes(blsPublicKey2),
361+
Weight: 50,
362+
NodeIDs: []ids.NodeID{nodeID2},
363+
},
355364
},
356-
nodeID2: {
357-
NodeID: nodeID2,
358-
PublicKey: blsPublicKey2,
359-
Weight: 50,
360-
},
361-
}, nil
365+
TotalWeight: 100,
366+
}
367+
avagoUtils.Sort(vdrs.Validators)
368+
return vdrs, nil
362369
},
363370
}
364371

@@ -645,24 +652,28 @@ func testReceiveWarpMessage(
645652
}
646653
return vm.ctx.SubnetID, nil
647654
},
648-
GetValidatorSetF: func(_ context.Context, height uint64, subnetID ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) {
655+
GetWarpValidatorSetF: func(_ context.Context, height uint64, subnetID ids.ID) (validators.WarpSet, error) {
649656
if height < minimumValidPChainHeight {
650-
return nil, getValidatorSetTestErr
657+
return validators.WarpSet{}, getValidatorSetTestErr
651658
}
652659
signers := subnetSigners
653660
if subnetID == constants.PrimaryNetworkID {
654661
signers = primarySigners
655662
}
656663

657-
vdrOutput := make(map[ids.NodeID]*validators.GetValidatorOutput)
664+
vdrs := validators.WarpSet{}
658665
for _, s := range signers {
659-
vdrOutput[s.nodeID] = &validators.GetValidatorOutput{
660-
NodeID: s.nodeID,
661-
PublicKey: s.secret.PublicKey(),
662-
Weight: s.weight,
663-
}
666+
pk := s.secret.PublicKey()
667+
vdrs.Validators = append(vdrs.Validators, &validators.Warp{
668+
PublicKey: pk,
669+
PublicKeyBytes: bls.PublicKeyToUncompressedBytes(pk),
670+
Weight: s.weight,
671+
NodeIDs: []ids.NodeID{s.nodeID},
672+
})
673+
vdrs.TotalWeight += s.weight
664674
}
665-
return vdrOutput, nil
675+
avagoUtils.Sort(vdrs.Validators)
676+
return vdrs, nil
666677
},
667678
}
668679

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/coreth/precompile/precompileconfig"
19-
20-
warpValidators "github.com/ava-labs/coreth/warp/validators"
2120
)
2221

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

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

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

215-
validatorSet, err := warp.GetCanonicalValidatorSetFromChainID(
216-
context.Background(),
217-
state,
235+
validatorSet, err := predicateContext.SnowCtx.ValidatorState.GetWarpValidatorSet(
236+
context.TODO(),
218237
predicateContext.ProposerVMBlockCtx.PChainHeight,
219-
warpMsg.UnsignedMessage.SourceChainID,
238+
sourceSubnetID,
220239
)
221240
if err != nil {
222-
log.Debug("failed to retrieve canonical validator set", "msgID", warpMsg.ID(), "err", err)
241+
log.Debug("failed to retrieve canonical validator set",
242+
"msgID", warpMsg.ID(),
243+
"subnetID", sourceSubnetID,
244+
"err", err,
245+
)
223246
return fmt.Errorf("%w: %w", errCannotRetrieveValidatorSet, err)
224247
}
225248

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

precompile/contracts/warp/predicate_test.go

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +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)
192-
191+
validatorSet := make(map[ids.NodeID]*validators.GetValidatorOutput)
193192
for _, validatorRange := range validatorRanges {
194193
for i := validatorRange.start; i < validatorRange.end; i++ {
195194
validatorOutput := &validators.GetValidatorOutput{
@@ -199,20 +198,19 @@ func createSnowCtx(tb testing.TB, validatorRanges []validatorRange) *snow.Contex
199198
if validatorRange.publicKey {
200199
validatorOutput.PublicKey = testVdrs[i].vdr.PublicKey
201200
}
202-
getValidatorsOutput[testVdrs[i].nodeID] = validatorOutput
201+
validatorSet[testVdrs[i].nodeID] = validatorOutput
203202
}
204203
}
205204

206205
snowCtx := snowtest.Context(tb, snowtest.CChainID)
207-
state := &validatorstest.State{
206+
snowCtx.ValidatorState = &validatorstest.State{
208207
GetSubnetIDF: func(context.Context, ids.ID) (ids.ID, error) {
209208
return sourceSubnetID, nil
210209
},
211-
GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) {
212-
return getValidatorsOutput, nil
210+
GetWarpValidatorSetF: func(context.Context, uint64, ids.ID) (validators.WarpSet, error) {
211+
return validators.FlattenValidatorSet(validatorSet)
213212
},
214213
}
215-
snowCtx.ValidatorState = state
216214
return snowCtx
217215
}
218216

@@ -247,20 +245,29 @@ func testWarpMessageFromPrimaryNetwork(t *testing.T, requirePrimaryNetworkSigner
247245
unsignedMsg, err := avalancheWarp.NewUnsignedMessage(constants.UnitTestID, cChainID, addressedCall.Bytes())
248246
require.NoError(err)
249247

250-
getValidatorsOutput := make(map[ids.NodeID]*validators.GetValidatorOutput)
251-
blsSignatures := make([]*bls.Signature, 0, numKeys)
248+
var (
249+
warpValidators = validators.WarpSet{
250+
Validators: make([]*validators.Warp, 0, numKeys),
251+
TotalWeight: 20 * uint64(numKeys),
252+
}
253+
blsSignatures = make([]*bls.Signature, 0, numKeys)
254+
)
252255
for i := 0; i < numKeys; i++ {
253-
sig, err := testVdrs[i].sk.Sign(unsignedMsg.Bytes())
256+
vdr := testVdrs[i]
257+
sig, err := vdr.sk.Sign(unsignedMsg.Bytes())
254258
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
262259
blsSignatures = append(blsSignatures, sig)
260+
261+
pk := vdr.sk.PublicKey()
262+
warpValidators.Validators = append(warpValidators.Validators, &validators.Warp{
263+
PublicKey: pk,
264+
PublicKeyBytes: bls.PublicKeyToUncompressedBytes(pk),
265+
Weight: 20,
266+
NodeIDs: []ids.NodeID{vdr.nodeID},
267+
})
263268
}
269+
agoUtils.Sort(warpValidators.Validators)
270+
264271
aggregateSignature, err := bls.AggregateSignatures(blsSignatures)
265272
require.NoError(err)
266273
bitSet := set.NewBits()
@@ -284,13 +291,13 @@ func testWarpMessageFromPrimaryNetwork(t *testing.T, requirePrimaryNetworkSigner
284291
require.Equal(chainID, cChainID)
285292
return constants.PrimaryNetworkID, nil // Return Primary Network SubnetID
286293
},
287-
GetValidatorSetF: func(_ context.Context, _ uint64, subnetID ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) {
294+
GetWarpValidatorSetF: func(_ context.Context, _ uint64, subnetID ids.ID) (validators.WarpSet, error) {
288295
expectedSubnetID := snowCtx.SubnetID
289296
if requirePrimaryNetworkSigners {
290297
expectedSubnetID = constants.PrimaryNetworkID
291298
}
292299
require.Equal(expectedSubnetID, subnetID)
293-
return getValidatorsOutput, nil
300+
return warpValidators, nil
294301
},
295302
}
296303

@@ -717,25 +724,26 @@ func makeWarpPredicateTests(tb testing.TB) map[string]precompiletest.PredicateTe
717724
testName := fmt.Sprintf("%d validators w/ %d signers/repeated PublicKeys", totalNodes, numSigners)
718725

719726
pred := createPredicate(numSigners)
720-
getValidatorsOutput := make(map[ids.NodeID]*validators.GetValidatorOutput, totalNodes)
727+
validatorSet := make(map[ids.NodeID]*validators.GetValidatorOutput, totalNodes)
721728
for i := 0; i < totalNodes; i++ {
722-
getValidatorsOutput[testVdrs[i].nodeID] = &validators.GetValidatorOutput{
729+
validatorSet[testVdrs[i].nodeID] = &validators.GetValidatorOutput{
723730
NodeID: testVdrs[i].nodeID,
724731
Weight: 20,
725732
PublicKey: testVdrs[i%numSigners].vdr.PublicKey,
726733
}
727734
}
735+
warpValidators, err := validators.FlattenValidatorSet(validatorSet)
736+
require.NoError(tb, err)
728737

729738
snowCtx := snowtest.Context(tb, snowtest.CChainID)
730-
state := &validatorstest.State{
739+
snowCtx.ValidatorState = &validatorstest.State{
731740
GetSubnetIDF: func(context.Context, ids.ID) (ids.ID, error) {
732741
return sourceSubnetID, nil
733742
},
734-
GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) {
735-
return getValidatorsOutput, nil
743+
GetWarpValidatorSetF: func(context.Context, uint64, ids.ID) (validators.WarpSet, error) {
744+
return warpValidators, nil
736745
},
737746
}
738-
snowCtx.ValidatorState = state
739747

740748
predicateTests[testName] = createValidPredicateTest(snowCtx, uint64(numSigners), pred)
741749
}

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)