forked from namecoin/namecoin-core
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathnames.py
138 lines (105 loc) · 4.46 KB
/
names.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#!/usr/bin/env python3
# Copyright (c) 2014-2019 Daniel Kraft
# Distributed under the MIT/X11 software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
# General code for Doichain tests.
from .test_framework import BitcoinTestFramework
from .util import assert_equal
class NameTestFramework (BitcoinTestFramework):
def setup_name_test (self, args = [[]] * 4):
self.num_nodes = len (args)
self.extra_args = args
self.node_groups = None
# Enable mocktime based on the value for the cached blockchain from
# test_framework.py. This is needed to get us out of IBD.
self.mocktime = 1388534400 + (201 * 10 * 60)
def firstupdateName (self, ind, name, newData, value,
opt = None, allowActive = False):
"""
Utility routine to perform a name_firstupdate command. The rand
and txid are taken from 'newData', as it is returned by name_new.
"""
node = self.nodes[ind]
if allowActive:
if opt is None:
opt = {}
return node.name_firstupdate (name, newData[1], newData[0],
value, opt, True)
if opt is None:
return node.name_firstupdate (name, newData[1], newData[0], value)
return node.name_firstupdate (name, newData[1], newData[0], value, opt)
def checkName (self, ind, name, value, expiresIn, expired):
"""
Query a name with name_show and check that certain data fields
match the expectations. Returns the full JSON object.
"""
data = self.nodes[ind].name_show (name)
self.checkNameData (data, name, value, expiresIn, expired)
return data
def checkNameData (self, data, name, value, expiresIn, expired):
"""
Check a name info object against expected data.
"""
assert_equal (data['name'], name)
assert_equal (data['value'], value)
if (expiresIn is not None):
assert_equal (data['expires_in'], expiresIn)
assert isinstance (data['expired'], bool)
assert_equal (data['expired'], expired)
def checkNameHistory (self, ind, name, values):
"""
Query for the name_history of 'name' and check that its historical
values, in order of increasing height, are the ones in 'values'.
"""
data = self.nodes[ind].name_history (name)
valuesFound = []
for e in data:
assert_equal (e['name'], name)
valuesFound.append (e['value'])
assert_equal (valuesFound, values)
def rawtxOutputIndex (self, ind, txhex, addr):
"""
Returns the index of the tx output in the given raw transaction that
is sent to the given address.
This is useful for building raw transactions with namerawtransaction.
"""
tx = self.nodes[ind].decoderawtransaction (txhex)
for i, vout in enumerate (tx['vout']):
if addr in vout['scriptPubKey']['addresses']:
return i
return None
def atomicTrade (self, name, value, price, fee, nameFrom, nameTo):
"""
Perform an atomic name trade, sending 'name' from the first to the
second node (referenced by their index). Also send 'price' (we assume
that it is less than each unspent output in 'listunspent') the
other way round. Returned is the txid.
"""
addrA = self.nodes[nameFrom].getnewaddress ()
addrB = self.nodes[nameTo].getnewaddress ()
addrChange = self.nodes[nameTo].getrawchangeaddress ()
inputs = []
unspents = self.nodes[nameTo].listunspent ()
txin = None
for u in unspents:
if u['amount'] >= price + fee:
txin = u
break
assert txin is not None
change = txin['amount'] - price - fee
inputs.append ({"txid": txin['txid'], "vout": txin['vout']})
data = self.nodes[nameFrom].name_show (name)
nameTxo = self.nodes[nameFrom].gettxout (data['txid'], data['vout'])
nameAmount = nameTxo['value']
inputs.append ({"txid": data['txid'], "vout": data['vout']})
outputs = {addrA: price, addrChange: change, addrB: nameAmount}
tx = self.nodes[nameFrom].createrawtransaction (inputs, outputs)
nameInd = self.rawtxOutputIndex (nameFrom, tx, addrB)
nameOp = {"op": "name_update", "name": name, "value": value}
tx = self.nodes[nameFrom].namerawtransaction (tx, nameInd, nameOp)
signed = self.nodes[nameFrom].signrawtransactionwithwallet (tx['hex'])
assert not signed['complete']
signed = self.nodes[nameTo].signrawtransactionwithwallet (signed['hex'])
assert signed['complete']
tx = signed['hex']
return self.nodes[nameFrom].sendrawtransaction (tx)