oxen-io / oxen-core

Oxen core repository, containing oxend and oxen cli wallets
https://oxen.io
Other
314 stars 120 forks source link

Fix ETH reward calculation #1684

Closed jagerman closed 2 months ago

jagerman commented 2 months ago

Batched earnings were considerably wrong on stagenet: e.g. after 70 blocks of rewards the batched_payments_accrued table contained:

sqlite> select * from batched_payments_accrued;
┌────────────────────────────────────────────┬────────┬───────────────┐
│                  address                   │ amount │ payout_offset │
├────────────────────────────────────────────┼────────┼───────────────┤
│ 0xb0cefd61ddb88176fb972955341adc6c1d05230e │ 73888  │ 0             │
│ 0x00979f83287a7ed917faa37bb1da51f9f7aeb767 │ 16436  │ 0             │
│ 0xb7649b5a5dfabaa0713acfb3040945035b0bbd9e │ 35560  │ 0             │
└────────────────────────────────────────────┴────────┴───────────────┘

which are miniscule (since amount is in thousandths of an atomic unit, i.e. that first one is 73 atomic SENT).

I tracked this down to some bugs in the registration handling and reward calculation code:

Putting them together, for a solo node, each operator in a 12-node network with the block reward around 0.1435 SENT per block, each operator earning just over 15 atomic SENT per block. (and so with 12 SNs and ~70 blocks of rewards that comes out to approximately the sum of the amounts in the table above).

This fixes these issues, but requires stopping oxend, removing the DATADIR/sqlite.db, and restarting oxend again to recompute the reward amounts from the chain.

Post rewards-db rebuild and restart, the rewards look reasonable:

sqlite> select * from batched_payments_accrued;
┌────────────────────────────────────────────┬────────────────┬───────────────┐
│                  address                   │     amount     │ payout_offset │
├────────────────────────────────────────────┼────────────────┼───────────────┤
│ 0xb0cefd61ddb88176fb972955341adc6c1d05230e │ 12754513865548 │ 0             │
│ 0x00979f83287a7ed917faa37bb1da51f9f7aeb767 │ 3620616586612  │ 0             │
│ 0xb7649b5a5dfabaa0713acfb3040945035b0bbd9e │ 7450017715032  │ 0             │
└────────────────────────────────────────────┴────────────────┴───────────────┘

which sums to the appropriate amount for 166 rewardable blocks with L2 per-block reward of 0.1436-0.1435 over the block range in question:

Total actually paid: 23.825148167192 SENT
166 rewardable blocks × 0.14355 reward = 23.8293 SENT

(There's slight imprecision here because of the changing per-block reward -- the 0.14355 amount is approximate).

Doy-lee commented 2 months ago

active_since_height was not being set for ETH registrations, and so service nodes were earning rewards immediately after registration instead of waiting until after SERVICE_NODE_PAYABLE_AFTER_BLOCKS blocks.

Did this change make it into the PR? For this I think we'd need to set the height in validate_and_get_ethereum_registration

jagerman commented 2 months ago

active_since_height was not being set for ETH registrations, and so service nodes were earning rewards immediately after registration instead of waiting until after SERVICE_NODE_PAYABLE_AFTER_BLOCKS blocks.

Did this change make it into the PR?

Yes, it's the:

info.active_since_height = block_height;

addition. Previously this was not getting set (and so was 0). This gets used both at registration, and reset at recommissions, so that you don't earn until currentheight >= active_since_height + 720 blocks after a new reg, or a recomm. (This was to vaguely capture the pre-batching reward days when a new reg or recomm would start at the bottom of the reward list and have to climb to the top before you get a reward; instead you now just have to wait a day of good behaviour before you start getting included in reward payouts).

Doy-lee commented 2 months ago

Oh I don't know how I missed that. LGTM