Skip to content

Commit

Permalink
Merge pull request #70 from cryptape/v119
Browse files Browse the repository at this point in the history
v119
  • Loading branch information
gpBlockchain authored Oct 29, 2024
2 parents 4656566 + a897637 commit 2d8bce3
Show file tree
Hide file tree
Showing 35 changed files with 867 additions and 28 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# This workflow will install Python dependencies, run tests and lint with a single version of Python
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python

name: Python application
name: ci_integration_tests

on:
push:
Expand All @@ -15,7 +15,7 @@ permissions:
jobs:
build:

runs-on: ubuntu-latest
runs-on: ubuntu-22.04

steps:
- uses: actions/checkout@v3
Expand Down
1 change: 1 addition & 0 deletions download.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"0.116.1",
"0.117.0",
"0.118.0",
"0.119.0",
] # Replace with your versions

DOWNLOAD_DIR = "download"
Expand Down
1 change: 1 addition & 0 deletions framework/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
# contract
ALWAYS_SUCCESS_CONTRACT_PATH = f"{get_project_root()}/source/contract/always_success"
SPAWN_CONTRACT_PATH = f"{get_project_root()}/source/contract/test_cases/spawn_demo"
UDT_CONTRACT_PATH = f"{get_project_root()}/source/contract/XUDTType"


def get_tmp_path():
Expand Down
99 changes: 99 additions & 0 deletions framework/fiber_rpc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import time

import requests

import json


class FiberRPCClient:
def __init__(self, url):
self.url = url

def send_btc(self, btc_pay_req):
return self.call("send_btc", [btc_pay_req])

def open_channel(self, param):
"""
curl --location 'http://127.0.0.1:8227' --header 'Content-Type: application/json' --data '{
"id": 42,
"jsonrpc": "2.0",
"method": "open_channel",
"params": [
{
"peer_id": "QmaQSn11jsAXWLhjHtZ9EVbauD88sCmYzty3GmYcoVWP2j",
"funding_amount": "0x2e90edd000"
}
]
}'
{"jsonrpc": "2.0", "result": {"temporary_channel_id": "0xbf1b507e730b08024180ed9cb5bb3655606d3a89e94476033cf34d206d352751"}, "id": 42}
"""
return self.call("open_channel", [param])

def list_channels(self, param):
"""
curl --location 'http://127.0.0.1:8227' --header 'Content-Type: application/json' --data '{
"id": 42,
"jsonrpc": "2.0",
"method": "list_channels",
"params": [
{
"peer_id": "QmaQSn11jsAXWLhjHtZ9EVbauD88sCmYzty3GmYcoVWP2j"
}
]
}'
{"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}
"""
return self.call("list_channels", [param])

def accept_channel(self, param):
return self.call("accept_channel", [param])

def add_tlc(self, param):
return self.call("add_tlc", [param])

def remove_tlc(self, param):
return self.call("remove_tlc", [param])

def shutdown_channel(self, param):
return self.call("shutdown_channel", [param])

def new_invoice(self, param):
return self.call("new_invoice", [param])

def parse_invoice(self, param):
return self.call("parse_invoice", [param])

def connect_peer(self, param):
return self.call("connect_peer", [param])

def disconnect_peer(self, param):
return self.call("disconnect_peer", [param])

def send_payment(self, param):
return self.call("send_payment", [param])

def call(self, method, params):
headers = {"content-type": "application/json"}
data = {"id": 42, "jsonrpc": "2.0", "method": method, "params": params}
print(
"curl --location '{url}' --header 'Content-Type: application/json' --data '{data}'".format(
url=self.url, data=json.dumps(data, indent=4)
)
)
for i in range(100):
try:
response = requests.post(
self.url, data=json.dumps(data), headers=headers
).json()
print("response:\n{response}".format(response=json.dumps(response)))
if "error" in response.keys():
error_message = response["error"].get("message", "Unknown error")
raise Exception(f"Error: {error_message}")

return response.get("result", None)
except requests.exceptions.ConnectionError as e:
print(e)
print("request too quickly, wait 2s")
time.sleep(2)
continue
raise Exception("request time out")
14 changes: 14 additions & 0 deletions framework/helper/ckb_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,20 @@ def tx_info(tx_file_path, api_url="http://127.0.0.1:8114"):
return run_command(cmd)


def tx_add_output(output, out_put_data, tx_file):
with open(tx_file, "r") as file:
tx_info_str = file.read()

with open(tx_file, "w") as f:
tx = json.loads(tx_info_str)
tx["transaction"]["outputs"].append(output)
tx["transaction"]["outputs_data"].append(out_put_data)

tx_info_str = json.dumps(tx, indent=4)
f.write(tx_info_str)
pass


def tx_add_type_out_put(
code_hash, hash_type, arg, capacity_hex, out_put_data, tx_file, with_type=True
):
Expand Down
29 changes: 21 additions & 8 deletions framework/helper/contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@

class CkbContract(ABC):

@abstractmethod
def deploy(self, account_private, node: CkbNode):
pass

@abstractmethod
def get_deploy_hash_and_index(self) -> (str, int):
pass

Expand Down Expand Up @@ -117,6 +115,8 @@ def invoke_ckb_contract(
fee=1000,
api_url="http://127.0.0.1:8114",
cell_deps=[],
input_cells=[],
output_lock_arg="0x470dcdc5e44064909650113a274b3b36aecb6dc7",
):
"""
Expand Down Expand Up @@ -154,7 +154,17 @@ def invoke_ckb_contract(
assert len(account_live_cells["live_cells"]) > 0
input_cell_out_points = []
input_cell_cap = 0
for i in range(len(input_cells)):
input_cell_out_points.append(input_cells[i])
cell = RPCClient(api_url).get_live_cell(
hex(input_cells[i]["index"]), input_cells[i]["tx_hash"], True
)
input_cell_cap += int(cell["cell"]["output"]["capacity"], 16)
input_cells_hashs = [input_cell["tx_hash"] for input_cell in input_cells]

for i in range(len(account_live_cells["live_cells"])):
if account_live_cells["live_cells"][i]["tx_hash"] in input_cells_hashs:
continue
input_cell_out_point = {
"tx_hash": account_live_cells["live_cells"][i]["tx_hash"],
"index": account_live_cells["live_cells"][i]["output_index"],
Expand All @@ -167,6 +177,7 @@ def invoke_ckb_contract(
)
* 100000000
)

input_cell_out_points.append(input_cell_out_point)
if input_cell_cap > 10000000000:
break
Expand All @@ -181,7 +192,7 @@ def invoke_ckb_contract(
"lock": {
"code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8",
"hash_type": "type",
"args": "0x470dcdc5e44064909650113a274b3b36aecb6dc7",
"args": output_lock_arg,
},
"type": {
"code_hash": contract_code_hash,
Expand Down Expand Up @@ -218,11 +229,8 @@ def invoke_ckb_contract(
print("add header:", head)
tx_add_header_dep(head, tmp_tx_file)
# add output
tx_add_type_out_put(
output_cell["type"]["code_hash"],
output_cell["type"]["hash_type"],
output_cell["type"]["args"],
output_cell["capacity"],
tx_add_output(
output_cell,
data,
tmp_tx_file,
)
Expand All @@ -236,6 +244,11 @@ def invoke_ckb_contract(
sign_data[0]["lock-arg"], sign_data[0]["signature"], tmp_tx_file, api_url
)
tx_info(tmp_tx_file, api_url)
for i in range(len(input_cells)):
cell = RPCClient(api_url).get_live_cell(
hex(input_cells[i]["index"]), input_cells[i]["tx_hash"], True
)

# send tx return hash
return tx_send(tmp_tx_file, api_url).strip()

Expand Down
93 changes: 93 additions & 0 deletions framework/helper/udt_contract.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
from framework.config import UDT_CONTRACT_PATH
from framework.helper.contract import deploy_ckb_contract, CkbContract
from framework.helper.miner import miner_until_tx_committed
from framework.test_node import CkbNode
from framework.util import (
ckb_hash_script,
to_big_uint128_le_compatible,
to_int_from_big_uint128_le,
)
from framework.helper.contract import get_ckb_contract_codehash


class UdtContract(CkbContract):

def __init__(self, contract_hash=None, contract_tx_index=None):
self.contract_hash = contract_hash
self.contract_tx_index = contract_tx_index
if contract_hash is None:
self.deployed = False
self.contract_path = UDT_CONTRACT_PATH
self.method = {"demo": {"args": "0x", "data": "0x"}}

def deploy(self, account_private, node: CkbNode):
if self.deployed:
return
self.contract_path = deploy_ckb_contract(
account_private, self.contract_path, api_url=node.getClient().url
)
self.contract_tx_index = 0
miner_until_tx_committed(node, self.contract_path)
self.deployed = True

def get_deploy_hash_and_index(self) -> (str, int):
if not self.deployed:
raise Exception("pls deploy first")
return self.contract_path, self.contract_tx_index

@classmethod
def issue(cls, own_arg, amount) -> (str, str):
return ckb_hash_script(own_arg), to_big_uint128_le_compatible(amount)

@classmethod
def transfer(cls, own_arg, amount) -> (str, str):
return ckb_hash_script(own_arg), to_big_uint128_le_compatible(amount)

def balance(self, client, own_arg, query_arg):
pass

def list_cell(self, client, own_arg, query_arg):
code_hash = get_ckb_contract_codehash(
self.contract_path,
self.contract_tx_index,
enable_type_id=True,
api_url=client.url,
)
cells = client.get_cells(
{
"script": {
"code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8",
"hash_type": "type",
"args": query_arg,
},
"script_type": "lock",
"filter": {
"script": {
"code_hash": code_hash,
"hash_type": "type",
"args": ckb_hash_script(own_arg),
}
},
},
"asc",
"0x64",
None,
)
info = []
for cell in cells["objects"]:
info.append(
{
"input_cell": {
"tx_hash": cell["out_point"]["tx_hash"],
"index": int(cell["out_point"]["index"], 16),
},
"balance": to_int_from_big_uint128_le(cell["output_data"]),
}
)
return info

def get_arg_and_data(self, key) -> (str, str):
if key not in self.method.keys():
# return "0x0","0x0"
raise Exception("key not exist in method list")
return self.method[key]["args"], self.method[key]["data"]
Loading

0 comments on commit 2d8bce3

Please sign in to comment.