Task
ControlMethod::ConfigSetUpstream sits on the ordinary tier, but its effect both outlives the
token that invoked it and confers authority on a principal — which is the contract's own
stated master-tier rule. It should be master tier here, so the two nodes that consult this predicate
cannot disagree.
Why
control.config.setUpstream persists a caller-chosen RPC upstream into dig-node's config.json.
Config::from_env reads it on the next start as the passthrough target for every method the node
does not implement — dig-node ships with it EMPTY precisely so an unimplemented method answers a
truthful local -32601 rather than something a third party made up. And pairing.revoke does not
touch it, so the escalation delegates and is not revocable: after the call the caller no longer
needs the token, and the operator's designated remedy leaves the hostile value in place.
That is the identical shape ChiaPeersAdd/ChiaPeersRemove are already master tier for, with
arguably wider reach: a trusted Chia peer dictates chain facts, while the upstream answers a whole
method surface.
The refined rule worth recording in the doc comment
"Outlives the token" is necessary and not sufficient. cache.setCap and log.setLevel also
persist and also survive revocation, and they should stay ordinary — promoting them would break the
cache control dig-app drives with a paired token, for no authority gained. The discriminator is
whether the surviving effect installs a principal the node will thereafter believe, obey, or speak
to:
| capability |
outlives token |
names a principal |
tier |
chiaPeers.add / .remove |
yes |
a peer believed without corroboration |
master |
config.setUpstream |
yes |
the third party unimplemented methods are forwarded to |
master (proposed) |
cache.setCap |
yes |
no — a local resource budget |
ordinary |
log.setLevel |
yes |
no — local verbosity |
ordinary |
Stating it as a rule is what lets the NEXT method be judged rather than matched by analogy.
Current state in dig-node — an interim overlay that RETIRES ITSELF
DIG-Network/dig-node#452 enforces master tier for this one method ahead of the contract, via a
single declared list (LOCALLY_MASTER_TIER_CONTROL_METHODS) applied before the contract lookup. It
only ever WIDENS the contract's set, never narrows it, and
locally_master_tier_methods_are_still_unclassified_by_the_contract FAILS the moment this ticket
lands — so adopting it here is what deletes the overlay, and the two statements of one rule cannot
drift in the meantime.
The overlay is a bridge, not a design. This ticket is the durable fix.
Acceptance
ControlMethod::ConfigSetUpstream.requires_master_token() returns true, the doc comment records
the refined rule and why cache.setCap/log.setLevel are deliberately excluded, and the crate is
published so dig-node can adopt it and delete the overlay.
Cross-references
Task
ControlMethod::ConfigSetUpstreamsits on the ordinary tier, but its effect both outlives thetoken that invoked it and confers authority on a principal — which is the contract's own
stated master-tier rule. It should be master tier here, so the two nodes that consult this predicate
cannot disagree.
Why
control.config.setUpstreampersists a caller-chosen RPC upstream into dig-node'sconfig.json.Config::from_envreads it on the next start as the passthrough target for every method the nodedoes not implement — dig-node ships with it EMPTY precisely so an unimplemented method answers a
truthful local
-32601rather than something a third party made up. Andpairing.revokedoes nottouch it, so the escalation delegates and is not revocable: after the call the caller no longer
needs the token, and the operator's designated remedy leaves the hostile value in place.
That is the identical shape
ChiaPeersAdd/ChiaPeersRemoveare already master tier for, witharguably wider reach: a trusted Chia peer dictates chain facts, while the upstream answers a whole
method surface.
The refined rule worth recording in the doc comment
"Outlives the token" is necessary and not sufficient.
cache.setCapandlog.setLevelalsopersist and also survive revocation, and they should stay ordinary — promoting them would break the
cache control dig-app drives with a paired token, for no authority gained. The discriminator is
whether the surviving effect installs a principal the node will thereafter believe, obey, or speak
to:
chiaPeers.add/.removeconfig.setUpstreamcache.setCaplog.setLevelStating it as a rule is what lets the NEXT method be judged rather than matched by analogy.
Current state in dig-node — an interim overlay that RETIRES ITSELF
DIG-Network/dig-node#452 enforces master tier for this one method ahead of the contract, via a
single declared list (
LOCALLY_MASTER_TIER_CONTROL_METHODS) applied before the contract lookup. Itonly ever WIDENS the contract's set, never narrows it, and
locally_master_tier_methods_are_still_unclassified_by_the_contractFAILS the moment this ticketlands — so adopting it here is what deletes the overlay, and the two statements of one rule cannot
drift in the meantime.
The overlay is a bridge, not a design. This ticket is the durable fix.
Acceptance
ControlMethod::ConfigSetUpstream.requires_master_token()returnstrue, the doc comment recordsthe refined rule and why
cache.setCap/log.setLevelare deliberately excluded, and the crate ispublished so dig-node can adopt it and delete the overlay.
Cross-references