-
Notifications
You must be signed in to change notification settings - Fork 310
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: introduce validator client #7854
Changes from 41 commits
78dbe1b
34b32af
59b82a6
f3fe10b
3e95501
2c0f307
0f515e5
b2f78ed
8831381
b7a5131
8b3c55e
6fa1fc1
437635a
5d2808b
0c50ee9
4c0a943
39f5d90
c8f1dba
45ac399
a1ff397
33fb87f
759982b
d2f0854
0cc6920
1a0d7e8
07c4203
064db45
95dfabf
842d8ce
27b33c5
e9a32d2
c284de0
27ad8bb
f5b45b6
f3adc08
2c1aeb7
0e25b4e
c4614fc
8ee6efc
8986e68
eefca64
dd80451
bde2469
5a47571
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -105,6 +105,7 @@ | |
"fuzzers", | ||
"gitmodules", | ||
"gitrepo", | ||
"Gossipable", | ||
"gossipsub", | ||
"grumpkin", | ||
"gtest", | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -130,6 +130,18 @@ contract Leonidas is Ownable, ILeonidas { | |
return epochs[_epoch].committee; | ||
} | ||
|
||
/** | ||
* @notice Get the validator set for the current epoch | ||
* | ||
* @dev Makes a call to setupEpoch under the hood, this should ONLY be called as a view function, and not from within | ||
* this contract. | ||
* @return The validator set for the current epoch | ||
*/ | ||
function getCurrentEpochCommittee() external override(ILeonidas) returns (address[] memory) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For this, I think we could be a bit smarter just to avoid the issue. In the We could potentially just alter the `getEpochCommittee(uint256 _epoch) function getCommitteeAt(uint256 _ts) public view override(ILeonidas) returns (address) {
uint256 epochNumber = getEpochAt(_ts);
uint256 slot = getSlotAt(_ts);
if (epochNumber == 0) {
return new address[1]();
}
Epoch storage epoch = epochs[epochNumber];
if (epoch.sampleSeed != 0) {
uint256 committeeSize = epoch.committee.length;
if (committeeSize == 0) {
return new address[1]();
}
return epoch.committee;
}
// Allow anyone if there is no validator set
if (validatorSet.length() == 0) {
return new address[1]();
}
// Emulate a sampling of the validators
uint256 sampleSeed = _getSampleSeed(epochNumber);
return _sampleValidators(epochNumber, sampleSeed);
}
|
||
setupEpoch(); | ||
return epochs[getCurrentEpoch()].committee; | ||
} | ||
|
||
/** | ||
* @notice Get the validator set | ||
* | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -54,6 +54,9 @@ | |
{ | ||
"path": "../types" | ||
}, | ||
{ | ||
"path": "../validator-client" | ||
}, | ||
{ | ||
"path": "../world-state" | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,28 @@ | ||
// Serde test for the block attestation type | ||
import { makeHeader } from '@aztec/circuits.js/testing'; | ||
|
||
import { BlockAttestation } from './block_attestation.js'; | ||
|
||
const makeBlockAttestation = (): BlockAttestation => { | ||
const blockHeader = makeHeader(1); | ||
const signature = Buffer.alloc(64, 1); | ||
|
||
return new BlockAttestation(blockHeader, signature); | ||
}; | ||
import { makeBlockAttestation, randomSigner } from './mocks.js'; | ||
|
||
describe('Block Attestation serialization / deserialization', () => { | ||
it('Should serialize / deserialize', () => { | ||
const attestation = makeBlockAttestation(); | ||
it('Should serialize / deserialize', async () => { | ||
const attestation = await makeBlockAttestation(); | ||
|
||
const serialized = attestation.toBuffer(); | ||
const deserialized = BlockAttestation.fromBuffer(serialized); | ||
|
||
expect(deserialized).toEqual(attestation); | ||
}); | ||
|
||
it('Should serialize / deserialize + recover sender', async () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🫡 |
||
const account = randomSigner(); | ||
|
||
const proposal = await makeBlockAttestation(account); | ||
const serialized = proposal.toBuffer(); | ||
const deserialized = BlockAttestation.fromBuffer(serialized); | ||
|
||
expect(deserialized).toEqual(proposal); | ||
|
||
// Recover signature | ||
const sender = await deserialized.getSender(); | ||
expect(sender.toChecksumString()).toEqual(account.address); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,15 @@ | ||
import { Header } from '@aztec/circuits.js'; | ||
import { BaseHashType } from '@aztec/foundation/hash'; | ||
import { EthAddress, Header } from '@aztec/circuits.js'; | ||
import { Buffer32 } from '@aztec/foundation/buffer'; | ||
import { Fr } from '@aztec/foundation/fields'; | ||
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; | ||
|
||
import { recoverMessageAddress } from 'viem'; | ||
|
||
import { Gossipable } from './gossipable.js'; | ||
import { Signature } from './signature.js'; | ||
import { TopicType, createTopicString } from './topic_type.js'; | ||
|
||
export class BlockAttestationHash extends BaseHashType { | ||
export class BlockAttestationHash extends Buffer32 { | ||
constructor(hash: Buffer) { | ||
super(hash); | ||
} | ||
|
@@ -20,11 +24,15 @@ export class BlockAttestationHash extends BaseHashType { | |
export class BlockAttestation extends Gossipable { | ||
static override p2pTopic: string; | ||
|
||
private sender: EthAddress | undefined; | ||
|
||
constructor( | ||
/** The block header the attestation is made over */ | ||
public readonly header: Header, | ||
// TODO: temp? | ||
public readonly archive: Fr, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Temp? Teasing aside. Yes think we will move it to the header hash as discussed in #7727 (comment) |
||
/** The signature of the block attester */ | ||
public readonly signature: Buffer, | ||
public readonly signature: Signature, | ||
) { | ||
super(); | ||
} | ||
|
@@ -33,16 +41,39 @@ export class BlockAttestation extends Gossipable { | |
this.p2pTopic = createTopicString(TopicType.block_attestation); | ||
} | ||
|
||
override p2pMessageIdentifier(): BaseHashType { | ||
return BlockAttestationHash.fromField(this.header.hash()); | ||
override p2pMessageIdentifier(): Buffer32 { | ||
return BlockAttestationHash.fromField(this.archive); | ||
} | ||
|
||
/**Get sender | ||
* | ||
* Lazily evaluate and cache the sender of the attestation | ||
* @returns The sender of the attestation | ||
*/ | ||
async getSender() { | ||
if (!this.sender) { | ||
// Recover the sender from the attestation | ||
const address = await recoverMessageAddress({ | ||
message: { raw: this.p2pMessageIdentifier().to0xString() }, | ||
signature: this.signature.to0xString(), | ||
}); | ||
// Cache the sender for later use | ||
this.sender = EthAddress.fromString(address); | ||
} | ||
|
||
return this.sender; | ||
} | ||
|
||
toBuffer(): Buffer { | ||
return serializeToBuffer([this.header, this.signature.length, this.signature]); | ||
return serializeToBuffer([this.header, this.archive, this.signature]); | ||
} | ||
|
||
static fromBuffer(buf: Buffer | BufferReader): BlockAttestation { | ||
const reader = BufferReader.asReader(buf); | ||
return new BlockAttestation(reader.readObject(Header), reader.readBuffer()); | ||
return new BlockAttestation(reader.readObject(Header), reader.readObject(Fr), reader.readObject(Signature)); | ||
} | ||
|
||
static empty(): BlockAttestation { | ||
return new BlockAttestation(Header.empty(), Fr.ZERO, Signature.empty()); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See below.