Skip to content
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

ability to re-send kudos on the xdai network (~1000x cost savings) #7702

Merged
merged 4 commits into from
Oct 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/app/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,7 @@ def callback(request):
KUDOS_OWNER_ACCOUNT = env('KUDOS_OWNER_ACCOUNT', default='0xD386793F1DB5F21609571C0164841E5eA2D33aD8')
KUDOS_PRIVATE_KEY = env('KUDOS_PRIVATE_KEY', default='')
KUDOS_CONTRACT_MAINNET = env('KUDOS_CONTRACT_MAINNET', default='0x2aea4add166ebf38b63d09a75de1a7b94aa24163')
KUDOS_CONTRACT_XDAI = env('KUDOS_CONTRACT_XDAI', default='0x74e596525C63393f42C76987b6A66F4e52733efa')
KUDOS_CONTRACT_RINKEBY = env('KUDOS_CONTRACT_RINKEBY', default='0x4077ae95eec529d924571d00e81ecde104601ae8')
KUDOS_CONTRACT_ROPSTEN = env('KUDOS_CONTRACT_ROPSTEN', default='0xcd520707fc68d153283d518b29ada466f9091ea8')
KUDOS_CONTRACT_TESTRPC = env('KUDOS_CONTRACT_TESTRPC', default='0x38c48d14a5bbc38c17ced9cd5f0695894336f426')
Expand Down
2 changes: 2 additions & 0 deletions app/dashboard/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,8 @@ def get_web3(network, sockets=False):
if network == 'rinkeby':
w3.middleware_stack.inject(geth_poa_middleware, layer=0)
return w3
elif network == 'xdai':
return Web3(HTTPProvider(f'https://dai.poa.network/'))
elif network == 'localhost' or 'custom network':
return Web3(Web3.HTTPProvider("http://testrpc:8545", request_kwargs={'timeout': 60}))

Expand Down
9 changes: 7 additions & 2 deletions app/kudos/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,15 @@ class TokenAdmin(admin.ModelAdmin):
ordering = ['-id']
search_fields = ['name', 'description']
raw_id_fields = ['contract']
readonly_fields = ['link', 'view_count']
readonly_fields = ['links', 'view_count']

def link(self, instance):
def links(self, instance):
html = f"<a href={instance.url}>{instance.url}</a>"
other_items = instance.on_networks
if other_items:
html += "<BR>also avaialble on :"
for oi in other_items:
html += f"<BR> - <a href='{oi[1].url}'>{oi[0]}</a>"
return mark_safe(html)

def view_count(self, instance):
Expand Down
4 changes: 2 additions & 2 deletions app/kudos/management/commands/mint_all_kudos.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def mint_kudos(kudos_contract, kudos, account, private_key, gas_price_gwei, mint
# Support Open Sea
if kudos_contract.network == 'rinkeby':
image_path = f'https://ss.gitcoin.co/static/v2/images/kudos/{image_name}'
elif kudos_contract.network == 'mainnet':
elif kudos_contract.network in ['mainnet', 'xdai']:
image_path = f'https://s.gitcoin.co/static/v2/images/kudos/{image_name}'
elif kudos_contract.network == 'localhost':
image_path = f'v2/images/kudos/{image_name}'
Expand All @@ -61,7 +61,7 @@ def mint_kudos(kudos_contract, kudos, account, private_key, gas_price_gwei, mint

if kudos_contract.network == 'rinkeby':
external_url = f'https://stage.gitcoin.co/kudos/{kudos_contract.address}/{kudos_contract.getLatestId() + 1}'
elif kudos_contract.network == 'mainnet':
elif kudos_contract.network in ['mainnet', 'xdai']:
external_url = f'https://gitcoin.co/kudos/{kudos_contract.address}/{kudos_contract.getLatestId() + 1}'
elif kudos_contract.network == 'localhost':
external_url = f'http://localhost:8000/kudos/{kudos_contract.address}/{kudos_contract.getLatestId() + 1}'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,24 @@ def add_arguments(self, parser):
parser.add_argument('num_to_process', type=int, help='num_to_process')
parser.add_argument('override_gas_price', type=int, help='override_gas_price (0 if none)')
parser.add_argument('async', type=int, help='async')
parser.add_argument('order_by', type=int, help='order_by')

def handle(self, *args, **options):
# config
num_to_process = options['num_to_process']
num_to_pull = options['num_to_pull']
_async = options['async']
override_gas_price = options['override_gas_price']
order_by = options['order_by']
delay_if_gas_prices_gt_redeem = 300
send_notif_email = True
send_on_xdai = true

counter_processed = 0
counter_pulled = 0
start_time = int(time.time())

kudos_transfers = KudosTransfer.objects.filter(txid='pending_celery')
kudos_transfers = KudosTransfer.objects.filter(txid='pending_celery').order_by(order_by)
for kt in kudos_transfers:
counter_pulled += 1
if counter_pulled < num_to_pull:
Expand All @@ -60,9 +63,16 @@ def handle(self, *args, **options):
print(f"({avg_processing}/s)")
print(f"PULL - {counter_pulled}/{num_to_pull} - {counter_processed}/{num_to_process} - {kt}")
counter_processed += 1
print(f"PROCESS - {counter_pulled}/{num_to_pull} - {counter_processed}/{num_to_process} - {kt}")
print(kt.admin_url)
if counter_processed < num_to_process:
print(f"PROCESS - {counter_pulled}/{num_to_pull} - {counter_processed}/{num_to_process} - {kt}")
print(kt.admin_url)
if send_on_xdai:
kt.network = 'xdai'
kt.kudos_token_cloned_from = kt.kudos_token_cloned_from.on_xdai
if not kt.kudos_token_cloned_from:
print("target token not found on xdai network :/")
continue
kt.save()
func = redeem_bulk_kudos.delay if _async else redeem_bulk_kudos
try:
func(kt.id, delay_if_gas_prices_gt_redeem=delay_if_gas_prices_gt_redeem, override_gas_price=override_gas_price, send_notif_email=send_notif_email)
Expand Down
67 changes: 67 additions & 0 deletions app/kudos/management/commands/re_mint_kudos_on_xdai.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
"""Define the burn kudos management command.

Copyright (C) 2020 Gitcoin Core

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.

"""
import logging
import time
import warnings

from django.conf import settings
from django.core.management.base import BaseCommand

from dashboard.models import Profile
from kudos.models import Token, TokenRequest
from kudos.tasks import mint_token_request


class Command(BaseCommand):

help = 'mints all kudos in the platform on xdai'

def handle(self, *args, **options):
# config
counter = 0
trs = TokenRequest.objects.filter(approved=True, network='mainnet')
print(trs.count())
for token in trs:
already_xdaid = TokenRequest.objects.filter(network='xdai', name=token.name)
if not already_xdaid:
token.pk = None
token.network = 'xdai'
token.save()
print(f'-/- {token.pk}')
mint_token_request(token.pk, send_notif_email=False)

for token in Token.objects.filter(contract__network='mainnet'):
if token.gen == 1 and not token.on_xdai:
tr = TokenRequest.objects.create(
network='xdai',
name=token.name,
description=token.description,
priceFinney=token.priceFinney,
artist=token.artist,
platform=token.platform,
to_address=token.to_address,
numClonesAllowed=token.numClonesAllowed,
metadata=token.metadata,
tags=token.tags,
approved=True,
profile=Profile.objects.get(handle='gitcoinbot'),
processed=True,
)
print(f'*/* {tr.pk}')
mint_token_request(tr.pk, send_notif_email=False)
36 changes: 36 additions & 0 deletions app/kudos/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,42 @@ class Meta:
# Token QuerySet Manager
objects = TokenQuerySet.as_manager()

@property
def on_xdai(self):
# returns a kudos token object thats on the xdai network; a mirro
# a mirror of the mainnet with 1000x better costs ( https://github.com/gitcoinco/web/pull/7702/ )
return self.on_network('xdai')

@property
def on_mainnet(self):
return self.on_network('mainnet')

@property
def on_rinkeby(self):
return self.on_network('rinkeby')

@property
def on_networks(self):
return_me = []
for network in ['xdai', 'rinkeby', 'mainnet']:
ref = self.on_network(network)
if ref:
return_me.append((network, ref))
return return_me


def on_network(self, network):
if self.contract.network == network:
return None
target = self
if self.gen > 1:
target = self.kudos_token_cloned_from
for token in Token.objects.filter(contract__network=network, num_clones_allowed__gt=1, name=target.name):
if token.gen == 1:
return token
return None


def save(self, *args, **kwargs):
if self.owner_address:
self.owner_address = to_checksum_address(self.owner_address)
Expand Down
16 changes: 9 additions & 7 deletions app/kudos/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
delay_if_gas_prices_gt_mint = 150

@app.shared_task(bind=True, max_retries=10)
def mint_token_request(self, token_req_id, retry=False):
def mint_token_request(self, token_req_id, send_notif_email=True, retry=False):
"""
:param self:
:param token_req_id:
Expand All @@ -48,11 +48,10 @@ def mint_token_request(self, token_req_id, retry=False):
if tx_id:
while not has_tx_mined(tx_id, obj.network):
time.sleep(1)
sync_latest(0)
sync_latest(1)
sync_latest(2)
sync_latest(3)
notify_kudos_minted(obj)
for i in range(0, 5):
sync_latest(i, network=obj.network)
if send_notif_email:
notify_kudos_minted(obj)
else:
self.retry(countdown=(30 * (self.request.retries + 1)))

Expand Down Expand Up @@ -108,12 +107,15 @@ def redeem_bulk_kudos(self, kt_id, delay_if_gas_prices_gt_redeem= 50, override_g
from_name = 'Kevin @ Gitcoin'
_to_email = obj.recipient_profile.email
subject = f"Your '{obj.kudos_token_cloned_from.name}' Kudos has been minted 🌈"
block_url = f'https://etherscan.io/tx/{obj.txid}'
if obj.network == 'xdai':
block_url = f'https://explorer.anyblock.tools/ethereum/poa/xdai/transaction/{obj.txid}'
body = f'''
Hello @{obj.recipient_profile.handle},

Back on {obj.created_on} you minted a '{obj.kudos_token_cloned_from.name}' Kudos, but the Ethereum network's gas fees were too high for us to mint it on-chain.

We're writing with good news. The gas prices on Ethereum have come down, and we are have now minted your token. You can now see the Kudos in your gitcoin profile ( https://gitcoin.co/{obj.recipient_profile.handle} ) or any blockchain wallet ( https://etherscan.io/tx/{obj.txid} ). HOORAY!
We're writing with good news. The gas prices on Ethereum have come down, and we are have now minted your token. You can now see the Kudos in your gitcoin profile ( https://gitcoin.co/{obj.recipient_profile.handle} ) or any blockchain wallet ( {block_url} ). HOORAY!

Party on,
Kevin + the Gitcoin team
Expand Down
11 changes: 11 additions & 0 deletions app/kudos/templates/kudos_details.html
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,17 @@
<img src="{% static 'v2/images/kudos/assets/cellarius_logo_horizontal.svg' %}" alt="Cellarius" height="40">
{% endif %}
<h3 id="kudosName" class="kudos-details__title">{{ kudos.ui_name }} {% if kudos.generation %}<small class="lead">Gen {{ kudos.generation }}</small>{% endif %}</h3>
<div>
Network: {{kudos.contract.network}}

{% if kudos.on_networks|length %}
(Also available on
{% for other_kudos in kudos.on_networks %}
<a href="{{other_kudos.1.url}}">{{other_kudos.0}}</a>
)
{% endfor %}
{% endif %}
</div>
<div>Owner Address: <a target="_blank" href="https://etherscan.io/address/{{ kudos.owner_address }}" class="kudos-details__address" title="{{ kudos.owner_address }}">{{ kudos.owner_address|humanize_address }}</a></div>
{% if kudos.artist %}
<div>Artist: <img style="width: 30px; height: 30px; border-radius: 20px;" src="/dynamic/avatar/{{kudos.artist}}" > <a href="/profile/{{kudos.artist}}/kudos" class="kudos-details__address" title="@{{ kudos.artist }} has this kudos on {{kudos.created_on}}">{{kudos.artist}}</a> | <a href="/kudos/marketplace?q={{kudos.artist}}">View all {{kudos.artist_count}} Kudos by @{{kudos.artist}}</a></div>
Expand Down
4 changes: 3 additions & 1 deletion app/kudos/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ def sync_db_without_txid(self, kudos_id):
kudos['contract'] = contract

try:
kudos_token = Token.objects.get(token_id=kudos_id)
kudos_token = Token.objects.get(token_id=kudos_id, contract__network=self.network)
if kudos_token.suppress_sync:
logger.info(f'Skipped sync-ing "{kudos_token.name}" kudos to the database because suppress_sync.')
return
Expand Down Expand Up @@ -367,6 +367,8 @@ def _get_contract_address(self):
return to_checksum_address(settings.KUDOS_CONTRACT_MAINNET)
if self.network == 'ropsten':
return to_checksum_address(settings.KUDOS_CONTRACT_ROPSTEN)
if self.network == 'xdai':
return to_checksum_address(settings.KUDOS_CONTRACT_XDAI)
if self.network == 'rinkeby':
return to_checksum_address(settings.KUDOS_CONTRACT_RINKEBY)
if self.network == 'localhost' or self.network == 'custom network':
Expand Down
2 changes: 1 addition & 1 deletion app/marketing/stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ def sendcryptoassets():
}

for key, SendCryptoAsset in iterate_me.items():
objs = SendCryptoAsset.objects.filter(network='mainnet').send_success()
objs = SendCryptoAsset.objects.filter(network__in=['mainnet', 'xdai']).send_success()
val = sum(obj.value_in_usdt for obj in objs if obj.value_in_usdt)

stats_to_create = [
Expand Down
1 change: 1 addition & 0 deletions scripts/crontab
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/us

## GITCOIN MARKETING
30 */12 * * * cd gitcoin/coin; bash scripts/run_management_command_if_not_already_running.bash sync_mail >> /var/log/gitcoin/sync_mail.log 2>&1
30 */6 * * * cd gitcoin/coin; bash scripts/run_management_command_if_not_already_running.bash process_pending_kudos_distributions 20 20 2 0 >> /var/log/gitcoin/process_pending_kudos_distributions.log 2>&1
0 0 * * * cd gitcoin/coin; bash scripts/run_management_command_if_not_already_running.bash create_offer_if_none_exists >> /var/log/gitcoin/create_offer_if_none_exists.log 2>&1
* * * * * cd gitcoin/coin; bash scripts/run_management_command_if_not_already_running.bash share_activity >> /var/log/gitcoin/share_activity.log 2>&1
35 14 * * 1,6 cd gitcoin/coin; bash scripts/run_management_command.bash remarket_bounties >> /var/log/gitcoin/remarket_bounties.log 2>&1
Expand Down