blockwatch-cc / tzstats-legacy

Tezos Block Explorer by Blockwatch
https://tzstats.com
MIT License
18 stars 10 forks source link

Delegate activation rules #23

Open echa opened 5 years ago

echa commented 5 years ago

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:

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

ezal commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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.