Skip to content
This repository has been archived by the owner on Dec 21, 2023. It is now read-only.

Delegate activation rules #23

Open
echa opened this issue Aug 6, 2019 · 3 comments
Open

Delegate activation rules #23

echa opened this issue Aug 6, 2019 · 3 comments
Assignees
Labels
help wanted Extra attention is needed

Comments

@echa
Copy link
Contributor

echa commented Aug 6, 2019

The Blockwatch/TzStats indexer maintains an internal representation of the full blockchain state which is constructed from replaying block receipts (plus pulling snapshot index and rights from context). Anything else like supply, consensus and voting rolls, balance and delegation history, etc is derived from these receipts.

This approach works for all balance updates, but diverges from a node's context for the active delegate set. Ideally, all events that lead to registration, deactivation and reactivation of a delegate should be observable in receipts and there should be a consistent set of rules. This issue tracks our research towards understanding these rules and how they changed across versions.

From available documentation here and here and some reverse engineering our current set of delegate activation rules is as follows:

  • Registration/Activation
    • a tz1/2/3 account sends a delegation operation and sets itself as delegate (example, example)
    • a tz1/2/3 account is defined as delegate in the genesis block, a.k.a. the 8 Foundation Bakers (example)
    • 🔥 a tz1/2/3 account sends an origination operation and sets itself as delegate on the created contract (example)
  • Deactivation
    • 🔥 a registered delegate is listed in the block header field metadata.deactivated which gets populated in the last block of a cycle (example)
  • Reactivation
    • an inactive delegate registers again using a delegation operation to self like above (example)
    • an inactive delegate receives a transaction operation (example)
    • an inactive delegate bakes or endorses a block (because it still has rights, example)

Problems with the approach above 🔥

  1. some deactivations are missing from block.metadata.deactivated (example, example, example, example)
    • all the examples are marked inactive in the context, but they were never signalled in block metadata; a full dump of all deactivations extracted from block headers until block 552,960 (cycle 134) is availabe at this Gist
    • Note: early protocol versions until block 200,704 created many duplicate deactivations, although that's not an issue here the same code change that fixed duplicates may have broken signalling of some deactivations afterwards
  2. delegate registration through origination is inconsistent: (a) sometimes such accounts become delegates immediatly (example), (b) sometimes they magically become delegates later (example), (c) sometimes they don't become delegates at all (example)

Open Questions

  • How come that some originate+delegate operations register the caller as delegate and some do not?
  • Before which block (if any specific block) or which release did an incoming transaction reactivate an inactive delegate? Is this still the case?
@echa echa added the help wanted Extra attention is needed label Aug 6, 2019
@echa echa self-assigned this Aug 6, 2019
@ezal
Copy link

ezal commented Aug 12, 2019

Concerning the second question: It is in the Athens release that receiving an incoming transaction did not anymore reactivate an inactive delegate. See diff in the credit function of lib_protocol/contract_storage.ml between proto_003_xxx and proto_004_yyy.

@echa
Copy link
Contributor Author

echa commented Aug 31, 2019

A little Internet archeology revealed that proto_002_xxx fixed a bug where non-registered delegates would accept delegations in an origination operation (registration case 3 above).

I found a changelog extract in the Tezos Slack archive https://log.tezos.link/index.php?date=20-07-2018 published at 20-07-2018 15:45:31 (block 26,579 cycle 6) mentioning

- Fixed a bug in delegations, where contracts could delegate to unregistered
   delegates. This will be enforced from now on, and the existing unregistered
   delegates will be automatically registered (except for two empty addresses).

This explains the weird RPC error messages before block 28,082 and the magic activations at block 28,083 where protocol v002 activated. Problem 2 above seems to be solved. Many of these magically activated delegates are still active today.

@echa
Copy link
Contributor Author

echa commented Sep 1, 2019

I switched our indexer to track the grace period of each delegate in the hope that I wouldn't have to rely on the deactivated list which is obviously buggy.

The idea is to deactivate delegates in the indexer when their grace period expires. Reverse engineered rules to set/update the grace period are as follows:

  1. on registration by self-delegation initial grace period is set to cycle+11 (this also applies to every subsequent re-registration by self-delegation independent of active/inactive status)
  2. when an inactive delegate bakes or endorses it will be reactivated and its grace period set to cycle+11 (this does not apply to sending manager operations like transactions!)
  3. when an active delegate sends a reveal operation, bakes or endorses a block its grace period is updated to max(grace, cycle+6) (this does not apply to sending transactions and originations, even reveal is unconfirmed here)

Until proto_004_xxx activated in cycle 111 the following additional conditions applied:

  1. receiving a transaction re-registers an inactive delegate setting grace period to cycle+11
  2. receiving a transaction as an active delegate updates the grace period to max(grace, cycle+6)

A bug fix in proto_002_xxx also sets the grace period of all eligible delegates to 17 (6+11). Eligible are all delegates with nono-zero balance that did not register through self-delegation, but were used as delegate in at least one origination operation.

When cross-checking this method another Tezos bug surfaced: against what's specified in the documentation, that one could extend the grace period by sending small meaningless transactions, that is not the case. Neither sent transactions nor sent originations (no matter using delegation or not) would update the grace period.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants