Skip to content

Commit

Permalink
Namecoin: Add name_autoregister command
Browse files Browse the repository at this point in the history
  • Loading branch information
JeremyRand committed Oct 18, 2018
1 parent bf407cb commit 8f37ca1
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 5 deletions.
9 changes: 7 additions & 2 deletions electrum_nmc/coinchooser.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,13 @@ def sufficient_funds(buckets):
return total_input >= spent_amount + fee_estimator_w(total_weight)

# Collect the coins into buckets, choose a subset of the buckets
buckets = self.bucketize_coins(coins)
buckets = self.choose_buckets(buckets, sufficient_funds,
# We check sufficient_funds against an empty list because in Namecoin
# we might have sufficient funds solely from the name inputs.
if sufficient_funds([]):
buckets = []
else:
buckets = self.bucketize_coins(coins)
buckets = self.choose_buckets(buckets, sufficient_funds,
self.penalty_func(tx))

tx.add_inputs(name_coins + [coin for b in buckets for coin in b.coins])
Expand Down
47 changes: 45 additions & 2 deletions electrum_nmc/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,17 @@ def verifymessage(self, address, signature, message):
def _mktx(self, outputs, fee, change_addr, domain, nocheck, unsigned, rbf, password, locktime=None, name_input_txids=[], name_input_identifiers=[], name_outputs=[]):
self.nocheck = nocheck
change_addr = self._resolver(change_addr)

# The domain map will (for unknown reasons) delete its contents when
# read. Since we want to use it multiple times for Namecoin, the most
# obvious workaround is to simply make copies of it before we cast it
# into a map.
name_txid_domain = copy.deepcopy(domain)
name_identifier_domain = copy.deepcopy(domain)

domain = None if domain is None else map(self._resolver, domain)
name_txid_domain = None if name_txid_domain is None else map(self._resolver, name_txid_domain)
name_identifier_domain = None if name_identifier_domain is None else map(self._resolver, name_identifier_domain)
final_outputs = []
for address, amount, name_op in name_outputs:
if address is None:
Expand All @@ -489,8 +499,8 @@ def _mktx(self, outputs, fee, change_addr, domain, nocheck, unsigned, rbf, passw
final_outputs.append(TxOutput(TYPE_ADDRESS, address, amount))

coins = self.wallet.get_spendable_coins(domain, self.config)
name_coins = self.wallet.get_spendable_coins(domain, self.config, include_names=True, only_uno_txids=name_input_txids)
name_coins += self.wallet.get_spendable_coins(domain, self.config, include_names=True, only_uno_identifiers=name_input_identifiers)
name_coins = self.wallet.get_spendable_coins(name_txid_domain, self.config, include_names=True, only_uno_txids=name_input_txids)
name_coins += self.wallet.get_spendable_coins(name_identifier_domain, self.config, include_names=True, only_uno_identifiers=name_input_identifiers)
tx = self.wallet.make_unsigned_transaction(coins, final_outputs, self.config, fee, change_addr, name_inputs=name_coins)
if locktime != None:
tx.locktime = locktime
Expand Down Expand Up @@ -596,6 +606,39 @@ def name_update(self, identifier, value=None, destination=None, amount=0.0, fee=
tx = self._mktx([], tx_fee, change_addr, domain, nocheck, unsigned, rbf, password, locktime, name_input_identifiers=[identifier_bytes], name_outputs=[(destination, amount, name_op)])
return tx.as_dict()

@command('wpn')
def name_autoregister(self, identifier, value, destination=None, amount=0.0, fee=None, from_addr=None, change_addr=None, nocheck=False, rbf=None, password=None, locktime=None, allow_existing=False):
"""Creates a name_new transaction, broadcasts it, creates a corresponding name_firstupdate transaction, and queues it. """

# TODO: Don't hardcode the 0.005 name_firstupdate fee
new_result = self.name_new(identifier, amount=amount+0.005, fee=fee, from_addr=from_addr, change_addr=change_addr, nocheck=nocheck, rbf=rbf, password=password, locktime=locktime, allow_existing=allow_existing)
new_txid = new_result["txid"]
new_rand = new_result["rand"]
new_tx = new_result["tx"]["hex"]

status, msg = self.broadcast(new_tx)
if not status:
raise Exception("Error broadcasting name pre-registration: " + msg)

# We add the name_new transaction to the wallet explicitly because
# otherwise, the wallet will only learn about the name_new once the
# ElectrumX server sends us a copy of the transaction, which is several
# seconds later, which will cause the wallet to fail to spend the
# name_new when we immediately create the name_firstupdate.
status = self.addtransaction(new_tx)
if not status:
raise Exception("Error adding name pre-registration to wallet")

for o in Transaction(new_tx).outputs():
if o.name_op is not None:
new_addr = o.address
break

firstupdate_result = self.name_firstupdate(identifier, new_rand, new_txid, value, destination=destination, amount=amount, fee=fee, from_addr=new_addr, change_addr=change_addr, nocheck=nocheck, rbf=rbf, password=password, locktime=locktime, allow_early=True)
firstupdate_tx = firstupdate_result["hex"]

self.queuetransaction(firstupdate_tx, 12, trigger_txid=new_txid)

@command('w')
def history(self, year=None, show_addresses=False, show_fiat=False):
"""Wallet history. Returns the transaction history of your wallet."""
Expand Down
2 changes: 1 addition & 1 deletion electrum_nmc/wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,7 @@ def make_unsigned_transaction(self, inputs, outputs, config, fixed_fee=None,
i_max = i

# Avoid index-out-of-range with inputs[0] below
if not inputs:
if not inputs and not name_inputs:
raise NotEnoughFunds()

if fixed_fee is None and config.fee_per_kb() is None:
Expand Down

0 comments on commit 8f37ca1

Please sign in to comment.