Skip to content

Instantly share code, notes, and snippets.

@etienne-napoleone
Last active June 22, 2019 20:20
Show Gist options
  • Select an option

  • Save etienne-napoleone/07cbd1823de7f8899bbe03fb8f9253db to your computer and use it in GitHub Desktop.

Select an option

Save etienne-napoleone/07cbd1823de7f8899bbe03fb8f9253db to your computer and use it in GitHub Desktop.
Terra validator dirty quick oracle
#!/usr/bin/env python3
import math
import os
import subprocess
import time
import uuid
import requests
# pls see requirements.txt in the gist
CHAIN_ID = "soju-0009"
PRICE_ENDPOINT = 'https://api.coinone.co.kr/ticker_utc?currency=luna'
REST_ENDPOINT = 'http://127.0.0.1:1317'
VALIDATOR = 'terravaloper1qjsdrnv5u59syrl7yzla9a7qkgwd5g5hkqg5dc'
FEEDER = 'terra1qjsdrnv5u59syrl7yzla9a7qkgwd5g5hk0yfat'
DENOM = 'ukrw'
ACCOUNT = os.getenv('ORACLE_ACCOUNT')
PASSWORD = os.getenv('ORACLE_PASSWORD')
def get_price():
"""Return the usd price of luna from Coingecko
This is jut to have an estimation for testing purpose
The result is too vague to have any meaning
"""
r = requests.get(PRICE_ENDPOINT)
json = r.json()
return json['last']
def gen_salt():
"""Gen a 4 chars random sting"""
return uuid.uuid4().hex[:4]
def get_period():
"""Return current period"""
height = requests.get(
REST_ENDPOINT + '/blocks/latest',
).json()['block_meta']['header']['height']
return math.floor(int(height) / 12)
def get_sequence():
"""Return the account next sequence number"""
seq = requests.get(
REST_ENDPOINT + '/auth/accounts/{}'.format(FEEDER),
).json()['value']['sequence']
return int(seq)
def prevote(price, salt):
"""Submit a prevote tx"""
command = [
'terracli', 'tx', 'oracle', 'prevote',
'--denom={}'.format(DENOM),
'--price={}'.format(price),
'--salt={}'.format(salt),
'--from={}'.format(ACCOUNT),
'--chain-id={}'.format(CHAIN_ID),
'-s={}'.format(get_sequence()),
'-y',
]
try:
subprocess.run(
command,
input='{}\n'.format(PASSWORD),
encoding='ascii',
)
return True
except Exception as e:
print('error: ', e)
return False
def vote(price, salt):
"""Submit a vote tx"""
command = [
'terracli', 'tx', 'oracle', 'vote',
'--denom={}'.format(DENOM),
'--salt={}'.format(salt),
'--price={}'.format(price),
'--from={}'.format(ACCOUNT),
'--validator={}'.format(VALIDATOR),
'--chain-id={}'.format(CHAIN_ID),
'--trust-node',
'-s={}'.format(get_sequence()),
'-y',
]
try:
subprocess.run(
command,
input='{}\n'.format(PASSWORD),
encoding='ascii',
)
return True
except Exception as e:
print('error: ', e)
return False
if __name__ == "__main__":
print('started oracle script')
periods = {}
while True:
current_period = get_period()
if current_period not in periods:
print('\n----- new period {}'.format(current_period))
if current_period - 1 in periods:
last_price, last_salt = periods[current_period - 1]
print('sending vote')
if vote(last_price, last_salt):
print(
'voted at {} {} with salt {}'
.format(last_price, DENOM, last_salt)
)
else:
print('vote failed')
# otherwise the prevote will not have a correct sequence number
# seems like the rest server takes some seconds to actualise
# whereas it's instant with `terracli query account`
time.sleep(20)
price = get_price()
salt = gen_salt()
if prevote(price, salt):
print(
'prevoted at {} {} with salt {}'
.format(price, DENOM, salt)
)
periods[current_period] = (price, salt)
else:
print('prevote failed')
periods[current_period] = False
time.sleep(15)
certifi==2019.6.16
chardet==3.0.4
idna==2.8
requests==2.22.0
urllib3==1.25.3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment