Replies: 9 comments 10 replies
-
I think this proposal is very useful because it can solve the problem of asset security for Validators, referring to ETH and FIL have similar practices |
Beta Was this translation helpful? Give feedback.
-
In the current proof verification process, it is required that the number of certificates submitted by validators exceeds a specified threshold. However, when running a validator, I need to sign with an account that has staked over 1 million Aleo. This is considered risky. Therefore, this proposal aims to modify the BatchHeader by separating the "author" into "owner" and "worker." Owner: Holds ownership of the validator and has the authority to modify the worker. Worker: Responsible for issuing certificates and handling the actual verification work. Through this separation, the owner can run the validator more securely without the need to sign with an account staking a significant amount of Aleo.
pub struct BatchHeader<N: Network> {
/// The batch ID, defined as the hash of the round number, timestamp, transmission IDs, and previous batch certificate IDs.
batch_id: Field<N>,
/// The of the batch.
author: Address<N>,
/// The worker of validator.
worker: Address<N>,
/// The round number.
round: u64,
/// The timestamp.
timestamp: i64,
/// The set of `transmission IDs`.
transmission_ids: IndexSet<TransmissionID<N>>,
/// The batch certificate IDs of the previous round.
previous_certificate_ids: IndexSet<Field<N>>,
/// The signature of the batch ID from the creator.
signature: Signature<N>,
}
pub fn new<R: Rng + CryptoRng>(
owner: Address<N>,
private_key: &PrivateKey<N>,
round: u64,
timestamp: i64,
transmission_ids: IndexSet<TransmissionID<N>>,
previous_certificate_ids: IndexSet<Field<N>>,
rng: &mut R,
) -> Result<Self> {
match round {
// If the round is zero or one, then there should be no previous certificate IDs.
0 | 1 => ensure!(previous_certificate_ids.is_empty(), "Invalid round number, must not have certificates"),
// If the round is not zero and not one, then there should be at least one previous certificate ID.
_ => ensure!(!previous_certificate_ids.is_empty(), "Invalid round number, must have certificates"),
}
// Retrieve the address.
let author = owner;
// Retrieve the address.
let worker = Address::try_from(private_key)?;
// Compute the batch ID.
let batch_id = Self::compute_batch_id(author, round, timestamp, &transmission_ids, &previous_certificate_ids)?;
// Sign the preimage.
let signature = private_key.sign(&[batch_id], rng)?;
// Return the batch header.
Ok(Self { author, worker, batch_id, round, timestamp, transmission_ids, previous_certificate_ids, signature })
}
pub fn from(
author: Address<N>,
worker: Address<N>,
round: u64,
timestamp: i64,
transmission_ids: IndexSet<TransmissionID<N>>,
previous_certificate_ids: IndexSet<Field<N>>,
signature: Signature<N>,
) -> Result<Self> {
match round {
// If the round is zero or one, then there should be no previous certificate IDs.
0 | 1 => ensure!(previous_certificate_ids.is_empty(), "Invalid round number, must not have certificates"),
// If the round is not zero and not one, then there should be at least one previous certificate ID.
_ => ensure!(!previous_certificate_ids.is_empty(), "Invalid round number, must have certificates"),
}
// Compute the batch ID.
let batch_id = Self::compute_batch_id(author, round, timestamp, &transmission_ids, &previous_certificate_ids)?;
// Verify the signature.
if !signature.verify(&worker, &[batch_id]) {
bail!("Invalid signature for the batch header");
}
// Return the batch header.
Ok(Self { author, worker, batch_id, round, timestamp, transmission_ids, previous_certificate_ids, signature })
}
|
Beta Was this translation helpful? Give feedback.
-
From my perspective, it is essential to separate a worker from a validator. Combined running validator and worker requires huge computation and division worker/validator would decrease its centralization and would reduce the impact of possible malicious behavior. |
Beta Was this translation helpful? Give feedback.
-
A simple implementation https://github.com/AleoHQ/snarkVM/pull/2185 |
Beta Was this translation helpful? Give feedback.
-
This is a very useful proposal |
Beta Was this translation helpful? Give feedback.
-
Expect the proposal to be incorporated into the mainnet |
Beta Was this translation helpful? Give feedback.
-
This proposal, while improving the security posture of a validator, introduces non-trivial changes to the protocol including functional and storage overhead. Instead, consider the alternate design:
@OzielLa what do you think? |
Beta Was this translation helpful? Give feedback.
-
On my point of view, it’s better to have two keys: one for working, such as vote, message signature, the other one for owner , can withdraw token. This is a practical solution in Filecoin. What's more, like ETH2.0, there are also two keys for validators: one is verifing key, used to verify the messages and produce block. the other one is withdrawing key, used to receive block rewards and transfer tokens. In this way, the validator's assets will be more secure. |
Beta Was this translation helpful? Give feedback.
-
I've implemented the change with the withdrawal address approach here - https://github.com/AleoHQ/snarkVM/pull/2385. More details are explained in the PR description, but TLDR -
|
Beta Was this translation helpful? Give feedback.
-
arc: ARC-0037
title: Validator Node, Separation of Owner Address and Worker Address
authors: OzielLa
topic: Protocol
status: Draft
created: 11/16/2023
Abstract
The validator address holds a significant amount of credits and requires real-time proof verification work, which imposes a significant security burden on the validator. To address this, a worker address is added to specifically handle real-time proof verification tasks. The validator address is responsible for managing the worker.
Specification
credits.aleo/struct committee_state
credits.aleo/setworker
Test Cases
Reference Implementations
Dependencies
Backwards Compatibility
Security & Compliance
References
Beta Was this translation helpful? Give feedback.
All reactions