## Job Declarator
This is the main orchestrator of the Job Declaration process.
It leverages a `impl JobValidationEngine` and a `TokenManager` to make sure that declared Custom Jobs are managed correctly.
## Job Validation Engine
The goal of the `JobValidationEngine` trait is to allow for Custom Job validation and solution propagation to be done over a modular interface that is agnostic to:
- Bitcoin node implementation
- Communication method with Bitcoin node implementation
The initial implementation is based on Bitcoin Core over IPC, but other approaches should be doable by implementing the `JobValidationEngine` trait.
Please note that token management is not covered here.
More specifically, it is the `JobDeclarator` responsability to leverage a `TokenManager` to manage the tokens to be
added to:
- `AllocateMiningJobToken.Success.mining_job_token`
- `DeclareMiningJob.Success.new_mining_job_token`
Similarly, validation of:
- `DeclareMiningJob.mining_job_token` against `AllocateMiningJobToken.Success.mining_job_token`
- `SetCustomMiningJob.mining_job_token` against `DeclareMiningJob.Success.new_mining_job_token`
are also `JobDeclarator` responsability via `TokenManager`.
## Token Management
`TokenManager` tracks two token states during the Job Declaration flow:
- Allocated tokens: provided to JDC via `AllocateMiningJobToken.Success.mining_job_token`
- Active tokens: provided to JDC via `DeclareMiningJob.Success.new_mining_job_token`
Token values for both allocated and active tokens are generated by atomically incrementing the same `AtomicU64` counter. Each allocation or activation increments the counter and uses the previous value as the token value, so tokens are unique within a `TokenManager` instance until counter wraparound.
Allocated tokens are created when a JDC requests a mining job token. The token is stored together with the downstream ID that requested it, so a later `DeclareMiningJob.mining_job_token` is valid only when it is well formed, still allocated, and owned by the same downstream.
When `DeclareMiningJob` is successfully validated, the allocated token is removed from the allocated-token set and a new active token is created. The allocated token value is retained only as an internal lookup key: when `SetCustomMiningJob` later presents the active token, the `JobDeclarator` maps it back to the original allocated token value so the `JobValidationEngine` can find the stored declaration.
Active tokens are single-use. During `SetCustomMiningJob` handling, the `JobDeclarator` deactivates the active token before passing the original allocated token value to the `JobValidationEngine`.
Malformed, unknown, expired, wrong-owner, or already consumed tokens are rejected with `invalid-mining-job-token`.
Allocated and active tokens are periodically removed by a janitor task after their configured timeouts. When a downstream disconnects, its allocated tokens are removed immediately because they only authorize future `DeclareMiningJob` messages from that JDS connection. Active tokens are retained until they are consumed or expire, because they authorize a later `SetCustomMiningJob` sent through the Pool's Mining Protocol path, not through the JDS connection.