-
-
Notifications
You must be signed in to change notification settings - Fork 300
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: improve state serialization (#6563)
* feat: implement ValidatorNodeStructType * chore: update serializeState.test.ts perf test * fix: use ViewDU.serializeToBytes() api for PersistentCPCache * fix: merge issue * chore: make constants * fix: address PR comments * fix: merge unstable * chore: refactor metric name
- Loading branch information
Showing
7 changed files
with
141 additions
and
34 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
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,76 @@ | ||
import {ByteViews, ContainerNodeStructType, ValueOfFields} from "@chainsafe/ssz"; | ||
import * as primitiveSsz from "../primitive/sszTypes.js"; | ||
|
||
const {Boolean, Bytes32, UintNum64, BLSPubkey, EpochInf} = primitiveSsz; | ||
|
||
// this is to work with uint32, see https://github.com/ChainSafe/ssz/blob/ssz-v0.15.1/packages/ssz/src/type/uint.ts | ||
const NUMBER_2_POW_32 = 2 ** 32; | ||
|
||
/* | ||
* Below constants are respective to their ssz type in `ValidatorType`. | ||
*/ | ||
const UINT32_SIZE = 4; | ||
const PUBKEY_SIZE = 48; | ||
const WITHDRAWAL_CREDENTIALS_SIZE = 32; | ||
const SLASHED_SIZE = 1; | ||
|
||
export const ValidatorType = { | ||
pubkey: BLSPubkey, | ||
withdrawalCredentials: Bytes32, | ||
effectiveBalance: UintNum64, | ||
slashed: Boolean, | ||
activationEligibilityEpoch: EpochInf, | ||
activationEpoch: EpochInf, | ||
exitEpoch: EpochInf, | ||
withdrawableEpoch: EpochInf, | ||
}; | ||
|
||
/** | ||
* Improve serialization performance for state.validators.serialize(); | ||
*/ | ||
export class ValidatorNodeStructType extends ContainerNodeStructType<typeof ValidatorType> { | ||
constructor() { | ||
super(ValidatorType, {typeName: "Validator", jsonCase: "eth2"}); | ||
} | ||
|
||
value_serializeToBytes( | ||
{uint8Array: output, dataView}: ByteViews, | ||
offset: number, | ||
validator: ValueOfFields<typeof ValidatorType> | ||
): number { | ||
output.set(validator.pubkey, offset); | ||
offset += PUBKEY_SIZE; | ||
output.set(validator.withdrawalCredentials, offset); | ||
offset += WITHDRAWAL_CREDENTIALS_SIZE; | ||
const {effectiveBalance, activationEligibilityEpoch, activationEpoch, exitEpoch, withdrawableEpoch} = validator; | ||
// effectiveBalance is UintNum64 | ||
dataView.setUint32(offset, effectiveBalance & 0xffffffff, true); | ||
offset += UINT32_SIZE; | ||
dataView.setUint32(offset, (effectiveBalance / NUMBER_2_POW_32) & 0xffffffff, true); | ||
offset += UINT32_SIZE; | ||
output[offset] = validator.slashed ? 1 : 0; | ||
offset += SLASHED_SIZE; | ||
offset = writeEpochInf(dataView, offset, activationEligibilityEpoch); | ||
offset = writeEpochInf(dataView, offset, activationEpoch); | ||
offset = writeEpochInf(dataView, offset, exitEpoch); | ||
offset = writeEpochInf(dataView, offset, withdrawableEpoch); | ||
|
||
return offset; | ||
} | ||
} | ||
|
||
function writeEpochInf(dataView: DataView, offset: number, value: number): number { | ||
if (value === Infinity) { | ||
dataView.setUint32(offset, 0xffffffff, true); | ||
offset += UINT32_SIZE; | ||
dataView.setUint32(offset, 0xffffffff, true); | ||
offset += UINT32_SIZE; | ||
} else { | ||
dataView.setUint32(offset, value & 0xffffffff, true); | ||
offset += UINT32_SIZE; | ||
dataView.setUint32(offset, (value / NUMBER_2_POW_32) & 0xffffffff, true); | ||
offset += UINT32_SIZE; | ||
} | ||
return offset; | ||
} | ||
export const ValidatorNodeStruct = new ValidatorNodeStructType(); |
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,31 @@ | ||
import {ContainerType} from "@chainsafe/ssz"; | ||
import {describe, it, expect} from "vitest"; | ||
import {ssz} from "../../../src/index.js"; | ||
import {ValidatorType} from "../../../src/phase0/validator.js"; | ||
|
||
const ValidatorContainer = new ContainerType(ValidatorType, {typeName: "Validator", jsonCase: "eth2"}); | ||
|
||
describe("Validator ssz types", function () { | ||
it("should serialize to the same value", () => { | ||
const seedValidator = { | ||
activationEligibilityEpoch: 10, | ||
activationEpoch: 11, | ||
exitEpoch: Infinity, | ||
slashed: false, | ||
withdrawableEpoch: 13, | ||
pubkey: Buffer.alloc(48, 100), | ||
withdrawalCredentials: Buffer.alloc(32, 100), | ||
}; | ||
|
||
const validators = [ | ||
{...seedValidator, effectiveBalance: 31000000000, slashed: false}, | ||
{...seedValidator, effectiveBalance: 32000000000, slashed: true}, | ||
]; | ||
|
||
for (const validator of validators) { | ||
const serialized = ValidatorContainer.serialize(validator); | ||
const serialized2 = ssz.phase0.Validator.serialize(validator); | ||
expect(serialized).toEqual(serialized2); | ||
} | ||
}); | ||
}); |