Yamale docs ← back to the site

x/enforcement

Transactions

MsgEmergencyFreeze

/blockchain.enforcement.v1.MsgEmergencyFreeze

Signed by the authority field.

EmergencyFreeze lets a country's enforcement authority stop an account in one block, without waiting for a validator to open a case.

Field Type Description
authority string authority must hold ROLE_ENFORCEMENT_AUTHORITY covering the country the target account is recorded in. It used to be a single address named in the module's parameters, chain-wide, able to freeze anything. The perimeter is the difference: an authority that needs to stop an account outside its own country needs the authority of that country, urgently or otherwise. Skipping the jurisdiction check because the situation is urgent would make the one path that acts on a single signature also the one path with no territorial limit.
target string
reason string reason is the grounds, in words the accused can read. Required, the same as for a validator's case: acting in an emergency is not a reason to leave the record blank, it is the reason the record matters.
evidence_uri string
evidence_hash string

MsgEmergencyRelease

/blockchain.enforcement.v1.MsgEmergencyRelease

Signed by the authority field.

EmergencyRelease lets it let the account go again, just as fast.

Field Type Description
authority string authority must hold ROLE_ENFORCEMENT_AUTHORITY covering the country the case's target is recorded in.
case_id uint64
reason string reason is why it was released, kept beside the original accusation. The case is not deleted: a freeze that was lifted as a mistake is part of the record of how this power has been used.

MsgOmbudsmanVeto

/blockchain.enforcement.v1.MsgOmbudsmanVeto

Signed by the ombudsman field.

OmbudsmanVeto stops a case that has not taken anything yet. The only message the ombudsman may sign, and the only thing it can do.

Field Type Description
ombudsman string ombudsman must equal the ombudsman parameter.
case_id uint64
reason string reason is why the case was stopped, kept beside the original accusation. Required: an office whose refusals need no grounds is not accountable either, and this one is a check rather than a privilege.

MsgOpenCase

/blockchain.enforcement.v1.MsgOpenCase

Signed by the opener field.

OpenCase accuses an address, and freezes it while the validators decide.

Field Type Description
opener string opener is the account that signs: either a bonded validator's account address — the key it signs with, not its operator address — or the account holding ROLE_ENFORCEMENT_AUTHORITY over the target's country. What gets recorded on the case differs, deliberately. A validator is recorded by its operator address, because that is the name the accusation is legible under; an office is recorded by the account itself, which is the group policy address a role-holders query can be read against. Both are identities somebody can look up, which is the property that matters: an accusation with no visible author is not an accusation.
target string
action CaseAction
reason string reason is the grounds, in words the accused can read.
evidence_uri string evidence_uri and evidence_hash point at and pin the evidence held off-chain. Required for a seizure unless the parameters say otherwise.
evidence_hash string
legal_instrument LegalInstrument legal_instrument names the external authority the seizure is carried out under and pins its content. Required for a seizure, always, with no parameter that turns it off — a requirement governance can vote away is a default, and this one is meant to be a requirement. Ignored for a freeze, which takes nothing and has to be openable the minute a theft is noticed.

MsgReverseCase

/blockchain.enforcement.v1.MsgReverseCase

Signed by the authority field.

ReverseCase is governance overturning a passed case: the appeal. It lifts the freeze and records the reversal, and it is deliberately a slower instrument than the one that imposed the freeze, because it is the one used when the chain got it wrong.

Field Type Description
authority string
case_id uint64
reason string reason is why it was overturned, kept beside the original accusation.

MsgSweep

/blockchain.enforcement.v1.MsgSweep

Signed by the sender field.

Sweep collects whatever a passed seizure can now reach. Permissionless and repeatable: funds that were staked arrive later, when unbonding matures, and somebody has to be able to collect them without another vote.

Field Type Description
sender string sender pays for the transaction and gets nothing for it. Anyone may send this: the destination is fixed by the parameters, so there is nothing to gain by being the one who calls it and nothing to lose by letting somebody else.
case_id uint64

MsgUpdateParams

/blockchain.enforcement.v1.MsgUpdateParams

Signed by the authority field.

UpdateParams defines a (governance) operation for updating the module parameters. The authority defaults to the x/gov module account.

Field Type Description
authority string authority is the address that controls the module (defaults to x/gov unless overwritten).
params Params NOTE: All parameters must be supplied.

MsgVoteCase

/blockchain.enforcement.v1.MsgVoteCase

Signed by the voter field.

VoteCase records one validator's judgement.

Field Type Description
voter string voter is the validator's account address, the key it signs with. Its operator address and its voting power are read from the staking module.
case_id uint64
option VoteOption

MsgWithdrawCase

/blockchain.enforcement.v1.MsgWithdrawCase

Signed by the opener field.

WithdrawCase takes back a case before the vote ends, lifting its freeze.

Field Type Description
opener string opener is the account that opened the case: a validator's account address, or the enforcement authority's own address. It is resolved the same way it was when the case was opened, so whichever of the two forms was recorded is the one that matches.
case_id uint64

Queries

CaseVotes

GET /yamale/blockchain/enforcement/v1/case/{case_id}/votes

CaseVotes queries how each validator voted on a case.

Request:

Field Type Description
case_id uint64

Response:

Field Type Description
votes repeated Vote
yes_power int64 The tallies as they stand, so a caller does not have to add up the votes and reach a different answer from the chain's.
no_power int64
abstain_power int64
total_power_at_open int64
required_power int64 required_power is what yes_power has to reach for the case to pass.

FreezeStatus

GET /yamale/blockchain/enforcement/v1/freeze/{address}

FreezeStatus answers whether one address can send, and if not, why.

Request:

Field Type Description
address string

Response:

Field Type Description
frozen bool
freeze Freeze freeze and case are set only when frozen. Together they are the answer to "why", which is the question this query exists for.
case Case

GetCase

GET /yamale/blockchain/enforcement/v1/case/{id}

GetCase queries one case, with its votes.

Request:

Field Type Description
id uint64

Response:

Field Type Description
case Case
votes repeated Vote

HeldCases

GET /yamale/blockchain/enforcement/v1/case/held

HeldCases queries the seizures that have been agreed and are waiting out their delay. This is the list an ombudsman reads: everything still stoppable at no cost to anybody, and how long there is left to stop it.

Response:

Field Type Description
case repeated Case

ListCase

GET /yamale/blockchain/enforcement/v1/case

ListCase queries every case ever opened, resolved or not.

Request:

Field Type Description
pagination PageRequest

Response:

Field Type Description
case repeated Case
pagination PageResponse

ListFreeze

GET /yamale/blockchain/enforcement/v1/freeze

ListFreeze queries every frozen address.

Request:

Field Type Description
pagination PageRequest

Response:

Field Type Description
freeze repeated Freeze
pagination PageResponse

OpenCases

GET /yamale/blockchain/enforcement/v1/case/open

OpenCases queries the cases still being voted on.

Response:

Field Type Description
case repeated Case

Params

GET /yamale/blockchain/enforcement/v1/params

Params queries the parameters of the module.

Response:

Field Type Description
params Params params holds all the parameters of this module.

Recovered

GET /yamale/blockchain/enforcement/v1/recovered

Recovered totals what this module has taken, across every case. It is the number that says how much this power has actually been used.

Response:

Field Type Description
total repeated Coin
cases_opened uint64 cases_passed and cases_opened put that total in proportion.
cases_passed uint64

SeizureWindow

GET /yamale/blockchain/enforcement/v1/window

SeizureWindow queries how much of the rolling cap is left.

Response:

Field Type Description
window_start_height int64
current_height int64
seized repeated Coin seized is the total inside the window; cap is the parameter it is measured against; remaining is cap minus seized, floored at zero and carrying only the denominations the cap names.
cap repeated Coin
remaining repeated Coin
seizure_count uint64 seizure_count and max_seizures are the other half of the cap: the one that binds every denomination, including ones the value cap does not name.
max_seizures uint64

State

Case

Case is an accusation against one address, and everything the chain did about it. Cases are never deleted: the record of who was frozen, on whose word, on what evidence, and by whose votes is the only thing that makes this power answerable.

Field Type Description
id uint64
target string target is the account accused.
opener string opener is the validator operator that opened the case, or the emergency authority when emergency is set. Not typed as a validator address for exactly that reason: an emergency case is opened by a group policy account, and rendering it as an operator address would name a validator that does not exist.
action CaseAction
status CaseStatus
reason string reason is the stated grounds, in plain words, for whoever is accused.
evidence_uri string evidence_uri points at the evidence held off-chain; evidence_hash is the SHA-256 of what it pointed at when the case was opened, so a document that is later edited can be shown to have been edited.
evidence_hash string
opened_at_height int64
voting_ends_at_height int64
resolved_at_height int64
total_power_at_open int64 total_power_at_open is the bonded power the threshold is measured against. Frozen at open so that power leaving the set mid-vote cannot lower the bar for what is already being decided.
yes_power int64
no_power int64
abstain_power int64
recovered repeated Coin recovered is everything this case has taken so far. It grows as unbonding funds arrive and are swept, which is why it is a running total rather than a single figure written once.
sweep_complete bool sweep_complete is set when a seizure has nothing left to collect: the account is empty and no unbonding remains. Until then the case stays sweepable by anyone.
emergency bool emergency marks a case opened by the emergency authority rather than by a validator. It changes nothing about how the case is decided — the validators still confirm or refuse it on the same terms — and exists so that nobody reading the record has to work out from an address whether the founders acted directly.
legal_instrument LegalInstrument legal_instrument is the external authority a seizure is carried out under. Required for a seizure and empty for a freeze: a freeze takes nothing and is meant to be openable in the minute a theft is noticed, which is not a minute in which anybody has a court order.
execute_at_height int64 execute_at_height is when a held seizure may be carried out — the height the delay its size earned runs to. Zero on any case that is not a seizure the validators have passed.
assessed_value repeated Coin assessed_value is what the target was found to hold when the case was decided: balance, stake and unbonding together. It is the figure the delay was sized from and the figure charged against the rolling cap, recorded on the case so that "why did this one wait a week" is answerable from the record rather than from a re-run of the arithmetic against state that has since moved.

EventCaseHeld

EventCaseHeld is emitted when a seizure is agreed and starts waiting out its delay. This is the block in which anybody who wants to object still can, so it carries the height the objection window closes at and the value the delay was sized from.

Field Type Description
case_id uint64
target string
assessed_value repeated Coin assessed_value is what the target was found to hold: balance, stake and unbonding together.
execute_at_height int64
delay_blocks uint64

EventCaseOpened

EventCaseOpened is emitted when a case is opened and its target frozen.

Field Type Description
case_id uint64
target string
opener string
action CaseAction
reason string
voting_ends_at_height int64
emergency bool emergency is set when the founders' group opened it directly rather than a validator. Anyone watching for this module's events should be able to tell the two apart without fetching the case.

EventCaseResolved

EventCaseResolved is emitted once, when a case reaches its final status — including when it expires with nobody having voted.

Field Type Description
case_id uint64
target string
status CaseStatus
yes_power int64
no_power int64
required_power int64

EventCaseVetoed

EventCaseVetoed is emitted when the ombudsman stops a case.

Its own event rather than an EventCaseResolved with a different status, because "the office outside the validator set refused this" is the single most important thing that can happen in this module and it should not have to be inferred from an enum by whoever is watching.

Field Type Description
case_id uint64
target string
ombudsman string
reason string
was_held bool was_held distinguishes a veto that stopped a seizure the validators had already agreed to from one that stopped a case still being argued. They are very different acts by the same office.

EventCaseVoted

EventCaseVoted is emitted for each validator's vote.

Field Type Description
case_id uint64
validator string
option VoteOption
power int64

EventFreezeLifted

EventFreezeLifted is emitted whenever an address becomes able to send again, whatever the reason — expiry, rejection, withdrawal or reversal.

Field Type Description
address string
case_id uint64
status CaseStatus

EventSeized

EventSeized is emitted every time a sweep collects something, which for a target with staked funds is more than once.

Field Type Description
case_id uint64
target string
destination string
collected repeated Coin
complete bool complete is set on the sweep that finishes the job: nothing liquid left, nothing staked, nothing unbonding.

EventSeizureDeferred

EventSeizureDeferred is emitted when a seizure comes due and the rolling cap refuses it.

Emitted every time it is refused, not once. A case that is quietly waiting is indistinguishable from a case that has been forgotten, and the difference matters to the person whose account is still frozen.

Field Type Description
case_id uint64
target string
retry_at_height int64 retry_at_height is the next height at which the window could have room — when the oldest seizure in it falls out.
reason string reason says which limit refused it, in words, so that nobody has to reconstruct the arithmetic from the parameters to find out.

Freeze

Freeze is the fact that stops the money moving.

It is kept as its own record rather than being derived by scanning cases, because it is read on every single transfer the chain processes.

Field Type Description
address string
case_id uint64 case_id is the case that put it there — so an account holder who is refused a transfer can be told which case to read, rather than "no".
expires_at_height int64 expires_at_height is the height the freeze lapses at, for the provisional freeze that comes with opening a case. Zero means it does not expire on its own: the validators voted for it, and lifting it takes a decision.
frozen_at_height int64

LegalInstrument

LegalInstrument is the external authority a seizure is carried out under.

This is deliberately not the evidence fields. Evidence is why the chain believes the allegation; an instrument is who, outside this chain, ordered that something be done about it. Keeping them in one pair of fields would let a case satisfy its authority requirement by attaching its own investigation report, which is exactly the substitution the requirement exists to prevent.

There is no URI here, and that is the design rather than an omission. A link is a document somebody controls: whoever hosts it can change it, take it down, or never have had it. What is stored instead is an identifier that names the instrument in the world — the issuing body and its own reference number — so that verification means going to that body's register, plus a hash that pins the content of what was served. A reader with the reference can find the instrument without this chain's help; a reader with the hash can prove the copy they were shown is the one the case was opened on. Neither depends on anyone keeping a web server up.

Field Type Description
issuing_authority string issuing_authority names the body that issued it, as it names itself — "High Court of Kenya at Nairobi", "Bank of Ghana". Free text because the set of courts and supervisors in the world is not enumerable in a proto file, and a wrong enum would be worse than an honest string.
reference string reference is the instrument's own identifier in the issuer's register: the case number, the direction number, the warrant number. This is the half that makes the instrument findable by somebody who does not trust this chain.
kind LegalInstrumentKind
hash string hash is the SHA-256, lowercase hex, of the instrument as it was served. It pins the content: an order that is later amended can be shown to have been amended, and a copy produced afterwards can be checked against what the validators actually voted on.
issued_at int64 issued_at is when the instrument was issued, as Unix seconds. Refused if it is in the future relative to the block: an order dated tomorrow has not been issued, and a case that claims one is either mistaken or manufactured.

SeizureDelayTier

SeizureDelayTier is one step in the schedule that decides how long a seizure waits between being decided and being carried out.

A tier matches when the value the case assessed reaches its threshold in that denomination, and a case takes the longest delay of every tier it matches. Longest rather than first, so the schedule does not depend on the order governance happened to write it in — an ordering bug in a parameter list is invisible until the day it lets somebody's life savings move at the speed meant for pocket change.

Field Type Description
threshold Coin threshold is the smallest amount, in base units, that falls into this tier.
delay_blocks uint64 delay_blocks is how long a case in this tier waits after the vote before anything moves.

SeizureRecord

SeizureRecord is one executed seizure, kept so the rolling window can be summed without replaying the chain.

Records fall out of the window by height, and the number that can be inside one is bounded by the cap itself — which is what keeps both the sum and the pruning bounded no matter how long the chain has been running.

Field Type Description
case_id uint64
height int64 height is when the seizure executed. It is the first component of the key, so the window is a range scan over recent heights rather than a filter over every seizure there has ever been.
amount repeated Coin amount is what this seizure counted for against the cap: the value assessed when the case was decided, or what execution actually moved if that was larger. Taking the larger of the two is what stops a deposit arriving during the hold from being taken outside the window's arithmetic.

Vote

Vote is one validator's judgement on one case, with the power it carried when it was cast.

Field Type Description
case_id uint64
validator string
option VoteOption
power int64 power is recorded as it was at the moment of voting. Reading it live at resolution instead would let a validator vote and then change what their vote meant.

Value types

CaseAction

CaseAction is what a case asks the chain to do.

Value Meaning
CASE_ACTION_UNSPECIFIED CASE_ACTION_UNSPECIFIED is the unset default and is never valid.
CASE_ACTION_FREEZE CASE_ACTION_FREEZE stops the account from sending anything. Nothing is taken and nothing is redistributed; the funds stay where they are and stay the account's.
CASE_ACTION_SEIZE CASE_ACTION_SEIZE freezes the account and, if the case passes, moves what it holds to the recovery destination. Delegations are unbonded so that staked funds come back and can be recovered as they mature.

CaseStatus

CaseStatus is where a case has got to.

Value Meaning
CASE_STATUS_UNSPECIFIED CASE_STATUS_UNSPECIFIED is the unset default and is never valid.
CASE_STATUS_VOTING CASE_STATUS_VOTING is open. The target is frozen for as long as it stays that way, or until the provisional freeze expires.
CASE_STATUS_PASSED CASE_STATUS_PASSED means the validators agreed. A freeze case ends here with the account frozen indefinitely; a seizure case sweeps and then keeps sweeping as unbonding funds arrive.
CASE_STATUS_REJECTED CASE_STATUS_REJECTED means they did not, and the freeze is lifted.
CASE_STATUS_EXPIRED CASE_STATUS_EXPIRED means the voting period ended without the threshold being reached — including the ordinary case where nobody voted at all. The freeze is lifted. This is deliberately not the same outcome as rejection: silence is not a finding, and the record should not claim it was.
CASE_STATUS_WITHDRAWN CASE_STATUS_WITHDRAWN means whoever opened it took it back before the vote ended, which also lifts the freeze.
CASE_STATUS_REVERSED CASE_STATUS_REVERSED means an authority overturned the case rather than the validators deciding it: governance reversing one that passed, or the emergency authority releasing an account it or a validator had frozen. Any freeze is lifted. What was already seized is not returned by this module — that takes a transfer from the recovery destination, by whoever controls it, and pretending otherwise would be a lie told by an enum value.
CASE_STATUS_HELD CASE_STATUS_HELD is a seizure the validators have agreed to that has not been carried out yet: it is waiting out the delay its size earned. It is a status of its own rather than a flag on PASSED because it is the only window in which the seizure can still be stopped without anything having to be given back. The ombudsman's veto lives here, and so does governance's chance to reverse a case before it costs anybody anything. A reader who cannot tell "decided" from "done" cannot tell those apart. The account stays frozen throughout, and the freeze no longer lapses: the set has decided, so there is nothing left for a lapse to protect against.
CASE_STATUS_VETOED CASE_STATUS_VETOED means the ombudsman stopped the case. Any freeze is lifted and nothing is taken. Distinct from REJECTED and from REVERSED on purpose. Rejected is the validator set disagreeing; reversed is an authority undoing something that already happened; vetoed is one office outside the set refusing to let it happen at all. Collapsing them would hide which check actually caught the case, and that is the only thing the record of a stopped case is for.

LegalInstrumentKind

LegalInstrumentKind is the sort of external authority a seizure rests on.

It is a closed list rather than free text because the list is the point: a seizure on this chain is the execution of something a court, a regulator or a magistrate already ordered, and "other" would let a case name its own paperwork as its authority.

Value Meaning
LEGAL_INSTRUMENT_KIND_UNSPECIFIED LEGAL_INSTRUMENT_KIND_UNSPECIFIED is the unset default and is never valid.
LEGAL_INSTRUMENT_KIND_COURT_ORDER LEGAL_INSTRUMENT_KIND_COURT_ORDER is an order of a court.
LEGAL_INSTRUMENT_KIND_REGULATORY_DIRECTION LEGAL_INSTRUMENT_KIND_REGULATORY_DIRECTION is a direction issued by a financial supervisor under its own statutory power — a central bank's directive, a financial intelligence unit's freezing direction.
LEGAL_INSTRUMENT_KIND_WARRANT LEGAL_INSTRUMENT_KIND_WARRANT is a warrant issued in a criminal matter.

VoteOption

VoteOption is how a validator voted.

Value Meaning
VOTE_OPTION_UNSPECIFIED VOTE_OPTION_UNSPECIFIED is the unset default and is never valid. A vote has to say something.
VOTE_OPTION_YES VOTE_OPTION_YES supports the case: freeze, or freeze and seize.
VOTE_OPTION_NO VOTE_OPTION_NO opposes it.
VOTE_OPTION_ABSTAIN VOTE_OPTION_ABSTAIN counts towards nothing. It exists so a validator can put on the record that they saw the case and declined to judge it, which is a different statement from not voting.

Errors

Every way a transaction to this module can be rejected.

Code Name Message
1100 ErrInvalidSigner expected gov account as only signer for proposal message
1101 ErrUnknownValidator not a bonded validator
1102 ErrCaseNotFound no such case
1103 ErrCaseClosed case is no longer open
1104 ErrAlreadyVoted this validator has already voted on this case
1105 ErrAlreadyFrozen an open case already freezes this address
1106 ErrNotTheOpener only the validator that opened the case may withdraw it
1107 ErrFrozen account is frozen by an enforcement case
1108 ErrEvidenceRequired a seizure case requires evidence
1109 ErrInvalidCase case is not valid
1110 ErrNotSeizure case did not order a seizure
1111 ErrNotPassed case has not passed
1112 ErrProtectedAddress address cannot be frozen or seized
1113 ErrLimitReached exceeds a configured maximum
1115 ErrLegalInstrumentRequired a seizure case requires an external legal instrument
1116 ErrNoOmbudsman no ombudsman is appointed
1117 ErrOmbudsmanCannotInitiate the ombudsman may only stop cases, never open, vote on, or advance one
1118 ErrSeizureCapReached this seizure would breach the rolling cap on what may be taken per window
1119 ErrNotHeld case is not waiting to be carried out