This was motivated by the Invalid parameter, duplicated address test.
Credit to @laanwj for multidict implementation.
72 | + assert_raises_rpc_error(-3, "Expected type object", self.nodes[0].createrawtransaction, [], 'foo') 73 | + assert_raises_rpc_error(-8, "Data must be hexadecimal string", self.nodes[0].createrawtransaction, [], {'data': 'foo'}) 74 | + assert_raises_rpc_error(-5, "Invalid Bitcoin address", self.nodes[0].createrawtransaction, [], {'foo': 0}) 75 | + assert_raises_rpc_error(-3, "Invalid amount", self.nodes[0].createrawtransaction, [], {address: 'foo'}) 76 | + assert_raises_rpc_error(-3, "Amount out of range", self.nodes[0].createrawtransaction, [], {address: -1}) 77 | + assert_raises_rpc_error(-8, "Invalid parameter, duplicated address: %s" % address, self.nodes[0].createrawtransaction, [], multidict([(address, 1), (address, 1)]))
So there is already a check for duplicated address? That's great!
Yes, createrawtransaction and sendmany RPC's check for duplicated address.
Indeed! I hadn't expected a check here because passing this is tricky in JSON object format.
utACK 0df137b
utACK 0df137b8c719a904c792240a0e373ca38c334443
14 | @@ -15,6 +15,16 @@ 15 | from test_framework.test_framework import BitcoinTestFramework 16 | from test_framework.util import * 17 | 18 | + 19 | +class multidict(dict):
Can you add a comment for this please? Something like:
"""Dictionary that allows duplicate keys.
Constructed with a list of (key, value) tuples. When dumped by the json module, will output invalid json with repeated keys, eg:
>>> json.dumps(multidict([(1,2),(1,2)])
'{"1": 2, "1": 2}'
Used to test calls to rpc methods with invalid repeated keys in the json object."""
Yeah submitting JSON objects in deterministic order and with potentially duplicated keys is the only thing it's good for, it's not quite a traditional multidict implementation.
Done.
48 | @@ -39,6 +49,41 @@ def run_test(self): 49 | self.nodes[0].generate(5) 50 | self.sync_all() 51 | 52 | + # Test `createrawtransaction` required parameters 53 | + assert_raises_rpc_error(-1, "createrawtransaction", self.nodes[0].createrawtransaction) 54 | + assert_raises_rpc_error(-1, "createrawtransaction", self.nodes[0].createrawtransaction, []) 55 | + 56 | + # Test `createrawtransaction` invalid extra parameters 57 | + assert_raises_rpc_error(-1, "createrawtransaction", self.nodes[0].createrawtransaction, [], {}, 0, False, 'foo')
nit: My personal style preference is to use named args when passing unnamed parameters. Not sure what others think.
In this case I'm not sure, because that will throw Unknown named parameter. But for other cases you mean?
assert_raises_rpc_error(-1, "createrawtransaction", self.nodes[0].createrawtransaction, inputs=[], outputs={}, locktime=0, replaceable=False)
Ah, right. Won't work in this case.
Concept ACK.
According to what others reviewed, only change should be adding a comment, so trivial to re-ACK. (ping @jnewbery )
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
utACK 88af5028ad3de71c8b86b50cb1c6bdd57c1ba6e5
-----BEGIN PGP SIGNATURE-----
iQIcBAEBCgAGBQJaMUWGAAoJENLqSFDnUoslcNUP/Ar1eK4SOmsoA/SvpfhbpwHE
4jMFEqkKhef4F1AYQIDaJAvh4HKUpyTX2o8IA9XRvrHLjTJz0vFMd/jMMuKbnB7M
6Ie1mmykyNRmFg3qvYJDa4XD6FdLEpR7Nwk4YYlAJemBm9+G24vAY1jL6r3Devle
g6z90/2iYBYOam6ihkhfd7luRMEFKcIi8fjIVsPXK+g8TLOlS4M9wTjRqQ+6RvC4
npkANcAsaHcF3f3d3VOggij3TrEUq40fiir5dtW/ViU27fT03YFZKJKfuSRjFxCf
NRGL1IDlgw4HFKnBLdC/Boq25Lx3f5w7PDUBU4C60YL/j6n5CehxjA3TAOHzDvh+
l2wGjk3y9TGTnrknZGmwmP7GRbM1a3bVPN0UsZoaKMBzwGnAe+UMpf/rkR+jxjhO
Ge73jZyowtpv0hPJotVb89kGcWCBaWWOXE6Btr1t8bc/NJB7UYJdjh5/uCHRpeOn
VeZOZAxS839xUphtgf9yaBF/sjM7lLO/TFIg5OTZBQd/Rs1aV8wijy/P3IeSn+zd
ZFAmBcqUYep9JQorRDNHzav4a0KIeL10kEJ3BYWezmJSPIkpdXJHX+f/vS8sbkNA
FMyJi1htT2dwffLal6YleHHEOmpkO2RF0WSzsV0Hs8f3tEImu/5Tgk47gTxo5Nvy
FqUd3vncrAM1cc5IyU4G
=IryX
-----END PGP SIGNATURE-----
Tested ACK 88af5028ad3de71c8b86b50cb1c6bdd57c1ba6e5. Comment looks good :slightly_smiling_face: