def test_heirfund(self, test_params): heirfund_schema = { 'type': 'object', 'properties': { 'result': { 'type': 'string' }, 'hex': { 'type': 'string' }, 'error': { 'type': 'string' } }, 'required': ['result'] } rpc1 = test_params.get('node1').get('rpc') pubkey1 = test_params.get('node1').get('pubkey') amount = '100' name = 'heir' + randomstring(5) inactivitytime = '20' res = rpc1.heirfund(amount, name, pubkey1, inactivitytime, 'testMemo') validate_template(res, heirfund_schema) txid = rpc1.sendrawtransaction(res.get('hex')) mine_and_waitconfirms(txid, rpc1)
def test_channelspayment(self, test_params): channelspayment_schema = { 'type': 'object', 'properties': { 'result': { 'type': 'string' }, 'error': { 'type': 'string' }, 'hex': { 'type': 'string' } }, 'required': ['result'] } rpc1 = test_params.get('node1').get('rpc') pubkey2 = test_params.get('node2').get('pubkey') open_txid = self.channelslist_get(rpc1) if not open_txid: open_txid = self.new_channel(rpc1, pubkey2, '10', '100000').get('open_txid') minpayment = '100000' else: minpayment = rpc1.channelsinfo(open_txid).get( "Denomination (satoshi)") res = rpc1.channelspayment(open_txid, minpayment) validate_template(res, channelspayment_schema) txid = rpc1.sendrawtransaction(res.get('hex')) mine_and_waitconfirms(txid, rpc1)
def test_heirclaim(self, test_params): heirclaim_schema = { 'type': 'object', 'properties': { 'result': { 'type': 'string' }, 'hex': { 'type': 'string' }, 'error': { 'type': 'string' } }, 'required': ['result'] } rpc1 = test_params.get('node1').get('rpc') # create heir plan to claim pubkey1 = test_params.get('node2').get('pubkey') amount = '100' name = 'heir' + randomstring(5) inactivitytime = '120' res = rpc1.heirfund(amount, name, pubkey1, inactivitytime, 'testMemo') fundtxid = rpc1.sendrawtransaction(res.get('hex')) mine_and_waitconfirms(fundtxid, rpc1) # Wait inactivitytime and claim funds time.sleep(int(inactivitytime)) print("\n Sleeping for inactivity time") res = rpc1.heirclaim(amount, fundtxid) validate_template(res, heirclaim_schema) claimtxid = rpc1.sendrawtransaction(res.get('hex')) mine_and_waitconfirms(claimtxid, rpc1)
def dicebet_maincheck(proxy, casino, schema): res = proxy.dicebet(casino.get('name'), casino.get('fundingtxid'), casino.get('minbet'), casino.get('maxodds')) validate_template(res, schema) assert res.get('result') == 'success' bettxid = proxy.sendrawtransaction(res.get('hex')) mine_and_waitconfirms(bettxid, proxy) return bettxid
def diceaddfunds_maincheck(proxy, amount, fundtxid, schema): name = proxy.diceinfo(fundtxid).get('name') res = proxy.diceaddfunds(name, fundtxid, amount) validate_template(res, schema) assert res.get('result') == 'success' addtxid = proxy.sendrawtransaction(res.get('hex')) mine_and_waitconfirms(addtxid, proxy)
def rewardsaddfunding_maincheck(proxy, fundtxid, schema): name = proxy.rewardsinfo(fundtxid).get('name') amount = proxy.rewardsinfo(fundtxid).get( 'mindeposit') # not related to mindeposit here, just to get amount res = proxy.rewardsaddfunding(name, fundtxid, amount) validate_template(res, schema) assert res.get('result') == 'success' txid = proxy.sendrawtransaction(res.get('hex')) mine_and_waitconfirms(txid, proxy)
def create_entropy(proxy, casino): amount = '1' for i in range(100): res = proxy.diceaddfunds(casino.get('name'), casino.get('fundingtxid'), amount) fhex = res.get('hex') proxy.sendrawtransaction(fhex) checkhex = proxy.diceaddfunds(casino.get('name'), casino.get('fundingtxid'), amount).get('hex') tx = proxy.sendrawtransaction(checkhex) mine_and_waitconfirms(tx, proxy)
def test_faucetget_mine(self, test_params): rpc1 = test_params.get('node1').get('rpc') res = rpc1.faucetget() try: fhex = res.get('hex') txid = rpc1.sendrawtransaction(fhex) mine_and_waitconfirms(txid, rpc1) except exc.RpcVerifyRejected: # excepts scenario when pubkey already received faucet funds warnings.warn( RuntimeWarning('Faucet funds were already claimed by pubkey'))
def un_lock_maincheck(proxy, fundtxid, schema): name = proxy.rewardsinfo(fundtxid).get('name') amount = proxy.rewardsinfo(fundtxid).get('mindeposit') res = proxy.rewardslock(name, fundtxid, amount) validate_template(res, schema) assert res.get('result') == 'success' locktxid = proxy.sendrawtransaction(res.get('hex')) mine_and_waitconfirms(locktxid, proxy) print('\nWaiting some time to gain reward for locked funds') time.sleep(10) res = proxy.rewardsunlock(name, fundtxid, locktxid) print(res) validate_template(res, schema) assert res.get('result') == 'error' # reward is less than txfee atm
def new_rewardsplan(proxy, schema=None): name = randomstring(4) amount = '250' apr = '25' mindays = '0' maxdays = '10' mindeposit = '10' res = proxy.rewardscreatefunding(name, amount, apr, mindays, maxdays, mindeposit) if schema: validate_template(res, schema) assert res.get('result') == 'success' txid = proxy.sendrawtransaction(res.get('hex')) mine_and_waitconfirms(txid, proxy) rewardsplan = {'fundingtxid': txid, 'name': name} return rewardsplan
def test_faucetfund(self, test_params): faucetfund_schema = { 'type': 'object', 'properties': { 'result': { 'type': 'string' }, 'hex': { 'type': 'string' }, } } rpc1 = test_params.get('node1').get('rpc') res = rpc1.faucetfund('10') validate_template(res, faucetfund_schema) txid = rpc1.sendrawtransaction(res.get('hex')) mine_and_waitconfirms(txid, rpc1, 1)
def new_channel(proxy: object, destpubkey: str, numpayments: str, paysize: str, schema=None, tokenid=None) -> dict: if tokenid: res = proxy.channelsopen(destpubkey, numpayments, paysize, tokenid) else: res = proxy.channelsopen(destpubkey, numpayments, paysize) if schema: validate_template(res, schema) open_txid = proxy.sendrawtransaction(res.get('hex')) mine_and_waitconfirms(open_txid, proxy) channel = { 'open_txid': open_txid, 'number_of_payments': numpayments, } if tokenid: channel.update({'tokenid': tokenid}) return channel
def new_casino(proxy, schema=None): rpc1 = proxy name = randomstring(4) funds = '777' minbet = '1' maxbet = '77' maxodds = '10' timeoutblocks = '5' res = rpc1.dicefund(name, funds, minbet, maxbet, maxodds, timeoutblocks) if schema: validate_template(res, schema) assert res.get('result') == 'success' txid = rpc1.sendrawtransaction(res.get('hex')) mine_and_waitconfirms(txid, rpc1) casino = { 'fundingtxid': txid, 'name': name, 'minbet': minbet, 'maxbet': maxbet, 'maxodds': maxodds } return casino
def test_channel_drain(self, test_params): rpc1 = test_params.get('node1').get('rpc') pubkey2 = test_params.get('node2').get('pubkey') payments = '3' pay_amount = '100000' channel = TestChannelsCCBase.new_channel(rpc1, pubkey2, payments, pay_amount) # draining channel (3 payment by 100000 satoshies in total to fit full capacity) for i in range(3): res = rpc1.channelspayment(channel.get('open_txid'), '100000') assert res.get('result') == 'success' payment_tx = rpc1.sendrawtransaction(res.get("hex")) mine_and_waitconfirms(payment_tx, rpc1) # last payment should indicate that 0 payments left res = rpc1.channelsinfo( channel.get('open_txid'))['Transactions'][-1]["Payments left"] assert res == 0 # no more payments possible res = rpc1.channelspayment(channel.get('open_txid'), '100000') assert res.get('result') == 'error' assert "error adding CC inputs" in res.get('error')
def test_channels_closenrefund(self, test_params): channelsclose_schema = { 'type': 'object', 'properties': { 'result': { 'type': 'string' }, 'error': { 'type': 'string' }, 'hex': { 'type': 'string' } }, 'required': ['result'] } channelsrefund_schema = { 'type': 'object', 'properties': { 'result': { 'type': 'string' }, 'error': { 'type': 'string' }, 'hex': { 'type': 'string' } }, 'required': ['result'] } rpc1 = test_params.get('node1').get('rpc') pubkey2 = test_params.get('node2').get('pubkey') minpayment = '100000' newchannel = self.new_channel(rpc1, pubkey2, '2', minpayment) # send 1 payment and close channel res = rpc1.channelspayment(newchannel.get('open_txid'), minpayment) txid = rpc1.sendrawtransaction(res.get('hex')) mine_and_waitconfirms(txid, rpc1) res = rpc1.channelsclose(newchannel.get('open_txid')) assert isinstance(res, str) # channelsclose returns only hex on success # validate_template(res, channelsclose_schema) close_txid = rpc1.sendrawtransaction(res) # res.get('hex') mine_and_waitconfirms(close_txid, rpc1) # execute refund res = rpc1.channelsrefund(newchannel.get('open_txid'), close_txid) assert isinstance(res, str) # same to above # validate_template(res, channelsrefund_schema) refund_txid = rpc1.sendrawtransaction(res) # res.get('hex') mine_and_waitconfirms(refund_txid, rpc1)
def test_heiradd(self, test_params): hieradd_schema = { 'type': 'object', 'properties': { 'result': { 'type': 'string' }, 'hex': { 'type': 'string' }, 'error': { 'type': 'string' } }, 'required': ['result'] } rpc1 = test_params.get('node1').get('rpc') amount = '100' try: fundid = rpc1.heirlist()[0] res = rpc1.heiradd(amount, fundid) validate_template(res, hieradd_schema) assert res.get('result') == 'success' txid = rpc1.sendrawtransaction(res.get('hex')) mine_and_waitconfirms(txid, rpc1) except IndexError: print('\nNo heirplan on chain, creating one\n') pubkey1 = test_params.get('node1').get('pubkey') amount = '100' name = 'heir' + randomstring(5) inactivitytime = '20' res = rpc1.heirfund(amount, name, pubkey1, inactivitytime, 'testMemoHeirInfo') txid = rpc1.sendrawtransaction(res.get('hex')) mine_and_waitconfirms(txid, rpc1) fundid = rpc1.heirlist()[0] res = rpc1.heiradd(amount, fundid) validate_template(res, hieradd_schema) assert res.get('result') == 'success' txid = rpc1.sendrawtransaction(res.get('hex')) mine_and_waitconfirms(txid, rpc1)
def test_heir_tokens_flow(self, test_params): rpc1 = test_params.get('node1').get('rpc') pubkey1 = test_params.get('node1').get('pubkey') rpc2 = test_params.get('node2').get('rpc') pubkey2 = test_params.get('node2').get('pubkey') inactivitytime = 70 # ideally, should be a bit more than blocktime amount = 100000000 plan_name = 'heir' + randomstring(5) comment = 'HeirFlowTest' + randomstring(5) token_name = 'token' + randomstring(5) # Create on-chain tokens res = rpc1.tokencreate(token_name, '1', 'heirCCTest') tokentx = rpc1.sendrawtransaction(res.get('hex')) mine_and_waitconfirms(tokentx, rpc1) res = rpc1.tokenbalance(tokentx, pubkey1)['balance'] assert res == amount # validate init tokenbalance res = rpc1.heirfund(str(amount), plan_name, pubkey2, str(inactivitytime), comment, tokentx) fundtx = rpc1.sendrawtransaction(res.get('hex')) mine_and_waitconfirms(fundtx, rpc1) time.sleep(5) # Check plan availability in heirlist res = rpc1.heirlist() assert fundtx in res # Check plan info res = rpc1.heirinfo(fundtx) assert res.get('result') == 'success' # check here stuff assert res['fundingtxid'] == fundtx assert res['name'] == plan_name assert res['owner'] == pubkey1 assert res['heir'] == pubkey2 assert res['memo'] == comment assert res['lifetime'] == str(amount) assert res['tokenid'] == tokentx assert res['type'] == 'tokens' assert res['InactivityTimeSetting'] == str(inactivitytime) # Check Heir spending allowed after inactivity time print("\n Sleeping for inactivity time") time.sleep(inactivitytime + 1) wait_blocks(rpc1, 2) check_synced(rpc1, rpc2) res = rpc1.heirinfo(fundtx) assert res['lifetime'] == str(amount) assert res['available'] == str(amount) assert res['IsHeirSpendingAllowed'] == 'true' # Claim all available funds from hier node res = rpc2.heirclaim(str(amount), fundtx) assert res.get('result') == 'success' claimtx = rpc2.sendrawtransaction(res.get('hex')) mine_and_waitconfirms(claimtx, rpc2) time.sleep(5) # Check claim success # Wait sync wait_blocks(rpc1, 1) check_synced(rpc1, rpc2) res = rpc1.heirinfo(fundtx) assert res['lifetime'] == str(amount) assert res['available'] == '0' res = rpc2.heirinfo(fundtx) assert res['lifetime'] == str(amount) assert res['available'] == '0' # Check heir balance after claim res = rpc2.tokenbalance(tokentx, pubkey2)['balance'] assert res == amount
def test_heir_flow(self, test_params): # Check basic heirCC flow from fund to claim # Create valid heir plan rpc1 = test_params.get('node1').get('rpc') pubkey1 = test_params.get('node1').get('pubkey') rpc2 = test_params.get('node2').get('rpc') pubkey2 = test_params.get('node2').get('pubkey') inactivitytime = 70 # ideally, should be a bit more than blocktime amount = 777 plan_name = 'heir' + randomstring(5) comment = 'HeirFlowTest' + randomstring(5) res = rpc1.heirfund(str(amount), plan_name, pubkey2, str(inactivitytime), comment) fundtx = rpc1.sendrawtransaction(res.get('hex')) mine_and_waitconfirms(fundtx, rpc1) time.sleep(5) # Check plan availability in heirlist res = rpc1.heirlist() assert fundtx in res # Check plan info res = rpc1.heirinfo(fundtx) assert res.get('result') == 'success' # check here stuff assert res['fundingtxid'] == fundtx assert res['name'] == plan_name assert res['owner'] == pubkey1 assert res['heir'] == pubkey2 assert res['memo'] == comment assert res['lifetime'] == str(amount) + '.00000000' assert res['type'] == "coins" assert res['InactivityTimeSetting'] == str(inactivitytime) # Check Heir spending allowed after inactivity time print("\n Sleeping for inactivity time") time.sleep(inactivitytime + 1) wait_blocks(rpc1, 2) check_synced( rpc1, rpc2) # prevents issues when inactivity time =< block time res = rpc1.heirinfo(fundtx) assert res['lifetime'] == str(amount) + '.00000000' assert res['available'] == str(amount) + '.00000000' assert res['IsHeirSpendingAllowed'] == 'true' # Claim all available funds from hier node res = rpc2.heirclaim(str(amount), fundtx) assert res.get('result') == 'success' claimtx = rpc2.sendrawtransaction(res.get('hex')) mine_and_waitconfirms(claimtx, rpc2) time.sleep(5) # Check claim success # Wait sync wait_blocks(rpc1, 2) check_synced(rpc1, rpc2) res = rpc1.heirinfo(fundtx) assert res['lifetime'] == str(amount) + '.00000000' assert res['available'] == '0.00000000' res = rpc2.heirinfo(fundtx) assert res['lifetime'] == str(amount) + '.00000000' assert res['available'] == '0.00000000'
def test_heirinfo(self, test_params): heirinfo_schema = { 'type': 'object', 'properties': { 'name': { 'type': 'string' }, 'fundingtxid': { 'type': 'string' }, 'owner': { 'type': 'string' }, 'tokenid': { 'type': 'string' }, 'heir': { 'type': 'string' }, 'type': { 'type': 'string' }, 'lifetime': { 'type': 'string' }, 'available': { 'type': 'string' }, 'OwnerRemainderTokens': { 'type': 'string' }, 'InactivityTimeSetting': { 'type': 'string' }, 'IsHeirSpendingAllowed': { 'type': 'string' }, 'memo': { 'type': 'string' }, 'result': { 'type': 'string' }, 'error': { 'type': 'string' } }, 'required': ['result'] } rpc1 = test_params.get('node1').get('rpc') try: fundid = rpc1.heirlist()[0] res = rpc1.heirinfo(fundid) validate_template(res, heirinfo_schema) assert res.get('result') == 'success' except IndexError: print('\nNo heirplan on chain, creating one\n') pubkey1 = test_params.get('node1').get('pubkey') amount = '100' name = 'heir' + randomstring(5) inactivitytime = '20' res = rpc1.heirfund(amount, name, pubkey1, inactivitytime, 'testMemoHeirInfo') txid = rpc1.sendrawtransaction(res.get('hex')) mine_and_waitconfirms(txid, rpc1) fundid = rpc1.heirlist()[0] res = rpc1.heirinfo(fundid) validate_template(res, heirinfo_schema) assert res.get('result') == 'success'
def test_channels_flow(self, test_params): rpc1 = test_params.get('node1').get('rpc') rpc2 = test_params.get('node2').get('rpc') pubkey2 = test_params.get('node2').get('pubkey') addr1 = test_params.get('node1').get('address') payments = '10' pay_amount = '100000' channel = TestChannelsCCBase.new_channel(rpc1, pubkey2, payments, pay_amount) # trying to make wrong denomination channel payment res = rpc1.channelspayment(channel.get('open_txid'), '199000') assert res.get('result') == 'error' # trying to make 0 channel payment res = rpc1.channelspayment(channel.get('open_txid'), '0') assert res.get('result') == 'error' # trying to make negative channel payment res = rpc1.channelspayment(channel.get('open_txid'), '-100000') assert res.get('result') == 'error' # lets try payment with x2 amount to ensure that counters works correct res = rpc1.channelspayment(channel.get('open_txid'), '200000') assert res.get('result') == 'success' payment_tx_id = rpc1.sendrawtransaction(res.get('hex')) mine_and_waitconfirms(payment_tx_id, rpc1) assert isinstance(payment_tx_id, str) res = rpc1.channelsinfo(channel.get('open_txid')) assert res['Transactions'][-1]['Payment'] == payment_tx_id assert res['Transactions'][-1]["Number of payments"] == 2 assert res['Transactions'][-1]["Payments left"] == 8 # 10 initial - 2 # check if payment value really transferred raw_transaction = rpc1.getrawtransaction(payment_tx_id, 1) res = raw_transaction['vout'][3]['valueSat'] assert res == 200000 res = rpc2.validateaddress(raw_transaction['vout'][3]['scriptPubKey'] ['addresses'][0])['ismine'] assert res # trying to initiate channels payment from node B without any secret res = rpc2.channelspayment(channel.get('open_txid'), "100000") assert res.get('result') == 'error' assert "invalid secret" in res.get('error') # trying to initiate channels payment from node B with secret from previous payment secret = rpc2.channelsinfo( channel.get('open_txid'))['Transactions'][-1]['Secret'] res = rpc2.channelspayment(channel.get('open_txid'), "100000", secret) assert res.get('result') == 'error' assert "invalid secret" in res.get('error') # executing channel close res = rpc1.channelsclose(channel.get('open_txid')) assert isinstance(res, str) close_txid = rpc1.sendrawtransaction(res) mine_and_waitconfirms(close_txid, rpc1) # now in channelinfo closed flag should appear res = rpc1.channelsinfo(channel.get('open_txid')) assert res['Transactions'][-1]['Close'] == close_txid # executing channel refund res = rpc1.channelsrefund(channel.get('open_txid'), close_txid) assert isinstance(res, str) refund_txid = rpc1.sendrawtransaction(res) mine_and_waitconfirms(refund_txid, rpc1) # checking if it refunded to opener address raw = rpc1.getrawtransaction(refund_txid, 1) res = raw['vout'] values = [] for vout in res: # find all txs to node1 address try: if vout.get('scriptPubKey').get('addresses')[0] == addr1 \ and "OP_CHECKSIG" in vout.get('scriptPubKey').get('asm'): values.append(vout.get('valueSat')) except TypeError: # to prevent fails on OP_RETURN // nulldata vout pass assert 800000 in values # 10 - 2 payments, worth of 100000 satoshi each