Cardano-db-sync: Seltsame Nichtübereinstimmung zwischen Belohnungstabelle und Blocktabelle

Erstellt am 2. Nov. 2020  ·  7Kommentare  ·  Quelle: input-output-hk/cardano-db-sync

Das ist #361 unglaublich ähnlich.

Im Mainnet:

cexplorer=# select reward.* from pool_hash
              inner join reward on reward.pool_id = pool_hash.id
              where pool_hash.hash_raw = '\x964d8d35d91603e0dcfbc64891ee8ffeba0e503ca96bf627bc8bcb55' ; 
   id   | addr_id |    amount    | epoch_no | pool_id | block_id 
--------+---------+--------------+----------+---------+----------
 452424 |   92628 | 133076705980 |      222 |    1250 |  4832319
 508325 |   92628 | 126562664576 |      223 |    1250 |  4853643
(2 rows)

was darauf hindeutet, dass diese Belohnungen von pool_id == 1250 verdient wurden.

Jedoch:

cexplorer=# select block.block_no, slot_leader.pool_hash_id
              from block inner join slot_leader on block.slot_leader_id = slot_leader.id
              where pool_hash_id = 1250 ;
 block_no | pool_hash_id 
----------+--------------
(0 rows)

Wenn sich herausstellt, dass diese durch ein ähnliches Problem wie das in #361 gelöste verursacht werden, benötigen wir unbedingt eine Validierung, um dies abzudecken.

Hilfreichster Kommentar

@erikd was ich dir gestern gesagt habe war falsch, Entschuldigung. Ich habe heute sowohl die Spezifikation als auch die Implementierung überprüft, die wie folgt übereinstimmen und funktionieren.

Die Belohnungskonten in den Stake Pool Zertifikaten:

  • müssen registriert werden
  • müssen NICHT delegiert werden

Wenn zwei Pools ein gemeinsames Prämienkonto auflisten, erhält das Konto außerdem die Summe der Prämien.

Alle 7 Kommentare

Dies unterscheidet sich von #361. Blick auf die addr_id von oben:

cexplorer=# select * from delegation where addr_id = 92628 ;
 id | addr_id | cert_index | pool_hash_id | active_epoch_no | tx_id 
----+---------+------------+--------------+-----------------+-------
(0 rows)

Das bedeutet, dass diese addr_id die Belohnungsadresse für ein Pool-Update sein muss, was trivial zu bestätigen ist:

cexplorer=# select id, hash_id, pledge, margin, fixed_cost, active_epoch_no, reward_addr_id
              from pool_update where reward_addr_id = 92628 ;
  id  | hash_id | pledge | margin | fixed_cost | active_epoch_no | reward_addr_id 
------+---------+--------+--------+------------+-----------------+----------------
 4621 |    1245 |      0 |      1 |  340000000 |             218 |          92628
 4622 |    1246 |      0 |      1 |  340000000 |             218 |          92628
 4623 |    1247 |      0 |      1 |  340000000 |             218 |          92628
 4624 |    1248 |      0 |      1 |  340000000 |             218 |          92628
 4625 |    1249 |      0 |      1 |  340000000 |             218 |          92628
 4626 |    1250 |      0 |      1 |  340000000 |             218 |          92628
 5683 |    1245 |      0 |      1 |  340000000 |             224 |          92628
 5684 |    1246 |      0 |      1 |  340000000 |             224 |          92628
 5685 |    1247 |      0 |      1 |  340000000 |             224 |          92628
(9 rows)

Das bedeutet, dass diese Adresse die Belohnungsadresse für eine Reihe verschiedener Pools ist. Das muss das Problem sein.

Das ist schwierig. Ich hatte die Vermutung in meinem Kopf, dass ein einzelner stake_address nur an einen einzigen Pool delegieren könnte. Das stimmt zwar, aber ein einzelnes stake_address kann als Prämienadresse für mehr als einen Pool verwendet werden.

Es ist tatsächlich komplizierter als das. Wenn stake_address als Prämienadresse für zwei Pools verwendet wird, ist der Prämienbetrag die Summe der Prämien für jeden Pool. Angesichts dessen, was ich derzeit habe, bin ich mir nicht sicher, ob dieses Ei entschlüsselt werden kann.

Das ist nicht nur knifflig, es ist eine komplette Dose voller Würmer.

Nachdem ich mit @JaredCorduan im IOHK-internen Slack gechattet hatte , wurde mir klar, dass die Behandlung von On-Chain-Daten durch db-sync nicht ganz korrekt war und dass einige SPOs ihre Pools möglicherweise nicht richtig eingerichtet haben.

Erstens, wenn ein Pool mit einer Stake-/Belohnungsadresse registriert ist, die selbst noch nie als Stake-Adresse registriert wurde, gilt gemäß Punkt 3 oder Abschnitt 3.3.4 der Shelley Design Spec :

Sollte die Prämienadresse nicht registriert sein, kann der Stake-Pool-Betreiber keine Prämien erhalten. In diesem Fall werden alle fälligen Belohnungen stattdessen an die Reserven zurückgeschickt (aber die Stake-Pool-Mitglieder würden immer noch ihre üblichen Belohnungen erhalten).

Zweitens, wenn zwei oder mehr Pools mit derselben Einsatz-/Belohnungsadresse registriert sind und zwei oder mehr Pools Belohnungen verdienen, dann gehen nur Belohnungen für den ersten (wie wird „erster“ bestimmt?) Pool an die Adresse und der Rest geht an die Reserven/Schatzkammer. Ich habe noch keine richtige Dokumentation dazu gefunden.

@erikd was ich dir gestern gesagt habe war falsch, Entschuldigung. Ich habe heute sowohl die Spezifikation als auch die Implementierung überprüft, die wie folgt übereinstimmen und funktionieren.

Die Belohnungskonten in den Stake Pool Zertifikaten:

  • müssen registriert werden
  • müssen NICHT delegiert werden

Wenn zwei Pools ein gemeinsames Prämienkonto auflisten, erhält das Konto außerdem die Summe der Prämien.

Es sieht derzeit so aus, als ob sich der Fix dafür in einer Bibliothek auf niedrigerer Ebene befindet. @JaredCorduan untersucht es.

Nicht sicher, was hier los ist. Dinge haben sich geändert.

> select * from pool_hash
      where pool_hash.hash_raw = '\x964d8d35d91603e0dcfbc64891ee8ffeba0e503ca96bf627bc8bcb55' ;
  id  |                          hash_raw                          |                           view                           
------+------------------------------------------------------------+----------------------------------------------------------
 4626 | \x964d8d35d91603e0dcfbc64891ee8ffeba0e503ca96bf627bc8bcb55 | pool1jexc6dwezcp7ph8mceyfrm50l6aqu5pu494lvfau309422t9c6z

aber:

> select reward.* from pool_hash
      inner join reward on reward.pool_id = pool_hash.id
      where pool_hash.hash_raw = '\x964d8d35d91603e0dcfbc64891ee8ffeba0e503ca96bf627bc8bcb55' ;
 id | addr_id | amount | epoch_no | pool_id | block_id | type 
----+---------+--------+----------+---------+----------+------
(0 rows)

Diese Abfragen wurden gegen eine Datenbank ausgeführt, auf der master bei Commit f7ee30a245131255f816d6952ef6f0b938e61b94 ausgeführt wurde

Ah, aber die Abfrage der Belohnungstabelle (die null Einträge zurückgibt) ist korrekt:

> select block.block_no, slot_leader.pool_hash_id
              from block inner join slot_leader on block.slot_leader_id = slot_leader.id
              where pool_hash_id = 4626 ;
 block_no | pool_hash_id 
----------+--------------
(0 rows)

Somit ist die eine oder andere Diskrepanz verschwunden und dieses Ticket kann geschlossen werden.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen