Validator Registration Flow

How adding a validator to an Avalanche L1 actually works: two L1 transactions, one P-Chain transaction, and two signature aggregations.

L1 OPERATIONS / VALIDATOR MANAGER

Add a validator.

L1 · SUBNET-EVMP-CHAIN · REGISTRYOperatoryouNew validator nodeNodeID + BLS keyValidatorManagercontract + Warp precompileL1 validator seteach syncs its own P-Chain viewSignature aggregatorcollects signaturesto 67% of weightP-Chainvalidator registryinitiateValidatorRegistration

STEP 01 / 06 · EVM TX

Initiate registration on the L1

The operator calls initiateValidatorRegistration on the ValidatorManager with the new node's NodeID, BLS public key, and weight. The contract emits an L1-sourced RegisterL1ValidatorMessage through the Warp precompile.

Run the whole flow in code

The six steps above are one call in the Avalanche TypeScript SDK: registerL1Validator from @avalanche-sdk/interchain orchestrates both L1 transactions, the two BLS signature rounds, and the P-Chain submission end to end. The package is early (0.1.x alpha), so pin your version.

npm install @avalanche-sdk/interchain
import { registerL1Validator } from "@avalanche-sdk/interchain/validator-manager";

const result = await registerL1Validator(walletClient, publicClient, {
  validatorManagerAddress,
  networkId,
  subnetId,
  validator,              // NodeID, BLS public key, weight
  aggregateSignatures,    // steps 02 + 05: the BLS signature rounds
  getBlsProofOfPossession,
  submitPChainRegisterTx, // step 03: RegisterL1ValidatorTx
  onProgress,
});

The six steps at a glance

The interactive explainer above is the narration; this table is the quick reference.

#StepWho actsWhat moves
01Initiate registration on the L1Operator, ValidatorManagerEVM tx: initiateValidatorRegistration emits the L1-sourced Warp message
02Validators sign the L1 messageValidator set, aggregatorBLS signatures to 67% of total weight
03Submit RegisterL1ValidatorTxAggregator, P-ChainP-Chain tx; the P-Chain assigns a validationID
04The P-Chain acknowledgesP-ChainNothing: the registration becomes a P-Chain fact
05Validators sign the P-Chain messageValidator set, aggregator, P-ChainBLS signatures over the P-Chain-sourced message
06Complete registration on the L1Aggregator, ValidatorManager, operatorThe signed message rides the completion tx's access list

When registration goes wrong

Every failure below is real: each one has occurred in production support cases.

requirePrimaryNetworkSigners

Some L1s set requirePrimaryNetworkSigners in their Warp configuration, which normally routes message verification to the primary network validator set. P-Chain-sourced messages are exempt in Subnet-EVM v0.8.0 and later, so validator registration completion is verified by the L1's own validator set either way.

Appendix: anatomy of the completion message

The P-Chain-sourced L1ValidatorRegistrationMessage that completes a registration is 95 bytes on the wire:

OffsetSizeFieldExample value
02Codec version0x0000
24Network ID0x00000001 (Mainnet)
632Source chain ID32 zero bytes (the P-Chain)
384Payload length0x00000035 (53)
4253AddressedCall payloadsee below

The 53-byte AddressedCall wraps the inner message: codec 0x0000, type ID 0x00000001, an empty source address (0x00000000), a payload length of 39, and finally the 39-byte L1ValidatorRegistration itself: codec 0x0000, type ID 0x00000002, the 32-byte validationID, and one registered flag byte (0x01).

Is this guide helpful?