Cardano-db-sync: Deposit after pool retirement should be in the rewards table

Created on 13 Nov 2020  ·  18Comments  ·  Source: input-output-hk/cardano-db-sync

After retiring a pool, the deposit should arrive to the rewards account. While visible in cardano-cli, it cannot be found in the database.

cardano-cli shelley query stake-address-info \
> --mainnet \
> --address stake1uywjy7h05jmhx9y3wzy94td6xz4txynuccgam0zfn800v8qq33z29
[
    {
        "address": "stake1uywjy7h05jmhx9y3wzy94td6xz4txynuccgam0zfn800v8qq33z29",
        "delegation": "pool1qnrqc7zpwye2r9wtkayh2dryvfqs7unp99f2039duljrsaffq5c",
        "rewardAccountBalance": 500009820
    }
]

image

Most helpful comment

@erikd
From the ledger spec:

Page 21

Recall that the stake pool retirement refunds are issued not when a certificate scheduling the
retirement is processed, but at the epoch boundary for which the retirement is scheduled.

Page 40

• The function poolRefunds is used to calculate the total refunds that must be distributed
for stake pools scheduled to retire. Note that this calculation takes a slot number corresponding to the epoch boundary slot when the calculation is performed. The returned
map maps pool operator hashkeys to the refunds, which will ultimately be returned to the
registered reward account.

All 18 comments

But the 'rewards' table is not the same as stake_address change... If we do this, we should also store to this table another things, like ITN rewards (table 'reserve' at the moment) for example

The only other way to get those deposits along with rewards would be to query the pool retirement table, whether a pool connected to this stake address expired in a given epoch, and add a hardcoded 500000000 value to the rewards if that value has not yet been withdrawn, which again requires computing if the withdrawals are not higher than rewards until that point in time, and so on and so forth, which seems really clunky.

However, I still think it should be stated in the db more explicitly without these hard coded values and such. Perhaps another table? Or a simpler relation?

If I would choose to get these 500 ADA from the pool_retirement table, if the pool has multiple owners how would I find out to which stake address these 500 ADA have been rewarded?

if the pool has multiple owners how would I find out to which stake address these 500 ADA have been rewarded?

the deposit is returned to the rewards address (is always one for a pool), not owner address

the deposit is returned to the rewards address (is always one for a pool), not owner address
That makes sense thank you!

So then the deposit of a retired pool will be returned to the pool's reward address which is declared in the pool_update table right?

I'm asking because I have the current example which confuses me:

SELECT SUM(amount) as reward, NULL as withdrawal
FROM reward
         LEFT JOIN stake_address sa on reward.addr_id = sa.id
WHERE sa.view = 'stake1u9rqg96sdsdrqshpx0x77jna40ws90drts2wks7vuy63dpqj6txws'
UNION
SELECT NULL, SUM(amount)
FROM withdrawal
         LEFT JOIN tx ON withdrawal.tx_id = tx.id
         LEFT JOIN block ON tx.block_id = block.id
         LEFT JOIN stake_address sa on withdrawal.addr_id = sa.id
WHERE sa.view = 'stake1u9rqg96sdsdrqshpx0x77jna40ws90drts2wks7vuy63dpqj6txws';

This query gives us the total rewards and the total withdrawals of an example stake address. The difference between those is exactly 500000000 lovelace. Sure it could be a coincidence but that's pretty hard to imagine since there are other examples like that. So let's just assume this is a returned pool deposit then this stake address should occur as a reward address in the pool_update table, right?

SELECT pool_retire.hash_id, sa.view FROM pool_retire
    LEFT JOIN pool_update pu ON pool_retire.hash_id = pu.hash_id
    LEFT JOIN stake_address sa on sa.id = pu.hash_id
WHERE sa.view = 'stake1u9rqg96sdsdrqshpx0x77jna40ws90drts2wks7vuy63dpqj6txws'

But this query leads to no results. The thing I could find out is that the stake address is a co-owner of a retired pool (pool_hash_id = 8) which led me to my first question.

I'm just wondering how I could determine where these 500 ADA are coming from. Could this deposit be related to the ITN?

So then the deposit of a retired pool will be returned to the pool's reward address which is declared in the pool_update table right?

right

But this query leads to no results

sa.id != pu.hash_id -> sa.id = pu.reward_addr_id

I'm just wondering how I could determine where these 500 ADA are coming from. Could this deposit be related to the ITN?

Almost certainly not.

Where are we up to with this issue. Seems to have been a bit of back-and-forth. Care to update me on the current state-of-play on this?

Sure, the issue got hijacked quite a bit.. So nothing changed about the question - deposit that should return to the rewards address after retiring a pool is nowhere explicitly in the DB (e.g. 500 ADA arrived in epoch 245). But you have to check the pool retirement table, whether the pool whose owner address is the rewards address you're looking for and then manually add a hardcoded value of '500' to user's rewards IF this amount from this exact retirement has not been withdrawn yet. Which seems really cumbersome to me and I proposed whether it could go into the rewards table, or somewhere else, but explicitly.

deposit that should return to the rewards address after retiring a pool is nowhere explicitly in the DB

Do you have an example mainnet address for me to investigate?

e11d227aefa4b773149170885aadba30aab3127cc611ddbc4999def61c / stake1uywjy7h05jmhx9y3wzy94td6xz4txynuccgam0zfn800v8qq33z29

You have a misconception about the deposit refund. Deposit refunds do not end up in the reward table but in the tx table. So lets find it.

For the address we are interested in:

cexplorer=# select id, view, registered_tx_id from stake_address
               where view = 'stake1uywjy7h05jmhx9y3wzy94td6xz4txynuccgam0zfn800v8qq33z29' ;
  id  |                            view                             | registered_tx_id 
------+-------------------------------------------------------------+------------------
 2820 | stake1uywjy7h05jmhx9y3wzy94td6xz4txynuccgam0zfn800v8qq33z29 |          2420601

the id field may be different across db-sync instances, but the id will be useful for this exploration.

A bit complex, but the refund can be seen using:

cexplorer=# select stake_deregistration.id, stake_deregistration.addr_id, stake_deregistration.tx_id,
               tx.deposit, block.epoch_no from stake_deregistration
               inner join tx on tx.id = stake_deregistration.tx_id
               inner join block on block.id = tx.block_id
               where stake_deregistration.addr_id = 2820 ; 
 id  | addr_id |  tx_id  | deposit  | epoch_no 
-----+---------+---------+----------+----------
 730 |    2820 | 2842157 | -2000000 |      223

Similarly, the registration can be seem using:

cexplorer=# select stake_registration.id, stake_registration.addr_id, stake_registration.tx_id, tx.deposit,
               block.epoch_no from stake_registration inner join tx on tx.id = stake_registration.tx_id
               inner join block on block.id = tx.block_id
               where stake_registration.addr_id = 2820 ; 
  id   | addr_id |  tx_id  | deposit | epoch_no 
-------+---------+---------+---------+----------
  1649 |    2820 | 2421547 | 2000000 |      208
 86926 |    2820 | 2842177 | 2000000 |      223
(2 rows)

I assume this stake address was:

  • registered in epoch 208
  • de-registered in epoch 223
  • re-registered again in epoch 223.

Does that all make sense?

It does make sense for stake registration, but I was talking about pool retirement. And the 500 ADA that should be returned to the pool owner's reward address.

I still don't think it goes back to the reward address. Do you have an example of a pool being retired?

The relation or the fact that it would show up in the database somewhere is actually my request for a feature, not a bug in the current version. Retired pool example: pool134dws3tyc7kphwl6gks26cm6l390554lns9lyatm3gkxs6dwj2z. The address I sent earlier is its owner

@erikd
From the ledger spec:

Page 21

Recall that the stake pool retirement refunds are issued not when a certificate scheduling the
retirement is processed, but at the epoch boundary for which the retirement is scheduled.

Page 40

• The function poolRefunds is used to calculate the total refunds that must be distributed
for stake pools scheduled to retire. Note that this calculation takes a slot number corresponding to the epoch boundary slot when the calculation is performed. The returned
map maps pool operator hashkeys to the refunds, which will ultimately be returned to the
registered reward account.

@xdzurman Sorry in this:

The relation or the fact that it would show up in the database somewhere is actually my request for a feature,

What exactly is the feature request?

@erikd To put the pool deposit (500 ADA) somewhere in the database, after a pool is retired. Currently it can't be explicitly linked to the reward address it belongs to.

Was this page helpful?
0 / 5 - 0 ratings