Skip to content

Commit 2d8bce3

Browse files
authored
Merge pull request #70 from cryptape/v119
v119
2 parents 4656566 + a897637 commit 2d8bce3

35 files changed

+867
-28
lines changed

.github/workflows/python-app.yml renamed to .github/workflows/ci_integration_tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# This workflow will install Python dependencies, run tests and lint with a single version of Python
22
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
33

4-
name: Python application
4+
name: ci_integration_tests
55

66
on:
77
push:
@@ -15,7 +15,7 @@ permissions:
1515
jobs:
1616
build:
1717

18-
runs-on: ubuntu-latest
18+
runs-on: ubuntu-22.04
1919

2020
steps:
2121
- uses: actions/checkout@v3

download.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"0.116.1",
2323
"0.117.0",
2424
"0.118.0",
25+
"0.119.0",
2526
] # Replace with your versions
2627

2728
DOWNLOAD_DIR = "download"

framework/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
# contract
4949
ALWAYS_SUCCESS_CONTRACT_PATH = f"{get_project_root()}/source/contract/always_success"
5050
SPAWN_CONTRACT_PATH = f"{get_project_root()}/source/contract/test_cases/spawn_demo"
51+
UDT_CONTRACT_PATH = f"{get_project_root()}/source/contract/XUDTType"
5152

5253

5354
def get_tmp_path():

framework/fiber_rpc.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import time
2+
3+
import requests
4+
5+
import json
6+
7+
8+
class FiberRPCClient:
9+
def __init__(self, url):
10+
self.url = url
11+
12+
def send_btc(self, btc_pay_req):
13+
return self.call("send_btc", [btc_pay_req])
14+
15+
def open_channel(self, param):
16+
"""
17+
curl --location 'http://127.0.0.1:8227' --header 'Content-Type: application/json' --data '{
18+
"id": 42,
19+
"jsonrpc": "2.0",
20+
"method": "open_channel",
21+
"params": [
22+
{
23+
"peer_id": "QmaQSn11jsAXWLhjHtZ9EVbauD88sCmYzty3GmYcoVWP2j",
24+
"funding_amount": "0x2e90edd000"
25+
}
26+
]
27+
}'
28+
{"jsonrpc": "2.0", "result": {"temporary_channel_id": "0xbf1b507e730b08024180ed9cb5bb3655606d3a89e94476033cf34d206d352751"}, "id": 42}
29+
"""
30+
return self.call("open_channel", [param])
31+
32+
def list_channels(self, param):
33+
"""
34+
curl --location 'http://127.0.0.1:8227' --header 'Content-Type: application/json' --data '{
35+
"id": 42,
36+
"jsonrpc": "2.0",
37+
"method": "list_channels",
38+
"params": [
39+
{
40+
"peer_id": "QmaQSn11jsAXWLhjHtZ9EVbauD88sCmYzty3GmYcoVWP2j"
41+
}
42+
]
43+
}'
44+
{"jsonrpc": "2.0", "result": {"channels": [{"channel_id": "0x2329a1ced09d0c9eff46068ac939596bb657a984b1d6385db563f2de837b8879", "peer_id": "QmaQSn11jsAXWLhjHtZ9EVbauD88sCmYzty3GmYcoVWP2j", "state": {"state_name": "NEGOTIATING_FUNDING", "state_flags": "OUR_INIT_SENT | THEIR_INIT_SENT"}, "local_balance": "0x2d1f615200", "sent_tlc_balance": "0x0", "remote_balance": "0x0", "received_tlc_balance": "0x0", "created_at": "0x620a0b7b1676b"}]}, "id": 42}
45+
"""
46+
return self.call("list_channels", [param])
47+
48+
def accept_channel(self, param):
49+
return self.call("accept_channel", [param])
50+
51+
def add_tlc(self, param):
52+
return self.call("add_tlc", [param])
53+
54+
def remove_tlc(self, param):
55+
return self.call("remove_tlc", [param])
56+
57+
def shutdown_channel(self, param):
58+
return self.call("shutdown_channel", [param])
59+
60+
def new_invoice(self, param):
61+
return self.call("new_invoice", [param])
62+
63+
def parse_invoice(self, param):
64+
return self.call("parse_invoice", [param])
65+
66+
def connect_peer(self, param):
67+
return self.call("connect_peer", [param])
68+
69+
def disconnect_peer(self, param):
70+
return self.call("disconnect_peer", [param])
71+
72+
def send_payment(self, param):
73+
return self.call("send_payment", [param])
74+
75+
def call(self, method, params):
76+
headers = {"content-type": "application/json"}
77+
data = {"id": 42, "jsonrpc": "2.0", "method": method, "params": params}
78+
print(
79+
"curl --location '{url}' --header 'Content-Type: application/json' --data '{data}'".format(
80+
url=self.url, data=json.dumps(data, indent=4)
81+
)
82+
)
83+
for i in range(100):
84+
try:
85+
response = requests.post(
86+
self.url, data=json.dumps(data), headers=headers
87+
).json()
88+
print("response:\n{response}".format(response=json.dumps(response)))
89+
if "error" in response.keys():
90+
error_message = response["error"].get("message", "Unknown error")
91+
raise Exception(f"Error: {error_message}")
92+
93+
return response.get("result", None)
94+
except requests.exceptions.ConnectionError as e:
95+
print(e)
96+
print("request too quickly, wait 2s")
97+
time.sleep(2)
98+
continue
99+
raise Exception("request time out")

framework/helper/ckb_cli.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,20 @@ def tx_info(tx_file_path, api_url="http://127.0.0.1:8114"):
428428
return run_command(cmd)
429429

430430

431+
def tx_add_output(output, out_put_data, tx_file):
432+
with open(tx_file, "r") as file:
433+
tx_info_str = file.read()
434+
435+
with open(tx_file, "w") as f:
436+
tx = json.loads(tx_info_str)
437+
tx["transaction"]["outputs"].append(output)
438+
tx["transaction"]["outputs_data"].append(out_put_data)
439+
440+
tx_info_str = json.dumps(tx, indent=4)
441+
f.write(tx_info_str)
442+
pass
443+
444+
431445
def tx_add_type_out_put(
432446
code_hash, hash_type, arg, capacity_hex, out_put_data, tx_file, with_type=True
433447
):

framework/helper/contract.py

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,9 @@
1010

1111
class CkbContract(ABC):
1212

13-
@abstractmethod
1413
def deploy(self, account_private, node: CkbNode):
1514
pass
1615

17-
@abstractmethod
1816
def get_deploy_hash_and_index(self) -> (str, int):
1917
pass
2018

@@ -117,6 +115,8 @@ def invoke_ckb_contract(
117115
fee=1000,
118116
api_url="http://127.0.0.1:8114",
119117
cell_deps=[],
118+
input_cells=[],
119+
output_lock_arg="0x470dcdc5e44064909650113a274b3b36aecb6dc7",
120120
):
121121
"""
122122
@@ -154,7 +154,17 @@ def invoke_ckb_contract(
154154
assert len(account_live_cells["live_cells"]) > 0
155155
input_cell_out_points = []
156156
input_cell_cap = 0
157+
for i in range(len(input_cells)):
158+
input_cell_out_points.append(input_cells[i])
159+
cell = RPCClient(api_url).get_live_cell(
160+
hex(input_cells[i]["index"]), input_cells[i]["tx_hash"], True
161+
)
162+
input_cell_cap += int(cell["cell"]["output"]["capacity"], 16)
163+
input_cells_hashs = [input_cell["tx_hash"] for input_cell in input_cells]
164+
157165
for i in range(len(account_live_cells["live_cells"])):
166+
if account_live_cells["live_cells"][i]["tx_hash"] in input_cells_hashs:
167+
continue
158168
input_cell_out_point = {
159169
"tx_hash": account_live_cells["live_cells"][i]["tx_hash"],
160170
"index": account_live_cells["live_cells"][i]["output_index"],
@@ -167,6 +177,7 @@ def invoke_ckb_contract(
167177
)
168178
* 100000000
169179
)
180+
170181
input_cell_out_points.append(input_cell_out_point)
171182
if input_cell_cap > 10000000000:
172183
break
@@ -181,7 +192,7 @@ def invoke_ckb_contract(
181192
"lock": {
182193
"code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8",
183194
"hash_type": "type",
184-
"args": "0x470dcdc5e44064909650113a274b3b36aecb6dc7",
195+
"args": output_lock_arg,
185196
},
186197
"type": {
187198
"code_hash": contract_code_hash,
@@ -218,11 +229,8 @@ def invoke_ckb_contract(
218229
print("add header:", head)
219230
tx_add_header_dep(head, tmp_tx_file)
220231
# add output
221-
tx_add_type_out_put(
222-
output_cell["type"]["code_hash"],
223-
output_cell["type"]["hash_type"],
224-
output_cell["type"]["args"],
225-
output_cell["capacity"],
232+
tx_add_output(
233+
output_cell,
226234
data,
227235
tmp_tx_file,
228236
)
@@ -236,6 +244,11 @@ def invoke_ckb_contract(
236244
sign_data[0]["lock-arg"], sign_data[0]["signature"], tmp_tx_file, api_url
237245
)
238246
tx_info(tmp_tx_file, api_url)
247+
for i in range(len(input_cells)):
248+
cell = RPCClient(api_url).get_live_cell(
249+
hex(input_cells[i]["index"]), input_cells[i]["tx_hash"], True
250+
)
251+
239252
# send tx return hash
240253
return tx_send(tmp_tx_file, api_url).strip()
241254

framework/helper/udt_contract.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
from framework.config import UDT_CONTRACT_PATH
2+
from framework.helper.contract import deploy_ckb_contract, CkbContract
3+
from framework.helper.miner import miner_until_tx_committed
4+
from framework.test_node import CkbNode
5+
from framework.util import (
6+
ckb_hash_script,
7+
to_big_uint128_le_compatible,
8+
to_int_from_big_uint128_le,
9+
)
10+
from framework.helper.contract import get_ckb_contract_codehash
11+
12+
13+
class UdtContract(CkbContract):
14+
15+
def __init__(self, contract_hash=None, contract_tx_index=None):
16+
self.contract_hash = contract_hash
17+
self.contract_tx_index = contract_tx_index
18+
if contract_hash is None:
19+
self.deployed = False
20+
self.contract_path = UDT_CONTRACT_PATH
21+
self.method = {"demo": {"args": "0x", "data": "0x"}}
22+
23+
def deploy(self, account_private, node: CkbNode):
24+
if self.deployed:
25+
return
26+
self.contract_path = deploy_ckb_contract(
27+
account_private, self.contract_path, api_url=node.getClient().url
28+
)
29+
self.contract_tx_index = 0
30+
miner_until_tx_committed(node, self.contract_path)
31+
self.deployed = True
32+
33+
def get_deploy_hash_and_index(self) -> (str, int):
34+
if not self.deployed:
35+
raise Exception("pls deploy first")
36+
return self.contract_path, self.contract_tx_index
37+
38+
@classmethod
39+
def issue(cls, own_arg, amount) -> (str, str):
40+
return ckb_hash_script(own_arg), to_big_uint128_le_compatible(amount)
41+
42+
@classmethod
43+
def transfer(cls, own_arg, amount) -> (str, str):
44+
return ckb_hash_script(own_arg), to_big_uint128_le_compatible(amount)
45+
46+
def balance(self, client, own_arg, query_arg):
47+
pass
48+
49+
def list_cell(self, client, own_arg, query_arg):
50+
code_hash = get_ckb_contract_codehash(
51+
self.contract_path,
52+
self.contract_tx_index,
53+
enable_type_id=True,
54+
api_url=client.url,
55+
)
56+
cells = client.get_cells(
57+
{
58+
"script": {
59+
"code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8",
60+
"hash_type": "type",
61+
"args": query_arg,
62+
},
63+
"script_type": "lock",
64+
"filter": {
65+
"script": {
66+
"code_hash": code_hash,
67+
"hash_type": "type",
68+
"args": ckb_hash_script(own_arg),
69+
}
70+
},
71+
},
72+
"asc",
73+
"0x64",
74+
None,
75+
)
76+
info = []
77+
for cell in cells["objects"]:
78+
info.append(
79+
{
80+
"input_cell": {
81+
"tx_hash": cell["out_point"]["tx_hash"],
82+
"index": int(cell["out_point"]["index"], 16),
83+
},
84+
"balance": to_int_from_big_uint128_le(cell["output_data"]),
85+
}
86+
)
87+
return info
88+
89+
def get_arg_and_data(self, key) -> (str, str):
90+
if key not in self.method.keys():
91+
# return "0x0","0x0"
92+
raise Exception("key not exist in method list")
93+
return self.method[key]["args"], self.method[key]["data"]

0 commit comments

Comments
 (0)