lidofinance / lido-oracle

Pythonic Lido Oracle daemon
GNU General Public License v3.0
48 stars 28 forks source link

WIP: No get_balances_by_epoch API method in beacon clients #16

Closed ongrid closed 4 years ago

ongrid commented 4 years ago

Preliminary, still in research. Prysm and Lighthouse beacon clients have no epoch argument for the validator's balance API request. This can significantly affect the oracle's algorithm.

On the Zoom on 02 Oct call decided to raise the question in clients' discord (+ teku client)

ongrid commented 4 years ago

Update: It's possible but needs normalization

In Prysm: available directly

GET /validators/balances?epoch=1331

{'epoch': '1331',
 'balances': [{'publicKey': 'j88oiWqF5edu6eUIQ44j5yU9oaI6ZQHjp9VhglINvPTNtErzJnMYGI8fQWg0IUba',
   'index': '0',
   'balance': '32077428710'},
  {'publicKey': 'hz5z7os+T88dL7DxA2uplqyZELWzSPZDi1+O9QhX1NqQddAhip0bmanq4jWjlwPh',
   'index': '1',
   'balance': '63923454600'},
  {'publicKey': 'jC9TXTvsZflctLpFVWbk7D3o2lwTpoFpng+A15Qtb9y87xjIzxj52hSqN5vdbSnF',
   'index': '2',
   'balance': '31923454600'},
  {'publicKey': 'qNm1tizDEUmtWKKBoik80/TcoRhVyYmD52/7YEedjpjlWS5UFfBACooj792EKzYF',
   'index': '3',
   'balance': '32074043852'},

implementation

In Lighthouse available indirectly by specifying state_root

post('/beacon/validators', data=json.dumps({'state_root':state_root,'pubkeys':['0xb99afaeda97ab060ded6178e006469eb28a0e1ee10ba4ececad06a5b80f6a34f6d1b1dab9418f6bf9c492995fbe2ef29']}))

[{'pubkey': '0xb99afaeda97ab060ded6178e006469eb28a0e1ee10ba4ececad06a5b80f6a34f6d1b1dab9418f6bf9c492995fbe2ef29',
  'validator_index': 678,
  'balance': 32000866425,
  'validator': {'pubkey': '0xb99afaeda97ab060ded6178e006469eb28a0e1ee10ba4ececad06a5b80f6a34f6d1b1dab9418f6bf9c492995fbe2ef29',
   'withdrawal_credentials': '0x0010361af430aa7ab4a9567eaaca50ec5e02315ca1513d9ee8d73bde96370091',
   'effective_balance': 32000000000,
   'slashed': False,
   'activation_eligibility_epoch': 0,
   'activation_epoch': 0,
   'exit_epoch': 18446744073709551615,
   'withdrawable_epoch': 18446744073709551615}}]

State root can be found by slot.

get('/beacon/state_root?slot=1000')

Slot can be calculated deterministically by unixtime and network constants.

Result:

ongrid commented 4 years ago

Lighthouse supports balance retrieval by given slot (which gets converted to epoch under the hood, divided by 32)

lh_beacon.get('/beacon/states/15588/validators/' + validator_key)

{'data': {'index': '4504',
  'balance': '32034794204',
  'status': 'Active',
  'validator': {'pubkey': '0x87a8e7a264837c85695a4648a78f4aa53a9ff635f9c2302d35f845f44814adf6c64fb9da899b8eae0cdc314e6a2291ec',
   'withdrawal_credentials': '0x00363abe96b09944581b8d523bb8047bfbf30640bb26774436d01066b2ed9dd1',
   'effective_balance': '32000000000',
   'slashed': False,
   'activation_eligibility_epoch': '51',
   'activation_epoch': '213',
   'exit_epoch': '18446744073709551615',
   'withdrawable_epoch': '18446744073709551615'}}}

Prysm supports state retrieval by epoch. Also needs conversion to base64 format

prysm.get('/validators/balances?epoch=486&publicKeys=' + hex_to_base64(deposit_data['pubkey']))

{'epoch': '486',
 'balances': [{'publicKey': 'jPzS0lUD8fU9eeGRPFJfIyOhSv08FxjRNmbJ4KyepgFOtS0iYR58kx74TpD577B/',
   'index': '4144',
   'balance': '32045769543',
   'status': 'ACTIVE'}],
 'nextPageToken': '',
 'totalSize': 1}