Skip to main content

StagedNodeKey

Struct StagedNodeKey 

Source
pub struct StagedNodeKey { /* private fields */ }
Expand description

A freshly-generated node key written to a temp file in data_dir, not yet committed to node.secret.

Staging (generate + write the temp) is separated from committing (archive-old + rename) so a multi-file rotation can generate all key material before touching any canonical file — a failure while generating the second secret then leaves the first untouched rather than half-rotated (#844). Produced by stage_node_key; finished with Self::commit.

Dropping a StagedNodeKey without committing removes the temp file, so an abandoned stage never litters data_dir.

Implementations§

Source§

impl StagedNodeKey

Source

pub fn public(&self) -> PublicKey

The public key of the staged secret, for logging the node id before the commit lands.

Source

pub fn sign(&self, msg: &[u8]) -> Signature

Sign msg with the staged secret, without committing it.

decdn node rotate-key needs this: CapacityBond.bindNodeId demands an ed25519 ownership proof from the key being bound, and that proof has to exist before the transaction is submitted — while committing node.secret has to happen after it confirms, or a reverted bind would leave the daemon serving under an unbound identity. Signing from the stage is what lets those two orders coexist.

The secret itself stays unreachable: this is deliberately a signing oracle rather than a secret() accessor, so a staged key cannot be copied out and persisted somewhere the archive-on-commit discipline does not cover.

Source

pub fn commit(&mut self) -> Result<Option<PathBuf>>

Commit the staged key: archive any existing node.secret (so the operator key-rotation runbook keeps the prior material, mirroring the no-stage path) and atomically rename the temp into place.

Returns the archive path if a prior key was moved aside, or None when there was nothing to archive (fresh install).

Takes &mut self rather than self so a failed commit does not destroy the key. Consuming self meant the ? below dropped the stage with committed == false, and Drop deleted the temp — on a caller path (decdn node rotate-key) that only reaches this call after proving on-chain that the binding moved to this key. The caller must stay able to Self::keep it instead. The cost is that a caller can now observe a committed stage; commit is idempotent-safe in that a second call would simply fail on the already-renamed temp.

§Errors

Returns an error if archiving the prior key or the install rename fails. The commit is fail-safe via install_staged: if the install rename fails after the prior key was archived, the archive is restored (best-effort) so the old key stays live, and the error states whether the restore succeeded or node.secret is now missing. On error committed stays false, so the caller may still Self::keep the staged key — and if it does not, Drop reclaims the temp.

Source

pub fn keep(self) -> Result<PathBuf>

Preserve the staged key without installing it, at <data_dir>/node.secret.pending.<node_id>. Returns the path it landed at.

The third outcome, between Self::commit and the Drop that discards an abandoned stage. It exists for one situation, reached three ways: a key-rotation transaction may have taken effect, but the caller cannot confirm the binding moved — the receipt could not be read at all, or it mined carrying no matching NodeIdBound, or it mined and the install of the confirmed key then failed. Whether the chain now names this key is unknown in the first two, and known in the third — where the key is even more valuable. Discarding the secret there is unrecoverable — if the transaction did land, the operator is bound to an identity whose private key no longer exists anywhere, and the daemon keeps serving under a key nothing binds. Installing it is equally wrong, because the transaction may instead have failed.

So the key is parked under a name that is deliberately not node.secret: no daemon will load it (load_or_create reads exactly <data_dir>/node.secret), and the operator can install it once they have checked whether the transaction confirmed.

§Errors

Returns an error if the destination has no parent directory, or if the rename fails. In both cases the staged temp is deliberately left in place and its path is named in the error, rather than being reclaimed by Drop: this is only ever called when the key may already be bound on-chain, so an awkwardly-named surviving file beats an unrecoverable identity. The caller is expected to print that path.

Trait Implementations§

Source§

impl Debug for StagedNodeKey

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Drop for StagedNodeKey

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> MaybeSend for T
where T: Send,

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more