Skip to content

Commit

Permalink
Whitelist P2SH addresses via createkycfile RPC (#248)
Browse files Browse the repository at this point in the history
* Whitelist P2SH addresses

* Whitelist P2PKH or P2SH addresses

* Reduce registeraddress tx size for contactintx=1

* Revert "Reduce registeraddress tx size for contactintx=1"

This reverts commit 837ebd5.

* Correct onboard_cit.py

* Whitelist P2SH addresses

* Correct error in whitelist.h

* Registeraddress script version 1

* Dont include pubkeys etc. in registeraddress TX if contractintx=0

* Test for P2PKH and P2SH address whitelisting

* Added test for whitelisting witness address.

* Revert dockerfile change.
  • Loading branch information
lawlawlaw authored and tomt1664 committed Oct 30, 2019
1 parent be8600c commit d062fd0
Show file tree
Hide file tree
Showing 28 changed files with 1,886 additions and 448 deletions.
3 changes: 1 addition & 2 deletions qa/pull-tester/rpc-tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,8 @@
'policytransactions.py',
'onboard.py',
'onboard_cit.py',
'onboardencrypted.py',
'onboardmanual.py',
'onboardmanualencrypted.py',
'onboardmanual_cit.py',
'fixedfee.py',
# Accounts not supported
#'wallet-accounts.py',
Expand Down
6 changes: 3 additions & 3 deletions qa/rpc-tests/onboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -417,23 +417,23 @@ def run_test (self):
multiAddress2=self.nodes[1].createmultisig(2,[clientAddress1['pubkey'],clientAddress2['pubkey'],clientAddress4['pubkey']])
self.nodes[1].addmultitowhitelist(multiAddress2['address'],[clientAddress1['derivedpubkey'],clientAddress2['derivedpubkey'],clientAddress3['derivedpubkey']],2)
except JSONRPCException as e:
assert("add_multisig_whitelist: address does not derive from public keys when tweaked with contract hash" in e.error['message'])
assert("TryValid: address does not derive from public keys when tweaked with contract hash" in e.error['message'])
else:
raise AssertionError("P2SH multisig with a different third pubkey has been validated and accepted to the whitelist.")

try:
multiAddress2=self.nodes[1].createmultisig(2,[clientAddress1['pubkey'],clientAddress2['pubkey'],clientAddress3['derivedpubkey']])
self.nodes[1].addmultitowhitelist(multiAddress2['address'],[clientAddress1['derivedpubkey'],clientAddress2['derivedpubkey'],clientAddress3['derivedpubkey']],2)
except JSONRPCException as e:
assert("add_multisig_whitelist: address does not derive from public keys when tweaked with contract hash" in e.error['message'])
assert("TryValid: address does not derive from public keys when tweaked with contract hash" in e.error['message'])
else:
raise AssertionError("P2SH multisig with an untweaked third pubkey has been validated and accepted to the whitelist.")

try:
multiAddress2=self.nodes[1].createmultisig(2,[clientAddress1['pubkey'],clientAddress2['pubkey'],clientAddress3['pubkey'],clientAddress4['pubkey']])
self.nodes[1].addmultitowhitelist(multiAddress2['address'],[clientAddress1['derivedpubkey'],clientAddress2['derivedpubkey'],clientAddress3['derivedpubkey']],2)
except JSONRPCException as e:
assert("add_multisig_whitelist: address does not derive from public keys when tweaked with contract hash" in e.error['message'])
assert("TryValid: address does not derive from public keys when tweaked with contract hash" in e.error['message'])
else:
raise AssertionError("P2SH multisig with more pubkeys in redeem script than rpc has been validated and accepted to the whitelist.")

Expand Down
10 changes: 10 additions & 0 deletions qa/rpc-tests/onboard_cit.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,11 +253,18 @@ def run_test (self):
#Onboard node0
kycfile0=self.initfile(os.path.join(self.options.tmpdir,"kycfile0.dat"))
userOnboardPubKey=self.nodes[0].dumpkycfile(kycfile0)
kycfile0_plain=self.initfile(os.path.join(self.options.tmpdir,"kycfile0_plain.dat"))
print("onboard node 0 \n")
print("read kycfile0 node 0 \n")
self.nodes[0].readkycfile(kycfile0, kycfile0_plain)
self.nodes[0].onboarduser(kycfile0)
print("generate block \n")
self.nodes[0].generate(101)
print("sync all \n")
self.sync_all()

wl1file=self.initfile(os.path.join(self.options.tmpdir,"wl1.dat"))
print("dump node1 wl \n")
self.nodes[1].dumpwhitelist(wl1file)
nlines=self.linecount(wl1file)
nlines_empty=self.linecount(wl1file_empty)
Expand Down Expand Up @@ -434,6 +441,9 @@ def run_test (self):
except JSONRPCException as e:
assert("Not implemented for unencrypted whitelist" in e.error['message'])


print("Multisig address: ")
print(multiAddress1['address'])
#Adding the created p2sh to the whitelist via addmultitowhitelist rpc
try:
self.nodes[1].addmultitowhitelist(multiAddress1['address'],[clientAddress1['derivedpubkey'],clientAddress2['derivedpubkey'],clientAddress3['derivedpubkey']],2,"")
Expand Down
6 changes: 5 additions & 1 deletion qa/rpc-tests/onboardencrypted.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,11 @@ def run_test (self):
wl1file=self.initfile(os.path.join(self.options.tmpdir,"wl1.dat"))
self.nodes[1].dumpwhitelist(wl1file)
nadd=100
saveres=self.nodes[1].sendaddtowhitelisttx(nadd,"CBT")
try:
saveres=self.nodes[1].sendaddtowhitelisttx(nadd,"CBT")
except Exception as e:
print(e.error['message'])
assert False
time.sleep(5)
self.nodes[0].generate(101)
self.sync_all()
Expand Down
143 changes: 136 additions & 7 deletions qa/rpc-tests/onboardmanual.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,16 @@ def run_test (self):
self.nodes[0].readwhitelist("keys.main")
os.remove("keys.main")

#Try and create kycfile when no KYC pub keys available
kycfile_test="kycfile_test.dat"
try:
userOnboardPubKey=self.nodes[1].createkycfile(kycfile_test,[], []);
#expect an exception
assert(False)
except JSONRPCException as e:
message=e.error['message']
assert('No unassigned KYC public keys available.' in message)

#Register a KYC public key
policyaddr=self.nodes[0].getnewaddress()
assert(self.nodes[0].querywhitelist(policyaddr))
Expand Down Expand Up @@ -135,13 +145,25 @@ def run_test (self):
self.sync_all()

#Onboard node1
kycfile="kycfile.dat"
kycfile_normal="kycfile_normal.dat"
kycfile_multisig="kycfile_multisig.dat"
kycfile_empty="kycfile_empty.dat"
kycfile=os.path.join(self.options.tmpdir,"kycfile.dat")
kycfile_normal=os.path.join(self.options.tmpdir,"kycfile_normal.dat")
kycfile_normal_plain=os.path.join(self.options.tmpdir,"kycfile_normal_plain.dat")
kycfile_multisig=os.path.join(self.options.tmpdir,"kycfile_multisig.dat")
kycfile_multisig_plain=os.path.join(self.options.tmpdir,"kycfile_multisig_plain.dat")
kycfile_empty=os.path.join(self.options.tmpdir,"kycfile_empty.dat")
#userOnboardPubKey=self.nodes[1].dumpkycfile(kycfile)

#Create empty file and checck validity

#Test invalid parameters
try:
userOnboardPubKey=self.nodes[1].createkycfile(kycfile_test,None, None);
#expect an exception
assert(False)
except JSONRPCException as e:
message=e.error['message']
assert("Invalid parameters, arguments 2 and 3 can't both be null" in message)

#Create empty file and check validity
try:
userOnboardPubKey=self.nodes[1].createkycfile(kycfile_empty,[], []);
except JSONRPCException as e:
Expand All @@ -159,11 +181,15 @@ def run_test (self):
onboardAddress1=self.nodes[1].validateaddress(self.nodes[1].getnewaddress())
onboardAddress2=self.nodes[1].validateaddress(self.nodes[1].getnewaddress())
try:
userOnboardPubKey=self.nodes[1].createkycfile(kycfile_normal, [{"address":onboardAddress1['address'],"pubkey":onboardAddress1['derivedpubkey']},{"address":onboardAddress2['address'],"pubkey":onboardAddress2['derivedpubkey']}], []);
userOnboardPubKey=self.nodes[1].createkycfile(kycfile_normal, [{"address":onboardAddress1['address'],"pubkey":onboardAddress1['derivedpubkey']},{"address":onboardAddress2['address'],
"pubkey":onboardAddress2['derivedpubkey']}],
[]);
except JSONRPCException as e:
print(e.error['message'])
assert(False)

self.nodes[0].readkycfile(kycfile_normal, kycfile_normal_plain)

valkyc=self.nodes[0].validatekycfile(kycfile_normal)
print(valkyc)
assert(valkyc["iswhitelisted"] == False)
Expand All @@ -172,6 +198,43 @@ def run_test (self):
self.nodes[0].generate(101)
self.sync_all()

#Test invalid parameters
try:
userOnboardPubKey=self.nodes[1].createkycfile(kycfile_test, [{"address":onboardAddress1['address']},{"address":onboardAddress2['address'],"pubkey":onboardAddress2['derivedpubkey']}], []);
#expect an exception
assert(False)
except JSONRPCException as e:
message=e.error['message']
print(message)
assert("Pubkey missing in pubkeylist" in message)

try:
userOnboardPubKey=self.nodes[1].createkycfile(kycfile_test, [{"pubkey":onboardAddress1['derivedpubk\
ey']},{"address":onboardAddress2['address'],"pubkey":onboardAddress2['derivedpubkey']}], []);
#expect an exception
assert(False)
except JSONRPCException as e:
message=e.error['message']
assert("Address missing in pubkeylist" in message)

try:
userOnboardPubKey=self.nodes[1].createkycfile(kycfile_test, [{"address":"myInvalidAddress","pubkey":onboardAddress1['derivedpubk\
ey']},{"address":onboardAddress2['address'],"pubkey":onboardAddress2['derivedpubkey']}], []);
#expect an exception
assert(False)
except JSONRPCException as e:
message=e.error['message']
assert("Invalid address in pubkeylist: myInvalidAddress" in message)

try:
userOnboardPubKey=self.nodes[1].createkycfile(kycfile_test, [{"address":onboardAddress1['address'],"pubkey":"myInvalidPubKey"},{"address":onboardAddress2['address'],
"pubkey":onboardAddress2['derivedpubkey']}], []);
#expect an exception
assert(False)
except JSONRPCException as e:
message=e.error['message']
assert("Invalid pubkey in pubkeylist: myInvalidPubKey" in message)

balance_1=self.nodes[0].getwalletinfo()["balance"]["WHITELIST"]
try:
self.nodes[0].onboarduser(kycfile_normal)
Expand All @@ -197,11 +260,12 @@ def run_test (self):
untweakedPubkeys2=[onboardAddress2['derivedpubkey'],onboardAddress3['derivedpubkey'],onboardAddress4['derivedpubkey']]
untweakedPubkeys3=[onboardAddress3['derivedpubkey'],onboardAddress4['derivedpubkey']]
try:
userOnboardPubKey=self.nodes[1].createkycfile(kycfile_multisig, [], [{"nmultisig":2,"pubkeys":untweakedPubkeys},{"nmultisig":2,"pubkeys":untweakedPubkeys2},{"nmultisig":2,"pubkeys":untweakedPubkeys3}]);
createResult=self.nodes[1].createkycfile(kycfile_multisig, [], [{"nmultisig":2,"pubkeys":untweakedPubkeys},{"nmultisig":2,"pubkeys":untweakedPubkeys2},{"nmultisig":2,"pubkeys":untweakedPubkeys3}]);
except JSONRPCException as e:
print(e.error['message'])
assert(False)

self.nodes[0].readkycfile(kycfile_multisig, kycfile_multisig_plain)
valkyc=self.nodes[0].validatekycfile(kycfile_multisig)
print(valkyc)
assert(valkyc["iswhitelisted"] == False)
Expand All @@ -216,12 +280,77 @@ def run_test (self):
self.nodes[0].generate(101)
self.sync_all()


valkyc=self.nodes[0].validatekycfile(kycfile_multisig)
print(valkyc)

print("querying whitelist for addresses...")
for addr in valkyc["addresses"]:
print(addr)
assert(self.nodes[0].querywhitelist(addr))

assert(valkyc["iswhitelisted"] == True)

os.remove(kycfile_multisig)


#Test invalid parameters
try:
userOnboardPubKey=self.nodes[1].createkycfile(kycfile_test, [], [{"pubkeys":untweakedPubkeys},{"nmultisig":2,"pubkeys":untweakedPubkeys2},{"nmultisig":2,"pubkeys":untweakedPubkeys3}]);
#expect an exception
assert(False)
except JSONRPCException as e:
message=e.error['message']
print(message)
assert("nmultisig missing in multisiglist" in message)

try:
userOnboardPubKey=self.nodes[1].createkycfile(kycfile_test, [], [{"nmultisig":2},{"nmultisig":2,"pubkeys":untweakedPubkeys2},{"nmultisig":2,"pubkeys":untweakedPubkeys3}]);
#expect an exception
assert(False)
except JSONRPCException as e:
message=e.error['message']
print(message)
assert("pubkeys missing in multisiglist" in message)

try:
userOnboardPubKey=self.nodes[1].createkycfile(kycfile_test, [], [{"nmultisig":2.1,"pubkeys":untweakedPubkeys},{"nmultisig":2,"pubkeys":untweakedPubkeys2},{"nmultisig":2,"pubkeys":untweakedPubkeys3}]);
#expect an exception
assert(False)
except JSONRPCException as e:
message=e.error['message']
print(message)
assert("JSON integer out of range" in message)

try:
userOnboardPubKey=self.nodes[1].createkycfile(kycfile_test, [], [{"nmultisig":16,"pubkeys":untweakedPubkeys},{"nmultisig":2,"pubkeys":untweakedPubkeys2},{"nmultisig":2,"pubkeys":untweakedPubkeys3}]);
#expect an exception
assert(False)
except JSONRPCException as e:
message=e.error['message']
print(message)
assert("nmultisig must be an integer between 1 and 15")

try:
userOnboardPubKey=self.nodes[1].createkycfile(kycfile_test, [], [{"nmultisig":0,"pubkeys":untweakedPubkeys},{"nmultisig":2,"pubkeys":untweakedPubkeys2},{"nmultisig":2,"pubkeys":untweakedPubkeys3}]);
#expect an exception
assert(False)
except JSONRPCException as e:
message=e.error['message']
assert("nmultisig must be an integer between 1 and 15")


invalidPubkeys=['myInvalidPubKey',onboardAddress2['derivedpubkey'],onboardAddress3['derivedpubkey']]

try:
userOnboardPubKey=self.nodes[1].createkycfile(kycfile_test, [], [{"nmultisig":2,"pubkeys":invalidPubkeys},{"nmultisig":2,"pubkeys":untweakedPubkeys2},{"nmultisig":2,"pubkeys":untweakedPubkeys3}]);
#expect an exception
assert(False)
except JSONRPCException as e:
message=e.error['message']
print(message)
assert("Invalid pubkey in multisiglist: " in message)

onboardAddress1=self.nodes[1].validateaddress(self.nodes[1].getnewaddress())
onboardAddress2=self.nodes[1].validateaddress(self.nodes[1].getnewaddress())
onboardAddress3=self.nodes[1].validateaddress(self.nodes[1].getnewaddress())
Expand Down
Loading

0 comments on commit d062fd0

Please sign in to comment.