mirror of
https://github.com/alexgo-io/stacks-puppet-node.git
synced 2026-04-14 22:20:17 +08:00
ensure that a namespace preorder paid the right amount of STACKs when it is revealed (but only if we're in the STACKs epochs)
This commit is contained in:
@@ -25,7 +25,7 @@ from ..config import *
|
||||
from ..hashing import *
|
||||
from ..scripts import *
|
||||
from ..nameset import *
|
||||
|
||||
import traceback
|
||||
from binascii import hexlify, unhexlify
|
||||
|
||||
import json
|
||||
@@ -61,7 +61,7 @@ FIELDS = [
|
||||
|
||||
# fields this operation changes
|
||||
# everything but the block number
|
||||
MUTATE_FIELDS = filter( lambda f: f not in ["block_number"], FIELDS )
|
||||
MUTATE_FIELDS = filter( lambda f: f not in ["block_number"], FIELDS ) + ['token_fee']
|
||||
|
||||
def namespacereveal_sanity_check( namespace_id, version, lifetime, coeff, base, bucket_exponents, nonalpha_discount, no_vowel_discount ):
|
||||
"""
|
||||
@@ -76,7 +76,7 @@ def namespacereveal_sanity_check( namespace_id, version, lifetime, coeff, base,
|
||||
if len(namespace_id) > LENGTHS['blockchain_id_namespace_id']:
|
||||
raise Exception("Invalid namespace ID length for '%s' (expected length between 1 and %s)" % (namespace_id, LENGTHS['blockchain_id_namespace_id']))
|
||||
|
||||
if version not in [NAMESPACE_VERSION_PAY_TO_BURN, NAMESPACE_VERSION_PAY_TO_CREATOR]:
|
||||
if version not in [NAMESPACE_VERSION_PAY_TO_BURN, NAMESPACE_VERSION_PAY_TO_CREATOR, NAMESPACE_VERSION_PAY_WITH_STACKS]:
|
||||
raise Exception("Invalid namespace version bits {:x}".format(version))
|
||||
|
||||
if lifetime < 0 or lifetime > (2**32 - 1):
|
||||
@@ -171,7 +171,26 @@ def check( state_engine, nameop, block_id, checked_ops ):
|
||||
# must be a version we support
|
||||
# pre F-day 2017: only support names that send payment to the burn address
|
||||
# post F-day 2017: support both pay-to-burn and pay-to-creator
|
||||
# 2018 phase 1: support paying for names with STACKs tokens
|
||||
namespace_version_bits = int(nameop['version'])
|
||||
if namespace_version_bits == NAMESPACE_VERSION_PAY_TO_CREATOR:
|
||||
# need to be in post F-day 2017 or later
|
||||
if EPOCH_FEATURE_NAMESPACE_BURN_TO_CREATOR not in epoch_features:
|
||||
log.debug("pay-to-creator is not supported in this epoch")
|
||||
return False
|
||||
|
||||
elif namespace_version_bits == NAMESPACE_VERSION_PAY_WITH_STACKS:
|
||||
# need to be in 2018 phase 1 or later
|
||||
if EPOCH_FEATURE_NAMESPACE_PAY_WITH_STACKS not in epoch_features:
|
||||
log.debug("pay-with-STACKs-tokens is not supported in this epoch")
|
||||
return False
|
||||
|
||||
elif namespace_version_bits != NAMESPACE_VERSION_PAY_TO_BURN:
|
||||
# not supported at all
|
||||
log.debug("Unsupported namespace version {:x}".format(namespace_version_bits))
|
||||
return False
|
||||
|
||||
'''
|
||||
if EPOCH_FEATURE_NAMESPACE_BURN_TO_CREATOR in epoch_features:
|
||||
# post F-day 2017
|
||||
# can send to burn address or namespace preorder address
|
||||
@@ -185,19 +204,54 @@ def check( state_engine, nameop, block_id, checked_ops ):
|
||||
if namespace_version_bits != NAMESPACE_VERSION_PAY_TO_BURN:
|
||||
log.debug("Namespace '%s' requires version %s, but this blockstack is version %s" % (namespace_id, nameop['version'], NAMESPACE_VERSION_PAY_TO_BURN))
|
||||
return False
|
||||
'''
|
||||
units = get_epoch_namespace_price_units(block_id)
|
||||
tokens_paid = 0
|
||||
|
||||
# check fee...
|
||||
if not 'op_fee' in namespace_preorder:
|
||||
log.debug("Namespace '%s' preorder did not pay the fee" % (namespace_id))
|
||||
return False
|
||||
if units == 'STACKS':
|
||||
if EPOCH_FEATURE_STACKS_BUY_NAMESPACES not in epoch_features:
|
||||
traceback.print_stack()
|
||||
log.fatal("Namespaces must be bought in STACKs, but this epoch does not support it!")
|
||||
os.abort()
|
||||
|
||||
namespace_fee = namespace_preorder['op_fee']
|
||||
# must buy namespaces with STACKs
|
||||
# how much did the NAMESPACE_PREORDER pay?
|
||||
if not 'token_fee' in namespace_preorder:
|
||||
log.debug("Namespace {} did not pay the token fee".format(namespace_id))
|
||||
return False
|
||||
|
||||
# must have paid enough
|
||||
if namespace_fee < price_namespace( namespace_id, block_id ):
|
||||
# not enough money
|
||||
log.debug("Namespace '%s' costs %s, but sender paid %s" % (namespace_id, price_namespace(namespace_id, block_id), namespace_fee ))
|
||||
return False
|
||||
tokens_paid = namespace_preorder['token_fee']
|
||||
assert isinstance(tokens_paid, (int,long))
|
||||
|
||||
token_namespace_fee = price_namespace(namespace_id, block_id, units)
|
||||
if token_namespace_fee is None:
|
||||
log.debug("Invalid namespace ID {}".format(namespace_id))
|
||||
return False
|
||||
|
||||
if tokens_paid < token_namespace_fee:
|
||||
# not enough!
|
||||
log.debug("Namespace buyer {} has {} tokens, but '{}' costs {} tokens".format(token_address, account_balance, token_name_fee))
|
||||
return False
|
||||
|
||||
elif units == 'BTC':
|
||||
# must buy namespaces with Bitcoin
|
||||
# check fee...
|
||||
if not 'op_fee' in namespace_preorder:
|
||||
log.debug("Namespace '%s' preorder did not pay the fee" % (namespace_id))
|
||||
return False
|
||||
|
||||
namespace_fee = namespace_preorder['op_fee']
|
||||
|
||||
# must have paid enough
|
||||
if namespace_fee < price_namespace(namespace_id, block_id, units):
|
||||
# not enough money
|
||||
log.debug("Namespace '%s' costs %s, but sender paid %s" % (namespace_id, price_namespace(namespace_id, block_id), namespace_fee ))
|
||||
return False
|
||||
|
||||
else:
|
||||
traceback.print_stack()
|
||||
log.fatal("Unknown payment unit {}".format(units))
|
||||
os.abort()
|
||||
|
||||
# is this the first time this namespace has been revealed?
|
||||
old_namespace = state_engine.get_namespace_op_state( namespace_id, block_id, include_expired=True )
|
||||
@@ -208,7 +262,6 @@ def check( state_engine, nameop, block_id, checked_ops ):
|
||||
# revealed for the first time
|
||||
log.debug("Revealing for the first time: '%s'" % namespace_id)
|
||||
namespace_block_number = namespace_preorder['block_number']
|
||||
# state_create_put_prior_history( nameop, None )
|
||||
|
||||
else:
|
||||
# revealed for the 2nd or later time
|
||||
@@ -217,19 +270,16 @@ def check( state_engine, nameop, block_id, checked_ops ):
|
||||
# push back preorder block number to the original preorder
|
||||
namespace_block_number = old_namespace['block_number']
|
||||
|
||||
# re-revealing
|
||||
# prior_hist = prior_history_create( nameop, old_namespace, preorder_block_number, state_engine, extra_backup_fields=['consensus_hash','preorder_hash'])
|
||||
# state_create_put_prior_history( nameop, prior_hist )
|
||||
|
||||
# record preorder
|
||||
nameop['block_number'] = namespace_block_number # namespace_preorder['block_number']
|
||||
nameop['block_number'] = namespace_block_number
|
||||
nameop['reveal_block'] = block_id
|
||||
state_create_put_preorder( nameop, namespace_preorder )
|
||||
|
||||
# NOTE: not fed into the consensus hash, but necessary for database constraints:
|
||||
nameop['ready_block'] = 0
|
||||
nameop['op_fee'] = namespace_preorder['op_fee']
|
||||
|
||||
|
||||
nameop['token_fee'] = '{}'.format(tokens_paid) # NOTE: avoids overflow
|
||||
# can begin import
|
||||
return True
|
||||
|
||||
|
||||
Reference in New Issue
Block a user