-
Notifications
You must be signed in to change notification settings - Fork 160
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Missing staking rewards #683
Comments
I agree that having logic in two places is asking for trouble. The problem is that the ledger cannot know what rewards are orphaned until the first block of a new epoch, at which time the information is used and discarded. For the ledger to provided such tagged rewards would mean storing a large map that is not used at all in the ledger. |
Re-tested this with the |
Adding instrumentation to this was a HUGE pain in the neck, but I managed to do it. Instrumenting the rewards for the address we are interested in before they are split into good vs orphaned rewards:
This matches the data in the database ( select * from reward where addr_id = 2865 order by epoch_no asc;
id | addr_id | type | amount | epoch_no | pool_id
-------+---------+--------+--------+----------+---------
68955 | 2865 | member | 121039 | 3820 | 3
68983 | 2865 | member | 99125 | 3821 | 3
69012 | 2865 | member | 109972 | 3822 | 3
69042 | 2865 | member | 95739 | 3823 | 3
69072 | 2865 | member | 109854 | 3824 | 3
69102 | 2865 | member | 111134 | 3825 | 3
(6 rows) That means any error is in If we had orphaned rewards in the rewards table (or vice versa) then that would be a |
Ah hang on. When
So rewards for epoch However, this is not just a mis-classification, the reward for the address in question is missing completely. That points to |
The part of this that is probably most amenable to debugging is that the address is de-regestered in epoch Recently, |
I can think of a scenario consistent with what we are seeing: If the owner of We could test this by seeing how much stake this address has in the snapshot taken on the 324 / 325 boundary. |
@JaredCorduan Here are the transactions for that stake address:
This is at epoch |
ok, thank you, back to the drawing board... |
On the select stake_registration.*, count (stake_registration.addr_id) as reg_count,
(select count (*) as rew_count from reward where addr_id = stake_registration.addr_id)
from stake_deregistration
inner join stake_registration on stake_registration.addr_id = stake_deregistration.addr_id
group by stake_registration.id
order by reg_count, rew_count asc ; From that table, entries of interest are: id | addr_id | cert_index | tx_id | reg_count | rew_count
-----+---------+------------+-------+-----------+-----------
269 | 1082 | 0 | 25308 | 1 | 1
176 | 649 | 0 | 23786 | 1 | 1
903 | 2865 | 0 | 27157 | 1 | 6
160 | 609 | 1 | 23693 | 1 | 8
162 | 612 | 5 | 23693 | 1 | 8
230 | 900 | 1 | 24755 | 1 | 13
232 | 903 | 5 | 24755 | 1 | 15
166 | 620 | 5 | 23719 | 1 | 45
164 | 617 | 1 | 23719 | 1 | 54 So, picking the first of these the registration: select stake_registration.*, block.block_no, block.epoch_no from stake_registration
inner join tx on tx.id = stake_registration.tx_id
inner join block on tx.block_id = block.id
where stake_registration.addr_id = 1082 order by epoch_no asc ;
id | addr_id | cert_index | tx_id | block_no | epoch_no
-----+---------+------------+-------+----------+----------
269 | 1082 | 0 | 25308 | 869838 | 2609
(1 row) the deregistration: select stake_deregistration.*, block.block_no, block.epoch_no from stake_deregistration
inner join tx on tx.id = stake_deregistration.tx_id
inner join block on tx.block_id = block.id
where stake_deregistration.addr_id = 1082 order by epoch_no asc ;
id | addr_id | cert_index | tx_id | block_no | epoch_no
----+---------+------------+-------+----------+----------
80 | 1082 | 0 | 25539 | 871267 | 2613
(1 row) the delegation: select * from delegation where addr_id = 1082 ;
id | addr_id | cert_index | pool_hash_id | active_epoch_no | tx_id | slot_no
-----+---------+------------+--------------+-----------------+-------+----------
204 | 1082 | 1 | 152 | 2611 | 25308 | 18771236
(1 row) the rewards: select * from reward where addr_id = 1082 ;
id | addr_id | type | amount | epoch_no | pool_id
-------+---------+--------+--------+----------+---------
36173 | 1082 | member | 9219 | 2611 | 152
(1 row) absence of orphaned rewards: select * from orphaned_reward where addr_id = 1082 order by epoch_no asc;
id | addr_id | type | amount | epoch_no | pool_id
----+---------+------+--------+----------+---------
(0 rows) but the pool did receive rewards for all the epochs of interest: select epoch_no, count (addr_id) as reward_count from
reward where pool_id = 152 and epoch_no >= 2608 and epoch_no < 2615
group by epoch_no order by epoch_no asc ;
epoch_no | reward_count
----------+--------------
2609 | 9
2610 | 10
2611 | 13
2612 | 12
2613 | 12
2614 | 12
(6 rows) Address |
I know exactly what is going on now. I wrote a custom version of the ledger-state client to view the history of We've run into one of the known warts described in the formal spec in 17 Errata:
In particular, the credential This logic has been around since the start of Shelley, there should be many instances of this on mainnet as well. |
I guess my question now is, do we need to track orphans? |
i am still detecting the presence of what should be orphaned rewards when using |
yep, the ledger will continue to produce them |
in case we want to accurately calculate the pool's ROS - yes, we need :) |
The easier way to compute the pool's ROS is to look at the pool provenance. In particular, The provenance is exposed by the node in one of the mini-protocols. |
good stuff, but is this value available for each epoch? we need to know this value for each epoch for pool's ROS calculation. |
I am at least 90% certain that the orphaned rewards being retrieved by If the |
Probably the best solution is for |
or at least provide the sum of rewards distributed by the pool (including orphan rewards) for each epoch |
The node exposes a query that can be used to get it: |
@JaredCorduan Users should not need to query the node to get data that should be in the database. I assume that is in ledger state somewhere. Please tell how and when I can access it. |
it is not in the ledger state, but you can query the node for it |
You almost certainly don't want to include the existing notion of orphaned rewards in any kind of calculation. The concept depends on incidental events. In the reward scheme, the rewards calculated for epoch n are calculated using a snapshot of the stake distribution from the end of epoch n-2. These rewards are available to withdraw from the end of epoch n+1. Rewards attributed to stake keys which are not registered go to the treasury. There are two points in time when this is checked. Once at the start of the reward calculation, and once at the end of epoch n+1. What I suspect you want is the set of all rewards for an epoch that were lost due to deregistrations. But this is not what the "orphaned rewards" give you! They only include the ones which were registered at the start of the reward calculation but not and the end of the epoch. Since the reward calculation starts partway into epoch n+1, I wouldn't expect this to be a reliable source of information.
The approach Jared mentioned above will work to find the whole set. |
Thanks for the info @redxaxder , I didn't know that
I see, thanks for the explanations |
@redxaxder |
So far, I have only seen this on the Shelley QA network (with the
10.0.0
release tag). I have looked for it onmainnet
but have not yet found one. If it happens on theshelley_qa
network then it is likely to happen onmainnet
.The address we are interested in:
Looking at its registrations:
and de-registrations:
looking at the rewards:
and orphaned rewards:
The odd thing here is that although the address was only de-registered in epoch
3827
it got no rewards after epoch3825
.We would expect to get rewards for epoch
3826
and orphaned rewards for epochs3827
and3829
.So how was this stake address delegated?:
The fact that
active_epoch_no
here is3820
explains why the first reward is in that epoch and not earlier.So, did this pool get any rewards for the relevant epochs?
So the pool did earn rewards for epochs
3826-3829
butdb-sync
did not capture them for this address. Why?There is no change between epoch
3825
and3826
, but the former got rewards and the later did not. Why?There is only a single pool update (ie when the pool is created), so there were no pool changes:
Is there an era change in the region of interest?
No, it switches from Shelley to Allegra somewhere between epoch
1331
and epoch1347
and from Allegra to Mary somewhere between epoch1978
and epoch1992
(can;t be more exact during to sparseness of logging) The era before, during and after the problem is Mary.As I have said elsewhere, having two vastly different implementations of the same complex logic and hoping that they produce the same results is un-reasonable and is just an incredibly bad idea. The
ledger-specs
library should provide the rewards already tagged to show whether they are good or orphaned.The text was updated successfully, but these errors were encountered: