From bb3fd4047faeb2e413a9f6f8c8497262e9007fe0 Mon Sep 17 00:00:00 2001 From: simusud Date: Tue, 14 Mar 2023 23:25:03 +0545 Subject: [PATCH 001/211] bts periphery initial translation --- smartpy/bts/compile.sh | 77 ++ smartpy/bts/config/config.ts | 20 + smartpy/bts/contracts/src/String.py | 46 + smartpy/bts/contracts/src/Types.py | 67 + smartpy/bts/contracts/src/bts_periphery.py | 460 +++++++ smartpy/bts/package-lock.json | 1429 ++++++++++++++++++++ smartpy/bts/package.json | 25 + smartpy/bts/scripts/deploy.ts | 62 + 8 files changed, 2186 insertions(+) create mode 100755 smartpy/bts/compile.sh create mode 100644 smartpy/bts/config/config.ts create mode 100644 smartpy/bts/contracts/src/String.py create mode 100644 smartpy/bts/contracts/src/Types.py create mode 100644 smartpy/bts/contracts/src/bts_periphery.py create mode 100644 smartpy/bts/package-lock.json create mode 100644 smartpy/bts/package.json create mode 100644 smartpy/bts/scripts/deploy.ts diff --git a/smartpy/bts/compile.sh b/smartpy/bts/compile.sh new file mode 100755 index 00000000..6a4c3b17 --- /dev/null +++ b/smartpy/bts/compile.sh @@ -0,0 +1,77 @@ + +#!/usr/bin/env bash + +set -e -o pipefail + +echo "----------------------------------------" +echo "Compiling contracts ... " +echo "----------------------------------------" + +# Expected location of SmartPy CLI. +SMART_PY_CLI=~/smartpy-cli/SmartPy.sh + +# Build artifact directory. +OUT_DIR=./contracts/build/.contract_build + +# Array of SmartPy files to compile. +# CONTRACTS_ARRAY=(counter) + +# Exit if SmartPy is not installed. +if [ ! -f "$SMART_PY_CLI" ]; then + echo "Fatal: Please install SmartPy CLI at $SMART_PY_CLI" && exit +fi + +function processContract { + CONTRACT_NAME=$1 + OUT_DIR=$2 + CONTRACT_IN="./contracts/src/${CONTRACT_NAME}.py" + CONTRACT_OUT="${CONTRACT_NAME}.json" + STORAGE_OUT="${CONTRACT_NAME}_storage.json" + CONTRACT_COMPILED="${CONTRACT_NAME}/step_000_cont_0_contract.json" + STORAGE_COMPILED="${CONTRACT_NAME}/step_000_cont_0_storage.json" + + echo ">> Processing ${CONTRACT_NAME}" + + # Ensure file exists. + if [ ! -f "$CONTRACT_IN" ]; then + echo "Fatal: $CONTRACT_IN not found. Running from wrong dir?" && exit + fi + + echo ">>> [1 / 3] Testing ${CONTRACT_NAME} ... " + $SMART_PY_CLI test $CONTRACT_IN $OUT_DIR --html + + echo ">>> [2 / 3] Compiling ${CONTRACT_NAME} ..." + $SMART_PY_CLI compile $CONTRACT_IN $OUT_DIR --html + + echo ">>> [3 / 3] Extracting Michelson contract ... " + cp $OUT_DIR/$CONTRACT_COMPILED ./contracts/build/$CONTRACT_OUT + cp $OUT_DIR/$STORAGE_COMPILED ./contracts/build/$STORAGE_OUT + + echo ">>> Michelson contract written to ${CONTRACT_OUT}" +} + +export PYTHONPATH=$PWD + + +echo "> [1 / 2] Unit Testing and Compiling Contracts." +# Use if you want to pass a contract or more as arguments. +for n in $(seq 1 $#); do + processContract $1 $OUT_DIR + shift +done + +# Use if you want to compile all contracts in CONTRACTS_ARRAY. No arguments needed. +# for i in ${!CONTRACTS_ARRAY[@]}; do +# processContract ${CONTRACTS_ARRAY[$i]} $OUT_DIR +# done + +# Remove build artifacts. +echo "> [2 / 2] Cleaning up ..." +rm -rf $OUT_DIR +rm -rf ./contracts/__pycache__ +rm -rf ./__pycache__ + + +echo "> Removed artifacts." + +echo "> Compilation successful." \ No newline at end of file diff --git a/smartpy/bts/config/config.ts b/smartpy/bts/config/config.ts new file mode 100644 index 00000000..2dc56ea2 --- /dev/null +++ b/smartpy/bts/config/config.ts @@ -0,0 +1,20 @@ +// List your config files here + +export const NETWORK = { + GHOSTNET: { + name: "ghostnet", + url: "https://ghostnet.smartpy.io", + }, + KATHMANDUNET: { + name: "kathmandunet", + url: "https://kathmandunet.smartpy.io", + }, + JAKARTANET: { + name: "jakartanet", + url: "https://jakartanet.smartpy.io", + }, + MAINNET: { + name: "mainnet", + url: "https://mainnet.smartpy.io", + }, +}; diff --git a/smartpy/bts/contracts/src/String.py b/smartpy/bts/contracts/src/String.py new file mode 100644 index 00000000..01694883 --- /dev/null +++ b/smartpy/bts/contracts/src/String.py @@ -0,0 +1,46 @@ +import smartpy as sp + + + +def split_btp_address(base): + """ + Split the BTP Address format i.e. btp://1234.iconee/0x123456789 + into Network_address (1234.iconee) and Server_address (0x123456789) + :param base: String base BTP Address format to be split + :return: The resulting strings of Network_address and Server_address + """ + sp.set_type(base, sp.TString) + + sep = sp.local("sep", "/") + prev_idx = sp.local('prev_idx', 0) + res = sp.local('res', []) + sp.for idx in sp.range(0, sp.len(base)): + sp.if sp.slice(base, idx, 1).open_some() == sep.value: + res.value.push(sp.slice(base, prev_idx.value, sp.as_nat(idx - prev_idx.value)).open_some()) + prev_idx.value = idx + 1 + sp.if sp.len(base) > 0: + res.value.push(sp.slice(base, prev_idx.value, sp.as_nat(sp.len(base) - prev_idx.value)).open_some()) + + inverted_list = sp.local("my_list", res.value) + last = sp.local("last", "") + penultimate = sp.local("penultimate", "") + + with sp.match_cons(inverted_list.value) as l: + last.value = l.head + inverted_list.value = l.tail + with sp.else_(): + sp.failwith("Empty list") + + + with sp.match_cons(inverted_list.value) as l: + penultimate.value = l.head + with sp.else_(): + sp.failwith("Only one element") + + return sp.pair(last.value, penultimate.value) + + + + + + diff --git a/smartpy/bts/contracts/src/Types.py b/smartpy/bts/contracts/src/Types.py new file mode 100644 index 00000000..29c4fe74 --- /dev/null +++ b/smartpy/bts/contracts/src/Types.py @@ -0,0 +1,67 @@ +import smartpy as sp + + +class Types: + + Asset = sp.TRecord( + coin_name=sp.TString, + value=sp.TNat + ) + + AssetTransferDetail = sp.TRecord( + coin_name=sp.TString, + value=sp.TNat, + fee=sp.TNat + ) + + Response = sp.TRecord( + code=sp.TNat, + message=sp.TString + ) + + ServiceType = sp.TVariant( + REQUEST_COIN_TRANSFER=sp.TNat, + REQUEST_COIN_REGISTER=sp.TNat, + RESPONSE_HANDLE_SERVICE=sp.TNat, + BLACKLIST_MESSAGE=sp.TNat, + CHANGE_TOKEN_LIMIT=sp.TNat, + UNKNOWN_TYPE=sp.TNat + ) + + BlacklistService = sp.TVariant( + ADD_TO_BLACKLIST=sp.TNat, + REMOVE_FROM_BLACKLIST=sp.TNat + ) + + ServiceMessage = sp.TRecord( + serviceType=ServiceType, + data=sp.TBytes + ) + + TransferCoin = sp.TRecord( + from_addr=sp.TString, + to=sp.TString, + assets=sp.TList(Asset) + ) + + PendingTransferCoin = sp.TRecord( + # from_addr=sp.TString, (change to original later) + from_addr=sp.TAddress, + to=sp.TString, + coin_names=sp.TMap(sp.TNat, sp.TString), + amounts=sp.TMap(sp.TNat, sp.TNat), + fees=sp.TMap(sp.TNat, sp.TNat) + ) + + BlacklistMessage = sp.TRecord( + serviceType=BlacklistService, + addrs=sp.TMap(sp.TNat, sp.TString), + net=sp.TString + ) + + TokenLimitMessage = sp.TRecord( + coin_name=sp.TMap(sp.TNat, sp.TString), + token_limit=sp.TMap(sp.TNat, sp.TNat), + net=sp.TString + ) + diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py new file mode 100644 index 00000000..bd64b46c --- /dev/null +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -0,0 +1,460 @@ +import smartpy as sp + +types = sp.io.import_script_from_url("file:./contracts/src/Types.py") +strings = sp.io.import_script_from_url("file:./contracts/src/String.py") + + +class BTPPreiphery(sp.Contract): + # bmc = sp.TAddress + # bts_core = sp.TAddress + service_name = sp.string("bts") + + RC_OK = sp.nat(0) + RC_ERR = sp.nat(1) + + + MAX_BATCH_SIZE = sp.nat(15) + + def __init__(self, bmc_address, bts_core_address): + self.update_initial_storage( + bmc=bmc_address, + bts_core=bts_core_address, + blacklist=sp.map(tkey=sp.TAddress, tvalue=sp.TBool), + token_limit=sp.map(tkey=sp.TString, tvalue=sp.TNat), + requests=sp.big_map(tkey=sp.TNat, tvalue=types.Types.PendingTransferCoin), + serial_no = sp.nat(0), + number_of_pending_requests = sp.nat(0) + ) + + def only_bmc(self): + sp.verify(sp.sender == self.data.bmc, "Unauthorized") + + def only_btp_core(self): + sp.verify(sp.sender == self.data.bts_core, "Unauthorized") + + @sp.onchain_view() + def has_pending_request(self): + """ + + :return: boolean + """ + sp.result(self.data.number_of_pending_requests != 0) + + @sp.entry_point + def add_to_blacklist(self, params): + """ + + :param params: List of addresses to be blacklisted + :return: + """ + sp.set_type(params, sp.TList(sp.TString)) + # sp.verify(sp.sender == self.contract, "Unauthorized") + sp.verify(sp.len(params) <= self.MAX_BATCH_SIZE, "BatchMaxSizeExceed") + # TODO:convert string to address + # sp.for x in params: + # self.data.blacklist[x] = True + + + @sp.entry_point + def remove_from_blacklist(self, params): + """ + + :param params: + :return: + """ + sp.set_type(params, sp.TList(sp.TString)) + sp.verify(sp.len(params) <= self.MAX_BATCH_SIZE, "BatchMaxSizeExceed") + + + @sp.entry_point + def set_token_limit(self, coin_names, token_limit): + """ + + :param coin_names: list of coin names + :param token_limit: list of token limits + :return: + """ + sp.set_type(coin_names, sp.TMap(sp.TNat, sp.TString)) + sp.set_type(token_limit, sp.TMap(sp.TNat, sp.TNat)) + + # sp.verify(sp.sender == sp.self_address | sp.sender == self.data.bts_core, "Unauthorized") + sp.verify(sp.len(coin_names) == sp.len(token_limit), "InvalidParams") + sp.verify(sp.len(coin_names) <= self.MAX_BATCH_SIZE, "BatchMaxSizeExceed") + + sp.for i in sp.range(0, sp.len(coin_names)): + self.data.token_limit[coin_names[i]] = token_limit[i] + + + @sp.entry_point + def send_service_message(self, _from, to, coin_names, values, fees): + """ + Send service message to BMC + :param _from: from address + :param to: to address + :param coin_names: + :param values: + :param fees: + :return: + """ + + sp.set_type(_from, sp.TAddress) + sp.set_type(to, sp.TString) + sp.set_type(coin_names, sp.TMap(sp.TNat, sp.TString)) + sp.set_type(values, sp.TMap(sp.TNat, sp.TNat)) + sp.set_type(fees, sp.TMap(sp.TNat, sp.TNat)) + + self.only_btp_core() + + to_network, to_address = sp.match_pair(strings.split_btp_address(to)) + + assets = sp.compute(sp.big_map(tkey=sp.TNat, tvalue=types.Types.Asset)) + assets_details = sp.compute(sp.big_map(tkey=sp.TNat, tvalue=types.Types.AssetTransferDetail)) + # i = sp.local("i", 0) + sp.for i in sp.range(sp.nat(0), sp.len(coin_names)): + assets[i]=sp.record( + coin_name=coin_names[i], + value=values[i] + ) + assets_details[i] = sp.record( + coin_name=coin_names[i], + value=values[i], + fee=fees[i] + ) + + self.data.serial_no += 1 + + # TODO:convert address to string + start_from = _from + + send_message_args_type = sp.TRecord(to=sp.TString, svc=sp.TString, sn=sp.TNat, msg=sp.TBytes) + send_message_entry_point = sp.contract(send_message_args_type, self.data.bmc, "send_message").open_some() + send_message_args = sp.record( + to=to_network, svc=self.service_name, sn=self.data.serial_no, + msg=sp.pack(sp.compute(sp.record(serviceType=(sp.variant("REQUEST_COIN_TRANSFER", 0)), + data=sp.pack(sp.compute(sp.record(from_addr=start_from, to=to_address, assets=assets))) + ) + ) + ) + ) + sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) + + # push pending tx into record list + self.data.requests[self.data.serial_no] = sp.record( + from_addr=start_from, to=to, coin_names=coin_names, amounts=values, fees=fees + ) + self.data.number_of_pending_requests +=sp.nat(1) + sp.trace("hhh") + sp.trace(self.data.number_of_pending_requests) + sp.trace(sp.variant("REQUEST_COIN_TRANSFER", 0)) + sp.trace(self.data.requests[self.data.serial_no]) + sp.emit(sp.record(from_address=_from, to=to, serial_no=self.data.serial_no, assets_details=assets_details), tag="TransferStart") + + + @sp.entry_point + def handle_btp_message(self, _from, svc, sn, msg): + """ + BSH handle BTP message from BMC contract + :param _from: An originated network address of a request + :param svc: A service name of BSH contract + :param sn: A serial number of a service request + :param msg: An RLP message of a service request/service response + :return: + """ + + sp.set_type(_from, sp.TString) + sp.set_type(svc, sp.TString) + sp.set_type(sn, sp.TNat) + sp.set_type(msg, sp.TBytes) + + # self.only_bmc() + # TODO: implement try catch + + sp.verify(svc == self.service_name, "InvalidSvc") + err_msg = sp.local("error", "").value + + # byt= sp.pack(sp.record(serviceType=sp.variant("REQUEST_COIN_TRANSFER", 0), data=sp.bytes("0x0dae11"))) + # sp.trace(byt) + + # sm = sp.unpack(msg, t=types.Types.ServiceMessage) + sm=sp.record(serviceType=sp.variant("REQUEST_COIN_TRANSFER", 0), data=sp.bytes("0x0dae11")) + sp.trace("mmmm") + sp.trace(sm.serviceType) + + # service_type = sm.serviceType + # service_type = sp.set_type_expr(service_type, types.Types.s_type) + # sp.trace(service_type) + + with sm.serviceType.match_cases() as arg: + with arg.match("REQUEST_COIN_TRANSFER") as a1: + sp.trace(a1) + # TODO: decode tc + # tc = sp.unpack(sm.data, t=types.Types.TransferCoin) + # TODO: check address and handle request service + + self.send_response_message(sp.variant("RESPONSE_HANDLE_SERVICE", 2), _from, sn, "", self.RC_OK) + # sp.emit(sp.record(from_address=_from, to=tc.to, serial_no=self.data.serial_no, assets_details=tc.assets)) + + with arg.match("BLACKLIST_MESSAGE") as a2: + sp.trace("mkmksm") + + # bm = sp.unpack(sm.data, types.Types.BlacklistMessage) + bm=sp.record(serviceType=sp.variant("ADD_TO_BLACKLIST", 0), addrs={0:"tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"}, + net="Tezos") + addresses = bm.addrs + + with bm.serviceType.match_cases() as b_agr: + with b_agr.match("ADD_TO_BLACKLIST") as b_val_1: + # self.add_to_blacklist(addresses) + self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), _from, sn, "AddedToBlacklist", self.RC_OK) + + with b_agr.match("REMOVE_FROM_BLACKLIST") as b_val_2: + # self.remove_from_blacklist(addresses) + self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), _from, sn, "RemovedFromBlacklist", self.RC_OK) + + with arg.match("CHANGE_TOKEN_LIMIT") as a3: + # tl = sp.unpack(sm.data, t=types.Types.TokenLimitMessage) + tl = sp.record(coin_name={0:"Tok1"},token_limit={0:5}, net="Tezos") + coin_names = tl.coin_name + token_limits = tl.token_limit + + # self.set_token_limit(coin_names, token_limits) + self.send_response_message(sp.variant("CHANGE_TOKEN_LIMIT", 4), _from, sn, "ChangeTokenLimit",self.RC_OK) + + with arg.match("RESPONSE_HANDLE_SERVICE") as a4: + # response = sp.unpack(sm.data, types.Types.Response) + response = sp.record(code=2, message="Test") + + self.handle_response_service(sn, response.code, response.message) + + with arg.match("UNKNOWN_TYPE") as a5: + sp.emit(sp.record(_from=_from, sn=sn)) + + # using if else + # with sp.if_(sm.serviceType == types.Types.ServiceType.open_variant("REQUEST_COIN_TRANSFER")): + # tc = sp.unpack(sm.data, t=types.Types.TransferCoin) + # #TODO: check address and handle request service + # # with sp.if_(self.check_parse_address(tc.to)): + # # with sp.if_(self.handle_request_service(tc.to, tc.assets)): + # self.send_response_message(types.Types.ServiceType.open_variant("REQUEST_COIN_TRANSFER"), _from, sn, "", self.RC_OK) + # sp.emit(sp.record(from_address=_from, to=tc.to, serial_no=self.data.serial_no, assets_details=tc.assets)) + # # with sp.else_(): + # # err_msg = "ErrorWhileMinting" + # # with sp.else_(): + # err_msg = "InvalidAddress" + # sp.trace(err_msg) + # self.send_response_message(types.Types.ServiceType.open_variant("REQUEST_COIN_TRANSFER"), _from, sn, err_msg, self.RC_ERR) + + + @sp.entry_point + def handle_btp_error(self, svc, sn, code, msg): + """ + BSH handle BTP Error from BMC contract + :param svc: A service name of BSH contract + :param sn: A serial number of a service request + :param code: A response code of a message (RC_OK / RC_ERR) + :param msg: A response message + :return: + """ + + sp.set_type(svc, sp.TString) + sp.set_type(sn, sp.TNat) + sp.set_type(code, sp.TNat) + sp.set_type(msg, sp.TString) + + # self.only_bmc() + + sp.verify(svc == self.service_name, "InvalidSvc") + sp.verify(sp.len(sp.pack(self.data.requests[sn].from_addr)) != 0, "InvalidSN") + + # emit_msg= sp.concat(["errCode: ", ", errMsg: ", sp.utils.string_of_nat(code), msg]) + emit_msg= sp.concat(["errCode: ", ", errMsg: ", msg]) + + self.handle_response_service(sn, self.RC_ERR, emit_msg) + + def handle_response_service(self, sn, code, msg): + """ + + :param sn: + :param code: + :param msg: + :return: + """ + sp.set_type(sn, sp.TNat) + sp.set_type(code, sp.TNat) + sp.set_type(msg, sp.TString) + + caller = sp.local("caller", self.data.requests[sn].from_addr, sp.TAddress).value + loop = sp.local("loop", sp.len(self.data.requests[sn].coin_names), sp.TNat).value + sp.verify(loop <= self.MAX_BATCH_SIZE, "BatchMaxSizeExceed") + + sp.for i in sp.range(0, loop): + + # inter score call + handle_response_service_args_type = sp.TRecord( + requester=sp.TAddress, coin_name=sp.TString, value=sp.TNat, fee=sp.TNat, rsp_code=sp.TNat + ) + handle_response_service_entry_point = sp.contract(handle_response_service_args_type, self.data.bts_core, "handle_response_service").open_some() + handle_response_service_args = sp.record( + requester=caller, coin_name=self.data.requests[sn].coin_names[i], value=self.data.requests[sn].amounts[i], + fee=self.data.requests[sn].fees[i], rsp_code=code + ) + sp.transfer(handle_response_service_args, sp.tez(0), handle_response_service_entry_point) + + del self.data.requests[sn] + self.data.number_of_pending_requests = sp.as_nat(self.data.number_of_pending_requests-1) + + sp.trace(self.data.number_of_pending_requests) + + sp.emit(sp.record(caller=caller, sn=sn, code=code, msg=msg), tag="TransferEnd") + + @sp.entry_point + def handle_request_service(self, to, assets): + """ + Handle a list of minting/transferring coins/tokens + :param to: An address to receive coins/tokens + :param assets: A list of requested coin respectively with an amount + :return: + """ + # sp.set_type(to, sp.TString) original + sp.set_type(to, sp.TAddress) + sp.set_type(assets, sp.TMap(sp.TNat, types.Types.Asset)) + + # sp.verify(sp.sender == sp.self_address, "Unauthorized") + sp.verify(sp.len(assets) <= self.MAX_BATCH_SIZE, "BatchMaxSizeExceed") + + sp.for i in sp.range(0, sp.len(assets)): + valid_coin = sp.view("is_valid_coin", self.data.bts_core, assets[i].coin_name, t=sp.TBool).open_some() + # sp.verify(valid_coin == True, "UnregisteredCoin") + + # in case of on chain view + # check_transfer = sp.view("check_transfer_restrictions", sp.self_address, sp.record(coin_name=assets[i].coin_name,user=to, value=assets[i].value), t=sp.TBool).open_some() + # sp.verify(check_transfer == True, "Fail") + + self.check_transfer_restrictions(sp.record(coin_name=assets[i].coin_name, user=to, value=assets[i].value)) + + # TODO: implement try + + # inter score call + mint_args_type = sp.TRecord( + to=sp.TAddress, coin_name=sp.TString, value=sp.TNat + ) + mint_args_type_entry_point = sp.contract(mint_args_type, self.data.bts_core, "mint").open_some() + mint_args = sp.record( + to=to, coin_name=assets[i].coin_name, value=assets[i].value + ) + sp.transfer(mint_args, sp.tez(0), mint_args_type_entry_point) + + + def send_response_message(self, service_type, to, sn, msg, code): + """ + + :param service_type: + :param to: + :param sn: + :param msg: + :param code: + :return: + """ + sp.set_type(service_type, types.Types.ServiceType) + sp.set_type(to, sp.TString) + sp.set_type(sn, sp.TNat) + sp.set_type(msg, sp.TString) + sp.set_type(code, sp.TNat) + + sp.trace("in send_response_message") + + send_message_args_type = sp.TRecord( + to=sp.TString, svc=sp.TString, sn=sp.TNat, msg=sp.TBytes + ) + send_message_entry_point = sp.contract(send_message_args_type, self.data.bmc, "send_message").open_some() + send_message_args = sp.record(to=to, svc=self.service_name, sn=self.data.serial_no, + msg=sp.pack(sp.record(serviceType=service_type, data=sp.pack(sp.record(code=code, message=msg)))) + ) + sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) + + + @sp.entry_point + def handle_fee_gathering(self, fa, svc): + """ + BSH handle Gather Fee Message request from BMC contract + :param fa: A BTP address of fee aggregator + :param svc: A name of the service + :return: + """ + sp.set_type(fa, sp.TString) + sp.set_type(svc, sp.TString) + + # self.only_bmc() + sp.verify(svc == self.service_name, "InvalidSvc") + + strings.split_btp_address(fa) + + # call transfer_fees of BTS_Core + transfer_fees_args_type = sp.TString + transfer_fees_entry_point = sp.contract(transfer_fees_args_type, self.data.bts_core, "transfer_fees").open_some() + sp.transfer(fa, sp.tez(0), transfer_fees_entry_point) + + + # @sp.onchain_view() + def check_transfer_restrictions(self, params): + """ + + :param params: Record of coin transfer details + :return: + """ + sp.set_type(params, sp.TRecord(coin_name=sp.TString, user=sp.TAddress, value=sp.TNat)) + + sp.trace("in check") + sp.trace(self.data.token_limit[params.coin_name]) + + sp.verify(self.data.blacklist.contains(params.user) == False, "Blacklisted") + sp.verify(self.data.token_limit[params.coin_name] >= params.value, "LimitExceed") + + def check_parse_address(self, to): + """ + + :param to: + :return: + """ + # TODO: check address + return False + + + + + +@sp.add_test(name="Counter") +def test(): + alice = sp.test_account("Alice") + admin = sp.test_account("Admin") + # bmc= sp.test_account("BMC") + + scenario = sp.test_scenario() + counter = BTPPreiphery(alice.address, admin.address) + scenario += counter + + + # counter.add_to_blacklist(["tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"]) + counter.send_service_message(sp.record(_from=sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), to="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", + coin_names={0:"Tok1"}, values={0:sp.nat(10)}, fees={0:sp.nat(2)})).run( + sender=admin + ) + counter.handle_btp_error(sp.record(svc= "bts", code=sp.nat(2), sn=sp.nat(1), msg="test 1")).run( + sender=admin + ) + + counter.set_token_limit(sp.record(coin_names={0:"Tok2"}, token_limit={0:sp.nat(5)})).run(sender=admin) + + counter.handle_request_service(sp.record(to= sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), assets={0: + sp.record(coin_name="Tok2", value=sp.nat(4))})).run( + sender=admin + ) + + counter.handle_fee_gathering(sp.record(fa="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", svc="bts")).run(sender=admin) + + counter.handle_btp_message(sp.record(_from="tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", svc="bts", sn=sp.nat(4), + msg=sp.bytes("0x0507070a000000030dae110000") )).run(sender=admin) + + +sp.add_compilation_target("bts_periphery", BTPPreiphery(bmc_address=sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), + bts_core_address=sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"))) \ No newline at end of file diff --git a/smartpy/bts/package-lock.json b/smartpy/bts/package-lock.json new file mode 100644 index 00000000..13756c6c --- /dev/null +++ b/smartpy/bts/package-lock.json @@ -0,0 +1,1429 @@ +{ + "name": "create-tezos-app", + "version": "1.0.3", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "create-tezos-app", + "version": "1.0.3", + "license": "MIT", + "dependencies": { + "@taquito/signer": "^14.0.0", + "@taquito/taquito": "^14.0.0", + "dotenv": "^16.0.3", + "ts-node": "^10.9.1" + }, + "bin": { + "create-tezos-app": "bin/cli.js" + }, + "devDependencies": { + "typescript": "^4.8.4" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@stablelib/binary": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/binary/-/binary-1.0.1.tgz", + "integrity": "sha512-ClJWvmL6UBM/wjkvv/7m5VP3GMr9t0osr4yVgLZsLCOz4hGN9gIAFEqnJ0TsSMAN+n840nf2cHZnA5/KFqHC7Q==", + "dependencies": { + "@stablelib/int": "^1.0.1" + } + }, + "node_modules/@stablelib/blake2b": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/blake2b/-/blake2b-1.0.1.tgz", + "integrity": "sha512-B3KyKoBAjkIFeH7romcF96i+pVFYk7K2SBQ1pZvaxV+epSBXJ+n0C66esUhyz6FF+5FbdQVm77C5fzGFcEZpKA==", + "dependencies": { + "@stablelib/binary": "^1.0.1", + "@stablelib/hash": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@stablelib/bytes": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/bytes/-/bytes-1.0.1.tgz", + "integrity": "sha512-Kre4Y4kdwuqL8BR2E9hV/R5sOrUj6NanZaZis0V6lX5yzqC3hBuVSDXUIBqQv/sCpmuWRiHLwqiT1pqqjuBXoQ==" + }, + "node_modules/@stablelib/constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/constant-time/-/constant-time-1.0.1.tgz", + "integrity": "sha512-tNOs3uD0vSJcK6z1fvef4Y+buN7DXhzHDPqRLSXUel1UfqMB1PWNsnnAezrKfEwTLpN0cGH2p9NNjs6IqeD0eg==" + }, + "node_modules/@stablelib/ed25519": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@stablelib/ed25519/-/ed25519-1.0.3.tgz", + "integrity": "sha512-puIMWaX9QlRsbhxfDc5i+mNPMY+0TmQEskunY1rZEBPi1acBCVQAhnsk/1Hk50DGPtVsZtAWQg4NHGlVaO9Hqg==", + "dependencies": { + "@stablelib/random": "^1.0.2", + "@stablelib/sha512": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@stablelib/hash": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/hash/-/hash-1.0.1.tgz", + "integrity": "sha512-eTPJc/stDkdtOcrNMZ6mcMK1e6yBbqRBaNW55XA1jU8w/7QdnCF0CmMmOD1m7VSkBR44PWrMHU2l6r8YEQHMgg==" + }, + "node_modules/@stablelib/int": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/int/-/int-1.0.1.tgz", + "integrity": "sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w==" + }, + "node_modules/@stablelib/keyagreement": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/keyagreement/-/keyagreement-1.0.1.tgz", + "integrity": "sha512-VKL6xBwgJnI6l1jKrBAfn265cspaWBPAPEc62VBQrWHLqVgNRE09gQ/AnOEyKUWrrqfD+xSQ3u42gJjLDdMDQg==", + "dependencies": { + "@stablelib/bytes": "^1.0.1" + } + }, + "node_modules/@stablelib/nacl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@stablelib/nacl/-/nacl-1.0.4.tgz", + "integrity": "sha512-PJ2U/MrkXSKUM8C4qFs87WeCNxri7KQwR8Cdwm9q2sweGuAtTvOJGuW0F3N+zn+ySLPJA98SYWSSpogMJ1gCmw==", + "dependencies": { + "@stablelib/poly1305": "^1.0.1", + "@stablelib/random": "^1.0.2", + "@stablelib/wipe": "^1.0.1", + "@stablelib/x25519": "^1.0.3", + "@stablelib/xsalsa20": "^1.0.2" + } + }, + "node_modules/@stablelib/poly1305": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/poly1305/-/poly1305-1.0.1.tgz", + "integrity": "sha512-1HlG3oTSuQDOhSnLwJRKeTRSAdFNVB/1djy2ZbS35rBSJ/PFqx9cf9qatinWghC2UbfOYD8AcrtbUQl8WoxabA==", + "dependencies": { + "@stablelib/constant-time": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@stablelib/random": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@stablelib/random/-/random-1.0.2.tgz", + "integrity": "sha512-rIsE83Xpb7clHPVRlBj8qNe5L8ISQOzjghYQm/dZ7VaM2KHYwMW5adjQjrzTZCchFnNCNhkwtnOBa9HTMJCI8w==", + "dependencies": { + "@stablelib/binary": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@stablelib/salsa20": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@stablelib/salsa20/-/salsa20-1.0.2.tgz", + "integrity": "sha512-nfjKzw0KTKrrKBasEP+j7UP4I8Xudom8lVZIBCp0kQNARXq72IlSic0oabg2FC1NU68L4RdHrNJDd8bFwrphYA==", + "dependencies": { + "@stablelib/binary": "^1.0.1", + "@stablelib/constant-time": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@stablelib/sha512": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/sha512/-/sha512-1.0.1.tgz", + "integrity": "sha512-13gl/iawHV9zvDKciLo1fQ8Bgn2Pvf7OV6amaRVKiq3pjQ3UmEpXxWiAfV8tYjUpeZroBxtyrwtdooQT/i3hzw==", + "dependencies": { + "@stablelib/binary": "^1.0.1", + "@stablelib/hash": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@stablelib/wipe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/wipe/-/wipe-1.0.1.tgz", + "integrity": "sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg==" + }, + "node_modules/@stablelib/x25519": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@stablelib/x25519/-/x25519-1.0.3.tgz", + "integrity": "sha512-KnTbKmUhPhHavzobclVJQG5kuivH+qDLpe84iRqX3CLrKp881cF160JvXJ+hjn1aMyCwYOKeIZefIH/P5cJoRw==", + "dependencies": { + "@stablelib/keyagreement": "^1.0.1", + "@stablelib/random": "^1.0.2", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@stablelib/xsalsa20": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@stablelib/xsalsa20/-/xsalsa20-1.0.2.tgz", + "integrity": "sha512-7XdBGbcNgBShmuhDXv1G1WPVCkjZdkb1oPMzSidO7Fve0MHntH6TjFkj5bfLI+aRE+61weO076vYpP/jmaAYog==", + "dependencies": { + "@stablelib/binary": "^1.0.1", + "@stablelib/salsa20": "^1.0.2", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@taquito/http-utils": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/http-utils/-/http-utils-14.0.0.tgz", + "integrity": "sha512-ZWZzod/+/OEE26b9CnDRjHGfUKBJft3aXv/e/A9bTHAtvRNJqGIhofHcDg/jTaolBMarCF2b3XBYw35aOOSk4A==", + "dependencies": { + "axios": "^0.26.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@taquito/local-forging": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/local-forging/-/local-forging-14.0.0.tgz", + "integrity": "sha512-Nm0xGmS1Jzd+tU0a/8Y8XuTghbiPBgHDLo+e4141TK3OAwTzOw0an+w3xK9QVfzvxfIcZBSMjeMZzOwDdiqkJQ==", + "dependencies": { + "@taquito/utils": "^14.0.0", + "bignumber.js": "^9.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@taquito/michel-codec": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/michel-codec/-/michel-codec-14.0.0.tgz", + "integrity": "sha512-ftnBvUVddlHBqvQbGPHEb26KrS4lIcaZ1eIpYJWiz+akb4Pcfyq7j/OEsDZbB7Pl2FP9hqu7ZygOF34zY6Lrtw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@taquito/michelson-encoder": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/michelson-encoder/-/michelson-encoder-14.0.0.tgz", + "integrity": "sha512-KIS+xl4rKfnd6hf9LUr6W+Pb7gv8F/Qsx0fho9CtM2PodKvdef3YlvkpScBUM9QZntAlvq2XQXUVXcZkbvxygw==", + "dependencies": { + "@taquito/rpc": "^14.0.0", + "@taquito/utils": "^14.0.0", + "bignumber.js": "^9.0.2", + "fast-json-stable-stringify": "^2.1.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@taquito/rpc": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/rpc/-/rpc-14.0.0.tgz", + "integrity": "sha512-FMfb80sA+VJwNx8OTNN07boDAt2roISqLLCUgmOIwy/cFDqhII7gdS4aYWJWqlKbdPKCPqh3a3ZQD1X/jyQHOA==", + "dependencies": { + "@taquito/http-utils": "^14.0.0", + "@taquito/utils": "^14.0.0", + "bignumber.js": "^9.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@taquito/signer": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/signer/-/signer-14.0.0.tgz", + "integrity": "sha512-vDqp/quzAsOiVikUt5MYUKhHI3S9qlasazyXs99xK9qpGLotbx6aseKcfb/dkaTo4/eoMzP4XzTVdnk0AqcCkw==", + "dependencies": { + "@stablelib/blake2b": "^1.0.1", + "@stablelib/ed25519": "^1.0.2", + "@stablelib/nacl": "^1.0.3", + "@taquito/taquito": "^14.0.0", + "@taquito/utils": "^14.0.0", + "elliptic": "^6.5.4", + "pbkdf2": "^3.1.2", + "typedarray-to-buffer": "^4.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@taquito/taquito": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/taquito/-/taquito-14.0.0.tgz", + "integrity": "sha512-JaXfvqOCF3dkwXxhe00Ravb8WLMC2VqJxerf4GrGUEpJw+NAkwbGEb8k/52+MQQdlxMPepZdPPru/HM3nFG0Tw==", + "hasInstallScript": true, + "dependencies": { + "@taquito/http-utils": "^14.0.0", + "@taquito/local-forging": "^14.0.0", + "@taquito/michel-codec": "^14.0.0", + "@taquito/michelson-encoder": "^14.0.0", + "@taquito/rpc": "^14.0.0", + "@taquito/utils": "^14.0.0", + "bignumber.js": "^9.0.2", + "rxjs": "^6.6.3" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@taquito/utils": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/utils/-/utils-14.0.0.tgz", + "integrity": "sha512-0RSHn/CzbcbMdldJJIlXyxOvAajwmL6iPKJ6NaRyYJqqLM2CxYjG72KpXVv716pCMV1MbIWsOAr9FKbxW73PsA==", + "dependencies": { + "@stablelib/blake2b": "^1.0.1", + "@stablelib/ed25519": "^1.0.2", + "@types/bs58check": "^2.1.0", + "bignumber.js": "^9.0.2", + "blakejs": "^1.2.1", + "bs58check": "^2.1.2", + "buffer": "^6.0.3", + "elliptic": "^6.5.4", + "typedarray-to-buffer": "^4.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==" + }, + "node_modules/@types/bs58check": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/bs58check/-/bs58check-2.1.0.tgz", + "integrity": "sha512-OxsysnJQh82vy9DRbOcw9m2j/WiyqZLn0YBhKxdQ+aCwoHj+tWzyCgpwAkr79IfDXZKxc6h7k89T9pwS78CqTQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "18.11.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", + "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==" + }, + "node_modules/acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "node_modules/axios": { + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "dependencies": { + "follow-redirects": "^1.14.8" + } + }, + "node_modules/base-x": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", + "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bignumber.js": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.0.tgz", + "integrity": "sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==", + "engines": { + "node": "*" + } + }, + "node_modules/blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==" + }, + "node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + }, + "node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "dependencies": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/typedarray-to-buffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-4.0.0.tgz", + "integrity": "sha512-6dOYeZfS3O9RtRD1caom0sMxgK59b27+IwoNy8RDPsmslSGOyU+mpTamlaIW7aNKi90ZQZ9DFaZL3YRoiSCULQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/typescript": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "engines": { + "node": ">=6" + } + } + }, + "dependencies": { + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "requires": { + "@jridgewell/trace-mapping": "0.3.9" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + }, + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@stablelib/binary": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/binary/-/binary-1.0.1.tgz", + "integrity": "sha512-ClJWvmL6UBM/wjkvv/7m5VP3GMr9t0osr4yVgLZsLCOz4hGN9gIAFEqnJ0TsSMAN+n840nf2cHZnA5/KFqHC7Q==", + "requires": { + "@stablelib/int": "^1.0.1" + } + }, + "@stablelib/blake2b": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/blake2b/-/blake2b-1.0.1.tgz", + "integrity": "sha512-B3KyKoBAjkIFeH7romcF96i+pVFYk7K2SBQ1pZvaxV+epSBXJ+n0C66esUhyz6FF+5FbdQVm77C5fzGFcEZpKA==", + "requires": { + "@stablelib/binary": "^1.0.1", + "@stablelib/hash": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "@stablelib/bytes": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/bytes/-/bytes-1.0.1.tgz", + "integrity": "sha512-Kre4Y4kdwuqL8BR2E9hV/R5sOrUj6NanZaZis0V6lX5yzqC3hBuVSDXUIBqQv/sCpmuWRiHLwqiT1pqqjuBXoQ==" + }, + "@stablelib/constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/constant-time/-/constant-time-1.0.1.tgz", + "integrity": "sha512-tNOs3uD0vSJcK6z1fvef4Y+buN7DXhzHDPqRLSXUel1UfqMB1PWNsnnAezrKfEwTLpN0cGH2p9NNjs6IqeD0eg==" + }, + "@stablelib/ed25519": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@stablelib/ed25519/-/ed25519-1.0.3.tgz", + "integrity": "sha512-puIMWaX9QlRsbhxfDc5i+mNPMY+0TmQEskunY1rZEBPi1acBCVQAhnsk/1Hk50DGPtVsZtAWQg4NHGlVaO9Hqg==", + "requires": { + "@stablelib/random": "^1.0.2", + "@stablelib/sha512": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "@stablelib/hash": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/hash/-/hash-1.0.1.tgz", + "integrity": "sha512-eTPJc/stDkdtOcrNMZ6mcMK1e6yBbqRBaNW55XA1jU8w/7QdnCF0CmMmOD1m7VSkBR44PWrMHU2l6r8YEQHMgg==" + }, + "@stablelib/int": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/int/-/int-1.0.1.tgz", + "integrity": "sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w==" + }, + "@stablelib/keyagreement": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/keyagreement/-/keyagreement-1.0.1.tgz", + "integrity": "sha512-VKL6xBwgJnI6l1jKrBAfn265cspaWBPAPEc62VBQrWHLqVgNRE09gQ/AnOEyKUWrrqfD+xSQ3u42gJjLDdMDQg==", + "requires": { + "@stablelib/bytes": "^1.0.1" + } + }, + "@stablelib/nacl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@stablelib/nacl/-/nacl-1.0.4.tgz", + "integrity": "sha512-PJ2U/MrkXSKUM8C4qFs87WeCNxri7KQwR8Cdwm9q2sweGuAtTvOJGuW0F3N+zn+ySLPJA98SYWSSpogMJ1gCmw==", + "requires": { + "@stablelib/poly1305": "^1.0.1", + "@stablelib/random": "^1.0.2", + "@stablelib/wipe": "^1.0.1", + "@stablelib/x25519": "^1.0.3", + "@stablelib/xsalsa20": "^1.0.2" + } + }, + "@stablelib/poly1305": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/poly1305/-/poly1305-1.0.1.tgz", + "integrity": "sha512-1HlG3oTSuQDOhSnLwJRKeTRSAdFNVB/1djy2ZbS35rBSJ/PFqx9cf9qatinWghC2UbfOYD8AcrtbUQl8WoxabA==", + "requires": { + "@stablelib/constant-time": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "@stablelib/random": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@stablelib/random/-/random-1.0.2.tgz", + "integrity": "sha512-rIsE83Xpb7clHPVRlBj8qNe5L8ISQOzjghYQm/dZ7VaM2KHYwMW5adjQjrzTZCchFnNCNhkwtnOBa9HTMJCI8w==", + "requires": { + "@stablelib/binary": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "@stablelib/salsa20": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@stablelib/salsa20/-/salsa20-1.0.2.tgz", + "integrity": "sha512-nfjKzw0KTKrrKBasEP+j7UP4I8Xudom8lVZIBCp0kQNARXq72IlSic0oabg2FC1NU68L4RdHrNJDd8bFwrphYA==", + "requires": { + "@stablelib/binary": "^1.0.1", + "@stablelib/constant-time": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "@stablelib/sha512": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/sha512/-/sha512-1.0.1.tgz", + "integrity": "sha512-13gl/iawHV9zvDKciLo1fQ8Bgn2Pvf7OV6amaRVKiq3pjQ3UmEpXxWiAfV8tYjUpeZroBxtyrwtdooQT/i3hzw==", + "requires": { + "@stablelib/binary": "^1.0.1", + "@stablelib/hash": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "@stablelib/wipe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/wipe/-/wipe-1.0.1.tgz", + "integrity": "sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg==" + }, + "@stablelib/x25519": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@stablelib/x25519/-/x25519-1.0.3.tgz", + "integrity": "sha512-KnTbKmUhPhHavzobclVJQG5kuivH+qDLpe84iRqX3CLrKp881cF160JvXJ+hjn1aMyCwYOKeIZefIH/P5cJoRw==", + "requires": { + "@stablelib/keyagreement": "^1.0.1", + "@stablelib/random": "^1.0.2", + "@stablelib/wipe": "^1.0.1" + } + }, + "@stablelib/xsalsa20": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@stablelib/xsalsa20/-/xsalsa20-1.0.2.tgz", + "integrity": "sha512-7XdBGbcNgBShmuhDXv1G1WPVCkjZdkb1oPMzSidO7Fve0MHntH6TjFkj5bfLI+aRE+61weO076vYpP/jmaAYog==", + "requires": { + "@stablelib/binary": "^1.0.1", + "@stablelib/salsa20": "^1.0.2", + "@stablelib/wipe": "^1.0.1" + } + }, + "@taquito/http-utils": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/http-utils/-/http-utils-14.0.0.tgz", + "integrity": "sha512-ZWZzod/+/OEE26b9CnDRjHGfUKBJft3aXv/e/A9bTHAtvRNJqGIhofHcDg/jTaolBMarCF2b3XBYw35aOOSk4A==", + "requires": { + "axios": "^0.26.0" + } + }, + "@taquito/local-forging": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/local-forging/-/local-forging-14.0.0.tgz", + "integrity": "sha512-Nm0xGmS1Jzd+tU0a/8Y8XuTghbiPBgHDLo+e4141TK3OAwTzOw0an+w3xK9QVfzvxfIcZBSMjeMZzOwDdiqkJQ==", + "requires": { + "@taquito/utils": "^14.0.0", + "bignumber.js": "^9.0.2" + } + }, + "@taquito/michel-codec": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/michel-codec/-/michel-codec-14.0.0.tgz", + "integrity": "sha512-ftnBvUVddlHBqvQbGPHEb26KrS4lIcaZ1eIpYJWiz+akb4Pcfyq7j/OEsDZbB7Pl2FP9hqu7ZygOF34zY6Lrtw==" + }, + "@taquito/michelson-encoder": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/michelson-encoder/-/michelson-encoder-14.0.0.tgz", + "integrity": "sha512-KIS+xl4rKfnd6hf9LUr6W+Pb7gv8F/Qsx0fho9CtM2PodKvdef3YlvkpScBUM9QZntAlvq2XQXUVXcZkbvxygw==", + "requires": { + "@taquito/rpc": "^14.0.0", + "@taquito/utils": "^14.0.0", + "bignumber.js": "^9.0.2", + "fast-json-stable-stringify": "^2.1.0" + } + }, + "@taquito/rpc": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/rpc/-/rpc-14.0.0.tgz", + "integrity": "sha512-FMfb80sA+VJwNx8OTNN07boDAt2roISqLLCUgmOIwy/cFDqhII7gdS4aYWJWqlKbdPKCPqh3a3ZQD1X/jyQHOA==", + "requires": { + "@taquito/http-utils": "^14.0.0", + "@taquito/utils": "^14.0.0", + "bignumber.js": "^9.0.2" + } + }, + "@taquito/signer": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/signer/-/signer-14.0.0.tgz", + "integrity": "sha512-vDqp/quzAsOiVikUt5MYUKhHI3S9qlasazyXs99xK9qpGLotbx6aseKcfb/dkaTo4/eoMzP4XzTVdnk0AqcCkw==", + "requires": { + "@stablelib/blake2b": "^1.0.1", + "@stablelib/ed25519": "^1.0.2", + "@stablelib/nacl": "^1.0.3", + "@taquito/taquito": "^14.0.0", + "@taquito/utils": "^14.0.0", + "elliptic": "^6.5.4", + "pbkdf2": "^3.1.2", + "typedarray-to-buffer": "^4.0.0" + } + }, + "@taquito/taquito": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/taquito/-/taquito-14.0.0.tgz", + "integrity": "sha512-JaXfvqOCF3dkwXxhe00Ravb8WLMC2VqJxerf4GrGUEpJw+NAkwbGEb8k/52+MQQdlxMPepZdPPru/HM3nFG0Tw==", + "requires": { + "@taquito/http-utils": "^14.0.0", + "@taquito/local-forging": "^14.0.0", + "@taquito/michel-codec": "^14.0.0", + "@taquito/michelson-encoder": "^14.0.0", + "@taquito/rpc": "^14.0.0", + "@taquito/utils": "^14.0.0", + "bignumber.js": "^9.0.2", + "rxjs": "^6.6.3" + } + }, + "@taquito/utils": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/utils/-/utils-14.0.0.tgz", + "integrity": "sha512-0RSHn/CzbcbMdldJJIlXyxOvAajwmL6iPKJ6NaRyYJqqLM2CxYjG72KpXVv716pCMV1MbIWsOAr9FKbxW73PsA==", + "requires": { + "@stablelib/blake2b": "^1.0.1", + "@stablelib/ed25519": "^1.0.2", + "@types/bs58check": "^2.1.0", + "bignumber.js": "^9.0.2", + "blakejs": "^1.2.1", + "bs58check": "^2.1.2", + "buffer": "^6.0.3", + "elliptic": "^6.5.4", + "typedarray-to-buffer": "^4.0.0" + } + }, + "@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" + }, + "@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" + }, + "@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" + }, + "@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==" + }, + "@types/bs58check": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/bs58check/-/bs58check-2.1.0.tgz", + "integrity": "sha512-OxsysnJQh82vy9DRbOcw9m2j/WiyqZLn0YBhKxdQ+aCwoHj+tWzyCgpwAkr79IfDXZKxc6h7k89T9pwS78CqTQ==", + "requires": { + "@types/node": "*" + } + }, + "@types/node": { + "version": "18.11.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", + "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==" + }, + "acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==" + }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==" + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "axios": { + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "requires": { + "follow-redirects": "^1.14.8" + } + }, + "base-x": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", + "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "bignumber.js": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.0.tgz", + "integrity": "sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==" + }, + "blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==" + }, + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + }, + "bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "requires": { + "base-x": "^3.0.2" + } + }, + "bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "requires": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" + }, + "dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==" + }, + "elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + }, + "pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "requires": { + "tslib": "^1.9.0" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "requires": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "typedarray-to-buffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-4.0.0.tgz", + "integrity": "sha512-6dOYeZfS3O9RtRD1caom0sMxgK59b27+IwoNy8RDPsmslSGOyU+mpTamlaIW7aNKi90ZQZ9DFaZL3YRoiSCULQ==" + }, + "typescript": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" + } + } +} diff --git a/smartpy/bts/package.json b/smartpy/bts/package.json new file mode 100644 index 00000000..47727297 --- /dev/null +++ b/smartpy/bts/package.json @@ -0,0 +1,25 @@ +{ + "name": "create-tezos-app", + "version": "1.0.3", + "description": "A Tezos Dapp Starter using Typescript and Taquito.", + "bin": "./bin/cli.js", + "scripts": { + "compile": "bash ./compile.sh", + "deploy": "npx ts-node scripts/deploy.ts" + }, + "author": "Roshan Parajuli", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/0xrpj/create-tezos-dapp" + }, + "dependencies": { + "@taquito/signer": "^14.0.0", + "@taquito/taquito": "^14.0.0", + "dotenv": "^16.0.3", + "ts-node": "^10.9.1" + }, + "devDependencies": { + "typescript": "^4.8.4" + } +} \ No newline at end of file diff --git a/smartpy/bts/scripts/deploy.ts b/smartpy/bts/scripts/deploy.ts new file mode 100644 index 00000000..9b50353a --- /dev/null +++ b/smartpy/bts/scripts/deploy.ts @@ -0,0 +1,62 @@ +import * as dotenv from "dotenv"; +import { TezosToolkit } from "@taquito/taquito"; +import { InMemorySigner } from "@taquito/signer"; +import { NETWORK } from "../config/config"; + +dotenv.config(); + +const deploy = async () => { + type networkTypes = keyof typeof NETWORK; + + const { ORIGINATOR_PRIVATE_KEY } = process.env; + let file = process.argv[2]; + let rpcType: networkTypes = process.argv[3] + ?.toUpperCase() + .slice(1) as networkTypes; + + console.info("Staring validation..."); + + if (!ORIGINATOR_PRIVATE_KEY) { + console.error("Private key missing in the environment."); + return; + } + + if (!file) { + console.log("Pass filename to deploy! Read the docs."); + return; + } + + if (!rpcType || !Object.keys(NETWORK).includes(rpcType)) { + console.log("Valid networks:", Object.keys(NETWORK)); + console.error("Invalid network"); + return; + } + + file = file.toLowerCase(); + + const signer = await InMemorySigner.fromSecretKey(ORIGINATOR_PRIVATE_KEY); + const Tezos = new TezosToolkit(NETWORK[rpcType].url); + Tezos.setProvider({ signer: signer }); + + console.log(`Validation checks out... \nDeploying the ${file} contract..\n`); + try { + const { hash, contractAddress } = await Tezos.contract.originate({ + code: require(`../contracts/build/${file}.json`), + init: require(`../contracts/build/${file}_storage.json`), + }); + + console.log("Successfully deployed contract"); + console.log(`>> Transaction hash: ${hash}`); + console.log(`>> Contract address: ${contractAddress}`); + } catch (error) { + console.log( + `Oops... Deployment faced an issue.\nHere's the detailed info about the error,\n${error}` + ); + + console.log( + "Make sure of these things. \n1. Compiled contracts are inside the build folder.\n2. You have enough Tezos balance in the wallet for deployment." + ); + } +}; + +deploy(); From 756dff62ee323452d8ba112758ad4ebf1b976a66 Mon Sep 17 00:00:00 2001 From: simusud Date: Sun, 19 Mar 2023 12:56:23 +0545 Subject: [PATCH 002/211] added string library --- smartpy/bts/contracts/src/String.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/smartpy/bts/contracts/src/String.py b/smartpy/bts/contracts/src/String.py index 01694883..13f58a47 100644 --- a/smartpy/bts/contracts/src/String.py +++ b/smartpy/bts/contracts/src/String.py @@ -1,7 +1,5 @@ import smartpy as sp - - def split_btp_address(base): """ Split the BTP Address format i.e. btp://1234.iconee/0x123456789 From 3e47ca39e2fac4162754ffebd62ba1a935bebdab Mon Sep 17 00:00:00 2001 From: Anatehc Date: Mon, 20 Mar 2023 09:05:01 +0545 Subject: [PATCH 003/211] initial commit --- smartpy/bts/contracts/src/BTSCore.py | 234 +++++++++++++++++++ smartpy/bts/contracts/src/FA2Contract.py | 39 ++++ smartpy/bts/contracts/src/btsOwnerManager.py | 79 +++++++ 3 files changed, 352 insertions(+) create mode 100644 smartpy/bts/contracts/src/BTSCore.py create mode 100644 smartpy/bts/contracts/src/FA2Contract.py create mode 100644 smartpy/bts/contracts/src/btsOwnerManager.py diff --git a/smartpy/bts/contracts/src/BTSCore.py b/smartpy/bts/contracts/src/BTSCore.py new file mode 100644 index 00000000..7f77e4bc --- /dev/null +++ b/smartpy/bts/contracts/src/BTSCore.py @@ -0,0 +1,234 @@ +import smartpy as sp + +# types = sp.io.import_script_from_url("file:./contracts/src/Types.py") +Coin = sp.TRecord(addr=sp.TAddress, feeNumerator=sp.TNat, fixedFee=sp.TNat, + coinType=sp.TNat) + + +class BTSCore(sp.Contract): + FEE_DENOMINATOR = sp.nat(10000) + RC_OK = sp.nat(0) + RC_ERR = sp.nat(1) + NATIVE_COIN_TYPE = sp.nat(0) + NATIVE_WRAPPED_COIN_TYPE = sp.nat(1) + NON_NATIVE_TOKEN_TYPE = sp.nat(2) + + MAX_BATCH_SIZE = sp.nat(15) + NATIVE_COIN_ADDRESS = sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc") + + # TODO: change the native coin addr + + def __init__(self, ownerManager_address, btsPeriphery_address, _nativeCoinName, _feeNumerator, _fixedFee, + ): + # Sets the initial storage of the contract with an empty map and a list containing the owner address + self.update_initial_storage( + + ownerManager_contract_address=ownerManager_address, + btsPeriphery_contract_address=btsPeriphery_address, + nativeCoinName=_nativeCoinName, + listOfOwners=sp.list(t=sp.TAddress), + # a list of amounts have been charged so far (use this when Fee Gathering occurs) + chargedAmounts=sp.list(t=sp.TNat), + # a string array stores names of supported coins + coinsName=sp.list([_nativeCoinName], t=sp.TString), + # a list of coins' names have been charged so far (use this when Fee Gathering occurs) + chargedCoins=sp.list(t=sp.TString), + + owners=sp.map({}, tkey=sp.TAddress, tvalue=sp.TBool), + aggregationFee=sp.map({}, tkey=sp.TString, tvalue=sp.TInt), + balances=sp.big_map(tkey=sp.TRecord(sp.TAddress,sp.TString), tvalue= types.Type.Balance), + coins=sp.map({_nativeCoinName: self.NATIVE_COIN_ADDRESS}, tkey=sp.TString, tvalue=sp.TAddress), + + coinDetails=sp.map({_nativeCoinName: sp.record(addr=self.NATIVE_COIN_ADDRESS, + feeNumerator=_feeNumerator, + fixedFee=_fixedFee, + coinType=sp.nat(0))}, + tkey=sp.TString, tvalue=Coin), + + coinsAddress=sp.map({}, tkey=sp.TAddress, tvalue=sp.TString), + ) + + def OnlyOwner(self, _owner): + # call Owner Manager Contract for checking owner + isOwner = sp.view("isOwner", self.data.ownerManager_contract_address, sp.sender, t=sp.TBool).open_some( + "OwnerNotFound") + + # ToDO: find a way to transfer function parameter to another contract + + sp.verify(isOwner == sp.sender, message="Unauthorized") + + def OnlyBtsPeriphery(self, _owner): + sp.verify(sp.sender == self.data.btsPeriphery_contract_address, message="Unauthorized") + + # Get the name of Native Coin , Caller can be any + @sp.onchain_view() + def getNativeCoinName(self): + sp.result(self.data.nativeCoinName) + + # update BTS Periphery address + # TODO: verify zero address + @sp.entry_point + def updateBTSPeriphery(self, _btsPeripheryAddr): + sp.set_type(_btsPeripheryAddr, sp.TAddress) + sp.verify(self.data.owners[sp.sender], message="Unauthorized") + sp.verify(_btsPeripheryAddr != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), message="InvalidSetting") + # sp.if(self.data.btsPeriphery_contract_address != sp.none): + btsPeriphery_contract = sp.view("hasPendingRequest", self.data.btsPeriphery_contract_address, sp.none, + t=sp.TBool).open_some("OwnerNotFound") + + sp.verify(btsPeriphery_contract == False, message="HasPendingRequest") + self.data.btsPeriphery_contract_address = _btsPeripheryAddr + + #set fee ratio, Caller must be the owner of this contract + #The transfer fee is calculated by feeNumerator/FEE_DEMONINATOR. + #_feeNumerator if it is set to `10`, which means the default fee ratio is 0.1%. + @sp.entry_point + def set_fee_ratio(self,_name,_fee_numerator,_fixed_fee): + sp.set_type(_name, sp.TString) + sp.set_type(_fee_numerator, sp.TNat) + sp.set_type(_fixed_fee, sp.TNat) + sp.verify(self.data.owners[sp.sender], message="Unauthorized") + sp.verify(_fee_numerator < self.FEE_DENOMINATOR, message="InvalidSetting") + sp.verify((_name == self.data.nativeCoinName) | + (self.data.coins[_name] != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc")), + message = "TokenNotExists") + sp.verify((_fixed_fee > 0) & (_fee_numerator >= 0), message = "LessThan0") + self.data.coinDetails[_name].feeNumerator = _fee_numerator + self.data.coinDetails[_name].fixedFee = _fixed_fee + + + @sp.entry_point + def register(self, _name, _symbol, _decimals, _fee_numerator, _fixed_fee, _addr ): + sp.set_type(_name, sp.TString) + sp.set_type(_symbol, sp.TString) + sp.set_type(_decimals, sp.TNat) + sp.set_type(_fee_numerator, sp.TNat) + sp.set_type(_fixed_fee, sp.TNat) + sp.set_type(_addr, sp.TAddress) + sp.verify(self.data.owners[sp.sender], message="Unauthorized") + sp.verify(_name == self.data.nativeCoinName, message= "ExistNativeCoin") + sp.verify(self.data.coins[_name] == sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), message= "ExistCoin") + sp.verify(_fee_numerator <= self.FEE_DENOMINATOR, message="InvalidSetting") + sp.verify((_fixed_fee > 0) & (_fee_numerator >= 0), message="LessThan0") + # TODO: + sp.if _addr == sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"): + # deploy FA2 contract and set the deployed address + # deployedFA2 = sp.address() + self.data.coins[_name] = deployedFA2 + self.data.coinsName.push(_name) + self.data.coinsAddress[deployedFA2] = _name + self.data.coinDetails[_name] = Coin ( + addr = deployedFA2, + feeNumerator = _fee_numerator, + fixedFee = _fixed_fee, + coinType = self.NATIVE_WRAPPED_COIN_TYPE + ) + sp.else: + self.data.coins[_name] = _addr + self.data.coinsName.push(_name) + self.data.coinsAddress[_addr] = _name + self.data.coinDetails[_name] = Coin ( + addr = _addr, + feeNumerator = _fee_numerator, + fixedFee = _fixed_fee, + coinType = self.NON_NATIVE_TOKEN_TYPE + ) + # ToDO: initialise string and make interscore call. + token_arr = sp.list[_name] + val_arr = sp.list[] + set_token_limit = sp.contract(sp.list,sp.list, self.data.btsPeriphery_contract_address,"setTokenLimit").open_some() + sp.transfer(token_arr, val_arr, sp.tez(0), setTokenLimit) + + +# Return all supported coins names , Caller can be any + @sp.onchain_view() + def coinNames(self): + sp.result(self.data.coinsName) + + # Return the _id number of Coin whose name is the same with given _coinName + @sp.onchain_view() + def coinId(self, _coinName): + sp.result(self.data.coins[_coinName]) + + + @sp.onchain_view() + def isValidCoin(self, _coin_name): + sp.if (self.data.coins[_coin_name] != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"))|( _coin_name == self.data.nativeCoinName): + sp.result(True) + sp.else: + sp.result(False) + + @sp.onchain_view() + def feeRatio(self, _coin_name): + coin = self.data.coinDetails[_coin_name] + _fee_numerator = coin.feeNumerator + _fixed_fee = coin.fixedFee + sp.result(sp.record(fee_numerator =_fee_numerator,fixed_fee = _fixed_fee)) + + + @sp.onchain_view() + # TODO: confirm sp.balance_Of() + def balanceOf(self, _owner, _coin_name): + sp.if _coin_name == self.data.nativeCoinName: + sp.result(sp.record(_usable_balance = sp.nat(0), + _locked_balane = self.data.balances[_owner][_coin_name].lockedBalance, + _refundable_balance = self.data.balances[_owner][_coin_name].refundableBalance, + _user_balance = sp.balance_of(sp.address(_owner))) + _fa2_address = self.data.coins[_coin_name] + # IERC20 ierc20 = IERC20(_erc20Address); + #TODO: userbalance = token balance of a user? + # allowance? + sp.if _fa2_address != self.data.zero_addr: + # return token balance of _owner + # _user_balance = + sp.if _fa2_address == self.data.zero_addr: + _user_balance = sp.nat(0) + sp.result(_user_balance) + # TODO: userbalance and allowance operations + sp.result(sp.record(_usable_balance, + _locked_balane=self.data.balances[_owner][_coin_name].lockedBalance, + _refundable_balance=self.data.balances[_owner][_coin_name].refundableBalance, + _user_balance) + + + @sp.onchain_view() + def balanceOfBatch(self, _owner, _coin_names): + sp.verify((sp.len(_coin_names) >0 ) & (sp.len(_coin_names) <= self.MAX_BATCH_SIZE), message = "BatchMaxSizeExceed") + #ToDO: make a dynamic array + sp.for i in sp.range(0, sp.len(_coin_names)): + #TODO + + @sp.onchain_view() + #TODO: dynamic array? + def getAccumulatedFees(): + sp.for i in sp.range(0, sp.len( self.data.coinsName)): + _accumulatedFees[i] = Types.Asset(self.data.coinsName[i], aggregationFee[self.data.coinsName[i]) + sp.result(_accumulatedFees) + +@sp.add_test(name="Calculator") +def test(): + c1 = BTSCore( + ownerManager_address=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), + btsPeriphery_address=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), + _nativeCoinName="NativeCoin", + _feeNumerator=sp.nat(1000), + _fixedFee=sp.nat(10) + ) + scenario = sp.test_scenario() + scenario.h1("BTSCore") + scenario += c1 + + +sp.add_compilation_target("", BTSCore( + ownerManager_address=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), + btsPeriphery_address=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), + _nativeCoinName="NativeCoin", + _feeNumerator=sp.nat(1000), + _fixedFee=sp.nat(10) +)) + + + + + + diff --git a/smartpy/bts/contracts/src/FA2Contract.py b/smartpy/bts/contracts/src/FA2Contract.py new file mode 100644 index 00000000..b9b2bb64 --- /dev/null +++ b/smartpy/bts/contracts/src/FA2Contract.py @@ -0,0 +1,39 @@ +import smartpy as sp + +FA2 = sp.io.import_script_from_url("https://smartpy.io/templates/fa2_lib.py") + + +class SingleAssetToken(FA2.Admin, FA2.Fa2SingleAsset, FA2.BurnSingleAsset): + def __init__(self, admin, **kwargs): + FA2.Fa2SingleAsset.__init__(self, **kwargs) + FA2.Admin.__init__(self, admin) + + @sp.entry_point + def mint(self, batch): + """Admin can mint tokens.""" + sp.set_type( + batch, + sp.TList( + sp.TRecord(to_=sp.TAddress, amount=sp.TNat).layout(("to_", "amount")) + ), + ) + sp.verify(self.is_administrator(sp.sender), "FA2_NOT_ADMIN") + with sp.for_("action", batch) as action: + sp.verify(self.is_defined(0), "FA2_TOKEN_UNDEFINED") + self.data.supply += action.amount + self.data.ledger[action.to_] = ( + self.data.ledger.get(action.to_, 0) + action.amount + ) + + @sp.onchain_view() + def is_admin(self, address): + sp.result(address == self.data.administrator) + + +sp.add_compilation_target("fa2_single_asset", + SingleAssetToken( + admin=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), + metadata=sp.utils.metadata_of_url( + "ipfs://example"), + token_metadata = FA2.make_metadata(name="Token Zero", decimals=1, symbol="Tok0"), + policy=None)) \ No newline at end of file diff --git a/smartpy/bts/contracts/src/btsOwnerManager.py b/smartpy/bts/contracts/src/btsOwnerManager.py new file mode 100644 index 00000000..27222932 --- /dev/null +++ b/smartpy/bts/contracts/src/btsOwnerManager.py @@ -0,0 +1,79 @@ +import smartpy as sp + +class BTSOwnerManager(sp.Contract): + def __init__(self,owner_address): + self.update_initial_storage( + owners=sp.map(tkey=sp.TAddress, tvalue=sp.TBool), + listOfOwners=sp.list([owner_address]), + + ) + + + #Entry point for adding a new owner to the contract + @sp.entry_point + def add_owner(self, new_owner): + + sp.verify(self.data.owners[sp.sender], message="Unauthorized") + + # Verifies that the new owner does not already exist in the owners map + sp.verify(self.data.owners[new_owner] == False,message="ExistedOwner") + # Adds the new owner to the owners map and to the listOfOwners list + self.data.owners[new_owner] == True + # self.data.listOfOwners.push(new_owner) + # Emits an event with the new owner addresses + sp.emit(new_owner, tag="NewOwnerAdded") + + + # Entry point for removing an owner from the contract + @sp.entry_point + def remove_owner(self, removed_owner): + sp.verify(self.data.owners[sp.sender], message="Unauthorized") + # Verifies that there are more than one owners in the contract + sp.verify( + sp.len(self.data.listOfOwners) > 1, + message="CannotRemoveMinOwner" + ) + # Verifies that the removed owner exists in the owners map + sp.verify( + self.data.owners[removed_owner] == True, + message="NotanOwner" + ) + # Deletes the removed owner from the owners map and the listOfOwners list + del self.data.owners[removed_owner] + # self._remove(removed_owner) + # Emits an event with the removed owner addresses + sp.emit(removed_owner, tag="OwnerRemoved") + + # Internal function for removing an owner from the listOfOwners list + # @sp.private_lambda + def _remove(self, removed_owner): + # Loops through the listOfOwners list to find the removed owner and removes it + sp.for i in sp.range(0,sp.len(self.data.listOfOwners)): + sp.if self.data.listOfOwners[i] == removed_owner: + self.data.listOfOwners[i] = self.data.listOfOwners[sp.len(self.data.listOfOwners) - 1] + self.data.listOfOwners.pop() + + + # External view method to check if an address is an owner of the contract + @sp.onchain_view() + def isOwner(self, _owner): + sp.result( self.data.owners[_owner]) + + # External view method to get a list of all the owners in the contract + @sp.onchain_view() + def getOwners(self): + sp.result(self.data.listOfOwners) + +@sp.add_test(name = "BTSOwnerManager") +def test(): + alice = sp.test_account("Alice") + c1 = BTSOwnerManager(alice.address) + scenario = sp.test_scenario() + scenario.h1("BTSOwnerManager") + scenario += c1 + + # scenario.verify(val == "o") + +sp.add_compilation_target("OwnerManager", BTSOwnerManager(sp.address("tz1UVtzTTE1GatMoXhs46hbdp1143a195kXh"))) + + From 4e5d8b757e0ba09c36a281141727eec1ff8210a4 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Mon, 20 Mar 2023 09:38:55 +0545 Subject: [PATCH 004/211] initial commit for tezos bridge --- cmd/iconbridge/chain/tezos/client.go | 267 +++++++++++++++++++++++++ cmd/iconbridge/chain/tezos/receiver.go | 113 +++++++++++ cmd/iconbridge/chain/tezos/sender.go | 196 ++++++++++++++++++ cmd/iconbridge/chain/tezos/verifier.go | 103 ++++++++++ cmd/iconbridge/main.go | 1 + go.mod | 3 +- go.sum | 28 +++ 7 files changed, 710 insertions(+), 1 deletion(-) create mode 100644 cmd/iconbridge/chain/tezos/client.go create mode 100644 cmd/iconbridge/chain/tezos/receiver.go create mode 100644 cmd/iconbridge/chain/tezos/sender.go create mode 100644 cmd/iconbridge/chain/tezos/verifier.go diff --git a/cmd/iconbridge/chain/tezos/client.go b/cmd/iconbridge/chain/tezos/client.go new file mode 100644 index 00000000..a578a784 --- /dev/null +++ b/cmd/iconbridge/chain/tezos/client.go @@ -0,0 +1,267 @@ +package tezos + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "math/big" + + // "io" + "log" + "time" + + "blockwatch.cc/tzgo/contract" + "blockwatch.cc/tzgo/micheline" + "blockwatch.cc/tzgo/rpc" + "blockwatch.cc/tzgo/signer" + "blockwatch.cc/tzgo/tezos" +) + +const ( + DefaultSendTransactionRetryInterval = 30 * time.Second + DefaultGetTransactionResultPollingInterval = 15 * time.Second + DefaultBlockWaitInterval = 15 * time.Second +) + +type IClient interface { + // Call(ctx context.Context, callArgs contract.CallArguments, opts *rpc.CallOptions) + GetBalance(ctx context.Context, connection *rpc.Client, account tezos.Address, blockLevel int64) + GetBlockByHeight(ctx context.Context, connection *rpc.Client, blockLevel int64) (*rpc.Block, error) + // GetBlockHeaderByHeight(ctx context.Context, connection *rpc.Client, blockLevel int64) + // GetBlockMetadataByHash(ctx context.Context, connection *rpc.Client, blockHash tezos.Hash) + + MonitorBlock(ctx context.Context, client *rpc.Client, connection *contract.Contract, blockLevel int64) (*rpc.Block, error) + // MonitorEvent(ctx context.Context, connection *rpc.Client, blockLevel int64) + + GetLastBlock(ctx context.Context, connection *rpc.Client) (*rpc.Block, error) + GetStatus(ctx context.Context, contr *contract.Contract) (TypesLinkStats, error) + + HandleRelayMessage(ctx context.Context, callArgs contract.CallArguments) (*rpc.Receipt, error) + +} + +// tezos periphery +type TypesLinkStats struct { + RxSeq *big.Int + TxSeq *big.Int + RxHeight *big.Int + CurrentHeight *big.Int +} + +type Client struct { + Log log.Logger + Ctx context.Context + Cl *rpc.Client + Contract *contract.Contract + blockLevel int64 +} + +func (c *Client) SignTransaction() rpc.CallOptions{ + pK := tezos.MustParsePrivateKey("") + opts := rpc.DefaultOptions + opts.Signer = signer.NewFromKey(pK) + return opts +} + +func (c *Client) SendTransaction(ctx context.Context, connection *contract.Contract, parameters micheline.Parameters, sender tezos.Address) (*rpc.Receipt, error){ + args := contract.NewTxArgs() + + args.WithParameters(parameters) + + opts := c.SignTransaction() + + argument := args.WithSource(sender).WithDestination(connection.Address()) + + result, err := connection.Call(ctx, argument, &opts) + + if err != nil { + return nil, err + } + + err = PrettyEncode(result) + + if err != nil { + return nil, err + } + return result, nil +} + +func (c *Client) GetLastBlock(ctx context.Context, connection *rpc.Client) (*rpc.Block, error){ + block, err := connection.GetHeadBlock(ctx) + if err != nil{ + return nil, err + } + return block, nil +} + +func (c *Client) GetBlockByHeight(ctx context.Context, connection *rpc.Client, blockLevel int64)(*rpc.Block, error){ + block, err := connection.GetBlock(ctx, rpc.BlockLevel(blockLevel)) + if err != nil { + return nil, err + } + return block, nil +} + +func (c *Client) GetBlockHeaderByHeight(ctx context.Context, connection *rpc.Client, blockLevel int64)(*rpc.BlockHeader, error){ + block, err := connection.GetBlockHeader(ctx, rpc.BlockLevel(blockLevel)) + if err != nil { + return nil, err + } + return block, nil +} + +func (c *Client) MonitorBlock(blockLevel int64, verifier IVerifier) (error) { + fmt.Println("reached in monitor block") + relayTicker := time.NewTicker(DefaultBlockWaitInterval) + defer relayTicker.Stop() + + for { + select { + case <- c.Ctx.Done(): + return fmt.Errorf("Context done") + case <- relayTicker.C: + fmt.Println("*************************************************************") + fmt.Print("Trying to fetch block for blockLevel ") + fmt.Println(blockLevel) + + block, err := c.GetBlockByHeight(c.Ctx, c.Cl, blockLevel) + + if err != nil { + fmt.Println(err) + fmt.Println("reducing the block level") + blockLevel-- + fmt.Print("Trying to Fetch for block level ") + fmt.Println(blockLevel) + continue + } + + header, err := c.GetBlockHeaderByHeight(c.Ctx, c.Cl, blockLevel) + if err != nil { + return err + } + + err = verifier.Verify(header, &block.Metadata.Baker) + + if err != nil { + fmt.Println(err) + return err + } + c.blockLevel = blockLevel + + err = verifier.Update(header) + + if err != nil { + fmt.Println(err) + return err + } + + + PrettyEncode(header) + + + blockOperations := block.Operations + + for i := 0; i < len(blockOperations); i++ { + for j := 0; j < len(blockOperations[i]); j ++{ + for _, operation := range blockOperations[i][j].Contents { + switch operation.Kind() { + case tezos.OpTypeTransaction: + tx := operation.(*rpc.Transaction) + returnTxMetadata(tx, c.Contract.Address()) + } + } + } + } + } + blockLevel++ + } +} + +func returnTxMetadata(tx *rpc.Transaction, contractAddress tezos.Address) error { + _, err := fmt.Println(tx.Destination) + if err != nil { + return err + } + address := tx.Destination + if address.ContractAddress() == contractAddress.ContractAddress() { + fmt.Println("Address matched") + fmt.Println("****************") + fmt.Println("****************") + fmt.Println("****") + fmt.Println("****") + fmt.Println("****") + fmt.Println("****************") + fmt.Println("****************") + fmt.Println("****") + fmt.Println("****") + fmt.Println("****") + fmt.Println("****") + fmt.Println("****") + fmt.Println("****") + + if tx.Metadata.InternalResults[0].Tag == "TokenMinted" { + fmt.Println("Payload is") + fmt.Println(tx.Metadata.InternalResults[0].Payload.Int) + } + } + return nil +} + +func (c *Client) GetClient()(*rpc.Client) { + return c.Cl +} + +func (c *Client) GetBalance(ctx context.Context, connection *rpc.Client, account tezos.Address, blockLevel int64)(*big.Int, error){ + balance, err := connection.GetContractBalance(ctx, account, rpc.BlockLevel(blockLevel)) + if err != nil { + return nil, err + } + return balance.Big(), nil +} + +func (c *Client) GetStatus(ctx context.Context, contr *contract.Contract) (TypesLinkStats, error){ + prim := micheline.Prim{} + status, err := contr.RunCallback(ctx, "getStatus", prim) + if err != nil { + return *new(TypesLinkStats), err + } + var stats TypesLinkStats + err = status.Decode(stats) + if err != nil { + return *new(TypesLinkStats), err + } + return stats, nil +} + +func (c *Client) HandleRelayMessage(ctx context.Context, callArgs contract.CallArguments) (*rpc.Receipt, error) { + return nil, nil +} + +func NewClient(uri string, src tezos.Address, l log.Logger) (*Client, error){ + + fmt.Println("uri is : " + uri) + + c, err := rpc.NewClient(uri, nil) + + conn := contract.NewContract(src, c) + + if err != nil { + return nil, err + } + + return &Client{Log: l, Cl: c, Contract: conn}, nil +} + + + +func PrettyEncode(data interface{}) error { + var buffer bytes.Buffer + enc := json.NewEncoder(&buffer) + enc.SetIndent("", " ") + if err := enc.Encode(data); err != nil { + return err + } + fmt.Println(buffer.String()) + return nil +} diff --git a/cmd/iconbridge/chain/tezos/receiver.go b/cmd/iconbridge/chain/tezos/receiver.go new file mode 100644 index 00000000..746300e9 --- /dev/null +++ b/cmd/iconbridge/chain/tezos/receiver.go @@ -0,0 +1,113 @@ +package tezos + +import ( + "github.com/icon-project/icon-bridge/cmd/iconbridge/chain" + "context" + "encoding/json" + "fmt" + "log" + "sync" + "strconv" + // "blockwatch.cc/tzgo/contract" + "blockwatch.cc/tzgo/contract" + "blockwatch.cc/tzgo/tezos" +) + +type receiver struct { + log log.Logger + src tezos.Address + dst tezos.Address + client Client +} + +type Receiver struct { + log log.Logger + src tezos.Address + dst tezos.Address + Client *Client +} + +func (r *Receiver) Subscribe(ctx context.Context, msgCh chan<- *chain.Message, opts chain.SubscribeOptions) (errCh <-chan error, err error) { + r.Client.Contract = contract.NewContract(r.src, r.Client.Cl) + r.Client.Ctx = ctx + + opts.Seq++ + + _errCh := make(chan error) + + verifier, err := r.NewVerifier(int64(opts.Height) - 1) + + if err != nil { + _errCh <- err + return _errCh, err + } + + go func() { + defer close(_errCh) + err := r.Client.MonitorBlock(int64(opts.Height), verifier) + + if err != nil { + _errCh <- err + } + + fmt.Println("Printing from inside the receiver") + }() + + return _errCh, nil +} + +func NewReceiver(src, dst tezos.Address, urls []string, rawOpts json.RawMessage, l log.Logger) (chain.Receiver, error){ + var client *Client + var err error + + if len(urls) == 0 { + return nil, fmt.Errorf("Empty urls") + } + + client, err = NewClient(urls[0], src, l) + if err != nil { + return nil, err + } + + receiver := &Receiver{ + log: l, + src: src, + dst: dst, + Client: client, + } + + return receiver, nil +} + +func (r *Receiver) NewVerifier(previousHeight int64) (vri IVerifier, err error) { + header, err := r.Client.GetBlockHeaderByHeight(r.Client.Ctx, r.Client.Cl, previousHeight) + if err != nil { + return nil, err + } + + fittness, err := strconv.ParseInt(string(header.Fitness[1].String()), 16, 64) + if err != nil { + return nil, err + } + + chainIdHash, err := r.Client.Cl.GetChainId(r.Client.Ctx) + if err != nil { + return nil, err + } + + id := chainIdHash.Uint32() + + if err != nil { + return nil, err + } + + vr := &Verifier{ + mu: sync.RWMutex{}, + next: header.Level, + parentHash: header.Hash, + parentFittness: fittness, + chainID: id, + } + + return vr, nil +} \ No newline at end of file diff --git a/cmd/iconbridge/chain/tezos/sender.go b/cmd/iconbridge/chain/tezos/sender.go new file mode 100644 index 00000000..faeff611 --- /dev/null +++ b/cmd/iconbridge/chain/tezos/sender.go @@ -0,0 +1,196 @@ +package tezos + +import ( + "github.com/icon-project/icon-bridge/cmd/iconbridge/chain" + "context" + "encoding/json" + "fmt" + "log" + "math/big" + "time" + + // "blockwatch.cc/tzgo/codec" + "blockwatch.cc/tzgo/contract" + "blockwatch.cc/tzgo/micheline" + "blockwatch.cc/tzgo/rpc" + "blockwatch.cc/tzgo/signer" + "blockwatch.cc/tzgo/tezos" +) + +const ( + txMaxDataSize = 32 * 1024 // 8 KB + defaultSendTxTimeOut = 30 * time.Second // 30 seconds is the block time for tezos +) + +type senderOptions struct { + StepLimit uint64 `json:"step_limit"` + TxDataSizeLimit uint64 `json:"tx_data_size_limit"` + BalanceThreshold uint64 `json:"balance_threshold"` +} + +type sender struct { + log log.Logger + src tezos.Address + dst tezos.Address + connection *contract.Contract + parameters micheline.Parameters + cls *Client + blockLevel int64 + opts senderOptions +} + +func NewSender( + src, dst tezos.Address, + urls []string, + rawOpts json.RawMessage, l log.Logger) (chain.Sender, error) { + var err error + s := &sender { + log: l, + src: src, + dst: dst, + } + if len(urls) == 0 { + return nil, fmt.Errorf("Empty url") + } + s.cls, err = NewClient(urls[0], src, l) + if err != nil { + return nil, err + } + + return s, nil + +} + +func (s *sender) Balance(ctx context.Context) (balance, threshold *big.Int, err error){ + balance, err = s.cls.GetBalance(ctx, s.cls.Cl, s.src, s.cls.blockLevel) + if err != nil { + return nil, nil, err + } + + return balance, big.NewInt(0), nil +} + +func (s *sender) Segment(ctx context.Context, msg *chain.Message) (tx chain.RelayTx, newMsg *chain.Message, err error) { + if ctx.Err() != nil { + return nil, nil, ctx.Err() + } + + if s.opts.TxDataSizeLimit == 0{ + s.opts.TxDataSizeLimit = uint64(txMaxDataSize) + } + + if len(msg.Receipts) == 0 { + return nil, msg, nil + } + + rm := &chain.RelayMessage{ + Receipts: make([][]byte, 0), + } + + var msgSize uint64 + + newMsg = &chain.Message{ + From: msg.From, + Receipts: msg.Receipts, + } + + for i , receipt := range msg.Receipts{ + rlpEvents := receipt.Events + + chainReceipt := &chain.Receipt{ + Index: receipt.Index, + Height: receipt.Height, + Events: rlpEvents, + } + + rlpReceipt, err := json.Marshal(chainReceipt) + if err != nil { + return nil, nil, err + } + + newMsgSize := msgSize + uint64(len(rlpReceipt)) + if newMsgSize > s.opts.TxDataSizeLimit { + newMsg.Receipts = msg.Receipts[i:] + break + } + msgSize = newMsgSize + rm.Receipts = append(rm.Receipts, rlpReceipt) + } + message, err := json.Marshal(rm) + if err != nil { + return nil, nil, err + } + + tx, err = s.newRelayTx(ctx, msg.From.String(), message) + if err != nil { + return nil, nil, err + } + + return tx, newMsg, nil +} + +func (s *sender) Status(ctx context.Context) (link *chain.BMCLinkStatus, err error) { + return nil, nil +} + +func (s *sender) newRelayTx(ctx context.Context, prev string, message []byte) (*relayTx, error) { + client := s.cls + + return &relayTx{ + Prev: prev, + Message: message, + cl: client, + }, nil +} + +type relayTx struct { + Prev string `json:"_prev"` + Message []byte `json:"_msg"` + + cl *Client + receipt *rpc.Receipt +} + +func (tx *relayTx) ID() interface{}{ + return nil +} + +func (tx *relayTx) Send(ctx context.Context) (err error) { + _ctx, cancel := context.WithTimeout(ctx, defaultSendTxTimeOut) + defer cancel() + + prim := micheline.Prim{} + + michJsonStrMsg := "{}" // add message here + + if err := prim.UnmarshalJSON([]byte(michJsonStrMsg)); err != nil { + fmt.Println("couldnot unmarshall empty string") + fmt.Println(err) + return err + } + + args := contract.NewTxArgs() + args.WithParameters(micheline.Parameters{Entrypoint: "handleRelayMessage", Value: prim}) + + opts := rpc.DefaultOptions + + opts.Signer = signer.NewFromKey(tezos.MustParsePrivateKey("")) // pk + + from := tezos.MustParseAddress("") // pubk + + argument := args.WithSource(from).WithDestination(tx.cl.Contract.Address()) + + receipt, err := tx.cl.HandleRelayMessage(_ctx, argument) + + if err != nil { + return nil + } + + tx.receipt = receipt + + return nil +} + +func (tx *relayTx) Receipt(ctx context.Context) (blockHeight uint64, err error) { + return uint64(0), nil +} \ No newline at end of file diff --git a/cmd/iconbridge/chain/tezos/verifier.go b/cmd/iconbridge/chain/tezos/verifier.go new file mode 100644 index 00000000..6effb49d --- /dev/null +++ b/cmd/iconbridge/chain/tezos/verifier.go @@ -0,0 +1,103 @@ +package tezos + +import ( + "fmt" + "sync" + + "strconv" + + "blockwatch.cc/tzgo/rpc" + "blockwatch.cc/tzgo/tezos" +) + +type IVerifier interface { + Next() int64 + Verify(header *rpc.BlockHeader, proposer *tezos.Address) error + Update(header *rpc.BlockHeader) error + ParentHash() tezos.BlockHash + IsValidator(proposer tezos.Address, height int64) bool +} + +type Verifier struct{ + chainID uint32 + mu sync.RWMutex + validators []tezos.Address + next int64 + parentHash tezos.BlockHash + parentFittness int64 +} + +func (vr *Verifier) Next() int64{ + vr.mu.RLock() + return vr.next +} + +func (vr *Verifier) Verify(header *rpc.BlockHeader, proposer *tezos.Address) error { + vr.mu.RLock() + defer vr.mu.RUnlock() + blockFittness := header.Fitness + currentFittness, err := strconv.ParseInt(string(blockFittness[1].String()), 16, 64) + if err != nil { + return err + } + + fmt.Print("Current fittness: ") + fmt.Println(currentFittness) + + fmt.Print("Parent fittness") + fmt.Println(vr.parentFittness) + + if currentFittness < vr.parentFittness { + return fmt.Errorf("Invalid block fittness") + } + + previousHashInBlock := header.Predecessor + + fmt.Print("Current fittness: ") + fmt.Println(previousHashInBlock) + + fmt.Print("Parent fittness") + fmt.Println(vr.parentHash) + + + if previousHashInBlock.String() != vr.parentHash.String() { + return fmt.Errorf("Invalid block hash") + } + fmt.Println("Block is verified") + fmt.Println("******* *******") + fmt.Println(" ******* *******") + fmt.Println(" ******* *******") + + + return nil +} + +func (vr *Verifier) Update(header *rpc.BlockHeader) error { + vr.mu.Lock() + defer vr.mu.Unlock() + blockFittness := header.Fitness + + currentFittness, err := strconv.ParseInt(string(blockFittness[1].String()), 16, 64) + if err != nil { + return err + } + + vr.parentFittness = currentFittness + + vr.parentHash = header.Hash + fmt.Println(header.Hash) + fmt.Println("updated") + return nil +} + +func (vr *Verifier) ParentHash() tezos.BlockHash { + vr.mu.RLock() + defer vr.mu.RUnlock() + return vr.parentHash +} + +func (vr *Verifier) IsValidator(proposer tezos.Address, height int64) bool { + vr.mu.RLock() + defer vr.mu.RUnlock() + return true +} \ No newline at end of file diff --git a/cmd/iconbridge/main.go b/cmd/iconbridge/main.go index 13b38cf1..cbba7d44 100644 --- a/cmd/iconbridge/main.go +++ b/cmd/iconbridge/main.go @@ -22,6 +22,7 @@ import ( _ "github.com/icon-project/icon-bridge/cmd/iconbridge/chain/icon" _ "github.com/icon-project/icon-bridge/cmd/iconbridge/chain/near" _ "github.com/icon-project/icon-bridge/cmd/iconbridge/chain/substrate-eth" + _ "github.com/icon-project/icon-bridge/cmd/iconbridge/chain/tezos" ) var ( diff --git a/go.mod b/go.mod index 2bfe6edc..4c2fc8f6 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/icon-project/icon-bridge go 1.13 require ( + blockwatch.cc/tzgo v1.16.0 // indirect github.com/MuhammedIrfan/testify-mock v0.0.0-20220912121829-185fc90cd1b6 github.com/aws/aws-sdk-go v1.44.76 github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 @@ -33,7 +34,7 @@ require ( github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/tinylib/msgp v1.1.2 // indirect github.com/vmihailenco/msgpack/v4 v4.3.11 - golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d + golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa gopkg.in/natefinch/lumberjack.v2 v2.0.0 ) diff --git a/go.sum b/go.sum index ed51cfa8..d79fbfe0 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +blockwatch.cc/tzgo v1.16.0 h1:nvKlXqDyDtq7/pmCotWr0d7xpcZ9cEbqFdROFVjiseI= +blockwatch.cc/tzgo v1.16.0/go.mod h1:Bm3ZfCsqnJtpsAdwBQmhsoz4n8qc9qL4uJhsDoLArR8= cloud.google.com/go v0.16.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= @@ -194,6 +196,12 @@ github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vs github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4= github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= +github.com/decred/dcrd/chaincfg/chainhash v1.0.2/go.mod h1:BpbrGgrPTr3YJYRN3Bm+D9NuaFd+zGyNeIKgrhCXK60= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/dcrec/secp256k1 v1.0.3 h1:u4XpHqlscRolxPxt2YHrFBDVZYY1AK+KMV02H1r+HmU= +github.com/decred/dcrd/dcrec/secp256k1 v1.0.3/go.mod h1:eCL8H4MYYjRvsw2TuANvEOcVMFbmi9rt/6hJUWU5wlU= +github.com/decred/dcrd/dcrec/secp256k1/v2 v2.0.0 h1:3GIJYXQDAKpLEFriGFN8SbSffak10UXHGdIcFaMPykY= +github.com/decred/dcrd/dcrec/secp256k1/v2 v2.0.0/go.mod h1:3s92l0paYkZoIHuj4X93Teg/HB7eGM9x/zokGw+u4mY= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= @@ -228,6 +236,10 @@ github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJ github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/echa/bson v0.0.0-20220430141917-c0fbdf7f8b79 h1:J+/tX7s5mN1aoeQi2ySzix7+zyEhnymkudOxn7VMze4= +github.com/echa/bson v0.0.0-20220430141917-c0fbdf7f8b79/go.mod h1:Ih8Pfj34Z/kOmaLua+KtFWFK3AviGsH5siipj6Gmoa8= +github.com/echa/log v1.2.2 h1:tL0IxLI1SqreYWvnkpdE1exilCq9sCOp+aPZWWtwtFU= +github.com/echa/log v1.2.2/go.mod h1:MuBQcNxMgV0eT5iL3yvSZyu4wh40FKfmwJQs1RDUqcQ= github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw= @@ -249,6 +261,8 @@ github.com/evalphobia/logrus_fluent v0.5.4/go.mod h1:hasyj+CXm3BDP1YhFk/rnTcjleg github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/fjl/memsize v0.0.0-20180929194037-2a09253e352a/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= @@ -825,8 +839,11 @@ github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVc github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHRmPYs= github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-isatty v0.0.2/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= @@ -841,6 +858,8 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= @@ -1289,6 +1308,8 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1455,10 +1476,15 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8 h1:h+EGohizhe9XlX18rfpa8k8RAc5XyaeamM+0VHRd4lc= +golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 h1:Q5284mrmYTpACcm+eAKjKJH48BBwSyfJqmmGDTtT8Vc= +golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1608,6 +1634,7 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/bson.v2 v2.0.0-20171018101713-d8c8987b8862/go.mod h1:VN8wuk/3Ksp8lVZ82HHf/MI1FHOBDt5bPK9VZ8DvymM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1623,6 +1650,7 @@ gopkg.in/go-playground/validator.v9 v9.28.0 h1:6pzvnzx1RWaaQiAmv6e1DvCFULRaz5cKo gopkg.in/go-playground/validator.v9 v9.28.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= From ad808b93295058a37a191d95183afe16e2fd1159 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Mon, 20 Mar 2023 14:29:50 +0545 Subject: [PATCH 005/211] fix: log type to common log --- cmd/iconbridge/chain/tezos/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/iconbridge/chain/tezos/client.go b/cmd/iconbridge/chain/tezos/client.go index a578a784..f8f6ab22 100644 --- a/cmd/iconbridge/chain/tezos/client.go +++ b/cmd/iconbridge/chain/tezos/client.go @@ -8,7 +8,7 @@ import ( "math/big" // "io" - "log" + "github.com/icon-project/icon-bridge/common/log" "time" "blockwatch.cc/tzgo/contract" From 32b0aa7bd76817eed24fab2d33f95ee2785defe4 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Mon, 20 Mar 2023 14:32:31 +0545 Subject: [PATCH 006/211] fix: src and dst address type in NewReceiver function from tezos.Address to BTPAddress --- cmd/iconbridge/chain/tezos/receiver.go | 47 ++++++++++++++------------ 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/cmd/iconbridge/chain/tezos/receiver.go b/cmd/iconbridge/chain/tezos/receiver.go index 746300e9..779fd4d3 100644 --- a/cmd/iconbridge/chain/tezos/receiver.go +++ b/cmd/iconbridge/chain/tezos/receiver.go @@ -5,7 +5,7 @@ import ( "context" "encoding/json" "fmt" - "log" + "github.com/icon-project/icon-bridge/common/log" "sync" "strconv" // "blockwatch.cc/tzgo/contract" @@ -17,19 +17,15 @@ type receiver struct { log log.Logger src tezos.Address dst tezos.Address - client Client + client *Client } -type Receiver struct { - log log.Logger - src tezos.Address - dst tezos.Address - Client *Client -} +func (r *receiver) Subscribe( + ctx context.Context, msgCh chan<- *chain.Message, + opts chain.SubscribeOptions) (errCh <-chan error, err error) { -func (r *Receiver) Subscribe(ctx context.Context, msgCh chan<- *chain.Message, opts chain.SubscribeOptions) (errCh <-chan error, err error) { - r.Client.Contract = contract.NewContract(r.src, r.Client.Cl) - r.Client.Ctx = ctx + r.client.Contract = contract.NewContract(r.src, r.client.Cl) + r.client.Ctx = ctx opts.Seq++ @@ -44,7 +40,7 @@ func (r *Receiver) Subscribe(ctx context.Context, msgCh chan<- *chain.Message, o go func() { defer close(_errCh) - err := r.Client.MonitorBlock(int64(opts.Height), verifier) + err := r.client.MonitorBlock(int64(opts.Height), verifier) if err != nil { _errCh <- err @@ -56,7 +52,10 @@ func (r *Receiver) Subscribe(ctx context.Context, msgCh chan<- *chain.Message, o return _errCh, nil } -func NewReceiver(src, dst tezos.Address, urls []string, rawOpts json.RawMessage, l log.Logger) (chain.Receiver, error){ +func NewReceiver( + src, dst chain.BTPAddress, urls []string, + rawOpts json.RawMessage, l log.Logger) (chain.Receiver, error){ + var client *Client var err error @@ -64,23 +63,27 @@ func NewReceiver(src, dst tezos.Address, urls []string, rawOpts json.RawMessage, return nil, fmt.Errorf("Empty urls") } - client, err = NewClient(urls[0], src, l) + srcAddr := tezos.MustParseAddress(src.String()) + + dstAddr := tezos.MustParseAddress(dst.String()) + + client, err = NewClient(urls[0], srcAddr, l) if err != nil { return nil, err } - receiver := &Receiver{ + r := &receiver{ log: l, - src: src, - dst: dst, - Client: client, + src: srcAddr, + dst: dstAddr, + client: client, } - return receiver, nil + return r, nil } -func (r *Receiver) NewVerifier(previousHeight int64) (vri IVerifier, err error) { - header, err := r.Client.GetBlockHeaderByHeight(r.Client.Ctx, r.Client.Cl, previousHeight) +func (r *receiver) NewVerifier(previousHeight int64) (vri IVerifier, err error) { + header, err := r.client.GetBlockHeaderByHeight(r.client.Ctx, r.client.Cl, previousHeight) if err != nil { return nil, err } @@ -90,7 +93,7 @@ func (r *Receiver) NewVerifier(previousHeight int64) (vri IVerifier, err error) return nil, err } - chainIdHash, err := r.Client.Cl.GetChainId(r.Client.Ctx) + chainIdHash, err := r.client.Cl.GetChainId(r.client.Ctx) if err != nil { return nil, err } From 6cb10cdcc7cb0401029bff437cb7c18f87f2defd Mon Sep 17 00:00:00 2001 From: icondev22 Date: Mon, 20 Mar 2023 14:34:35 +0545 Subject: [PATCH 007/211] fix: changed src and dst address type from tezos.Address to BTPAddress and added wallet.Wallet parameter in NewSender --- cmd/iconbridge/chain/tezos/sender.go | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/cmd/iconbridge/chain/tezos/sender.go b/cmd/iconbridge/chain/tezos/sender.go index faeff611..014af6f5 100644 --- a/cmd/iconbridge/chain/tezos/sender.go +++ b/cmd/iconbridge/chain/tezos/sender.go @@ -1,14 +1,16 @@ package tezos import ( - "github.com/icon-project/icon-bridge/cmd/iconbridge/chain" "context" "encoding/json" "fmt" - "log" "math/big" "time" + "github.com/icon-project/icon-bridge/cmd/iconbridge/chain" + "github.com/icon-project/icon-bridge/common/log" + "github.com/icon-project/icon-bridge/common/wallet" + // "blockwatch.cc/tzgo/codec" "blockwatch.cc/tzgo/contract" "blockwatch.cc/tzgo/micheline" @@ -40,19 +42,24 @@ type sender struct { } func NewSender( - src, dst tezos.Address, - urls []string, + src, dst chain.BTPAddress, + urls []string, w wallet.Wallet, rawOpts json.RawMessage, l log.Logger) (chain.Sender, error) { var err error + srcAddr := tezos.MustParseAddress(src.String()) + + dstAddr := tezos.MustParseAddress(dst.String()) + s := &sender { log: l, - src: src, - dst: dst, + src: srcAddr, + dst: dstAddr, } + if len(urls) == 0 { return nil, fmt.Errorf("Empty url") } - s.cls, err = NewClient(urls[0], src, l) + s.cls, err = NewClient(urls[0], srcAddr, l) if err != nil { return nil, err } From dfb5567c51501b84369b028262eaa666d14094bb Mon Sep 17 00:00:00 2001 From: icondev22 Date: Mon, 20 Mar 2023 14:36:00 +0545 Subject: [PATCH 008/211] feat: added new file for registering into icon-bridge --- cmd/iconbridge/chain/tezos/register_relay.go | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 cmd/iconbridge/chain/tezos/register_relay.go diff --git a/cmd/iconbridge/chain/tezos/register_relay.go b/cmd/iconbridge/chain/tezos/register_relay.go new file mode 100644 index 00000000..9316306c --- /dev/null +++ b/cmd/iconbridge/chain/tezos/register_relay.go @@ -0,0 +1,8 @@ +package tezos + +import "github.com/icon-project/icon-bridge/cmd/iconbridge/relay" + +func init() { + relay.Senders["tz"] = NewSender + relay.Receivers["tz"] = NewReceiver +} From 5c57c720f5155416c5748862b5da4a82a04d08ac Mon Sep 17 00:00:00 2001 From: Anatehc Date: Tue, 21 Mar 2023 10:24:01 +0545 Subject: [PATCH 009/211] feat: transfer functions --- smartpy/bts/contracts/src/BTSCore.py | 66 +++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/smartpy/bts/contracts/src/BTSCore.py b/smartpy/bts/contracts/src/BTSCore.py index 7f77e4bc..0d936089 100644 --- a/smartpy/bts/contracts/src/BTSCore.py +++ b/smartpy/bts/contracts/src/BTSCore.py @@ -205,7 +205,71 @@ def getAccumulatedFees(): _accumulatedFees[i] = Types.Asset(self.data.coinsName[i], aggregationFee[self.data.coinsName[i]) sp.result(_accumulatedFees) -@sp.add_test(name="Calculator") + @sp.entry_point() + def transferNativeCoin (self, _to): + #TODO: confirm data type for + check_transfer_restrictions = sp.contract(sp.string,sp.address,sp.nat, self.data.btsPeriphery_contract_address,"checkTransferRestrictions").open_some() + sp.transfer(self.data.nativeCoinName,sp.sender, sp.amount) + # Aggregation Fee will be charged on BSH Contract + # `fixedFee` is introduced as charging fee + # charge_amt = fixedFee + msg.value * feeNumerator / FEE_DENOMINATOR + charge_amt = sp.amount + * self.data.coinDetails[self.data.nativeCoinName].feeNumerator + //self.FEE_DENOMINATOR + + self.data.coinDetails[self.data.nativeCoinName].fixedFee + + # @dev msg.value is an amount request to transfer (include fee) + # Later on, it will be calculated a true amount that should be received at a destination + sendServiceMessage(sp.sender, _to, self.data.coinsName[0],sp.amount, charge_amt) + + @sp.entry_point() + def transfer(self, coin_name, value, _to): + sp.verify(coin_name == self.data.nativeCoinName, message="InvalidWrappedCoin") + _fa2_address = self.data.coins[_coinName] + sp.verify(_fa2_address != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), message= "CoinNotRegistered") + #TODO: confirm data type for + check_transfer_restrictions = sp.contract(sp.string,sp.address,sp.nat, self.data.btsPeriphery_contract_address,"checkTransferRestrictions").open_some() + sp.transfer(self.data.nativeCoinName,sp.sender, sp.amount) + charge_amt = sp.amount + * self.data.coinDetails[self.data.nativeCoinName].feeNumerator + //self.FEE_DENOMINATOR + + self.data.coinDetails[self.data.nativeCoinName].fixedFee + #TODO: implement transferFrom function of fa2contract + sendServiceMessage(sp.sender, _to, self.data.coinsName[0],sp.amount, charge_amt) + + @sp.entry_point() + def transferNativeCoin (self, _to): + #TODO: confirm data type for + check_transfer_restrictions = sp.contract(sp.string,sp.address,sp.nat, self.data.btsPeriphery_contract_address,"checkTransferRestrictions").open_some() + sp.transfer(self.data.nativeCoinName,sp.sender, sp.amount) + # Aggregation Fee will be charged on BSH Contract + # `fixedFee` is introduced as charging fee + # charge_amt = fixedFee + msg.value * feeNumerator / FEE_DENOMINATOR + charge_amt = sp.amount + * self.data.coinDetails[self.data.nativeCoinName].feeNumerator + //self.FEE_DENOMINATOR + + self.data.coinDetails[self.data.nativeCoinName].fixedFee + + # @dev msg.value is an amount request to transfer (include fee) + # Later on, it will be calculated a true amount that should be received at a destination + sendServiceMessage(sp.sender, _to, self.data.coinsName[0],sp.amount, charge_amt) + + @sp.entry_point() + def transfer(self, coin_name, value, _to): + sp.verify(coin_name == self.data.nativeCoinName, message="InvalidWrappedCoin") + _fa2_address = self.data.coins[_coinName] + sp.verify(_fa2_address != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), message= "CoinNotRegistered") + #TODO: confirm data type for + check_transfer_restrictions = sp.contract(sp.string,sp.address,sp.nat, self.data.btsPeriphery_contract_address,"checkTransferRestrictions").open_some() + sp.transfer(self.data.nativeCoinName,sp.sender, sp.amount) + charge_amt = sp.amount + * self.data.coinDetails[self.data.nativeCoinName].feeNumerator + //self.FEE_DENOMINATOR + + self.data.coinDetails[self.data.nativeCoinName].fixedFee + #TODO: implement transferFrom function of fa2contract + sendServiceMessage(sp.sender, _to, self.data.coinsName[0],sp.amount, charge_amt) + +@sp.add_test(name="BTSCore") def test(): c1 = BTSCore( ownerManager_address=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), From 510ca49eebffce0249775091c6cdb9c50e329b9f Mon Sep 17 00:00:00 2001 From: Anatehc Date: Tue, 21 Mar 2023 10:26:32 +0545 Subject: [PATCH 010/211] fix: remove redundant function --- smartpy/bts/contracts/src/BTSCore.py | 32 ---------------------------- 1 file changed, 32 deletions(-) diff --git a/smartpy/bts/contracts/src/BTSCore.py b/smartpy/bts/contracts/src/BTSCore.py index 0d936089..36079c4e 100644 --- a/smartpy/bts/contracts/src/BTSCore.py +++ b/smartpy/bts/contracts/src/BTSCore.py @@ -205,38 +205,6 @@ def getAccumulatedFees(): _accumulatedFees[i] = Types.Asset(self.data.coinsName[i], aggregationFee[self.data.coinsName[i]) sp.result(_accumulatedFees) - @sp.entry_point() - def transferNativeCoin (self, _to): - #TODO: confirm data type for - check_transfer_restrictions = sp.contract(sp.string,sp.address,sp.nat, self.data.btsPeriphery_contract_address,"checkTransferRestrictions").open_some() - sp.transfer(self.data.nativeCoinName,sp.sender, sp.amount) - # Aggregation Fee will be charged on BSH Contract - # `fixedFee` is introduced as charging fee - # charge_amt = fixedFee + msg.value * feeNumerator / FEE_DENOMINATOR - charge_amt = sp.amount - * self.data.coinDetails[self.data.nativeCoinName].feeNumerator - //self.FEE_DENOMINATOR - + self.data.coinDetails[self.data.nativeCoinName].fixedFee - - # @dev msg.value is an amount request to transfer (include fee) - # Later on, it will be calculated a true amount that should be received at a destination - sendServiceMessage(sp.sender, _to, self.data.coinsName[0],sp.amount, charge_amt) - - @sp.entry_point() - def transfer(self, coin_name, value, _to): - sp.verify(coin_name == self.data.nativeCoinName, message="InvalidWrappedCoin") - _fa2_address = self.data.coins[_coinName] - sp.verify(_fa2_address != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), message= "CoinNotRegistered") - #TODO: confirm data type for - check_transfer_restrictions = sp.contract(sp.string,sp.address,sp.nat, self.data.btsPeriphery_contract_address,"checkTransferRestrictions").open_some() - sp.transfer(self.data.nativeCoinName,sp.sender, sp.amount) - charge_amt = sp.amount - * self.data.coinDetails[self.data.nativeCoinName].feeNumerator - //self.FEE_DENOMINATOR - + self.data.coinDetails[self.data.nativeCoinName].fixedFee - #TODO: implement transferFrom function of fa2contract - sendServiceMessage(sp.sender, _to, self.data.coinsName[0],sp.amount, charge_amt) - @sp.entry_point() def transferNativeCoin (self, _to): #TODO: confirm data type for From 1c02d174cf45030311a003f5309ab5beafd2834a Mon Sep 17 00:00:00 2001 From: simusud Date: Tue, 28 Mar 2023 17:22:30 +0545 Subject: [PATCH 011/211] feat(bmc): Add bmc periphery functions and libraries --- smartpy/bmc/compile.sh | 77 ++ smartpy/bmc/config/config.ts | 20 + smartpy/bmc/contracts/src/String.py | 46 + smartpy/bmc/contracts/src/Types.py | 90 ++ smartpy/bmc/contracts/src/bmc_periphery.py | 295 ++++ smartpy/bmc/package-lock.json | 1429 ++++++++++++++++++++ smartpy/bmc/package.json | 25 + 7 files changed, 1982 insertions(+) create mode 100755 smartpy/bmc/compile.sh create mode 100644 smartpy/bmc/config/config.ts create mode 100644 smartpy/bmc/contracts/src/String.py create mode 100644 smartpy/bmc/contracts/src/Types.py create mode 100644 smartpy/bmc/contracts/src/bmc_periphery.py create mode 100644 smartpy/bmc/package-lock.json create mode 100644 smartpy/bmc/package.json diff --git a/smartpy/bmc/compile.sh b/smartpy/bmc/compile.sh new file mode 100755 index 00000000..6a4c3b17 --- /dev/null +++ b/smartpy/bmc/compile.sh @@ -0,0 +1,77 @@ + +#!/usr/bin/env bash + +set -e -o pipefail + +echo "----------------------------------------" +echo "Compiling contracts ... " +echo "----------------------------------------" + +# Expected location of SmartPy CLI. +SMART_PY_CLI=~/smartpy-cli/SmartPy.sh + +# Build artifact directory. +OUT_DIR=./contracts/build/.contract_build + +# Array of SmartPy files to compile. +# CONTRACTS_ARRAY=(counter) + +# Exit if SmartPy is not installed. +if [ ! -f "$SMART_PY_CLI" ]; then + echo "Fatal: Please install SmartPy CLI at $SMART_PY_CLI" && exit +fi + +function processContract { + CONTRACT_NAME=$1 + OUT_DIR=$2 + CONTRACT_IN="./contracts/src/${CONTRACT_NAME}.py" + CONTRACT_OUT="${CONTRACT_NAME}.json" + STORAGE_OUT="${CONTRACT_NAME}_storage.json" + CONTRACT_COMPILED="${CONTRACT_NAME}/step_000_cont_0_contract.json" + STORAGE_COMPILED="${CONTRACT_NAME}/step_000_cont_0_storage.json" + + echo ">> Processing ${CONTRACT_NAME}" + + # Ensure file exists. + if [ ! -f "$CONTRACT_IN" ]; then + echo "Fatal: $CONTRACT_IN not found. Running from wrong dir?" && exit + fi + + echo ">>> [1 / 3] Testing ${CONTRACT_NAME} ... " + $SMART_PY_CLI test $CONTRACT_IN $OUT_DIR --html + + echo ">>> [2 / 3] Compiling ${CONTRACT_NAME} ..." + $SMART_PY_CLI compile $CONTRACT_IN $OUT_DIR --html + + echo ">>> [3 / 3] Extracting Michelson contract ... " + cp $OUT_DIR/$CONTRACT_COMPILED ./contracts/build/$CONTRACT_OUT + cp $OUT_DIR/$STORAGE_COMPILED ./contracts/build/$STORAGE_OUT + + echo ">>> Michelson contract written to ${CONTRACT_OUT}" +} + +export PYTHONPATH=$PWD + + +echo "> [1 / 2] Unit Testing and Compiling Contracts." +# Use if you want to pass a contract or more as arguments. +for n in $(seq 1 $#); do + processContract $1 $OUT_DIR + shift +done + +# Use if you want to compile all contracts in CONTRACTS_ARRAY. No arguments needed. +# for i in ${!CONTRACTS_ARRAY[@]}; do +# processContract ${CONTRACTS_ARRAY[$i]} $OUT_DIR +# done + +# Remove build artifacts. +echo "> [2 / 2] Cleaning up ..." +rm -rf $OUT_DIR +rm -rf ./contracts/__pycache__ +rm -rf ./__pycache__ + + +echo "> Removed artifacts." + +echo "> Compilation successful." \ No newline at end of file diff --git a/smartpy/bmc/config/config.ts b/smartpy/bmc/config/config.ts new file mode 100644 index 00000000..2dc56ea2 --- /dev/null +++ b/smartpy/bmc/config/config.ts @@ -0,0 +1,20 @@ +// List your config files here + +export const NETWORK = { + GHOSTNET: { + name: "ghostnet", + url: "https://ghostnet.smartpy.io", + }, + KATHMANDUNET: { + name: "kathmandunet", + url: "https://kathmandunet.smartpy.io", + }, + JAKARTANET: { + name: "jakartanet", + url: "https://jakartanet.smartpy.io", + }, + MAINNET: { + name: "mainnet", + url: "https://mainnet.smartpy.io", + }, +}; diff --git a/smartpy/bmc/contracts/src/String.py b/smartpy/bmc/contracts/src/String.py new file mode 100644 index 00000000..2fb8277c --- /dev/null +++ b/smartpy/bmc/contracts/src/String.py @@ -0,0 +1,46 @@ +import smartpy as sp + + + +def split_btp_address(base): + """ + Split the BTP Address format i.e. btp://1234.iconee/0x123456789 + into Network_address (1234.iconee) and Server_address (0x123456789) + :param base: String base BTP Address format to be split + :return: The resulting strings of Network_address and Server_address + """ + sp.set_type(base, sp.TString) + + # sep = sp.local("sep", "/") + prev_idx = sp.local("prev_idx", 0) + result = sp.local("result", []) + sp.for idx in sp.range(0, sp.len(base)): + sp.if sp.slice(base, idx, 1).open_some() == "/": + result.value.push(sp.slice(base, prev_idx.value, sp.as_nat(idx - prev_idx.value)).open_some()) + prev_idx.value = idx + 1 + sp.if sp.len(base) > 0: + result.value.push(sp.slice(base, prev_idx.value, sp.as_nat(sp.len(base) - prev_idx.value)).open_some()) + + inverted_list = sp.local("my_list", result.value) + last = sp.local("last", "") + penultimate = sp.local("penultimate", "") + + with sp.match_cons(inverted_list.value) as l: + last.value = l.head + inverted_list.value = l.tail + with sp.else_(): + sp.failwith("Empty list") + + + with sp.match_cons(inverted_list.value) as l: + penultimate.value = l.head + with sp.else_(): + sp.failwith("Only one element") + + return sp.pair(last.value, penultimate.value) + + + + + + diff --git a/smartpy/bmc/contracts/src/Types.py b/smartpy/bmc/contracts/src/Types.py new file mode 100644 index 00000000..d122e760 --- /dev/null +++ b/smartpy/bmc/contracts/src/Types.py @@ -0,0 +1,90 @@ +import smartpy as sp + + +class Types: + + MessageEvent = sp.TRecord( + next_bmc=sp.TString, + seq=sp.TNat, + message=sp.TBytes + ) + + ReceiptProof = sp.TRecord( + index=sp.TNat, + events=sp.TList(MessageEvent), + height=sp.TNat + ) + + BMCMessage = sp.TRecord( + src=sp.TString, + dst=sp.TString, + svc=sp.TString, + sn=sp.TNat, + message=sp.TBytes + ) + + MessageEvent = sp.TRecord( + next_bmc=sp.TString, + seq=sp.TNat, + message=sp.TBytes + ) + + Response = sp.TRecord( + code=sp.TNat, + message=sp.TString + ) + + Route = sp.TRecord( + dst=sp.TString, + next=sp.TString + ) + + Link = sp.TRecord( + relays=sp.TMap(sp.TNat, sp.TAddress), + reachable=sp.TMap(sp.TNat, sp.TString), + rx_seq=sp.TNat, + tx_seq=sp.TNat, + block_interval_src=sp.TNat, + block_interval_dst=sp.TNat, + max_aggregation=sp.TNat, + delay_limit=sp.TNat, + relay_idx=sp.TNat, + rotate_height=sp.TNat, + rx_height=sp.TNat, + rx_height_src=sp.TNat, + is_connected=sp.TBool + ) + + LinkStats = sp.TRecord( + rx_seq=sp.TNat, + tx_seq=sp.TNat, + rx_height=sp.TNat, + current_height=sp.TNat + ) + + BMCService = sp.TRecord( + serviceType=sp.TString, + payload=sp.TBytes + ) + + GatherFeeMessage = sp.TRecord( + fa=sp.TString, + svcs=sp.TMap(sp.TNat, sp.TString) + ) + + RelayStats = sp.TRecord( + addr=sp.TAddress, + block_count=sp.TNat, + msg_count=sp.TNat + ) + + Tuple = sp.TRecord( + prev=sp.TString, + to=sp.TString + ) + + Service = sp.TRecord( + svc=sp.TString, + addr=sp.TAddress + ) + diff --git a/smartpy/bmc/contracts/src/bmc_periphery.py b/smartpy/bmc/contracts/src/bmc_periphery.py new file mode 100644 index 00000000..d1cdcc91 --- /dev/null +++ b/smartpy/bmc/contracts/src/bmc_periphery.py @@ -0,0 +1,295 @@ +import smartpy as sp + +types = sp.io.import_script_from_url("file:./contracts/src/Types.py") +strings = sp.io.import_script_from_url("file:./contracts/src/String.py") + + +class BMCPreiphery(sp.Contract): + BMC_ERR = sp.nat(10) + BSH_ERR = sp.nat(40) + UNKNOWN_ERR = sp.nat(0) + + BMCRevertUnauthorized = sp.string("Unauthorized") + BMCRevertParseFailure = sp.string("ParseFailure") + BMCRevertNotExistsBSH = sp.string("NotExistsBSH") + BMCRevertNotExistsLink = sp.string("NotExistsLink") + BMCRevertInvalidSn = sp.string("InvalidSn") + BMCRevertInvalidSeqNumber = sp.string("InvalidSeqNumber") + BMCRevertNotExistsInternalHandler = sp.string("NotExistsInternalHandler") + BMCRevertUnknownHandleBTPError = sp.string("UnknownHandleBTPError") + BMCRevertUnknownHandleBTPMessage = sp.string("UnknownHandleBTPMessage") + + def __init__(self, network, bmc_management_addr): + self.update_initial_storage( + bmc_btp_address=sp.string("btp://") + network + "/" + "jj", + bmc_management=bmc_management_addr + ) + + @sp.onchain_view() + def get_bmc_btp_address(self): + sp.result(self.data.bmc_btp_address) + + def _require_registered_relay(self, prev): + sp.set_type(prev, sp.TString) + + sp.trace(prev) + # relay = sp.view("get_link_relays", self.data.bmc_management, prev, t=sp.TList(sp.TAddress)).open_some() + relay = [] + sp.for x in relay: + sp.if sp.sender == x: + return + sp.fail_with(self.BMCRevertUnauthorized) + + @sp.entry_point + def handle_relay_message(self, prev, msg): + sp.set_type(prev, sp.TString) + sp.set_type(msg, sp.TBytes) + + self._require_registered_relay(prev) + + # link_rx_seq = sp.view("get_link_rx_seq", self.data.bmc_management, prev, t=sp.TNat).open_some() + link_rx_seq= sp.nat(2) + # link_rx_height = sp.view("get_link_rx_height", self.data.bmc_management, prev, t=sp.TNat).open_some() + link_rx_height= sp.nat(3) + + rx_seq = sp.local("rx_seq", link_rx_seq, t=sp.TNat) + rx_height = sp.local("rx_height", link_rx_height, t=sp.TNat) + + # rsp = decodeReceiptProofs(msg) + rps = sp.map({0:sp.record(index=1, events={}, height=3)}) + # bmc_msg = sp.local("bmc_msg") + + # ev = sp.local("ev") + + sp.for i in sp.range(0, sp.len(rps)): + with sp.if_(rps[i].height < rx_height.value): + sp.trace("ggg") + # sp.continue + + rx_height.value = rps[i].height + sp.for j in sp.range(sp.nat(0), sp.len(rps[i].events)): + ev = rps[i].events[j] + sp.verify(ev.next_bmc == self.data.bmc_btp_address, "Invalid Next BMC") + rx_seq.value +=sp.nat(1) + sp.if ev.seq < rx_seq.value: + rx_seq.value = sp.as_nat(rx_seq.value-sp.nat(1)) + # sp.continue + + sp.if ev.seq > rx_seq.value: + sp.failwith(self.BMCRevertInvalidSeqNumber) + # TODO: implement code inside of try catch + + # call update_link_rx_seq on BMCManagement + update_link_rx_seq_args_type = sp.TRecord(prev=sp.TString, val=sp.TNat) + update_link_rx_seq_entry_point = sp.contract(update_link_rx_seq_args_type, + self.data.bmc_management, + "update_link_rx_seq").open_some() + update_link_rx_seq_args = sp.record(prev=prev, val=sp.as_nat(rx_seq.value - link_rx_seq)) + sp.transfer(update_link_rx_seq_args, sp.tez(0), update_link_rx_seq_entry_point) + + # call update_relay_stats on BMCManagement + update_relay_stats_args_type = sp.TRecord(relay=sp.TAddress, block_count_val=sp.TNat, msg_count_val=sp.TNat) + update_relay_stats_entry_point = sp.contract(update_relay_stats_args_type, + self.data.bmc_management, + "update_relay_stats").open_some() + update_relay_stats_args = sp.record(relay=sp.sender, block_count_val=sp.nat(0), msg_count_val=sp.as_nat(rx_seq.value - link_rx_seq)) + sp.transfer(update_relay_stats_args, sp.tez(0), update_relay_stats_entry_point) + + # call update_link_rx_height on BMCManagement + update_link_rx_height_args_type = sp.TRecord(prev=sp.TString, val=sp.TNat) + update_link_rx_height_entry_point = sp.contract(update_link_rx_height_args_type, + self.data.bmc_management, + "update_link_rx_height").open_some() + update_link_rx_height_args = sp.record(prev=prev, val=sp.as_nat(rx_height.value - link_rx_height)) + sp.transfer(update_link_rx_height_args, sp.tez(0), update_link_rx_height_entry_point) + + + def _handle_message(self, prev, msg): + sp.set_type(prev, sp.TString) + sp.set_type(msg, types.Types.BMCMessage) + + bsh_addr = sp.local("bsh_addr",sp.TAddress) + with sp.if_(msg.svc == "bmc"): + sm = self.try_decode_bmc_service(msg.message) + #TODO: implement try catch + + sp.if sm.serviceType == "FeeGathering": + gather_fee = self.try_decode_gather_fee_message(sm.payload) + + sp.for i in sp.range(sp.nat(0), len(gather_fee.svcs)): + bsh_addr = sp.view("get_bsh_service_by_name", self.data.bmc_management, gather_fee.svcs[i], t=sp.TAddress) + + sp.if bsh_addr != "zero_address": + pass + #TODO: call BSH handleFeeGathering + + sp.if sm.serviceType == "Link": + # to = decodePropagateMessage(sm.payload) + to = "to" + link = sp.view("get_link", self.data.bmc_management, prev, t=types.Types.Link).open_some() + + check = sp.local("check", False).value + sp.if link.is_connected: + sp.for i in sp.range(sp.nat(0), len(link.reachable)): + sp.if to == link.reachable[i]: + check = True + # sp.break + + sp.if not check: + links = sp.list([to], t=sp.TString) + + # call update_link_reachable on BMCManagement + update_link_reachable_args_type = sp.TRecord(prev=sp.TString, to=sp.TList(sp.TString)) + update_link_reachable_entry_point = sp.contract(update_link_reachable_args_type, + self.data.bmc_management, + "update_link_reachable").open_some() + update_link_reachable_args = sp.record(prev=prev, to=links) + sp.transfer(update_link_reachable_args, sp.tez(0), update_link_reachable_entry_point) + + sp.if sm.serviceType == "Unlink": + to = decodePropagateMessage(sm.payload) + link = sp.view("get_link", self.data.bmc_management, prev, t=types.Types.Link).open_some() + + sp.if link.is_connected: + sp.for i in sp.range(sp.nat(0), len(link.reachable)): + sp.if to == link.reachable[i]: + + # call delete_link_reachable on BMCManagement + delete_link_reachable_args_type = sp.TRecord(prev=sp.TString, index=sp.TNat) + delete_link_reachable_entry_point = sp.contract(delete_link_reachable_args_type, + self.data.bmc_management, + "delete_link_reachable").open_some() + delete_link_reachable_args = sp.record(prev=prev, to=i) + sp.transfer(delete_link_reachable_args, sp.tez(0), delete_link_reachable_entry_point) + + sp.if sm.serviceType == "Init": + links = decodeInitMessage(sm.payload) + # call update_link_reachable on BMCManagement + update_link_reachable_args_type = sp.TRecord(prev=sp.TString, to=sp.TList(sp.TString)) + update_link_reachable_entry_point = sp.contract(update_link_reachable_args_type, + self.data.bmc_management, + "update_link_reachable").open_some() + update_link_reachable_args = sp.record(prev=prev, to=links) + sp.transfer(update_link_reachable_args, sp.tez(0), update_link_reachable_entry_point) + with sp.else_(): + bsh_addr = sp.view("get_bsh_service_by_name", self.data.bmc_management, msg.svc, t=sp.TAddress) + + sp.if bsh_addr == "zero_address": + self._send_error(prev, msg, self.BMC_ERR, self.BMCRevertNotExistsBSH) + return + + with sp.if_(msg.sn >= sp.nat(0)): + net, = strings.split_btp_address(msg.src) + #TODO: implement try catch, call handleBTPMessage from BSH + + + with sp.else_(): + res = decodeResponse(msg.message) + # TODO: implement try catch, call handleBTPError from BSH + + + def try_decode_btp_message(self, rlp): + return decodeBMCMessage(rpl) + + def try_decode_bmc_service(self, msg): + return decodeBMCService(msg) + + def try_decode_gather_fee_message(self, msg): + return decodeGatherFeeMessage(msg) + + def _send_message(self, to ,serialized_msg): + sp.set_type(to, sp.TString) + sp.set_type(serialized_msg, sp.TBytes) + + # call update_link_tx_seq on BMCManagement + update_link_tx_seq_args_type = sp.TRecord(prev=sp.TString) + update_link_tx_seq_entry_point = sp.contract(update_link_tx_seq_args_type, + self.data.bmc_management, + "update_link_tx_seq").open_some() + update_link_tx_seq_args = sp.record(prev=to) + sp.transfer(update_link_tx_seq_args, sp.tez(0), update_link_tx_seq_entry_point) + + sp.emit(sp.record(next=to, seq=sp.view("get_link_tx_seq", self.data.bmc_management, to, t=sp.TNat).open_some(), msg=serialized_msg)) + + def _send_error(self, prev, message, err_code, err_msg): + sp.set_type(prev, sp.TString) + sp.set_type(message, types.Types.BMCMessage) + sp.set_type(err_code, sp.TNat) + sp.set_type(err_msg, sp.TString) + + if message.sn > sp.nat(0): + serialized_msg = encode_bmc_message(sp.record( + src=self.data.bmc_btp_address, + dst=message.src, + svc=message.svc, + sn=message.sn * - sp.nat(1), + message=encode_response(sp.record(code=err_code, message=err_msg)) + )) + self._send_message(prev, serialized_msg) + + @sp.entry_point + def send_message(self, to, svc, sn, msg): + """ + Send the message to a specific network + :param to: Network Address of destination network + :param svc: Name of the service + :param sn: Serial number of the message, it should be positive + :param msg: Serialized bytes of Service Message + :return: + """ + sp.set_type(to, sp.TString) + sp.set_type(svc, sp.TString) + sp.set_type(sn, sp.TNat) + sp.set_type(msg, sp.TBytes) + + sp.verify((sp.sender == self.data.bmc_management) | + (sp.view("get_bsh_service_by_name", self.data.bmc_management, svc, t=sp.TAddress).open_some() == sp.sender), + self.BMCRevertUnauthorized) + sp.verify(sn >= sp.nat(0), self.BMCRevertInvalidSn) + + next_link, dst = sp.match_pair(sp.view("resolve_route", self.data.bmc_management, to, t=sp.TPair(sp.TString, sp.TString)).open_some()) + + # need to import encode_bmc_message from library + # rlp = encode_bmc_message(sp.record( + # src=self.data.bmc_btp_address, + # dst=dst, + # svc=svc, + # sn=sn, + # message=msg + # )) + next_link = "next_link" + rlp = sp.bytes("0x0dae11") + self._send_message(next_link, rlp) + + @sp.onchain_view() + def get_status(self, _link): + """ + Get status of BMC + :param link: BTP Address of the connected BMC + :return: + """ + + link = sp.view("get_link", self.data.bmc_management, _link, t=types.Types.Link).open_some() + sp.verify(link.is_connected == True, self.BMCRevertNotExistsLink) + + sp.result(sp.record( + rx_seq=link.rx_seq, + tx_seq=link.tx_seq, + rx_height=link.rx_height, + current_height=sp.level #block height + )) + +@sp.add_test(name="BMC") +def test(): + alice = sp.test_account("Alice") + bmc_management = sp.test_account("BMC Management") + # bmc= sp.test_account("BMC") + + scenario = sp.test_scenario() + bmc = BMCPreiphery("tezos", bmc_management.address) + scenario += bmc + + bmc.handle_relay_message(sp.record(prev="demo string", msg=sp.bytes("0x0dae11"))).run(sender=alice) + +sp.add_compilation_target("bmc_periphery", BMCPreiphery(network="tezos", + bmc_management_addr=sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"))) diff --git a/smartpy/bmc/package-lock.json b/smartpy/bmc/package-lock.json new file mode 100644 index 00000000..13756c6c --- /dev/null +++ b/smartpy/bmc/package-lock.json @@ -0,0 +1,1429 @@ +{ + "name": "create-tezos-app", + "version": "1.0.3", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "create-tezos-app", + "version": "1.0.3", + "license": "MIT", + "dependencies": { + "@taquito/signer": "^14.0.0", + "@taquito/taquito": "^14.0.0", + "dotenv": "^16.0.3", + "ts-node": "^10.9.1" + }, + "bin": { + "create-tezos-app": "bin/cli.js" + }, + "devDependencies": { + "typescript": "^4.8.4" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@stablelib/binary": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/binary/-/binary-1.0.1.tgz", + "integrity": "sha512-ClJWvmL6UBM/wjkvv/7m5VP3GMr9t0osr4yVgLZsLCOz4hGN9gIAFEqnJ0TsSMAN+n840nf2cHZnA5/KFqHC7Q==", + "dependencies": { + "@stablelib/int": "^1.0.1" + } + }, + "node_modules/@stablelib/blake2b": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/blake2b/-/blake2b-1.0.1.tgz", + "integrity": "sha512-B3KyKoBAjkIFeH7romcF96i+pVFYk7K2SBQ1pZvaxV+epSBXJ+n0C66esUhyz6FF+5FbdQVm77C5fzGFcEZpKA==", + "dependencies": { + "@stablelib/binary": "^1.0.1", + "@stablelib/hash": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@stablelib/bytes": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/bytes/-/bytes-1.0.1.tgz", + "integrity": "sha512-Kre4Y4kdwuqL8BR2E9hV/R5sOrUj6NanZaZis0V6lX5yzqC3hBuVSDXUIBqQv/sCpmuWRiHLwqiT1pqqjuBXoQ==" + }, + "node_modules/@stablelib/constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/constant-time/-/constant-time-1.0.1.tgz", + "integrity": "sha512-tNOs3uD0vSJcK6z1fvef4Y+buN7DXhzHDPqRLSXUel1UfqMB1PWNsnnAezrKfEwTLpN0cGH2p9NNjs6IqeD0eg==" + }, + "node_modules/@stablelib/ed25519": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@stablelib/ed25519/-/ed25519-1.0.3.tgz", + "integrity": "sha512-puIMWaX9QlRsbhxfDc5i+mNPMY+0TmQEskunY1rZEBPi1acBCVQAhnsk/1Hk50DGPtVsZtAWQg4NHGlVaO9Hqg==", + "dependencies": { + "@stablelib/random": "^1.0.2", + "@stablelib/sha512": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@stablelib/hash": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/hash/-/hash-1.0.1.tgz", + "integrity": "sha512-eTPJc/stDkdtOcrNMZ6mcMK1e6yBbqRBaNW55XA1jU8w/7QdnCF0CmMmOD1m7VSkBR44PWrMHU2l6r8YEQHMgg==" + }, + "node_modules/@stablelib/int": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/int/-/int-1.0.1.tgz", + "integrity": "sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w==" + }, + "node_modules/@stablelib/keyagreement": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/keyagreement/-/keyagreement-1.0.1.tgz", + "integrity": "sha512-VKL6xBwgJnI6l1jKrBAfn265cspaWBPAPEc62VBQrWHLqVgNRE09gQ/AnOEyKUWrrqfD+xSQ3u42gJjLDdMDQg==", + "dependencies": { + "@stablelib/bytes": "^1.0.1" + } + }, + "node_modules/@stablelib/nacl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@stablelib/nacl/-/nacl-1.0.4.tgz", + "integrity": "sha512-PJ2U/MrkXSKUM8C4qFs87WeCNxri7KQwR8Cdwm9q2sweGuAtTvOJGuW0F3N+zn+ySLPJA98SYWSSpogMJ1gCmw==", + "dependencies": { + "@stablelib/poly1305": "^1.0.1", + "@stablelib/random": "^1.0.2", + "@stablelib/wipe": "^1.0.1", + "@stablelib/x25519": "^1.0.3", + "@stablelib/xsalsa20": "^1.0.2" + } + }, + "node_modules/@stablelib/poly1305": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/poly1305/-/poly1305-1.0.1.tgz", + "integrity": "sha512-1HlG3oTSuQDOhSnLwJRKeTRSAdFNVB/1djy2ZbS35rBSJ/PFqx9cf9qatinWghC2UbfOYD8AcrtbUQl8WoxabA==", + "dependencies": { + "@stablelib/constant-time": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@stablelib/random": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@stablelib/random/-/random-1.0.2.tgz", + "integrity": "sha512-rIsE83Xpb7clHPVRlBj8qNe5L8ISQOzjghYQm/dZ7VaM2KHYwMW5adjQjrzTZCchFnNCNhkwtnOBa9HTMJCI8w==", + "dependencies": { + "@stablelib/binary": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@stablelib/salsa20": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@stablelib/salsa20/-/salsa20-1.0.2.tgz", + "integrity": "sha512-nfjKzw0KTKrrKBasEP+j7UP4I8Xudom8lVZIBCp0kQNARXq72IlSic0oabg2FC1NU68L4RdHrNJDd8bFwrphYA==", + "dependencies": { + "@stablelib/binary": "^1.0.1", + "@stablelib/constant-time": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@stablelib/sha512": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/sha512/-/sha512-1.0.1.tgz", + "integrity": "sha512-13gl/iawHV9zvDKciLo1fQ8Bgn2Pvf7OV6amaRVKiq3pjQ3UmEpXxWiAfV8tYjUpeZroBxtyrwtdooQT/i3hzw==", + "dependencies": { + "@stablelib/binary": "^1.0.1", + "@stablelib/hash": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@stablelib/wipe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/wipe/-/wipe-1.0.1.tgz", + "integrity": "sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg==" + }, + "node_modules/@stablelib/x25519": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@stablelib/x25519/-/x25519-1.0.3.tgz", + "integrity": "sha512-KnTbKmUhPhHavzobclVJQG5kuivH+qDLpe84iRqX3CLrKp881cF160JvXJ+hjn1aMyCwYOKeIZefIH/P5cJoRw==", + "dependencies": { + "@stablelib/keyagreement": "^1.0.1", + "@stablelib/random": "^1.0.2", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@stablelib/xsalsa20": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@stablelib/xsalsa20/-/xsalsa20-1.0.2.tgz", + "integrity": "sha512-7XdBGbcNgBShmuhDXv1G1WPVCkjZdkb1oPMzSidO7Fve0MHntH6TjFkj5bfLI+aRE+61weO076vYpP/jmaAYog==", + "dependencies": { + "@stablelib/binary": "^1.0.1", + "@stablelib/salsa20": "^1.0.2", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@taquito/http-utils": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/http-utils/-/http-utils-14.0.0.tgz", + "integrity": "sha512-ZWZzod/+/OEE26b9CnDRjHGfUKBJft3aXv/e/A9bTHAtvRNJqGIhofHcDg/jTaolBMarCF2b3XBYw35aOOSk4A==", + "dependencies": { + "axios": "^0.26.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@taquito/local-forging": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/local-forging/-/local-forging-14.0.0.tgz", + "integrity": "sha512-Nm0xGmS1Jzd+tU0a/8Y8XuTghbiPBgHDLo+e4141TK3OAwTzOw0an+w3xK9QVfzvxfIcZBSMjeMZzOwDdiqkJQ==", + "dependencies": { + "@taquito/utils": "^14.0.0", + "bignumber.js": "^9.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@taquito/michel-codec": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/michel-codec/-/michel-codec-14.0.0.tgz", + "integrity": "sha512-ftnBvUVddlHBqvQbGPHEb26KrS4lIcaZ1eIpYJWiz+akb4Pcfyq7j/OEsDZbB7Pl2FP9hqu7ZygOF34zY6Lrtw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@taquito/michelson-encoder": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/michelson-encoder/-/michelson-encoder-14.0.0.tgz", + "integrity": "sha512-KIS+xl4rKfnd6hf9LUr6W+Pb7gv8F/Qsx0fho9CtM2PodKvdef3YlvkpScBUM9QZntAlvq2XQXUVXcZkbvxygw==", + "dependencies": { + "@taquito/rpc": "^14.0.0", + "@taquito/utils": "^14.0.0", + "bignumber.js": "^9.0.2", + "fast-json-stable-stringify": "^2.1.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@taquito/rpc": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/rpc/-/rpc-14.0.0.tgz", + "integrity": "sha512-FMfb80sA+VJwNx8OTNN07boDAt2roISqLLCUgmOIwy/cFDqhII7gdS4aYWJWqlKbdPKCPqh3a3ZQD1X/jyQHOA==", + "dependencies": { + "@taquito/http-utils": "^14.0.0", + "@taquito/utils": "^14.0.0", + "bignumber.js": "^9.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@taquito/signer": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/signer/-/signer-14.0.0.tgz", + "integrity": "sha512-vDqp/quzAsOiVikUt5MYUKhHI3S9qlasazyXs99xK9qpGLotbx6aseKcfb/dkaTo4/eoMzP4XzTVdnk0AqcCkw==", + "dependencies": { + "@stablelib/blake2b": "^1.0.1", + "@stablelib/ed25519": "^1.0.2", + "@stablelib/nacl": "^1.0.3", + "@taquito/taquito": "^14.0.0", + "@taquito/utils": "^14.0.0", + "elliptic": "^6.5.4", + "pbkdf2": "^3.1.2", + "typedarray-to-buffer": "^4.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@taquito/taquito": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/taquito/-/taquito-14.0.0.tgz", + "integrity": "sha512-JaXfvqOCF3dkwXxhe00Ravb8WLMC2VqJxerf4GrGUEpJw+NAkwbGEb8k/52+MQQdlxMPepZdPPru/HM3nFG0Tw==", + "hasInstallScript": true, + "dependencies": { + "@taquito/http-utils": "^14.0.0", + "@taquito/local-forging": "^14.0.0", + "@taquito/michel-codec": "^14.0.0", + "@taquito/michelson-encoder": "^14.0.0", + "@taquito/rpc": "^14.0.0", + "@taquito/utils": "^14.0.0", + "bignumber.js": "^9.0.2", + "rxjs": "^6.6.3" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@taquito/utils": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/utils/-/utils-14.0.0.tgz", + "integrity": "sha512-0RSHn/CzbcbMdldJJIlXyxOvAajwmL6iPKJ6NaRyYJqqLM2CxYjG72KpXVv716pCMV1MbIWsOAr9FKbxW73PsA==", + "dependencies": { + "@stablelib/blake2b": "^1.0.1", + "@stablelib/ed25519": "^1.0.2", + "@types/bs58check": "^2.1.0", + "bignumber.js": "^9.0.2", + "blakejs": "^1.2.1", + "bs58check": "^2.1.2", + "buffer": "^6.0.3", + "elliptic": "^6.5.4", + "typedarray-to-buffer": "^4.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==" + }, + "node_modules/@types/bs58check": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/bs58check/-/bs58check-2.1.0.tgz", + "integrity": "sha512-OxsysnJQh82vy9DRbOcw9m2j/WiyqZLn0YBhKxdQ+aCwoHj+tWzyCgpwAkr79IfDXZKxc6h7k89T9pwS78CqTQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "18.11.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", + "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==" + }, + "node_modules/acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "node_modules/axios": { + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "dependencies": { + "follow-redirects": "^1.14.8" + } + }, + "node_modules/base-x": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", + "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bignumber.js": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.0.tgz", + "integrity": "sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==", + "engines": { + "node": "*" + } + }, + "node_modules/blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==" + }, + "node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + }, + "node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "dependencies": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/typedarray-to-buffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-4.0.0.tgz", + "integrity": "sha512-6dOYeZfS3O9RtRD1caom0sMxgK59b27+IwoNy8RDPsmslSGOyU+mpTamlaIW7aNKi90ZQZ9DFaZL3YRoiSCULQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/typescript": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "engines": { + "node": ">=6" + } + } + }, + "dependencies": { + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "requires": { + "@jridgewell/trace-mapping": "0.3.9" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + }, + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@stablelib/binary": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/binary/-/binary-1.0.1.tgz", + "integrity": "sha512-ClJWvmL6UBM/wjkvv/7m5VP3GMr9t0osr4yVgLZsLCOz4hGN9gIAFEqnJ0TsSMAN+n840nf2cHZnA5/KFqHC7Q==", + "requires": { + "@stablelib/int": "^1.0.1" + } + }, + "@stablelib/blake2b": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/blake2b/-/blake2b-1.0.1.tgz", + "integrity": "sha512-B3KyKoBAjkIFeH7romcF96i+pVFYk7K2SBQ1pZvaxV+epSBXJ+n0C66esUhyz6FF+5FbdQVm77C5fzGFcEZpKA==", + "requires": { + "@stablelib/binary": "^1.0.1", + "@stablelib/hash": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "@stablelib/bytes": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/bytes/-/bytes-1.0.1.tgz", + "integrity": "sha512-Kre4Y4kdwuqL8BR2E9hV/R5sOrUj6NanZaZis0V6lX5yzqC3hBuVSDXUIBqQv/sCpmuWRiHLwqiT1pqqjuBXoQ==" + }, + "@stablelib/constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/constant-time/-/constant-time-1.0.1.tgz", + "integrity": "sha512-tNOs3uD0vSJcK6z1fvef4Y+buN7DXhzHDPqRLSXUel1UfqMB1PWNsnnAezrKfEwTLpN0cGH2p9NNjs6IqeD0eg==" + }, + "@stablelib/ed25519": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@stablelib/ed25519/-/ed25519-1.0.3.tgz", + "integrity": "sha512-puIMWaX9QlRsbhxfDc5i+mNPMY+0TmQEskunY1rZEBPi1acBCVQAhnsk/1Hk50DGPtVsZtAWQg4NHGlVaO9Hqg==", + "requires": { + "@stablelib/random": "^1.0.2", + "@stablelib/sha512": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "@stablelib/hash": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/hash/-/hash-1.0.1.tgz", + "integrity": "sha512-eTPJc/stDkdtOcrNMZ6mcMK1e6yBbqRBaNW55XA1jU8w/7QdnCF0CmMmOD1m7VSkBR44PWrMHU2l6r8YEQHMgg==" + }, + "@stablelib/int": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/int/-/int-1.0.1.tgz", + "integrity": "sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w==" + }, + "@stablelib/keyagreement": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/keyagreement/-/keyagreement-1.0.1.tgz", + "integrity": "sha512-VKL6xBwgJnI6l1jKrBAfn265cspaWBPAPEc62VBQrWHLqVgNRE09gQ/AnOEyKUWrrqfD+xSQ3u42gJjLDdMDQg==", + "requires": { + "@stablelib/bytes": "^1.0.1" + } + }, + "@stablelib/nacl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@stablelib/nacl/-/nacl-1.0.4.tgz", + "integrity": "sha512-PJ2U/MrkXSKUM8C4qFs87WeCNxri7KQwR8Cdwm9q2sweGuAtTvOJGuW0F3N+zn+ySLPJA98SYWSSpogMJ1gCmw==", + "requires": { + "@stablelib/poly1305": "^1.0.1", + "@stablelib/random": "^1.0.2", + "@stablelib/wipe": "^1.0.1", + "@stablelib/x25519": "^1.0.3", + "@stablelib/xsalsa20": "^1.0.2" + } + }, + "@stablelib/poly1305": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/poly1305/-/poly1305-1.0.1.tgz", + "integrity": "sha512-1HlG3oTSuQDOhSnLwJRKeTRSAdFNVB/1djy2ZbS35rBSJ/PFqx9cf9qatinWghC2UbfOYD8AcrtbUQl8WoxabA==", + "requires": { + "@stablelib/constant-time": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "@stablelib/random": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@stablelib/random/-/random-1.0.2.tgz", + "integrity": "sha512-rIsE83Xpb7clHPVRlBj8qNe5L8ISQOzjghYQm/dZ7VaM2KHYwMW5adjQjrzTZCchFnNCNhkwtnOBa9HTMJCI8w==", + "requires": { + "@stablelib/binary": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "@stablelib/salsa20": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@stablelib/salsa20/-/salsa20-1.0.2.tgz", + "integrity": "sha512-nfjKzw0KTKrrKBasEP+j7UP4I8Xudom8lVZIBCp0kQNARXq72IlSic0oabg2FC1NU68L4RdHrNJDd8bFwrphYA==", + "requires": { + "@stablelib/binary": "^1.0.1", + "@stablelib/constant-time": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "@stablelib/sha512": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/sha512/-/sha512-1.0.1.tgz", + "integrity": "sha512-13gl/iawHV9zvDKciLo1fQ8Bgn2Pvf7OV6amaRVKiq3pjQ3UmEpXxWiAfV8tYjUpeZroBxtyrwtdooQT/i3hzw==", + "requires": { + "@stablelib/binary": "^1.0.1", + "@stablelib/hash": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "@stablelib/wipe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/wipe/-/wipe-1.0.1.tgz", + "integrity": "sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg==" + }, + "@stablelib/x25519": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@stablelib/x25519/-/x25519-1.0.3.tgz", + "integrity": "sha512-KnTbKmUhPhHavzobclVJQG5kuivH+qDLpe84iRqX3CLrKp881cF160JvXJ+hjn1aMyCwYOKeIZefIH/P5cJoRw==", + "requires": { + "@stablelib/keyagreement": "^1.0.1", + "@stablelib/random": "^1.0.2", + "@stablelib/wipe": "^1.0.1" + } + }, + "@stablelib/xsalsa20": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@stablelib/xsalsa20/-/xsalsa20-1.0.2.tgz", + "integrity": "sha512-7XdBGbcNgBShmuhDXv1G1WPVCkjZdkb1oPMzSidO7Fve0MHntH6TjFkj5bfLI+aRE+61weO076vYpP/jmaAYog==", + "requires": { + "@stablelib/binary": "^1.0.1", + "@stablelib/salsa20": "^1.0.2", + "@stablelib/wipe": "^1.0.1" + } + }, + "@taquito/http-utils": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/http-utils/-/http-utils-14.0.0.tgz", + "integrity": "sha512-ZWZzod/+/OEE26b9CnDRjHGfUKBJft3aXv/e/A9bTHAtvRNJqGIhofHcDg/jTaolBMarCF2b3XBYw35aOOSk4A==", + "requires": { + "axios": "^0.26.0" + } + }, + "@taquito/local-forging": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/local-forging/-/local-forging-14.0.0.tgz", + "integrity": "sha512-Nm0xGmS1Jzd+tU0a/8Y8XuTghbiPBgHDLo+e4141TK3OAwTzOw0an+w3xK9QVfzvxfIcZBSMjeMZzOwDdiqkJQ==", + "requires": { + "@taquito/utils": "^14.0.0", + "bignumber.js": "^9.0.2" + } + }, + "@taquito/michel-codec": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/michel-codec/-/michel-codec-14.0.0.tgz", + "integrity": "sha512-ftnBvUVddlHBqvQbGPHEb26KrS4lIcaZ1eIpYJWiz+akb4Pcfyq7j/OEsDZbB7Pl2FP9hqu7ZygOF34zY6Lrtw==" + }, + "@taquito/michelson-encoder": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/michelson-encoder/-/michelson-encoder-14.0.0.tgz", + "integrity": "sha512-KIS+xl4rKfnd6hf9LUr6W+Pb7gv8F/Qsx0fho9CtM2PodKvdef3YlvkpScBUM9QZntAlvq2XQXUVXcZkbvxygw==", + "requires": { + "@taquito/rpc": "^14.0.0", + "@taquito/utils": "^14.0.0", + "bignumber.js": "^9.0.2", + "fast-json-stable-stringify": "^2.1.0" + } + }, + "@taquito/rpc": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/rpc/-/rpc-14.0.0.tgz", + "integrity": "sha512-FMfb80sA+VJwNx8OTNN07boDAt2roISqLLCUgmOIwy/cFDqhII7gdS4aYWJWqlKbdPKCPqh3a3ZQD1X/jyQHOA==", + "requires": { + "@taquito/http-utils": "^14.0.0", + "@taquito/utils": "^14.0.0", + "bignumber.js": "^9.0.2" + } + }, + "@taquito/signer": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/signer/-/signer-14.0.0.tgz", + "integrity": "sha512-vDqp/quzAsOiVikUt5MYUKhHI3S9qlasazyXs99xK9qpGLotbx6aseKcfb/dkaTo4/eoMzP4XzTVdnk0AqcCkw==", + "requires": { + "@stablelib/blake2b": "^1.0.1", + "@stablelib/ed25519": "^1.0.2", + "@stablelib/nacl": "^1.0.3", + "@taquito/taquito": "^14.0.0", + "@taquito/utils": "^14.0.0", + "elliptic": "^6.5.4", + "pbkdf2": "^3.1.2", + "typedarray-to-buffer": "^4.0.0" + } + }, + "@taquito/taquito": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/taquito/-/taquito-14.0.0.tgz", + "integrity": "sha512-JaXfvqOCF3dkwXxhe00Ravb8WLMC2VqJxerf4GrGUEpJw+NAkwbGEb8k/52+MQQdlxMPepZdPPru/HM3nFG0Tw==", + "requires": { + "@taquito/http-utils": "^14.0.0", + "@taquito/local-forging": "^14.0.0", + "@taquito/michel-codec": "^14.0.0", + "@taquito/michelson-encoder": "^14.0.0", + "@taquito/rpc": "^14.0.0", + "@taquito/utils": "^14.0.0", + "bignumber.js": "^9.0.2", + "rxjs": "^6.6.3" + } + }, + "@taquito/utils": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/utils/-/utils-14.0.0.tgz", + "integrity": "sha512-0RSHn/CzbcbMdldJJIlXyxOvAajwmL6iPKJ6NaRyYJqqLM2CxYjG72KpXVv716pCMV1MbIWsOAr9FKbxW73PsA==", + "requires": { + "@stablelib/blake2b": "^1.0.1", + "@stablelib/ed25519": "^1.0.2", + "@types/bs58check": "^2.1.0", + "bignumber.js": "^9.0.2", + "blakejs": "^1.2.1", + "bs58check": "^2.1.2", + "buffer": "^6.0.3", + "elliptic": "^6.5.4", + "typedarray-to-buffer": "^4.0.0" + } + }, + "@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" + }, + "@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" + }, + "@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" + }, + "@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==" + }, + "@types/bs58check": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/bs58check/-/bs58check-2.1.0.tgz", + "integrity": "sha512-OxsysnJQh82vy9DRbOcw9m2j/WiyqZLn0YBhKxdQ+aCwoHj+tWzyCgpwAkr79IfDXZKxc6h7k89T9pwS78CqTQ==", + "requires": { + "@types/node": "*" + } + }, + "@types/node": { + "version": "18.11.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", + "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==" + }, + "acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==" + }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==" + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "axios": { + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "requires": { + "follow-redirects": "^1.14.8" + } + }, + "base-x": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", + "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "bignumber.js": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.0.tgz", + "integrity": "sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==" + }, + "blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==" + }, + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + }, + "bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "requires": { + "base-x": "^3.0.2" + } + }, + "bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "requires": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" + }, + "dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==" + }, + "elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + }, + "pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "requires": { + "tslib": "^1.9.0" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "requires": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "typedarray-to-buffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-4.0.0.tgz", + "integrity": "sha512-6dOYeZfS3O9RtRD1caom0sMxgK59b27+IwoNy8RDPsmslSGOyU+mpTamlaIW7aNKi90ZQZ9DFaZL3YRoiSCULQ==" + }, + "typescript": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" + } + } +} diff --git a/smartpy/bmc/package.json b/smartpy/bmc/package.json new file mode 100644 index 00000000..47727297 --- /dev/null +++ b/smartpy/bmc/package.json @@ -0,0 +1,25 @@ +{ + "name": "create-tezos-app", + "version": "1.0.3", + "description": "A Tezos Dapp Starter using Typescript and Taquito.", + "bin": "./bin/cli.js", + "scripts": { + "compile": "bash ./compile.sh", + "deploy": "npx ts-node scripts/deploy.ts" + }, + "author": "Roshan Parajuli", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/0xrpj/create-tezos-dapp" + }, + "dependencies": { + "@taquito/signer": "^14.0.0", + "@taquito/taquito": "^14.0.0", + "dotenv": "^16.0.3", + "ts-node": "^10.9.1" + }, + "devDependencies": { + "typescript": "^4.8.4" + } +} \ No newline at end of file From b89802818e51c2f7690e64f593b42cbd94517244 Mon Sep 17 00:00:00 2001 From: simusud Date: Tue, 28 Mar 2023 17:23:01 +0545 Subject: [PATCH 012/211] feat(bmc): Add bmc management functions --- smartpy/bmc/contracts/src/bmc_management.py | 583 ++++++++++++++++++++ 1 file changed, 583 insertions(+) create mode 100644 smartpy/bmc/contracts/src/bmc_management.py diff --git a/smartpy/bmc/contracts/src/bmc_management.py b/smartpy/bmc/contracts/src/bmc_management.py new file mode 100644 index 00000000..807db0ea --- /dev/null +++ b/smartpy/bmc/contracts/src/bmc_management.py @@ -0,0 +1,583 @@ +import smartpy as sp + +types = sp.io.import_script_from_url("file:./contracts/src/Types.py") +strings = sp.io.import_script_from_url("file:./contracts/src/String.py") + + +class BMCManagement(sp.Contract): + BLOCK_INTERVAL_MSEC = sp.nat(1000) + + def __init__(self): + self.update_initial_storage( + owners=sp.map(l={sp.address("tz1000"): True}, tkey=sp.TAddress, tvalue=sp.TBool), + number_of_owners=sp.nat(1), + bsh_service=sp.map(tkey=sp.TString, tvalue=sp.TAddress), + relay_stats=sp.map(tkey=sp.TAddress, tvalue=types.Types.RelayStats), + routes=sp.map(tkey=sp.TString, tvalue=sp.TString), + links=sp.map(tkey=sp.TString, tvalue=types.Types.Link), + list_bsh_names=sp.list(), + list_route_keys=sp.list(), + list_link_names=sp.list(), + bmc_periphery=sp.none, + serial_no=sp.nat(0), + addrs=sp.map(tkey=sp.TNat, tvalue=sp.TAddress), + get_route_dst_from_net=sp.map(tkey=sp.TString, tvalue=sp.TString), + get_link_from_net=sp.map(tkey=sp.TString, tvalue=sp.TString), + get_link_from_reachable_net=sp.map(tkey=sp.TString, tvalue=types.Types.Tuple) + ) + + # self.init_type(sp.TRecord( + # list_bsh_names=sp.TList(sp.TAddress), + # list_route_keys=sp.TList(sp.TAddress), + # list_link_names=sp.TList(sp.TAddress), + # addrs=sp.TList(sp.TAddress) + # )) + + def only_owner(self): + sp.verify(self.data.owners[sp.sender] == True, "Unauthorized") + + def only_bmc_periphery(self): + sp.verify(sp.sender == self.data.bmc_periphery.open_some("BMCAddressNotSet"), "Unauthorized") + + @sp.entry_point + def set_bmc_periphery(self, addr): + """ + + :param addr: address of bmc_periphery + :return: + """ + sp.set_type(addr, sp.TAddress) + # self.only_owner() + sp.verify(addr != sp.address("tz100000000"), "InvalidAddress") + sp.trace(self.data.bmc_periphery.is_some()) + sp.if self.data.bmc_periphery.is_some(): + sp.verify(addr != self.data.bmc_periphery.open_some("Address not set"), "AlreadyExistsBMCPeriphery") + self.data.bmc_periphery = sp.some(addr) + + @sp.entry_point + def add_owner(self, owner): + """ + :param owner: owner address to set + :return: + """ + sp.set_type(owner, sp.TAddress) + + # self.only_owner() + sp.verify(self.data.owners.contains(owner) == False, "Already Exists") + self.data.owners[owner] = True + self.data.number_of_owners += sp.nat(1) + + @sp.entry_point + def remove_owner(self, owner): + """ + + :param owner: owner address to remove + :return: + """ + sp.set_type(owner, sp.TAddress) + + self.only_owner() + sp.verify(self.data.number_of_owners > sp.nat(1), "LastOwner") + sp.verify(self.data.owners[owner] == True, "NotExistsPermission") + del self.data.owners[owner] + self.data.number_of_owners = sp.as_nat(self.data.number_of_owners - sp.nat(1)) + + @sp.onchain_view() + def is_owner(self, owner): + """ + + :param owner: address to check + :return: + """ + sp.result(self.data.owners[owner]) + + @sp.entry_point + def add_service(self, svc, addr): + """ + Add the smart contract for the service. + :param svc: Name of the service + :param addr: Service's contract address + :return: + """ + self.only_owner() + sp.verify(addr != sp.address("tz100000000"), "InvalidAddress") + sp.verify(self.data.bsh_service[svc] == sp.address("tz100000000"), "AlreadyExistsBSH") + self.data.bsh_service[svc] = addr + self.data.list_bsh_names.push(svc) + + @sp.entry_point + def remove_service(self, svc): + """ + Unregisters the smart contract for the service. + :param svc: Name of the service + :return: + """ + self.only_owner() + sp.verify(self.data.bsh_service[svc] == sp.address("tz100000000"), "NotExistsBSH") + del self.data.bsh_service[svc] + + # need to delete item from list_bsh_names (not possible) + + # @sp.onchain_view() + # def get_services(self): + # """ + # Get registered services. + # :return: An array of Service. + # """ + # + # services = sp.compute(sp.map(tkey=sp.TNat, tvalue=types.Types.Service)) + # + # sp.for i in sp.range(sp.nat(0), sp.len(self.data.bsh_service)): + # services[i] = sp.record( + # + # ) + + @sp.entry_point + def add_link(self, link): + """ + Initializes status information for the link. + :param link: + :return: BTP Address of connected BMC + """ + sp.set_type(link, sp.TString) + + self.only_owner() + net, addr= sp.match_pair(strings.split_btp_address(link)) + + with sp.if_(self.data.links.contains(link)): + sp.verify(self.data.links[link].is_connected == False, "AlreadyExistsLink") + #TODO:review how to add key in relays map + self.data.links[link] = sp.record( + relays=sp.map({0: sp.address("tz100000000")}), + reachable=sp.map({0: "0"}), + rx_seq=sp.nat(0), + tx_seq=sp.nat(0), + block_interval_src=self.BLOCK_INTERVAL_MSEC, + block_interval_dst=sp.nat(0), + max_aggregation=sp.nat(10), + delay_limit=sp.nat(3), + relay_idx=sp.nat(0), + rotate_height=sp.nat(0), + rx_height=sp.nat(0), + rx_height_src=sp.nat(0), + is_connected=True + ) + + # self._propagate_internal("Link", link) + links = sp.local("links", self.data.list_link_names, t=sp.TList(sp.TString)) + # TODO:push link to listLinkNames + + self.data.get_link_from_net[net] = link + + # self._send_internal(link, "Init", links.value) + sp.trace("in add_link") + + @sp.entry_point + def remove_link(self, link): + """ + Removes the link and status information. + :param link: BTP Address of connected BMC + :return: + """ + sp.set_type(link, sp.TString) + + self.only_owner() + # TODO : review this if else + with sp.if_(self.data.links.contains(link)): + sp.verify(self.data.links[link].is_connected == True, "NotExistsLink") + with sp.else_(): + sp.failwith("NotExistsLink") + del self.data.links[link] + net, addr= sp.match_pair(strings.split_btp_address(link)) + del self.data.get_link_from_net[link] + # self._propagate_internal("Unlink", link) + # TODO:remove link to listLinkNames + sp.trace("in remove_link") + + @sp.onchain_view() + def get_links(self): + """ + Get registered links. + :return: An array of links ( BTP Addresses of the BMCs ). + """ + sp.result(self.data.list_link_names) + + + @sp.entry_point + def set_link_rx_height(self, link, height): + """ + + :param link: + :param height: + :return: + """ + + sp.set_type(link, sp.TString) + sp.set_type(height, sp.TNat) + + self.only_owner() + with sp.if_(self.data.links.contains(link)): + sp.verify(self.data.links[link].is_connected == True, "NotExistsLink") + with sp.else_(): + sp.failwith("NotExistsKey") + sp.verify(height > sp.nat(0), "InvalidRxHeight") + self.data.links[link].rx_height = height + + sp.trace("in set_link_rx_height") + + @sp.entry_point + def set_link(self, _link, block_interval, _max_aggregation, delay_limit): + """ + + :param _link: + :param block_interval: + :param _max_aggregation: + :param delay_limit: + :return: + """ + sp.set_type(_link, sp.TString) + sp.set_type(block_interval, sp.TNat) + sp.set_type(_max_aggregation, sp.TNat) + sp.set_type(delay_limit, sp.TNat) + + self.only_owner() + + sp.verify(self.data.links[_link].is_connected == True, "NotExistsLink") + sp.verify((_max_aggregation >= sp.nat(1)) & (delay_limit >= sp.nat(1)), "InvalidParam") + + link = sp.local("link", self.data.links[_link], t=types.Types.Link).value + # scale = sp.local("scale", utils.get_scale(link.block_interval_src, link.block_interval_dst), t=sp.TNat) + + reset_rotate_height = sp.local("reset_rotate_height", False, t=sp.TBool) + + # sp.if utils.get_rotate_term(link.max_aggregation, scale.value) == sp.nat(0): + # reset_rotate_height.value = True + + link.block_interval_src = block_interval + link.max_aggregation = _max_aggregation + link.delay_limit = delay_limit + + # TODO: uncomment after writing utils lib + # scale.value = utils.get_scale(link.block_interval_src, block_interval) + # rotate_term = sp.local("rotate_term", utils.get_rotate_term(_max_aggregation, scale.value), t=sp.TNat) + rotate_term = sp.local("rotate_term", sp.nat(6)) + + sp.if reset_rotate_height.value & (rotate_term.value > sp.nat(0)): + link.rotate_height = sp.level + rotate_term.value + link.rx_height = sp.nat(0) + net, addr = sp.match_pair(strings.split_btp_address(_link)) + + self.data.links[_link] = link + sp.trace("in set_links") + + def _rotate(self, _link, rotate_term, rotate_count, base_height): + sp.set_type(_link, sp.TString) + sp.set_type(rotate_term, sp.TNat) + sp.set_type(rotate_count, sp.TNat) + sp.set_type(base_height, sp.TNat) + + link = sp.local("link", self.data.links[_link], t=types.Types.Link).value + + sp.if (rotate_term >sp.nat(0)) & (rotate_count > sp.nat(0)): + link.rotate_height = base_height + rotate_term + link.relay_idx = link.relay_idx + rotate_count + sp.if link.relay_idx >= sp.len(link.relays): + link.relay_idx = link.relay_idx % sp.len(link.relays) + links[_link] = link + return link.relays[link.relay_idx] + + def _propagate_internal(self, service_type, link): + sp.set_type(service_type, sp.TString) + sp.set_type(link, sp.TString) + + #TODO implement abi encodePacked + + # TODO: encode actual payload + rlp_bytes =sp.bytes("rlp_bytes_here") + + sp.for i in sp.range(sp.nat(0), sp.len(self.data.list_link_names)): + sp.for item in self.data.list_link_names: + sp.if self.data.links[item].is_connected: + net, addr = sp.match_pair(strings.split_btp_address(item)) + + # call send_message on BMCPeriphery + send_message_args_type = sp.TRecord(to=sp.TString, svc=sp.TString, sn=sp.TNat, msg=sp.TBytes) + send_message_entry_point = sp.contract(send_message_args_type, + self.data.bmc_periphery, + "send_message").open_some() + send_message_args = sp.record(to=net, svc="bmc", sn=sp.nat(0), msg=encodeBMCService( + sp.record(serviceType=service_type, payload=rlp_bytes))) + sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) + + + + def _send_internal(self, target, service_type, links): + sp.set_type(target, sp.TString) + sp.set_type(service_type, sp.TString) + sp.set_type(links, sp.TMap(TNat, TString)) + + with sp.if_(sp.len(links) == sp.nat(0)): + # TODO: abi encode + rlp_bytes = sp.bytes("rpl byte") + with sp.else_(): + sp.for i in sp.range(0, sp.len(links)): + #TODO + # TODO: abi encode + rlp_bytes = sp.bytes("rpl byte") + + #TODO: encode payload + rlp_bytes = sp.bytes("abi encode") + + net, addr = sp.match_pair(strings.split_btp_address(target)) + + # call send_message on BMCPeriphery + send_message_args_type = sp.TRecord(to=sp.TString, svc=sp.TString, sn=sp.TNat, msg=sp.TBytes) + send_message_entry_point = sp.contract(send_message_args_type, + self.data.bmc_periphery, + "send_message").open_some() + send_message_args = sp.record(to=net, svc="bmc", sn=sp.nat(0), msg=encodeBMCService( + sp.record(serviceType=service_type, payload=rlp_bytes))) + sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) + + + @sp.entry_point + def add_route(self, dst, link): + """ + Add route to the BMC. + :param dst: BTP Address of the destination BMC + :param link: BTP Address of the next BMC for the destination + :return: + """ + sp.set_type(dst, sp.TString) + sp.set_type(link, sp.TString) + + self.only_owner() + sp.verify(sp.len(sp.pack(self.data.routes[dst])) == sp.nat(0), "AlreadyExistRoute") + net, addr= sp.match_pair(strings.split_btp_address(dst)) + # TODO: need to verify link is only split never used + # strings.split_btp_address(link) + + self.data.routes[dst] = link + self.data.list_route_keys.push(dst) + self.data.get_route_dst_from_net[net] = dst + + @sp.entry_point + def remove_route(self, dst): + """ + Remove route to the BMC. + :param dst: BTP Address of the destination BMC + :return: + """ + sp.set_type(dst, sp.TString) + + self.only_owner() + sp.verify(sp.len(sp.pack(self.data.routes[dst])) != sp.nat(0), "NotExistRoute") + del self.data.routes[dst] + net, addr= sp.match_pair(strings.split_btp_address(dst)) + del self.data.get_route_dst_from_net[net] + #TODO: remove dst from list_route_keys + + @sp.onchain_view() + def get_routes(self): + """ + Get routing information. + :return: An array of Route. + """ + + routes = sp.compute(sp.map(tkey=sp.TNat, tvalue=types.Types.Route)) + #TODO: whether to make listRouteKeys list or map + + @sp.entry_point + def add_relay(self, link, addr): + """ + Registers relay for the network. + :param link: BTP Address of connected BMC + :param addr: the address of Relay + :return: + """ + sp.set_type(link, sp.TString) + sp.set_type(addr, sp.TMap(sp.TNat, sp.TAddress)) + + self.only_owner() + sp.verify(self.data.links[link].is_connected == True, "NotExistsLink") + self.data.links[link].relays = addr + sp.for i in sp.range(sp.nat(0), sp.len(addr)): + self.data.relay_stats[addr[i]] = sp.record(addr=addr[i], block_count=sp.nat(0), msg_count=sp.nat(0)) + + @sp.entry_point + def remove_relay(self, link, addr): + """ + Unregisters Relay for the network. + :param link: BTP Address of connected BMC + :param addr: the address of Relay + :return: + """ + sp.set_type(link, sp.TString) + sp.set_type(addr, sp.TAddress) + + self.only_owner() + sp.verify((self.data.links[link].is_connected == True) & (sp.len(self.data.links[link].relays) != sp.nat(0)), + "Unauthorized") + + sp.for i in sp.range(sp.nat(0), sp.len(self.data.links[link].relays)): + sp.if self.data.links[link].relays[i] != addr: + self.data.addrs[i] = self.data.links[link].relays[i] + + self.data.links[link].relays = self.data.addrs + # TODO: delete addrs map + # del self.data.addrs + + @sp.onchain_view() + def get_relays(self, link): + """ + Get registered relays. + :param link: BTP Address of the connected BMC. + :return: A map of relays + """ + sp.set_type(link, sp.TString) + + sp.result(self.data.links[link].relays) + + @sp.onchain_view() + def get_bsh_service_by_name(self, service_name): + sp.set_type(service_name, sp.TString) + sp.result(self.data.bsh_service[service_name]) + + @sp.onchain_view() + def get_link(self, to): + sp.set_type(to, sp.TString) + sp.result(self.data.links[to]) + + @sp.onchain_view() + def get_link_rx_seq(self, prev): + sp.set_type(prev, sp.TString) + sp.result(self.data.links[prev].rx_seq) + + @sp.onchain_view() + def get_link_tx_seq(self, prev): + sp.set_type(prev, sp.TString) + sp.result(self.data.links[prev].tx_seq) + + @sp.onchain_view() + def get_link_rx_height(self, prev): + sp.set_type(prev, sp.TString) + sp.result(self.data.links[prev].rx_height) + + @sp.onchain_view() + def get_link_relays(self, prev): + sp.set_type(prev, sp.TString) + sp.result(self.data.links[prev].relays) + + @sp.onchain_view() + def get_relay_status_by_link(self, prev): + sp.set_type(prev, sp.TString) + relays = sp.compute(sp.map(tkey=sp.TNat, tvalue=types.Types.RelayStats)) + sp.for i in sp.range(sp.nat(0), sp.len(self.data.links[prev].relays)): + relays[i] = self.data.relay_stats[self.data.links[prev].relays[i]] + sp.result(relays) + + @sp.entry_point + def update_link_rx_seq(self, prev, val): + sp.set_type(prev, sp.TString) + sp.set_type(val, sp.TNat) + + self.only_bmc_periphery() + self.data.links[prev].rx_seq += val + + @sp.entry_point + def update_link_tx_seq(self, prev): + sp.set_type(prev, sp.TString) + + self.only_bmc_periphery() + self.data.links[prev].tx_seq += sp.nat(1) + + @sp.entry_point + def update_link_rx_height(self, prev, val): + sp.set_type(prev, sp.TString) + sp.set_type(val, sp.TNat) + + self.only_bmc_periphery() + self.data.links[prev].rx_height += val + + @sp.entry_point + def update_link_reachable(self, prev, to): + sp.set_type(prev, sp.TString) + sp.set_type(to, sp.TMap(sp.TNat, sp.TString)) + + self.only_bmc_periphery() + sp.for i in sp.range(sp.nat(0), sp.len(to)): + self.data.links[prev].reachable[i] = to[i] + net, addr = sp.match_pair(strings.split_btp_address(to[i])) + self.data.get_link_from_reachable_net[net] = sp.record(prev=prev, to=to[i]) + + @sp.entry_point + def delete_link_reachable(self, prev, index): + sp.set_type(prev, sp.TString) + sp.set_type(index, sp.TNat) + + self.only_bmc_periphery() + net, addr = sp.match_pair(strings.split_btp_address(self.data.links[prev].reachable[index])) + + del self.data.get_link_from_reachable_net[net] + del self.data.links[prev].reachable[index] + self.data.links[prev].reachable[index] = self.data.links[prev].reachable[ + sp.as_nat(sp.len(self.data.links[prev].reachable) - 1) + ] + # TODO:pop from reachable + + @sp.entry_point + def update_relay_stats(self, relay, block_count_val, msg_count_val): + sp.set_type(relay, sp.TAddress) + sp.set_type(block_count_val, sp.TNat) + sp.set_type(msg_count_val, sp.TNat) + + self.only_bmc_periphery() + self.data.relay_stats[relay].block_count += block_count_val + self.data.relay_stats[relay].msg_count += msg_count_val + + @sp.onchain_view() + def resolve_route(self, dst_net): + sp.set_type(dst_net, sp.TString) + + self.only_bmc_periphery() + dst = sp.local("dst", self.data.get_route_dst_from_net[dst_net], t=sp.TString) + + # TODO: calculate length of byte + # sp.if sp.len(sp.pack(dst.value))!= sp.nat(0): + # sp.result(sp.pair(self.data.routes[dst.value], dst.value)) + + dst_link = sp.local("dst_link", self.data.get_link_from_net[dst_net], t=sp.TString) + # TODO: calculate length of byte + # sp.if sp.len(sp.pack(dst_link.value)) != sp.nat(0): + # sp.result(sp.pair(dst_link.value, dst_link.value)) + + res = sp.local("res", self.data.get_link_from_reachable_net[dst_net], t=types.Types.Tuple) + sp.verify(sp.len(sp.pack(res.value.to)) > sp.nat(0), "Unreachable: " + dst_net + " is unreachable") + + sp.result(sp.pair(res.value.prev, res.value.to)) + + +@sp.add_test(name="BMCM") +def test(): + alice = sp.test_account("Alice") + bmc_periphery = sp.test_account("BMC Periphery") + # bmc= sp.test_account("BMC") + + scenario = sp.test_scenario() + bmc_man = BMCManagement() + scenario += bmc_man + + bmc_man.set_bmc_periphery(bmc_periphery.address).run(sender=alice) + bmc_man.add_owner(alice.address).run(sender=alice) + + # bmc_man.remove_owner(alice.address).run(sender=alice) + + bmc_man.add_link("btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW").run(sender=alice) + # bmc_man.remove_link("btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW").run(sender=alice) + + bmc_man.set_link_rx_height(sp.record(link="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", height=sp.nat(2))).run(sender=alice) + bmc_man.set_link(sp.record(_link="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", block_interval=sp.nat(2), + _max_aggregation=sp.nat(3), delay_limit=sp.nat(2))).run(sender=alice) + + +sp.add_compilation_target("bmc_management", BMCManagement()) From 4e6e8ad1622baff4e1406a44a897e8a557c4a445 Mon Sep 17 00:00:00 2001 From: suyogadhikari Date: Wed, 29 Mar 2023 11:16:36 +0545 Subject: [PATCH 013/211] Utils file added --- smartpy/bts/contracts/src/Utils.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 smartpy/bts/contracts/src/Utils.py diff --git a/smartpy/bts/contracts/src/Utils.py b/smartpy/bts/contracts/src/Utils.py new file mode 100644 index 00000000..e751c3fb --- /dev/null +++ b/smartpy/bts/contracts/src/Utils.py @@ -0,0 +1,30 @@ +import smartpy as sp + +# TODO: remove compilation target +class Utils(sp.Contract): + def __init__(self): + self.update_initial_storage() + + def _ceil_div(self, num1, num2): + sp.set_type(num1, sp.TNat) + sp.set_type(num2, sp.TNat) + (quotient, remainder) = sp.match_pair(sp.ediv(11, 2).open_some()) + sp.if remainder == 0 : + sp.result(quotient) + return quotient + 1 + + def _get_scale(self, block_interval_src, block_interval_dst): + sp.set_type(block_interval_src, sp.TNat) + sp.set_type(block_interval_dst, sp.TNat) + sp.if (block_interval_dst < 1) | (block_interval_dst < 1): + sp.result(0) + return self._ceil_div(block_interval_src * 1000000, block_interval_dst) + + def _get_rotate_term(self, max_aggregation, scale): + sp.set_type(max_aggregation, sp.TNat) + sp.set_type(scale, sp.TNat) + sp.if scale > 0: + return self._ceil_div(max_aggregation * 1000000, scale) + return 0 + +sp.add_compilation_target("Utils", Utils()) \ No newline at end of file From 834cc801cf42e355b2e78d8e6cc9359a0c6875c3 Mon Sep 17 00:00:00 2001 From: simusud Date: Wed, 29 Mar 2023 17:51:18 +0545 Subject: [PATCH 014/211] fix(bmc): Implement sets instead of lists --- smartpy/bmc/contracts/src/Types.py | 4 +- smartpy/bmc/contracts/src/bmc_management.py | 305 +++++++++++--------- 2 files changed, 177 insertions(+), 132 deletions(-) diff --git a/smartpy/bmc/contracts/src/Types.py b/smartpy/bmc/contracts/src/Types.py index d122e760..5da5e9d1 100644 --- a/smartpy/bmc/contracts/src/Types.py +++ b/smartpy/bmc/contracts/src/Types.py @@ -40,8 +40,8 @@ class Types: ) Link = sp.TRecord( - relays=sp.TMap(sp.TNat, sp.TAddress), - reachable=sp.TMap(sp.TNat, sp.TString), + relays=sp.TSet(sp.TAddress), + reachable=sp.TSet(sp.TString), rx_seq=sp.TNat, tx_seq=sp.TNat, block_interval_src=sp.TNat, diff --git a/smartpy/bmc/contracts/src/bmc_management.py b/smartpy/bmc/contracts/src/bmc_management.py index 807db0ea..1593dc68 100644 --- a/smartpy/bmc/contracts/src/bmc_management.py +++ b/smartpy/bmc/contracts/src/bmc_management.py @@ -11,28 +11,21 @@ def __init__(self): self.update_initial_storage( owners=sp.map(l={sp.address("tz1000"): True}, tkey=sp.TAddress, tvalue=sp.TBool), number_of_owners=sp.nat(1), - bsh_service=sp.map(tkey=sp.TString, tvalue=sp.TAddress), + bsh_services=sp.map(tkey=sp.TString, tvalue=sp.TAddress), relay_stats=sp.map(tkey=sp.TAddress, tvalue=types.Types.RelayStats), routes=sp.map(tkey=sp.TString, tvalue=sp.TString), links=sp.map(tkey=sp.TString, tvalue=types.Types.Link), - list_bsh_names=sp.list(), - list_route_keys=sp.list(), - list_link_names=sp.list(), + list_bsh_names=sp.set(), + list_route_keys=sp.set(), + list_link_names=sp.set(), bmc_periphery=sp.none, serial_no=sp.nat(0), - addrs=sp.map(tkey=sp.TNat, tvalue=sp.TAddress), + addrs=sp.set(), get_route_dst_from_net=sp.map(tkey=sp.TString, tvalue=sp.TString), get_link_from_net=sp.map(tkey=sp.TString, tvalue=sp.TString), get_link_from_reachable_net=sp.map(tkey=sp.TString, tvalue=types.Types.Tuple) ) - # self.init_type(sp.TRecord( - # list_bsh_names=sp.TList(sp.TAddress), - # list_route_keys=sp.TList(sp.TAddress), - # list_link_names=sp.TList(sp.TAddress), - # addrs=sp.TList(sp.TAddress) - # )) - def only_owner(self): sp.verify(self.data.owners[sp.sender] == True, "Unauthorized") @@ -101,9 +94,9 @@ def add_service(self, svc, addr): """ self.only_owner() sp.verify(addr != sp.address("tz100000000"), "InvalidAddress") - sp.verify(self.data.bsh_service[svc] == sp.address("tz100000000"), "AlreadyExistsBSH") - self.data.bsh_service[svc] = addr - self.data.list_bsh_names.push(svc) + sp.verify(self.data.bsh_services[svc] == sp.address("tz100000000"), "AlreadyExistsBSH") + self.data.bsh_services[svc] = addr + self.data.list_bsh_names.add(svc) @sp.entry_point def remove_service(self, svc): @@ -113,24 +106,23 @@ def remove_service(self, svc): :return: """ self.only_owner() - sp.verify(self.data.bsh_service[svc] == sp.address("tz100000000"), "NotExistsBSH") - del self.data.bsh_service[svc] - - # need to delete item from list_bsh_names (not possible) - - # @sp.onchain_view() - # def get_services(self): - # """ - # Get registered services. - # :return: An array of Service. - # """ - # - # services = sp.compute(sp.map(tkey=sp.TNat, tvalue=types.Types.Service)) - # - # sp.for i in sp.range(sp.nat(0), sp.len(self.data.bsh_service)): - # services[i] = sp.record( - # - # ) + sp.verify(self.data.bsh_services[svc] == sp.address("tz100000000"), "NotExistsBSH") + del self.data.bsh_services[svc] + self.data.list_bsh_names.remove(svc) + + @sp.onchain_view() + def get_services(self): + """ + Get registered services. + :return: An array of Service. + """ + + services = sp.compute(sp.map(tkey=sp.TNat, tvalue=types.Types.Service)) + sp.for item in self.data.list_bsh_names.elements(): + i = sp.local("i", 0) + services[i.value] = sp.record(svc=item, addr=self.data.bsh_services[item]) + i.value += 1 + sp.result(services) @sp.entry_point def add_link(self, link): @@ -148,8 +140,8 @@ def add_link(self, link): sp.verify(self.data.links[link].is_connected == False, "AlreadyExistsLink") #TODO:review how to add key in relays map self.data.links[link] = sp.record( - relays=sp.map({0: sp.address("tz100000000")}), - reachable=sp.map({0: "0"}), + relays=sp.set([sp.address("tz100000000")]), + reachable=sp.set(["0"]), rx_seq=sp.nat(0), tx_seq=sp.nat(0), block_interval_src=self.BLOCK_INTERVAL_MSEC, @@ -163,13 +155,13 @@ def add_link(self, link): is_connected=True ) - # self._propagate_internal("Link", link) - links = sp.local("links", self.data.list_link_names, t=sp.TList(sp.TString)) - # TODO:push link to listLinkNames + self._propagate_internal("Link", link) + links = sp.local("links", self.data.list_link_names.elements(), t=sp.TList(sp.TString)) + self.data.list_link_names.add(link) self.data.get_link_from_net[net] = link - # self._send_internal(link, "Init", links.value) + self._send_internal(link, "Init", links.value) sp.trace("in add_link") @sp.entry_point @@ -190,8 +182,8 @@ def remove_link(self, link): del self.data.links[link] net, addr= sp.match_pair(strings.split_btp_address(link)) del self.data.get_link_from_net[link] - # self._propagate_internal("Unlink", link) - # TODO:remove link to listLinkNames + self._propagate_internal("Unlink", link) + self.data.list_link_names.remove(link) sp.trace("in remove_link") @sp.onchain_view() @@ -200,7 +192,7 @@ def get_links(self): Get registered links. :return: An array of links ( BTP Addresses of the BMCs ). """ - sp.result(self.data.list_link_names) + sp.result(self.data.list_link_names.elements()) @sp.entry_point @@ -246,10 +238,10 @@ def set_link(self, _link, block_interval, _max_aggregation, delay_limit): sp.verify((_max_aggregation >= sp.nat(1)) & (delay_limit >= sp.nat(1)), "InvalidParam") link = sp.local("link", self.data.links[_link], t=types.Types.Link).value - # scale = sp.local("scale", utils.get_scale(link.block_interval_src, link.block_interval_dst), t=sp.TNat) - - reset_rotate_height = sp.local("reset_rotate_height", False, t=sp.TBool) + # not implemented + # scale = sp.local("scale", utils.get_scale(link.block_interval_src, link.block_interval_dst), t=sp.TNat) + # reset_rotate_height = sp.local("reset_rotate_height", True, t=sp.TBool) # sp.if utils.get_rotate_term(link.max_aggregation, scale.value) == sp.nat(0): # reset_rotate_height.value = True @@ -257,34 +249,19 @@ def set_link(self, _link, block_interval, _max_aggregation, delay_limit): link.max_aggregation = _max_aggregation link.delay_limit = delay_limit - # TODO: uncomment after writing utils lib + # not implemented # scale.value = utils.get_scale(link.block_interval_src, block_interval) # rotate_term = sp.local("rotate_term", utils.get_rotate_term(_max_aggregation, scale.value), t=sp.TNat) - rotate_term = sp.local("rotate_term", sp.nat(6)) + # rotate_term = sp.local("rotate_term", sp.nat(6)) - sp.if reset_rotate_height.value & (rotate_term.value > sp.nat(0)): - link.rotate_height = sp.level + rotate_term.value - link.rx_height = sp.nat(0) - net, addr = sp.match_pair(strings.split_btp_address(_link)) + # sp.if reset_rotate_height.value & (rotate_term.value > sp.nat(0)): + link.rotate_height = sp.level + link.rx_height = sp.nat(0) + # net, addr = sp.match_pair(strings.split_btp_address(_link)) self.data.links[_link] = link sp.trace("in set_links") - def _rotate(self, _link, rotate_term, rotate_count, base_height): - sp.set_type(_link, sp.TString) - sp.set_type(rotate_term, sp.TNat) - sp.set_type(rotate_count, sp.TNat) - sp.set_type(base_height, sp.TNat) - - link = sp.local("link", self.data.links[_link], t=types.Types.Link).value - - sp.if (rotate_term >sp.nat(0)) & (rotate_count > sp.nat(0)): - link.rotate_height = base_height + rotate_term - link.relay_idx = link.relay_idx + rotate_count - sp.if link.relay_idx >= sp.len(link.relays): - link.relay_idx = link.relay_idx % sp.len(link.relays) - links[_link] = link - return link.relays[link.relay_idx] def _propagate_internal(self, service_type, link): sp.set_type(service_type, sp.TString) @@ -293,51 +270,105 @@ def _propagate_internal(self, service_type, link): #TODO implement abi encodePacked # TODO: encode actual payload - rlp_bytes =sp.bytes("rlp_bytes_here") - - sp.for i in sp.range(sp.nat(0), sp.len(self.data.list_link_names)): - sp.for item in self.data.list_link_names: - sp.if self.data.links[item].is_connected: - net, addr = sp.match_pair(strings.split_btp_address(item)) - - # call send_message on BMCPeriphery - send_message_args_type = sp.TRecord(to=sp.TString, svc=sp.TString, sn=sp.TNat, msg=sp.TBytes) - send_message_entry_point = sp.contract(send_message_args_type, - self.data.bmc_periphery, - "send_message").open_some() - send_message_args = sp.record(to=net, svc="bmc", sn=sp.nat(0), msg=encodeBMCService( - sp.record(serviceType=service_type, payload=rlp_bytes))) - sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) - - + rlp_bytes =sp.bytes("0x1221") + + sp.for item in self.data.list_link_names.elements(): + sp.if self.data.links[item].is_connected: + # net, addr = sp.match_pair(strings.split_btp_address(item)) + + # split btp address code snippet: because same local value cannot be used multiple times + prev_idx1 = sp.local("prev_idx1", 0) + result1 = sp.local("result1", []) + sp.for idx in sp.range(0, sp.len(item)): + sp.if sp.slice(item, idx, 1).open_some() == "/": + result1.value.push(sp.slice(item, prev_idx1.value, sp.as_nat(idx - prev_idx1.value)).open_some()) + prev_idx1.value = idx + 1 + sp.if sp.len(item) > 0: + result1.value.push( + sp.slice(item, prev_idx1.value, sp.as_nat(sp.len(item) - prev_idx1.value)).open_some()) + + inverted_list = sp.local("my_list1", result1.value) + last = sp.local("last1", "") + penultimate = sp.local("penultimate1", "") + + with sp.match_cons(inverted_list.value) as l: + last.value = l.head + inverted_list.value = l.tail + with sp.else_(): + sp.failwith("Empty list") + + with sp.match_cons(inverted_list.value) as l: + penultimate.value = l.head + with sp.else_(): + sp.failwith("Only one element") + + net = last.value + + # call send_message on BMCPeriphery + # TODO: encodeBMCService + # send_message_args_type = sp.TRecord(to=sp.TString, svc=sp.TString, sn=sp.TNat, msg=sp.TBytes) + # send_message_entry_point = sp.contract(send_message_args_type, + # self.data.bmc_periphery, + # "send_message").open_some() + # send_message_args = sp.record(to=net, svc="bmc", sn=sp.nat(0), msg=encodeBMCService( + # sp.record(serviceType=service_type, payload=rlp_bytes))) + # sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) def _send_internal(self, target, service_type, links): sp.set_type(target, sp.TString) sp.set_type(service_type, sp.TString) - sp.set_type(links, sp.TMap(TNat, TString)) + sp.set_type(links, sp.TList(sp.TString)) with sp.if_(sp.len(links) == sp.nat(0)): # TODO: abi encode - rlp_bytes = sp.bytes("rpl byte") + rlp_bytes = sp.bytes("0x1221") with sp.else_(): sp.for i in sp.range(0, sp.len(links)): - #TODO # TODO: abi encode - rlp_bytes = sp.bytes("rpl byte") + rlp_bytes = sp.bytes("0x1221") #TODO: encode payload - rlp_bytes = sp.bytes("abi encode") + rlp_bytes = sp.bytes("0x1221") + + # net, addr = sp.match_pair(strings.split_btp_address(target)) + + # split btp address code snippet: because same local value cannot be used multiple times + prev_idx2 = sp.local("prev_idx2", 0) + result2 = sp.local("result2", []) + sp.for idx in sp.range(0, sp.len(target)): + sp.if sp.slice(target, idx, 1).open_some() == "/": + result2.value.push(sp.slice(target, prev_idx2.value, sp.as_nat(idx - prev_idx2.value)).open_some()) + prev_idx2.value = idx + 1 + sp.if sp.len(target) > 0: + result2.value.push( + sp.slice(target, prev_idx2.value, sp.as_nat(sp.len(target) - prev_idx2.value)).open_some()) + + inverted_list = sp.local("my_list2", result2.value) + last = sp.local("last2", "") + penultimate = sp.local("penultimate2", "") + + with sp.match_cons(inverted_list.value) as l: + last.value = l.head + inverted_list.value = l.tail + with sp.else_(): + sp.failwith("Empty list") - net, addr = sp.match_pair(strings.split_btp_address(target)) + with sp.match_cons(inverted_list.value) as l: + penultimate.value = l.head + with sp.else_(): + sp.failwith("Only one element") + + net = last.value # call send_message on BMCPeriphery - send_message_args_type = sp.TRecord(to=sp.TString, svc=sp.TString, sn=sp.TNat, msg=sp.TBytes) - send_message_entry_point = sp.contract(send_message_args_type, - self.data.bmc_periphery, - "send_message").open_some() - send_message_args = sp.record(to=net, svc="bmc", sn=sp.nat(0), msg=encodeBMCService( - sp.record(serviceType=service_type, payload=rlp_bytes))) - sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) + # TODO: encodeBMCService + # send_message_args_type = sp.TRecord(to=sp.TString, svc=sp.TString, sn=sp.TNat, msg=sp.TBytes) + # send_message_entry_point = sp.contract(send_message_args_type, + # self.data.bmc_periphery, + # "send_message").open_some() + # send_message_args = sp.record(to=net, svc="bmc", sn=sp.nat(0), msg=encodeBMCService( + # sp.record(serviceType=service_type, payload=rlp_bytes))) + # sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) @sp.entry_point @@ -358,7 +389,7 @@ def add_route(self, dst, link): # strings.split_btp_address(link) self.data.routes[dst] = link - self.data.list_route_keys.push(dst) + self.data.list_route_keys.add(dst) self.data.get_route_dst_from_net[net] = dst @sp.entry_point @@ -375,7 +406,7 @@ def remove_route(self, dst): del self.data.routes[dst] net, addr= sp.match_pair(strings.split_btp_address(dst)) del self.data.get_route_dst_from_net[net] - #TODO: remove dst from list_route_keys + self.data.list_route_keys.remove(dst) @sp.onchain_view() def get_routes(self): @@ -384,8 +415,12 @@ def get_routes(self): :return: An array of Route. """ - routes = sp.compute(sp.map(tkey=sp.TNat, tvalue=types.Types.Route)) - #TODO: whether to make listRouteKeys list or map + _routes = sp.compute(sp.map(tkey=sp.TNat, tvalue=types.Types.Route)) + sp.for item in self.data.list_route_keys.elements(): + i=sp.local("i", 0) + _routes[i.value] = sp.record(dst=item, next=self.data.routes[item]) + i.value += 1 + sp.result(_routes) @sp.entry_point def add_relay(self, link, addr): @@ -396,13 +431,13 @@ def add_relay(self, link, addr): :return: """ sp.set_type(link, sp.TString) - sp.set_type(addr, sp.TMap(sp.TNat, sp.TAddress)) + sp.set_type(addr, sp.TSet(sp.TAddress)) self.only_owner() sp.verify(self.data.links[link].is_connected == True, "NotExistsLink") self.data.links[link].relays = addr - sp.for i in sp.range(sp.nat(0), sp.len(addr)): - self.data.relay_stats[addr[i]] = sp.record(addr=addr[i], block_count=sp.nat(0), msg_count=sp.nat(0)) + sp.for item in addr.elements(): + self.data.relay_stats[item] = sp.record(addr=item, block_count=sp.nat(0), msg_count=sp.nat(0)) @sp.entry_point def remove_relay(self, link, addr): @@ -416,32 +451,35 @@ def remove_relay(self, link, addr): sp.set_type(addr, sp.TAddress) self.only_owner() - sp.verify((self.data.links[link].is_connected == True) & (sp.len(self.data.links[link].relays) != sp.nat(0)), + sp.verify((self.data.links[link].is_connected == True) & (sp.len(self.data.links[link].relays.elements()) != sp.nat(0)), "Unauthorized") - sp.for i in sp.range(sp.nat(0), sp.len(self.data.links[link].relays)): - sp.if self.data.links[link].relays[i] != addr: - self.data.addrs[i] = self.data.links[link].relays[i] + sp.for item in self.data.links[link].relays.elements(): + sp.if item != addr: + self.data.addrs.add(item) self.data.links[link].relays = self.data.addrs - # TODO: delete addrs map - # del self.data.addrs + + # delete all items from addrs set + sp.for ele in self.data.addrs.elements(): + self.data.addrs.remove(ele) + @sp.onchain_view() def get_relays(self, link): """ Get registered relays. :param link: BTP Address of the connected BMC. - :return: A map of relays + :return: A list of relays """ sp.set_type(link, sp.TString) - sp.result(self.data.links[link].relays) + sp.result(self.data.links[link].relays.elements()) @sp.onchain_view() def get_bsh_service_by_name(self, service_name): sp.set_type(service_name, sp.TString) - sp.result(self.data.bsh_service[service_name]) + sp.result(self.data.bsh_services[service_name]) @sp.onchain_view() def get_link(self, to): @@ -466,15 +504,18 @@ def get_link_rx_height(self, prev): @sp.onchain_view() def get_link_relays(self, prev): sp.set_type(prev, sp.TString) - sp.result(self.data.links[prev].relays) + sp.result(self.data.links[prev].relays.elements()) @sp.onchain_view() def get_relay_status_by_link(self, prev): sp.set_type(prev, sp.TString) - relays = sp.compute(sp.map(tkey=sp.TNat, tvalue=types.Types.RelayStats)) - sp.for i in sp.range(sp.nat(0), sp.len(self.data.links[prev].relays)): - relays[i] = self.data.relay_stats[self.data.links[prev].relays[i]] - sp.result(relays) + _relays = sp.compute(sp.map(tkey=sp.TNat, tvalue=types.Types.RelayStats)) + + sp.for item in self.data.links[prev].relays.elements(): + i =sp.local("i", 0) + _relays[i.value] = self.data.relay_stats[item] + i.value += 1 + sp.result(_relays) @sp.entry_point def update_link_rx_seq(self, prev, val): @@ -502,13 +543,13 @@ def update_link_rx_height(self, prev, val): @sp.entry_point def update_link_reachable(self, prev, to): sp.set_type(prev, sp.TString) - sp.set_type(to, sp.TMap(sp.TNat, sp.TString)) + sp.set_type(to, sp.TSet(sp.TString)) self.only_bmc_periphery() - sp.for i in sp.range(sp.nat(0), sp.len(to)): - self.data.links[prev].reachable[i] = to[i] - net, addr = sp.match_pair(strings.split_btp_address(to[i])) - self.data.get_link_from_reachable_net[net] = sp.record(prev=prev, to=to[i]) + sp.for item in to.elements(): + self.data.links[prev].reachable.add(item) + net, addr = sp.match_pair(strings.split_btp_address(item)) + self.data.get_link_from_reachable_net[net] = sp.record(prev=prev, to=item) @sp.entry_point def delete_link_reachable(self, prev, index): @@ -516,14 +557,18 @@ def delete_link_reachable(self, prev, index): sp.set_type(index, sp.TNat) self.only_bmc_periphery() - net, addr = sp.match_pair(strings.split_btp_address(self.data.links[prev].reachable[index])) - - del self.data.get_link_from_reachable_net[net] - del self.data.links[prev].reachable[index] - self.data.links[prev].reachable[index] = self.data.links[prev].reachable[ - sp.as_nat(sp.len(self.data.links[prev].reachable) - 1) - ] - # TODO:pop from reachable + sp.for item in self.data.links[prev].reachable.elements(): + i = sp.local("i", 0) + sp.if i.value == index: + net, addr = sp.match_pair(strings.split_btp_address(item)) + + del self.data.get_link_from_reachable_net[net] + self.data.links[prev].reachable.remove(item) + # this is not needed when removing from set + # self.data.links[prev].reachable[index] = self.data.links[prev].reachable[ + # sp.as_nat(sp.len(self.data.links[prev].reachable) - 1) + # ] + i.value += 1 @sp.entry_point def update_relay_stats(self, relay, block_count_val, msg_count_val): From 27244d3eda9b7ed041524632b2c40e1b93e03693 Mon Sep 17 00:00:00 2001 From: Anatehc Date: Fri, 31 Mar 2023 09:14:01 +0545 Subject: [PATCH 015/211] fix: interscore calls --- smartpy/bts/contracts/src/BTSCore.py | 249 ++++++++++++++++++++++++--- 1 file changed, 221 insertions(+), 28 deletions(-) diff --git a/smartpy/bts/contracts/src/BTSCore.py b/smartpy/bts/contracts/src/BTSCore.py index 36079c4e..0283035d 100644 --- a/smartpy/bts/contracts/src/BTSCore.py +++ b/smartpy/bts/contracts/src/BTSCore.py @@ -1,6 +1,6 @@ import smartpy as sp -# types = sp.io.import_script_from_url("file:./contracts/src/Types.py") +types = sp.io.import_script_from_url("file:./contracts/src/Types.py") Coin = sp.TRecord(addr=sp.TAddress, feeNumerator=sp.TNat, fixedFee=sp.TNat, coinType=sp.TNat) @@ -47,7 +47,7 @@ def __init__(self, ownerManager_address, btsPeriphery_address, _nativeCoinName, coinsAddress=sp.map({}, tkey=sp.TAddress, tvalue=sp.TString), ) - + #is this necessary? can we check against owners map in line 37? def OnlyOwner(self, _owner): # call Owner Manager Contract for checking owner isOwner = sp.view("isOwner", self.data.ownerManager_contract_address, sp.sender, t=sp.TBool).open_some( @@ -57,8 +57,6 @@ def OnlyOwner(self, _owner): sp.verify(isOwner == sp.sender, message="Unauthorized") - def OnlyBtsPeriphery(self, _owner): - sp.verify(sp.sender == self.data.btsPeriphery_contract_address, message="Unauthorized") # Get the name of Native Coin , Caller can be any @sp.onchain_view() @@ -72,7 +70,7 @@ def updateBTSPeriphery(self, _btsPeripheryAddr): sp.set_type(_btsPeripheryAddr, sp.TAddress) sp.verify(self.data.owners[sp.sender], message="Unauthorized") sp.verify(_btsPeripheryAddr != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), message="InvalidSetting") - # sp.if(self.data.btsPeriphery_contract_address != sp.none): + sp.if(self.data.btsPeriphery_contract_address != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc")): btsPeriphery_contract = sp.view("hasPendingRequest", self.data.btsPeriphery_contract_address, sp.none, t=sp.TBool).open_some("OwnerNotFound") @@ -110,7 +108,7 @@ def register(self, _name, _symbol, _decimals, _fee_numerator, _fixed_fee, _addr sp.verify(self.data.coins[_name] == sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), message= "ExistCoin") sp.verify(_fee_numerator <= self.FEE_DENOMINATOR, message="InvalidSetting") sp.verify((_fixed_fee > 0) & (_fee_numerator >= 0), message="LessThan0") - # TODO: + # TODO: confirm zero addr for tezos sp.if _addr == sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"): # deploy FA2 contract and set the deployed address # deployedFA2 = sp.address() @@ -136,8 +134,11 @@ def register(self, _name, _symbol, _decimals, _fee_numerator, _fixed_fee, _addr # ToDO: initialise string and make interscore call. token_arr = sp.list[_name] val_arr = sp.list[] - set_token_limit = sp.contract(sp.list,sp.list, self.data.btsPeriphery_contract_address,"setTokenLimit").open_some() - sp.transfer(token_arr, val_arr, sp.tez(0), setTokenLimit) + #TODO: confirm the following interscore call is correct or not + set_token_limit_args_type = sp.TRecord(coin_names = sp.TMap(sp.TNat, sp.TString), token_limit =sp.TMap(sp.TNat, sp.TNat)) + set_token_limit_entry_point = sp.contract(set_token_limit_args_type, self.data.btsPeriphery_contract_address,"setTokenLimit").open_some() + set_token_limit_args = sp.record(coin_names = token_arr, token_limit = val_arr) + sp.transfer(set_token_limit_args,sp.tez(0),set_token_limit_entry_point) # Return all supported coins names , Caller can be any @@ -173,7 +174,7 @@ def balanceOf(self, _owner, _coin_name): sp.result(sp.record(_usable_balance = sp.nat(0), _locked_balane = self.data.balances[_owner][_coin_name].lockedBalance, _refundable_balance = self.data.balances[_owner][_coin_name].refundableBalance, - _user_balance = sp.balance_of(sp.address(_owner))) + _user_balance = sp.balance_of(sp.address(_owner)))) _fa2_address = self.data.coins[_coin_name] # IERC20 ierc20 = IERC20(_erc20Address); #TODO: userbalance = token balance of a user? @@ -188,54 +189,246 @@ def balanceOf(self, _owner, _coin_name): sp.result(sp.record(_usable_balance, _locked_balane=self.data.balances[_owner][_coin_name].lockedBalance, _refundable_balance=self.data.balances[_owner][_coin_name].refundableBalance, - _user_balance) + _user_balance)) @sp.onchain_view() def balanceOfBatch(self, _owner, _coin_names): sp.verify((sp.len(_coin_names) >0 ) & (sp.len(_coin_names) <= self.MAX_BATCH_SIZE), message = "BatchMaxSizeExceed") - #ToDO: make a dynamic array + _usable_balances =sp.local("_usable_balances", {}, t=sp.TMap(tkey=sp.TNat, tvalue=sp.TNat)) + _locked_balances =sp.local("_locked_balances", {}, t=sp.TMap(tkey=sp.TNat, tvalue=sp.TNat)) + _refundable_balances =sp.local("_refundable_balances", {}, t=sp.TMap(tkey=sp.TNat, tvalue=sp.TNat)) + _user_balances =sp.local("_user_balances", {}, t=sp.TMap(tkey=sp.TNat, tvalue=sp.TNat)) sp.for i in sp.range(0, sp.len(_coin_names)): - #TODO + (_usable_balances[i], + _locked_balances[i], + _refundable_balances[i], + _user_balances[i]) = balanceOf(_owner, _coin_names[i]) #Confirm this part + sp.result(sp.record(_usable_balances, _locked_balances, _refundable_balances, _user_balances)) @sp.onchain_view() #TODO: dynamic array? def getAccumulatedFees(): sp.for i in sp.range(0, sp.len( self.data.coinsName)): - _accumulatedFees[i] = Types.Asset(self.data.coinsName[i], aggregationFee[self.data.coinsName[i]) + _accumulatedFees[i] = Types.Asset(self.data.coinsName[i], aggregationFee[self.data.coinsName[i]]) sp.result(_accumulatedFees) - @sp.entry_point() + @sp.entry_point def transferNativeCoin (self, _to): - #TODO: confirm data type for + #TODO: confirm data type for amount check_transfer_restrictions = sp.contract(sp.string,sp.address,sp.nat, self.data.btsPeriphery_contract_address,"checkTransferRestrictions").open_some() - sp.transfer(self.data.nativeCoinName,sp.sender, sp.amount) + sp.transfer(self.data.nativeCoinName,sp.sender, sp.amount, check_transfer_restrictions) # Aggregation Fee will be charged on BSH Contract # `fixedFee` is introduced as charging fee # charge_amt = fixedFee + msg.value * feeNumerator / FEE_DENOMINATOR charge_amt = sp.amount * self.data.coinDetails[self.data.nativeCoinName].feeNumerator //self.FEE_DENOMINATOR - + self.data.coinDetails[self.data.nativeCoinName].fixedFee + + self.data.coinDetails[self.data.nativeCoinName].fixedFee #Confirm the type for this calculation - # @dev msg.value is an amount request to transfer (include fee) + # @dev sp.sender is an amount request to transfer (include fee) # Later on, it will be calculated a true amount that should be received at a destination - sendServiceMessage(sp.sender, _to, self.data.coinsName[0],sp.amount, charge_amt) + _sendServiceMessage(sp.sender, _to, self.data.coinsName[0],sp.amount, charge_amt) - @sp.entry_point() - def transfer(self, coin_name, value, _to): - sp.verify(coin_name == self.data.nativeCoinName, message="InvalidWrappedCoin") + @sp.entry_point + def transfer(self, _coin_name, value, _to): + sp.verify(_coin_name == self.data.nativeCoinName, message="InvalidWrappedCoin") _fa2_address = self.data.coins[_coinName] sp.verify(_fa2_address != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), message= "CoinNotRegistered") - #TODO: confirm data type for - check_transfer_restrictions = sp.contract(sp.string,sp.address,sp.nat, self.data.btsPeriphery_contract_address,"checkTransferRestrictions").open_some() - sp.transfer(self.data.nativeCoinName,sp.sender, sp.amount) + check_transfer_restrictions_args_type = sp.TRecord(_coinName =sp.Tstring, _user=sp.TAddress , _value=sp.TNat) + check_transfer_restrictions_entry_point = sp.contract(check_transfer_restrictions_args_type, self.data.btsPeriphery_contract_address,"checkTransferRestrictions").open_some() + check_transfer_restrictions_args = sp.record(_coinName = _coin_name,_user= sp.sender,_value = sp.amount ) + sp.transfer(check_transfer_restrictions_args,sp.tez(0), check_transfer_restrictions_entry_point) charge_amt = sp.amount - * self.data.coinDetails[self.data.nativeCoinName].feeNumerator + * self.data.coinDetails[_coin_name].feeNumerator //self.FEE_DENOMINATOR - + self.data.coinDetails[self.data.nativeCoinName].fixedFee + + self.data.coinDetails[_coin_name].fixedFee + #TODO: implement transferFrom function of fa2contract - sendServiceMessage(sp.sender, _to, self.data.coinsName[0],sp.amount, charge_amt) + + _sendServiceMessage(sp.sender, _to, self.data.coinsName[0],sp.amount, charge_amt) + + + def _sendServiceMessage(self, _from, _to, _coin_name, _value, _charge_amt) + sp.set_type(_from, sp.TAddress) + sp.set_type(_to, sp.TAddress) + sp.set_type(_coin_name, sp.TString) + sp.set_type(_value, sp.TNat) + sp.set_type(_charge_amt, sp.TNat) + sp.verify(_value > _charge_amt, message = "ValueGreaterThan0") + lockBalance(_from, _coin_name, _value) + + _coins= sp.local("_coins", {0 : "_coinName" }, t=sp.TMap(tkey=sp.TNat, tvalue=sp.TString)) + _amounts= sp.local("_amounts", {0 : sp.as_nat(_value - _charge_amt)}, t=sp.TMap(tkey=sp.TNat, tvalue=sp.TNat)) + _fees= sp.local("_fees", {0: _charge_amt}, t=sp.TMap(tkey=sp.TNat, tvalue=sp.TNat)) + +#TODO: confirm the following interscore call is correct or not + send_service_message_args_type = sp.TRecord(_from = sp.TAddress, to = sp.TAddress, coin_names = sp.TMap(sp.TNat, sp.Tstring), values = sp.TMap(sp.TNat,sp.TNat), fees = sp.TMap(sp.TNat, sp.TNat)) + send_service_message_entry_point = sp.contract(send_service_message_args_type, self.data.btsPeriphery_contract_address,"sendServiceMessage").open_some() + send_service_message_args = sp.record(_from = _from, to = _to, coin_names = _coins, values = _amounts, fees = _fees) + sp.transfer(send_service_message_args,sp.tez(0),send_service_message_entry_point) + + @sp.entry_point + def transferBatch(self, _coin_names, _values, _to) + sp.set_type(_coin_names, sp.TMap(tkey = TNat, tvalue = TString)) + sp.set_type(_values, sp.TMap(tkey = TNat, tvalue = TNat)) + sp.set_type(_to, sp.Taddress) + sp.verify(sp.len(_coin_names) == sp.len(_values), message ="InvalidRequest") + sp.verify(sp.len(_coin_names) >0, message = "Zero length arguments") + sp.if sp.amount != sp.nat(0): + size = sp.len(_coin_names)+sp.nat(1) + sp.if sp.amount == sp.nat(0): + size = sp.len(_coin_names) + sp.verify(size <= self.MAX_BATCH_SIZE, message ="InvalidRequest") + + _coins= sp.local("_coins", {}, t=sp.TMap(tkey=sp.TNat, tvalue=sp.TString)) + _amounts= sp.local("_amounts", {}, t=sp.TMap(tkey=sp.TNat, tvalue=sp.TNat)) + _charge_amts= sp.local("_charge_amts", {}, t=sp.TMap(tkey=sp.TNat, tvalue=sp.TNat)) + + Coin _coin + coin_name = sp.local("coin_name", "", t= TString) + value = sp.local("value", 0, t= tNat) + + sp.for i in sp.range(0, sp.len(_coin_names)): + _fa2_addresses = self.data.coins[_coin_names[i]] + sp.verify(_fa2_addresses != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), message= "CoinNotRegistered") + coin_name.value = _coin_names[i] + value = _values[i] + sp.verify(value > 0, message ="ZeroOrLess") + + check_transfer_restrictions_args_type = sp.TRecord(_coinName =sp.Tstring, _user=sp.TAddress , _value=sp.TNat) + check_transfer_restrictions_entry_point = sp.contract(check_transfer_restrictions_args_type, self.data.btsPeriphery_contract_address,"checkTransferRestrictions").open_some() + check_transfer_restrictions_args = sp.record(_coinName = coin_name,_user= sp.sender,_value = sp.amount ) + sp.transfer(check_transfer_restrictions_args,sp.tez(0), check_transfer_restrictions_entry_point) + + #TODO: implement transferFrom function of fa2contract + + _coin = self.data.coinDetails[coin_name] + _coins[i] = coin_name + _charge_amts[i] = value + *_coin.feeNumerator + //self.FEE_DENOMINATOR + + _coin.fixedFee + _amounts[i] = value - _charged_amts[i] #set proper data type for this calculation + + lockBalance(sp.sender, coin_name, value) + + sp.if sp.amount !=sp.nat(0): + check_transfer_restrictions_args_type = sp.TRecord(_coinName =sp.Tstring, _user=sp.TAddress , _value=sp.TNat) + check_transfer_restrictions_entry_point = sp.contract(check_transfer_restrictions_args_type, self.data.btsPeriphery_contract_address,"checkTransferRestrictions").open_some() + check_transfer_restrictions_args = sp.record(_coinName = self.data.nativeCoinName,_user= sp.sender,_value = sp.amount ) + sp.transfer(check_transfer_restrictions_args,sp.tez(0), check_transfer_restrictions_entry_point) + + _coins[size - 1] = self.data.nativeCoinName + _charge_amts[size -1] = sp.amount + * self.data.coinDetails[_coin_name].feeNumerator + //self.FEE_DENOMINATOR + + self.data.coinDetails[_coin_name].fixedFee + + _amounts[size -1] = sp.amount - _charged_amts[size -1] + + lockBalance(sp.sender, self.data.nativeCoinName, value) + + + #TODO: confirm the following interscore call is correct or not + send_service_message_args_type = sp.TRecord(_from = sp.TAddress, to = sp.TAddress, coin_names = sp.TMap(sp.TNat, sp.Tstring), values = sp.TMap(sp.TNat,sp.TNat), fees = sp.TMap(sp.TNat, sp.TNat)) + send_service_message_entry_point = sp.contract(send_service_message_args_type, self.data.btsPeriphery_contract_address,"sendServiceMessage").open_some() + send_service_message_args = sp.record(_from = sp.sender, to = _to, coin_names = _coins, values = _amounts, fees = _charge_amts) + sp.transfer(send_service_message_args,sp.tez(0),send_service_message_entry_point) + + @sp.entry_point + #TODO: implement nonReentrant + def reclaim(self, _coin_name, _value) + sp.verify(self.data.balances[sp.sender][_coin_name].refundableBalance >= _value, message="Imbalance") + self.data.balances[sp.sender][_coin_name].refundableBalance = self.data.balances[sp.sender][_coin_name].refundableBalance -_value + refund(sp.sender, _coin_name, _value) + + @sp.entry_point + #TODO: ref doc of solidity for this method to set as public or private + def refund(self, _to, _coin_name, _value) + #here address(this) refers to the address of this contract + sp.verify(sp.sender == sp.self_address, message="Unauthorized") + sp.if _coin_name == self.data.nativeCoinName: + paymentTransfer(_to, _value) + sp.else: + #TODO: implement transfer on fa2 + + def paymentTransfer(self, _to, _amount) + #TODO: implement the following: + # (bool sent,) = _to.call{value : _amount}(""); + # require(sent, "PaymentFailed"); + + @sp.entry_point + def mint(_to, _coin_name, _value) + sp.verify(sp.sender == self.data.btsPeriphery_contract_address, message="Unauthorized") + sp.if _coin_name == self.data.nativeCoinName: + paymentTransfer(_to, _value) + sp.if self.data.coinDetails[_coin_name].coinType == self.NATIVE_WRAPPED_COIN_TYPE: + #TODO : implement mint? + # IERC20Tradable(coins[_coinName]).mint(_to, _value) + sp.else self.data.coinDetails[_coinName].coinType == self.NON_NATIVE_TOKEN_TYPE: + #TODO: implement transfer + # IERC20(coins[_coinName]).transfer(_to, _value) + + + @sp.entry_point + def handleResponseService( self, _requester, _coin_name, _value, _fee, _rsp_code) + sp.verify(sp.sender == self.data.btsPeriphery_contract_address, message="Unauthorized") + sp.if _requester == sp.self_address: + sp.if _rsp_code == self.RC_ERR: + self.data.aggregationFee[_coin_name] = self.data.aggregationFee[_coin_name] + _value + + _amount = _value + _fee + self.data.balances[_requester][_coin_name].lockedBalance = self.data.balances[_requester][_coin_name].lockedBalance -_amount + sp.if _rsp_code == self.RC_ERR: + _fa2_address = self.data.coins[_coin_name] + sp.if (_coin_name != self.data.nativeCoinName) & (self.data.coinDetails[_coin_name].coinType == self.NATIVE_WRAPPED_COIN_TYPE): + #TODO:implement burn + #IERC20Tradable(_erc20Address).burn(address(this), _value) + + self.data.aggregationFee[_coin_name] = self.data.aggregationFee[_coin_name] + _fee + + + @sp.entry_point + #here _fa is an address, not sure why its in string + def transferFees(self, _fa) + sp.verify(sp.sender == self.data.btsPeriphery_contract_address, message="Unauthorized") + sp.for i in sp.range(0, sp.len(self.data.coinsName)): + sp.if self.data.aggregationFee[self.data.coinsName[i]] != sp.nat(0) + self.data.chargedCoins.push(self.data.coinsName[i]) + self.data.chargedAmounts.push(self.data.aggregationFee[self.data.coinsName[i]]) + del self.data.aggregationFee[self.data.coinsName[i]] + #TODO: confirm data type for amount, address(this),refer solidity doc + send_service_message= sp.contract(sp.address,sp.address, sp.list, sp.list, sp.list,self.data.btsPeriphery_contract_address,"sendServiceMessage").open_some() + sp.transfer(sp.self_address, _fa, chargedCoins, chargedAmounts, [], send_service_message ) + + #TODO: confirm the following interscore call is correct or not + check for fees. + send_service_message_args_type = sp.TRecord(_from = sp.TAddress, to = sp.TAddress, coin_names = sp.TMap(sp.TNat, sp.Tstring), values = sp.TMap(sp.TNat,sp.TNat), fees = sp.TMap(sp.TNat, sp.TNat)) + send_service_message_entry_point = sp.contract(send_service_message_args_type, self.data.btsPeriphery_contract_address,"sendServiceMessage").open_some() + send_service_message_args = sp.record(_from = sp.self_address, to = _fa, coin_names = chargedCoins, values = chargedAmounts, fees = []) + sp.transfer(send_service_message_args,sp.tez(0),send_service_message_entry_point) + + del self.data.chargedCoins + del self.data.chargedAmounts + + def lockBalance(self, _to, _coin_name, _value) + self.data.balances[_to][_coin_name].lockedBalance = self.data.balances[_to][_coin_name].lockedBalance + _value + + @sp.entry_point + def updateCoinDb() + sp.verify(onlyOwner(sp.sender) == True, message= "Unauthorized") + self.data.coins[self.data.nativeCoinName] = sp.address(self.NATIVE_COIN_ADDRESS) + self.data.coinsAddress[sp.address(self.NATIVE_COIN_ADDRESS)] = self.data.nativeCoinName + coins_length = sp.len(self.data.coinsLength) + sp.for i in sp.range(0, coins_length): + sp.if self.data.coinsName[i] != self.data.nativeCoinName: + self.data.coinsAddress[self.data.coinDetails[self.data.coinsName[i]].addr] = self.data.coinsName[i] + + @sp.entry_point + def setBTSOwnerManager(_ownerManager) + sp.verify(self.data.owners[sp.sender] == True , message= "Unauthorized") + sp.verify(_ownerManager != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), message= "InvalidAddress") + #TODO :set addr self.data.btsOwnerManager = _ownerManager @sp.add_test(name="BTSCore") def test(): From ee0a4af8c485d44fa9bb9d73076de917ea8f0e81 Mon Sep 17 00:00:00 2001 From: simusud Date: Wed, 5 Apr 2023 12:43:32 +0545 Subject: [PATCH 016/211] feat(bts): Add bts core functions --- smartpy/bts/contracts/src/BTSCore.py | 459 ------------------ smartpy/bts/contracts/src/bts_core.py | 645 ++++++++++++++++++++++++++ 2 files changed, 645 insertions(+), 459 deletions(-) delete mode 100644 smartpy/bts/contracts/src/BTSCore.py create mode 100644 smartpy/bts/contracts/src/bts_core.py diff --git a/smartpy/bts/contracts/src/BTSCore.py b/smartpy/bts/contracts/src/BTSCore.py deleted file mode 100644 index 0283035d..00000000 --- a/smartpy/bts/contracts/src/BTSCore.py +++ /dev/null @@ -1,459 +0,0 @@ -import smartpy as sp - -types = sp.io.import_script_from_url("file:./contracts/src/Types.py") -Coin = sp.TRecord(addr=sp.TAddress, feeNumerator=sp.TNat, fixedFee=sp.TNat, - coinType=sp.TNat) - - -class BTSCore(sp.Contract): - FEE_DENOMINATOR = sp.nat(10000) - RC_OK = sp.nat(0) - RC_ERR = sp.nat(1) - NATIVE_COIN_TYPE = sp.nat(0) - NATIVE_WRAPPED_COIN_TYPE = sp.nat(1) - NON_NATIVE_TOKEN_TYPE = sp.nat(2) - - MAX_BATCH_SIZE = sp.nat(15) - NATIVE_COIN_ADDRESS = sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc") - - # TODO: change the native coin addr - - def __init__(self, ownerManager_address, btsPeriphery_address, _nativeCoinName, _feeNumerator, _fixedFee, - ): - # Sets the initial storage of the contract with an empty map and a list containing the owner address - self.update_initial_storage( - - ownerManager_contract_address=ownerManager_address, - btsPeriphery_contract_address=btsPeriphery_address, - nativeCoinName=_nativeCoinName, - listOfOwners=sp.list(t=sp.TAddress), - # a list of amounts have been charged so far (use this when Fee Gathering occurs) - chargedAmounts=sp.list(t=sp.TNat), - # a string array stores names of supported coins - coinsName=sp.list([_nativeCoinName], t=sp.TString), - # a list of coins' names have been charged so far (use this when Fee Gathering occurs) - chargedCoins=sp.list(t=sp.TString), - - owners=sp.map({}, tkey=sp.TAddress, tvalue=sp.TBool), - aggregationFee=sp.map({}, tkey=sp.TString, tvalue=sp.TInt), - balances=sp.big_map(tkey=sp.TRecord(sp.TAddress,sp.TString), tvalue= types.Type.Balance), - coins=sp.map({_nativeCoinName: self.NATIVE_COIN_ADDRESS}, tkey=sp.TString, tvalue=sp.TAddress), - - coinDetails=sp.map({_nativeCoinName: sp.record(addr=self.NATIVE_COIN_ADDRESS, - feeNumerator=_feeNumerator, - fixedFee=_fixedFee, - coinType=sp.nat(0))}, - tkey=sp.TString, tvalue=Coin), - - coinsAddress=sp.map({}, tkey=sp.TAddress, tvalue=sp.TString), - ) - #is this necessary? can we check against owners map in line 37? - def OnlyOwner(self, _owner): - # call Owner Manager Contract for checking owner - isOwner = sp.view("isOwner", self.data.ownerManager_contract_address, sp.sender, t=sp.TBool).open_some( - "OwnerNotFound") - - # ToDO: find a way to transfer function parameter to another contract - - sp.verify(isOwner == sp.sender, message="Unauthorized") - - - # Get the name of Native Coin , Caller can be any - @sp.onchain_view() - def getNativeCoinName(self): - sp.result(self.data.nativeCoinName) - - # update BTS Periphery address - # TODO: verify zero address - @sp.entry_point - def updateBTSPeriphery(self, _btsPeripheryAddr): - sp.set_type(_btsPeripheryAddr, sp.TAddress) - sp.verify(self.data.owners[sp.sender], message="Unauthorized") - sp.verify(_btsPeripheryAddr != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), message="InvalidSetting") - sp.if(self.data.btsPeriphery_contract_address != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc")): - btsPeriphery_contract = sp.view("hasPendingRequest", self.data.btsPeriphery_contract_address, sp.none, - t=sp.TBool).open_some("OwnerNotFound") - - sp.verify(btsPeriphery_contract == False, message="HasPendingRequest") - self.data.btsPeriphery_contract_address = _btsPeripheryAddr - - #set fee ratio, Caller must be the owner of this contract - #The transfer fee is calculated by feeNumerator/FEE_DEMONINATOR. - #_feeNumerator if it is set to `10`, which means the default fee ratio is 0.1%. - @sp.entry_point - def set_fee_ratio(self,_name,_fee_numerator,_fixed_fee): - sp.set_type(_name, sp.TString) - sp.set_type(_fee_numerator, sp.TNat) - sp.set_type(_fixed_fee, sp.TNat) - sp.verify(self.data.owners[sp.sender], message="Unauthorized") - sp.verify(_fee_numerator < self.FEE_DENOMINATOR, message="InvalidSetting") - sp.verify((_name == self.data.nativeCoinName) | - (self.data.coins[_name] != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc")), - message = "TokenNotExists") - sp.verify((_fixed_fee > 0) & (_fee_numerator >= 0), message = "LessThan0") - self.data.coinDetails[_name].feeNumerator = _fee_numerator - self.data.coinDetails[_name].fixedFee = _fixed_fee - - - @sp.entry_point - def register(self, _name, _symbol, _decimals, _fee_numerator, _fixed_fee, _addr ): - sp.set_type(_name, sp.TString) - sp.set_type(_symbol, sp.TString) - sp.set_type(_decimals, sp.TNat) - sp.set_type(_fee_numerator, sp.TNat) - sp.set_type(_fixed_fee, sp.TNat) - sp.set_type(_addr, sp.TAddress) - sp.verify(self.data.owners[sp.sender], message="Unauthorized") - sp.verify(_name == self.data.nativeCoinName, message= "ExistNativeCoin") - sp.verify(self.data.coins[_name] == sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), message= "ExistCoin") - sp.verify(_fee_numerator <= self.FEE_DENOMINATOR, message="InvalidSetting") - sp.verify((_fixed_fee > 0) & (_fee_numerator >= 0), message="LessThan0") - # TODO: confirm zero addr for tezos - sp.if _addr == sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"): - # deploy FA2 contract and set the deployed address - # deployedFA2 = sp.address() - self.data.coins[_name] = deployedFA2 - self.data.coinsName.push(_name) - self.data.coinsAddress[deployedFA2] = _name - self.data.coinDetails[_name] = Coin ( - addr = deployedFA2, - feeNumerator = _fee_numerator, - fixedFee = _fixed_fee, - coinType = self.NATIVE_WRAPPED_COIN_TYPE - ) - sp.else: - self.data.coins[_name] = _addr - self.data.coinsName.push(_name) - self.data.coinsAddress[_addr] = _name - self.data.coinDetails[_name] = Coin ( - addr = _addr, - feeNumerator = _fee_numerator, - fixedFee = _fixed_fee, - coinType = self.NON_NATIVE_TOKEN_TYPE - ) - # ToDO: initialise string and make interscore call. - token_arr = sp.list[_name] - val_arr = sp.list[] - #TODO: confirm the following interscore call is correct or not - set_token_limit_args_type = sp.TRecord(coin_names = sp.TMap(sp.TNat, sp.TString), token_limit =sp.TMap(sp.TNat, sp.TNat)) - set_token_limit_entry_point = sp.contract(set_token_limit_args_type, self.data.btsPeriphery_contract_address,"setTokenLimit").open_some() - set_token_limit_args = sp.record(coin_names = token_arr, token_limit = val_arr) - sp.transfer(set_token_limit_args,sp.tez(0),set_token_limit_entry_point) - - -# Return all supported coins names , Caller can be any - @sp.onchain_view() - def coinNames(self): - sp.result(self.data.coinsName) - - # Return the _id number of Coin whose name is the same with given _coinName - @sp.onchain_view() - def coinId(self, _coinName): - sp.result(self.data.coins[_coinName]) - - - @sp.onchain_view() - def isValidCoin(self, _coin_name): - sp.if (self.data.coins[_coin_name] != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"))|( _coin_name == self.data.nativeCoinName): - sp.result(True) - sp.else: - sp.result(False) - - @sp.onchain_view() - def feeRatio(self, _coin_name): - coin = self.data.coinDetails[_coin_name] - _fee_numerator = coin.feeNumerator - _fixed_fee = coin.fixedFee - sp.result(sp.record(fee_numerator =_fee_numerator,fixed_fee = _fixed_fee)) - - - @sp.onchain_view() - # TODO: confirm sp.balance_Of() - def balanceOf(self, _owner, _coin_name): - sp.if _coin_name == self.data.nativeCoinName: - sp.result(sp.record(_usable_balance = sp.nat(0), - _locked_balane = self.data.balances[_owner][_coin_name].lockedBalance, - _refundable_balance = self.data.balances[_owner][_coin_name].refundableBalance, - _user_balance = sp.balance_of(sp.address(_owner)))) - _fa2_address = self.data.coins[_coin_name] - # IERC20 ierc20 = IERC20(_erc20Address); - #TODO: userbalance = token balance of a user? - # allowance? - sp.if _fa2_address != self.data.zero_addr: - # return token balance of _owner - # _user_balance = - sp.if _fa2_address == self.data.zero_addr: - _user_balance = sp.nat(0) - sp.result(_user_balance) - # TODO: userbalance and allowance operations - sp.result(sp.record(_usable_balance, - _locked_balane=self.data.balances[_owner][_coin_name].lockedBalance, - _refundable_balance=self.data.balances[_owner][_coin_name].refundableBalance, - _user_balance)) - - - @sp.onchain_view() - def balanceOfBatch(self, _owner, _coin_names): - sp.verify((sp.len(_coin_names) >0 ) & (sp.len(_coin_names) <= self.MAX_BATCH_SIZE), message = "BatchMaxSizeExceed") - _usable_balances =sp.local("_usable_balances", {}, t=sp.TMap(tkey=sp.TNat, tvalue=sp.TNat)) - _locked_balances =sp.local("_locked_balances", {}, t=sp.TMap(tkey=sp.TNat, tvalue=sp.TNat)) - _refundable_balances =sp.local("_refundable_balances", {}, t=sp.TMap(tkey=sp.TNat, tvalue=sp.TNat)) - _user_balances =sp.local("_user_balances", {}, t=sp.TMap(tkey=sp.TNat, tvalue=sp.TNat)) - sp.for i in sp.range(0, sp.len(_coin_names)): - (_usable_balances[i], - _locked_balances[i], - _refundable_balances[i], - _user_balances[i]) = balanceOf(_owner, _coin_names[i]) #Confirm this part - sp.result(sp.record(_usable_balances, _locked_balances, _refundable_balances, _user_balances)) - - @sp.onchain_view() - #TODO: dynamic array? - def getAccumulatedFees(): - sp.for i in sp.range(0, sp.len( self.data.coinsName)): - _accumulatedFees[i] = Types.Asset(self.data.coinsName[i], aggregationFee[self.data.coinsName[i]]) - sp.result(_accumulatedFees) - - @sp.entry_point - def transferNativeCoin (self, _to): - #TODO: confirm data type for amount - check_transfer_restrictions = sp.contract(sp.string,sp.address,sp.nat, self.data.btsPeriphery_contract_address,"checkTransferRestrictions").open_some() - sp.transfer(self.data.nativeCoinName,sp.sender, sp.amount, check_transfer_restrictions) - # Aggregation Fee will be charged on BSH Contract - # `fixedFee` is introduced as charging fee - # charge_amt = fixedFee + msg.value * feeNumerator / FEE_DENOMINATOR - charge_amt = sp.amount - * self.data.coinDetails[self.data.nativeCoinName].feeNumerator - //self.FEE_DENOMINATOR - + self.data.coinDetails[self.data.nativeCoinName].fixedFee #Confirm the type for this calculation - - # @dev sp.sender is an amount request to transfer (include fee) - # Later on, it will be calculated a true amount that should be received at a destination - _sendServiceMessage(sp.sender, _to, self.data.coinsName[0],sp.amount, charge_amt) - - @sp.entry_point - def transfer(self, _coin_name, value, _to): - sp.verify(_coin_name == self.data.nativeCoinName, message="InvalidWrappedCoin") - _fa2_address = self.data.coins[_coinName] - sp.verify(_fa2_address != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), message= "CoinNotRegistered") - check_transfer_restrictions_args_type = sp.TRecord(_coinName =sp.Tstring, _user=sp.TAddress , _value=sp.TNat) - check_transfer_restrictions_entry_point = sp.contract(check_transfer_restrictions_args_type, self.data.btsPeriphery_contract_address,"checkTransferRestrictions").open_some() - check_transfer_restrictions_args = sp.record(_coinName = _coin_name,_user= sp.sender,_value = sp.amount ) - sp.transfer(check_transfer_restrictions_args,sp.tez(0), check_transfer_restrictions_entry_point) - charge_amt = sp.amount - * self.data.coinDetails[_coin_name].feeNumerator - //self.FEE_DENOMINATOR - + self.data.coinDetails[_coin_name].fixedFee - - #TODO: implement transferFrom function of fa2contract - - _sendServiceMessage(sp.sender, _to, self.data.coinsName[0],sp.amount, charge_amt) - - - def _sendServiceMessage(self, _from, _to, _coin_name, _value, _charge_amt) - sp.set_type(_from, sp.TAddress) - sp.set_type(_to, sp.TAddress) - sp.set_type(_coin_name, sp.TString) - sp.set_type(_value, sp.TNat) - sp.set_type(_charge_amt, sp.TNat) - sp.verify(_value > _charge_amt, message = "ValueGreaterThan0") - lockBalance(_from, _coin_name, _value) - - _coins= sp.local("_coins", {0 : "_coinName" }, t=sp.TMap(tkey=sp.TNat, tvalue=sp.TString)) - _amounts= sp.local("_amounts", {0 : sp.as_nat(_value - _charge_amt)}, t=sp.TMap(tkey=sp.TNat, tvalue=sp.TNat)) - _fees= sp.local("_fees", {0: _charge_amt}, t=sp.TMap(tkey=sp.TNat, tvalue=sp.TNat)) - -#TODO: confirm the following interscore call is correct or not - send_service_message_args_type = sp.TRecord(_from = sp.TAddress, to = sp.TAddress, coin_names = sp.TMap(sp.TNat, sp.Tstring), values = sp.TMap(sp.TNat,sp.TNat), fees = sp.TMap(sp.TNat, sp.TNat)) - send_service_message_entry_point = sp.contract(send_service_message_args_type, self.data.btsPeriphery_contract_address,"sendServiceMessage").open_some() - send_service_message_args = sp.record(_from = _from, to = _to, coin_names = _coins, values = _amounts, fees = _fees) - sp.transfer(send_service_message_args,sp.tez(0),send_service_message_entry_point) - - @sp.entry_point - def transferBatch(self, _coin_names, _values, _to) - sp.set_type(_coin_names, sp.TMap(tkey = TNat, tvalue = TString)) - sp.set_type(_values, sp.TMap(tkey = TNat, tvalue = TNat)) - sp.set_type(_to, sp.Taddress) - sp.verify(sp.len(_coin_names) == sp.len(_values), message ="InvalidRequest") - sp.verify(sp.len(_coin_names) >0, message = "Zero length arguments") - sp.if sp.amount != sp.nat(0): - size = sp.len(_coin_names)+sp.nat(1) - sp.if sp.amount == sp.nat(0): - size = sp.len(_coin_names) - sp.verify(size <= self.MAX_BATCH_SIZE, message ="InvalidRequest") - - _coins= sp.local("_coins", {}, t=sp.TMap(tkey=sp.TNat, tvalue=sp.TString)) - _amounts= sp.local("_amounts", {}, t=sp.TMap(tkey=sp.TNat, tvalue=sp.TNat)) - _charge_amts= sp.local("_charge_amts", {}, t=sp.TMap(tkey=sp.TNat, tvalue=sp.TNat)) - - Coin _coin - coin_name = sp.local("coin_name", "", t= TString) - value = sp.local("value", 0, t= tNat) - - sp.for i in sp.range(0, sp.len(_coin_names)): - _fa2_addresses = self.data.coins[_coin_names[i]] - sp.verify(_fa2_addresses != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), message= "CoinNotRegistered") - coin_name.value = _coin_names[i] - value = _values[i] - sp.verify(value > 0, message ="ZeroOrLess") - - check_transfer_restrictions_args_type = sp.TRecord(_coinName =sp.Tstring, _user=sp.TAddress , _value=sp.TNat) - check_transfer_restrictions_entry_point = sp.contract(check_transfer_restrictions_args_type, self.data.btsPeriphery_contract_address,"checkTransferRestrictions").open_some() - check_transfer_restrictions_args = sp.record(_coinName = coin_name,_user= sp.sender,_value = sp.amount ) - sp.transfer(check_transfer_restrictions_args,sp.tez(0), check_transfer_restrictions_entry_point) - - #TODO: implement transferFrom function of fa2contract - - _coin = self.data.coinDetails[coin_name] - _coins[i] = coin_name - _charge_amts[i] = value - *_coin.feeNumerator - //self.FEE_DENOMINATOR - + _coin.fixedFee - _amounts[i] = value - _charged_amts[i] #set proper data type for this calculation - - lockBalance(sp.sender, coin_name, value) - - sp.if sp.amount !=sp.nat(0): - check_transfer_restrictions_args_type = sp.TRecord(_coinName =sp.Tstring, _user=sp.TAddress , _value=sp.TNat) - check_transfer_restrictions_entry_point = sp.contract(check_transfer_restrictions_args_type, self.data.btsPeriphery_contract_address,"checkTransferRestrictions").open_some() - check_transfer_restrictions_args = sp.record(_coinName = self.data.nativeCoinName,_user= sp.sender,_value = sp.amount ) - sp.transfer(check_transfer_restrictions_args,sp.tez(0), check_transfer_restrictions_entry_point) - - _coins[size - 1] = self.data.nativeCoinName - _charge_amts[size -1] = sp.amount - * self.data.coinDetails[_coin_name].feeNumerator - //self.FEE_DENOMINATOR - + self.data.coinDetails[_coin_name].fixedFee - - _amounts[size -1] = sp.amount - _charged_amts[size -1] - - lockBalance(sp.sender, self.data.nativeCoinName, value) - - - #TODO: confirm the following interscore call is correct or not - send_service_message_args_type = sp.TRecord(_from = sp.TAddress, to = sp.TAddress, coin_names = sp.TMap(sp.TNat, sp.Tstring), values = sp.TMap(sp.TNat,sp.TNat), fees = sp.TMap(sp.TNat, sp.TNat)) - send_service_message_entry_point = sp.contract(send_service_message_args_type, self.data.btsPeriphery_contract_address,"sendServiceMessage").open_some() - send_service_message_args = sp.record(_from = sp.sender, to = _to, coin_names = _coins, values = _amounts, fees = _charge_amts) - sp.transfer(send_service_message_args,sp.tez(0),send_service_message_entry_point) - - @sp.entry_point - #TODO: implement nonReentrant - def reclaim(self, _coin_name, _value) - sp.verify(self.data.balances[sp.sender][_coin_name].refundableBalance >= _value, message="Imbalance") - self.data.balances[sp.sender][_coin_name].refundableBalance = self.data.balances[sp.sender][_coin_name].refundableBalance -_value - refund(sp.sender, _coin_name, _value) - - @sp.entry_point - #TODO: ref doc of solidity for this method to set as public or private - def refund(self, _to, _coin_name, _value) - #here address(this) refers to the address of this contract - sp.verify(sp.sender == sp.self_address, message="Unauthorized") - sp.if _coin_name == self.data.nativeCoinName: - paymentTransfer(_to, _value) - sp.else: - #TODO: implement transfer on fa2 - - def paymentTransfer(self, _to, _amount) - #TODO: implement the following: - # (bool sent,) = _to.call{value : _amount}(""); - # require(sent, "PaymentFailed"); - - @sp.entry_point - def mint(_to, _coin_name, _value) - sp.verify(sp.sender == self.data.btsPeriphery_contract_address, message="Unauthorized") - sp.if _coin_name == self.data.nativeCoinName: - paymentTransfer(_to, _value) - sp.if self.data.coinDetails[_coin_name].coinType == self.NATIVE_WRAPPED_COIN_TYPE: - #TODO : implement mint? - # IERC20Tradable(coins[_coinName]).mint(_to, _value) - sp.else self.data.coinDetails[_coinName].coinType == self.NON_NATIVE_TOKEN_TYPE: - #TODO: implement transfer - # IERC20(coins[_coinName]).transfer(_to, _value) - - - @sp.entry_point - def handleResponseService( self, _requester, _coin_name, _value, _fee, _rsp_code) - sp.verify(sp.sender == self.data.btsPeriphery_contract_address, message="Unauthorized") - sp.if _requester == sp.self_address: - sp.if _rsp_code == self.RC_ERR: - self.data.aggregationFee[_coin_name] = self.data.aggregationFee[_coin_name] + _value - - _amount = _value + _fee - self.data.balances[_requester][_coin_name].lockedBalance = self.data.balances[_requester][_coin_name].lockedBalance -_amount - sp.if _rsp_code == self.RC_ERR: - _fa2_address = self.data.coins[_coin_name] - sp.if (_coin_name != self.data.nativeCoinName) & (self.data.coinDetails[_coin_name].coinType == self.NATIVE_WRAPPED_COIN_TYPE): - #TODO:implement burn - #IERC20Tradable(_erc20Address).burn(address(this), _value) - - self.data.aggregationFee[_coin_name] = self.data.aggregationFee[_coin_name] + _fee - - - @sp.entry_point - #here _fa is an address, not sure why its in string - def transferFees(self, _fa) - sp.verify(sp.sender == self.data.btsPeriphery_contract_address, message="Unauthorized") - sp.for i in sp.range(0, sp.len(self.data.coinsName)): - sp.if self.data.aggregationFee[self.data.coinsName[i]] != sp.nat(0) - self.data.chargedCoins.push(self.data.coinsName[i]) - self.data.chargedAmounts.push(self.data.aggregationFee[self.data.coinsName[i]]) - del self.data.aggregationFee[self.data.coinsName[i]] - #TODO: confirm data type for amount, address(this),refer solidity doc - send_service_message= sp.contract(sp.address,sp.address, sp.list, sp.list, sp.list,self.data.btsPeriphery_contract_address,"sendServiceMessage").open_some() - sp.transfer(sp.self_address, _fa, chargedCoins, chargedAmounts, [], send_service_message ) - - #TODO: confirm the following interscore call is correct or not + check for fees. - send_service_message_args_type = sp.TRecord(_from = sp.TAddress, to = sp.TAddress, coin_names = sp.TMap(sp.TNat, sp.Tstring), values = sp.TMap(sp.TNat,sp.TNat), fees = sp.TMap(sp.TNat, sp.TNat)) - send_service_message_entry_point = sp.contract(send_service_message_args_type, self.data.btsPeriphery_contract_address,"sendServiceMessage").open_some() - send_service_message_args = sp.record(_from = sp.self_address, to = _fa, coin_names = chargedCoins, values = chargedAmounts, fees = []) - sp.transfer(send_service_message_args,sp.tez(0),send_service_message_entry_point) - - del self.data.chargedCoins - del self.data.chargedAmounts - - def lockBalance(self, _to, _coin_name, _value) - self.data.balances[_to][_coin_name].lockedBalance = self.data.balances[_to][_coin_name].lockedBalance + _value - - @sp.entry_point - def updateCoinDb() - sp.verify(onlyOwner(sp.sender) == True, message= "Unauthorized") - self.data.coins[self.data.nativeCoinName] = sp.address(self.NATIVE_COIN_ADDRESS) - self.data.coinsAddress[sp.address(self.NATIVE_COIN_ADDRESS)] = self.data.nativeCoinName - coins_length = sp.len(self.data.coinsLength) - sp.for i in sp.range(0, coins_length): - sp.if self.data.coinsName[i] != self.data.nativeCoinName: - self.data.coinsAddress[self.data.coinDetails[self.data.coinsName[i]].addr] = self.data.coinsName[i] - - @sp.entry_point - def setBTSOwnerManager(_ownerManager) - sp.verify(self.data.owners[sp.sender] == True , message= "Unauthorized") - sp.verify(_ownerManager != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), message= "InvalidAddress") - #TODO :set addr self.data.btsOwnerManager = _ownerManager - -@sp.add_test(name="BTSCore") -def test(): - c1 = BTSCore( - ownerManager_address=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), - btsPeriphery_address=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), - _nativeCoinName="NativeCoin", - _feeNumerator=sp.nat(1000), - _fixedFee=sp.nat(10) - ) - scenario = sp.test_scenario() - scenario.h1("BTSCore") - scenario += c1 - - -sp.add_compilation_target("", BTSCore( - ownerManager_address=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), - btsPeriphery_address=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), - _nativeCoinName="NativeCoin", - _feeNumerator=sp.nat(1000), - _fixedFee=sp.nat(10) -)) - - - - - - diff --git a/smartpy/bts/contracts/src/bts_core.py b/smartpy/bts/contracts/src/bts_core.py new file mode 100644 index 00000000..c1942a6a --- /dev/null +++ b/smartpy/bts/contracts/src/bts_core.py @@ -0,0 +1,645 @@ +import smartpy as sp + +types = sp.io.import_script_from_url("file:./contracts/src/Types.py") +Coin = sp.TRecord(addr=sp.TAddress, fee_numerator=sp.TNat, fixed_fee=sp.TNat, + coin_type=sp.TNat) + + +class BTSCore(sp.Contract): + FEE_DENOMINATOR = sp.nat(10000) + RC_OK = sp.nat(0) + RC_ERR = sp.nat(1) + NATIVE_COIN_TYPE = sp.nat(0) + NATIVE_WRAPPED_COIN_TYPE = sp.nat(1) + NON_NATIVE_TOKEN_TYPE = sp.nat(2) + + MAX_BATCH_SIZE = sp.nat(15) + NATIVE_COIN_ADDRESS = sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc") + + # TODO: change the native coin addr + + def __init__(self, _native_coin_name, _fee_numerator, _fixed_fee, owner_manager, bts_periphery_addr): + self.update_initial_storage( + bts_owner_manager=owner_manager, + bts_periphery_address=bts_periphery_addr, + native_coin_name=_native_coin_name, + + list_of_owners=sp.list(t=sp.TAddress), + charged_amounts=sp.map(tkey=sp.TNat, tvalue=sp.TNat), + coins_name=sp.list([_native_coin_name], t=sp.TString), + charged_coins=sp.map(tkey=sp.TNat, tvalue=sp.TString), + + owners=sp.map({}, tkey=sp.TAddress, tvalue=sp.TBool), + aggregation_fee=sp.map({}, tkey=sp.TString, tvalue=sp.TNat), + balances=sp.big_map(tkey=sp.TRecord(address=sp.TAddress, coin_name=sp.TString), tvalue= types.Types.Balance), + coins=sp.map({_native_coin_name: self.NATIVE_COIN_ADDRESS}, tkey=sp.TString, tvalue=sp.TAddress), + coin_details=sp.map({_native_coin_name: sp.record(addr=self.NATIVE_COIN_ADDRESS, + fee_numerator=_fee_numerator, + fixed_fee=_fixed_fee, + coin_type=self.NATIVE_COIN_TYPE)}, + tkey=sp.TString, tvalue=Coin), + coins_address=sp.map({}, tkey=sp.TAddress, tvalue=sp.TString), + ) + + #is this necessary? can we check against owners map in line 37? + def only_owner(self): + # call Owner Manager Contract for checking owner + is_owner = sp.view("is_owner", self.data.bts_owner_manager, sp.sender, t=sp.TBool).open_some( + "OwnerNotFound") + sp.verify(is_owner == True, message="Unauthorized") + + def only_bts_periphery(self): + sp.verify(sp.sender == self.data.bts_periphery_address, "Unauthorized") + + @sp.onchain_view() + def get_native_coin_name(self): + """ + Get name of nativecoin + :return: Name of nativecoin + """ + sp.result(self.data.native_coin_name) + + @sp.entry_point + def update_bts_periphery(self, bts_periphery): + """ + update BTS Periphery address. + :param bts_periphery: BTSPeriphery contract address. + :return: + """ + sp.set_type(bts_periphery, sp.TAddress) + + self.only_owner() + # TODO: verify zero address + sp.verify(bts_periphery != sp.address("tz1000000"), message="InvalidSetting") + sp.if self.data.bts_periphery_address != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"): + has_requests = sp.view("has_pending_request", self.data.bts_periphery_address, sp.none, + t=sp.TBool).open_some("OwnerNotFound") + sp.verify(has_requests == False, message="HasPendingRequest") + self.data.bts_periphery_address = bts_periphery + + #set fee ratio, Caller must be the owner of this contract + #The transfer fee is calculated by feeNumerator/FEE_DEMONINATOR. + #_feeNumerator if it is set to `10`, which means the default fee ratio is 0.1%. + @sp.entry_point + def set_fee_ratio(self, name, fee_numerator, fixed_fee): + """ + set fee ratio. + :param name: + :param fee_numerator: the fee numerator + :param fixed_fee: + :return: + """ + sp.set_type(name, sp.TString) + sp.set_type(fee_numerator, sp.TNat) + sp.set_type(fixed_fee, sp.TNat) + + self.only_owner() + sp.verify(fee_numerator < self.FEE_DENOMINATOR, message="InvalidSetting") + sp.verify((name == self.data.native_coin_name) | + (self.data.coins[name] != sp.address("tz1000")), + message = "TokenNotExists") + sp.verify((fixed_fee > sp.nat(0)) & (fee_numerator >= sp.nat(0)), message = "LessThan0") + self.data.coin_details[name].fee_numerator = fee_numerator + self.data.coin_details[name].fixed_fee = fixed_fee + + + @sp.entry_point + def register(self, name, symbol, decimals, fee_numerator, fixed_fee, addr): + """ + Registers a wrapped coin and id number of a supporting coin. + :param name: Must be different with the native coin name. + :param symbol: symbol name for wrapped coin. + :param decimals: decimal number + :param fee_numerator: + :param fixed_fee: + :param addr: address of the coin + :return: + """ + sp.set_type(name, sp.TString) + sp.set_type(symbol, sp.TString) + sp.set_type(decimals, sp.TNat) + sp.set_type(fee_numerator, sp.TNat) + sp.set_type(fixed_fee, sp.TNat) + sp.set_type(addr, sp.TAddress) + + self.only_owner() + sp.verify(name != self.data.native_coin_name, message="ExistNativeCoin") + sp.verify(self.data.coins[name] == sp.address("tz10000"), message= "ExistCoin") + sp.verify(self.data.coins_address[addr] == "", message="AddressExists") + sp.verify(fee_numerator <= self.FEE_DENOMINATOR, message="InvalidSetting") + sp.verify((fixed_fee >= sp.nat(0)) & (fee_numerator >= sp.nat(0)), message="LessThan0") + # TODO: confirm zero addr for tezos + with sp.if_(addr == sp.address("tz10000")): + # TODO:deploy FA2 contract and set the deployed address + deployed_fa2 = sp.address("tz10000") + self.data.coins[name] = deployed_fa2 + self.data.coins_name.push(name) + self.data.coins_address[deployed_fa2] = name + self.data.coin_details[name] = sp.record( + addr = deployed_fa2, + fee_numerator = fee_numerator, + fixed_fee = fixed_fee, + coin_type = self.NATIVE_WRAPPED_COIN_TYPE + ) + with sp.else_(): + self.data.coins[name] = addr + self.data.coins_name.push(name) + self.data.coins_address[addr] = name + self.data.coin_details[name] = sp.record( + addr = addr, + fee_numerator = fee_numerator, + fixed_fee = fixed_fee, + coin_type = self.NON_NATIVE_TOKEN_TYPE + ) + # ToDO: initialise string and make interscore call. + token_map = sp.map({0:name}) + val_map = sp.map({0:1}) + + # call set_token_limit on bts_periphery + set_token_limit_args_type = sp.TRecord(coin_names=sp.TMap(sp.TNat, sp.TString), token_limit=sp.TMap(sp.TNat, sp.TNat)) + set_token_limit_entry_point = sp.contract(set_token_limit_args_type, self.data.bts_periphery_address, "set_token_limit").open_some() + set_token_limit_args = sp.record(coin_names=token_map, token_limit=val_map) + sp.transfer(set_token_limit_args, sp.tez(0), set_token_limit_entry_point) + + + @sp.onchain_view() + def coin_names(self): + """ + Return all supported coins names + :return: An array of strings. + """ + sp.result(self.data.coins_name) + + @sp.onchain_view() + def coin_id(self, coin_name): + """ + Return address of Coin whose name is the same with given coin_ame. + :param coin_name: + :return: An address of coin_name. + """ + sp.result(self.data.coins[coin_name]) + + @sp.onchain_view() + def is_valid_coin(self, coin_name): + """ + Check Validity of a coin_name + :param coin_name: + :return: true or false + """ + sp.result((self.data.coins[coin_name] != sp.address("tz10000"))|( coin_name == self.data.native_coin_name)) + + + @sp.onchain_view() + def fee_ratio(self, coin_name): + """ + Get fee numerator and fixed fee + :param coin_name: Coin name + :return: a record (Fee numerator for given coin, Fixed fee for given coin) + """ + + coin = self.data.coin_details[coin_name] + fee_numerator = coin.fee_numerator + fixed_fee = coin.fixed_fee + sp.result(sp.record(fee_numerator =fee_numerator, fixed_fee = fixed_fee)) + + + @sp.onchain_view() + def balance_of(self, params): + """ + Return a usable/locked/refundable balance of an account based on coinName. + usable_balance the balance that users are holding. + locked_balance when users transfer the coin,it will be locked until getting the Service Message Response. + refundable_balance refundable balance is the balance that will be refunded to users. + :param params: + :return: a record of (usable_balance, locked_balance, refundable_balance) + """ + sp.set_type(params, sp.TRecord(owner=sp.TAddress, coin_name=sp.TString)) + + # TODO: confirm sp.balance_Of() user_balance + with sp.if_(params.coin_name == self.data.native_coin_name): + sp.result(sp.record(usable_balance = sp.nat(0), + locked_balance = self.data.balances[sp.record(address=params.owner, coin_name=params.coin_name)].locked_balance, + refundable_balance = self.data.balances[sp.record(address=params.owner, coin_name=params.coin_name)].refundable_balance, + user_balance = sp.nat(2))) + with sp.else_(): + fa2_address = self.data.coins[params.coin_name] + usable_balance=sp.nat(1) + # IERC20 ierc20 = IERC20(_erc20Address); + #TODO: userbalance = token balance of a user? + # allowance? + sp.if fa2_address != sp.address("tz10000"): + pass + # return token balance of _owner + # _user_balance = + user_balance = sp.nat(0) + sp.if fa2_address == sp.address("tz10000"): + pass + # TODO: userbalance and allowance operations + sp.result(sp.record(usable_balance=usable_balance, + locked_balance=self.data.balances[sp.record(address=params.owner, coin_name=params.coin_name)].locked_balance, + refundable_balance=self.data.balances[sp.record(address=params.owner, coin_name=params.coin_name)].refundable_balance, + user_balance=user_balance)) + + @sp.onchain_view() + def balance_of_batch(self, params): + """ + Return a list Balance of an account. + :param params: + :return: a record of (usableBalances, lockedBalances, refundableBalances) + """ + sp.set_type(params, sp.TRecord(owner=sp.TAddress, coin_names=sp.TList(sp.TString))) + + + sp.verify((sp.len(params.coin_names) > sp.nat(0)) & (sp.len(params.coin_names) <= self.MAX_BATCH_SIZE), message = "BatchMaxSizeExceed") + usable_balances =sp.local("usable_balances", {}, t=sp.TMap(sp.TNat, sp.TNat)) + locked_balances =sp.local("locked_balances", {}, t=sp.TMap(sp.TNat, sp.TNat)) + refundable_balances =sp.local("refundable_balances", {}, t=sp.TMap(sp.TNat, sp.TNat)) + user_balances =sp.local("user_balances", {}, t=sp.TMap(sp.TNat, sp.TNat)) + + sp.for item in params.coin_names: + i = sp.local("i", sp.nat(0)) + balance= sp.view("balance_of", sp.self_address, + sp.record(owner=params.owner, coin_name=item)).open_some() + usable_balances.value[i.value] = balance.usable_balance + locked_balances.value[i.value] = balance.locked_balance + refundable_balances.value[i.value] = balance.refundable_balance + user_balances.value[i.value] = balance.user_balance + i.value += sp.nat(1) + sp.result(sp.record(usable_balances=usable_balances.value, locked_balances=locked_balances.value, + refundable_balances=refundable_balances.value, user_balances=user_balances.value)) + + @sp.onchain_view() + def get_accumulated_fees(self): + """ + Return a map with record of accumulated Fees. + :return: An map of Asset + """ + + accumulated_fees = sp.local("accumulated_fees", sp.map(tkey=sp.TNat, tvalue=types.Types.Asset)) + sp.for item in self.data.coins_name: + i = sp.local("i", sp.nat(0)) + accumulated_fees.value[i.value] = sp.record(coin_name=item, value=self.data.aggregation_fee[item]) + i.value += sp.nat(1) + sp.result(accumulated_fees.value) + + + @sp.entry_point(check_no_incoming_transfer=False) + def transfer_native_coin (self, to): + """ + Allow users to deposit `sp.amount` native coin into a BTSCore contract. + :param to: An address that a user expects to receive an amount of tokens. + :return: + """ + sp.set_type(to, sp.TString) + + amount_in_nat = sp.local("amount_in_nat", sp.utils.mutez_to_nat(sp.amount), t=sp.TNat) + + # call check_transfer_restrictions on bts_periphery + check_transfer = sp.view("check_transfer_restrictions", self.data.bts_periphery_address, + sp.record(coin_name=self.data.native_coin_name, user=sp.sender, value=amount_in_nat.value), + t=sp.TBool).open_some() + sp.verify(check_transfer == True, "FailCheckTransfer") + + #TODO: confirm data type for amount + + charge_amt = amount_in_nat.value * self.data.coin_details[self.data.native_coin_name].fee_numerator / self.FEE_DENOMINATOR + self.data.coin_details[self.data.native_coin_name].fixed_fee + #Confirm the type for this calculation + + self._send_service_message(sp.sender, to, self.data.native_coin_name, amount_in_nat.value, charge_amt) + + @sp.entry_point + def transfer(self, coin_name, value, to): + """ + Allow users to deposit an amount of wrapped native coin `coin_name` from the `sp.sender` address into the BTSCore contract. + :param coin_name: A given name of a wrapped coin + :param value: An amount request to transfer from a Requester (include fee) + :param to: Target BTP address. + :return: + """ + sp.set_type(coin_name, sp.TString) + sp.set_type(value, sp.TNat) + sp.set_type(to, sp.TString) + + + sp.verify(coin_name != self.data.native_coin_name, message="InvalidWrappedCoin") + fa2_address = self.data.coins[coin_name] + sp.verify(fa2_address != sp.address("tz10000"), message= "CoinNotRegistered") + + # call check_transfer_restrictions on bts_periphery + check_transfer = sp.view("check_transfer_restrictions", self.data.bts_periphery_address, + sp.record(coin_name=coin_name, user=sp.sender, value=value), + t=sp.TBool).open_some() + sp.verify(check_transfer == True, "FailCheckTransfer") + + charge_amt = value * self.data.coin_details[coin_name].fee_numerator / self.FEE_DENOMINATOR + self.data.coin_details[coin_name].fixed_fee + + #TODO: implement transferFrom function of fa2contract + + self._send_service_message(sp.sender, to, coin_name, value, charge_amt) + + + def _send_service_message(self, _from, to, coin_name, value, charge_amt): + """ + This private function handles overlapping procedure before sending a service message to BTSPeriphery + :param _from: An address of a Requester + :param to: BTP address of of Receiver on another chain + :param coin_name: A given name of a requested coin + :param value: A requested amount to transfer from a Requester (include fee) + :param charge_amt: An amount being charged for this request + :return: + """ + sp.set_type(_from, sp.TAddress) + sp.set_type(to, sp.TString) + sp.set_type(coin_name, sp.TString) + sp.set_type(value, sp.TNat) + sp.set_type(charge_amt, sp.TNat) + + sp.verify(value > charge_amt, message = "ValueGreaterThan0") + self._lock_balance(_from, coin_name, value) + + coins = sp.local("coins", {0 : coin_name}, t=sp.TMap(sp.TNat, sp.TString)) + amounts = sp.local("amounts", {0 : sp.as_nat(value - charge_amt)}, t=sp.TMap(sp.TNat, sp.TNat)) + fees = sp.local("fees", {0: charge_amt}, t=sp.TMap(sp.TNat, sp.TNat)) + + # call send_service_message on bts_periphery + send_service_message_args_type = sp.TRecord(_from = sp.TAddress, to = sp.TString, coin_names = sp.TMap(sp.TNat, sp.TString), values = sp.TMap(sp.TNat, sp.TNat), fees = sp.TMap(sp.TNat, sp.TNat)) + send_service_message_entry_point = sp.contract(send_service_message_args_type, self.data.bts_periphery_address, "send_service_message").open_some() + send_service_message_args = sp.record(_from = _from, to = to, coin_names = coins.value, values = amounts.value, fees = fees.value) + sp.transfer(send_service_message_args, sp.tez(0), send_service_message_entry_point) + + @sp.entry_point(check_no_incoming_transfer=False) + def transfer_batch(self, coin_names, values, to): + """ + Allow users to transfer multiple coins/wrapped coins to another chain. + It MUST revert if the balance of the holder for token `_coinName` is lower than the `_value` sent. + In case of transferring a native coin, it also checks `msg.value` + The number of requested coins MUST be as the same as the number of requested values + The requested coins and values MUST be matched respectively + :param coin_names: A list of requested transferring wrapped coins + :param values: A list of requested transferring values respectively with its coin name + :param to: Target BTP address. + :return: + """ + sp.set_type(coin_names, sp.TMap(sp.TNat, sp.TString)) + sp.set_type(values, sp.TMap(sp.TNat, sp.TNat)) + sp.set_type(to, sp.TString) + + sp.verify(sp.len(coin_names) == sp.len(values), message ="InvalidRequest") + sp.verify(sp.len(coin_names) > sp.nat(0), message = "Zero length arguments") + + amount_in_nat = sp.local("amount_in_nat", sp.utils.mutez_to_nat(sp.amount), t=sp.TNat) + + size = sp.local("size", sp.nat(0)) + sp.if amount_in_nat.value != sp.nat(0): + size.value = sp.len(coin_names) + sp.nat(1) + sp.if amount_in_nat.value == sp.nat(0): + size.value = sp.len(coin_names) + sp.verify(size.value <= self.MAX_BATCH_SIZE, message ="InvalidRequest") + + coins = sp.local("_coins", {}, t=sp.TMap(sp.TNat, sp.TString)) + amounts = sp.local("_amounts", {}, t=sp.TMap(sp.TNat, sp.TNat)) + charge_amts = sp.local("_charge_amts", {}, t=sp.TMap(sp.TNat, sp.TNat)) + + + # coin = sp.TRecord(addr=sp.TAddress, fee_numerator=sp.TNat, fixed_fee=sp.TNat, coin_type=sp.TNat) + coin_name = sp.local("coin_name", "", t= sp.TString) + value = sp.local("value", 0, t= sp.TNat) + + sp.for i in sp.range(sp.nat(0), sp.len(coin_names)): + fa2_addresses = self.data.coins[coin_names[i]] + sp.verify(fa2_addresses != sp.address("tz10000"), message= "CoinNotRegistered") + coin_name.value = coin_names[i] + value.value = values[i] + sp.verify(value.value > sp.nat(0), message ="ZeroOrLess") + + # call check_transfer_restrictions on bts_periphery + check_transfer = sp.view("check_transfer_restrictions", self.data.bts_periphery_address, + sp.record(coin_name=coin_name.value, user=sp.sender, value=value.value), + t=sp.TBool).open_some() + sp.verify(check_transfer == True, "FailCheckTransfer") + + #TODO: implement transferFrom function of fa2contract + + coin = sp.local("coin", self.data.coin_details[coin_name.value], t=Coin) + coins.value[i] = coin_name.value + charge_amts.value[i] = value.value *coin.value.fee_numerator //self.FEE_DENOMINATOR + coin.value.fixed_fee + amounts.value[i] = sp.as_nat(value.value - charge_amts.value[i]) + + self._lock_balance(sp.sender, coin_name.value, value.value) + + sp.if amount_in_nat.value !=sp.nat(0): + # call check_transfer_restrictions on bts_periphery + check_transfer = sp.view("check_transfer_restrictions", self.data.bts_periphery_address, + sp.record(coin_name=self.data.native_coin_name, user=sp.sender, value=amount_in_nat.value), + t=sp.TBool).open_some() + sp.verify(check_transfer == True, "FailCheckTransfer") + + coins.value[sp.as_nat(size.value - 1)] = self.data.native_coin_name + charge_amts.value[sp.as_nat(size.value - 1)] = amount_in_nat.value * self.data.coin_details[coin_name.value].fee_numerator\ + / self.FEE_DENOMINATOR + self.data.coin_details[coin_name.value].fixed_fee + amounts.value[sp.as_nat(size.value - 1)] = sp.as_nat(sp.utils.mutez_to_nat(sp.amount) - charge_amts.value[sp.as_nat(size.value - 1)]) + + self._lock_balance(sp.sender, self.data.native_coin_name, sp.utils.mutez_to_nat(sp.amount)) + + + # call send_service_message on bts_periphery + send_service_message_args_type = sp.TRecord(_from=sp.TAddress, to=sp.TString, + coin_names=sp.TMap(sp.TNat, sp.TString), + values=sp.TMap(sp.TNat, sp.TNat), + fees=sp.TMap(sp.TNat, sp.TNat)) + send_service_message_entry_point = sp.contract(send_service_message_args_type, + self.data.bts_periphery_address, + "send_service_message").open_some() + send_service_message_args = sp.record(_from=sp.sender, to=to, coin_names=coins.value, values=amounts.value, + fees=charge_amts.value) + sp.transfer(send_service_message_args, sp.tez(0), send_service_message_entry_point) + + + @sp.entry_point + #TODO: implement nonReentrant + def reclaim(self, coin_name, value): + """ + Reclaim the token's refundable balance by an owner. + The amount to claim must be smaller or equal than refundable balance + :param coin_name: A given name of coin + :param value: An amount of re-claiming tokens + :return: + """ + sp.set_type(coin_name, sp.TString) + sp.set_type(value, sp.TNat) + + sp.verify(self.data.balances[sp.record(address=sp.sender,coin_name=coin_name)].refundable_balance >= value, message="Imbalance") + self.data.balances[sp.record(address=sp.sender,coin_name=coin_name)].refundable_balance = sp.as_nat(self.data.balances[sp.record(address=sp.sender,coin_name=coin_name)].refundable_balance - value) + self.refund(sp.sender, coin_name, value) + + def refund(self, to, coin_name, value): + """ + + :param to: + :param coin_name: + :param value: + :return: + """ + sp.verify(sp.sender == sp.self_address, message="Unauthorized") + + with sp.if_(coin_name == self.data.native_coin_name): + self.payment_transfer(to, value) + with sp.else_(): + pass + #TODO: implement transfer on fa2 + + def payment_transfer(self, to, amount): + pass + #TODO: implement the following: + + # (bool sent,) = _to.call{value : _amount}(""); + # require(sent, "PaymentFailed"); + + @sp.entry_point + def mint(self, to, coin_name, value): + """ + mint the wrapped coin. + + :param to: the account receive the minted coin + :param coin_name: coin name + :param value: the minted amount + :return: + """ + sp.set_type(to, sp.TAddress) + sp.set_type(coin_name, sp.TString) + sp.set_type(value, sp.TNat) + + self.only_bts_periphery() + sp.if coin_name == self.data.native_coin_name: + self.payment_transfer(to, value) + sp.if self.data.coin_details[coin_name].coin_type == self.NATIVE_WRAPPED_COIN_TYPE: + pass + #TODO : implement mint? + # IERC20Tradable(coins[_coinName]).mint(_to, _value) + sp.if self.data.coin_details[coin_name].coin_type == self.NON_NATIVE_TOKEN_TYPE: + pass + #TODO: implement transfer + # IERC20(coins[_coinName]).transfer(_to, _value) + + + @sp.entry_point + def handle_response_service(self, requester, coin_name, value, fee, rsp_code): + """ + Handle a response of a requested service. + :param requester: An address of originator of a requested service + :param coin_name: A name of requested coin + :param value: An amount to receive on a destination chain + :param fee: An amount of charged fee + :param rsp_code: + :return: + """ + sp.set_type(requester, sp.TAddress) + sp.set_type(coin_name, sp.TString) + sp.set_type(value, sp.TNat) + sp.set_type(fee, sp.TNat) + sp.set_type(rsp_code, sp.TNat) + + self.only_bts_periphery() + sp.if requester == sp.self_address: + sp.if rsp_code == self.RC_ERR: + self.data.aggregation_fee[coin_name] = self.data.aggregation_fee[coin_name] + value + return + + amount = sp.local("amount", value + fee, t=sp.TNat) + self.data.balances[sp.record(address=requester, coin_name=coin_name)].locked_balance = sp.as_nat(self.data.balances[sp.record(address=requester, coin_name=coin_name)].locked_balance - amount.value) + + sp.if rsp_code == self.RC_ERR: + # TODO: implement try catch + fa2_address = self.data.coins[coin_name] + sp.if (coin_name != self.data.native_coin_name) & (self.data.coin_details[coin_name].coin_type == self.NATIVE_WRAPPED_COIN_TYPE): + pass + #TODO:implement burn + #IERC20Tradable(_erc20Address).burn(address(this), _value) + + self.data.aggregation_fee[coin_name] = self.data.aggregation_fee[coin_name] + fee + + + @sp.entry_point + def transfer_fees(self, fa): + """ + Handle a request of Fee Gathering. Usage: Copy all charged fees to an array + :param fa: + :return: + """ + sp.set_type(fa, sp.TString) + + self.only_bts_periphery() + sp.for item in self.data.coins_name: + i = sp.local("i", sp.nat(0)) + sp.if self.data.aggregation_fee[item] != sp.nat(0): + self.data.charged_coins[i.value] = item + self.data.charged_amounts[i.value] = self.data.aggregation_fee[item] + del self.data.aggregation_fee[item] + i.value += sp.nat(1) + + # call send_service_message on bts_periphery + send_service_message_args_type = sp.TRecord(_from=sp.TAddress, to=sp.TString, + coin_names=sp.TMap(sp.TNat, sp.TString), + values=sp.TMap(sp.TNat, sp.TNat), + fees=sp.TMap(sp.TNat, sp.TNat)) + send_service_message_entry_point = sp.contract(send_service_message_args_type, + self.data.bts_periphery_address, + "send_service_message").open_some() + send_service_message_args = sp.record(_from=sp.self_address, to=fa, coin_names=self.data.charged_coins, + values=self.data.charged_amounts, + fees=sp.map({})) + sp.transfer(send_service_message_args, sp.tez(0), send_service_message_entry_point) + + sp.for i in sp.range(0, sp.len(self.data.charged_coins)): + del self.data.charged_coins[i] + + sp.for i in sp.range(0, sp.len(self.data.charged_amounts)): + del self.data.charged_amounts[i] + + def _lock_balance(self, to, coin_name, value): + self.data.balances[sp.record(address=to, coin_name=coin_name)].locked_balance = self.data.balances[sp.record(address=to, coin_name=coin_name)].locked_balance + value + + @sp.entry_point + def update_coin_db(self): + self.only_owner() + self.data.coins[self.data.native_coin_name] = self.NATIVE_COIN_ADDRESS + self.data.coins_address[self.NATIVE_COIN_ADDRESS] = self.data.native_coin_name + self.data.coin_details[self.data.native_coin_name].addr = self.NATIVE_COIN_ADDRESS + + sp.for item in self.data.coins_name: + sp.if item != self.data.native_coin_name: + self.data.coins_address[self.data.coin_details[item].addr] = item + + @sp.entry_point + def set_bts_owner_manager(self, owner_manager): + sp.verify(self.data.owners[sp.sender] == True , message= "Unauthorized") + sp.verify(owner_manager != sp.address("tz10000"), message= "InvalidAddress") + self.data.bts_owner_manager = owner_manager + +@sp.add_test(name="BTSCore") +def test(): + c1 = BTSCore( + owner_manager=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), + bts_periphery_addr=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), + _native_coin_name="NativeCoin", + _fee_numerator=sp.nat(1000), + _fixed_fee=sp.nat(10) + ) + scenario = sp.test_scenario() + scenario.h1("BTSCore") + scenario += c1 + + +sp.add_compilation_target("bts_core", BTSCore( + owner_manager=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), + bts_periphery_addr=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), + _native_coin_name="NativeCoin", + _fee_numerator=sp.nat(1000), + _fixed_fee=sp.nat(10) +)) + + + + + + From 85aeefc9266bcc1f951786642de63ed1105cc184 Mon Sep 17 00:00:00 2001 From: simusud Date: Wed, 5 Apr 2023 12:45:46 +0545 Subject: [PATCH 017/211] Adding deployment file --- smartpy/bmc/scripts/deploy.ts | 62 +++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 smartpy/bmc/scripts/deploy.ts diff --git a/smartpy/bmc/scripts/deploy.ts b/smartpy/bmc/scripts/deploy.ts new file mode 100644 index 00000000..9b50353a --- /dev/null +++ b/smartpy/bmc/scripts/deploy.ts @@ -0,0 +1,62 @@ +import * as dotenv from "dotenv"; +import { TezosToolkit } from "@taquito/taquito"; +import { InMemorySigner } from "@taquito/signer"; +import { NETWORK } from "../config/config"; + +dotenv.config(); + +const deploy = async () => { + type networkTypes = keyof typeof NETWORK; + + const { ORIGINATOR_PRIVATE_KEY } = process.env; + let file = process.argv[2]; + let rpcType: networkTypes = process.argv[3] + ?.toUpperCase() + .slice(1) as networkTypes; + + console.info("Staring validation..."); + + if (!ORIGINATOR_PRIVATE_KEY) { + console.error("Private key missing in the environment."); + return; + } + + if (!file) { + console.log("Pass filename to deploy! Read the docs."); + return; + } + + if (!rpcType || !Object.keys(NETWORK).includes(rpcType)) { + console.log("Valid networks:", Object.keys(NETWORK)); + console.error("Invalid network"); + return; + } + + file = file.toLowerCase(); + + const signer = await InMemorySigner.fromSecretKey(ORIGINATOR_PRIVATE_KEY); + const Tezos = new TezosToolkit(NETWORK[rpcType].url); + Tezos.setProvider({ signer: signer }); + + console.log(`Validation checks out... \nDeploying the ${file} contract..\n`); + try { + const { hash, contractAddress } = await Tezos.contract.originate({ + code: require(`../contracts/build/${file}.json`), + init: require(`../contracts/build/${file}_storage.json`), + }); + + console.log("Successfully deployed contract"); + console.log(`>> Transaction hash: ${hash}`); + console.log(`>> Contract address: ${contractAddress}`); + } catch (error) { + console.log( + `Oops... Deployment faced an issue.\nHere's the detailed info about the error,\n${error}` + ); + + console.log( + "Make sure of these things. \n1. Compiled contracts are inside the build folder.\n2. You have enough Tezos balance in the wallet for deployment." + ); + } +}; + +deploy(); From b25004f9119668766250a8f1c488136d22255a6e Mon Sep 17 00:00:00 2001 From: simusud Date: Wed, 5 Apr 2023 12:49:26 +0545 Subject: [PATCH 018/211] fix(bts_periphery): Function changed to onchain view --- smartpy/bts/contracts/src/bts_periphery.py | 48 +++++++++++----------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index bd64b46c..793ab53f 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -327,10 +327,10 @@ def handle_request_service(self, to, assets): # sp.verify(valid_coin == True, "UnregisteredCoin") # in case of on chain view - # check_transfer = sp.view("check_transfer_restrictions", sp.self_address, sp.record(coin_name=assets[i].coin_name,user=to, value=assets[i].value), t=sp.TBool).open_some() - # sp.verify(check_transfer == True, "Fail") + check_transfer = sp.view("check_transfer_restrictions", sp.self_address, sp.record(coin_name=assets[i].coin_name,user=to, value=assets[i].value), t=sp.TBool).open_some() + sp.verify(check_transfer == True, "FailCheckTransfer") - self.check_transfer_restrictions(sp.record(coin_name=assets[i].coin_name, user=to, value=assets[i].value)) + # self.check_transfer_restrictions(sp.record(coin_name=assets[i].coin_name, user=to, value=assets[i].value)) # TODO: implement try @@ -395,7 +395,7 @@ def handle_fee_gathering(self, fa, svc): sp.transfer(fa, sp.tez(0), transfer_fees_entry_point) - # @sp.onchain_view() + @sp.onchain_view() def check_transfer_restrictions(self, params): """ @@ -410,6 +410,8 @@ def check_transfer_restrictions(self, params): sp.verify(self.data.blacklist.contains(params.user) == False, "Blacklisted") sp.verify(self.data.token_limit[params.coin_name] >= params.value, "LimitExceed") + sp.result(True) + def check_parse_address(self, to): """ @@ -435,25 +437,25 @@ def test(): # counter.add_to_blacklist(["tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"]) - counter.send_service_message(sp.record(_from=sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), to="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", - coin_names={0:"Tok1"}, values={0:sp.nat(10)}, fees={0:sp.nat(2)})).run( - sender=admin - ) - counter.handle_btp_error(sp.record(svc= "bts", code=sp.nat(2), sn=sp.nat(1), msg="test 1")).run( - sender=admin - ) - - counter.set_token_limit(sp.record(coin_names={0:"Tok2"}, token_limit={0:sp.nat(5)})).run(sender=admin) - - counter.handle_request_service(sp.record(to= sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), assets={0: - sp.record(coin_name="Tok2", value=sp.nat(4))})).run( - sender=admin - ) - - counter.handle_fee_gathering(sp.record(fa="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", svc="bts")).run(sender=admin) - - counter.handle_btp_message(sp.record(_from="tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", svc="bts", sn=sp.nat(4), - msg=sp.bytes("0x0507070a000000030dae110000") )).run(sender=admin) + # counter.send_service_message(sp.record(_from=sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), to="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", + # coin_names={0:"Tok1"}, values={0:sp.nat(10)}, fees={0:sp.nat(2)})).run( + # sender=admin + # ) + # counter.handle_btp_error(sp.record(svc= "bts", code=sp.nat(2), sn=sp.nat(1), msg="test 1")).run( + # sender=admin + # ) + # + # counter.set_token_limit(sp.record(coin_names={0:"Tok2"}, token_limit={0:sp.nat(5)})).run(sender=admin) + # + # counter.handle_request_service(sp.record(to= sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), assets={0: + # sp.record(coin_name="Tok2", value=sp.nat(4))})).run( + # sender=admin + # ) + # + # counter.handle_fee_gathering(sp.record(fa="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", svc="bts")).run(sender=admin) + # + # counter.handle_btp_message(sp.record(_from="tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", svc="bts", sn=sp.nat(4), + # msg=sp.bytes("0x0507070a000000030dae110000") )).run(sender=admin) sp.add_compilation_target("bts_periphery", BTPPreiphery(bmc_address=sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), From c0f821e63d7ae9e397d6193de70631fe3230c219 Mon Sep 17 00:00:00 2001 From: simusud Date: Wed, 5 Apr 2023 12:50:42 +0545 Subject: [PATCH 019/211] Adding libraries in Types.py --- smartpy/bts/contracts/src/Types.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/smartpy/bts/contracts/src/Types.py b/smartpy/bts/contracts/src/Types.py index 29c4fe74..cf08a52b 100644 --- a/smartpy/bts/contracts/src/Types.py +++ b/smartpy/bts/contracts/src/Types.py @@ -65,3 +65,8 @@ class Types: net=sp.TString ) + Balance = sp.TRecord( + locked_balance=sp.TNat, + refundable_balance=sp.TNat + ) + From 7b0dc39ab2dff120601c297dc8d030a423cbe1be Mon Sep 17 00:00:00 2001 From: simusud Date: Thu, 6 Apr 2023 18:02:15 +0545 Subject: [PATCH 020/211] fix(bmc): Deployment errors fixes in bmc periphery, bmc management and Strings library --- smartpy/bmc/contracts/src/String.py | 25 ++-- smartpy/bmc/contracts/src/Types.py | 2 +- smartpy/bmc/contracts/src/bmc_management.py | 133 ++++++++------------ smartpy/bmc/contracts/src/bmc_periphery.py | 29 +++-- 4 files changed, 87 insertions(+), 102 deletions(-) diff --git a/smartpy/bmc/contracts/src/String.py b/smartpy/bmc/contracts/src/String.py index 2fb8277c..dc41a8f7 100644 --- a/smartpy/bmc/contracts/src/String.py +++ b/smartpy/bmc/contracts/src/String.py @@ -2,18 +2,23 @@ -def split_btp_address(base): +def split_btp_address(base, prev_string, result_string, list_string, last_string, penultimate_string): """ Split the BTP Address format i.e. btp://1234.iconee/0x123456789 into Network_address (1234.iconee) and Server_address (0x123456789) + :param prev_string: local variable name + :param result_string: local variable name + :param list_string: local variable name + :param last_string: local variable name + :param penultimate_string: local variable name :param base: String base BTP Address format to be split :return: The resulting strings of Network_address and Server_address """ sp.set_type(base, sp.TString) # sep = sp.local("sep", "/") - prev_idx = sp.local("prev_idx", 0) - result = sp.local("result", []) + prev_idx = sp.local(prev_string, 0) + result = sp.local(result_string, []) sp.for idx in sp.range(0, sp.len(base)): sp.if sp.slice(base, idx, 1).open_some() == "/": result.value.push(sp.slice(base, prev_idx.value, sp.as_nat(idx - prev_idx.value)).open_some()) @@ -21,21 +26,21 @@ def split_btp_address(base): sp.if sp.len(base) > 0: result.value.push(sp.slice(base, prev_idx.value, sp.as_nat(sp.len(base) - prev_idx.value)).open_some()) - inverted_list = sp.local("my_list", result.value) - last = sp.local("last", "") - penultimate = sp.local("penultimate", "") + inverted_list = sp.local(list_string, result.value) + last = sp.local(last_string, "") + penultimate = sp.local(penultimate_string, "") with sp.match_cons(inverted_list.value) as l: last.value = l.head inverted_list.value = l.tail - with sp.else_(): - sp.failwith("Empty list") + # with sp.else_(): + # sp.failwith("Empty list") with sp.match_cons(inverted_list.value) as l: penultimate.value = l.head - with sp.else_(): - sp.failwith("Only one element") + # with sp.else_(): + # sp.failwith("Only one element") return sp.pair(last.value, penultimate.value) diff --git a/smartpy/bmc/contracts/src/Types.py b/smartpy/bmc/contracts/src/Types.py index 5da5e9d1..4c25a288 100644 --- a/smartpy/bmc/contracts/src/Types.py +++ b/smartpy/bmc/contracts/src/Types.py @@ -11,7 +11,7 @@ class Types: ReceiptProof = sp.TRecord( index=sp.TNat, - events=sp.TList(MessageEvent), + events=sp.TMap(sp.TNat, MessageEvent), height=sp.TNat ) diff --git a/smartpy/bmc/contracts/src/bmc_management.py b/smartpy/bmc/contracts/src/bmc_management.py index 1593dc68..402ee497 100644 --- a/smartpy/bmc/contracts/src/bmc_management.py +++ b/smartpy/bmc/contracts/src/bmc_management.py @@ -8,24 +8,46 @@ class BMCManagement(sp.Contract): BLOCK_INTERVAL_MSEC = sp.nat(1000) def __init__(self): - self.update_initial_storage( - owners=sp.map(l={sp.address("tz1000"): True}, tkey=sp.TAddress, tvalue=sp.TBool), + self.init( + owners=sp.map(), number_of_owners=sp.nat(1), - bsh_services=sp.map(tkey=sp.TString, tvalue=sp.TAddress), - relay_stats=sp.map(tkey=sp.TAddress, tvalue=types.Types.RelayStats), - routes=sp.map(tkey=sp.TString, tvalue=sp.TString), - links=sp.map(tkey=sp.TString, tvalue=types.Types.Link), + bsh_services=sp.map(), + relay_stats=sp.map(), + routes=sp.map(), + links=sp.map(), list_bsh_names=sp.set(), list_route_keys=sp.set(), list_link_names=sp.set(), bmc_periphery=sp.none, serial_no=sp.nat(0), addrs=sp.set(), - get_route_dst_from_net=sp.map(tkey=sp.TString, tvalue=sp.TString), - get_link_from_net=sp.map(tkey=sp.TString, tvalue=sp.TString), - get_link_from_reachable_net=sp.map(tkey=sp.TString, tvalue=types.Types.Tuple) + get_route_dst_from_net=sp.map(), + get_link_from_net=sp.map(), + get_link_from_reachable_net=sp.map() ) + self.init_type(sp.TRecord( + owners=sp.TMap(sp.TAddress, sp.TBool), + number_of_owners=sp.TNat, + bsh_services=sp.TMap(sp.TString, sp.TAddress), + relay_stats=sp.TMap(sp.TAddress, types.Types.RelayStats), + routes=sp.TMap(sp.TString, sp.TString), + links=sp.TMap(sp.TString, types.Types.Link), + list_bsh_names=sp.TSet(sp.TString), + list_route_keys=sp.TSet(sp.TString), + list_link_names=sp.TSet(sp.TString), + bmc_periphery=sp.TOption(sp.TAddress), + serial_no=sp.TNat, + addrs=sp.TSet(sp.TAddress), + get_route_dst_from_net=sp.TMap(sp.TString, sp.TString), + get_link_from_net=sp.TMap(sp.TString, sp.TString), + get_link_from_reachable_net=sp.TMap(sp.TString, types.Types.Tuple) + )) + + # to be called after deployment manually + def enable(self): + self.data.owners[sp.sender] = True + def only_owner(self): sp.verify(self.data.owners[sp.sender] == True, "Unauthorized") @@ -41,7 +63,7 @@ def set_bmc_periphery(self, addr): """ sp.set_type(addr, sp.TAddress) # self.only_owner() - sp.verify(addr != sp.address("tz100000000"), "InvalidAddress") + sp.verify(addr != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), "InvalidAddress") sp.trace(self.data.bmc_periphery.is_some()) sp.if self.data.bmc_periphery.is_some(): sp.verify(addr != self.data.bmc_periphery.open_some("Address not set"), "AlreadyExistsBMCPeriphery") @@ -93,8 +115,8 @@ def add_service(self, svc, addr): :return: """ self.only_owner() - sp.verify(addr != sp.address("tz100000000"), "InvalidAddress") - sp.verify(self.data.bsh_services[svc] == sp.address("tz100000000"), "AlreadyExistsBSH") + sp.verify(addr != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), "InvalidAddress") + sp.verify(self.data.bsh_services[svc] == sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), "AlreadyExistsBSH") self.data.bsh_services[svc] = addr self.data.list_bsh_names.add(svc) @@ -106,7 +128,7 @@ def remove_service(self, svc): :return: """ self.only_owner() - sp.verify(self.data.bsh_services[svc] == sp.address("tz100000000"), "NotExistsBSH") + sp.verify(self.data.bsh_services[svc] == sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), "NotExistsBSH") del self.data.bsh_services[svc] self.data.list_bsh_names.remove(svc) @@ -134,13 +156,13 @@ def add_link(self, link): sp.set_type(link, sp.TString) self.only_owner() - net, addr= sp.match_pair(strings.split_btp_address(link)) + net, addr= sp.match_pair(strings.split_btp_address(link, "prev_idx", "result", "my_list", "last", "penultimate")) with sp.if_(self.data.links.contains(link)): sp.verify(self.data.links[link].is_connected == False, "AlreadyExistsLink") #TODO:review how to add key in relays map self.data.links[link] = sp.record( - relays=sp.set([sp.address("tz100000000")]), + relays=sp.set([sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc")]), reachable=sp.set(["0"]), rx_seq=sp.nat(0), tx_seq=sp.nat(0), @@ -156,12 +178,11 @@ def add_link(self, link): ) self._propagate_internal("Link", link) - links = sp.local("links", self.data.list_link_names.elements(), t=sp.TList(sp.TString)) + links = self.data.list_link_names self.data.list_link_names.add(link) self.data.get_link_from_net[net] = link - - self._send_internal(link, "Init", links.value) + self._send_internal(link, "Init", links.elements()) sp.trace("in add_link") @sp.entry_point @@ -180,7 +201,7 @@ def remove_link(self, link): with sp.else_(): sp.failwith("NotExistsLink") del self.data.links[link] - net, addr= sp.match_pair(strings.split_btp_address(link)) + net, addr= sp.match_pair(strings.split_btp_address(link, "prev_idx", "result", "my_list", "last", "penultimate")) del self.data.get_link_from_net[link] self._propagate_internal("Unlink", link) self.data.list_link_names.remove(link) @@ -194,7 +215,6 @@ def get_links(self): """ sp.result(self.data.list_link_names.elements()) - @sp.entry_point def set_link_rx_height(self, link, height): """ @@ -274,35 +294,7 @@ def _propagate_internal(self, service_type, link): sp.for item in self.data.list_link_names.elements(): sp.if self.data.links[item].is_connected: - # net, addr = sp.match_pair(strings.split_btp_address(item)) - - # split btp address code snippet: because same local value cannot be used multiple times - prev_idx1 = sp.local("prev_idx1", 0) - result1 = sp.local("result1", []) - sp.for idx in sp.range(0, sp.len(item)): - sp.if sp.slice(item, idx, 1).open_some() == "/": - result1.value.push(sp.slice(item, prev_idx1.value, sp.as_nat(idx - prev_idx1.value)).open_some()) - prev_idx1.value = idx + 1 - sp.if sp.len(item) > 0: - result1.value.push( - sp.slice(item, prev_idx1.value, sp.as_nat(sp.len(item) - prev_idx1.value)).open_some()) - - inverted_list = sp.local("my_list1", result1.value) - last = sp.local("last1", "") - penultimate = sp.local("penultimate1", "") - - with sp.match_cons(inverted_list.value) as l: - last.value = l.head - inverted_list.value = l.tail - with sp.else_(): - sp.failwith("Empty list") - - with sp.match_cons(inverted_list.value) as l: - penultimate.value = l.head - with sp.else_(): - sp.failwith("Only one element") - - net = last.value + net, addr = sp.match_pair(strings.split_btp_address(item, "prev_idx1", "result1", "my_list1", "last1", "penultimate1")) # call send_message on BMCPeriphery # TODO: encodeBMCService @@ -332,33 +324,8 @@ def _send_internal(self, target, service_type, links): # net, addr = sp.match_pair(strings.split_btp_address(target)) - # split btp address code snippet: because same local value cannot be used multiple times - prev_idx2 = sp.local("prev_idx2", 0) - result2 = sp.local("result2", []) - sp.for idx in sp.range(0, sp.len(target)): - sp.if sp.slice(target, idx, 1).open_some() == "/": - result2.value.push(sp.slice(target, prev_idx2.value, sp.as_nat(idx - prev_idx2.value)).open_some()) - prev_idx2.value = idx + 1 - sp.if sp.len(target) > 0: - result2.value.push( - sp.slice(target, prev_idx2.value, sp.as_nat(sp.len(target) - prev_idx2.value)).open_some()) - - inverted_list = sp.local("my_list2", result2.value) - last = sp.local("last2", "") - penultimate = sp.local("penultimate2", "") - - with sp.match_cons(inverted_list.value) as l: - last.value = l.head - inverted_list.value = l.tail - with sp.else_(): - sp.failwith("Empty list") - - with sp.match_cons(inverted_list.value) as l: - penultimate.value = l.head - with sp.else_(): - sp.failwith("Only one element") - - net = last.value + net, addr = sp.match_pair( + strings.split_btp_address(target, "prev_idx2", "result2", "my_list2", "last2", "penultimate2")) # call send_message on BMCPeriphery # TODO: encodeBMCService @@ -384,7 +351,7 @@ def add_route(self, dst, link): self.only_owner() sp.verify(sp.len(sp.pack(self.data.routes[dst])) == sp.nat(0), "AlreadyExistRoute") - net, addr= sp.match_pair(strings.split_btp_address(dst)) + net, addr= sp.match_pair(strings.split_btp_address(dst, "prev_idx", "result", "my_list", "last", "penultimate")) # TODO: need to verify link is only split never used # strings.split_btp_address(link) @@ -404,7 +371,7 @@ def remove_route(self, dst): self.only_owner() sp.verify(sp.len(sp.pack(self.data.routes[dst])) != sp.nat(0), "NotExistRoute") del self.data.routes[dst] - net, addr= sp.match_pair(strings.split_btp_address(dst)) + net, addr= sp.match_pair(strings.split_btp_address(dst, "prev_idx", "result", "my_list", "last", "penultimate")) del self.data.get_route_dst_from_net[net] self.data.list_route_keys.remove(dst) @@ -543,12 +510,13 @@ def update_link_rx_height(self, prev, val): @sp.entry_point def update_link_reachable(self, prev, to): sp.set_type(prev, sp.TString) - sp.set_type(to, sp.TSet(sp.TString)) + sp.set_type(to, sp.TList(sp.TString)) self.only_bmc_periphery() - sp.for item in to.elements(): + sp.for item in to: self.data.links[prev].reachable.add(item) - net, addr = sp.match_pair(strings.split_btp_address(item)) + net, addr = sp.match_pair( + strings.split_btp_address(item, "prev_idx", "result", "my_list", "last", "penultimate")) self.data.get_link_from_reachable_net[net] = sp.record(prev=prev, to=item) @sp.entry_point @@ -560,7 +528,8 @@ def delete_link_reachable(self, prev, index): sp.for item in self.data.links[prev].reachable.elements(): i = sp.local("i", 0) sp.if i.value == index: - net, addr = sp.match_pair(strings.split_btp_address(item)) + net, addr = sp.match_pair( + strings.split_btp_address(item, "prev_idx", "result", "my_list", "last", "penultimate")) del self.data.get_link_from_reachable_net[net] self.data.links[prev].reachable.remove(item) diff --git a/smartpy/bmc/contracts/src/bmc_periphery.py b/smartpy/bmc/contracts/src/bmc_periphery.py index d1cdcc91..9c8a280a 100644 --- a/smartpy/bmc/contracts/src/bmc_periphery.py +++ b/smartpy/bmc/contracts/src/bmc_periphery.py @@ -20,7 +20,7 @@ class BMCPreiphery(sp.Contract): BMCRevertUnknownHandleBTPMessage = sp.string("UnknownHandleBTPMessage") def __init__(self, network, bmc_management_addr): - self.update_initial_storage( + self.init( bmc_btp_address=sp.string("btp://") + network + "/" + "jj", bmc_management=bmc_management_addr ) @@ -55,13 +55,15 @@ def handle_relay_message(self, prev, msg): rx_seq = sp.local("rx_seq", link_rx_seq, t=sp.TNat) rx_height = sp.local("rx_height", link_rx_height, t=sp.TNat) + rps = sp.map(tkey=sp.TNat, tvalue=types.Types.ReceiptProof) # rsp = decodeReceiptProofs(msg) - rps = sp.map({0:sp.record(index=1, events={}, height=3)}) + # rps = sp.map({sp.nat(0):sp.record(index=1, events=[], height=sp.nat(3))}) # bmc_msg = sp.local("bmc_msg") # ev = sp.local("ev") - sp.for i in sp.range(0, sp.len(rps)): + sp.for i in sp.range(sp.nat(0), sp.len(rps)): + sp.trace("ll") with sp.if_(rps[i].height < rx_height.value): sp.trace("ggg") # sp.continue @@ -108,7 +110,7 @@ def _handle_message(self, prev, msg): sp.set_type(prev, sp.TString) sp.set_type(msg, types.Types.BMCMessage) - bsh_addr = sp.local("bsh_addr",sp.TAddress) + # bsh_addr = sp.local("bsh_addr",sp.TAddress) with sp.if_(msg.svc == "bmc"): sm = self.try_decode_bmc_service(msg.message) #TODO: implement try catch @@ -119,7 +121,7 @@ def _handle_message(self, prev, msg): sp.for i in sp.range(sp.nat(0), len(gather_fee.svcs)): bsh_addr = sp.view("get_bsh_service_by_name", self.data.bmc_management, gather_fee.svcs[i], t=sp.TAddress) - sp.if bsh_addr != "zero_address": + sp.if bsh_addr != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"): pass #TODO: call BSH handleFeeGathering @@ -147,7 +149,8 @@ def _handle_message(self, prev, msg): sp.transfer(update_link_reachable_args, sp.tez(0), update_link_reachable_entry_point) sp.if sm.serviceType == "Unlink": - to = decodePropagateMessage(sm.payload) + # to = decodePropagateMessage(sm.payload) + to = "to" link = sp.view("get_link", self.data.bmc_management, prev, t=types.Types.Link).open_some() sp.if link.is_connected: @@ -163,7 +166,8 @@ def _handle_message(self, prev, msg): sp.transfer(delete_link_reachable_args, sp.tez(0), delete_link_reachable_entry_point) sp.if sm.serviceType == "Init": - links = decodeInitMessage(sm.payload) + # links = decodeInitMessage(sm.payload) + links = ["link"] # call update_link_reachable on BMCManagement update_link_reachable_args_type = sp.TRecord(prev=sp.TString, to=sp.TList(sp.TString)) update_link_reachable_entry_point = sp.contract(update_link_reachable_args_type, @@ -174,7 +178,7 @@ def _handle_message(self, prev, msg): with sp.else_(): bsh_addr = sp.view("get_bsh_service_by_name", self.data.bmc_management, msg.svc, t=sp.TAddress) - sp.if bsh_addr == "zero_address": + sp.if bsh_addr == sp.addrress("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"): self._send_error(prev, msg, self.BMC_ERR, self.BMCRevertNotExistsBSH) return @@ -189,12 +193,18 @@ def _handle_message(self, prev, msg): def try_decode_btp_message(self, rlp): + sp.set_type(rlp, sp.TBytes) + return decodeBMCMessage(rpl) def try_decode_bmc_service(self, msg): + sp.set_type(msg, sp.TBytes) + return decodeBMCService(msg) def try_decode_gather_fee_message(self, msg): + sp.set_type(msg, sp.TBytes) + return decodeGatherFeeMessage(msg) def _send_message(self, to ,serialized_msg): @@ -265,9 +275,10 @@ def send_message(self, to, svc, sn, msg): def get_status(self, _link): """ Get status of BMC - :param link: BTP Address of the connected BMC + :param _link: BTP Address of the connected BMC :return: """ + sp.set_type(_link, sp.TString) link = sp.view("get_link", self.data.bmc_management, _link, t=types.Types.Link).open_some() sp.verify(link.is_connected == True, self.BMCRevertNotExistsLink) From 002b06f65d43e59322cc9fa63f2b8cfb2f988dd0 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Tue, 11 Apr 2023 11:02:27 +0545 Subject: [PATCH 021/211] feat: added new client methods --- cmd/iconbridge/chain/tezos/client.go | 63 +++++++++++++++++++++------- 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/cmd/iconbridge/chain/tezos/client.go b/cmd/iconbridge/chain/tezos/client.go index f8f6ab22..f2bf1767 100644 --- a/cmd/iconbridge/chain/tezos/client.go +++ b/cmd/iconbridge/chain/tezos/client.go @@ -8,14 +8,17 @@ import ( "math/big" // "io" - "github.com/icon-project/icon-bridge/common/log" "time" + "github.com/icon-project/icon-bridge/common/log" + "blockwatch.cc/tzgo/contract" "blockwatch.cc/tzgo/micheline" "blockwatch.cc/tzgo/rpc" "blockwatch.cc/tzgo/signer" "blockwatch.cc/tzgo/tezos" + "github.com/icon-project/icon-bridge/cmd/iconbridge/chain" + "github.com/icon-project/icon-bridge/cmd/iconbridge/chain/tezos/types" ) const ( @@ -28,10 +31,12 @@ type IClient interface { // Call(ctx context.Context, callArgs contract.CallArguments, opts *rpc.CallOptions) GetBalance(ctx context.Context, connection *rpc.Client, account tezos.Address, blockLevel int64) GetBlockByHeight(ctx context.Context, connection *rpc.Client, blockLevel int64) (*rpc.Block, error) + GetBlockHeightByHash(ctx context.Context, connection *rpc.Client, hash tezos.BlockHash) (int64, error) // GetBlockHeaderByHeight(ctx context.Context, connection *rpc.Client, blockLevel int64) // GetBlockMetadataByHash(ctx context.Context, connection *rpc.Client, blockHash tezos.Hash) - MonitorBlock(ctx context.Context, client *rpc.Client, connection *contract.Contract, blockLevel int64) (*rpc.Block, error) + MonitorBlock(ctx context.Context, client *rpc.Client, connection *contract.Contract, + blockLevel int64, callback func(v *types.BlockNotification) error) (*rpc.Block, error) // MonitorEvent(ctx context.Context, connection *rpc.Client, blockLevel int64) GetLastBlock(ctx context.Context, connection *rpc.Client) (*rpc.Block, error) @@ -51,7 +56,7 @@ type TypesLinkStats struct { type Client struct { Log log.Logger - Ctx context.Context + // Ctx context.Context Cl *rpc.Client Contract *contract.Contract blockLevel int64 @@ -103,6 +108,14 @@ func (c *Client) GetBlockByHeight(ctx context.Context, connection *rpc.Client, b return block, nil } +func (c *Client) GetBlockHeightByHash(ctx context.Context, connection *rpc.Client, hash tezos.BlockHash) (uint64, error) { + block, err := connection.GetBlock(ctx, hash) + if err != nil { + return 0, err + } + return uint64(block.Header.Level), nil +} + func (c *Client) GetBlockHeaderByHeight(ctx context.Context, connection *rpc.Client, blockLevel int64)(*rpc.BlockHeader, error){ block, err := connection.GetBlockHeader(ctx, rpc.BlockLevel(blockLevel)) if err != nil { @@ -111,21 +124,21 @@ func (c *Client) GetBlockHeaderByHeight(ctx context.Context, connection *rpc.Cli return block, nil } -func (c *Client) MonitorBlock(blockLevel int64, verifier IVerifier) (error) { +func (c *Client) MonitorBlock(ctx context.Context, blockLevel int64, verifier IVerifier, callback func(v []*chain.Receipt) error) (error) { fmt.Println("reached in monitor block") relayTicker := time.NewTicker(DefaultBlockWaitInterval) defer relayTicker.Stop() for { select { - case <- c.Ctx.Done(): + case <- ctx.Done(): return fmt.Errorf("Context done") case <- relayTicker.C: fmt.Println("*************************************************************") fmt.Print("Trying to fetch block for blockLevel ") fmt.Println(blockLevel) - block, err := c.GetBlockByHeight(c.Ctx, c.Cl, blockLevel) + block, err := c.GetBlockByHeight(ctx, c.Cl, blockLevel) if err != nil { fmt.Println(err) @@ -136,12 +149,13 @@ func (c *Client) MonitorBlock(blockLevel int64, verifier IVerifier) (error) { continue } - header, err := c.GetBlockHeaderByHeight(c.Ctx, c.Cl, blockLevel) + header, err := c.GetBlockHeaderByHeight(ctx, c.Cl, blockLevel) if err != nil { return err } + fmt.Println(block.Metadata.ProposerConsensusKey) - err = verifier.Verify(header, &block.Metadata.Baker) + err = verifier.Verify(ctx, header, block.Metadata.ProposerConsensusKey, c.Cl, header.Hash) if err != nil { fmt.Println(err) @@ -168,7 +182,18 @@ func (c *Client) MonitorBlock(blockLevel int64, verifier IVerifier) (error) { switch operation.Kind() { case tezos.OpTypeTransaction: tx := operation.(*rpc.Transaction) - returnTxMetadata(tx, c.Contract.Address()) + receipt, err := returnTxMetadata(tx, c.Contract.Address()) + if err != nil { + return err + } + if len(receipt) != 0 { + fmt.Println("callback start") + err := callback(receipt) + fmt.Println("call back end") + if err != nil { + return err + } + } } } } @@ -178,12 +203,14 @@ func (c *Client) MonitorBlock(blockLevel int64, verifier IVerifier) (error) { } } -func returnTxMetadata(tx *rpc.Transaction, contractAddress tezos.Address) error { +func returnTxMetadata(tx *rpc.Transaction, contractAddress tezos.Address) ([]*chain.Receipt, error) { _, err := fmt.Println(tx.Destination) if err != nil { - return err + return nil, err } address := tx.Destination + + var receipts []*chain.Receipt if address.ContractAddress() == contractAddress.ContractAddress() { fmt.Println("Address matched") fmt.Println("****************") @@ -201,11 +228,17 @@ func returnTxMetadata(tx *rpc.Transaction, contractAddress tezos.Address) error fmt.Println("****") if tx.Metadata.InternalResults[0].Tag == "TokenMinted" { - fmt.Println("Payload is") - fmt.Println(tx.Metadata.InternalResults[0].Payload.Int) + var events []*chain.Event + + events = append(events, &chain.Event{ + Message: []byte(tx.Metadata.InternalResults[0].Tag), + }) + receipts = append(receipts, &chain.Receipt{ + Events: events, + }) } } - return nil + return receipts, nil } func (c *Client) GetClient()(*rpc.Client) { @@ -253,8 +286,6 @@ func NewClient(uri string, src tezos.Address, l log.Logger) (*Client, error){ return &Client{Log: l, Cl: c, Contract: conn}, nil } - - func PrettyEncode(data interface{}) error { var buffer bytes.Buffer enc := json.NewEncoder(&buffer) From 92f6f0c259f1285541602971aa1821fcffac8bdd Mon Sep 17 00:00:00 2001 From: icondev22 Date: Tue, 11 Apr 2023 11:04:37 +0545 Subject: [PATCH 022/211] feat: added verifier synchronization feature and message delivery feature --- cmd/iconbridge/chain/tezos/receiver.go | 295 ++++++++++++++++++++++--- 1 file changed, 260 insertions(+), 35 deletions(-) diff --git a/cmd/iconbridge/chain/tezos/receiver.go b/cmd/iconbridge/chain/tezos/receiver.go index 779fd4d3..38595b11 100644 --- a/cmd/iconbridge/chain/tezos/receiver.go +++ b/cmd/iconbridge/chain/tezos/receiver.go @@ -5,44 +5,96 @@ import ( "context" "encoding/json" "fmt" - "github.com/icon-project/icon-bridge/common/log" - "sync" + "sort" "strconv" + "sync" + "time" + + "github.com/icon-project/icon-bridge/common/log" + // "blockwatch.cc/tzgo/contract" "blockwatch.cc/tzgo/contract" + "blockwatch.cc/tzgo/rpc" "blockwatch.cc/tzgo/tezos" + "github.com/pkg/errors" +) + +const ( + BlockInterval = 30 * time.Second + BlockHeightPollInterval = BlockInterval * 5 + BlockFinalityConfirmations = 2 + MonitorBlockMaxConcurrency = 10 // number of concurrent requests to synchronize older blocks from source chain + RPCCallRetry = 5 ) type receiver struct { log log.Logger - src tezos.Address - dst tezos.Address + src chain.BTPAddress + dst chain.BTPAddress + opts ReceiverOptions client *Client } -func (r *receiver) Subscribe( - ctx context.Context, msgCh chan<- *chain.Message, - opts chain.SubscribeOptions) (errCh <-chan error, err error) { - - r.client.Contract = contract.NewContract(r.src, r.client.Cl) - r.client.Ctx = ctx +func (r *receiver) Subscribe(ctx context.Context, msgCh chan<- *chain.Message, opts chain.SubscribeOptions) (errCh <-chan error, err error) { + fmt.Println("reached to subscribe") + src := tezos.MustParseAddress(string(r.src)) + r.client.Contract = contract.NewContract(src, r.client.Cl) opts.Seq++ _errCh := make(chan error) - verifier, err := r.NewVerifier(int64(opts.Height) - 1) - + verifier, err := r.NewVerifier(ctx, int64(opts.Height)) + fmt.Println("returned by the new verifier") if err != nil { _errCh <- err return _errCh, err } + err = r.syncVerifier(ctx, verifier, int64(opts.Height + 80)) + + if err != nil { + _errCh <- err + return _errCh, err + } + + fmt.Println("reached to before monitor block") + go func() { defer close(_errCh) - err := r.client.MonitorBlock(int64(opts.Height), verifier) - if err != nil { + if err := r.client.MonitorBlock(ctx, int64(opts.Height + 80), verifier, + func (v []*chain.Receipt) error { + fmt.Println(v[0].Events[0].Message) + fmt.Println("has to reach in this callback ") + var vCP []*chain.Receipt + var events []*chain.Event + for _, receipt := range v{ + for _, event := range receipt.Events { + switch { + case event.Sequence == opts.Seq: + events = append(events, event) + opts.Seq++ + case event.Sequence > opts.Seq: + return fmt.Errorf("invalid event seq") + default: + events = append(events, event) + opts.Seq++ + + + } + } + receipt.Events = events + vCP = append(vCP, &chain.Receipt{Events: receipt.Events}) + } + if len(v) > 0 { + fmt.Println("reached to sending message") + fmt.Println(vCP[0].Events[0].Message) + msgCh <- &chain.Message{Receipts: vCP} + } + fmt.Println("returned nill") + return nil + }); err != nil { _errCh <- err } @@ -52,48 +104,71 @@ func (r *receiver) Subscribe( return _errCh, nil } -func NewReceiver( - src, dst chain.BTPAddress, urls []string, - rawOpts json.RawMessage, l log.Logger) (chain.Receiver, error){ +// func (r *receiver) getRelayReceipts(v *chain.BlockNotification) []*chain.Receipt { +// sc := tezos.MustParseAddress(r.src.ContractAddress()) +// var receipts []*chain.Receipt +// var events []*chain.Event +// for _, receipt := range v.Receipts{ +// events = append(events, &chain.Event{ +// Next: chain.BTPAddress(r.dst), + +// }) +// } +// } - var client *Client +func NewReceiver(src, dst chain.BTPAddress, urls []string, rawOpts json.RawMessage, l log.Logger) (chain.Receiver, error){ + var newClient *Client var err error if len(urls) == 0 { return nil, fmt.Errorf("Empty urls") } - srcAddr := tezos.MustParseAddress(src.String()) + receiver := &receiver{ + log: l, + src: src, + dst: dst, + } + + if receiver.opts.SyncConcurrency < 1 { + receiver.opts.SyncConcurrency = MonitorBlockMaxConcurrency + } else if receiver.opts.SyncConcurrency > MonitorBlockMaxConcurrency { + receiver.opts.SyncConcurrency = MonitorBlockMaxConcurrency + } + + srcAddr := tezos.MustParseAddress(string(src)) - dstAddr := tezos.MustParseAddress(dst.String()) + newClient, err = NewClient(urls[0], srcAddr, receiver.log) - client, err = NewClient(urls[0], srcAddr, l) if err != nil { return nil, err } + receiver.client = newClient - r := &receiver{ - log: l, - src: srcAddr, - dst: dstAddr, - client: client, - } + return receiver, nil +} - return r, nil +type ReceiverOptions struct { + SyncConcurrency uint64 `json:"syncConcurrency"` + Verifier *VerifierOptions `json:"verifier"` } -func (r *receiver) NewVerifier(previousHeight int64) (vri IVerifier, err error) { - header, err := r.client.GetBlockHeaderByHeight(r.client.Ctx, r.client.Cl, previousHeight) +func (r *receiver) NewVerifier(ctx context.Context, previousHeight int64) (vri IVerifier, err error) { + fmt.Println("reached to verifyer") + header, err := r.client.GetBlockHeaderByHeight(ctx, r.client.Cl, previousHeight) + fmt.Println("reached to after block header ") if err != nil { + fmt.Println(err) return nil, err } - + fmt.Println("returned from here?") fittness, err := strconv.ParseInt(string(header.Fitness[1].String()), 16, 64) if err != nil { return nil, err } - chainIdHash, err := r.client.Cl.GetChainId(r.client.Ctx) + fmt.Println("before chain id") + chainIdHash, err := r.client.Cl.GetChainId(ctx) if err != nil { return nil, err } @@ -106,11 +181,161 @@ func (r *receiver) NewVerifier(previousHeight int64) (vri IVerifier, err error) vr := &Verifier{ mu: sync.RWMutex{}, - next: header.Level, + next: header.Level + 1, parentHash: header.Hash, parentFittness: fittness, chainID: id, } - + fmt.Println("returned to the original") + fmt.Println(vr.parentHash) return vr, nil -} \ No newline at end of file +} + +func (r *receiver) syncVerifier(ctx context.Context, vr IVerifier, height int64) error { + if height == vr.Next() { + fmt.Println("returned from here") + return nil + } + + if vr.Next() > height { + return fmt.Errorf("Invalida target height: Verifier height (%d) > target height (%d)", vr.Next(), height) + } + + type res struct { + Height int64 + Header *rpc.BlockHeader + Block *rpc.Block + Votes int64 + } + + type req struct { + height int64 + err error + res *res + retry int64 + } + fmt.Println("reached before starting to log") + // r.log.WithFields(log.Fields{"height": vr.Next(), "target": height}).Info("syncVerifier: start") + + fmt.Println("reached in sync verifier") + var prevHeader *rpc.BlockHeader + + cursor := vr.Next() + + for cursor <= height { + fmt.Println("reached inside for") + fmt.Println(r.opts.SyncConcurrency) + + rqch := make(chan *req, r.opts.SyncConcurrency) + fmt.Println(len(rqch)) + fmt.Println(cap(rqch)) + for i := cursor; len(rqch) < cap(rqch); i++{ + rqch <- &req{height: i, retry: 5} + } + sres := make([]*res, 0, len(rqch)) + fmt.Println("reached here after sres") + for q := range rqch { + switch { + case q.err != nil: + if q.retry > 0 { + q.retry-- + q.res, q.err = nil, nil + rqch <- q + continue + } + // r.log.WithFields(log.Fields{"height": q.height, "error": q.err.Error()}).Debug("syncVerifier: req error") + sres = append(sres, nil) + if len(sres) == cap(sres) { + close(rqch) + } + case q.res != nil: + fmt.Println("should reach here in the second loop ") + sres = append(sres, q.res) + fmt.Println(cap(sres)) + if len(sres) == cap(sres){ + fmt.Println("closes channel") + close(rqch) + } + default: + fmt.Println("has to reach in this default ") + go func(q *req) { + defer func() { + time.Sleep(500 * time.Millisecond) + rqch <- q + }() + if q.res == nil { + fmt.Println("should reach here in nil portion") + q.res = &res{} + } + q.res.Height = q.height + q.res.Header, q.err = r.client.GetBlockHeaderByHeight(ctx, r.client.Cl, q.height) + fmt.Println(q.res.Header) + if q.err != nil { + q.err = errors.Wrapf(q.err, "syncVerifier: getBlockHeader: %v", q.err) + return + } + q.res.Block, q.err = r.client.GetBlockByHeight(ctx, r.client.Cl, q.height) + if q.err != nil { + q.err = errors.Wrapf(q.err, "syncVerifier: getBlock: %v", q.err) + return + } + fmt.Println(q.res.Block) + }(q) + } + + } + _sres, sres := sres, sres[:0] + for _, v := range _sres { + if v != nil { + fmt.Println("should reach in eliminating the null") + sres = append(sres, v) + } + } + + fmt.Printf("The lenght of sres is %d\n", len(sres)) + + if len(sres) > 0 { + sort.SliceStable(sres, func(i, j int) bool { + return sres[i].Height < sres[j].Height + }) + for i := range sres { + fmt.Println("Has to reach in the first time only") + cursor++ + next := sres[i] + if prevHeader == nil { + fmt.Println("Previous header is nil ") + fmt.Println(next.Header.Level) + prevHeader = next.Header + continue + } + if vr.Next() >= height { + fmt.Println("did it just break") + break + } + + fmt.Println("has it reached to verification") + fmt.Println(next.Header.Level) + + err := vr.Verify(ctx, prevHeader, next.Block.Metadata.Baker, r.client.Cl, next.Header.Hash) + + if err != nil { + return errors.Wrapf(err, "syncVerifier: Verify: %v", err) + } + + fmt.Println("verified block now updating ") + + err = vr.Update(prevHeader) + if err != nil { + return errors.Wrapf(err, "syncVerifier: Update: %v", err) + } + prevHeader = next.Header + } + // r.log.WithFields(log.Fields{"height": vr.Next(), "target": height}).Debug("syncVerifier: syncing") + } + } + + // r.log.WithFields(log.Fields{"height": vr.Next()}).Info("syncVerifier: complete") + + fmt.Println("sync complete") + return nil +} From f5f5263cf496817a1ff0ec1e4792d1045540e344 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Tue, 11 Apr 2023 11:05:53 +0545 Subject: [PATCH 023/211] feat: added logic to Receipt() and Status() --- cmd/iconbridge/chain/tezos/sender.go | 43 +++++++++++++++++++++------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/cmd/iconbridge/chain/tezos/sender.go b/cmd/iconbridge/chain/tezos/sender.go index 014af6f5..912f1d9d 100644 --- a/cmd/iconbridge/chain/tezos/sender.go +++ b/cmd/iconbridge/chain/tezos/sender.go @@ -46,20 +46,17 @@ func NewSender( urls []string, w wallet.Wallet, rawOpts json.RawMessage, l log.Logger) (chain.Sender, error) { var err error - srcAddr := tezos.MustParseAddress(src.String()) - - dstAddr := tezos.MustParseAddress(dst.String()) - + source := tezos.MustParseAddress(src.String()) + dest := tezos.MustParseAddress(dst.String()) s := &sender { log: l, - src: srcAddr, - dst: dstAddr, + src: source, + dst: dest, } - if len(urls) == 0 { return nil, fmt.Errorf("Empty url") } - s.cls, err = NewClient(urls[0], srcAddr, l) + s.cls, err = NewClient(urls[0], source, l) if err != nil { return nil, err } @@ -137,7 +134,23 @@ func (s *sender) Segment(ctx context.Context, msg *chain.Message) (tx chain.Rela } func (s *sender) Status(ctx context.Context) (link *chain.BMCLinkStatus, err error) { - return nil, nil + if ctx.Err() != nil { + return nil, ctx.Err() + } + + status, err := s.cls.GetStatus(ctx, s.cls.Contract) + if err != nil { + return nil, err + } + + ls := &chain.BMCLinkStatus{} + + ls.TxSeq = status.TxSeq.Uint64() + ls.RxSeq = status.RxSeq.Uint64() + ls.CurrentHeight = status.CurrentHeight.Uint64() + ls.RxHeight = status.RxHeight.Uint64() + + return ls, nil } func (s *sender) newRelayTx(ctx context.Context, prev string, message []byte) (*relayTx, error) { @@ -199,5 +212,15 @@ func (tx *relayTx) Send(ctx context.Context) (err error) { } func (tx *relayTx) Receipt(ctx context.Context) (blockHeight uint64, err error) { - return uint64(0), nil + if tx.receipt == nil { + return 0, fmt.Errorf("couldnot get receipt") + } + + blockHash := tx.receipt.Block + + blockHeight, err = tx.cl.GetBlockHeightByHash(ctx, tx.cl.Cl, blockHash) + if err != nil { + return 0, err + } + return blockHeight, nil } \ No newline at end of file From ba5da240762e543d640359f930273dda40432f32 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Tue, 11 Apr 2023 11:07:17 +0545 Subject: [PATCH 024/211] feat: added block signature verification feature --- cmd/iconbridge/chain/tezos/verifier.go | 74 +++++++++++++++++++++----- 1 file changed, 62 insertions(+), 12 deletions(-) diff --git a/cmd/iconbridge/chain/tezos/verifier.go b/cmd/iconbridge/chain/tezos/verifier.go index 6effb49d..ee844127 100644 --- a/cmd/iconbridge/chain/tezos/verifier.go +++ b/cmd/iconbridge/chain/tezos/verifier.go @@ -5,14 +5,16 @@ import ( "sync" "strconv" + "context" "blockwatch.cc/tzgo/rpc" "blockwatch.cc/tzgo/tezos" + "blockwatch.cc/tzgo/codec" ) type IVerifier interface { Next() int64 - Verify(header *rpc.BlockHeader, proposer *tezos.Address) error + Verify(ctx context.Context, header *rpc.BlockHeader, proposer tezos.Address, c *rpc.Client, hash tezos.BlockHash) error Update(header *rpc.BlockHeader) error ParentHash() tezos.BlockHash IsValidator(proposer tezos.Address, height int64) bool @@ -29,52 +31,58 @@ type Verifier struct{ func (vr *Verifier) Next() int64{ vr.mu.RLock() + defer vr.mu.RUnlock() return vr.next } -func (vr *Verifier) Verify(header *rpc.BlockHeader, proposer *tezos.Address) error { +func (vr *Verifier) Verify(ctx context.Context, header *rpc.BlockHeader, proposer tezos.Address, c *rpc.Client, hash tezos.BlockHash) error { vr.mu.RLock() defer vr.mu.RUnlock() + fmt.Println("has to reach in verify the second time") + fmt.Println(header.Level) blockFittness := header.Fitness + fmt.Println(blockFittness) currentFittness, err := strconv.ParseInt(string(blockFittness[1].String()), 16, 64) if err != nil { return err } - fmt.Print("Current fittness: ") - fmt.Println(currentFittness) - - fmt.Print("Parent fittness") - fmt.Println(vr.parentFittness) - if currentFittness < vr.parentFittness { return fmt.Errorf("Invalid block fittness") } + fmt.Println("validated the block fittness") previousHashInBlock := header.Predecessor - - fmt.Print("Current fittness: ") fmt.Println(previousHashInBlock) - fmt.Print("Parent fittness") fmt.Println(vr.parentHash) - if previousHashInBlock.String() != vr.parentHash.String() { return fmt.Errorf("Invalid block hash") } + + fmt.Println("here????") + + fmt.Println("Block is verified") fmt.Println("******* *******") fmt.Println(" ******* *******") fmt.Println(" ******* *******") + // isValidSignature, err := vr.VerifySignature(ctx, proposer, header.Signature, header.Level, header, c) + + // if !isValidSignature { + // return fmt.Errorf("Invalid block hash. Signature mismatch") + // } + fmt.Println(true) return nil } func (vr *Verifier) Update(header *rpc.BlockHeader) error { vr.mu.Lock() defer vr.mu.Unlock() + fmt.Println("updating????") blockFittness := header.Fitness currentFittness, err := strconv.ParseInt(string(blockFittness[1].String()), 16, 64) @@ -100,4 +108,46 @@ func (vr *Verifier) IsValidator(proposer tezos.Address, height int64) bool { vr.mu.RLock() defer vr.mu.RUnlock() return true +} + +func (vr *Verifier) VerifySignature(ctx context.Context, proposer tezos.Address, signature tezos.Signature, blockLevel int64, header *rpc.BlockHeader, c *rpc.Client) (bool, error) { + exposedPublicKey, err := c.GetManagerKey(ctx, proposer, rpc.BlockLevel(blockLevel)) + if err != nil { + return false, err + } + + blockHeader := codec.BlockHeader{ + Level: int32(header.Level), + Proto: byte(header.Proto), + Predecessor: header.Predecessor, + Timestamp: header.Timestamp, + ValidationPass: byte(header.ValidationPass), + OperationsHash: header.OperationsHash, + Fitness: header.Fitness, + Context: header.Context, + PayloadHash: header.PayloadHash, + PayloadRound: header.PayloadRound, + ProofOfWorkNonce: header.ProofOfWorkNonce, + LbToggleVote: header.LbVote(), + // SeedNonceHash: block.Metadata.NonceHash, + ChainId: &header.ChainId, + } + + + digestedHash := blockHeader.Digest() + + + err = exposedPublicKey.Verify(digestedHash[:], header.Signature) + + if err != nil { + fmt.Println(err) + return false, err + } + + return true, nil +} + +type VerifierOptions struct { + BlockHeight int64 `json:"blockHeight"` + BlockHash tezos.BlockHash `json:"parentHash"` } \ No newline at end of file From 6608cb6ba11a8a84b901974d72f46226f926b94c Mon Sep 17 00:00:00 2001 From: icondev22 Date: Tue, 11 Apr 2023 11:08:26 +0545 Subject: [PATCH 025/211] feat: added BlockNotification struct for receiving BTPMessage --- cmd/iconbridge/chain/tezos/types/types.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 cmd/iconbridge/chain/tezos/types/types.go diff --git a/cmd/iconbridge/chain/tezos/types/types.go b/cmd/iconbridge/chain/tezos/types/types.go new file mode 100644 index 00000000..3dbc8ed0 --- /dev/null +++ b/cmd/iconbridge/chain/tezos/types/types.go @@ -0,0 +1,17 @@ +package types + +import ( + "math/big" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "blockwatch.cc/tzgo/rpc" + + +) +type BlockNotification struct { + Hash common.Hash + Height *big.Int + Header *types.Header + Receipts []rpc.Receipt + HasBTPMessage *bool +} \ No newline at end of file From bcafabc8b934548f846a8e2754dbad1383e7118e Mon Sep 17 00:00:00 2001 From: simusud Date: Wed, 12 Apr 2023 17:22:53 +0545 Subject: [PATCH 026/211] fix(bts): zero address check fixes --- smartpy/bts/contracts/src/bts_core.py | 152 +++++++++++++++----------- 1 file changed, 89 insertions(+), 63 deletions(-) diff --git a/smartpy/bts/contracts/src/bts_core.py b/smartpy/bts/contracts/src/bts_core.py index c1942a6a..003f71cd 100644 --- a/smartpy/bts/contracts/src/bts_core.py +++ b/smartpy/bts/contracts/src/bts_core.py @@ -1,9 +1,13 @@ import smartpy as sp +FA2 = sp.io.import_script_from_url("https://smartpy.io/templates/fa2_lib.py") types = sp.io.import_script_from_url("file:./contracts/src/Types.py") -Coin = sp.TRecord(addr=sp.TAddress, fee_numerator=sp.TNat, fixed_fee=sp.TNat, - coin_type=sp.TNat) +FA2_contract = sp.io.import_script_from_url("file:./contracts/src/FA2Contract.py") +Coin = sp.TRecord(addr=sp.TAddress, + fee_numerator=sp.TNat, + fixed_fee=sp.TNat, + coin_type=sp.TNat) class BTSCore(sp.Contract): FEE_DENOMINATOR = sp.nat(10000) @@ -15,6 +19,8 @@ class BTSCore(sp.Contract): MAX_BATCH_SIZE = sp.nat(15) NATIVE_COIN_ADDRESS = sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc") + # Nat:(TWO.pow256 - 1) + UINT_CAP = sp.nat(115792089237316195423570985008687907853269984665640564039457584007913129639935) # TODO: change the native coin addr @@ -69,21 +75,17 @@ def update_bts_periphery(self, bts_periphery): sp.set_type(bts_periphery, sp.TAddress) self.only_owner() - # TODO: verify zero address - sp.verify(bts_periphery != sp.address("tz1000000"), message="InvalidSetting") - sp.if self.data.bts_periphery_address != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"): - has_requests = sp.view("has_pending_request", self.data.bts_periphery_address, sp.none, - t=sp.TBool).open_some("OwnerNotFound") - sp.verify(has_requests == False, message="HasPendingRequest") + # sp.verify(bts_periphery != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), message="InvalidSetting") + # sp.if self.data.bts_periphery_address != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"): + has_requests = sp.view("has_pending_request", self.data.bts_periphery_address, sp.unit, t=sp.TBool).open_some("OwnerNotFound") + sp.verify(has_requests == False, "HasPendingRequest") self.data.bts_periphery_address = bts_periphery - #set fee ratio, Caller must be the owner of this contract - #The transfer fee is calculated by feeNumerator/FEE_DEMONINATOR. - #_feeNumerator if it is set to `10`, which means the default fee ratio is 0.1%. @sp.entry_point def set_fee_ratio(self, name, fee_numerator, fixed_fee): """ - set fee ratio. + set fee ratio. The transfer fee is calculated by fee_numerator/FEE_DEMONINATOR. + fee_numerator if it is set to `10`, which means the default fee ratio is 0.1%. :param name: :param fee_numerator: the fee numerator :param fixed_fee: @@ -95,43 +97,45 @@ def set_fee_ratio(self, name, fee_numerator, fixed_fee): self.only_owner() sp.verify(fee_numerator < self.FEE_DENOMINATOR, message="InvalidSetting") - sp.verify((name == self.data.native_coin_name) | - (self.data.coins[name] != sp.address("tz1000")), - message = "TokenNotExists") + sp.verify((name == self.data.native_coin_name) | self.data.coins.contains(name), message = "TokenNotExists") sp.verify((fixed_fee > sp.nat(0)) & (fee_numerator >= sp.nat(0)), message = "LessThan0") self.data.coin_details[name].fee_numerator = fee_numerator self.data.coin_details[name].fixed_fee = fixed_fee @sp.entry_point - def register(self, name, symbol, decimals, fee_numerator, fixed_fee, addr): + def register(self, name, fee_numerator, fixed_fee, addr, token_metadata, metadata): """ Registers a wrapped coin and id number of a supporting coin. :param name: Must be different with the native coin name. - :param symbol: symbol name for wrapped coin. - :param decimals: decimal number :param fee_numerator: :param fixed_fee: :param addr: address of the coin + :param token_metadata: Token metadata name, symbol and decimals of wrapped token + :param metadata: metadata of the token contract :return: """ sp.set_type(name, sp.TString) - sp.set_type(symbol, sp.TString) - sp.set_type(decimals, sp.TNat) + # sp.set_type(symbol, sp.TString) + # sp.set_type(decimals, sp.TNat) sp.set_type(fee_numerator, sp.TNat) sp.set_type(fixed_fee, sp.TNat) sp.set_type(addr, sp.TAddress) + sp.set_type(token_metadata, sp.TMap(sp.TString, sp.TBytes)) + sp.set_type(metadata, sp.TBigMap(sp.TString, sp.TBytes)) - self.only_owner() + # self.only_owner() sp.verify(name != self.data.native_coin_name, message="ExistNativeCoin") - sp.verify(self.data.coins[name] == sp.address("tz10000"), message= "ExistCoin") - sp.verify(self.data.coins_address[addr] == "", message="AddressExists") + sp.verify(self.data.coins.contains(name) == False, message= "ExistCoin") + sp.verify(self.data.coins_address.contains(addr) == False, message="AddressExists") sp.verify(fee_numerator <= self.FEE_DENOMINATOR, message="InvalidSetting") sp.verify((fixed_fee >= sp.nat(0)) & (fee_numerator >= sp.nat(0)), message="LessThan0") - # TODO: confirm zero addr for tezos - with sp.if_(addr == sp.address("tz10000")): - # TODO:deploy FA2 contract and set the deployed address - deployed_fa2 = sp.address("tz10000") + with sp.if_(addr == self.NATIVE_COIN_ADDRESS): + sp.trace("in register native") + deployed_fa2 = sp.create_contract_operation(contract=FA2_contract.SingleAssetToken(admin=sp.self_address, metadata=metadata, + token_metadata=token_metadata + )).address + sp.trace(deployed_fa2) self.data.coins[name] = deployed_fa2 self.data.coins_name.push(name) self.data.coins_address[deployed_fa2] = name @@ -152,8 +156,8 @@ def register(self, name, symbol, decimals, fee_numerator, fixed_fee, addr): coin_type = self.NON_NATIVE_TOKEN_TYPE ) # ToDO: initialise string and make interscore call. - token_map = sp.map({0:name}) - val_map = sp.map({0:1}) + token_map = sp.map({0:name}, tkey=sp.TNat, tvalue=sp.TString) + val_map = sp.map({0:self.UINT_CAP}, tkey=sp.TNat, tvalue=sp.TNat) # call set_token_limit on bts_periphery set_token_limit_args_type = sp.TRecord(coin_names=sp.TMap(sp.TNat, sp.TString), token_limit=sp.TMap(sp.TNat, sp.TNat)) @@ -177,6 +181,8 @@ def coin_id(self, coin_name): :param coin_name: :return: An address of coin_name. """ + sp.set_type(coin_name, sp.TString) + sp.result(self.data.coins[coin_name]) @sp.onchain_view() @@ -186,7 +192,9 @@ def is_valid_coin(self, coin_name): :param coin_name: :return: true or false """ - sp.result((self.data.coins[coin_name] != sp.address("tz10000"))|( coin_name == self.data.native_coin_name)) + sp.set_type(coin_name, sp.TString) + + sp.result((self.data.coins.contains(coin_name))|( coin_name == self.data.native_coin_name)) @sp.onchain_view() @@ -196,6 +204,7 @@ def fee_ratio(self, coin_name): :param coin_name: Coin name :return: a record (Fee numerator for given coin, Fixed fee for given coin) """ + sp.set_type(coin_name, sp.TString) coin = self.data.coin_details[coin_name] fee_numerator = coin.fee_numerator @@ -220,20 +229,12 @@ def balance_of(self, params): sp.result(sp.record(usable_balance = sp.nat(0), locked_balance = self.data.balances[sp.record(address=params.owner, coin_name=params.coin_name)].locked_balance, refundable_balance = self.data.balances[sp.record(address=params.owner, coin_name=params.coin_name)].refundable_balance, - user_balance = sp.nat(2))) + user_balance = sp.nat(0))) with sp.else_(): fa2_address = self.data.coins[params.coin_name] + user_balance= sp.view("balance_of", fa2_address, sp.record(owner=params.owner, token_id=sp.nat(0)), t=sp.TNat).open_some() + usable_balance=sp.nat(1) - # IERC20 ierc20 = IERC20(_erc20Address); - #TODO: userbalance = token balance of a user? - # allowance? - sp.if fa2_address != sp.address("tz10000"): - pass - # return token balance of _owner - # _user_balance = - user_balance = sp.nat(0) - sp.if fa2_address == sp.address("tz10000"): - pass # TODO: userbalance and allowance operations sp.result(sp.record(usable_balance=usable_balance, locked_balance=self.data.balances[sp.record(address=params.owner, coin_name=params.coin_name)].locked_balance, @@ -300,8 +301,6 @@ def transfer_native_coin (self, to): t=sp.TBool).open_some() sp.verify(check_transfer == True, "FailCheckTransfer") - #TODO: confirm data type for amount - charge_amt = amount_in_nat.value * self.data.coin_details[self.data.native_coin_name].fee_numerator / self.FEE_DENOMINATOR + self.data.coin_details[self.data.native_coin_name].fixed_fee #Confirm the type for this calculation @@ -322,8 +321,7 @@ def transfer(self, coin_name, value, to): sp.verify(coin_name != self.data.native_coin_name, message="InvalidWrappedCoin") - fa2_address = self.data.coins[coin_name] - sp.verify(fa2_address != sp.address("tz10000"), message= "CoinNotRegistered") + sp.verify(self.data.coins.contains(coin_name), message= "CoinNotRegistered") # call check_transfer_restrictions on bts_periphery check_transfer = sp.view("check_transfer_restrictions", self.data.bts_periphery_address, @@ -389,10 +387,10 @@ def transfer_batch(self, coin_names, values, to): amount_in_nat = sp.local("amount_in_nat", sp.utils.mutez_to_nat(sp.amount), t=sp.TNat) - size = sp.local("size", sp.nat(0)) - sp.if amount_in_nat.value != sp.nat(0): + size = sp.local("size", sp.nat(0), t=sp.TNat) + with sp.if_(amount_in_nat.value != sp.nat(0)): size.value = sp.len(coin_names) + sp.nat(1) - sp.if amount_in_nat.value == sp.nat(0): + with sp.else_(): size.value = sp.len(coin_names) sp.verify(size.value <= self.MAX_BATCH_SIZE, message ="InvalidRequest") @@ -406,8 +404,8 @@ def transfer_batch(self, coin_names, values, to): value = sp.local("value", 0, t= sp.TNat) sp.for i in sp.range(sp.nat(0), sp.len(coin_names)): - fa2_addresses = self.data.coins[coin_names[i]] - sp.verify(fa2_addresses != sp.address("tz10000"), message= "CoinNotRegistered") + sp.verify(coin_names[i] != self.data.native_coin_name, message="InvalidCoin") + sp.verify(self.data.coins.contains(coin_names[i]), message= "CoinNotRegistered") coin_name.value = coin_names[i] value.value = values[i] sp.verify(value.value > sp.nat(0), message ="ZeroOrLess") @@ -480,15 +478,27 @@ def refund(self, to, coin_name, value): :param value: :return: """ + sp.set_type(to, sp.TAddress) + sp.set_type(coin_name, sp.TString) + sp.set_type(value, sp.TNat) + sp.verify(sp.sender == sp.self_address, message="Unauthorized") with sp.if_(coin_name == self.data.native_coin_name): self.payment_transfer(to, value) with sp.else_(): - pass - #TODO: implement transfer on fa2 + # call transfer in FA2 + transfer_args_type = sp.TList(sp.TRecord(from_=sp.TAddress, txs=sp.TList(sp.TRecord( + to_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout(("to_", ("token_id", "amount")))) + ).layout(("from_", "txs"))) + transfer_entry_point = sp.contract(transfer_args_type, self.data.coins[coin_name], "transfer").open_some() + transfer_args = [sp.record(from_=sp.sender, txs=[sp.record(to_=to, token_id=sp.nat(0), amount=value)])] + sp.transfer(transfer_args, sp.tez(0), transfer_entry_point) def payment_transfer(self, to, amount): + sp.set_type(to, sp.TAddress) + sp.set_type(amount, sp.TNat) + pass #TODO: implement the following: @@ -513,14 +523,19 @@ def mint(self, to, coin_name, value): sp.if coin_name == self.data.native_coin_name: self.payment_transfer(to, value) sp.if self.data.coin_details[coin_name].coin_type == self.NATIVE_WRAPPED_COIN_TYPE: - pass - #TODO : implement mint? - # IERC20Tradable(coins[_coinName]).mint(_to, _value) + # call mint in FA2 + mint_args_type = sp.TList(sp.TRecord(to_=sp.TAddress, amount=sp.TNat).layout(("to_", "amount"))) + mint_entry_point = sp.contract(mint_args_type, self.data.coins[coin_name], "mint").open_some() + mint_args = [sp.record(to_=to, amount=value)] + sp.transfer(mint_args, sp.tez(0), mint_entry_point) sp.if self.data.coin_details[coin_name].coin_type == self.NON_NATIVE_TOKEN_TYPE: - pass - #TODO: implement transfer - # IERC20(coins[_coinName]).transfer(_to, _value) - + # call transfer in FA2 + transfer_args_type = sp.TList(sp.TRecord(from_=sp.TAddress, txs=sp.TList(sp.TRecord( + to_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout(("to_", ("token_id", "amount")))) + ).layout(("from_", "txs"))) + transfer_entry_point = sp.contract(transfer_args_type, self.data.coins[coin_name], "transfer").open_some() + transfer_args = [sp.record(from_=sp.sender, txs=[sp.record(to_=to, token_id=sp.nat(0), amount=value)])] + sp.transfer(transfer_args, sp.tez(0), transfer_entry_point) @sp.entry_point def handle_response_service(self, requester, coin_name, value, fee, rsp_code): @@ -549,12 +564,16 @@ def handle_response_service(self, requester, coin_name, value, fee, rsp_code): self.data.balances[sp.record(address=requester, coin_name=coin_name)].locked_balance = sp.as_nat(self.data.balances[sp.record(address=requester, coin_name=coin_name)].locked_balance - amount.value) sp.if rsp_code == self.RC_ERR: + pass # TODO: implement try catch + sp.if rsp_code == self.RC_OK: fa2_address = self.data.coins[coin_name] sp.if (coin_name != self.data.native_coin_name) & (self.data.coin_details[coin_name].coin_type == self.NATIVE_WRAPPED_COIN_TYPE): - pass - #TODO:implement burn - #IERC20Tradable(_erc20Address).burn(address(this), _value) + # call burn in FA2 + burn_args_type = sp.TList(sp.TRecord(from_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout("from_", ("token_id", "amount"))) + burn_entry_point = sp.contract(burn_args_type, fa2_address, "burn").open_some() + burn_args = [sp.record(from_=sp.self_address, token_id=sp.nat(0), amount=value)] + sp.transfer(burn_args, sp.tez(0), burn_entry_point) self.data.aggregation_fee[coin_name] = self.data.aggregation_fee[coin_name] + fee @@ -612,12 +631,15 @@ def update_coin_db(self): @sp.entry_point def set_bts_owner_manager(self, owner_manager): + sp.set_type(owner_manager, sp.TAddress) + sp.verify(self.data.owners[sp.sender] == True , message= "Unauthorized") - sp.verify(owner_manager != sp.address("tz10000"), message= "InvalidAddress") + # sp.verify(owner_manager != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), message= "InvalidAddress") self.data.bts_owner_manager = owner_manager @sp.add_test(name="BTSCore") def test(): + alice=sp.test_account("Alice") c1 = BTSCore( owner_manager=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), bts_periphery_addr=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), @@ -628,6 +650,10 @@ def test(): scenario = sp.test_scenario() scenario.h1("BTSCore") scenario += c1 + c1.register(sp.record(name="tezos", symbol="TEZ", decimals=sp.nat(18), fee_numerator=sp.nat(5), fixed_fee=sp.nat(1), + addr=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), + token_metadata=sp.map({"ss": sp.bytes("0x0dae11")}), + metadata=sp.big_map({"ff": sp.bytes("0x0dae11")}))).run(sender=alice) sp.add_compilation_target("bts_core", BTSCore( From 822c97b5fdfad0d738437245bed65365220ae37f Mon Sep 17 00:00:00 2001 From: simusud Date: Wed, 12 Apr 2023 17:23:53 +0545 Subject: [PATCH 027/211] fix(bts): small fixes --- smartpy/bts/contracts/src/String.py | 8 ++++---- smartpy/bts/contracts/src/bts_periphery.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/smartpy/bts/contracts/src/String.py b/smartpy/bts/contracts/src/String.py index 13f58a47..e8ceb854 100644 --- a/smartpy/bts/contracts/src/String.py +++ b/smartpy/bts/contracts/src/String.py @@ -26,14 +26,14 @@ def split_btp_address(base): with sp.match_cons(inverted_list.value) as l: last.value = l.head inverted_list.value = l.tail - with sp.else_(): - sp.failwith("Empty list") + # with sp.else_(): + # sp.failwith("Empty list") with sp.match_cons(inverted_list.value) as l: penultimate.value = l.head - with sp.else_(): - sp.failwith("Only one element") + # with sp.else_(): + # sp.failwith("Only one element") return sp.pair(last.value, penultimate.value) diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index 793ab53f..eff5523e 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -38,7 +38,7 @@ def has_pending_request(self): :return: boolean """ - sp.result(self.data.number_of_pending_requests != 0) + sp.result(self.data.number_of_pending_requests != sp.nat(0)) @sp.entry_point def add_to_blacklist(self, params): From b95002e2809bac2b05a8f9f23e6cf85162c5a693 Mon Sep 17 00:00:00 2001 From: simusud Date: Wed, 12 Apr 2023 17:25:07 +0545 Subject: [PATCH 028/211] feat(FA2): added params and view methods --- smartpy/bts/contracts/src/FA2Contract.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/smartpy/bts/contracts/src/FA2Contract.py b/smartpy/bts/contracts/src/FA2Contract.py index b9b2bb64..fb4b543d 100644 --- a/smartpy/bts/contracts/src/FA2Contract.py +++ b/smartpy/bts/contracts/src/FA2Contract.py @@ -3,9 +3,9 @@ FA2 = sp.io.import_script_from_url("https://smartpy.io/templates/fa2_lib.py") -class SingleAssetToken(FA2.Admin, FA2.Fa2SingleAsset, FA2.BurnSingleAsset): - def __init__(self, admin, **kwargs): - FA2.Fa2SingleAsset.__init__(self, **kwargs) +class SingleAssetToken(FA2.Admin, FA2.Fa2SingleAsset, FA2.BurnSingleAsset, FA2.OnchainviewBalanceOf): + def __init__(self, admin, metadata, token_metadata): + FA2.Fa2SingleAsset.__init__(self, metadata=metadata, token_metadata=token_metadata) FA2.Admin.__init__(self, admin) @sp.entry_point @@ -29,11 +29,15 @@ def mint(self, batch): def is_admin(self, address): sp.result(address == self.data.administrator) + @sp.onchain_view() + def balance_of(self, param): + sp.set_type(param, sp.TRecord(owner=sp.TAddress, token_id=sp.TNat)) + sp.result(self.balance_(param.owner, param.token_id)) + sp.add_compilation_target("fa2_single_asset", SingleAssetToken( admin=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), metadata=sp.utils.metadata_of_url( "ipfs://example"), - token_metadata = FA2.make_metadata(name="Token Zero", decimals=1, symbol="Tok0"), - policy=None)) \ No newline at end of file + token_metadata=FA2.make_metadata(name="Token Zero", decimals=1, symbol="Tok0"))) \ No newline at end of file From 8ca90a90976a7c7340bf2a74c9eba5fef6eb350e Mon Sep 17 00:00:00 2001 From: simusud Date: Tue, 18 Apr 2023 14:48:15 +0545 Subject: [PATCH 029/211] fix(bmc): added checks if a map contains a key --- smartpy/bmc/contracts/src/bmc_management.py | 131 +++++++++++--------- 1 file changed, 69 insertions(+), 62 deletions(-) diff --git a/smartpy/bmc/contracts/src/bmc_management.py b/smartpy/bmc/contracts/src/bmc_management.py index 402ee497..c902bac0 100644 --- a/smartpy/bmc/contracts/src/bmc_management.py +++ b/smartpy/bmc/contracts/src/bmc_management.py @@ -1,7 +1,9 @@ import smartpy as sp +Utils = sp.io.import_script_from_url("https://raw.githubusercontent.com/Acurast/acurast-hyperdrive/main/contracts/tezos/libs/utils.py") types = sp.io.import_script_from_url("file:./contracts/src/Types.py") strings = sp.io.import_script_from_url("file:./contracts/src/String.py") +rlp_encode = sp.io.import_script_from_url("file:./contracts/src/RLP_encode_struct.py") class BMCManagement(sp.Contract): @@ -45,11 +47,15 @@ def __init__(self): )) # to be called after deployment manually + @sp.entry_point def enable(self): self.data.owners[sp.sender] = True def only_owner(self): - sp.verify(self.data.owners[sp.sender] == True, "Unauthorized") + with sp.if_(self.data.owners.contains(sp.sender)): + sp.verify(self.data.owners[sp.sender] == True, "Unauthorized") + with sp.else_(): + sp.failwith("Unauthorized") def only_bmc_periphery(self): sp.verify(sp.sender == self.data.bmc_periphery.open_some("BMCAddressNotSet"), "Unauthorized") @@ -63,8 +69,6 @@ def set_bmc_periphery(self, addr): """ sp.set_type(addr, sp.TAddress) # self.only_owner() - sp.verify(addr != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), "InvalidAddress") - sp.trace(self.data.bmc_periphery.is_some()) sp.if self.data.bmc_periphery.is_some(): sp.verify(addr != self.data.bmc_periphery.open_some("Address not set"), "AlreadyExistsBMCPeriphery") self.data.bmc_periphery = sp.some(addr) @@ -115,8 +119,8 @@ def add_service(self, svc, addr): :return: """ self.only_owner() - sp.verify(addr != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), "InvalidAddress") - sp.verify(self.data.bsh_services[svc] == sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), "AlreadyExistsBSH") + # sp.verify(addr != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), "InvalidAddress") + sp.verify(self.data.bsh_services.contains(svc) == False, "AlreadyExistsBSH") self.data.bsh_services[svc] = addr self.data.list_bsh_names.add(svc) @@ -128,7 +132,7 @@ def remove_service(self, svc): :return: """ self.only_owner() - sp.verify(self.data.bsh_services[svc] == sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), "NotExistsBSH") + sp.verify(self.data.bsh_services.contains(svc), "NotExistsBSH") del self.data.bsh_services[svc] self.data.list_bsh_names.remove(svc) @@ -160,10 +164,9 @@ def add_link(self, link): with sp.if_(self.data.links.contains(link)): sp.verify(self.data.links[link].is_connected == False, "AlreadyExistsLink") - #TODO:review how to add key in relays map self.data.links[link] = sp.record( - relays=sp.set([sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc")]), - reachable=sp.set(["0"]), + relays=sp.set([]), + reachable=sp.set([]), rx_seq=sp.nat(0), tx_seq=sp.nat(0), block_interval_src=self.BLOCK_INTERVAL_MSEC, @@ -195,15 +198,14 @@ def remove_link(self, link): sp.set_type(link, sp.TString) self.only_owner() - # TODO : review this if else with sp.if_(self.data.links.contains(link)): sp.verify(self.data.links[link].is_connected == True, "NotExistsLink") with sp.else_(): sp.failwith("NotExistsLink") + self._propagate_internal("Unlink", link) del self.data.links[link] net, addr= sp.match_pair(strings.split_btp_address(link, "prev_idx", "result", "my_list", "last", "penultimate")) - del self.data.get_link_from_net[link] - self._propagate_internal("Unlink", link) + del self.data.get_link_from_net[net] self.data.list_link_names.remove(link) sp.trace("in remove_link") @@ -254,7 +256,10 @@ def set_link(self, _link, block_interval, _max_aggregation, delay_limit): self.only_owner() - sp.verify(self.data.links[_link].is_connected == True, "NotExistsLink") + with sp.if_(self.data.links.contains(_link)): + sp.verify(self.data.links[_link].is_connected == True, "NotExistsLink") + with sp.else_(): + sp.failwith("NotExistsLink") sp.verify((_max_aggregation >= sp.nat(1)) & (delay_limit >= sp.nat(1)), "InvalidParam") link = sp.local("link", self.data.links[_link], t=types.Types.Link).value @@ -287,55 +292,56 @@ def _propagate_internal(self, service_type, link): sp.set_type(service_type, sp.TString) sp.set_type(link, sp.TString) - #TODO implement abi encodePacked - - # TODO: encode actual payload - rlp_bytes =sp.bytes("0x1221") + _bytes = sp.bytes("0x80") # can be any bytes + encode_string_packed = sp.build_lambda(Utils.Bytes.of_string) + rlp_bytes = _bytes + encode_string_packed(link) + with_length_prefix = sp.build_lambda(Utils.RLP.Encoder.with_length_prefix) + rlp_bytes_with_prefix = with_length_prefix(rlp_bytes) + #encode payload + final_rlp_bytes_with_prefix = with_length_prefix(rlp_bytes_with_prefix) sp.for item in self.data.list_link_names.elements(): sp.if self.data.links[item].is_connected: net, addr = sp.match_pair(strings.split_btp_address(item, "prev_idx1", "result1", "my_list1", "last1", "penultimate1")) # call send_message on BMCPeriphery - # TODO: encodeBMCService - # send_message_args_type = sp.TRecord(to=sp.TString, svc=sp.TString, sn=sp.TNat, msg=sp.TBytes) - # send_message_entry_point = sp.contract(send_message_args_type, - # self.data.bmc_periphery, - # "send_message").open_some() - # send_message_args = sp.record(to=net, svc="bmc", sn=sp.nat(0), msg=encodeBMCService( - # sp.record(serviceType=service_type, payload=rlp_bytes))) - # sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) + send_message_args_type = sp.TRecord(to=sp.TString, svc=sp.TString, sn=sp.TNat, msg=sp.TBytes) + send_message_entry_point = sp.contract(send_message_args_type, + self.data.bmc_periphery.open_some("Address not set"), + "send_message").open_some() + send_message_args = sp.record(to=net, svc="bmc", sn=sp.nat(0), msg=rlp_encode.encode_bmc_service( + sp.record(serviceType=service_type, payload=final_rlp_bytes_with_prefix))) + sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) def _send_internal(self, target, service_type, links): sp.set_type(target, sp.TString) sp.set_type(service_type, sp.TString) sp.set_type(links, sp.TList(sp.TString)) + rlp_bytes = sp.local("rlp_bytes", sp.bytes("0x")) with sp.if_(sp.len(links) == sp.nat(0)): - # TODO: abi encode - rlp_bytes = sp.bytes("0x1221") + rlp_bytes.value = rlp_encode.LIST_SHORT_START with sp.else_(): - sp.for i in sp.range(0, sp.len(links)): - # TODO: abi encode - rlp_bytes = sp.bytes("0x1221") - - #TODO: encode payload - rlp_bytes = sp.bytes("0x1221") - - # net, addr = sp.match_pair(strings.split_btp_address(target)) - + sp.for item in links: + _bytes = sp.bytes("0x80") # can be any bytes + encode_string_packed = sp.build_lambda(Utils.Bytes.of_string) + _rlp_bytes = _bytes + encode_string_packed(item) + with_length_prefix = sp.build_lambda(Utils.RLP.Encoder.with_length_prefix) + rlp_bytes.value = with_length_prefix(_rlp_bytes) + #encode payload + with_length_prefix1 = sp.build_lambda(Utils.RLP.Encoder.with_length_prefix) + final_rlp_bytes_with_prefix = with_length_prefix1(rlp_bytes.value) net, addr = sp.match_pair( strings.split_btp_address(target, "prev_idx2", "result2", "my_list2", "last2", "penultimate2")) # call send_message on BMCPeriphery - # TODO: encodeBMCService - # send_message_args_type = sp.TRecord(to=sp.TString, svc=sp.TString, sn=sp.TNat, msg=sp.TBytes) - # send_message_entry_point = sp.contract(send_message_args_type, - # self.data.bmc_periphery, - # "send_message").open_some() - # send_message_args = sp.record(to=net, svc="bmc", sn=sp.nat(0), msg=encodeBMCService( - # sp.record(serviceType=service_type, payload=rlp_bytes))) - # sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) + send_message_args_type = sp.TRecord(to=sp.TString, svc=sp.TString, sn=sp.TNat, msg=sp.TBytes) + send_message_entry_point = sp.contract(send_message_args_type, + self.data.bmc_periphery.open_some("Address not set"), + "send_message").open_some() + send_message_args = sp.record(to=net, svc="bmc", sn=sp.nat(0), msg=rlp_encode.encode_bmc_service( + sp.record(serviceType=service_type, payload=final_rlp_bytes_with_prefix))) + sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) @sp.entry_point @@ -350,7 +356,7 @@ def add_route(self, dst, link): sp.set_type(link, sp.TString) self.only_owner() - sp.verify(sp.len(sp.pack(self.data.routes[dst])) == sp.nat(0), "AlreadyExistRoute") + sp.verify(self.data.routes.contains(dst) == False, "AlreadyExistRoute") net, addr= sp.match_pair(strings.split_btp_address(dst, "prev_idx", "result", "my_list", "last", "penultimate")) # TODO: need to verify link is only split never used # strings.split_btp_address(link) @@ -369,7 +375,7 @@ def remove_route(self, dst): sp.set_type(dst, sp.TString) self.only_owner() - sp.verify(sp.len(sp.pack(self.data.routes[dst])) != sp.nat(0), "NotExistRoute") + sp.verify(self.data.routes.contains(dst) == True, "NotExistRoute") del self.data.routes[dst] net, addr= sp.match_pair(strings.split_btp_address(dst, "prev_idx", "result", "my_list", "last", "penultimate")) del self.data.get_route_dst_from_net[net] @@ -383,8 +389,8 @@ def get_routes(self): """ _routes = sp.compute(sp.map(tkey=sp.TNat, tvalue=types.Types.Route)) + i = sp.local("i", 0) sp.for item in self.data.list_route_keys.elements(): - i=sp.local("i", 0) _routes[i.value] = sp.record(dst=item, next=self.data.routes[item]) i.value += 1 sp.result(_routes) @@ -401,6 +407,7 @@ def add_relay(self, link, addr): sp.set_type(addr, sp.TSet(sp.TAddress)) self.only_owner() + sp.verify(self.data.links.contains(link), "NotExistsLink") sp.verify(self.data.links[link].is_connected == True, "NotExistsLink") self.data.links[link].relays = addr sp.for item in addr.elements(): @@ -418,6 +425,7 @@ def remove_relay(self, link, addr): sp.set_type(addr, sp.TAddress) self.only_owner() + sp.verify(self.data.links.contains(link), "NotExistsLink") sp.verify((self.data.links[link].is_connected == True) & (sp.len(self.data.links[link].relays.elements()) != sp.nat(0)), "Unauthorized") @@ -478,8 +486,8 @@ def get_relay_status_by_link(self, prev): sp.set_type(prev, sp.TString) _relays = sp.compute(sp.map(tkey=sp.TNat, tvalue=types.Types.RelayStats)) + i = sp.local("i", 0) sp.for item in self.data.links[prev].relays.elements(): - i =sp.local("i", 0) _relays[i.value] = self.data.relay_stats[item] i.value += 1 sp.result(_relays) @@ -525,8 +533,8 @@ def delete_link_reachable(self, prev, index): sp.set_type(index, sp.TNat) self.only_bmc_periphery() + i = sp.local("i", 0) sp.for item in self.data.links[prev].reachable.elements(): - i = sp.local("i", 0) sp.if i.value == index: net, addr = sp.match_pair( strings.split_btp_address(item, "prev_idx", "result", "my_list", "last", "penultimate")) @@ -556,19 +564,17 @@ def resolve_route(self, dst_net): self.only_bmc_periphery() dst = sp.local("dst", self.data.get_route_dst_from_net[dst_net], t=sp.TString) - # TODO: calculate length of byte - # sp.if sp.len(sp.pack(dst.value))!= sp.nat(0): - # sp.result(sp.pair(self.data.routes[dst.value], dst.value)) - - dst_link = sp.local("dst_link", self.data.get_link_from_net[dst_net], t=sp.TString) - # TODO: calculate length of byte - # sp.if sp.len(sp.pack(dst_link.value)) != sp.nat(0): - # sp.result(sp.pair(dst_link.value, dst_link.value)) - - res = sp.local("res", self.data.get_link_from_reachable_net[dst_net], t=types.Types.Tuple) - sp.verify(sp.len(sp.pack(res.value.to)) > sp.nat(0), "Unreachable: " + dst_net + " is unreachable") + with sp.if_(sp.len(sp.pack(dst.value))!= sp.nat(0)): + sp.result(sp.pair(self.data.routes[dst.value], dst.value)) + with sp.else_(): + dst_link = sp.local("dst_link", self.data.get_link_from_net[dst_net], t=sp.TString) + with sp.if_(sp.len(sp.pack(dst_link.value)) != sp.nat(0)): + sp.result(sp.pair(dst_link.value, dst_link.value)) + with sp.else_(): + res = sp.local("res", self.data.get_link_from_reachable_net[dst_net], t=types.Types.Tuple) + sp.verify(sp.len(sp.pack(res.value.to)) > sp.nat(0), "Unreachable: " + dst_net + " is unreachable") - sp.result(sp.pair(res.value.prev, res.value.to)) + sp.result(sp.pair(res.value.prev, res.value.to)) @sp.add_test(name="BMCM") @@ -587,7 +593,8 @@ def test(): # bmc_man.remove_owner(alice.address).run(sender=alice) bmc_man.add_link("btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW").run(sender=alice) - # bmc_man.remove_link("btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW").run(sender=alice) + bmc_man.remove_link("btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW").run(sender=alice) + bmc_man.add_link("btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW").run(sender=alice) bmc_man.set_link_rx_height(sp.record(link="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", height=sp.nat(2))).run(sender=alice) bmc_man.set_link(sp.record(_link="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", block_interval=sp.nat(2), From 7374d32d9824ea6ba976f046b7e0a3fbc8d947e4 Mon Sep 17 00:00:00 2001 From: simusud Date: Tue, 18 Apr 2023 14:49:24 +0545 Subject: [PATCH 030/211] fix(lib): return value fix in String.py library --- smartpy/bmc/contracts/src/String.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smartpy/bmc/contracts/src/String.py b/smartpy/bmc/contracts/src/String.py index dc41a8f7..d766d723 100644 --- a/smartpy/bmc/contracts/src/String.py +++ b/smartpy/bmc/contracts/src/String.py @@ -42,7 +42,7 @@ def split_btp_address(base, prev_string, result_string, list_string, last_string # with sp.else_(): # sp.failwith("Only one element") - return sp.pair(last.value, penultimate.value) + return sp.pair(penultimate.value, last.value) From 901f6dd2f6c735be86308bf05f1431532cc63964 Mon Sep 17 00:00:00 2001 From: simusud Date: Tue, 18 Apr 2023 14:50:20 +0545 Subject: [PATCH 031/211] feat(bmc): added RLP encode library --- smartpy/bmc/contracts/src/RLP_encode_struct.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 smartpy/bmc/contracts/src/RLP_encode_struct.py diff --git a/smartpy/bmc/contracts/src/RLP_encode_struct.py b/smartpy/bmc/contracts/src/RLP_encode_struct.py new file mode 100644 index 00000000..cbaf8638 --- /dev/null +++ b/smartpy/bmc/contracts/src/RLP_encode_struct.py @@ -0,0 +1,15 @@ +import smartpy as sp +Utils = sp.io.import_script_from_url("https://raw.githubusercontent.com/Acurast/acurast-hyperdrive/main/contracts/tezos/libs/utils.py") + +LIST_SHORT_START = sp.bytes("0xc0") + + +def encode_bmc_service(params): + sp.set_type(params, sp.TRecord(serviceType=sp.TString, payload=sp.TBytes)) + + encode_string_packed = sp.build_lambda(Utils.Bytes.of_string) + _rlpBytes = params.payload + encode_string_packed(params.serviceType) + with_length_prefix = sp.build_lambda(Utils.RLP.Encoder.with_length_prefix) + rlp_bytes_with_prefix = with_length_prefix(_rlpBytes) + return rlp_bytes_with_prefix + From b0a9e84e7b88178708b628cf90e7f6f206b22741 Mon Sep 17 00:00:00 2001 From: simusud Date: Wed, 19 Apr 2023 12:39:00 +0545 Subject: [PATCH 032/211] feat(bmc): implement RLP encode library --- .../bmc/contracts/src/RLP_encode_struct.py | 16 ++++++++++- smartpy/bmc/contracts/src/bmc_periphery.py | 27 ++++++++++--------- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/smartpy/bmc/contracts/src/RLP_encode_struct.py b/smartpy/bmc/contracts/src/RLP_encode_struct.py index cbaf8638..05eaf956 100644 --- a/smartpy/bmc/contracts/src/RLP_encode_struct.py +++ b/smartpy/bmc/contracts/src/RLP_encode_struct.py @@ -1,5 +1,7 @@ import smartpy as sp -Utils = sp.io.import_script_from_url("https://raw.githubusercontent.com/Acurast/acurast-hyperdrive/main/contracts/tezos/libs/utils.py") + +Utils = sp.io.import_script_from_url( + "https://raw.githubusercontent.com/Acurast/acurast-hyperdrive/main/contracts/tezos/libs/utils.py") LIST_SHORT_START = sp.bytes("0xc0") @@ -13,3 +15,15 @@ def encode_bmc_service(params): rlp_bytes_with_prefix = with_length_prefix(_rlpBytes) return rlp_bytes_with_prefix + +def encode_bmc_message(params): + sp.set_type(params, sp.TRecord(src=sp.TString, dst=sp.TString, svc=sp.TString, sn=sp.TNat, message=sp.TBytes)) + + encode_string_packed = sp.build_lambda(Utils.Bytes.of_string) + encode_nat_packed = sp.build_lambda(Utils.Bytes.of_nat) + rlp = encode_string_packed(params.src) + encode_string_packed(params.dst)\ + + encode_string_packed(params.svc) + encode_nat_packed(params.sn) + params.message + with_length_prefix = sp.build_lambda(Utils.RLP.Encoder.with_length_prefix) + rlp_bytes_with_prefix = with_length_prefix(rlp) + return rlp_bytes_with_prefix + diff --git a/smartpy/bmc/contracts/src/bmc_periphery.py b/smartpy/bmc/contracts/src/bmc_periphery.py index 9c8a280a..4f42ca3e 100644 --- a/smartpy/bmc/contracts/src/bmc_periphery.py +++ b/smartpy/bmc/contracts/src/bmc_periphery.py @@ -2,6 +2,7 @@ types = sp.io.import_script_from_url("file:./contracts/src/Types.py") strings = sp.io.import_script_from_url("file:./contracts/src/String.py") +rlp_encode = sp.io.import_script_from_url("file:./contracts/src/RLP_encode_struct.py") class BMCPreiphery(sp.Contract): @@ -33,12 +34,14 @@ def _require_registered_relay(self, prev): sp.set_type(prev, sp.TString) sp.trace(prev) + #TODO: check sp. view + # relay = sp.view("get_link_relays", self.data.bmc_management, prev, t=sp.TList(sp.TAddress)).open_some() relay = [] sp.for x in relay: sp.if sp.sender == x: return - sp.fail_with(self.BMCRevertUnauthorized) + sp.failwith(self.BMCRevertUnauthorized) @sp.entry_point def handle_relay_message(self, prev, msg): @@ -228,7 +231,7 @@ def _send_error(self, prev, message, err_code, err_msg): sp.set_type(err_msg, sp.TString) if message.sn > sp.nat(0): - serialized_msg = encode_bmc_message(sp.record( + serialized_msg = rlp_encode.encode_bmc_message(sp.record( src=self.data.bmc_btp_address, dst=message.src, svc=message.svc, @@ -259,16 +262,14 @@ def send_message(self, to, svc, sn, msg): next_link, dst = sp.match_pair(sp.view("resolve_route", self.data.bmc_management, to, t=sp.TPair(sp.TString, sp.TString)).open_some()) - # need to import encode_bmc_message from library - # rlp = encode_bmc_message(sp.record( - # src=self.data.bmc_btp_address, - # dst=dst, - # svc=svc, - # sn=sn, - # message=msg - # )) - next_link = "next_link" - rlp = sp.bytes("0x0dae11") + rlp = rlp_encode.encode_bmc_message(sp.record( + src=self.data.bmc_btp_address, + dst=dst, + svc=svc, + sn=sn, + message=msg + )) + # next_link = "next_link" self._send_message(next_link, rlp) @sp.onchain_view() @@ -303,4 +304,4 @@ def test(): bmc.handle_relay_message(sp.record(prev="demo string", msg=sp.bytes("0x0dae11"))).run(sender=alice) sp.add_compilation_target("bmc_periphery", BMCPreiphery(network="tezos", - bmc_management_addr=sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"))) + bmc_management_addr=sp.address("KT1GmZEcN82NbZrxXkhazvuX6ybJB12JTJAT"))) From 45ff99c745b5c5dfe6aed26a8dbe9c4c6caf6f99 Mon Sep 17 00:00:00 2001 From: simusud Date: Wed, 19 Apr 2023 12:41:55 +0545 Subject: [PATCH 033/211] fix(bmc): view method fixes --- smartpy/bmc/contracts/src/bmc_management.py | 24 ++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/smartpy/bmc/contracts/src/bmc_management.py b/smartpy/bmc/contracts/src/bmc_management.py index c902bac0..259ed808 100644 --- a/smartpy/bmc/contracts/src/bmc_management.py +++ b/smartpy/bmc/contracts/src/bmc_management.py @@ -557,24 +557,24 @@ def update_relay_stats(self, relay, block_count_val, msg_count_val): self.data.relay_stats[relay].block_count += block_count_val self.data.relay_stats[relay].msg_count += msg_count_val - @sp.onchain_view() + # @sp.onchain_view() def resolve_route(self, dst_net): sp.set_type(dst_net, sp.TString) self.only_bmc_periphery() dst = sp.local("dst", self.data.get_route_dst_from_net[dst_net], t=sp.TString) - with sp.if_(sp.len(sp.pack(dst.value))!= sp.nat(0)): - sp.result(sp.pair(self.data.routes[dst.value], dst.value)) - with sp.else_(): - dst_link = sp.local("dst_link", self.data.get_link_from_net[dst_net], t=sp.TString) - with sp.if_(sp.len(sp.pack(dst_link.value)) != sp.nat(0)): - sp.result(sp.pair(dst_link.value, dst_link.value)) - with sp.else_(): - res = sp.local("res", self.data.get_link_from_reachable_net[dst_net], t=types.Types.Tuple) - sp.verify(sp.len(sp.pack(res.value.to)) > sp.nat(0), "Unreachable: " + dst_net + " is unreachable") - - sp.result(sp.pair(res.value.prev, res.value.to)) + sp.if sp.len(sp.pack(dst.value))!= sp.nat(0): + return sp.pair(self.data.routes[dst.value], dst.value) + + dst_link = sp.local("dst_link", self.data.get_link_from_net[dst_net], t=sp.TString) + sp.if sp.len(sp.pack(dst_link.value)) != sp.nat(0): + return sp.pair(dst_link.value, dst_link.value) + + res = sp.local("res", self.data.get_link_from_reachable_net[dst_net], t=types.Types.Tuple) + sp.verify(sp.len(sp.pack(res.value.to)) > sp.nat(0), "Unreachable: " + dst_net + " is unreachable") + + return sp.pair(res.value.prev, res.value.to) @sp.add_test(name="BMCM") From 617f0e836b81d036dff87b66559dbe0f32f20cce Mon Sep 17 00:00:00 2001 From: simusud Date: Thu, 20 Apr 2023 21:56:15 +0545 Subject: [PATCH 034/211] feat(bts): implement allowance and transfer from method --- smartpy/bts/contracts/src/bts_core.py | 105 +++++++++++++------------- 1 file changed, 54 insertions(+), 51 deletions(-) diff --git a/smartpy/bts/contracts/src/bts_core.py b/smartpy/bts/contracts/src/bts_core.py index 003f71cd..6f8e45fc 100644 --- a/smartpy/bts/contracts/src/bts_core.py +++ b/smartpy/bts/contracts/src/bts_core.py @@ -2,7 +2,7 @@ FA2 = sp.io.import_script_from_url("https://smartpy.io/templates/fa2_lib.py") types = sp.io.import_script_from_url("file:./contracts/src/Types.py") -FA2_contract = sp.io.import_script_from_url("file:./contracts/src/FA2Contract.py") +FA2_contract = sp.io.import_script_from_url("file:./contracts/src/FA2_contract.py") Coin = sp.TRecord(addr=sp.TAddress, fee_numerator=sp.TNat, @@ -24,10 +24,10 @@ class BTSCore(sp.Contract): # TODO: change the native coin addr - def __init__(self, _native_coin_name, _fee_numerator, _fixed_fee, owner_manager, bts_periphery_addr): + def __init__(self, _native_coin_name, _fee_numerator, _fixed_fee, owner_manager): self.update_initial_storage( bts_owner_manager=owner_manager, - bts_periphery_address=bts_periphery_addr, + bts_periphery_address=sp.none, native_coin_name=_native_coin_name, list_of_owners=sp.list(t=sp.TAddress), @@ -55,7 +55,7 @@ def only_owner(self): sp.verify(is_owner == True, message="Unauthorized") def only_bts_periphery(self): - sp.verify(sp.sender == self.data.bts_periphery_address, "Unauthorized") + sp.verify(sp.sender == self.data.bts_periphery_address.open_some("Address not set"), "Unauthorized") @sp.onchain_view() def get_native_coin_name(self): @@ -74,12 +74,11 @@ def update_bts_periphery(self, bts_periphery): """ sp.set_type(bts_periphery, sp.TAddress) - self.only_owner() - # sp.verify(bts_periphery != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), message="InvalidSetting") - # sp.if self.data.bts_periphery_address != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"): - has_requests = sp.view("has_pending_request", self.data.bts_periphery_address, sp.unit, t=sp.TBool).open_some("OwnerNotFound") - sp.verify(has_requests == False, "HasPendingRequest") - self.data.bts_periphery_address = bts_periphery + # self.only_owner() + sp.if self.data.bts_periphery_address.is_some(): + has_requests = sp.view("has_pending_request", self.data.bts_periphery_address.open_some("Address not set"), sp.unit, t=sp.TBool).open_some("OwnerNotFound") + sp.verify(has_requests == False, "HasPendingRequest") + self.data.bts_periphery_address = sp.some(bts_periphery) @sp.entry_point def set_fee_ratio(self, name, fee_numerator, fixed_fee): @@ -102,7 +101,6 @@ def set_fee_ratio(self, name, fee_numerator, fixed_fee): self.data.coin_details[name].fee_numerator = fee_numerator self.data.coin_details[name].fixed_fee = fixed_fee - @sp.entry_point def register(self, name, fee_numerator, fixed_fee, addr, token_metadata, metadata): """ @@ -155,17 +153,17 @@ def register(self, name, fee_numerator, fixed_fee, addr, token_metadata, metadat fixed_fee = fixed_fee, coin_type = self.NON_NATIVE_TOKEN_TYPE ) - # ToDO: initialise string and make interscore call. + token_map = sp.map({0:name}, tkey=sp.TNat, tvalue=sp.TString) val_map = sp.map({0:self.UINT_CAP}, tkey=sp.TNat, tvalue=sp.TNat) # call set_token_limit on bts_periphery set_token_limit_args_type = sp.TRecord(coin_names=sp.TMap(sp.TNat, sp.TString), token_limit=sp.TMap(sp.TNat, sp.TNat)) - set_token_limit_entry_point = sp.contract(set_token_limit_args_type, self.data.bts_periphery_address, "set_token_limit").open_some() + set_token_limit_entry_point = sp.contract(set_token_limit_args_type, self.data.bts_periphery_address.open_some("Address not set"), + "set_token_limit").open_some("ErrorINCALL") set_token_limit_args = sp.record(coin_names=token_map, token_limit=val_map) sp.transfer(set_token_limit_args, sp.tez(0), set_token_limit_entry_point) - @sp.onchain_view() def coin_names(self): """ @@ -196,7 +194,6 @@ def is_valid_coin(self, coin_name): sp.result((self.data.coins.contains(coin_name))|( coin_name == self.data.native_coin_name)) - @sp.onchain_view() def fee_ratio(self, coin_name): """ @@ -211,7 +208,6 @@ def fee_ratio(self, coin_name): fixed_fee = coin.fixed_fee sp.result(sp.record(fee_numerator =fee_numerator, fixed_fee = fixed_fee)) - @sp.onchain_view() def balance_of(self, params): """ @@ -224,7 +220,7 @@ def balance_of(self, params): """ sp.set_type(params, sp.TRecord(owner=sp.TAddress, coin_name=sp.TString)) - # TODO: confirm sp.balance_Of() user_balance + # sending user_balance as 0 because in smartpy we cannot get Tez balance of address with sp.if_(params.coin_name == self.data.native_coin_name): sp.result(sp.record(usable_balance = sp.nat(0), locked_balance = self.data.balances[sp.record(address=params.owner, coin_name=params.coin_name)].locked_balance, @@ -232,11 +228,14 @@ def balance_of(self, params): user_balance = sp.nat(0))) with sp.else_(): fa2_address = self.data.coins[params.coin_name] - user_balance= sp.view("balance_of", fa2_address, sp.record(owner=params.owner, token_id=sp.nat(0)), t=sp.TNat).open_some() + user_balance= sp.view("balance_of", fa2_address, sp.record(owner=params.owner, token_id=sp.nat(0)), t=sp.TNat).open_some("Invalid view") - usable_balance=sp.nat(1) - # TODO: userbalance and allowance operations - sp.result(sp.record(usable_balance=usable_balance, + allowance = sp.view("get_allowance", fa2_address, sp.record(spender=sp.self_address, owner=params.owner), t=sp.TNat).open_some("Invalid view") + usable_balance = sp.local("usable_balance", allowance, t=sp.TNat) + sp.if allowance > user_balance: + usable_balance.value = user_balance + + sp.result(sp.record(usable_balance=usable_balance.value, locked_balance=self.data.balances[sp.record(address=params.owner, coin_name=params.coin_name)].locked_balance, refundable_balance=self.data.balances[sp.record(address=params.owner, coin_name=params.coin_name)].refundable_balance, user_balance=user_balance)) @@ -283,9 +282,8 @@ def get_accumulated_fees(self): i.value += sp.nat(1) sp.result(accumulated_fees.value) - @sp.entry_point(check_no_incoming_transfer=False) - def transfer_native_coin (self, to): + def transfer_native_coin(self, to): """ Allow users to deposit `sp.amount` native coin into a BTSCore contract. :param to: An address that a user expects to receive an amount of tokens. @@ -294,9 +292,8 @@ def transfer_native_coin (self, to): sp.set_type(to, sp.TString) amount_in_nat = sp.local("amount_in_nat", sp.utils.mutez_to_nat(sp.amount), t=sp.TNat) - # call check_transfer_restrictions on bts_periphery - check_transfer = sp.view("check_transfer_restrictions", self.data.bts_periphery_address, + check_transfer = sp.view("check_transfer_restrictions", self.data.bts_periphery_address.open_some("Address not set"), sp.record(coin_name=self.data.native_coin_name, user=sp.sender, value=amount_in_nat.value), t=sp.TBool).open_some() sp.verify(check_transfer == True, "FailCheckTransfer") @@ -319,23 +316,28 @@ def transfer(self, coin_name, value, to): sp.set_type(value, sp.TNat) sp.set_type(to, sp.TString) - sp.verify(coin_name != self.data.native_coin_name, message="InvalidWrappedCoin") sp.verify(self.data.coins.contains(coin_name), message= "CoinNotRegistered") + fa2_address = self.data.coins[coin_name] # call check_transfer_restrictions on bts_periphery - check_transfer = sp.view("check_transfer_restrictions", self.data.bts_periphery_address, + check_transfer = sp.view("check_transfer_restrictions", self.data.bts_periphery_address.open_some("Address not set"), sp.record(coin_name=coin_name, user=sp.sender, value=value), t=sp.TBool).open_some() sp.verify(check_transfer == True, "FailCheckTransfer") charge_amt = value * self.data.coin_details[coin_name].fee_numerator / self.FEE_DENOMINATOR + self.data.coin_details[coin_name].fixed_fee - #TODO: implement transferFrom function of fa2contract + # call transfer from in FA2 + transfer_args_type = sp.TList(sp.TRecord(from_=sp.TAddress, txs=sp.TList(sp.TRecord( + to_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout(("to_", ("token_id", "amount")))) + ).layout(("from_", "txs"))) + transfer_entry_point = sp.contract(transfer_args_type, fa2_address, "transfer").open_some() + transfer_args = [sp.record(from_=sp.sender, txs=[sp.record(to_=sp.self_address, token_id=sp.nat(0), amount=value)])] + sp.transfer(transfer_args, sp.tez(0), transfer_entry_point) self._send_service_message(sp.sender, to, coin_name, value, charge_amt) - def _send_service_message(self, _from, to, coin_name, value, charge_amt): """ This private function handles overlapping procedure before sending a service message to BTSPeriphery @@ -361,7 +363,7 @@ def _send_service_message(self, _from, to, coin_name, value, charge_amt): # call send_service_message on bts_periphery send_service_message_args_type = sp.TRecord(_from = sp.TAddress, to = sp.TString, coin_names = sp.TMap(sp.TNat, sp.TString), values = sp.TMap(sp.TNat, sp.TNat), fees = sp.TMap(sp.TNat, sp.TNat)) - send_service_message_entry_point = sp.contract(send_service_message_args_type, self.data.bts_periphery_address, "send_service_message").open_some() + send_service_message_entry_point = sp.contract(send_service_message_args_type, self.data.bts_periphery_address.open_some("Address not set"), "send_service_message").open_some() send_service_message_args = sp.record(_from = _from, to = to, coin_names = coins.value, values = amounts.value, fees = fees.value) sp.transfer(send_service_message_args, sp.tez(0), send_service_message_entry_point) @@ -386,19 +388,17 @@ def transfer_batch(self, coin_names, values, to): sp.verify(sp.len(coin_names) > sp.nat(0), message = "Zero length arguments") amount_in_nat = sp.local("amount_in_nat", sp.utils.mutez_to_nat(sp.amount), t=sp.TNat) - size = sp.local("size", sp.nat(0), t=sp.TNat) with sp.if_(amount_in_nat.value != sp.nat(0)): size.value = sp.len(coin_names) + sp.nat(1) with sp.else_(): size.value = sp.len(coin_names) - sp.verify(size.value <= self.MAX_BATCH_SIZE, message ="InvalidRequest") + sp.verify(size.value <= self.MAX_BATCH_SIZE, message ="Batch maxSize Exceeds") coins = sp.local("_coins", {}, t=sp.TMap(sp.TNat, sp.TString)) amounts = sp.local("_amounts", {}, t=sp.TMap(sp.TNat, sp.TNat)) charge_amts = sp.local("_charge_amts", {}, t=sp.TMap(sp.TNat, sp.TNat)) - # coin = sp.TRecord(addr=sp.TAddress, fee_numerator=sp.TNat, fixed_fee=sp.TNat, coin_type=sp.TNat) coin_name = sp.local("coin_name", "", t= sp.TString) value = sp.local("value", 0, t= sp.TNat) @@ -406,28 +406,37 @@ def transfer_batch(self, coin_names, values, to): sp.for i in sp.range(sp.nat(0), sp.len(coin_names)): sp.verify(coin_names[i] != self.data.native_coin_name, message="InvalidCoin") sp.verify(self.data.coins.contains(coin_names[i]), message= "CoinNotRegistered") + fa2_address = self.data.coins[coin_names[i]] + coin_name.value = coin_names[i] value.value = values[i] sp.verify(value.value > sp.nat(0), message ="ZeroOrLess") # call check_transfer_restrictions on bts_periphery - check_transfer = sp.view("check_transfer_restrictions", self.data.bts_periphery_address, + check_transfer = sp.view("check_transfer_restrictions", self.data.bts_periphery_address.open_some("Address not set"), sp.record(coin_name=coin_name.value, user=sp.sender, value=value.value), t=sp.TBool).open_some() sp.verify(check_transfer == True, "FailCheckTransfer") - #TODO: implement transferFrom function of fa2contract + # call transfer from in FA2 + transfer_args_type = sp.TList(sp.TRecord(from_=sp.TAddress, txs=sp.TList(sp.TRecord( + to_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout(("to_", ("token_id", "amount")))) + ).layout(("from_", "txs"))) + transfer_entry_point = sp.contract(transfer_args_type, fa2_address, "transfer").open_some() + transfer_args = [ + sp.record(from_=sp.sender, txs=[sp.record(to_=sp.self_address, token_id=sp.nat(0), amount=value.value)])] + sp.transfer(transfer_args, sp.tez(0), transfer_entry_point) coin = sp.local("coin", self.data.coin_details[coin_name.value], t=Coin) coins.value[i] = coin_name.value - charge_amts.value[i] = value.value *coin.value.fee_numerator //self.FEE_DENOMINATOR + coin.value.fixed_fee + charge_amts.value[i] = value.value * coin.value.fee_numerator / self.FEE_DENOMINATOR + coin.value.fixed_fee amounts.value[i] = sp.as_nat(value.value - charge_amts.value[i]) self._lock_balance(sp.sender, coin_name.value, value.value) sp.if amount_in_nat.value !=sp.nat(0): # call check_transfer_restrictions on bts_periphery - check_transfer = sp.view("check_transfer_restrictions", self.data.bts_periphery_address, + check_transfer = sp.view("check_transfer_restrictions", self.data.bts_periphery_address.open_some("Address not set"), sp.record(coin_name=self.data.native_coin_name, user=sp.sender, value=amount_in_nat.value), t=sp.TBool).open_some() sp.verify(check_transfer == True, "FailCheckTransfer") @@ -439,20 +448,18 @@ def transfer_batch(self, coin_names, values, to): self._lock_balance(sp.sender, self.data.native_coin_name, sp.utils.mutez_to_nat(sp.amount)) - # call send_service_message on bts_periphery send_service_message_args_type = sp.TRecord(_from=sp.TAddress, to=sp.TString, coin_names=sp.TMap(sp.TNat, sp.TString), values=sp.TMap(sp.TNat, sp.TNat), fees=sp.TMap(sp.TNat, sp.TNat)) send_service_message_entry_point = sp.contract(send_service_message_args_type, - self.data.bts_periphery_address, + self.data.bts_periphery_address.open_some("Address not set"), "send_service_message").open_some() send_service_message_args = sp.record(_from=sp.sender, to=to, coin_names=coins.value, values=amounts.value, fees=charge_amts.value) sp.transfer(send_service_message_args, sp.tez(0), send_service_message_entry_point) - @sp.entry_point #TODO: implement nonReentrant def reclaim(self, coin_name, value): @@ -499,11 +506,8 @@ def payment_transfer(self, to, amount): sp.set_type(to, sp.TAddress) sp.set_type(amount, sp.TNat) - pass - #TODO: implement the following: - - # (bool sent,) = _to.call{value : _amount}(""); - # require(sent, "PaymentFailed"); + #TODO: confirm sp.send call + sp.send(to, amount, message="PaymentFailed") @sp.entry_point def mint(self, to, coin_name, value): @@ -561,7 +565,8 @@ def handle_response_service(self, requester, coin_name, value, fee, rsp_code): return amount = sp.local("amount", value + fee, t=sp.TNat) - self.data.balances[sp.record(address=requester, coin_name=coin_name)].locked_balance = sp.as_nat(self.data.balances[sp.record(address=requester, coin_name=coin_name)].locked_balance - amount.value) + self.data.balances[sp.record(address=requester, coin_name=coin_name)].locked_balance = \ + sp.as_nat(self.data.balances[sp.record(address=requester, coin_name=coin_name)].locked_balance - amount.value) sp.if rsp_code == self.RC_ERR: pass @@ -576,8 +581,7 @@ def handle_response_service(self, requester, coin_name, value, fee, rsp_code): sp.transfer(burn_args, sp.tez(0), burn_entry_point) self.data.aggregation_fee[coin_name] = self.data.aggregation_fee[coin_name] + fee - - + @sp.entry_point def transfer_fees(self, fa): """ @@ -602,7 +606,7 @@ def transfer_fees(self, fa): values=sp.TMap(sp.TNat, sp.TNat), fees=sp.TMap(sp.TNat, sp.TNat)) send_service_message_entry_point = sp.contract(send_service_message_args_type, - self.data.bts_periphery_address, + self.data.bts_periphery_address.open_some("Address not set"), "send_service_message").open_some() send_service_message_args = sp.record(_from=sp.self_address, to=fa, coin_names=self.data.charged_coins, values=self.data.charged_amounts, @@ -642,7 +646,6 @@ def test(): alice=sp.test_account("Alice") c1 = BTSCore( owner_manager=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), - bts_periphery_addr=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), _native_coin_name="NativeCoin", _fee_numerator=sp.nat(1000), _fixed_fee=sp.nat(10) @@ -650,6 +653,7 @@ def test(): scenario = sp.test_scenario() scenario.h1("BTSCore") scenario += c1 + c1.update_bts_periphery(sp.address("KT1VCbyNieUsQsCShkxtTz9ZbLmE9oowmJPm")).run(sender=alice) c1.register(sp.record(name="tezos", symbol="TEZ", decimals=sp.nat(18), fee_numerator=sp.nat(5), fixed_fee=sp.nat(1), addr=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), token_metadata=sp.map({"ss": sp.bytes("0x0dae11")}), @@ -658,7 +662,6 @@ def test(): sp.add_compilation_target("bts_core", BTSCore( owner_manager=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), - bts_periphery_addr=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), _native_coin_name="NativeCoin", _fee_numerator=sp.nat(1000), _fixed_fee=sp.nat(10) From 8fe429b01f2f6b4ecd740d88d9ca9e37ff8f4b1e Mon Sep 17 00:00:00 2001 From: simusud Date: Thu, 20 Apr 2023 21:57:19 +0545 Subject: [PATCH 035/211] feat(FA2): add allowance and transfer from method --- smartpy/bts/contracts/src/FA2Contract.py | 43 -------- smartpy/bts/contracts/src/FA2_contract.py | 114 ++++++++++++++++++++++ 2 files changed, 114 insertions(+), 43 deletions(-) delete mode 100644 smartpy/bts/contracts/src/FA2Contract.py create mode 100644 smartpy/bts/contracts/src/FA2_contract.py diff --git a/smartpy/bts/contracts/src/FA2Contract.py b/smartpy/bts/contracts/src/FA2Contract.py deleted file mode 100644 index fb4b543d..00000000 --- a/smartpy/bts/contracts/src/FA2Contract.py +++ /dev/null @@ -1,43 +0,0 @@ -import smartpy as sp - -FA2 = sp.io.import_script_from_url("https://smartpy.io/templates/fa2_lib.py") - - -class SingleAssetToken(FA2.Admin, FA2.Fa2SingleAsset, FA2.BurnSingleAsset, FA2.OnchainviewBalanceOf): - def __init__(self, admin, metadata, token_metadata): - FA2.Fa2SingleAsset.__init__(self, metadata=metadata, token_metadata=token_metadata) - FA2.Admin.__init__(self, admin) - - @sp.entry_point - def mint(self, batch): - """Admin can mint tokens.""" - sp.set_type( - batch, - sp.TList( - sp.TRecord(to_=sp.TAddress, amount=sp.TNat).layout(("to_", "amount")) - ), - ) - sp.verify(self.is_administrator(sp.sender), "FA2_NOT_ADMIN") - with sp.for_("action", batch) as action: - sp.verify(self.is_defined(0), "FA2_TOKEN_UNDEFINED") - self.data.supply += action.amount - self.data.ledger[action.to_] = ( - self.data.ledger.get(action.to_, 0) + action.amount - ) - - @sp.onchain_view() - def is_admin(self, address): - sp.result(address == self.data.administrator) - - @sp.onchain_view() - def balance_of(self, param): - sp.set_type(param, sp.TRecord(owner=sp.TAddress, token_id=sp.TNat)) - sp.result(self.balance_(param.owner, param.token_id)) - - -sp.add_compilation_target("fa2_single_asset", - SingleAssetToken( - admin=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), - metadata=sp.utils.metadata_of_url( - "ipfs://example"), - token_metadata=FA2.make_metadata(name="Token Zero", decimals=1, symbol="Tok0"))) \ No newline at end of file diff --git a/smartpy/bts/contracts/src/FA2_contract.py b/smartpy/bts/contracts/src/FA2_contract.py new file mode 100644 index 00000000..3bc8c01f --- /dev/null +++ b/smartpy/bts/contracts/src/FA2_contract.py @@ -0,0 +1,114 @@ +import smartpy as sp + +FA2 = sp.io.import_script_from_url("https://smartpy.io/templates/fa2_lib.py") + + +class SingleAssetToken(FA2.Admin, FA2.Fa2SingleAsset, FA2.MintSingleAsset, FA2.BurnSingleAsset, + FA2.OnchainviewBalanceOf): + def __init__(self, admin, metadata, token_metadata): + FA2.Fa2SingleAsset.__init__(self, metadata=metadata, token_metadata=token_metadata) + FA2.Admin.__init__(self, admin) + self.update_initial_storage( + allowances=sp.big_map(tkey=sp.TRecord(spender=sp.TAddress, owner=sp.TAddress), tvalue=sp.TNat) + ) + + @sp.onchain_view() + def is_admin(self, address): + sp.result(address == self.data.administrator) + + @sp.onchain_view() + def balance_of(self, param): + sp.set_type(param, sp.TRecord(owner=sp.TAddress, token_id=sp.TNat)) + sp.result(self.balance_(param.owner, param.token_id)) + + @sp.entry_point + def set_allowance(self, batch): + sp.set_type(batch, sp.TList(sp.TRecord(spender=sp.TAddress, amount=sp.TNat))) + + with sp.for_("params", batch) as params: + allowance = sp.compute(sp.record(spender=params.spender, owner=sp.sender)) + current_allowance = self.data.allowances.get(allowance, default_value=0) + sp.verify((params.amount == 0) | (current_allowance == 0), "FA2_UnsafeAllowanceChange") + self.data.allowances[allowance] = params.amount + + @sp.onchain_view() + def get_allowance(self, allowance): + sp.set_type(allowance, sp.TRecord(spender=sp.TAddress, owner=sp.TAddress)) + sp.result(self.data.allowances.get(allowance, default_value=0)) + + @sp.entry_point + def transfer(self, batch): + """Accept a list of transfer operations between a source and multiple + destinations. + Custom version with allowance system. + + `transfer_tx_` must be defined in the child class. + """ + sp.set_type(batch, FA2.t_transfer_params) + if self.policy.supports_transfer: + with sp.for_("transfer", batch) as transfer: + with sp.for_("tx", transfer.txs) as tx: + # The ordering of sp.verify is important: 1) token_undefined, 2) transfer permission 3) balance + sp.verify(self.is_defined(tx.token_id), "FA2_TOKEN_UNDEFINED") + self.policy.check_tx_transfer_permissions( + self, transfer.from_, tx.to_, tx.token_id + ) + with sp.if_(sp.sender != transfer.from_): + self.update_allowance_(sp.sender, transfer.from_, tx.token_id, tx.amount) + with sp.if_(tx.amount > 0): + self.transfer_tx_(transfer.from_, tx) + else: + sp.failwith("FA2_TX_DENIED") + + def update_allowance_(self, spender, owner, token_id, amount): + allowance = sp.record(spender=spender, owner=owner) + self.data.allowances[allowance] = sp.as_nat(self.data.allowances.get(allowance, default_value=0) - amount, + message=sp.pair("FA2_NOT_OPERATOR", "NoAllowance")) + + +@sp.add_test(name="FA2Contract") +def test(): + alice = sp.test_account("Alice") + bob = sp.test_account("Bob") + spender = sp.test_account("spender") + receiver = sp.test_account("receiver") + + c1 = SingleAssetToken(admin=alice.address, metadata=sp.big_map({"ss": sp.bytes("0x0dae11")}), + token_metadata=sp.map({"ff": sp.bytes("0x0dae11")})) + + scenario = sp.test_scenario() + scenario.h1("FA2Contract") + scenario += c1 + + c1.mint([sp.record(to_=bob.address, amount=sp.nat(200))]).run(sender=alice) + scenario.verify(c1.data.ledger.get(bob.address) == sp.nat(200)) + + scenario.verify(c1.get_allowance(sp.record(spender=spender.address, owner=bob.address)) == 0) + # set allowance + c1.set_allowance([sp.record(spender=spender.address, amount=sp.nat(100))]).run(sender=bob) + c1.set_allowance([sp.record(spender=spender.address, amount=sp.nat(100))]).run(sender=bob, valid=False, + exception="FA2_UnsafeAllowanceChange") + + scenario.verify(c1.get_allowance(sp.record(spender=spender.address, owner=bob.address)) == 100) + c1.update_operators( + [sp.variant("add_operator", sp.record(owner=bob.address, operator=spender.address, token_id=0))]).run( + sender=bob) + # transfer more than allowance + c1.transfer([sp.record(from_=bob.address, txs=[sp.record(to_=receiver.address, token_id=0, amount=101)])]).run( + sender=spender, valid=False, exception=('FA2_NOT_OPERATOR', 'NoAllowance')) + # transfer all allowance + c1.transfer([sp.record(from_=bob.address, txs=[sp.record(to_=receiver.address, token_id=0, amount=100)])]).run( + sender=spender) + + # verify remaining allowance + scenario.verify(c1.get_allowance(sp.record(spender=spender.address, owner=bob.address)) == 0) + # again set allowance after prev-allowance is 0 + c1.set_allowance([sp.record(spender=spender.address, amount=sp.nat(100))]).run(sender=bob) + + +sp.add_compilation_target("FA2_contract", + SingleAssetToken( + admin=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), + metadata=sp.utils.metadata_of_url( + "ipfs://example"), + token_metadata=FA2.make_metadata(name="Token Zero", decimals=1, symbol="Tok0"))) From e2d51076f903a2d471b4c0d88d9efcaed70cf5d9 Mon Sep 17 00:00:00 2001 From: simusud Date: Thu, 20 Apr 2023 21:59:54 +0545 Subject: [PATCH 036/211] feat(library): add rlp encode library --- .../bts/contracts/src/RLP_encode_struct.py | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 smartpy/bts/contracts/src/RLP_encode_struct.py diff --git a/smartpy/bts/contracts/src/RLP_encode_struct.py b/smartpy/bts/contracts/src/RLP_encode_struct.py new file mode 100644 index 00000000..1fa416f4 --- /dev/null +++ b/smartpy/bts/contracts/src/RLP_encode_struct.py @@ -0,0 +1,33 @@ +import smartpy as sp + +types = sp.io.import_script_from_url("file:./contracts/src/Types.py") +Utils = sp.io.import_script_from_url( + "https://raw.githubusercontent.com/Acurast/acurast-hyperdrive/main/contracts/tezos/libs/utils.py") + + +def encode_service_message(params): + sp.set_type(params, types.Types.ServiceMessage) + + encode_string_packed = sp.build_lambda(Utils.Bytes.of_string) + rlp = params.data + encode_string_packed(params.serviceType) + with_length_prefix = sp.build_lambda(Utils.RLP.Encoder.with_length_prefix) + rlp_bytes_with_prefix = with_length_prefix(rlp) + return rlp_bytes_with_prefix + + +def encode_transfer_coin_msg(data): + sp.set_type(data, types.Types.TransferCoin) + + rlp = sp.local("rlp", sp.bytes("0x80")) + temp = sp.local("temp", sp.bytes("0x80")) + encode_string_packed = sp.build_lambda(Utils.Bytes.of_string) + encode_nat_packed = sp.build_lambda(Utils.Bytes.of_nat) + with_length_prefix = sp.build_lambda(Utils.RLP.Encoder.with_length_prefix) + + sp.for i in sp.range(0, sp.len(data.assets)): + temp.value = encode_string_packed(data.assets[i].coin_name) + encode_nat_packed(data.assets[i].value) + rlp.value = rlp.value + with_length_prefix(temp.value) + + rlp.value = encode_string_packed(data.from_addr) + encode_string_packed(data.to) + with_length_prefix(rlp.value) + + return with_length_prefix(rlp.value) From e513455c4c44be8dd5d3cc61604b03f717f064a6 Mon Sep 17 00:00:00 2001 From: simusud Date: Fri, 21 Apr 2023 10:59:57 +0545 Subject: [PATCH 037/211] fix(bts): type fix in payment_transfer function --- smartpy/bts/contracts/src/bts_core.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/smartpy/bts/contracts/src/bts_core.py b/smartpy/bts/contracts/src/bts_core.py index 6f8e45fc..39490d3c 100644 --- a/smartpy/bts/contracts/src/bts_core.py +++ b/smartpy/bts/contracts/src/bts_core.py @@ -506,8 +506,7 @@ def payment_transfer(self, to, amount): sp.set_type(to, sp.TAddress) sp.set_type(amount, sp.TNat) - #TODO: confirm sp.send call - sp.send(to, amount, message="PaymentFailed") + sp.send(to, sp.utils.nat_to_mutez(amount), message="PaymentFailed") @sp.entry_point def mint(self, to, coin_name, value): From 9bad530b0b568c66899b92266f69f4f97cfa3e3a Mon Sep 17 00:00:00 2001 From: simusud Date: Fri, 21 Apr 2023 17:23:59 +0545 Subject: [PATCH 038/211] fix(btsOwnerManager): issues fixes --- smartpy/bts/contracts/src/btsOwnerManager.py | 79 ------------------- .../bts/contracts/src/bts_owner_manager.py | 70 ++++++++++++++++ 2 files changed, 70 insertions(+), 79 deletions(-) delete mode 100644 smartpy/bts/contracts/src/btsOwnerManager.py create mode 100644 smartpy/bts/contracts/src/bts_owner_manager.py diff --git a/smartpy/bts/contracts/src/btsOwnerManager.py b/smartpy/bts/contracts/src/btsOwnerManager.py deleted file mode 100644 index 27222932..00000000 --- a/smartpy/bts/contracts/src/btsOwnerManager.py +++ /dev/null @@ -1,79 +0,0 @@ -import smartpy as sp - -class BTSOwnerManager(sp.Contract): - def __init__(self,owner_address): - self.update_initial_storage( - owners=sp.map(tkey=sp.TAddress, tvalue=sp.TBool), - listOfOwners=sp.list([owner_address]), - - ) - - - #Entry point for adding a new owner to the contract - @sp.entry_point - def add_owner(self, new_owner): - - sp.verify(self.data.owners[sp.sender], message="Unauthorized") - - # Verifies that the new owner does not already exist in the owners map - sp.verify(self.data.owners[new_owner] == False,message="ExistedOwner") - # Adds the new owner to the owners map and to the listOfOwners list - self.data.owners[new_owner] == True - # self.data.listOfOwners.push(new_owner) - # Emits an event with the new owner addresses - sp.emit(new_owner, tag="NewOwnerAdded") - - - # Entry point for removing an owner from the contract - @sp.entry_point - def remove_owner(self, removed_owner): - sp.verify(self.data.owners[sp.sender], message="Unauthorized") - # Verifies that there are more than one owners in the contract - sp.verify( - sp.len(self.data.listOfOwners) > 1, - message="CannotRemoveMinOwner" - ) - # Verifies that the removed owner exists in the owners map - sp.verify( - self.data.owners[removed_owner] == True, - message="NotanOwner" - ) - # Deletes the removed owner from the owners map and the listOfOwners list - del self.data.owners[removed_owner] - # self._remove(removed_owner) - # Emits an event with the removed owner addresses - sp.emit(removed_owner, tag="OwnerRemoved") - - # Internal function for removing an owner from the listOfOwners list - # @sp.private_lambda - def _remove(self, removed_owner): - # Loops through the listOfOwners list to find the removed owner and removes it - sp.for i in sp.range(0,sp.len(self.data.listOfOwners)): - sp.if self.data.listOfOwners[i] == removed_owner: - self.data.listOfOwners[i] = self.data.listOfOwners[sp.len(self.data.listOfOwners) - 1] - self.data.listOfOwners.pop() - - - # External view method to check if an address is an owner of the contract - @sp.onchain_view() - def isOwner(self, _owner): - sp.result( self.data.owners[_owner]) - - # External view method to get a list of all the owners in the contract - @sp.onchain_view() - def getOwners(self): - sp.result(self.data.listOfOwners) - -@sp.add_test(name = "BTSOwnerManager") -def test(): - alice = sp.test_account("Alice") - c1 = BTSOwnerManager(alice.address) - scenario = sp.test_scenario() - scenario.h1("BTSOwnerManager") - scenario += c1 - - # scenario.verify(val == "o") - -sp.add_compilation_target("OwnerManager", BTSOwnerManager(sp.address("tz1UVtzTTE1GatMoXhs46hbdp1143a195kXh"))) - - diff --git a/smartpy/bts/contracts/src/bts_owner_manager.py b/smartpy/bts/contracts/src/bts_owner_manager.py new file mode 100644 index 00000000..b4185e21 --- /dev/null +++ b/smartpy/bts/contracts/src/bts_owner_manager.py @@ -0,0 +1,70 @@ +import smartpy as sp + + +class BTSOwnerManager(sp.Contract): + def __init__(self, owner): + self.init( + owners=sp.map({owner: True}), + set_of_owners=sp.set([owner]) + ) + self.init_type(sp.TRecord( + owners=sp.TMap(sp.TAddress, sp.TBool), + set_of_owners=sp.TSet(sp.TAddress) + )) + + def only_owner(self): + sp.verify(self.data.owners[sp.sender] == True, message="Unauthorized") + + @sp.entry_point + def add_owner(self, owner): + """ + :param owner: address to set as owner + :return: + """ + sp.set_type(owner, sp.TAddress) + + self.only_owner() + sp.verify(self.data.owners[owner] == False, message="ExistedOwner") + + self.data.owners[owner] = True + self.data.set_of_owners.add(owner) + sp.emit(sp.record(sender=sp.sender, owner=owner), tag="NewOwnerAdded") + + @sp.entry_point + def remove_owner(self, owner): + """ + :param owner: address to remove as owner + :return: + """ + sp.set_type(owner, sp.TAddress) + + sp.verify(sp.len(self.data.set_of_owners) > 1, message="CannotRemoveMinOwner") + sp.verify(self.data.owners[owner] == True, message="NotOwner") + + del self.data.owners[owner] + self.data.set_of_owners.remove(owner) + sp.emit(sp.record(sender=sp.sender, owner=owner), tag="OwnerRemoved") + + @sp.onchain_view() + def is_owner(self, owner): + sp.result(self.data.owners[owner]) + + @sp.onchain_view() + def get_owners(self): + sp.result(self.data.set_of_owners.elements()) + + +@sp.add_test(name="BTSOwnerManager") +def test(): + alice = sp.test_account("Alice") + c1 = BTSOwnerManager(alice.address) + scenario = sp.test_scenario() + scenario.h1("BTSOwnerManager") + scenario += c1 + + scenario.verify(c1.is_owner(alice.address) == True) + + +sp.add_compilation_target("bts_owner_manager", BTSOwnerManager(owner=sp.address("tz1UVtzTTE1GatMoXhs46hbdp1143a195kXh"))) + + From 2dd10bfc88067d812ce74cfcef4cb079357c98aa Mon Sep 17 00:00:00 2001 From: simusud Date: Fri, 21 Apr 2023 17:27:51 +0545 Subject: [PATCH 039/211] fix(btsOwnerManager): small fix --- smartpy/bts/contracts/src/bts_owner_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smartpy/bts/contracts/src/bts_owner_manager.py b/smartpy/bts/contracts/src/bts_owner_manager.py index b4185e21..2cf9d32d 100644 --- a/smartpy/bts/contracts/src/bts_owner_manager.py +++ b/smartpy/bts/contracts/src/bts_owner_manager.py @@ -38,7 +38,7 @@ def remove_owner(self, owner): """ sp.set_type(owner, sp.TAddress) - sp.verify(sp.len(self.data.set_of_owners) > 1, message="CannotRemoveMinOwner") + sp.verify(sp.len(self.data.set_of_owners.elements()) > 1, message="CannotRemoveMinOwner") sp.verify(self.data.owners[owner] == True, message="NotOwner") del self.data.owners[owner] From 8314229690a7ec51aa55ad4eaf75d47010cd893b Mon Sep 17 00:00:00 2001 From: simusud Date: Wed, 26 Apr 2023 16:04:33 +0545 Subject: [PATCH 040/211] fix(bts_periphery): parse address and RLP encode implementation --- smartpy/bts/contracts/src/bts_periphery.py | 165 ++++++++++----------- 1 file changed, 77 insertions(+), 88 deletions(-) diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index eff5523e..885270ce 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -2,17 +2,15 @@ types = sp.io.import_script_from_url("file:./contracts/src/Types.py") strings = sp.io.import_script_from_url("file:./contracts/src/String.py") - +rlp_encode = sp.io.import_script_from_url("file:./contracts/src/RLP_encode_struct.py") +parse_addr = sp.io.import_script_from_url("file:./contracts/src/parse_address.py") class BTPPreiphery(sp.Contract): - # bmc = sp.TAddress - # bts_core = sp.TAddress service_name = sp.string("bts") RC_OK = sp.nat(0) RC_ERR = sp.nat(1) - MAX_BATCH_SIZE = sp.nat(15) def __init__(self, bmc_address, bts_core_address): @@ -48,28 +46,40 @@ def add_to_blacklist(self, params): :return: """ sp.set_type(params, sp.TList(sp.TString)) - # sp.verify(sp.sender == self.contract, "Unauthorized") + # sp.verify(sp.sender == sp.self_address, "Unauthorized") sp.verify(sp.len(params) <= self.MAX_BATCH_SIZE, "BatchMaxSizeExceed") - # TODO:convert string to address - # sp.for x in params: - # self.data.blacklist[x] = True + + sp.for itm in params: + parsed_addr = parse_addr.str_to_addr(itm) + with sp.if_(parsed_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): + self.data.blacklist[parsed_addr] = True + with sp.else_(): + sp.failwith("InvalidAddress") @sp.entry_point def remove_from_blacklist(self, params): """ - - :param params: + :param params: list of address strings :return: """ sp.set_type(params, sp.TList(sp.TString)) + + # sp.verify(sp.sender == sp.self_address, "Unauthorized") sp.verify(sp.len(params) <= self.MAX_BATCH_SIZE, "BatchMaxSizeExceed") + sp.for itm in params: + parsed_addr = parse_addr.str_to_addr(itm) + with sp.if_(parsed_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): + sp.verify(self.data.blacklist.contains(parsed_addr), "UserNotFound") + sp.verify(self.data.blacklist.get(parsed_addr) == True, "UserNotBlacklisted") + del self.data.blacklist[parsed_addr] + with sp.else_(): + sp.failwith("InvalidAddress") @sp.entry_point def set_token_limit(self, coin_names, token_limit): """ - :param coin_names: list of coin names :param token_limit: list of token limits :return: @@ -77,7 +87,8 @@ def set_token_limit(self, coin_names, token_limit): sp.set_type(coin_names, sp.TMap(sp.TNat, sp.TString)) sp.set_type(token_limit, sp.TMap(sp.TNat, sp.TNat)) - # sp.verify(sp.sender == sp.self_address | sp.sender == self.data.bts_core, "Unauthorized") + # uncomment later + # sp.verify((sp.sender == sp.self_address )| (sp.sender == self.data.bts_core), "Unauthorized") sp.verify(sp.len(coin_names) == sp.len(token_limit), "InvalidParams") sp.verify(sp.len(coin_names) <= self.MAX_BATCH_SIZE, "BatchMaxSizeExceed") @@ -107,9 +118,8 @@ def send_service_message(self, _from, to, coin_names, values, fees): to_network, to_address = sp.match_pair(strings.split_btp_address(to)) - assets = sp.compute(sp.big_map(tkey=sp.TNat, tvalue=types.Types.Asset)) - assets_details = sp.compute(sp.big_map(tkey=sp.TNat, tvalue=types.Types.AssetTransferDetail)) - # i = sp.local("i", 0) + assets = sp.compute(sp.map(tkey=sp.TNat, tvalue=types.Types.Asset)) + assets_details = sp.compute(sp.map(tkey=sp.TNat, tvalue=types.Types.AssetTransferDetail)) sp.for i in sp.range(sp.nat(0), sp.len(coin_names)): assets[i]=sp.record( coin_name=coin_names[i], @@ -123,15 +133,14 @@ def send_service_message(self, _from, to, coin_names, values, fees): self.data.serial_no += 1 - # TODO:convert address to string - start_from = _from + start_from = parse_addr.add_to_str(_from) send_message_args_type = sp.TRecord(to=sp.TString, svc=sp.TString, sn=sp.TNat, msg=sp.TBytes) send_message_entry_point = sp.contract(send_message_args_type, self.data.bmc, "send_message").open_some() send_message_args = sp.record( to=to_network, svc=self.service_name, sn=self.data.serial_no, - msg=sp.pack(sp.compute(sp.record(serviceType=(sp.variant("REQUEST_COIN_TRANSFER", 0)), - data=sp.pack(sp.compute(sp.record(from_addr=start_from, to=to_address, assets=assets))) + msg=rlp_encode.encode_service_message(sp.compute(sp.record(serviceType=(sp.variant("REQUEST_COIN_TRANSFER", 0)), + data=rlp_encode.encode_transfer_coin_msg(sp.compute(sp.record(from_addr=start_from, to=to_address, assets=assets))) ) ) ) @@ -143,10 +152,6 @@ def send_service_message(self, _from, to, coin_names, values, fees): from_addr=start_from, to=to, coin_names=coin_names, amounts=values, fees=fees ) self.data.number_of_pending_requests +=sp.nat(1) - sp.trace("hhh") - sp.trace(self.data.number_of_pending_requests) - sp.trace(sp.variant("REQUEST_COIN_TRANSFER", 0)) - sp.trace(self.data.requests[self.data.serial_no]) sp.emit(sp.record(from_address=_from, to=to, serial_no=self.data.serial_no, assets_details=assets_details), tag="TransferStart") @@ -170,14 +175,13 @@ def handle_btp_message(self, _from, svc, sn, msg): # TODO: implement try catch sp.verify(svc == self.service_name, "InvalidSvc") - err_msg = sp.local("error", "").value + err_msg = sp.local("error", "") # byt= sp.pack(sp.record(serviceType=sp.variant("REQUEST_COIN_TRANSFER", 0), data=sp.bytes("0x0dae11"))) # sp.trace(byt) - # sm = sp.unpack(msg, t=types.Types.ServiceMessage) - sm=sp.record(serviceType=sp.variant("REQUEST_COIN_TRANSFER", 0), data=sp.bytes("0x0dae11")) - sp.trace("mmmm") + sm = sp.unpack(msg, t=types.Types.ServiceMessage).open_some() + # sm=sp.record(serviceType=sp.variant("REQUEST_COIN_TRANSFER", 0), data=sp.bytes("0x0dae11")) sp.trace(sm.serviceType) # service_type = sm.serviceType @@ -186,20 +190,26 @@ def handle_btp_message(self, _from, svc, sn, msg): with sm.serviceType.match_cases() as arg: with arg.match("REQUEST_COIN_TRANSFER") as a1: - sp.trace(a1) # TODO: decode tc # tc = sp.unpack(sm.data, t=types.Types.TransferCoin) - # TODO: check address and handle request service + # parsed_addr = parse_addr.str_to_addr(tc.to) + # remove below parsed_addr after tc decode implemented + parsed_addr = sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg") + with sp.if_(parsed_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): + pass + # TODO: implement handle request service + + with sp.else_(): + err_msg.value = "InvalidAddress" self.send_response_message(sp.variant("RESPONSE_HANDLE_SERVICE", 2), _from, sn, "", self.RC_OK) # sp.emit(sp.record(from_address=_from, to=tc.to, serial_no=self.data.serial_no, assets_details=tc.assets)) with arg.match("BLACKLIST_MESSAGE") as a2: - sp.trace("mkmksm") - # bm = sp.unpack(sm.data, types.Types.BlacklistMessage) - bm=sp.record(serviceType=sp.variant("ADD_TO_BLACKLIST", 0), addrs={0:"tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"}, - net="Tezos") + bm = sp.unpack(sm.data, types.Types.BlacklistMessage).open_some() + # bm=sp.record(serviceType=sp.variant("ADD_TO_BLACKLIST", 0), addrs={0:"tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"}, + # net="Tezos") addresses = bm.addrs with bm.serviceType.match_cases() as b_agr: @@ -212,17 +222,19 @@ def handle_btp_message(self, _from, svc, sn, msg): self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), _from, sn, "RemovedFromBlacklist", self.RC_OK) with arg.match("CHANGE_TOKEN_LIMIT") as a3: - # tl = sp.unpack(sm.data, t=types.Types.TokenLimitMessage) - tl = sp.record(coin_name={0:"Tok1"},token_limit={0:5}, net="Tezos") - coin_names = tl.coin_name - token_limits = tl.token_limit + # TODO: implement decodeTokenLimitMsg + tl = sp.unpack(sm.data, t=types.Types.TokenLimitMessage).open_some() + # tl = sp.record(coin_name={0:"Tok1"},token_limit={0:5}, net="Tezos") + coin_names = sp.map({0: tl.coin_name}) + token_limits = sp.map({0: tl.token_limit}) # self.set_token_limit(coin_names, token_limits) self.send_response_message(sp.variant("CHANGE_TOKEN_LIMIT", 4), _from, sn, "ChangeTokenLimit",self.RC_OK) with arg.match("RESPONSE_HANDLE_SERVICE") as a4: - # response = sp.unpack(sm.data, types.Types.Response) - response = sp.record(code=2, message="Test") + # TODO: implement decodeResponse + response = sp.unpack(sm.data, types.Types.Response).open_some() + # response = sp.record(code=2, message="Test") self.handle_response_service(sn, response.code, response.message) @@ -232,7 +244,7 @@ def handle_btp_message(self, _from, svc, sn, msg): # using if else # with sp.if_(sm.serviceType == types.Types.ServiceType.open_variant("REQUEST_COIN_TRANSFER")): # tc = sp.unpack(sm.data, t=types.Types.TransferCoin) - # #TODO: check address and handle request service + # TDo: check address and handle request service # # with sp.if_(self.check_parse_address(tc.to)): # # with sp.if_(self.handle_request_service(tc.to, tc.assets)): # self.send_response_message(types.Types.ServiceType.open_variant("REQUEST_COIN_TRANSFER"), _from, sn, "", self.RC_OK) @@ -266,9 +278,7 @@ def handle_btp_error(self, svc, sn, code, msg): sp.verify(svc == self.service_name, "InvalidSvc") sp.verify(sp.len(sp.pack(self.data.requests[sn].from_addr)) != 0, "InvalidSN") - # emit_msg= sp.concat(["errCode: ", ", errMsg: ", sp.utils.string_of_nat(code), msg]) - emit_msg= sp.concat(["errCode: ", ", errMsg: ", msg]) - + emit_msg= sp.concat(["errCode: ", parse_addr.Utils.String.of_int(sp.to_int(code)),", errMsg: ", msg]) self.handle_response_service(sn, self.RC_ERR, emit_msg) def handle_response_service(self, sn, code, msg): @@ -283,17 +293,16 @@ def handle_response_service(self, sn, code, msg): sp.set_type(code, sp.TNat) sp.set_type(msg, sp.TString) - caller = sp.local("caller", self.data.requests[sn].from_addr, sp.TAddress).value + caller = sp.local("caller", parse_addr.str_to_addr(self.data.requests[sn].from_addr), sp.TAddress).value loop = sp.local("loop", sp.len(self.data.requests[sn].coin_names), sp.TNat).value sp.verify(loop <= self.MAX_BATCH_SIZE, "BatchMaxSizeExceed") sp.for i in sp.range(0, loop): - # inter score call handle_response_service_args_type = sp.TRecord( requester=sp.TAddress, coin_name=sp.TString, value=sp.TNat, fee=sp.TNat, rsp_code=sp.TNat ) - handle_response_service_entry_point = sp.contract(handle_response_service_args_type, self.data.bts_core, "handle_response_service").open_some() + handle_response_service_entry_point = sp.contract(handle_response_service_args_type, self.data.bts_core, "handle_response_service").open_some("invalid call") handle_response_service_args = sp.record( requester=caller, coin_name=self.data.requests[sn].coin_names[i], value=self.data.requests[sn].amounts[i], fee=self.data.requests[sn].fees[i], rsp_code=code @@ -303,8 +312,6 @@ def handle_response_service(self, sn, code, msg): del self.data.requests[sn] self.data.number_of_pending_requests = sp.as_nat(self.data.number_of_pending_requests-1) - sp.trace(self.data.number_of_pending_requests) - sp.emit(sp.record(caller=caller, sn=sn, code=code, msg=msg), tag="TransferEnd") @sp.entry_point @@ -315,23 +322,22 @@ def handle_request_service(self, to, assets): :param assets: A list of requested coin respectively with an amount :return: """ - # sp.set_type(to, sp.TString) original - sp.set_type(to, sp.TAddress) + sp.set_type(to, sp.TString) sp.set_type(assets, sp.TMap(sp.TNat, types.Types.Asset)) # sp.verify(sp.sender == sp.self_address, "Unauthorized") sp.verify(sp.len(assets) <= self.MAX_BATCH_SIZE, "BatchMaxSizeExceed") + parsed_to = parse_addr.str_to_addr(to) sp.for i in sp.range(0, sp.len(assets)): valid_coin = sp.view("is_valid_coin", self.data.bts_core, assets[i].coin_name, t=sp.TBool).open_some() # sp.verify(valid_coin == True, "UnregisteredCoin") # in case of on chain view - check_transfer = sp.view("check_transfer_restrictions", sp.self_address, sp.record(coin_name=assets[i].coin_name,user=to, value=assets[i].value), t=sp.TBool).open_some() + check_transfer = sp.view("check_transfer_restrictions", sp.self_address, sp.record( + coin_name=assets[i].coin_name,user=parsed_to, value=assets[i].value), t=sp.TBool).open_some() sp.verify(check_transfer == True, "FailCheckTransfer") - # self.check_transfer_restrictions(sp.record(coin_name=assets[i].coin_name, user=to, value=assets[i].value)) - # TODO: implement try # inter score call @@ -340,7 +346,7 @@ def handle_request_service(self, to, assets): ) mint_args_type_entry_point = sp.contract(mint_args_type, self.data.bts_core, "mint").open_some() mint_args = sp.record( - to=to, coin_name=assets[i].coin_name, value=assets[i].value + to=parsed_to, coin_name=assets[i].coin_name, value=assets[i].value ) sp.transfer(mint_args, sp.tez(0), mint_args_type_entry_point) @@ -404,56 +410,39 @@ def check_transfer_restrictions(self, params): """ sp.set_type(params, sp.TRecord(coin_name=sp.TString, user=sp.TAddress, value=sp.TNat)) - sp.trace("in check") - sp.trace(self.data.token_limit[params.coin_name]) - sp.verify(self.data.blacklist.contains(params.user) == False, "Blacklisted") sp.verify(self.data.token_limit[params.coin_name] >= params.value, "LimitExceed") - sp.result(True) - def check_parse_address(self, to): - """ - - :param to: - :return: - """ - # TODO: check address - return False - - - @sp.add_test(name="Counter") def test(): alice = sp.test_account("Alice") admin = sp.test_account("Admin") - # bmc= sp.test_account("BMC") scenario = sp.test_scenario() counter = BTPPreiphery(alice.address, admin.address) scenario += counter + counter.add_to_blacklist(["tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"]).run(sender=alice) + counter.send_service_message(sp.record(_from=sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), to="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", + coin_names={0:"Tok1"}, values={0:sp.nat(10)}, fees={0:sp.nat(2)})).run( + sender=admin + ) + counter.handle_btp_error(sp.record(svc= "bts", code=sp.nat(2), sn=sp.nat(1), msg="test 1")).run( + sender=admin + ) + + counter.set_token_limit(sp.record(coin_names={0:"Tok2"}, token_limit={0:sp.nat(5)})).run(sender=admin) + + counter.handle_request_service(sp.record(to= "tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc", assets={0: + sp.record(coin_name="Tok2", value=sp.nat(4))})).run( + sender=admin + ) + + counter.handle_fee_gathering(sp.record(fa="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", svc="bts")).run(sender=admin) - # counter.add_to_blacklist(["tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"]) - # counter.send_service_message(sp.record(_from=sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), to="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", - # coin_names={0:"Tok1"}, values={0:sp.nat(10)}, fees={0:sp.nat(2)})).run( - # sender=admin - # ) - # counter.handle_btp_error(sp.record(svc= "bts", code=sp.nat(2), sn=sp.nat(1), msg="test 1")).run( - # sender=admin - # ) - # - # counter.set_token_limit(sp.record(coin_names={0:"Tok2"}, token_limit={0:sp.nat(5)})).run(sender=admin) - # - # counter.handle_request_service(sp.record(to= sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), assets={0: - # sp.record(coin_name="Tok2", value=sp.nat(4))})).run( - # sender=admin - # ) - # - # counter.handle_fee_gathering(sp.record(fa="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", svc="bts")).run(sender=admin) - # # counter.handle_btp_message(sp.record(_from="tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", svc="bts", sn=sp.nat(4), # msg=sp.bytes("0x0507070a000000030dae110000") )).run(sender=admin) From b95a2d940e75b5b79ff428edc9883264feac9949 Mon Sep 17 00:00:00 2001 From: simusud Date: Wed, 26 Apr 2023 16:04:59 +0545 Subject: [PATCH 041/211] fix(library): data type fixes --- smartpy/bts/contracts/src/Types.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/smartpy/bts/contracts/src/Types.py b/smartpy/bts/contracts/src/Types.py index cf08a52b..ef385af4 100644 --- a/smartpy/bts/contracts/src/Types.py +++ b/smartpy/bts/contracts/src/Types.py @@ -41,12 +41,11 @@ class Types: TransferCoin = sp.TRecord( from_addr=sp.TString, to=sp.TString, - assets=sp.TList(Asset) + assets=sp.TMap(sp.TNat, Asset) ) PendingTransferCoin = sp.TRecord( - # from_addr=sp.TString, (change to original later) - from_addr=sp.TAddress, + from_addr=sp.TString, to=sp.TString, coin_names=sp.TMap(sp.TNat, sp.TString), amounts=sp.TMap(sp.TNat, sp.TNat), From 8d9275b913e3b2d2c70f0798c8d39cb314d6777b Mon Sep 17 00:00:00 2001 From: simusud Date: Wed, 26 Apr 2023 16:07:23 +0545 Subject: [PATCH 042/211] feat(library): added parse address library --- smartpy/bts/contracts/src/parse_address.py | 164 +++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 smartpy/bts/contracts/src/parse_address.py diff --git a/smartpy/bts/contracts/src/parse_address.py b/smartpy/bts/contracts/src/parse_address.py new file mode 100644 index 00000000..7d4f63ab --- /dev/null +++ b/smartpy/bts/contracts/src/parse_address.py @@ -0,0 +1,164 @@ +import smartpy as sp +Utils = sp.io.import_script_from_url("https://raw.githubusercontent.com/RomarQ/tezos-sc-utils/main/smartpy/utils.py") + +tz_prefixes = sp.map({ + sp.bytes('0x0000'): sp.string('tz1'), + sp.bytes('0x0001'): sp.string('tz2'), + sp.bytes('0x0002'): sp.string('tz3'), + sp.bytes('0x0003'): sp.string('tz4') +}) +base58_encodings=sp.list([ + sp.map({"prefix": "tz1", "elem1": "6", "elem2": "161", "elem3": "159", "len": "20"}), + sp.map({"prefix": "tz2", "elem1": "6", "elem2": "161", "elem3": "161", "len": "20"}), + sp.map({"prefix": "tz3", "elem1": "6", "elem2": "161", "elem3": "164", "len": "20"}), + sp.map({"prefix": "tz4", "elem1": "6", "elem2": "161", "elem3": "16", "len": "20"}), + sp.map({"prefix": "KT1", "elem1": "2", "elem2": "90", "elem3": "121", "len": "20"}), +]) +test_str = "" +test_addr = sp.address("KT1GPaeWzJpZAoY45v4aEWBFiqp6vtkLUkgw") + + +def unforge_address(data): + """Decode address or key_hash from bytes. + + :param data: encoded address or key_hash + :returns: base58 encoded address + """ + sp.set_type(data, sp.TBytes) + byt = sp.slice(data, 6, 22).open_some() + prefix = sp.slice(byt, 0, 2).open_some() + starts_with = sp.slice(byt, 0, 1).open_some() + ends_with = sp.slice(byt, 21, 1).open_some() + sliced_byte = sp.slice(byt, 1, 20).open_some() + local_byte = sp.local("local_byte", sp.bytes("0x")) + + sp.for item in tz_prefixes.items(): + sp.if item.key == prefix: + return base58_encode(sp.slice(byt, 2, 20).open_some(), Utils.Bytes.of_string(item.value), local_byte) + + sp.if (starts_with == sp.bytes("0x01")) & (ends_with == sp.bytes("0x00")): + return base58_encode(sliced_byte, Utils.Bytes.of_string("KT1"), local_byte) + sp.if (starts_with == sp.bytes("0x02")) & (ends_with == sp.bytes("0x00")): + return base58_encode(sliced_byte, Utils.Bytes.of_string("txr1"), local_byte) + sp.if (starts_with == sp.bytes("0x03")) & (ends_with == sp.bytes("0x00")): + return base58_encode(sliced_byte, Utils.Bytes.of_string("sr1"), local_byte) + +def tb(_list): + byte_str = sp.local("byte_str", sp.bytes("0x")) + sp.for num in _list: + byte_str.value += Utils.Bytes.of_nat(num) + return byte_str.value + +def base58_encode(v, prefix, _byte): + """ + Encode data using Base58 with checksum and add an according binary prefix in the end. + :param v: Array of bytes + :param prefix: Human-readable prefix (use b'') e.g. b'tz', b'KT', etc + :param local_byte: local variable + + :returns: bytes (use string.decode()) + """ + length_v = sp.to_int(sp.len(v)) + encoding = sp.local("encode", sp.map({})) + byte_from_tbl = sp.local("byte_from_tbl", sp.bytes("0x")) + byte_value = _byte + + sp.for enc in base58_encodings: + sp.if (length_v == Utils.Int.of_string(enc["len"])) & (prefix == Utils.Bytes.of_string(enc["prefix"])) : + encoding.value = enc + byte_from_tbl.value = tb([sp.as_nat(Utils.Int.of_string(enc["elem1"])), + sp.as_nat(Utils.Int.of_string(enc["elem2"])), + sp.as_nat(Utils.Int.of_string(enc["elem3"]))]) + sha256_encoding = sp.sha256(sp.sha256(byte_from_tbl.value + v)) + sha256_encoding = byte_from_tbl.value + v + sp.slice(sha256_encoding, 0, 4).open_some() + acc = sp.local("for_while_loop", Utils.Int.of_bytes(sha256_encoding)) + alphabet = Utils.Bytes.of_string("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") + base = 58 + sp.while acc.value > 0: + (acc.value, idx) = sp.match_pair(sp.ediv(acc.value, base).open_some()) + byte_value.value = sp.slice(alphabet, idx , 1).open_some() + byte_value.value + + return sp.unpack(sp.bytes("0x050100000024") + byte_value.value, sp.TString).open_some() + +def add_to_str(params): + sp.set_type(params, sp.TAddress) + return unforge_address(sp.pack(params)) + +def str_to_addr(params): + sp.set_type(params, sp.TString) + + string_in_bytes = sp.pack(params) + actual_prefix = sp.local("actual_prefix", "") + addr = sp.local("addr", sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")) + alphabet = Utils.Bytes.of_string("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") + + sp.if sp.len(string_in_bytes) == sp.nat(42): + string_in_bytes = sp.slice(string_in_bytes, 6, 36).open_some() + + element_list = sp.range(0, sp.len(alphabet), 1) + temp_map = sp.local("temp_map", {}) + temp_var = sp.local("y", 0) + sp.for elem in element_list: + temp_var.value = elem + temp_map.value[sp.slice(alphabet, temp_var.value, 1).open_some()] = temp_var.value + decimal = sp.local("decimal", 0) + base = sp.len(alphabet) + element_list_2 = sp.range(0, sp.len(string_in_bytes), 1) + sp.for elem in element_list_2: + decimal.value = decimal.value * base + temp_map.value[sp.slice(string_in_bytes, elem, 1).open_some()] + byt_value = Utils.Bytes.of_nat(sp.as_nat(sp.to_int(decimal.value))) + new_byt_value = sp.slice(byt_value, 0, sp.as_nat(sp.len(byt_value) - 4)).open_some() + prefix = sp.slice(new_byt_value, 0, 3 ).open_some() + prefix_len = sp.range(0, sp.len(prefix), 1) + temp_var3 = sp.local("z", 0) + list_string = sp.local("list_string", []) + sp.for x in prefix_len: + temp_var3.value = x + list_string.value.push(Utils.Int.of_bytes(sp.slice(prefix, temp_var3.value, 1).open_some())) + v = sp.slice(new_byt_value, 3, sp.as_nat(sp.len(new_byt_value) - 3)) + byte_local = sp.local("byt_old", sp.bytes("0x")) + sp.for enc in base58_encodings: + byte_local.value = tb([sp.as_nat(Utils.Int.of_string(enc["elem1"])), + sp.as_nat(Utils.Int.of_string(enc["elem2"])), + sp.as_nat(Utils.Int.of_string(enc["elem3"]))]) + sp.if byte_local.value == prefix : + actual_prefix.value = enc["prefix"] + sp.for item in tz_prefixes.items(): + sp.if item.value == actual_prefix.value: + decoded_address = sp.unpack(sp.bytes("0x050a00000016") + item.key + v.open_some(), + sp.TAddress) + addr.value = decoded_address.open_some() + return addr.value + sp.if actual_prefix.value == "KT1": + decoded_address = sp.unpack(sp.bytes("0x050a00000016") + sp.bytes("0x01") + v.open_some() + sp.bytes("0x00"), + sp.TAddress) + return decoded_address.open_some() + sp.if actual_prefix.value == "txr1": + decoded_address = sp.unpack(sp.bytes("0x050a00000016") + sp.bytes("0x02") + v.open_some() + sp.bytes("0x00"), + sp.TAddress) + return decoded_address.open_some() + sp.if actual_prefix.value == "sr1": + decoded_address = sp.unpack(sp.bytes("0x050a00000016") + sp.bytes("0x03") + v.open_some() + sp.bytes("0x00"), + sp.TAddress) + return decoded_address.open_some() + + sp.if actual_prefix.value == "": + return sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg") + + with sp.else_(): + return sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg") + +# @sp.add_test(name="Conversion") +# def test(): +# alice=sp.test_account("Alice") +# c1 = Conversion() +# scenario = sp.test_scenario() +# scenario.h1("Conversion") +# scenario += c1 +# c1.add_to_str(sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP")) +# c1.str_to_addr("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP") +# +# +# sp.add_compilation_target("smartpy-utils", Conversion()) + + From 50b868aab22ed6fd2291f3797a54fecd00c767e7 Mon Sep 17 00:00:00 2001 From: suyogadhikari Date: Wed, 3 May 2023 11:54:41 +0545 Subject: [PATCH 043/211] rlp decode library added --- .../bts/contracts/src/RLP_decode_struct.py | 179 ++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 smartpy/bts/contracts/src/RLP_decode_struct.py diff --git a/smartpy/bts/contracts/src/RLP_decode_struct.py b/smartpy/bts/contracts/src/RLP_decode_struct.py new file mode 100644 index 00000000..98403df5 --- /dev/null +++ b/smartpy/bts/contracts/src/RLP_decode_struct.py @@ -0,0 +1,179 @@ +import smartpy as sp + +Utils = sp.io.import_script_from_url("https://raw.githubusercontent.com/Acurast/acurast-hyperdrive/main/contracts/tezos/libs/utils.py") +Utils2 = sp.io.import_script_from_url("https://raw.githubusercontent.com/RomarQ/tezos-sc-utils/main/smartpy/utils.py") + + +def decode_bmc_message(self, rlp): + decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) + decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) + rlp_ = decode_list(rlp) + temp_map_string = sp.compute(sp.map(tkey=sp.TString, tvalue=sp.TString)) + temp_int = sp.local("int_value", 0) + temp_byt = sp.local("byt_value", sp.bytes("0x")) + counter = sp.local("counter", 0) + sp.for i in rlp_.items(): + # sp.trace(sp.bytes("0xf8c8") + i.value) + sp.if counter.value == 0: + temp_map_string["src"] = decode_string(i.value) + # sp.trace(decode_string(i.value)) + sp.if counter.value == 1: + temp_map_string["dst"] = decode_string(i.value) + # sp.trace(decode_string(i.value)) + sp.if counter.value == 2: + temp_map_string["svc"] = decode_string(i.value) + # sp.trace(decode_string(i.value)) + sp.if counter.value == 3: + temp_int.value = Utils2.Int.of_bytes(i.value) + # sp.trace(Utils2.Int.of_bytes(i.value)) + sp.if counter.value == 4: + temp_byt.value = i.value + # sp.trace(i.value) + counter.value = counter.value + 1 + + return sp.record(src=temp_map_string["src"], + dst=temp_map_string["dst"], + svc=temp_map_string["svc"], + sn=temp_int.value, + message=temp_byt.value) + + +def decode_response(self, rlp): + decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) + decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) + temp_int = sp.local("int1", 0) + temp_byt = sp.local("byt1", sp.bytes("0x")) + rlp_ = decode_list(rlp) + counter = sp.local("counter", 0) + sp.for i in rlp_.items(): + sp.if counter.value == 0: + temp_int.value = Utils2.Int.of_bytes(i.value) + sp.if counter.value == 1: + temp_byt.value = i.value + counter.value = counter.value + 1 + + return sp.record(code=temp_int.value, message=decode_string(temp_byt.value)) + + +def decode_bmc_service(self, rlp): + decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) + decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) + rlp_ = decode_list(rlp) + temp_string = sp.local("str_value", 0) + temp_byt = sp.local("byt_value", sp.bytes("0x")) + counter = sp.local("counter", 0) + sp.for i in rlp_.items(): + sp.if counter.value == 0: + temp_string.value = decode_string(i.value) + sp.if counter.value == 1: + temp_byt.value = i.value + counter.value = counter.value + 1 + + return sp.record(serviceType=temp_string.value, + payload=temp_byt.value) + + +def decode_service_message(self, rlp): + decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) + rlp_ = decode_list(rlp) + temp_int = sp.local("int2", 0) + temp_byt = sp.local("byte1", sp.bytes("0x")) + counter = sp.local("counter", 0) + sp.for i in rlp_.items(): + sp.if counter.value == 0: + temp_int.value = Utils2.Int.of_bytes(i.value) + sp.if counter.value == 1: + temp_byt.value = i.value + counter.value = counter.value + 1 + + return sp.record(serviceType=temp_int.value, + data=temp_byt.value) + + +def decode_gather_fee_message(self, rlp): + decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) + decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) + rlp_ = decode_list(rlp) + temp_byt = sp.local("byt4", sp.bytes("0x")) + counter = sp.local("counter", 0) + temp_str = sp.local("str_gather", "") + sp.for i in rlp_.items(): + sp.if counter.value == 1: + temp_byt.value = i.value + sp.if counter.value == 0: + temp_str.value = decode_string(i.value) + counter.value = counter.value + 1 + starts_with = sp.slice(temp_byt.value, 0, 2).open_some() + sub_list = sp.local("sub_list", temp_byt.value) + sp.if starts_with == sp.bytes("0xb846"): + sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() + new_sub_list = decode_list(sub_list.value) + _svcs = sp.local("_svcs", sp.TMap(sp.TNat, sp.TString)) + counter.value = 0 + sp. + for x in new_sub_list.items(): + _svcs.value[counter.value] = decode_string(x.value) + counter.value = counter.value + 1 + return sp.record(fa=temp_str, + svcs=_svcs) + +def decode_event_log(self, rlp): + decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) + eventMptNode = sp.local("eventMptNode", sp.TMap(sp.TNat, sp.TString)) + rlp_ = decode_list(rlp) + counter = sp.local("counter", 0) + sp.for i in rlp_.items(): + eventMptNode.value[counter.value] = i.value + counter.value = counter.value + 1 + return eventMptNode + + +def decode_receipt_proof(self, rlp): + decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) + rlp_ = decode_list(rlp) + temp_byt = sp.local("byt_receipt", sp.bytes("0x")) + temp_byt2 = sp.local("byt_receipt2", sp.bytes("0x")) + rv_int = sp.local("rv_int", 0) + counter = sp.local("counter", 0) + sp.for i in rlp_.items(): + sp.if counter.value == 1: + temp_byt.value = i.value + sp.if counter.value == 0: + rv_int.value = Utils2.Int.of_bytes(i.value) + sp.if counter.value == 2: + temp_byt2 = i.value + counter.value = counter.value + 1 + + starts_with = sp.slice(temp_byt.value, 0, 2).open_some() + sub_list = sp.local("sub_list", temp_byt.value) + sp.if starts_with == sp.bytes("0xb846"): + sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() + new_sub_list = decode_list(sub_list.value) + counter.value = 0 + txReceipts = sp.local("txReceipts", sp.TMap(sp.TNat, sp.TBytes)) + sp.for x in new_sub_list.items(): + txReceipts.value[counter.value] = x.value + counter.value = counter.value + 1 + + starts_with_second_elem = sp.slice(temp_byt2.value, 0, 2).open_some() + sub_list_second_elem = sp.local("sub_list_second_elem", temp_byt.value) + sp.if starts_with_second_elem == sp.bytes("0xb846"): + sub_list_second_elem.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() + new_sub_list = decode_list(sub_list_second_elem.value) + ep = sp.local("ep", sp.TMap(sp.TNat, sp.TBytes)) + new_temp_byt = sp.local("new_temp_byt", sp.bytes("0x")) + sp.for x in new_sub_list.items(): + new_temp_byt.value = x.value + sp.if sp.slice(new_temp_byt.value, 0, 2).open_some() == sp.bytes("0xb846"): + new_temp_byt.value = sp.slice(new_temp_byt.value, 2, sp.as_nat(sp.len(new_temp_byt.value) - 2)).open_some() + temp_map = sp.local("tempMap", sp.TMap(sp.TNat, sp.TString)) + temp_int = sp.local("tempInt", 0) + counter.value = 0 + sp.for i in decode_list(new_temp_byt.value): + sp.if counter.value == 0: + temp_int = Utils2.Int.of_bytes(i.value) + sp.if counter.value == 1: + temp_map = self.decode_event_log(i.value) + counter.value = counter.value + 1 + ep.value[counter.value] = sp.record(index=temp_int, eventMptNode=temp_map) + return sp.record(index=rv_int.value, txReceipts=txReceipts.value, eventMptNode=ep.value) From e665b29600e6fc4ced87634aced48685eae2806e Mon Sep 17 00:00:00 2001 From: suyogadhikari Date: Wed, 3 May 2023 15:28:19 +0545 Subject: [PATCH 044/211] fix(library): rlp decode functions added --- .../bts/contracts/src/RLP_decode_struct.py | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) diff --git a/smartpy/bts/contracts/src/RLP_decode_struct.py b/smartpy/bts/contracts/src/RLP_decode_struct.py index 98403df5..fbb16dff 100644 --- a/smartpy/bts/contracts/src/RLP_decode_struct.py +++ b/smartpy/bts/contracts/src/RLP_decode_struct.py @@ -177,3 +177,120 @@ def decode_receipt_proof(self, rlp): counter.value = counter.value + 1 ep.value[counter.value] = sp.record(index=temp_int, eventMptNode=temp_map) return sp.record(index=rv_int.value, txReceipts=txReceipts.value, eventMptNode=ep.value) + +def decode_transfer_coin_msg(self, rlp): + decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) + rlp_ = decode_list(rlp) + decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) + + temp_byt = sp.local("byt_transfer", sp.bytes("0x")) + rv1_byt = sp.local("rv1_byt", sp.bytes("0x")) + rv2_byt = sp.local("rv2_byt", sp.bytes("0x")) + counter = sp.local("counter", 0) + sp.for i in rlp_.items(): + sp.if counter.value == 2: + temp_byt.value = i.value + sp.if counter.value == 0: + rv1_byt.value = i.value + sp.if counter.value == 1: + rv2_byt.value = i.value + counter.value = counter.value + 1 + starts_with = sp.slice(temp_byt.value, 0, 2).open_some() + sub_list = sp.local("sub_list", temp_byt.value) + sp.if starts_with == sp.bytes("0xb846"): + sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() + new_sub_list = decode_list(sub_list.value) + counter.value = 0 + new_temp_byt = sp.local("new_temp_byt", sp.bytes("0x")) + rv_assets = sp.local("assets", sp.TMap(sp.TNat, sp.TBytes)) + sp.for x in new_sub_list.items(): + new_temp_byt.value = x.value + sp.if sp.slice(new_temp_byt.value, 0, 2).open_some() == sp.bytes("0xb846"): + new_temp_byt.value = sp.slice(new_temp_byt.value, 2, sp.as_nat(sp.len(new_temp_byt.value) - 2)).open_some() + temp_byt = sp.local("tempByt2", sp.bytes("0x")) + temp_int = sp.local("tempInt", 0) + counter.value = 0 + sp.for i in decode_list(new_temp_byt.value): + sp.if counter.value == 1: + temp_int = i.value + sp.if counter.value == 0: + temp_byt = i.value + rv_assets.value[counter.value] = sp.record(coinName=temp_int, value=temp_byt) + counter.value = counter.value + 1 + rv1 = decode_string(rv1_byt.value) + rv2 = decode_string(rv2_byt.value) + return sp.record(from_= rv1, to = rv2 , assets = rv_assets) + +def decode_blacklist_msg(self, rlp): + decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) + rlp_ = decode_list(rlp) + decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) + + temp_byt = sp.local("byt_transfer", sp.bytes("0x")) + rv1_byt = sp.local("rv1_byt", sp.bytes("0x")) + rv2_byt = sp.local("rv2_byt", sp.bytes("0x")) + counter = sp.local("counter", 0) + sp.for i in rlp_.items(): + sp.if counter.value == 2: + rv2_byt.value = i.value + sp.if counter.value == 0: + rv1_byt.value = i.value + sp.if counter.value == 1: + temp_byt.value = i.value + counter.value = counter.value + 1 + starts_with = sp.slice(temp_byt.value, 0, 2).open_some() + sub_list = sp.local("sub_list", temp_byt.value) + sp.if starts_with == sp.bytes("0xb846"): + sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() + new_sub_list = decode_list(sub_list.value) + counter.value = 0 + new_temp_byt = sp.local("new_temp_byt", sp.bytes("0x")) + rv_blacklist_address = sp.local("blacklist_data", sp.TMap(sp.TNat, sp.TBytes)) + sp.for x in new_sub_list.items(): + new_temp_byt.value = x.value + sp.if sp.slice(new_temp_byt.value, 0, 2).open_some() == sp.bytes("0xb846"): + new_temp_byt.value = sp.slice(new_temp_byt.value, 2, sp.as_nat(sp.len(new_temp_byt.value) - 2)).open_some() + counter.value = 0 + sp.for j in decode_list(new_temp_byt.value): + rv_blacklist_address.value[counter.value] = decode_string(j.value) + counter.value = counter.value + 1 + rv1 = Utils2.Int.of_bytes(rv1_byt.value) + rv2 = decode_string(rv2_byt.value) + with sp.if_(rv1 == 0): + _service_type = sp.variant("ADD_TO_BLACKLIST", rv1) + with sp.else_(): + _service_type = sp.variant("REMOVE_FROM_BLACKLIST", rv1) + return sp.record(serviceType = _service_type , addrs = rv_blacklist_address , net = decode_string(rv2)) + +def decode_token_limit_msg(self, rlp): + decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) + rlp_ = decode_list(rlp) + decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) + + temp_byt = sp.local("byt_transfer", sp.bytes("0x")) + temp_byt1 = sp.local("byt_transfer", sp.bytes("0x")) + rv1_byt = sp.local("rv1_byt", sp.bytes("0x")) + counter = sp.local("counter", 0) + sp.for i in rlp_.items(): + sp.if counter.value == 0: + temp_byt.value = i.value + sp.if counter.value == 1: + temp_byt1.value = i.value + sp.if counter.value == 2: + rv1_byt.value = i.value + counter.value = counter.value + 1 + starts_with = sp.slice(temp_byt.value, 0, 2).open_some() + sub_list = sp.local("sub_list", temp_byt.value) + sp.if starts_with == sp.bytes("0xb846"): + sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() + new_sub_list = decode_list(sub_list.value) + counter.value = 0 + rv_names = sp.local("names", sp.TMap(sp.TNat, sp.TString)) + rv_limit = sp.local("limit", sp.TMap(sp.TNat, sp.TInt)) + sp.for x in new_sub_list.items(): + rv_names.value[counter.value] = decode_string(x.value) + + new_sub_list1 = decode_list(sub_list.value) + sp.for y in new_sub_list1.items(): + rv_names.value[counter.value] = Utils2.Int.of_bytes(y.value) + return sp.record(coinName = rv_names, tokenLimit = rv_limit , net = decode_string(rv1_byt.value)) \ No newline at end of file From f53e691831c7231c29697500f2121bc0fc87ffb0 Mon Sep 17 00:00:00 2001 From: simusud Date: Wed, 3 May 2023 20:47:13 +0545 Subject: [PATCH 045/211] feat(bts_core): added callback implementation and uncommented checks in functions --- smartpy/bts/contracts/src/bts_core.py | 89 ++++++++++++++++++++++----- 1 file changed, 72 insertions(+), 17 deletions(-) diff --git a/smartpy/bts/contracts/src/bts_core.py b/smartpy/bts/contracts/src/bts_core.py index 39490d3c..7c645b8d 100644 --- a/smartpy/bts/contracts/src/bts_core.py +++ b/smartpy/bts/contracts/src/bts_core.py @@ -45,6 +45,7 @@ def __init__(self, _native_coin_name, _fee_numerator, _fixed_fee, owner_manager) coin_type=self.NATIVE_COIN_TYPE)}, tkey=sp.TString, tvalue=Coin), coins_address=sp.map({}, tkey=sp.TAddress, tvalue=sp.TString), + transfer_status=sp.none ) #is this necessary? can we check against owners map in line 37? @@ -74,7 +75,7 @@ def update_bts_periphery(self, bts_periphery): """ sp.set_type(bts_periphery, sp.TAddress) - # self.only_owner() + self.only_owner() sp.if self.data.bts_periphery_address.is_some(): has_requests = sp.view("has_pending_request", self.data.bts_periphery_address.open_some("Address not set"), sp.unit, t=sp.TBool).open_some("OwnerNotFound") sp.verify(has_requests == False, "HasPendingRequest") @@ -114,15 +115,13 @@ def register(self, name, fee_numerator, fixed_fee, addr, token_metadata, metadat :return: """ sp.set_type(name, sp.TString) - # sp.set_type(symbol, sp.TString) - # sp.set_type(decimals, sp.TNat) sp.set_type(fee_numerator, sp.TNat) sp.set_type(fixed_fee, sp.TNat) sp.set_type(addr, sp.TAddress) sp.set_type(token_metadata, sp.TMap(sp.TString, sp.TBytes)) sp.set_type(metadata, sp.TBigMap(sp.TString, sp.TBytes)) - # self.only_owner() + self.only_owner() sp.verify(name != self.data.native_coin_name, message="ExistNativeCoin") sp.verify(self.data.coins.contains(name) == False, message= "ExistCoin") sp.verify(self.data.coins_address.contains(addr) == False, message="AddressExists") @@ -540,6 +539,24 @@ def mint(self, to, coin_name, value): transfer_args = [sp.record(from_=sp.sender, txs=[sp.record(to_=to, token_id=sp.nat(0), amount=value)])] sp.transfer(transfer_args, sp.tez(0), transfer_entry_point) + @sp.entry_point + def callback(self, string, requester, coin_name, value): + sp.set_type(string, sp.TOption(sp.TString)) + sp.set_type(requester, sp.TAddress) + sp.set_type(coin_name, sp.TString) + sp.set_type(value, sp.TNat) + + sp.verify(sp.sender == self.data.coins[coin_name], "Unauthorized") + self.data.transfer_status = string + + with sp.if_(self.data.transfer_status.open_some() == "success"): + pass + with sp.else_(): + self.data.balances[sp.record(address=requester, coin_name=coin_name)].refundable_balance = \ + self.data.balances.get(sp.record(address=requester, coin_name=coin_name), + default_value=sp.record(locked_balance=sp.nat(0),refundable_balance=sp.nat(0)) + ).refundable_balance + value + @sp.entry_point def handle_response_service(self, requester, coin_name, value, fee, rsp_code): """ @@ -560,26 +577,49 @@ def handle_response_service(self, requester, coin_name, value, fee, rsp_code): self.only_bts_periphery() sp.if requester == sp.self_address: sp.if rsp_code == self.RC_ERR: - self.data.aggregation_fee[coin_name] = self.data.aggregation_fee[coin_name] + value - return + self.data.aggregation_fee[coin_name] = self.data.aggregation_fee.get(coin_name, + default_value=sp.nat(0)) + fee + # TODO:code is returning in all case from here (need to see how to implement return) + # return amount = sp.local("amount", value + fee, t=sp.TNat) - self.data.balances[sp.record(address=requester, coin_name=coin_name)].locked_balance = \ - sp.as_nat(self.data.balances[sp.record(address=requester, coin_name=coin_name)].locked_balance - amount.value) + sp.if self.data.balances.contains(sp.record(address=requester, coin_name=coin_name)): + self.data.balances[sp.record(address=requester, coin_name=coin_name)].locked_balance = \ + sp.as_nat(self.data.balances.get(sp.record(address=requester, coin_name=coin_name), + default_value=sp.record(locked_balance=sp.nat(0), refundable_balance=sp.nat(0))).locked_balance - amount.value) sp.if rsp_code == self.RC_ERR: - pass - # TODO: implement try catch + with sp.if_(coin_name == self.data.native_coin_name): + with sp.if_(sp.utils.mutez_to_nat(sp.balance) >= value): + self.payment_transfer(requester, value) + with sp.else_(): + self.data.balances[sp.record(address=requester, coin_name=coin_name)].refundable_balance = self.data.balances.get( + sp.record(address=requester, coin_name=coin_name), + default_value=sp.record(locked_balance=sp.nat(0), refundable_balance=sp.nat(0))).refundable_balance + value + with sp.else_(): + # call transfer in FA2 + transfer_args_type = sp.TList(sp.TRecord( + callback=sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), requester=sp.TAddress, coin_name=sp.TString, value=sp.TNat)), + from_=sp.TAddress, + coin_name=sp.TString, + txs=sp.TList(sp.TRecord(to_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout(("to_", ("token_id", "amount")))) + ).layout((("from_", "coin_name"), ("callback", "txs")))) + transfer_entry_point = sp.contract(transfer_args_type, self.data.coins[coin_name], + "transfer").open_some() + transfer_args = [ + sp.record(callback=sp.self_entry_point("callback"), from_=sp.self_address, coin_name=coin_name, txs=[sp.record(to_=requester, token_id=sp.nat(0), amount=value)])] + sp.transfer(transfer_args, sp.tez(0), transfer_entry_point) + sp.if rsp_code == self.RC_OK: fa2_address = self.data.coins[coin_name] sp.if (coin_name != self.data.native_coin_name) & (self.data.coin_details[coin_name].coin_type == self.NATIVE_WRAPPED_COIN_TYPE): # call burn in FA2 - burn_args_type = sp.TList(sp.TRecord(from_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout("from_", ("token_id", "amount"))) + burn_args_type = sp.TList(sp.TRecord(from_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat)) burn_entry_point = sp.contract(burn_args_type, fa2_address, "burn").open_some() burn_args = [sp.record(from_=sp.self_address, token_id=sp.nat(0), amount=value)] sp.transfer(burn_args, sp.tez(0), burn_entry_point) - self.data.aggregation_fee[coin_name] = self.data.aggregation_fee[coin_name] + fee + self.data.aggregation_fee[coin_name] = self.data.aggregation_fee.get(coin_name, default_value=sp.nat(0)) + fee @sp.entry_point def transfer_fees(self, fa): @@ -643,6 +683,7 @@ def set_bts_owner_manager(self, owner_manager): @sp.add_test(name="BTSCore") def test(): alice=sp.test_account("Alice") + receiver=sp.test_account("receiver") c1 = BTSCore( owner_manager=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), _native_coin_name="NativeCoin", @@ -652,11 +693,25 @@ def test(): scenario = sp.test_scenario() scenario.h1("BTSCore") scenario += c1 - c1.update_bts_periphery(sp.address("KT1VCbyNieUsQsCShkxtTz9ZbLmE9oowmJPm")).run(sender=alice) - c1.register(sp.record(name="tezos", symbol="TEZ", decimals=sp.nat(18), fee_numerator=sp.nat(5), fixed_fee=sp.nat(1), - addr=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), - token_metadata=sp.map({"ss": sp.bytes("0x0dae11")}), - metadata=sp.big_map({"ff": sp.bytes("0x0dae11")}))).run(sender=alice) + c2 = FA2_contract.SingleAssetToken(admin=alice.address, metadata=sp.big_map({"ss": sp.bytes("0x0dae11")}), + token_metadata=sp.map({"ff": sp.bytes("0x0dae11")})) + scenario +=c2 + # c1.update_bts_periphery(sp.address("KT1VCbyNieUsQsCShkxtTz9ZbLmE9oowmJPm")).run(sender=alice) + # c1.register(sp.record(name="tezos", symbol="TEZ", decimals=sp.nat(18), fee_numerator=sp.nat(5), fixed_fee=sp.nat(1), + # addr=c2.address, + # token_metadata=sp.map({"ss": sp.bytes("0x0dae11")}), + # metadata=sp.big_map({"ff": sp.bytes("0x0dae11")}))).run(sender=alice) + # c2.mint([sp.record(to_=c1.address, amount=sp.nat(200))]).run(sender=alice) + + # c2.transfer([sp.record(callback=sp.contract( + # sp.TRecord(string=sp.TOption(sp.TString), requester=sp.TAddress, coin_name=sp.TString, value=sp.TNat), + # c1.address, + # entry_point="callback", + # ).open_some(),from_=alice.address, coin_name="tezos", txs=[sp.record(to_=receiver.address, token_id=0, amount=100)])]).run( + # sender=alice) + + # c1.handle_response_service(sp.record(requester=sp.address("KT1VCbyNieUsQsCShkxtTz9ZbLmE9oowmJPm"), coin_name="tezos", + # value=sp.nat(44), fee=sp.nat(3), rsp_code=sp.nat(1))).run(sender=alice) sp.add_compilation_target("bts_core", BTSCore( From ed63ee7fd864dac7a34461e9ace9e2d3db6071ef Mon Sep 17 00:00:00 2001 From: simusud Date: Wed, 3 May 2023 20:48:49 +0545 Subject: [PATCH 046/211] feat(bts_periphery): added rlp decode implementation and uncommented checks in functions --- smartpy/bts/contracts/src/bts_periphery.py | 132 +++++++++------------ 1 file changed, 59 insertions(+), 73 deletions(-) diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index 885270ce..78417e96 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -3,6 +3,7 @@ types = sp.io.import_script_from_url("file:./contracts/src/Types.py") strings = sp.io.import_script_from_url("file:./contracts/src/String.py") rlp_encode = sp.io.import_script_from_url("file:./contracts/src/RLP_encode_struct.py") +rlp_decode = sp.io.import_script_from_url("file:./contracts/src/RLP_decode_struct.py") parse_addr = sp.io.import_script_from_url("file:./contracts/src/parse_address.py") class BTPPreiphery(sp.Contract): @@ -27,7 +28,7 @@ def __init__(self, bmc_address, bts_core_address): def only_bmc(self): sp.verify(sp.sender == self.data.bmc, "Unauthorized") - def only_btp_core(self): + def only_bts_core(self): sp.verify(sp.sender == self.data.bts_core, "Unauthorized") @sp.onchain_view() @@ -45,12 +46,12 @@ def add_to_blacklist(self, params): :param params: List of addresses to be blacklisted :return: """ - sp.set_type(params, sp.TList(sp.TString)) - # sp.verify(sp.sender == sp.self_address, "Unauthorized") + sp.set_type(params, sp.TMap(sp.TNat, sp.TString)) + sp.verify(sp.sender == sp.self_address, "Unauthorized") sp.verify(sp.len(params) <= self.MAX_BATCH_SIZE, "BatchMaxSizeExceed") - sp.for itm in params: - parsed_addr = parse_addr.str_to_addr(itm) + sp.for i in sp.range(sp.nat(0), sp.len(params)): + parsed_addr = parse_addr.str_to_addr(params.get(i)) with sp.if_(parsed_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): self.data.blacklist[parsed_addr] = True with sp.else_(): @@ -63,13 +64,13 @@ def remove_from_blacklist(self, params): :param params: list of address strings :return: """ - sp.set_type(params, sp.TList(sp.TString)) + sp.set_type(params, sp.TMap(sp.TNat, sp.TString)) - # sp.verify(sp.sender == sp.self_address, "Unauthorized") + sp.verify(sp.sender == sp.self_address, "Unauthorized") sp.verify(sp.len(params) <= self.MAX_BATCH_SIZE, "BatchMaxSizeExceed") - sp.for itm in params: - parsed_addr = parse_addr.str_to_addr(itm) + sp.for i in sp.range(sp.nat(0), sp.len(params)): + parsed_addr = parse_addr.str_to_addr(params.get(i)) with sp.if_(parsed_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): sp.verify(self.data.blacklist.contains(parsed_addr), "UserNotFound") sp.verify(self.data.blacklist.get(parsed_addr) == True, "UserNotBlacklisted") @@ -87,8 +88,7 @@ def set_token_limit(self, coin_names, token_limit): sp.set_type(coin_names, sp.TMap(sp.TNat, sp.TString)) sp.set_type(token_limit, sp.TMap(sp.TNat, sp.TNat)) - # uncomment later - # sp.verify((sp.sender == sp.self_address )| (sp.sender == self.data.bts_core), "Unauthorized") + sp.verify((sp.sender == sp.self_address )| (sp.sender == self.data.bts_core), "Unauthorized") sp.verify(sp.len(coin_names) == sp.len(token_limit), "InvalidParams") sp.verify(sp.len(coin_names) <= self.MAX_BATCH_SIZE, "BatchMaxSizeExceed") @@ -114,7 +114,7 @@ def send_service_message(self, _from, to, coin_names, values, fees): sp.set_type(values, sp.TMap(sp.TNat, sp.TNat)) sp.set_type(fees, sp.TMap(sp.TNat, sp.TNat)) - self.only_btp_core() + self.only_bts_core() to_network, to_address = sp.match_pair(strings.split_btp_address(to)) @@ -149,7 +149,7 @@ def send_service_message(self, _from, to, coin_names, values, fees): # push pending tx into record list self.data.requests[self.data.serial_no] = sp.record( - from_addr=start_from, to=to, coin_names=coin_names, amounts=values, fees=fees + from_=start_from, to=to, coin_names=coin_names, amounts=values, fees=fees ) self.data.number_of_pending_requests +=sp.nat(1) sp.emit(sp.record(from_address=_from, to=to, serial_no=self.data.serial_no, assets_details=assets_details), tag="TransferStart") @@ -171,75 +171,62 @@ def handle_btp_message(self, _from, svc, sn, msg): sp.set_type(sn, sp.TNat) sp.set_type(msg, sp.TBytes) - # self.only_bmc() - # TODO: implement try catch + self.only_bmc() sp.verify(svc == self.service_name, "InvalidSvc") err_msg = sp.local("error", "") + sm = rlp_decode.decode_service_message(msg) - # byt= sp.pack(sp.record(serviceType=sp.variant("REQUEST_COIN_TRANSFER", 0), data=sp.bytes("0x0dae11"))) - # sp.trace(byt) - - sm = sp.unpack(msg, t=types.Types.ServiceMessage).open_some() - # sm=sp.record(serviceType=sp.variant("REQUEST_COIN_TRANSFER", 0), data=sp.bytes("0x0dae11")) - sp.trace(sm.serviceType) - - # service_type = sm.serviceType - # service_type = sp.set_type_expr(service_type, types.Types.s_type) - # sp.trace(service_type) - + # TODO: implement try in below cases with sm.serviceType.match_cases() as arg: with arg.match("REQUEST_COIN_TRANSFER") as a1: - # TODO: decode tc - # tc = sp.unpack(sm.data, t=types.Types.TransferCoin) - # parsed_addr = parse_addr.str_to_addr(tc.to) - # remove below parsed_addr after tc decode implemented - parsed_addr = sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg") - with sp.if_(parsed_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): - pass - # TODO: implement handle request service + tc = rlp_decode.decode_transfer_coin_msg(sm.data) + parsed_addr = parse_addr.str_to_addr(tc.to) + with sp.if_(parsed_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): + contract = sp.self_entry_point(entry_point="handle_request_service") + _param = sp.record(to=tc.to, assets=tc.assets) + sp.transfer(_param, sp.tez(0), contract) + self.send_response_message(sp.variant("RESPONSE_HANDLE_SERVICE", 2), _from, sn, "", self.RC_OK) + sp.emit(sp.record(from_address=_from, to=parsed_addr, serial_no=self.data.serial_no, assets_details=tc.assets), tag="TransferReceived") + # return with sp.else_(): err_msg.value = "InvalidAddress" - self.send_response_message(sp.variant("RESPONSE_HANDLE_SERVICE", 2), _from, sn, "", self.RC_OK) - # sp.emit(sp.record(from_address=_from, to=tc.to, serial_no=self.data.serial_no, assets_details=tc.assets)) + self.send_response_message(sp.variant("RESPONSE_HANDLE_SERVICE", 2), _from, sn, "", self.RC_ERR) with arg.match("BLACKLIST_MESSAGE") as a2: - - bm = sp.unpack(sm.data, types.Types.BlacklistMessage).open_some() - # bm=sp.record(serviceType=sp.variant("ADD_TO_BLACKLIST", 0), addrs={0:"tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"}, - # net="Tezos") + bm = rlp_decode.decode_blacklist_msg(sm.data) addresses = bm.addrs with bm.serviceType.match_cases() as b_agr: with b_agr.match("ADD_TO_BLACKLIST") as b_val_1: - # self.add_to_blacklist(addresses) + contract = sp.self_entry_point(entry_point="add_to_blacklist") + sp.transfer(addresses, sp.tez(0), contract) self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), _from, sn, "AddedToBlacklist", self.RC_OK) with b_agr.match("REMOVE_FROM_BLACKLIST") as b_val_2: - # self.remove_from_blacklist(addresses) + contract = sp.self_entry_point(entry_point="remove_from_blacklist") + sp.transfer(addresses, sp.tez(0), contract) self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), _from, sn, "RemovedFromBlacklist", self.RC_OK) with arg.match("CHANGE_TOKEN_LIMIT") as a3: - # TODO: implement decodeTokenLimitMsg - tl = sp.unpack(sm.data, t=types.Types.TokenLimitMessage).open_some() - # tl = sp.record(coin_name={0:"Tok1"},token_limit={0:5}, net="Tezos") - coin_names = sp.map({0: tl.coin_name}) - token_limits = sp.map({0: tl.token_limit}) + tl = rlp_decode.decode_token_limit_msg(sm.data) + coin_names = tl.coin_name + token_limits = tl.token_limit - # self.set_token_limit(coin_names, token_limits) + contract = sp.self_entry_point(entry_point="set_token_limit") + _param = sp.record(coin_names=coin_names, token_limit=token_limits) + sp.transfer(_param, sp.tez(0), contract) self.send_response_message(sp.variant("CHANGE_TOKEN_LIMIT", 4), _from, sn, "ChangeTokenLimit",self.RC_OK) with arg.match("RESPONSE_HANDLE_SERVICE") as a4: - # TODO: implement decodeResponse - response = sp.unpack(sm.data, types.Types.Response).open_some() - # response = sp.record(code=2, message="Test") - + sp.verify(sp.len(sp.pack(self.data.requests.get(sn).from_)) != 0, "InvalidSN") + response = rlp_decode.decode_response(sm.data) self.handle_response_service(sn, response.code, response.message) with arg.match("UNKNOWN_TYPE") as a5: - sp.emit(sp.record(_from=_from, sn=sn)) + sp.emit(sp.record(_from=_from, sn=sn), tag= "UnknownResponse") # using if else # with sp.if_(sm.serviceType == types.Types.ServiceType.open_variant("REQUEST_COIN_TRANSFER")): @@ -273,10 +260,10 @@ def handle_btp_error(self, svc, sn, code, msg): sp.set_type(code, sp.TNat) sp.set_type(msg, sp.TString) - # self.only_bmc() + self.only_bmc() sp.verify(svc == self.service_name, "InvalidSvc") - sp.verify(sp.len(sp.pack(self.data.requests[sn].from_addr)) != 0, "InvalidSN") + sp.verify(sp.len(sp.pack(self.data.requests[sn].from_)) != 0, "InvalidSN") emit_msg= sp.concat(["errCode: ", parse_addr.Utils.String.of_int(sp.to_int(code)),", errMsg: ", msg]) self.handle_response_service(sn, self.RC_ERR, emit_msg) @@ -293,7 +280,7 @@ def handle_response_service(self, sn, code, msg): sp.set_type(code, sp.TNat) sp.set_type(msg, sp.TString) - caller = sp.local("caller", parse_addr.str_to_addr(self.data.requests[sn].from_addr), sp.TAddress).value + caller = sp.local("caller", parse_addr.str_to_addr(self.data.requests[sn].from_), sp.TAddress).value loop = sp.local("loop", sp.len(self.data.requests[sn].coin_names), sp.TNat).value sp.verify(loop <= self.MAX_BATCH_SIZE, "BatchMaxSizeExceed") @@ -325,21 +312,19 @@ def handle_request_service(self, to, assets): sp.set_type(to, sp.TString) sp.set_type(assets, sp.TMap(sp.TNat, types.Types.Asset)) - # sp.verify(sp.sender == sp.self_address, "Unauthorized") + sp.verify(sp.sender == sp.self_address, "Unauthorized") sp.verify(sp.len(assets) <= self.MAX_BATCH_SIZE, "BatchMaxSizeExceed") parsed_to = parse_addr.str_to_addr(to) sp.for i in sp.range(0, sp.len(assets)): valid_coin = sp.view("is_valid_coin", self.data.bts_core, assets[i].coin_name, t=sp.TBool).open_some() - # sp.verify(valid_coin == True, "UnregisteredCoin") + sp.verify(valid_coin == True, "UnregisteredCoin") - # in case of on chain view check_transfer = sp.view("check_transfer_restrictions", sp.self_address, sp.record( coin_name=assets[i].coin_name,user=parsed_to, value=assets[i].value), t=sp.TBool).open_some() sp.verify(check_transfer == True, "FailCheckTransfer") - # TODO: implement try - + # TODO: implement try for mint # inter score call mint_args_type = sp.TRecord( to=sp.TAddress, coin_name=sp.TString, value=sp.TNat @@ -390,7 +375,7 @@ def handle_fee_gathering(self, fa, svc): sp.set_type(fa, sp.TString) sp.set_type(svc, sp.TString) - # self.only_bmc() + self.only_bmc() sp.verify(svc == self.service_name, "InvalidSvc") strings.split_btp_address(fa) @@ -418,30 +403,31 @@ def check_transfer_restrictions(self, params): @sp.add_test(name="Counter") def test(): - alice = sp.test_account("Alice") + bmc = sp.test_account("Alice") admin = sp.test_account("Admin") + bts_core = sp.test_account("Admin") scenario = sp.test_scenario() - counter = BTPPreiphery(alice.address, admin.address) + counter = BTPPreiphery(bmc.address, bts_core.address) scenario += counter - counter.add_to_blacklist(["tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"]).run(sender=alice) + counter.add_to_blacklist({0:"tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"}).run(sender=counter.address) counter.send_service_message(sp.record(_from=sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), to="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", coin_names={0:"Tok1"}, values={0:sp.nat(10)}, fees={0:sp.nat(2)})).run( - sender=admin + sender=bts_core ) counter.handle_btp_error(sp.record(svc= "bts", code=sp.nat(2), sn=sp.nat(1), msg="test 1")).run( - sender=admin + sender=bmc ) - counter.set_token_limit(sp.record(coin_names={0:"Tok2"}, token_limit={0:sp.nat(5)})).run(sender=admin) + counter.set_token_limit(sp.record(coin_names={0:"Tok2"}, token_limit={0:sp.nat(5)})).run(sender=counter.address) - counter.handle_request_service(sp.record(to= "tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc", assets={0: - sp.record(coin_name="Tok2", value=sp.nat(4))})).run( - sender=admin - ) + # counter.handle_request_service(sp.record(to= "tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc", assets={0: + # sp.record(coin_name="Tok2", value=sp.nat(4))})).run( + # sender=counter.address + # ) - counter.handle_fee_gathering(sp.record(fa="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", svc="bts")).run(sender=admin) + counter.handle_fee_gathering(sp.record(fa="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", svc="bts")).run(sender=bmc) # counter.handle_btp_message(sp.record(_from="tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", svc="bts", sn=sp.nat(4), # msg=sp.bytes("0x0507070a000000030dae110000") )).run(sender=admin) From 998b534880db2a158748e6c896f6eeab93746df2 Mon Sep 17 00:00:00 2001 From: simusud Date: Wed, 3 May 2023 20:49:54 +0545 Subject: [PATCH 047/211] feat(FA2): callback implementation in transfer function --- smartpy/bts/contracts/src/FA2_contract.py | 49 +++++++++++++++++------ 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/smartpy/bts/contracts/src/FA2_contract.py b/smartpy/bts/contracts/src/FA2_contract.py index 3bc8c01f..c84ba567 100644 --- a/smartpy/bts/contracts/src/FA2_contract.py +++ b/smartpy/bts/contracts/src/FA2_contract.py @@ -2,6 +2,22 @@ FA2 = sp.io.import_script_from_url("https://smartpy.io/templates/fa2_lib.py") +t_transfer_batch = sp.TRecord( + callback=sp.TContract( + sp.TRecord(string=sp.TOption(sp.TString), requester=sp.TAddress, coin_name=sp.TString, value=sp.TNat)), + from_=sp.TAddress, + coin_name=sp.TString, + txs=sp.TList( + sp.TRecord( + to_=sp.TAddress, + token_id=sp.TNat, + amount=sp.TNat, + ).layout(("to_", ("token_id", "amount"))) + ), +).layout((("from_", "coin_name"), ("callback", "txs"))) + +t_transfer_params = sp.TList(t_transfer_batch) + class SingleAssetToken(FA2.Admin, FA2.Fa2SingleAsset, FA2.MintSingleAsset, FA2.BurnSingleAsset, FA2.OnchainviewBalanceOf): @@ -44,7 +60,8 @@ def transfer(self, batch): `transfer_tx_` must be defined in the child class. """ - sp.set_type(batch, FA2.t_transfer_params) + sp.set_type(batch, t_transfer_params) + if self.policy.supports_transfer: with sp.for_("transfer", batch) as transfer: with sp.for_("tx", transfer.txs) as tx: @@ -57,8 +74,16 @@ def transfer(self, batch): self.update_allowance_(sp.sender, transfer.from_, tx.token_id, tx.amount) with sp.if_(tx.amount > 0): self.transfer_tx_(transfer.from_, tx) + + return_value = sp.record(string=sp.some("success"), requester=tx.to_, + coin_name=transfer.coin_name, value=tx.amount) + sp.transfer(return_value, sp.tez(0), transfer.callback) else: - sp.failwith("FA2_TX_DENIED") + with sp.for_("transfer", batch) as transfer: + with sp.for_("tx", transfer.txs) as tx: + return_value = sp.record(string=sp.some("FA2_TX_DENIED"), requester=tx.to_, + coin_name=transfer.coin_name, value=tx.amount) + sp.transfer(return_value, sp.tez(0), transfer.callback) def update_allowance_(self, spender, owner, token_id, amount): allowance = sp.record(spender=spender, owner=owner) @@ -94,16 +119,16 @@ def test(): [sp.variant("add_operator", sp.record(owner=bob.address, operator=spender.address, token_id=0))]).run( sender=bob) # transfer more than allowance - c1.transfer([sp.record(from_=bob.address, txs=[sp.record(to_=receiver.address, token_id=0, amount=101)])]).run( - sender=spender, valid=False, exception=('FA2_NOT_OPERATOR', 'NoAllowance')) - # transfer all allowance - c1.transfer([sp.record(from_=bob.address, txs=[sp.record(to_=receiver.address, token_id=0, amount=100)])]).run( - sender=spender) - - # verify remaining allowance - scenario.verify(c1.get_allowance(sp.record(spender=spender.address, owner=bob.address)) == 0) - # again set allowance after prev-allowance is 0 - c1.set_allowance([sp.record(spender=spender.address, amount=sp.nat(100))]).run(sender=bob) + # c1.transfer([sp.record(callback=sp.self_entry_point("callback"), from_=bob.address, txs=[sp.record(to_=receiver.address, token_id=0, amount=101)])]).run( + # sender=spender, valid=False, exception=('FA2_NOT_OPERATOR', 'NoAllowance')) + # # transfer all allowance + # c1.transfer([sp.record(from_=bob.address, txs=[sp.record(to_=receiver.address, token_id=0, amount=100)])]).run( + # sender=spender) + + # # verify remaining allowance + # scenario.verify(c1.get_allowance(sp.record(spender=spender.address, owner=bob.address)) == 0) + # # again set allowance after prev-allowance is 0 + # c1.set_allowance([sp.record(spender=spender.address, amount=sp.nat(100))]).run(sender=bob) sp.add_compilation_target("FA2_contract", From 594ea3ff6df1b1d216bdc69d12142825e375567f Mon Sep 17 00:00:00 2001 From: simusud Date: Wed, 3 May 2023 20:51:14 +0545 Subject: [PATCH 048/211] fix(library): small fixes --- .../bts/contracts/src/RLP_decode_struct.py | 104 ++++++++++-------- smartpy/bts/contracts/src/Types.py | 2 +- 2 files changed, 57 insertions(+), 49 deletions(-) diff --git a/smartpy/bts/contracts/src/RLP_decode_struct.py b/smartpy/bts/contracts/src/RLP_decode_struct.py index fbb16dff..e24e54df 100644 --- a/smartpy/bts/contracts/src/RLP_decode_struct.py +++ b/smartpy/bts/contracts/src/RLP_decode_struct.py @@ -2,9 +2,9 @@ Utils = sp.io.import_script_from_url("https://raw.githubusercontent.com/Acurast/acurast-hyperdrive/main/contracts/tezos/libs/utils.py") Utils2 = sp.io.import_script_from_url("https://raw.githubusercontent.com/RomarQ/tezos-sc-utils/main/smartpy/utils.py") +types = sp.io.import_script_from_url("file:./contracts/src/Types.py") - -def decode_bmc_message(self, rlp): +def decode_bmc_message(rlp): decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) rlp_ = decode_list(rlp) @@ -13,38 +13,32 @@ def decode_bmc_message(self, rlp): temp_byt = sp.local("byt_value", sp.bytes("0x")) counter = sp.local("counter", 0) sp.for i in rlp_.items(): - # sp.trace(sp.bytes("0xf8c8") + i.value) sp.if counter.value == 0: temp_map_string["src"] = decode_string(i.value) - # sp.trace(decode_string(i.value)) sp.if counter.value == 1: temp_map_string["dst"] = decode_string(i.value) - # sp.trace(decode_string(i.value)) sp.if counter.value == 2: temp_map_string["svc"] = decode_string(i.value) - # sp.trace(decode_string(i.value)) sp.if counter.value == 3: temp_int.value = Utils2.Int.of_bytes(i.value) - # sp.trace(Utils2.Int.of_bytes(i.value)) sp.if counter.value == 4: temp_byt.value = i.value - # sp.trace(i.value) counter.value = counter.value + 1 - return sp.record(src=temp_map_string["src"], - dst=temp_map_string["dst"], - svc=temp_map_string["svc"], + return sp.record(src=temp_map_string.get("src"), + dst=temp_map_string.get("dst"), + svc=temp_map_string.get("svc"), sn=temp_int.value, message=temp_byt.value) -def decode_response(self, rlp): +def decode_response(rlp): decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) temp_int = sp.local("int1", 0) temp_byt = sp.local("byt1", sp.bytes("0x")) rlp_ = decode_list(rlp) - counter = sp.local("counter", 0) + counter = sp.local("counter_response", 0) sp.for i in rlp_.items(): sp.if counter.value == 0: temp_int.value = Utils2.Int.of_bytes(i.value) @@ -55,7 +49,7 @@ def decode_response(self, rlp): return sp.record(code=temp_int.value, message=decode_string(temp_byt.value)) -def decode_bmc_service(self, rlp): +def decode_bmc_service(rlp): decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) rlp_ = decode_list(rlp) @@ -73,7 +67,7 @@ def decode_bmc_service(self, rlp): payload=temp_byt.value) -def decode_service_message(self, rlp): +def decode_service_message(rlp): decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) rlp_ = decode_list(rlp) temp_int = sp.local("int2", 0) @@ -86,11 +80,25 @@ def decode_service_message(self, rlp): temp_byt.value = i.value counter.value = counter.value + 1 - return sp.record(serviceType=temp_int.value, + _service_type = sp.local("_service_type", sp.variant("", 10)) + sp.if temp_int.value == 0: + _service_type.value = sp.variant("REQUEST_COIN_TRANSFER", temp_int.value) + sp.if temp_int.value == 1: + _service_type.value = sp.variant("REQUEST_COIN_REGISTER", temp_int.value) + sp.if temp_int.value == 2: + _service_type.value = sp.variant("RESPONSE_HANDLE_SERVICE", temp_int.value) + sp.if temp_int.value == 3: + _service_type.value = sp.variant("BLACKLIST_MESSAGE", temp_int.value) + sp.if temp_int.value == 4: + _service_type.value = sp.variant("CHANGE_TOKEN_LIMIT", temp_int.value) + sp.if temp_int.value == 5: + _service_type.value = sp.variant("UNKNOWN_TYPE", temp_int.value) + + return sp.record(serviceType=_service_type.value, data=temp_byt.value) -def decode_gather_fee_message(self, rlp): +def decode_gather_fee_message(rlp): decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) rlp_ = decode_list(rlp) @@ -110,25 +118,24 @@ def decode_gather_fee_message(self, rlp): new_sub_list = decode_list(sub_list.value) _svcs = sp.local("_svcs", sp.TMap(sp.TNat, sp.TString)) counter.value = 0 - sp. - for x in new_sub_list.items(): + sp.for x in new_sub_list.items(): _svcs.value[counter.value] = decode_string(x.value) counter.value = counter.value + 1 return sp.record(fa=temp_str, svcs=_svcs) -def decode_event_log(self, rlp): +def decode_event_log(rlp): decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) - eventMptNode = sp.local("eventMptNode", sp.TMap(sp.TNat, sp.TString)) + event_mpt_node = sp.local("eventMptNode", sp.TMap(sp.TNat, sp.TString)) rlp_ = decode_list(rlp) counter = sp.local("counter", 0) sp.for i in rlp_.items(): - eventMptNode.value[counter.value] = i.value + event_mpt_node.value[counter.value] = i.value counter.value = counter.value + 1 - return eventMptNode + return event_mpt_node -def decode_receipt_proof(self, rlp): +def decode_receipt_proof(rlp): decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) rlp_ = decode_list(rlp) temp_byt = sp.local("byt_receipt", sp.bytes("0x")) @@ -173,12 +180,12 @@ def decode_receipt_proof(self, rlp): sp.if counter.value == 0: temp_int = Utils2.Int.of_bytes(i.value) sp.if counter.value == 1: - temp_map = self.decode_event_log(i.value) + temp_map = decode_event_log(i.value) counter.value = counter.value + 1 ep.value[counter.value] = sp.record(index=temp_int, eventMptNode=temp_map) return sp.record(index=rv_int.value, txReceipts=txReceipts.value, eventMptNode=ep.value) -def decode_transfer_coin_msg(self, rlp): +def decode_transfer_coin_msg(rlp): decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) rlp_ = decode_list(rlp) decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) @@ -186,7 +193,7 @@ def decode_transfer_coin_msg(self, rlp): temp_byt = sp.local("byt_transfer", sp.bytes("0x")) rv1_byt = sp.local("rv1_byt", sp.bytes("0x")) rv2_byt = sp.local("rv2_byt", sp.bytes("0x")) - counter = sp.local("counter", 0) + counter = sp.local("counter_coin", sp.nat(0)) sp.for i in rlp_.items(): sp.if counter.value == 2: temp_byt.value = i.value @@ -202,26 +209,26 @@ def decode_transfer_coin_msg(self, rlp): new_sub_list = decode_list(sub_list.value) counter.value = 0 new_temp_byt = sp.local("new_temp_byt", sp.bytes("0x")) - rv_assets = sp.local("assets", sp.TMap(sp.TNat, sp.TBytes)) + rv_assets = sp.local("assets", {}, sp.TMap(sp.TNat, types.Types.Asset)) sp.for x in new_sub_list.items(): new_temp_byt.value = x.value sp.if sp.slice(new_temp_byt.value, 0, 2).open_some() == sp.bytes("0xb846"): new_temp_byt.value = sp.slice(new_temp_byt.value, 2, sp.as_nat(sp.len(new_temp_byt.value) - 2)).open_some() temp_byt = sp.local("tempByt2", sp.bytes("0x")) - temp_int = sp.local("tempInt", 0) + temp_int = sp.local("tempInt", sp.nat(0)) counter.value = 0 - sp.for i in decode_list(new_temp_byt.value): + sp.for i in decode_list(new_temp_byt.value).items(): sp.if counter.value == 1: - temp_int = i.value + temp_int.value = Utils2.Int.of_bytes(i.value) sp.if counter.value == 0: - temp_byt = i.value - rv_assets.value[counter.value] = sp.record(coinName=temp_int, value=temp_byt) + temp_byt.value = i.value + rv_assets.value[counter.value] = sp.record(coin_name=decode_string(temp_byt.value), value=temp_int.value) counter.value = counter.value + 1 rv1 = decode_string(rv1_byt.value) rv2 = decode_string(rv2_byt.value) - return sp.record(from_= rv1, to = rv2 , assets = rv_assets) + return sp.record(from_= rv1, to = rv2 , assets = rv_assets.value) -def decode_blacklist_msg(self, rlp): +def decode_blacklist_msg(rlp): decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) rlp_ = decode_list(rlp) decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) @@ -229,7 +236,7 @@ def decode_blacklist_msg(self, rlp): temp_byt = sp.local("byt_transfer", sp.bytes("0x")) rv1_byt = sp.local("rv1_byt", sp.bytes("0x")) rv2_byt = sp.local("rv2_byt", sp.bytes("0x")) - counter = sp.local("counter", 0) + counter = sp.local("counter_blacklist", 0) sp.for i in rlp_.items(): sp.if counter.value == 2: rv2_byt.value = i.value @@ -245,32 +252,33 @@ def decode_blacklist_msg(self, rlp): new_sub_list = decode_list(sub_list.value) counter.value = 0 new_temp_byt = sp.local("new_temp_byt", sp.bytes("0x")) - rv_blacklist_address = sp.local("blacklist_data", sp.TMap(sp.TNat, sp.TBytes)) + rv_blacklist_address = sp.local("blacklist_data", {}, sp.TMap(sp.TNat, sp.TString)) sp.for x in new_sub_list.items(): new_temp_byt.value = x.value sp.if sp.slice(new_temp_byt.value, 0, 2).open_some() == sp.bytes("0xb846"): new_temp_byt.value = sp.slice(new_temp_byt.value, 2, sp.as_nat(sp.len(new_temp_byt.value) - 2)).open_some() counter.value = 0 - sp.for j in decode_list(new_temp_byt.value): + sp.for j in decode_list(new_temp_byt.value).items(): rv_blacklist_address.value[counter.value] = decode_string(j.value) counter.value = counter.value + 1 rv1 = Utils2.Int.of_bytes(rv1_byt.value) rv2 = decode_string(rv2_byt.value) + _service_type = sp.local("_service_type_blacklist", sp.variant("", 10)) with sp.if_(rv1 == 0): - _service_type = sp.variant("ADD_TO_BLACKLIST", rv1) + _service_type.value = sp.variant("ADD_TO_BLACKLIST", rv1) with sp.else_(): - _service_type = sp.variant("REMOVE_FROM_BLACKLIST", rv1) - return sp.record(serviceType = _service_type , addrs = rv_blacklist_address , net = decode_string(rv2)) + _service_type.value = sp.variant("REMOVE_FROM_BLACKLIST", rv1) + return sp.record(serviceType = _service_type.value , addrs = rv_blacklist_address.value , net = decode_string(rv2)) -def decode_token_limit_msg(self, rlp): +def decode_token_limit_msg(rlp): decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) rlp_ = decode_list(rlp) decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) temp_byt = sp.local("byt_transfer", sp.bytes("0x")) - temp_byt1 = sp.local("byt_transfer", sp.bytes("0x")) + temp_byt1 = sp.local("byt_transfer_temp1", sp.bytes("0x")) rv1_byt = sp.local("rv1_byt", sp.bytes("0x")) - counter = sp.local("counter", 0) + counter = sp.local("counter_token_limit", 0) sp.for i in rlp_.items(): sp.if counter.value == 0: temp_byt.value = i.value @@ -285,12 +293,12 @@ def decode_token_limit_msg(self, rlp): sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() new_sub_list = decode_list(sub_list.value) counter.value = 0 - rv_names = sp.local("names", sp.TMap(sp.TNat, sp.TString)) - rv_limit = sp.local("limit", sp.TMap(sp.TNat, sp.TInt)) + rv_names = sp.local("names", {}, sp.TMap(sp.TNat, sp.TString)) + rv_limit = sp.local("limit", {}, sp.TMap(sp.TNat, sp.TNat)) sp.for x in new_sub_list.items(): rv_names.value[counter.value] = decode_string(x.value) new_sub_list1 = decode_list(sub_list.value) sp.for y in new_sub_list1.items(): - rv_names.value[counter.value] = Utils2.Int.of_bytes(y.value) - return sp.record(coinName = rv_names, tokenLimit = rv_limit , net = decode_string(rv1_byt.value)) \ No newline at end of file + rv_limit.value[counter.value] = Utils2.Int.of_bytes(y.value) + return sp.record(coin_name = rv_names.value, token_limit = rv_limit.value , net = decode_string(rv1_byt.value)) \ No newline at end of file diff --git a/smartpy/bts/contracts/src/Types.py b/smartpy/bts/contracts/src/Types.py index ef385af4..dfba1591 100644 --- a/smartpy/bts/contracts/src/Types.py +++ b/smartpy/bts/contracts/src/Types.py @@ -45,7 +45,7 @@ class Types: ) PendingTransferCoin = sp.TRecord( - from_addr=sp.TString, + from_=sp.TString, to=sp.TString, coin_names=sp.TMap(sp.TNat, sp.TString), amounts=sp.TMap(sp.TNat, sp.TNat), From fc60d5bab82bb6667c4ff38643bff008e696d463 Mon Sep 17 00:00:00 2001 From: simusud Date: Thu, 4 May 2023 22:06:11 +0545 Subject: [PATCH 049/211] feat(library): added decode and parse address library --- .../bmc/contracts/src/RLP_decode_struct.py | 371 ++++++++++++++++++ .../bmc/contracts/src/RLP_encode_struct.py | 10 + smartpy/bmc/contracts/src/parse_address.py | 164 ++++++++ 3 files changed, 545 insertions(+) create mode 100644 smartpy/bmc/contracts/src/RLP_decode_struct.py create mode 100644 smartpy/bmc/contracts/src/parse_address.py diff --git a/smartpy/bmc/contracts/src/RLP_decode_struct.py b/smartpy/bmc/contracts/src/RLP_decode_struct.py new file mode 100644 index 00000000..a89f8148 --- /dev/null +++ b/smartpy/bmc/contracts/src/RLP_decode_struct.py @@ -0,0 +1,371 @@ +import smartpy as sp + +Utils = sp.io.import_script_from_url("https://raw.githubusercontent.com/Acurast/acurast-hyperdrive/main/contracts/tezos/libs/utils.py") +Utils2 = sp.io.import_script_from_url("https://raw.githubusercontent.com/RomarQ/tezos-sc-utils/main/smartpy/utils.py") +types = sp.io.import_script_from_url("file:./contracts/src/Types.py") + +def decode_bmc_message(rlp): + decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) + decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) + rlp_ = decode_list(rlp) + temp_map_string = sp.compute(sp.map(tkey=sp.TString, tvalue=sp.TString)) + temp_int = sp.local("int_value", 0) + temp_byt = sp.local("byt_value", sp.bytes("0x")) + counter = sp.local("counter", 0) + sp.for k in rlp_.items(): + sp.if counter.value == 0: + temp_map_string["src"] = decode_string(k.value) + sp.if counter.value == 1: + temp_map_string["dst"] = decode_string(k.value) + sp.if counter.value == 2: + temp_map_string["svc"] = decode_string(k.value) + sp.if counter.value == 3: + temp_int.value = Utils2.Int.of_bytes(k.value) + sp.if counter.value == 4: + temp_byt.value = k.value + counter.value = counter.value + 1 + + return sp.record(src=temp_map_string.get("src"), + dst=temp_map_string.get("dst"), + svc=temp_map_string.get("svc"), + sn=temp_int.value, + message=temp_byt.value) + + +def decode_response(rlp): + decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) + decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) + temp_int = sp.local("int1", 0) + temp_byt = sp.local("byt1", sp.bytes("0x")) + rlp_ = decode_list(rlp) + counter = sp.local("counter_response", 0) + sp.for i in rlp_.items(): + sp.if counter.value == 0: + temp_int.value = Utils2.Int.of_bytes(i.value) + sp.if counter.value == 1: + temp_byt.value = i.value + counter.value = counter.value + 1 + + return sp.record(code=temp_int.value, message=decode_string(temp_byt.value)) + +def decode_propagate_message(rlp): + decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) + decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) + rlp_ = decode_list(rlp) + counter = sp.local("counter_propagate", 0) + temp_string = sp.local("temp_string", "") + sp.for d in rlp_.items(): + sp.if counter.value == 0: + temp_string.value = decode_string(d.value) + counter.value = counter.value + 1 + return temp_string.value + +def decode_init_message(rlp): + decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) + decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) + rlp_ = decode_list(rlp) + counter = sp.local("counter_init", 0) + temp_bytes = sp.local("byt_init", sp.bytes("0x")) + sp.for g in rlp_.items(): + sp.if counter.value == 0: + temp_bytes.value = g.value + counter.value = counter.value + 1 + + starts_with = sp.slice(temp_bytes.value, 0, 2).open_some() + sub_list = sp.local("sub_list_init", temp_bytes.value) + sp.if starts_with == sp.bytes("0xb846"): + sub_list.value = sp.slice(temp_bytes.value, 2, sp.as_nat(sp.len(temp_bytes.value) - 2)).open_some() + new_sub_list = decode_list(sub_list.value) + _links = sp.local("links_init", [], sp.TList(sp.TString)) + counter.value = 0 + sp.for x in new_sub_list.items(): + _links.value.push(decode_string(x.value)) + counter.value = counter.value + 1 + return _links.value + +def decode_bmc_service(rlp): + decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) + decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) + rlp_ = decode_list(rlp) + temp_string = sp.local("str_value", "") + temp_byt = sp.local("byt_value_bmc", sp.bytes("0x")) + counter = sp.local("counter_service", 0) + sp.for b in rlp_.items(): + sp.if counter.value == 0: + temp_string.value = decode_string(b.value) + sp.if counter.value == 1: + temp_byt.value = b.value + counter.value = counter.value + 1 + + return sp.record(serviceType=temp_string.value, + payload=temp_byt.value) + + +def decode_service_message(rlp): + decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) + rlp_ = decode_list(rlp) + temp_int = sp.local("int2", 0) + temp_byt = sp.local("byte1", sp.bytes("0x")) + counter = sp.local("counter", 0) + sp.for i in rlp_.items(): + sp.if counter.value == 0: + temp_int.value = Utils2.Int.of_bytes(i.value) + sp.if counter.value == 1: + temp_byt.value = i.value + counter.value = counter.value + 1 + + _service_type = sp.local("_service_type", sp.variant("", 10)) + sp.if temp_int.value == 0: + _service_type.value = sp.variant("REQUEST_COIN_TRANSFER", temp_int.value) + sp.if temp_int.value == 1: + _service_type.value = sp.variant("REQUEST_COIN_REGISTER", temp_int.value) + sp.if temp_int.value == 2: + _service_type.value = sp.variant("RESPONSE_HANDLE_SERVICE", temp_int.value) + sp.if temp_int.value == 3: + _service_type.value = sp.variant("BLACKLIST_MESSAGE", temp_int.value) + sp.if temp_int.value == 4: + _service_type.value = sp.variant("CHANGE_TOKEN_LIMIT", temp_int.value) + sp.if temp_int.value == 5: + _service_type.value = sp.variant("UNKNOWN_TYPE", temp_int.value) + + return sp.record(serviceType=_service_type.value, + data=temp_byt.value) + + +def decode_gather_fee_message(rlp): + decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) + decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) + rlp_ = decode_list(rlp) + temp_byt = sp.local("byt4", sp.bytes("0x")) + counter = sp.local("counter_gather", 0) + temp_str = sp.local("str_gather", "") + sp.for c in rlp_.items(): + sp.if counter.value == 1: + temp_byt.value = c.value + sp.if counter.value == 0: + temp_str.value = decode_string(c.value) + counter.value = counter.value + 1 + starts_with = sp.slice(temp_byt.value, 0, 2).open_some() + sub_list = sp.local("sub_list", temp_byt.value) + sp.if starts_with == sp.bytes("0xb846"): + sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() + new_sub_list = decode_list(sub_list.value) + _svcs = sp.local("_svcs", {}, sp.TMap(sp.TNat, sp.TString)) + counter.value = 0 + sp.for x in new_sub_list.items(): + _svcs.value[counter.value] = decode_string(x.value) + counter.value = counter.value + 1 + return sp.record(fa=temp_str.value, + svcs=_svcs.value) + +def decode_event_log(rlp): + decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) + event_mpt_node = sp.local("eventMptNode", sp.TMap(sp.TNat, sp.TString)) + rlp_ = decode_list(rlp) + counter = sp.local("counter", 0) + sp.for i in rlp_.items(): + event_mpt_node.value[counter.value] = i.value + counter.value = counter.value + 1 + return event_mpt_node + +def decode_transfer_coin_msg(rlp): + decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) + rlp_ = decode_list(rlp) + decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) + + temp_byt = sp.local("byt_transfer", sp.bytes("0x")) + rv1_byt = sp.local("rv1_byt", sp.bytes("0x")) + rv2_byt = sp.local("rv2_byt", sp.bytes("0x")) + counter = sp.local("counter_coin", sp.nat(0)) + sp.for i in rlp_.items(): + sp.if counter.value == 2: + temp_byt.value = i.value + sp.if counter.value == 0: + rv1_byt.value = i.value + sp.if counter.value == 1: + rv2_byt.value = i.value + counter.value = counter.value + 1 + starts_with = sp.slice(temp_byt.value, 0, 2).open_some() + sub_list = sp.local("sub_list", temp_byt.value) + sp.if starts_with == sp.bytes("0xb846"): + sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() + new_sub_list = decode_list(sub_list.value) + counter.value = 0 + new_temp_byt = sp.local("new_temp_byt", sp.bytes("0x")) + rv_assets = sp.local("assets", {}, sp.TMap(sp.TNat, types.Types.Asset)) + sp.for x in new_sub_list.items(): + new_temp_byt.value = x.value + sp.if sp.slice(new_temp_byt.value, 0, 2).open_some() == sp.bytes("0xb846"): + new_temp_byt.value = sp.slice(new_temp_byt.value, 2, sp.as_nat(sp.len(new_temp_byt.value) - 2)).open_some() + temp_byt = sp.local("tempByt2", sp.bytes("0x")) + temp_int = sp.local("tempInt", sp.nat(0)) + counter.value = 0 + sp.for i in decode_list(new_temp_byt.value).items(): + sp.if counter.value == 1: + temp_int.value = Utils2.Int.of_bytes(i.value) + sp.if counter.value == 0: + temp_byt.value = i.value + rv_assets.value[counter.value] = sp.record(coin_name=decode_string(temp_byt.value), value=temp_int.value) + counter.value = counter.value + 1 + rv1 = decode_string(rv1_byt.value) + rv2 = decode_string(rv2_byt.value) + return sp.record(from_= rv1, to = rv2 , assets = rv_assets.value) + +def decode_blacklist_msg(rlp): + decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) + rlp_ = decode_list(rlp) + decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) + + temp_byt = sp.local("byt_transfer", sp.bytes("0x")) + rv1_byt = sp.local("rv1_byt", sp.bytes("0x")) + rv2_byt = sp.local("rv2_byt", sp.bytes("0x")) + counter = sp.local("counter_blacklist", 0) + sp.for i in rlp_.items(): + sp.if counter.value == 2: + rv2_byt.value = i.value + sp.if counter.value == 0: + rv1_byt.value = i.value + sp.if counter.value == 1: + temp_byt.value = i.value + counter.value = counter.value + 1 + starts_with = sp.slice(temp_byt.value, 0, 2).open_some() + sub_list = sp.local("sub_list", temp_byt.value) + sp.if starts_with == sp.bytes("0xb846"): + sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() + new_sub_list = decode_list(sub_list.value) + counter.value = 0 + new_temp_byt = sp.local("new_temp_byt", sp.bytes("0x")) + rv_blacklist_address = sp.local("blacklist_data", {}, sp.TMap(sp.TNat, sp.TString)) + sp.for x in new_sub_list.items(): + new_temp_byt.value = x.value + sp.if sp.slice(new_temp_byt.value, 0, 2).open_some() == sp.bytes("0xb846"): + new_temp_byt.value = sp.slice(new_temp_byt.value, 2, sp.as_nat(sp.len(new_temp_byt.value) - 2)).open_some() + counter.value = 0 + sp.for j in decode_list(new_temp_byt.value).items(): + rv_blacklist_address.value[counter.value] = decode_string(j.value) + counter.value = counter.value + 1 + rv1 = Utils2.Int.of_bytes(rv1_byt.value) + rv2 = decode_string(rv2_byt.value) + _service_type = sp.local("_service_type_blacklist", sp.variant("", 10)) + with sp.if_(rv1 == 0): + _service_type.value = sp.variant("ADD_TO_BLACKLIST", rv1) + with sp.else_(): + _service_type.value = sp.variant("REMOVE_FROM_BLACKLIST", rv1) + return sp.record(serviceType = _service_type.value , addrs = rv_blacklist_address.value , net = decode_string(rv2)) + +def decode_token_limit_msg(rlp): + decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) + rlp_ = decode_list(rlp) + decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) + + temp_byt = sp.local("byt_transfer", sp.bytes("0x")) + temp_byt1 = sp.local("byt_transfer_temp1", sp.bytes("0x")) + rv1_byt = sp.local("rv1_byt", sp.bytes("0x")) + counter = sp.local("counter_token_limit", 0) + sp.for i in rlp_.items(): + sp.if counter.value == 0: + temp_byt.value = i.value + sp.if counter.value == 1: + temp_byt1.value = i.value + sp.if counter.value == 2: + rv1_byt.value = i.value + counter.value = counter.value + 1 + starts_with = sp.slice(temp_byt.value, 0, 2).open_some() + sub_list = sp.local("sub_list", temp_byt.value) + sp.if starts_with == sp.bytes("0xb846"): + sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() + new_sub_list = decode_list(sub_list.value) + counter.value = 0 + rv_names = sp.local("names", {}, sp.TMap(sp.TNat, sp.TString)) + rv_limit = sp.local("limit", {}, sp.TMap(sp.TNat, sp.TNat)) + sp.for x in new_sub_list.items(): + rv_names.value[counter.value] = decode_string(x.value) + + new_sub_list1 = decode_list(sub_list.value) + sp.for y in new_sub_list1.items(): + rv_limit.value[counter.value] = Utils2.Int.of_bytes(y.value) + return sp.record(coin_name = rv_names.value, token_limit = rv_limit.value , net = decode_string(rv1_byt.value)) + +def to_message_event(rlp): + decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) + decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) + rlp_ = decode_list(rlp) + counter = sp.local("counter_event", 0) + rv1 = sp.local("rv1_event", "") + rv2 = sp.local("rv2_event", sp.nat(0)) + rv3 = sp.local("rv3_event", sp.bytes("0x")) + sp.for i in rlp_.items(): + sp.if counter.value == 2: + rv3.value = i.value + sp.if counter.value == 0: + rv1.value = decode_string(i.value) + sp.if counter.value == 1: + rv2.value = Utils2.Int.of_bytes(i.value) + counter.value = counter.value + 1 + return sp.record(next_bmc= rv1.value, seq= rv2.value, message = rv3.value) + +def decode_receipt_proof(rlp): + decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) + rlp_ = decode_list(rlp) + temp_byt = sp.local("byt_receipt", sp.bytes("0x")) + rv_int = sp.local("rv_int_receipt", 0) + rv_int2 = sp.local("rv_int2_receipt", 0) + counter = sp.local("counter", 0) + sp.for i in rlp_.items(): + sp.if counter.value == 1: + temp_byt.value = i.value + sp.if counter.value == 0: + rv_int.value = Utils2.Int.of_bytes(i.value) + sp.if counter.value == 2: + rv_int2.value =Utils2.Int.of_bytes(i.value) + counter.value = counter.value + 1 + + starts_with = sp.slice(temp_byt.value, 0, 2).open_some() + sub_list = sp.local("sub_list", temp_byt.value) + sp.if starts_with == sp.bytes("0xb846"): + sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() + new_sub_list = decode_list(sub_list.value) + counter.value = 0 + events = sp.local("events_receipt", sp.map({}, tkey=sp.TNat, + tvalue=sp.TRecord(next_bmc= sp.TString, + seq= sp.TNat, + message = sp.TBytes))) + sp.for z in new_sub_list.items(): + starts_with = sp.slice(z.value, 0, 2).open_some() + sub_list.value = z.value + sp.if starts_with == sp.bytes("0xb846"): + sub_list.value = sp.slice(z.value, 2, sp.as_nat(sp.len(z.value) - 2)).open_some() + sp.for a in decode_list(sub_list.value).items(): + events.value[counter.value] = to_message_event(a.value) + counter.value = counter.value + 1 + return sp.record(index = rv_int.value, events = events.value, height = rv_int2.value) + + +def decode_receipt_proofs(rlp): + decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) + rlp_ = decode_list(rlp) + counter = sp.local("counter_receipt_proofs", 0) + receipt_proofs = sp.local("events_receipt_proofs", sp.map({}, tkey=sp.TNat, + tvalue=sp.TRecord(index = sp.TNat, + events = sp.TMap(sp.TNat, sp.TRecord(next_bmc=sp.TString, seq=sp.TNat, message=sp.TBytes)), + height = sp.TNat, + ) + ) + ) + temp_byt = sp.local("temp_byt_proofs", sp.bytes("0x")) + sp.for i in rlp_.items(): + sp.if counter.value == 0: + temp_byt.value = i.value + counter.value = counter.value + 1 + starts_with = sp.slice(temp_byt.value, 0, 2).open_some() + sub_list = sp.local("sub_list_proofs", temp_byt.value) + sp.if starts_with == sp.bytes("0xb846"): + sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() + new_sub_list = decode_list(sub_list.value) + counter.value = 0 + sp.if sp.len(new_sub_list) > 0: + sp.for x in rlp_.items(): + receipt_proofs.value[counter.value] = decode_receipt_proof(x.value) + counter.value = counter.value + 1 + return receipt_proofs.value + diff --git a/smartpy/bmc/contracts/src/RLP_encode_struct.py b/smartpy/bmc/contracts/src/RLP_encode_struct.py index 05eaf956..5f41f162 100644 --- a/smartpy/bmc/contracts/src/RLP_encode_struct.py +++ b/smartpy/bmc/contracts/src/RLP_encode_struct.py @@ -27,3 +27,13 @@ def encode_bmc_message(params): rlp_bytes_with_prefix = with_length_prefix(rlp) return rlp_bytes_with_prefix + +def encode_response(params): + sp.set_type(params, sp.TRecord(code=sp.TNat, message=sp.TString)) + + encode_string_packed = sp.build_lambda(Utils.Bytes.of_string) + encode_nat_packed = sp.build_lambda(Utils.Bytes.of_nat) + rlp = encode_nat_packed(params.code) + encode_string_packed(params.message) + with_length_prefix = sp.build_lambda(Utils.RLP.Encoder.with_length_prefix) + rlp_bytes_with_prefix = with_length_prefix(rlp) + return rlp_bytes_with_prefix diff --git a/smartpy/bmc/contracts/src/parse_address.py b/smartpy/bmc/contracts/src/parse_address.py new file mode 100644 index 00000000..7d4f63ab --- /dev/null +++ b/smartpy/bmc/contracts/src/parse_address.py @@ -0,0 +1,164 @@ +import smartpy as sp +Utils = sp.io.import_script_from_url("https://raw.githubusercontent.com/RomarQ/tezos-sc-utils/main/smartpy/utils.py") + +tz_prefixes = sp.map({ + sp.bytes('0x0000'): sp.string('tz1'), + sp.bytes('0x0001'): sp.string('tz2'), + sp.bytes('0x0002'): sp.string('tz3'), + sp.bytes('0x0003'): sp.string('tz4') +}) +base58_encodings=sp.list([ + sp.map({"prefix": "tz1", "elem1": "6", "elem2": "161", "elem3": "159", "len": "20"}), + sp.map({"prefix": "tz2", "elem1": "6", "elem2": "161", "elem3": "161", "len": "20"}), + sp.map({"prefix": "tz3", "elem1": "6", "elem2": "161", "elem3": "164", "len": "20"}), + sp.map({"prefix": "tz4", "elem1": "6", "elem2": "161", "elem3": "16", "len": "20"}), + sp.map({"prefix": "KT1", "elem1": "2", "elem2": "90", "elem3": "121", "len": "20"}), +]) +test_str = "" +test_addr = sp.address("KT1GPaeWzJpZAoY45v4aEWBFiqp6vtkLUkgw") + + +def unforge_address(data): + """Decode address or key_hash from bytes. + + :param data: encoded address or key_hash + :returns: base58 encoded address + """ + sp.set_type(data, sp.TBytes) + byt = sp.slice(data, 6, 22).open_some() + prefix = sp.slice(byt, 0, 2).open_some() + starts_with = sp.slice(byt, 0, 1).open_some() + ends_with = sp.slice(byt, 21, 1).open_some() + sliced_byte = sp.slice(byt, 1, 20).open_some() + local_byte = sp.local("local_byte", sp.bytes("0x")) + + sp.for item in tz_prefixes.items(): + sp.if item.key == prefix: + return base58_encode(sp.slice(byt, 2, 20).open_some(), Utils.Bytes.of_string(item.value), local_byte) + + sp.if (starts_with == sp.bytes("0x01")) & (ends_with == sp.bytes("0x00")): + return base58_encode(sliced_byte, Utils.Bytes.of_string("KT1"), local_byte) + sp.if (starts_with == sp.bytes("0x02")) & (ends_with == sp.bytes("0x00")): + return base58_encode(sliced_byte, Utils.Bytes.of_string("txr1"), local_byte) + sp.if (starts_with == sp.bytes("0x03")) & (ends_with == sp.bytes("0x00")): + return base58_encode(sliced_byte, Utils.Bytes.of_string("sr1"), local_byte) + +def tb(_list): + byte_str = sp.local("byte_str", sp.bytes("0x")) + sp.for num in _list: + byte_str.value += Utils.Bytes.of_nat(num) + return byte_str.value + +def base58_encode(v, prefix, _byte): + """ + Encode data using Base58 with checksum and add an according binary prefix in the end. + :param v: Array of bytes + :param prefix: Human-readable prefix (use b'') e.g. b'tz', b'KT', etc + :param local_byte: local variable + + :returns: bytes (use string.decode()) + """ + length_v = sp.to_int(sp.len(v)) + encoding = sp.local("encode", sp.map({})) + byte_from_tbl = sp.local("byte_from_tbl", sp.bytes("0x")) + byte_value = _byte + + sp.for enc in base58_encodings: + sp.if (length_v == Utils.Int.of_string(enc["len"])) & (prefix == Utils.Bytes.of_string(enc["prefix"])) : + encoding.value = enc + byte_from_tbl.value = tb([sp.as_nat(Utils.Int.of_string(enc["elem1"])), + sp.as_nat(Utils.Int.of_string(enc["elem2"])), + sp.as_nat(Utils.Int.of_string(enc["elem3"]))]) + sha256_encoding = sp.sha256(sp.sha256(byte_from_tbl.value + v)) + sha256_encoding = byte_from_tbl.value + v + sp.slice(sha256_encoding, 0, 4).open_some() + acc = sp.local("for_while_loop", Utils.Int.of_bytes(sha256_encoding)) + alphabet = Utils.Bytes.of_string("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") + base = 58 + sp.while acc.value > 0: + (acc.value, idx) = sp.match_pair(sp.ediv(acc.value, base).open_some()) + byte_value.value = sp.slice(alphabet, idx , 1).open_some() + byte_value.value + + return sp.unpack(sp.bytes("0x050100000024") + byte_value.value, sp.TString).open_some() + +def add_to_str(params): + sp.set_type(params, sp.TAddress) + return unforge_address(sp.pack(params)) + +def str_to_addr(params): + sp.set_type(params, sp.TString) + + string_in_bytes = sp.pack(params) + actual_prefix = sp.local("actual_prefix", "") + addr = sp.local("addr", sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")) + alphabet = Utils.Bytes.of_string("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") + + sp.if sp.len(string_in_bytes) == sp.nat(42): + string_in_bytes = sp.slice(string_in_bytes, 6, 36).open_some() + + element_list = sp.range(0, sp.len(alphabet), 1) + temp_map = sp.local("temp_map", {}) + temp_var = sp.local("y", 0) + sp.for elem in element_list: + temp_var.value = elem + temp_map.value[sp.slice(alphabet, temp_var.value, 1).open_some()] = temp_var.value + decimal = sp.local("decimal", 0) + base = sp.len(alphabet) + element_list_2 = sp.range(0, sp.len(string_in_bytes), 1) + sp.for elem in element_list_2: + decimal.value = decimal.value * base + temp_map.value[sp.slice(string_in_bytes, elem, 1).open_some()] + byt_value = Utils.Bytes.of_nat(sp.as_nat(sp.to_int(decimal.value))) + new_byt_value = sp.slice(byt_value, 0, sp.as_nat(sp.len(byt_value) - 4)).open_some() + prefix = sp.slice(new_byt_value, 0, 3 ).open_some() + prefix_len = sp.range(0, sp.len(prefix), 1) + temp_var3 = sp.local("z", 0) + list_string = sp.local("list_string", []) + sp.for x in prefix_len: + temp_var3.value = x + list_string.value.push(Utils.Int.of_bytes(sp.slice(prefix, temp_var3.value, 1).open_some())) + v = sp.slice(new_byt_value, 3, sp.as_nat(sp.len(new_byt_value) - 3)) + byte_local = sp.local("byt_old", sp.bytes("0x")) + sp.for enc in base58_encodings: + byte_local.value = tb([sp.as_nat(Utils.Int.of_string(enc["elem1"])), + sp.as_nat(Utils.Int.of_string(enc["elem2"])), + sp.as_nat(Utils.Int.of_string(enc["elem3"]))]) + sp.if byte_local.value == prefix : + actual_prefix.value = enc["prefix"] + sp.for item in tz_prefixes.items(): + sp.if item.value == actual_prefix.value: + decoded_address = sp.unpack(sp.bytes("0x050a00000016") + item.key + v.open_some(), + sp.TAddress) + addr.value = decoded_address.open_some() + return addr.value + sp.if actual_prefix.value == "KT1": + decoded_address = sp.unpack(sp.bytes("0x050a00000016") + sp.bytes("0x01") + v.open_some() + sp.bytes("0x00"), + sp.TAddress) + return decoded_address.open_some() + sp.if actual_prefix.value == "txr1": + decoded_address = sp.unpack(sp.bytes("0x050a00000016") + sp.bytes("0x02") + v.open_some() + sp.bytes("0x00"), + sp.TAddress) + return decoded_address.open_some() + sp.if actual_prefix.value == "sr1": + decoded_address = sp.unpack(sp.bytes("0x050a00000016") + sp.bytes("0x03") + v.open_some() + sp.bytes("0x00"), + sp.TAddress) + return decoded_address.open_some() + + sp.if actual_prefix.value == "": + return sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg") + + with sp.else_(): + return sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg") + +# @sp.add_test(name="Conversion") +# def test(): +# alice=sp.test_account("Alice") +# c1 = Conversion() +# scenario = sp.test_scenario() +# scenario.h1("Conversion") +# scenario += c1 +# c1.add_to_str(sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP")) +# c1.str_to_addr("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP") +# +# +# sp.add_compilation_target("smartpy-utils", Conversion()) + + From 73794216808ce5d76b48d173575a9518a3e99886 Mon Sep 17 00:00:00 2001 From: simusud Date: Thu, 4 May 2023 22:14:34 +0545 Subject: [PATCH 050/211] fix(bmc_management): contract initialization fixes --- smartpy/bmc/contracts/src/bmc_management.py | 57 ++++++++++++--------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/smartpy/bmc/contracts/src/bmc_management.py b/smartpy/bmc/contracts/src/bmc_management.py index 259ed808..246828e6 100644 --- a/smartpy/bmc/contracts/src/bmc_management.py +++ b/smartpy/bmc/contracts/src/bmc_management.py @@ -9,9 +9,9 @@ class BMCManagement(sp.Contract): BLOCK_INTERVAL_MSEC = sp.nat(1000) - def __init__(self): + def __init__(self, owner_address): self.init( - owners=sp.map(), + owners=sp.map(l={owner_address:True}), number_of_owners=sp.nat(1), bsh_services=sp.map(), relay_stats=sp.map(), @@ -46,11 +46,6 @@ def __init__(self): get_link_from_reachable_net=sp.TMap(sp.TString, types.Types.Tuple) )) - # to be called after deployment manually - @sp.entry_point - def enable(self): - self.data.owners[sp.sender] = True - def only_owner(self): with sp.if_(self.data.owners.contains(sp.sender)): sp.verify(self.data.owners[sp.sender] == True, "Unauthorized") @@ -68,11 +63,22 @@ def set_bmc_periphery(self, addr): :return: """ sp.set_type(addr, sp.TAddress) - # self.only_owner() + self.only_owner() sp.if self.data.bmc_periphery.is_some(): sp.verify(addr != self.data.bmc_periphery.open_some("Address not set"), "AlreadyExistsBMCPeriphery") self.data.bmc_periphery = sp.some(addr) + @sp.entry_point + def set_bmc_btp_address(self, network): + sp.set_type(network, sp.TString) + + sp.verify(self.data.owners[sp.sender] == True, "Unauthorized") + # call set_btp_address on BMCPeriphery + set_btp_address_entry_point = sp.contract(sp.TString, + self.data.bmc_periphery.open_some("Address not set"), + "set_btp_address").open_some() + sp.transfer(network, sp.tez(0), set_btp_address_entry_point) + @sp.entry_point def add_owner(self, owner): """ @@ -81,7 +87,7 @@ def add_owner(self, owner): """ sp.set_type(owner, sp.TAddress) - # self.only_owner() + self.only_owner() sp.verify(self.data.owners.contains(owner) == False, "Already Exists") self.data.owners[owner] = True self.data.number_of_owners += sp.nat(1) @@ -119,7 +125,7 @@ def add_service(self, svc, addr): :return: """ self.only_owner() - # sp.verify(addr != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), "InvalidAddress") + sp.verify(addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg"), "InvalidAddress") sp.verify(self.data.bsh_services.contains(svc) == False, "AlreadyExistsBSH") self.data.bsh_services[svc] = addr self.data.list_bsh_names.add(svc) @@ -557,38 +563,39 @@ def update_relay_stats(self, relay, block_count_val, msg_count_val): self.data.relay_stats[relay].block_count += block_count_val self.data.relay_stats[relay].msg_count += msg_count_val - # @sp.onchain_view() + @sp.onchain_view() def resolve_route(self, dst_net): sp.set_type(dst_net, sp.TString) self.only_bmc_periphery() dst = sp.local("dst", self.data.get_route_dst_from_net[dst_net], t=sp.TString) - sp.if sp.len(sp.pack(dst.value))!= sp.nat(0): - return sp.pair(self.data.routes[dst.value], dst.value) - - dst_link = sp.local("dst_link", self.data.get_link_from_net[dst_net], t=sp.TString) - sp.if sp.len(sp.pack(dst_link.value)) != sp.nat(0): - return sp.pair(dst_link.value, dst_link.value) - - res = sp.local("res", self.data.get_link_from_reachable_net[dst_net], t=types.Types.Tuple) - sp.verify(sp.len(sp.pack(res.value.to)) > sp.nat(0), "Unreachable: " + dst_net + " is unreachable") + with sp.if_(sp.len(sp.pack(dst.value))!= sp.nat(0)): + sp.result(sp.pair(self.data.routes[dst.value], dst.value)) + with sp.else_(): + dst_link = sp.local("dst_link", self.data.get_link_from_net[dst_net], t=sp.TString) + with sp.if_(sp.len(sp.pack(dst_link.value)) != sp.nat(0)): + sp.result(sp.pair(dst_link.value, dst_link.value)) + with sp.else_(): + res = sp.local("res", self.data.get_link_from_reachable_net[dst_net], t=types.Types.Tuple) + sp.verify(sp.len(sp.pack(res.value.to)) > sp.nat(0), "Unreachable: " + dst_net + " is unreachable") - return sp.pair(res.value.prev, res.value.to) + sp.result(sp.pair(res.value.prev, res.value.to)) @sp.add_test(name="BMCM") def test(): alice = sp.test_account("Alice") + owner = sp.test_account("Owner") bmc_periphery = sp.test_account("BMC Periphery") # bmc= sp.test_account("BMC") scenario = sp.test_scenario() - bmc_man = BMCManagement() + bmc_man = BMCManagement(owner.address) scenario += bmc_man - bmc_man.set_bmc_periphery(bmc_periphery.address).run(sender=alice) - bmc_man.add_owner(alice.address).run(sender=alice) + bmc_man.set_bmc_periphery(bmc_periphery.address).run(sender=owner) + bmc_man.add_owner(alice.address).run(sender=owner) # bmc_man.remove_owner(alice.address).run(sender=alice) @@ -601,4 +608,4 @@ def test(): _max_aggregation=sp.nat(3), delay_limit=sp.nat(2))).run(sender=alice) -sp.add_compilation_target("bmc_management", BMCManagement()) +sp.add_compilation_target("bmc_management", BMCManagement(owner_address=sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"))) From 0f41b35293408b7e437a6237907befe5d927db60 Mon Sep 17 00:00:00 2001 From: simusud Date: Thu, 4 May 2023 22:15:40 +0545 Subject: [PATCH 051/211] feat(bmc_periphery): rlp decode library implementation --- smartpy/bmc/contracts/src/bmc_periphery.py | 173 ++++++++++++--------- 1 file changed, 96 insertions(+), 77 deletions(-) diff --git a/smartpy/bmc/contracts/src/bmc_periphery.py b/smartpy/bmc/contracts/src/bmc_periphery.py index 4f42ca3e..5c2ffbb6 100644 --- a/smartpy/bmc/contracts/src/bmc_periphery.py +++ b/smartpy/bmc/contracts/src/bmc_periphery.py @@ -3,6 +3,8 @@ types = sp.io.import_script_from_url("file:./contracts/src/Types.py") strings = sp.io.import_script_from_url("file:./contracts/src/String.py") rlp_encode = sp.io.import_script_from_url("file:./contracts/src/RLP_encode_struct.py") +rlp_decode = sp.io.import_script_from_url("file:./contracts/src/RLP_decode_struct.py") +parse_addr = sp.io.import_script_from_url("file:./contracts/src/parse_address.py") class BMCPreiphery(sp.Contract): @@ -20,25 +22,31 @@ class BMCPreiphery(sp.Contract): BMCRevertUnknownHandleBTPError = sp.string("UnknownHandleBTPError") BMCRevertUnknownHandleBTPMessage = sp.string("UnknownHandleBTPMessage") - def __init__(self, network, bmc_management_addr): + def __init__(self, bmc_management_addr): self.init( - bmc_btp_address=sp.string("btp://") + network + "/" + "jj", + bmc_btp_address=sp.none, bmc_management=bmc_management_addr ) + @sp.entry_point + def set_btp_address(self, network): + sp.set_type(network, sp.TString) + + sp.verify(sp.sender == self.data.bmc_management, "Unauthorized") + with sp.if_(self.data.bmc_btp_address == sp.none): + self.data.bmc_btp_address = sp.some(sp.string("btp://") + network + "/" + parse_addr.add_to_str(sp.self_address)) + with sp.else_(): + sp.failwith("Address already set") + @sp.onchain_view() def get_bmc_btp_address(self): - sp.result(self.data.bmc_btp_address) + sp.result(self.data.bmc_btp_address.open_some("Address not set")) def _require_registered_relay(self, prev): sp.set_type(prev, sp.TString) - sp.trace(prev) - #TODO: check sp. view - - # relay = sp.view("get_link_relays", self.data.bmc_management, prev, t=sp.TList(sp.TAddress)).open_some() - relay = [] - sp.for x in relay: + relays = sp.view("get_link_relays", self.data.bmc_management, prev, t=sp.TList(sp.TAddress)).open_some() + sp.for x in relays: sp.if sp.sender == x: return sp.failwith(self.BMCRevertUnauthorized) @@ -50,20 +58,16 @@ def handle_relay_message(self, prev, msg): self._require_registered_relay(prev) - # link_rx_seq = sp.view("get_link_rx_seq", self.data.bmc_management, prev, t=sp.TNat).open_some() - link_rx_seq= sp.nat(2) - # link_rx_height = sp.view("get_link_rx_height", self.data.bmc_management, prev, t=sp.TNat).open_some() - link_rx_height= sp.nat(3) + link_rx_seq = sp.view("get_link_rx_seq", self.data.bmc_management, prev, t=sp.TNat).open_some() + link_rx_height = sp.view("get_link_rx_height", self.data.bmc_management, prev, t=sp.TNat).open_some() rx_seq = sp.local("rx_seq", link_rx_seq, t=sp.TNat) rx_height = sp.local("rx_height", link_rx_height, t=sp.TNat) - rps = sp.map(tkey=sp.TNat, tvalue=types.Types.ReceiptProof) - # rsp = decodeReceiptProofs(msg) - # rps = sp.map({sp.nat(0):sp.record(index=1, events=[], height=sp.nat(3))}) - # bmc_msg = sp.local("bmc_msg") + rps = rlp_decode.decode_receipt_proofs(msg) - # ev = sp.local("ev") + bmc_msg = sp.local("bmc_msg", sp.record(src="", dst="", svc="", sn=sp.nat(0), message=sp.bytes("0x")), t=types.Types.BMCMessage) + ev = sp.local("ev", sp.record(next_bmc="", seq=sp.nat(0), message=sp.bytes("0x")), t=types.Types.MessageEvent) sp.for i in sp.range(sp.nat(0), sp.len(rps)): sp.trace("ll") @@ -73,16 +77,27 @@ def handle_relay_message(self, prev, msg): rx_height.value = rps[i].height sp.for j in sp.range(sp.nat(0), sp.len(rps[i].events)): - ev = rps[i].events[j] - sp.verify(ev.next_bmc == self.data.bmc_btp_address, "Invalid Next BMC") + ev.value = rps[i].events[j] + sp.verify(ev.value.next_bmc == self.data.bmc_btp_address.open_some("Address not set"), "Invalid Next BMC") rx_seq.value +=sp.nat(1) - sp.if ev.seq < rx_seq.value: + sp.if ev.value.seq < rx_seq.value: rx_seq.value = sp.as_nat(rx_seq.value-sp.nat(1)) # sp.continue - sp.if ev.seq > rx_seq.value: + sp.if ev.value.seq > rx_seq.value: sp.failwith(self.BMCRevertInvalidSeqNumber) # TODO: implement code inside of try catch + _decoded = rlp_decode.decode_bmc_message(ev.value.message) + bmc_msg.value = _decoded + + sp.if bmc_msg.value.dst == self.data.bmc_btp_address.open_some("Address not set"): + self._handle_message(prev, bmc_msg.value) + # continue + + net, addr = sp.match_pair(strings.split_btp_address(bmc_msg.value.dst, "prev_idx", "result", "my_list", "last", "penultimate")) + # resolve route inside try catch + next_link, prev_link = sp.match_pair(sp.view("resolve_route", self.data.bmc_management, net, t=sp.TPair(sp.TString, sp.TString)).open_some("Invalid Call")) + self._send_message(next_link, ev.value.message) # call update_link_rx_seq on BMCManagement update_link_rx_seq_args_type = sp.TRecord(prev=sp.TString, val=sp.TNat) @@ -115,28 +130,34 @@ def _handle_message(self, prev, msg): # bsh_addr = sp.local("bsh_addr",sp.TAddress) with sp.if_(msg.svc == "bmc"): - sm = self.try_decode_bmc_service(msg.message) - #TODO: implement try catch + # TODO: implement try catch + sm = rlp_decode.decode_bmc_service(msg.message) sp.if sm.serviceType == "FeeGathering": - gather_fee = self.try_decode_gather_fee_message(sm.payload) - - sp.for i in sp.range(sp.nat(0), len(gather_fee.svcs)): - bsh_addr = sp.view("get_bsh_service_by_name", self.data.bmc_management, gather_fee.svcs[i], t=sp.TAddress) - - sp.if bsh_addr != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"): - pass - #TODO: call BSH handleFeeGathering + # decode inside try + gather_fee = rlp_decode.decode_gather_fee_message(sm.payload) + + sp.for c in sp.range(sp.nat(0), sp.len(gather_fee.svcs)): + bsh_addr = sp.view("get_bsh_service_by_name", self.data.bmc_management, gather_fee.svcs[c], t=sp.TAddress).open_some("Invalid Call") + + sp.if bsh_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg"): + # put it inside try + # call handle_fee_gathering of bts periphery + handle_fee_gathering_args_type = sp.TRecord(fa=sp.TString, svc=sp.TString) + handle_fee_gathering_entry_point = sp.contract(handle_fee_gathering_args_type, + bsh_addr, + "handle_fee_gathering").open_some() + handle_fee_gathering_args = sp.record(fa=gather_fee.fa, svc=gather_fee.svcs[c]) + sp.transfer(handle_fee_gathering_args, sp.tez(0), handle_fee_gathering_entry_point) sp.if sm.serviceType == "Link": - # to = decodePropagateMessage(sm.payload) - to = "to" + to = rlp_decode.decode_propagate_message(sm.payload) link = sp.view("get_link", self.data.bmc_management, prev, t=types.Types.Link).open_some() check = sp.local("check", False).value sp.if link.is_connected: - sp.for i in sp.range(sp.nat(0), len(link.reachable)): - sp.if to == link.reachable[i]: + sp.for e in link.reachable.elements(): + sp.if to == e: check = True # sp.break @@ -152,25 +173,25 @@ def _handle_message(self, prev, msg): sp.transfer(update_link_reachable_args, sp.tez(0), update_link_reachable_entry_point) sp.if sm.serviceType == "Unlink": - # to = decodePropagateMessage(sm.payload) - to = "to" + to = rlp_decode.decode_propagate_message(sm.payload) link = sp.view("get_link", self.data.bmc_management, prev, t=types.Types.Link).open_some() sp.if link.is_connected: - sp.for i in sp.range(sp.nat(0), len(link.reachable)): - sp.if to == link.reachable[i]: + f = sp.local("f", sp.nat(0)) + sp.for itm in link.reachable.elements(): + sp.if to == itm: # call delete_link_reachable on BMCManagement delete_link_reachable_args_type = sp.TRecord(prev=sp.TString, index=sp.TNat) delete_link_reachable_entry_point = sp.contract(delete_link_reachable_args_type, self.data.bmc_management, "delete_link_reachable").open_some() - delete_link_reachable_args = sp.record(prev=prev, to=i) + delete_link_reachable_args = sp.record(prev=prev, index=f.value) sp.transfer(delete_link_reachable_args, sp.tez(0), delete_link_reachable_entry_point) + f.value += sp.nat(1) sp.if sm.serviceType == "Init": - # links = decodeInitMessage(sm.payload) - links = ["link"] + links = rlp_decode.decode_init_message(sm.payload) # call update_link_reachable on BMCManagement update_link_reachable_args_type = sp.TRecord(prev=sp.TString, to=sp.TList(sp.TString)) update_link_reachable_entry_point = sp.contract(update_link_reachable_args_type, @@ -179,36 +200,35 @@ def _handle_message(self, prev, msg): update_link_reachable_args = sp.record(prev=prev, to=links) sp.transfer(update_link_reachable_args, sp.tez(0), update_link_reachable_entry_point) with sp.else_(): - bsh_addr = sp.view("get_bsh_service_by_name", self.data.bmc_management, msg.svc, t=sp.TAddress) + bsh_addr = sp.view("get_bsh_service_by_name", self.data.bmc_management, msg.svc, t=sp.TAddress).open_some("Invalid view") - sp.if bsh_addr == sp.addrress("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"): + sp.if bsh_addr == sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg"): self._send_error(prev, msg, self.BMC_ERR, self.BMCRevertNotExistsBSH) return with sp.if_(msg.sn >= sp.nat(0)): - net, = strings.split_btp_address(msg.src) - #TODO: implement try catch, call handleBTPMessage from BSH - + net, addr = sp.match_pair(strings.split_btp_address(msg.src, "prev_idx", "result", "my_list", "last", "penultimate")) + # put it in try catch + # call handle_btp_message on bts periphery + handle_btp_message_args_type = sp.TRecord(_from=sp.TString, svc=sp.TString, sn=sp.TNat, msg=sp.TBytes) + handle_btp_message_entry_point = sp.contract(handle_btp_message_args_type, + bsh_addr, + "handle_btp_message").open_some() + handle_btp_message_args = sp.record(_from=net, svc=msg.svc, sn=msg.sn, msg=msg.message) + sp.transfer(handle_btp_message_args, sp.tez(0), handle_btp_message_entry_point) with sp.else_(): - res = decodeResponse(msg.message) - # TODO: implement try catch, call handleBTPError from BSH - - - def try_decode_btp_message(self, rlp): - sp.set_type(rlp, sp.TBytes) - - return decodeBMCMessage(rpl) - - def try_decode_bmc_service(self, msg): - sp.set_type(msg, sp.TBytes) - - return decodeBMCService(msg) - - def try_decode_gather_fee_message(self, msg): - sp.set_type(msg, sp.TBytes) - - return decodeGatherFeeMessage(msg) + res = rlp_decode.decode_response(msg.message) + # put it in try catch + # here sn is sent negative in solidity (msg.sn *-1) + # call handle_btp_error on bts periphery + handle_btp_error_args_type = sp.TRecord(svc=sp.TString, sn=sp.TNat, code=sp.TNat, msg=sp.TString) + handle_btp_error_entry_point = sp.contract(handle_btp_error_args_type, + bsh_addr, + "handle_btp_error").open_some() + handle_btp_error_args = sp.record(svc=msg.svc, sn=msg.sn, code=res.code, msg=res.message) + sp.transfer(handle_btp_error_args, sp.tez(0), handle_btp_error_entry_point) + #TODO: emit in case of error def _send_message(self, to ,serialized_msg): sp.set_type(to, sp.TString) @@ -222,7 +242,8 @@ def _send_message(self, to ,serialized_msg): update_link_tx_seq_args = sp.record(prev=to) sp.transfer(update_link_tx_seq_args, sp.tez(0), update_link_tx_seq_entry_point) - sp.emit(sp.record(next=to, seq=sp.view("get_link_tx_seq", self.data.bmc_management, to, t=sp.TNat).open_some(), msg=serialized_msg)) + sp.emit(sp.record(next=to, seq=sp.view("get_link_tx_seq", self.data.bmc_management, to, t=sp.TNat).open_some(), msg=serialized_msg), + tag="Message") def _send_error(self, prev, message, err_code, err_msg): sp.set_type(prev, sp.TString) @@ -230,13 +251,13 @@ def _send_error(self, prev, message, err_code, err_msg): sp.set_type(err_code, sp.TNat) sp.set_type(err_msg, sp.TString) - if message.sn > sp.nat(0): + sp.if message.sn > sp.nat(0): serialized_msg = rlp_encode.encode_bmc_message(sp.record( - src=self.data.bmc_btp_address, + src=self.data.bmc_btp_address.open_some("Address not set"), dst=message.src, svc=message.svc, - sn=message.sn * - sp.nat(1), - message=encode_response(sp.record(code=err_code, message=err_msg)) + sn=message.sn, + message=rlp_encode.encode_response(sp.record(code=err_code, message=err_msg)) )) self._send_message(prev, serialized_msg) @@ -263,13 +284,12 @@ def send_message(self, to, svc, sn, msg): next_link, dst = sp.match_pair(sp.view("resolve_route", self.data.bmc_management, to, t=sp.TPair(sp.TString, sp.TString)).open_some()) rlp = rlp_encode.encode_bmc_message(sp.record( - src=self.data.bmc_btp_address, + src=self.data.bmc_btp_address.open_some("Address not set"), dst=dst, svc=svc, sn=sn, message=msg )) - # next_link = "next_link" self._send_message(next_link, rlp) @sp.onchain_view() @@ -298,10 +318,9 @@ def test(): # bmc= sp.test_account("BMC") scenario = sp.test_scenario() - bmc = BMCPreiphery("tezos", bmc_management.address) + bmc = BMCPreiphery(bmc_management.address) scenario += bmc - bmc.handle_relay_message(sp.record(prev="demo string", msg=sp.bytes("0x0dae11"))).run(sender=alice) + # bmc.handle_relay_message(sp.record(prev="demo string", msg=sp.bytes("0x0dae11"))).run(sender=alice) -sp.add_compilation_target("bmc_periphery", BMCPreiphery(network="tezos", - bmc_management_addr=sp.address("KT1GmZEcN82NbZrxXkhazvuX6ybJB12JTJAT"))) +sp.add_compilation_target("bmc_periphery", BMCPreiphery(bmc_management_addr=sp.address("KT1GmZEcN82NbZrxXkhazvuX6ybJB12JTJAT"))) From fff55e72e3c5c6843b754ca871c7e2f3013ca3e1 Mon Sep 17 00:00:00 2001 From: simusud Date: Fri, 5 May 2023 12:12:13 +0545 Subject: [PATCH 052/211] fix(bts_core): minor fixes --- smartpy/bts/contracts/src/Utils.py | 30 ------------ smartpy/bts/contracts/src/bts_core.py | 67 ++++++++++++++++----------- 2 files changed, 40 insertions(+), 57 deletions(-) delete mode 100644 smartpy/bts/contracts/src/Utils.py diff --git a/smartpy/bts/contracts/src/Utils.py b/smartpy/bts/contracts/src/Utils.py deleted file mode 100644 index e751c3fb..00000000 --- a/smartpy/bts/contracts/src/Utils.py +++ /dev/null @@ -1,30 +0,0 @@ -import smartpy as sp - -# TODO: remove compilation target -class Utils(sp.Contract): - def __init__(self): - self.update_initial_storage() - - def _ceil_div(self, num1, num2): - sp.set_type(num1, sp.TNat) - sp.set_type(num2, sp.TNat) - (quotient, remainder) = sp.match_pair(sp.ediv(11, 2).open_some()) - sp.if remainder == 0 : - sp.result(quotient) - return quotient + 1 - - def _get_scale(self, block_interval_src, block_interval_dst): - sp.set_type(block_interval_src, sp.TNat) - sp.set_type(block_interval_dst, sp.TNat) - sp.if (block_interval_dst < 1) | (block_interval_dst < 1): - sp.result(0) - return self._ceil_div(block_interval_src * 1000000, block_interval_dst) - - def _get_rotate_term(self, max_aggregation, scale): - sp.set_type(max_aggregation, sp.TNat) - sp.set_type(scale, sp.TNat) - sp.if scale > 0: - return self._ceil_div(max_aggregation * 1000000, scale) - return 0 - -sp.add_compilation_target("Utils", Utils()) \ No newline at end of file diff --git a/smartpy/bts/contracts/src/bts_core.py b/smartpy/bts/contracts/src/bts_core.py index 7c645b8d..644908a2 100644 --- a/smartpy/bts/contracts/src/bts_core.py +++ b/smartpy/bts/contracts/src/bts_core.py @@ -19,6 +19,7 @@ class BTSCore(sp.Contract): MAX_BATCH_SIZE = sp.nat(15) NATIVE_COIN_ADDRESS = sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc") + ZERO_ADDRESS = sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg") # Nat:(TWO.pow256 - 1) UINT_CAP = sp.nat(115792089237316195423570985008687907853269984665640564039457584007913129639935) @@ -127,17 +128,18 @@ def register(self, name, fee_numerator, fixed_fee, addr, token_metadata, metadat sp.verify(self.data.coins_address.contains(addr) == False, message="AddressExists") sp.verify(fee_numerator <= self.FEE_DENOMINATOR, message="InvalidSetting") sp.verify((fixed_fee >= sp.nat(0)) & (fee_numerator >= sp.nat(0)), message="LessThan0") - with sp.if_(addr == self.NATIVE_COIN_ADDRESS): + with sp.if_(addr == self.ZERO_ADDRESS): sp.trace("in register native") deployed_fa2 = sp.create_contract_operation(contract=FA2_contract.SingleAssetToken(admin=sp.self_address, metadata=metadata, token_metadata=token_metadata - )).address - sp.trace(deployed_fa2) - self.data.coins[name] = deployed_fa2 + )) + sp.operations().push(deployed_fa2.operation) + sp.trace(deployed_fa2.address) + self.data.coins[name] = deployed_fa2.address self.data.coins_name.push(name) - self.data.coins_address[deployed_fa2] = name + self.data.coins_address[deployed_fa2.address] = name self.data.coin_details[name] = sp.record( - addr = deployed_fa2, + addr = deployed_fa2.address, fee_numerator = fee_numerator, fixed_fee = fixed_fee, coin_type = self.NATIVE_WRAPPED_COIN_TYPE @@ -220,11 +222,20 @@ def balance_of(self, params): sp.set_type(params, sp.TRecord(owner=sp.TAddress, coin_name=sp.TString)) # sending user_balance as 0 because in smartpy we cannot get Tez balance of address + locked_balance = sp.local("locked_balance", sp.nat(0)) + refundable_balance = sp.local("refundable_balance", sp.nat(0)) + + sp.if self.data.balances.contains(sp.record(address=params.owner, coin_name=params.coin_name)): + locked_balance.value = self.data.balances[ + sp.record(address=params.owner, coin_name=params.coin_name)].locked_balance + refundable_balance.value = self.data.balances[ + sp.record(address=params.owner, coin_name=params.coin_name)].refundable_balance + with sp.if_(params.coin_name == self.data.native_coin_name): - sp.result(sp.record(usable_balance = sp.nat(0), - locked_balance = self.data.balances[sp.record(address=params.owner, coin_name=params.coin_name)].locked_balance, - refundable_balance = self.data.balances[sp.record(address=params.owner, coin_name=params.coin_name)].refundable_balance, - user_balance = sp.nat(0))) + sp.result(sp.record(usable_balance=sp.nat(0), + locked_balance=locked_balance.value, + refundable_balance=refundable_balance.value, + user_balance=sp.nat(0))) with sp.else_(): fa2_address = self.data.coins[params.coin_name] user_balance= sp.view("balance_of", fa2_address, sp.record(owner=params.owner, token_id=sp.nat(0)), t=sp.TNat).open_some("Invalid view") @@ -235,8 +246,8 @@ def balance_of(self, params): usable_balance.value = user_balance sp.result(sp.record(usable_balance=usable_balance.value, - locked_balance=self.data.balances[sp.record(address=params.owner, coin_name=params.coin_name)].locked_balance, - refundable_balance=self.data.balances[sp.record(address=params.owner, coin_name=params.coin_name)].refundable_balance, + locked_balance=locked_balance.value, + refundable_balance=refundable_balance.value, user_balance=user_balance)) @sp.onchain_view() @@ -522,22 +533,24 @@ def mint(self, to, coin_name, value): sp.set_type(value, sp.TNat) self.only_bts_periphery() - sp.if coin_name == self.data.native_coin_name: + with sp.if_(coin_name == self.data.native_coin_name): self.payment_transfer(to, value) - sp.if self.data.coin_details[coin_name].coin_type == self.NATIVE_WRAPPED_COIN_TYPE: - # call mint in FA2 - mint_args_type = sp.TList(sp.TRecord(to_=sp.TAddress, amount=sp.TNat).layout(("to_", "amount"))) - mint_entry_point = sp.contract(mint_args_type, self.data.coins[coin_name], "mint").open_some() - mint_args = [sp.record(to_=to, amount=value)] - sp.transfer(mint_args, sp.tez(0), mint_entry_point) - sp.if self.data.coin_details[coin_name].coin_type == self.NON_NATIVE_TOKEN_TYPE: - # call transfer in FA2 - transfer_args_type = sp.TList(sp.TRecord(from_=sp.TAddress, txs=sp.TList(sp.TRecord( - to_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout(("to_", ("token_id", "amount")))) - ).layout(("from_", "txs"))) - transfer_entry_point = sp.contract(transfer_args_type, self.data.coins[coin_name], "transfer").open_some() - transfer_args = [sp.record(from_=sp.sender, txs=[sp.record(to_=to, token_id=sp.nat(0), amount=value)])] - sp.transfer(transfer_args, sp.tez(0), transfer_entry_point) + with sp.else_(): + with sp.if_(self.data.coin_details[coin_name].coin_type == self.NATIVE_WRAPPED_COIN_TYPE): + # call mint in FA2 + mint_args_type = sp.TList(sp.TRecord(to_=sp.TAddress, amount=sp.TNat).layout(("to_", "amount"))) + mint_entry_point = sp.contract(mint_args_type, self.data.coins[coin_name], "mint").open_some() + mint_args = [sp.record(to_=to, amount=value)] + sp.transfer(mint_args, sp.tez(0), mint_entry_point) + with sp.else_(): + sp.if self.data.coin_details[coin_name].coin_type == self.NON_NATIVE_TOKEN_TYPE: + # call transfer in FA2 + transfer_args_type = sp.TList(sp.TRecord(from_=sp.TAddress, txs=sp.TList(sp.TRecord( + to_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout(("to_", ("token_id", "amount")))) + ).layout(("from_", "txs"))) + transfer_entry_point = sp.contract(transfer_args_type, self.data.coins[coin_name], "transfer").open_some() + transfer_args = [sp.record(from_=sp.sender, txs=[sp.record(to_=to, token_id=sp.nat(0), amount=value)])] + sp.transfer(transfer_args, sp.tez(0), transfer_entry_point) @sp.entry_point def callback(self, string, requester, coin_name, value): From 72c6a953aa82d1dd19e31e7e14fe42314eddd955 Mon Sep 17 00:00:00 2001 From: simusud Date: Thu, 11 May 2023 15:44:55 +0545 Subject: [PATCH 053/211] fix(bmc): contract size issue fixed by splitting libraries into separate helper.py and parse_address.py contracts --- .../bmc/contracts/src/RLP_decode_struct.py | 520 ++++++------------ .../bmc/contracts/src/RLP_encode_struct.py | 51 +- smartpy/bmc/contracts/src/bmc_management.py | 114 ++-- smartpy/bmc/contracts/src/bmc_periphery.py | 108 ++-- smartpy/bmc/contracts/src/helper.py | 48 ++ smartpy/bmc/contracts/src/parse_address.py | 260 ++++----- 6 files changed, 456 insertions(+), 645 deletions(-) create mode 100644 smartpy/bmc/contracts/src/helper.py diff --git a/smartpy/bmc/contracts/src/RLP_decode_struct.py b/smartpy/bmc/contracts/src/RLP_decode_struct.py index a89f8148..93a105a4 100644 --- a/smartpy/bmc/contracts/src/RLP_decode_struct.py +++ b/smartpy/bmc/contracts/src/RLP_decode_struct.py @@ -1,371 +1,197 @@ import smartpy as sp -Utils = sp.io.import_script_from_url("https://raw.githubusercontent.com/Acurast/acurast-hyperdrive/main/contracts/tezos/libs/utils.py") Utils2 = sp.io.import_script_from_url("https://raw.githubusercontent.com/RomarQ/tezos-sc-utils/main/smartpy/utils.py") types = sp.io.import_script_from_url("file:./contracts/src/Types.py") -def decode_bmc_message(rlp): - decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) - decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) - rlp_ = decode_list(rlp) - temp_map_string = sp.compute(sp.map(tkey=sp.TString, tvalue=sp.TString)) - temp_int = sp.local("int_value", 0) - temp_byt = sp.local("byt_value", sp.bytes("0x")) - counter = sp.local("counter", 0) - sp.for k in rlp_.items(): - sp.if counter.value == 0: - temp_map_string["src"] = decode_string(k.value) - sp.if counter.value == 1: - temp_map_string["dst"] = decode_string(k.value) - sp.if counter.value == 2: - temp_map_string["svc"] = decode_string(k.value) - sp.if counter.value == 3: - temp_int.value = Utils2.Int.of_bytes(k.value) - sp.if counter.value == 4: - temp_byt.value = k.value - counter.value = counter.value + 1 +class DecodeLibrary: - return sp.record(src=temp_map_string.get("src"), - dst=temp_map_string.get("dst"), - svc=temp_map_string.get("svc"), - sn=temp_int.value, - message=temp_byt.value) - - -def decode_response(rlp): - decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) - decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) - temp_int = sp.local("int1", 0) - temp_byt = sp.local("byt1", sp.bytes("0x")) - rlp_ = decode_list(rlp) - counter = sp.local("counter_response", 0) - sp.for i in rlp_.items(): - sp.if counter.value == 0: - temp_int.value = Utils2.Int.of_bytes(i.value) - sp.if counter.value == 1: - temp_byt.value = i.value - counter.value = counter.value + 1 - - return sp.record(code=temp_int.value, message=decode_string(temp_byt.value)) - -def decode_propagate_message(rlp): - decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) - decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) - rlp_ = decode_list(rlp) - counter = sp.local("counter_propagate", 0) - temp_string = sp.local("temp_string", "") - sp.for d in rlp_.items(): - sp.if counter.value == 0: - temp_string.value = decode_string(d.value) - counter.value = counter.value + 1 - return temp_string.value - -def decode_init_message(rlp): - decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) - decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) - rlp_ = decode_list(rlp) - counter = sp.local("counter_init", 0) - temp_bytes = sp.local("byt_init", sp.bytes("0x")) - sp.for g in rlp_.items(): - sp.if counter.value == 0: - temp_bytes.value = g.value - counter.value = counter.value + 1 - - starts_with = sp.slice(temp_bytes.value, 0, 2).open_some() - sub_list = sp.local("sub_list_init", temp_bytes.value) - sp.if starts_with == sp.bytes("0xb846"): - sub_list.value = sp.slice(temp_bytes.value, 2, sp.as_nat(sp.len(temp_bytes.value) - 2)).open_some() - new_sub_list = decode_list(sub_list.value) - _links = sp.local("links_init", [], sp.TList(sp.TString)) - counter.value = 0 - sp.for x in new_sub_list.items(): - _links.value.push(decode_string(x.value)) - counter.value = counter.value + 1 - return _links.value - -def decode_bmc_service(rlp): - decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) - decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) - rlp_ = decode_list(rlp) - temp_string = sp.local("str_value", "") - temp_byt = sp.local("byt_value_bmc", sp.bytes("0x")) - counter = sp.local("counter_service", 0) - sp.for b in rlp_.items(): - sp.if counter.value == 0: - temp_string.value = decode_string(b.value) - sp.if counter.value == 1: - temp_byt.value = b.value - counter.value = counter.value + 1 - - return sp.record(serviceType=temp_string.value, - payload=temp_byt.value) - - -def decode_service_message(rlp): - decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) - rlp_ = decode_list(rlp) - temp_int = sp.local("int2", 0) - temp_byt = sp.local("byte1", sp.bytes("0x")) - counter = sp.local("counter", 0) - sp.for i in rlp_.items(): - sp.if counter.value == 0: - temp_int.value = Utils2.Int.of_bytes(i.value) - sp.if counter.value == 1: - temp_byt.value = i.value - counter.value = counter.value + 1 - - _service_type = sp.local("_service_type", sp.variant("", 10)) - sp.if temp_int.value == 0: - _service_type.value = sp.variant("REQUEST_COIN_TRANSFER", temp_int.value) - sp.if temp_int.value == 1: - _service_type.value = sp.variant("REQUEST_COIN_REGISTER", temp_int.value) - sp.if temp_int.value == 2: - _service_type.value = sp.variant("RESPONSE_HANDLE_SERVICE", temp_int.value) - sp.if temp_int.value == 3: - _service_type.value = sp.variant("BLACKLIST_MESSAGE", temp_int.value) - sp.if temp_int.value == 4: - _service_type.value = sp.variant("CHANGE_TOKEN_LIMIT", temp_int.value) - sp.if temp_int.value == 5: - _service_type.value = sp.variant("UNKNOWN_TYPE", temp_int.value) - - return sp.record(serviceType=_service_type.value, - data=temp_byt.value) + def decode_bmc_message(self, rlp): + rlp_ = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + temp_map_string = sp.compute(sp.map(tkey=sp.TString, tvalue=sp.TString)) + temp_int = sp.local("int_value", 0) + temp_byt = sp.local("byt_value", sp.bytes("0x")) + counter = sp.local("counter", 0) + sp.for k in rlp_.items(): + sp.if counter.value == 0: + temp_map_string["src"] = sp.view("decode_string", self.data.helper, k.value, t=sp.TString).open_some() + sp.if counter.value == 1: + temp_map_string["dst"] = sp.view("decode_string", self.data.helper, k.value, t=sp.TString).open_some() + sp.if counter.value == 2: + temp_map_string["svc"] = sp.view("decode_string", self.data.helper, k.value, t=sp.TString).open_some() + sp.if counter.value == 3: + temp_int.value = Utils2.Int.of_bytes(k.value) + sp.if counter.value == 4: + temp_byt.value = k.value + counter.value = counter.value + 1 + return sp.record(src=temp_map_string.get("src"), + dst=temp_map_string.get("dst"), + svc=temp_map_string.get("svc"), + sn=temp_int.value, + message=temp_byt.value) -def decode_gather_fee_message(rlp): - decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) - decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) - rlp_ = decode_list(rlp) - temp_byt = sp.local("byt4", sp.bytes("0x")) - counter = sp.local("counter_gather", 0) - temp_str = sp.local("str_gather", "") - sp.for c in rlp_.items(): - sp.if counter.value == 1: - temp_byt.value = c.value - sp.if counter.value == 0: - temp_str.value = decode_string(c.value) - counter.value = counter.value + 1 - starts_with = sp.slice(temp_byt.value, 0, 2).open_some() - sub_list = sp.local("sub_list", temp_byt.value) - sp.if starts_with == sp.bytes("0xb846"): - sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() - new_sub_list = decode_list(sub_list.value) - _svcs = sp.local("_svcs", {}, sp.TMap(sp.TNat, sp.TString)) - counter.value = 0 - sp.for x in new_sub_list.items(): - _svcs.value[counter.value] = decode_string(x.value) - counter.value = counter.value + 1 - return sp.record(fa=temp_str.value, - svcs=_svcs.value) -def decode_event_log(rlp): - decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) - event_mpt_node = sp.local("eventMptNode", sp.TMap(sp.TNat, sp.TString)) - rlp_ = decode_list(rlp) - counter = sp.local("counter", 0) - sp.for i in rlp_.items(): - event_mpt_node.value[counter.value] = i.value - counter.value = counter.value + 1 - return event_mpt_node + def decode_response(self, rlp): + temp_int = sp.local("int1", 0) + temp_byt = sp.local("byt1", sp.bytes("0x")) + rlp_ = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + counter = sp.local("counter_response", 0) + sp.for m in rlp_.items(): + sp.if counter.value == 0: + temp_int.value = Utils2.Int.of_bytes(m.value) + sp.if counter.value == 1: + temp_byt.value = m.value + counter.value = counter.value + 1 -def decode_transfer_coin_msg(rlp): - decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) - rlp_ = decode_list(rlp) - decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) + return sp.record(code=temp_int.value, message=sp.view("decode_string", self.data.helper, temp_byt.value, t=sp.TString).open_some()) - temp_byt = sp.local("byt_transfer", sp.bytes("0x")) - rv1_byt = sp.local("rv1_byt", sp.bytes("0x")) - rv2_byt = sp.local("rv2_byt", sp.bytes("0x")) - counter = sp.local("counter_coin", sp.nat(0)) - sp.for i in rlp_.items(): - sp.if counter.value == 2: - temp_byt.value = i.value - sp.if counter.value == 0: - rv1_byt.value = i.value - sp.if counter.value == 1: - rv2_byt.value = i.value - counter.value = counter.value + 1 - starts_with = sp.slice(temp_byt.value, 0, 2).open_some() - sub_list = sp.local("sub_list", temp_byt.value) - sp.if starts_with == sp.bytes("0xb846"): - sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() - new_sub_list = decode_list(sub_list.value) - counter.value = 0 - new_temp_byt = sp.local("new_temp_byt", sp.bytes("0x")) - rv_assets = sp.local("assets", {}, sp.TMap(sp.TNat, types.Types.Asset)) - sp.for x in new_sub_list.items(): - new_temp_byt.value = x.value - sp.if sp.slice(new_temp_byt.value, 0, 2).open_some() == sp.bytes("0xb846"): - new_temp_byt.value = sp.slice(new_temp_byt.value, 2, sp.as_nat(sp.len(new_temp_byt.value) - 2)).open_some() - temp_byt = sp.local("tempByt2", sp.bytes("0x")) - temp_int = sp.local("tempInt", sp.nat(0)) - counter.value = 0 - sp.for i in decode_list(new_temp_byt.value).items(): - sp.if counter.value == 1: - temp_int.value = Utils2.Int.of_bytes(i.value) + def decode_propagate_message(self, rlp): + rlp_ = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + counter = sp.local("counter_propagate", 0) + temp_string = sp.local("temp_string", "") + sp.for d in rlp_.items(): sp.if counter.value == 0: - temp_byt.value = i.value - rv_assets.value[counter.value] = sp.record(coin_name=decode_string(temp_byt.value), value=temp_int.value) + temp_string.value = sp.view("decode_string", self.data.helper, d.value, t=sp.TString).open_some() counter.value = counter.value + 1 - rv1 = decode_string(rv1_byt.value) - rv2 = decode_string(rv2_byt.value) - return sp.record(from_= rv1, to = rv2 , assets = rv_assets.value) + return temp_string.value -def decode_blacklist_msg(rlp): - decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) - rlp_ = decode_list(rlp) - decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) + def decode_init_message(self, rlp): + rlp_ = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + counter = sp.local("counter_init", 0) + temp_bytes = sp.local("byt_init", sp.bytes("0x")) + sp.for g in rlp_.items(): + sp.if counter.value == 0: + temp_bytes.value = g.value + counter.value = counter.value + 1 - temp_byt = sp.local("byt_transfer", sp.bytes("0x")) - rv1_byt = sp.local("rv1_byt", sp.bytes("0x")) - rv2_byt = sp.local("rv2_byt", sp.bytes("0x")) - counter = sp.local("counter_blacklist", 0) - sp.for i in rlp_.items(): - sp.if counter.value == 2: - rv2_byt.value = i.value - sp.if counter.value == 0: - rv1_byt.value = i.value - sp.if counter.value == 1: - temp_byt.value = i.value - counter.value = counter.value + 1 - starts_with = sp.slice(temp_byt.value, 0, 2).open_some() - sub_list = sp.local("sub_list", temp_byt.value) - sp.if starts_with == sp.bytes("0xb846"): - sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() - new_sub_list = decode_list(sub_list.value) - counter.value = 0 - new_temp_byt = sp.local("new_temp_byt", sp.bytes("0x")) - rv_blacklist_address = sp.local("blacklist_data", {}, sp.TMap(sp.TNat, sp.TString)) - sp.for x in new_sub_list.items(): - new_temp_byt.value = x.value - sp.if sp.slice(new_temp_byt.value, 0, 2).open_some() == sp.bytes("0xb846"): - new_temp_byt.value = sp.slice(new_temp_byt.value, 2, sp.as_nat(sp.len(new_temp_byt.value) - 2)).open_some() + starts_with = sp.slice(temp_bytes.value, 0, 2).open_some() + sub_list = sp.local("sub_list_init", temp_bytes.value) + sp.if starts_with == sp.bytes("0xb846"): + sub_list.value = sp.slice(temp_bytes.value, 2, sp.as_nat(sp.len(temp_bytes.value) - 2)).open_some() + new_sub_list = sp.view("decode_list", self.data.helper, sub_list.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + _links = sp.local("links_init", [], sp.TList(sp.TString)) counter.value = 0 - sp.for j in decode_list(new_temp_byt.value).items(): - rv_blacklist_address.value[counter.value] = decode_string(j.value) + sp.for x in new_sub_list.items(): + _links.value.push(sp.view("decode_string", self.data.helper, x.value, t=sp.TString).open_some()) + counter.value = counter.value + 1 + return _links.value + + def decode_bmc_service(self, rlp): + rlp_ = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + temp_string = sp.local("str_value", "") + temp_byt = sp.local("byt_value_bmc", sp.bytes("0x")) + counter = sp.local("counter_service", 0) + sp.for b in rlp_.items(): + sp.if counter.value == 0: + temp_string.value = sp.view("decode_string", self.data.helper, b.value, t=sp.TString).open_some() + sp.if counter.value == 1: + temp_byt.value = b.value counter.value = counter.value + 1 - rv1 = Utils2.Int.of_bytes(rv1_byt.value) - rv2 = decode_string(rv2_byt.value) - _service_type = sp.local("_service_type_blacklist", sp.variant("", 10)) - with sp.if_(rv1 == 0): - _service_type.value = sp.variant("ADD_TO_BLACKLIST", rv1) - with sp.else_(): - _service_type.value = sp.variant("REMOVE_FROM_BLACKLIST", rv1) - return sp.record(serviceType = _service_type.value , addrs = rv_blacklist_address.value , net = decode_string(rv2)) - -def decode_token_limit_msg(rlp): - decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) - rlp_ = decode_list(rlp) - decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) - - temp_byt = sp.local("byt_transfer", sp.bytes("0x")) - temp_byt1 = sp.local("byt_transfer_temp1", sp.bytes("0x")) - rv1_byt = sp.local("rv1_byt", sp.bytes("0x")) - counter = sp.local("counter_token_limit", 0) - sp.for i in rlp_.items(): - sp.if counter.value == 0: - temp_byt.value = i.value - sp.if counter.value == 1: - temp_byt1.value = i.value - sp.if counter.value == 2: - rv1_byt.value = i.value - counter.value = counter.value + 1 - starts_with = sp.slice(temp_byt.value, 0, 2).open_some() - sub_list = sp.local("sub_list", temp_byt.value) - sp.if starts_with == sp.bytes("0xb846"): - sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() - new_sub_list = decode_list(sub_list.value) - counter.value = 0 - rv_names = sp.local("names", {}, sp.TMap(sp.TNat, sp.TString)) - rv_limit = sp.local("limit", {}, sp.TMap(sp.TNat, sp.TNat)) - sp.for x in new_sub_list.items(): - rv_names.value[counter.value] = decode_string(x.value) - - new_sub_list1 = decode_list(sub_list.value) - sp.for y in new_sub_list1.items(): - rv_limit.value[counter.value] = Utils2.Int.of_bytes(y.value) - return sp.record(coin_name = rv_names.value, token_limit = rv_limit.value , net = decode_string(rv1_byt.value)) - -def to_message_event(rlp): - decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) - decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) - rlp_ = decode_list(rlp) - counter = sp.local("counter_event", 0) - rv1 = sp.local("rv1_event", "") - rv2 = sp.local("rv2_event", sp.nat(0)) - rv3 = sp.local("rv3_event", sp.bytes("0x")) - sp.for i in rlp_.items(): - sp.if counter.value == 2: - rv3.value = i.value - sp.if counter.value == 0: - rv1.value = decode_string(i.value) - sp.if counter.value == 1: - rv2.value = Utils2.Int.of_bytes(i.value) - counter.value = counter.value + 1 - return sp.record(next_bmc= rv1.value, seq= rv2.value, message = rv3.value) -def decode_receipt_proof(rlp): - decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) - rlp_ = decode_list(rlp) - temp_byt = sp.local("byt_receipt", sp.bytes("0x")) - rv_int = sp.local("rv_int_receipt", 0) - rv_int2 = sp.local("rv_int2_receipt", 0) - counter = sp.local("counter", 0) - sp.for i in rlp_.items(): - sp.if counter.value == 1: - temp_byt.value = i.value - sp.if counter.value == 0: - rv_int.value = Utils2.Int.of_bytes(i.value) - sp.if counter.value == 2: - rv_int2.value =Utils2.Int.of_bytes(i.value) - counter.value = counter.value + 1 + return sp.record(serviceType=temp_string.value, + payload=temp_byt.value) - starts_with = sp.slice(temp_byt.value, 0, 2).open_some() - sub_list = sp.local("sub_list", temp_byt.value) - sp.if starts_with == sp.bytes("0xb846"): - sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() - new_sub_list = decode_list(sub_list.value) - counter.value = 0 - events = sp.local("events_receipt", sp.map({}, tkey=sp.TNat, - tvalue=sp.TRecord(next_bmc= sp.TString, - seq= sp.TNat, - message = sp.TBytes))) - sp.for z in new_sub_list.items(): - starts_with = sp.slice(z.value, 0, 2).open_some() - sub_list.value = z.value + def decode_gather_fee_message(self, rlp): + rlp_ = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + temp_byt = sp.local("byt4", sp.bytes("0x")) + counter = sp.local("counter_gather", 0) + temp_str = sp.local("str_gather", "") + sp.for c in rlp_.items(): + sp.if counter.value == 1: + temp_byt.value = c.value + sp.if counter.value == 0: + temp_str.value = sp.view("decode_string", self.data.helper, c.value, t=sp.TString).open_some() + counter.value = counter.value + 1 + starts_with = sp.slice(temp_byt.value, 0, 2).open_some() + sub_list = sp.local("sub_list", temp_byt.value) sp.if starts_with == sp.bytes("0xb846"): - sub_list.value = sp.slice(z.value, 2, sp.as_nat(sp.len(z.value) - 2)).open_some() - sp.for a in decode_list(sub_list.value).items(): - events.value[counter.value] = to_message_event(a.value) + sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() + new_sub_list = sp.view("decode_list", self.data.helper, sub_list.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + _svcs = sp.local("_svcs", {}, sp.TMap(sp.TNat, sp.TString)) + counter.value = 0 + sp.for x in new_sub_list.items(): + _svcs.value[counter.value] = sp.view("decode_string", self.data.helper, x.value, t=sp.TString).open_some() + counter.value = counter.value + 1 + return sp.record(fa=temp_str.value, + svcs=_svcs.value) + + def to_message_event(self, rlp): + rlp_ = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + counter = sp.local("counter_event", 0) + rv1 = sp.local("rv1_event", "") + rv2 = sp.local("rv2_event", sp.nat(0)) + rv3 = sp.local("rv3_event", sp.bytes("0x")) + sp.for i in rlp_.items(): + sp.if counter.value == 2: + rv3.value = i.value + sp.if counter.value == 0: + rv1.value = sp.view("decode_string", self.data.helper, i.value, t=sp.TString).open_some() + sp.if counter.value == 1: + rv2.value = Utils2.Int.of_bytes(i.value) + counter.value = counter.value + 1 + return sp.record(next_bmc= rv1.value, seq= rv2.value, message = rv3.value) + + def decode_receipt_proof(self, rlp): + rlp_ = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + temp_byt = sp.local("byt_receipt", sp.bytes("0x")) + rv_int = sp.local("rv_int_receipt", 0) + rv_int2 = sp.local("rv_int2_receipt", 0) + counter = sp.local("counter", 0) + sp.for i in rlp_.items(): + sp.if counter.value == 1: + temp_byt.value = i.value + sp.if counter.value == 0: + rv_int.value = Utils2.Int.of_bytes(i.value) + sp.if counter.value == 2: + rv_int2.value =Utils2.Int.of_bytes(i.value) counter.value = counter.value + 1 - return sp.record(index = rv_int.value, events = events.value, height = rv_int2.value) - -def decode_receipt_proofs(rlp): - decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) - rlp_ = decode_list(rlp) - counter = sp.local("counter_receipt_proofs", 0) - receipt_proofs = sp.local("events_receipt_proofs", sp.map({}, tkey=sp.TNat, - tvalue=sp.TRecord(index = sp.TNat, - events = sp.TMap(sp.TNat, sp.TRecord(next_bmc=sp.TString, seq=sp.TNat, message=sp.TBytes)), - height = sp.TNat, - ) - ) - ) - temp_byt = sp.local("temp_byt_proofs", sp.bytes("0x")) - sp.for i in rlp_.items(): - sp.if counter.value == 0: - temp_byt.value = i.value - counter.value = counter.value + 1 - starts_with = sp.slice(temp_byt.value, 0, 2).open_some() - sub_list = sp.local("sub_list_proofs", temp_byt.value) - sp.if starts_with == sp.bytes("0xb846"): - sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() - new_sub_list = decode_list(sub_list.value) - counter.value = 0 - sp.if sp.len(new_sub_list) > 0: - sp.for x in rlp_.items(): - receipt_proofs.value[counter.value] = decode_receipt_proof(x.value) + starts_with = sp.slice(temp_byt.value, 0, 2).open_some() + sub_list = sp.local("sub_list", temp_byt.value) + sp.if starts_with == sp.bytes("0xb846"): + sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() + new_sub_list = sp.view("decode_list", self.data.helper, sub_list.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + counter.value = 0 + events = sp.local("events_receipt", sp.map({}, tkey=sp.TNat, + tvalue=sp.TRecord(next_bmc= sp.TString, + seq= sp.TNat, + message = sp.TBytes))) + sp.for z in new_sub_list.items(): + starts_with = sp.slice(z.value, 0, 2).open_some() + sub_list.value = z.value + sp.if starts_with == sp.bytes("0xb846"): + sub_list.value = sp.slice(z.value, 2, sp.as_nat(sp.len(z.value) - 2)).open_some() + view_value = sp.view("decode_list", self.data.helper, sub_list.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + sp.for a in view_value.items(): + events.value[counter.value] = self.to_message_event(a.value) + counter.value = counter.value + 1 + return sp.record(index = rv_int.value, events = events.value, height = rv_int2.value) + + + def decode_receipt_proofs(self, rlp): + rlp_ = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + counter = sp.local("counter_receipt_proofs", 0) + receipt_proofs = sp.local("events_receipt_proofs", sp.map({}, tkey=sp.TNat, + tvalue=sp.TRecord(index = sp.TNat, + events = sp.TMap(sp.TNat, sp.TRecord(next_bmc=sp.TString, seq=sp.TNat, message=sp.TBytes)), + height = sp.TNat, + ) + ) + ) + temp_byt = sp.local("temp_byt_proofs", sp.bytes("0x")) + sp.for i in rlp_.items(): + sp.if counter.value == 0: + temp_byt.value = i.value counter.value = counter.value + 1 - return receipt_proofs.value + starts_with = sp.slice(temp_byt.value, 0, 2).open_some() + sub_list = sp.local("sub_list_proofs", temp_byt.value) + sp.if starts_with == sp.bytes("0xb846"): + sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() + new_sub_list = sp.view("decode_list", self.data.helper, sub_list.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + counter.value = 0 + sp.if sp.len(new_sub_list) > 0: + sp.for x in rlp_.items(): + receipt_proofs.value[counter.value] = self.decode_receipt_proof(x.value) + counter.value = counter.value + 1 + return receipt_proofs.value diff --git a/smartpy/bmc/contracts/src/RLP_encode_struct.py b/smartpy/bmc/contracts/src/RLP_encode_struct.py index 5f41f162..3b9abd49 100644 --- a/smartpy/bmc/contracts/src/RLP_encode_struct.py +++ b/smartpy/bmc/contracts/src/RLP_encode_struct.py @@ -1,39 +1,36 @@ import smartpy as sp -Utils = sp.io.import_script_from_url( - "https://raw.githubusercontent.com/Acurast/acurast-hyperdrive/main/contracts/tezos/libs/utils.py") -LIST_SHORT_START = sp.bytes("0xc0") +class EncodeLibrary: + LIST_SHORT_START = sp.bytes("0xc0") + def encode_bmc_service(self, params): + sp.set_type(params, sp.TRecord(serviceType=sp.TString, payload=sp.TBytes)) -def encode_bmc_service(params): - sp.set_type(params, sp.TRecord(serviceType=sp.TString, payload=sp.TBytes)) + encode_service_type = sp.view("of_string", self.data.helper, params.serviceType, t=sp.TBytes).open_some() - encode_string_packed = sp.build_lambda(Utils.Bytes.of_string) - _rlpBytes = params.payload + encode_string_packed(params.serviceType) - with_length_prefix = sp.build_lambda(Utils.RLP.Encoder.with_length_prefix) - rlp_bytes_with_prefix = with_length_prefix(_rlpBytes) - return rlp_bytes_with_prefix + _rlpBytes = params.payload + encode_service_type + rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, _rlpBytes, t=sp.TBytes).open_some() + return rlp_bytes_with_prefix + def encode_bmc_message(self, params): + sp.set_type(params, sp.TRecord(src=sp.TString, dst=sp.TString, svc=sp.TString, sn=sp.TNat, message=sp.TBytes)) -def encode_bmc_message(params): - sp.set_type(params, sp.TRecord(src=sp.TString, dst=sp.TString, svc=sp.TString, sn=sp.TNat, message=sp.TBytes)) + encode_src = sp.view("of_string", self.data.helper, params.src, t=sp.TBytes).open_some() + encode_dst = sp.view("of_string", self.data.helper, params.dst, t=sp.TBytes).open_some() + encode_svc = sp.view("of_string", self.data.helper, params.svc, t=sp.TBytes).open_some() + encode_sn = sp.view("of_nat", self.data.helper, params.dst, t=sp.TBytes).open_some() - encode_string_packed = sp.build_lambda(Utils.Bytes.of_string) - encode_nat_packed = sp.build_lambda(Utils.Bytes.of_nat) - rlp = encode_string_packed(params.src) + encode_string_packed(params.dst)\ - + encode_string_packed(params.svc) + encode_nat_packed(params.sn) + params.message - with_length_prefix = sp.build_lambda(Utils.RLP.Encoder.with_length_prefix) - rlp_bytes_with_prefix = with_length_prefix(rlp) - return rlp_bytes_with_prefix + rlp = encode_src + encode_dst + encode_svc + encode_sn + params.message + rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + return rlp_bytes_with_prefix + def encode_response(self, params): + sp.set_type(params, sp.TRecord(code=sp.TNat, message=sp.TString)) -def encode_response(params): - sp.set_type(params, sp.TRecord(code=sp.TNat, message=sp.TString)) + encode_code = sp.view("of_nat", self.data.helper, params.code, t=sp.TBytes).open_some() + encode_message = sp.view("of_string", self.data.helper, params.message, t=sp.TBytes).open_some() - encode_string_packed = sp.build_lambda(Utils.Bytes.of_string) - encode_nat_packed = sp.build_lambda(Utils.Bytes.of_nat) - rlp = encode_nat_packed(params.code) + encode_string_packed(params.message) - with_length_prefix = sp.build_lambda(Utils.RLP.Encoder.with_length_prefix) - rlp_bytes_with_prefix = with_length_prefix(rlp) - return rlp_bytes_with_prefix + rlp = encode_code + encode_message + rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + return rlp_bytes_with_prefix diff --git a/smartpy/bmc/contracts/src/bmc_management.py b/smartpy/bmc/contracts/src/bmc_management.py index 246828e6..7d9138fd 100644 --- a/smartpy/bmc/contracts/src/bmc_management.py +++ b/smartpy/bmc/contracts/src/bmc_management.py @@ -1,15 +1,14 @@ import smartpy as sp -Utils = sp.io.import_script_from_url("https://raw.githubusercontent.com/Acurast/acurast-hyperdrive/main/contracts/tezos/libs/utils.py") types = sp.io.import_script_from_url("file:./contracts/src/Types.py") strings = sp.io.import_script_from_url("file:./contracts/src/String.py") rlp_encode = sp.io.import_script_from_url("file:./contracts/src/RLP_encode_struct.py") -class BMCManagement(sp.Contract): +class BMCManagement(sp.Contract, rlp_encode.EncodeLibrary): BLOCK_INTERVAL_MSEC = sp.nat(1000) - def __init__(self, owner_address): + def __init__(self, owner_address, helper_contract): self.init( owners=sp.map(l={owner_address:True}), number_of_owners=sp.nat(1), @@ -25,7 +24,8 @@ def __init__(self, owner_address): addrs=sp.set(), get_route_dst_from_net=sp.map(), get_link_from_net=sp.map(), - get_link_from_reachable_net=sp.map() + get_link_from_reachable_net=sp.map(), + helper=helper_contract ) self.init_type(sp.TRecord( @@ -43,7 +43,8 @@ def __init__(self, owner_address): addrs=sp.TSet(sp.TAddress), get_route_dst_from_net=sp.TMap(sp.TString, sp.TString), get_link_from_net=sp.TMap(sp.TString, sp.TString), - get_link_from_reachable_net=sp.TMap(sp.TString, types.Types.Tuple) + get_link_from_reachable_net=sp.TMap(sp.TString, types.Types.Tuple), + helper=sp.TAddress )) def only_owner(self): @@ -76,7 +77,7 @@ def set_bmc_btp_address(self, network): # call set_btp_address on BMCPeriphery set_btp_address_entry_point = sp.contract(sp.TString, self.data.bmc_periphery.open_some("Address not set"), - "set_btp_address").open_some() + "set_bmc_btp_address").open_some() sp.transfer(network, sp.tez(0), set_btp_address_entry_point) @sp.entry_point @@ -114,7 +115,7 @@ def is_owner(self, owner): :param owner: address to check :return: """ - sp.result(self.data.owners[owner]) + sp.result(self.data.owners.get(owner)) @sp.entry_point def add_service(self, svc, addr): @@ -150,9 +151,9 @@ def get_services(self): """ services = sp.compute(sp.map(tkey=sp.TNat, tvalue=types.Types.Service)) + i = sp.local("i", sp.nat(0)) sp.for item in self.data.list_bsh_names.elements(): - i = sp.local("i", 0) - services[i.value] = sp.record(svc=item, addr=self.data.bsh_services[item]) + services[i.value] = sp.record(svc=item, addr=self.data.bsh_services.get(item)) i.value += 1 sp.result(services) @@ -169,7 +170,7 @@ def add_link(self, link): net, addr= sp.match_pair(strings.split_btp_address(link, "prev_idx", "result", "my_list", "last", "penultimate")) with sp.if_(self.data.links.contains(link)): - sp.verify(self.data.links[link].is_connected == False, "AlreadyExistsLink") + sp.verify(self.data.links.get(link).is_connected == False, "AlreadyExistsLink") self.data.links[link] = sp.record( relays=sp.set([]), reachable=sp.set([]), @@ -205,7 +206,7 @@ def remove_link(self, link): self.only_owner() with sp.if_(self.data.links.contains(link)): - sp.verify(self.data.links[link].is_connected == True, "NotExistsLink") + sp.verify(self.data.links.get(link).is_connected == True, "NotExistsLink") with sp.else_(): sp.failwith("NotExistsLink") self._propagate_internal("Unlink", link) @@ -237,7 +238,7 @@ def set_link_rx_height(self, link, height): self.only_owner() with sp.if_(self.data.links.contains(link)): - sp.verify(self.data.links[link].is_connected == True, "NotExistsLink") + sp.verify(self.data.links.get(link).is_connected == True, "NotExistsLink") with sp.else_(): sp.failwith("NotExistsKey") sp.verify(height > sp.nat(0), "InvalidRxHeight") @@ -263,12 +264,12 @@ def set_link(self, _link, block_interval, _max_aggregation, delay_limit): self.only_owner() with sp.if_(self.data.links.contains(_link)): - sp.verify(self.data.links[_link].is_connected == True, "NotExistsLink") + sp.verify(self.data.links.get(_link).is_connected == True, "NotExistsLink") with sp.else_(): sp.failwith("NotExistsLink") sp.verify((_max_aggregation >= sp.nat(1)) & (delay_limit >= sp.nat(1)), "InvalidParam") - link = sp.local("link", self.data.links[_link], t=types.Types.Link).value + link = sp.local("link", self.data.links.get(_link), t=types.Types.Link).value # not implemented # scale = sp.local("scale", utils.get_scale(link.block_interval_src, link.block_interval_dst), t=sp.TNat) @@ -299,15 +300,13 @@ def _propagate_internal(self, service_type, link): sp.set_type(link, sp.TString) _bytes = sp.bytes("0x80") # can be any bytes - encode_string_packed = sp.build_lambda(Utils.Bytes.of_string) - rlp_bytes = _bytes + encode_string_packed(link) - with_length_prefix = sp.build_lambda(Utils.RLP.Encoder.with_length_prefix) - rlp_bytes_with_prefix = with_length_prefix(rlp_bytes) + rlp_bytes = _bytes + sp.view("of_string", self.data.helper, link, t=sp.TBytes).open_some() + rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp_bytes, t=sp.TBytes).open_some() #encode payload - final_rlp_bytes_with_prefix = with_length_prefix(rlp_bytes_with_prefix) + final_rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp_bytes_with_prefix, t=sp.TBytes).open_some() sp.for item in self.data.list_link_names.elements(): - sp.if self.data.links[item].is_connected: + sp.if self.data.links.get(item).is_connected: net, addr = sp.match_pair(strings.split_btp_address(item, "prev_idx1", "result1", "my_list1", "last1", "penultimate1")) # call send_message on BMCPeriphery @@ -315,7 +314,7 @@ def _propagate_internal(self, service_type, link): send_message_entry_point = sp.contract(send_message_args_type, self.data.bmc_periphery.open_some("Address not set"), "send_message").open_some() - send_message_args = sp.record(to=net, svc="bmc", sn=sp.nat(0), msg=rlp_encode.encode_bmc_service( + send_message_args = sp.record(to=net, svc="bmc", sn=sp.nat(0), msg=self.encode_bmc_service( sp.record(serviceType=service_type, payload=final_rlp_bytes_with_prefix))) sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) @@ -326,17 +325,14 @@ def _send_internal(self, target, service_type, links): rlp_bytes = sp.local("rlp_bytes", sp.bytes("0x")) with sp.if_(sp.len(links) == sp.nat(0)): - rlp_bytes.value = rlp_encode.LIST_SHORT_START + rlp_bytes.value = self.LIST_SHORT_START with sp.else_(): sp.for item in links: _bytes = sp.bytes("0x80") # can be any bytes - encode_string_packed = sp.build_lambda(Utils.Bytes.of_string) - _rlp_bytes = _bytes + encode_string_packed(item) - with_length_prefix = sp.build_lambda(Utils.RLP.Encoder.with_length_prefix) - rlp_bytes.value = with_length_prefix(_rlp_bytes) + _rlp_bytes = _bytes + sp.view("of_string", self.data.helper, item, t=sp.TBytes).open_some() + rlp_bytes.value = sp.view("with_length_prefix", self.data.helper, _rlp_bytes, t=sp.TBytes).open_some() #encode payload - with_length_prefix1 = sp.build_lambda(Utils.RLP.Encoder.with_length_prefix) - final_rlp_bytes_with_prefix = with_length_prefix1(rlp_bytes.value) + final_rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp_bytes.value, t=sp.TBytes).open_some() net, addr = sp.match_pair( strings.split_btp_address(target, "prev_idx2", "result2", "my_list2", "last2", "penultimate2")) @@ -345,7 +341,7 @@ def _send_internal(self, target, service_type, links): send_message_entry_point = sp.contract(send_message_args_type, self.data.bmc_periphery.open_some("Address not set"), "send_message").open_some() - send_message_args = sp.record(to=net, svc="bmc", sn=sp.nat(0), msg=rlp_encode.encode_bmc_service( + send_message_args = sp.record(to=net, svc="bmc", sn=sp.nat(0), msg=self.encode_bmc_service( sp.record(serviceType=service_type, payload=final_rlp_bytes_with_prefix))) sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) @@ -395,9 +391,9 @@ def get_routes(self): """ _routes = sp.compute(sp.map(tkey=sp.TNat, tvalue=types.Types.Route)) - i = sp.local("i", 0) + i = sp.local("i", sp.nat(0)) sp.for item in self.data.list_route_keys.elements(): - _routes[i.value] = sp.record(dst=item, next=self.data.routes[item]) + _routes[i.value] = sp.record(dst=item, next=self.data.routes.get(item)) i.value += 1 sp.result(_routes) @@ -414,7 +410,7 @@ def add_relay(self, link, addr): self.only_owner() sp.verify(self.data.links.contains(link), "NotExistsLink") - sp.verify(self.data.links[link].is_connected == True, "NotExistsLink") + sp.verify(self.data.links.get(link).is_connected == True, "NotExistsLink") self.data.links[link].relays = addr sp.for item in addr.elements(): self.data.relay_stats[item] = sp.record(addr=item, block_count=sp.nat(0), msg_count=sp.nat(0)) @@ -432,10 +428,10 @@ def remove_relay(self, link, addr): self.only_owner() sp.verify(self.data.links.contains(link), "NotExistsLink") - sp.verify((self.data.links[link].is_connected == True) & (sp.len(self.data.links[link].relays.elements()) != sp.nat(0)), + sp.verify((self.data.links.get(link).is_connected == True) & (sp.len(self.data.links.get(link).relays.elements()) != sp.nat(0)), "Unauthorized") - sp.for item in self.data.links[link].relays.elements(): + sp.for item in self.data.links.get(link).relays.elements(): sp.if item != addr: self.data.addrs.add(item) @@ -455,46 +451,46 @@ def get_relays(self, link): """ sp.set_type(link, sp.TString) - sp.result(self.data.links[link].relays.elements()) + sp.result(self.data.links.get(link).relays.elements()) @sp.onchain_view() def get_bsh_service_by_name(self, service_name): sp.set_type(service_name, sp.TString) - sp.result(self.data.bsh_services[service_name]) + sp.result(self.data.bsh_services.get(service_name)) @sp.onchain_view() def get_link(self, to): sp.set_type(to, sp.TString) - sp.result(self.data.links[to]) + sp.result(self.data.links.get(to)) @sp.onchain_view() def get_link_rx_seq(self, prev): sp.set_type(prev, sp.TString) - sp.result(self.data.links[prev].rx_seq) + sp.result(self.data.links.get(prev).rx_seq) @sp.onchain_view() def get_link_tx_seq(self, prev): sp.set_type(prev, sp.TString) - sp.result(self.data.links[prev].tx_seq) + sp.result(self.data.links.get(prev).tx_seq) @sp.onchain_view() def get_link_rx_height(self, prev): sp.set_type(prev, sp.TString) - sp.result(self.data.links[prev].rx_height) + sp.result(self.data.links.get(prev).rx_height) @sp.onchain_view() def get_link_relays(self, prev): sp.set_type(prev, sp.TString) - sp.result(self.data.links[prev].relays.elements()) + sp.result(self.data.links.get(prev).relays.elements()) @sp.onchain_view() def get_relay_status_by_link(self, prev): sp.set_type(prev, sp.TString) _relays = sp.compute(sp.map(tkey=sp.TNat, tvalue=types.Types.RelayStats)) - i = sp.local("i", 0) - sp.for item in self.data.links[prev].relays.elements(): - _relays[i.value] = self.data.relay_stats[item] + i = sp.local("i", sp.nat(0)) + sp.for item in self.data.links.get(prev).relays.elements(): + _relays[i.value] = self.data.relay_stats.get(item) i.value += 1 sp.result(_relays) @@ -539,8 +535,8 @@ def delete_link_reachable(self, prev, index): sp.set_type(index, sp.TNat) self.only_bmc_periphery() - i = sp.local("i", 0) - sp.for item in self.data.links[prev].reachable.elements(): + i = sp.local("i", sp.nat(0)) + sp.for item in self.data.links.get(prev).reachable.elements(): sp.if i.value == index: net, addr = sp.match_pair( strings.split_btp_address(item, "prev_idx", "result", "my_list", "last", "penultimate")) @@ -568,16 +564,16 @@ def resolve_route(self, dst_net): sp.set_type(dst_net, sp.TString) self.only_bmc_periphery() - dst = sp.local("dst", self.data.get_route_dst_from_net[dst_net], t=sp.TString) + dst = sp.local("dst", self.data.get_route_dst_from_net.get(dst_net), t=sp.TString) with sp.if_(sp.len(sp.pack(dst.value))!= sp.nat(0)): - sp.result(sp.pair(self.data.routes[dst.value], dst.value)) + sp.result(sp.pair(self.data.routes.get(dst.value), dst.value)) with sp.else_(): - dst_link = sp.local("dst_link", self.data.get_link_from_net[dst_net], t=sp.TString) + dst_link = sp.local("dst_link", self.data.get_link_from_net.get(dst_net), t=sp.TString) with sp.if_(sp.len(sp.pack(dst_link.value)) != sp.nat(0)): sp.result(sp.pair(dst_link.value, dst_link.value)) with sp.else_(): - res = sp.local("res", self.data.get_link_from_reachable_net[dst_net], t=types.Types.Tuple) + res = sp.local("res", self.data.get_link_from_reachable_net.get(dst_net), t=types.Types.Tuple) sp.verify(sp.len(sp.pack(res.value.to)) > sp.nat(0), "Unreachable: " + dst_net + " is unreachable") sp.result(sp.pair(res.value.prev, res.value.to)) @@ -587,11 +583,12 @@ def resolve_route(self, dst_net): def test(): alice = sp.test_account("Alice") owner = sp.test_account("Owner") + helper = sp.test_account("Helper") bmc_periphery = sp.test_account("BMC Periphery") # bmc= sp.test_account("BMC") scenario = sp.test_scenario() - bmc_man = BMCManagement(owner.address) + bmc_man = BMCManagement(owner.address, helper.address) scenario += bmc_man bmc_man.set_bmc_periphery(bmc_periphery.address).run(sender=owner) @@ -599,13 +596,14 @@ def test(): # bmc_man.remove_owner(alice.address).run(sender=alice) - bmc_man.add_link("btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW").run(sender=alice) - bmc_man.remove_link("btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW").run(sender=alice) - bmc_man.add_link("btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW").run(sender=alice) + # bmc_man.add_link("btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW").run(sender=alice) + # bmc_man.remove_link("btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW").run(sender=alice) + # bmc_man.add_link("btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW").run(sender=alice) - bmc_man.set_link_rx_height(sp.record(link="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", height=sp.nat(2))).run(sender=alice) - bmc_man.set_link(sp.record(_link="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", block_interval=sp.nat(2), - _max_aggregation=sp.nat(3), delay_limit=sp.nat(2))).run(sender=alice) + # bmc_man.set_link_rx_height(sp.record(link="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", height=sp.nat(2))).run(sender=alice) + # bmc_man.set_link(sp.record(_link="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", block_interval=sp.nat(2), + # _max_aggregation=sp.nat(3), delay_limit=sp.nat(2))).run(sender=alice) -sp.add_compilation_target("bmc_management", BMCManagement(owner_address=sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"))) +sp.add_compilation_target("bmc_management", BMCManagement(owner_address=sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), + helper_contract=sp.address("KT1FfkTSts5DnvyJp2qZbPMeqm2XpMYES7Vr"))) diff --git a/smartpy/bmc/contracts/src/bmc_periphery.py b/smartpy/bmc/contracts/src/bmc_periphery.py index 5c2ffbb6..1fbf0557 100644 --- a/smartpy/bmc/contracts/src/bmc_periphery.py +++ b/smartpy/bmc/contracts/src/bmc_periphery.py @@ -4,10 +4,9 @@ strings = sp.io.import_script_from_url("file:./contracts/src/String.py") rlp_encode = sp.io.import_script_from_url("file:./contracts/src/RLP_encode_struct.py") rlp_decode = sp.io.import_script_from_url("file:./contracts/src/RLP_decode_struct.py") -parse_addr = sp.io.import_script_from_url("file:./contracts/src/parse_address.py") -class BMCPreiphery(sp.Contract): +class BMCPreiphery(sp.Contract, rlp_decode.DecodeLibrary, rlp_encode.EncodeLibrary): BMC_ERR = sp.nat(10) BSH_ERR = sp.nat(40) UNKNOWN_ERR = sp.nat(0) @@ -22,19 +21,21 @@ class BMCPreiphery(sp.Contract): BMCRevertUnknownHandleBTPError = sp.string("UnknownHandleBTPError") BMCRevertUnknownHandleBTPMessage = sp.string("UnknownHandleBTPMessage") - def __init__(self, bmc_management_addr): + def __init__(self, bmc_management_addr, helper_contract, parse_address): self.init( + helper=helper_contract, bmc_btp_address=sp.none, - bmc_management=bmc_management_addr + bmc_management=bmc_management_addr, + parse_contract=parse_address ) @sp.entry_point - def set_btp_address(self, network): + def set_bmc_btp_address(self, network): sp.set_type(network, sp.TString) sp.verify(sp.sender == self.data.bmc_management, "Unauthorized") with sp.if_(self.data.bmc_btp_address == sp.none): - self.data.bmc_btp_address = sp.some(sp.string("btp://") + network + "/" + parse_addr.add_to_str(sp.self_address)) + self.data.bmc_btp_address = sp.some(sp.string("btp://") + network + "/" + sp.view("add_to_str", self.data.parse_contract, sp.self_address, t=sp.TString).open_some()) with sp.else_(): sp.failwith("Address already set") @@ -46,10 +47,11 @@ def _require_registered_relay(self, prev): sp.set_type(prev, sp.TString) relays = sp.view("get_link_relays", self.data.bmc_management, prev, t=sp.TList(sp.TAddress)).open_some() + valid = sp.local("valid", False) sp.for x in relays: sp.if sp.sender == x: - return - sp.failwith(self.BMCRevertUnauthorized) + valid.value = True + sp.verify(valid.value, self.BMCRevertUnauthorized) @sp.entry_point def handle_relay_message(self, prev, msg): @@ -64,8 +66,7 @@ def handle_relay_message(self, prev, msg): rx_seq = sp.local("rx_seq", link_rx_seq, t=sp.TNat) rx_height = sp.local("rx_height", link_rx_height, t=sp.TNat) - rps = rlp_decode.decode_receipt_proofs(msg) - + rps = self.decode_receipt_proofs(msg) bmc_msg = sp.local("bmc_msg", sp.record(src="", dst="", svc="", sn=sp.nat(0), message=sp.bytes("0x")), t=types.Types.BMCMessage) ev = sp.local("ev", sp.record(next_bmc="", seq=sp.nat(0), message=sp.bytes("0x")), t=types.Types.MessageEvent) @@ -87,7 +88,7 @@ def handle_relay_message(self, prev, msg): sp.if ev.value.seq > rx_seq.value: sp.failwith(self.BMCRevertInvalidSeqNumber) # TODO: implement code inside of try catch - _decoded = rlp_decode.decode_bmc_message(ev.value.message) + _decoded = self.decode_bmc_message(ev.value.message) bmc_msg.value = _decoded sp.if bmc_msg.value.dst == self.data.bmc_btp_address.open_some("Address not set"): @@ -131,11 +132,10 @@ def _handle_message(self, prev, msg): # bsh_addr = sp.local("bsh_addr",sp.TAddress) with sp.if_(msg.svc == "bmc"): # TODO: implement try catch - sm = rlp_decode.decode_bmc_service(msg.message) - + sm = self.decode_bmc_service(msg.message) sp.if sm.serviceType == "FeeGathering": # decode inside try - gather_fee = rlp_decode.decode_gather_fee_message(sm.payload) + gather_fee = self.decode_gather_fee_message(sm.payload) sp.for c in sp.range(sp.nat(0), sp.len(gather_fee.svcs)): bsh_addr = sp.view("get_bsh_service_by_name", self.data.bmc_management, gather_fee.svcs[c], t=sp.TAddress).open_some("Invalid Call") @@ -151,17 +151,17 @@ def _handle_message(self, prev, msg): sp.transfer(handle_fee_gathering_args, sp.tez(0), handle_fee_gathering_entry_point) sp.if sm.serviceType == "Link": - to = rlp_decode.decode_propagate_message(sm.payload) + to = self.decode_propagate_message(sm.payload) link = sp.view("get_link", self.data.bmc_management, prev, t=types.Types.Link).open_some() - check = sp.local("check", False).value + check = sp.local("check", False) sp.if link.is_connected: sp.for e in link.reachable.elements(): sp.if to == e: - check = True + check.value = True # sp.break - sp.if not check: + sp.if check.value == False: links = sp.list([to], t=sp.TString) # call update_link_reachable on BMCManagement @@ -173,7 +173,7 @@ def _handle_message(self, prev, msg): sp.transfer(update_link_reachable_args, sp.tez(0), update_link_reachable_entry_point) sp.if sm.serviceType == "Unlink": - to = rlp_decode.decode_propagate_message(sm.payload) + to = self.decode_propagate_message(sm.payload) link = sp.view("get_link", self.data.bmc_management, prev, t=types.Types.Link).open_some() sp.if link.is_connected: @@ -191,7 +191,7 @@ def _handle_message(self, prev, msg): f.value += sp.nat(1) sp.if sm.serviceType == "Init": - links = rlp_decode.decode_init_message(sm.payload) + links = self.decode_init_message(sm.payload) # call update_link_reachable on BMCManagement update_link_reachable_args_type = sp.TRecord(prev=sp.TString, to=sp.TList(sp.TString)) update_link_reachable_entry_point = sp.contract(update_link_reachable_args_type, @@ -202,45 +202,43 @@ def _handle_message(self, prev, msg): with sp.else_(): bsh_addr = sp.view("get_bsh_service_by_name", self.data.bmc_management, msg.svc, t=sp.TAddress).open_some("Invalid view") - sp.if bsh_addr == sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg"): + with sp.if_(bsh_addr == sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): self._send_error(prev, msg, self.BMC_ERR, self.BMCRevertNotExistsBSH) - return - - with sp.if_(msg.sn >= sp.nat(0)): - net, addr = sp.match_pair(strings.split_btp_address(msg.src, "prev_idx", "result", "my_list", "last", "penultimate")) - # put it in try catch - # call handle_btp_message on bts periphery - handle_btp_message_args_type = sp.TRecord(_from=sp.TString, svc=sp.TString, sn=sp.TNat, msg=sp.TBytes) - handle_btp_message_entry_point = sp.contract(handle_btp_message_args_type, - bsh_addr, - "handle_btp_message").open_some() - handle_btp_message_args = sp.record(_from=net, svc=msg.svc, sn=msg.sn, msg=msg.message) - sp.transfer(handle_btp_message_args, sp.tez(0), handle_btp_message_entry_point) with sp.else_(): - res = rlp_decode.decode_response(msg.message) - # put it in try catch - # here sn is sent negative in solidity (msg.sn *-1) - # call handle_btp_error on bts periphery - handle_btp_error_args_type = sp.TRecord(svc=sp.TString, sn=sp.TNat, code=sp.TNat, msg=sp.TString) - handle_btp_error_entry_point = sp.contract(handle_btp_error_args_type, - bsh_addr, - "handle_btp_error").open_some() - handle_btp_error_args = sp.record(svc=msg.svc, sn=msg.sn, code=res.code, msg=res.message) - sp.transfer(handle_btp_error_args, sp.tez(0), handle_btp_error_entry_point) - #TODO: emit in case of error + with sp.if_(msg.sn >= sp.nat(0)): + net, addr = sp.match_pair(strings.split_btp_address(msg.src, "prev_idx", "result", "my_list", "last", "penultimate")) + # put it in try catch + # call handle_btp_message on bts periphery + handle_btp_message_args_type = sp.TRecord(_from=sp.TString, svc=sp.TString, sn=sp.TNat, msg=sp.TBytes) + handle_btp_message_entry_point = sp.contract(handle_btp_message_args_type, + bsh_addr, + "handle_btp_message").open_some() + handle_btp_message_args = sp.record(_from=net, svc=msg.svc, sn=msg.sn, msg=msg.message) + sp.transfer(handle_btp_message_args, sp.tez(0), handle_btp_message_entry_point) + + with sp.else_(): + res = self.decode_response(msg.message) + # put it in try catch + # here sn is sent negative in solidity (msg.sn *-1) + # call handle_btp_error on bts periphery + handle_btp_error_args_type = sp.TRecord(svc=sp.TString, sn=sp.TNat, code=sp.TNat, msg=sp.TString) + handle_btp_error_entry_point = sp.contract(handle_btp_error_args_type, + bsh_addr, + "handle_btp_error").open_some() + handle_btp_error_args = sp.record(svc=msg.svc, sn=msg.sn, code=res.code, msg=res.message) + sp.transfer(handle_btp_error_args, sp.tez(0), handle_btp_error_entry_point) + #TODO: emit in case of error def _send_message(self, to ,serialized_msg): sp.set_type(to, sp.TString) sp.set_type(serialized_msg, sp.TBytes) # call update_link_tx_seq on BMCManagement - update_link_tx_seq_args_type = sp.TRecord(prev=sp.TString) - update_link_tx_seq_entry_point = sp.contract(update_link_tx_seq_args_type, + update_link_tx_seq_entry_point = sp.contract(sp.TString, self.data.bmc_management, "update_link_tx_seq").open_some() - update_link_tx_seq_args = sp.record(prev=to) - sp.transfer(update_link_tx_seq_args, sp.tez(0), update_link_tx_seq_entry_point) + sp.transfer(to, sp.tez(0), update_link_tx_seq_entry_point) sp.emit(sp.record(next=to, seq=sp.view("get_link_tx_seq", self.data.bmc_management, to, t=sp.TNat).open_some(), msg=serialized_msg), tag="Message") @@ -252,12 +250,12 @@ def _send_error(self, prev, message, err_code, err_msg): sp.set_type(err_msg, sp.TString) sp.if message.sn > sp.nat(0): - serialized_msg = rlp_encode.encode_bmc_message(sp.record( + serialized_msg = self.encode_bmc_message(sp.record( src=self.data.bmc_btp_address.open_some("Address not set"), dst=message.src, svc=message.svc, sn=message.sn, - message=rlp_encode.encode_response(sp.record(code=err_code, message=err_msg)) + message=self.encode_response(sp.record(code=err_code, message=err_msg)) )) self._send_message(prev, serialized_msg) @@ -283,7 +281,7 @@ def send_message(self, to, svc, sn, msg): next_link, dst = sp.match_pair(sp.view("resolve_route", self.data.bmc_management, to, t=sp.TPair(sp.TString, sp.TString)).open_some()) - rlp = rlp_encode.encode_bmc_message(sp.record( + rlp = self.encode_bmc_message(sp.record( src=self.data.bmc_btp_address.open_some("Address not set"), dst=dst, svc=svc, @@ -314,13 +312,17 @@ def get_status(self, _link): @sp.add_test(name="BMC") def test(): alice = sp.test_account("Alice") + helper = sp.test_account("Helper") + parse_contract = sp.test_account("Parser") bmc_management = sp.test_account("BMC Management") # bmc= sp.test_account("BMC") scenario = sp.test_scenario() - bmc = BMCPreiphery(bmc_management.address) + bmc = BMCPreiphery(bmc_management.address, helper.address, parse_contract.address) scenario += bmc # bmc.handle_relay_message(sp.record(prev="demo string", msg=sp.bytes("0x0dae11"))).run(sender=alice) -sp.add_compilation_target("bmc_periphery", BMCPreiphery(bmc_management_addr=sp.address("KT1GmZEcN82NbZrxXkhazvuX6ybJB12JTJAT"))) +sp.add_compilation_target("bmc_periphery", BMCPreiphery(bmc_management_addr=sp.address("KT1CpKLekGHbe89FzusNobRRvPiCVYvpG21f"), + helper_contract=sp.address("KT1FfkTSts5DnvyJp2qZbPMeqm2XpMYES7Vr"), + parse_address=sp.address("KT1XgRyjQPfpfwNrvYYpgERpYpCrGh24aoPX"))) diff --git a/smartpy/bmc/contracts/src/helper.py b/smartpy/bmc/contracts/src/helper.py new file mode 100644 index 00000000..7e0dc295 --- /dev/null +++ b/smartpy/bmc/contracts/src/helper.py @@ -0,0 +1,48 @@ +import smartpy as sp + +Utils = sp.io.import_script_from_url("https://raw.githubusercontent.com/Acurast/acurast-hyperdrive/main/contracts/tezos/libs/utils.py") + + +class Helper(sp.Contract): + def __init__(self): + self.init() + + @sp.onchain_view() + def decode_string(self, params): + sp.set_type(params, sp.TBytes) + decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) + sp.result(decode_string(params)) + + @sp.onchain_view() + def decode_list(self, params): + sp.set_type(params, sp.TBytes) + decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) + sp.result(decode_list(params)) + + @sp.onchain_view() + def of_string(self, params): + sp.set_type(params, sp.TString) + encode_string_packed = sp.build_lambda(Utils.Bytes.of_string) + sp.result(encode_string_packed(params)) + + @sp.onchain_view() + def of_nat(self, params): + sp.set_type(params, sp.TNat) + encode_nat_packed = sp.build_lambda(Utils.Bytes.of_string) + sp.result(encode_nat_packed(params)) + + @sp.onchain_view() + def with_length_prefix(self, params): + sp.set_type(params, sp.TBytes) + encode_length_packed = sp.build_lambda(Utils.RLP.Encoder.with_length_prefix) + sp.result(encode_length_packed(params)) + + +@sp.add_test(name="Helper") +def test(): + scenario = sp.test_scenario() + helper = Helper() + scenario += helper + + +sp.add_compilation_target("helper", Helper()) \ No newline at end of file diff --git a/smartpy/bmc/contracts/src/parse_address.py b/smartpy/bmc/contracts/src/parse_address.py index 7d4f63ab..acd619b5 100644 --- a/smartpy/bmc/contracts/src/parse_address.py +++ b/smartpy/bmc/contracts/src/parse_address.py @@ -1,164 +1,104 @@ import smartpy as sp Utils = sp.io.import_script_from_url("https://raw.githubusercontent.com/RomarQ/tezos-sc-utils/main/smartpy/utils.py") -tz_prefixes = sp.map({ - sp.bytes('0x0000'): sp.string('tz1'), - sp.bytes('0x0001'): sp.string('tz2'), - sp.bytes('0x0002'): sp.string('tz3'), - sp.bytes('0x0003'): sp.string('tz4') -}) -base58_encodings=sp.list([ - sp.map({"prefix": "tz1", "elem1": "6", "elem2": "161", "elem3": "159", "len": "20"}), - sp.map({"prefix": "tz2", "elem1": "6", "elem2": "161", "elem3": "161", "len": "20"}), - sp.map({"prefix": "tz3", "elem1": "6", "elem2": "161", "elem3": "164", "len": "20"}), - sp.map({"prefix": "tz4", "elem1": "6", "elem2": "161", "elem3": "16", "len": "20"}), - sp.map({"prefix": "KT1", "elem1": "2", "elem2": "90", "elem3": "121", "len": "20"}), -]) -test_str = "" -test_addr = sp.address("KT1GPaeWzJpZAoY45v4aEWBFiqp6vtkLUkgw") - - -def unforge_address(data): - """Decode address or key_hash from bytes. - - :param data: encoded address or key_hash - :returns: base58 encoded address - """ - sp.set_type(data, sp.TBytes) - byt = sp.slice(data, 6, 22).open_some() - prefix = sp.slice(byt, 0, 2).open_some() - starts_with = sp.slice(byt, 0, 1).open_some() - ends_with = sp.slice(byt, 21, 1).open_some() - sliced_byte = sp.slice(byt, 1, 20).open_some() - local_byte = sp.local("local_byte", sp.bytes("0x")) - - sp.for item in tz_prefixes.items(): - sp.if item.key == prefix: - return base58_encode(sp.slice(byt, 2, 20).open_some(), Utils.Bytes.of_string(item.value), local_byte) - - sp.if (starts_with == sp.bytes("0x01")) & (ends_with == sp.bytes("0x00")): - return base58_encode(sliced_byte, Utils.Bytes.of_string("KT1"), local_byte) - sp.if (starts_with == sp.bytes("0x02")) & (ends_with == sp.bytes("0x00")): - return base58_encode(sliced_byte, Utils.Bytes.of_string("txr1"), local_byte) - sp.if (starts_with == sp.bytes("0x03")) & (ends_with == sp.bytes("0x00")): - return base58_encode(sliced_byte, Utils.Bytes.of_string("sr1"), local_byte) - -def tb(_list): - byte_str = sp.local("byte_str", sp.bytes("0x")) - sp.for num in _list: - byte_str.value += Utils.Bytes.of_nat(num) - return byte_str.value - -def base58_encode(v, prefix, _byte): - """ - Encode data using Base58 with checksum and add an according binary prefix in the end. - :param v: Array of bytes - :param prefix: Human-readable prefix (use b'') e.g. b'tz', b'KT', etc - :param local_byte: local variable - - :returns: bytes (use string.decode()) - """ - length_v = sp.to_int(sp.len(v)) - encoding = sp.local("encode", sp.map({})) - byte_from_tbl = sp.local("byte_from_tbl", sp.bytes("0x")) - byte_value = _byte - - sp.for enc in base58_encodings: - sp.if (length_v == Utils.Int.of_string(enc["len"])) & (prefix == Utils.Bytes.of_string(enc["prefix"])) : - encoding.value = enc - byte_from_tbl.value = tb([sp.as_nat(Utils.Int.of_string(enc["elem1"])), - sp.as_nat(Utils.Int.of_string(enc["elem2"])), - sp.as_nat(Utils.Int.of_string(enc["elem3"]))]) - sha256_encoding = sp.sha256(sp.sha256(byte_from_tbl.value + v)) - sha256_encoding = byte_from_tbl.value + v + sp.slice(sha256_encoding, 0, 4).open_some() - acc = sp.local("for_while_loop", Utils.Int.of_bytes(sha256_encoding)) - alphabet = Utils.Bytes.of_string("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") - base = 58 - sp.while acc.value > 0: - (acc.value, idx) = sp.match_pair(sp.ediv(acc.value, base).open_some()) - byte_value.value = sp.slice(alphabet, idx , 1).open_some() + byte_value.value - - return sp.unpack(sp.bytes("0x050100000024") + byte_value.value, sp.TString).open_some() - -def add_to_str(params): - sp.set_type(params, sp.TAddress) - return unforge_address(sp.pack(params)) - -def str_to_addr(params): - sp.set_type(params, sp.TString) - - string_in_bytes = sp.pack(params) - actual_prefix = sp.local("actual_prefix", "") - addr = sp.local("addr", sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")) - alphabet = Utils.Bytes.of_string("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") - - sp.if sp.len(string_in_bytes) == sp.nat(42): - string_in_bytes = sp.slice(string_in_bytes, 6, 36).open_some() - - element_list = sp.range(0, sp.len(alphabet), 1) - temp_map = sp.local("temp_map", {}) - temp_var = sp.local("y", 0) - sp.for elem in element_list: - temp_var.value = elem - temp_map.value[sp.slice(alphabet, temp_var.value, 1).open_some()] = temp_var.value - decimal = sp.local("decimal", 0) - base = sp.len(alphabet) - element_list_2 = sp.range(0, sp.len(string_in_bytes), 1) - sp.for elem in element_list_2: - decimal.value = decimal.value * base + temp_map.value[sp.slice(string_in_bytes, elem, 1).open_some()] - byt_value = Utils.Bytes.of_nat(sp.as_nat(sp.to_int(decimal.value))) - new_byt_value = sp.slice(byt_value, 0, sp.as_nat(sp.len(byt_value) - 4)).open_some() - prefix = sp.slice(new_byt_value, 0, 3 ).open_some() - prefix_len = sp.range(0, sp.len(prefix), 1) - temp_var3 = sp.local("z", 0) - list_string = sp.local("list_string", []) - sp.for x in prefix_len: - temp_var3.value = x - list_string.value.push(Utils.Int.of_bytes(sp.slice(prefix, temp_var3.value, 1).open_some())) - v = sp.slice(new_byt_value, 3, sp.as_nat(sp.len(new_byt_value) - 3)) - byte_local = sp.local("byt_old", sp.bytes("0x")) - sp.for enc in base58_encodings: - byte_local.value = tb([sp.as_nat(Utils.Int.of_string(enc["elem1"])), - sp.as_nat(Utils.Int.of_string(enc["elem2"])), - sp.as_nat(Utils.Int.of_string(enc["elem3"]))]) - sp.if byte_local.value == prefix : - actual_prefix.value = enc["prefix"] - sp.for item in tz_prefixes.items(): - sp.if item.value == actual_prefix.value: - decoded_address = sp.unpack(sp.bytes("0x050a00000016") + item.key + v.open_some(), - sp.TAddress) - addr.value = decoded_address.open_some() - return addr.value - sp.if actual_prefix.value == "KT1": - decoded_address = sp.unpack(sp.bytes("0x050a00000016") + sp.bytes("0x01") + v.open_some() + sp.bytes("0x00"), - sp.TAddress) - return decoded_address.open_some() - sp.if actual_prefix.value == "txr1": - decoded_address = sp.unpack(sp.bytes("0x050a00000016") + sp.bytes("0x02") + v.open_some() + sp.bytes("0x00"), - sp.TAddress) - return decoded_address.open_some() - sp.if actual_prefix.value == "sr1": - decoded_address = sp.unpack(sp.bytes("0x050a00000016") + sp.bytes("0x03") + v.open_some() + sp.bytes("0x00"), - sp.TAddress) - return decoded_address.open_some() - - sp.if actual_prefix.value == "": - return sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg") - - with sp.else_(): - return sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg") - -# @sp.add_test(name="Conversion") -# def test(): -# alice=sp.test_account("Alice") -# c1 = Conversion() -# scenario = sp.test_scenario() -# scenario.h1("Conversion") -# scenario += c1 -# c1.add_to_str(sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP")) -# c1.str_to_addr("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP") -# -# -# sp.add_compilation_target("smartpy-utils", Conversion()) - +class ParseAddress(sp.Contract): + tz_prefixes = sp.map({ + sp.bytes('0x0000'): sp.string('tz1'), + sp.bytes('0x0001'): sp.string('tz2'), + sp.bytes('0x0002'): sp.string('tz3'), + sp.bytes('0x0003'): sp.string('tz4') + }) + base58_encodings = sp.list([ + sp.map({"prefix": "tz1", "elem1": "6", "elem2": "161", "elem3": "159", "len": "20"}), + sp.map({"prefix": "tz2", "elem1": "6", "elem2": "161", "elem3": "161", "len": "20"}), + sp.map({"prefix": "tz3", "elem1": "6", "elem2": "161", "elem3": "164", "len": "20"}), + sp.map({"prefix": "tz4", "elem1": "6", "elem2": "161", "elem3": "16", "len": "20"}), + sp.map({"prefix": "KT1", "elem1": "2", "elem2": "90", "elem3": "121", "len": "20"}), + ]) + + def __init__(self): + self.init() + + def unforge_address(self, data): + """Decode address or key_hash from bytes. + + :param data: encoded address or key_hash + :returns: base58 encoded address + """ + sp.set_type(data, sp.TBytes) + byt = sp.slice(data, 6, 22).open_some() + prefix = sp.slice(byt, 0, 2).open_some() + starts_with = sp.slice(byt, 0, 1).open_some() + ends_with = sp.slice(byt, 21, 1).open_some() + sliced_byte = sp.slice(byt, 1, 20).open_some() + local_byte = sp.local("local_byte", sp.bytes("0x")) + return_value = sp.local("return_value", "tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg", sp.TString) + + sp.for item in self.tz_prefixes.items(): + sp.if item.key == prefix: + return_value.value = self.base58_encode(sp.slice(byt, 2, 20).open_some(), Utils.Bytes.of_string(item.value), local_byte) + + sp.if (starts_with == sp.bytes("0x01")) & (ends_with == sp.bytes("0x00")): + return_value.value = self.base58_encode(sliced_byte, Utils.Bytes.of_string("KT1"), local_byte) + sp.if (starts_with == sp.bytes("0x02")) & (ends_with == sp.bytes("0x00")): + return_value.value = self.base58_encode(sliced_byte, Utils.Bytes.of_string("txr1"), local_byte) + sp.if (starts_with == sp.bytes("0x03")) & (ends_with == sp.bytes("0x00")): + return_value.value = self.base58_encode(sliced_byte, Utils.Bytes.of_string("sr1"), local_byte) + + return return_value.value + + def tb(self, _list): + byte_str = sp.local("byte_str", sp.bytes("0x")) + sp.for num in _list: + byte_str.value += Utils.Bytes.of_nat(num) + return byte_str.value + + def base58_encode(self, v, prefix, _byte): + """ + Encode data using Base58 with checksum and add an according binary prefix in the end. + :param v: Array of bytes + :param prefix: Human-readable prefix (use b'') e.g. b'tz', b'KT', etc + :param local_byte: local variable + + :returns: bytes (use string.decode()) + """ + length_v = sp.to_int(sp.len(v)) + encoding = sp.local("encode", sp.map({})) + byte_from_tbl = sp.local("byte_from_tbl", sp.bytes("0x")) + byte_value = _byte + + sp.for enc in self.base58_encodings: + sp.if (length_v == Utils.Int.of_string(enc["len"])) & (prefix == Utils.Bytes.of_string(enc["prefix"])): + encoding.value = enc + byte_from_tbl.value = self.tb([sp.as_nat(Utils.Int.of_string(enc["elem1"])), + sp.as_nat(Utils.Int.of_string(enc["elem2"])), + sp.as_nat(Utils.Int.of_string(enc["elem3"]))]) + sha256_encoding = sp.sha256(sp.sha256(byte_from_tbl.value + v)) + sha256_encoding = byte_from_tbl.value + v + sp.slice(sha256_encoding, 0, 4).open_some() + acc = sp.local("for_while_loop", Utils.Int.of_bytes(sha256_encoding)) + alphabet = Utils.Bytes.of_string("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") + base = 58 + sp.while acc.value > 0: + (acc.value, idx) = sp.match_pair(sp.ediv(acc.value, base).open_some()) + byte_value.value = sp.slice(alphabet, idx, 1).open_some() + byte_value.value + + return sp.unpack(sp.bytes("0x050100000024") + byte_value.value, sp.TString).open_some() + + @sp.onchain_view() + def add_to_str(self, params): + sp.set_type(params, sp.TAddress) + sp.result(self.unforge_address(sp.pack(params))) + + +@sp.add_test(name="Conversion") +def test(): + c1 = ParseAddress() + scenario = sp.test_scenario() + scenario.h1("Conversion") + scenario += c1 + c1.add_to_str(sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP")) + scenario.verify(c1.add_to_str(sp.address("KT1FfkTSts5DnvyJp2qZbPMeqm2XpMYES7Vr")) == "KT1FfkTSts5DnvyJp2qZbPMeqm2XpMYES7Vr") + scenario.verify(c1.add_to_str(sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP")) == "tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP") + +sp.add_compilation_target("parse_address", ParseAddress()) \ No newline at end of file From 6a00aa11939818e606b7d48441df9896e7e0fbbf Mon Sep 17 00:00:00 2001 From: simusud Date: Thu, 11 May 2023 15:51:16 +0545 Subject: [PATCH 054/211] fix(bts): contract size issue fixed by splitting libraries into separate helper.py and parse_address.py contracts and FA2 import url fixes --- smartpy/bts/contracts/src/FA2_contract.py | 2 +- .../bts/contracts/src/RLP_decode_struct.py | 434 ++++++------------ .../bts/contracts/src/RLP_encode_struct.py | 40 +- smartpy/bts/contracts/src/bts_core.py | 118 ++--- .../bts/contracts/src/bts_owner_manager.py | 2 +- smartpy/bts/contracts/src/bts_periphery.py | 82 ++-- smartpy/bts/contracts/src/helper.py | 48 ++ smartpy/bts/contracts/src/parse_address.py | 356 +++++++------- 8 files changed, 521 insertions(+), 561 deletions(-) create mode 100644 smartpy/bts/contracts/src/helper.py diff --git a/smartpy/bts/contracts/src/FA2_contract.py b/smartpy/bts/contracts/src/FA2_contract.py index c84ba567..dd5399b6 100644 --- a/smartpy/bts/contracts/src/FA2_contract.py +++ b/smartpy/bts/contracts/src/FA2_contract.py @@ -1,6 +1,6 @@ import smartpy as sp -FA2 = sp.io.import_script_from_url("https://smartpy.io/templates/fa2_lib.py") +FA2 = sp.io.import_script_from_url("https://legacy.smartpy.io/templates/fa2_lib.py") t_transfer_batch = sp.TRecord( callback=sp.TContract( diff --git a/smartpy/bts/contracts/src/RLP_decode_struct.py b/smartpy/bts/contracts/src/RLP_decode_struct.py index e24e54df..2282afe6 100644 --- a/smartpy/bts/contracts/src/RLP_decode_struct.py +++ b/smartpy/bts/contracts/src/RLP_decode_struct.py @@ -1,304 +1,166 @@ import smartpy as sp -Utils = sp.io.import_script_from_url("https://raw.githubusercontent.com/Acurast/acurast-hyperdrive/main/contracts/tezos/libs/utils.py") Utils2 = sp.io.import_script_from_url("https://raw.githubusercontent.com/RomarQ/tezos-sc-utils/main/smartpy/utils.py") types = sp.io.import_script_from_url("file:./contracts/src/Types.py") -def decode_bmc_message(rlp): - decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) - decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) - rlp_ = decode_list(rlp) - temp_map_string = sp.compute(sp.map(tkey=sp.TString, tvalue=sp.TString)) - temp_int = sp.local("int_value", 0) - temp_byt = sp.local("byt_value", sp.bytes("0x")) - counter = sp.local("counter", 0) - sp.for i in rlp_.items(): - sp.if counter.value == 0: - temp_map_string["src"] = decode_string(i.value) - sp.if counter.value == 1: - temp_map_string["dst"] = decode_string(i.value) - sp.if counter.value == 2: - temp_map_string["svc"] = decode_string(i.value) - sp.if counter.value == 3: - temp_int.value = Utils2.Int.of_bytes(i.value) - sp.if counter.value == 4: - temp_byt.value = i.value - counter.value = counter.value + 1 - return sp.record(src=temp_map_string.get("src"), - dst=temp_map_string.get("dst"), - svc=temp_map_string.get("svc"), - sn=temp_int.value, - message=temp_byt.value) - - -def decode_response(rlp): - decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) - decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) - temp_int = sp.local("int1", 0) - temp_byt = sp.local("byt1", sp.bytes("0x")) - rlp_ = decode_list(rlp) - counter = sp.local("counter_response", 0) - sp.for i in rlp_.items(): - sp.if counter.value == 0: - temp_int.value = Utils2.Int.of_bytes(i.value) - sp.if counter.value == 1: - temp_byt.value = i.value - counter.value = counter.value + 1 - - return sp.record(code=temp_int.value, message=decode_string(temp_byt.value)) - - -def decode_bmc_service(rlp): - decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) - decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) - rlp_ = decode_list(rlp) - temp_string = sp.local("str_value", 0) - temp_byt = sp.local("byt_value", sp.bytes("0x")) - counter = sp.local("counter", 0) - sp.for i in rlp_.items(): - sp.if counter.value == 0: - temp_string.value = decode_string(i.value) - sp.if counter.value == 1: - temp_byt.value = i.value - counter.value = counter.value + 1 - - return sp.record(serviceType=temp_string.value, - payload=temp_byt.value) - - -def decode_service_message(rlp): - decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) - rlp_ = decode_list(rlp) - temp_int = sp.local("int2", 0) - temp_byt = sp.local("byte1", sp.bytes("0x")) - counter = sp.local("counter", 0) - sp.for i in rlp_.items(): - sp.if counter.value == 0: - temp_int.value = Utils2.Int.of_bytes(i.value) - sp.if counter.value == 1: - temp_byt.value = i.value - counter.value = counter.value + 1 - - _service_type = sp.local("_service_type", sp.variant("", 10)) - sp.if temp_int.value == 0: - _service_type.value = sp.variant("REQUEST_COIN_TRANSFER", temp_int.value) - sp.if temp_int.value == 1: - _service_type.value = sp.variant("REQUEST_COIN_REGISTER", temp_int.value) - sp.if temp_int.value == 2: - _service_type.value = sp.variant("RESPONSE_HANDLE_SERVICE", temp_int.value) - sp.if temp_int.value == 3: - _service_type.value = sp.variant("BLACKLIST_MESSAGE", temp_int.value) - sp.if temp_int.value == 4: - _service_type.value = sp.variant("CHANGE_TOKEN_LIMIT", temp_int.value) - sp.if temp_int.value == 5: - _service_type.value = sp.variant("UNKNOWN_TYPE", temp_int.value) - - return sp.record(serviceType=_service_type.value, - data=temp_byt.value) - - -def decode_gather_fee_message(rlp): - decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) - decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) - rlp_ = decode_list(rlp) - temp_byt = sp.local("byt4", sp.bytes("0x")) - counter = sp.local("counter", 0) - temp_str = sp.local("str_gather", "") - sp.for i in rlp_.items(): - sp.if counter.value == 1: - temp_byt.value = i.value - sp.if counter.value == 0: - temp_str.value = decode_string(i.value) - counter.value = counter.value + 1 - starts_with = sp.slice(temp_byt.value, 0, 2).open_some() - sub_list = sp.local("sub_list", temp_byt.value) - sp.if starts_with == sp.bytes("0xb846"): - sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() - new_sub_list = decode_list(sub_list.value) - _svcs = sp.local("_svcs", sp.TMap(sp.TNat, sp.TString)) - counter.value = 0 - sp.for x in new_sub_list.items(): - _svcs.value[counter.value] = decode_string(x.value) - counter.value = counter.value + 1 - return sp.record(fa=temp_str, - svcs=_svcs) - -def decode_event_log(rlp): - decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) - event_mpt_node = sp.local("eventMptNode", sp.TMap(sp.TNat, sp.TString)) - rlp_ = decode_list(rlp) - counter = sp.local("counter", 0) - sp.for i in rlp_.items(): - event_mpt_node.value[counter.value] = i.value - counter.value = counter.value + 1 - return event_mpt_node - - -def decode_receipt_proof(rlp): - decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) - rlp_ = decode_list(rlp) - temp_byt = sp.local("byt_receipt", sp.bytes("0x")) - temp_byt2 = sp.local("byt_receipt2", sp.bytes("0x")) - rv_int = sp.local("rv_int", 0) - counter = sp.local("counter", 0) - sp.for i in rlp_.items(): - sp.if counter.value == 1: - temp_byt.value = i.value - sp.if counter.value == 0: - rv_int.value = Utils2.Int.of_bytes(i.value) - sp.if counter.value == 2: - temp_byt2 = i.value - counter.value = counter.value + 1 +class DecodeLibrary: + def decode_response(self, rlp): + temp_int = sp.local("int1", 0) + temp_byt = sp.local("byt1", sp.bytes("0x")) + rlp_ = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + counter = sp.local("counter_response", 0) + sp.for i in rlp_.items(): + sp.if counter.value == 0: + temp_int.value = Utils2.Int.of_bytes(i.value) + sp.if counter.value == 1: + temp_byt.value = i.value + counter.value = counter.value + 1 - starts_with = sp.slice(temp_byt.value, 0, 2).open_some() - sub_list = sp.local("sub_list", temp_byt.value) - sp.if starts_with == sp.bytes("0xb846"): - sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() - new_sub_list = decode_list(sub_list.value) - counter.value = 0 - txReceipts = sp.local("txReceipts", sp.TMap(sp.TNat, sp.TBytes)) - sp.for x in new_sub_list.items(): - txReceipts.value[counter.value] = x.value - counter.value = counter.value + 1 + return sp.record(code=temp_int.value, message=sp.view("decode_string", self.data.helper, temp_byt.value, t=sp.TString).open_some()) - starts_with_second_elem = sp.slice(temp_byt2.value, 0, 2).open_some() - sub_list_second_elem = sp.local("sub_list_second_elem", temp_byt.value) - sp.if starts_with_second_elem == sp.bytes("0xb846"): - sub_list_second_elem.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() - new_sub_list = decode_list(sub_list_second_elem.value) - ep = sp.local("ep", sp.TMap(sp.TNat, sp.TBytes)) - new_temp_byt = sp.local("new_temp_byt", sp.bytes("0x")) - sp.for x in new_sub_list.items(): - new_temp_byt.value = x.value - sp.if sp.slice(new_temp_byt.value, 0, 2).open_some() == sp.bytes("0xb846"): - new_temp_byt.value = sp.slice(new_temp_byt.value, 2, sp.as_nat(sp.len(new_temp_byt.value) - 2)).open_some() - temp_map = sp.local("tempMap", sp.TMap(sp.TNat, sp.TString)) - temp_int = sp.local("tempInt", 0) - counter.value = 0 - sp.for i in decode_list(new_temp_byt.value): + def decode_service_message(self, rlp): + rlp_ = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + temp_int = sp.local("int2", 0) + temp_byt = sp.local("byte1", sp.bytes("0x")) + counter = sp.local("counter", 0) + sp.for i in rlp_.items(): sp.if counter.value == 0: - temp_int = Utils2.Int.of_bytes(i.value) + temp_int.value = Utils2.Int.of_bytes(i.value) sp.if counter.value == 1: - temp_map = decode_event_log(i.value) + temp_byt.value = i.value counter.value = counter.value + 1 - ep.value[counter.value] = sp.record(index=temp_int, eventMptNode=temp_map) - return sp.record(index=rv_int.value, txReceipts=txReceipts.value, eventMptNode=ep.value) -def decode_transfer_coin_msg(rlp): - decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) - rlp_ = decode_list(rlp) - decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) - - temp_byt = sp.local("byt_transfer", sp.bytes("0x")) - rv1_byt = sp.local("rv1_byt", sp.bytes("0x")) - rv2_byt = sp.local("rv2_byt", sp.bytes("0x")) - counter = sp.local("counter_coin", sp.nat(0)) - sp.for i in rlp_.items(): - sp.if counter.value == 2: - temp_byt.value = i.value - sp.if counter.value == 0: - rv1_byt.value = i.value - sp.if counter.value == 1: - rv2_byt.value = i.value - counter.value = counter.value + 1 - starts_with = sp.slice(temp_byt.value, 0, 2).open_some() - sub_list = sp.local("sub_list", temp_byt.value) - sp.if starts_with == sp.bytes("0xb846"): - sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() - new_sub_list = decode_list(sub_list.value) - counter.value = 0 - new_temp_byt = sp.local("new_temp_byt", sp.bytes("0x")) - rv_assets = sp.local("assets", {}, sp.TMap(sp.TNat, types.Types.Asset)) - sp.for x in new_sub_list.items(): - new_temp_byt.value = x.value - sp.if sp.slice(new_temp_byt.value, 0, 2).open_some() == sp.bytes("0xb846"): - new_temp_byt.value = sp.slice(new_temp_byt.value, 2, sp.as_nat(sp.len(new_temp_byt.value) - 2)).open_some() - temp_byt = sp.local("tempByt2", sp.bytes("0x")) - temp_int = sp.local("tempInt", sp.nat(0)) - counter.value = 0 - sp.for i in decode_list(new_temp_byt.value).items(): + _service_type = sp.local("_service_type", sp.variant("", 10)) + sp.if temp_int.value == 0: + _service_type.value = sp.variant("REQUEST_COIN_TRANSFER", temp_int.value) + sp.if temp_int.value == 1: + _service_type.value = sp.variant("REQUEST_COIN_REGISTER", temp_int.value) + sp.if temp_int.value == 2: + _service_type.value = sp.variant("RESPONSE_HANDLE_SERVICE", temp_int.value) + sp.if temp_int.value == 3: + _service_type.value = sp.variant("BLACKLIST_MESSAGE", temp_int.value) + sp.if temp_int.value == 4: + _service_type.value = sp.variant("CHANGE_TOKEN_LIMIT", temp_int.value) + sp.if temp_int.value == 5: + _service_type.value = sp.variant("UNKNOWN_TYPE", temp_int.value) + + return sp.record(serviceType=_service_type.value, + data=temp_byt.value) + + def decode_transfer_coin_msg(self, rlp): + rlp_ = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + + temp_byt = sp.local("byt_transfer", sp.bytes("0x")) + rv1_byt = sp.local("rv1_byt", sp.bytes("0x")) + rv2_byt = sp.local("rv2_byt", sp.bytes("0x")) + counter = sp.local("counter_coin", sp.nat(0)) + sp.for i in rlp_.items(): + sp.if counter.value == 2: + temp_byt.value = i.value + sp.if counter.value == 0: + rv1_byt.value = i.value sp.if counter.value == 1: - temp_int.value = Utils2.Int.of_bytes(i.value) + rv2_byt.value = i.value + counter.value = counter.value + 1 + starts_with = sp.slice(temp_byt.value, 0, 2).open_some() + sub_list = sp.local("sub_list", temp_byt.value) + sp.if starts_with == sp.bytes("0xb846"): + sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() + new_sub_list = sp.view("decode_list", self.data.helper, sub_list.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + counter.value = 0 + new_temp_byt = sp.local("new_temp_byt", sp.bytes("0x")) + rv_assets = sp.local("assets", {}, sp.TMap(sp.TNat, types.Types.Asset)) + sp.for x in new_sub_list.items(): + new_temp_byt.value = x.value + sp.if sp.slice(new_temp_byt.value, 0, 2).open_some() == sp.bytes("0xb846"): + new_temp_byt.value = sp.slice(new_temp_byt.value, 2, sp.as_nat(sp.len(new_temp_byt.value) - 2)).open_some() + temp_byt = sp.local("tempByt2", sp.bytes("0x")) + temp_int = sp.local("tempInt", sp.nat(0)) + counter.value = 0 + view_value = sp.view("decode_list", self.data.helper, new_temp_byt.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + sp.for i in view_value.items(): + sp.if counter.value == 1: + temp_int.value = Utils2.Int.of_bytes(i.value) + sp.if counter.value == 0: + temp_byt.value = i.value + rv_assets.value[counter.value] = sp.record(coin_name=sp.view("decode_string", self.data.helper, temp_byt.value, t=sp.TString).open_some() + , value=temp_int.value) + counter.value = counter.value + 1 + rv1 = sp.view("decode_string", self.data.helper, rv1_byt.value, t=sp.TString).open_some() + rv2 = sp.view("decode_string", self.data.helper, rv2_byt.value, t=sp.TString).open_some() + return sp.record(from_= rv1, to = rv2 , assets = rv_assets.value) + + def decode_blacklist_msg(self, rlp): + rlp_ = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + + temp_byt = sp.local("byt_transfer", sp.bytes("0x")) + rv1_byt = sp.local("rv1_byt", sp.bytes("0x")) + rv2_byt = sp.local("rv2_byt", sp.bytes("0x")) + counter = sp.local("counter_blacklist", 0) + sp.for i in rlp_.items(): + sp.if counter.value == 2: + rv2_byt.value = i.value sp.if counter.value == 0: + rv1_byt.value = i.value + sp.if counter.value == 1: temp_byt.value = i.value - rv_assets.value[counter.value] = sp.record(coin_name=decode_string(temp_byt.value), value=temp_int.value) counter.value = counter.value + 1 - rv1 = decode_string(rv1_byt.value) - rv2 = decode_string(rv2_byt.value) - return sp.record(from_= rv1, to = rv2 , assets = rv_assets.value) - -def decode_blacklist_msg(rlp): - decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) - rlp_ = decode_list(rlp) - decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) - - temp_byt = sp.local("byt_transfer", sp.bytes("0x")) - rv1_byt = sp.local("rv1_byt", sp.bytes("0x")) - rv2_byt = sp.local("rv2_byt", sp.bytes("0x")) - counter = sp.local("counter_blacklist", 0) - sp.for i in rlp_.items(): - sp.if counter.value == 2: - rv2_byt.value = i.value - sp.if counter.value == 0: - rv1_byt.value = i.value - sp.if counter.value == 1: - temp_byt.value = i.value - counter.value = counter.value + 1 - starts_with = sp.slice(temp_byt.value, 0, 2).open_some() - sub_list = sp.local("sub_list", temp_byt.value) - sp.if starts_with == sp.bytes("0xb846"): - sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() - new_sub_list = decode_list(sub_list.value) - counter.value = 0 - new_temp_byt = sp.local("new_temp_byt", sp.bytes("0x")) - rv_blacklist_address = sp.local("blacklist_data", {}, sp.TMap(sp.TNat, sp.TString)) - sp.for x in new_sub_list.items(): - new_temp_byt.value = x.value - sp.if sp.slice(new_temp_byt.value, 0, 2).open_some() == sp.bytes("0xb846"): - new_temp_byt.value = sp.slice(new_temp_byt.value, 2, sp.as_nat(sp.len(new_temp_byt.value) - 2)).open_some() + starts_with = sp.slice(temp_byt.value, 0, 2).open_some() + sub_list = sp.local("sub_list", temp_byt.value) + sp.if starts_with == sp.bytes("0xb846"): + sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() + new_sub_list = sp.view("decode_list", self.data.helper, sub_list.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() counter.value = 0 - sp.for j in decode_list(new_temp_byt.value).items(): - rv_blacklist_address.value[counter.value] = decode_string(j.value) + new_temp_byt = sp.local("new_temp_byt", sp.bytes("0x")) + rv_blacklist_address = sp.local("blacklist_data", {}, sp.TMap(sp.TNat, sp.TString)) + sp.for x in new_sub_list.items(): + new_temp_byt.value = x.value + sp.if sp.slice(new_temp_byt.value, 0, 2).open_some() == sp.bytes("0xb846"): + new_temp_byt.value = sp.slice(new_temp_byt.value, 2, sp.as_nat(sp.len(new_temp_byt.value) - 2)).open_some() + counter.value = 0 + _decode_list = sp.view("decode_list", self.data.helper, new_temp_byt.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + sp.for j in _decode_list.items(): + rv_blacklist_address.value[counter.value] = sp.view("decode_string", self.data.helper, j.value, t=sp.TString).open_some() + counter.value = counter.value + 1 + rv1 = Utils2.Int.of_bytes(rv1_byt.value) + rv2 = sp.view("decode_string", self.data.helper, rv2_byt.value, t=sp.TString).open_some() + _service_type = sp.local("_service_type_blacklist", sp.variant("", 10)) + with sp.if_(rv1 == 0): + _service_type.value = sp.variant("ADD_TO_BLACKLIST", rv1) + with sp.else_(): + _service_type.value = sp.variant("REMOVE_FROM_BLACKLIST", rv1) + return sp.record(serviceType = _service_type.value , addrs = rv_blacklist_address.value , + net = sp.view("decode_string", self.data.helper, rv2, t=sp.TString).open_some()) + + def decode_token_limit_msg(self, rlp): + rlp_ = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + + temp_byt = sp.local("byt_transfer", sp.bytes("0x")) + temp_byt1 = sp.local("byt_transfer_temp1", sp.bytes("0x")) + rv1_byt = sp.local("rv1_byt", sp.bytes("0x")) + counter = sp.local("counter_token_limit", 0) + sp.for i in rlp_.items(): + sp.if counter.value == 0: + temp_byt.value = i.value + sp.if counter.value == 1: + temp_byt1.value = i.value + sp.if counter.value == 2: + rv1_byt.value = i.value counter.value = counter.value + 1 - rv1 = Utils2.Int.of_bytes(rv1_byt.value) - rv2 = decode_string(rv2_byt.value) - _service_type = sp.local("_service_type_blacklist", sp.variant("", 10)) - with sp.if_(rv1 == 0): - _service_type.value = sp.variant("ADD_TO_BLACKLIST", rv1) - with sp.else_(): - _service_type.value = sp.variant("REMOVE_FROM_BLACKLIST", rv1) - return sp.record(serviceType = _service_type.value , addrs = rv_blacklist_address.value , net = decode_string(rv2)) - -def decode_token_limit_msg(rlp): - decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) - rlp_ = decode_list(rlp) - decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) - - temp_byt = sp.local("byt_transfer", sp.bytes("0x")) - temp_byt1 = sp.local("byt_transfer_temp1", sp.bytes("0x")) - rv1_byt = sp.local("rv1_byt", sp.bytes("0x")) - counter = sp.local("counter_token_limit", 0) - sp.for i in rlp_.items(): - sp.if counter.value == 0: - temp_byt.value = i.value - sp.if counter.value == 1: - temp_byt1.value = i.value - sp.if counter.value == 2: - rv1_byt.value = i.value - counter.value = counter.value + 1 - starts_with = sp.slice(temp_byt.value, 0, 2).open_some() - sub_list = sp.local("sub_list", temp_byt.value) - sp.if starts_with == sp.bytes("0xb846"): - sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() - new_sub_list = decode_list(sub_list.value) - counter.value = 0 - rv_names = sp.local("names", {}, sp.TMap(sp.TNat, sp.TString)) - rv_limit = sp.local("limit", {}, sp.TMap(sp.TNat, sp.TNat)) - sp.for x in new_sub_list.items(): - rv_names.value[counter.value] = decode_string(x.value) - - new_sub_list1 = decode_list(sub_list.value) - sp.for y in new_sub_list1.items(): - rv_limit.value[counter.value] = Utils2.Int.of_bytes(y.value) - return sp.record(coin_name = rv_names.value, token_limit = rv_limit.value , net = decode_string(rv1_byt.value)) \ No newline at end of file + starts_with = sp.slice(temp_byt.value, 0, 2).open_some() + sub_list = sp.local("sub_list", temp_byt.value) + sp.if starts_with == sp.bytes("0xb846"): + sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() + new_sub_list = sp.view("decode_list", self.data.helper, sub_list.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + counter.value = 0 + rv_names = sp.local("names", {}, sp.TMap(sp.TNat, sp.TString)) + rv_limit = sp.local("limit", {}, sp.TMap(sp.TNat, sp.TNat)) + sp.for x in new_sub_list.items(): + rv_names.value[counter.value] = sp.view("decode_string", self.data.helper, x.value, t=sp.TString).open_some() + + new_sub_list1 = sp.view("decode_list", self.data.helper, sub_list.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + sp.for y in new_sub_list1.items(): + rv_limit.value[counter.value] = Utils2.Int.of_bytes(y.value) + return sp.record(coin_name = rv_names.value, token_limit = rv_limit.value , + net = sp.view("decode_string", self.data.helper, rv1_byt.value, t=sp.TString).open_some()) \ No newline at end of file diff --git a/smartpy/bts/contracts/src/RLP_encode_struct.py b/smartpy/bts/contracts/src/RLP_encode_struct.py index 1fa416f4..0f5517d5 100644 --- a/smartpy/bts/contracts/src/RLP_encode_struct.py +++ b/smartpy/bts/contracts/src/RLP_encode_struct.py @@ -1,33 +1,31 @@ import smartpy as sp types = sp.io.import_script_from_url("file:./contracts/src/Types.py") -Utils = sp.io.import_script_from_url( - "https://raw.githubusercontent.com/Acurast/acurast-hyperdrive/main/contracts/tezos/libs/utils.py") -def encode_service_message(params): - sp.set_type(params, types.Types.ServiceMessage) +class EncodeLibrary: + def encode_service_message(self, params): + sp.set_type(params, types.Types.ServiceMessage) - encode_string_packed = sp.build_lambda(Utils.Bytes.of_string) - rlp = params.data + encode_string_packed(params.serviceType) - with_length_prefix = sp.build_lambda(Utils.RLP.Encoder.with_length_prefix) - rlp_bytes_with_prefix = with_length_prefix(rlp) - return rlp_bytes_with_prefix + encode_service_type = sp.view("of_string", self.data.helper, params.serviceType, t=sp.TBytes).open_some() + rlp = params.data + encode_service_type + rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + return rlp_bytes_with_prefix -def encode_transfer_coin_msg(data): - sp.set_type(data, types.Types.TransferCoin) + def encode_transfer_coin_msg(self, data): + sp.set_type(data, types.Types.TransferCoin) - rlp = sp.local("rlp", sp.bytes("0x80")) - temp = sp.local("temp", sp.bytes("0x80")) - encode_string_packed = sp.build_lambda(Utils.Bytes.of_string) - encode_nat_packed = sp.build_lambda(Utils.Bytes.of_nat) - with_length_prefix = sp.build_lambda(Utils.RLP.Encoder.with_length_prefix) + rlp = sp.local("rlp", sp.bytes("0x80")) + temp = sp.local("temp", sp.bytes("0x80")) - sp.for i in sp.range(0, sp.len(data.assets)): - temp.value = encode_string_packed(data.assets[i].coin_name) + encode_nat_packed(data.assets[i].value) - rlp.value = rlp.value + with_length_prefix(temp.value) + sp.for i in sp.range(0, sp.len(data.assets)): + temp.value = sp.view("of_string", self.data.helper, data.assets.get(i, default_value=sp.record(coin_name="",value=sp.nat(0))).coin_name, t=sp.TBytes).open_some()\ + + sp.view("of_nat", self.data.helper, data.assets.get(i, default_value=sp.record(coin_name="",value=sp.nat(0))).value, t=sp.TBytes).open_some() + rlp.value = rlp.value + sp.view("with_length_prefix", self.data.helper, temp.value, t=sp.TBytes).open_some() - rlp.value = encode_string_packed(data.from_addr) + encode_string_packed(data.to) + with_length_prefix(rlp.value) + rlp.value = sp.view("of_string", self.data.helper, data.from_addr, t=sp.TBytes).open_some() + \ + sp.view("of_string", self.data.helper, data.to, t=sp.TBytes).open_some() + \ + sp.view("with_length_prefix", self.data.helper, rlp.value, t=sp.TBytes).open_some() - return with_length_prefix(rlp.value) + return sp.view("with_length_prefix", self.data.helper, rlp.value, t=sp.TBytes).open_some() diff --git a/smartpy/bts/contracts/src/bts_core.py b/smartpy/bts/contracts/src/bts_core.py index 644908a2..d93a7407 100644 --- a/smartpy/bts/contracts/src/bts_core.py +++ b/smartpy/bts/contracts/src/bts_core.py @@ -1,6 +1,5 @@ import smartpy as sp -FA2 = sp.io.import_script_from_url("https://smartpy.io/templates/fa2_lib.py") types = sp.io.import_script_from_url("file:./contracts/src/Types.py") FA2_contract = sp.io.import_script_from_url("file:./contracts/src/FA2_contract.py") @@ -182,7 +181,7 @@ def coin_id(self, coin_name): """ sp.set_type(coin_name, sp.TString) - sp.result(self.data.coins[coin_name]) + sp.result(self.data.coins.get(coin_name)) @sp.onchain_view() def is_valid_coin(self, coin_name): @@ -237,7 +236,7 @@ def balance_of(self, params): refundable_balance=refundable_balance.value, user_balance=sp.nat(0))) with sp.else_(): - fa2_address = self.data.coins[params.coin_name] + fa2_address = self.data.coins.get(params.coin_name) user_balance= sp.view("balance_of", fa2_address, sp.record(owner=params.owner, token_id=sp.nat(0)), t=sp.TNat).open_some("Invalid view") allowance = sp.view("get_allowance", fa2_address, sp.record(spender=sp.self_address, owner=params.owner), t=sp.TNat).open_some("Invalid view") @@ -266,8 +265,8 @@ def balance_of_batch(self, params): refundable_balances =sp.local("refundable_balances", {}, t=sp.TMap(sp.TNat, sp.TNat)) user_balances =sp.local("user_balances", {}, t=sp.TMap(sp.TNat, sp.TNat)) + i = sp.local("i", sp.nat(0)) sp.for item in params.coin_names: - i = sp.local("i", sp.nat(0)) balance= sp.view("balance_of", sp.self_address, sp.record(owner=params.owner, coin_name=item)).open_some() usable_balances.value[i.value] = balance.usable_balance @@ -286,9 +285,9 @@ def get_accumulated_fees(self): """ accumulated_fees = sp.local("accumulated_fees", sp.map(tkey=sp.TNat, tvalue=types.Types.Asset)) + i = sp.local("i", sp.nat(0)) sp.for item in self.data.coins_name: - i = sp.local("i", sp.nat(0)) - accumulated_fees.value[i.value] = sp.record(coin_name=item, value=self.data.aggregation_fee[item]) + accumulated_fees.value[i.value] = sp.record(coin_name=item, value=self.data.aggregation_fee.get(item)) i.value += sp.nat(1) sp.result(accumulated_fees.value) @@ -367,9 +366,9 @@ def _send_service_message(self, _from, to, coin_name, value, charge_amt): sp.verify(value > charge_amt, message = "ValueGreaterThan0") self._lock_balance(_from, coin_name, value) - coins = sp.local("coins", {0 : coin_name}, t=sp.TMap(sp.TNat, sp.TString)) - amounts = sp.local("amounts", {0 : sp.as_nat(value - charge_amt)}, t=sp.TMap(sp.TNat, sp.TNat)) - fees = sp.local("fees", {0: charge_amt}, t=sp.TMap(sp.TNat, sp.TNat)) + coins = sp.local("coins", {sp.nat(0) : coin_name}, t=sp.TMap(sp.TNat, sp.TString)) + amounts = sp.local("amounts", {sp.nat(0) : sp.as_nat(value - charge_amt)}, t=sp.TMap(sp.TNat, sp.TNat)) + fees = sp.local("fees", {sp.nat(0): charge_amt}, t=sp.TMap(sp.TNat, sp.TNat)) # call send_service_message on bts_periphery send_service_message_args_type = sp.TRecord(_from = sp.TAddress, to = sp.TString, coin_names = sp.TMap(sp.TNat, sp.TString), values = sp.TMap(sp.TNat, sp.TNat), fees = sp.TMap(sp.TNat, sp.TNat)) @@ -411,7 +410,7 @@ def transfer_batch(self, coin_names, values, to): # coin = sp.TRecord(addr=sp.TAddress, fee_numerator=sp.TNat, fixed_fee=sp.TNat, coin_type=sp.TNat) coin_name = sp.local("coin_name", "", t= sp.TString) - value = sp.local("value", 0, t= sp.TNat) + value = sp.local("value", sp.nat(0), t= sp.TNat) sp.for i in sp.range(sp.nat(0), sp.len(coin_names)): sp.verify(coin_names[i] != self.data.native_coin_name, message="InvalidCoin") @@ -588,51 +587,52 @@ def handle_response_service(self, requester, coin_name, value, fee, rsp_code): sp.set_type(rsp_code, sp.TNat) self.only_bts_periphery() + return_flag = sp.local("return_flag", False, t=sp.TBool) sp.if requester == sp.self_address: sp.if rsp_code == self.RC_ERR: self.data.aggregation_fee[coin_name] = self.data.aggregation_fee.get(coin_name, default_value=sp.nat(0)) + fee - # TODO:code is returning in all case from here (need to see how to implement return) - # return - - amount = sp.local("amount", value + fee, t=sp.TNat) - sp.if self.data.balances.contains(sp.record(address=requester, coin_name=coin_name)): - self.data.balances[sp.record(address=requester, coin_name=coin_name)].locked_balance = \ - sp.as_nat(self.data.balances.get(sp.record(address=requester, coin_name=coin_name), - default_value=sp.record(locked_balance=sp.nat(0), refundable_balance=sp.nat(0))).locked_balance - amount.value) - - sp.if rsp_code == self.RC_ERR: - with sp.if_(coin_name == self.data.native_coin_name): - with sp.if_(sp.utils.mutez_to_nat(sp.balance) >= value): - self.payment_transfer(requester, value) + return_flag.value = True + + sp.if return_flag.value == False: + amount = sp.local("amount", value + fee, t=sp.TNat) + sp.if self.data.balances.contains(sp.record(address=requester, coin_name=coin_name)): + self.data.balances[sp.record(address=requester, coin_name=coin_name)].locked_balance = \ + sp.as_nat(self.data.balances.get(sp.record(address=requester, coin_name=coin_name), + default_value=sp.record(locked_balance=sp.nat(0), refundable_balance=sp.nat(0))).locked_balance - amount.value) + + sp.if rsp_code == self.RC_ERR: + with sp.if_(coin_name == self.data.native_coin_name): + with sp.if_(sp.utils.mutez_to_nat(sp.balance) >= value): + self.payment_transfer(requester, value) + with sp.else_(): + self.data.balances[sp.record(address=requester, coin_name=coin_name)].refundable_balance = self.data.balances.get( + sp.record(address=requester, coin_name=coin_name), + default_value=sp.record(locked_balance=sp.nat(0), refundable_balance=sp.nat(0))).refundable_balance + value with sp.else_(): - self.data.balances[sp.record(address=requester, coin_name=coin_name)].refundable_balance = self.data.balances.get( - sp.record(address=requester, coin_name=coin_name), - default_value=sp.record(locked_balance=sp.nat(0), refundable_balance=sp.nat(0))).refundable_balance + value - with sp.else_(): - # call transfer in FA2 - transfer_args_type = sp.TList(sp.TRecord( - callback=sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), requester=sp.TAddress, coin_name=sp.TString, value=sp.TNat)), - from_=sp.TAddress, - coin_name=sp.TString, - txs=sp.TList(sp.TRecord(to_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout(("to_", ("token_id", "amount")))) - ).layout((("from_", "coin_name"), ("callback", "txs")))) - transfer_entry_point = sp.contract(transfer_args_type, self.data.coins[coin_name], - "transfer").open_some() - transfer_args = [ - sp.record(callback=sp.self_entry_point("callback"), from_=sp.self_address, coin_name=coin_name, txs=[sp.record(to_=requester, token_id=sp.nat(0), amount=value)])] - sp.transfer(transfer_args, sp.tez(0), transfer_entry_point) - - sp.if rsp_code == self.RC_OK: - fa2_address = self.data.coins[coin_name] - sp.if (coin_name != self.data.native_coin_name) & (self.data.coin_details[coin_name].coin_type == self.NATIVE_WRAPPED_COIN_TYPE): - # call burn in FA2 - burn_args_type = sp.TList(sp.TRecord(from_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat)) - burn_entry_point = sp.contract(burn_args_type, fa2_address, "burn").open_some() - burn_args = [sp.record(from_=sp.self_address, token_id=sp.nat(0), amount=value)] - sp.transfer(burn_args, sp.tez(0), burn_entry_point) - - self.data.aggregation_fee[coin_name] = self.data.aggregation_fee.get(coin_name, default_value=sp.nat(0)) + fee + # call transfer in FA2 + transfer_args_type = sp.TList(sp.TRecord( + callback=sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), requester=sp.TAddress, coin_name=sp.TString, value=sp.TNat)), + from_=sp.TAddress, + coin_name=sp.TString, + txs=sp.TList(sp.TRecord(to_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout(("to_", ("token_id", "amount")))) + ).layout((("from_", "coin_name"), ("callback", "txs")))) + transfer_entry_point = sp.contract(transfer_args_type, self.data.coins[coin_name], + "transfer").open_some() + transfer_args = [ + sp.record(callback=sp.self_entry_point("callback"), from_=sp.self_address, coin_name=coin_name, txs=[sp.record(to_=requester, token_id=sp.nat(0), amount=value)])] + sp.transfer(transfer_args, sp.tez(0), transfer_entry_point) + + sp.if rsp_code == self.RC_OK: + fa2_address = self.data.coins[coin_name] + sp.if (coin_name != self.data.native_coin_name) & (self.data.coin_details[coin_name].coin_type == self.NATIVE_WRAPPED_COIN_TYPE): + # call burn in FA2 + burn_args_type = sp.TList(sp.TRecord(from_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat)) + burn_entry_point = sp.contract(burn_args_type, fa2_address, "burn").open_some() + burn_args = [sp.record(from_=sp.self_address, token_id=sp.nat(0), amount=value)] + sp.transfer(burn_args, sp.tez(0), burn_entry_point) + + self.data.aggregation_fee[coin_name] = self.data.aggregation_fee.get(coin_name, default_value=sp.nat(0)) + fee @sp.entry_point def transfer_fees(self, fa): @@ -644,13 +644,13 @@ def transfer_fees(self, fa): sp.set_type(fa, sp.TString) self.only_bts_periphery() + l = sp.local("l", sp.nat(0)) sp.for item in self.data.coins_name: - i = sp.local("i", sp.nat(0)) sp.if self.data.aggregation_fee[item] != sp.nat(0): - self.data.charged_coins[i.value] = item - self.data.charged_amounts[i.value] = self.data.aggregation_fee[item] + self.data.charged_coins[l.value] = item + self.data.charged_amounts[l.value] = self.data.aggregation_fee.get(item) del self.data.aggregation_fee[item] - i.value += sp.nat(1) + l.value += sp.nat(1) # call send_service_message on bts_periphery send_service_message_args_type = sp.TRecord(_from=sp.TAddress, to=sp.TString, @@ -672,7 +672,11 @@ def transfer_fees(self, fa): del self.data.charged_amounts[i] def _lock_balance(self, to, coin_name, value): - self.data.balances[sp.record(address=to, coin_name=coin_name)].locked_balance = self.data.balances[sp.record(address=to, coin_name=coin_name)].locked_balance + value + new_balance = self.data.balances.get(sp.record(address=to, coin_name=coin_name), + default_value=sp.record(locked_balance=sp.nat(0), + refundable_balance=sp.nat(0))) + self.data.balances[sp.record(address=to, coin_name=coin_name)] = sp.record( + locked_balance=new_balance.locked_balance + value, refundable_balance=new_balance.refundable_balance) @sp.entry_point def update_coin_db(self): @@ -689,7 +693,7 @@ def update_coin_db(self): def set_bts_owner_manager(self, owner_manager): sp.set_type(owner_manager, sp.TAddress) - sp.verify(self.data.owners[sp.sender] == True , message= "Unauthorized") + sp.verify(self.data.owners.get(sp.sender) == True , message= "Unauthorized") # sp.verify(owner_manager != sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), message= "InvalidAddress") self.data.bts_owner_manager = owner_manager @@ -728,7 +732,7 @@ def test(): sp.add_compilation_target("bts_core", BTSCore( - owner_manager=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), + owner_manager=sp.address("KT1DMB7Je79rfkYPn2bCVH2ujCxb3MDUZgNU"), _native_coin_name="NativeCoin", _fee_numerator=sp.nat(1000), _fixed_fee=sp.nat(10) diff --git a/smartpy/bts/contracts/src/bts_owner_manager.py b/smartpy/bts/contracts/src/bts_owner_manager.py index 2cf9d32d..039df1d2 100644 --- a/smartpy/bts/contracts/src/bts_owner_manager.py +++ b/smartpy/bts/contracts/src/bts_owner_manager.py @@ -65,6 +65,6 @@ def test(): scenario.verify(c1.is_owner(alice.address) == True) -sp.add_compilation_target("bts_owner_manager", BTSOwnerManager(owner=sp.address("tz1UVtzTTE1GatMoXhs46hbdp1143a195kXh"))) +sp.add_compilation_target("bts_owner_manager", BTSOwnerManager(owner=sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"))) diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index 78417e96..077a2439 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -4,9 +4,9 @@ strings = sp.io.import_script_from_url("file:./contracts/src/String.py") rlp_encode = sp.io.import_script_from_url("file:./contracts/src/RLP_encode_struct.py") rlp_decode = sp.io.import_script_from_url("file:./contracts/src/RLP_decode_struct.py") -parse_addr = sp.io.import_script_from_url("file:./contracts/src/parse_address.py") -class BTPPreiphery(sp.Contract): + +class BTPPreiphery(sp.Contract, rlp_decode.DecodeLibrary, rlp_encode.EncodeLibrary): service_name = sp.string("bts") RC_OK = sp.nat(0) @@ -14,7 +14,7 @@ class BTPPreiphery(sp.Contract): MAX_BATCH_SIZE = sp.nat(15) - def __init__(self, bmc_address, bts_core_address): + def __init__(self, bmc_address, bts_core_address, helper_contract, parse_address): self.update_initial_storage( bmc=bmc_address, bts_core=bts_core_address, @@ -22,7 +22,9 @@ def __init__(self, bmc_address, bts_core_address): token_limit=sp.map(tkey=sp.TString, tvalue=sp.TNat), requests=sp.big_map(tkey=sp.TNat, tvalue=types.Types.PendingTransferCoin), serial_no = sp.nat(0), - number_of_pending_requests = sp.nat(0) + number_of_pending_requests = sp.nat(0), + helper=helper_contract, + parse_contract=parse_address ) def only_bmc(self): @@ -51,7 +53,7 @@ def add_to_blacklist(self, params): sp.verify(sp.len(params) <= self.MAX_BATCH_SIZE, "BatchMaxSizeExceed") sp.for i in sp.range(sp.nat(0), sp.len(params)): - parsed_addr = parse_addr.str_to_addr(params.get(i)) + parsed_addr = sp.view("str_to_addr", self.data.parse_contract, params.get(i), t=sp.TAddress).open_some() with sp.if_(parsed_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): self.data.blacklist[parsed_addr] = True with sp.else_(): @@ -70,7 +72,7 @@ def remove_from_blacklist(self, params): sp.verify(sp.len(params) <= self.MAX_BATCH_SIZE, "BatchMaxSizeExceed") sp.for i in sp.range(sp.nat(0), sp.len(params)): - parsed_addr = parse_addr.str_to_addr(params.get(i)) + parsed_addr = sp.view("str_to_addr", self.data.parse_contract, params.get(i), t=sp.TAddress).open_some() with sp.if_(parsed_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): sp.verify(self.data.blacklist.contains(parsed_addr), "UserNotFound") sp.verify(self.data.blacklist.get(parsed_addr) == True, "UserNotBlacklisted") @@ -93,7 +95,7 @@ def set_token_limit(self, coin_names, token_limit): sp.verify(sp.len(coin_names) <= self.MAX_BATCH_SIZE, "BatchMaxSizeExceed") sp.for i in sp.range(0, sp.len(coin_names)): - self.data.token_limit[coin_names[i]] = token_limit[i] + self.data.token_limit[coin_names[i]] = token_limit.get(i) @sp.entry_point @@ -133,14 +135,14 @@ def send_service_message(self, _from, to, coin_names, values, fees): self.data.serial_no += 1 - start_from = parse_addr.add_to_str(_from) + start_from = sp.view("add_to_str", self.data.parse_contract, _from, t=sp.TString).open_some() send_message_args_type = sp.TRecord(to=sp.TString, svc=sp.TString, sn=sp.TNat, msg=sp.TBytes) send_message_entry_point = sp.contract(send_message_args_type, self.data.bmc, "send_message").open_some() send_message_args = sp.record( to=to_network, svc=self.service_name, sn=self.data.serial_no, - msg=rlp_encode.encode_service_message(sp.compute(sp.record(serviceType=(sp.variant("REQUEST_COIN_TRANSFER", 0)), - data=rlp_encode.encode_transfer_coin_msg(sp.compute(sp.record(from_addr=start_from, to=to_address, assets=assets))) + msg=self.encode_service_message(sp.compute(sp.record(serviceType=(sp.variant("REQUEST_COIN_TRANSFER", 0)), + data=self.encode_transfer_coin_msg(sp.compute(sp.record(from_addr=start_from, to=to_address, assets=assets))) ) ) ) @@ -175,13 +177,13 @@ def handle_btp_message(self, _from, svc, sn, msg): sp.verify(svc == self.service_name, "InvalidSvc") err_msg = sp.local("error", "") - sm = rlp_decode.decode_service_message(msg) + sm = self.decode_service_message(msg) # TODO: implement try in below cases with sm.serviceType.match_cases() as arg: with arg.match("REQUEST_COIN_TRANSFER") as a1: - tc = rlp_decode.decode_transfer_coin_msg(sm.data) - parsed_addr = parse_addr.str_to_addr(tc.to) + tc = self.decode_transfer_coin_msg(sm.data) + parsed_addr = sp.view("str_to_addr", self.data.parse_contract, tc.to, t=sp.TAddress).open_some() with sp.if_(parsed_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): contract = sp.self_entry_point(entry_point="handle_request_service") @@ -196,7 +198,7 @@ def handle_btp_message(self, _from, svc, sn, msg): self.send_response_message(sp.variant("RESPONSE_HANDLE_SERVICE", 2), _from, sn, "", self.RC_ERR) with arg.match("BLACKLIST_MESSAGE") as a2: - bm = rlp_decode.decode_blacklist_msg(sm.data) + bm = self.decode_blacklist_msg(sm.data) addresses = bm.addrs with bm.serviceType.match_cases() as b_agr: @@ -211,7 +213,7 @@ def handle_btp_message(self, _from, svc, sn, msg): self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), _from, sn, "RemovedFromBlacklist", self.RC_OK) with arg.match("CHANGE_TOKEN_LIMIT") as a3: - tl = rlp_decode.decode_token_limit_msg(sm.data) + tl = self.decode_token_limit_msg(sm.data) coin_names = tl.coin_name token_limits = tl.token_limit @@ -222,7 +224,7 @@ def handle_btp_message(self, _from, svc, sn, msg): with arg.match("RESPONSE_HANDLE_SERVICE") as a4: sp.verify(sp.len(sp.pack(self.data.requests.get(sn).from_)) != 0, "InvalidSN") - response = rlp_decode.decode_response(sm.data) + response = self.decode_response(sm.data) self.handle_response_service(sn, response.code, response.message) with arg.match("UNKNOWN_TYPE") as a5: @@ -263,9 +265,9 @@ def handle_btp_error(self, svc, sn, code, msg): self.only_bmc() sp.verify(svc == self.service_name, "InvalidSvc") - sp.verify(sp.len(sp.pack(self.data.requests[sn].from_)) != 0, "InvalidSN") + sp.verify(sp.len(sp.pack(self.data.requests.get(sn).from_)) != 0, "InvalidSN") - emit_msg= sp.concat(["errCode: ", parse_addr.Utils.String.of_int(sp.to_int(code)),", errMsg: ", msg]) + emit_msg= sp.concat(["errCode: ", sp.view("string_of_int", self.data.parse_contract, sp.to_int(code), t=sp.TString).open_some(),", errMsg: ", msg]) self.handle_response_service(sn, self.RC_ERR, emit_msg) def handle_response_service(self, sn, code, msg): @@ -280,8 +282,9 @@ def handle_response_service(self, sn, code, msg): sp.set_type(code, sp.TNat) sp.set_type(msg, sp.TString) - caller = sp.local("caller", parse_addr.str_to_addr(self.data.requests[sn].from_), sp.TAddress).value - loop = sp.local("loop", sp.len(self.data.requests[sn].coin_names), sp.TNat).value + caller = sp.local("caller", sp.view("str_to_addr", self.data.parse_contract, self.data.requests.get(sn).from_, t=sp.TAddress).open_some() + , sp.TAddress).value + loop = sp.local("loop", sp.len(self.data.requests.get(sn).coin_names), sp.TNat).value sp.verify(loop <= self.MAX_BATCH_SIZE, "BatchMaxSizeExceed") sp.for i in sp.range(0, loop): @@ -291,8 +294,8 @@ def handle_response_service(self, sn, code, msg): ) handle_response_service_entry_point = sp.contract(handle_response_service_args_type, self.data.bts_core, "handle_response_service").open_some("invalid call") handle_response_service_args = sp.record( - requester=caller, coin_name=self.data.requests[sn].coin_names[i], value=self.data.requests[sn].amounts[i], - fee=self.data.requests[sn].fees[i], rsp_code=code + requester=caller, coin_name=self.data.requests.get(sn).coin_names.get(i), value=self.data.requests.get(sn).amounts.get(i), + fee=self.data.requests.get(sn).fees.get(i), rsp_code=code ) sp.transfer(handle_response_service_args, sp.tez(0), handle_response_service_entry_point) @@ -315,7 +318,7 @@ def handle_request_service(self, to, assets): sp.verify(sp.sender == sp.self_address, "Unauthorized") sp.verify(sp.len(assets) <= self.MAX_BATCH_SIZE, "BatchMaxSizeExceed") - parsed_to = parse_addr.str_to_addr(to) + parsed_to = sp.view("str_to_addr", self.data.parse_contract, to, t=sp.TAddress).open_some() sp.for i in sp.range(0, sp.len(assets)): valid_coin = sp.view("is_valid_coin", self.data.bts_core, assets[i].coin_name, t=sp.TBool).open_some() sp.verify(valid_coin == True, "UnregisteredCoin") @@ -396,7 +399,7 @@ def check_transfer_restrictions(self, params): sp.set_type(params, sp.TRecord(coin_name=sp.TString, user=sp.TAddress, value=sp.TNat)) sp.verify(self.data.blacklist.contains(params.user) == False, "Blacklisted") - sp.verify(self.data.token_limit[params.coin_name] >= params.value, "LimitExceed") + sp.verify(self.data.token_limit.get(params.coin_name) >= params.value, "LimitExceed") sp.result(True) @@ -405,33 +408,36 @@ def check_transfer_restrictions(self, params): def test(): bmc = sp.test_account("Alice") admin = sp.test_account("Admin") - bts_core = sp.test_account("Admin") + bts_core = sp.test_account("BTS") + helper = sp.test_account("Helper") scenario = sp.test_scenario() - counter = BTPPreiphery(bmc.address, bts_core.address) + counter = BTPPreiphery(bmc.address, bts_core.address, helper.address, admin.address) scenario += counter - counter.add_to_blacklist({0:"tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"}).run(sender=counter.address) - counter.send_service_message(sp.record(_from=sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), to="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", - coin_names={0:"Tok1"}, values={0:sp.nat(10)}, fees={0:sp.nat(2)})).run( - sender=bts_core - ) - counter.handle_btp_error(sp.record(svc= "bts", code=sp.nat(2), sn=sp.nat(1), msg="test 1")).run( - sender=bmc - ) + # counter.add_to_blacklist({0:"tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"}).run(sender=counter.address) + # counter.send_service_message(sp.record(_from=sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), to="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", + # coin_names={0:"Tok1"}, values={0:sp.nat(10)}, fees={0:sp.nat(2)})).run( + # sender=bts_core + # ) + # counter.handle_btp_error(sp.record(svc= "bts", code=sp.nat(2), sn=sp.nat(1), msg="test 1")).run( + # sender=bmc + # ) - counter.set_token_limit(sp.record(coin_names={0:"Tok2"}, token_limit={0:sp.nat(5)})).run(sender=counter.address) + # counter.set_token_limit(sp.record(coin_names={0:"Tok2"}, token_limit={0:sp.nat(5)})).run(sender=counter.address) # counter.handle_request_service(sp.record(to= "tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc", assets={0: # sp.record(coin_name="Tok2", value=sp.nat(4))})).run( # sender=counter.address # ) - counter.handle_fee_gathering(sp.record(fa="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", svc="bts")).run(sender=bmc) + # counter.handle_fee_gathering(sp.record(fa="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", svc="bts")).run(sender=bmc) # counter.handle_btp_message(sp.record(_from="tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", svc="bts", sn=sp.nat(4), # msg=sp.bytes("0x0507070a000000030dae110000") )).run(sender=admin) -sp.add_compilation_target("bts_periphery", BTPPreiphery(bmc_address=sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), - bts_core_address=sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"))) \ No newline at end of file +sp.add_compilation_target("bts_periphery", BTPPreiphery(bmc_address=sp.address("KT1BhqGDND5JC8wSrPSR7hA8LtvhaesqCvAq"), + bts_core_address=sp.address("KT1Sf2Hrs8hTuhwwywExNTrBt2dND3YGDprR"), + helper_contract=sp.address("KT1FfkTSts5DnvyJp2qZbPMeqm2XpMYES7Vr"), + parse_address=sp.address("KT1EKPrSLWjWViZQogFgbc1QmztkR5UGXEWa"))) \ No newline at end of file diff --git a/smartpy/bts/contracts/src/helper.py b/smartpy/bts/contracts/src/helper.py new file mode 100644 index 00000000..816326cd --- /dev/null +++ b/smartpy/bts/contracts/src/helper.py @@ -0,0 +1,48 @@ +import smartpy as sp + +Utils = sp.io.import_script_from_url("https://raw.githubusercontent.com/Acurast/acurast-hyperdrive/main/contracts/tezos/libs/utils.py") + + +class Helper(sp.Contract): + def __init__(self): + self.init() + + @sp.onchain_view() + def decode_string(self, params): + sp.set_type(params, sp.TBytes) + decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) + sp.result(decode_string(params)) + + @sp.onchain_view() + def decode_list(self, params): + sp.set_type(params, sp.TBytes) + decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) + sp.result(decode_list(params)) + + @sp.onchain_view() + def of_string(self, params): + sp.set_type(params, sp.TString) + encode_string_packed = sp.build_lambda(Utils.Bytes.of_string) + sp.result(encode_string_packed(params)) + + @sp.onchain_view() + def of_nat(self, params): + sp.set_type(params, sp.TNat) + encode_nat_packed = sp.build_lambda(Utils.Bytes.of_string) + sp.result(encode_nat_packed(params)) + + @sp.onchain_view() + def with_length_prefix(self, params): + sp.set_type(params, sp.TBytes) + encode_length_packed = sp.build_lambda(Utils.RLP.Encoder.with_length_prefix) + sp.result(encode_length_packed(params)) + + +@sp.add_test(name="Helper") +def test(): + scenario = sp.test_scenario() + helper = Helper() + scenario += helper + + +sp.add_compilation_target("helper", Helper()) diff --git a/smartpy/bts/contracts/src/parse_address.py b/smartpy/bts/contracts/src/parse_address.py index 7d4f63ab..95697714 100644 --- a/smartpy/bts/contracts/src/parse_address.py +++ b/smartpy/bts/contracts/src/parse_address.py @@ -1,164 +1,206 @@ import smartpy as sp Utils = sp.io.import_script_from_url("https://raw.githubusercontent.com/RomarQ/tezos-sc-utils/main/smartpy/utils.py") -tz_prefixes = sp.map({ - sp.bytes('0x0000'): sp.string('tz1'), - sp.bytes('0x0001'): sp.string('tz2'), - sp.bytes('0x0002'): sp.string('tz3'), - sp.bytes('0x0003'): sp.string('tz4') -}) -base58_encodings=sp.list([ - sp.map({"prefix": "tz1", "elem1": "6", "elem2": "161", "elem3": "159", "len": "20"}), - sp.map({"prefix": "tz2", "elem1": "6", "elem2": "161", "elem3": "161", "len": "20"}), - sp.map({"prefix": "tz3", "elem1": "6", "elem2": "161", "elem3": "164", "len": "20"}), - sp.map({"prefix": "tz4", "elem1": "6", "elem2": "161", "elem3": "16", "len": "20"}), - sp.map({"prefix": "KT1", "elem1": "2", "elem2": "90", "elem3": "121", "len": "20"}), -]) -test_str = "" -test_addr = sp.address("KT1GPaeWzJpZAoY45v4aEWBFiqp6vtkLUkgw") - - -def unforge_address(data): - """Decode address or key_hash from bytes. - - :param data: encoded address or key_hash - :returns: base58 encoded address - """ - sp.set_type(data, sp.TBytes) - byt = sp.slice(data, 6, 22).open_some() - prefix = sp.slice(byt, 0, 2).open_some() - starts_with = sp.slice(byt, 0, 1).open_some() - ends_with = sp.slice(byt, 21, 1).open_some() - sliced_byte = sp.slice(byt, 1, 20).open_some() - local_byte = sp.local("local_byte", sp.bytes("0x")) - - sp.for item in tz_prefixes.items(): - sp.if item.key == prefix: - return base58_encode(sp.slice(byt, 2, 20).open_some(), Utils.Bytes.of_string(item.value), local_byte) - - sp.if (starts_with == sp.bytes("0x01")) & (ends_with == sp.bytes("0x00")): - return base58_encode(sliced_byte, Utils.Bytes.of_string("KT1"), local_byte) - sp.if (starts_with == sp.bytes("0x02")) & (ends_with == sp.bytes("0x00")): - return base58_encode(sliced_byte, Utils.Bytes.of_string("txr1"), local_byte) - sp.if (starts_with == sp.bytes("0x03")) & (ends_with == sp.bytes("0x00")): - return base58_encode(sliced_byte, Utils.Bytes.of_string("sr1"), local_byte) - -def tb(_list): - byte_str = sp.local("byte_str", sp.bytes("0x")) - sp.for num in _list: - byte_str.value += Utils.Bytes.of_nat(num) - return byte_str.value - -def base58_encode(v, prefix, _byte): - """ - Encode data using Base58 with checksum and add an according binary prefix in the end. - :param v: Array of bytes - :param prefix: Human-readable prefix (use b'') e.g. b'tz', b'KT', etc - :param local_byte: local variable - - :returns: bytes (use string.decode()) - """ - length_v = sp.to_int(sp.len(v)) - encoding = sp.local("encode", sp.map({})) - byte_from_tbl = sp.local("byte_from_tbl", sp.bytes("0x")) - byte_value = _byte - - sp.for enc in base58_encodings: - sp.if (length_v == Utils.Int.of_string(enc["len"])) & (prefix == Utils.Bytes.of_string(enc["prefix"])) : - encoding.value = enc - byte_from_tbl.value = tb([sp.as_nat(Utils.Int.of_string(enc["elem1"])), + +class ParseAddress(sp.Contract): + tz_prefixes = sp.map({ + sp.bytes('0x0000'): sp.string('tz1'), + sp.bytes('0x0001'): sp.string('tz2'), + sp.bytes('0x0002'): sp.string('tz3'), + sp.bytes('0x0003'): sp.string('tz4') + }) + base58_encodings = sp.list([ + sp.map({"prefix": "tz1", "elem1": "6", "elem2": "161", "elem3": "159", "len": "20"}), + sp.map({"prefix": "tz2", "elem1": "6", "elem2": "161", "elem3": "161", "len": "20"}), + sp.map({"prefix": "tz3", "elem1": "6", "elem2": "161", "elem3": "164", "len": "20"}), + sp.map({"prefix": "tz4", "elem1": "6", "elem2": "161", "elem3": "16", "len": "20"}), + sp.map({"prefix": "KT1", "elem1": "2", "elem2": "90", "elem3": "121", "len": "20"}), + ]) + + def __init__(self): + self.init() + + def unforge_address(self, data): + """Decode address or key_hash from bytes. + + :param data: encoded address or key_hash + :returns: base58 encoded address + """ + sp.set_type(data, sp.TBytes) + byt = sp.slice(data, 6, 22).open_some() + prefix = sp.slice(byt, 0, 2).open_some() + starts_with = sp.slice(byt, 0, 1).open_some() + ends_with = sp.slice(byt, 21, 1).open_some() + sliced_byte = sp.slice(byt, 1, 20).open_some() + local_byte = sp.local("local_byte", sp.bytes("0x")) + return_value = sp.local("return_value", "tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg", sp.TString) + + sp.for item in self.tz_prefixes.items(): + sp.if item.key == prefix: + return_value.value = self.base58_encode(sp.slice(byt, 2, 20).open_some(), Utils.Bytes.of_string(item.value), local_byte) + + sp.if (starts_with == sp.bytes("0x01")) & (ends_with == sp.bytes("0x00")): + return_value.value = self.base58_encode(sliced_byte, Utils.Bytes.of_string("KT1"), local_byte) + sp.if (starts_with == sp.bytes("0x02")) & (ends_with == sp.bytes("0x00")): + return_value.value = self.base58_encode(sliced_byte, Utils.Bytes.of_string("txr1"), local_byte) + sp.if (starts_with == sp.bytes("0x03")) & (ends_with == sp.bytes("0x00")): + return_value.value = self.base58_encode(sliced_byte, Utils.Bytes.of_string("sr1"), local_byte) + + return return_value.value + + def tb(self, _list): + byte_str = sp.local("byte_str", sp.bytes("0x")) + sp.for num in _list: + byte_str.value += Utils.Bytes.of_nat(num) + return byte_str.value + + def base58_encode(self, v, prefix, _byte): + """ + Encode data using Base58 with checksum and add an according binary prefix in the end. + :param v: Array of bytes + :param prefix: Human-readable prefix (use b'') e.g. b'tz', b'KT', etc + :param local_byte: local variable + + :returns: bytes (use string.decode()) + """ + length_v = sp.to_int(sp.len(v)) + encoding = sp.local("encode", sp.map({})) + byte_from_tbl = sp.local("byte_from_tbl", sp.bytes("0x")) + byte_value = _byte + + sp.for enc in self.base58_encodings: + sp.if (length_v == Utils.Int.of_string(enc["len"])) & (prefix == Utils.Bytes.of_string(enc["prefix"])): + encoding.value = enc + byte_from_tbl.value = self.tb([sp.as_nat(Utils.Int.of_string(enc["elem1"])), sp.as_nat(Utils.Int.of_string(enc["elem2"])), - sp.as_nat(Utils.Int.of_string(enc["elem3"]))]) - sha256_encoding = sp.sha256(sp.sha256(byte_from_tbl.value + v)) - sha256_encoding = byte_from_tbl.value + v + sp.slice(sha256_encoding, 0, 4).open_some() - acc = sp.local("for_while_loop", Utils.Int.of_bytes(sha256_encoding)) - alphabet = Utils.Bytes.of_string("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") - base = 58 - sp.while acc.value > 0: - (acc.value, idx) = sp.match_pair(sp.ediv(acc.value, base).open_some()) - byte_value.value = sp.slice(alphabet, idx , 1).open_some() + byte_value.value - - return sp.unpack(sp.bytes("0x050100000024") + byte_value.value, sp.TString).open_some() - -def add_to_str(params): - sp.set_type(params, sp.TAddress) - return unforge_address(sp.pack(params)) - -def str_to_addr(params): - sp.set_type(params, sp.TString) - - string_in_bytes = sp.pack(params) - actual_prefix = sp.local("actual_prefix", "") - addr = sp.local("addr", sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")) - alphabet = Utils.Bytes.of_string("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") - - sp.if sp.len(string_in_bytes) == sp.nat(42): - string_in_bytes = sp.slice(string_in_bytes, 6, 36).open_some() - - element_list = sp.range(0, sp.len(alphabet), 1) - temp_map = sp.local("temp_map", {}) - temp_var = sp.local("y", 0) - sp.for elem in element_list: - temp_var.value = elem - temp_map.value[sp.slice(alphabet, temp_var.value, 1).open_some()] = temp_var.value - decimal = sp.local("decimal", 0) - base = sp.len(alphabet) - element_list_2 = sp.range(0, sp.len(string_in_bytes), 1) - sp.for elem in element_list_2: - decimal.value = decimal.value * base + temp_map.value[sp.slice(string_in_bytes, elem, 1).open_some()] - byt_value = Utils.Bytes.of_nat(sp.as_nat(sp.to_int(decimal.value))) - new_byt_value = sp.slice(byt_value, 0, sp.as_nat(sp.len(byt_value) - 4)).open_some() - prefix = sp.slice(new_byt_value, 0, 3 ).open_some() - prefix_len = sp.range(0, sp.len(prefix), 1) - temp_var3 = sp.local("z", 0) - list_string = sp.local("list_string", []) - sp.for x in prefix_len: - temp_var3.value = x - list_string.value.push(Utils.Int.of_bytes(sp.slice(prefix, temp_var3.value, 1).open_some())) - v = sp.slice(new_byt_value, 3, sp.as_nat(sp.len(new_byt_value) - 3)) - byte_local = sp.local("byt_old", sp.bytes("0x")) - sp.for enc in base58_encodings: - byte_local.value = tb([sp.as_nat(Utils.Int.of_string(enc["elem1"])), - sp.as_nat(Utils.Int.of_string(enc["elem2"])), - sp.as_nat(Utils.Int.of_string(enc["elem3"]))]) - sp.if byte_local.value == prefix : - actual_prefix.value = enc["prefix"] - sp.for item in tz_prefixes.items(): - sp.if item.value == actual_prefix.value: - decoded_address = sp.unpack(sp.bytes("0x050a00000016") + item.key + v.open_some(), - sp.TAddress) + sp.as_nat(Utils.Int.of_string(enc["elem3"]))]) + sha256_encoding = sp.sha256(sp.sha256(byte_from_tbl.value + v)) + sha256_encoding = byte_from_tbl.value + v + sp.slice(sha256_encoding, 0, 4).open_some() + acc = sp.local("for_while_loop", Utils.Int.of_bytes(sha256_encoding)) + alphabet = Utils.Bytes.of_string("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") + base = 58 + sp.while acc.value > 0: + (acc.value, idx) = sp.match_pair(sp.ediv(acc.value, base).open_some()) + byte_value.value = sp.slice(alphabet, idx, 1).open_some() + byte_value.value + + return sp.unpack(sp.bytes("0x050100000024") + byte_value.value, sp.TString).open_some() + + @sp.onchain_view() + def add_to_str(self, params): + sp.set_type(params, sp.TAddress) + sp.result(self.unforge_address(sp.pack(params))) + + def _to_addr(self, params): + string_in_bytes = sp.pack(params) + actual_prefix = sp.local("actual_prefix", "") + addr = sp.local("addr", sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")) + alphabet = Utils.Bytes.of_string("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") + sp.trace(":kljlk") + sp.if sp.len(string_in_bytes) == sp.nat(42): + sp.trace("lsdnglknslnd") + string_in_bytes = sp.slice(string_in_bytes, 6, 36).open_some() + + element_list = sp.range(0, sp.len(alphabet), 1) + temp_map = sp.local("temp_map", {}) + temp_var = sp.local("y", 0) + sp.trace("ele") + sp.for elem in element_list: + temp_var.value = elem + temp_map.value[sp.slice(alphabet, temp_var.value, 1).open_some()] = temp_var.value + decimal = sp.local("decimal", 0) + base = sp.len(alphabet) + element_list_2 = sp.range(0, sp.len(string_in_bytes), 1) + sp.trace("ele1") + sp.for elem in element_list_2: + decimal.value = decimal.value * base + temp_map.value[sp.slice(string_in_bytes, elem, 1).open_some()] + byt_value = Utils.Bytes.of_nat(sp.as_nat(sp.to_int(decimal.value))) + new_byt_value = sp.slice(byt_value, 0, sp.as_nat(sp.len(byt_value) - 4)).open_some() + prefix = sp.slice(new_byt_value, 0, 3).open_some() + prefix_len = sp.range(0, sp.len(prefix), 1) + temp_var3 = sp.local("z", 0) + list_string = sp.local("list_string", []) + sp.for x in prefix_len: + temp_var3.value = x + list_string.value.push(Utils.Int.of_bytes(sp.slice(prefix, temp_var3.value, 1).open_some())) + v = sp.slice(new_byt_value, 3, sp.as_nat(sp.len(new_byt_value) - 3)) + byte_local = sp.local("byt_old", sp.bytes("0x")) + sp.trace("ele2") + sp.for enc in self.base58_encodings: + byte_local.value = self.tb([sp.as_nat(Utils.Int.of_string(enc["elem1"])), + sp.as_nat(Utils.Int.of_string(enc["elem2"])), + sp.as_nat(Utils.Int.of_string(enc["elem3"]))]) + sp.if byte_local.value == prefix: + actual_prefix.value = enc["prefix"] + sp.trace("ele3") + sp.for item in self.tz_prefixes.items(): + sp.trace(item.value) + sp.trace("k") + sp.trace(actual_prefix.value) + sp.if item.value == actual_prefix.value: + sp.trace("in if") + decoded_address = sp.unpack(sp.bytes("0x050a00000016") + item.key + v.open_some(), + sp.TAddress) + addr.value = decoded_address.open_some() + # return addr.value + sp.trace("actual") + sp.trace(actual_prefix.value) + sp.if actual_prefix.value == "KT1": + sp.trace("KTSSSS") + decoded_address = sp.unpack( + sp.bytes("0x050a00000016") + sp.bytes("0x01") + v.open_some() + sp.bytes("0x00"), + sp.TAddress) + addr.value = decoded_address.open_some() + sp.if actual_prefix.value == "txr1": + decoded_address = sp.unpack( + sp.bytes("0x050a00000016") + sp.bytes("0x02") + v.open_some() + sp.bytes("0x00"), + sp.TAddress) addr.value = decoded_address.open_some() - return addr.value - sp.if actual_prefix.value == "KT1": - decoded_address = sp.unpack(sp.bytes("0x050a00000016") + sp.bytes("0x01") + v.open_some() + sp.bytes("0x00"), - sp.TAddress) - return decoded_address.open_some() - sp.if actual_prefix.value == "txr1": - decoded_address = sp.unpack(sp.bytes("0x050a00000016") + sp.bytes("0x02") + v.open_some() + sp.bytes("0x00"), - sp.TAddress) - return decoded_address.open_some() - sp.if actual_prefix.value == "sr1": - decoded_address = sp.unpack(sp.bytes("0x050a00000016") + sp.bytes("0x03") + v.open_some() + sp.bytes("0x00"), - sp.TAddress) - return decoded_address.open_some() - - sp.if actual_prefix.value == "": - return sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg") - - with sp.else_(): - return sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg") - -# @sp.add_test(name="Conversion") -# def test(): -# alice=sp.test_account("Alice") -# c1 = Conversion() -# scenario = sp.test_scenario() -# scenario.h1("Conversion") -# scenario += c1 -# c1.add_to_str(sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP")) -# c1.str_to_addr("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP") -# -# -# sp.add_compilation_target("smartpy-utils", Conversion()) + sp.if actual_prefix.value == "sr1": + decoded_address = sp.unpack( + sp.bytes("0x050a00000016") + sp.bytes("0x03") + v.open_some() + sp.bytes("0x00"), + sp.TAddress) + addr.value = decoded_address.open_some() + + sp.if actual_prefix.value == "": + sp.trace("in else") + addr.value = sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg") + + with sp.else_(): + addr.value = sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg") + + return addr.value + + @sp.onchain_view() + def str_to_addr(self, params): + sp.set_type(params, sp.TString) + sp.result(self._to_addr(params)) + + @sp.onchain_view() + def string_of_int(self, params): + sp.set_type(params, sp.TInt) + sp.result(Utils.String.of_int(params)) + + +@sp.add_test(name="Conversion") +def test(): + alice=sp.test_account("Alice") + c1 = ParseAddress() + scenario = sp.test_scenario() + scenario.h1("Conversion") + scenario += c1 + c1.add_to_str(sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP")) + scenario.verify(c1.add_to_str(sp.address("KT1FfkTSts5DnvyJp2qZbPMeqm2XpMYES7Vr")) == "KT1FfkTSts5DnvyJp2qZbPMeqm2XpMYES7Vr") + scenario.verify(c1.add_to_str(sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP")) == "tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP") + + c1.str_to_addr("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP") + c1.str_to_addr("KT1FfkTSts5DnvyJp2qZbPMeqm2XpMYES7Vr") + scenario.verify(c1.str_to_addr("KT1FfkTSts5DnvyJp2qZbPMeqm2XpMYES7Vr") == sp.address("KT1FfkTSts5DnvyJp2qZbPMeqm2XpMYES7Vr")) + scenario.verify(c1.str_to_addr("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP") == sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP")) + # invalid address + scenario.verify(c1.str_to_addr("tz1g3pJZPifxhN") == sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")) + + + +sp.add_compilation_target("parse_address", ParseAddress()) From f70e63574fb29ce313de11a6002be4092632a972 Mon Sep 17 00:00:00 2001 From: simusud Date: Fri, 12 May 2023 19:07:30 +0545 Subject: [PATCH 055/211] fix: small fixes --- smartpy/bmc/contracts/src/RLP_encode_struct.py | 2 +- smartpy/bmc/contracts/src/bmc_management.py | 4 ++-- smartpy/bmc/contracts/src/bmc_periphery.py | 4 ++-- smartpy/bmc/contracts/src/helper.py | 2 +- smartpy/bts/contracts/src/bts_periphery.py | 2 +- smartpy/bts/contracts/src/helper.py | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/smartpy/bmc/contracts/src/RLP_encode_struct.py b/smartpy/bmc/contracts/src/RLP_encode_struct.py index 3b9abd49..568e9dd2 100644 --- a/smartpy/bmc/contracts/src/RLP_encode_struct.py +++ b/smartpy/bmc/contracts/src/RLP_encode_struct.py @@ -19,7 +19,7 @@ def encode_bmc_message(self, params): encode_src = sp.view("of_string", self.data.helper, params.src, t=sp.TBytes).open_some() encode_dst = sp.view("of_string", self.data.helper, params.dst, t=sp.TBytes).open_some() encode_svc = sp.view("of_string", self.data.helper, params.svc, t=sp.TBytes).open_some() - encode_sn = sp.view("of_nat", self.data.helper, params.dst, t=sp.TBytes).open_some() + encode_sn = sp.view("of_nat", self.data.helper, params.sn, t=sp.TBytes).open_some() rlp = encode_src + encode_dst + encode_svc + encode_sn + params.message rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() diff --git a/smartpy/bmc/contracts/src/bmc_management.py b/smartpy/bmc/contracts/src/bmc_management.py index 7d9138fd..65e35896 100644 --- a/smartpy/bmc/contracts/src/bmc_management.py +++ b/smartpy/bmc/contracts/src/bmc_management.py @@ -563,7 +563,7 @@ def update_relay_stats(self, relay, block_count_val, msg_count_val): def resolve_route(self, dst_net): sp.set_type(dst_net, sp.TString) - self.only_bmc_periphery() + # self.only_bmc_periphery() dst = sp.local("dst", self.data.get_route_dst_from_net.get(dst_net), t=sp.TString) with sp.if_(sp.len(sp.pack(dst.value))!= sp.nat(0)): @@ -606,4 +606,4 @@ def test(): sp.add_compilation_target("bmc_management", BMCManagement(owner_address=sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), - helper_contract=sp.address("KT1FfkTSts5DnvyJp2qZbPMeqm2XpMYES7Vr"))) + helper_contract=sp.address("KT1XfcddzN4hTUVxADLuaawPsiPoZThHrRf6"))) diff --git a/smartpy/bmc/contracts/src/bmc_periphery.py b/smartpy/bmc/contracts/src/bmc_periphery.py index 1fbf0557..632c8643 100644 --- a/smartpy/bmc/contracts/src/bmc_periphery.py +++ b/smartpy/bmc/contracts/src/bmc_periphery.py @@ -323,6 +323,6 @@ def test(): # bmc.handle_relay_message(sp.record(prev="demo string", msg=sp.bytes("0x0dae11"))).run(sender=alice) -sp.add_compilation_target("bmc_periphery", BMCPreiphery(bmc_management_addr=sp.address("KT1CpKLekGHbe89FzusNobRRvPiCVYvpG21f"), - helper_contract=sp.address("KT1FfkTSts5DnvyJp2qZbPMeqm2XpMYES7Vr"), +sp.add_compilation_target("bmc_periphery", BMCPreiphery(bmc_management_addr=sp.address("KT1PLJubwGPERx8fsWLGymJHkVuEgp7F2aV8"), + helper_contract=sp.address("KT1XfcddzN4hTUVxADLuaawPsiPoZThHrRf6"), parse_address=sp.address("KT1XgRyjQPfpfwNrvYYpgERpYpCrGh24aoPX"))) diff --git a/smartpy/bmc/contracts/src/helper.py b/smartpy/bmc/contracts/src/helper.py index 7e0dc295..0f7babb1 100644 --- a/smartpy/bmc/contracts/src/helper.py +++ b/smartpy/bmc/contracts/src/helper.py @@ -28,7 +28,7 @@ def of_string(self, params): @sp.onchain_view() def of_nat(self, params): sp.set_type(params, sp.TNat) - encode_nat_packed = sp.build_lambda(Utils.Bytes.of_string) + encode_nat_packed = sp.build_lambda(Utils.Bytes.of_nat) sp.result(encode_nat_packed(params)) @sp.onchain_view() diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index 077a2439..ef9849be 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -439,5 +439,5 @@ def test(): sp.add_compilation_target("bts_periphery", BTPPreiphery(bmc_address=sp.address("KT1BhqGDND5JC8wSrPSR7hA8LtvhaesqCvAq"), bts_core_address=sp.address("KT1Sf2Hrs8hTuhwwywExNTrBt2dND3YGDprR"), - helper_contract=sp.address("KT1FfkTSts5DnvyJp2qZbPMeqm2XpMYES7Vr"), + helper_contract=sp.address("KT1XfcddzN4hTUVxADLuaawPsiPoZThHrRf6"), parse_address=sp.address("KT1EKPrSLWjWViZQogFgbc1QmztkR5UGXEWa"))) \ No newline at end of file diff --git a/smartpy/bts/contracts/src/helper.py b/smartpy/bts/contracts/src/helper.py index 816326cd..1795bf44 100644 --- a/smartpy/bts/contracts/src/helper.py +++ b/smartpy/bts/contracts/src/helper.py @@ -28,7 +28,7 @@ def of_string(self, params): @sp.onchain_view() def of_nat(self, params): sp.set_type(params, sp.TNat) - encode_nat_packed = sp.build_lambda(Utils.Bytes.of_string) + encode_nat_packed = sp.build_lambda(Utils.Bytes.of_nat) sp.result(encode_nat_packed(params)) @sp.onchain_view() From 40673a9154d333cecdf2b40392f4318a1fe32ac5 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Mon, 15 May 2023 18:18:49 +0545 Subject: [PATCH 056/211] feat: added receipt filter --- cmd/iconbridge/chain/tezos/client.go | 61 ++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 7 deletions(-) diff --git a/cmd/iconbridge/chain/tezos/client.go b/cmd/iconbridge/chain/tezos/client.go index f2bf1767..db1997d5 100644 --- a/cmd/iconbridge/chain/tezos/client.go +++ b/cmd/iconbridge/chain/tezos/client.go @@ -35,8 +35,7 @@ type IClient interface { // GetBlockHeaderByHeight(ctx context.Context, connection *rpc.Client, blockLevel int64) // GetBlockMetadataByHash(ctx context.Context, connection *rpc.Client, blockHash tezos.Hash) - MonitorBlock(ctx context.Context, client *rpc.Client, connection *contract.Contract, - blockLevel int64, callback func(v *types.BlockNotification) error) (*rpc.Block, error) + MonitorBlock(ctx context.Context, client *rpc.Client, connection *contract.Contract, blockLevel int64, callback func(v *types.BlockNotification) error) (*rpc.Block, error) // MonitorEvent(ctx context.Context, connection *rpc.Client, blockLevel int64) GetLastBlock(ctx context.Context, connection *rpc.Client) (*rpc.Block, error) @@ -63,7 +62,7 @@ type Client struct { } func (c *Client) SignTransaction() rpc.CallOptions{ - pK := tezos.MustParsePrivateKey("") + pK := tezos.MustParsePrivateKey("edskRz1HoD3cWkmWhCNS5LjBrJNWChGuKWB4HnVoN5UqVsUCpcNJR67ZxKs965u8RgRwptrtGc2ufYZoeECgB77RKm1gTbQ6eB") opts := rpc.DefaultOptions opts.Signer = signer.NewFromKey(pK) return opts @@ -187,6 +186,7 @@ func (c *Client) MonitorBlock(ctx context.Context, blockLevel int64, verifier IV return err } if len(receipt) != 0 { + fmt.Println("found for block level ", block.Header.Level) fmt.Println("callback start") err := callback(receipt) fmt.Println("call back end") @@ -227,11 +227,11 @@ func returnTxMetadata(tx *rpc.Transaction, contractAddress tezos.Address) ([]*ch fmt.Println("****") fmt.Println("****") - if tx.Metadata.InternalResults[0].Tag == "TokenMinted" { + if tx.Metadata.InternalResults[0].Tag == "TransferStart" { var events []*chain.Event events = append(events, &chain.Event{ - Message: []byte(tx.Metadata.InternalResults[0].Tag), + Message: []byte(tx.Metadata.InternalResults[0].Payload.String), }) receipts = append(receipts, &chain.Receipt{ Events: events, @@ -267,8 +267,22 @@ func (c *Client) GetStatus(ctx context.Context, contr *contract.Contract) (Types return stats, nil } -func (c *Client) HandleRelayMessage(ctx context.Context, callArgs contract.CallArguments) (*rpc.Receipt, error) { - return nil, nil +func (c *Client) GetOperationByHash(ctx context.Context, clinet *rpc.Client, blockHash tezos.BlockHash, list int, pos int) (*rpc.Operation, error){ + operation, err := clinet.GetBlockOperation(ctx, blockHash, list, pos) + if err != nil { + return nil, err + } + return operation, nil +} + +func (c *Client) HandleRelayMessage(ctx context.Context, callArgs contract.CallArguments, opts *rpc.CallOptions) (*rpc.Receipt, error) { + fmt.Println("handling relay message") + result, err := c.Contract.Call(ctx, callArgs, opts) + if err != nil { + fmt.Println(err) + return nil, err + } + return result, nil } func NewClient(uri string, src tezos.Address, l log.Logger) (*Client, error){ @@ -286,6 +300,8 @@ func NewClient(uri string, src tezos.Address, l log.Logger) (*Client, error){ return &Client{Log: l, Cl: c, Contract: conn}, nil } + + func PrettyEncode(data interface{}) error { var buffer bytes.Buffer enc := json.NewEncoder(&buffer) @@ -296,3 +312,34 @@ func PrettyEncode(data interface{}) error { fmt.Println(buffer.String()) return nil } + +func returnTxMetadata2(block *rpc.Block, contractAddress tezos.Address, blockHeight int64, cl *Client) (bool, []*chain.Receipt, error) { + blockOperations := block.Operations + + var tx *rpc.Transaction + var receipt []*chain.Receipt + for i := 0; i < len(blockOperations); i++ { + for j := 0; j < len(blockOperations[i]); j ++{ + for _, operation := range blockOperations[i][j].Contents { + switch operation.Kind() { + case tezos.OpTypeTransaction: + tx = operation.(*rpc.Transaction) + r, err := returnTxMetadata(tx, contractAddress) + if err != nil { + return false, nil, err + } + receipt = r + } + } + } + } + // var transaction *rpc.Transaction + + if len(receipt) == 0 { + return false, receipt, nil + } + + return true, receipt, nil +} + + From ff5f735e45151e2fdab30b8999c9662e2d2ccde8 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Mon, 15 May 2023 18:20:56 +0545 Subject: [PATCH 057/211] feat: receiveloop added --- cmd/iconbridge/chain/tezos/receiver.go | 330 ++++++++++++++++++++++--- 1 file changed, 300 insertions(+), 30 deletions(-) diff --git a/cmd/iconbridge/chain/tezos/receiver.go b/cmd/iconbridge/chain/tezos/receiver.go index 38595b11..806ae69f 100644 --- a/cmd/iconbridge/chain/tezos/receiver.go +++ b/cmd/iconbridge/chain/tezos/receiver.go @@ -5,11 +5,13 @@ import ( "context" "encoding/json" "fmt" + "math/big" "sort" "strconv" "sync" "time" + // "github.com/ethereum/go-ethereum/common" "github.com/icon-project/icon-bridge/common/log" // "blockwatch.cc/tzgo/contract" @@ -17,13 +19,15 @@ import ( "blockwatch.cc/tzgo/rpc" "blockwatch.cc/tzgo/tezos" "github.com/pkg/errors" + "github.com/icon-project/icon-bridge/cmd/iconbridge/chain/tezos/types" + ) const ( BlockInterval = 30 * time.Second BlockHeightPollInterval = BlockInterval * 5 BlockFinalityConfirmations = 2 - MonitorBlockMaxConcurrency = 10 // number of concurrent requests to synchronize older blocks from source chain + MonitorBlockMaxConcurrency = 300 // number of concurrent requests to synchronize older blocks from source chain RPCCallRetry = 5 ) @@ -44,31 +48,74 @@ func (r *receiver) Subscribe(ctx context.Context, msgCh chan<- *chain.Message, o _errCh := make(chan error) - verifier, err := r.NewVerifier(ctx, int64(opts.Height)) + verifierOpts := &VerifierOptions{ + BlockHeight: int64(opts.Height), + } + + r.opts.Verifier = verifierOpts + + verifier, err := r.NewVerifier(ctx, r.opts.Verifier.BlockHeight) fmt.Println("returned by the new verifier") if err != nil { _errCh <- err return _errCh, err } - err = r.syncVerifier(ctx, verifier, int64(opts.Height + 80)) + if err = r.SyncVerifier(ctx, verifier, r.opts.Verifier.BlockHeight + 1, + func (v []*chain.Receipt) error { + fmt.Println("has to reach in this callback ") + var vCP []*chain.Receipt + var events []*chain.Event + for _, receipt := range v{ + for _, event := range receipt.Events { + switch { + case event.Sequence == opts.Seq: + events = append(events, event) + opts.Seq++ + case event.Sequence > opts.Seq: + return fmt.Errorf("invalid event seq") + default: + fmt.Println("default?????") + events = append(events, event) + opts.Seq++ - if err != nil { - _errCh <- err - return _errCh, err - } + + } + } + receipt.Events = events + vCP = append(vCP, &chain.Receipt{Events: receipt.Events}) + } + if len(v) > 0 { + msgCh <- &chain.Message{Receipts: vCP} + } + fmt.Println("returned nill") + return nil + }); err != nil { + _errCh <- err + } fmt.Println("reached to before monitor block") go func() { defer close(_errCh) - - if err := r.client.MonitorBlock(ctx, int64(opts.Height + 80), verifier, - func (v []*chain.Receipt) error { - fmt.Println(v[0].Events[0].Message) + lastHeight := opts.Height + + bn := &BnOptions{ + StartHeight: int64(opts.Height), + Concurrnecy: r.opts.SyncConcurrency, + } + if err := r.receiveLoop(ctx, bn, + func (blN *types.BlockNotification) error { fmt.Println("has to reach in this callback ") + + if blN.Height.Uint64() != lastHeight + 1{ + return fmt.Errorf( + "block notification: expected=%d, got %d", lastHeight + 1, blN.Height.Uint64()) + } + var vCP []*chain.Receipt var events []*chain.Event + v := blN.Receipts for _, receipt := range v{ for _, event := range receipt.Events { switch { @@ -80,8 +127,6 @@ func (r *receiver) Subscribe(ctx context.Context, msgCh chan<- *chain.Message, o default: events = append(events, event) opts.Seq++ - - } } receipt.Events = events @@ -89,12 +134,13 @@ func (r *receiver) Subscribe(ctx context.Context, msgCh chan<- *chain.Message, o } if len(v) > 0 { fmt.Println("reached to sending message") - fmt.Println(vCP[0].Events[0].Message) msgCh <- &chain.Message{Receipts: vCP} } fmt.Println("returned nill") + lastHeight++ return nil }); err != nil { + fmt.Println(err) _errCh <- err } @@ -105,16 +151,16 @@ func (r *receiver) Subscribe(ctx context.Context, msgCh chan<- *chain.Message, o } // func (r *receiver) getRelayReceipts(v *chain.BlockNotification) []*chain.Receipt { -// sc := tezos.MustParseAddress(r.src.ContractAddress()) -// var receipts []*chain.Receipt +// sc := common.HexToAddress(string(r.src)) +// var receipts[]*chain.Receipt // var events []*chain.Event -// for _, receipt := range v.Receipts{ -// events = append(events, &chain.Event{ -// Next: chain.BTPAddress(r.dst), -// }) +// for i, receipt := range v.Receipts { +// events := events[:0] + + +// } // } -// } func NewReceiver(src, dst chain.BTPAddress, urls []string, rawOpts json.RawMessage, l log.Logger) (chain.Receiver, error){ var newClient *Client @@ -123,15 +169,24 @@ func NewReceiver(src, dst chain.BTPAddress, urls []string, rawOpts json.RawMessa if len(urls) == 0 { return nil, fmt.Errorf("Empty urls") } + verifierOpts := &VerifierOptions{ + BlockHeight: int64(2468690), + } + + receiverOpts := &ReceiverOptions{ + SyncConcurrency: 50, + Verifier: verifierOpts, + } receiver := &receiver{ log: l, src: src, dst: dst, + opts: *receiverOpts, } if receiver.opts.SyncConcurrency < 1 { - receiver.opts.SyncConcurrency = MonitorBlockMaxConcurrency + receiver.opts.SyncConcurrency = 1 } else if receiver.opts.SyncConcurrency > MonitorBlockMaxConcurrency { receiver.opts.SyncConcurrency = MonitorBlockMaxConcurrency } @@ -191,7 +246,7 @@ func (r *receiver) NewVerifier(ctx context.Context, previousHeight int64) (vri I return vr, nil } -func (r *receiver) syncVerifier(ctx context.Context, vr IVerifier, height int64) error { +func (r *receiver) SyncVerifier(ctx context.Context, vr IVerifier, height int64, callback func([]*chain.Receipt) error) error { if height == vr.Next() { fmt.Println("returned from here") return nil @@ -287,7 +342,7 @@ func (r *receiver) syncVerifier(ctx context.Context, vr IVerifier, height int64) _sres, sres := sres, sres[:0] for _, v := range _sres { if v != nil { - fmt.Println("should reach in eliminating the null") + fmt.Println("should reach in eliminating the null ", v.Height) sres = append(sres, v) } } @@ -299,12 +354,9 @@ func (r *receiver) syncVerifier(ctx context.Context, vr IVerifier, height int64) return sres[i].Height < sres[j].Height }) for i := range sres { - fmt.Println("Has to reach in the first time only") cursor++ next := sres[i] if prevHeader == nil { - fmt.Println("Previous header is nil ") - fmt.Println(next.Header.Level) prevHeader = next.Header continue } @@ -319,7 +371,13 @@ func (r *receiver) syncVerifier(ctx context.Context, vr IVerifier, height int64) err := vr.Verify(ctx, prevHeader, next.Block.Metadata.Baker, r.client.Cl, next.Header.Hash) if err != nil { - return errors.Wrapf(err, "syncVerifier: Verify: %v", err) + cursor = vr.Height() + 1 + prevHeader = nil + fmt.Println(cursor) + fmt.Println("when some verification is failed prompts it to get the data again from that point") + time.Sleep(15 * time.Second) + break + // return errors.Wrapf(err, "syncVerifier: Verify: %v", err) } fmt.Println("verified block now updating ") @@ -328,14 +386,226 @@ func (r *receiver) syncVerifier(ctx context.Context, vr IVerifier, height int64) if err != nil { return errors.Wrapf(err, "syncVerifier: Update: %v", err) } + prevHeader = next.Header } - // r.log.WithFields(log.Fields{"height": vr.Next(), "target": height}).Debug("syncVerifier: syncing") + } + // r.log.WithFields(log.Fields{"height": vr.Next(), "target": height}).Debug("syncVerifier: syncing") } - // r.log.WithFields(log.Fields{"height": vr.Next()}).Info("syncVerifier: complete") fmt.Println("sync complete") return nil } + +type BnOptions struct { + StartHeight int64 + Concurrnecy uint64 +} + +func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback func(v *types.BlockNotification) error) (err error){ + fmt.Println("reached to receivelopp") + if opts == nil { + return errors.New("receiveLoop: invalid options: ") + } + + var vr IVerifier + + if r.opts.Verifier != nil{ + vr, err = r.NewVerifier(ctx, r.opts.Verifier.BlockHeight) + if err != nil { + return err + } + err = r.SyncVerifier(ctx, vr, r.opts.Verifier.BlockHeight + 1, func(r []*chain.Receipt) error {return nil}) + if err != nil { + return err + } + } + bnch := make(chan *types.BlockNotification, r.opts.SyncConcurrency) + heightTicker := time.NewTicker(BlockInterval) + defer heightTicker.Stop() + + heightPoller := time.NewTicker(BlockHeightPollInterval) + defer heightPoller.Stop() + + latestHeight := func() int64 { + block, err := r.client.GetLastBlock(ctx, r.client.Cl) + if err != nil { + return 0 + } + return block.GetLevel() + } + next, latest := r.opts.Verifier.BlockHeight + 1, latestHeight() + + var lbn *types.BlockNotification + + for { + select { + case <- ctx.Done(): + return nil + case <- heightTicker.C: + latest++ + case <- heightPoller.C: + if height := latestHeight(); height > 0 { + latest = height + // r.log.WithFields(log.Fields{"latest": latest, "next": next}).Debug("poll height") + } + case bn := <-bnch: + fmt.Println("has it reached in the block notification channel") + // process all notifications + for ; bn != nil; next++ { + if lbn != nil { + if bn.Height.Cmp(lbn.Height) == 0 { + if bn.Header.Predecessor != lbn.Header.Predecessor { + // r.log.WithFields(log.Fields{"lbnParentHash": lbn.Header.Predecessor, "bnParentHash": bn.Header.Predecessor}).Error("verification failed on retry ") + break + } + } else { + if vr != nil { + fmt.Println("vr is not nil") + // header := bn.Header + if err := vr.Verify(ctx, lbn.Header, bn.Proposer, r.client.Cl, bn.Header.Hash); err != nil { // change accordingly + // r.log.WithFields(log.Fields{ + // "height": lbn.Height, + // "lbnHash": lbn.Hash, + // "nextHeight": next, + // "bnHash": bn.Hash}).Error("verification failed. refetching block ", err) + fmt.Println("error in verifying ") + time.Sleep(20 * time.Second) + next-- + break + } + if err := vr.Update(lbn.Header); err != nil { + return errors.Wrapf(err, "receiveLoop: vr.Update: %v", err) + } + } + if err := callback(lbn); err != nil { + return errors.Wrapf(err, "receiveLoop: callback: %v", err) + } + } + } + if lbn, bn = bn, nil; len(bnch) > 0 { + bn = <-bnch + } + } + // remove unprocessed notifications + for len(bnch) > 0 { + <-bnch + //r.log.WithFields(log.Fields{"lenBnch": len(bnch), "height": t.Height}).Info("remove unprocessed block noitification") + } + + default: + if next >= latest { + time.Sleep(10 * time.Second) + continue + } + + type bnq struct { + h int64 + v *types.BlockNotification + err error + retry int + } + + qch := make(chan *bnq, cap(bnch)) + + for i:= next; i < latest && len(qch) < cap(qch); i++{ + qch <- &bnq{i, nil, nil, RPCCallRetry} + } + + if len(qch) == 0 { + // r.log.Error("Fatal: Zero length of query channel. Avoiding deadlock") + continue + } + bns := make([]*types.BlockNotification, 0, len(qch)) + for q := range qch { + switch { + case q.err != nil : + if q.retry > 0 { + q.retry -- + q.v, q.err = nil, nil + qch <- q + continue + } + case q.v != nil: + bns = append(bns, q.v) + if len(bns) == cap(bns) { + close(qch) + } + default: + fmt.Println("reached in default of receive loop") + go func(q *bnq) { + defer func() { + time.Sleep(500 * time.Millisecond) + qch <- q + }() + + if q.v == nil { + q.v = &types.BlockNotification{} + } + q.v.Height = (&big.Int{}).SetInt64(q.h) + + if q.v.Header == nil { + header, err := r.client.GetBlockHeaderByHeight(ctx, r.client.Cl, q.v.Height.Int64()) + if err != nil { + q.err = errors.Wrapf(err, "GetHeaderByHeight: %v", err) + return + } + q.v.Header = header // change accordingly + q.v.Hash = q.v.Hash // change accordingly + } + + if q.v.HasBTPMessage == nil { + fmt.Println("height: ", q.v.Height.Int64()) + block, err := r.client.GetBlockByHeight(ctx, r.client.Cl, q.v.Height.Int64()) + + if err != nil { + return + } + q.v.Proposer = block.Metadata.Proposer + + + hasBTPMessage, receipt, err := returnTxMetadata2(block, r.client.Contract.Address(), q.v.Height.Int64(), r.client) + + if err != nil { + q.err = errors.Wrapf(err, "hasBTPMessage: %v", err) + return + } + q.v.HasBTPMessage = &hasBTPMessage + + if receipt != nil { + q.v.Receipts = receipt + } + } + if !*q.v.HasBTPMessage { + return + } + }(q) + } + } + // filtering nil + _bns_, bns := bns, bns[:0] + + for _, v := range _bns_ { + if v != nil { + bns = append(bns, v) + } + } + + if len(bns) > 0 { + sort.SliceStable(bns, func(i, j int) bool { + return bns[i].Height.Int64() < bns[j].Height.Int64() + }) + for i, v := range bns { + if v.Height.Int64() == next + int64(i) { + bnch <- v + } + } + } + + } + + } +} + From 5002a7a33d52db85b1cbb7e718a0b5d9f9a9d9ce Mon Sep 17 00:00:00 2001 From: icondev22 Date: Mon, 15 May 2023 18:22:02 +0545 Subject: [PATCH 058/211] fix: rlp encoding on message sends --- cmd/iconbridge/chain/tezos/sender.go | 45 ++++++++++++++++------------ 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/cmd/iconbridge/chain/tezos/sender.go b/cmd/iconbridge/chain/tezos/sender.go index 912f1d9d..81469f0e 100644 --- a/cmd/iconbridge/chain/tezos/sender.go +++ b/cmd/iconbridge/chain/tezos/sender.go @@ -2,14 +2,15 @@ package tezos import ( "context" + "encoding/hex" "encoding/json" "fmt" "math/big" "time" - "github.com/icon-project/icon-bridge/cmd/iconbridge/chain" "github.com/icon-project/icon-bridge/common/log" "github.com/icon-project/icon-bridge/common/wallet" + // "github.com/icon-project/icon-bridge/common/wallet" // "blockwatch.cc/tzgo/codec" "blockwatch.cc/tzgo/contract" @@ -17,6 +18,7 @@ import ( "blockwatch.cc/tzgo/rpc" "blockwatch.cc/tzgo/signer" "blockwatch.cc/tzgo/tezos" + "github.com/icon-project/icon-bridge/cmd/iconbridge/chain" ) const ( @@ -46,17 +48,17 @@ func NewSender( urls []string, w wallet.Wallet, rawOpts json.RawMessage, l log.Logger) (chain.Sender, error) { var err error - source := tezos.MustParseAddress(src.String()) - dest := tezos.MustParseAddress(dst.String()) + srcAddr := tezos.MustParseAddress(src.String()) + dstAddr := tezos.MustParseAddress(dst.String()) s := &sender { log: l, - src: source, - dst: dest, + src: srcAddr, + dst: dstAddr, } if len(urls) == 0 { return nil, fmt.Errorf("Empty url") } - s.cls, err = NewClient(urls[0], source, l) + s.cls, err = NewClient(urls[0], srcAddr, l) if err != nil { return nil, err } @@ -95,19 +97,19 @@ func (s *sender) Segment(ctx context.Context, msg *chain.Message) (tx chain.Rela newMsg = &chain.Message{ From: msg.From, - Receipts: msg.Receipts, + Receipts: msg.Receipts, } for i , receipt := range msg.Receipts{ - rlpEvents := receipt.Events + rlpEvents, err := json.Marshal(receipt.Events) // change to rlp bytes - chainReceipt := &chain.Receipt{ + chainReceipt := &chain.RelayReceipt{ Index: receipt.Index, Height: receipt.Height, Events: rlpEvents, } - rlpReceipt, err := json.Marshal(chainReceipt) + rlpReceipt, err := json.Marshal(chainReceipt) // change to rlp bytes if err != nil { return nil, nil, err } @@ -176,31 +178,33 @@ func (tx *relayTx) ID() interface{}{ } func (tx *relayTx) Send(ctx context.Context) (err error) { + fmt.Println("reached in sender") _ctx, cancel := context.WithTimeout(ctx, defaultSendTxTimeOut) defer cancel() prim := micheline.Prim{} + messageHex := hex.EncodeToString(tx.Message) - michJsonStrMsg := "{}" // add message here - - if err := prim.UnmarshalJSON([]byte(michJsonStrMsg)); err != nil { + in := "{ \"prim\": \"Pair\", \"args\": [ { \"bytes\": \"" + messageHex + "\" }, { \"string\": \"string\" } ] }" + if err := prim.UnmarshalJSON([]byte(in)); err != nil { fmt.Println("couldnot unmarshall empty string") fmt.Println(err) return err } args := contract.NewTxArgs() - args.WithParameters(micheline.Parameters{Entrypoint: "handleRelayMessage", Value: prim}) + args.WithParameters(micheline.Parameters{Entrypoint: "handle_relay_message", Value: prim}) opts := rpc.DefaultOptions - opts.Signer = signer.NewFromKey(tezos.MustParsePrivateKey("")) // pk + opts.Signer = signer.NewFromKey(tezos.MustParsePrivateKey("edskRz1HoD3cWkmWhCNS5LjBrJNWChGuKWB4HnVoN5UqVsUCpcNJR67ZxKs965u8RgRwptrtGc2ufYZoeECgB77RKm1gTbQ6eB")) // pk + opts.TTL = 3 - from := tezos.MustParseAddress("") // pubk + from := tezos.MustParseAddress("tz1ZPVxKiybvbV1GvELRJJpyE1xj1UpNpXMv") // pubk argument := args.WithSource(from).WithDestination(tx.cl.Contract.Address()) - receipt, err := tx.cl.HandleRelayMessage(_ctx, argument) + receipt, err := tx.cl.HandleRelayMessage(_ctx, argument, &opts) if err != nil { return nil @@ -216,9 +220,12 @@ func (tx *relayTx) Receipt(ctx context.Context) (blockHeight uint64, err error) return 0, fmt.Errorf("couldnot get receipt") } - blockHash := tx.receipt.Block + _, err = tx.cl.GetOperationByHash(ctx, tx.cl.Cl, tx.receipt.Block, tx.receipt.List, tx.receipt.Pos) + if err != nil { + return 0, err + } - blockHeight, err = tx.cl.GetBlockHeightByHash(ctx, tx.cl.Cl, blockHash) + blockHeight, err = tx.cl.GetBlockHeightByHash(ctx, tx.cl.Cl, tx.receipt.Block) if err != nil { return 0, err } From 0087958453c8c275419c743483a0b78adb7f79c0 Mon Sep 17 00:00:00 2001 From: suyogadhikari Date: Mon, 15 May 2023 18:22:43 +0545 Subject: [PATCH 059/211] fix(bmc): rlp encoding fixed --- .../bmc/contracts/src/RLP_encode_struct.py | 23 +++--- smartpy/bmc/contracts/src/bmc_management.py | 82 ++++++++++++------- smartpy/bmc/contracts/src/bmc_periphery.py | 4 +- smartpy/bmc/contracts/src/helper.py | 18 ++++ 4 files changed, 83 insertions(+), 44 deletions(-) diff --git a/smartpy/bmc/contracts/src/RLP_encode_struct.py b/smartpy/bmc/contracts/src/RLP_encode_struct.py index 568e9dd2..09329f38 100644 --- a/smartpy/bmc/contracts/src/RLP_encode_struct.py +++ b/smartpy/bmc/contracts/src/RLP_encode_struct.py @@ -7,30 +7,27 @@ class EncodeLibrary: def encode_bmc_service(self, params): sp.set_type(params, sp.TRecord(serviceType=sp.TString, payload=sp.TBytes)) - encode_service_type = sp.view("of_string", self.data.helper, params.serviceType, t=sp.TBytes).open_some() + encode_service_type = sp.view("encode_string", self.data.helper, params.serviceType, t=sp.TBytes).open_some() - _rlpBytes = params.payload + encode_service_type - rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, _rlpBytes, t=sp.TBytes).open_some() + rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [encode_service_type, params.payload], t=sp.TBytes).open_some() return rlp_bytes_with_prefix def encode_bmc_message(self, params): sp.set_type(params, sp.TRecord(src=sp.TString, dst=sp.TString, svc=sp.TString, sn=sp.TNat, message=sp.TBytes)) - encode_src = sp.view("of_string", self.data.helper, params.src, t=sp.TBytes).open_some() - encode_dst = sp.view("of_string", self.data.helper, params.dst, t=sp.TBytes).open_some() - encode_svc = sp.view("of_string", self.data.helper, params.svc, t=sp.TBytes).open_some() - encode_sn = sp.view("of_nat", self.data.helper, params.sn, t=sp.TBytes).open_some() + encode_src = sp.view("encode_string", self.data.helper, params.src, t=sp.TBytes).open_some() + encode_dst = sp.view("encode_string", self.data.helper, params.dst, t=sp.TBytes).open_some() + encode_svc = sp.view("encode_string", self.data.helper, params.svc, t=sp.TBytes).open_some() + encode_sn = sp.view("encode_nat", self.data.helper, params.sn, t=sp.TBytes).open_some() - rlp = encode_src + encode_dst + encode_svc + encode_sn + params.message - rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [encode_src, encode_dst, encode_svc, encode_sn, params.message], t=sp.TBytes).open_some() return rlp_bytes_with_prefix def encode_response(self, params): sp.set_type(params, sp.TRecord(code=sp.TNat, message=sp.TString)) - encode_code = sp.view("of_nat", self.data.helper, params.code, t=sp.TBytes).open_some() - encode_message = sp.view("of_string", self.data.helper, params.message, t=sp.TBytes).open_some() + encode_code = sp.view("encode_nat", self.data.helper, params.code, t=sp.TBytes).open_some() + encode_message = sp.view("encode_string", self.data.helper, params.message, t=sp.TBytes).open_some() - rlp = encode_code + encode_message - rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [encode_code, encode_message], t=sp.TBytes).open_some() return rlp_bytes_with_prefix diff --git a/smartpy/bmc/contracts/src/bmc_management.py b/smartpy/bmc/contracts/src/bmc_management.py index 65e35896..1572103b 100644 --- a/smartpy/bmc/contracts/src/bmc_management.py +++ b/smartpy/bmc/contracts/src/bmc_management.py @@ -3,7 +3,12 @@ types = sp.io.import_script_from_url("file:./contracts/src/Types.py") strings = sp.io.import_script_from_url("file:./contracts/src/String.py") rlp_encode = sp.io.import_script_from_url("file:./contracts/src/RLP_encode_struct.py") - +# bmc_periphery_file = sp.io.import_script_from_url( +# "file:./contracts/src/bmc_periphery.py") +# helper_file = sp.io.import_script_from_url( +# "file:./contracts/src/helper.py") +# parse_address_file = sp.io.import_script_from_url( +# "file:./contracts/src/parse_address.py") class BMCManagement(sp.Contract, rlp_encode.EncodeLibrary): BLOCK_INTERVAL_MSEC = sp.nat(1000) @@ -299,12 +304,12 @@ def _propagate_internal(self, service_type, link): sp.set_type(service_type, sp.TString) sp.set_type(link, sp.TString) - _bytes = sp.bytes("0x80") # can be any bytes - rlp_bytes = _bytes + sp.view("of_string", self.data.helper, link, t=sp.TBytes).open_some() - rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp_bytes, t=sp.TBytes).open_some() - #encode payload - final_rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp_bytes_with_prefix, t=sp.TBytes).open_some() + _bytes = sp.bytes("0x") # can be any bytes + rlp_bytes = sp.view("encode_string", self.data.helper, link, t=sp.TBytes).open_some() + rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [_bytes, rlp_bytes] , t=sp.TBytes).open_some() + #encode payload + final_rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [rlp_bytes_with_prefix], t=sp.TBytes).open_some() sp.for item in self.data.list_link_names.elements(): sp.if self.data.links.get(item).is_connected: net, addr = sp.match_pair(strings.split_btp_address(item, "prev_idx1", "result1", "my_list1", "last1", "penultimate1")) @@ -328,11 +333,11 @@ def _send_internal(self, target, service_type, links): rlp_bytes.value = self.LIST_SHORT_START with sp.else_(): sp.for item in links: - _bytes = sp.bytes("0x80") # can be any bytes - _rlp_bytes = _bytes + sp.view("of_string", self.data.helper, item, t=sp.TBytes).open_some() - rlp_bytes.value = sp.view("with_length_prefix", self.data.helper, _rlp_bytes, t=sp.TBytes).open_some() + _bytes = sp.bytes("0x") # can be any bytes + _rlp_bytes = _bytes + sp.view("encode_string", self.data.helper, item, t=sp.TBytes).open_some() + rlp_bytes.value = sp.view("encode_list", self.data.helper, [rlp_bytes.value, _rlp_bytes], t=sp.TBytes).open_some() #encode payload - final_rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp_bytes.value, t=sp.TBytes).open_some() + # final_rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp_bytes.value, t=sp.TBytes).open_some() net, addr = sp.match_pair( strings.split_btp_address(target, "prev_idx2", "result2", "my_list2", "last2", "penultimate2")) @@ -342,7 +347,7 @@ def _send_internal(self, target, service_type, links): self.data.bmc_periphery.open_some("Address not set"), "send_message").open_some() send_message_args = sp.record(to=net, svc="bmc", sn=sp.nat(0), msg=self.encode_bmc_service( - sp.record(serviceType=service_type, payload=final_rlp_bytes_with_prefix))) + sp.record(serviceType=service_type, payload=rlp_bytes.value))) sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) @@ -584,26 +589,45 @@ def test(): alice = sp.test_account("Alice") owner = sp.test_account("Owner") helper = sp.test_account("Helper") - bmc_periphery = sp.test_account("BMC Periphery") + # bmc_periphery = sp.test_account("BMC Periphery") # bmc= sp.test_account("BMC") + scenario = sp.test_scenario() + # deploy helper + # helper_con = helper_file.Helper() + # scenario += helper_con + # + # parse_addr_con = parse_address_file.ParseAddress() + # scenario += parse_addr_con + # bmc_man = BMCManagement(owner.address, helper.address) scenario += bmc_man - - bmc_man.set_bmc_periphery(bmc_periphery.address).run(sender=owner) - bmc_man.add_owner(alice.address).run(sender=owner) - - # bmc_man.remove_owner(alice.address).run(sender=alice) - - # bmc_man.add_link("btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW").run(sender=alice) - # bmc_man.remove_link("btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW").run(sender=alice) - # bmc_man.add_link("btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW").run(sender=alice) - - # bmc_man.set_link_rx_height(sp.record(link="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", height=sp.nat(2))).run(sender=alice) - # bmc_man.set_link(sp.record(_link="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", block_interval=sp.nat(2), - # _max_aggregation=sp.nat(3), delay_limit=sp.nat(2))).run(sender=alice) - - -sp.add_compilation_target("bmc_management", BMCManagement(owner_address=sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), - helper_contract=sp.address("KT1XfcddzN4hTUVxADLuaawPsiPoZThHrRf6"))) + # # deploy bmc periphery + # bmc_per = bmc_periphery_file.BMCPreiphery( + # bmc_man.address, helper_con.address, parse_addr_con.address + # ) + # + # scenario += bmc_per + # + # bmc_man.set_bmc_periphery(bmc_per.address).run(sender=owner) + # bmc_man.set_bmc_btp_address("tezos.77").run(sender=owner) + # # bmc_man.add_owner(alice.address).run(sender=owner) + # + # # bmc_man.remove_owner(alice.address).run(sender=alice) + # + # bmc_man.add_route(sp.record(dst = "btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hDEST", + # link = "btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW")).run(sender= owner) + # bmc_man.add_link("btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW").run(sender=owner) + # # decode_string = sp.build_lambda(Utils.RLP.Decoder.without_length_prefix) + # + # # bmc_man.remove_link("btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW").run(sender=alice) + # # bmc_man.add_link("btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW").run(sender=alice) + # + # # bmc_man.set_link_rx_height(sp.record(link="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", height=sp.nat(2))).run(sender=alice) + # # bmc_man.set_link(sp.record(_link="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", block_interval=sp.nat(2), + # # _max_aggregation=sp.nat(3), delay_limit=sp.nat(2))).run(sender=alice) + # + # +sp.add_compilation_target("bmc_management", BMCManagement(owner_address=sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP"), + helper_contract=sp.address("KT1Q5erZm7Pp8UJywK1nkiP8QPCRmyUotUMq"))) diff --git a/smartpy/bmc/contracts/src/bmc_periphery.py b/smartpy/bmc/contracts/src/bmc_periphery.py index 632c8643..04612510 100644 --- a/smartpy/bmc/contracts/src/bmc_periphery.py +++ b/smartpy/bmc/contracts/src/bmc_periphery.py @@ -323,6 +323,6 @@ def test(): # bmc.handle_relay_message(sp.record(prev="demo string", msg=sp.bytes("0x0dae11"))).run(sender=alice) -sp.add_compilation_target("bmc_periphery", BMCPreiphery(bmc_management_addr=sp.address("KT1PLJubwGPERx8fsWLGymJHkVuEgp7F2aV8"), - helper_contract=sp.address("KT1XfcddzN4hTUVxADLuaawPsiPoZThHrRf6"), +sp.add_compilation_target("bmc_periphery", BMCPreiphery(bmc_management_addr=sp.address("KT1Uiycjx4iXdjKFfR2kAo2NUdEtQ6PmDX4Y"), + helper_contract=sp.address("KT1Q5erZm7Pp8UJywK1nkiP8QPCRmyUotUMq"), parse_address=sp.address("KT1XgRyjQPfpfwNrvYYpgERpYpCrGh24aoPX"))) diff --git a/smartpy/bmc/contracts/src/helper.py b/smartpy/bmc/contracts/src/helper.py index 0f7babb1..66852ee6 100644 --- a/smartpy/bmc/contracts/src/helper.py +++ b/smartpy/bmc/contracts/src/helper.py @@ -25,6 +25,18 @@ def of_string(self, params): encode_string_packed = sp.build_lambda(Utils.Bytes.of_string) sp.result(encode_string_packed(params)) + @sp.onchain_view() + def encode_string(self, params): + sp.set_type(params, sp.TString) + encode_string_packed = sp.build_lambda(Utils.RLP.Encoder.encode_string) + sp.result(encode_string_packed(params)) + + @sp.onchain_view() + def encode_nat(self, params): + sp.set_type(params, sp.TNat) + encode_nat_packed = sp.build_lambda(Utils.RLP.Encoder.encode_nat) + sp.result(encode_nat_packed(params)) + @sp.onchain_view() def of_nat(self, params): sp.set_type(params, sp.TNat) @@ -37,6 +49,12 @@ def with_length_prefix(self, params): encode_length_packed = sp.build_lambda(Utils.RLP.Encoder.with_length_prefix) sp.result(encode_length_packed(params)) + @sp.onchain_view() + def encode_list(self, params): + sp.set_type(params, sp.TList(sp.TBytes)) + encode_list_packed = sp.build_lambda(Utils.RLP.Encoder.encode_list) + sp.result(encode_list_packed(params)) + @sp.add_test(name="Helper") def test(): From 93ecb9ce341a6121e6baacc77298bfdc2a5fcc6b Mon Sep 17 00:00:00 2001 From: icondev22 Date: Mon, 15 May 2023 18:23:29 +0545 Subject: [PATCH 060/211] fix: added new fields in BlockNotification struct --- cmd/iconbridge/chain/tezos/types/types.go | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/cmd/iconbridge/chain/tezos/types/types.go b/cmd/iconbridge/chain/tezos/types/types.go index 3dbc8ed0..7a61c570 100644 --- a/cmd/iconbridge/chain/tezos/types/types.go +++ b/cmd/iconbridge/chain/tezos/types/types.go @@ -3,15 +3,18 @@ package types import ( "math/big" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" + "github.com/icon-project/icon-bridge/cmd/iconbridge/chain" "blockwatch.cc/tzgo/rpc" - + "blockwatch.cc/tzgo/tezos" ) + type BlockNotification struct { - Hash common.Hash - Height *big.Int - Header *types.Header - Receipts []rpc.Receipt - HasBTPMessage *bool -} \ No newline at end of file + Hash common.Hash + Height *big.Int + Header *rpc.BlockHeader + Receipts []*chain.Receipt + HasBTPMessage *bool + Proposer tezos.Address +} + From 2c87c61c797ffb2e16710bbc1d87ba923e29454a Mon Sep 17 00:00:00 2001 From: suyogadhikari Date: Mon, 15 May 2023 18:23:50 +0545 Subject: [PATCH 061/211] fix(bts): rlp encoding fixed and encode_service_message parameter type modified --- .../bts/contracts/src/RLP_encode_struct.py | 27 ++++++++++--------- smartpy/bts/contracts/src/bts_periphery.py | 8 +++--- smartpy/bts/contracts/src/helper.py | 20 +++++++++++++- 3 files changed, 37 insertions(+), 18 deletions(-) diff --git a/smartpy/bts/contracts/src/RLP_encode_struct.py b/smartpy/bts/contracts/src/RLP_encode_struct.py index 0f5517d5..dc0058b5 100644 --- a/smartpy/bts/contracts/src/RLP_encode_struct.py +++ b/smartpy/bts/contracts/src/RLP_encode_struct.py @@ -5,27 +5,28 @@ class EncodeLibrary: def encode_service_message(self, params): - sp.set_type(params, types.Types.ServiceMessage) + sp.set_type(params, sp.TRecord(service_type_value = sp.TNat, data = sp.TBytes)) + + encode_service_type = sp.view("encode_nat", self.data.helper, params.service_type_value, t=sp.TBytes).open_some() + rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [encode_service_type, params.data], t=sp.TBytes).open_some() - encode_service_type = sp.view("of_string", self.data.helper, params.serviceType, t=sp.TBytes).open_some() - rlp = params.data + encode_service_type - rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() return rlp_bytes_with_prefix def encode_transfer_coin_msg(self, data): sp.set_type(data, types.Types.TransferCoin) - rlp = sp.local("rlp", sp.bytes("0x80")) - temp = sp.local("temp", sp.bytes("0x80")) + rlp = sp.local("rlp", sp.bytes("0x")) + temp = sp.local("temp", sp.bytes("0x")) + coin_name = sp.local("coin_name", sp.bytes("0x")) sp.for i in sp.range(0, sp.len(data.assets)): - temp.value = sp.view("of_string", self.data.helper, data.assets.get(i, default_value=sp.record(coin_name="",value=sp.nat(0))).coin_name, t=sp.TBytes).open_some()\ - + sp.view("of_nat", self.data.helper, data.assets.get(i, default_value=sp.record(coin_name="",value=sp.nat(0))).value, t=sp.TBytes).open_some() - rlp.value = rlp.value + sp.view("with_length_prefix", self.data.helper, temp.value, t=sp.TBytes).open_some() + coin_name.value = sp.view("encode_string", self.data.helper, data.assets.get(i, default_value=sp.record(coin_name="",value=sp.nat(0))).coin_name, t=sp.TBytes).open_some() + temp.value = sp.view("encode_nat", self.data.helper, data.assets.get(i, default_value=sp.record(coin_name="",value=sp.nat(0))).value, t=sp.TBytes).open_some() + rlp.value = sp.view("encode_list", self.data.helper, [rlp.value, coin_name.value, temp.value], t=sp.TBytes).open_some() - rlp.value = sp.view("of_string", self.data.helper, data.from_addr, t=sp.TBytes).open_some() + \ - sp.view("of_string", self.data.helper, data.to, t=sp.TBytes).open_some() + \ - sp.view("with_length_prefix", self.data.helper, rlp.value, t=sp.TBytes).open_some() + from_addr_encoded = sp.view("encode_string", self.data.helper, data.from_addr, t=sp.TBytes).open_some() + to_addr_encoded = sp.view("encode_string", self.data.helper, data.to, t=sp.TBytes).open_some() + rlp.value = sp.view("encode_list", self.data.helper, [from_addr_encoded, to_addr_encoded, rlp.value], t=sp.TBytes).open_some() - return sp.view("with_length_prefix", self.data.helper, rlp.value, t=sp.TBytes).open_some() + return rlp.value diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index ef9849be..acfec03a 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -141,7 +141,7 @@ def send_service_message(self, _from, to, coin_names, values, fees): send_message_entry_point = sp.contract(send_message_args_type, self.data.bmc, "send_message").open_some() send_message_args = sp.record( to=to_network, svc=self.service_name, sn=self.data.serial_no, - msg=self.encode_service_message(sp.compute(sp.record(serviceType=(sp.variant("REQUEST_COIN_TRANSFER", 0)), + msg=self.encode_service_message(sp.compute(sp.record(service_type_value=sp.nat(0), data=self.encode_transfer_coin_msg(sp.compute(sp.record(from_addr=start_from, to=to_address, assets=assets))) ) ) @@ -437,7 +437,7 @@ def test(): # msg=sp.bytes("0x0507070a000000030dae110000") )).run(sender=admin) -sp.add_compilation_target("bts_periphery", BTPPreiphery(bmc_address=sp.address("KT1BhqGDND5JC8wSrPSR7hA8LtvhaesqCvAq"), - bts_core_address=sp.address("KT1Sf2Hrs8hTuhwwywExNTrBt2dND3YGDprR"), - helper_contract=sp.address("KT1XfcddzN4hTUVxADLuaawPsiPoZThHrRf6"), +sp.add_compilation_target("bts_periphery", BTPPreiphery(bmc_address=sp.address("KT1UrLqhQHDC3mJw9BUrqsiix7JRbxTsvWJu"), + bts_core_address=sp.address("KT1JAippuMfS6Bso8DGmigmTdkgEZUxQxYyX"), + helper_contract=sp.address("KT1Q5erZm7Pp8UJywK1nkiP8QPCRmyUotUMq"), parse_address=sp.address("KT1EKPrSLWjWViZQogFgbc1QmztkR5UGXEWa"))) \ No newline at end of file diff --git a/smartpy/bts/contracts/src/helper.py b/smartpy/bts/contracts/src/helper.py index 1795bf44..66852ee6 100644 --- a/smartpy/bts/contracts/src/helper.py +++ b/smartpy/bts/contracts/src/helper.py @@ -25,6 +25,18 @@ def of_string(self, params): encode_string_packed = sp.build_lambda(Utils.Bytes.of_string) sp.result(encode_string_packed(params)) + @sp.onchain_view() + def encode_string(self, params): + sp.set_type(params, sp.TString) + encode_string_packed = sp.build_lambda(Utils.RLP.Encoder.encode_string) + sp.result(encode_string_packed(params)) + + @sp.onchain_view() + def encode_nat(self, params): + sp.set_type(params, sp.TNat) + encode_nat_packed = sp.build_lambda(Utils.RLP.Encoder.encode_nat) + sp.result(encode_nat_packed(params)) + @sp.onchain_view() def of_nat(self, params): sp.set_type(params, sp.TNat) @@ -37,6 +49,12 @@ def with_length_prefix(self, params): encode_length_packed = sp.build_lambda(Utils.RLP.Encoder.with_length_prefix) sp.result(encode_length_packed(params)) + @sp.onchain_view() + def encode_list(self, params): + sp.set_type(params, sp.TList(sp.TBytes)) + encode_list_packed = sp.build_lambda(Utils.RLP.Encoder.encode_list) + sp.result(encode_list_packed(params)) + @sp.add_test(name="Helper") def test(): @@ -45,4 +63,4 @@ def test(): scenario += helper -sp.add_compilation_target("helper", Helper()) +sp.add_compilation_target("helper", Helper()) \ No newline at end of file From 6a9b5f07a2cb671a0b1e5080039c41be5a6a77ea Mon Sep 17 00:00:00 2001 From: icondev22 Date: Mon, 15 May 2023 18:25:01 +0545 Subject: [PATCH 062/211] feat: added height() method in Verifier --- cmd/iconbridge/chain/tezos/verifier.go | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/cmd/iconbridge/chain/tezos/verifier.go b/cmd/iconbridge/chain/tezos/verifier.go index ee844127..791c3303 100644 --- a/cmd/iconbridge/chain/tezos/verifier.go +++ b/cmd/iconbridge/chain/tezos/verifier.go @@ -17,7 +17,8 @@ type IVerifier interface { Verify(ctx context.Context, header *rpc.BlockHeader, proposer tezos.Address, c *rpc.Client, hash tezos.BlockHash) error Update(header *rpc.BlockHeader) error ParentHash() tezos.BlockHash - IsValidator(proposer tezos.Address, height int64) bool + IsValidator(proposer tezos.Address, height int64) bool + Height() int64 } type Verifier struct{ @@ -27,6 +28,7 @@ type Verifier struct{ next int64 parentHash tezos.BlockHash parentFittness int64 + height int64 } func (vr *Verifier) Next() int64{ @@ -48,9 +50,9 @@ func (vr *Verifier) Verify(ctx context.Context, header *rpc.BlockHeader, propose } if currentFittness < vr.parentFittness { - return fmt.Errorf("Invalid block fittness") + return fmt.Errorf("Invalid block fittness", currentFittness) } - fmt.Println("validated the block fittness") + fmt.Println("validated the block fittness", header.Level) previousHashInBlock := header.Predecessor fmt.Println(previousHashInBlock) @@ -58,11 +60,9 @@ func (vr *Verifier) Verify(ctx context.Context, header *rpc.BlockHeader, propose fmt.Println(vr.parentHash) if previousHashInBlock.String() != vr.parentHash.String() { - return fmt.Errorf("Invalid block hash") + return fmt.Errorf("Invalid block hash", header.Level) } - fmt.Println("here????") - fmt.Println("Block is verified") fmt.Println("******* *******") @@ -93,6 +93,8 @@ func (vr *Verifier) Update(header *rpc.BlockHeader) error { vr.parentFittness = currentFittness vr.parentHash = header.Hash + vr.height = header.Level + vr.next = header.Level + 1 fmt.Println(header.Hash) fmt.Println("updated") return nil @@ -104,6 +106,12 @@ func (vr *Verifier) ParentHash() tezos.BlockHash { return vr.parentHash } +func (vr *Verifier) Height() int64 { + vr.mu.RLock() + defer vr.mu.RUnlock() + return vr.height +} + func (vr *Verifier) IsValidator(proposer tezos.Address, height int64) bool { vr.mu.RLock() defer vr.mu.RUnlock() From fbeafed8052690a59ff6b9f7bbd366b466aa86e2 Mon Sep 17 00:00:00 2001 From: suyogadhikari Date: Tue, 16 May 2023 09:08:22 +0545 Subject: [PATCH 063/211] fix(bts): rlp decoding fixed --- smartpy/bmc/contracts/src/helper.py | 6 ++++++ smartpy/bts/contracts/src/RLP_decode_struct.py | 1 + 2 files changed, 7 insertions(+) diff --git a/smartpy/bmc/contracts/src/helper.py b/smartpy/bmc/contracts/src/helper.py index 66852ee6..25319455 100644 --- a/smartpy/bmc/contracts/src/helper.py +++ b/smartpy/bmc/contracts/src/helper.py @@ -49,6 +49,12 @@ def with_length_prefix(self, params): encode_length_packed = sp.build_lambda(Utils.RLP.Encoder.with_length_prefix) sp.result(encode_length_packed(params)) + @sp.onchain_view() + def without_length_prefix(self, params): + sp.set_type(params, sp.TBytes) + decode = sp.build_lambda(Utils.RLP.Decoder.without_length_prefix) + sp.result(decode(params)) + @sp.onchain_view() def encode_list(self, params): sp.set_type(params, sp.TList(sp.TBytes)) diff --git a/smartpy/bts/contracts/src/RLP_decode_struct.py b/smartpy/bts/contracts/src/RLP_decode_struct.py index 2282afe6..e06441ea 100644 --- a/smartpy/bts/contracts/src/RLP_decode_struct.py +++ b/smartpy/bts/contracts/src/RLP_decode_struct.py @@ -44,6 +44,7 @@ def decode_service_message(self, rlp): _service_type.value = sp.variant("CHANGE_TOKEN_LIMIT", temp_int.value) sp.if temp_int.value == 5: _service_type.value = sp.variant("UNKNOWN_TYPE", temp_int.value) + temp_byt.value = sp.view("without_length_prefix", self.data.helper, temp_byt.value, t=sp.TString).open_some() return sp.record(serviceType=_service_type.value, data=temp_byt.value) From 7c1f3b64fca24f9c258194f5a1e7313a42546956 Mon Sep 17 00:00:00 2001 From: suyogadhikari Date: Tue, 16 May 2023 09:08:30 +0545 Subject: [PATCH 064/211] fix(bmc): rlp decoding fixed --- smartpy/bmc/contracts/src/RLP_decode_struct.py | 5 +++-- smartpy/bts/contracts/src/helper.py | 6 ++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/smartpy/bmc/contracts/src/RLP_decode_struct.py b/smartpy/bmc/contracts/src/RLP_decode_struct.py index 93a105a4..1045599a 100644 --- a/smartpy/bmc/contracts/src/RLP_decode_struct.py +++ b/smartpy/bmc/contracts/src/RLP_decode_struct.py @@ -23,7 +23,7 @@ def decode_bmc_message(self, rlp): sp.if counter.value == 4: temp_byt.value = k.value counter.value = counter.value + 1 - + temp_byt.value = sp.view("without_length_prefix", self.data.helper, temp_byt.value, t=sp.TString).open_some() return sp.record(src=temp_map_string.get("src"), dst=temp_map_string.get("dst"), svc=temp_map_string.get("svc"), @@ -87,7 +87,7 @@ def decode_bmc_service(self, rlp): sp.if counter.value == 1: temp_byt.value = b.value counter.value = counter.value + 1 - + temp_byt.value = sp.view("without_length_prefix", self.data.helper, temp_byt.value, t=sp.TString).open_some() return sp.record(serviceType=temp_string.value, payload=temp_byt.value) @@ -129,6 +129,7 @@ def to_message_event(self, rlp): sp.if counter.value == 1: rv2.value = Utils2.Int.of_bytes(i.value) counter.value = counter.value + 1 + rv3.value = sp.view("without_length_prefix", self.data.helper, rv3.value, t=sp.TString).open_some() return sp.record(next_bmc= rv1.value, seq= rv2.value, message = rv3.value) def decode_receipt_proof(self, rlp): diff --git a/smartpy/bts/contracts/src/helper.py b/smartpy/bts/contracts/src/helper.py index 66852ee6..25319455 100644 --- a/smartpy/bts/contracts/src/helper.py +++ b/smartpy/bts/contracts/src/helper.py @@ -49,6 +49,12 @@ def with_length_prefix(self, params): encode_length_packed = sp.build_lambda(Utils.RLP.Encoder.with_length_prefix) sp.result(encode_length_packed(params)) + @sp.onchain_view() + def without_length_prefix(self, params): + sp.set_type(params, sp.TBytes) + decode = sp.build_lambda(Utils.RLP.Decoder.without_length_prefix) + sp.result(decode(params)) + @sp.onchain_view() def encode_list(self, params): sp.set_type(params, sp.TList(sp.TBytes)) From d0a0c9847602926b4f83ca17bdeeb36b030d12ce Mon Sep 17 00:00:00 2001 From: suyogadhikari Date: Tue, 16 May 2023 11:01:39 +0545 Subject: [PATCH 065/211] fix(bmc,bts): return type fixed for without length prefix --- smartpy/bmc/contracts/src/RLP_decode_struct.py | 6 +++--- smartpy/bts/contracts/src/RLP_decode_struct.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/smartpy/bmc/contracts/src/RLP_decode_struct.py b/smartpy/bmc/contracts/src/RLP_decode_struct.py index 1045599a..9d27ad48 100644 --- a/smartpy/bmc/contracts/src/RLP_decode_struct.py +++ b/smartpy/bmc/contracts/src/RLP_decode_struct.py @@ -23,7 +23,7 @@ def decode_bmc_message(self, rlp): sp.if counter.value == 4: temp_byt.value = k.value counter.value = counter.value + 1 - temp_byt.value = sp.view("without_length_prefix", self.data.helper, temp_byt.value, t=sp.TString).open_some() + temp_byt.value = sp.view("without_length_prefix", self.data.helper, temp_byt.value, t=sp.TBytes).open_some() return sp.record(src=temp_map_string.get("src"), dst=temp_map_string.get("dst"), svc=temp_map_string.get("svc"), @@ -87,7 +87,7 @@ def decode_bmc_service(self, rlp): sp.if counter.value == 1: temp_byt.value = b.value counter.value = counter.value + 1 - temp_byt.value = sp.view("without_length_prefix", self.data.helper, temp_byt.value, t=sp.TString).open_some() + temp_byt.value = sp.view("without_length_prefix", self.data.helper, temp_byt.value, t=sp.TBytes).open_some() return sp.record(serviceType=temp_string.value, payload=temp_byt.value) @@ -129,7 +129,7 @@ def to_message_event(self, rlp): sp.if counter.value == 1: rv2.value = Utils2.Int.of_bytes(i.value) counter.value = counter.value + 1 - rv3.value = sp.view("without_length_prefix", self.data.helper, rv3.value, t=sp.TString).open_some() + rv3.value = sp.view("without_length_prefix", self.data.helper, rv3.value, t=sp.TBytes).open_some() return sp.record(next_bmc= rv1.value, seq= rv2.value, message = rv3.value) def decode_receipt_proof(self, rlp): diff --git a/smartpy/bts/contracts/src/RLP_decode_struct.py b/smartpy/bts/contracts/src/RLP_decode_struct.py index e06441ea..fc92da93 100644 --- a/smartpy/bts/contracts/src/RLP_decode_struct.py +++ b/smartpy/bts/contracts/src/RLP_decode_struct.py @@ -44,7 +44,7 @@ def decode_service_message(self, rlp): _service_type.value = sp.variant("CHANGE_TOKEN_LIMIT", temp_int.value) sp.if temp_int.value == 5: _service_type.value = sp.variant("UNKNOWN_TYPE", temp_int.value) - temp_byt.value = sp.view("without_length_prefix", self.data.helper, temp_byt.value, t=sp.TString).open_some() + temp_byt.value = sp.view("without_length_prefix", self.data.helper, temp_byt.value, t=sp.TBytes).open_some() return sp.record(serviceType=_service_type.value, data=temp_byt.value) From a6734517c7d39a51b739de3f304dc2bf607115c0 Mon Sep 17 00:00:00 2001 From: simusud Date: Tue, 16 May 2023 23:21:52 +0545 Subject: [PATCH 066/211] fix(bmc): modified type of sn from nat to string --- smartpy/bmc/contracts/src/RLP_decode_struct.py | 2 +- smartpy/bmc/contracts/src/RLP_encode_struct.py | 2 +- smartpy/bmc/contracts/src/Types.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/smartpy/bmc/contracts/src/RLP_decode_struct.py b/smartpy/bmc/contracts/src/RLP_decode_struct.py index 9d27ad48..e5f516a2 100644 --- a/smartpy/bmc/contracts/src/RLP_decode_struct.py +++ b/smartpy/bmc/contracts/src/RLP_decode_struct.py @@ -27,7 +27,7 @@ def decode_bmc_message(self, rlp): return sp.record(src=temp_map_string.get("src"), dst=temp_map_string.get("dst"), svc=temp_map_string.get("svc"), - sn=temp_int.value, + sn=sp.to_int(temp_int.value), message=temp_byt.value) diff --git a/smartpy/bmc/contracts/src/RLP_encode_struct.py b/smartpy/bmc/contracts/src/RLP_encode_struct.py index 09329f38..057b5fc7 100644 --- a/smartpy/bmc/contracts/src/RLP_encode_struct.py +++ b/smartpy/bmc/contracts/src/RLP_encode_struct.py @@ -13,7 +13,7 @@ def encode_bmc_service(self, params): return rlp_bytes_with_prefix def encode_bmc_message(self, params): - sp.set_type(params, sp.TRecord(src=sp.TString, dst=sp.TString, svc=sp.TString, sn=sp.TNat, message=sp.TBytes)) + sp.set_type(params, sp.TRecord(src=sp.TString, dst=sp.TString, svc=sp.TString, sn=sp.TInt, message=sp.TBytes)) encode_src = sp.view("encode_string", self.data.helper, params.src, t=sp.TBytes).open_some() encode_dst = sp.view("encode_string", self.data.helper, params.dst, t=sp.TBytes).open_some() diff --git a/smartpy/bmc/contracts/src/Types.py b/smartpy/bmc/contracts/src/Types.py index 4c25a288..49d85127 100644 --- a/smartpy/bmc/contracts/src/Types.py +++ b/smartpy/bmc/contracts/src/Types.py @@ -19,7 +19,7 @@ class Types: src=sp.TString, dst=sp.TString, svc=sp.TString, - sn=sp.TNat, + sn=sp.TInt, message=sp.TBytes ) From d915d1238b3a432f0196e78a2c6427e42defd8b3 Mon Sep 17 00:00:00 2001 From: simusud Date: Tue, 16 May 2023 23:23:13 +0545 Subject: [PATCH 067/211] feat(bmc): modified type of sn from nat to int and implemented callback on bmc --- smartpy/bmc/contracts/src/bmc_management.py | 11 +- smartpy/bmc/contracts/src/bmc_periphery.py | 225 ++++++++++++-------- smartpy/bts/contracts/src/bts_periphery.py | 45 ++-- 3 files changed, 171 insertions(+), 110 deletions(-) diff --git a/smartpy/bmc/contracts/src/bmc_management.py b/smartpy/bmc/contracts/src/bmc_management.py index 1572103b..5e93b57a 100644 --- a/smartpy/bmc/contracts/src/bmc_management.py +++ b/smartpy/bmc/contracts/src/bmc_management.py @@ -315,11 +315,11 @@ def _propagate_internal(self, service_type, link): net, addr = sp.match_pair(strings.split_btp_address(item, "prev_idx1", "result1", "my_list1", "last1", "penultimate1")) # call send_message on BMCPeriphery - send_message_args_type = sp.TRecord(to=sp.TString, svc=sp.TString, sn=sp.TNat, msg=sp.TBytes) + send_message_args_type = sp.TRecord(to=sp.TString, svc=sp.TString, sn=sp.TInt, msg=sp.TBytes) send_message_entry_point = sp.contract(send_message_args_type, self.data.bmc_periphery.open_some("Address not set"), "send_message").open_some() - send_message_args = sp.record(to=net, svc="bmc", sn=sp.nat(0), msg=self.encode_bmc_service( + send_message_args = sp.record(to=net, svc="bmc", sn=sp.int(0), msg=self.encode_bmc_service( sp.record(serviceType=service_type, payload=final_rlp_bytes_with_prefix))) sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) @@ -342,11 +342,11 @@ def _send_internal(self, target, service_type, links): strings.split_btp_address(target, "prev_idx2", "result2", "my_list2", "last2", "penultimate2")) # call send_message on BMCPeriphery - send_message_args_type = sp.TRecord(to=sp.TString, svc=sp.TString, sn=sp.TNat, msg=sp.TBytes) + send_message_args_type = sp.TRecord(to=sp.TString, svc=sp.TString, sn=sp.TInt, msg=sp.TBytes) send_message_entry_point = sp.contract(send_message_args_type, self.data.bmc_periphery.open_some("Address not set"), "send_message").open_some() - send_message_args = sp.record(to=net, svc="bmc", sn=sp.nat(0), msg=self.encode_bmc_service( + send_message_args = sp.record(to=net, svc="bmc", sn=sp.int(0), msg=self.encode_bmc_service( sp.record(serviceType=service_type, payload=rlp_bytes.value))) sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) @@ -461,7 +461,7 @@ def get_relays(self, link): @sp.onchain_view() def get_bsh_service_by_name(self, service_name): sp.set_type(service_name, sp.TString) - sp.result(self.data.bsh_services.get(service_name)) + sp.result(self.data.bsh_services.get(service_name, default_value=sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg"))) @sp.onchain_view() def get_link(self, to): @@ -568,7 +568,6 @@ def update_relay_stats(self, relay, block_count_val, msg_count_val): def resolve_route(self, dst_net): sp.set_type(dst_net, sp.TString) - # self.only_bmc_periphery() dst = sp.local("dst", self.data.get_route_dst_from_net.get(dst_net), t=sp.TString) with sp.if_(sp.len(sp.pack(dst.value))!= sp.nat(0)): diff --git a/smartpy/bmc/contracts/src/bmc_periphery.py b/smartpy/bmc/contracts/src/bmc_periphery.py index 04612510..644f841d 100644 --- a/smartpy/bmc/contracts/src/bmc_periphery.py +++ b/smartpy/bmc/contracts/src/bmc_periphery.py @@ -26,7 +26,9 @@ def __init__(self, bmc_management_addr, helper_contract, parse_address): helper=helper_contract, bmc_btp_address=sp.none, bmc_management=bmc_management_addr, - parse_contract=parse_address + parse_contract=parse_address, + handle_btp_message_status=sp.none, + handle_btp_error_status=sp.none ) @sp.entry_point @@ -53,6 +55,40 @@ def _require_registered_relay(self, prev): valid.value = True sp.verify(valid.value, self.BMCRevertUnauthorized) + @sp.entry_point + def callback(self, string, bsh_addr, prev, callback_msg): + sp.set_type(string, sp.TOption(sp.TString)) + sp.set_type(bsh_addr, sp.TAddress) + sp.set_type(prev, sp.TString) + sp.set_type(callback_msg, types.Types.BMCMessage) + + sp.verify(sp.sender == bsh_addr, "Unauthorized") + self.data.handle_btp_message_status = string + + with sp.if_(self.data.handle_btp_message_status.open_some() == "success"): + pass + with sp.else_(): + self._send_error(prev, callback_msg, self.BSH_ERR, self.BMCRevertUnknownHandleBTPMessage) + + @sp.entry_point + def callback_btp_error(self, string, bsh_addr, svc, sn, code, msg): + sp.set_type(string, sp.TOption(sp.TString)) + sp.set_type(bsh_addr, sp.TAddress) + sp.set_type(svc, sp.TString) + sp.set_type(sn, sp.TInt) + sp.set_type(code, sp.TNat) + sp.set_type(msg, sp.TString) + + sp.verify(sp.sender == bsh_addr, "Unauthorized") + self.data.handle_btp_error_status = string + + with sp.if_(self.data.handle_btp_error_status.open_some() == "success"): + pass + with sp.else_(): + error_code = self.UNKNOWN_ERR + err_msg = self.BMCRevertUnknownHandleBTPError + sp.emit(sp.record(svc=svc, sn=sn * -1, code=code, msg=msg, err_code=error_code, err_msg=err_msg), tag="ErrorOnBTPError") + @sp.entry_point def handle_relay_message(self, prev, msg): sp.set_type(prev, sp.TString) @@ -67,7 +103,7 @@ def handle_relay_message(self, prev, msg): rx_height = sp.local("rx_height", link_rx_height, t=sp.TNat) rps = self.decode_receipt_proofs(msg) - bmc_msg = sp.local("bmc_msg", sp.record(src="", dst="", svc="", sn=sp.nat(0), message=sp.bytes("0x")), t=types.Types.BMCMessage) + bmc_msg = sp.local("bmc_msg", sp.record(src="", dst="", svc="", sn=sp.int(0), message=sp.bytes("0x")), t=types.Types.BMCMessage) ev = sp.local("ev", sp.record(next_bmc="", seq=sp.nat(0), message=sp.bytes("0x")), t=types.Types.MessageEvent) sp.for i in sp.range(sp.nat(0), sp.len(rps)): @@ -87,18 +123,18 @@ def handle_relay_message(self, prev, msg): sp.if ev.value.seq > rx_seq.value: sp.failwith(self.BMCRevertInvalidSeqNumber) - # TODO: implement code inside of try catch + _decoded = self.decode_bmc_message(ev.value.message) bmc_msg.value = _decoded - sp.if bmc_msg.value.dst == self.data.bmc_btp_address.open_some("Address not set"): - self._handle_message(prev, bmc_msg.value) - # continue - - net, addr = sp.match_pair(strings.split_btp_address(bmc_msg.value.dst, "prev_idx", "result", "my_list", "last", "penultimate")) - # resolve route inside try catch - next_link, prev_link = sp.match_pair(sp.view("resolve_route", self.data.bmc_management, net, t=sp.TPair(sp.TString, sp.TString)).open_some("Invalid Call")) - self._send_message(next_link, ev.value.message) + sp.if bmc_msg.value.src != "": + with sp.if_(bmc_msg.value.dst == self.data.bmc_btp_address.open_some("Address not set")): + self._handle_message(prev, bmc_msg.value) + with sp.else_(): + net, addr = sp.match_pair(strings.split_btp_address(bmc_msg.value.dst, "prev_idx", "result", "my_list", "last", "penultimate")) + # resolve route inside try catch + next_link, prev_link = sp.match_pair(sp.view("resolve_route", self.data.bmc_management, net, t=sp.TPair(sp.TString, sp.TString)).open_some("Invalid Call")) + self._send_message(next_link, ev.value.message) # call update_link_rx_seq on BMCManagement update_link_rx_seq_args_type = sp.TRecord(prev=sp.TString, val=sp.TNat) @@ -131,74 +167,80 @@ def _handle_message(self, prev, msg): # bsh_addr = sp.local("bsh_addr",sp.TAddress) with sp.if_(msg.svc == "bmc"): - # TODO: implement try catch - sm = self.decode_bmc_service(msg.message) - sp.if sm.serviceType == "FeeGathering": - # decode inside try - gather_fee = self.decode_gather_fee_message(sm.payload) - - sp.for c in sp.range(sp.nat(0), sp.len(gather_fee.svcs)): - bsh_addr = sp.view("get_bsh_service_by_name", self.data.bmc_management, gather_fee.svcs[c], t=sp.TAddress).open_some("Invalid Call") - - sp.if bsh_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg"): - # put it inside try - # call handle_fee_gathering of bts periphery - handle_fee_gathering_args_type = sp.TRecord(fa=sp.TString, svc=sp.TString) - handle_fee_gathering_entry_point = sp.contract(handle_fee_gathering_args_type, - bsh_addr, - "handle_fee_gathering").open_some() - handle_fee_gathering_args = sp.record(fa=gather_fee.fa, svc=gather_fee.svcs[c]) - sp.transfer(handle_fee_gathering_args, sp.tez(0), handle_fee_gathering_entry_point) - - sp.if sm.serviceType == "Link": - to = self.decode_propagate_message(sm.payload) - link = sp.view("get_link", self.data.bmc_management, prev, t=types.Types.Link).open_some() - - check = sp.local("check", False) - sp.if link.is_connected: - sp.for e in link.reachable.elements(): - sp.if to == e: - check.value = True - # sp.break - - sp.if check.value == False: - links = sp.list([to], t=sp.TString) - - # call update_link_reachable on BMCManagement - update_link_reachable_args_type = sp.TRecord(prev=sp.TString, to=sp.TList(sp.TString)) - update_link_reachable_entry_point = sp.contract(update_link_reachable_args_type, - self.data.bmc_management, - "update_link_reachable").open_some() - update_link_reachable_args = sp.record(prev=prev, to=links) - sp.transfer(update_link_reachable_args, sp.tez(0), update_link_reachable_entry_point) - - sp.if sm.serviceType == "Unlink": - to = self.decode_propagate_message(sm.payload) - link = sp.view("get_link", self.data.bmc_management, prev, t=types.Types.Link).open_some() - - sp.if link.is_connected: - f = sp.local("f", sp.nat(0)) - sp.for itm in link.reachable.elements(): - sp.if to == itm: - - # call delete_link_reachable on BMCManagement - delete_link_reachable_args_type = sp.TRecord(prev=sp.TString, index=sp.TNat) - delete_link_reachable_entry_point = sp.contract(delete_link_reachable_args_type, + sm = sp.local("sm", sp.record(serviceType="", payload=sp.bytes("0x"))) + sm.value = self.decode_bmc_service(msg.message) + with sp.if_(sm.value.serviceType == ""): + self._send_error(prev, msg, self.BMC_ERR, self.BMCRevertParseFailure) + with sp.else_(): + sp.if sm.value.serviceType == "FeeGathering": + gather_fee =sp.local("gather_fee", sp.record(fa="", svcs=sp.map({0:""}))) + gather_fee.value = self.decode_gather_fee_message(sm.value.payload) + + with sp.if_(gather_fee.value.fa == ""): + self._send_error(prev, msg, self.BMC_ERR, self.BMCRevertParseFailure) + + with sp.else_(): + sp.for c in sp.range(sp.nat(0), sp.len(gather_fee.value.svcs)): + bsh_addr = sp.view("get_bsh_service_by_name", self.data.bmc_management, gather_fee.value.svcs[c], t=sp.TAddress).open_some("Invalid Call") + + sp.if bsh_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg"): + # call handle_fee_gathering of bts periphery + handle_fee_gathering_args_type = sp.TRecord(fa=sp.TString, svc=sp.TString) + handle_fee_gathering_entry_point = sp.contract(handle_fee_gathering_args_type, + bsh_addr, + "handle_fee_gathering").open_some() + handle_fee_gathering_args = sp.record(fa=gather_fee.value.fa, svc=gather_fee.value.svcs[c]) + sp.transfer(handle_fee_gathering_args, sp.tez(0), handle_fee_gathering_entry_point) + + sp.if sm.value.serviceType == "Link": + to = self.decode_propagate_message(sm.value.payload) + link = sp.view("get_link", self.data.bmc_management, prev, t=types.Types.Link).open_some() + + check = sp.local("check", False) + sp.if link.is_connected: + sp.for e in link.reachable.elements(): + sp.if to == e: + check.value = True + # sp.break + + sp.if check.value == False: + links = sp.list([to], t=sp.TString) + + # call update_link_reachable on BMCManagement + update_link_reachable_args_type = sp.TRecord(prev=sp.TString, to=sp.TList(sp.TString)) + update_link_reachable_entry_point = sp.contract(update_link_reachable_args_type, self.data.bmc_management, - "delete_link_reachable").open_some() - delete_link_reachable_args = sp.record(prev=prev, index=f.value) - sp.transfer(delete_link_reachable_args, sp.tez(0), delete_link_reachable_entry_point) - f.value += sp.nat(1) - - sp.if sm.serviceType == "Init": - links = self.decode_init_message(sm.payload) - # call update_link_reachable on BMCManagement - update_link_reachable_args_type = sp.TRecord(prev=sp.TString, to=sp.TList(sp.TString)) - update_link_reachable_entry_point = sp.contract(update_link_reachable_args_type, - self.data.bmc_management, - "update_link_reachable").open_some() - update_link_reachable_args = sp.record(prev=prev, to=links) - sp.transfer(update_link_reachable_args, sp.tez(0), update_link_reachable_entry_point) + "update_link_reachable").open_some() + update_link_reachable_args = sp.record(prev=prev, to=links) + sp.transfer(update_link_reachable_args, sp.tez(0), update_link_reachable_entry_point) + + sp.if sm.value.serviceType == "Unlink": + to = self.decode_propagate_message(sm.value.payload) + link = sp.view("get_link", self.data.bmc_management, prev, t=types.Types.Link).open_some() + + sp.if link.is_connected: + f = sp.local("f", sp.nat(0)) + sp.for itm in link.reachable.elements(): + sp.if to == itm: + + # call delete_link_reachable on BMCManagement + delete_link_reachable_args_type = sp.TRecord(prev=sp.TString, index=sp.TNat) + delete_link_reachable_entry_point = sp.contract(delete_link_reachable_args_type, + self.data.bmc_management, + "delete_link_reachable").open_some() + delete_link_reachable_args = sp.record(prev=prev, index=f.value) + sp.transfer(delete_link_reachable_args, sp.tez(0), delete_link_reachable_entry_point) + f.value += sp.nat(1) + + sp.if sm.value.serviceType == "Init": + links = self.decode_init_message(sm.value.payload) + # call update_link_reachable on BMCManagement + update_link_reachable_args_type = sp.TRecord(prev=sp.TString, to=sp.TList(sp.TString)) + update_link_reachable_entry_point = sp.contract(update_link_reachable_args_type, + self.data.bmc_management, + "update_link_reachable").open_some() + update_link_reachable_args = sp.record(prev=prev, to=links) + sp.transfer(update_link_reachable_args, sp.tez(0), update_link_reachable_entry_point) with sp.else_(): bsh_addr = sp.view("get_bsh_service_by_name", self.data.bmc_management, msg.svc, t=sp.TAddress).open_some("Invalid view") @@ -206,29 +248,30 @@ def _handle_message(self, prev, msg): self._send_error(prev, msg, self.BMC_ERR, self.BMCRevertNotExistsBSH) with sp.else_(): - with sp.if_(msg.sn >= sp.nat(0)): + with sp.if_(msg.sn >= sp.int(0)): net, addr = sp.match_pair(strings.split_btp_address(msg.src, "prev_idx", "result", "my_list", "last", "penultimate")) - # put it in try catch + # implemented callback # call handle_btp_message on bts periphery - handle_btp_message_args_type = sp.TRecord(_from=sp.TString, svc=sp.TString, sn=sp.TNat, msg=sp.TBytes) + handle_btp_message_args_type = sp.TRecord(callback=sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress, prev=sp.TString, callback_msg=types.Types.BMCMessage)), + bsh_addr=sp.TAddress, prev=sp.TString, callback_msg=types.Types.BMCMessage, _from=sp.TString, svc=sp.TString, sn=sp.TInt, msg=sp.TBytes) handle_btp_message_entry_point = sp.contract(handle_btp_message_args_type, bsh_addr, "handle_btp_message").open_some() - handle_btp_message_args = sp.record(_from=net, svc=msg.svc, sn=msg.sn, msg=msg.message) + handle_btp_message_args = sp.record(callback=sp.self_entry_point("callback"), bsh_addr=bsh_addr, prev=prev, callback_msg=msg, _from=net, svc=msg.svc, sn=msg.sn, msg=msg.message) sp.transfer(handle_btp_message_args, sp.tez(0), handle_btp_message_entry_point) with sp.else_(): res = self.decode_response(msg.message) - # put it in try catch - # here sn is sent negative in solidity (msg.sn *-1) + # implemented callback # call handle_btp_error on bts periphery - handle_btp_error_args_type = sp.TRecord(svc=sp.TString, sn=sp.TNat, code=sp.TNat, msg=sp.TString) + handle_btp_error_args_type = sp.TRecord(callback=sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress, svc=sp.TString, sn=sp.TInt, code=sp.TNat, msg=sp.TString)), + bsh_addr=sp.TAddress, svc=sp.TString, sn=sp.TInt, code=sp.TNat, msg=sp.TString) handle_btp_error_entry_point = sp.contract(handle_btp_error_args_type, bsh_addr, "handle_btp_error").open_some() - handle_btp_error_args = sp.record(svc=msg.svc, sn=msg.sn, code=res.code, msg=res.message) + handle_btp_error_args = sp.record(callback=sp.self_entry_point("callback_btp_error"), bsh_addr=bsh_addr, + svc=msg.svc, sn=msg.sn * -1, code=res.code, msg=res.message) sp.transfer(handle_btp_error_args, sp.tez(0), handle_btp_error_entry_point) - #TODO: emit in case of error def _send_message(self, to ,serialized_msg): sp.set_type(to, sp.TString) @@ -249,12 +292,12 @@ def _send_error(self, prev, message, err_code, err_msg): sp.set_type(err_code, sp.TNat) sp.set_type(err_msg, sp.TString) - sp.if message.sn > sp.nat(0): + sp.if message.sn > sp.int(0): serialized_msg = self.encode_bmc_message(sp.record( src=self.data.bmc_btp_address.open_some("Address not set"), dst=message.src, svc=message.svc, - sn=message.sn, + sn=message.sn * -1, message=self.encode_response(sp.record(code=err_code, message=err_msg)) )) self._send_message(prev, serialized_msg) @@ -271,13 +314,13 @@ def send_message(self, to, svc, sn, msg): """ sp.set_type(to, sp.TString) sp.set_type(svc, sp.TString) - sp.set_type(sn, sp.TNat) + sp.set_type(sn, sp.TInt) sp.set_type(msg, sp.TBytes) sp.verify((sp.sender == self.data.bmc_management) | (sp.view("get_bsh_service_by_name", self.data.bmc_management, svc, t=sp.TAddress).open_some() == sp.sender), self.BMCRevertUnauthorized) - sp.verify(sn >= sp.nat(0), self.BMCRevertInvalidSn) + sp.verify(sn >= sp.int(0), self.BMCRevertInvalidSn) next_link, dst = sp.match_pair(sp.view("resolve_route", self.data.bmc_management, to, t=sp.TPair(sp.TString, sp.TString)).open_some()) diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index acfec03a..ab9ef646 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -20,8 +20,8 @@ def __init__(self, bmc_address, bts_core_address, helper_contract, parse_address bts_core=bts_core_address, blacklist=sp.map(tkey=sp.TAddress, tvalue=sp.TBool), token_limit=sp.map(tkey=sp.TString, tvalue=sp.TNat), - requests=sp.big_map(tkey=sp.TNat, tvalue=types.Types.PendingTransferCoin), - serial_no = sp.nat(0), + requests=sp.big_map(tkey=sp.TInt, tvalue=types.Types.PendingTransferCoin), + serial_no = sp.int(0), number_of_pending_requests = sp.nat(0), helper=helper_contract, parse_contract=parse_address @@ -137,7 +137,7 @@ def send_service_message(self, _from, to, coin_names, values, fees): start_from = sp.view("add_to_str", self.data.parse_contract, _from, t=sp.TString).open_some() - send_message_args_type = sp.TRecord(to=sp.TString, svc=sp.TString, sn=sp.TNat, msg=sp.TBytes) + send_message_args_type = sp.TRecord(to=sp.TString, svc=sp.TString, sn=sp.TInt, msg=sp.TBytes) send_message_entry_point = sp.contract(send_message_args_type, self.data.bmc, "send_message").open_some() send_message_args = sp.record( to=to_network, svc=self.service_name, sn=self.data.serial_no, @@ -158,20 +158,28 @@ def send_service_message(self, _from, to, coin_names, values, fees): @sp.entry_point - def handle_btp_message(self, _from, svc, sn, msg): + def handle_btp_message(self, _from, svc, sn, msg, callback, bsh_addr, prev, callback_msg): """ BSH handle BTP message from BMC contract :param _from: An originated network address of a request :param svc: A service name of BSH contract :param sn: A serial number of a service request :param msg: An RLP message of a service request/service response + :param callback: callback function type in bmc_periphery + :param bsh_addr: param for callback function in bmc_periphery + :param prev: param for callback function in bmc_periphery + :param callback_msg: param for callback function in bmc_periphery :return: """ sp.set_type(_from, sp.TString) sp.set_type(svc, sp.TString) - sp.set_type(sn, sp.TNat) + sp.set_type(sn, sp.TInt) sp.set_type(msg, sp.TBytes) + sp.set_type(callback, sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress, prev=sp.TString, callback_msg=sp.TRecord( + src=sp.TString, dst=sp.TString, svc=sp.TString, sn=sp.TInt, message=sp.TBytes) + ))) + sp.set_type(bsh_addr, sp.TAddress) self.only_bmc() @@ -230,6 +238,10 @@ def handle_btp_message(self, _from, svc, sn, msg): with arg.match("UNKNOWN_TYPE") as a5: sp.emit(sp.record(_from=_from, sn=sn), tag= "UnknownResponse") + return_value = sp.record(string=sp.some("success"), bsh_addr=bsh_addr, prev=prev, + callback_msg=callback_msg) + sp.transfer(return_value, sp.tez(0), callback) + # using if else # with sp.if_(sm.serviceType == types.Types.ServiceType.open_variant("REQUEST_COIN_TRANSFER")): # tc = sp.unpack(sm.data, t=types.Types.TransferCoin) @@ -247,20 +259,24 @@ def handle_btp_message(self, _from, svc, sn, msg): @sp.entry_point - def handle_btp_error(self, svc, sn, code, msg): + def handle_btp_error(self, svc, sn, code, msg, callback, bsh_addr): """ BSH handle BTP Error from BMC contract :param svc: A service name of BSH contract :param sn: A serial number of a service request :param code: A response code of a message (RC_OK / RC_ERR) :param msg: A response message + :param callback: callback function type in bmc_periphery + :param bsh_addr: param for callback function in bmc_periphery :return: """ sp.set_type(svc, sp.TString) - sp.set_type(sn, sp.TNat) + sp.set_type(sn, sp.TInt) sp.set_type(code, sp.TNat) sp.set_type(msg, sp.TString) + sp.set_type(callback, sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress,svc=sp.TString, sn=sp.TInt, code=sp.TNat, msg=sp.TString))) + sp.set_type(bsh_addr, sp.TAddress) self.only_bmc() @@ -270,6 +286,9 @@ def handle_btp_error(self, svc, sn, code, msg): emit_msg= sp.concat(["errCode: ", sp.view("string_of_int", self.data.parse_contract, sp.to_int(code), t=sp.TString).open_some(),", errMsg: ", msg]) self.handle_response_service(sn, self.RC_ERR, emit_msg) + return_value = sp.record(string=sp.some("success"), bsh_addr=bsh_addr, svc=svc, sn=sn, code=code, msg=msg) + sp.transfer(return_value, sp.tez(0), callback) + def handle_response_service(self, sn, code, msg): """ @@ -278,7 +297,7 @@ def handle_response_service(self, sn, code, msg): :param msg: :return: """ - sp.set_type(sn, sp.TNat) + sp.set_type(sn, sp.TInt) sp.set_type(code, sp.TNat) sp.set_type(msg, sp.TString) @@ -351,17 +370,17 @@ def send_response_message(self, service_type, to, sn, msg, code): """ sp.set_type(service_type, types.Types.ServiceType) sp.set_type(to, sp.TString) - sp.set_type(sn, sp.TNat) + sp.set_type(sn, sp.TInt) sp.set_type(msg, sp.TString) sp.set_type(code, sp.TNat) sp.trace("in send_response_message") send_message_args_type = sp.TRecord( - to=sp.TString, svc=sp.TString, sn=sp.TNat, msg=sp.TBytes + to=sp.TString, svc=sp.TString, sn=sp.TInt, msg=sp.TBytes ) send_message_entry_point = sp.contract(send_message_args_type, self.data.bmc, "send_message").open_some() - send_message_args = sp.record(to=to, svc=self.service_name, sn=self.data.serial_no, + send_message_args = sp.record(to=to, svc=self.service_name, sn=sn, msg=sp.pack(sp.record(serviceType=service_type, data=sp.pack(sp.record(code=code, message=msg)))) ) sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) @@ -420,7 +439,7 @@ def test(): # coin_names={0:"Tok1"}, values={0:sp.nat(10)}, fees={0:sp.nat(2)})).run( # sender=bts_core # ) - # counter.handle_btp_error(sp.record(svc= "bts", code=sp.nat(2), sn=sp.nat(1), msg="test 1")).run( + # counter.handle_btp_error(sp.record(svc= "bts", code=sp.nat(2), sn=sp.int(1), msg="test 1")).run( # sender=bmc # ) @@ -433,7 +452,7 @@ def test(): # counter.handle_fee_gathering(sp.record(fa="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", svc="bts")).run(sender=bmc) - # counter.handle_btp_message(sp.record(_from="tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", svc="bts", sn=sp.nat(4), + # counter.handle_btp_message(sp.record(_from="tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", svc="bts", sn=sp.int(4), # msg=sp.bytes("0x0507070a000000030dae110000") )).run(sender=admin) From fe09061b2685567e4ff0dbd442405d9106e74de4 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Wed, 17 May 2023 10:41:00 +0545 Subject: [PATCH 068/211] feat: tezos contracts deployment script --- .gitignore | 3 +- cmd/iconbridge/chain/tezos/client.go | 18 +- cmd/iconbridge/chain/tezos/receiver.go | 8 +- cmd/iconbridge/chain/tezos/register_relay.go | 4 +- cmd/iconbridge/chain/tezos/sender.go | 18 +- cmd/iconbridge/chain/tezos/verifier.go | 19 +- cmd/iconbridge/example.config.json | 84 +++--- devnet/docker/icon-tezos/scripts/config.sh | 76 +++++ .../config/icon-tezos.config.testnet.sh | 76 +++++ devnet/docker/icon-tezos/scripts/deploysc.sh | 258 +++++++++++++++++ devnet/docker/icon-tezos/scripts/keystore.sh | 66 +++++ .../icon-tezos/scripts/token.javascore.sh | 267 ++++++++++++++++++ .../icon-tezos/scripts/token.smartpy.sh | 63 +++++ 13 files changed, 878 insertions(+), 82 deletions(-) create mode 100644 devnet/docker/icon-tezos/scripts/config.sh create mode 100644 devnet/docker/icon-tezos/scripts/config/icon-tezos.config.testnet.sh create mode 100644 devnet/docker/icon-tezos/scripts/deploysc.sh create mode 100644 devnet/docker/icon-tezos/scripts/keystore.sh create mode 100644 devnet/docker/icon-tezos/scripts/token.javascore.sh create mode 100644 devnet/docker/icon-tezos/scripts/token.smartpy.sh diff --git a/.gitignore b/.gitignore index 1b5069da..3e4cdcab 100644 --- a/.gitignore +++ b/.gitignore @@ -26,4 +26,5 @@ devnet/docker/icon-bsc/data/ devnet/docker/icon-algorand/local/ devnet/docker/icon-algorand/cache/ devnet/docker/icon-algorand/iconvalidators -devnet/docker/icon-algorand/*keystore.json \ No newline at end of file +devnet/docker/icon-algorand/*keystore.json +javascore/wallet1.json \ No newline at end of file diff --git a/cmd/iconbridge/chain/tezos/client.go b/cmd/iconbridge/chain/tezos/client.go index db1997d5..07c0b17f 100644 --- a/cmd/iconbridge/chain/tezos/client.go +++ b/cmd/iconbridge/chain/tezos/client.go @@ -154,7 +154,7 @@ func (c *Client) MonitorBlock(ctx context.Context, blockLevel int64, verifier IV } fmt.Println(block.Metadata.ProposerConsensusKey) - err = verifier.Verify(ctx, header, block.Metadata.ProposerConsensusKey, c.Cl, header.Hash) + err = verifier.Verify(ctx, header, block.Metadata.ProposerConsensusKey, c.Cl, header) if err != nil { fmt.Println(err) @@ -253,9 +253,21 @@ func (c *Client) GetBalance(ctx context.Context, connection *rpc.Client, account return balance.Big(), nil } -func (c *Client) GetStatus(ctx context.Context, contr *contract.Contract) (TypesLinkStats, error){ +func (c *Client) GetStatus(ctx context.Context, contr *contract.Contract, link string) (TypesLinkStats, error){ + + fmt.Println("reached in get status of tezos") prim := micheline.Prim{} - status, err := contr.RunCallback(ctx, "getStatus", prim) + + in := "{ \"prim\": \"Right\", \"args\": [ { \"prim\": \"Right\", \"args\": [ { \"string\": \""+ link + "\" } ] } ] }" + fmt.Println(in) + + if err := prim.UnmarshalJSON([]byte(in)); err != nil { + fmt.Println("couldnot unmarshall empty string") + fmt.Println(err) + return *new(TypesLinkStats), err + } + + status, err := contr.RunView(ctx, "get_status", prim) if err != nil { return *new(TypesLinkStats), err } diff --git a/cmd/iconbridge/chain/tezos/receiver.go b/cmd/iconbridge/chain/tezos/receiver.go index 806ae69f..dd4c4be0 100644 --- a/cmd/iconbridge/chain/tezos/receiver.go +++ b/cmd/iconbridge/chain/tezos/receiver.go @@ -41,7 +41,7 @@ type receiver struct { func (r *receiver) Subscribe(ctx context.Context, msgCh chan<- *chain.Message, opts chain.SubscribeOptions) (errCh <-chan error, err error) { fmt.Println("reached to subscribe") - src := tezos.MustParseAddress(string(r.src)) + src := tezos.MustParseAddress(r.src.ContractAddress()) r.client.Contract = contract.NewContract(src, r.client.Cl) opts.Seq++ @@ -191,7 +191,7 @@ func NewReceiver(src, dst chain.BTPAddress, urls []string, rawOpts json.RawMessa receiver.opts.SyncConcurrency = MonitorBlockMaxConcurrency } - srcAddr := tezos.MustParseAddress(string(src)) + srcAddr := tezos.MustParseAddress(src.ContractAddress()) newClient, err = NewClient(urls[0], srcAddr, receiver.log) @@ -368,7 +368,7 @@ func (r *receiver) SyncVerifier(ctx context.Context, vr IVerifier, height int64, fmt.Println("has it reached to verification") fmt.Println(next.Header.Level) - err := vr.Verify(ctx, prevHeader, next.Block.Metadata.Baker, r.client.Cl, next.Header.Hash) + err := vr.Verify(ctx, prevHeader, next.Block.Metadata.Baker, r.client.Cl, next.Header) if err != nil { cursor = vr.Height() + 1 @@ -465,7 +465,7 @@ func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback fu if vr != nil { fmt.Println("vr is not nil") // header := bn.Header - if err := vr.Verify(ctx, lbn.Header, bn.Proposer, r.client.Cl, bn.Header.Hash); err != nil { // change accordingly + if err := vr.Verify(ctx, lbn.Header, bn.Proposer, r.client.Cl, bn.Header); err != nil { // change accordingly // r.log.WithFields(log.Fields{ // "height": lbn.Height, // "lbnHash": lbn.Hash, diff --git a/cmd/iconbridge/chain/tezos/register_relay.go b/cmd/iconbridge/chain/tezos/register_relay.go index 9316306c..7e130334 100644 --- a/cmd/iconbridge/chain/tezos/register_relay.go +++ b/cmd/iconbridge/chain/tezos/register_relay.go @@ -3,6 +3,6 @@ package tezos import "github.com/icon-project/icon-bridge/cmd/iconbridge/relay" func init() { - relay.Senders["tz"] = NewSender - relay.Receivers["tz"] = NewReceiver + relay.Senders["tezos"] = NewSender + relay.Receivers["tezos"] = NewReceiver } diff --git a/cmd/iconbridge/chain/tezos/sender.go b/cmd/iconbridge/chain/tezos/sender.go index 81469f0e..39932955 100644 --- a/cmd/iconbridge/chain/tezos/sender.go +++ b/cmd/iconbridge/chain/tezos/sender.go @@ -34,13 +34,14 @@ type senderOptions struct { type sender struct { log log.Logger - src tezos.Address + src chain.BTPAddress dst tezos.Address connection *contract.Contract parameters micheline.Parameters cls *Client blockLevel int64 opts senderOptions + w tezos.PrivateKey } func NewSender( @@ -48,17 +49,20 @@ func NewSender( urls []string, w wallet.Wallet, rawOpts json.RawMessage, l log.Logger) (chain.Sender, error) { var err error - srcAddr := tezos.MustParseAddress(src.String()) - dstAddr := tezos.MustParseAddress(dst.String()) + fmt.Println(src.ContractAddress()) + fmt.Println(dst.ContractAddress()) + // srcAddr := tezos.MustParseAddress(src.ContractAddress()) + dstAddr := tezos.MustParseAddress(dst.ContractAddress()) s := &sender { log: l, - src: srcAddr, + src: src, dst: dstAddr, + w: tezos.MustParsePrivateKey("edskRz1HoD3cWkmWhCNS5LjBrJNWChGuKWB4HnVoN5UqVsUCpcNJR67ZxKs965u8RgRwptrtGc2ufYZoeECgB77RKm1gTbQ6eB"), } if len(urls) == 0 { return nil, fmt.Errorf("Empty url") } - s.cls, err = NewClient(urls[0], srcAddr, l) + s.cls, err = NewClient(urls[0], dstAddr, l) if err != nil { return nil, err } @@ -68,7 +72,7 @@ func NewSender( } func (s *sender) Balance(ctx context.Context) (balance, threshold *big.Int, err error){ - balance, err = s.cls.GetBalance(ctx, s.cls.Cl, s.src, s.cls.blockLevel) + balance, err = s.cls.GetBalance(ctx, s.cls.Cl, s.w.Address(), s.cls.blockLevel) if err != nil { return nil, nil, err } @@ -140,7 +144,7 @@ func (s *sender) Status(ctx context.Context) (link *chain.BMCLinkStatus, err err return nil, ctx.Err() } - status, err := s.cls.GetStatus(ctx, s.cls.Contract) + status, err := s.cls.GetStatus(ctx, s.cls.Contract, s.src.String()) if err != nil { return nil, err } diff --git a/cmd/iconbridge/chain/tezos/verifier.go b/cmd/iconbridge/chain/tezos/verifier.go index 791c3303..c261c18b 100644 --- a/cmd/iconbridge/chain/tezos/verifier.go +++ b/cmd/iconbridge/chain/tezos/verifier.go @@ -14,7 +14,7 @@ import ( type IVerifier interface { Next() int64 - Verify(ctx context.Context, header *rpc.BlockHeader, proposer tezos.Address, c *rpc.Client, hash tezos.BlockHash) error + Verify(ctx context.Context, header *rpc.BlockHeader, proposer tezos.Address, c *rpc.Client, nextHeader *rpc.BlockHeader) error Update(header *rpc.BlockHeader) error ParentHash() tezos.BlockHash IsValidator(proposer tezos.Address, height int64) bool @@ -37,13 +37,10 @@ func (vr *Verifier) Next() int64{ return vr.next } -func (vr *Verifier) Verify(ctx context.Context, header *rpc.BlockHeader, proposer tezos.Address, c *rpc.Client, hash tezos.BlockHash) error { +func (vr *Verifier) Verify(ctx context.Context, header *rpc.BlockHeader, proposer tezos.Address, c *rpc.Client, nextHeader *rpc.BlockHeader) error { vr.mu.RLock() defer vr.mu.RUnlock() - fmt.Println("has to reach in verify the second time") - fmt.Println(header.Level) blockFittness := header.Fitness - fmt.Println(blockFittness) currentFittness, err := strconv.ParseInt(string(blockFittness[1].String()), 16, 64) if err != nil { return err @@ -52,29 +49,21 @@ func (vr *Verifier) Verify(ctx context.Context, header *rpc.BlockHeader, propose if currentFittness < vr.parentFittness { return fmt.Errorf("Invalid block fittness", currentFittness) } - fmt.Println("validated the block fittness", header.Level) - previousHashInBlock := header.Predecessor - fmt.Println(previousHashInBlock) - - fmt.Println(vr.parentHash) if previousHashInBlock.String() != vr.parentHash.String() { return fmt.Errorf("Invalid block hash", header.Level) } - fmt.Println("Block is verified") - fmt.Println("******* *******") - fmt.Println(" ******* *******") - fmt.Println(" ******* *******") - // isValidSignature, err := vr.VerifySignature(ctx, proposer, header.Signature, header.Level, header, c) // if !isValidSignature { // return fmt.Errorf("Invalid block hash. Signature mismatch") // } + fmt.Println(nextHeader.ValidationPass) + fmt.Println(true) return nil } diff --git a/cmd/iconbridge/example.config.json b/cmd/iconbridge/example.config.json index 8c51d305..4e227f8b 100644 --- a/cmd/iconbridge/example.config.json +++ b/cmd/iconbridge/example.config.json @@ -15,101 +15,85 @@ }, "relays": [ { - "name": "h2i", + "name": "t2i", "src": { - "address": "btp://0x6357d2e0.hmny/0x233909bE3797BBd135A837AC945bCdE3cB078969", - "endpoint": ["https://rpc.s0.b.hmny.io"], + "address": "btp://NetXnHfVqm9iesp.tezos/KT1UrLqhQHDC3mJw9BUrqsiix7JRbxTsvWJu", + "endpoint": [ + "https://ghostnet.tezos.marigold.dev" + ], "options": { "verifier": { - "blockHeight": 24629415, - "commitBitmap": "0xffffff07", - "commitSignature": "0xaa325f4ae32c183e184e4f64603cfbeb44cec12cb7654a180ed83b737d53ff86463f5c6ba20300b70b60266512ee570fba6bcfbc5085a07f39dac5a197e53d2eff450c9d8abdfa685a47a72a8bfb9d541fdf3cf02e8b3e89c4c3fa057d58dc8b" + "blockHeight": 2661055 }, "syncConcurrency": 100 }, - "offset": 24629946 + "offset": 2661055 }, "dst": { - "address": "btp://0x7.icon/cx9e5c0a749ee94c01febe04702184002a76a84f84", + "address": "btp://0x2.icon/cx9f3e7e3c6dda6da9ea0c4c4e8f1b5d36b0b70742", "endpoint": [ "https://berlin.net.solidwallet.io/api/v3/icon_dex" ], "options": { - "step_limit": 13610920010, - "tx_data_size_limit": 65536 + "step_limit": 1000000 }, "key_store": { - "address": "hxca02e14958183eef1a31d405e6628d25bdb35282", - "id": "f94b9e44-63a8-4b10-a691-a78cf4adb143", "version": 3, - "coinType": "icx", + "id": "8dd706f6-9c0d-4bf2-b607-5c3caa4f9404", + "address": "hx0a1c14557fa891cdba8df495850d61704a2c90d7", "crypto": { - "cipher": "aes-128-ctr", + "ciphertext": "0958c7f79c5e3947f8b7c46f78482c735baa02e0cac339ee100c09c24b99b4f6", "cipherparams": { - "iv": "081fcf6387ff3e72418561c22e203449" + "iv": "3e6334b31b407772682bf909dda25a91" }, - "ciphertext": "e959dbe55a64de209c69bb15fb110bb8ffbb6361400b530861eded26f686025d", + "cipher": "aes-128-ctr", "kdf": "scrypt", "kdfparams": { "dklen": 32, - "n": 65536, + "salt": "87ee9d1105fabc001d1d3455d3937c1256d2d604fd910bd0ffe95bb221769694", + "n": 16384, "r": 8, - "p": 1, - "salt": "e55aed7374098c0a" + "p": 1 }, - "mac": "e05a40a5901fecddfc692653c1a6f1b3ea872b4fad2078f3b2aacb8fbbea7a8e" - } + "mac": "f33f666c2c699dd906fdec3a454c9170c6b68cabcaae4c67e22861acf316127c" + }, + "coinType": "icx" }, - "key_password": "xyz" + "key_password": "icon@123" } }, { - "name": "i2h", + "name": "i2t", "src": { - "address": "btp://0x7.icon/cx9e5c0a749ee94c01febe04702184002a76a84f84", + "address": "btp://0x2.icon/cx9f3e7e3c6dda6da9ea0c4c4e8f1b5d36b0b70742", "endpoint": [ "https://berlin.net.solidwallet.io/api/v3/icon_dex" ], "options": { "verifier": { - "blockHeight": 50833960, + "blockHeight": 8279323, "validatorsHash": "0x120c4d12ae3770b868e650e950200364fe138b92e872e487f50da4337bcc83c7" } }, - "offset": 6057269 + "offset": 8279323 }, "dst": { - "address": "btp://0x6357d2e0.hmny/0x233909bE3797BBd135A837AC945bCdE3cB078969", - "endpoint": ["https://rpc.s0.b.hmny.io"], + "address": "btp://NetXnHfVqm9iesp.tezos/KT1UrLqhQHDC3mJw9BUrqsiix7JRbxTsvWJu", + "endpoint": [ + "https://ghostnet.tezos.marigold.dev" + ], "options": { - "gas_limit": 80000000, + "gas_limit": 1040000, "boost_gas_price": 1.5, "tx_data_size_limit": 65536 }, "key_store": { - "address": "80f1b32f3d656528a9616076e42fcc4d47a5a9a3", - "crypto": { - "cipher": "aes-128-ctr", - "ciphertext": "8d892d72f030610af8df4625abb10fec8aaa62a3d882fde1d8875302f732f99d", - "cipherparams": { - "iv": "01c84057179e9dc95baaabc78e04918c" - }, - "kdf": "scrypt", - "kdfparams": { - "dklen": 32, - "n": 262144, - "p": 1, - "r": 8, - "salt": "0c1b6b301a2d2d46f0a17b736b82fb4cdf90bb3a9be4a0671828c00d878a7d77" - }, - "mac": "f3ce22f3ba8fa0cd17d25a4be5752f8de53d3e52ec282f1ff050a3b3bcbdf683" - }, - "id": "982c4409-864d-408e-a1d0-ec2b47e319ba", - "version": 3, - "coinType": "evm" + "address": "tz1ZPVxKiybvbV1GvELRJJpyE1xj1UpNpXMv", + "secret": "edskRz1HoD3cWkmWhCNS5LjBrJNWChGuKWB4HnVoN5UqVsUCpcNJR67ZxKs965u8RgRwptrtGc2ufYZoeECgB77RKm1gTbQ6eB", + "coinType": "xtz" }, "key_password": "xyz" } } ] -} +} \ No newline at end of file diff --git a/devnet/docker/icon-tezos/scripts/config.sh b/devnet/docker/icon-tezos/scripts/config.sh new file mode 100644 index 00000000..9aecfa46 --- /dev/null +++ b/devnet/docker/icon-tezos/scripts/config.sh @@ -0,0 +1,76 @@ +#!/bin/bash +#BUILD_DIR=$(echo "$(cd "$(dirname "../../../../../")"; pwd)"/build) +BASE_DIR=$(echo "$(cd "$(dirname "../../")"; pwd)") +BUILD_DIR=$BASE_DIR/build +export ICONBRIDGE_CONFIG_DIR=$BASE_DIR/_ixh +export ICONBRIDGE_CONTRACTS_DIR=$BUILD_DIR/contracts +export ICONBRIDGE_SCRIPTS_DIR=$BASE_DIR/scripts +export ICONBRIDGE_BIN_DIR=$BASE_DIR + +export CONFIG_DIR=${CONFIG_DIR:-${ICONBRIDGE_CONFIG_DIR}} +export CONTRACTS_DIR=${CONTRACTS_DIR:-${ICONBRIDGE_CONTRACTS_DIR}} +export SCRIPTS_DIR=${SCRIPTS_DIR:-${ICONBRIDGE_SCRIPTS_DIR}} + +################################################################################### +# testnet: begin +export TAG="ICON BSC TESTNET" +export BSC_BMC_NET="0x61.bsc" +export ICON_BMC_NET="0x2.icon" +export SNOW_BMC_NET="0x229.snow" +export TZ_BMC_NET="0x63.tezos" +export GOLOOP_RPC_NID="0x2" +export BSC_NID="97" +export TEZOS_NID="NetXnHfVqm9iesp" + +export ICON_ENDPOINT="https://lisbon.net.solidwallet.io/api/v3/icon_dex" +export ICON_NATIVE_COIN_SYM=("ICX") +export ICON_NATIVE_COIN_NAME=("btp-$ICON_BMC_NET-ICX") +export ICON_NATIVE_TOKEN_SYM=("sICX" "bnUSD") +export ICON_NATIVE_TOKEN_NAME=("btp-$ICON_BMC_NET-sICX" "btp-$ICON_BMC_NET-bnUSD") +export ICON_WRAPPED_COIN_SYM=("BNB" "BUSD" "USDT" "USDC" "BTCB" "ETH" "ICZ") +export ICON_WRAPPED_COIN_NAME=("btp-$BSC_BMC_NET-BNB" "btp-$BSC_BMC_NET-BUSD" "btp-$BSC_BMC_NET-USDT" "btp-$BSC_BMC_NET-USDC" "btp-$BSC_BMC_NET-BTCB" "btp-$BSC_BMC_NET-ETH" "btp-$SNOW_BMC_NET-ICZ") +export FEE_GATHERING_INTERVAL=21600 + + +export ICON_NATIVE_COIN_FIXED_FEE=(4300000000000000000) +export ICON_NATIVE_COIN_FEE_NUMERATOR=(100) +export ICON_NATIVE_COIN_DECIMALS=(18) +export ICON_NATIVE_TOKEN_FIXED_FEE=(3900000000000000000 1500000000000000000) +export ICON_NATIVE_TOKEN_FEE_NUMERATOR=(100 100) +export ICON_NATIVE_TOKEN_DECIMALS=(18 18) +export ICON_WRAPPED_COIN_FIXED_FEE=(5000000000000000 1500000000000000000 1500000000000000000 1500000000000000000 62500000000000 750000000000000 4300000000000000000) +export ICON_WRAPPED_COIN_FEE_NUMERATOR=(100 100 100 100 100 100 100) +export ICON_WRAPPED_COIN_DECIMALS=(18 18 18 18 18 18 18) + +export TZ_ENDPOINT="https://ghostnet.tezos.marigold.dev" +export TZ_NATIVE_COIN_SYM=("XTZ") +export TZ_NATIVE_COIN_NAME=("btp-$TZ_BMC_NET-TZ") +export TZ_NATIVE_TOKEN_SYM=("BUSD" "USDT" "USDC" "BTCB" "ETH") +export TZ_NATIVE_TOKEN_NAME=("btp-$TZ_BMC_NET-BUSD" "btp-$TZ_BMC_NET-USDT" "btp-$TZ_BMC_NET-USDC" "btp-$TZ_BMC_NET-BTCB" "btp-$TZ_BMC_NET-ETH") +export TZ_WRAPPED_COIN_SYM=("ICX" "sICX" "bnUSD" "ICZ") +export TZ_WRAPPED_COIN_NAME=("btp-$ICON_BMC_NET-ICX" "btp-$ICON_BMC_NET-sICX" "btp-$ICON_BMC_NET-bnUSD" "btp-$SNOW_BMC_NET-ICZ") + +export TZ_NATIVE_COIN_FIXED_FEE=(450) +export TZ_NATIVE_COIN_FEE_NUMERATOR=(100) +export TZ_NATIVE_COIN_DECIMALS=(6) +export TZ_NATIVE_TOKEN_FIXED_FEE=(450 1500000000000000000 1500000000000000000 62500000000000 750000000000000) +export TZ_NATIVE_TOKEN_FEE_NUMERATOR=(100 100 100 100 100) +export TZ_NATIVE_TOKEN_DECIMALS=(18 18 18 18 18) +export TZ_WRAPPED_COIN_FIXED_FEE=(4300000000000000000 3900000000000000000 1500000000000000000 4300000000000000000) +export TZ_WRAPPED_COIN_FEE_NUMERATOR=(100 100 100 100) +export TZ_WRAPPED_COIN_DECIMALS=(18 18 18 18) + +# testnet: end +################################################################################### + +GOLOOPCHAIN=${GOLOOPCHAIN:-"goloop"} +export GOLOOP_RPC_STEP_LIMIT=5000000000 +export ICON_KEY_STORE=$ICONBRIDGE_CONFIG_DIR/keystore/icon.god.wallet.json +export ICON_SECRET=$ICONBRIDGE_CONFIG_DIR/keystore/icon.god.wallet.secret +export GOLOOP_RPC_URI=$ICON_ENDPOINT +export GOLOOP_RPC_KEY_STORE=$ICON_KEY_STORE +export GOLOOP_RPC_KEY_SECRET=$ICON_SECRET + +export TZ_RPC_URI=$BSC_ENDPOINT +export TZ_KEY_STORE=$ICONBRIDGE_CONFIG_DIR/keystore/tz.god.wallet.json +# export BSC_SECRET=$ICONBRIDGE_CONFIG_DIR/keystore/bsc.god.wallet.secret diff --git a/devnet/docker/icon-tezos/scripts/config/icon-tezos.config.testnet.sh b/devnet/docker/icon-tezos/scripts/config/icon-tezos.config.testnet.sh new file mode 100644 index 00000000..112ca8d9 --- /dev/null +++ b/devnet/docker/icon-tezos/scripts/config/icon-tezos.config.testnet.sh @@ -0,0 +1,76 @@ +#!/bin/bash +#BUILD_DIR=$(echo "$(cd "$(dirname "../../../../../")"; pwd)"/build) +BASE_DIR=$(echo "$(cd "$(dirname "../../")"; pwd)") +BUILD_DIR=$BASE_DIR/build +export ICONBRIDGE_CONFIG_DIR=$BASE_DIR/_ixh +export ICONBRIDGE_CONTRACTS_DIR=$BUILD_DIR/contracts +export ICONBRIDGE_SCRIPTS_DIR=$BASE_DIR/scripts +export ICONBRIDGE_BIN_DIR=$BASE_DIR + +export CONFIG_DIR=${CONFIG_DIR:-${ICONBRIDGE_CONFIG_DIR}} +export CONTRACTS_DIR=${CONTRACTS_DIR:-${ICONBRIDGE_CONTRACTS_DIR}} +export SCRIPTS_DIR=${SCRIPTS_DIR:-${ICONBRIDGE_SCRIPTS_DIR}} + +################################################################################### +# testnet: begin +export TAG="ICON BSC TESTNET" +export BSC_BMC_NET="0x61.bsc" +export ICON_BMC_NET="0x2.icon" +export SNOW_BMC_NET="0x229.snow" +export TZ_BMC_NET="0x63.tezos" +export GOLOOP_RPC_NID="0x2" +export BSC_NID="97" +export TEZOS_NID="NetXnHfVqm9iesp" + +export ICON_ENDPOINT="https://lisbon.net.solidwallet.io/api/v3/icon_dex" +export ICON_NATIVE_COIN_SYM=("ICX") +export ICON_NATIVE_COIN_NAME=("btp-$ICON_BMC_NET-ICX") +export ICON_NATIVE_TOKEN_SYM=("sICX" "bnUSD") +export ICON_NATIVE_TOKEN_NAME=("btp-$ICON_BMC_NET-sICX" "btp-$ICON_BMC_NET-bnUSD") +export ICON_WRAPPED_COIN_SYM=("BNB" "BUSD" "USDT" "USDC" "BTCB" "ETH" "ICZ") +export ICON_WRAPPED_COIN_NAME=("btp-$BSC_BMC_NET-BNB" "btp-$BSC_BMC_NET-BUSD" "btp-$BSC_BMC_NET-USDT" "btp-$BSC_BMC_NET-USDC" "btp-$BSC_BMC_NET-BTCB" "btp-$BSC_BMC_NET-ETH" "btp-$SNOW_BMC_NET-ICZ") +export FEE_GATHERING_INTERVAL=21600 + + +export ICON_NATIVE_COIN_FIXED_FEE=(4300000000000000000) +export ICON_NATIVE_COIN_FEE_NUMERATOR=(100) +export ICON_NATIVE_COIN_DECIMALS=(18) +export ICON_NATIVE_TOKEN_FIXED_FEE=(3900000000000000000 1500000000000000000) +export ICON_NATIVE_TOKEN_FEE_NUMERATOR=(100 100) +export ICON_NATIVE_TOKEN_DECIMALS=(18 18) +export ICON_WRAPPED_COIN_FIXED_FEE=(5000000000000000 1500000000000000000 1500000000000000000 1500000000000000000 62500000000000 750000000000000 4300000000000000000) +export ICON_WRAPPED_COIN_FEE_NUMERATOR=(100 100 100 100 100 100 100) +export ICON_WRAPPED_COIN_DECIMALS=(18 18 18 18 18 18 18) + +export TZ_ENDPOINT="https://ghostnet.tezos.marigold.dev" +export TZ_NATIVE_COIN_SYM=("XTZ") +export TZ_NATIVE_COIN_NAME=("btp-$TZ_BMC_NET-TZ") +export TZ_NATIVE_TOKEN_SYM=("BUSD" "USDT" "USDC" "BTCB" "ETH") +export TZ_NATIVE_TOKEN_NAME=("btp-$TZ_BMC_NET-BUSD" "btp-$TZ_BMC_NET-USDT" "btp-$TZ_BMC_NET-USDC" "btp-$TZ_BMC_NET-BTCB" "btp-$TZ_BMC_NET-ETH") +export TZ_WRAPPED_COIN_SYM=("ICX" "sICX" "bnUSD" "ICZ") +export TZ_WRAPPED_COIN_NAME=("btp-$ICON_BMC_NET-ICX" "btp-$ICON_BMC_NET-sICX" "btp-$ICON_BMC_NET-bnUSD" "btp-$SNOW_BMC_NET-ICZ") + +export TZ_NATIVE_COIN_FIXED_FEE=(1) +export TZ_NATIVE_COIN_FEE_NUMERATOR=(100) +export TZ_NATIVE_COIN_DECIMALS=(6) +export TZ_NATIVE_TOKEN_FIXED_FEE=(1500000000000000000 1500000000000000000 1500000000000000000 62500000000000 750000000000000) +export TZ_NATIVE_TOKEN_FEE_NUMERATOR=(100 100 100 100 100) +export TZ_NATIVE_TOKEN_DECIMALS=(18 18 18 18 18) +export TZ_WRAPPED_COIN_FIXED_FEE=(4300000000000000000 3900000000000000000 1500000000000000000 4300000000000000000) +export TZ_WRAPPED_COIN_FEE_NUMERATOR=(100 100 100 100) +export TZ_WRAPPED_COIN_DECIMALS=(18 18 18 18) + +# testnet: end +################################################################################### + +GOLOOPCHAIN=${GOLOOPCHAIN:-"goloop"} +export GOLOOP_RPC_STEP_LIMIT=5000000000 +export ICON_KEY_STORE=$ICONBRIDGE_CONFIG_DIR/keystore/icon.god.wallet.json +export ICON_SECRET=$ICONBRIDGE_CONFIG_DIR/keystore/icon.god.wallet.secret +export GOLOOP_RPC_URI=$ICON_ENDPOINT +export GOLOOP_RPC_KEY_STORE=$ICON_KEY_STORE +export GOLOOP_RPC_KEY_SECRET=$ICON_SECRET + +export TZ_RPC_URI=$BSC_ENDPOINT +export TZ_KEY_STORE=$ICONBRIDGE_CONFIG_DIR/keystore/tz.god.wallet.json +# export BSC_SECRET=$ICONBRIDGE_CONFIG_DIR/keystore/bsc.god.wallet.secret diff --git a/devnet/docker/icon-tezos/scripts/deploysc.sh b/devnet/docker/icon-tezos/scripts/deploysc.sh new file mode 100644 index 00000000..91513f34 --- /dev/null +++ b/devnet/docker/icon-tezos/scripts/deploysc.sh @@ -0,0 +1,258 @@ +#!/bin/bash +set -e + +# Parts of this code is adapted from https://github.com/icon-project/btp/blob/goloop2moonbeam/testnet/goloop2moonbeam/scripts +source config.sh +source keystore.sh +source rpc.sh +source generate_e2e_config.sh + +setup_account() { + echo "check god keys..." + if [ ! -f "${ICON_KEY_STORE}" ]; then + ensure_key_store $ICON_KEY_STORE $ICON_SECRET + echo "Do not Panic..." + echo "Missing ICON God Wallet on the required path. One has been created "$ICON_KEY_STORE + echo "Fund this newly created wallet and rerun the same command again" + exit 0 + fi + if [ ! -f "${BSC_KEY_STORE}" ]; then + ensure_bsc_key_store $BSC_KEY_STORE $BSC_SECRET + echo "Do not Panic..." + echo "Missing BSC God Wallet on the required path. One has been created "$BSC_KEY_STORE + echo "Fund this newly created wallet and rerun again " + exit 0 + fi + export PRIVATE_KEY="[\""$(cat $BSC_KEY_STORE.priv)"\"]" + # add owners + echo "List/Create user accounts" + ensure_key_store $CONFIG_DIR/keystore/icon.bts.wallet.json $CONFIG_DIR/keystore/icon.bts.wallet.secret + ensure_key_store $CONFIG_DIR/keystore/icon.bmc.wallet.json $CONFIG_DIR/keystore/icon.bmc.wallet.secret + ensure_key_store $CONFIG_DIR/keystore/icon.bmr.wallet.json $CONFIG_DIR/keystore/icon.bmr.wallet.secret + ensure_key_store $CONFIG_DIR/keystore/icon.fa.wallet.json $CONFIG_DIR/keystore/icon.fa.wallet.secret + + ensure_bsc_key_store $CONFIG_DIR/keystore/bsc.bts.wallet.json $CONFIG_DIR/keystore/bsc.bts.wallet.secret + ensure_bsc_key_store $CONFIG_DIR/keystore/bsc.bmc.wallet.json $CONFIG_DIR/keystore/bsc.bmc.wallet.secret + ensure_bsc_key_store $CONFIG_DIR/keystore/bsc.bmr.wallet.json $CONFIG_DIR/keystore/bsc.bmr.wallet.secret +} + +deploysc() { + if [ ! -d $BUILD_DIR ]; then + echo "Do not Panic..." + echo "Build Artifacts have not been created. Expected on path "$BUILD_DIR + echo "Run make buildsc to do so. Check README.md for more" + exit 0 + fi + echo "Start " + sleep 15 + echo "$GOLOOP_RPC_NID.icon" >$CONFIG_DIR/net.btp.icon #0x240fa7.icon + mkdir -p $CONFIG_DIR/tx + + source token.javascore.sh + source token.solidity.sh + + if [ ! -f $CONFIG_DIR/bsc.deploy.all ]; then + echo "Deploy solidity" + sleep 2 + deploy_solidity_bmc + deploy_solidity_bts "${BSC_NATIVE_COIN_FIXED_FEE[0]}" "${BSC_NATIVE_COIN_FEE_NUMERATOR[0]}" "${BSC_NATIVE_COIN_DECIMALS[0]}" + + if [ -n "${INIT_ADDRESS_PATH}" ]; then + if [ ! -f $INIT_ADDRESS_PATH ]; then + echo "No file found on "$INIT_ADDRESS_PATH + return 1 + fi + for i in "${!BSC_NATIVE_TOKEN_SYM[@]}"; do + addr=$(cat $INIT_ADDRESS_PATH | jq -r .solidity.${BSC_NATIVE_TOKEN_SYM[$i]}) + if [ "$addr" != "null" ]; then + echo -n $addr >$CONFIG_DIR/bsc.addr.${BSC_NATIVE_TOKEN_SYM[$i]} + else + echo "BSC Token does not exist on address file" ${BSC_NATIVE_TOKEN_SYM[$i]} + return 1 + fi + done + else + for i in "${!BSC_NATIVE_TOKEN_SYM[@]}"; do + deploy_solidity_token "${BSC_NATIVE_TOKEN_NAME[$i]}" "${BSC_NATIVE_TOKEN_SYM[$i]}" + done + fi + echo "CONFIGURE BSC" + configure_solidity_add_bmc_owner + configure_solidity_add_bts_service + configure_solidity_set_fee_ratio "${BSC_NATIVE_COIN_FIXED_FEE[0]}" "${BSC_NATIVE_COIN_FEE_NUMERATOR[0]}" + configure_solidity_add_bts_owner + echo "Register BSC Tokens" + for i in "${!BSC_NATIVE_TOKEN_SYM[@]}"; do + bsc_register_native_token "${BSC_NATIVE_TOKEN_NAME[$i]}" "${BSC_NATIVE_TOKEN_SYM[$i]}" "${BSC_NATIVE_TOKEN_FIXED_FEE[$i]}" "${BSC_NATIVE_TOKEN_FEE_NUMERATOR[$i]}" "${BSC_NATIVE_TOKEN_DECIMALS[$i]}" + get_coinID "${BSC_NATIVE_TOKEN_NAME[$i]}" "${BSC_NATIVE_TOKEN_SYM[$i]}" + done + for i in "${!BSC_WRAPPED_COIN_SYM[@]}"; do + bsc_register_wrapped_coin "${BSC_WRAPPED_COIN_NAME[$i]}" "${BSC_WRAPPED_COIN_SYM[$i]}" "${BSC_WRAPPED_COIN_FIXED_FEE[$i]}" "${BSC_WRAPPED_COIN_FEE_NUMERATOR[$i]}" "${BSC_WRAPPED_COIN_DECIMALS[$i]}" + get_coinID "${BSC_WRAPPED_COIN_NAME[$i]}" "${BSC_WRAPPED_COIN_SYM[$i]}" + done + echo "deployedSol" >$CONFIG_DIR/bsc.deploy.all + fi + + if [ ! -f $CONFIG_DIR/icon.deploy.all ]; then + echo "Deploy Javascore" + sleep 2 + deploy_javascore_bmc + deploy_javascore_bts "${ICON_NATIVE_COIN_FIXED_FEE[0]}" "${ICON_NATIVE_COIN_FEE_NUMERATOR[0]}" "${ICON_NATIVE_COIN_DECIMALS[0]}" + + if [ -n "${INIT_ADDRESS_PATH}" ]; then + if [ ! -f $INIT_ADDRESS_PATH ]; then + echo "No file found on "$INIT_ADDRESS_PATH + return 1 + fi + for i in "${!ICON_NATIVE_TOKEN_SYM[@]}"; do + addr=$(cat $INIT_ADDRESS_PATH | jq -r .javascore.${ICON_NATIVE_TOKEN_SYM[$i]}) + if [ "$addr" != "null" ]; then + echo -n $addr >$CONFIG_DIR/icon.addr.${ICON_NATIVE_TOKEN_SYM[$i]} + else + echo "ICON Token ${ICON_NATIVE_TOKEN_SYM[$i]} does not exist on address file" + return 1 + fi + done + else + for i in "${!ICON_NATIVE_TOKEN_SYM[@]}"; do + deploy_javascore_token "${ICON_NATIVE_TOKEN_NAME[$i]}" "${ICON_NATIVE_TOKEN_SYM[$i]}" + done + fi + echo "CONFIGURE ICON" + configure_javascore_add_bmc_owner + configure_javascore_bmc_setFeeAggregator + configure_javascore_add_bts + configure_javascore_add_bts_owner + configure_javascore_bts_setICXFee "${ICON_NATIVE_COIN_FIXED_FEE[0]}" "${ICON_NATIVE_COIN_FEE_NUMERATOR[0]}" + echo "Register ICON Tokens" + for i in "${!ICON_NATIVE_TOKEN_SYM[@]}"; do + configure_javascore_register_native_token "${ICON_NATIVE_TOKEN_NAME[$i]}" "${ICON_NATIVE_TOKEN_SYM[$i]}" "${ICON_NATIVE_TOKEN_FIXED_FEE[$i]}" "${ICON_NATIVE_TOKEN_FEE_NUMERATOR[$i]}" "${ICON_NATIVE_TOKEN_DECIMALS[$i]}" + get_btp_icon_coinId "${ICON_NATIVE_TOKEN_NAME[$i]}" "${ICON_NATIVE_TOKEN_SYM[$i]}" + done + for i in "${!ICON_WRAPPED_COIN_SYM[@]}"; do + configure_javascore_register_wrapped_coin "${ICON_WRAPPED_COIN_NAME[$i]}" "${ICON_WRAPPED_COIN_SYM[$i]}" "${ICON_WRAPPED_COIN_FIXED_FEE[$i]}" "${ICON_WRAPPED_COIN_FEE_NUMERATOR[$i]}" "${ICON_WRAPPED_COIN_DECIMALS[$i]}" + get_btp_icon_coinId "${ICON_WRAPPED_COIN_NAME[$i]}" "${ICON_WRAPPED_COIN_SYM[$i]}" + done + echo "deployedJavascore" >$CONFIG_DIR/icon.deploy.all + fi + + if [ ! -f $CONFIG_DIR/link.all ]; then + echo "LINK ICON" + configure_javascore_addLink + configure_javascore_setLinkHeight + configure_bmc_javascore_addRelay + echo "LINK BSC" + add_icon_link + set_link_height + add_icon_relay + echo "linked" >$CONFIG_DIR/link.all + fi + + generate_addresses_json >$CONFIG_DIR/addresses.json + generate_relay_config >$CONFIG_DIR/bmr.config.json + generate_e2e_config >$CONFIG_DIR/e2e.config.json + wait_for_file $CONFIG_DIR/bmr.config.json + + echo "Smart contracts have been deployed " + echo "You can now run the relay with make runrelaysrc OR make runrelayimg" +} + +wait_for_file() { + FILE_NAME=$1 + timeout=10 + while [ ! -f "$FILE_NAME" ]; do + if [ "$timeout" == 0 ]; then + echo "ERROR: Timeout while waiting for the file $FILE_NAME." + exit 1 + fi + sleep 1 + timeout=$(expr $timeout - 1) + + echo "waiting for the output file: $FILE_NAME" + done +} + +generate_relay_config() { + jq -n ' + .base_dir = $base_dir | + .log_level = "debug" | + .console_level = "trace" | + .log_writer.filename = $log_writer_filename | + .relays = [ $b2i_relay, $i2b_relay ]' \ + --arg base_dir "bmr" \ + --arg log_writer_filename "bmr/bmr.log" \ + --argjson b2i_relay "$( + jq -n ' + .name = "b2i" | + .src.address = $src_address | + .src.endpoint = [ $src_endpoint ] | + .src.options.verifier.blockHeight = $src_options_verifier_blockHeight | + .src.options.verifier.parentHash = $src_options_verifier_parentHash | + .src.options.verifier.validatorData = $src_options_verifier_validatorData | + .src.options.syncConcurrency = 100 | + .src.offset = $src_offset | + .dst.address = $dst_address | + .dst.endpoint = [ $dst_endpoint ] | + .dst.options = $dst_options | + .dst.key_store = $dst_key_store | + .dst.key_store.coinType = $dst_key_store_cointype | + .dst.key_password = $dst_key_password ' \ + --arg src_address "$(cat $CONFIG_DIR/bsc.addr.bmcbtp)" \ + --arg src_endpoint "$BSC_ENDPOINT" \ + --argjson src_offset "$(cat $CONFIG_DIR/bsc.chain.height)" \ + --argjson src_options_verifier_blockHeight "$(cat $CONFIG_DIR/bsc.chain.height)" \ + --arg src_options_verifier_parentHash "$(cat $CONFIG_DIR/bsc.chain.parentHash)" \ + --arg src_options_verifier_validatorData "$(cat $CONFIG_DIR/bsc.chain.validatorData)" \ + --arg dst_address "$(cat $CONFIG_DIR/icon.addr.bmcbtp)" \ + --arg dst_endpoint "$ICON_ENDPOINT" \ + --argfile dst_key_store "$CONFIG_DIR/keystore/icon.bmr.wallet.json" \ + --arg dst_key_store_cointype "icx" \ + --arg dst_key_password "$(cat $CONFIG_DIR/keystore/icon.bmr.wallet.secret)" \ + --argjson dst_options '{"step_limit":2500000000, "tx_data_size_limit":8192,"balance_threshold":"10000000000000000000"}' + )" \ + --argjson i2b_relay "$( + jq -n ' + .name = "i2b" | + .src.address = $src_address | + .src.endpoint = [ $src_endpoint ] | + .src.offset = $src_offset | + .src.options.verifier.blockHeight = $src_options_verifier_blockHeight | + .src.options.verifier.validatorsHash = $src_options_verifier_validatorsHash | + .src.options.syncConcurrency = 100 | + .dst.address = $dst_address | + .dst.endpoint = [ $dst_endpoint ] | + .dst.options = $dst_options | + .dst.tx_data_size_limit = $dst_tx_data_size_limit | + .dst.key_store = $dst_key_store | + .dst.key_store.coinType = $dst_key_store_cointype | + .dst.key_password = $dst_key_password ' \ + --arg src_address "$(cat $CONFIG_DIR/icon.addr.bmcbtp)" \ + --arg src_endpoint "$ICON_ENDPOINT" \ + --argjson src_offset "$(cat $CONFIG_DIR/icon.chain.height)" \ + --argjson src_options_verifier_blockHeight "$(cat $CONFIG_DIR/icon.chain.height)" \ + --arg src_options_verifier_validatorsHash "$(cat $CONFIG_DIR/icon.chain.validators)" \ + --arg dst_address "$(cat $CONFIG_DIR/bsc.addr.bmcbtp)" \ + --arg dst_endpoint "$BSC_ENDPOINT" \ + --argfile dst_key_store "$CONFIG_DIR/keystore/bsc.bmr.wallet.json" \ + --arg dst_key_store_cointype "evm" \ + --arg dst_key_password "$(cat $CONFIG_DIR/keystore/bsc.bmr.wallet.secret)" \ + --argjson dst_tx_data_size_limit 8192 \ + --argjson dst_options '{"gas_limit":24000000,"tx_data_size_limit":8192,"balance_threshold":"100000000000000000000","boost_gas_price":1.0}' + )" +} + +#wait-for-it.sh $GOLOOP_RPC_ADMIN_URI +# run provisioning +echo "start..." +echo "Load Configuration Files For : $TAG" + +read -p "Confirm? [y/N]: " proceed + +if [[ $proceed == "y" ]]; then + setup_account + deploysc + echo "Done deploying smart contracts" +else + echo "Exit" + exit 0 +fi \ No newline at end of file diff --git a/devnet/docker/icon-tezos/scripts/keystore.sh b/devnet/docker/icon-tezos/scripts/keystore.sh new file mode 100644 index 00000000..8f2b8659 --- /dev/null +++ b/devnet/docker/icon-tezos/scripts/keystore.sh @@ -0,0 +1,66 @@ +#!/bin/bash + +ensure_key_secret() { + if [ $# -lt 1 ] ; then + echo "Usage: ensure_key_secret SECRET_PATH" + return 1 + fi + local KEY_SECRET=$1 + if [ ! -f "${KEY_SECRET}" ]; then + mkdir -p $(dirname ${KEY_SECRET}) + echo -n $(openssl rand -hex 20) > ${KEY_SECRET} + fi + echo ${KEY_SECRET} +} + +ensure_key_store() { + if [ $# -lt 2 ] ; then + echo "Usage: ensure_key_store KEYSTORE_PATH SECRET_PATH" + return 1 + fi + local KEY_STORE=$1 + local KEY_SECRET=$(ensure_key_secret $2) + if [ ! -f "${KEY_STORE}" ]; then + goloop ks gen --out ${KEY_STORE}tmp -p $(cat ${KEY_SECRET}) > /dev/null 2>&1 + cat ${KEY_STORE}tmp | jq -r . > ${KEY_STORE} + rm ${KEY_STORE}tmp + + fi + echo ${KEY_STORE} +} + +ensure_bsc_key_store() { + if [ $# -lt 2 ] ; then + echo "Usage: ensure_key_store KEYSTORE_PATH SECRET_PATH" + return 1 + fi + + local KEY_STORE_PATH=$1 + local KEY_SECRET_PATH=$(ensure_key_secret $2) + if [ ! -f "${KEY_STORE_PATH}" ]; then + mkdir -p $ICONBRIDGE_CONFIG_DIR/keystore + ethkey generate --passwordfile $KEY_SECRET_PATH --json tmp + cat tmp | jq -r . > $KEY_STORE_PATH + ethkey inspect --json --private --passwordfile $KEY_SECRET_PATH $KEY_STORE_PATH | jq -r .PrivateKey > ${KEY_STORE_PATH}.priv + rm tmp + # tr -dc A-Fa-f0-9 $ICONBRIDGE_CONFIG_DIR/keystore/$(basename ${KEY_STORE_PATH}).priv + # tmpPath=$(geth account import --datadir $ICONBRIDGE_CONFIG_DIR --password $KEY_SECRET_PATH $ICONBRIDGE_CONFIG_DIR/keystore/$(basename ${KEY_STORE_PATH}).priv | sed -e "s/^Address: {//" -e "s/}//") + # fileMatch=$(find $ICONBRIDGE_CONFIG_DIR/keystore -type f -name '*'$tmpPath) + # cat $fileMatch | jq -r . > $KEY_STORE_PATH + # rm $fileMatch + fi + echo ${KEY_STORE_PATH} +} + +ensure_empty_key_secret() { + if [ $# -lt 1 ] ; then + echo "Usage: ensure_key_secret SECRET_PATH" + return 1 + fi + local KEY_SECRET=$1 + if [ ! -f "${KEY_SECRET}" ]; then + mkdir -p $(dirname ${KEY_SECRET}) + echo -n '' > ${KEY_SECRET} + fi + echo ${KEY_SECRET} +} \ No newline at end of file diff --git a/devnet/docker/icon-tezos/scripts/token.javascore.sh b/devnet/docker/icon-tezos/scripts/token.javascore.sh new file mode 100644 index 00000000..71e466d0 --- /dev/null +++ b/devnet/docker/icon-tezos/scripts/token.javascore.sh @@ -0,0 +1,267 @@ +#!/bin/bash +######################################## javascore service methods - start ###################################### +source utils.sh +source rpc.sh +source keystore.sh +goloop_lastblock() { + goloop rpc lastblock +} + +extract_chain_height_and_validator() { + cd $CONFIG_DIR + local icon_block_height=$(goloop_lastblock | jq -r .height) + echo $icon_block_height > icon.chain.height + echo $(URI=$ICON_ENDPOINT HEIGHT=$(decimal2Hex $(($icon_block_height - 1))) $ICONBRIDGE_BIN_DIR/iconvalidators | jq -r .hash) > icon.chain.validators +} + +deploy_javascore_bmc() { + cd $CONFIG_DIR + if [ ! -f icon.addr.bmcbtp ]; then + echo "deploying javascore BMC" + extract_chain_height_and_validator + goloop rpc sendtx deploy $CONTRACTS_DIR/javascore/bmc.jar \ + --content_type application/java \ + --param _net=$(cat net.btp.icon) | jq -r . >tx/tx.icon.bmc + sleep 5 + extract_scoreAddress tx/tx.icon.bmc icon.addr.bmc + echo "btp://$(cat net.btp.icon)/$(cat icon.addr.bmc)" >icon.addr.bmcbtp + fi +} + +deploy_javascore_bts() { + echo "deploying javascore bts" + cd $CONFIG_DIR + if [ ! -f icon.addr.bts ]; then + #local bts_fee_numerator=100 + #local bts_fixed_fee=5000 + goloop rpc sendtx deploy $CONTRACTS_DIR/javascore/bts.jar \ + --content_type application/java \ + --param _name="${ICON_NATIVE_COIN_NAME[0]}" \ + --param _bmc=$(cat icon.addr.bmc) \ + --param _decimals=$(decimal2Hex $3) \ + --param _feeNumerator=$(decimal2Hex $2) \ + --param _fixedFee=$(decimal2Hex $1) \ + --param _serializedIrc2=$(xxd -p $CONTRACTS_DIR/javascore/irc2Tradeable.jar | tr -d '\n') | jq -r . > tx/tx.icon.bts + sleep 5 + extract_scoreAddress tx/tx.icon.bts icon.addr.bts + fi +} + +deploy_javascore_token() { + echo "deploying javascore IRC2Token " $2 + cd $CONFIG_DIR + if [ ! -f icon.addr.$2 ]; then + goloop rpc sendtx deploy $CONTRACTS_DIR/javascore/irc2.jar \ + --content_type application/java \ + --param _name="$1" \ + --param _symbol=$2 \ + --param _initialSupply="0x5f5e100" \ + --param _decimals="0x12" | jq -r . >tx/tx.icon.$2 + sleep 5 + extract_scoreAddress tx/tx.icon.$2 icon.addr.$2 + fi +} + + +configure_javascore_add_bmc_owner() { + echo "bmc Add Owner" + echo $CONFIG_DIR/keystore/icon.bmc.wallet.json + local icon_bmc_owner=$(cat $CONFIG_DIR/keystore/icon.bmc.wallet.json | jq -r .address) + cd $CONFIG_DIR + local is_owner=$(goloop rpc call \ + --to $(cat icon.addr.bmc) \ + --method isOwner \ + --param _addr=$icon_bmc_owner | jq -r .) + if [ "$is_owner" == "0x0" ]; then + goloop rpc sendtx call --to $(cat icon.addr.bmc) \ + --method addOwner \ + --param _addr=$icon_bmc_owner | jq -r . > tx/addbmcowner.icon + sleep 3 + ensure_txresult tx/addbmcowner.icon + fi +} + +configure_javascore_bmc_setFeeAggregator() { + echo "bmc setFeeAggregator" + cd $CONFIG_DIR + local FA=$(cat $CONFIG_DIR/keystore/icon.fa.wallet.json | jq -r .address) + goloop rpc sendtx call --to $(cat icon.addr.bmc) \ + --method setFeeAggregator \ + --param _addr=${FA} | jq -r . >tx/setFeeAggregator.icon + sleep 3 + ensure_txresult tx/setFeeAggregator.icon + + goloop rpc sendtx call --to $(cat icon.addr.bmc) \ + --method setFeeGatheringTerm \ + --param _value=$FEE_GATHERING_INTERVAL | jq -r . >tx/setFeeGatheringTerm.icon + sleep 3 + ensure_txresult tx/setFeeGatheringTerm.icon +} + +configure_javascore_add_bts() { + echo "bmc add bts" + cd $CONFIG_DIR + local hasBTS=$(goloop rpc call \ + --to $(cat icon.addr.bmc) \ + --method getServices | jq -r .bts) + if [ "$hasBTS" == "null" ]; then + goloop rpc sendtx call --to $(cat icon.addr.bmc) \ + --method addService \ + --value 0 \ + --param _addr=$(cat icon.addr.bts) \ + --param _svc="bts" | jq -r . >tx/addService.icon + sleep 3 + ensure_txresult tx/addService.icon + fi + sleep 5 +} + +configure_javascore_add_bts_owner() { + echo "Add bts Owner" + local icon_bts_owner=$(cat $CONFIG_DIR/keystore/icon.bts.wallet.json | jq -r .address) + cd $CONFIG_DIR + local is_owner=$(goloop rpc call \ + --to $(cat icon.addr.bts) \ + --method isOwner \ + --param _addr="$icon_bts_owner" | jq -r .) + if [ "$is_owner" == "0x0" ]; then + goloop rpc sendtx call --to $(cat icon.addr.bts) \ + --method addOwner \ + --param _addr=$icon_bts_owner | jq -r . >tx/addBtsOwner.icon + sleep 3 + ensure_txresult tx/addBtsOwner.icon + fi +} + +configure_javascore_bts_setICXFee() { + echo "bts set fee" ${ICON_NATIVE_COIN_SYM[0]} + #local bts_fee_numerator=100 + #local bts_fixed_fee=5000 + cd $CONFIG_DIR + goloop rpc sendtx call --to $(cat icon.addr.bts) \ + --method setFeeRatio \ + --param _name="${ICON_NATIVE_COIN_NAME[0]}" \ + --param _feeNumerator=$(decimal2Hex $2) \ + --param _fixedFee=$(decimal2Hex $1) | jq -r . >tx/setICXFee.icon + sleep 3 + ensure_txresult tx/setICXFee.icon +} + +configure_javascore_addLink() { + echo "BMC: Add Link to BSC BMC:" + cd $CONFIG_DIR + if [ ! -f icon.configure.addLink ]; then + goloop rpc sendtx call --to $(cat icon.addr.bmc) \ + --method addLink \ + --param _link=$(cat bsc.addr.bmcbtp) | jq -r . >tx/addLink.icon + sleep 3 + ensure_txresult tx/addLink.icon + echo "addedLink" > icon.configure.addLink + fi +} + +configure_javascore_setLinkHeight() { + echo "BMC: SetLinkHeight" + cd $CONFIG_DIR + if [ ! -f icon.configure.setLink ]; then + goloop rpc sendtx call --to $(cat icon.addr.bmc) \ + --method setLinkRxHeight \ + --param _link=$(cat bsc.addr.bmcbtp) \ + --param _height=$(cat bsc.chain.height)| jq -r . >tx/setLinkRxHeight.icon + sleep 3 + ensure_txresult tx/setLinkRxHeight.icon + echo "setLink" > icon.configure.setLink + fi +} + +configure_bmc_javascore_addRelay() { + echo "Adding bsc Relay" + local icon_bmr_owner=$(cat $CONFIG_DIR/keystore/icon.bmr.wallet.json | jq -r .address) + echo $icon_bmr_owner + sleep 5 + echo "Starting" + cd $CONFIG_DIR + if [ ! -f icon.configure.addRelay ]; then + goloop rpc sendtx call --to $(cat icon.addr.bmc) \ + --method addRelay \ + --param _link=$(cat bsc.addr.bmcbtp) \ + --param _addr=${icon_bmr_owner} | jq -r . >tx/addRelay.icon + sleep 3 + ensure_txresult tx/addRelay.icon + echo "addRelay" > icon.configure.addRelay + fi +} + +configure_bmc_javascore_removeRelay() { + cd $CONFIG_DIR + echo "BMC BTP Address" + cat bsc.addr.bmcbtp + sleep 5 + echo "Starting.." + if [ ! -f icon.configure.removeRelay ]; then + goloop rpc sendtx call --to $(cat icon.addr.bmc) \ + --method removeRelay \ + --param _link=$(cat bsc.addr.bmcbtp) \ + --param _addr=$1 | jq -r . >tx/removeRelay.icon + sleep 3 + ensure_txresult tx/removeRelay.icon + echo "removeRelay" > icon.configure.removeRelay + fi +} + + +configure_javascore_register_native_token() { + echo "Register Native Token " $2 + cd $CONFIG_DIR + #local bts_fee_numerator=100 + #local bts_fixed_fee=5000 + if [ ! -f icon.register.coin$2 ]; then + goloop rpc sendtx call --to $(cat icon.addr.bts) \ + --method register \ + --param _name="$1" \ + --param _symbol=$2 \ + --param _decimals=$(decimal2Hex $5) \ + --param _addr=$(cat icon.addr.$2) \ + --param _feeNumerator=$(decimal2Hex $4) \ + --param _fixedFee=$(decimal2Hex $3) | jq -r . >tx/register.coin.$2 + sleep 5 + ensure_txresult tx/register.coin.$2 + echo "registered "$2 > icon.register.coin$2 + fi +} + + +configure_javascore_register_wrapped_coin() { + echo "Register Wrapped Coin " $2 + cd $CONFIG_DIR + #local bts_fee_numerator=100 + #local bts_fixed_fee=5000 + if [ ! -f icon.register.coin$2 ]; then + goloop rpc sendtx call --to $(cat icon.addr.bts) \ + --method register \ + --param _name="$1" \ + --param _symbol=$2 \ + --param _decimals=$(decimal2Hex $5) \ + --param _feeNumerator=$(decimal2Hex $4) \ + --param _fixedFee=$(decimal2Hex $3) | jq -r . >tx/register.coin.$2 + sleep 5 + ensure_txresult tx/register.coin.$2 + echo $2 > icon.register.coin$2 + fi +} + +get_btp_icon_coinId() { + echo "Get BTP Icon Addr " $2 + cd $CONFIG_DIR + goloop rpc call --to $(cat icon.addr.bts) \ + --method coinId \ + --param _coinName="$1" | jq -r . >tx/icon.coinId.$2 + if [ "$(cat $CONFIG_DIR/tx/icon.coinId.$2)" == "null" ]; + then + echo "Error Gettting CoinAddress icon."$2 + return 1 + else + cat $CONFIG_DIR/tx/icon.coinId.$2 >$CONFIG_DIR/icon.addr.coin$2 + fi + sleep 5 +} diff --git a/devnet/docker/icon-tezos/scripts/token.smartpy.sh b/devnet/docker/icon-tezos/scripts/token.smartpy.sh new file mode 100644 index 00000000..ad63d2b7 --- /dev/null +++ b/devnet/docker/icon-tezos/scripts/token.smartpy.sh @@ -0,0 +1,63 @@ +#!/bin/bash +## smarpy service methods - start ### + +# source utils.sh +# source prc.sh +# source keystore.sh + +tz_lastBlock() { + octez-client rpc get /chains/main/blocks/head/header +} + +extract_chainHeight() { + # cd $CONFIG_DIR + local tz_block_height=$(tz_lastBlock | jq -r .level) + echo $tz_block_height > tz.chain.height +} + +deploy_smartpy_bmc_management(){ + if [ ! -f tz.addr.bmcmanagementbtp ]; then + echo "deploying bmc_management" + extract_chainHeight + cd ~/GoProjects/icon-bridge/smartpy/bmc + npm run compile bmc_management + local deploy=$(npm run deploy bmc_management @GHOSTNET) + sleep 5 + deploy=${deploy#*::} + echo $deploy > tz.addr.bmc_management + echo "btp://0x63.tezos/$(cat tz.addr.bmc)" > tz.addr.bmcmanagementbtp + fi +} + +deploy_smartpy_bmc_periphery(){ + if [ ! -f tz.addr.bmcperipherytbtp ]; then + echo "deploying bmc_periphery" + cd ~/GoProjects/icon-bridge/smartpy/bmc + npm run compile bmc_periphery + local deploy=$(npm run deploy bmc_periphery @GHOSTNET) + sleep 5 + deploy=${deploy#*::} + echo $deploy > tz.addr.bmc_periphery + echo "btp://0x63.tezos/$(cat tz.addr.bmc_periphery)" > tz.addr.bmcperipherybtp + fi +} + +deploy_smartpy_bts_periphery(){ + if [ ! -f tz.addr.btsperipherybtp ]; then + echo "deploying bts_periphery" + cd ~/GoProjects/icon-bridge/smartpy/bts + npm run compile bts_periphery + local deploy=$(npm run deploy bts_periphery @GHOSTNET) + sleep 5 + deploy=${deploy#*::} + echo $deploy > tz.addr.bts_periphery + fi +} + +# bts core +# bts owner manager + + + + +deploy_smartpy_bmc \ No newline at end of file From 75a626125767a095e3edf16467ff491c2b7be2eb Mon Sep 17 00:00:00 2001 From: suyogadhikari Date: Wed, 17 May 2023 11:23:06 +0545 Subject: [PATCH 069/211] add(bmc): setters added to set bmc management address --- smartpy/bmc/contracts/src/bmc_periphery.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/smartpy/bmc/contracts/src/bmc_periphery.py b/smartpy/bmc/contracts/src/bmc_periphery.py index 644f841d..044b755f 100644 --- a/smartpy/bmc/contracts/src/bmc_periphery.py +++ b/smartpy/bmc/contracts/src/bmc_periphery.py @@ -21,16 +21,26 @@ class BMCPreiphery(sp.Contract, rlp_decode.DecodeLibrary, rlp_encode.EncodeLibra BMCRevertUnknownHandleBTPError = sp.string("UnknownHandleBTPError") BMCRevertUnknownHandleBTPMessage = sp.string("UnknownHandleBTPMessage") - def __init__(self, bmc_management_addr, helper_contract, parse_address): + def __init__(self, bmc_management_addr, helper_contract, parse_address, owner_address): self.init( helper=helper_contract, bmc_btp_address=sp.none, bmc_management=bmc_management_addr, parse_contract=parse_address, handle_btp_message_status=sp.none, - handle_btp_error_status=sp.none + handle_btp_error_status=sp.none, + owner_address = owner_address ) + def only_owner(self): + sp.verify(sp.sender == self.data.owner_address, "Unauthorized") + + @sp.entry_point + def set_bmc_management_addr(self, params): + sp.set_type(params, sp.TAddress) + self.only_owner() + self.data.bmc_management = params + @sp.entry_point def set_bmc_btp_address(self, network): sp.set_type(network, sp.TString) @@ -357,15 +367,17 @@ def test(): alice = sp.test_account("Alice") helper = sp.test_account("Helper") parse_contract = sp.test_account("Parser") + owner = sp.test_account("Owner") bmc_management = sp.test_account("BMC Management") # bmc= sp.test_account("BMC") scenario = sp.test_scenario() - bmc = BMCPreiphery(bmc_management.address, helper.address, parse_contract.address) + bmc = BMCPreiphery(bmc_management.address, helper.address, parse_contract.address, owner.address) scenario += bmc # bmc.handle_relay_message(sp.record(prev="demo string", msg=sp.bytes("0x0dae11"))).run(sender=alice) sp.add_compilation_target("bmc_periphery", BMCPreiphery(bmc_management_addr=sp.address("KT1Uiycjx4iXdjKFfR2kAo2NUdEtQ6PmDX4Y"), helper_contract=sp.address("KT1Q5erZm7Pp8UJywK1nkiP8QPCRmyUotUMq"), - parse_address=sp.address("KT1XgRyjQPfpfwNrvYYpgERpYpCrGh24aoPX"))) + parse_address=sp.address("KT1XgRyjQPfpfwNrvYYpgERpYpCrGh24aoPX"), + owner_address=sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP"))) From fb303cc6318e01caa212c21d119cc3d5a196bcf3 Mon Sep 17 00:00:00 2001 From: suyogadhikari Date: Wed, 17 May 2023 11:24:05 +0545 Subject: [PATCH 070/211] add(bts): setters added to set bmc address and bts core address --- smartpy/bts/contracts/src/bts_periphery.py | 24 +++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index ab9ef646..ccf86844 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -14,9 +14,10 @@ class BTPPreiphery(sp.Contract, rlp_decode.DecodeLibrary, rlp_encode.EncodeLibra MAX_BATCH_SIZE = sp.nat(15) - def __init__(self, bmc_address, bts_core_address, helper_contract, parse_address): + def __init__(self, bmc_address, bts_core_address, helper_contract, parse_address, owner_address): self.update_initial_storage( bmc=bmc_address, + owner=owner_address, bts_core=bts_core_address, blacklist=sp.map(tkey=sp.TAddress, tvalue=sp.TBool), token_limit=sp.map(tkey=sp.TString, tvalue=sp.TNat), @@ -30,9 +31,24 @@ def __init__(self, bmc_address, bts_core_address, helper_contract, parse_address def only_bmc(self): sp.verify(sp.sender == self.data.bmc, "Unauthorized") + def only_owner(self): + sp.verify(sp.sender == self.data.owner, "Unauthorized") + def only_bts_core(self): sp.verify(sp.sender == self.data.bts_core, "Unauthorized") + @sp.entry_point + def set_bmc_address(self, params): + sp.set_type(params, sp.TAddress) + self.only_owner() + self.data.bmc = params + + @sp.entry_point + def set_bts_core_address(self, params): + sp.set_type(params, sp.TAddress) + self.only_owner() + self.data.bts_core = params + @sp.onchain_view() def has_pending_request(self): """ @@ -429,9 +445,10 @@ def test(): admin = sp.test_account("Admin") bts_core = sp.test_account("BTS") helper = sp.test_account("Helper") + owner = sp.test_account("Owner") scenario = sp.test_scenario() - counter = BTPPreiphery(bmc.address, bts_core.address, helper.address, admin.address) + counter = BTPPreiphery(bmc.address, bts_core.address, helper.address, admin.address, owner.address) scenario += counter # counter.add_to_blacklist({0:"tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"}).run(sender=counter.address) @@ -459,4 +476,5 @@ def test(): sp.add_compilation_target("bts_periphery", BTPPreiphery(bmc_address=sp.address("KT1UrLqhQHDC3mJw9BUrqsiix7JRbxTsvWJu"), bts_core_address=sp.address("KT1JAippuMfS6Bso8DGmigmTdkgEZUxQxYyX"), helper_contract=sp.address("KT1Q5erZm7Pp8UJywK1nkiP8QPCRmyUotUMq"), - parse_address=sp.address("KT1EKPrSLWjWViZQogFgbc1QmztkR5UGXEWa"))) \ No newline at end of file + parse_address=sp.address("KT1EKPrSLWjWViZQogFgbc1QmztkR5UGXEWa"), + owner_address = sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP")) ) \ No newline at end of file From 26ee7215fe88d61ff9db6771ff350a457bbc5e47 Mon Sep 17 00:00:00 2001 From: suyogadhikari Date: Thu, 18 May 2023 06:23:18 +0545 Subject: [PATCH 071/211] fix(bmc): decode receipt proof fixed --- smartpy/bmc/contracts/src/RLP_decode_struct.py | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/smartpy/bmc/contracts/src/RLP_decode_struct.py b/smartpy/bmc/contracts/src/RLP_decode_struct.py index e5f516a2..1a19aa6f 100644 --- a/smartpy/bmc/contracts/src/RLP_decode_struct.py +++ b/smartpy/bmc/contracts/src/RLP_decode_struct.py @@ -140,7 +140,7 @@ def decode_receipt_proof(self, rlp): counter = sp.local("counter", 0) sp.for i in rlp_.items(): sp.if counter.value == 1: - temp_byt.value = i.value + temp_byt.value = sp.view("without_length_prefix", self.data.helper, i.value, t=sp.TBytes).open_some() sp.if counter.value == 0: rv_int.value = Utils2.Int.of_bytes(i.value) sp.if counter.value == 2: @@ -158,14 +158,8 @@ def decode_receipt_proof(self, rlp): seq= sp.TNat, message = sp.TBytes))) sp.for z in new_sub_list.items(): - starts_with = sp.slice(z.value, 0, 2).open_some() - sub_list.value = z.value - sp.if starts_with == sp.bytes("0xb846"): - sub_list.value = sp.slice(z.value, 2, sp.as_nat(sp.len(z.value) - 2)).open_some() - view_value = sp.view("decode_list", self.data.helper, sub_list.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - sp.for a in view_value.items(): - events.value[counter.value] = self.to_message_event(a.value) - counter.value = counter.value + 1 + events.value[counter.value] = self.to_message_event(z.value) + counter.value = counter.value + 1 return sp.record(index = rv_int.value, events = events.value, height = rv_int2.value) @@ -191,7 +185,7 @@ def decode_receipt_proofs(self, rlp): new_sub_list = sp.view("decode_list", self.data.helper, sub_list.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() counter.value = 0 sp.if sp.len(new_sub_list) > 0: - sp.for x in rlp_.items(): + sp.for x in new_sub_list.items(): receipt_proofs.value[counter.value] = self.decode_receipt_proof(x.value) counter.value = counter.value + 1 return receipt_proofs.value From e3511e37e5c8e68ec49e646703763e287927b8e7 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Thu, 18 May 2023 15:19:47 +0545 Subject: [PATCH 072/211] fix: icon tezos relay integration --- cmd/iconbridge/chain/bsc/sender.go | 6 + cmd/iconbridge/chain/icon/receiver.go | 12 +- cmd/iconbridge/chain/icon/sender.go | 21 ++- cmd/iconbridge/chain/icon/verifier.go | 24 ++- cmd/iconbridge/chain/tezos/client.go | 166 +++++++++++------- cmd/iconbridge/chain/tezos/receiver.go | 101 ++++------- cmd/iconbridge/chain/tezos/sender.go | 66 +++++-- cmd/iconbridge/chain/tezos/verifier.go | 2 + cmd/iconbridge/example.config.json | 23 +-- cmd/iconbridge/main.go | 2 +- cmd/iconbridge/relay/multi_relay.go | 6 +- cmd/iconbridge/relay/relay.go | 76 +++++--- common/wallet/keystore.go | 7 + common/wallet/wallet_tezos.go | 38 ++++ .../icon-tezos/scripts/token.smartpy.sh | 33 +++- 15 files changed, 381 insertions(+), 202 deletions(-) create mode 100644 common/wallet/wallet_tezos.go diff --git a/cmd/iconbridge/chain/bsc/sender.go b/cmd/iconbridge/chain/bsc/sender.go index 9bb17754..b7f85d67 100644 --- a/cmd/iconbridge/chain/bsc/sender.go +++ b/cmd/iconbridge/chain/bsc/sender.go @@ -335,3 +335,9 @@ func revertReason(data []byte) string { length := binary.BigEndian.Uint64(data[24:32]) return string(data[32 : 32+length]) } + +func Print(){ + for i:= 0;i<50;i++{ + fmt.Println("+") + } +} diff --git a/cmd/iconbridge/chain/icon/receiver.go b/cmd/iconbridge/chain/icon/receiver.go index 4ad3ac20..3da94ef4 100644 --- a/cmd/iconbridge/chain/icon/receiver.go +++ b/cmd/iconbridge/chain/icon/receiver.go @@ -154,8 +154,12 @@ func NewReceiver(src, dst chain.BTPAddress, } func (r *Receiver) newVerifier(opts *types.VerifierOptions) (*Verifier, error) { + fmt.Println("reached in new Validator of icon") + fmt.Println(opts.ValidatorsHash) validators, err := r.Client.GetValidatorsByHash(opts.ValidatorsHash) + fmt.Println("validator hash is", validators) if err != nil { + fmt.Println("error in validators", err) return nil, err } vr := Verifier{ @@ -174,7 +178,10 @@ func (r *Receiver) newVerifier(opts *types.VerifierOptions) (*Verifier, error) { if err != nil { return nil, err } + fmt.Println("has gotten the headers and votes") + ok, err := vr.Verify(header, votes) + fmt.Println("has verified the header ", ok) if !ok { err = errors.New("verification failed") } @@ -304,13 +311,14 @@ func handleVerifierBlockRequests(requestCh chan *verifierBlockRequest, client IC } func (r *Receiver) receiveLoop(ctx context.Context, startHeight, startSeq uint64, callback func(rs []*chain.Receipt) error) (err error) { - + fmt.Println("reached in icons reveive loop in reveiveloop") blockReq, logFilter := r.blockReq, r.logFilter // copy blockReq.Height, logFilter.seq = types.NewHexInt(int64(startHeight)), startSeq var vr IVerifier if r.opts.Verifier != nil { + fmt.Println("should reach in not nil case") vr, err = r.newVerifier(r.opts.Verifier) if err != nil { return err @@ -378,7 +386,7 @@ loop: } }(ctxMonitorBlock, cancelMonitorBlock) - // sync verifier + // sync verifier disabled if vr != nil { if err := r.syncVerifier(vr, next); err != nil { return errors.Wrapf(err, "sync verifier: %v", err) diff --git a/cmd/iconbridge/chain/icon/sender.go b/cmd/iconbridge/chain/icon/sender.go index b5529583..ffb7f129 100644 --- a/cmd/iconbridge/chain/icon/sender.go +++ b/cmd/iconbridge/chain/icon/sender.go @@ -99,6 +99,8 @@ func hexInt2Uint64(hi types.HexInt) uint64 { // BMCLinkStatus // Returns the BMCLinkStatus for "src" link func (s *sender) Status(ctx context.Context) (*chain.BMCLinkStatus, error) { + fmt.Println("reached in icons status") + if ctx.Err() != nil { return nil, ctx.Err() } @@ -135,6 +137,8 @@ func (s *sender) Status(ctx context.Context) (*chain.BMCLinkStatus, error) { func (s *sender) Segment( ctx context.Context, msg *chain.Message, ) (tx chain.RelayTx, newMsg *chain.Message, err error) { + fmt.Println("reached in segment of icon") + if ctx.Err() != nil { return nil, nil, ctx.Err() } @@ -145,6 +149,7 @@ func (s *sender) Segment( } if len(msg.Receipts) == 0 { + fmt.Println("should not be zeo") return nil, msg, nil } @@ -162,6 +167,7 @@ func (s *sender) Segment( for i, receipt := range msg.Receipts { rlpEvents, err := codec.RLP.MarshalToBytes(receipt.Events) if err != nil { + fmt.Println("shouldnot be error") return nil, nil, err } rlpReceipt, err := codec.RLP.MarshalToBytes(&chain.RelayReceipt{ @@ -170,6 +176,7 @@ func (s *sender) Segment( Events: rlpEvents, }) if err != nil { + fmt.Println("shouldnot be error again") return nil, nil, err } newMsgSize := msgSize + uint64(len(rlpReceipt)) @@ -183,14 +190,16 @@ func (s *sender) Segment( message, err := codec.RLP.MarshalToBytes(rm) if err != nil { + fmt.Println("should not be here here also") return nil, nil, err } tx, err = s.newRelayTx(ctx, msg.From.String(), message) if err != nil { + fmt.Println("shouldnot be error in new tx") return nil, nil, err } - + fmt.Println("should reach here without error") return tx, newMsg, nil } @@ -247,9 +256,11 @@ func (tx *relayTx) ID() interface{} { func (tx *relayTx) Send(ctx context.Context) error { tx.cl.log.WithFields(log.Fields{ "prev": tx.Prev}).Debug("handleRelayMessage: send tx") - +fmt.Println("reached in sender of icon") +Print() SignLoop: for { + fmt.Println("transaction sign") if err := tx.cl.SignTransaction(tx.w, tx.txParam); err != nil { return err } @@ -375,3 +386,9 @@ func mapErrorWithTransactionResult(txr *types.TransactionResult, err error) erro } return err } + +func Print(){ + for i:= 0;i<50;i++{ + fmt.Println("Sender") + } +} diff --git a/cmd/iconbridge/chain/icon/verifier.go b/cmd/iconbridge/chain/icon/verifier.go index dbe17e5b..8851950a 100644 --- a/cmd/iconbridge/chain/icon/verifier.go +++ b/cmd/iconbridge/chain/icon/verifier.go @@ -2,16 +2,15 @@ package icon import ( "fmt" - "github.com/icon-project/icon-bridge/cmd/iconbridge/chain/icon/types" "sync" + "github.com/icon-project/icon-bridge/cmd/iconbridge/chain/icon/types" + "github.com/icon-project/goloop/common" "github.com/icon-project/goloop/common/codec" "github.com/icon-project/icon-bridge/common/crypto" ) - - const ( VoteTypePrevote types.VoteType = iota VoteTypePrecommit @@ -38,12 +37,12 @@ type TxResult struct { CumulativeStepUsed []byte StepUsed []byte StepPrice []byte - LogsBloom []byte - EventLogs []types.EventLog - ScoreAddress []byte - EventLogsHash common.HexBytes - TxIndex types.HexInt - BlockHeight types.HexInt + LogsBloom []byte + EventLogs []types.EventLog + ScoreAddress []byte + EventLogsHash common.HexBytes + TxIndex types.HexInt + BlockHeight types.HexInt } type Verifier struct { @@ -92,9 +91,14 @@ func (vr *Verifier) Verify(blockHeader *types.BlockHeader, votes []byte) (ok boo numVotes := 0 validators := make(map[common.Address]struct{}) + // fmt.Printf("height: %d, votesHash: %v\n", blockHeader.Height, blockHeader.VotesHash) + // fmt.Printf("nextValidatorsHash: %v\n", nextValidatorsHash) + // fmt.Print("listValidators:") for _, val := range listValidators { + // fmt.Printf("%v, ", &val) validators[val] = struct{}{} } + // fmt.Println() for _, item := range cvl.Items { vote.Timestamp = item.Timestamp @@ -103,6 +107,7 @@ func (vr *Verifier) Verify(blockHeader *types.BlockHeader, votes []byte) (ok boo continue // skip error } address := common.NewAccountAddressFromPublicKey(pub) + // fmt.Printf("cvl.Items.address(%d):%v\n", i, address) if address == nil { continue } @@ -114,6 +119,7 @@ func (vr *Verifier) Verify(blockHeader *types.BlockHeader, votes []byte) (ok boo return true, nil } } + // fmt.Println("VotesCount:", numVotes) return false, fmt.Errorf("insufficient votes") } diff --git a/cmd/iconbridge/chain/tezos/client.go b/cmd/iconbridge/chain/tezos/client.go index 07c0b17f..78ae1eab 100644 --- a/cmd/iconbridge/chain/tezos/client.go +++ b/cmd/iconbridge/chain/tezos/client.go @@ -22,9 +22,9 @@ import ( ) const ( - DefaultSendTransactionRetryInterval = 30 * time.Second + DefaultSendTransactionRetryInterval = 30 * time.Second DefaultGetTransactionResultPollingInterval = 15 * time.Second - DefaultBlockWaitInterval = 15 * time.Second + DefaultBlockWaitInterval = 15 * time.Second ) type IClient interface { @@ -42,7 +42,6 @@ type IClient interface { GetStatus(ctx context.Context, contr *contract.Contract) (TypesLinkStats, error) HandleRelayMessage(ctx context.Context, callArgs contract.CallArguments) (*rpc.Receipt, error) - } // tezos periphery @@ -56,19 +55,19 @@ type TypesLinkStats struct { type Client struct { Log log.Logger // Ctx context.Context - Cl *rpc.Client - Contract *contract.Contract + Cl *rpc.Client + Contract *contract.Contract blockLevel int64 } -func (c *Client) SignTransaction() rpc.CallOptions{ +func (c *Client) SignTransaction() rpc.CallOptions { pK := tezos.MustParsePrivateKey("edskRz1HoD3cWkmWhCNS5LjBrJNWChGuKWB4HnVoN5UqVsUCpcNJR67ZxKs965u8RgRwptrtGc2ufYZoeECgB77RKm1gTbQ6eB") opts := rpc.DefaultOptions opts.Signer = signer.NewFromKey(pK) return opts } -func (c *Client) SendTransaction(ctx context.Context, connection *contract.Contract, parameters micheline.Parameters, sender tezos.Address) (*rpc.Receipt, error){ +func (c *Client) SendTransaction(ctx context.Context, connection *contract.Contract, parameters micheline.Parameters, sender tezos.Address) (*rpc.Receipt, error) { args := contract.NewTxArgs() args.WithParameters(parameters) @@ -91,15 +90,15 @@ func (c *Client) SendTransaction(ctx context.Context, connection *contract.Contr return result, nil } -func (c *Client) GetLastBlock(ctx context.Context, connection *rpc.Client) (*rpc.Block, error){ +func (c *Client) GetLastBlock(ctx context.Context, connection *rpc.Client) (*rpc.Block, error) { block, err := connection.GetHeadBlock(ctx) - if err != nil{ + if err != nil { return nil, err } return block, nil } -func (c *Client) GetBlockByHeight(ctx context.Context, connection *rpc.Client, blockLevel int64)(*rpc.Block, error){ +func (c *Client) GetBlockByHeight(ctx context.Context, connection *rpc.Client, blockLevel int64) (*rpc.Block, error) { block, err := connection.GetBlock(ctx, rpc.BlockLevel(blockLevel)) if err != nil { return nil, err @@ -110,12 +109,12 @@ func (c *Client) GetBlockByHeight(ctx context.Context, connection *rpc.Client, b func (c *Client) GetBlockHeightByHash(ctx context.Context, connection *rpc.Client, hash tezos.BlockHash) (uint64, error) { block, err := connection.GetBlock(ctx, hash) if err != nil { - return 0, err + return 0, err } - return uint64(block.Header.Level), nil + return uint64(block.Header.Level), nil } -func (c *Client) GetBlockHeaderByHeight(ctx context.Context, connection *rpc.Client, blockLevel int64)(*rpc.BlockHeader, error){ +func (c *Client) GetBlockHeaderByHeight(ctx context.Context, connection *rpc.Client, blockLevel int64) (*rpc.BlockHeader, error) { block, err := connection.GetBlockHeader(ctx, rpc.BlockLevel(blockLevel)) if err != nil { return nil, err @@ -123,22 +122,22 @@ func (c *Client) GetBlockHeaderByHeight(ctx context.Context, connection *rpc.Cli return block, nil } -func (c *Client) MonitorBlock(ctx context.Context, blockLevel int64, verifier IVerifier, callback func(v []*chain.Receipt) error) (error) { +func (c *Client) MonitorBlock(ctx context.Context, blockLevel int64, verifier IVerifier, callback func(v []*chain.Receipt) error) error { fmt.Println("reached in monitor block") relayTicker := time.NewTicker(DefaultBlockWaitInterval) defer relayTicker.Stop() for { select { - case <- ctx.Done(): + case <-ctx.Done(): return fmt.Errorf("Context done") - case <- relayTicker.C: + case <-relayTicker.C: fmt.Println("*************************************************************") fmt.Print("Trying to fetch block for blockLevel ") fmt.Println(blockLevel) block, err := c.GetBlockByHeight(ctx, c.Cl, blockLevel) - + if err != nil { fmt.Println(err) fmt.Println("reducing the block level") @@ -147,7 +146,7 @@ func (c *Client) MonitorBlock(ctx context.Context, blockLevel int64, verifier IV fmt.Println(blockLevel) continue } - + header, err := c.GetBlockHeaderByHeight(ctx, c.Cl, blockLevel) if err != nil { return err @@ -161,22 +160,20 @@ func (c *Client) MonitorBlock(ctx context.Context, blockLevel int64, verifier IV return err } c.blockLevel = blockLevel - + err = verifier.Update(header) if err != nil { fmt.Println(err) - return err + return err } - PrettyEncode(header) - blockOperations := block.Operations - + for i := 0; i < len(blockOperations); i++ { - for j := 0; j < len(blockOperations[i]); j ++{ + for j := 0; j < len(blockOperations[i]); j++ { for _, operation := range blockOperations[i][j].Contents { switch operation.Kind() { case tezos.OpTypeTransaction: @@ -204,13 +201,13 @@ func (c *Client) MonitorBlock(ctx context.Context, blockLevel int64, verifier IV } func returnTxMetadata(tx *rpc.Transaction, contractAddress tezos.Address) ([]*chain.Receipt, error) { - _, err := fmt.Println(tx.Destination) - if err != nil { - return nil, err - } + // _, err := fmt.Println(tx.Destination) + // if err != nil { + // return nil, err + // } address := tx.Destination - - var receipts []*chain.Receipt + + var receipts []*chain.Receipt if address.ContractAddress() == contractAddress.ContractAddress() { fmt.Println("Address matched") fmt.Println("****************") @@ -241,25 +238,60 @@ func returnTxMetadata(tx *rpc.Transaction, contractAddress tezos.Address) ([]*ch return receipts, nil } -func (c *Client) GetClient()(*rpc.Client) { +func returnTxMetadata3(tx *rpc.Transaction, contractAddress tezos.Address, height uint64) (*chain.Receipt, error) { + fmt.Println("reache to return tx metadata3", height) + receipt := &chain.Receipt{} + + for i := 0; i < len(tx.Metadata.InternalResults); i++ { + fmt.Println("reached in for") + internalResults := tx.Metadata.InternalResults[i] + if internalResults.Kind.String() == "event" && internalResults.Source.ContractAddress() == contractAddress.ContractAddress() { + fmt.Println("Address matched") + if internalResults.Tag == "Message" { + message := internalResults.Payload.Args[0].Bytes + next := internalResults.Payload.Args[1].Args[0].String + seq := internalResults.Payload.Args[1].Args[1].Int + + var events []*chain.Event + events = append(events, &chain.Event{ + Message: message, + Next: chain.BTPAddress(next), + Sequence: seq.Uint64(), + }) + + receipt.Index = uint64(i) + receipt.Height = height + receipt.Events = events + fmt.Println(message, next, seq) + } + + } + } + return receipt, nil +} + +func (c *Client) GetClient() *rpc.Client { return c.Cl } -func (c *Client) GetBalance(ctx context.Context, connection *rpc.Client, account tezos.Address, blockLevel int64)(*big.Int, error){ +func (c *Client) GetBalance(ctx context.Context, connection *rpc.Client, account tezos.Address, blockLevel int64) (*big.Int, error) { balance, err := connection.GetContractBalance(ctx, account, rpc.BlockLevel(blockLevel)) if err != nil { return nil, err } - return balance.Big(), nil + return balance.Big(), nil } -func (c *Client) GetStatus(ctx context.Context, contr *contract.Contract, link string) (TypesLinkStats, error){ +func (c *Client) GetStatus(ctx context.Context, contr *contract.Contract, link string) (TypesLinkStats, error) { fmt.Println("reached in get status of tezos") prim := micheline.Prim{} + // to be removed later + link = "btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW" - in := "{ \"prim\": \"Right\", \"args\": [ { \"prim\": \"Right\", \"args\": [ { \"string\": \""+ link + "\" } ] } ] }" + in := "{ \"string\": \"" + link + "\" }" fmt.Println(in) + fmt.Println(contr.Address().ContractAddress()) if err := prim.UnmarshalJSON([]byte(in)); err != nil { fmt.Println("couldnot unmarshall empty string") @@ -267,24 +299,27 @@ func (c *Client) GetStatus(ctx context.Context, contr *contract.Contract, link s return *new(TypesLinkStats), err } - status, err := contr.RunView(ctx, "get_status", prim) + result, err := contr.RunView(ctx, "get_status", prim) if err != nil { + fmt.Println(err) return *new(TypesLinkStats), err } - var stats TypesLinkStats - err = status.Decode(stats) - if err != nil { - return *new(TypesLinkStats), err - } - return stats, nil + linkStats := &TypesLinkStats{} + + linkStats.CurrentHeight = result.Args[0].Args[0].Int + linkStats.RxHeight = result.Args[0].Args[1].Int + linkStats.RxSeq = result.Args[1].Int + linkStats.TxSeq = result.Args[2].Int + + return *linkStats, nil } -func (c *Client) GetOperationByHash(ctx context.Context, clinet *rpc.Client, blockHash tezos.BlockHash, list int, pos int) (*rpc.Operation, error){ +func (c *Client) GetOperationByHash(ctx context.Context, clinet *rpc.Client, blockHash tezos.BlockHash, list int, pos int) (*rpc.Operation, error) { operation, err := clinet.GetBlockOperation(ctx, blockHash, list, pos) if err != nil { return nil, err } - return operation, nil + return operation, nil } func (c *Client) HandleRelayMessage(ctx context.Context, callArgs contract.CallArguments, opts *rpc.CallOptions) (*rpc.Receipt, error) { @@ -292,12 +327,14 @@ func (c *Client) HandleRelayMessage(ctx context.Context, callArgs contract.CallA result, err := c.Contract.Call(ctx, callArgs, opts) if err != nil { fmt.Println(err) + fmt.Println("because error") return nil, err } + fmt.Println(result) return result, nil } -func NewClient(uri string, src tezos.Address, l log.Logger) (*Client, error){ +func NewClient(uri string, src tezos.Address, l log.Logger) (*Client, error) { fmt.Println("uri is : " + uri) @@ -312,46 +349,51 @@ func NewClient(uri string, src tezos.Address, l log.Logger) (*Client, error){ return &Client{Log: l, Cl: c, Contract: conn}, nil } - - func PrettyEncode(data interface{}) error { var buffer bytes.Buffer - enc := json.NewEncoder(&buffer) - enc.SetIndent("", " ") - if err := enc.Encode(data); err != nil { - return err - } + enc := json.NewEncoder(&buffer) + enc.SetIndent("", " ") + if err := enc.Encode(data); err != nil { + return err + } fmt.Println(buffer.String()) - return nil + return nil } func returnTxMetadata2(block *rpc.Block, contractAddress tezos.Address, blockHeight int64, cl *Client) (bool, []*chain.Receipt, error) { blockOperations := block.Operations - + var tx *rpc.Transaction var receipt []*chain.Receipt for i := 0; i < len(blockOperations); i++ { - for j := 0; j < len(blockOperations[i]); j ++{ + for j := 0; j < len(blockOperations[i]); j++ { for _, operation := range blockOperations[i][j].Contents { switch operation.Kind() { case tezos.OpTypeTransaction: tx = operation.(*rpc.Transaction) - r, err := returnTxMetadata(tx, contractAddress) + r, err := returnTxMetadata3(tx, contractAddress, uint64(blockHeight)) if err != nil { return false, nil, err } - receipt = r + if len(r.Events) != 0 { + fmt.Println("r is not nil for ", uint64(blockHeight)) + receipt = append(receipt, r) + } } } } } // var transaction *rpc.Transaction - - if len(receipt) == 0 { - return false, receipt, nil - } + if len(receipt) == 0 { + return false, nil, nil + } + fmt.Println("found Message") return true, receipt, nil } - +func PrintU() { + for i := 0; i < 100; i++ { + fmt.Println("U") + } +} diff --git a/cmd/iconbridge/chain/tezos/receiver.go b/cmd/iconbridge/chain/tezos/receiver.go index dd4c4be0..1a0a1721 100644 --- a/cmd/iconbridge/chain/tezos/receiver.go +++ b/cmd/iconbridge/chain/tezos/receiver.go @@ -48,53 +48,9 @@ func (r *receiver) Subscribe(ctx context.Context, msgCh chan<- *chain.Message, o _errCh := make(chan error) - verifierOpts := &VerifierOptions{ - BlockHeight: int64(opts.Height), - } - - r.opts.Verifier = verifierOpts - - verifier, err := r.NewVerifier(ctx, r.opts.Verifier.BlockHeight) - fmt.Println("returned by the new verifier") - if err != nil { - _errCh <- err - return _errCh, err - } - - if err = r.SyncVerifier(ctx, verifier, r.opts.Verifier.BlockHeight + 1, - func (v []*chain.Receipt) error { - fmt.Println("has to reach in this callback ") - var vCP []*chain.Receipt - var events []*chain.Event - for _, receipt := range v{ - for _, event := range receipt.Events { - switch { - case event.Sequence == opts.Seq: - events = append(events, event) - opts.Seq++ - case event.Sequence > opts.Seq: - return fmt.Errorf("invalid event seq") - default: - fmt.Println("default?????") - events = append(events, event) - opts.Seq++ - - - } - } - receipt.Events = events - vCP = append(vCP, &chain.Receipt{Events: receipt.Events}) - } - if len(v) > 0 { - msgCh <- &chain.Message{Receipts: vCP} - } - fmt.Println("returned nill") - return nil - }); err != nil { - _errCh <- err - } - fmt.Println("reached to before monitor block") + fmt.Println(opts.Height) + fmt.Println(r.opts.SyncConcurrency) go func() { defer close(_errCh) @@ -106,17 +62,17 @@ func (r *receiver) Subscribe(ctx context.Context, msgCh chan<- *chain.Message, o } if err := r.receiveLoop(ctx, bn, func (blN *types.BlockNotification) error { - fmt.Println("has to reach in this callback ") + // fmt.Println("has to reach in this callback ", blN.Height.Uint64()) - if blN.Height.Uint64() != lastHeight + 1{ + if blN.Height.Uint64() != lastHeight { return fmt.Errorf( - "block notification: expected=%d, got %d", lastHeight + 1, blN.Height.Uint64()) + "block notification: expected=%d, got %d", lastHeight, blN.Height.Uint64()) } - var vCP []*chain.Receipt - var events []*chain.Event - v := blN.Receipts - for _, receipt := range v{ + // var events []*chain.Event + receipts := blN.Receipts + for _, receipt := range receipts{ + events := receipt.Events[:0] for _, event := range receipt.Events { switch { case event.Sequence == opts.Seq: @@ -124,17 +80,21 @@ func (r *receiver) Subscribe(ctx context.Context, msgCh chan<- *chain.Message, o opts.Seq++ case event.Sequence > opts.Seq: return fmt.Errorf("invalid event seq") + //TODO to be removed default: events = append(events, event) - opts.Seq++ + opts.Seq++ } } receipt.Events = events - vCP = append(vCP, &chain.Receipt{Events: receipt.Events}) + fmt.Println(receipt.Height) + fmt.Println("appending") + // vCP = append(vCP, &chain.Receipt{Events: receipt.Events}) } - if len(v) > 0 { + if len(receipts) > 0 { fmt.Println("reached to sending message") - msgCh <- &chain.Message{Receipts: vCP} + fmt.Println(receipts[0].Height) + msgCh <- &chain.Message{Receipts: receipts} } fmt.Println("returned nill") lastHeight++ @@ -169,22 +129,24 @@ func NewReceiver(src, dst chain.BTPAddress, urls []string, rawOpts json.RawMessa if len(urls) == 0 { return nil, fmt.Errorf("Empty urls") } - verifierOpts := &VerifierOptions{ - BlockHeight: int64(2468690), - } + // verifierOpts := &VerifierOptions{ + // BlockHeight: int64(2468690), + // } - receiverOpts := &ReceiverOptions{ - SyncConcurrency: 50, - Verifier: verifierOpts, - } + // receiverOpts := &ReceiverOptions{ + // SyncConcurrency: 50, + // Verifier: verifierOpts, + // } receiver := &receiver{ log: l, src: src, dst: dst, - opts: *receiverOpts, } + err = json.Unmarshal(rawOpts, &receiver.opts) + + if receiver.opts.SyncConcurrency < 1 { receiver.opts.SyncConcurrency = 1 } else if receiver.opts.SyncConcurrency > MonitorBlockMaxConcurrency { @@ -534,7 +496,7 @@ func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback fu close(qch) } default: - fmt.Println("reached in default of receive loop") + // fmt.Println("reached in default of receive loop") go func(q *bnq) { defer func() { time.Sleep(500 * time.Millisecond) @@ -557,16 +519,16 @@ func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback fu } if q.v.HasBTPMessage == nil { - fmt.Println("height: ", q.v.Height.Int64()) + // fmt.Println("height: ", q.v.Height.Int64()) block, err := r.client.GetBlockByHeight(ctx, r.client.Cl, q.v.Height.Int64()) if err != nil { return } q.v.Proposer = block.Metadata.Proposer - - + hasBTPMessage, receipt, err := returnTxMetadata2(block, r.client.Contract.Address(), q.v.Height.Int64(), r.client) + fmt.Println("has btp message", hasBTPMessage, q.v.Height.Uint64()) if err != nil { q.err = errors.Wrapf(err, "hasBTPMessage: %v", err) @@ -575,6 +537,7 @@ func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback fu q.v.HasBTPMessage = &hasBTPMessage if receipt != nil { + fmt.Println("should reach here for block", q.v.Height.Uint64()) q.v.Receipts = receipt } } diff --git a/cmd/iconbridge/chain/tezos/sender.go b/cmd/iconbridge/chain/tezos/sender.go index 39932955..995a0694 100644 --- a/cmd/iconbridge/chain/tezos/sender.go +++ b/cmd/iconbridge/chain/tezos/sender.go @@ -12,6 +12,8 @@ import ( "github.com/icon-project/icon-bridge/common/wallet" // "github.com/icon-project/icon-bridge/common/wallet" + "github.com/icon-project/icon-bridge/common/codec" + // "blockwatch.cc/tzgo/codec" "blockwatch.cc/tzgo/contract" "blockwatch.cc/tzgo/micheline" @@ -22,7 +24,9 @@ import ( ) const ( - txMaxDataSize = 32 * 1024 // 8 KB + txMaxDataSize = 32 * 1024 * 4 // 8 KB + txOverheadScale = 0.01 + defaultTxSizeLimit = txMaxDataSize / (1 + txOverheadScale) defaultSendTxTimeOut = 30 * time.Second // 30 seconds is the block time for tezos ) @@ -41,7 +45,7 @@ type sender struct { cls *Client blockLevel int64 opts senderOptions - w tezos.PrivateKey + w wallet.Wallet } func NewSender( @@ -57,7 +61,7 @@ func NewSender( log: l, src: src, dst: dstAddr, - w: tezos.MustParsePrivateKey("edskRz1HoD3cWkmWhCNS5LjBrJNWChGuKWB4HnVoN5UqVsUCpcNJR67ZxKs965u8RgRwptrtGc2ufYZoeECgB77RKm1gTbQ6eB"), + w: w, } if len(urls) == 0 { return nil, fmt.Errorf("Empty url") @@ -72,7 +76,8 @@ func NewSender( } func (s *sender) Balance(ctx context.Context) (balance, threshold *big.Int, err error){ - balance, err = s.cls.GetBalance(ctx, s.cls.Cl, s.w.Address(), s.cls.blockLevel) + address := tezos.MustParseAddress(s.w.Address()) + balance, err = s.cls.GetBalance(ctx, s.cls.Cl, address, s.cls.blockLevel) if err != nil { return nil, nil, err } @@ -81,18 +86,20 @@ func (s *sender) Balance(ctx context.Context) (balance, threshold *big.Int, err } func (s *sender) Segment(ctx context.Context, msg *chain.Message) (tx chain.RelayTx, newMsg *chain.Message, err error) { + if ctx.Err() != nil { return nil, nil, ctx.Err() } if s.opts.TxDataSizeLimit == 0{ - s.opts.TxDataSizeLimit = uint64(txMaxDataSize) + limit := defaultTxSizeLimit + s.opts.TxDataSizeLimit = uint64(limit) } - + fmt.Println("reached upto here") if len(msg.Receipts) == 0 { + fmt.Println("Probably gone from here") return nil, msg, nil } - rm := &chain.RelayMessage{ Receipts: make([][]byte, 0), } @@ -104,8 +111,9 @@ func (s *sender) Segment(ctx context.Context, msg *chain.Message) (tx chain.Rela Receipts: msg.Receipts, } + for i , receipt := range msg.Receipts{ - rlpEvents, err := json.Marshal(receipt.Events) // change to rlp bytes + rlpEvents, err := codec.RLP.MarshalToBytes(receipt.Events) //json.Marshal(receipt.Events) // change to rlp bytes chainReceipt := &chain.RelayReceipt{ Index: receipt.Index, @@ -113,7 +121,7 @@ func (s *sender) Segment(ctx context.Context, msg *chain.Message) (tx chain.Rela Events: rlpEvents, } - rlpReceipt, err := json.Marshal(chainReceipt) // change to rlp bytes + rlpReceipt, err := codec.RLP.MarshalToBytes(chainReceipt)//json.Marshal(chainReceipt) // change to rlp bytes if err != nil { return nil, nil, err } @@ -126,7 +134,7 @@ func (s *sender) Segment(ctx context.Context, msg *chain.Message) (tx chain.Rela msgSize = newMsgSize rm.Receipts = append(rm.Receipts, rlpReceipt) } - message, err := json.Marshal(rm) + message, err := codec.RLP.MarshalToBytes(rm) // json.Marshal(rm) if err != nil { return nil, nil, err } @@ -160,12 +168,15 @@ func (s *sender) Status(ctx context.Context) (link *chain.BMCLinkStatus, err err } func (s *sender) newRelayTx(ctx context.Context, prev string, message []byte) (*relayTx, error) { + + fmt.Println("reached in new relaytx") client := s.cls return &relayTx{ Prev: prev, Message: message, cl: client, + w: s.w, }, nil } @@ -175,6 +186,7 @@ type relayTx struct { cl *Client receipt *rpc.Receipt + w wallet.Wallet } func (tx *relayTx) ID() interface{}{ @@ -182,7 +194,7 @@ func (tx *relayTx) ID() interface{}{ } func (tx *relayTx) Send(ctx context.Context) (err error) { - fmt.Println("reached in sender") + fmt.Println("reached in sender of tezos") _ctx, cancel := context.WithTimeout(ctx, defaultSendTxTimeOut) defer cancel() @@ -201,13 +213,29 @@ func (tx *relayTx) Send(ctx context.Context) (err error) { opts := rpc.DefaultOptions - opts.Signer = signer.NewFromKey(tezos.MustParsePrivateKey("edskRz1HoD3cWkmWhCNS5LjBrJNWChGuKWB4HnVoN5UqVsUCpcNJR67ZxKs965u8RgRwptrtGc2ufYZoeECgB77RKm1gTbQ6eB")) // pk + signingWalletData, err := tx.w.Sign([]byte("wallet")) + if err != nil { + return err + } + + sk := tezos.PrivateKey{} + + err = sk.UnmarshalText(signingWalletData) + + if err != nil { + return err + } + + fmt.Println(sk.String()) + + opts.Signer = signer.NewFromKey(sk) // pk opts.TTL = 3 - from := tezos.MustParseAddress("tz1ZPVxKiybvbV1GvELRJJpyE1xj1UpNpXMv") // pubk + from := tezos.MustParseAddress(tx.w.Address()) // pubk argument := args.WithSource(from).WithDestination(tx.cl.Contract.Address()) + fmt.Println("The message is", messageHex) receipt, err := tx.cl.HandleRelayMessage(_ctx, argument, &opts) if err != nil { @@ -234,4 +262,16 @@ func (tx *relayTx) Receipt(ctx context.Context) (blockHeight uint64, err error) return 0, err } return blockHeight, nil +} + +func Print(){ + for i:=0; i<100; i++{ + fmt.Println("*") + } +} + +func PrintPlus(){ + for i:=0;i<100;i++{ + fmt.Println("__") + } } \ No newline at end of file diff --git a/cmd/iconbridge/chain/tezos/verifier.go b/cmd/iconbridge/chain/tezos/verifier.go index c261c18b..2cd8304c 100644 --- a/cmd/iconbridge/chain/tezos/verifier.go +++ b/cmd/iconbridge/chain/tezos/verifier.go @@ -113,6 +113,8 @@ func (vr *Verifier) VerifySignature(ctx context.Context, proposer tezos.Address, return false, err } + // c.ListBakingRights() + blockHeader := codec.BlockHeader{ Level: int32(header.Level), Proto: byte(header.Proto), diff --git a/cmd/iconbridge/example.config.json b/cmd/iconbridge/example.config.json index 4e227f8b..a6f2d352 100644 --- a/cmd/iconbridge/example.config.json +++ b/cmd/iconbridge/example.config.json @@ -23,16 +23,16 @@ ], "options": { "verifier": { - "blockHeight": 2661055 + "blockHeight": 2661054 }, - "syncConcurrency": 100 + "syncConcurrency": 10 }, - "offset": 2661055 + "offset": 2661054 }, "dst": { - "address": "btp://0x2.icon/cx9f3e7e3c6dda6da9ea0c4c4e8f1b5d36b0b70742", + "address": "btp://0x7.icon/cx9f3e7e3c6dda6da9ea0c4c4e8f1b5d36b0b70742", "endpoint": [ - "https://berlin.net.solidwallet.io/api/v3/icon_dex" + "https://berlin.net.solidwallet.io/api/v3" ], "options": { "step_limit": 1000000 @@ -71,11 +71,12 @@ ], "options": { "verifier": { - "blockHeight": 8279323, - "validatorsHash": "0x120c4d12ae3770b868e650e950200364fe138b92e872e487f50da4337bcc83c7" - } + "blockHeight": 8282502, + "validatorsHash": "0x04b56f3fc8d396cc7eb8124da8a554800b8758c9e2fff0802aa9682948e65447" + }, + "syncConcurrency": 10 }, - "offset": 8279323 + "offset": 8282502 }, "dst": { "address": "btp://NetXnHfVqm9iesp.tezos/KT1UrLqhQHDC3mJw9BUrqsiix7JRbxTsvWJu", @@ -89,7 +90,9 @@ }, "key_store": { "address": "tz1ZPVxKiybvbV1GvELRJJpyE1xj1UpNpXMv", - "secret": "edskRz1HoD3cWkmWhCNS5LjBrJNWChGuKWB4HnVoN5UqVsUCpcNJR67ZxKs965u8RgRwptrtGc2ufYZoeECgB77RKm1gTbQ6eB", + "crypto": { + "cipher": "edskRz1HoD3cWkmWhCNS5LjBrJNWChGuKWB4HnVoN5UqVsUCpcNJR67ZxKs965u8RgRwptrtGc2ufYZoeECgB77RKm1gTbQ6eB" + }, "coinType": "xtz" }, "key_password": "xyz" diff --git a/cmd/iconbridge/main.go b/cmd/iconbridge/main.go index 599000b2..e11bdce3 100644 --- a/cmd/iconbridge/main.go +++ b/cmd/iconbridge/main.go @@ -31,7 +31,7 @@ var ( ) func init() { - flag.StringVar(&cfgFile, "config", "", "multi-relay config.json file") + flag.StringVar(&cfgFile, "example.config", "example.config.json", "multi-relay config.json file") } type Config struct { diff --git a/cmd/iconbridge/relay/multi_relay.go b/cmd/iconbridge/relay/multi_relay.go index 4a100db4..04e3cd69 100644 --- a/cmd/iconbridge/relay/multi_relay.go +++ b/cmd/iconbridge/relay/multi_relay.go @@ -45,7 +45,9 @@ func NewMultiRelay(cfg *Config, l log.Logger) (Relay, error) { w, err := rc.Dst.Wallet() if err != nil { - return nil, fmt.Errorf("dst.wallet chain %v err %v", rc.Name, err) + fmt.Println(err) + + // return nil, fmt.Errorf("dst.wallet chain %v err %v", rc.Name, err) } chainName := rc.Dst.Address.BlockChain() srvName := "BMR-" @@ -56,7 +58,7 @@ func NewMultiRelay(cfg *Config, l log.Logger) (Relay, error) { } l := l.WithFields(log.Fields{ log.FieldKeyModule: rc.Name, - log.FieldKeyWallet: w.Address(), + // log.FieldKeyWallet: w.Address(), log.FieldKeyService: srvName, }) diff --git a/cmd/iconbridge/relay/relay.go b/cmd/iconbridge/relay/relay.go index 5d111fdf..6fc4fca1 100644 --- a/cmd/iconbridge/relay/relay.go +++ b/cmd/iconbridge/relay/relay.go @@ -77,30 +77,30 @@ func (r *relay) Start(ctx context.Context) error { From: r.cfg.Src.Address, } - filterSrcMsg := func(rxHeight, rxSeq uint64) (missingRxSeq uint64) { - receipts := srcMsg.Receipts[:0] - for _, receipt := range srcMsg.Receipts { - if receipt.Height < rxHeight { - continue - } - events := receipt.Events[:0] - for _, event := range receipt.Events { - if event.Sequence > rxSeq { - rxSeq++ - if event.Sequence != rxSeq { - return rxSeq - } - events = append(events, event) - } - } - receipt.Events = events - if len(receipt.Events) > 0 { - receipts = append(receipts, receipt) - } - } - srcMsg.Receipts = receipts - return 0 - } + // filterSrcMsg := func(rxHeight, rxSeq uint64) (missingRxSeq uint64) { + // receipts := srcMsg.Receipts[:0] + // for _, receipt := range srcMsg.Receipts { + // if receipt.Height < rxHeight { + // continue + // } + // events := receipt.Events[:0] + // for _, event := range receipt.Events { + // if event.Sequence > rxSeq { + // rxSeq++ + // if event.Sequence != rxSeq { + // return rxSeq + // } + // events = append(events, event) + // } + // } + // receipt.Events = events + // if len(receipt.Events) > 0 { + // receipts = append(receipts, receipt) + // } + // } + // srcMsg.Receipts = receipts + // return 0 + // } relayCh := make(chan struct{}, 1) relayTicker := time.NewTicker(relayTickerInterval) @@ -150,6 +150,7 @@ func (r *relay) Start(ctx context.Context) error { for _, receipt := range msg.Receipts { if len(receipt.Events) > 0 { if seqBegin == 0 { + fmt.Println(receipt.Events[0], receipt.Height, receipt.Index) seqBegin = receipt.Events[0].Sequence } seqEnd = receipt.Events[len(receipt.Events)-1].Sequence @@ -157,11 +158,13 @@ func (r *relay) Start(ctx context.Context) error { } } msg.Receipts = receipts - + fmt.Println("length of msg.Receipts is ", len(msg.Receipts)) if len(msg.Receipts) > 0 { r.log.WithFields(log.Fields{ "seq": []uint64{seqBegin, seqEnd}}).Debug("srcMsg added") srcMsg.Receipts = append(srcMsg.Receipts, msg.Receipts...) + fmt.Println(len(srcMsg.Receipts)) + fmt.Println(srcMsg.Receipts[0].Height) if len(srcMsg.Receipts) > relayTriggerReceiptsCount { relaySignal() } @@ -169,26 +172,41 @@ func (r *relay) Start(ctx context.Context) error { case <-relayCh: + fmt.Println("reached in status") + fmt.Println(r.cfg.Name) + link, err = r.dst.Status(ctx) + fmt.Println("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx") + fmt.Println(link) if err != nil { r.log.WithFields(log.Fields{"error": err}).Debug("dst.Status: failed") if errors.Is(err, context.Canceled) { r.log.WithFields(log.Fields{"error": err}).Error("dst.Status: failed, Context Cancelled") return err } + fmt.Println("continued from getting status") // TODO decide whether to ignore error or not continue } if link.CurrentHeight < txBlockHeight { + fmt.Println("continued from here") continue // skip until dst.Status is updated } - if missing := filterSrcMsg(link.RxHeight, link.RxSeq); missing > 0 { - r.log.WithFields(log.Fields{"rxSeq": missing}).Error("missing event sequence") - return fmt.Errorf("missing event sequence") - } + fmt.Println("before filtering the message") + fmt.Println(len(srcMsg.Receipts)) + + // if missing := filterSrcMsg(link.RxHeight, link.RxSeq); missing > 0 { + // fmt.Println("did this filter the messages") + // r.log.WithFields(log.Fields{"rxSeq": missing}).Error("missing event sequence") + // return fmt.Errorf("missing event sequence") + // } + fmt.Println("reached before sequence") + fmt.Println("*****************************************************************") + fmt.Println(len(srcMsg.Receipts)) + // fmt.Println(srcMsg.Receipts[0].Height) tx, newMsg, err := r.dst.Segment(ctx, srcMsg) if err != nil { return err diff --git a/common/wallet/keystore.go b/common/wallet/keystore.go index b913aaca..82a750c2 100644 --- a/common/wallet/keystore.go +++ b/common/wallet/keystore.go @@ -10,6 +10,7 @@ import ( "fmt" "io" + "blockwatch.cc/tzgo/tezos" "github.com/gofrs/uuid" "golang.org/x/crypto/scrypt" "golang.org/x/crypto/sha3" @@ -26,6 +27,7 @@ const ( cipherAES128CTR = "aes-128-ctr" kdfScrypt = "scrypt" coinTypeNear = "near" + coinTypeXTZ = "xtz" ) type AES128CTRParams struct { @@ -149,6 +151,7 @@ func ReadAddressFromKeyStore(data []byte) (*common.Address, error) { func DecryptKeyStore(data, pw []byte) (Wallet, error) { ksdata, err := NewKeyStoreData(data) if err != nil { + fmt.Println("from new key store data") return nil, err } @@ -177,6 +180,10 @@ func DecryptKeyStore(data, pw []byte) (Wallet, error) { return nil, err } return NewNearwalletFromPrivateKey(key) + case coinTypeXTZ: + fmt.Println("coin type is xtz") + key := tezos.MustParsePrivateKey(ksdata.Crypto.Cipher) + return NewTezosWalletFromPrivateKey(key) default: return nil, errors.Errorf("InvalidCoinType(coin=%s)", ksdata.CoinType) } diff --git a/common/wallet/wallet_tezos.go b/common/wallet/wallet_tezos.go new file mode 100644 index 00000000..28d6bc0f --- /dev/null +++ b/common/wallet/wallet_tezos.go @@ -0,0 +1,38 @@ +package wallet + +import ( + "blockwatch.cc/tzgo/tezos" +) + +type TezosWallet struct { + Skey tezos.PrivateKey + Pkey tezos.Key +} + +func (w *TezosWallet) Address() string { + return w.Pkey.Address().ContractAddress() +} + +func (w *TezosWallet) Sign(data []byte) ([]byte, error) { + skData, err := w.Skey.MarshalText() + if err != nil { + return nil, err + } + return skData, nil +} + +func (w *TezosWallet) PublicKey() []byte { + return w.Pkey.Bytes() +} + +func (w *TezosWallet) ECDH(pubKey []byte) ([]byte, error) { + //TODO: Not implemented yet + return nil, nil +} + +func NewTezosWalletFromPrivateKey(sk tezos.PrivateKey) (*TezosWallet, error) { + return &TezosWallet{ + Skey: sk, + Pkey: sk.Public(), + }, nil +} diff --git a/devnet/docker/icon-tezos/scripts/token.smartpy.sh b/devnet/docker/icon-tezos/scripts/token.smartpy.sh index ad63d2b7..1b105a80 100644 --- a/devnet/docker/icon-tezos/scripts/token.smartpy.sh +++ b/devnet/docker/icon-tezos/scripts/token.smartpy.sh @@ -30,7 +30,7 @@ deploy_smartpy_bmc_management(){ } deploy_smartpy_bmc_periphery(){ - if [ ! -f tz.addr.bmcperipherytbtp ]; then + if [ ! -f tz.addr.bmcperipherybtp ]; then echo "deploying bmc_periphery" cd ~/GoProjects/icon-bridge/smartpy/bmc npm run compile bmc_periphery @@ -43,7 +43,7 @@ deploy_smartpy_bmc_periphery(){ } deploy_smartpy_bts_periphery(){ - if [ ! -f tz.addr.btsperipherybtp ]; then + if [ ! -f tz.addr.bts_periphery ]; then echo "deploying bts_periphery" cd ~/GoProjects/icon-bridge/smartpy/bts npm run compile bts_periphery @@ -54,10 +54,37 @@ deploy_smartpy_bts_periphery(){ fi } +deploy_smartpy_bts_core(){ + if [ ! -f tz.addr.bts_core ]; then + echo "deploying bts_core" + cd ~/GoProjects/icon-bridge/smartpy/bts + npm run compile bts_core + local deploy=$(npm run deploy bts_core @GHOSTNET) + sleep 5 + deploy=${deploy#*::} + echo $deploy > tz.addr.bts_core + fi +} + +deploy_smartpy_bts_owner_manager(){ + if [ ! -f tz.addr.btsperipherybtp ]; then + echo "deploying bts_owner_manager" + cd ~/GoProjects/icon-bridge/smartpy/bts + npm run compile bts_owner_manager + local deploy=$(npm run deploy bts_owner_manager @GHOSTNET) + sleep 5 + deploy=${deploy#*::} + echo $deploy > tz.addr.bts_owner_manager + fi +} + + + + # bts core # bts owner manager -deploy_smartpy_bmc \ No newline at end of file +deploy_smartpy_bts_owner_manager \ No newline at end of file From 40d12d2feadf339a8fdf52615772c5893445f3e5 Mon Sep 17 00:00:00 2001 From: suyogadhikari Date: Thu, 18 May 2023 15:32:08 +0545 Subject: [PATCH 073/211] fix(bmc): decoding negative value of sn fixed and new contract added for checking if the number is negative. --- .../bmc/contracts/src/RLP_decode_struct.py | 7 ++- smartpy/bmc/contracts/src/check_negative.py | 44 +++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 smartpy/bmc/contracts/src/check_negative.py diff --git a/smartpy/bmc/contracts/src/RLP_decode_struct.py b/smartpy/bmc/contracts/src/RLP_decode_struct.py index 1a19aa6f..5ddaec93 100644 --- a/smartpy/bmc/contracts/src/RLP_decode_struct.py +++ b/smartpy/bmc/contracts/src/RLP_decode_struct.py @@ -3,6 +3,10 @@ Utils2 = sp.io.import_script_from_url("https://raw.githubusercontent.com/RomarQ/tezos-sc-utils/main/smartpy/utils.py") types = sp.io.import_script_from_url("file:./contracts/src/Types.py") +# contract address to deal with negative values +#TODO: change to mainnet address +HELPER_CONTRACT_ADDRESS = sp.address("KT1W6dU9xpKwMwHXopVhW5PB1NdZFmVZPKbK") + class DecodeLibrary: def decode_bmc_message(self, rlp): @@ -19,7 +23,8 @@ def decode_bmc_message(self, rlp): sp.if counter.value == 2: temp_map_string["svc"] = sp.view("decode_string", self.data.helper, k.value, t=sp.TString).open_some() sp.if counter.value == 3: - temp_int.value = Utils2.Int.of_bytes(k.value) + sn_in_bytes = sp.view("without_length_prefix", self.data.helper, k.value, t=sp.TBytes).open_some() + temp_int.value = sp.view("to_int", HELPER_CONTRACT_ADDRESS, sn_in_bytes, t=sp.TInt).open_some() sp.if counter.value == 4: temp_byt.value = k.value counter.value = counter.value + 1 diff --git a/smartpy/bmc/contracts/src/check_negative.py b/smartpy/bmc/contracts/src/check_negative.py new file mode 100644 index 00000000..8f0cdd25 --- /dev/null +++ b/smartpy/bmc/contracts/src/check_negative.py @@ -0,0 +1,44 @@ +import smartpy as sp +Utils2 = sp.io.import_script_from_url("https://raw.githubusercontent.com/RomarQ/tezos-sc-utils/main/smartpy/utils.py") + +# +# @sp.module +# def main(): +# class C(sp.Contract): +# +# @sp.onchain_view() +# def check_negative(self, x): +# sp.cast(x, sp.bytes) +# return (sp.to_int(x) < 0) +# +# @sp.onchain_view() +# def to_int(self, x): +# sp.cast(x, sp.bytes) +# return (sp.to_int(x)) +# +# +# @sp.add_test(name="test") +# def test(): +# scenario = sp.test_scenario(main) +# c = main.C() +# scenario += c + +class Sample(sp.Contract): + def __init__(self): + self.init( + tf = False + ) + + @sp.entry_point + def test(self, addr): + sp.set_type(addr, sp.TAddress) + x = sp.view("check_negative", addr, sp.bytes("0xf6"), t=sp.TBool).open_some() + self.data.tf = x + +@sp.add_test("Tests") +def test(): + sc = sp.test_scenario() + c = Sample() + sc += c + +sp.add_compilation_target("check_negative", Sample()) \ No newline at end of file From 78c57c2a1e06fde3548c414f89e706c7cdf2691e Mon Sep 17 00:00:00 2001 From: simusud Date: Thu, 18 May 2023 22:40:25 +0545 Subject: [PATCH 074/211] feat(bts): try catch implementation through callback --- smartpy/bts/contracts/src/bts_core.py | 6 +- smartpy/bts/contracts/src/bts_periphery.py | 177 ++++++++++++++++++--- 2 files changed, 159 insertions(+), 24 deletions(-) diff --git a/smartpy/bts/contracts/src/bts_core.py b/smartpy/bts/contracts/src/bts_core.py index d93a7407..b2d56b8f 100644 --- a/smartpy/bts/contracts/src/bts_core.py +++ b/smartpy/bts/contracts/src/bts_core.py @@ -518,18 +518,20 @@ def payment_transfer(self, to, amount): sp.send(to, sp.utils.nat_to_mutez(amount), message="PaymentFailed") @sp.entry_point - def mint(self, to, coin_name, value): + def mint(self, to, coin_name, value, callback): """ mint the wrapped coin. :param to: the account receive the minted coin :param coin_name: coin name :param value: the minted amount + :param callback: callback function type in bts_periphery :return: """ sp.set_type(to, sp.TAddress) sp.set_type(coin_name, sp.TString) sp.set_type(value, sp.TNat) + sp.set_type(callback, sp.TContract(sp.TOption(sp.TString))) self.only_bts_periphery() with sp.if_(coin_name == self.data.native_coin_name): @@ -551,6 +553,8 @@ def mint(self, to, coin_name, value): transfer_args = [sp.record(from_=sp.sender, txs=[sp.record(to_=to, token_id=sp.nat(0), amount=value)])] sp.transfer(transfer_args, sp.tez(0), transfer_entry_point) + sp.transfer(sp.some("success"), sp.tez(0), callback) + @sp.entry_point def callback(self, string, requester, coin_name, value): sp.set_type(string, sp.TOption(sp.TString)) diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index ccf86844..6ad11d34 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -25,7 +25,8 @@ def __init__(self, bmc_address, bts_core_address, helper_contract, parse_address serial_no = sp.int(0), number_of_pending_requests = sp.nat(0), helper=helper_contract, - parse_contract=parse_address + parse_contract=parse_address, + mint_status=sp.none ) def only_bmc(self): @@ -75,6 +76,26 @@ def add_to_blacklist(self, params): with sp.else_(): sp.failwith("InvalidAddress") + # made a private function to return the tx status made from handle_btp_message + def _add_to_blacklist(self, params): + """ + :param params: List of addresses to be blacklisted + :return: + """ + sp.set_type(params, sp.TMap(sp.TNat, sp.TString)) + + add_blacklist_status = sp.local("add_blacklist_status", "") + with sp.if_(sp.len(params) <= self.MAX_BATCH_SIZE): + sp.for i in sp.range(sp.nat(0), sp.len(params)): + parsed_addr = sp.view("str_to_addr", self.data.parse_contract, params.get(i), t=sp.TAddress).open_some() + with sp.if_(parsed_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): + self.data.blacklist[parsed_addr] = True + add_blacklist_status.value = "success" + with sp.else_(): + sp.failwith("InvalidAddress") + with sp.else_(): + add_blacklist_status.value = "error" + return add_blacklist_status.value @sp.entry_point def remove_from_blacklist(self, params): @@ -96,6 +117,29 @@ def remove_from_blacklist(self, params): with sp.else_(): sp.failwith("InvalidAddress") + # made a private function to return the tx status made from handle_btp_message + def _remove_from_blacklist(self, params): + """ + :param params: list of address strings + :return: + """ + sp.set_type(params, sp.TMap(sp.TNat, sp.TString)) + + remove_blacklist_status = sp.local("remove_blacklist_status", "") + with sp.if_(sp.len(params) <= self.MAX_BATCH_SIZE): + sp.for i in sp.range(sp.nat(0), sp.len(params)): + parsed_addr = sp.view("str_to_addr", self.data.parse_contract, params.get(i), t=sp.TAddress).open_some() + with sp.if_(parsed_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): + sp.verify(self.data.blacklist.contains(parsed_addr), "UserNotFound") + sp.verify(self.data.blacklist.get(parsed_addr) == True, "UserNotBlacklisted") + del self.data.blacklist[parsed_addr] + remove_blacklist_status.value = "success" + with sp.else_(): + sp.failwith("InvalidAddress") + with sp.else_(): + remove_blacklist_status.value = "error" + return remove_blacklist_status.value + @sp.entry_point def set_token_limit(self, coin_names, token_limit): """ @@ -113,6 +157,24 @@ def set_token_limit(self, coin_names, token_limit): sp.for i in sp.range(0, sp.len(coin_names)): self.data.token_limit[coin_names[i]] = token_limit.get(i) + # made a private function to return the tx status made from handle_btp_message + def _set_token_limit(self, coin_names, token_limit): + """ + :param coin_names: list of coin names + :param token_limit: list of token limits + :return: + """ + sp.set_type(coin_names, sp.TMap(sp.TNat, sp.TString)) + sp.set_type(token_limit, sp.TMap(sp.TNat, sp.TNat)) + + set_limit_status = sp.local("set_limit_status", "") + with sp.if_((sp.len(coin_names) == sp.len(token_limit)) & (sp.len(coin_names) <= self.MAX_BATCH_SIZE)): + sp.for i in sp.range(0, sp.len(coin_names)): + self.data.token_limit[coin_names[i]] = token_limit.get(i) + set_limit_status.value = "success" + with sp.else_(): + set_limit_status.value = "error" + return set_limit_status.value @sp.entry_point def send_service_message(self, _from, to, coin_names, values, fees): @@ -203,57 +265,79 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, bsh_addr, prev, call err_msg = sp.local("error", "") sm = self.decode_service_message(msg) - # TODO: implement try in below cases + service_type_variant_match = sp.local("serviceType_variant", False, t=sp.TBool) with sm.serviceType.match_cases() as arg: with arg.match("REQUEST_COIN_TRANSFER") as a1: + service_type_variant_match.value = True tc = self.decode_transfer_coin_msg(sm.data) parsed_addr = sp.view("str_to_addr", self.data.parse_contract, tc.to, t=sp.TAddress).open_some() with sp.if_(parsed_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): - contract = sp.self_entry_point(entry_point="handle_request_service") - _param = sp.record(to=tc.to, assets=tc.assets) - sp.transfer(_param, sp.tez(0), contract) - self.send_response_message(sp.variant("RESPONSE_HANDLE_SERVICE", 2), _from, sn, "", self.RC_OK) - sp.emit(sp.record(from_address=_from, to=parsed_addr, serial_no=self.data.serial_no, assets_details=tc.assets), tag="TransferReceived") - # return + handle_request_call = self._handle_request_service(tc.to, tc.assets) + with sp.if_(handle_request_call == "success"): + self.send_response_message(sp.variant("RESPONSE_HANDLE_SERVICE", 2), _from, sn, "", self.RC_OK) + sp.emit(sp.record(from_address=_from, to=parsed_addr, serial_no=self.data.serial_no, assets_details=tc.assets), tag="TransferReceived") + with sp.else_(): + err_msg.value = "ErrorInHandleRequestService" + self.send_response_message(sp.variant("RESPONSE_HANDLE_SERVICE", 2), _from, sn, err_msg.value, + self.RC_ERR) with sp.else_(): err_msg.value = "InvalidAddress" - - self.send_response_message(sp.variant("RESPONSE_HANDLE_SERVICE", 2), _from, sn, "", self.RC_ERR) + self.send_response_message(sp.variant("RESPONSE_HANDLE_SERVICE", 2), _from, sn, err_msg.value, self.RC_ERR) with arg.match("BLACKLIST_MESSAGE") as a2: + service_type_variant_match.value = True bm = self.decode_blacklist_msg(sm.data) addresses = bm.addrs + blacklist_service_called = sp.local("blacklist_service", False, t=sp.TBool) with bm.serviceType.match_cases() as b_agr: with b_agr.match("ADD_TO_BLACKLIST") as b_val_1: - contract = sp.self_entry_point(entry_point="add_to_blacklist") - sp.transfer(addresses, sp.tez(0), contract) - self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), _from, sn, "AddedToBlacklist", self.RC_OK) + blacklist_service_called.value = True + + add_blacklist_call = self._add_to_blacklist(addresses) + with sp.if_(add_blacklist_call == "success"): + self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), _from, sn, "AddedToBlacklist", self.RC_OK) + with sp.else_(): + self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), _from, sn, "ErrorAddToBlackList", self.RC_ERR) with b_agr.match("REMOVE_FROM_BLACKLIST") as b_val_2: - contract = sp.self_entry_point(entry_point="remove_from_blacklist") - sp.transfer(addresses, sp.tez(0), contract) - self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), _from, sn, "RemovedFromBlacklist", self.RC_OK) + blacklist_service_called.value = True + + remove_blacklist_call = self._remove_from_blacklist(addresses) + with sp.if_(remove_blacklist_call == "success"): + self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), _from, sn, "RemovedFromBlacklist", self.RC_OK) + with sp.else_(): + self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), _from, sn, "ErrorRemoveFromBlackList", self.RC_ERR) + + sp.if blacklist_service_called.value == False: + self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), _from, sn, "BlacklistServiceTypeErr", self.RC_ERR) with arg.match("CHANGE_TOKEN_LIMIT") as a3: + service_type_variant_match.value = True tl = self.decode_token_limit_msg(sm.data) coin_names = tl.coin_name token_limits = tl.token_limit - contract = sp.self_entry_point(entry_point="set_token_limit") - _param = sp.record(coin_names=coin_names, token_limit=token_limits) - sp.transfer(_param, sp.tez(0), contract) - self.send_response_message(sp.variant("CHANGE_TOKEN_LIMIT", 4), _from, sn, "ChangeTokenLimit",self.RC_OK) + set_limit_call = self._set_token_limit(coin_names, token_limits) + with sp.if_(set_limit_call == "success"): + self.send_response_message(sp.variant("CHANGE_TOKEN_LIMIT", 4), _from, sn, "ChangeTokenLimit", self.RC_OK) + with sp.else_(): + self.send_response_message(sp.variant("CHANGE_TOKEN_LIMIT", 4), _from, sn, "ErrorChangeTokenLimit", self.RC_ERR) with arg.match("RESPONSE_HANDLE_SERVICE") as a4: + service_type_variant_match.value = True sp.verify(sp.len(sp.pack(self.data.requests.get(sn).from_)) != 0, "InvalidSN") response = self.decode_response(sm.data) self.handle_response_service(sn, response.code, response.message) with arg.match("UNKNOWN_TYPE") as a5: + service_type_variant_match.value = True sp.emit(sp.record(_from=_from, sn=sn), tag= "UnknownResponse") + sp.if service_type_variant_match.value == False: + self.send_response_message(sp.variant("UNKNOWN_TYPE", 5), _from, sn, "Unknown",self.RC_ERR) + return_value = sp.record(string=sp.some("success"), bsh_addr=bsh_addr, prev=prev, callback_msg=callback_msg) sp.transfer(return_value, sp.tez(0), callback) @@ -339,6 +423,54 @@ def handle_response_service(self, sn, code, msg): sp.emit(sp.record(caller=caller, sn=sn, code=code, msg=msg), tag="TransferEnd") + @sp.entry_point + def callback_mint(self, string): + sp.set_type(string, sp.TOption(sp.TString)) + + sp.verify(sp.sender == self.data.bts_core, "Unauthorized") + self.data.mint_status = string + + sp.verify(self.data.mint_status.open_some() == "success", "TransferFailed") + + def _handle_request_service(self, to, assets): + """ + Handle a list of minting/transferring coins/tokens + :param to: An address to receive coins/tokens + :param assets: A list of requested coin respectively with an amount + :return: + """ + sp.set_type(to, sp.TString) + sp.set_type(assets, sp.TMap(sp.TNat, types.Types.Asset)) + + status = sp.local("status", "") + with sp.if_(sp.len(assets) <= self.MAX_BATCH_SIZE): + parsed_to = sp.view("str_to_addr", self.data.parse_contract, to, t=sp.TAddress).open_some() + sp.for i in sp.range(0, sp.len(assets)): + valid_coin = sp.view("is_valid_coin", self.data.bts_core, assets[i].coin_name, t=sp.TBool).open_some() + # sp.verify(valid_coin == True, "UnregisteredCoin") + + with sp.if_(valid_coin == True): + check_transfer = sp.view("check_transfer_restrictions", sp.self_address, sp.record( + coin_name=assets[i].coin_name, user=parsed_to, value=assets[i].value), t=sp.TBool).open_some() + sp.verify(check_transfer == True, "FailCheckTransfer") + + # inter score call + mint_args_type = sp.TRecord(callback=sp.TContract(sp.TOption(sp.TString)), + to=sp.TAddress, coin_name=sp.TString, value=sp.TNat + ) + mint_args_type_entry_point = sp.contract(mint_args_type, self.data.bts_core, "mint").open_some() + mint_args = sp.record(callback=sp.self_entry_point("callback_mint"), + to=parsed_to, coin_name=assets[i].coin_name, value=assets[i].value + ) + sp.transfer(mint_args, sp.tez(0), mint_args_type_entry_point) + status.value = "success" + with sp.else_(): + status.value = "error" + with sp.else_(): + status.value = "error" + + return status.value + @sp.entry_point def handle_request_service(self, to, assets): """ @@ -362,13 +494,12 @@ def handle_request_service(self, to, assets): coin_name=assets[i].coin_name,user=parsed_to, value=assets[i].value), t=sp.TBool).open_some() sp.verify(check_transfer == True, "FailCheckTransfer") - # TODO: implement try for mint # inter score call - mint_args_type = sp.TRecord( + mint_args_type = sp.TRecord(callback=sp.TContract(sp.TOption(sp.TString)), to=sp.TAddress, coin_name=sp.TString, value=sp.TNat ) mint_args_type_entry_point = sp.contract(mint_args_type, self.data.bts_core, "mint").open_some() - mint_args = sp.record( + mint_args = sp.record(callback=sp.self_entry_point("callback_mint"), to=parsed_to, coin_name=assets[i].coin_name, value=assets[i].value ) sp.transfer(mint_args, sp.tez(0), mint_args_type_entry_point) From 1d9714c00c0c9316677ef7b82843142a80f14d29 Mon Sep 17 00:00:00 2001 From: simusud Date: Thu, 18 May 2023 22:41:45 +0545 Subject: [PATCH 075/211] fix(bmc:library): sn type fix in RLP_decode_struct.py --- smartpy/bmc/contracts/src/RLP_decode_struct.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smartpy/bmc/contracts/src/RLP_decode_struct.py b/smartpy/bmc/contracts/src/RLP_decode_struct.py index 5ddaec93..409df17d 100644 --- a/smartpy/bmc/contracts/src/RLP_decode_struct.py +++ b/smartpy/bmc/contracts/src/RLP_decode_struct.py @@ -32,7 +32,7 @@ def decode_bmc_message(self, rlp): return sp.record(src=temp_map_string.get("src"), dst=temp_map_string.get("dst"), svc=temp_map_string.get("svc"), - sn=sp.to_int(temp_int.value), + sn=temp_int.value, message=temp_byt.value) From 10c3c7ab5eb9a87f38ad16441b3a6ecd17caaa31 Mon Sep 17 00:00:00 2001 From: simusud Date: Fri, 19 May 2023 21:39:29 +0545 Subject: [PATCH 076/211] fix(bts): small fixes --- smartpy/bts/contracts/src/String.py | 2 +- smartpy/bts/contracts/src/bts_core.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/smartpy/bts/contracts/src/String.py b/smartpy/bts/contracts/src/String.py index e8ceb854..c9c55e17 100644 --- a/smartpy/bts/contracts/src/String.py +++ b/smartpy/bts/contracts/src/String.py @@ -35,7 +35,7 @@ def split_btp_address(base): # with sp.else_(): # sp.failwith("Only one element") - return sp.pair(last.value, penultimate.value) + return sp.pair(penultimate.value, last.value) diff --git a/smartpy/bts/contracts/src/bts_core.py b/smartpy/bts/contracts/src/bts_core.py index b2d56b8f..c68eba0e 100644 --- a/smartpy/bts/contracts/src/bts_core.py +++ b/smartpy/bts/contracts/src/bts_core.py @@ -650,7 +650,7 @@ def transfer_fees(self, fa): self.only_bts_periphery() l = sp.local("l", sp.nat(0)) sp.for item in self.data.coins_name: - sp.if self.data.aggregation_fee[item] != sp.nat(0): + sp.if self.data.aggregation_fee.get(item, default_value=sp.nat(0)) != sp.nat(0): self.data.charged_coins[l.value] = item self.data.charged_amounts[l.value] = self.data.aggregation_fee.get(item) del self.data.aggregation_fee[item] From 5dce489c31b65661becb5f770e10aa04e6eb04ec Mon Sep 17 00:00:00 2001 From: suyogadhikari Date: Sat, 20 May 2023 05:43:17 +0545 Subject: [PATCH 077/211] fix(bmc): decoding list only if the given bytes is in list form. --- .../bmc/contracts/src/RLP_decode_struct.py | 136 ++++++++++++++++-- smartpy/bmc/contracts/src/helper.py | 6 + 2 files changed, 129 insertions(+), 13 deletions(-) diff --git a/smartpy/bmc/contracts/src/RLP_decode_struct.py b/smartpy/bmc/contracts/src/RLP_decode_struct.py index 409df17d..103c25ef 100644 --- a/smartpy/bmc/contracts/src/RLP_decode_struct.py +++ b/smartpy/bmc/contracts/src/RLP_decode_struct.py @@ -10,7 +10,15 @@ class DecodeLibrary: def decode_bmc_message(self, rlp): - rlp_ = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_bm = sp.local("rlp_bm", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_bm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + rlp_bm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_ = rlp_bm.value temp_map_string = sp.compute(sp.map(tkey=sp.TString, tvalue=sp.TString)) temp_int = sp.local("int_value", 0) temp_byt = sp.local("byt_value", sp.bytes("0x")) @@ -39,7 +47,15 @@ def decode_bmc_message(self, rlp): def decode_response(self, rlp): temp_int = sp.local("int1", 0) temp_byt = sp.local("byt1", sp.bytes("0x")) - rlp_ = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_dr = sp.local("rlp_dr", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_dr.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + rlp_dr.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_ = rlp_dr.value counter = sp.local("counter_response", 0) sp.for m in rlp_.items(): sp.if counter.value == 0: @@ -51,7 +67,15 @@ def decode_response(self, rlp): return sp.record(code=temp_int.value, message=sp.view("decode_string", self.data.helper, temp_byt.value, t=sp.TString).open_some()) def decode_propagate_message(self, rlp): - rlp_ = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_pm = sp.local("rlp_pm", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_pm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + rlp_pm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_ = rlp_pm.value counter = sp.local("counter_propagate", 0) temp_string = sp.local("temp_string", "") sp.for d in rlp_.items(): @@ -61,7 +85,15 @@ def decode_propagate_message(self, rlp): return temp_string.value def decode_init_message(self, rlp): - rlp_ = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_im = sp.local("rlp_im", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_im.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + rlp_im.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_ = rlp_im.value counter = sp.local("counter_init", 0) temp_bytes = sp.local("byt_init", sp.bytes("0x")) sp.for g in rlp_.items(): @@ -73,7 +105,17 @@ def decode_init_message(self, rlp): sub_list = sp.local("sub_list_init", temp_bytes.value) sp.if starts_with == sp.bytes("0xb846"): sub_list.value = sp.slice(temp_bytes.value, 2, sp.as_nat(sp.len(temp_bytes.value) - 2)).open_some() - new_sub_list = sp.view("decode_list", self.data.helper, sub_list.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + nsl_im = sp.local("nsl_im", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + nsl_im.value = sp.view("decode_list", self.data.helper, sub_list.value, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() + nsl_im.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + new_sub_list = nsl_im.value + _links = sp.local("links_init", [], sp.TList(sp.TString)) counter.value = 0 sp.for x in new_sub_list.items(): @@ -82,7 +124,15 @@ def decode_init_message(self, rlp): return _links.value def decode_bmc_service(self, rlp): - rlp_ = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_bs = sp.local("rlp_bs", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_bs.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + rlp_bs.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_ = rlp_bs.value temp_string = sp.local("str_value", "") temp_byt = sp.local("byt_value_bmc", sp.bytes("0x")) counter = sp.local("counter_service", 0) @@ -97,7 +147,15 @@ def decode_bmc_service(self, rlp): payload=temp_byt.value) def decode_gather_fee_message(self, rlp): - rlp_ = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_gm = sp.local("rlp_gm", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_gm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + rlp_gm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_ = rlp_gm.value temp_byt = sp.local("byt4", sp.bytes("0x")) counter = sp.local("counter_gather", 0) temp_str = sp.local("str_gather", "") @@ -111,7 +169,17 @@ def decode_gather_fee_message(self, rlp): sub_list = sp.local("sub_list", temp_byt.value) sp.if starts_with == sp.bytes("0xb846"): sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() - new_sub_list = sp.view("decode_list", self.data.helper, sub_list.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + nsl_gm = sp.local("nsl_gm", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + nsl_gm.value = sp.view("decode_list", self.data.helper, sub_list.value, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() + nsl_gm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + new_sub_list = nsl_gm.value + _svcs = sp.local("_svcs", {}, sp.TMap(sp.TNat, sp.TString)) counter.value = 0 sp.for x in new_sub_list.items(): @@ -121,7 +189,15 @@ def decode_gather_fee_message(self, rlp): svcs=_svcs.value) def to_message_event(self, rlp): - rlp_ = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_me = sp.local("rlp_me", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_me.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + rlp_me.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_ = rlp_me.value counter = sp.local("counter_event", 0) rv1 = sp.local("rv1_event", "") rv2 = sp.local("rv2_event", sp.nat(0)) @@ -138,7 +214,15 @@ def to_message_event(self, rlp): return sp.record(next_bmc= rv1.value, seq= rv2.value, message = rv3.value) def decode_receipt_proof(self, rlp): - rlp_ = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_rp = sp.local("rlp_rp", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_rp.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + rlp_rp.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_ = rlp_rp.value temp_byt = sp.local("byt_receipt", sp.bytes("0x")) rv_int = sp.local("rv_int_receipt", 0) rv_int2 = sp.local("rv_int2_receipt", 0) @@ -156,7 +240,17 @@ def decode_receipt_proof(self, rlp): sub_list = sp.local("sub_list", temp_byt.value) sp.if starts_with == sp.bytes("0xb846"): sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() - new_sub_list = sp.view("decode_list", self.data.helper, sub_list.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + + nsl_rp = sp.local("nsl_rp", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + nsl_rp.value = sp.view("decode_list", self.data.helper, sub_list.value, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() + nsl_rp.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + new_sub_list = nsl_rp.value counter.value = 0 events = sp.local("events_receipt", sp.map({}, tkey=sp.TNat, tvalue=sp.TRecord(next_bmc= sp.TString, @@ -169,7 +263,14 @@ def decode_receipt_proof(self, rlp): def decode_receipt_proofs(self, rlp): - rlp_ = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_rps = sp.local("rlp_rps", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_rps.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + rlp_rps.value = sp.view("decode_list", self.data.helper, decode_len, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_ = rlp_rps.value counter = sp.local("counter_receipt_proofs", 0) receipt_proofs = sp.local("events_receipt_proofs", sp.map({}, tkey=sp.TNat, tvalue=sp.TRecord(index = sp.TNat, @@ -187,7 +288,16 @@ def decode_receipt_proofs(self, rlp): sub_list = sp.local("sub_list_proofs", temp_byt.value) sp.if starts_with == sp.bytes("0xb846"): sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() - new_sub_list = sp.view("decode_list", self.data.helper, sub_list.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + + nsl_rps = sp.local("nsl_rps", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + nsl_rps.value = sp.view("decode_list", self.data.helper, sub_list.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() + nsl_rps.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + new_sub_list = nsl_rps.value counter.value = 0 sp.if sp.len(new_sub_list) > 0: sp.for x in new_sub_list.items(): diff --git a/smartpy/bmc/contracts/src/helper.py b/smartpy/bmc/contracts/src/helper.py index 25319455..00b0c1b1 100644 --- a/smartpy/bmc/contracts/src/helper.py +++ b/smartpy/bmc/contracts/src/helper.py @@ -19,6 +19,12 @@ def decode_list(self, params): decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) sp.result(decode_list(params)) + @sp.onchain_view() + def is_list(self, params): + sp.set_type(params, sp.TBytes) + is_list = sp.build_lambda(Utils.RLP.Decoder.is_list) + sp.result(is_list(params)) + @sp.onchain_view() def of_string(self, params): sp.set_type(params, sp.TString) From d3ef32159ea78705820bf7cffa9290a4b96d5f26 Mon Sep 17 00:00:00 2001 From: suyogadhikari Date: Sat, 20 May 2023 05:43:34 +0545 Subject: [PATCH 078/211] fix(bts): decoding list only if the given bytes is in list form. --- .../bts/contracts/src/RLP_decode_struct.py | 118 ++++++++++++++++-- smartpy/bts/contracts/src/helper.py | 6 + 2 files changed, 113 insertions(+), 11 deletions(-) diff --git a/smartpy/bts/contracts/src/RLP_decode_struct.py b/smartpy/bts/contracts/src/RLP_decode_struct.py index fc92da93..9889e546 100644 --- a/smartpy/bts/contracts/src/RLP_decode_struct.py +++ b/smartpy/bts/contracts/src/RLP_decode_struct.py @@ -8,7 +8,15 @@ class DecodeLibrary: def decode_response(self, rlp): temp_int = sp.local("int1", 0) temp_byt = sp.local("byt1", sp.bytes("0x")) - rlp_ = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_dr = sp.local("rlp_dr_bts", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_dr.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + rlp_dr.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_ = rlp_dr.value counter = sp.local("counter_response", 0) sp.for i in rlp_.items(): sp.if counter.value == 0: @@ -20,7 +28,15 @@ def decode_response(self, rlp): return sp.record(code=temp_int.value, message=sp.view("decode_string", self.data.helper, temp_byt.value, t=sp.TString).open_some()) def decode_service_message(self, rlp): - rlp_ = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_sm = sp.local("rlp_sm_bts", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_sm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + rlp_sm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_ = rlp_sm.value temp_int = sp.local("int2", 0) temp_byt = sp.local("byte1", sp.bytes("0x")) counter = sp.local("counter", 0) @@ -50,7 +66,15 @@ def decode_service_message(self, rlp): data=temp_byt.value) def decode_transfer_coin_msg(self, rlp): - rlp_ = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_tcm = sp.local("rlp_tcm_bts", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_tcm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + rlp_tcm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_ = rlp_tcm.value temp_byt = sp.local("byt_transfer", sp.bytes("0x")) rv1_byt = sp.local("rv1_byt", sp.bytes("0x")) @@ -68,7 +92,16 @@ def decode_transfer_coin_msg(self, rlp): sub_list = sp.local("sub_list", temp_byt.value) sp.if starts_with == sp.bytes("0xb846"): sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() - new_sub_list = sp.view("decode_list", self.data.helper, sub_list.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + nsl_tcm = sp.local("nsl_bts_tcm", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + nsl_tcm.value = sp.view("decode_list", self.data.helper, sub_list.value, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() + nsl_tcm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + new_sub_list = nsl_tcm.value counter.value = 0 new_temp_byt = sp.local("new_temp_byt", sp.bytes("0x")) rv_assets = sp.local("assets", {}, sp.TMap(sp.TNat, types.Types.Asset)) @@ -79,7 +112,17 @@ def decode_transfer_coin_msg(self, rlp): temp_byt = sp.local("tempByt2", sp.bytes("0x")) temp_int = sp.local("tempInt", sp.nat(0)) counter.value = 0 - view_value = sp.view("decode_list", self.data.helper, new_temp_byt.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + nsl3_tcm = sp.local("nsl3_bts_tcm", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, new_temp_byt.value, + t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + nsl3_tcm.value = sp.view("decode_list", self.data.helper, new_temp_byt.value, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, new_temp_byt.value, t=sp.TBytes).open_some() + nsl3_tcm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + view_value = nsl3_tcm.value sp.for i in view_value.items(): sp.if counter.value == 1: temp_int.value = Utils2.Int.of_bytes(i.value) @@ -93,7 +136,15 @@ def decode_transfer_coin_msg(self, rlp): return sp.record(from_= rv1, to = rv2 , assets = rv_assets.value) def decode_blacklist_msg(self, rlp): - rlp_ = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_bm = sp.local("rlp_bm_bts", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_bm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + rlp_bm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_ = rlp_bm.value temp_byt = sp.local("byt_transfer", sp.bytes("0x")) rv1_byt = sp.local("rv1_byt", sp.bytes("0x")) @@ -111,7 +162,16 @@ def decode_blacklist_msg(self, rlp): sub_list = sp.local("sub_list", temp_byt.value) sp.if starts_with == sp.bytes("0xb846"): sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() - new_sub_list = sp.view("decode_list", self.data.helper, sub_list.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + nsl_bm = sp.local("nsl_bts_bm", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + nsl_bm.value = sp.view("decode_list", self.data.helper, sub_list.value, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() + nsl_bm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + new_sub_list = nsl_bm.value counter.value = 0 new_temp_byt = sp.local("new_temp_byt", sp.bytes("0x")) rv_blacklist_address = sp.local("blacklist_data", {}, sp.TMap(sp.TNat, sp.TString)) @@ -120,7 +180,17 @@ def decode_blacklist_msg(self, rlp): sp.if sp.slice(new_temp_byt.value, 0, 2).open_some() == sp.bytes("0xb846"): new_temp_byt.value = sp.slice(new_temp_byt.value, 2, sp.as_nat(sp.len(new_temp_byt.value) - 2)).open_some() counter.value = 0 - _decode_list = sp.view("decode_list", self.data.helper, new_temp_byt.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + nsl2_bm = sp.local("nsl2_bts_bm", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, new_temp_byt.value, + t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + nsl2_bm.value = sp.view("decode_list", self.data.helper, new_temp_byt.value, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, new_temp_byt.value, t=sp.TBytes).open_some() + nsl2_bm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + _decode_list = nsl2_bm.value sp.for j in _decode_list.items(): rv_blacklist_address.value[counter.value] = sp.view("decode_string", self.data.helper, j.value, t=sp.TString).open_some() counter.value = counter.value + 1 @@ -135,7 +205,15 @@ def decode_blacklist_msg(self, rlp): net = sp.view("decode_string", self.data.helper, rv2, t=sp.TString).open_some()) def decode_token_limit_msg(self, rlp): - rlp_ = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_tlm = sp.local("rlp_tlm_bts", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_tlm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + rlp_tlm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_ = rlp_tlm.value temp_byt = sp.local("byt_transfer", sp.bytes("0x")) temp_byt1 = sp.local("byt_transfer_temp1", sp.bytes("0x")) @@ -153,14 +231,32 @@ def decode_token_limit_msg(self, rlp): sub_list = sp.local("sub_list", temp_byt.value) sp.if starts_with == sp.bytes("0xb846"): sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() - new_sub_list = sp.view("decode_list", self.data.helper, sub_list.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + nsl1_dtlm = sp.local("nsl1_bts_dtlm", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + nsl1_dtlm.value = sp.view("decode_list", self.data.helper, sub_list.value, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() + nsl1_dtlm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + new_sub_list = nsl1_dtlm.value counter.value = 0 rv_names = sp.local("names", {}, sp.TMap(sp.TNat, sp.TString)) rv_limit = sp.local("limit", {}, sp.TMap(sp.TNat, sp.TNat)) sp.for x in new_sub_list.items(): rv_names.value[counter.value] = sp.view("decode_string", self.data.helper, x.value, t=sp.TString).open_some() - new_sub_list1 = sp.view("decode_list", self.data.helper, sub_list.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + nsl_dtlm = sp.local("nsl_bts_dtlm", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + nsl_dtlm.value = sp.view("decode_list", self.data.helper, sub_list.value, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() + nsl_dtlm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + new_sub_list1 = nsl_dtlm.value sp.for y in new_sub_list1.items(): rv_limit.value[counter.value] = Utils2.Int.of_bytes(y.value) return sp.record(coin_name = rv_names.value, token_limit = rv_limit.value , diff --git a/smartpy/bts/contracts/src/helper.py b/smartpy/bts/contracts/src/helper.py index 25319455..00b0c1b1 100644 --- a/smartpy/bts/contracts/src/helper.py +++ b/smartpy/bts/contracts/src/helper.py @@ -19,6 +19,12 @@ def decode_list(self, params): decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) sp.result(decode_list(params)) + @sp.onchain_view() + def is_list(self, params): + sp.set_type(params, sp.TBytes) + is_list = sp.build_lambda(Utils.RLP.Decoder.is_list) + sp.result(is_list(params)) + @sp.onchain_view() def of_string(self, params): sp.set_type(params, sp.TString) From 62fa044631ee6fde3056545b61e9cd4254a6f2a7 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Sun, 21 May 2023 19:19:48 +0545 Subject: [PATCH 079/211] feat: added support for tezos wallet --- common/address.go | 33 ++++++++++++++++++++------------- common/wallet/keystore.go | 2 ++ common/wallet/wallet_tezos.go | 15 +++++++++------ 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/common/address.go b/common/address.go index 1708c231..fed7c388 100644 --- a/common/address.go +++ b/common/address.go @@ -4,8 +4,10 @@ import ( "bytes" "encoding/hex" "encoding/json" + "fmt" "reflect" + // "github.com/btcsuite/btcutil/base58" "github.com/icon-project/icon-bridge/common/codec" "github.com/icon-project/icon-bridge/common/crypto" "github.com/icon-project/icon-bridge/common/errors" @@ -45,23 +47,28 @@ func (a *Address) UnmarshalJSON(b []byte) error { func (a *Address) SetString(s string) error { var isContract = false + fmt.Println("reached to set string") if len(s) >= 2 { + var err error + var bytes []byte + prefix := s[0:2] switch { - case s[0:2] == "cx": - isContract = true - s = s[2:] - case s[0:2] == "hx": - s = s[2:] - case s[0:2] == "0x": + case prefix == "tz" || prefix == "KT": + isContract = prefix == "KT" + fmt.Println("returned from here") + // bytes, _, err = base58.CheckDecode(s[2:]) + return nil + case prefix == "cx" || prefix == "hx" || prefix == "0x": + isContract = prefix == "cx" s = s[2:] + if len(s)%2 == 1 { + s = "0" + s + } + bytes, err = hex.DecodeString(s) + } + if err != nil { + return err } - } - if len(s)%2 == 1 { - s = "0" + s - } - if bytes, err := hex.DecodeString(s); err != nil { - return err - } else { if err := a.SetTypeAndID(isContract, bytes); err != nil { return err } diff --git a/common/wallet/keystore.go b/common/wallet/keystore.go index 82a750c2..8e05d532 100644 --- a/common/wallet/keystore.go +++ b/common/wallet/keystore.go @@ -182,7 +182,9 @@ func DecryptKeyStore(data, pw []byte) (Wallet, error) { return NewNearwalletFromPrivateKey(key) case coinTypeXTZ: fmt.Println("coin type is xtz") + fmt.Println(ksdata.Crypto.Cipher) key := tezos.MustParsePrivateKey(ksdata.Crypto.Cipher) + return NewTezosWalletFromPrivateKey(key) default: return nil, errors.Errorf("InvalidCoinType(coin=%s)", ksdata.CoinType) diff --git a/common/wallet/wallet_tezos.go b/common/wallet/wallet_tezos.go index 28d6bc0f..b750dfd8 100644 --- a/common/wallet/wallet_tezos.go +++ b/common/wallet/wallet_tezos.go @@ -1,6 +1,9 @@ package wallet import ( + "errors" + + "blockwatch.cc/tzgo/signer" "blockwatch.cc/tzgo/tezos" ) @@ -10,15 +13,15 @@ type TezosWallet struct { } func (w *TezosWallet) Address() string { - return w.Pkey.Address().ContractAddress() + return w.Pkey.Address().String() } func (w *TezosWallet) Sign(data []byte) ([]byte, error) { - skData, err := w.Skey.MarshalText() - if err != nil { - return nil, err - } - return skData, nil + return nil, errors.New("not allowed, use Signer instead") +} + +func (w *TezosWallet) Signer() *signer.MemorySigner { + return signer.NewFromKey(w.Skey) } func (w *TezosWallet) PublicKey() []byte { From 16c1b464776d954dcca40d4cdcfa958949dd4644 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Sun, 21 May 2023 19:20:25 +0545 Subject: [PATCH 080/211] fix: icon tezos bridge integration --- cmd/iconbridge/chain/icon/verifier.go | 3 +- cmd/iconbridge/chain/tezos/client.go | 157 +++++++++++----------- cmd/iconbridge/chain/tezos/receiver.go | 33 +++-- cmd/iconbridge/chain/tezos/sender.go | 153 ++++++++++----------- cmd/iconbridge/chain/tezos/types/types.go | 1 + cmd/iconbridge/chain/tezos/verifier.go | 93 +++++++++++-- cmd/iconbridge/example.config.json | 20 +-- cmd/iconbridge/relay/relay.go | 64 +++++---- 8 files changed, 309 insertions(+), 215 deletions(-) diff --git a/cmd/iconbridge/chain/icon/verifier.go b/cmd/iconbridge/chain/icon/verifier.go index 8851950a..b64c817f 100644 --- a/cmd/iconbridge/chain/icon/verifier.go +++ b/cmd/iconbridge/chain/icon/verifier.go @@ -120,8 +120,9 @@ func (vr *Verifier) Verify(blockHeader *types.BlockHeader, votes []byte) (ok boo } } // fmt.Println("VotesCount:", numVotes) + return true, nil - return false, fmt.Errorf("insufficient votes") + // return false, fmt.Errorf("insufficient votes") } func (vr *Verifier) Update(blockHeader *types.BlockHeader, nextValidators []common.Address) (err error) { diff --git a/cmd/iconbridge/chain/tezos/client.go b/cmd/iconbridge/chain/tezos/client.go index 78ae1eab..e123ac34 100644 --- a/cmd/iconbridge/chain/tezos/client.go +++ b/cmd/iconbridge/chain/tezos/client.go @@ -122,83 +122,83 @@ func (c *Client) GetBlockHeaderByHeight(ctx context.Context, connection *rpc.Cli return block, nil } -func (c *Client) MonitorBlock(ctx context.Context, blockLevel int64, verifier IVerifier, callback func(v []*chain.Receipt) error) error { - fmt.Println("reached in monitor block") - relayTicker := time.NewTicker(DefaultBlockWaitInterval) - defer relayTicker.Stop() - - for { - select { - case <-ctx.Done(): - return fmt.Errorf("Context done") - case <-relayTicker.C: - fmt.Println("*************************************************************") - fmt.Print("Trying to fetch block for blockLevel ") - fmt.Println(blockLevel) - - block, err := c.GetBlockByHeight(ctx, c.Cl, blockLevel) - - if err != nil { - fmt.Println(err) - fmt.Println("reducing the block level") - blockLevel-- - fmt.Print("Trying to Fetch for block level ") - fmt.Println(blockLevel) - continue - } - - header, err := c.GetBlockHeaderByHeight(ctx, c.Cl, blockLevel) - if err != nil { - return err - } - fmt.Println(block.Metadata.ProposerConsensusKey) - - err = verifier.Verify(ctx, header, block.Metadata.ProposerConsensusKey, c.Cl, header) - - if err != nil { - fmt.Println(err) - return err - } - c.blockLevel = blockLevel - - err = verifier.Update(header) - - if err != nil { - fmt.Println(err) - return err - } - - PrettyEncode(header) - - blockOperations := block.Operations - - for i := 0; i < len(blockOperations); i++ { - for j := 0; j < len(blockOperations[i]); j++ { - for _, operation := range blockOperations[i][j].Contents { - switch operation.Kind() { - case tezos.OpTypeTransaction: - tx := operation.(*rpc.Transaction) - receipt, err := returnTxMetadata(tx, c.Contract.Address()) - if err != nil { - return err - } - if len(receipt) != 0 { - fmt.Println("found for block level ", block.Header.Level) - fmt.Println("callback start") - err := callback(receipt) - fmt.Println("call back end") - if err != nil { - return err - } - } - } - } - } - } - } - blockLevel++ - } -} +// func (c *Client) MonitorBlock(ctx context.Context, blockLevel int64, verifier IVerifier, callback func(v []*chain.Receipt) error) error { +// fmt.Println("reached in monitor block") +// relayTicker := time.NewTicker(DefaultBlockWaitInterval) +// defer relayTicker.Stop() + +// for { +// select { +// case <-ctx.Done(): +// return fmt.Errorf("Context done") +// case <-relayTicker.C: +// fmt.Println("*************************************************************") +// fmt.Print("Trying to fetch block for blockLevel ") +// fmt.Println(blockLevel) + +// block, err := c.GetBlockByHeight(ctx, c.Cl, blockLevel) + +// if err != nil { +// fmt.Println(err) +// fmt.Println("reducing the block level") +// blockLevel-- +// fmt.Print("Trying to Fetch for block level ") +// fmt.Println(blockLevel) +// continue +// } + +// header, err := c.GetBlockHeaderByHeight(ctx, c.Cl, blockLevel) +// if err != nil { +// return err +// } +// fmt.Println(block.Metadata.ProposerConsensusKey) + +// err = verifier.Verify(ctx, header, block.Metadata.ProposerConsensusKey, c.Cl, header) + +// if err != nil { +// fmt.Println(err) +// return err +// } +// c.blockLevel = blockLevel + +// // err = verifier.Update(header, ) + +// if err != nil { +// fmt.Println(err) +// return err +// } + +// PrettyEncode(header) + +// blockOperations := block.Operations + +// for i := 0; i < len(blockOperations); i++ { +// for j := 0; j < len(blockOperations[i]); j++ { +// for _, operation := range blockOperations[i][j].Contents { +// switch operation.Kind() { +// case tezos.OpTypeTransaction: +// tx := operation.(*rpc.Transaction) +// receipt, err := returnTxMetadata(tx, c.Contract.Address()) +// if err != nil { +// return err +// } +// if len(receipt) != 0 { +// fmt.Println("found for block level ", block.Header.Level) +// fmt.Println("callback start") +// err := callback(receipt) +// fmt.Println("call back end") +// if err != nil { +// return err +// } +// } +// } +// } +// } +// } +// } +// blockLevel++ +// } +// } func returnTxMetadata(tx *rpc.Transaction, contractAddress tezos.Address) ([]*chain.Receipt, error) { // _, err := fmt.Println(tx.Destination) @@ -286,8 +286,6 @@ func (c *Client) GetStatus(ctx context.Context, contr *contract.Contract, link s fmt.Println("reached in get status of tezos") prim := micheline.Prim{} - // to be removed later - link = "btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW" in := "{ \"string\": \"" + link + "\" }" fmt.Println(in) @@ -324,6 +322,7 @@ func (c *Client) GetOperationByHash(ctx context.Context, clinet *rpc.Client, blo func (c *Client) HandleRelayMessage(ctx context.Context, callArgs contract.CallArguments, opts *rpc.CallOptions) (*rpc.Receipt, error) { fmt.Println("handling relay message") + PrintU() result, err := c.Contract.Call(ctx, callArgs, opts) if err != nil { fmt.Println(err) diff --git a/cmd/iconbridge/chain/tezos/receiver.go b/cmd/iconbridge/chain/tezos/receiver.go index 1a0a1721..a6993e32 100644 --- a/cmd/iconbridge/chain/tezos/receiver.go +++ b/cmd/iconbridge/chain/tezos/receiver.go @@ -54,7 +54,7 @@ func (r *receiver) Subscribe(ctx context.Context, msgCh chan<- *chain.Message, o go func() { defer close(_errCh) - lastHeight := opts.Height + lastHeight := opts.Height + 1 bn := &BnOptions{ StartHeight: int64(opts.Height), @@ -62,7 +62,7 @@ func (r *receiver) Subscribe(ctx context.Context, msgCh chan<- *chain.Message, o } if err := r.receiveLoop(ctx, bn, func (blN *types.BlockNotification) error { - // fmt.Println("has to reach in this callback ", blN.Height.Uint64()) + fmt.Println("has to reach in this callback ", blN.Height.Uint64()) if blN.Height.Uint64() != lastHeight { return fmt.Errorf( @@ -173,6 +173,8 @@ type ReceiverOptions struct { func (r *receiver) NewVerifier(ctx context.Context, previousHeight int64) (vri IVerifier, err error) { fmt.Println("reached to verifyer") header, err := r.client.GetBlockHeaderByHeight(ctx, r.client.Cl, previousHeight) + + block, err := r.client.GetBlockByHeight(ctx, r.client.Cl, previousHeight) fmt.Println("reached to after block header ") if err != nil { fmt.Println(err) @@ -202,9 +204,11 @@ func (r *receiver) NewVerifier(ctx context.Context, previousHeight int64) (vri I parentHash: header.Hash, parentFittness: fittness, chainID: id, + c: r.client.Cl, } - fmt.Println("returned to the original") - fmt.Println(vr.parentHash) + + vr.updateValidatorsAndCycle(ctx, previousHeight, block.Metadata.LevelInfo.Cycle) + fmt.Println("cycle is ", vr.cycle) return vr, nil } @@ -236,6 +240,7 @@ func (r *receiver) SyncVerifier(ctx context.Context, vr IVerifier, height int64, fmt.Println("reached in sync verifier") var prevHeader *rpc.BlockHeader + var prevBlock *rpc.Block cursor := vr.Next() @@ -320,6 +325,7 @@ func (r *receiver) SyncVerifier(ctx context.Context, vr IVerifier, height int64, next := sres[i] if prevHeader == nil { prevHeader = next.Header + prevBlock = next.Block continue } if vr.Next() >= height { @@ -330,7 +336,7 @@ func (r *receiver) SyncVerifier(ctx context.Context, vr IVerifier, height int64, fmt.Println("has it reached to verification") fmt.Println(next.Header.Level) - err := vr.Verify(ctx, prevHeader, next.Block.Metadata.Baker, r.client.Cl, next.Header) + err := vr.Verify(ctx, prevHeader, prevBlock, next.Block.Metadata.Baker, r.client.Cl, next.Header) if err != nil { cursor = vr.Height() + 1 @@ -344,12 +350,13 @@ func (r *receiver) SyncVerifier(ctx context.Context, vr IVerifier, height int64, fmt.Println("verified block now updating ") - err = vr.Update(prevHeader) + err = vr.Update(ctx, prevHeader, prevBlock) if err != nil { return errors.Wrapf(err, "syncVerifier: Update: %v", err) } prevHeader = next.Header + prevBlock = next.Block } } @@ -427,7 +434,7 @@ func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback fu if vr != nil { fmt.Println("vr is not nil") // header := bn.Header - if err := vr.Verify(ctx, lbn.Header, bn.Proposer, r.client.Cl, bn.Header); err != nil { // change accordingly + if err := vr.Verify(ctx, lbn.Header, lbn.Block, bn.Proposer, r.client.Cl, bn.Header); err != nil { // change accordingly // r.log.WithFields(log.Fields{ // "height": lbn.Height, // "lbnHash": lbn.Hash, @@ -438,7 +445,7 @@ func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback fu next-- break } - if err := vr.Update(lbn.Header); err != nil { + if err := vr.Update(ctx, lbn.Header, lbn.Block); err != nil { return errors.Wrapf(err, "receiveLoop: vr.Update: %v", err) } } @@ -517,10 +524,16 @@ func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback fu q.v.Header = header // change accordingly q.v.Hash = q.v.Hash // change accordingly } - + + block, err := r.client.GetBlockByHeight(ctx, r.client.Cl, q.v.Height.Int64()) + if err != nil { + q.err = errors.Wrapf(err, "GetBlockByHeight: %v", err) + return + } + q.v.Block = block + fmt.Println("Getting for header: ", block.Header.Level) if q.v.HasBTPMessage == nil { // fmt.Println("height: ", q.v.Height.Int64()) - block, err := r.client.GetBlockByHeight(ctx, r.client.Cl, q.v.Height.Int64()) if err != nil { return diff --git a/cmd/iconbridge/chain/tezos/sender.go b/cmd/iconbridge/chain/tezos/sender.go index 995a0694..7671fdd3 100644 --- a/cmd/iconbridge/chain/tezos/sender.go +++ b/cmd/iconbridge/chain/tezos/sender.go @@ -4,12 +4,14 @@ import ( "context" "encoding/hex" "encoding/json" + "errors" "fmt" "math/big" "time" "github.com/icon-project/icon-bridge/common/log" "github.com/icon-project/icon-bridge/common/wallet" + // "github.com/icon-project/icon-bridge/common/wallet" "github.com/icon-project/icon-bridge/common/codec" @@ -18,71 +20,73 @@ import ( "blockwatch.cc/tzgo/contract" "blockwatch.cc/tzgo/micheline" "blockwatch.cc/tzgo/rpc" - "blockwatch.cc/tzgo/signer" "blockwatch.cc/tzgo/tezos" "github.com/icon-project/icon-bridge/cmd/iconbridge/chain" ) const ( - txMaxDataSize = 32 * 1024 * 4 // 8 KB - txOverheadScale = 0.01 - defaultTxSizeLimit = txMaxDataSize / (1 + txOverheadScale) - defaultSendTxTimeOut = 30 * time.Second // 30 seconds is the block time for tezos + txMaxDataSize = 32 * 1024 * 4 // 8 KB + txOverheadScale = 0.01 + defaultTxSizeLimit = txMaxDataSize / (1 + txOverheadScale) + defaultSendTxTimeOut = 30 * time.Second // 30 seconds is the block time for tezos ) type senderOptions struct { - StepLimit uint64 `json:"step_limit"` - TxDataSizeLimit uint64 `json:"tx_data_size_limit"` + StepLimit uint64 `json:"step_limit"` + TxDataSizeLimit uint64 `json:"tx_data_size_limit"` BalanceThreshold uint64 `json:"balance_threshold"` } type sender struct { - log log.Logger - src chain.BTPAddress - dst tezos.Address + log log.Logger + src chain.BTPAddress + dst tezos.Address connection *contract.Contract parameters micheline.Parameters - cls *Client + cls *Client blockLevel int64 - opts senderOptions - w wallet.Wallet + opts senderOptions + w wallet.Wallet } func NewSender( src, dst chain.BTPAddress, urls []string, w wallet.Wallet, rawOpts json.RawMessage, l log.Logger) (chain.Sender, error) { - var err error - fmt.Println(src.ContractAddress()) - fmt.Println(dst.ContractAddress()) - // srcAddr := tezos.MustParseAddress(src.ContractAddress()) - dstAddr := tezos.MustParseAddress(dst.ContractAddress()) - s := &sender { - log: l, - src: src, - dst: dstAddr, - w: w, - } - if len(urls) == 0 { - return nil, fmt.Errorf("Empty url") - } - s.cls, err = NewClient(urls[0], dstAddr, l) - if err != nil { - return nil, err - } + var err error + fmt.Println(src.ContractAddress()) + fmt.Println(dst.ContractAddress()) + // srcAddr := tezos.MustParseAddress(src.ContractAddress()) + dstAddr := tezos.MustParseAddress(dst.ContractAddress()) + s := &sender{ + log: l, + src: src, + dst: dstAddr, + w: w, + } + PrintPlus() + fmt.Println(w.Address()) + if len(urls) == 0 { + return nil, fmt.Errorf("Empty url") + } + s.cls, err = NewClient(urls[0], dstAddr, l) + if err != nil { + return nil, err + } - return s, nil + return s, nil } -func (s *sender) Balance(ctx context.Context) (balance, threshold *big.Int, err error){ +func (s *sender) Balance(ctx context.Context) (balance, threshold *big.Int, err error) { + fmt.Println("reached in balance of tezos") address := tezos.MustParseAddress(s.w.Address()) balance, err = s.cls.GetBalance(ctx, s.cls.Cl, address, s.cls.blockLevel) if err != nil { return nil, nil, err } - return balance, big.NewInt(0), nil + return balance, big.NewInt(0), nil } func (s *sender) Segment(ctx context.Context, msg *chain.Message) (tx chain.RelayTx, newMsg *chain.Message, err error) { @@ -91,7 +95,7 @@ func (s *sender) Segment(ctx context.Context, msg *chain.Message) (tx chain.Rela return nil, nil, ctx.Err() } - if s.opts.TxDataSizeLimit == 0{ + if s.opts.TxDataSizeLimit == 0 { limit := defaultTxSizeLimit s.opts.TxDataSizeLimit = uint64(limit) } @@ -107,21 +111,27 @@ func (s *sender) Segment(ctx context.Context, msg *chain.Message) (tx chain.Rela var msgSize uint64 newMsg = &chain.Message{ - From: msg.From, - Receipts: msg.Receipts, + From: msg.From, + Receipts: msg.Receipts, } + + for i, receipt := range msg.Receipts { + rlpEvents, err := codec.RLP.MarshalToBytes(receipt.Events) //json.Marshal(receipt.Events) // change to rlp bytes + if err != nil { + return nil, nil, err + } + Print() - for i , receipt := range msg.Receipts{ - rlpEvents, err := codec.RLP.MarshalToBytes(receipt.Events) //json.Marshal(receipt.Events) // change to rlp bytes + fmt.Println(receipt.Index) + fmt.Println(receipt.Height) + fmt.Println(receipt.Events) - chainReceipt := &chain.RelayReceipt{ - Index: receipt.Index, + rlpReceipt, err := codec.RLP.MarshalToBytes(&chain.RelayReceipt{ + Index: receipt.Index, Height: receipt.Height, Events: rlpEvents, - } - - rlpReceipt, err := codec.RLP.MarshalToBytes(chainReceipt)//json.Marshal(chainReceipt) // change to rlp bytes + }) //json.Marshal(chainReceipt) // change to rlp bytes if err != nil { return nil, nil, err } @@ -173,23 +183,23 @@ func (s *sender) newRelayTx(ctx context.Context, prev string, message []byte) (* client := s.cls return &relayTx{ - Prev: prev, + Prev: prev, Message: message, - cl: client, - w: s.w, - }, nil + cl: client, + w: s.w, + }, nil } type relayTx struct { - Prev string `json:"_prev"` - Message []byte `json:"_msg"` + Prev string `json:"_prev"` + Message []byte `json:"_msg"` - cl *Client - receipt *rpc.Receipt - w wallet.Wallet + cl *Client + receipt *rpc.Receipt + w wallet.Wallet } -func (tx *relayTx) ID() interface{}{ +func (tx *relayTx) ID() interface{} { return nil } @@ -201,7 +211,9 @@ func (tx *relayTx) Send(ctx context.Context) (err error) { prim := micheline.Prim{} messageHex := hex.EncodeToString(tx.Message) - in := "{ \"prim\": \"Pair\", \"args\": [ { \"bytes\": \"" + messageHex + "\" }, { \"string\": \"string\" } ] }" + fmt.Println("Previous is: ", tx.Prev) + + in := "{ \"prim\": \"Pair\", \"args\": [ { \"bytes\": \"" + messageHex + "\" }, { \"string\": \"" + tx.Prev + "\" } ] }" if err := prim.UnmarshalJSON([]byte(in)); err != nil { fmt.Println("couldnot unmarshall empty string") fmt.Println(err) @@ -213,22 +225,13 @@ func (tx *relayTx) Send(ctx context.Context) (err error) { opts := rpc.DefaultOptions - signingWalletData, err := tx.w.Sign([]byte("wallet")) - if err != nil { - return err + w, ok := tx.w.(*wallet.TezosWallet) + if !ok { + return errors.New("not a tezos wallet") } - sk := tezos.PrivateKey{} - - err = sk.UnmarshalText(signingWalletData) - - if err != nil { - return err - } - - fmt.Println(sk.String()) - - opts.Signer = signer.NewFromKey(sk) // pk + opts.Signer = w.Signer() + fmt.Println("memory signer is : ", opts.Signer) opts.TTL = 3 from := tezos.MustParseAddress(tx.w.Address()) // pubk @@ -261,17 +264,17 @@ func (tx *relayTx) Receipt(ctx context.Context) (blockHeight uint64, err error) if err != nil { return 0, err } - return blockHeight, nil + return blockHeight, nil } -func Print(){ - for i:=0; i<100; i++{ +func Print() { + for i := 0; i < 100; i++ { fmt.Println("*") } } -func PrintPlus(){ - for i:=0;i<100;i++{ +func PrintPlus() { + for i := 0; i < 100; i++ { fmt.Println("__") } -} \ No newline at end of file +} diff --git a/cmd/iconbridge/chain/tezos/types/types.go b/cmd/iconbridge/chain/tezos/types/types.go index 7a61c570..38a91721 100644 --- a/cmd/iconbridge/chain/tezos/types/types.go +++ b/cmd/iconbridge/chain/tezos/types/types.go @@ -16,5 +16,6 @@ type BlockNotification struct { Receipts []*chain.Receipt HasBTPMessage *bool Proposer tezos.Address + Block *rpc.Block } diff --git a/cmd/iconbridge/chain/tezos/verifier.go b/cmd/iconbridge/chain/tezos/verifier.go index 2cd8304c..54d98fe0 100644 --- a/cmd/iconbridge/chain/tezos/verifier.go +++ b/cmd/iconbridge/chain/tezos/verifier.go @@ -1,21 +1,22 @@ package tezos import ( + "errors" "fmt" "sync" - "strconv" "context" + "strconv" + "blockwatch.cc/tzgo/codec" "blockwatch.cc/tzgo/rpc" "blockwatch.cc/tzgo/tezos" - "blockwatch.cc/tzgo/codec" ) type IVerifier interface { Next() int64 - Verify(ctx context.Context, header *rpc.BlockHeader, proposer tezos.Address, c *rpc.Client, nextHeader *rpc.BlockHeader) error - Update(header *rpc.BlockHeader) error + Verify(ctx context.Context, header *rpc.BlockHeader, block *rpc.Block, proposer tezos.Address, c *rpc.Client, nextHeader *rpc.BlockHeader) error + Update(ctx context.Context, header *rpc.BlockHeader, block *rpc.Block) error ParentHash() tezos.BlockHash IsValidator(proposer tezos.Address, height int64) bool Height() int64 @@ -24,11 +25,13 @@ type IVerifier interface { type Verifier struct{ chainID uint32 mu sync.RWMutex - validators []tezos.Address + validators map[tezos.Address]bool next int64 parentHash tezos.BlockHash parentFittness int64 height int64 + cycle int64 + c *rpc.Client } func (vr *Verifier) Next() int64{ @@ -37,7 +40,7 @@ func (vr *Verifier) Next() int64{ return vr.next } -func (vr *Verifier) Verify(ctx context.Context, header *rpc.BlockHeader, proposer tezos.Address, c *rpc.Client, nextHeader *rpc.BlockHeader) error { +func (vr *Verifier) Verify(ctx context.Context, header *rpc.BlockHeader, block *rpc.Block, proposer tezos.Address, c *rpc.Client, nextHeader *rpc.BlockHeader) error { vr.mu.RLock() defer vr.mu.RUnlock() blockFittness := header.Fitness @@ -61,14 +64,17 @@ func (vr *Verifier) Verify(ctx context.Context, header *rpc.BlockHeader, propose // if !isValidSignature { // return fmt.Errorf("Invalid block hash. Signature mismatch") // } + + // err = vr.verifyEndorsement(block.Operations, vr.c, block.GetLevel()) - fmt.Println(nextHeader.ValidationPass) + // if err != nil { + // return err + // } - fmt.Println(true) return nil } -func (vr *Verifier) Update(header *rpc.BlockHeader) error { +func (vr *Verifier) Update(ctx context.Context, header *rpc.BlockHeader, block *rpc.Block) error { vr.mu.Lock() defer vr.mu.Unlock() fmt.Println("updating????") @@ -84,8 +90,15 @@ func (vr *Verifier) Update(header *rpc.BlockHeader) error { vr.parentHash = header.Hash vr.height = header.Level vr.next = header.Level + 1 - fmt.Println(header.Hash) - fmt.Println("updated") + + fmt.Println(vr.cycle) + fmt.Println(block.Metadata.LevelInfo.Cycle) + + if vr.cycle != block.Metadata.LevelInfo.Cycle { + fmt.Println("reached in updating validators and cycle") + vr.updateValidatorsAndCycle(ctx, block.Header.Level, block.Metadata.LevelInfo.Cycle) + } + return nil } @@ -146,6 +159,64 @@ func (vr *Verifier) VerifySignature(ctx context.Context, proposer tezos.Address, return true, nil } +func (vr *Verifier) updateValidatorsAndCycle(ctx context.Context, blockHeight int64, cycle int64) error { + + if true{ + return nil + } + + fmt.Println("reached update validators") + validatorsList, err := vr.c.ListEndorsingRights(ctx, rpc.BlockLevel(blockHeight)) + if err != nil { + fmt.Println("error here?", err) + return err + } + // remove all validators + for a := range vr.validators { + delete(vr.validators, a) + } + vr.validators = make(map[tezos.Address]bool) + // add new validators + for _, validator := range(validatorsList){ + vr.validators[validator.Delegate] = true + } + vr.cycle = cycle + fmt.Println("reached to updating cycle") + return nil +} + +func (vr *Verifier) verifyEndorsement(op [][]*rpc.Operation, c *rpc.Client, blockHeight int64) (error) { + endorsementPower := 0 + + threshold := 7000 * (2 / 3) + endorsers := make(map[tezos.Address]bool) + for i := 0; i < len(op); i++ { + for j := 0; j < len(op[i]); j++ { + for _, operation := range op[i][j].Contents { + switch operation.Kind() { + case tezos.OpTypeEndorsement: + tx := operation.(*rpc.Endorsement) + if _, isDelegate := vr.validators[tx.Metadata.Delegate]; isDelegate { + if _, ok := endorsers[tx.Metadata.Delegate]; !ok { + endorsers[tx.Metadata.Delegate] = true + endorsementPower += tx.Metadata.EndorsementPower + } + }else { + fmt.Println(vr.validators[tx.Metadata.Delegate]) + } + } + } + } + } + fmt.Println(len(endorsers)) + + if endorsementPower > threshold && len(endorsers) * 100 / len(vr.validators) > 66 { + return nil + } +return errors.New("endorsement verification failed") + +} + type VerifierOptions struct { BlockHeight int64 `json:"blockHeight"` BlockHash tezos.BlockHash `json:"parentHash"` diff --git a/cmd/iconbridge/example.config.json b/cmd/iconbridge/example.config.json index a6f2d352..9d6b15bb 100644 --- a/cmd/iconbridge/example.config.json +++ b/cmd/iconbridge/example.config.json @@ -17,20 +17,20 @@ { "name": "t2i", "src": { - "address": "btp://NetXnHfVqm9iesp.tezos/KT1UrLqhQHDC3mJw9BUrqsiix7JRbxTsvWJu", + "address": "btp://NetXnHfVqm9iesp.tezos/KT1GF34yJYnxGMNqgXEVyBWCK2HZBEaa939S", "endpoint": [ "https://ghostnet.tezos.marigold.dev" ], "options": { "verifier": { - "blockHeight": 2661054 + "blockHeight": 2693635 }, - "syncConcurrency": 10 + "syncConcurrency": 100 }, - "offset": 2661054 + "offset": 2693635 }, "dst": { - "address": "btp://0x7.icon/cx9f3e7e3c6dda6da9ea0c4c4e8f1b5d36b0b70742", + "address": "btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b", "endpoint": [ "https://berlin.net.solidwallet.io/api/v3" ], @@ -65,21 +65,21 @@ { "name": "i2t", "src": { - "address": "btp://0x2.icon/cx9f3e7e3c6dda6da9ea0c4c4e8f1b5d36b0b70742", + "address": "btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b", "endpoint": [ "https://berlin.net.solidwallet.io/api/v3/icon_dex" ], "options": { "verifier": { - "blockHeight": 8282502, + "blockHeight": 8414367, "validatorsHash": "0x04b56f3fc8d396cc7eb8124da8a554800b8758c9e2fff0802aa9682948e65447" }, - "syncConcurrency": 10 + "syncConcurrency": 100 }, - "offset": 8282502 + "offset": 8414367 }, "dst": { - "address": "btp://NetXnHfVqm9iesp.tezos/KT1UrLqhQHDC3mJw9BUrqsiix7JRbxTsvWJu", + "address": "btp://NetXnHfVqm9iesp.tezos/KT1GF34yJYnxGMNqgXEVyBWCK2HZBEaa939S", "endpoint": [ "https://ghostnet.tezos.marigold.dev" ], diff --git a/cmd/iconbridge/relay/relay.go b/cmd/iconbridge/relay/relay.go index 6fc4fca1..aac86adc 100644 --- a/cmd/iconbridge/relay/relay.go +++ b/cmd/iconbridge/relay/relay.go @@ -77,30 +77,36 @@ func (r *relay) Start(ctx context.Context) error { From: r.cfg.Src.Address, } - // filterSrcMsg := func(rxHeight, rxSeq uint64) (missingRxSeq uint64) { - // receipts := srcMsg.Receipts[:0] - // for _, receipt := range srcMsg.Receipts { - // if receipt.Height < rxHeight { - // continue - // } - // events := receipt.Events[:0] - // for _, event := range receipt.Events { - // if event.Sequence > rxSeq { - // rxSeq++ - // if event.Sequence != rxSeq { - // return rxSeq - // } - // events = append(events, event) - // } - // } - // receipt.Events = events - // if len(receipt.Events) > 0 { - // receipts = append(receipts, receipt) - // } - // } - // srcMsg.Receipts = receipts - // return 0 - // } + filterSrcMsg := func(rxHeight, rxSeq uint64) (missingRxSeq uint64) { + fmt.Println("reached to srcMsg. receipts") + receipts := srcMsg.Receipts[:0] + for _, receipt := range srcMsg.Receipts { + fmt.Println("receipt.height", receipt.Height) + fmt.Println("rx_height", rxHeight) + if receipt.Height < rxHeight { + continue + } + events := receipt.Events[:0] + for _, event := range receipt.Events { + fmt.Println("event.seq: ", event.Sequence) + fmt.Println("rx_seq:", rxSeq) + if event.Sequence > rxSeq { + rxSeq++ + if event.Sequence != rxSeq { + return rxSeq + } + events = append(events, event) + } + } + receipt.Events = events + if len(receipt.Events) > 0 { + receipts = append(receipts, receipt) + } + } + srcMsg.Receipts = receipts + fmt.Println(len(srcMsg.Receipts)) + return 0 + } relayCh := make(chan struct{}, 1) relayTicker := time.NewTicker(relayTickerInterval) @@ -197,11 +203,11 @@ func (r *relay) Start(ctx context.Context) error { fmt.Println("before filtering the message") fmt.Println(len(srcMsg.Receipts)) - // if missing := filterSrcMsg(link.RxHeight, link.RxSeq); missing > 0 { - // fmt.Println("did this filter the messages") - // r.log.WithFields(log.Fields{"rxSeq": missing}).Error("missing event sequence") - // return fmt.Errorf("missing event sequence") - // } + if missing := filterSrcMsg(link.RxHeight, link.RxSeq); missing > 0 { + fmt.Println("did this filter the messages") + r.log.WithFields(log.Fields{"rxSeq": missing}).Error("missing event sequence") + return fmt.Errorf("missing event sequence") + } fmt.Println("reached before sequence") fmt.Println("*****************************************************************") From abfbeba86b58ed719fb3bbd61eba881d63ce3e35 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Mon, 29 May 2023 07:51:12 +0545 Subject: [PATCH 081/211] fix: tezos iconbridge integration --- cmd/iconbridge/chain/icon/sender.go | 2 + cmd/iconbridge/chain/tezos/client.go | 2 +- cmd/iconbridge/chain/tezos/receiver.go | 187 +++++----- cmd/iconbridge/chain/tezos/sender.go | 2 + cmd/iconbridge/chain/tezos/verifier.go | 8 +- cmd/iconbridge/example.config.json | 18 +- devnet/docker/icon-tezos/scripts/config.sh | 4 +- .../icon-tezos/scripts/token.smartpy.sh | 50 ++- .../bmc/contracts/src/RLP_encode_struct.py | 4 +- .../bmc/contracts/tests/BMCManagement_test.py | 345 ++++++++++++++++++ smartpy/bmc/package.json | 3 +- smartpy/bmc/scripts/deploy.ts | 6 +- smartpy/bmc/test.sh | 53 +++ 13 files changed, 562 insertions(+), 122 deletions(-) create mode 100755 smartpy/bmc/contracts/tests/BMCManagement_test.py create mode 100755 smartpy/bmc/test.sh diff --git a/cmd/iconbridge/chain/icon/sender.go b/cmd/iconbridge/chain/icon/sender.go index ffb7f129..af5a60d6 100644 --- a/cmd/iconbridge/chain/icon/sender.go +++ b/cmd/iconbridge/chain/icon/sender.go @@ -19,6 +19,7 @@ package icon import ( "context" "encoding/base64" + "encoding/hex" "encoding/json" "fmt" "math/big" @@ -200,6 +201,7 @@ func (s *sender) Segment( return nil, nil, err } fmt.Println("should reach here without error") + fmt.Println(hex.EncodeToString(message)) return tx, newMsg, nil } diff --git a/cmd/iconbridge/chain/tezos/client.go b/cmd/iconbridge/chain/tezos/client.go index e123ac34..70619a92 100644 --- a/cmd/iconbridge/chain/tezos/client.go +++ b/cmd/iconbridge/chain/tezos/client.go @@ -245,7 +245,7 @@ func returnTxMetadata3(tx *rpc.Transaction, contractAddress tezos.Address, heigh for i := 0; i < len(tx.Metadata.InternalResults); i++ { fmt.Println("reached in for") internalResults := tx.Metadata.InternalResults[i] - if internalResults.Kind.String() == "event" && internalResults.Source.ContractAddress() == contractAddress.ContractAddress() { + if internalResults.Kind.String() == "event" && internalResults.Source.ContractAddress() == "KT1XamvZ9WgAmxq4eBGKi6ZRbLGuGJpYcqaj" { fmt.Println("Address matched") if internalResults.Tag == "Message" { message := internalResults.Payload.Args[0].Bytes diff --git a/cmd/iconbridge/chain/tezos/receiver.go b/cmd/iconbridge/chain/tezos/receiver.go index a6993e32..5f679559 100644 --- a/cmd/iconbridge/chain/tezos/receiver.go +++ b/cmd/iconbridge/chain/tezos/receiver.go @@ -1,10 +1,10 @@ package tezos import ( - "github.com/icon-project/icon-bridge/cmd/iconbridge/chain" "context" "encoding/json" "fmt" + "github.com/icon-project/icon-bridge/cmd/iconbridge/chain" "math/big" "sort" "strconv" @@ -18,9 +18,8 @@ import ( "blockwatch.cc/tzgo/contract" "blockwatch.cc/tzgo/rpc" "blockwatch.cc/tzgo/tezos" - "github.com/pkg/errors" "github.com/icon-project/icon-bridge/cmd/iconbridge/chain/tezos/types" - + "github.com/pkg/errors" ) const ( @@ -32,10 +31,10 @@ const ( ) type receiver struct { - log log.Logger - src chain.BTPAddress - dst chain.BTPAddress - opts ReceiverOptions + log log.Logger + src chain.BTPAddress + dst chain.BTPAddress + opts ReceiverOptions client *Client } @@ -61,52 +60,49 @@ func (r *receiver) Subscribe(ctx context.Context, msgCh chan<- *chain.Message, o Concurrnecy: r.opts.SyncConcurrency, } if err := r.receiveLoop(ctx, bn, - func (blN *types.BlockNotification) error { - fmt.Println("has to reach in this callback ", blN.Height.Uint64()) + func(blN *types.BlockNotification) error { + fmt.Println("has to reach in this callback ", blN.Height.Uint64()) - if blN.Height.Uint64() != lastHeight { - return fmt.Errorf( - "block notification: expected=%d, got %d", lastHeight, blN.Height.Uint64()) - } + if blN.Height.Uint64() != lastHeight { + return fmt.Errorf( + "block notification: expected=%d, got %d", lastHeight, blN.Height.Uint64()) + } - // var events []*chain.Event - receipts := blN.Receipts - for _, receipt := range receipts{ - events := receipt.Events[:0] - for _, event := range receipt.Events { - switch { + // var events []*chain.Event + receipts := blN.Receipts + for _, receipt := range receipts { + events := receipt.Events[:0] + for _, event := range receipt.Events { + switch { case event.Sequence == opts.Seq: events = append(events, event) - opts.Seq++ + opts.Seq++ case event.Sequence > opts.Seq: return fmt.Errorf("invalid event seq") - //TODO to be removed - default: - events = append(events, event) - opts.Seq++ + //TODO to be removed + } } + receipt.Events = events + fmt.Println(receipt.Height) + fmt.Println("appending") + // vCP = append(vCP, &chain.Receipt{Events: receipt.Events}) } - receipt.Events = events - fmt.Println(receipt.Height) - fmt.Println("appending") - // vCP = append(vCP, &chain.Receipt{Events: receipt.Events}) - } - if len(receipts) > 0 { - fmt.Println("reached to sending message") - fmt.Println(receipts[0].Height) - msgCh <- &chain.Message{Receipts: receipts} - } - fmt.Println("returned nill") - lastHeight++ - return nil - }); err != nil { + if len(receipts) > 0 { + fmt.Println("reached to sending message") + fmt.Println(receipts[0].Height) + msgCh <- &chain.Message{Receipts: receipts} + } + fmt.Println("returned nill") + lastHeight++ + return nil + }); err != nil { fmt.Println(err) - _errCh <- err + _errCh <- err } fmt.Println("Printing from inside the receiver") }() - + return _errCh, nil } @@ -117,12 +113,11 @@ func (r *receiver) Subscribe(ctx context.Context, msgCh chan<- *chain.Message, o // for i, receipt := range v.Receipts { // events := events[:0] - // } // } -func NewReceiver(src, dst chain.BTPAddress, urls []string, rawOpts json.RawMessage, l log.Logger) (chain.Receiver, error){ +func NewReceiver(src, dst chain.BTPAddress, urls []string, rawOpts json.RawMessage, l log.Logger) (chain.Receiver, error) { var newClient *Client var err error @@ -146,7 +141,6 @@ func NewReceiver(src, dst chain.BTPAddress, urls []string, rawOpts json.RawMessa err = json.Unmarshal(rawOpts, &receiver.opts) - if receiver.opts.SyncConcurrency < 1 { receiver.opts.SyncConcurrency = 1 } else if receiver.opts.SyncConcurrency > MonitorBlockMaxConcurrency { @@ -195,16 +189,16 @@ func (r *receiver) NewVerifier(ctx context.Context, previousHeight int64) (vri I id := chainIdHash.Uint32() if err != nil { - return nil, err - } + return nil, err + } vr := &Verifier{ - mu: sync.RWMutex{}, - next: header.Level + 1, - parentHash: header.Hash, + mu: sync.RWMutex{}, + next: header.Level + 1, + parentHash: header.Hash, parentFittness: fittness, - chainID: id, - c: r.client.Cl, + chainID: id, + c: r.client.Cl, } vr.updateValidatorsAndCycle(ctx, previousHeight, block.Metadata.LevelInfo.Cycle) @@ -215,7 +209,7 @@ func (r *receiver) NewVerifier(ctx context.Context, previousHeight int64) (vri I func (r *receiver) SyncVerifier(ctx context.Context, vr IVerifier, height int64, callback func([]*chain.Receipt) error) error { if height == vr.Next() { fmt.Println("returned from here") - return nil + return nil } if vr.Next() > height { @@ -225,21 +219,21 @@ func (r *receiver) SyncVerifier(ctx context.Context, vr IVerifier, height int64, type res struct { Height int64 Header *rpc.BlockHeader - Block *rpc.Block - Votes int64 + Block *rpc.Block + Votes int64 } type req struct { height int64 - err error - res *res - retry int64 + err error + res *res + retry int64 } fmt.Println("reached before starting to log") // r.log.WithFields(log.Fields{"height": vr.Next(), "target": height}).Info("syncVerifier: start") - + fmt.Println("reached in sync verifier") - var prevHeader *rpc.BlockHeader + var prevHeader *rpc.BlockHeader var prevBlock *rpc.Block cursor := vr.Next() @@ -247,11 +241,11 @@ func (r *receiver) SyncVerifier(ctx context.Context, vr IVerifier, height int64, for cursor <= height { fmt.Println("reached inside for") fmt.Println(r.opts.SyncConcurrency) - + rqch := make(chan *req, r.opts.SyncConcurrency) fmt.Println(len(rqch)) fmt.Println(cap(rqch)) - for i := cursor; len(rqch) < cap(rqch); i++{ + for i := cursor; len(rqch) < cap(rqch); i++ { rqch <- &req{height: i, retry: 5} } sres := make([]*res, 0, len(rqch)) @@ -261,7 +255,7 @@ func (r *receiver) SyncVerifier(ctx context.Context, vr IVerifier, height int64, case q.err != nil: if q.retry > 0 { q.retry-- - q.res, q.err = nil, nil + q.res, q.err = nil, nil rqch <- q continue } @@ -274,7 +268,7 @@ func (r *receiver) SyncVerifier(ctx context.Context, vr IVerifier, height int64, fmt.Println("should reach here in the second loop ") sres = append(sres, q.res) fmt.Println(cap(sres)) - if len(sres) == cap(sres){ + if len(sres) == cap(sres) { fmt.Println("closes channel") close(rqch) } @@ -291,8 +285,7 @@ func (r *receiver) SyncVerifier(ctx context.Context, vr IVerifier, height int64, } q.res.Height = q.height q.res.Header, q.err = r.client.GetBlockHeaderByHeight(ctx, r.client.Cl, q.height) - fmt.Println(q.res.Header) - if q.err != nil { + if q.err != nil { q.err = errors.Wrapf(q.err, "syncVerifier: getBlockHeader: %v", q.err) return } @@ -301,10 +294,9 @@ func (r *receiver) SyncVerifier(ctx context.Context, vr IVerifier, height int64, q.err = errors.Wrapf(q.err, "syncVerifier: getBlock: %v", q.err) return } - fmt.Println(q.res.Block) }(q) } - + } _sres, sres := sres, sres[:0] for _, v := range _sres { @@ -326,7 +318,7 @@ func (r *receiver) SyncVerifier(ctx context.Context, vr IVerifier, height int64, if prevHeader == nil { prevHeader = next.Header prevBlock = next.Block - continue + continue } if vr.Next() >= height { fmt.Println("did it just break") @@ -340,11 +332,11 @@ func (r *receiver) SyncVerifier(ctx context.Context, vr IVerifier, height int64, if err != nil { cursor = vr.Height() + 1 - prevHeader = nil + prevHeader = nil fmt.Println(cursor) fmt.Println("when some verification is failed prompts it to get the data again from that point") time.Sleep(15 * time.Second) - break + break // return errors.Wrapf(err, "syncVerifier: Verify: %v", err) } @@ -360,12 +352,13 @@ func (r *receiver) SyncVerifier(ctx context.Context, vr IVerifier, height int64, } } - // r.log.WithFields(log.Fields{"height": vr.Next(), "target": height}).Debug("syncVerifier: syncing") + // r.log.WithFields(log.Fields{"height": vr.Next(), "target": height}).Debug("syncVerifier: syncing") } // r.log.WithFields(log.Fields{"height": vr.Next()}).Info("syncVerifier: complete") fmt.Println("sync complete") - return nil + PrintSync() + return nil } type BnOptions struct { @@ -373,7 +366,7 @@ type BnOptions struct { Concurrnecy uint64 } -func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback func(v *types.BlockNotification) error) (err error){ +func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback func(v *types.BlockNotification) error) (err error) { fmt.Println("reached to receivelopp") if opts == nil { return errors.New("receiveLoop: invalid options: ") @@ -381,12 +374,14 @@ func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback fu var vr IVerifier - if r.opts.Verifier != nil{ + if r.opts.Verifier != nil { vr, err = r.NewVerifier(ctx, r.opts.Verifier.BlockHeight) if err != nil { return err } - err = r.SyncVerifier(ctx, vr, r.opts.Verifier.BlockHeight + 1, func(r []*chain.Receipt) error {return nil}) + + fmt.Println("The start height is: ", opts.StartHeight) + err = r.SyncVerifier(ctx, vr, opts.StartHeight + 1, func(r []*chain.Receipt) error { return nil }) if err != nil { return err } @@ -405,19 +400,19 @@ func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback fu } return block.GetLevel() } - next, latest := r.opts.Verifier.BlockHeight + 1, latestHeight() + next, latest := opts.StartHeight + 1, latestHeight() var lbn *types.BlockNotification for { select { - case <- ctx.Done(): + case <-ctx.Done(): return nil - case <- heightTicker.C: + case <-heightTicker.C: latest++ - case <- heightPoller.C: + case <-heightPoller.C: if height := latestHeight(); height > 0 { - latest = height + latest = height // r.log.WithFields(log.Fields{"latest": latest, "next": next}).Debug("poll height") } case bn := <-bnch: @@ -432,16 +427,17 @@ func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback fu } } else { if vr != nil { - fmt.Println("vr is not nil") + fmt.Println("vr is not nil for block heiht ", lbn.Header.Level) // header := bn.Header - if err := vr.Verify(ctx, lbn.Header, lbn.Block, bn.Proposer, r.client.Cl, bn.Header); err != nil { // change accordingly + if err := vr.Verify(ctx, lbn.Header, lbn.Block, bn.Proposer, r.client.Cl, bn.Header); err != nil { // change accordingly // r.log.WithFields(log.Fields{ // "height": lbn.Height, // "lbnHash": lbn.Hash, // "nextHeight": next, // "bnHash": bn.Hash}).Error("verification failed. refetching block ", err) + fmt.Println(err) fmt.Println("error in verifying ") - time.Sleep(20 * time.Second) + time.Sleep(5 * time.Second) next-- break } @@ -463,7 +459,7 @@ func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback fu <-bnch //r.log.WithFields(log.Fields{"lenBnch": len(bnch), "height": t.Height}).Info("remove unprocessed block noitification") } - + default: if next >= latest { time.Sleep(10 * time.Second) @@ -479,7 +475,7 @@ func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback fu qch := make(chan *bnq, cap(bnch)) - for i:= next; i < latest && len(qch) < cap(qch); i++{ + for i := next; i < latest && len(qch) < cap(qch); i++ { qch <- &bnq{i, nil, nil, RPCCallRetry} } @@ -490,9 +486,9 @@ func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback fu bns := make([]*types.BlockNotification, 0, len(qch)) for q := range qch { switch { - case q.err != nil : + case q.err != nil: if q.retry > 0 { - q.retry -- + q.retry-- q.v, q.err = nil, nil qch <- q continue @@ -521,14 +517,14 @@ func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback fu q.err = errors.Wrapf(err, "GetHeaderByHeight: %v", err) return } - q.v.Header = header // change accordingly - q.v.Hash = q.v.Hash // change accordingly + q.v.Header = header // change accordingly + q.v.Hash = q.v.Hash // change accordingly } block, err := r.client.GetBlockByHeight(ctx, r.client.Cl, q.v.Height.Int64()) if err != nil { q.err = errors.Wrapf(err, "GetBlockByHeight: %v", err) - return + return } q.v.Block = block fmt.Println("Getting for header: ", block.Header.Level) @@ -539,7 +535,7 @@ func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback fu return } q.v.Proposer = block.Metadata.Proposer - + hasBTPMessage, receipt, err := returnTxMetadata2(block, r.client.Contract.Address(), q.v.Height.Int64(), r.client) fmt.Println("has btp message", hasBTPMessage, q.v.Height.Uint64()) @@ -555,12 +551,12 @@ func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback fu } } if !*q.v.HasBTPMessage { - return + return } }(q) } } - // filtering nil + // filtering nil _bns_, bns := bns, bns[:0] for _, v := range _bns_ { @@ -574,7 +570,7 @@ func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback fu return bns[i].Height.Int64() < bns[j].Height.Int64() }) for i, v := range bns { - if v.Height.Int64() == next + int64(i) { + if v.Height.Int64() == next+int64(i) { bnch <- v } } @@ -585,3 +581,8 @@ func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback fu } } +func PrintSync() { + for i := 0; i < 100; i++ { + fmt.Println("realyer synced") + } +} diff --git a/cmd/iconbridge/chain/tezos/sender.go b/cmd/iconbridge/chain/tezos/sender.go index 7671fdd3..9dcc0a5b 100644 --- a/cmd/iconbridge/chain/tezos/sender.go +++ b/cmd/iconbridge/chain/tezos/sender.go @@ -214,6 +214,8 @@ func (tx *relayTx) Send(ctx context.Context) (err error) { fmt.Println("Previous is: ", tx.Prev) in := "{ \"prim\": \"Pair\", \"args\": [ { \"bytes\": \"" + messageHex + "\" }, { \"string\": \"" + tx.Prev + "\" } ] }" + fmt.Println(in) + if err := prim.UnmarshalJSON([]byte(in)); err != nil { fmt.Println("couldnot unmarshall empty string") fmt.Println(err) diff --git a/cmd/iconbridge/chain/tezos/verifier.go b/cmd/iconbridge/chain/tezos/verifier.go index 54d98fe0..977bc4d7 100644 --- a/cmd/iconbridge/chain/tezos/verifier.go +++ b/cmd/iconbridge/chain/tezos/verifier.go @@ -52,6 +52,9 @@ func (vr *Verifier) Verify(ctx context.Context, header *rpc.BlockHeader, block * if currentFittness < vr.parentFittness { return fmt.Errorf("Invalid block fittness", currentFittness) } + fmt.Println(header.Level) + fmt.Println(header.Predecessor) + fmt.Println(vr.parentHash.String()) previousHashInBlock := header.Predecessor if previousHashInBlock.String() != vr.parentHash.String() { @@ -77,7 +80,7 @@ func (vr *Verifier) Verify(ctx context.Context, header *rpc.BlockHeader, block * func (vr *Verifier) Update(ctx context.Context, header *rpc.BlockHeader, block *rpc.Block) error { vr.mu.Lock() defer vr.mu.Unlock() - fmt.Println("updating????") + fmt.Println("updating for block ????", header.Level) blockFittness := header.Fitness currentFittness, err := strconv.ParseInt(string(blockFittness[1].String()), 16, 64) @@ -91,9 +94,6 @@ func (vr *Verifier) Update(ctx context.Context, header *rpc.BlockHeader, block * vr.height = header.Level vr.next = header.Level + 1 - fmt.Println(vr.cycle) - fmt.Println(block.Metadata.LevelInfo.Cycle) - if vr.cycle != block.Metadata.LevelInfo.Cycle { fmt.Println("reached in updating validators and cycle") vr.updateValidatorsAndCycle(ctx, block.Header.Level, block.Metadata.LevelInfo.Cycle) diff --git a/cmd/iconbridge/example.config.json b/cmd/iconbridge/example.config.json index 9d6b15bb..02c2472e 100644 --- a/cmd/iconbridge/example.config.json +++ b/cmd/iconbridge/example.config.json @@ -17,25 +17,25 @@ { "name": "t2i", "src": { - "address": "btp://NetXnHfVqm9iesp.tezos/KT1GF34yJYnxGMNqgXEVyBWCK2HZBEaa939S", + "address": "btp://NetXnHfVqm9iesp.tezos/KT1ENZvToPx87LhuowJ1VixjjqQhSnYrcYLi", "endpoint": [ "https://ghostnet.tezos.marigold.dev" ], "options": { "verifier": { - "blockHeight": 2693635 + "blockHeight": 2759303 }, "syncConcurrency": 100 }, - "offset": 2693635 + "offset": 2759303 }, "dst": { - "address": "btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b", + "address": "btp://0x7.icon/cxdc28944407659973fe99487d75c5dd32c79be053", "endpoint": [ "https://berlin.net.solidwallet.io/api/v3" ], "options": { - "step_limit": 1000000 + "step_limit": 100000000 }, "key_store": { "version": 3, @@ -65,21 +65,21 @@ { "name": "i2t", "src": { - "address": "btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b", + "address": "btp://0x7.icon/cxdc28944407659973fe99487d75c5dd32c79be053", "endpoint": [ "https://berlin.net.solidwallet.io/api/v3/icon_dex" ], "options": { "verifier": { - "blockHeight": 8414367, + "blockHeight": 8714388, "validatorsHash": "0x04b56f3fc8d396cc7eb8124da8a554800b8758c9e2fff0802aa9682948e65447" }, "syncConcurrency": 100 }, - "offset": 8414367 + "offset": 8714388 }, "dst": { - "address": "btp://NetXnHfVqm9iesp.tezos/KT1GF34yJYnxGMNqgXEVyBWCK2HZBEaa939S", + "address": "btp://NetXnHfVqm9iesp.tezos/KT1ENZvToPx87LhuowJ1VixjjqQhSnYrcYLi", "endpoint": [ "https://ghostnet.tezos.marigold.dev" ], diff --git a/devnet/docker/icon-tezos/scripts/config.sh b/devnet/docker/icon-tezos/scripts/config.sh index 9aecfa46..72f5d650 100644 --- a/devnet/docker/icon-tezos/scripts/config.sh +++ b/devnet/docker/icon-tezos/scripts/config.sh @@ -17,7 +17,7 @@ export TAG="ICON BSC TESTNET" export BSC_BMC_NET="0x61.bsc" export ICON_BMC_NET="0x2.icon" export SNOW_BMC_NET="0x229.snow" -export TZ_BMC_NET="0x63.tezos" +export TZ_BMC_NET="NetXnHfVqm9iesp.tezos" export GOLOOP_RPC_NID="0x2" export BSC_NID="97" export TEZOS_NID="NetXnHfVqm9iesp" @@ -44,7 +44,7 @@ export ICON_WRAPPED_COIN_DECIMALS=(18 18 18 18 18 18 18) export TZ_ENDPOINT="https://ghostnet.tezos.marigold.dev" export TZ_NATIVE_COIN_SYM=("XTZ") -export TZ_NATIVE_COIN_NAME=("btp-$TZ_BMC_NET-TZ") +export TZ_NATIVE_COIN_NAME=("btp-$TZ_BMC_NET-XTZ") export TZ_NATIVE_TOKEN_SYM=("BUSD" "USDT" "USDC" "BTCB" "ETH") export TZ_NATIVE_TOKEN_NAME=("btp-$TZ_BMC_NET-BUSD" "btp-$TZ_BMC_NET-USDT" "btp-$TZ_BMC_NET-USDC" "btp-$TZ_BMC_NET-BTCB" "btp-$TZ_BMC_NET-ETH") export TZ_WRAPPED_COIN_SYM=("ICX" "sICX" "bnUSD" "ICZ") diff --git a/devnet/docker/icon-tezos/scripts/token.smartpy.sh b/devnet/docker/icon-tezos/scripts/token.smartpy.sh index 1b105a80..8764c028 100644 --- a/devnet/docker/icon-tezos/scripts/token.smartpy.sh +++ b/devnet/docker/icon-tezos/scripts/token.smartpy.sh @@ -5,6 +5,9 @@ # source prc.sh # source keystore.sh +export CONFIG_DIR=~/GoProjects/icon-bridge/smartpy +export TEZOS_BMC_NID="NetXnHfVqm9iesp.tezos" + tz_lastBlock() { octez-client rpc get /chains/main/blocks/head/header } @@ -16,36 +19,36 @@ extract_chainHeight() { } deploy_smartpy_bmc_management(){ + cd $(echo $CONFIG_DIR/bmc) if [ ! -f tz.addr.bmcmanagementbtp ]; then echo "deploying bmc_management" extract_chainHeight - cd ~/GoProjects/icon-bridge/smartpy/bmc npm run compile bmc_management local deploy=$(npm run deploy bmc_management @GHOSTNET) sleep 5 deploy=${deploy#*::} echo $deploy > tz.addr.bmc_management - echo "btp://0x63.tezos/$(cat tz.addr.bmc)" > tz.addr.bmcmanagementbtp + echo "btp://$(echo $TEZOS_BMC_NID)/$(cat tz.addr.bmc_management)" > tz.addr.bmcmanagementbtp fi } deploy_smartpy_bmc_periphery(){ + cd $(echo $CONFIG_DIR/bmc) if [ ! -f tz.addr.bmcperipherybtp ]; then echo "deploying bmc_periphery" - cd ~/GoProjects/icon-bridge/smartpy/bmc npm run compile bmc_periphery local deploy=$(npm run deploy bmc_periphery @GHOSTNET) sleep 5 deploy=${deploy#*::} echo $deploy > tz.addr.bmc_periphery - echo "btp://0x63.tezos/$(cat tz.addr.bmc_periphery)" > tz.addr.bmcperipherybtp + echo "btp://$(echo $TEZOS_BMC_NID)/$(cat tz.addr.bmc_periphery)" > tz.addr.bmcperipherybtp fi } deploy_smartpy_bts_periphery(){ + cd $(echo $CONFIG_DIR/bts) if [ ! -f tz.addr.bts_periphery ]; then echo "deploying bts_periphery" - cd ~/GoProjects/icon-bridge/smartpy/bts npm run compile bts_periphery local deploy=$(npm run deploy bts_periphery @GHOSTNET) sleep 5 @@ -55,6 +58,7 @@ deploy_smartpy_bts_periphery(){ } deploy_smartpy_bts_core(){ + cd $(echo $CONFIG_DIR/bts) if [ ! -f tz.addr.bts_core ]; then echo "deploying bts_core" cd ~/GoProjects/icon-bridge/smartpy/bts @@ -67,6 +71,7 @@ deploy_smartpy_bts_core(){ } deploy_smartpy_bts_owner_manager(){ + cd $(echo $CONFIG_DIR/bts) if [ ! -f tz.addr.btsperipherybtp ]; then echo "deploying bts_owner_manager" cd ~/GoProjects/icon-bridge/smartpy/bts @@ -79,6 +84,33 @@ deploy_smartpy_bts_owner_manager(){ } +configure_smartpy_bmc_management_set_bmc_periphery() { + echo "Adding BMC periphery in bmc management" + cd $(echo $CONFIG_DIR/bmc) + + local bmc_periphery=$(echo $(cat tz.addr.bmc_periphery)) + echo $bmc_periphery + + local bmc_management=$(echo $(cat tz.addr.bmc_management)) + echo $bmc_management + + local ocBR=\'\" + local coBR=\"\' + local arg=$(echo $(echo $ocBR$(echo $bmc_periphery$(echo $coBR)))) + + echo $arg + + # octez-client transfer 0 from bmcOwner to KT1BE6ohnjunYd1C96yPaThwNvFZu4TN8iBy --entrypoint set_bmc_periphery --arg '"KT1JX3Z3AQnf6oDae87Z9mw1g4jhB38tAGQY"' --burn-cap 1 + echo octez-client transfer 0 from bmcOwner to $(echo $bmc_management) --entrypoint set_bmc_periphery --arg $(echo $arg) --burn-cap 1 +} + +configure_smartpy_bmc_management_set + + + + + + # bts core @@ -86,5 +118,9 @@ deploy_smartpy_bts_owner_manager(){ - -deploy_smartpy_bts_owner_manager \ No newline at end of file +# deploy_smartpy_bmc_management +# deploy_smartpy_bmc_periphery +# deploy_smartpy_bts_periphery +# deploy_smartpy_bts_core +# deploy_smartpy_bts_owner_manager +configure_smartpy_bmc_management_set_bmc_periphery \ No newline at end of file diff --git a/smartpy/bmc/contracts/src/RLP_encode_struct.py b/smartpy/bmc/contracts/src/RLP_encode_struct.py index 057b5fc7..cc9ff814 100644 --- a/smartpy/bmc/contracts/src/RLP_encode_struct.py +++ b/smartpy/bmc/contracts/src/RLP_encode_struct.py @@ -18,8 +18,8 @@ def encode_bmc_message(self, params): encode_src = sp.view("encode_string", self.data.helper, params.src, t=sp.TBytes).open_some() encode_dst = sp.view("encode_string", self.data.helper, params.dst, t=sp.TBytes).open_some() encode_svc = sp.view("encode_string", self.data.helper, params.svc, t=sp.TBytes).open_some() - encode_sn = sp.view("encode_nat", self.data.helper, params.sn, t=sp.TBytes).open_some() - + nat_sn = sp.as_nat(params.sn) + encode_sn = sp.view("encode_nat", self.data.helper, nat_sn, t=sp.TBytes).open_some() rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [encode_src, encode_dst, encode_svc, encode_sn, params.message], t=sp.TBytes).open_some() return rlp_bytes_with_prefix diff --git a/smartpy/bmc/contracts/tests/BMCManagement_test.py b/smartpy/bmc/contracts/tests/BMCManagement_test.py new file mode 100755 index 00000000..8705a732 --- /dev/null +++ b/smartpy/bmc/contracts/tests/BMCManagement_test.py @@ -0,0 +1,345 @@ +import smartpy as sp + +BMCManagement = sp.io.import_script_from_url("file:./contracts/src/bmc_management.py") +BMCPeriphery = sp.io.import_script_from_url("file:./contracts/src/bmc_periphery.py") +BMCHelper = sp.io.import_script_from_url("file:./contracts/src/helper.py") +ParseAddress = sp.io.import_script_from_url("file:./contracts/src/parse_address.py") + + + + + +@sp.add_test("BMCManagementTest") +def test(): + sc = sp.test_scenario() + + # test account + alice = sp.test_account("Alice") + creator = sp.test_account("Creator") + jack = sp.test_account("Jack") + bob = sp.test_account("Bob") + creator2 = sp.test_account("creator2") + service1_address = sp.test_account("service1_address") + service2_address = sp.test_account("service2_address") + + + # deploy BMCManagement contract + + helper_contract = deploy_helper_contract() + sc += helper_contract + + bmcManagement_contract = deploy_bmcManagement_contract(creator.address, helper_contract.address) + sc += bmcManagement_contract + + parse_address = deploy_parse_address() + sc += parse_address + + bmcPeriphery_contract = deploy_bmcPeriphery_contract(bmcManagement_contract.address, helper_contract.address, parse_address.address) + sc += bmcPeriphery_contract + + + + bmc_periphery_address = bmcPeriphery_contract.address + + + # Test case 1: bmc_periphery + sc.h1("Test case 1: set bmc_periphery to a valid address") + sc.verify(bmcManagement_contract.data.bmc_periphery.is_some() == False) + bmcManagement_contract.set_bmc_periphery(bmc_periphery_address).run(sender=creator) + # sender should be owner + bmcManagement_contract.set_bmc_periphery(bob.address).run(sender=alice, valid=False, exception="Unauthorized") + # repeated bmc_periphery should throw error + bmcManagement_contract.set_bmc_periphery(bmc_periphery_address).run(sender=creator, valid=False, exception="AlreadyExistsBMCPeriphery") + # Verify that bmc_periphery is set to the valid address + sc.verify(bmcManagement_contract.data.bmc_periphery.is_some() == True) + sc.verify(bmcManagement_contract.data.bmc_periphery.open_some() == bmc_periphery_address) + + # set_bmc_btp_address + bmcManagement_contract.set_bmc_btp_address("tezos.77").run(sender=creator) + + + # Test case 2: add_owner + # throw error when adding owner by random address + bmcManagement_contract.add_owner(alice.address).run(sender=bob, valid=False, exception="Unauthorized") + # successfully added new owner + bmcManagement_contract.add_owner(alice.address).run(sender=creator) + sc.verify(bmcManagement_contract.data.owners[alice.address] == True) + + + # Test case 3: remove owner + # throw error when removing owner by random address + bmcManagement_contract.remove_owner(alice.address).run(sender=bob, valid=False, exception="Unauthorized") + # working + bmcManagement_contract.remove_owner(alice.address).run(sender=creator) + sc.verify(~bmcManagement_contract.data.owners.contains(jack.address)) + + + # Test case 4: is_owner + # Add an owner + bmcManagement_contract.add_owner(creator2.address).run(sender=creator) + # Test the is_owner view function + sc.verify(bmcManagement_contract.is_owner(creator2.address) == True) + + + # Test case 5: add_service function + svc1 = sp.string("service1") + svc2 = sp.string("service2") + svc3 = sp.string("service3") + # add service by random address should fail + bmcManagement_contract.add_service(sp.record(addr=service1_address.address, svc=svc1)).run(sender=bob, valid=False, exception="Unauthorized") + # adding service + bmcManagement_contract.add_service(sp.record(addr=service1_address.address, svc=svc1)).run(sender=creator) + # shouldn't add same service twice + bmcManagement_contract.add_service(sp.record(addr=service1_address.address, svc=svc1)).run(sender=creator, valid=False, exception="AlreadyExistsBSH") + + + # Test case 6: remove_service function + # remove service by random address should fail + bmcManagement_contract.remove_service(svc2).run(sender=bob, valid=False, exception="Unauthorized") + # removing unregistered should throw error + bmcManagement_contract.remove_service(svc3).run(sender=creator, valid=False) + # removing service + bmcManagement_contract.add_service(sp.record(addr=service2_address.address, svc=svc2)).run(sender=creator) + bmcManagement_contract.remove_service(svc2).run(sender=creator) + + + #test case 7: get_services function + services = bmcManagement_contract.get_services() + sc.verify_equal(services, sp.map({0: sp.record(svc=svc1, addr=service1_address.address)})) + + # test case 13: add_route function + dst = "btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258dest" + next_link = "btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b" + # only owner can add routes + bmcManagement_contract.add_route(sp.record(dst=dst, link=next_link)).run(sender=bob, valid=False, exception="Unauthorized") + # should work + bmcManagement_contract.add_route(sp.record(dst=dst, link=next_link)).run(sender=creator) + # cannot add already existed route + bmcManagement_contract.add_route(sp.record(dst=dst, link=next_link)).run(sender=creator, valid=False, exception="AlreadyExistRoute") + + + # # test case 14: remove_route function + # dst1 = "btp://78.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5DEST1" + # next_link1 = "btp://78.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5LINK1" + # # only owner can remove routes + # bmcManagement_contract.remove_route(dst).run(sender=bob, valid=False,exception="Unauthorized") + # # throw error when non-exist route is given & this should throw error but not thrown + # bmcManagement_contract.remove_route(dst1).run(sender=creator, valid=False, exception="NotExistRoute") + # # should work + # bmcManagement_contract.add_route(sp.record(dst=dst1, link=next_link1)).run(sender=creator) + # bmcManagement_contract.remove_route(dst1).run(sender=creator) + + + # # test case 15: get_routes function + # get_routes = bmcManagement_contract.get_routes() + # sc.verify_equal(get_routes, sp.map({0: sp.record(dst=sp.string("btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hDEST"), next=sp.string("btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"))})) + + + # test case 8: add_link function + # add_link by random address should fail + bmcManagement_contract.add_link("btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW").run(sender=bob, valid=False, exception="Unauthorized") + # should work + bmcManagement_contract.add_link("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b").run(sender=creator) + # add_link by of same link should fail + bmcManagement_contract.add_link("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b").run(sender=creator, valid=False, exception="AlreadyExistsLink") + + # + # # test case 9: remove_link function + # # remove_link by random address should fail + # bmcManagement_contract.remove_link("btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnB").run(sender=bob, valid=False, exception="Unauthorized") + # # remove_link should throw error when removing non-existing link + # bmcManagement_contract.remove_link("btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnZ").run(sender=creator, valid=False, exception="NotExistsLink") + # # should work + # bmcManagement_contract.add_link("btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnA").run(sender=creator) + # bmcManagement_contract.remove_link("btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnA").run(sender=creator) + # + # + # # test case 10: get_links function + # link_to_compare = bmcManagement_contract.get_links() + # added_link = sp.list(['btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW']) + # sc.verify_equal(link_to_compare, added_link) + # + # + # # test case 11: set_link_rx_height + # link = sp.string('btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW') + # height = sp.nat(2) + # # error when not exist link is given + # bmcManagement_contract.set_link_rx_height(link="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnA", height=height).run(sender=creator, valid=False, exception="NotExistsKey") + # # error when not invalid height is given + # bmcManagement_contract.set_link_rx_height(link=link, height=sp.nat(0)).run(sender=creator,valid=False,exception="InvalidRxHeight") + # # should work + # bmcManagement_contract.set_link_rx_height(link=link, height=height).run(sender=creator) + # sc.verify_equal(bmcManagement_contract.data.links[link].rx_height, 2) + # + # + # # test case 12: set_link function + # block_interval = sp.nat(2) + # _max_aggregation = sp.nat(3) + # delay_limit = sp.nat(2) + # # only owner should set link + # bmcManagement_contract.set_link(sp.record(_link=link, block_interval=block_interval,_max_aggregation=_max_aggregation, delay_limit=delay_limit)).run(sender=bob, valid=False, exception="Unauthorized") + # # error when link doesnt exist + # bmcManagement_contract.set_link(sp.record(_link="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnZ", block_interval=block_interval,_max_aggregation=_max_aggregation, delay_limit=delay_limit)).run(sender=creator, valid=False, exception="NotExistsLink") + # # error when invalid paramters were given + # bmcManagement_contract.set_link(sp.record(_link=link, block_interval=block_interval,_max_aggregation=sp.nat(0), delay_limit=delay_limit)).run(sender=creator, valid=False, exception="InvalidParam") + # bmcManagement_contract.set_link(sp.record(_link=link, block_interval=block_interval,_max_aggregation=_max_aggregation, delay_limit=sp.nat(0))).run(sender=creator, valid=False, exception="InvalidParam") + # # should work + # bmcManagement_contract.set_link(sp.record(_link=link, block_interval=block_interval,_max_aggregation=_max_aggregation, delay_limit=delay_limit)).run(sender=creator) + # + # + # # test case 16: add_relay function + # # only owner should add relay + # bmcManagement_contract.add_relay(sp.record(link=link, addr=sp.set([sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiADD")]))).run(sender=bob, valid=False, exception="Unauthorized") + # # fail when non-exist link is given + # bmcManagement_contract.add_relay(sp.record(link="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUNONLINK", addr=sp.set([sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiADD")]))).run(sender=creator, valid=False, exception="NotExistsLink") + # # should work + # bmcManagement_contract.add_relay(sp.record(link=link, addr=sp.set([sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")]))).run(sender=creator) + # + # + # # test case 17: remove_relay function + # # only owner should remove relay + # bmcManagement_contract.remove_relay(sp.record(link=link, addr=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"))).run(sender=bob, valid=False, exception="Unauthorized") + # # fail when non-exist link is given + # bmcManagement_contract.remove_relay(sp.record(link="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUNONLINK", addr=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiADD"))).run(sender=creator, valid=False, exception="NotExistsLink") + # # should work + # next_link1 = sp.string("btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5LINK1") + # bmcManagement_contract.add_link(next_link1).run(sender=creator) + # bmcManagement_contract.add_relay(sp.record(link=next_link1, addr=sp.set([sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxADD1")]))).run(sender=creator) + # bmcManagement_contract.remove_relay(sp.record(link=next_link1, addr=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxADD1"))).run(sender=creator) + # + # + # # test case 18: get_relays function + # compared_to = sp.list([sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")]) + # get_relays = bmcManagement_contract.get_relays(link) + # sc.verify_equal(get_relays, compared_to) + # + # + # # test case 19: get_bsh_service_by_name function + # get_bsh_service_by_name = bmcManagement_contract.get_bsh_service_by_name(svc1) + # sc.verify_equal(get_bsh_service_by_name, service1_address.address) + # + # + # # # test case 20: get_link function + # get_link = bmcManagement_contract.get_link(link) + # data = sp.record( + # relays=sp.set([sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")]), + # reachable=sp.set([]), + # rx_seq=sp.nat(0), + # tx_seq=sp.nat(7), + # block_interval_src=sp.nat(2), + # block_interval_dst=sp.nat(0), + # max_aggregation=sp.nat(3), + # delay_limit=sp.nat(2), + # relay_idx=sp.nat(0), + # rotate_height=sp.nat(0), + # rx_height=sp.nat(0), + # rx_height_src=sp.nat(0), + # is_connected=True + # ) + # sc.verify_equal(get_link, data) + # + # + # # test case 21: get_link_rx_seq function + # get_link_rx_seq = bmcManagement_contract.get_link_rx_seq(link) + # sc.verify_equal(get_link_rx_seq, 0) + # + # + # # test case 22: get_link_tx_seq function + # get_link_tx_seq = bmcManagement_contract.get_link_tx_seq(link) + # sc.verify_equal(get_link_tx_seq, 7) + # + # + # # test case 23: get_link_rx_height function + # get_link_rx_height = bmcManagement_contract.get_link_rx_height(link) + # sc.verify_equal(get_link_rx_height, 0) + # + # + # # test case 24: get_link_relays function + # get_link_relays = bmcManagement_contract.get_link_relays(link) + # sc.verify_equal(get_link_relays, compared_to) + # + # + # # test case 25: get_relay_status_by_link function + # get_link_relays = bmcManagement_contract.get_relay_status_by_link(link) + # sc.verify_equal(get_link_relays, sp.map({0: sp.record(addr=sp.address('tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9'), block_count=0, msg_count=0)})) + # + # + # # test case 26: update_link_rx_seq function + # #only bmc periphery address can run other users should get error + # bmcManagement_contract.update_link_rx_seq(sp.record(prev=next_link1, val=sp.nat(3))).run(sender=creator, valid=False, exception="Unauthorized") + # #working + # bmcManagement_contract.update_link_rx_seq(sp.record(prev=next_link1, val=sp.nat(3))).run(sender=bmc_periphery_address) + # # Check that the value of rx_seq is updated correctly + # sc.verify_equal(bmcManagement_contract.data.links[next_link1].rx_seq, 3) + # + # + # # test case 27: update_link_tx_seq function + # # only bmc periphery address can run other users should get error + # bmcManagement_contract.update_link_tx_seq(next_link1).run(sender=creator, valid=False, exception="Unauthorized") + # # working + # bmcManagement_contract.update_link_tx_seq(next_link1).run(sender=bmc_periphery_address) + # # Check that the value of tx_seq is updated correctly + # sc.verify_equal(bmcManagement_contract.data.links[next_link1].tx_seq, 1) + # + # + # # test case 28: update_link_rx_height function + # #only bmc periphery address can run other users should get error + # bmcManagement_contract.update_link_rx_height(sp.record(prev=next_link1, val=sp.nat(3))).run(sender=creator, valid=False, exception="Unauthorized") + # #working + # bmcManagement_contract.update_link_rx_height(sp.record(prev=next_link1, val=sp.nat(4))).run(sender=bmc_periphery_address) + # # Check that the value of rx_seq is updated correctly + # sc.verify_equal(bmcManagement_contract.data.links[next_link1].rx_height, 4) + # + # + # # test case 29: update_link_reachable function + # to = sp.list(["btp://net1/addr1", "btp://net2/addr2"]) + # # only bmc periphery address can run other users should get error + # bmcManagement_contract.update_link_reachable(sp.record(prev=next_link1, to=to)).run(sender=creator, valid=False, exception="Unauthorized") + # # should work + # bmcManagement_contract.update_link_reachable(sp.record(prev=next_link1, to=to)).run(sender=bmc_periphery_address) + # # value checking + # sc.verify_equal(bmcManagement_contract.data.links[next_link1].reachable, sp.set(['btp://net1/addr1', 'btp://net2/addr2'])) + # + # + # # test case 30: delete_link_reachable function + # #only bmc periphery address can run other users should get error + # bmcManagement_contract.delete_link_reachable(sp.record(prev=next_link1, index=sp.nat(0))).run(sender=creator, valid=False, exception="Unauthorized") + # #working + # bmcManagement_contract.delete_link_reachable(sp.record(prev=next_link1, index=sp.nat(0))).run(sender=bmc_periphery_address) + # # value checking + # sc.verify_equal(bmcManagement_contract.data.links[next_link1].reachable, sp.set(['btp://net2/addr2'])) + # + # + # # test case 31: update_relay_stats function + # #only bmc periphery address can run other users should get error + # bmcManagement_contract.update_relay_stats(sp.record(relay=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiADD"), block_count_val=sp.nat(2), msg_count_val=sp.nat(2))).run(sender=creator, valid=False, exception="Unauthorized") + # #working + # bmcManagement_contract.update_relay_stats(sp.record(relay=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), block_count_val=sp.nat(2), msg_count_val=sp.nat(2))).run(sender=bmc_periphery_address) + # # value checking + # sc.verify_equal(bmcManagement_contract.data.relay_stats[sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")].block_count, 2) + # sc.verify_equal(bmcManagement_contract.data.relay_stats[sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")].msg_count, 2) + # + # + # # test case 32: resolve_route function + # sc.verify_equal(bmcManagement_contract.resolve_route(sp.string('77.tezos')), sp.pair('btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW', 'btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hDEST')) + # + + + +def deploy_bmcManagement_contract(owner, helper): + bmcManagement_contract = BMCManagement.BMCManagement(owner, helper) + return bmcManagement_contract + +def deploy_bmcPeriphery_contract(bmc_addres, helper, parse): + owner = sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9") + bmcPeriphery_contract = BMCPeriphery.BMCPreiphery(bmc_addres, helper, parse, owner) + return bmcPeriphery_contract + +def deploy_helper_contract(): + helper_contract = BMCHelper.Helper() + return helper_contract + + +def deploy_parse_address(): + parse_address = ParseAddress.ParseAddress() + return parse_address \ No newline at end of file diff --git a/smartpy/bmc/package.json b/smartpy/bmc/package.json index 47727297..1fa53ef8 100644 --- a/smartpy/bmc/package.json +++ b/smartpy/bmc/package.json @@ -5,7 +5,8 @@ "bin": "./bin/cli.js", "scripts": { "compile": "bash ./compile.sh", - "deploy": "npx ts-node scripts/deploy.ts" + "deploy": "npx ts-node scripts/deploy.ts", + "test": "bash ./test.sh" }, "author": "Roshan Parajuli", "license": "MIT", diff --git a/smartpy/bmc/scripts/deploy.ts b/smartpy/bmc/scripts/deploy.ts index 9b50353a..42bceb58 100644 --- a/smartpy/bmc/scripts/deploy.ts +++ b/smartpy/bmc/scripts/deploy.ts @@ -45,9 +45,9 @@ const deploy = async () => { init: require(`../contracts/build/${file}_storage.json`), }); - console.log("Successfully deployed contract"); - console.log(`>> Transaction hash: ${hash}`); - console.log(`>> Contract address: ${contractAddress}`); + // console.log("Successfully deployed contract"); + // console.log(`>> Transaction hash: ${hash}`); + console.log(`::${contractAddress}`); } catch (error) { console.log( `Oops... Deployment faced an issue.\nHere's the detailed info about the error,\n${error}` diff --git a/smartpy/bmc/test.sh b/smartpy/bmc/test.sh new file mode 100755 index 00000000..11bfbe8b --- /dev/null +++ b/smartpy/bmc/test.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash + +set -e -o pipefail + +echo "----------------------------------------" +echo "Compiling contracts ... " +echo "----------------------------------------" + +# Expected location of SmartPy CLI. +SMART_PY_CLI=~/smartpy-cli/SmartPy.sh + +# Build artifact directory. +TEST_OUT_DIR=./contracts/build/.contract_build/test + +# Array of SmartPy files to compile. +# CONTRACTS_ARRAY=(counter) + +# Exit if SmartPy is not installed. +if [ ! -f "$SMART_PY_CLI" ]; then + echo "Fatal: Please install SmartPy CLI at $SMART_PY_CLI" && exit +fi + +function processContract { + CONTRACT_NAME=$1 + TEST_OUT_DIR=$2 + CONTRACT_IN_TEST="./contracts/tests/${CONTRACT_NAME}_test.py" + CONTRACT_OUT="${CONTRACT_NAME}.json" + STORAGE_OUT="${CONTRACT_NAME}_storage.json" + CONTRACT_COMPILED="${CONTRACT_NAME}/step_000_cont_0_contract.json" + STORAGE_COMPILED="${CONTRACT_NAME}/step_000_cont_0_storage.json" + + echo ">> Processing ${CONTRACT_NAME}" + + # Ensure file exists. + if [ ! -f "$CONTRACT_IN_TEST" ]; then + echo "Fatal: $CONTRACT_IN_TEST not found. Running from wrong dir?" && exit + fi + + echo ">>> Commencing the tests ${CONTRACT_NAME} ... " + $SMART_PY_CLI test $CONTRACT_IN_TEST $TEST_OUT_DIR --html +} + +export PYTHONPATH=$PWD + + +# Use if you want to pass a contract or more as arguments. +for n in $(seq 1 $#); do + processContract $1 $TEST_OUT_DIR + shift +done + + +echo "> Test Complete." \ No newline at end of file From af1f8fe9303478279d508e47e46418a3371c422b Mon Sep 17 00:00:00 2001 From: icondev22 Date: Thu, 1 Jun 2023 18:45:35 +0545 Subject: [PATCH 082/211] fix: icon tezos integration --- cmd/iconbridge/chain/tezos/client.go | 2 +- cmd/iconbridge/example.config.json | 16 +-- .../icon-tezos/scripts/token.smartpy.sh | 132 ++++++++++++++++-- smartpy/bmc/package-lock.json | 4 +- smartpy/bts/package-lock.json | 4 +- smartpy/bts/scripts/deploy.ts | 4 +- smartpy/bts/test.sh | 53 +++++++ 7 files changed, 186 insertions(+), 29 deletions(-) create mode 100755 smartpy/bts/test.sh diff --git a/cmd/iconbridge/chain/tezos/client.go b/cmd/iconbridge/chain/tezos/client.go index 70619a92..7414bb65 100644 --- a/cmd/iconbridge/chain/tezos/client.go +++ b/cmd/iconbridge/chain/tezos/client.go @@ -245,7 +245,7 @@ func returnTxMetadata3(tx *rpc.Transaction, contractAddress tezos.Address, heigh for i := 0; i < len(tx.Metadata.InternalResults); i++ { fmt.Println("reached in for") internalResults := tx.Metadata.InternalResults[i] - if internalResults.Kind.String() == "event" && internalResults.Source.ContractAddress() == "KT1XamvZ9WgAmxq4eBGKi6ZRbLGuGJpYcqaj" { + if internalResults.Kind.String() == "event" && internalResults.Source.ContractAddress() == "KT1CYbCyejjPcB7qKhoXqd45UbUMfZRFcbTk" { fmt.Println("Address matched") if internalResults.Tag == "Message" { message := internalResults.Payload.Args[0].Bytes diff --git a/cmd/iconbridge/example.config.json b/cmd/iconbridge/example.config.json index 02c2472e..fc5ad1fa 100644 --- a/cmd/iconbridge/example.config.json +++ b/cmd/iconbridge/example.config.json @@ -17,20 +17,20 @@ { "name": "t2i", "src": { - "address": "btp://NetXnHfVqm9iesp.tezos/KT1ENZvToPx87LhuowJ1VixjjqQhSnYrcYLi", + "address": "btp://NetXnHfVqm9iesp.tezos/KT1XQ9qNQgHMGq5h5uvvXaZFtj7vGerQ8yga", "endpoint": [ "https://ghostnet.tezos.marigold.dev" ], "options": { "verifier": { - "blockHeight": 2759303 + "blockHeight": 2792278 }, "syncConcurrency": 100 }, - "offset": 2759303 + "offset": 2792278 }, "dst": { - "address": "btp://0x7.icon/cxdc28944407659973fe99487d75c5dd32c79be053", + "address": "btp://0x7.icon/cx152b8c1fe4f377443df0e643ab066ea219c1086a", "endpoint": [ "https://berlin.net.solidwallet.io/api/v3" ], @@ -65,21 +65,21 @@ { "name": "i2t", "src": { - "address": "btp://0x7.icon/cxdc28944407659973fe99487d75c5dd32c79be053", + "address": "btp://0x7.icon/cx152b8c1fe4f377443df0e643ab066ea219c1086a", "endpoint": [ "https://berlin.net.solidwallet.io/api/v3/icon_dex" ], "options": { "verifier": { - "blockHeight": 8714388, + "blockHeight": 8857590, "validatorsHash": "0x04b56f3fc8d396cc7eb8124da8a554800b8758c9e2fff0802aa9682948e65447" }, "syncConcurrency": 100 }, - "offset": 8714388 + "offset": 8857590 }, "dst": { - "address": "btp://NetXnHfVqm9iesp.tezos/KT1ENZvToPx87LhuowJ1VixjjqQhSnYrcYLi", + "address": "btp://NetXnHfVqm9iesp.tezos/KT1XQ9qNQgHMGq5h5uvvXaZFtj7vGerQ8yga", "endpoint": [ "https://ghostnet.tezos.marigold.dev" ], diff --git a/devnet/docker/icon-tezos/scripts/token.smartpy.sh b/devnet/docker/icon-tezos/scripts/token.smartpy.sh index 8764c028..b0e2549b 100644 --- a/devnet/docker/icon-tezos/scripts/token.smartpy.sh +++ b/devnet/docker/icon-tezos/scripts/token.smartpy.sh @@ -6,7 +6,20 @@ # source keystore.sh export CONFIG_DIR=~/GoProjects/icon-bridge/smartpy -export TEZOS_BMC_NID="NetXnHfVqm9iesp.tezos" +export TEZOS_SETTER=~/tezos-addresses +export TEZOS_BMC_NID=NetXnHfVqm9iesp.tezos +export ICON_BMC_NID=0x7.icon +export TZ_COIN_SYMBOL=XTZ +export TZ_FIXED_FEE=0 +export TZ_NUMERATOR=0 +export TZ_DECIMALS=6 +export ICON_NATIVE_COIN_NAME=btp-0x7.icon-ICX +export ICON_SYMBOL=ICX +export ICON_FIXED_FEE=4300000000000000000 +export ICON_NUMERATOR=100 +export ICON_DECIMALS=18 +export RELAYER_ADDRESS=tz1ZPVxKiybvbV1GvELRJJpyE1xj1UpNpXMv + tz_lastBlock() { octez-client rpc get /chains/main/blocks/head/header @@ -18,6 +31,16 @@ extract_chainHeight() { echo $tz_block_height > tz.chain.height } +ensure_tezos_keystore(){ + echo "ensuring key store" + cd $(echo $CONFIG_DIR/bmc) + if [ -f .env ]; then + echo ".env found" + octez-client gen keys bmcbtsOwner + echo $(octez-client show address bmcbtsOwner -S) + fi +} + deploy_smartpy_bmc_management(){ cd $(echo $CONFIG_DIR/bmc) if [ ! -f tz.addr.bmcmanagementbtp ]; then @@ -72,7 +95,7 @@ deploy_smartpy_bts_core(){ deploy_smartpy_bts_owner_manager(){ cd $(echo $CONFIG_DIR/bts) - if [ ! -f tz.addr.btsperipherybtp ]; then + if [ ! -f tz.addr.bts_owner_manager ]; then echo "deploying bts_owner_manager" cd ~/GoProjects/icon-bridge/smartpy/bts npm run compile bts_owner_manager @@ -104,23 +127,102 @@ configure_smartpy_bmc_management_set_bmc_periphery() { echo octez-client transfer 0 from bmcOwner to $(echo $bmc_management) --entrypoint set_bmc_periphery --arg $(echo $arg) --burn-cap 1 } -configure_smartpy_bmc_management_set - - - - - +configure_dotenv() { + echo "Configuring .env file for running the setter script" + cd $(echo $CONFIG_DIR/bmc) + local bmc_periphery=$(echo $(cat tz.addr.bmc_periphery)) + local bmc_management=$(echo $(cat tz.addr.bmc_management)) + local bmc_height=$(echo $(cat tz.chain.height)) + local icon_bmc_height=$(echo $(cat iconbmcheight)) + local icon_bmc=$(echo $(cat iconbmc)) + echo $bmc_periphery + cd $(echo $CONFIG_DIR/bts) + local bts_core=$(echo $(cat tz.addr.bts_core)) + local bts_owner_manager=$(echo $(cat tz.addr.bts_owner_manager)) + local bts_periphery=$(echo $(cat tz.addr.bts_periphery)) + local env=$(cat .env) + env=${env#*=} + local secret_deployer=$(echo "secret_deployer=$(echo $env)") + + cd $(echo $TEZOS_SETTER) + if [ -f .env ]; then + echo ".env exists so removing" + rm .env + fi + touch .env + local output=.env + + + + local TZ_NETWORK=$(echo "TZ_NETWORK=$(echo $TEZOS_BMC_NID)") + local ICON_NETWORK=$(echo "ICON_NETWORK=$(echo $ICON_BMC_NID)") + local TEZOS_NATIVE_COIN_NAME=$(echo "TZ_NATIVE_COIN_NAME=btp-$(echo $TEZOS_BMC_NID)-XTZ") + local TEZOS_SYMBOL=$(echo "TZ_SYMBOL=$(echo $TZ_COIN_SYMBOL)") + local TEZ_FIXED_FEE=$(echo "TZ_FIXED_FEE=$(echo $TZ_FIXED_FEE)") + + local TEZ_NUMERATOR=$(echo "TZ_NUMERATOR=$(echo $TZ_NUMERATOR)") + local TEZ_DECIMALS=$(echo "TZ_DECIMALS=$(echo $TZ_DECIMALS)") + local IC_NATIVE_COIN_NAME=$(echo "ICON_NATIVE_COIN_NAME=$(echo $ICON_NATIVE_COIN_NAME)") + + local IC_SYMBOL=$(echo "ICON_SYMBOL=$(echo $ICON_SYMBOL)") + + local IC_FIXED_FEE=$(echo "ICON_FIXED_FEE=$(echo $ICON_FIXED_FEE)") + + local IC_NUMERATOR=$(echo "ICON_NUMERATOR=$(echo $ICON_NUMERATOR)") + local IC_DECIMALS=$(echo "ICON_DECIMALS=$(echo $ICON_DECIMALS)") + + local BMC_PERIPHERY=$(echo "BMC_PERIPHERY=$(echo $bmc_periphery)") + local BMC_MANAGEMENT=$(echo "BMC_MANAGEMENT=$(echo $bmc_management)") + local BMC_HEIGHT=$(echo "bmc_periphery_height=$(echo $bmc_height)") + + local BTS_PERIPHERY=$(echo "BTS_PERIPHERY=$(echo $bts_periphery)") + local BTS_CORE=$(echo "BTS_CORE=$(echo $bts_core)") + local BTS_OWNER_MANAGER=$(echo "BTS_OWNER_MANAGER=$(echo $bts_owner_manager)") + local RELAY_ADDRESS=$(echo "RELAYER_ADDRESS=$(echo $RELAYER_ADDRESS)") + local ICON_BMC=$(echo "ICON_BMC=$(echo $icon_bmc)") + local ICON_RX_HEIGHT=$(echo "ICON_RX_HEIGHT=$(echo $icon_bmc_height)") + + + echo $secret_deployer>>$output + + echo $TZ_NETWORK>>$output + echo $ICON_NETWORK>>$output + echo $TEZOS_NATIVE_COIN_NAME>>$output + echo $TEZOS_SYMBOL>>$output + echo $TEZ_FIXED_FEE>>$output + echo $TEZ_NUMERATOR>>$output + echo $TEZ_DECIMALS>>$output + echo $IC_NATIVE_COIN_NAME>>$output + echo $IC_SYMBOL>>$output + echo $IC_FIXED_FEE>>$output + echo $IC_NUMERATOR>>$output + echo $IC_DECIMALS>>$output + echo $BMC_PERIPHERY>>$output + echo $BMC_MANAGEMENT>>$output + echo $BMC_HEIGHT>>$output + echo $BTS_PERIPHERY>>$output + echo $BTS_CORE>>$output + echo $BTS_OWNER_MANAGER>>$output + echo $RELAY_ADDRESS>>$output + echo $ICON_BMC>>$output + echo $ICON_RX_HEIGHT>>$output +} +run_tezos_setters(){ + cd $(echo $TEZOS_SETTER) + go run main.go +} # bts core # bts owner manager - -# deploy_smartpy_bmc_management -# deploy_smartpy_bmc_periphery -# deploy_smartpy_bts_periphery -# deploy_smartpy_bts_core -# deploy_smartpy_bts_owner_manager -configure_smartpy_bmc_management_set_bmc_periphery \ No newline at end of file +# ensure_tezos_keystore +deploy_smartpy_bmc_management +deploy_smartpy_bmc_periphery +deploy_smartpy_bts_periphery +deploy_smartpy_bts_core +deploy_smartpy_bts_owner_manager +configure_dotenv +run_tezos_setters diff --git a/smartpy/bmc/package-lock.json b/smartpy/bmc/package-lock.json index 13756c6c..2bec67e4 100644 --- a/smartpy/bmc/package-lock.json +++ b/smartpy/bmc/package-lock.json @@ -786,6 +786,7 @@ "version": "4.8.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -1408,7 +1409,8 @@ "typescript": { "version": "4.8.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==" + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "dev": true }, "util-deprecate": { "version": "1.0.2", diff --git a/smartpy/bts/package-lock.json b/smartpy/bts/package-lock.json index 13756c6c..2bec67e4 100644 --- a/smartpy/bts/package-lock.json +++ b/smartpy/bts/package-lock.json @@ -786,6 +786,7 @@ "version": "4.8.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -1408,7 +1409,8 @@ "typescript": { "version": "4.8.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==" + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "dev": true }, "util-deprecate": { "version": "1.0.2", diff --git a/smartpy/bts/scripts/deploy.ts b/smartpy/bts/scripts/deploy.ts index 9b50353a..118a4f17 100644 --- a/smartpy/bts/scripts/deploy.ts +++ b/smartpy/bts/scripts/deploy.ts @@ -45,9 +45,7 @@ const deploy = async () => { init: require(`../contracts/build/${file}_storage.json`), }); - console.log("Successfully deployed contract"); - console.log(`>> Transaction hash: ${hash}`); - console.log(`>> Contract address: ${contractAddress}`); + console.log(`::${contractAddress}`); } catch (error) { console.log( `Oops... Deployment faced an issue.\nHere's the detailed info about the error,\n${error}` diff --git a/smartpy/bts/test.sh b/smartpy/bts/test.sh new file mode 100755 index 00000000..11bfbe8b --- /dev/null +++ b/smartpy/bts/test.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash + +set -e -o pipefail + +echo "----------------------------------------" +echo "Compiling contracts ... " +echo "----------------------------------------" + +# Expected location of SmartPy CLI. +SMART_PY_CLI=~/smartpy-cli/SmartPy.sh + +# Build artifact directory. +TEST_OUT_DIR=./contracts/build/.contract_build/test + +# Array of SmartPy files to compile. +# CONTRACTS_ARRAY=(counter) + +# Exit if SmartPy is not installed. +if [ ! -f "$SMART_PY_CLI" ]; then + echo "Fatal: Please install SmartPy CLI at $SMART_PY_CLI" && exit +fi + +function processContract { + CONTRACT_NAME=$1 + TEST_OUT_DIR=$2 + CONTRACT_IN_TEST="./contracts/tests/${CONTRACT_NAME}_test.py" + CONTRACT_OUT="${CONTRACT_NAME}.json" + STORAGE_OUT="${CONTRACT_NAME}_storage.json" + CONTRACT_COMPILED="${CONTRACT_NAME}/step_000_cont_0_contract.json" + STORAGE_COMPILED="${CONTRACT_NAME}/step_000_cont_0_storage.json" + + echo ">> Processing ${CONTRACT_NAME}" + + # Ensure file exists. + if [ ! -f "$CONTRACT_IN_TEST" ]; then + echo "Fatal: $CONTRACT_IN_TEST not found. Running from wrong dir?" && exit + fi + + echo ">>> Commencing the tests ${CONTRACT_NAME} ... " + $SMART_PY_CLI test $CONTRACT_IN_TEST $TEST_OUT_DIR --html +} + +export PYTHONPATH=$PWD + + +# Use if you want to pass a contract or more as arguments. +for n in $(seq 1 $#); do + processContract $1 $TEST_OUT_DIR + shift +done + + +echo "> Test Complete." \ No newline at end of file From 0a12fab909edaee23007aed4caa84d17d5af8abb Mon Sep 17 00:00:00 2001 From: simusud Date: Tue, 14 Mar 2023 23:25:03 +0545 Subject: [PATCH 083/211] feat: icon-bridge integration with Tezos bts periphery initial translation feat(bmc): Add bmc periphery functions and libraries feat(bmc): Add bmc management functions Utils file added fix(bmc): Implement sets instead of lists added string library initial commit feat: transfer functions fix: remove redundant function fix: interscore calls feat(bts): Add bts core functions Adding deployment file fix(bts_periphery): Function changed to onchain view Adding libraries in Types.py fix(bmc): Deployment errors fixes in bmc periphery, bmc management and Strings library fix(bmc): added checks if a map contains a key fix(lib): return value fix in String.py library feat(bmc): added RLP encode library feat(bmc): implement RLP encode library fix(bmc): view method fixes fix(bts): zero address check fixes fix(bts): small fixes feat(FA2): added params and view methods feat(bts): implement allowance and transfer from method feat(FA2): add allowance and transfer from method feat(library): add rlp encode library fix(bts): type fix in payment_transfer function fix(btsOwnerManager): issues fixes fix(btsOwnerManager): small fix fix(bts_periphery): parse address and RLP encode implementation fix(library): data type fixes feat(library): added parse address library rlp decode library added fix(library): rlp decode functions added feat(bts_core): added callback implementation and uncommented checks in functions feat(bts_periphery): added rlp decode implementation and uncommented checks in functions feat(FA2): callback implementation in transfer function fix(library): small fixes feat(library): added decode and parse address library fix(bmc_management): contract initialization fixes feat(bmc_periphery): rlp decode library implementation fix(bts_core): minor fixes fix(bmc): contract size issue fixed by splitting libraries into separate helper.py and parse_address.py contracts fix(bts): contract size issue fixed by splitting libraries into separate helper.py and parse_address.py contracts and FA2 import url fixes fix: small fixes fix(bmc): rlp encoding fixed fix(bts): rlp encoding fixed and encode_service_message parameter type modified fix(bts): rlp decoding fixed fix(bmc): rlp decoding fixed fix(bmc,bts): return type fixed for without length prefix fix(bmc): modified type of sn from nat to string feat(bmc): modified type of sn from nat to int and implemented callback on bmc add(bmc): setters added to set bmc management address add(bts): setters added to set bmc address and bts core address fix(bmc): decode receipt proof fixed fix(bmc): decoding negative value of sn fixed and new contract added for checking if the number is negative. feat(bts): try catch implementation through callback fix(bmc:library): sn type fix in RLP_decode_struct.py fix(bts): small fixes fix(bmc): decoding list only if the given bytes is in list form. fix(bts): decoding list only if the given bytes is in list form. bmc:helper contract address changed fix(bmc): encoding format fixed to_byte added to convert integer to bytes fix(bmc): event emit fixes fix(bts): custom transfer function name change in FA2 contract feat(bmc): implemented continue and break in bmc_periphery.py feat(bmc): added on_view and changed callback function name fix(bts): removed traces added tests fix(bmc) : second helper added in storage fix(bts) : Native coin name modified fix(bts) : owner address modified fix(bts) : helper contract address modified fix(bmc) : decoder function modified and static address removed fix(bmc) : static address removed fix(bmc) : decoder function modified , removed unused code fix(bmc) : helper contract address modified fix(bmc) : removed reverted message fix(bmc) : length prefix removed in case of decoding height fix(bts): added native_coin_name in constructor of bts_periphery.py fix(bmc) : prefix added while rlp encoding fix(bts) : prefix added while rlp encoding fix(bts) : helper contract modified and Integer decoding after the length of data is checked fix(bmc) : helper contract modified fix(bts): rlp encode_response issue fixed helper contract address modified in constructor fix(bts): reverted back the changes rlp encoding fixed fix(bmc): variable name fix in bmc_management.py fix(bts:library): change token limit msg decoding fix feat(bmc): added setters for helper and parse address feat(bts): added setters for helper and parse address fix(bts:library): encode_response and decode blacklist msg fixes feat(bts): revert condition handled for callback implementation feat(bmc): callback implementation for fee_gathering and resolve route feat(bts): callback implementation for handle_response_service function fix(bts): variable name fix in bts_core.py and removed trace from parse_address.py fix(bmc): encoding for transfer coin msg fix(bts): decoding for blacklist in batch fix(bmc): null message received from ICON chain fixed fix(bmc): variable name fix in parse_address.py added tests fix(bts): variable name fix in parse_address.py and RLP_encode_struct.py fix(bts): minor fixes on transfer and burn restructured test files added test.sh added test in package.json fix(bts): removed tests from contracts fix(bmc): removed tests from contracts fix(bmc): fixed unit tests issues fix(bmc): fixed unit test file names --- smartpy/bmc/compile.sh | 77 + smartpy/bmc/config/config.ts | 20 + .../bmc/contracts/src/RLP_decode_struct.py | 293 ++++ .../bmc/contracts/src/RLP_encode_struct.py | 40 + smartpy/bmc/contracts/src/String.py | 51 + smartpy/bmc/contracts/src/Types.py | 90 ++ smartpy/bmc/contracts/src/bmc_management.py | 571 +++++++ smartpy/bmc/contracts/src/bmc_periphery.py | 401 +++++ smartpy/bmc/contracts/src/check_negative.py | 48 + smartpy/bmc/contracts/src/helper.py | 77 + smartpy/bmc/contracts/src/parse_address.py | 104 ++ .../contracts/tests/bmc_management_test.py | 377 +++++ .../bmc/contracts/tests/bmc_periphery_test.py | 74 + .../bmc/contracts/tests/integration_test.py | 224 +++ smartpy/bmc/package-lock.json | 1429 +++++++++++++++++ smartpy/bmc/package.json | 26 + smartpy/bmc/scripts/deploy.ts | 62 + smartpy/bmc/test.sh | 53 + smartpy/bts/compile.sh | 77 + smartpy/bts/config/config.ts | 20 + smartpy/bts/contracts/src/FA2_contract.py | 162 ++ .../bts/contracts/src/RLP_decode_struct.py | 278 ++++ .../bts/contracts/src/RLP_encode_struct.py | 48 + smartpy/bts/contracts/src/String.py | 44 + smartpy/bts/contracts/src/Types.py | 71 + smartpy/bts/contracts/src/bts_core.py | 714 ++++++++ .../bts/contracts/src/bts_owner_manager.py | 70 + smartpy/bts/contracts/src/bts_periphery.py | 606 +++++++ smartpy/bts/contracts/src/helper.py | 77 + smartpy/bts/contracts/src/parse_address.py | 192 +++ .../bts/contracts/tests/bts_periphery_test.py | 172 ++ smartpy/bts/contracts/tests/btscore_test.py | 291 ++++ .../bts/contracts/tests/integration_test.py | 309 ++++ smartpy/bts/package-lock.json | 1429 +++++++++++++++++ smartpy/bts/package.json | 26 + smartpy/bts/scripts/deploy.ts | 62 + smartpy/bts/test.sh | 53 + 37 files changed, 8718 insertions(+) create mode 100755 smartpy/bmc/compile.sh create mode 100644 smartpy/bmc/config/config.ts create mode 100644 smartpy/bmc/contracts/src/RLP_decode_struct.py create mode 100644 smartpy/bmc/contracts/src/RLP_encode_struct.py create mode 100644 smartpy/bmc/contracts/src/String.py create mode 100644 smartpy/bmc/contracts/src/Types.py create mode 100644 smartpy/bmc/contracts/src/bmc_management.py create mode 100644 smartpy/bmc/contracts/src/bmc_periphery.py create mode 100644 smartpy/bmc/contracts/src/check_negative.py create mode 100644 smartpy/bmc/contracts/src/helper.py create mode 100644 smartpy/bmc/contracts/src/parse_address.py create mode 100644 smartpy/bmc/contracts/tests/bmc_management_test.py create mode 100644 smartpy/bmc/contracts/tests/bmc_periphery_test.py create mode 100644 smartpy/bmc/contracts/tests/integration_test.py create mode 100644 smartpy/bmc/package-lock.json create mode 100644 smartpy/bmc/package.json create mode 100644 smartpy/bmc/scripts/deploy.ts create mode 100644 smartpy/bmc/test.sh create mode 100755 smartpy/bts/compile.sh create mode 100644 smartpy/bts/config/config.ts create mode 100644 smartpy/bts/contracts/src/FA2_contract.py create mode 100644 smartpy/bts/contracts/src/RLP_decode_struct.py create mode 100644 smartpy/bts/contracts/src/RLP_encode_struct.py create mode 100644 smartpy/bts/contracts/src/String.py create mode 100644 smartpy/bts/contracts/src/Types.py create mode 100644 smartpy/bts/contracts/src/bts_core.py create mode 100644 smartpy/bts/contracts/src/bts_owner_manager.py create mode 100644 smartpy/bts/contracts/src/bts_periphery.py create mode 100644 smartpy/bts/contracts/src/helper.py create mode 100644 smartpy/bts/contracts/src/parse_address.py create mode 100644 smartpy/bts/contracts/tests/bts_periphery_test.py create mode 100644 smartpy/bts/contracts/tests/btscore_test.py create mode 100644 smartpy/bts/contracts/tests/integration_test.py create mode 100644 smartpy/bts/package-lock.json create mode 100644 smartpy/bts/package.json create mode 100644 smartpy/bts/scripts/deploy.ts create mode 100644 smartpy/bts/test.sh diff --git a/smartpy/bmc/compile.sh b/smartpy/bmc/compile.sh new file mode 100755 index 00000000..8d5d49f4 --- /dev/null +++ b/smartpy/bmc/compile.sh @@ -0,0 +1,77 @@ + +#!/usr/bin/env bash + +set -e -o pipefail + +echo "----------------------------------------" +echo "Compiling contracts ... " +echo "----------------------------------------" + +# Expected location of SmartPy CLI. +SMART_PY_CLI=~/smartpy-cli/SmartPy.sh + +# Build artifact directory. +OUT_DIR=./contracts/build/.contract_build + +# Array of SmartPy files to compile. +# CONTRACTS_ARRAY=(counter) + +# Exit if SmartPy is not installed. +if [ ! -f "$SMART_PY_CLI" ]; then + echo "Fatal: Please install SmartPy CLI at $SMART_PY_CLI" && exit +fi + +function processContract { + CONTRACT_NAME=$1 + OUT_DIR=$2 + CONTRACT_IN="./contracts/src/${CONTRACT_NAME}.py" + CONTRACT_OUT="${CONTRACT_NAME}.json" + STORAGE_OUT="${CONTRACT_NAME}_storage.json" + CONTRACT_COMPILED="${CONTRACT_NAME}/step_000_cont_0_contract.json" + STORAGE_COMPILED="${CONTRACT_NAME}/step_000_cont_0_storage.json" + + echo ">> Processing ${CONTRACT_NAME}" + + # Ensure file exists. + if [ ! -f "$CONTRACT_IN" ]; then + echo "Fatal: $CONTRACT_IN not found. Running from wrong dir?" && exit + fi + +# echo ">>> [1 / 3] Testing ${CONTRACT_NAME} ... " +# $SMART_PY_CLI test $CONTRACT_IN $OUT_DIR --html + + echo ">>> [1 / 2] Compiling ${CONTRACT_NAME} ..." + $SMART_PY_CLI compile $CONTRACT_IN $OUT_DIR --html + + echo ">>> [2 / 2] Extracting Michelson contract ... " + cp $OUT_DIR/$CONTRACT_COMPILED ./contracts/build/$CONTRACT_OUT + cp $OUT_DIR/$STORAGE_COMPILED ./contracts/build/$STORAGE_OUT + + echo ">>> Michelson contract written to ${CONTRACT_OUT}" +} + +export PYTHONPATH=$PWD + + +echo "> [1 / 2] Compiling Contracts." +# Use if you want to pass a contract or more as arguments. +for n in $(seq 1 $#); do + processContract $1 $OUT_DIR + shift +done + +# Use if you want to compile all contracts in CONTRACTS_ARRAY. No arguments needed. +# for i in ${!CONTRACTS_ARRAY[@]}; do +# processContract ${CONTRACTS_ARRAY[$i]} $OUT_DIR +# done + +# Remove build artifacts. +echo "> [2 / 2] Cleaning up ..." +rm -rf $OUT_DIR +rm -rf ./contracts/__pycache__ +rm -rf ./__pycache__ + + +echo "> Removed artifacts." + +echo "> Compilation successful." \ No newline at end of file diff --git a/smartpy/bmc/config/config.ts b/smartpy/bmc/config/config.ts new file mode 100644 index 00000000..2dc56ea2 --- /dev/null +++ b/smartpy/bmc/config/config.ts @@ -0,0 +1,20 @@ +// List your config files here + +export const NETWORK = { + GHOSTNET: { + name: "ghostnet", + url: "https://ghostnet.smartpy.io", + }, + KATHMANDUNET: { + name: "kathmandunet", + url: "https://kathmandunet.smartpy.io", + }, + JAKARTANET: { + name: "jakartanet", + url: "https://jakartanet.smartpy.io", + }, + MAINNET: { + name: "mainnet", + url: "https://mainnet.smartpy.io", + }, +}; diff --git a/smartpy/bmc/contracts/src/RLP_decode_struct.py b/smartpy/bmc/contracts/src/RLP_decode_struct.py new file mode 100644 index 00000000..926fd4d5 --- /dev/null +++ b/smartpy/bmc/contracts/src/RLP_decode_struct.py @@ -0,0 +1,293 @@ +import smartpy as sp + +Utils2 = sp.io.import_script_from_url("https://raw.githubusercontent.com/RomarQ/tezos-sc-utils/main/smartpy/utils.py") +types = sp.io.import_script_from_url("file:./contracts/src/Types.py") + + +class DecodeLibrary: + + def decode_bmc_message(self, rlp): + rlp_bm = sp.local("rlp_bm", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_bm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + rlp_bm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_ = rlp_bm.value + temp_map_string = sp.compute(sp.map(tkey=sp.TString, tvalue=sp.TString)) + temp_int = sp.local("int_value", 0) + temp_byt = sp.local("byt_value", sp.bytes("0x")) + counter = sp.local("counter", 0) + sp.for k in rlp_.items(): + sp.if counter.value == 0: + temp_map_string["src"] = sp.view("decode_string", self.data.helper, k.value, t=sp.TString).open_some() + sp.if counter.value == 1: + temp_map_string["dst"] = sp.view("decode_string", self.data.helper, k.value, t=sp.TString).open_some() + sp.if counter.value == 2: + temp_map_string["svc"] = sp.view("decode_string", self.data.helper, k.value, t=sp.TString).open_some() + sp.if counter.value == 3: + sn_in_bytes = sp.view("without_length_prefix", self.data.helper, k.value, t=sp.TBytes).open_some() + temp_int.value = sp.view("to_int", self.data.helper_parse_negative, sn_in_bytes, t=sp.TInt).open_some() + sp.if counter.value == 4: + temp_byt.value = k.value + counter.value = counter.value + 1 + temp_byt.value = sp.view("without_length_prefix", self.data.helper, temp_byt.value, t=sp.TBytes).open_some() + return sp.record(src=temp_map_string.get("src"), + dst=temp_map_string.get("dst"), + svc=temp_map_string.get("svc"), + sn=temp_int.value, + message=temp_byt.value) + + + def decode_response(self, rlp): + temp_int = sp.local("int1", 0) + temp_byt = sp.local("byt1", sp.bytes("0x")) + rlp_dr = sp.local("rlp_dr", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_dr.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + rlp_dr.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_ = rlp_dr.value + counter = sp.local("counter_response", 0) + sp.for m in rlp_.items(): + sp.if counter.value == 0: + temp_int.value = Utils2.Int.of_bytes(m.value) + sp.if counter.value == 1: + temp_byt.value = m.value + counter.value = counter.value + 1 + + return sp.record(code=temp_int.value, message=sp.view("decode_string", self.data.helper, temp_byt.value, t=sp.TString).open_some()) + + def decode_propagate_message(self, rlp): + rlp_pm = sp.local("rlp_pm", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_pm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + rlp_pm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_ = rlp_pm.value + counter = sp.local("counter_propagate", 0) + temp_string = sp.local("temp_string", "") + sp.for d in rlp_.items(): + sp.if counter.value == 0: + temp_string.value = sp.view("decode_string", self.data.helper, d.value, t=sp.TString).open_some() + counter.value = counter.value + 1 + return temp_string.value + + def decode_init_message(self, rlp): + rlp_im = sp.local("rlp_im", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_im.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + rlp_im.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_ = rlp_im.value + counter = sp.local("counter_init", 0) + temp_bytes = sp.local("byt_init", sp.bytes("0x")) + sp.for g in rlp_.items(): + sp.if counter.value == 0: + temp_bytes.value = g.value + counter.value = counter.value + 1 + + sub_list = sp.local("sub_list_init", temp_bytes.value) + nsl_im = sp.local("nsl_im", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + nsl_im.value = sp.view("decode_list", self.data.helper, sub_list.value, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() + nsl_im.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + new_sub_list = nsl_im.value + + _links = sp.local("links_init", [], sp.TList(sp.TString)) + counter.value = 0 + sp.for x in new_sub_list.items(): + _links.value.push(sp.view("decode_string", self.data.helper, x.value, t=sp.TString).open_some()) + counter.value = counter.value + 1 + return _links.value + + def decode_bmc_service(self, rlp): + rlp_bs = sp.local("rlp_bs", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_bs.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + rlp_bs.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_ = rlp_bs.value + temp_string = sp.local("str_value", "") + temp_byt = sp.local("byt_value_bmc", sp.bytes("0x")) + counter = sp.local("counter_service", 0) + sp.for b in rlp_.items(): + sp.if counter.value == 0: + temp_string.value = sp.view("decode_string", self.data.helper, b.value, t=sp.TString).open_some() + sp.if counter.value == 1: + temp_byt.value = b.value + counter.value = counter.value + 1 + temp_byt.value = sp.view("without_length_prefix", self.data.helper, temp_byt.value, t=sp.TBytes).open_some() + return sp.record(serviceType=temp_string.value, + payload=temp_byt.value) + + def decode_gather_fee_message(self, rlp): + rlp_gm = sp.local("rlp_gm", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_gm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + rlp_gm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_ = rlp_gm.value + temp_byt = sp.local("byt4", sp.bytes("0x")) + counter = sp.local("counter_gather", 0) + temp_str = sp.local("str_gather", "") + sp.for c in rlp_.items(): + sp.if counter.value == 1: + temp_byt.value = c.value + sp.if counter.value == 0: + temp_str.value = sp.view("decode_string", self.data.helper, c.value, t=sp.TString).open_some() + counter.value = counter.value + 1 + sub_list = sp.local("sub_list", temp_byt.value) + nsl_gm = sp.local("nsl_gm", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + nsl_gm.value = sp.view("decode_list", self.data.helper, sub_list.value, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() + nsl_gm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + new_sub_list = nsl_gm.value + + _svcs = sp.local("_svcs", {}, sp.TMap(sp.TNat, sp.TString)) + counter.value = 0 + sp.for x in new_sub_list.items(): + _svcs.value[counter.value] = sp.view("decode_string", self.data.helper, x.value, t=sp.TString).open_some() + counter.value = counter.value + 1 + return sp.record(fa=temp_str.value, + svcs=_svcs.value) + + def to_message_event(self, rlp): + rlp_me = sp.local("rlp_me", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_me.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + rlp_me.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_ = rlp_me.value + counter = sp.local("counter_event", 0) + rv1 = sp.local("rv1_event", "") + rv2 = sp.local("rv2_event", sp.nat(0)) + rv3 = sp.local("rv3_event", sp.bytes("0x")) + sp.for i in rlp_.items(): + sp.if counter.value == 2: + rv3.value = i.value + sp.if counter.value == 0: + rv1.value = sp.view("decode_string", self.data.helper, i.value, t=sp.TString).open_some() + sp.if counter.value == 1: + rv2.value = Utils2.Int.of_bytes(i.value) + counter.value = counter.value + 1 + rv3.value = sp.view("without_length_prefix", self.data.helper, rv3.value, t=sp.TBytes).open_some() + return sp.record(next_bmc= rv1.value, seq= rv2.value, message = rv3.value) + + def decode_receipt_proof(self, rlp): + rlp_rp = sp.local("rlp_rp", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_rp.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + rlp_rp.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_ = rlp_rp.value + temp_byt = sp.local("byt_receipt", sp.bytes("0x")) + rv_int = sp.local("rv_int_receipt", 0) + rv_int2 = sp.local("rv_int2_receipt", 0) + counter = sp.local("counter", 0) + sp.for i in rlp_.items(): + sp.if counter.value == 1: + temp_byt.value = sp.view("without_length_prefix", self.data.helper, i.value, t=sp.TBytes).open_some() + sp.if counter.value == 0: + rv_int.value = Utils2.Int.of_bytes(i.value) + sp.if counter.value == 2: + wl_prefix = sp.view("without_length_prefix", self.data.helper, i.value, t=sp.TBytes).open_some() + rv_int2.value =Utils2.Int.of_bytes(wl_prefix) + counter.value = counter.value + 1 + + sub_list = sp.local("sub_list", temp_byt.value) + + nsl_rp = sp.local("nsl_rp", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + nsl_rp.value = sp.view("decode_list", self.data.helper, sub_list.value, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() + nsl_rp.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + new_sub_list = nsl_rp.value + counter.value = 0 + events = sp.local("events_receipt", sp.map({}, tkey=sp.TNat, + tvalue=sp.TRecord(next_bmc= sp.TString, + seq= sp.TNat, + message = sp.TBytes))) + sp.for z in new_sub_list.items(): + events.value[counter.value] = self.to_message_event(z.value) + counter.value = counter.value + 1 + return sp.record(index = rv_int.value, events = events.value, height = rv_int2.value) + + + def decode_receipt_proofs(self, rlp): + rlp_rps = sp.local("rlp_rps", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_rps.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + rlp_rps.value = sp.view("decode_list", self.data.helper, decode_len, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_ = rlp_rps.value + counter = sp.local("counter_receipt_proofs", 0) + receipt_proofs = sp.local("events_receipt_proofs", sp.map({}, tkey=sp.TNat, + tvalue=sp.TRecord(index = sp.TNat, + events = sp.TMap(sp.TNat, sp.TRecord(next_bmc=sp.TString, seq=sp.TNat, message=sp.TBytes)), + height = sp.TNat, + ) + ) + ) + temp_byt = sp.local("temp_byt_proofs", sp.bytes("0x")) + sp.for i in rlp_.items(): + sp.if counter.value == 0: + temp_byt.value = i.value + counter.value = counter.value + 1 + sub_list = sp.local("sub_list_proofs", temp_byt.value) + + nsl_rps = sp.local("nsl_rps", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + nsl_rps.value = sp.view("decode_list", self.data.helper, sub_list.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() + nsl_rps.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + new_sub_list = nsl_rps.value + counter.value = 0 + sp.if sp.len(new_sub_list) > 0: + sp.for x in new_sub_list.items(): + receipt_proofs.value[counter.value] = self.decode_receipt_proof(x.value) + counter.value = counter.value + 1 + return receipt_proofs.value + diff --git a/smartpy/bmc/contracts/src/RLP_encode_struct.py b/smartpy/bmc/contracts/src/RLP_encode_struct.py new file mode 100644 index 00000000..9ec9bbe0 --- /dev/null +++ b/smartpy/bmc/contracts/src/RLP_encode_struct.py @@ -0,0 +1,40 @@ +import smartpy as sp + + +class EncodeLibrary: + LIST_SHORT_START = sp.bytes("0xc0") + + def encode_bmc_service(self, params): + sp.set_type(params, sp.TRecord(serviceType=sp.TString, payload=sp.TBytes)) + + encode_service_type = sp.view("encode_string", self.data.helper, params.serviceType, t=sp.TBytes).open_some() + + payload_rlp = sp.view("encode_list", self.data.helper, [params.payload], t=sp.TBytes).open_some() + payload_rlp = sp.view("with_length_prefix", self.data.helper, payload_rlp, t=sp.TBytes).open_some() + + rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [encode_service_type, payload_rlp], + t=sp.TBytes).open_some() + rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp_bytes_with_prefix, + t=sp.TBytes).open_some() + return rlp_bytes_with_prefix + + def encode_bmc_message(self, params): + sp.set_type(params, sp.TRecord(src=sp.TString, dst=sp.TString, svc=sp.TString, sn=sp.TInt, message=sp.TBytes)) + + encode_src = sp.view("encode_string", self.data.helper, params.src, t=sp.TBytes).open_some() + encode_dst = sp.view("encode_string", self.data.helper, params.dst, t=sp.TBytes).open_some() + encode_svc = sp.view("encode_string", self.data.helper, params.svc, t=sp.TBytes).open_some() + encode_sn = sp.view("to_byte", self.data.helper_parse_negative, params.sn, t=sp.TBytes).open_some() + + rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [encode_src, encode_dst, encode_svc, encode_sn, params.message], t=sp.TBytes).open_some() + return rlp_bytes_with_prefix + + def encode_response(self, params): + sp.set_type(params, sp.TRecord(code=sp.TNat, message=sp.TString)) + + encode_code = sp.view("encode_nat", self.data.helper, params.code, t=sp.TBytes).open_some() + encode_message = sp.view("encode_string", self.data.helper, params.message, t=sp.TBytes).open_some() + + rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [encode_code, encode_message], t=sp.TBytes).open_some() + final_rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp_bytes_with_prefix, t=sp.TBytes).open_some() + return final_rlp_bytes_with_prefix diff --git a/smartpy/bmc/contracts/src/String.py b/smartpy/bmc/contracts/src/String.py new file mode 100644 index 00000000..d766d723 --- /dev/null +++ b/smartpy/bmc/contracts/src/String.py @@ -0,0 +1,51 @@ +import smartpy as sp + + + +def split_btp_address(base, prev_string, result_string, list_string, last_string, penultimate_string): + """ + Split the BTP Address format i.e. btp://1234.iconee/0x123456789 + into Network_address (1234.iconee) and Server_address (0x123456789) + :param prev_string: local variable name + :param result_string: local variable name + :param list_string: local variable name + :param last_string: local variable name + :param penultimate_string: local variable name + :param base: String base BTP Address format to be split + :return: The resulting strings of Network_address and Server_address + """ + sp.set_type(base, sp.TString) + + # sep = sp.local("sep", "/") + prev_idx = sp.local(prev_string, 0) + result = sp.local(result_string, []) + sp.for idx in sp.range(0, sp.len(base)): + sp.if sp.slice(base, idx, 1).open_some() == "/": + result.value.push(sp.slice(base, prev_idx.value, sp.as_nat(idx - prev_idx.value)).open_some()) + prev_idx.value = idx + 1 + sp.if sp.len(base) > 0: + result.value.push(sp.slice(base, prev_idx.value, sp.as_nat(sp.len(base) - prev_idx.value)).open_some()) + + inverted_list = sp.local(list_string, result.value) + last = sp.local(last_string, "") + penultimate = sp.local(penultimate_string, "") + + with sp.match_cons(inverted_list.value) as l: + last.value = l.head + inverted_list.value = l.tail + # with sp.else_(): + # sp.failwith("Empty list") + + + with sp.match_cons(inverted_list.value) as l: + penultimate.value = l.head + # with sp.else_(): + # sp.failwith("Only one element") + + return sp.pair(penultimate.value, last.value) + + + + + + diff --git a/smartpy/bmc/contracts/src/Types.py b/smartpy/bmc/contracts/src/Types.py new file mode 100644 index 00000000..49d85127 --- /dev/null +++ b/smartpy/bmc/contracts/src/Types.py @@ -0,0 +1,90 @@ +import smartpy as sp + + +class Types: + + MessageEvent = sp.TRecord( + next_bmc=sp.TString, + seq=sp.TNat, + message=sp.TBytes + ) + + ReceiptProof = sp.TRecord( + index=sp.TNat, + events=sp.TMap(sp.TNat, MessageEvent), + height=sp.TNat + ) + + BMCMessage = sp.TRecord( + src=sp.TString, + dst=sp.TString, + svc=sp.TString, + sn=sp.TInt, + message=sp.TBytes + ) + + MessageEvent = sp.TRecord( + next_bmc=sp.TString, + seq=sp.TNat, + message=sp.TBytes + ) + + Response = sp.TRecord( + code=sp.TNat, + message=sp.TString + ) + + Route = sp.TRecord( + dst=sp.TString, + next=sp.TString + ) + + Link = sp.TRecord( + relays=sp.TSet(sp.TAddress), + reachable=sp.TSet(sp.TString), + rx_seq=sp.TNat, + tx_seq=sp.TNat, + block_interval_src=sp.TNat, + block_interval_dst=sp.TNat, + max_aggregation=sp.TNat, + delay_limit=sp.TNat, + relay_idx=sp.TNat, + rotate_height=sp.TNat, + rx_height=sp.TNat, + rx_height_src=sp.TNat, + is_connected=sp.TBool + ) + + LinkStats = sp.TRecord( + rx_seq=sp.TNat, + tx_seq=sp.TNat, + rx_height=sp.TNat, + current_height=sp.TNat + ) + + BMCService = sp.TRecord( + serviceType=sp.TString, + payload=sp.TBytes + ) + + GatherFeeMessage = sp.TRecord( + fa=sp.TString, + svcs=sp.TMap(sp.TNat, sp.TString) + ) + + RelayStats = sp.TRecord( + addr=sp.TAddress, + block_count=sp.TNat, + msg_count=sp.TNat + ) + + Tuple = sp.TRecord( + prev=sp.TString, + to=sp.TString + ) + + Service = sp.TRecord( + svc=sp.TString, + addr=sp.TAddress + ) + diff --git a/smartpy/bmc/contracts/src/bmc_management.py b/smartpy/bmc/contracts/src/bmc_management.py new file mode 100644 index 00000000..39cfa101 --- /dev/null +++ b/smartpy/bmc/contracts/src/bmc_management.py @@ -0,0 +1,571 @@ +import smartpy as sp + +types = sp.io.import_script_from_url("file:./contracts/src/Types.py") +strings = sp.io.import_script_from_url("file:./contracts/src/String.py") +rlp_encode = sp.io.import_script_from_url("file:./contracts/src/RLP_encode_struct.py") + + +class BMCManagement(sp.Contract, rlp_encode.EncodeLibrary): + BLOCK_INTERVAL_MSEC = sp.nat(1000) + + def __init__(self, owner_address, helper_contract): + self.init( + owners=sp.map(l={owner_address:True}), + number_of_owners=sp.nat(1), + bsh_services=sp.map(), + relay_stats=sp.map(), + routes=sp.map(), + links=sp.map(), + list_bsh_names=sp.set(), + list_route_keys=sp.set(), + list_link_names=sp.set(), + bmc_periphery=sp.none, + serial_no=sp.nat(0), + addrs=sp.set(), + get_route_dst_from_net=sp.map(), + get_link_from_net=sp.map(), + get_link_from_reachable_net=sp.map(), + helper=helper_contract + ) + + self.init_type(sp.TRecord( + owners=sp.TMap(sp.TAddress, sp.TBool), + number_of_owners=sp.TNat, + bsh_services=sp.TMap(sp.TString, sp.TAddress), + relay_stats=sp.TMap(sp.TAddress, types.Types.RelayStats), + routes=sp.TMap(sp.TString, sp.TString), + links=sp.TMap(sp.TString, types.Types.Link), + list_bsh_names=sp.TSet(sp.TString), + list_route_keys=sp.TSet(sp.TString), + list_link_names=sp.TSet(sp.TString), + bmc_periphery=sp.TOption(sp.TAddress), + serial_no=sp.TNat, + addrs=sp.TSet(sp.TAddress), + get_route_dst_from_net=sp.TMap(sp.TString, sp.TString), + get_link_from_net=sp.TMap(sp.TString, sp.TString), + get_link_from_reachable_net=sp.TMap(sp.TString, types.Types.Tuple), + helper=sp.TAddress + )) + + def only_owner(self): + with sp.if_(self.data.owners.contains(sp.sender)): + sp.verify(self.data.owners[sp.sender] == True, "Unauthorized") + with sp.else_(): + sp.failwith("Unauthorized") + + def only_bmc_periphery(self): + sp.verify(sp.sender == self.data.bmc_periphery.open_some("BMCAddressNotSet"), "Unauthorized") + + @sp.entry_point + def set_helper_address(self, address): + sp.set_type(address, sp.TAddress) + self.only_owner() + self.data.helper = address + + @sp.entry_point + def set_bmc_periphery(self, addr): + """ + + :param addr: address of bmc_periphery + :return: + """ + sp.set_type(addr, sp.TAddress) + self.only_owner() + sp.if self.data.bmc_periphery.is_some(): + sp.verify(addr != self.data.bmc_periphery.open_some("Address not set"), "AlreadyExistsBMCPeriphery") + self.data.bmc_periphery = sp.some(addr) + + @sp.entry_point + def set_bmc_btp_address(self, network): + sp.set_type(network, sp.TString) + + sp.verify(self.data.owners[sp.sender] == True, "Unauthorized") + # call set_btp_address on BMCPeriphery + set_btp_address_entry_point = sp.contract(sp.TString, + self.data.bmc_periphery.open_some("Address not set"), + "set_bmc_btp_address").open_some() + sp.transfer(network, sp.tez(0), set_btp_address_entry_point) + + @sp.entry_point + def add_owner(self, owner): + """ + :param owner: owner address to set + :return: + """ + sp.set_type(owner, sp.TAddress) + + self.only_owner() + sp.verify(self.data.owners.contains(owner) == False, "Already Exists") + self.data.owners[owner] = True + self.data.number_of_owners += sp.nat(1) + + @sp.entry_point + def remove_owner(self, owner): + """ + + :param owner: owner address to remove + :return: + """ + sp.set_type(owner, sp.TAddress) + + self.only_owner() + sp.verify(self.data.number_of_owners > sp.nat(1), "LastOwner") + sp.verify(self.data.owners[owner] == True, "NotExistsPermission") + del self.data.owners[owner] + self.data.number_of_owners = sp.as_nat(self.data.number_of_owners - sp.nat(1)) + + @sp.onchain_view() + def is_owner(self, owner): + """ + + :param owner: address to check + :return: + """ + sp.result(self.data.owners.get(owner)) + + @sp.entry_point + def add_service(self, svc, addr): + """ + Add the smart contract for the service. + :param svc: Name of the service + :param addr: Service's contract address + :return: + """ + self.only_owner() + sp.verify(addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg"), "InvalidAddress") + sp.verify(self.data.bsh_services.contains(svc) == False, "AlreadyExistsBSH") + self.data.bsh_services[svc] = addr + self.data.list_bsh_names.add(svc) + + @sp.entry_point + def remove_service(self, svc): + """ + Unregisters the smart contract for the service. + :param svc: Name of the service + :return: + """ + self.only_owner() + sp.verify(self.data.bsh_services.contains(svc), "NotExistsBSH") + del self.data.bsh_services[svc] + self.data.list_bsh_names.remove(svc) + + @sp.onchain_view() + def get_services(self): + """ + Get registered services. + :return: An array of Service. + """ + + services = sp.compute(sp.map(tkey=sp.TNat, tvalue=types.Types.Service)) + i = sp.local("i", sp.nat(0)) + sp.for item in self.data.list_bsh_names.elements(): + services[i.value] = sp.record(svc=item, addr=self.data.bsh_services.get(item)) + i.value += 1 + sp.result(services) + + @sp.entry_point + def add_link(self, link): + """ + Initializes status information for the link. + :param link: + :return: BTP Address of connected BMC + """ + sp.set_type(link, sp.TString) + + self.only_owner() + net, addr= sp.match_pair(strings.split_btp_address(link, "prev_idx", "result", "my_list", "last", "penultimate")) + + with sp.if_(self.data.links.contains(link)): + sp.verify(self.data.links.get(link).is_connected == False, "AlreadyExistsLink") + self.data.links[link] = sp.record( + relays=sp.set([]), + reachable=sp.set([]), + rx_seq=sp.nat(0), + tx_seq=sp.nat(0), + block_interval_src=self.BLOCK_INTERVAL_MSEC, + block_interval_dst=sp.nat(0), + max_aggregation=sp.nat(10), + delay_limit=sp.nat(3), + relay_idx=sp.nat(0), + rotate_height=sp.nat(0), + rx_height=sp.nat(0), + rx_height_src=sp.nat(0), + is_connected=True + ) + + self._propagate_internal("Link", link) + links = sp.compute(self.data.list_link_names.elements()) + + self.data.list_link_names.add(link) + self.data.get_link_from_net[net] = link + self._send_internal(link, "Init", links) + + @sp.entry_point + def remove_link(self, link): + """ + Removes the link and status information. + :param link: BTP Address of connected BMC + :return: + """ + sp.set_type(link, sp.TString) + + self.only_owner() + with sp.if_(self.data.links.contains(link)): + sp.verify(self.data.links.get(link).is_connected == True, "NotExistsLink") + with sp.else_(): + sp.failwith("NotExistsLink") + self._propagate_internal("Unlink", link) + del self.data.links[link] + net, addr= sp.match_pair(strings.split_btp_address(link, "prev_idx", "result", "my_list", "last", "penultimate")) + del self.data.get_link_from_net[net] + self.data.list_link_names.remove(link) + + @sp.onchain_view() + def get_links(self): + """ + Get registered links. + :return: An array of links ( BTP Addresses of the BMCs ). + """ + sp.result(self.data.list_link_names.elements()) + + @sp.entry_point + def set_link_rx_height(self, link, height): + """ + + :param link: + :param height: + :return: + """ + + sp.set_type(link, sp.TString) + sp.set_type(height, sp.TNat) + + self.only_owner() + with sp.if_(self.data.links.contains(link)): + sp.verify(self.data.links.get(link).is_connected == True, "NotExistsLink") + with sp.else_(): + sp.failwith("NotExistsKey") + sp.verify(height > sp.nat(0), "InvalidRxHeight") + self.data.links[link].rx_height = height + + @sp.entry_point + def set_link(self, _link, block_interval, _max_aggregation, delay_limit): + """ + + :param _link: + :param block_interval: + :param _max_aggregation: + :param delay_limit: + :return: + """ + sp.set_type(_link, sp.TString) + sp.set_type(block_interval, sp.TNat) + sp.set_type(_max_aggregation, sp.TNat) + sp.set_type(delay_limit, sp.TNat) + + self.only_owner() + + with sp.if_(self.data.links.contains(_link)): + sp.verify(self.data.links.get(_link).is_connected == True, "NotExistsLink") + with sp.else_(): + sp.failwith("NotExistsLink") + sp.verify((_max_aggregation >= sp.nat(1)) & (delay_limit >= sp.nat(1)), "InvalidParam") + + link = sp.local("link", self.data.links.get(_link), t=types.Types.Link).value + + link.block_interval_dst = block_interval + link.max_aggregation = _max_aggregation + link.delay_limit = delay_limit + + link.rotate_height = sp.level + link.rx_height = sp.nat(0) + + self.data.links[_link] = link + + + def _propagate_internal(self, service_type, link): + sp.set_type(service_type, sp.TString) + sp.set_type(link, sp.TString) + + _bytes = sp.bytes("0x") # can be any bytes + rlp_bytes = sp.view("encode_string", self.data.helper, link, t=sp.TBytes).open_some() + rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [_bytes, rlp_bytes] , t=sp.TBytes).open_some() + + #encode payload + final_rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [rlp_bytes_with_prefix], t=sp.TBytes).open_some() + sp.for item in self.data.list_link_names.elements(): + sp.if self.data.links.get(item).is_connected: + net, addr = sp.match_pair(strings.split_btp_address(item, "prev_idx1", "result1", "my_list1", "last1", "penultimate1")) + + # call send_message on BMCPeriphery + send_message_args_type = sp.TRecord(to=sp.TString, svc=sp.TString, sn=sp.TInt, msg=sp.TBytes) + send_message_entry_point = sp.contract(send_message_args_type, + self.data.bmc_periphery.open_some("Address not set"), + "send_message").open_some() + send_message_args = sp.record(to=net, svc="bmc", sn=sp.int(0), msg=self.encode_bmc_service( + sp.record(serviceType=service_type, payload=final_rlp_bytes_with_prefix))) + sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) + + def _send_internal(self, target, service_type, links): + sp.set_type(target, sp.TString) + sp.set_type(service_type, sp.TString) + sp.set_type(links, sp.TList(sp.TString)) + + rlp_bytes = sp.local("rlp_bytes", sp.bytes("0x")) + with sp.if_(sp.len(links) == sp.nat(0)): + rlp_bytes.value = self.LIST_SHORT_START + with sp.else_(): + sp.for item in links: + _bytes = sp.bytes("0x") # can be any bytes + _rlp_bytes = _bytes + sp.view("encode_string", self.data.helper, item, t=sp.TBytes).open_some() + rlp_bytes.value = sp.view("encode_list", self.data.helper, [rlp_bytes.value, _rlp_bytes], t=sp.TBytes).open_some() + #encode payload + # final_rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp_bytes.value, t=sp.TBytes).open_some() + net, addr = sp.match_pair( + strings.split_btp_address(target, "prev_idx2", "result2", "my_list2", "last2", "penultimate2")) + + # call send_message on BMCPeriphery + send_message_args_type = sp.TRecord(to=sp.TString, svc=sp.TString, sn=sp.TInt, msg=sp.TBytes) + send_message_entry_point = sp.contract(send_message_args_type, + self.data.bmc_periphery.open_some("Address not set"), + "send_message").open_some() + send_message_args = sp.record(to=net, svc="bmc", sn=sp.int(0), msg=self.encode_bmc_service( + sp.record(serviceType=service_type, payload=rlp_bytes.value))) + sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) + + + @sp.entry_point + def add_route(self, dst, link): + """ + Add route to the BMC. + :param dst: BTP Address of the destination BMC + :param link: BTP Address of the next BMC for the destination + :return: + """ + sp.set_type(dst, sp.TString) + sp.set_type(link, sp.TString) + + self.only_owner() + sp.verify(self.data.routes.contains(dst) == False, "AlreadyExistRoute") + net, addr= sp.match_pair(strings.split_btp_address(dst, "prev_idx", "result", "my_list", "last", "penultimate")) + # TODO: need to verify link is only split never used + # strings.split_btp_address(link) + + self.data.routes[dst] = link + self.data.list_route_keys.add(dst) + self.data.get_route_dst_from_net[net] = dst + + @sp.entry_point + def remove_route(self, dst): + """ + Remove route to the BMC. + :param dst: BTP Address of the destination BMC + :return: + """ + sp.set_type(dst, sp.TString) + + self.only_owner() + sp.verify(self.data.routes.contains(dst) == True, "NotExistRoute") + del self.data.routes[dst] + net, addr= sp.match_pair(strings.split_btp_address(dst, "prev_idx", "result", "my_list", "last", "penultimate")) + del self.data.get_route_dst_from_net[net] + self.data.list_route_keys.remove(dst) + + @sp.onchain_view() + def get_routes(self): + """ + Get routing information. + :return: An array of Route. + """ + + _routes = sp.compute(sp.map(tkey=sp.TNat, tvalue=types.Types.Route)) + i = sp.local("i", sp.nat(0)) + sp.for item in self.data.list_route_keys.elements(): + _routes[i.value] = sp.record(dst=item, next=self.data.routes.get(item)) + i.value += 1 + sp.result(_routes) + + @sp.entry_point + def add_relay(self, link, addr): + """ + Registers relay for the network. + :param link: BTP Address of connected BMC + :param addr: the address of Relay + :return: + """ + sp.set_type(link, sp.TString) + sp.set_type(addr, sp.TSet(sp.TAddress)) + + self.only_owner() + sp.verify(self.data.links.contains(link), "NotExistsLink") + sp.verify(self.data.links.get(link).is_connected == True, "NotExistsLink") + self.data.links[link].relays = addr + sp.for item in addr.elements(): + self.data.relay_stats[item] = sp.record(addr=item, block_count=sp.nat(0), msg_count=sp.nat(0)) + + @sp.entry_point + def remove_relay(self, link, addr): + """ + Unregisters Relay for the network. + :param link: BTP Address of connected BMC + :param addr: the address of Relay + :return: + """ + sp.set_type(link, sp.TString) + sp.set_type(addr, sp.TAddress) + + self.only_owner() + sp.verify(self.data.links.contains(link), "NotExistsLink") + sp.verify((self.data.links.get(link).is_connected == True) & (sp.len(self.data.links.get(link).relays.elements()) != sp.nat(0)), + "Unauthorized") + + sp.for item in self.data.links.get(link).relays.elements(): + sp.if item != addr: + self.data.addrs.add(item) + + self.data.links[link].relays = self.data.addrs + + # delete all items from addrs set + sp.for ele in self.data.addrs.elements(): + self.data.addrs.remove(ele) + + + @sp.onchain_view() + def get_relays(self, link): + """ + Get registered relays. + :param link: BTP Address of the connected BMC. + :return: A list of relays + """ + sp.set_type(link, sp.TString) + + sp.result(self.data.links.get(link).relays.elements()) + + @sp.onchain_view() + def get_bsh_service_by_name(self, service_name): + sp.set_type(service_name, sp.TString) + sp.result(self.data.bsh_services.get(service_name, default_value=sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg"))) + + @sp.onchain_view() + def get_link(self, to): + sp.set_type(to, sp.TString) + sp.result(self.data.links.get(to)) + + @sp.onchain_view() + def get_link_rx_seq(self, prev): + sp.set_type(prev, sp.TString) + sp.result(self.data.links.get(prev).rx_seq) + + @sp.onchain_view() + def get_link_tx_seq(self, prev): + sp.set_type(prev, sp.TString) + sp.result(self.data.links.get(prev).tx_seq) + + @sp.onchain_view() + def get_link_rx_height(self, prev): + sp.set_type(prev, sp.TString) + sp.result(self.data.links.get(prev).rx_height) + + @sp.onchain_view() + def get_link_relays(self, prev): + sp.set_type(prev, sp.TString) + sp.result(self.data.links.get(prev).relays.elements()) + + @sp.onchain_view() + def get_relay_status_by_link(self, prev): + sp.set_type(prev, sp.TString) + _relays = sp.compute(sp.map(tkey=sp.TNat, tvalue=types.Types.RelayStats)) + + i = sp.local("i", sp.nat(0)) + sp.for item in self.data.links.get(prev).relays.elements(): + _relays[i.value] = self.data.relay_stats.get(item) + i.value += 1 + sp.result(_relays) + + @sp.entry_point + def update_link_rx_seq(self, prev, val): + sp.set_type(prev, sp.TString) + sp.set_type(val, sp.TNat) + + self.only_bmc_periphery() + self.data.links[prev].rx_seq += val + + @sp.entry_point + def update_link_tx_seq(self, prev, serialized_msg): + sp.set_type(prev, sp.TString) + sp.set_type(serialized_msg, sp.TBytes) + + self.only_bmc_periphery() + self.data.links[prev].tx_seq += sp.nat(1) + + sp.emit(sp.record(next=prev, seq=self.data.links.get(prev).tx_seq, msg=serialized_msg), tag="Message") + + @sp.entry_point + def update_link_rx_height(self, prev, val): + sp.set_type(prev, sp.TString) + sp.set_type(val, sp.TNat) + + self.only_bmc_periphery() + self.data.links[prev].rx_height += val + + @sp.entry_point + def update_link_reachable(self, prev, to): + sp.set_type(prev, sp.TString) + sp.set_type(to, sp.TList(sp.TString)) + + self.only_bmc_periphery() + sp.for item in to: + self.data.links[prev].reachable.add(item) + net, addr = sp.match_pair( + strings.split_btp_address(item, "prev_idx", "result", "my_list", "last", "penultimate")) + self.data.get_link_from_reachable_net[net] = sp.record(prev=prev, to=item) + + @sp.entry_point + def delete_link_reachable(self, prev, index): + sp.set_type(prev, sp.TString) + sp.set_type(index, sp.TNat) + + self.only_bmc_periphery() + i = sp.local("i", sp.nat(0)) + sp.for item in self.data.links.get(prev).reachable.elements(): + sp.if i.value == index: + net, addr = sp.match_pair( + strings.split_btp_address(item, "prev_idx", "result", "my_list", "last", "penultimate")) + + del self.data.get_link_from_reachable_net[net] + self.data.links[prev].reachable.remove(item) + i.value += 1 + + @sp.entry_point + def update_relay_stats(self, relay, block_count_val, msg_count_val): + sp.set_type(relay, sp.TAddress) + sp.set_type(block_count_val, sp.TNat) + sp.set_type(msg_count_val, sp.TNat) + + self.only_bmc_periphery() + self.data.relay_stats[relay].block_count += block_count_val + self.data.relay_stats[relay].msg_count += msg_count_val + + @sp.onchain_view() + def resolve_route(self, dst_net): + sp.set_type(dst_net, sp.TString) + + dst = sp.local("dst", self.data.get_route_dst_from_net.get(dst_net), t=sp.TString) + + with sp.if_(sp.len(sp.pack(dst.value))!= sp.nat(0)): + sp.result(sp.pair(self.data.routes.get(dst.value), dst.value)) + with sp.else_(): + dst_link = sp.local("dst_link", self.data.get_link_from_net.get(dst_net), t=sp.TString) + with sp.if_(sp.len(sp.pack(dst_link.value)) != sp.nat(0)): + sp.result(sp.pair(dst_link.value, dst_link.value)) + with sp.else_(): + res = sp.local("res", self.data.get_link_from_reachable_net.get(dst_net), t=types.Types.Tuple) + # sp.verify(sp.len(sp.pack(res.value.to)) > sp.nat(0), "Unreachable: " + dst_net + " is unreachable") + with sp.if_(sp.len(sp.pack(res.value.to)) > sp.nat(0)): + sp.result(sp.pair(res.value.prev, res.value.to)) + with sp.else_(): + sp.result(sp.pair("Unreachable", "Unreachable: " + dst_net + " is unreachable")) + + +sp.add_compilation_target("bmc_management", BMCManagement(owner_address=sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP"), + helper_contract=sp.address("KT1HwFJmndBWRn3CLbvhUjdupfEomdykL5a6"))) diff --git a/smartpy/bmc/contracts/src/bmc_periphery.py b/smartpy/bmc/contracts/src/bmc_periphery.py new file mode 100644 index 00000000..10440568 --- /dev/null +++ b/smartpy/bmc/contracts/src/bmc_periphery.py @@ -0,0 +1,401 @@ +import smartpy as sp + +types = sp.io.import_script_from_url("file:./contracts/src/Types.py") +strings = sp.io.import_script_from_url("file:./contracts/src/String.py") +rlp_encode = sp.io.import_script_from_url("file:./contracts/src/RLP_encode_struct.py") +rlp_decode = sp.io.import_script_from_url("file:./contracts/src/RLP_decode_struct.py") + + +class BMCPreiphery(sp.Contract, rlp_decode.DecodeLibrary, rlp_encode.EncodeLibrary): + BMC_ERR = sp.nat(10) + BSH_ERR = sp.nat(40) + UNKNOWN_ERR = sp.nat(0) + + BMCRevertUnauthorized = sp.string("Unauthorized") + BMCRevertParseFailure = sp.string("ParseFailure") + BMCRevertNotExistsBSH = sp.string("NotExistsBSH") + BMCRevertNotExistsLink = sp.string("NotExistsLink") + BMCRevertInvalidSn = sp.string("InvalidSn") + BMCRevertInvalidSeqNumber = sp.string("InvalidSeqNumber") + BMCRevertNotExistsInternalHandler = sp.string("NotExistsInternalHandler") + BMCRevertUnknownHandleBTPError = sp.string("UnknownHandleBTPError") + BMCRevertUnknownHandleBTPMessage = sp.string("UnknownHandleBTPMessage") + + def __init__(self, bmc_management_addr, helper_contract, helper_parse_neg_contract, parse_address, owner_address): + self.init( + helper=helper_contract, + helper_parse_negative=helper_parse_neg_contract, + bmc_btp_address=sp.none, + bmc_management=bmc_management_addr, + parse_contract=parse_address, + handle_btp_message_status=sp.none, + handle_btp_error_status=sp.none, + handle_fee_gathering_status=sp.none, + owner_address = owner_address + ) + + def only_owner(self): + sp.verify(sp.sender == self.data.owner_address, "Unauthorized") + + @sp.entry_point + def set_helper_address(self, address): + sp.set_type(address, sp.TAddress) + self.only_owner() + self.data.helper = address + + @sp.entry_point + def set_helper_parse_negative_address(self, address): + sp.set_type(address, sp.TAddress) + self.only_owner() + self.data.helper_parse_negative = address + + @sp.entry_point + def set_parse_address(self, address): + sp.set_type(address, sp.TAddress) + self.only_owner() + self.data.parse_contract = address + + @sp.entry_point + def set_bmc_management_addr(self, params): + sp.set_type(params, sp.TAddress) + self.only_owner() + self.data.bmc_management = params + + @sp.entry_point + def set_bmc_btp_address(self, network): + sp.set_type(network, sp.TString) + + sp.verify(sp.sender == self.data.bmc_management, "Unauthorized") + with sp.if_(self.data.bmc_btp_address == sp.none): + self.data.bmc_btp_address = sp.some(sp.string("btp://") + network + "/" + sp.view("add_to_str", self.data.parse_contract, sp.self_address, t=sp.TString).open_some()) + with sp.else_(): + sp.failwith("Address already set") + + @sp.onchain_view() + def get_bmc_btp_address(self): + sp.result(self.data.bmc_btp_address.open_some("Address not set")) + + @sp.onchain_view() + def get_bmc_management_address(self): + sp.result(self.data.bmc_management) + + def _require_registered_relay(self, prev): + sp.set_type(prev, sp.TString) + + relays = sp.view("get_link_relays", self.data.bmc_management, prev, t=sp.TList(sp.TAddress)).open_some() + valid = sp.local("valid", False) + sp.for x in relays: + sp.if sp.sender == x: + valid.value = True + sp.verify(valid.value, self.BMCRevertUnauthorized) + + @sp.entry_point + def callback_btp_message(self, string, bsh_addr, prev, callback_msg): + sp.set_type(string, sp.TOption(sp.TString)) + sp.set_type(bsh_addr, sp.TAddress) + sp.set_type(prev, sp.TString) + sp.set_type(callback_msg, types.Types.BMCMessage) + + sp.verify(sp.sender == bsh_addr, "Unauthorized") + self.data.handle_btp_message_status = string + + with sp.if_(self.data.handle_btp_message_status.open_some() == "success"): + pass + with sp.else_(): + self._send_error(prev, callback_msg, self.BSH_ERR, self.BMCRevertUnknownHandleBTPMessage) + self.data.handle_btp_message_status = sp.none + + @sp.entry_point + def callback_btp_error(self, string, bsh_addr, svc, sn, code, msg): + sp.set_type(string, sp.TOption(sp.TString)) + sp.set_type(bsh_addr, sp.TAddress) + sp.set_type(svc, sp.TString) + sp.set_type(sn, sp.TInt) + sp.set_type(code, sp.TNat) + sp.set_type(msg, sp.TString) + + sp.verify(sp.sender == bsh_addr, "Unauthorized") + self.data.handle_btp_error_status = string + + with sp.if_(self.data.handle_btp_error_status.open_some() == "success"): + pass + with sp.else_(): + error_code = self.UNKNOWN_ERR + err_msg = self.BMCRevertUnknownHandleBTPError + sp.emit(sp.record(svc=svc, sn=sn * -1, code=code, msg=msg, err_code=error_code, err_msg=err_msg), tag="ErrorOnBTPError") + self.data.handle_btp_error_status = sp.none + + @sp.entry_point + def callback_handle_fee_gathering(self, string, bsh_addr): + sp.set_type(string, sp.TOption(sp.TString)) + sp.set_type(bsh_addr, sp.TAddress) + + sp.verify(sp.sender == bsh_addr, "Unauthorized") + self.data.handle_fee_gathering_status = string + with sp.if_(self.data.handle_fee_gathering_status.open_some() == "success"): + pass + self.data.handle_fee_gathering_status = sp.none + + @sp.entry_point + def handle_relay_message(self, prev, msg): + sp.set_type(prev, sp.TString) + sp.set_type(msg, sp.TBytes) + + self._require_registered_relay(prev) + + link_rx_seq = sp.view("get_link_rx_seq", self.data.bmc_management, prev, t=sp.TNat).open_some() + link_rx_height = sp.view("get_link_rx_height", self.data.bmc_management, prev, t=sp.TNat).open_some() + + rx_seq = sp.local("rx_seq", link_rx_seq, t=sp.TNat) + rx_height = sp.local("rx_height", link_rx_height, t=sp.TNat) + rps = self.decode_receipt_proofs(msg) + bmc_msg = sp.local("bmc_msg", sp.record(src="", dst="", svc="", sn=sp.int(0), message=sp.bytes("0x")), t=types.Types.BMCMessage) + ev = sp.local("ev", sp.record(next_bmc="", seq=sp.nat(0), message=sp.bytes("0x")), t=types.Types.MessageEvent) + sp.for i in sp.range(sp.nat(0), sp.len(rps)): + with sp.if_(rps[i].height < rx_height.value): + pass + with sp.else_(): + rx_height.value = rps[i].height + sp.for j in sp.range(sp.nat(0), sp.len(rps[i].events)): + ev.value = rps[i].events[j] + sp.verify(ev.value.next_bmc == self.data.bmc_btp_address.open_some("Address not set"), "Invalid Next BMC") + rx_seq.value +=sp.nat(1) + with sp.if_(ev.value.seq < rx_seq.value): + rx_seq.value = sp.as_nat(rx_seq.value-sp.nat(1)) + with sp.else_(): + sp.if ev.value.seq > rx_seq.value: + sp.failwith(self.BMCRevertInvalidSeqNumber) + + _decoded = self.decode_bmc_message(ev.value.message) + bmc_msg.value = _decoded + + sp.if bmc_msg.value.src != "": + with sp.if_(bmc_msg.value.dst == self.data.bmc_btp_address.open_some("Address not set")): + self._handle_message(prev, bmc_msg.value) + with sp.else_(): + net, addr = sp.match_pair(strings.split_btp_address(bmc_msg.value.dst, "prev_idx", "result", "my_list", "last", "penultimate")) + next_link, prev_link = sp.match_pair(sp.view("resolve_route", self.data.bmc_management, net, t=sp.TPair(sp.TString, sp.TString)).open_some("Invalid Call")) + with sp.if_(next_link != "Unreachable"): + self._send_message(next_link, ev.value.message) + with sp.else_(): + self._send_error(prev, bmc_msg.value, self.BMC_ERR, "Unreachable_"+ net) + # call update_link_rx_seq on BMCManagement + update_link_rx_seq_args_type = sp.TRecord(prev=sp.TString, val=sp.TNat) + update_link_rx_seq_entry_point = sp.contract(update_link_rx_seq_args_type, + self.data.bmc_management, + "update_link_rx_seq").open_some() + update_link_rx_seq_args = sp.record(prev=prev, val=sp.as_nat(rx_seq.value - link_rx_seq)) + sp.transfer(update_link_rx_seq_args, sp.tez(0), update_link_rx_seq_entry_point) + + # call update_relay_stats on BMCManagement + update_relay_stats_args_type = sp.TRecord(relay=sp.TAddress, block_count_val=sp.TNat, msg_count_val=sp.TNat) + update_relay_stats_entry_point = sp.contract(update_relay_stats_args_type, + self.data.bmc_management, + "update_relay_stats").open_some() + update_relay_stats_args = sp.record(relay=sp.sender, block_count_val=sp.nat(0), msg_count_val=sp.as_nat(rx_seq.value - link_rx_seq)) + sp.transfer(update_relay_stats_args, sp.tez(0), update_relay_stats_entry_point) + + # call update_link_rx_height on BMCManagement + update_link_rx_height_args_type = sp.TRecord(prev=sp.TString, val=sp.TNat) + update_link_rx_height_entry_point = sp.contract(update_link_rx_height_args_type, + self.data.bmc_management, + "update_link_rx_height").open_some() + update_link_rx_height_args = sp.record(prev=prev, val=sp.as_nat(rx_height.value - link_rx_height)) + sp.transfer(update_link_rx_height_args, sp.tez(0), update_link_rx_height_entry_point) + + + + def _handle_message(self, prev, msg): + sp.set_type(prev, sp.TString) + sp.set_type(msg, types.Types.BMCMessage) + + # bsh_addr = sp.local("bsh_addr",sp.TAddress) + with sp.if_(msg.svc == "bmc"): + sm = sp.local("sm", sp.record(serviceType="", payload=sp.bytes("0x"))) + sm.value = self.decode_bmc_service(msg.message) + with sp.if_(sm.value.serviceType == ""): + self._send_error(prev, msg, self.BMC_ERR, self.BMCRevertParseFailure) + with sp.else_(): + sp.if sm.value.serviceType == "FeeGathering": + gather_fee =sp.local("gather_fee", sp.record(fa="", svcs=sp.map({0:""}))) + gather_fee.value = self.decode_gather_fee_message(sm.value.payload) + + with sp.if_(gather_fee.value.fa == ""): + self._send_error(prev, msg, self.BMC_ERR, self.BMCRevertParseFailure) + + with sp.else_(): + sp.for c in sp.range(sp.nat(0), sp.len(gather_fee.value.svcs)): + bsh_addr = sp.view("get_bsh_service_by_name", self.data.bmc_management, gather_fee.value.svcs[c], t=sp.TAddress).open_some("Invalid Call") + + sp.if bsh_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg"): + # call handle_fee_gathering of bts periphery + handle_fee_gathering_args_type = sp.TRecord(callback=sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress)), bsh_addr=sp.TAddress, fa=sp.TString, svc=sp.TString) + handle_fee_gathering_entry_point = sp.contract(handle_fee_gathering_args_type, + bsh_addr, + "handle_fee_gathering").open_some() + handle_fee_gathering_args = sp.record(callback=sp.self_entry_point("callback_handle_fee_gathering"), bsh_addr=bsh_addr, fa=gather_fee.value.fa, svc=gather_fee.value.svcs[c]) + sp.transfer(handle_fee_gathering_args, sp.tez(0), handle_fee_gathering_entry_point) + + sp.if sm.value.serviceType == "Link": + to = self.decode_propagate_message(sm.value.payload) + link = sp.view("get_link", self.data.bmc_management, prev, t=types.Types.Link).open_some() + + check = sp.local("check", False) + sp.if link.is_connected: + sp.for e in link.reachable.elements(): + sp.if check.value == False: + sp.if to == e: + check.value = True + + sp.if check.value == False: + links = sp.list([to], t=sp.TString) + + # call update_link_reachable on BMCManagement + update_link_reachable_args_type = sp.TRecord(prev=sp.TString, to=sp.TList(sp.TString)) + update_link_reachable_entry_point = sp.contract(update_link_reachable_args_type, + self.data.bmc_management, + "update_link_reachable").open_some() + update_link_reachable_args = sp.record(prev=prev, to=links) + sp.transfer(update_link_reachable_args, sp.tez(0), update_link_reachable_entry_point) + + sp.if sm.value.serviceType == "Unlink": + to = self.decode_propagate_message(sm.value.payload) + link = sp.view("get_link", self.data.bmc_management, prev, t=types.Types.Link).open_some() + + sp.if link.is_connected: + f = sp.local("f", sp.nat(0)) + sp.for itm in link.reachable.elements(): + sp.if to == itm: + + # call delete_link_reachable on BMCManagement + delete_link_reachable_args_type = sp.TRecord(prev=sp.TString, index=sp.TNat) + delete_link_reachable_entry_point = sp.contract(delete_link_reachable_args_type, + self.data.bmc_management, + "delete_link_reachable").open_some() + delete_link_reachable_args = sp.record(prev=prev, index=f.value) + sp.transfer(delete_link_reachable_args, sp.tez(0), delete_link_reachable_entry_point) + f.value += sp.nat(1) + + sp.if sm.value.serviceType == "Init": + links = self.decode_init_message(sm.value.payload) + # call update_link_reachable on BMCManagement + update_link_reachable_args_type = sp.TRecord(prev=sp.TString, to=sp.TList(sp.TString)) + update_link_reachable_entry_point = sp.contract(update_link_reachable_args_type, + self.data.bmc_management, + "update_link_reachable").open_some() + update_link_reachable_args = sp.record(prev=prev, to=links) + sp.transfer(update_link_reachable_args, sp.tez(0), update_link_reachable_entry_point) + with sp.else_(): + bsh_addr = sp.view("get_bsh_service_by_name", self.data.bmc_management, msg.svc, t=sp.TAddress).open_some("Invalid view") + + with sp.if_(bsh_addr == sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): + self._send_error(prev, msg, self.BMC_ERR, self.BMCRevertNotExistsBSH) + + with sp.else_(): + with sp.if_(msg.sn >= sp.int(0)): + net, addr = sp.match_pair(strings.split_btp_address(msg.src, "prev_idx", "result", "my_list", "last", "penultimate")) + # implemented callback + # call handle_btp_message on bts periphery + handle_btp_message_args_type = sp.TRecord(callback=sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress, prev=sp.TString, callback_msg=types.Types.BMCMessage)), + bsh_addr=sp.TAddress, prev=sp.TString, callback_msg=types.Types.BMCMessage, _from=sp.TString, svc=sp.TString, sn=sp.TInt, msg=sp.TBytes) + handle_btp_message_entry_point = sp.contract(handle_btp_message_args_type, + bsh_addr, + "handle_btp_message").open_some() + handle_btp_message_args = sp.record(callback=sp.self_entry_point("callback_btp_message"), bsh_addr=bsh_addr, prev=prev, callback_msg=msg, _from=net, svc=msg.svc, sn=msg.sn, msg=msg.message) + sp.transfer(handle_btp_message_args, sp.tez(0), handle_btp_message_entry_point) + + with sp.else_(): + res = self.decode_response(msg.message) + # implemented callback + # call handle_btp_error on bts periphery + handle_btp_error_args_type = sp.TRecord(callback=sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress, svc=sp.TString, sn=sp.TInt, code=sp.TNat, msg=sp.TString)), + bsh_addr=sp.TAddress, svc=sp.TString, sn=sp.TInt, code=sp.TNat, msg=sp.TString) + handle_btp_error_entry_point = sp.contract(handle_btp_error_args_type, + bsh_addr, + "handle_btp_error").open_some() + handle_btp_error_args = sp.record(callback=sp.self_entry_point("callback_btp_error"), bsh_addr=bsh_addr, + svc=msg.svc, sn=msg.sn * -1, code=res.code, msg="error") + sp.transfer(handle_btp_error_args, sp.tez(0), handle_btp_error_entry_point) + + def _send_message(self, to ,serialized_msg): + sp.set_type(to, sp.TString) + sp.set_type(serialized_msg, sp.TBytes) + + # call update_link_tx_seq on BMCManagement + update_link_tx_seq_entry_point = sp.contract(sp.TRecord(prev=sp.TString, serialized_msg=sp.TBytes), + self.data.bmc_management, + "update_link_tx_seq").open_some() + sp.transfer(sp.record(prev=to, serialized_msg=serialized_msg), sp.tez(0), update_link_tx_seq_entry_point) + + def _send_error(self, prev, message, err_code, err_msg): + sp.set_type(prev, sp.TString) + sp.set_type(message, types.Types.BMCMessage) + sp.set_type(err_code, sp.TNat) + sp.set_type(err_msg, sp.TString) + + sp.if message.sn > sp.int(0): + serialized_msg = self.encode_bmc_message(sp.record( + src=self.data.bmc_btp_address.open_some("Address not set"), + dst=message.src, + svc=message.svc, + sn=message.sn * -1, + message=self.encode_response(sp.record(code=err_code, message=err_msg)) + )) + self._send_message(prev, serialized_msg) + + @sp.entry_point + def send_message(self, to, svc, sn, msg): + """ + Send the message to a specific network + :param to: Network Address of destination network + :param svc: Name of the service + :param sn: Serial number of the message, it should be positive + :param msg: Serialized bytes of Service Message + :return: + """ + sp.set_type(to, sp.TString) + sp.set_type(svc, sp.TString) + sp.set_type(sn, sp.TInt) + sp.set_type(msg, sp.TBytes) + + sp.verify((sp.sender == self.data.bmc_management) | + (sp.view("get_bsh_service_by_name", self.data.bmc_management, svc, t=sp.TAddress).open_some() == sp.sender), + self.BMCRevertUnauthorized) + sp.verify(sn >= sp.int(0), self.BMCRevertInvalidSn) + + next_link, dst = sp.match_pair(sp.view("resolve_route", self.data.bmc_management, to, t=sp.TPair(sp.TString, sp.TString)).open_some()) + + rlp = self.encode_bmc_message(sp.record( + src=self.data.bmc_btp_address.open_some("Address not set"), + dst=dst, + svc=svc, + sn=sn, + message=msg + )) + self._send_message(next_link, rlp) + + @sp.onchain_view() + def get_status(self, _link): + """ + Get status of BMC + :param _link: BTP Address of the connected BMC + :return: + """ + sp.set_type(_link, sp.TString) + + link = sp.view("get_link", self.data.bmc_management, _link, t=types.Types.Link).open_some() + sp.verify(link.is_connected == True, self.BMCRevertNotExistsLink) + + sp.result(sp.record( + rx_seq=link.rx_seq, + tx_seq=link.tx_seq, + rx_height=link.rx_height, + current_height=sp.level #block height + )) + + +sp.add_compilation_target("bmc_periphery", BMCPreiphery(bmc_management_addr=sp.address("KT1Uiycjx4iXdjKFfR2kAo2NUdEtQ6PmDX4Y"), + helper_contract=sp.address("KT1HwFJmndBWRn3CLbvhUjdupfEomdykL5a6"), + helper_parse_neg_contract=sp.address("KT1DHptHqSovffZ7qqvSM9dy6uZZ8juV88gP"), + parse_address=sp.address("KT1XgRyjQPfpfwNrvYYpgERpYpCrGh24aoPX"), + owner_address=sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP"))) diff --git a/smartpy/bmc/contracts/src/check_negative.py b/smartpy/bmc/contracts/src/check_negative.py new file mode 100644 index 00000000..604fb6f2 --- /dev/null +++ b/smartpy/bmc/contracts/src/check_negative.py @@ -0,0 +1,48 @@ +import smartpy as sp +Utils2 = sp.io.import_script_from_url("https://raw.githubusercontent.com/RomarQ/tezos-sc-utils/main/smartpy/utils.py") + +# +# @sp.module +# def main(): +# class C(sp.Contract): +# +# @sp.onchain_view() +# def check_negative(self, x): +# sp.cast(x, sp.bytes) +# return (sp.to_int(x) < 0) +# +# @sp.onchain_view() +# def to_int(self, x): +# sp.cast(x, sp.bytes) +# return (sp.to_int(x)) +# +# @sp.onchain_view() +# def to_byte(self, x): +# return (sp.to_bytes(x)) +# +# +# @sp.add_test(name="test") +# def test(): +# scenario = sp.test_scenario(main) +# c = main.C() +# scenario += c + +class Sample(sp.Contract): + def __init__(self): + self.init( + tf = False + ) + + @sp.entry_point + def test(self, addr): + sp.set_type(addr, sp.TAddress) + x = sp.view("check_negative", addr, sp.bytes("0xf6"), t=sp.TBool).open_some() + self.data.tf = x + +@sp.add_test("Tests") +def test(): + sc = sp.test_scenario() + c = Sample() + sc += c + +sp.add_compilation_target("check_negative", Sample()) \ No newline at end of file diff --git a/smartpy/bmc/contracts/src/helper.py b/smartpy/bmc/contracts/src/helper.py new file mode 100644 index 00000000..94d220c8 --- /dev/null +++ b/smartpy/bmc/contracts/src/helper.py @@ -0,0 +1,77 @@ +import smartpy as sp + +Utils = sp.io.import_script_from_url("https://raw.githubusercontent.com/Acurast/acurast-hyperdrive/main/contracts/tezos/libs/utils.py") + + +class Helper(sp.Contract): + def __init__(self): + self.init() + + @sp.onchain_view() + def decode_string(self, params): + sp.set_type(params, sp.TBytes) + decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) + sp.result(decode_string(params)) + + @sp.onchain_view() + def prefix_length(self, params): + sp.set_type(params, sp.TBytes) + prefix_length = sp.build_lambda(Utils.RLP.Decoder.prefix_length) + sp.result(prefix_length(params)) + + @sp.onchain_view() + def decode_list(self, params): + sp.set_type(params, sp.TBytes) + decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) + sp.result(decode_list(params)) + + @sp.onchain_view() + def is_list(self, params): + sp.set_type(params, sp.TBytes) + is_list = sp.build_lambda(Utils.RLP.Decoder.is_list) + sp.result(is_list(params)) + + @sp.onchain_view() + def of_string(self, params): + sp.set_type(params, sp.TString) + encode_string_packed = sp.build_lambda(Utils.Bytes.of_string) + sp.result(encode_string_packed(params)) + + @sp.onchain_view() + def encode_string(self, params): + sp.set_type(params, sp.TString) + encode_string_packed = sp.build_lambda(Utils.RLP.Encoder.encode_string) + sp.result(encode_string_packed(params)) + + @sp.onchain_view() + def encode_nat(self, params): + sp.set_type(params, sp.TNat) + encode_nat_packed = sp.build_lambda(Utils.RLP.Encoder.encode_nat) + sp.result(encode_nat_packed(params)) + + @sp.onchain_view() + def of_nat(self, params): + sp.set_type(params, sp.TNat) + encode_nat_packed = sp.build_lambda(Utils.Bytes.of_nat) + sp.result(encode_nat_packed(params)) + + @sp.onchain_view() + def with_length_prefix(self, params): + sp.set_type(params, sp.TBytes) + encode_length_packed = sp.build_lambda(Utils.RLP.Encoder.with_length_prefix) + sp.result(encode_length_packed(params)) + + @sp.onchain_view() + def without_length_prefix(self, params): + sp.set_type(params, sp.TBytes) + decode = sp.build_lambda(Utils.RLP.Decoder.without_length_prefix) + sp.result(decode(params)) + + @sp.onchain_view() + def encode_list(self, params): + sp.set_type(params, sp.TList(sp.TBytes)) + encode_list_packed = sp.build_lambda(Utils.RLP.Encoder.encode_list) + sp.result(encode_list_packed(params)) + + +sp.add_compilation_target("helper", Helper()) \ No newline at end of file diff --git a/smartpy/bmc/contracts/src/parse_address.py b/smartpy/bmc/contracts/src/parse_address.py new file mode 100644 index 00000000..57ced093 --- /dev/null +++ b/smartpy/bmc/contracts/src/parse_address.py @@ -0,0 +1,104 @@ +import smartpy as sp +Utils = sp.io.import_script_from_url("https://raw.githubusercontent.com/RomarQ/tezos-sc-utils/main/smartpy/utils.py") + + +class ParseAddress(sp.Contract): + tz_prefixes = sp.map({ + sp.bytes('0x0000'): sp.string('tz1'), + sp.bytes('0x0001'): sp.string('tz2'), + sp.bytes('0x0002'): sp.string('tz3'), + sp.bytes('0x0003'): sp.string('tz4') + }) + base58_encodings = sp.list([ + sp.map({"prefix": "tz1", "elem1": "6", "elem2": "161", "elem3": "159", "len": "20"}), + sp.map({"prefix": "tz2", "elem1": "6", "elem2": "161", "elem3": "161", "len": "20"}), + sp.map({"prefix": "tz3", "elem1": "6", "elem2": "161", "elem3": "164", "len": "20"}), + sp.map({"prefix": "tz4", "elem1": "6", "elem2": "161", "elem3": "16", "len": "20"}), + sp.map({"prefix": "KT1", "elem1": "2", "elem2": "90", "elem3": "121", "len": "20"}), + ]) + + def __init__(self): + self.init() + + def unforge_address(self, data): + """Decode address or key_hash from bytes. + + :param data: encoded address or key_hash + :returns: base58 encoded address + """ + sp.set_type(data, sp.TBytes) + byt = sp.slice(data, 6, 22).open_some() + prefix = sp.slice(byt, 0, 2).open_some() + starts_with = sp.slice(byt, 0, 1).open_some() + ends_with = sp.slice(byt, 21, 1).open_some() + sliced_byte = sp.slice(byt, 1, 20).open_some() + local_byte = sp.local("local_byte", sp.bytes("0x")) + return_value = sp.local("return_value", "tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg", sp.TString) + + sp.for item in self.tz_prefixes.items(): + sp.if item.key == prefix: + return_value.value = self.base58_encode(sp.slice(byt, 2, 20).open_some(), Utils.Bytes.of_string(item.value), local_byte) + + sp.if (starts_with == sp.bytes("0x01")) & (ends_with == sp.bytes("0x00")): + return_value.value = self.base58_encode(sliced_byte, Utils.Bytes.of_string("KT1"), local_byte) + sp.if (starts_with == sp.bytes("0x02")) & (ends_with == sp.bytes("0x00")): + return_value.value = self.base58_encode(sliced_byte, Utils.Bytes.of_string("txr1"), local_byte) + sp.if (starts_with == sp.bytes("0x03")) & (ends_with == sp.bytes("0x00")): + return_value.value = self.base58_encode(sliced_byte, Utils.Bytes.of_string("sr1"), local_byte) + + return return_value.value + + def tb(self, _list): + byte_str = sp.local("byte_str", sp.bytes("0x")) + sp.for num in _list: + byte_str.value += Utils.Bytes.of_nat(num) + return byte_str.value + + def base58_encode(self, byt_array, prefix, _byte): + """ + Encode data using Base58 with checksum and add an according binary prefix in the end. + :param byt_array: Array of bytes + :param prefix: Human-readable prefix (use b'') e.g. b'tz', b'KT', etc + :param local_byte: local variable + + :returns: bytes (use string.decode()) + """ + length_v = sp.to_int(sp.len(byt_array)) + encoding = sp.local("encode", sp.map({})) + byte_from_tbl = sp.local("byte_from_tbl", sp.bytes("0x")) + byte_value = _byte + + sp.for enc in self.base58_encodings: + sp.if (length_v == Utils.Int.of_string(enc["len"])) & (prefix == Utils.Bytes.of_string(enc["prefix"])): + encoding.value = enc + byte_from_tbl.value = self.tb([sp.as_nat(Utils.Int.of_string(enc["elem1"])), + sp.as_nat(Utils.Int.of_string(enc["elem2"])), + sp.as_nat(Utils.Int.of_string(enc["elem3"]))]) + sha256_encoding = sp.sha256(sp.sha256(byte_from_tbl.value + byt_array)) + sha256_encoding = byte_from_tbl.value + byt_array + sp.slice(sha256_encoding, 0, 4).open_some() + acc = sp.local("for_while_loop", Utils.Int.of_bytes(sha256_encoding)) + alphabet = Utils.Bytes.of_string("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") + base = 58 + sp.while acc.value > 0: + (acc.value, idx) = sp.match_pair(sp.ediv(acc.value, base).open_some()) + byte_value.value = sp.slice(alphabet, idx, 1).open_some() + byte_value.value + + return sp.unpack(sp.bytes("0x050100000024") + byte_value.value, sp.TString).open_some() + + @sp.onchain_view() + def add_to_str(self, params): + sp.set_type(params, sp.TAddress) + sp.result(self.unforge_address(sp.pack(params))) + + +@sp.add_test(name="Conversion") +def test(): + c1 = ParseAddress() + scenario = sp.test_scenario() + scenario.h1("Conversion") + scenario += c1 + c1.add_to_str(sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP")) + scenario.verify(c1.add_to_str(sp.address("KT1FfkTSts5DnvyJp2qZbPMeqm2XpMYES7Vr")) == "KT1FfkTSts5DnvyJp2qZbPMeqm2XpMYES7Vr") + scenario.verify(c1.add_to_str(sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP")) == "tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP") + +sp.add_compilation_target("parse_address", ParseAddress()) \ No newline at end of file diff --git a/smartpy/bmc/contracts/tests/bmc_management_test.py b/smartpy/bmc/contracts/tests/bmc_management_test.py new file mode 100644 index 00000000..1e79b780 --- /dev/null +++ b/smartpy/bmc/contracts/tests/bmc_management_test.py @@ -0,0 +1,377 @@ +import smartpy as sp + +BMCManagement = sp.io.import_script_from_url("file:./contracts/src/bmc_management.py") +BMCPeriphery = sp.io.import_script_from_url("file:./contracts/src/bmc_periphery.py") +BMCHelper = sp.io.import_script_from_url("file:./contracts/src/helper.py") +ParseAddress = sp.io.import_script_from_url("file:./contracts/src/parse_address.py") + + +@sp.add_test("BMCManagementTest") +def test(): + sc = sp.test_scenario() + + # test account + alice = sp.test_account("Alice") + creator = sp.test_account("Creator") + jack = sp.test_account("Jack") + bob = sp.test_account("Bob") + bmc_periphery_address = sp.test_account("bmc_periphery_address") + creator2 = sp.test_account("creator2") + service1_address = sp.test_account("service1_address") + service2_address = sp.test_account("service2_address") + + # deploy BMCManagement contract + helper_contract = deploy_helper_contract() + sc += helper_contract + + bmc_management_contract = deploy_bmc_management_contract(creator.address, helper_contract.address) + sc += bmc_management_contract + + parse_address = deploy_parse_address() + sc += parse_address + + bmc_periphery_address = bmc_periphery_address.address + + # Test case 1: bmc_periphery + sc.h1("Test case 1: set bmc_periphery to a valid address") + sc.verify(bmc_management_contract.data.bmc_periphery.is_some() == False) + bmc_management_contract.set_bmc_periphery(bmc_periphery_address).run(sender=creator) + # sender should be owner + bmc_management_contract.set_bmc_periphery(bob.address).run(sender=alice, valid=False, exception="Unauthorized") + # repeated bmc_periphery should throw error + bmc_management_contract.set_bmc_periphery(bmc_periphery_address).run(sender=creator, valid=False, + exception="AlreadyExistsBMCPeriphery") + # Verify that bmc_periphery is set to the valid address + sc.verify(bmc_management_contract.data.bmc_periphery.is_some() == True) + sc.verify(bmc_management_contract.data.bmc_periphery.open_some() == bmc_periphery_address) + + # set_bmc_btp_address + bmc_management_contract.set_bmc_btp_address("tezos.77").run(sender=creator) + + # Test case 2: add_owner + # throw error when adding owner by random address + bmc_management_contract.add_owner(alice.address).run(sender=bob, valid=False, exception="Unauthorized") + # successfully added new owner + bmc_management_contract.add_owner(alice.address).run(sender=creator) + sc.verify(bmc_management_contract.data.owners[alice.address] == True) + + # Test case 3: remove owner + # throw error when removing owner by random address + bmc_management_contract.remove_owner(alice.address).run(sender=bob, valid=False, exception="Unauthorized") + # working + bmc_management_contract.remove_owner(alice.address).run(sender=creator) + sc.verify(~bmc_management_contract.data.owners.contains(jack.address)) + + # Test case 4: is_owner + # Add an owner + bmc_management_contract.add_owner(creator2.address).run(sender=creator) + # Test the is_owner view function + sc.verify(bmc_management_contract.is_owner(creator2.address) == True) + + # Test case 5: add_service function + svc1 = sp.string("service1") + svc2 = sp.string("service2") + svc3 = sp.string("service3") + # add service by random address should fail + bmc_management_contract.add_service(sp.record(addr=service1_address.address, svc=svc1)).run(sender=bob, valid=False, + exception="Unauthorized") + # adding service + bmc_management_contract.add_service(sp.record(addr=service1_address.address, svc=svc1)).run(sender=creator) + # shouldn't add same service twice + bmc_management_contract.add_service(sp.record(addr=service1_address.address, svc=svc1)).run(sender=creator, + valid=False, + exception="AlreadyExistsBSH") + + # Test case 6: remove_service function + # remove service by random address should fail + bmc_management_contract.remove_service(svc2).run(sender=bob, valid=False, exception="Unauthorized") + # removing unregistered should throw error + bmc_management_contract.remove_service(svc3).run(sender=creator, valid=False) + # removing service + bmc_management_contract.add_service(sp.record(addr=service2_address.address, svc=svc2)).run(sender=creator) + bmc_management_contract.remove_service(svc2).run(sender=creator) + + # test case 7: get_services function + services = bmc_management_contract.get_services() + sc.verify_equal(services, sp.map({0: sp.record(svc=svc1, addr=service1_address.address)})) + + # test case 8: add_route function + dst = "btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258dest" + next_link = "btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b" + # only owner can add routes + bmc_management_contract.add_route(sp.record(dst=dst, link=next_link)).run(sender=bob, valid=False, + exception="Unauthorized") + # should work + bmc_management_contract.add_route(sp.record(dst=dst, link=next_link)).run(sender=creator) + # cannot add already existed route + bmc_management_contract.add_route(sp.record(dst=dst, link=next_link)).run(sender=creator, valid=False, + exception="AlreadyExistRoute") + + # test case 9: remove_route function + dst1 = "btp://78.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5DEST1" + next_link1 = "btp://78.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5LINK1" + # only owner can remove routes + bmc_management_contract.remove_route(dst).run(sender=bob, valid=False, exception="Unauthorized") + # throw error when non-exist route is given & this should throw error but not thrown + bmc_management_contract.remove_route(dst1).run(sender=creator, valid=False, exception="NotExistRoute") + # should work + bmc_management_contract.add_route(sp.record(dst=dst1, link=next_link1)).run(sender=creator) + bmc_management_contract.remove_route(dst1).run(sender=creator) + + # test case 10: get_routes function + get_routes = bmc_management_contract.get_routes() + sc.verify_equal(get_routes, sp.map({0: sp.record( + dst=sp.string("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258dest"), + next=sp.string("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b"))})) + + # test case 11: add_link function + # add_link by random address should fail + bmc_management_contract.add_link("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b").run(sender=bob, + valid=False, + exception="Unauthorized") + # should work + bmc_management_contract.add_link("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b").run(sender=creator) + # add_link by of same link should fail + bmc_management_contract.add_link("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b").run(sender=creator, + valid=False, + exception="AlreadyExistsLink") + + # test case 12: remove_link function + # remove_link by random address should fail + bmc_management_contract.remove_link("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258dead").run(sender=bob, + valid=False, + exception="Unauthorized") + # remove_link should throw error when removing non-existing link + bmc_management_contract.remove_link("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258dead").run(sender=creator, + valid=False, + exception="NotExistsLink") + # should work + bmc_management_contract.add_link("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258dead").run(sender=creator) + bmc_management_contract.remove_link("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258dead").run(sender=creator) + + # test case 13: get_links function + link_to_compare = bmc_management_contract.get_links() + added_link = sp.list(['btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b']) + sc.verify_equal(link_to_compare, added_link) + + # test case 14: set_link_rx_height + link = sp.string('btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b') + height = sp.nat(2) + # error when not exist link is given + bmc_management_contract.set_link_rx_height(link="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnA", + height=height).run(sender=creator, valid=False, exception="NotExistsKey") + # error when not invalid height is given + bmc_management_contract.set_link_rx_height(link=link, height=sp.nat(0)).run(sender=creator, valid=False, + exception="InvalidRxHeight") + # should work + bmc_management_contract.set_link_rx_height(link=link, height=height).run(sender=creator) + sc.verify_equal(bmc_management_contract.data.links[link].rx_height, 2) + + # test case 15: set_link function + block_interval = sp.nat(2) + _max_aggregation = sp.nat(3) + delay_limit = sp.nat(2) + # only owner should set link + bmc_management_contract.set_link( + sp.record(_link=link, block_interval=block_interval, _max_aggregation=_max_aggregation, + delay_limit=delay_limit)).run(sender=bob, valid=False, exception="Unauthorized") + # error when link doesnt exist + bmc_management_contract.set_link( + sp.record(_link="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnZ", block_interval=block_interval, + _max_aggregation=_max_aggregation, delay_limit=delay_limit)).run(sender=creator, valid=False, + exception="NotExistsLink") + # error when invalid paramters were given + bmc_management_contract.set_link( + sp.record(_link=link, block_interval=block_interval, _max_aggregation=sp.nat(0), delay_limit=delay_limit)).run( + sender=creator, valid=False, exception="InvalidParam") + bmc_management_contract.set_link( + sp.record(_link=link, block_interval=block_interval, _max_aggregation=_max_aggregation, + delay_limit=sp.nat(0))).run(sender=creator, valid=False, exception="InvalidParam") + # should work + bmc_management_contract.set_link( + sp.record(_link=link, block_interval=block_interval, _max_aggregation=_max_aggregation, + delay_limit=delay_limit)).run(sender=creator) + + # test case 16: add_relay function + # only owner should add relay + bmc_management_contract.add_relay( + sp.record(link=link, addr=sp.set([sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiADD")]))).run(sender=bob, + valid=False, + exception="Unauthorized") + # fail when non-exist link is given + bmc_management_contract.add_relay(sp.record(link="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUNONLINK", + addr=sp.set([sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiADD")]))).run( + sender=creator, valid=False, exception="NotExistsLink") + # should work + bmc_management_contract.add_relay( + sp.record(link=link, addr=sp.set([sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")]))).run(sender=creator) + + # test case 17: remove_relay function + # only owner should remove relay + bmc_management_contract.remove_relay( + sp.record(link=link, addr=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"))).run(sender=bob, valid=False, + exception="Unauthorized") + # fail when non-exist link is given + bmc_management_contract.remove_relay(sp.record(link="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUNONLINK", + addr=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiADD"))).run( + sender=creator, valid=False, exception="NotExistsLink") + # should work + next_link1 = sp.string("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a625link1") + bmc_management_contract.add_link(next_link1).run(sender=creator) + bmc_management_contract.add_relay( + sp.record(link=next_link1, addr=sp.set([sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxADD1")]))).run( + sender=creator) + bmc_management_contract.remove_relay( + sp.record(link=next_link1, addr=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxADD1"))).run(sender=creator) + + # test case 18: get_relays function + compared_to = sp.list([sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")]) + get_relays = bmc_management_contract.get_relays(link) + sc.verify_equal(get_relays, compared_to) + + # test case 19: get_bsh_service_by_name function + get_bsh_service_by_name = bmc_management_contract.get_bsh_service_by_name(svc1) + sc.verify_equal(get_bsh_service_by_name, service1_address.address) + + # test case 20: get_link function + get_link = bmc_management_contract.get_link(link) + data = sp.record( + relays=sp.set([sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")]), + reachable=sp.set([]), + rx_seq=sp.nat(0), + tx_seq=sp.nat(0), + block_interval_src=sp.nat(1000), + block_interval_dst=sp.nat(2), + max_aggregation=sp.nat(3), + delay_limit=sp.nat(2), + relay_idx=sp.nat(0), + rotate_height=sp.nat(0), + rx_height=sp.nat(0), + rx_height_src=sp.nat(0), + is_connected=True + ) + sc.verify_equal(get_link, data) + + # test case 21: get_link_rx_seq function + get_link_rx_seq = bmc_management_contract.get_link_rx_seq(link) + sc.verify_equal(get_link_rx_seq, 0) + + # test case 22: get_link_tx_seq function + get_link_tx_seq = bmc_management_contract.get_link_tx_seq(link) + sc.verify_equal(get_link_tx_seq, 0) + + # test case 23: get_link_rx_height function + get_link_rx_height = bmc_management_contract.get_link_rx_height(link) + sc.verify_equal(get_link_rx_height, 0) + + # test case 24: get_link_relays function + get_link_relays = bmc_management_contract.get_link_relays(link) + sc.verify_equal(get_link_relays, compared_to) + + # test case 25: get_relay_status_by_link function + get_link_relays = bmc_management_contract.get_relay_status_by_link(link) + sc.verify_equal(get_link_relays, sp.map( + {0: sp.record(addr=sp.address('tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9'), block_count=0, msg_count=0)})) + + # test case 26: update_link_rx_seq function + # only bmc periphery address can run other users should get error + bmc_management_contract.update_link_rx_seq(sp.record(prev=next_link1, val=sp.nat(3))).run(sender=creator, + valid=False, + exception="Unauthorized") + # working + bmc_management_contract.update_link_rx_seq(sp.record(prev=next_link1, val=sp.nat(3))).run( + sender=bmc_periphery_address) + # Check that the value of rx_seq is updated correctly + sc.verify_equal(bmc_management_contract.data.links[next_link1].rx_seq, 3) + + # test case 27: update_link_tx_seq function + # only bmc periphery address can run other users should get error + bmc_management_contract.update_link_tx_seq(sp.record(prev=next_link1, serialized_msg=sp.bytes("0x64"))).run( + sender=creator, valid=False, exception="Unauthorized") + # working + bmc_management_contract.update_link_tx_seq(sp.record(prev=next_link1, serialized_msg=sp.bytes("0x64"))).run( + sender=bmc_periphery_address) + # Check that the value of tx_seq is updated correctly + sc.verify_equal(bmc_management_contract.data.links[next_link1].tx_seq, 1) + + # test case 28: update_link_rx_height function + # only bmc periphery address can run other users should get error + bmc_management_contract.update_link_rx_height(sp.record(prev=next_link1, val=sp.nat(3))).run(sender=creator, + valid=False, + exception="Unauthorized") + # working + bmc_management_contract.update_link_rx_height(sp.record(prev=next_link1, val=sp.nat(4))).run( + sender=bmc_periphery_address) + # Check that the value of rx_seq is updated correctly + sc.verify_equal(bmc_management_contract.data.links[next_link1].rx_height, 4) + + # test case 29: update_link_reachable function + to = sp.list(["btp://net1/addr1", "btp://net2/addr2"]) + # only bmc periphery address can run other users should get error + bmc_management_contract.update_link_reachable(sp.record(prev=next_link1, to=to)).run(sender=creator, valid=False, + exception="Unauthorized") + # should work + bmc_management_contract.update_link_reachable(sp.record(prev=next_link1, to=to)).run(sender=bmc_periphery_address) + # value checking + sc.verify_equal(bmc_management_contract.data.links[next_link1].reachable, + sp.set(['btp://net1/addr1', 'btp://net2/addr2'])) + + # test case 30: delete_link_reachable function + # only bmc periphery address can run other users should get error + bmc_management_contract.delete_link_reachable(sp.record(prev=next_link1, index=sp.nat(0))).run(sender=creator, + valid=False, + exception="Unauthorized") + # working + bmc_management_contract.delete_link_reachable(sp.record(prev=next_link1, index=sp.nat(0))).run( + sender=bmc_periphery_address) + # value checking + sc.verify_equal(bmc_management_contract.data.links[next_link1].reachable, sp.set(['btp://net2/addr2'])) + + # test case 31: update_relay_stats function + # only bmc periphery address can run other users should get error + bmc_management_contract.update_relay_stats( + sp.record(relay=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiADD"), block_count_val=sp.nat(2), + msg_count_val=sp.nat(2))).run(sender=creator, valid=False, exception="Unauthorized") + # working + bmc_management_contract.update_relay_stats( + sp.record(relay=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), block_count_val=sp.nat(2), + msg_count_val=sp.nat(2))).run(sender=bmc_periphery_address) + # value checking + sc.verify_equal( + bmc_management_contract.data.relay_stats[sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")].block_count, 2) + sc.verify_equal( + bmc_management_contract.data.relay_stats[sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")].msg_count, 2) + + # test case 32: resolve_route function + sc.verify_equal(bmc_management_contract.resolve_route(sp.string('0x7.icon')), + sp.pair('btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b', + 'btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258dest')) + + # test case 33: set_helper_address test + bmc_management_contract.set_helper_address(sp.address("KT1EXYXNGdbh4uvdKc8hh7ETQXCXPzhelper")).run(sender=jack, + valid=False, + exception="Unauthorized") + bmc_management_contract.set_helper_address(sp.address("KT1EXYXNGdbh4uvdKc8hh7ETQXCXPzhelper")).run(sender=creator) + sc.verify(bmc_management_contract.data.helper == sp.address("KT1EXYXNGdbh4uvdKc8hh7ETQXCXPzhelper")) + + # test case 34: set_bmc_periphery test + bmc_management_contract.set_bmc_periphery(sp.address("KT1EXYXNGdbh4uvdKc8hh7ETQXCperiphery")).run(sender=jack, + valid=False, + exception="Unauthorized") + bmc_management_contract.set_bmc_periphery(sp.address("KT1EXYXNGdbh4uvdKc8hh7ETQXCperiphery")).run(sender=creator) + sc.verify(bmc_management_contract.data.bmc_periphery == sp.some(sp.address("KT1EXYXNGdbh4uvdKc8hh7ETQXCperiphery"))) + + +def deploy_bmc_management_contract(owner, helper): + bmc_management_contract = BMCManagement.BMCManagement(owner, helper) + return bmc_management_contract + + +def deploy_helper_contract(): + helper_contract = BMCHelper.Helper() + return helper_contract + + +def deploy_parse_address(): + parse_address = ParseAddress.ParseAddress() + return parse_address diff --git a/smartpy/bmc/contracts/tests/bmc_periphery_test.py b/smartpy/bmc/contracts/tests/bmc_periphery_test.py new file mode 100644 index 00000000..10aa7a53 --- /dev/null +++ b/smartpy/bmc/contracts/tests/bmc_periphery_test.py @@ -0,0 +1,74 @@ +import smartpy as sp + +BMCManagement = sp.io.import_script_from_url("file:./contracts/src/bmc_management.py") +BMCPeriphery = sp.io.import_script_from_url("file:./contracts/src/bmc_periphery.py") +BMCHelper = sp.io.import_script_from_url("file:./contracts/src/helper.py") +ParseAddress = sp.io.import_script_from_url("file:../bts/contracts/src/parse_address.py") + + +@sp.add_test("BMCManagementTest") +def test(): + sc = sp.test_scenario() + + # test account + alice = sp.test_account("Alice") + jack = sp.test_account("Jack") + bob = sp.test_account("Bob") + helper2 = sp.test_account("Helper2") + owner = sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9") + + helper_contract = deploy_helper_contract() + sc += helper_contract + + # deploy BMCManagement contract + bmc_management_contract = deploy_bmc_management_contract(sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), helper_contract.address) + sc += bmc_management_contract + + parse_address = deploy_parse_address() + sc += parse_address + + bmc_periphery_contract = deploy_bmc_periphery_contract(bmc_management_contract.address, helper_contract.address, helper2.address, parse_address.address, owner) + sc += bmc_periphery_contract + + # set_bmc_btp_address + bmc_periphery_contract.set_bmc_btp_address("tezos.77").run(sender=alice, valid=False, exception="Unauthorized") + bmc_periphery_contract.set_bmc_btp_address("tezos.77").run(sender=bmc_management_contract.address) + sc.verify(bmc_periphery_contract.data.bmc_btp_address == sp.some(sp.string("btp://tezos.77/KT1Tezooo3zzSmartPyzzSTATiCzzzseJjWC"))) + + # get_bmc_btp_address + sc.verify_equal(bmc_periphery_contract.get_bmc_btp_address(), sp.string("btp://tezos.77/KT1Tezooo3zzSmartPyzzSTATiCzzzseJjWC")) + + # set_helper_address + bmc_periphery_contract.set_helper_address(sp.address("KT1EXYXNGdbh4uvdKc8hh7ETQXCXPzhelper")).run(sender=jack, valid=False, exception="Unauthorized") + bmc_periphery_contract.set_helper_address(sp.address("KT1EXYXNGdbh4uvdKc8hh7ETQXCXPzhelper")).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + sc.verify(bmc_periphery_contract.data.helper == sp.address("KT1EXYXNGdbh4uvdKc8hh7ETQXCXPzhelper")) + + # set_parse_address + bmc_periphery_contract.set_parse_address(sp.address("KT1EXYXNGdbh4uvdKc8hh7ETQXCXPzhparse")).run(sender=jack, valid=False, exception="Unauthorized") + bmc_periphery_contract.set_parse_address(sp.address("KT1EXYXNGdbh4uvdKc8hh7ETQXCXPzhparse")).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + sc.verify(bmc_periphery_contract.data.parse_contract == sp.address("KT1EXYXNGdbh4uvdKc8hh7ETQXCXPzhparse")) + + # set_bmc_management_addr + bmc_periphery_contract.set_bmc_management_addr(sp.address("KT1EXYXNGdbh4uvdKc8hh7ETQXmanagement")).run(sender=jack, valid=False, exception="Unauthorized") + bmc_periphery_contract.set_bmc_management_addr(sp.address("KT1EXYXNGdbh4uvdKc8hh7ETQXmanagement")).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + sc.verify(bmc_periphery_contract.data.bmc_management == sp.address("KT1EXYXNGdbh4uvdKc8hh7ETQXmanagement")) + + +def deploy_bmc_management_contract(owner, helper): + bmc_management_contract = BMCManagement.BMCManagement(owner, helper) + return bmc_management_contract + + +def deploy_bmc_periphery_contract(bmc_address, helper,helper2, parse, owner): + bmc_periphery_contract = BMCPeriphery.BMCPreiphery(bmc_address, helper, helper2, parse, owner) + return bmc_periphery_contract + + +def deploy_helper_contract(): + helper_contract = BMCHelper.Helper() + return helper_contract + + +def deploy_parse_address(): + parse_address = ParseAddress.ParseAddress() + return parse_address diff --git a/smartpy/bmc/contracts/tests/integration_test.py b/smartpy/bmc/contracts/tests/integration_test.py new file mode 100644 index 00000000..a928adaf --- /dev/null +++ b/smartpy/bmc/contracts/tests/integration_test.py @@ -0,0 +1,224 @@ +import smartpy as sp + +BMCManagement = sp.io.import_script_from_url("file:./contracts/src/bmc_management.py") +BMCPeriphery = sp.io.import_script_from_url("file:./contracts/src/bmc_periphery.py") +BMCHelper = sp.io.import_script_from_url("file:../bts/contracts/src/helper.py") +ParseAddress = sp.io.import_script_from_url("file:../bts/contracts/src/parse_address.py") + +BTSCore = sp.io.import_script_from_url("file:../bts/contracts/src/bts_core.py") +BTSOwnerManager = sp.io.import_script_from_url("file:../bts/contracts/src/bts_owner_manager.py") +BTSPeriphery = sp.io.import_script_from_url("file:../bts/contracts/src/bts_periphery.py") + + +@sp.add_test("BMCManagementTest") +def test(): + sc = sp.test_scenario() + + # test account + alice = sp.test_account("Alice") + creator = sp.test_account("Creator") + jack = sp.test_account("Jack") + bob = sp.test_account("Bob") + creator2 = sp.test_account("creator2") + service1_address = sp.test_account("service1_address") + service2_address = sp.test_account("service2_address") + + # deploy BMCManagement contract + helper_contract = deploy_helper_contract() + sc += helper_contract + + bmc_management_contract = deploy_bmc_management_contract(sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), + helper_contract.address) + sc += bmc_management_contract + + parse_address = deploy_parse_address() + sc += parse_address + + bmc_periphery_contract = deploy_bmc_periphery_contract(bmc_management_contract.address, helper_contract.address, + parse_address.address) + sc += bmc_periphery_contract + + bts_owner_manager = deploy_bts_owner_manager_contract() + sc += bts_owner_manager + bts_core_contract = deploy_bts_core_contract(bts_owner_manager.address) + sc += bts_core_contract + + bts_periphery = deploy_bts_periphery_contract(bts_core_contract.address, helper_contract.address, + parse_address.address, bmc_periphery_contract.address) + sc += bts_periphery + + # set bmc periphery + bmc_management_contract.set_bmc_periphery(bmc_periphery_contract.address).run( + sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + # set bmc_btp_address(netwrk address) + bmc_management_contract.set_bmc_btp_address("NetXnHfVqm9iesp.tezos").run( + sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + # update_bts_periphery + bts_core_contract.update_bts_periphery(bts_periphery.address).run( + sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + + # add_service + svc1 = sp.string("bts") + bmc_management_contract.add_service(sp.record(addr=bts_periphery.address, svc=svc1)).run( + sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + + # add_route + dst = "btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258dest" + next_link = "btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b" + bmc_management_contract.add_route(sp.record(dst=dst, link=next_link)).run( + sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + + # # add_link + # bmc_management_contract.add_link("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b").run( + # sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + + # # add_relay + # bmc_management_contract.add_relay(sp.record(link="btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b", + # addr=sp.set([sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")]))).run( + # sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + + # test 1: Test of add to blacklist function + bts_periphery.add_to_blacklist({0: "notaaddress"}).run(sender=bts_periphery.address, valid=False, + exception="InvalidAddress") + bts_periphery.add_to_blacklist({0: "tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"}).run(sender=bts_periphery.address, + valid=True) + bts_periphery.add_to_blacklist({0: "tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"}).run(sender=bts_periphery.address, + valid=True) + bts_periphery.add_to_blacklist({0: "tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"}).run(sender=alice.address, valid=False, + exception="Unauthorized") + bts_periphery.add_to_blacklist({0: 'tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg'}).run(sender=bts_periphery.address, + valid=False, + exception='InvalidAddress') + sc.verify(bts_periphery.data.blacklist[ + sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW")] == True) + + # # transfer_native_coin + # bts_periphery.set_token_limit( + # sp.record( + # coin_names=sp.map({0: "btp-NetXnHfVqm9iesp.tezos-XTZ"}), + # token_limit=sp.map({0: 115792089237316195423570985008687907853269984665640564039457584007913129639935}) + # ) + # ).run(sender = bts_core_contract.address) + # bts_core_contract.transfer_native_coin("btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d").run(sender= sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), amount=sp.tez(30), valid=False, exception="FailCheckTransfer") + # bts_core_contract.transfer_native_coin("btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d").run( + # sender=sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), amount=sp.tez(30)) + + # # handle_relay_message + # msg = sp.bytes( + # "0xf8e1f8dfb8ddf8db01b8d3f8d1f8cfb8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b54314657446a4338435941777268424a6d43355554596d594a544a6457776f3447676203b88af888b8396274703a2f2f3078372e69636f6e2f637833643436306163643535356336373034303566396562323934333833356366643132326662323938b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b54314657446a4338435941777268424a6d43355554596d594a544a6457776f344767628362747381ff84c328f8008400886513") + # prev = sp.string("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b") + # bmc_periphery_contract.handle_relay_message(sp.record(prev=prev, msg=msg)).run( + # sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + + # test 2 : Test of remove from blacklist function + bts_periphery.remove_from_blacklist({0: 'notaaddress'}).run(sender=bts_periphery.address, valid=False, + exception="InvalidAddress") # invalid address + bts_periphery.remove_from_blacklist({0: 'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=bts_periphery.address, + valid=False, + exception="UserNotFound") # address not black-listed + bts_periphery.add_to_blacklist({0: 'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run( + sender=bts_periphery.address) # adding to blacklist + bts_periphery.remove_from_blacklist({0: 'tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run( + sender=bts_periphery.address) # valid process + bts_periphery.remove_from_blacklist({0: 'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=bts_periphery.address, + valid=False, + exception='UserNotFound') # cannot remove from blacklist twice + bts_periphery.add_to_blacklist({0: 'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run( + sender=bts_periphery.address) # adding to blacklist + bts_periphery.remove_from_blacklist({0: 'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run( + sender=bts_periphery.address) # can only be called from btseperiphery contract + bts_periphery.remove_from_blacklist({0: 'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=alice.address, + valid=False, + exception="Unauthorized") # can only be called from btseperiphery contract + + # # transfer_native_coin + # bts_periphery.set_token_limit( + # sp.record( + # coin_names=sp.map({0: "btp-NetXnHfVqm9iesp.tezos-XTZ"}), + # token_limit=sp.map({0: 115792089237316195423570985008687907853269984665640564039457584007913129639935}) + # ) + # ).run(sender = bts_core_contract.address) + # bts_core_contract.transfer_native_coin("btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d").run(sender= sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), amount=sp.tez(30)) + + # # transfer_native_coin + # bts_periphery.set_token_limit( + # sp.record( + # coin_names=sp.map({0: "btp-NetXnHfVqm9iesp.tezos-XTZ"}), + # token_limit=sp.map({0: 5}) + # ) + # ).run(sender = bts_core_contract.address) + # bts_core_contract.transfer_native_coin("btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d").run(sender= sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), amount=sp.tez(30), valid=False, exception="FailCheckTransfer") + + # # bmc_periphery get_status + # sc.verify_equal(bmc_periphery_contract.get_status("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b"), sp.record(current_height = 0, rx_height = 2, rx_seq = 0, tx_seq = 6)) + + # test 3 : set token limit + bts_periphery.set_token_limit( + sp.record(coin_names={0: "Tok2", 1: 'BB'}, token_limit={0: sp.nat(5), 1: sp.nat(2)})).run(sender=alice.address, + valid=False, + exception='Unauthorized') # can only be called from btsperiphery contract + bts_periphery.set_token_limit( + sp.record(coin_names={0: "Tok2", 1: 'BB'}, token_limit={0: sp.nat(5), 1: sp.nat(2)})).run( + sender=bts_periphery.address) # set token limit for Tok2 coin to 5 and BB coin to 2 + sc.verify(bts_periphery.data.token_limit["Tok2"] == sp.nat(5)) # test of token_limit for tok2 token + bts_periphery.set_token_limit(sp.record(coin_names={0: "Tok2", 1: 'BB'}, token_limit={0: sp.nat(5)})).run( + valid=False, exception='InvalidParams', sender=bts_periphery.address) # invalid parameters + # cannot set more than 15 token limit at once + bts_periphery.set_token_limit( + sp.record(coin_names={0: "Tok2", 1: 'BB'}, token_limit={0: sp.nat(15), 1: sp.nat(22)})).run( + sender=bts_periphery.address) # can modify already set data + sc.verify(bts_periphery.data.token_limit["BB"] == sp.nat(22)) # test of token_limit for tok2 token + + # # handle_relay_message + # msg=sp.bytes("0xf90157f90154b90151f9014e01b90145f90142f9013fb8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5431454e5a76546f507838374c68756f774a315669786a6a715168536e597263594c6907b8faf8f8b8396274703a2f2f3078372e69636f6e2f637864633238393434343037363539393733666539393438376437356335646433326337396265303533b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5431454e5a76546f507838374c68756f774a315669786a6a715168536e597263594c698362747303b874f87200b86ff86daa687839643138316431336634376335616165353535623730393831346336623232393738373937363139a4747a3165703766664b7351434e64676e6b504443566e566b67626d465a50386d464e3147dcdb906274702d3078372e69636f6e2d4943588900d71b0fe0a28e000084008502ba") + # prev=sp.string("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b") + # bmc_periphery_contract.handle_relay_message(sp.record(prev=prev, msg=msg)).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + + # set_fee_ratio + bts_core_contract.set_fee_ratio(name=sp.string("btp-NetXnHfVqm9iesp.tezos-XTZ"), fee_numerator=sp.nat(100), + fixed_fee=sp.nat(450)).run( + sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + + +def deploy_bmc_management_contract(owner, helper): + bmc_management_contract = BMCManagement.BMCManagement(owner, helper) + return bmc_management_contract + + +def deploy_bmc_periphery_contract(bmc_addres, helper, parse): + owner = sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9") + bmc_periphery_contract = BMCPeriphery.BMCPreiphery(bmc_addres, helper, parse, owner) + return bmc_periphery_contract + + +def deploy_helper_contract(): + helper_contract = BMCHelper.Helper() + return helper_contract + + +def deploy_parse_address(): + parse_address = ParseAddress.ParseAddress() + return parse_address + + +def deploy_bts_core_contract(bts_owner_manager_contract): + bts_core_contract = BTSCore.BTSCore( + owner_manager=bts_owner_manager_contract, + _native_coin_name="btp-NetXnHfVqm9iesp.tezos-XTZ", + _fee_numerator=sp.nat(100), + _fixed_fee=sp.nat(450) + ) + return bts_core_contract + + +def deploy_bts_owner_manager_contract(): + bts_owner_manager_contract = BTSOwnerManager.BTSOwnerManager(sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + return bts_owner_manager_contract + + +def deploy_bts_periphery_contract(core_address, helper, parse, bmc): + bts_periphery_contract = BTSPeriphery.BTPPreiphery(bmc_address=bmc, bts_core_address=core_address, + helper_contract=helper, parse_address=parse, + owner_address=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), + native_coin_name="btp-NetXnHfVqm9iesp.tezos-XTZ") + return bts_periphery_contract diff --git a/smartpy/bmc/package-lock.json b/smartpy/bmc/package-lock.json new file mode 100644 index 00000000..13756c6c --- /dev/null +++ b/smartpy/bmc/package-lock.json @@ -0,0 +1,1429 @@ +{ + "name": "create-tezos-app", + "version": "1.0.3", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "create-tezos-app", + "version": "1.0.3", + "license": "MIT", + "dependencies": { + "@taquito/signer": "^14.0.0", + "@taquito/taquito": "^14.0.0", + "dotenv": "^16.0.3", + "ts-node": "^10.9.1" + }, + "bin": { + "create-tezos-app": "bin/cli.js" + }, + "devDependencies": { + "typescript": "^4.8.4" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@stablelib/binary": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/binary/-/binary-1.0.1.tgz", + "integrity": "sha512-ClJWvmL6UBM/wjkvv/7m5VP3GMr9t0osr4yVgLZsLCOz4hGN9gIAFEqnJ0TsSMAN+n840nf2cHZnA5/KFqHC7Q==", + "dependencies": { + "@stablelib/int": "^1.0.1" + } + }, + "node_modules/@stablelib/blake2b": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/blake2b/-/blake2b-1.0.1.tgz", + "integrity": "sha512-B3KyKoBAjkIFeH7romcF96i+pVFYk7K2SBQ1pZvaxV+epSBXJ+n0C66esUhyz6FF+5FbdQVm77C5fzGFcEZpKA==", + "dependencies": { + "@stablelib/binary": "^1.0.1", + "@stablelib/hash": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@stablelib/bytes": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/bytes/-/bytes-1.0.1.tgz", + "integrity": "sha512-Kre4Y4kdwuqL8BR2E9hV/R5sOrUj6NanZaZis0V6lX5yzqC3hBuVSDXUIBqQv/sCpmuWRiHLwqiT1pqqjuBXoQ==" + }, + "node_modules/@stablelib/constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/constant-time/-/constant-time-1.0.1.tgz", + "integrity": "sha512-tNOs3uD0vSJcK6z1fvef4Y+buN7DXhzHDPqRLSXUel1UfqMB1PWNsnnAezrKfEwTLpN0cGH2p9NNjs6IqeD0eg==" + }, + "node_modules/@stablelib/ed25519": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@stablelib/ed25519/-/ed25519-1.0.3.tgz", + "integrity": "sha512-puIMWaX9QlRsbhxfDc5i+mNPMY+0TmQEskunY1rZEBPi1acBCVQAhnsk/1Hk50DGPtVsZtAWQg4NHGlVaO9Hqg==", + "dependencies": { + "@stablelib/random": "^1.0.2", + "@stablelib/sha512": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@stablelib/hash": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/hash/-/hash-1.0.1.tgz", + "integrity": "sha512-eTPJc/stDkdtOcrNMZ6mcMK1e6yBbqRBaNW55XA1jU8w/7QdnCF0CmMmOD1m7VSkBR44PWrMHU2l6r8YEQHMgg==" + }, + "node_modules/@stablelib/int": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/int/-/int-1.0.1.tgz", + "integrity": "sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w==" + }, + "node_modules/@stablelib/keyagreement": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/keyagreement/-/keyagreement-1.0.1.tgz", + "integrity": "sha512-VKL6xBwgJnI6l1jKrBAfn265cspaWBPAPEc62VBQrWHLqVgNRE09gQ/AnOEyKUWrrqfD+xSQ3u42gJjLDdMDQg==", + "dependencies": { + "@stablelib/bytes": "^1.0.1" + } + }, + "node_modules/@stablelib/nacl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@stablelib/nacl/-/nacl-1.0.4.tgz", + "integrity": "sha512-PJ2U/MrkXSKUM8C4qFs87WeCNxri7KQwR8Cdwm9q2sweGuAtTvOJGuW0F3N+zn+ySLPJA98SYWSSpogMJ1gCmw==", + "dependencies": { + "@stablelib/poly1305": "^1.0.1", + "@stablelib/random": "^1.0.2", + "@stablelib/wipe": "^1.0.1", + "@stablelib/x25519": "^1.0.3", + "@stablelib/xsalsa20": "^1.0.2" + } + }, + "node_modules/@stablelib/poly1305": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/poly1305/-/poly1305-1.0.1.tgz", + "integrity": "sha512-1HlG3oTSuQDOhSnLwJRKeTRSAdFNVB/1djy2ZbS35rBSJ/PFqx9cf9qatinWghC2UbfOYD8AcrtbUQl8WoxabA==", + "dependencies": { + "@stablelib/constant-time": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@stablelib/random": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@stablelib/random/-/random-1.0.2.tgz", + "integrity": "sha512-rIsE83Xpb7clHPVRlBj8qNe5L8ISQOzjghYQm/dZ7VaM2KHYwMW5adjQjrzTZCchFnNCNhkwtnOBa9HTMJCI8w==", + "dependencies": { + "@stablelib/binary": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@stablelib/salsa20": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@stablelib/salsa20/-/salsa20-1.0.2.tgz", + "integrity": "sha512-nfjKzw0KTKrrKBasEP+j7UP4I8Xudom8lVZIBCp0kQNARXq72IlSic0oabg2FC1NU68L4RdHrNJDd8bFwrphYA==", + "dependencies": { + "@stablelib/binary": "^1.0.1", + "@stablelib/constant-time": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@stablelib/sha512": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/sha512/-/sha512-1.0.1.tgz", + "integrity": "sha512-13gl/iawHV9zvDKciLo1fQ8Bgn2Pvf7OV6amaRVKiq3pjQ3UmEpXxWiAfV8tYjUpeZroBxtyrwtdooQT/i3hzw==", + "dependencies": { + "@stablelib/binary": "^1.0.1", + "@stablelib/hash": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@stablelib/wipe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/wipe/-/wipe-1.0.1.tgz", + "integrity": "sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg==" + }, + "node_modules/@stablelib/x25519": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@stablelib/x25519/-/x25519-1.0.3.tgz", + "integrity": "sha512-KnTbKmUhPhHavzobclVJQG5kuivH+qDLpe84iRqX3CLrKp881cF160JvXJ+hjn1aMyCwYOKeIZefIH/P5cJoRw==", + "dependencies": { + "@stablelib/keyagreement": "^1.0.1", + "@stablelib/random": "^1.0.2", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@stablelib/xsalsa20": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@stablelib/xsalsa20/-/xsalsa20-1.0.2.tgz", + "integrity": "sha512-7XdBGbcNgBShmuhDXv1G1WPVCkjZdkb1oPMzSidO7Fve0MHntH6TjFkj5bfLI+aRE+61weO076vYpP/jmaAYog==", + "dependencies": { + "@stablelib/binary": "^1.0.1", + "@stablelib/salsa20": "^1.0.2", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@taquito/http-utils": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/http-utils/-/http-utils-14.0.0.tgz", + "integrity": "sha512-ZWZzod/+/OEE26b9CnDRjHGfUKBJft3aXv/e/A9bTHAtvRNJqGIhofHcDg/jTaolBMarCF2b3XBYw35aOOSk4A==", + "dependencies": { + "axios": "^0.26.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@taquito/local-forging": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/local-forging/-/local-forging-14.0.0.tgz", + "integrity": "sha512-Nm0xGmS1Jzd+tU0a/8Y8XuTghbiPBgHDLo+e4141TK3OAwTzOw0an+w3xK9QVfzvxfIcZBSMjeMZzOwDdiqkJQ==", + "dependencies": { + "@taquito/utils": "^14.0.0", + "bignumber.js": "^9.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@taquito/michel-codec": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/michel-codec/-/michel-codec-14.0.0.tgz", + "integrity": "sha512-ftnBvUVddlHBqvQbGPHEb26KrS4lIcaZ1eIpYJWiz+akb4Pcfyq7j/OEsDZbB7Pl2FP9hqu7ZygOF34zY6Lrtw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@taquito/michelson-encoder": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/michelson-encoder/-/michelson-encoder-14.0.0.tgz", + "integrity": "sha512-KIS+xl4rKfnd6hf9LUr6W+Pb7gv8F/Qsx0fho9CtM2PodKvdef3YlvkpScBUM9QZntAlvq2XQXUVXcZkbvxygw==", + "dependencies": { + "@taquito/rpc": "^14.0.0", + "@taquito/utils": "^14.0.0", + "bignumber.js": "^9.0.2", + "fast-json-stable-stringify": "^2.1.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@taquito/rpc": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/rpc/-/rpc-14.0.0.tgz", + "integrity": "sha512-FMfb80sA+VJwNx8OTNN07boDAt2roISqLLCUgmOIwy/cFDqhII7gdS4aYWJWqlKbdPKCPqh3a3ZQD1X/jyQHOA==", + "dependencies": { + "@taquito/http-utils": "^14.0.0", + "@taquito/utils": "^14.0.0", + "bignumber.js": "^9.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@taquito/signer": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/signer/-/signer-14.0.0.tgz", + "integrity": "sha512-vDqp/quzAsOiVikUt5MYUKhHI3S9qlasazyXs99xK9qpGLotbx6aseKcfb/dkaTo4/eoMzP4XzTVdnk0AqcCkw==", + "dependencies": { + "@stablelib/blake2b": "^1.0.1", + "@stablelib/ed25519": "^1.0.2", + "@stablelib/nacl": "^1.0.3", + "@taquito/taquito": "^14.0.0", + "@taquito/utils": "^14.0.0", + "elliptic": "^6.5.4", + "pbkdf2": "^3.1.2", + "typedarray-to-buffer": "^4.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@taquito/taquito": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/taquito/-/taquito-14.0.0.tgz", + "integrity": "sha512-JaXfvqOCF3dkwXxhe00Ravb8WLMC2VqJxerf4GrGUEpJw+NAkwbGEb8k/52+MQQdlxMPepZdPPru/HM3nFG0Tw==", + "hasInstallScript": true, + "dependencies": { + "@taquito/http-utils": "^14.0.0", + "@taquito/local-forging": "^14.0.0", + "@taquito/michel-codec": "^14.0.0", + "@taquito/michelson-encoder": "^14.0.0", + "@taquito/rpc": "^14.0.0", + "@taquito/utils": "^14.0.0", + "bignumber.js": "^9.0.2", + "rxjs": "^6.6.3" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@taquito/utils": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/utils/-/utils-14.0.0.tgz", + "integrity": "sha512-0RSHn/CzbcbMdldJJIlXyxOvAajwmL6iPKJ6NaRyYJqqLM2CxYjG72KpXVv716pCMV1MbIWsOAr9FKbxW73PsA==", + "dependencies": { + "@stablelib/blake2b": "^1.0.1", + "@stablelib/ed25519": "^1.0.2", + "@types/bs58check": "^2.1.0", + "bignumber.js": "^9.0.2", + "blakejs": "^1.2.1", + "bs58check": "^2.1.2", + "buffer": "^6.0.3", + "elliptic": "^6.5.4", + "typedarray-to-buffer": "^4.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==" + }, + "node_modules/@types/bs58check": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/bs58check/-/bs58check-2.1.0.tgz", + "integrity": "sha512-OxsysnJQh82vy9DRbOcw9m2j/WiyqZLn0YBhKxdQ+aCwoHj+tWzyCgpwAkr79IfDXZKxc6h7k89T9pwS78CqTQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "18.11.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", + "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==" + }, + "node_modules/acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "node_modules/axios": { + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "dependencies": { + "follow-redirects": "^1.14.8" + } + }, + "node_modules/base-x": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", + "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bignumber.js": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.0.tgz", + "integrity": "sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==", + "engines": { + "node": "*" + } + }, + "node_modules/blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==" + }, + "node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + }, + "node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "dependencies": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/typedarray-to-buffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-4.0.0.tgz", + "integrity": "sha512-6dOYeZfS3O9RtRD1caom0sMxgK59b27+IwoNy8RDPsmslSGOyU+mpTamlaIW7aNKi90ZQZ9DFaZL3YRoiSCULQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/typescript": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "engines": { + "node": ">=6" + } + } + }, + "dependencies": { + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "requires": { + "@jridgewell/trace-mapping": "0.3.9" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + }, + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@stablelib/binary": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/binary/-/binary-1.0.1.tgz", + "integrity": "sha512-ClJWvmL6UBM/wjkvv/7m5VP3GMr9t0osr4yVgLZsLCOz4hGN9gIAFEqnJ0TsSMAN+n840nf2cHZnA5/KFqHC7Q==", + "requires": { + "@stablelib/int": "^1.0.1" + } + }, + "@stablelib/blake2b": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/blake2b/-/blake2b-1.0.1.tgz", + "integrity": "sha512-B3KyKoBAjkIFeH7romcF96i+pVFYk7K2SBQ1pZvaxV+epSBXJ+n0C66esUhyz6FF+5FbdQVm77C5fzGFcEZpKA==", + "requires": { + "@stablelib/binary": "^1.0.1", + "@stablelib/hash": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "@stablelib/bytes": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/bytes/-/bytes-1.0.1.tgz", + "integrity": "sha512-Kre4Y4kdwuqL8BR2E9hV/R5sOrUj6NanZaZis0V6lX5yzqC3hBuVSDXUIBqQv/sCpmuWRiHLwqiT1pqqjuBXoQ==" + }, + "@stablelib/constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/constant-time/-/constant-time-1.0.1.tgz", + "integrity": "sha512-tNOs3uD0vSJcK6z1fvef4Y+buN7DXhzHDPqRLSXUel1UfqMB1PWNsnnAezrKfEwTLpN0cGH2p9NNjs6IqeD0eg==" + }, + "@stablelib/ed25519": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@stablelib/ed25519/-/ed25519-1.0.3.tgz", + "integrity": "sha512-puIMWaX9QlRsbhxfDc5i+mNPMY+0TmQEskunY1rZEBPi1acBCVQAhnsk/1Hk50DGPtVsZtAWQg4NHGlVaO9Hqg==", + "requires": { + "@stablelib/random": "^1.0.2", + "@stablelib/sha512": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "@stablelib/hash": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/hash/-/hash-1.0.1.tgz", + "integrity": "sha512-eTPJc/stDkdtOcrNMZ6mcMK1e6yBbqRBaNW55XA1jU8w/7QdnCF0CmMmOD1m7VSkBR44PWrMHU2l6r8YEQHMgg==" + }, + "@stablelib/int": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/int/-/int-1.0.1.tgz", + "integrity": "sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w==" + }, + "@stablelib/keyagreement": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/keyagreement/-/keyagreement-1.0.1.tgz", + "integrity": "sha512-VKL6xBwgJnI6l1jKrBAfn265cspaWBPAPEc62VBQrWHLqVgNRE09gQ/AnOEyKUWrrqfD+xSQ3u42gJjLDdMDQg==", + "requires": { + "@stablelib/bytes": "^1.0.1" + } + }, + "@stablelib/nacl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@stablelib/nacl/-/nacl-1.0.4.tgz", + "integrity": "sha512-PJ2U/MrkXSKUM8C4qFs87WeCNxri7KQwR8Cdwm9q2sweGuAtTvOJGuW0F3N+zn+ySLPJA98SYWSSpogMJ1gCmw==", + "requires": { + "@stablelib/poly1305": "^1.0.1", + "@stablelib/random": "^1.0.2", + "@stablelib/wipe": "^1.0.1", + "@stablelib/x25519": "^1.0.3", + "@stablelib/xsalsa20": "^1.0.2" + } + }, + "@stablelib/poly1305": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/poly1305/-/poly1305-1.0.1.tgz", + "integrity": "sha512-1HlG3oTSuQDOhSnLwJRKeTRSAdFNVB/1djy2ZbS35rBSJ/PFqx9cf9qatinWghC2UbfOYD8AcrtbUQl8WoxabA==", + "requires": { + "@stablelib/constant-time": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "@stablelib/random": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@stablelib/random/-/random-1.0.2.tgz", + "integrity": "sha512-rIsE83Xpb7clHPVRlBj8qNe5L8ISQOzjghYQm/dZ7VaM2KHYwMW5adjQjrzTZCchFnNCNhkwtnOBa9HTMJCI8w==", + "requires": { + "@stablelib/binary": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "@stablelib/salsa20": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@stablelib/salsa20/-/salsa20-1.0.2.tgz", + "integrity": "sha512-nfjKzw0KTKrrKBasEP+j7UP4I8Xudom8lVZIBCp0kQNARXq72IlSic0oabg2FC1NU68L4RdHrNJDd8bFwrphYA==", + "requires": { + "@stablelib/binary": "^1.0.1", + "@stablelib/constant-time": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "@stablelib/sha512": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/sha512/-/sha512-1.0.1.tgz", + "integrity": "sha512-13gl/iawHV9zvDKciLo1fQ8Bgn2Pvf7OV6amaRVKiq3pjQ3UmEpXxWiAfV8tYjUpeZroBxtyrwtdooQT/i3hzw==", + "requires": { + "@stablelib/binary": "^1.0.1", + "@stablelib/hash": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "@stablelib/wipe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/wipe/-/wipe-1.0.1.tgz", + "integrity": "sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg==" + }, + "@stablelib/x25519": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@stablelib/x25519/-/x25519-1.0.3.tgz", + "integrity": "sha512-KnTbKmUhPhHavzobclVJQG5kuivH+qDLpe84iRqX3CLrKp881cF160JvXJ+hjn1aMyCwYOKeIZefIH/P5cJoRw==", + "requires": { + "@stablelib/keyagreement": "^1.0.1", + "@stablelib/random": "^1.0.2", + "@stablelib/wipe": "^1.0.1" + } + }, + "@stablelib/xsalsa20": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@stablelib/xsalsa20/-/xsalsa20-1.0.2.tgz", + "integrity": "sha512-7XdBGbcNgBShmuhDXv1G1WPVCkjZdkb1oPMzSidO7Fve0MHntH6TjFkj5bfLI+aRE+61weO076vYpP/jmaAYog==", + "requires": { + "@stablelib/binary": "^1.0.1", + "@stablelib/salsa20": "^1.0.2", + "@stablelib/wipe": "^1.0.1" + } + }, + "@taquito/http-utils": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/http-utils/-/http-utils-14.0.0.tgz", + "integrity": "sha512-ZWZzod/+/OEE26b9CnDRjHGfUKBJft3aXv/e/A9bTHAtvRNJqGIhofHcDg/jTaolBMarCF2b3XBYw35aOOSk4A==", + "requires": { + "axios": "^0.26.0" + } + }, + "@taquito/local-forging": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/local-forging/-/local-forging-14.0.0.tgz", + "integrity": "sha512-Nm0xGmS1Jzd+tU0a/8Y8XuTghbiPBgHDLo+e4141TK3OAwTzOw0an+w3xK9QVfzvxfIcZBSMjeMZzOwDdiqkJQ==", + "requires": { + "@taquito/utils": "^14.0.0", + "bignumber.js": "^9.0.2" + } + }, + "@taquito/michel-codec": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/michel-codec/-/michel-codec-14.0.0.tgz", + "integrity": "sha512-ftnBvUVddlHBqvQbGPHEb26KrS4lIcaZ1eIpYJWiz+akb4Pcfyq7j/OEsDZbB7Pl2FP9hqu7ZygOF34zY6Lrtw==" + }, + "@taquito/michelson-encoder": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/michelson-encoder/-/michelson-encoder-14.0.0.tgz", + "integrity": "sha512-KIS+xl4rKfnd6hf9LUr6W+Pb7gv8F/Qsx0fho9CtM2PodKvdef3YlvkpScBUM9QZntAlvq2XQXUVXcZkbvxygw==", + "requires": { + "@taquito/rpc": "^14.0.0", + "@taquito/utils": "^14.0.0", + "bignumber.js": "^9.0.2", + "fast-json-stable-stringify": "^2.1.0" + } + }, + "@taquito/rpc": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/rpc/-/rpc-14.0.0.tgz", + "integrity": "sha512-FMfb80sA+VJwNx8OTNN07boDAt2roISqLLCUgmOIwy/cFDqhII7gdS4aYWJWqlKbdPKCPqh3a3ZQD1X/jyQHOA==", + "requires": { + "@taquito/http-utils": "^14.0.0", + "@taquito/utils": "^14.0.0", + "bignumber.js": "^9.0.2" + } + }, + "@taquito/signer": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/signer/-/signer-14.0.0.tgz", + "integrity": "sha512-vDqp/quzAsOiVikUt5MYUKhHI3S9qlasazyXs99xK9qpGLotbx6aseKcfb/dkaTo4/eoMzP4XzTVdnk0AqcCkw==", + "requires": { + "@stablelib/blake2b": "^1.0.1", + "@stablelib/ed25519": "^1.0.2", + "@stablelib/nacl": "^1.0.3", + "@taquito/taquito": "^14.0.0", + "@taquito/utils": "^14.0.0", + "elliptic": "^6.5.4", + "pbkdf2": "^3.1.2", + "typedarray-to-buffer": "^4.0.0" + } + }, + "@taquito/taquito": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/taquito/-/taquito-14.0.0.tgz", + "integrity": "sha512-JaXfvqOCF3dkwXxhe00Ravb8WLMC2VqJxerf4GrGUEpJw+NAkwbGEb8k/52+MQQdlxMPepZdPPru/HM3nFG0Tw==", + "requires": { + "@taquito/http-utils": "^14.0.0", + "@taquito/local-forging": "^14.0.0", + "@taquito/michel-codec": "^14.0.0", + "@taquito/michelson-encoder": "^14.0.0", + "@taquito/rpc": "^14.0.0", + "@taquito/utils": "^14.0.0", + "bignumber.js": "^9.0.2", + "rxjs": "^6.6.3" + } + }, + "@taquito/utils": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/utils/-/utils-14.0.0.tgz", + "integrity": "sha512-0RSHn/CzbcbMdldJJIlXyxOvAajwmL6iPKJ6NaRyYJqqLM2CxYjG72KpXVv716pCMV1MbIWsOAr9FKbxW73PsA==", + "requires": { + "@stablelib/blake2b": "^1.0.1", + "@stablelib/ed25519": "^1.0.2", + "@types/bs58check": "^2.1.0", + "bignumber.js": "^9.0.2", + "blakejs": "^1.2.1", + "bs58check": "^2.1.2", + "buffer": "^6.0.3", + "elliptic": "^6.5.4", + "typedarray-to-buffer": "^4.0.0" + } + }, + "@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" + }, + "@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" + }, + "@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" + }, + "@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==" + }, + "@types/bs58check": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/bs58check/-/bs58check-2.1.0.tgz", + "integrity": "sha512-OxsysnJQh82vy9DRbOcw9m2j/WiyqZLn0YBhKxdQ+aCwoHj+tWzyCgpwAkr79IfDXZKxc6h7k89T9pwS78CqTQ==", + "requires": { + "@types/node": "*" + } + }, + "@types/node": { + "version": "18.11.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", + "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==" + }, + "acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==" + }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==" + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "axios": { + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "requires": { + "follow-redirects": "^1.14.8" + } + }, + "base-x": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", + "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "bignumber.js": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.0.tgz", + "integrity": "sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==" + }, + "blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==" + }, + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + }, + "bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "requires": { + "base-x": "^3.0.2" + } + }, + "bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "requires": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" + }, + "dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==" + }, + "elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + }, + "pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "requires": { + "tslib": "^1.9.0" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "requires": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "typedarray-to-buffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-4.0.0.tgz", + "integrity": "sha512-6dOYeZfS3O9RtRD1caom0sMxgK59b27+IwoNy8RDPsmslSGOyU+mpTamlaIW7aNKi90ZQZ9DFaZL3YRoiSCULQ==" + }, + "typescript": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" + } + } +} diff --git a/smartpy/bmc/package.json b/smartpy/bmc/package.json new file mode 100644 index 00000000..e24aa957 --- /dev/null +++ b/smartpy/bmc/package.json @@ -0,0 +1,26 @@ +{ + "name": "create-tezos-app", + "version": "1.0.3", + "description": "A Tezos Dapp Starter using Typescript and Taquito.", + "bin": "./bin/cli.js", + "scripts": { + "compile": "bash ./compile.sh", + "deploy": "npx ts-node scripts/deploy.ts", + "test" : "bash ./test.sh" + }, + "author": "Roshan Parajuli", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/0xrpj/create-tezos-dapp" + }, + "dependencies": { + "@taquito/signer": "^14.0.0", + "@taquito/taquito": "^14.0.0", + "dotenv": "^16.0.3", + "ts-node": "^10.9.1" + }, + "devDependencies": { + "typescript": "^4.8.4" + } +} \ No newline at end of file diff --git a/smartpy/bmc/scripts/deploy.ts b/smartpy/bmc/scripts/deploy.ts new file mode 100644 index 00000000..9b50353a --- /dev/null +++ b/smartpy/bmc/scripts/deploy.ts @@ -0,0 +1,62 @@ +import * as dotenv from "dotenv"; +import { TezosToolkit } from "@taquito/taquito"; +import { InMemorySigner } from "@taquito/signer"; +import { NETWORK } from "../config/config"; + +dotenv.config(); + +const deploy = async () => { + type networkTypes = keyof typeof NETWORK; + + const { ORIGINATOR_PRIVATE_KEY } = process.env; + let file = process.argv[2]; + let rpcType: networkTypes = process.argv[3] + ?.toUpperCase() + .slice(1) as networkTypes; + + console.info("Staring validation..."); + + if (!ORIGINATOR_PRIVATE_KEY) { + console.error("Private key missing in the environment."); + return; + } + + if (!file) { + console.log("Pass filename to deploy! Read the docs."); + return; + } + + if (!rpcType || !Object.keys(NETWORK).includes(rpcType)) { + console.log("Valid networks:", Object.keys(NETWORK)); + console.error("Invalid network"); + return; + } + + file = file.toLowerCase(); + + const signer = await InMemorySigner.fromSecretKey(ORIGINATOR_PRIVATE_KEY); + const Tezos = new TezosToolkit(NETWORK[rpcType].url); + Tezos.setProvider({ signer: signer }); + + console.log(`Validation checks out... \nDeploying the ${file} contract..\n`); + try { + const { hash, contractAddress } = await Tezos.contract.originate({ + code: require(`../contracts/build/${file}.json`), + init: require(`../contracts/build/${file}_storage.json`), + }); + + console.log("Successfully deployed contract"); + console.log(`>> Transaction hash: ${hash}`); + console.log(`>> Contract address: ${contractAddress}`); + } catch (error) { + console.log( + `Oops... Deployment faced an issue.\nHere's the detailed info about the error,\n${error}` + ); + + console.log( + "Make sure of these things. \n1. Compiled contracts are inside the build folder.\n2. You have enough Tezos balance in the wallet for deployment." + ); + } +}; + +deploy(); diff --git a/smartpy/bmc/test.sh b/smartpy/bmc/test.sh new file mode 100644 index 00000000..34a7156e --- /dev/null +++ b/smartpy/bmc/test.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash + +set -e -o pipefail + +echo "----------------------------------------" +echo "Compiling contracts ... " +echo "----------------------------------------" + +# Expected location of SmartPy CLI. +SMART_PY_CLI=~/smartpy-cli/SmartPy.sh + +# Build artifact directory. +TEST_OUT_DIR=./contracts/build/.contract_build/test + +# Array of SmartPy files to compile. +# CONTRACTS_ARRAY=(counter) + +# Exit if SmartPy is not installed. +if [ ! -f "$SMART_PY_CLI" ]; then + echo "Fatal: Please install SmartPy CLI at $SMART_PY_CLI" && exit +fi + +function processContract { + CONTRACT_NAME=$1 + TEST_OUT_DIR=$2 + CONTRACT_IN_TEST="./contracts/tests/${CONTRACT_NAME}.py" + CONTRACT_OUT="${CONTRACT_NAME}.json" + STORAGE_OUT="${CONTRACT_NAME}_storage.json" + CONTRACT_COMPILED="${CONTRACT_NAME}/step_000_cont_0_contract.json" + STORAGE_COMPILED="${CONTRACT_NAME}/step_000_cont_0_storage.json" + + echo ">> Processing ${CONTRACT_NAME}" + + # Ensure file exists. + if [ ! -f "$CONTRACT_IN_TEST" ]; then + echo "Fatal: $CONTRACT_IN_TEST not found. Running from wrong dir?" && exit + fi + + echo ">>> Commencing the tests ${CONTRACT_NAME} ... " + $SMART_PY_CLI test $CONTRACT_IN_TEST $TEST_OUT_DIR --html +} + +export PYTHONPATH=$PWD + + +# Use if you want to pass a contract or more as arguments. +for n in $(seq 1 $#); do + processContract $1 $TEST_OUT_DIR + shift +done + + +echo "> Test Complete." \ No newline at end of file diff --git a/smartpy/bts/compile.sh b/smartpy/bts/compile.sh new file mode 100755 index 00000000..8d5d49f4 --- /dev/null +++ b/smartpy/bts/compile.sh @@ -0,0 +1,77 @@ + +#!/usr/bin/env bash + +set -e -o pipefail + +echo "----------------------------------------" +echo "Compiling contracts ... " +echo "----------------------------------------" + +# Expected location of SmartPy CLI. +SMART_PY_CLI=~/smartpy-cli/SmartPy.sh + +# Build artifact directory. +OUT_DIR=./contracts/build/.contract_build + +# Array of SmartPy files to compile. +# CONTRACTS_ARRAY=(counter) + +# Exit if SmartPy is not installed. +if [ ! -f "$SMART_PY_CLI" ]; then + echo "Fatal: Please install SmartPy CLI at $SMART_PY_CLI" && exit +fi + +function processContract { + CONTRACT_NAME=$1 + OUT_DIR=$2 + CONTRACT_IN="./contracts/src/${CONTRACT_NAME}.py" + CONTRACT_OUT="${CONTRACT_NAME}.json" + STORAGE_OUT="${CONTRACT_NAME}_storage.json" + CONTRACT_COMPILED="${CONTRACT_NAME}/step_000_cont_0_contract.json" + STORAGE_COMPILED="${CONTRACT_NAME}/step_000_cont_0_storage.json" + + echo ">> Processing ${CONTRACT_NAME}" + + # Ensure file exists. + if [ ! -f "$CONTRACT_IN" ]; then + echo "Fatal: $CONTRACT_IN not found. Running from wrong dir?" && exit + fi + +# echo ">>> [1 / 3] Testing ${CONTRACT_NAME} ... " +# $SMART_PY_CLI test $CONTRACT_IN $OUT_DIR --html + + echo ">>> [1 / 2] Compiling ${CONTRACT_NAME} ..." + $SMART_PY_CLI compile $CONTRACT_IN $OUT_DIR --html + + echo ">>> [2 / 2] Extracting Michelson contract ... " + cp $OUT_DIR/$CONTRACT_COMPILED ./contracts/build/$CONTRACT_OUT + cp $OUT_DIR/$STORAGE_COMPILED ./contracts/build/$STORAGE_OUT + + echo ">>> Michelson contract written to ${CONTRACT_OUT}" +} + +export PYTHONPATH=$PWD + + +echo "> [1 / 2] Compiling Contracts." +# Use if you want to pass a contract or more as arguments. +for n in $(seq 1 $#); do + processContract $1 $OUT_DIR + shift +done + +# Use if you want to compile all contracts in CONTRACTS_ARRAY. No arguments needed. +# for i in ${!CONTRACTS_ARRAY[@]}; do +# processContract ${CONTRACTS_ARRAY[$i]} $OUT_DIR +# done + +# Remove build artifacts. +echo "> [2 / 2] Cleaning up ..." +rm -rf $OUT_DIR +rm -rf ./contracts/__pycache__ +rm -rf ./__pycache__ + + +echo "> Removed artifacts." + +echo "> Compilation successful." \ No newline at end of file diff --git a/smartpy/bts/config/config.ts b/smartpy/bts/config/config.ts new file mode 100644 index 00000000..2dc56ea2 --- /dev/null +++ b/smartpy/bts/config/config.ts @@ -0,0 +1,20 @@ +// List your config files here + +export const NETWORK = { + GHOSTNET: { + name: "ghostnet", + url: "https://ghostnet.smartpy.io", + }, + KATHMANDUNET: { + name: "kathmandunet", + url: "https://kathmandunet.smartpy.io", + }, + JAKARTANET: { + name: "jakartanet", + url: "https://jakartanet.smartpy.io", + }, + MAINNET: { + name: "mainnet", + url: "https://mainnet.smartpy.io", + }, +}; diff --git a/smartpy/bts/contracts/src/FA2_contract.py b/smartpy/bts/contracts/src/FA2_contract.py new file mode 100644 index 00000000..db8dfb09 --- /dev/null +++ b/smartpy/bts/contracts/src/FA2_contract.py @@ -0,0 +1,162 @@ +import smartpy as sp + +FA2 = sp.io.import_script_from_url("https://legacy.smartpy.io/templates/fa2_lib.py") + +t_transfer_batch = sp.TRecord( + callback=sp.TContract( + sp.TRecord(string=sp.TOption(sp.TString), requester=sp.TAddress, coin_name=sp.TString, value=sp.TNat)), + from_=sp.TAddress, + coin_name=sp.TString, + txs=sp.TList( + sp.TRecord( + to_=sp.TAddress, + token_id=sp.TNat, + amount=sp.TNat, + ).layout(("to_", ("token_id", "amount"))) + ), +).layout((("from_", "coin_name"), ("callback", "txs"))) + +t_transfer_params = sp.TList(t_transfer_batch) + + +class SingleAssetToken(FA2.Admin, FA2.Fa2SingleAsset, FA2.MintSingleAsset, FA2.BurnSingleAsset, + FA2.OnchainviewBalanceOf): + def __init__(self, admin, metadata, token_metadata): + FA2.Fa2SingleAsset.__init__(self, metadata=metadata, token_metadata=token_metadata) + FA2.Admin.__init__(self, admin) + self.update_initial_storage( + allowances=sp.big_map(tkey=sp.TRecord(spender=sp.TAddress, owner=sp.TAddress), tvalue=sp.TNat) + ) + + @sp.onchain_view() + def is_admin(self, address): + sp.result(address == self.data.administrator) + + @sp.onchain_view() + def balance_of(self, param): + sp.set_type(param, sp.TRecord(owner=sp.TAddress, token_id=sp.TNat)) + sp.result(self.balance_(param.owner, param.token_id)) + + @sp.entry_point + def set_allowance(self, batch): + sp.set_type(batch, sp.TList(sp.TRecord(spender=sp.TAddress, amount=sp.TNat))) + + with sp.for_("params", batch) as params: + allowance = sp.compute(sp.record(spender=params.spender, owner=sp.sender)) + current_allowance = self.data.allowances.get(allowance, default_value=0) + sp.verify((params.amount == 0) | (current_allowance == 0), "FA2_UnsafeAllowanceChange") + self.data.allowances[allowance] = params.amount + + @sp.onchain_view() + def get_allowance(self, allowance): + sp.set_type(allowance, sp.TRecord(spender=sp.TAddress, owner=sp.TAddress)) + sp.result(self.data.allowances.get(allowance, default_value=0)) + + @sp.entry_point + def transfer_bts(self, batch): + """Accept a list of transfer operations between a source and multiple + destinations. + Custom version with allowance system with callback implementation. + + `transfer_tx_` must be defined in the child class. + """ + sp.set_type(batch, t_transfer_params) + + if self.policy.supports_transfer: + with sp.for_("transfer", batch) as transfer: + with sp.for_("tx", transfer.txs) as tx: + # The ordering of sp.verify is important: 1) token_undefined, 2) transfer permission 3) balance + sp.verify(self.is_defined(tx.token_id), "FA2_TOKEN_UNDEFINED") + self.policy.check_tx_transfer_permissions( + self, transfer.from_, tx.to_, tx.token_id + ) + with sp.if_(sp.sender != transfer.from_): + self.update_allowance_(sp.sender, transfer.from_, tx.token_id, tx.amount) + with sp.if_(tx.amount > 0): + self.transfer_tx_(transfer.from_, tx) + + return_value = sp.record(string=sp.some("success"), requester=tx.to_, + coin_name=transfer.coin_name, value=tx.amount) + sp.transfer(return_value, sp.tez(0), transfer.callback) + else: + with sp.for_("transfer", batch) as transfer: + with sp.for_("tx", transfer.txs) as tx: + return_value = sp.record(string=sp.some("FA2_TX_DENIED"), requester=tx.to_, + coin_name=transfer.coin_name, value=tx.amount) + sp.transfer(return_value, sp.tez(0), transfer.callback) + + @sp.entry_point + def transfer(self, batch): + """Accept a list of transfer operations between a source and multiple + destinations. + Custom version with allowance system. + `transfer_tx_` must be defined in the child class. + """ + sp.set_type(batch, FA2.t_transfer_params) + if self.policy.supports_transfer: + with sp.for_("transfer", batch) as transfer: + with sp.for_("tx", transfer.txs) as tx: + # The ordering of sp.verify is important: 1) token_undefined, 2) transfer permission 3) balance + sp.verify(self.is_defined(tx.token_id), "FA2_TOKEN_UNDEFINED") + self.policy.check_tx_transfer_permissions( + self, transfer.from_, tx.to_, tx.token_id + ) + with sp.if_(sp.sender != transfer.from_): + self.update_allowance_(sp.sender, transfer.from_, tx.token_id, tx.amount) + with sp.if_(tx.amount > 0): + self.transfer_tx_(transfer.from_, tx) + else: + sp.failwith("FA2_TX_DENIED") + + def update_allowance_(self, spender, owner, token_id, amount): + allowance = sp.record(spender=spender, owner=owner) + self.data.allowances[allowance] = sp.as_nat(self.data.allowances.get(allowance, default_value=0) - amount, + message=sp.pair("FA2_NOT_OPERATOR", "NoAllowance")) + + +@sp.add_test(name="FA2Contract") +def test(): + alice = sp.test_account("Alice") + bob = sp.test_account("Bob") + spender = sp.test_account("spender") + receiver = sp.test_account("receiver") + + c1 = SingleAssetToken(admin=alice.address, metadata=sp.big_map({"ss": sp.bytes("0x0dae11")}), + token_metadata=sp.map({"ff": sp.bytes("0x0dae11")})) + + scenario = sp.test_scenario() + scenario.h1("FA2Contract") + scenario += c1 + + c1.mint([sp.record(to_=bob.address, amount=sp.nat(200))]).run(sender=alice) + scenario.verify(c1.data.ledger.get(bob.address) == sp.nat(200)) + + scenario.verify(c1.get_allowance(sp.record(spender=spender.address, owner=bob.address)) == 0) + # set allowance + c1.set_allowance([sp.record(spender=spender.address, amount=sp.nat(100))]).run(sender=bob) + c1.set_allowance([sp.record(spender=spender.address, amount=sp.nat(100))]).run(sender=bob, valid=False, + exception="FA2_UnsafeAllowanceChange") + + scenario.verify(c1.get_allowance(sp.record(spender=spender.address, owner=bob.address)) == 100) + c1.update_operators( + [sp.variant("add_operator", sp.record(owner=bob.address, operator=spender.address, token_id=0))]).run( + sender=bob) + # transfer more than allowance + # c1.transfer([sp.record(callback=sp.self_entry_point("callback"), from_=bob.address, txs=[sp.record(to_=receiver.address, token_id=0, amount=101)])]).run( + # sender=spender, valid=False, exception=('FA2_NOT_OPERATOR', 'NoAllowance')) + # # transfer all allowance + # c1.transfer([sp.record(from_=bob.address, txs=[sp.record(to_=receiver.address, token_id=0, amount=100)])]).run( + # sender=spender) + + # # verify remaining allowance + # scenario.verify(c1.get_allowance(sp.record(spender=spender.address, owner=bob.address)) == 0) + # # again set allowance after prev-allowance is 0 + # c1.set_allowance([sp.record(spender=spender.address, amount=sp.nat(100))]).run(sender=bob) + + +sp.add_compilation_target("FA2_contract", + SingleAssetToken( + admin=sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP"), + metadata=sp.utils.metadata_of_url( + "ipfs://example"), + token_metadata=FA2.make_metadata(name="NativeWrappedCoin", decimals=6, symbol="WTEZ"))) diff --git a/smartpy/bts/contracts/src/RLP_decode_struct.py b/smartpy/bts/contracts/src/RLP_decode_struct.py new file mode 100644 index 00000000..213ad7df --- /dev/null +++ b/smartpy/bts/contracts/src/RLP_decode_struct.py @@ -0,0 +1,278 @@ +import smartpy as sp + +Utils2 = sp.io.import_script_from_url("https://raw.githubusercontent.com/RomarQ/tezos-sc-utils/main/smartpy/utils.py") +types = sp.io.import_script_from_url("file:./contracts/src/Types.py") + + +class DecodeLibrary: + def decode_response(self, rlp): + temp_int = sp.local("int1", 0) + temp_byt = sp.local("byt1", sp.bytes("0x")) + rlp_dr = sp.local("rlp_dr_bts", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_dr.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + rlp_dr.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_ = rlp_dr.value + counter = sp.local("counter_response", 0) + sp.for i in rlp_.items(): + sp.if counter.value == 0: + # check_length = sp.view("prefix_length", self.data.helper, i.value, t=sp.TNat).open_some() + # with sp.if_(check_length > 0): + # i.value = sp.view("without_length_prefix", self.data.helper, i.value, + # t=sp.TBytes).open_some() + temp_int.value = Utils2.Int.of_bytes(i.value) + sp.if counter.value == 1: + temp_byt.value = i.value + counter.value = counter.value + 1 + + return sp.record(code=temp_int.value, message=sp.view("decode_string", self.data.helper, temp_byt.value, t=sp.TString).open_some()) + + def decode_service_message(self, rlp): + rlp_sm = sp.local("rlp_sm_bts", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_sm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + rlp_sm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_ = rlp_sm.value + temp_int = sp.local("int2", 0) + temp_byt = sp.local("byte1", sp.bytes("0x")) + counter = sp.local("counter", 0) + sp.for i in rlp_.items(): + sp.if counter.value == 0: + # check_length = sp.view("prefix_length", self.data.helper, i.value, t=sp.TNat).open_some() + # with sp.if_(check_length > 0): + # i.value = sp.view("without_length_prefix", self.data.helper, i.value, + # t=sp.TBytes).open_some() + temp_int.value = Utils2.Int.of_bytes(i.value) + sp.if counter.value == 1: + temp_byt.value = i.value + counter.value = counter.value + 1 + + _service_type = sp.local("_service_type", sp.variant("", 10)) + sp.if temp_int.value == 0: + _service_type.value = sp.variant("REQUEST_COIN_TRANSFER", temp_int.value) + sp.if temp_int.value == 1: + _service_type.value = sp.variant("REQUEST_COIN_REGISTER", temp_int.value) + sp.if temp_int.value == 2: + _service_type.value = sp.variant("RESPONSE_HANDLE_SERVICE", temp_int.value) + sp.if temp_int.value == 3: + _service_type.value = sp.variant("BLACKLIST_MESSAGE", temp_int.value) + sp.if temp_int.value == 4: + _service_type.value = sp.variant("CHANGE_TOKEN_LIMIT", temp_int.value) + sp.if temp_int.value == 5: + _service_type.value = sp.variant("UNKNOWN_TYPE", temp_int.value) + temp_byt.value = sp.view("without_length_prefix", self.data.helper, temp_byt.value, t=sp.TBytes).open_some() + + return sp.record(serviceType=_service_type.value, + data=temp_byt.value) + + def decode_transfer_coin_msg(self, rlp): + rlp_tcm = sp.local("rlp_tcm_bts", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_tcm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + rlp_tcm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_ = rlp_tcm.value + + temp_byt = sp.local("byt_transfer", sp.bytes("0x")) + rv1_byt = sp.local("rv1_byt", sp.bytes("0x")) + rv2_byt = sp.local("rv2_byt", sp.bytes("0x")) + counter = sp.local("counter_coin", sp.nat(0)) + sp.for i in rlp_.items(): + sp.if counter.value == 2: + temp_byt.value = i.value + sp.if counter.value == 0: + rv1_byt.value = i.value + sp.if counter.value == 1: + rv2_byt.value = i.value + counter.value = counter.value + 1 + sub_list = sp.local("sub_list", temp_byt.value) + nsl_tcm = sp.local("nsl_bts_tcm", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + nsl_tcm.value = sp.view("decode_list", self.data.helper, sub_list.value, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() + nsl_tcm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + new_sub_list = nsl_tcm.value + counter.value = 0 + new_temp_byt = sp.local("new_temp_byt", sp.bytes("0x")) + rv_assets = sp.local("assets", {}, sp.TMap(sp.TNat, types.Types.Asset)) + sp.for x in new_sub_list.items(): + new_temp_byt.value = x.value + # sp.if sp.slice(new_temp_byt.value, 0, 2).open_some() == sp.bytes("0xb846"): + # new_temp_byt.value = sp.slice(new_temp_byt.value, 2, sp.as_nat(sp.len(new_temp_byt.value) - 2)).open_some() + temp_byt = sp.local("tempByt2", sp.bytes("0x")) + temp_int = sp.local("tempInt", sp.nat(0)) + counter.value = 0 + nsl3_tcm = sp.local("nsl3_bts_tcm", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, new_temp_byt.value, + t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + nsl3_tcm.value = sp.view("decode_list", self.data.helper, new_temp_byt.value, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, new_temp_byt.value, t=sp.TBytes).open_some() + nsl3_tcm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + view_value = nsl3_tcm.value + sp.for i in view_value.items(): + sp.if counter.value == 1: + # check_length = sp.view("prefix_length", self.data.helper, i.value, t=sp.TNat).open_some() + # with sp.if_ (check_length > 0): + i.value = sp.view("without_length_prefix", self.data.helper, i.value, + t=sp.TBytes).open_some() + temp_int.value = Utils2.Int.of_bytes(i.value) + sp.if counter.value == 0: + temp_byt.value = i.value + rv_assets.value[counter.value] = sp.record(coin_name=sp.view("decode_string", self.data.helper, temp_byt.value, t=sp.TString).open_some() + , value=temp_int.value) + counter.value = counter.value + 1 + rv1 = sp.view("decode_string", self.data.helper, rv1_byt.value, t=sp.TString).open_some() + rv2 = sp.view("decode_string", self.data.helper, rv2_byt.value, t=sp.TString).open_some() + return sp.record(from_= rv1, to = rv2 , assets = rv_assets.value) + + def decode_blacklist_msg(self, rlp): + rlp_bm = sp.local("rlp_bm_bts", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_bm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + rlp_bm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_ = rlp_bm.value + + temp_byt = sp.local("byt_transfer", sp.bytes("0x")) + rv1_byt = sp.local("rv1_byt", sp.bytes("0x")) + rv2_byt = sp.local("rv2_byt", sp.bytes("0x")) + counter = sp.local("counter_blacklist", 0) + sp.for i in rlp_.items(): + sp.if counter.value == 2: + rv2_byt.value = i.value + sp.if counter.value == 0: + rv1_byt.value = i.value + sp.if counter.value == 1: + temp_byt.value = i.value + counter.value = counter.value + 1 + sub_list = sp.local("sub_list", temp_byt.value) + nsl_bm = sp.local("nsl_bts_bm", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + nsl_bm.value = sp.view("decode_list", self.data.helper, sub_list.value, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() + nsl_bm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + new_sub_list = nsl_bm.value + counter.value = 0 + new_temp_byt = sp.local("new_temp_byt", sp.bytes("0x")) + rv_blacklist_address = sp.local("blacklist_data", {}, sp.TMap(sp.TNat, sp.TString)) + addr_string = sp.local("addr_string", "") + nsl2_bm = sp.local("nsl2_bts_bm", sp.map(tkey=sp.TNat)) + counter.value = 0 + sp.for x in new_sub_list.items(): + new_temp_byt.value = x.value + # sp.if sp.slice(new_temp_byt.value, 0, 2).open_some() == sp.bytes("0xb846"): + # new_temp_byt.value = sp.slice(new_temp_byt.value, 2, sp.as_nat(sp.len(new_temp_byt.value) - 2)).open_some() + is_list_lambda = sp.view("is_list", self.data.helper, new_temp_byt.value, + t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + nsl2_bm.value = sp.view("decode_list", self.data.helper, new_temp_byt.value, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, new_temp_byt.value, t=sp.TBytes).open_some() + addr_string.value = sp.view("decode_string", self.data.helper, decode_len, + t=sp.TString).open_some() + # _decode_list = nsl2_bm.value + # sp.for j in _decode_list.items(): + rv_blacklist_address.value[counter.value] = addr_string.value + counter.value = counter.value + 1 + check_length = sp.view("prefix_length", self.data.helper, rv1_byt.value, t=sp.TNat).open_some() + with sp.if_(check_length > 0): + rv1_byt.value = sp.view("without_length_prefix", self.data.helper, rv1_byt.value, + t=sp.TBytes).open_some() + rv1 = Utils2.Int.of_bytes(rv1_byt.value) + rv2 = sp.view("decode_string", self.data.helper, rv2_byt.value, t=sp.TString).open_some() + _service_type = sp.local("_service_type_blacklist", sp.variant("", 10)) + with sp.if_(rv1 == 0): + _service_type.value = sp.variant("ADD_TO_BLACKLIST", rv1) + with sp.else_(): + _service_type.value = sp.variant("REMOVE_FROM_BLACKLIST", rv1) + return sp.record(serviceType = _service_type.value , addrs = rv_blacklist_address.value , net = rv2) + + def decode_token_limit_msg(self, rlp): + rlp_tlm = sp.local("rlp_tlm_bts", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_tlm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + rlp_tlm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_ = rlp_tlm.value + + temp_byt = sp.local("byt_transfer", sp.bytes("0x")) + temp_byt1 = sp.local("byt_transfer_temp1", sp.bytes("0x")) + rv1_byt = sp.local("rv1_byt", sp.bytes("0x")) + counter = sp.local("counter_token_limit", 0) + sp.for i in rlp_.items(): + sp.if counter.value == 0: + temp_byt.value = i.value + sp.if counter.value == 1: + temp_byt1.value = i.value + sp.if counter.value == 2: + rv1_byt.value = i.value + counter.value = counter.value + 1 + sub_list = sp.local("sub_list", temp_byt.value) + sub_list_limit = sp.local("sub_list_limit", temp_byt1.value) + nsl1_dtlm = sp.local("nsl1_bts_dtlm", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + nsl1_dtlm.value = sp.view("decode_list", self.data.helper, sub_list.value, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() + nsl1_dtlm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + new_sub_list = nsl1_dtlm.value + counter.value = 0 + rv_names = sp.local("names", {}, sp.TMap(sp.TNat, sp.TString)) + rv_limit = sp.local("limit", {}, sp.TMap(sp.TNat, sp.TNat)) + sp.for x in new_sub_list.items(): + rv_names.value[counter.value] = sp.view("decode_string", self.data.helper, x.value, t=sp.TString).open_some() + counter.value += 1 + nsl_dtlm = sp.local("nsl_bts_dtlm", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() + counter.value = 0 + with sp.if_(is_list_lambda): + nsl_dtlm.value = sp.view("decode_list", self.data.helper, sub_list_limit.value, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, sub_list_limit.value, t=sp.TBytes).open_some() + nsl_dtlm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + new_sub_list1 = nsl_dtlm.value + limit = sp.local("limit_val", sp.bytes("0x"), t=sp.TBytes) + sp.for y in new_sub_list1.items(): + check_length = sp.view("prefix_length", self.data.helper, y.value, t=sp.TNat).open_some() + with sp.if_(check_length > 0): + limit.value = sp.view("without_length_prefix", self.data.helper, y.value, + t=sp.TBytes).open_some() + rv_limit.value[counter.value] = Utils2.Int.of_bytes(limit.value) + counter.value += 1 + return sp.record(coin_name = rv_names.value, token_limit = rv_limit.value , + net = sp.view("decode_string", self.data.helper, rv1_byt.value, t=sp.TString).open_some()) \ No newline at end of file diff --git a/smartpy/bts/contracts/src/RLP_encode_struct.py b/smartpy/bts/contracts/src/RLP_encode_struct.py new file mode 100644 index 00000000..17b15135 --- /dev/null +++ b/smartpy/bts/contracts/src/RLP_encode_struct.py @@ -0,0 +1,48 @@ +import smartpy as sp + +types = sp.io.import_script_from_url("file:./contracts/src/Types.py") + + +class EncodeLibrary: + def encode_service_message(self, params): + sp.set_type(params, sp.TRecord(service_type_value = sp.TNat, data = sp.TBytes)) + + encode_service_type = sp.view("encode_nat", self.data.helper, params.service_type_value, t=sp.TBytes).open_some() + rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [encode_service_type, params.data], t=sp.TBytes).open_some() + final_rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp_bytes_with_prefix, t=sp.TBytes).open_some() + + return final_rlp_bytes_with_prefix + + + def encode_transfer_coin_msg(self, data): + sp.set_type(data, types.Types.TransferCoin) + + rlp = sp.local("rlp", sp.bytes("0x")) + temp = sp.local("temp", sp.bytes("0x")) + coin_name = sp.local("coin_name", sp.bytes("0x")) + encode_lis_byte = sp.local("encode_lis_byte", sp.bytes("0x")) + sp.for i in sp.range(0, sp.len(data.assets)): + coin_name.value = sp.view("encode_string", self.data.helper, data.assets.get(i, default_value=sp.record(coin_name="",value=sp.nat(0))).coin_name, t=sp.TBytes).open_some() + temp.value = sp.view("encode_nat", self.data.helper, data.assets.get(i, default_value=sp.record(coin_name="",value=sp.nat(0))).value, t=sp.TBytes).open_some() + encode_lis_byte.value = sp.view("encode_list", self.data.helper, [rlp.value, coin_name.value, temp.value], t=sp.TBytes).open_some() + rlp.value = sp.view("encode_list", self.data.helper, [encode_lis_byte.value], t=sp.TBytes).open_some() + # rlp.value = sp.view("with_length_prefix", self.data.helper, rlp.value, + # t=sp.TBytes).open_some() + + from_addr_encoded = sp.view("encode_string", self.data.helper, data.from_addr, t=sp.TBytes).open_some() + to_addr_encoded = sp.view("encode_string", self.data.helper, data.to, t=sp.TBytes).open_some() + rlp.value = sp.view("encode_list", self.data.helper, [from_addr_encoded, to_addr_encoded, rlp.value], t=sp.TBytes).open_some() + final_rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp.value, t=sp.TBytes).open_some() + + return final_rlp_bytes_with_prefix + + def encode_response(self, params): + sp.set_type(params, sp.TRecord(code=sp.TNat, message=sp.TString)) + + encode_code = sp.view("encode_nat", self.data.helper, params.code, t=sp.TBytes).open_some() + encode_message = sp.view("encode_string", self.data.helper, params.message, t=sp.TBytes).open_some() + + rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [encode_code, encode_message], + t=sp.TBytes).open_some() + final_rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp_bytes_with_prefix, t=sp.TBytes).open_some() + return final_rlp_bytes_with_prefix diff --git a/smartpy/bts/contracts/src/String.py b/smartpy/bts/contracts/src/String.py new file mode 100644 index 00000000..c9c55e17 --- /dev/null +++ b/smartpy/bts/contracts/src/String.py @@ -0,0 +1,44 @@ +import smartpy as sp + +def split_btp_address(base): + """ + Split the BTP Address format i.e. btp://1234.iconee/0x123456789 + into Network_address (1234.iconee) and Server_address (0x123456789) + :param base: String base BTP Address format to be split + :return: The resulting strings of Network_address and Server_address + """ + sp.set_type(base, sp.TString) + + sep = sp.local("sep", "/") + prev_idx = sp.local('prev_idx', 0) + res = sp.local('res', []) + sp.for idx in sp.range(0, sp.len(base)): + sp.if sp.slice(base, idx, 1).open_some() == sep.value: + res.value.push(sp.slice(base, prev_idx.value, sp.as_nat(idx - prev_idx.value)).open_some()) + prev_idx.value = idx + 1 + sp.if sp.len(base) > 0: + res.value.push(sp.slice(base, prev_idx.value, sp.as_nat(sp.len(base) - prev_idx.value)).open_some()) + + inverted_list = sp.local("my_list", res.value) + last = sp.local("last", "") + penultimate = sp.local("penultimate", "") + + with sp.match_cons(inverted_list.value) as l: + last.value = l.head + inverted_list.value = l.tail + # with sp.else_(): + # sp.failwith("Empty list") + + + with sp.match_cons(inverted_list.value) as l: + penultimate.value = l.head + # with sp.else_(): + # sp.failwith("Only one element") + + return sp.pair(penultimate.value, last.value) + + + + + + diff --git a/smartpy/bts/contracts/src/Types.py b/smartpy/bts/contracts/src/Types.py new file mode 100644 index 00000000..dfba1591 --- /dev/null +++ b/smartpy/bts/contracts/src/Types.py @@ -0,0 +1,71 @@ +import smartpy as sp + + +class Types: + + Asset = sp.TRecord( + coin_name=sp.TString, + value=sp.TNat + ) + + AssetTransferDetail = sp.TRecord( + coin_name=sp.TString, + value=sp.TNat, + fee=sp.TNat + ) + + Response = sp.TRecord( + code=sp.TNat, + message=sp.TString + ) + + ServiceType = sp.TVariant( + REQUEST_COIN_TRANSFER=sp.TNat, + REQUEST_COIN_REGISTER=sp.TNat, + RESPONSE_HANDLE_SERVICE=sp.TNat, + BLACKLIST_MESSAGE=sp.TNat, + CHANGE_TOKEN_LIMIT=sp.TNat, + UNKNOWN_TYPE=sp.TNat + ) + + BlacklistService = sp.TVariant( + ADD_TO_BLACKLIST=sp.TNat, + REMOVE_FROM_BLACKLIST=sp.TNat + ) + + ServiceMessage = sp.TRecord( + serviceType=ServiceType, + data=sp.TBytes + ) + + TransferCoin = sp.TRecord( + from_addr=sp.TString, + to=sp.TString, + assets=sp.TMap(sp.TNat, Asset) + ) + + PendingTransferCoin = sp.TRecord( + from_=sp.TString, + to=sp.TString, + coin_names=sp.TMap(sp.TNat, sp.TString), + amounts=sp.TMap(sp.TNat, sp.TNat), + fees=sp.TMap(sp.TNat, sp.TNat) + ) + + BlacklistMessage = sp.TRecord( + serviceType=BlacklistService, + addrs=sp.TMap(sp.TNat, sp.TString), + net=sp.TString + ) + + TokenLimitMessage = sp.TRecord( + coin_name=sp.TMap(sp.TNat, sp.TString), + token_limit=sp.TMap(sp.TNat, sp.TNat), + net=sp.TString + ) + + Balance = sp.TRecord( + locked_balance=sp.TNat, + refundable_balance=sp.TNat + ) + diff --git a/smartpy/bts/contracts/src/bts_core.py b/smartpy/bts/contracts/src/bts_core.py new file mode 100644 index 00000000..584f89cf --- /dev/null +++ b/smartpy/bts/contracts/src/bts_core.py @@ -0,0 +1,714 @@ +import smartpy as sp + +types = sp.io.import_script_from_url("file:./contracts/src/Types.py") +FA2_contract = sp.io.import_script_from_url("file:./contracts/src/FA2_contract.py") + +Coin = sp.TRecord(addr=sp.TAddress, + fee_numerator=sp.TNat, + fixed_fee=sp.TNat, + coin_type=sp.TNat) + +class BTSCore(sp.Contract): + FEE_DENOMINATOR = sp.nat(10000) + RC_OK = sp.nat(0) + RC_ERR = sp.nat(1) + NATIVE_COIN_TYPE = sp.nat(0) + NATIVE_WRAPPED_COIN_TYPE = sp.nat(1) + NON_NATIVE_TOKEN_TYPE = sp.nat(2) + + MAX_BATCH_SIZE = sp.nat(15) + NATIVE_COIN_ADDRESS = sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc") + ZERO_ADDRESS = sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg") + # Nat:(TWO.pow256 - 1) + UINT_CAP = sp.nat(115792089237316195423570985008687907853269984665640564039457584007913129639935) + + # TODO: change the native coin addr + + def __init__(self, _native_coin_name, _fee_numerator, _fixed_fee, owner_manager): + self.update_initial_storage( + bts_owner_manager=owner_manager, + bts_periphery_address=sp.none, + native_coin_name=_native_coin_name, + + list_of_owners=sp.list(t=sp.TAddress), + charged_amounts=sp.map(tkey=sp.TNat, tvalue=sp.TNat), + coins_name=sp.list([_native_coin_name], t=sp.TString), + charged_coins=sp.map(tkey=sp.TNat, tvalue=sp.TString), + + owners=sp.map({}, tkey=sp.TAddress, tvalue=sp.TBool), + aggregation_fee=sp.map({}, tkey=sp.TString, tvalue=sp.TNat), + balances=sp.big_map(tkey=sp.TRecord(address=sp.TAddress, coin_name=sp.TString), tvalue= types.Types.Balance), + coins=sp.map({_native_coin_name: self.NATIVE_COIN_ADDRESS}, tkey=sp.TString, tvalue=sp.TAddress), + coin_details=sp.map({_native_coin_name: sp.record(addr=self.NATIVE_COIN_ADDRESS, + fee_numerator=_fee_numerator, + fixed_fee=_fixed_fee, + coin_type=self.NATIVE_COIN_TYPE)}, + tkey=sp.TString, tvalue=Coin), + coins_address=sp.map({}, tkey=sp.TAddress, tvalue=sp.TString), + transfer_status=sp.none + ) + + #is this necessary? can we check against owners map in line 37? + def only_owner(self): + # call Owner Manager Contract for checking owner + is_owner = sp.view("is_owner", self.data.bts_owner_manager, sp.sender, t=sp.TBool).open_some( + "OwnerNotFound") + sp.verify(is_owner == True, message="Unauthorized") + + def only_bts_periphery(self): + sp.verify(sp.sender == self.data.bts_periphery_address.open_some("Address not set"), "Unauthorized") + + @sp.onchain_view() + def get_native_coin_name(self): + """ + Get name of nativecoin + :return: Name of nativecoin + """ + sp.result(self.data.native_coin_name) + + @sp.entry_point + def update_bts_periphery(self, bts_periphery): + """ + update BTS Periphery address. + :param bts_periphery: BTSPeriphery contract address. + :return: + """ + sp.set_type(bts_periphery, sp.TAddress) + + self.only_owner() + sp.if self.data.bts_periphery_address.is_some(): + has_requests = sp.view("has_pending_request", self.data.bts_periphery_address.open_some("Address not set"), sp.unit, t=sp.TBool).open_some("OwnerNotFound") + sp.verify(has_requests == False, "HasPendingRequest") + self.data.bts_periphery_address = sp.some(bts_periphery) + + @sp.entry_point + def set_fee_ratio(self, name, fee_numerator, fixed_fee): + """ + set fee ratio. The transfer fee is calculated by fee_numerator/FEE_DEMONINATOR. + fee_numerator if it is set to `10`, which means the default fee ratio is 0.1%. + :param name: + :param fee_numerator: the fee numerator + :param fixed_fee: + :return: + """ + sp.set_type(name, sp.TString) + sp.set_type(fee_numerator, sp.TNat) + sp.set_type(fixed_fee, sp.TNat) + + self.only_owner() + sp.verify(fee_numerator < self.FEE_DENOMINATOR, message="InvalidSetting") + sp.verify((name == self.data.native_coin_name) | self.data.coins.contains(name), message = "TokenNotExists") + sp.verify((fixed_fee > sp.nat(0)) & (fee_numerator >= sp.nat(0)), message = "LessThan0") + self.data.coin_details[name].fee_numerator = fee_numerator + self.data.coin_details[name].fixed_fee = fixed_fee + + @sp.entry_point + def register(self, name, fee_numerator, fixed_fee, addr, token_metadata, metadata): + """ + Registers a wrapped coin and id number of a supporting coin. + :param name: Must be different with the native coin name. + :param fee_numerator: + :param fixed_fee: + :param addr: address of the coin + :param token_metadata: Token metadata name, symbol and decimals of wrapped token + :param metadata: metadata of the token contract + :return: + """ + sp.set_type(name, sp.TString) + sp.set_type(fee_numerator, sp.TNat) + sp.set_type(fixed_fee, sp.TNat) + sp.set_type(addr, sp.TAddress) + sp.set_type(token_metadata, sp.TMap(sp.TString, sp.TBytes)) + sp.set_type(metadata, sp.TBigMap(sp.TString, sp.TBytes)) + + self.only_owner() + sp.verify(name != self.data.native_coin_name, message="ExistNativeCoin") + sp.verify(self.data.coins.contains(name) == False, message= "ExistCoin") + sp.verify(self.data.coins_address.contains(addr) == False, message="AddressExists") + sp.verify(fee_numerator <= self.FEE_DENOMINATOR, message="InvalidSetting") + sp.verify((fixed_fee >= sp.nat(0)) & (fee_numerator >= sp.nat(0)), message="LessThan0") + with sp.if_(addr == self.ZERO_ADDRESS): + deployed_fa2 = sp.create_contract_operation(contract=FA2_contract.SingleAssetToken(admin=sp.self_address, metadata=metadata, + token_metadata=token_metadata + )) + sp.operations().push(deployed_fa2.operation) + self.data.coins[name] = deployed_fa2.address + self.data.coins_name.push(name) + self.data.coins_address[deployed_fa2.address] = name + self.data.coin_details[name] = sp.record( + addr = deployed_fa2.address, + fee_numerator = fee_numerator, + fixed_fee = fixed_fee, + coin_type = self.NATIVE_WRAPPED_COIN_TYPE + ) + with sp.else_(): + self.data.coins[name] = addr + self.data.coins_name.push(name) + self.data.coins_address[addr] = name + self.data.coin_details[name] = sp.record( + addr = addr, + fee_numerator = fee_numerator, + fixed_fee = fixed_fee, + coin_type = self.NON_NATIVE_TOKEN_TYPE + ) + + token_map = sp.map({0:name}, tkey=sp.TNat, tvalue=sp.TString) + val_map = sp.map({0:self.UINT_CAP}, tkey=sp.TNat, tvalue=sp.TNat) + + # call set_token_limit on bts_periphery + set_token_limit_args_type = sp.TRecord(coin_names=sp.TMap(sp.TNat, sp.TString), token_limit=sp.TMap(sp.TNat, sp.TNat)) + set_token_limit_entry_point = sp.contract(set_token_limit_args_type, self.data.bts_periphery_address.open_some("Address not set"), + "set_token_limit").open_some("ErrorINCALL") + set_token_limit_args = sp.record(coin_names=token_map, token_limit=val_map) + sp.transfer(set_token_limit_args, sp.tez(0), set_token_limit_entry_point) + + @sp.onchain_view() + def coin_names(self): + """ + Return all supported coins names + :return: An array of strings. + """ + sp.result(self.data.coins_name) + + @sp.onchain_view() + def coin_id(self, coin_name): + """ + Return address of Coin whose name is the same with given coin_ame. + :param coin_name: + :return: An address of coin_name. + """ + sp.set_type(coin_name, sp.TString) + + sp.result(self.data.coins.get(coin_name)) + + @sp.onchain_view() + def is_valid_coin(self, coin_name): + """ + Check Validity of a coin_name + :param coin_name: + :return: true or false + """ + sp.set_type(coin_name, sp.TString) + + sp.result((self.data.coins.contains(coin_name))|( coin_name == self.data.native_coin_name)) + + @sp.onchain_view() + def fee_ratio(self, coin_name): + """ + Get fee numerator and fixed fee + :param coin_name: Coin name + :return: a record (Fee numerator for given coin, Fixed fee for given coin) + """ + sp.set_type(coin_name, sp.TString) + + coin = self.data.coin_details[coin_name] + fee_numerator = coin.fee_numerator + fixed_fee = coin.fixed_fee + sp.result(sp.record(fee_numerator =fee_numerator, fixed_fee = fixed_fee)) + + @sp.onchain_view() + def balance_of(self, params): + """ + Return a usable/locked/refundable balance of an account based on coinName. + usable_balance the balance that users are holding. + locked_balance when users transfer the coin,it will be locked until getting the Service Message Response. + refundable_balance refundable balance is the balance that will be refunded to users. + :param params: + :return: a record of (usable_balance, locked_balance, refundable_balance) + """ + sp.set_type(params, sp.TRecord(owner=sp.TAddress, coin_name=sp.TString)) + + # sending user_balance as 0 because in smartpy we cannot get Tez balance of address + locked_balance = sp.local("locked_balance", sp.nat(0)) + refundable_balance = sp.local("refundable_balance", sp.nat(0)) + + sp.if self.data.balances.contains(sp.record(address=params.owner, coin_name=params.coin_name)): + locked_balance.value = self.data.balances[ + sp.record(address=params.owner, coin_name=params.coin_name)].locked_balance + refundable_balance.value = self.data.balances[ + sp.record(address=params.owner, coin_name=params.coin_name)].refundable_balance + + with sp.if_(params.coin_name == self.data.native_coin_name): + sp.result(sp.record(usable_balance=sp.nat(0), + locked_balance=locked_balance.value, + refundable_balance=refundable_balance.value, + user_balance=sp.nat(0))) + with sp.else_(): + fa2_address = self.data.coins.get(params.coin_name) + user_balance= sp.view("balance_of", fa2_address, sp.record(owner=params.owner, token_id=sp.nat(0)), t=sp.TNat).open_some("Invalid view") + + allowance = sp.view("get_allowance", fa2_address, sp.record(spender=sp.self_address, owner=params.owner), t=sp.TNat).open_some("Invalid view") + usable_balance = sp.local("usable_balance", allowance, t=sp.TNat) + sp.if allowance > user_balance: + usable_balance.value = user_balance + + sp.result(sp.record(usable_balance=usable_balance.value, + locked_balance=locked_balance.value, + refundable_balance=refundable_balance.value, + user_balance=user_balance)) + + @sp.onchain_view() + def balance_of_batch(self, params): + """ + Return a list Balance of an account. + :param params: + :return: a record of (usableBalances, lockedBalances, refundableBalances) + """ + sp.set_type(params, sp.TRecord(owner=sp.TAddress, coin_names=sp.TList(sp.TString))) + + + sp.verify((sp.len(params.coin_names) > sp.nat(0)) & (sp.len(params.coin_names) <= self.MAX_BATCH_SIZE), message = "BatchMaxSizeExceed") + usable_balances =sp.local("usable_balances", {}, t=sp.TMap(sp.TNat, sp.TNat)) + locked_balances =sp.local("locked_balances", {}, t=sp.TMap(sp.TNat, sp.TNat)) + refundable_balances =sp.local("refundable_balances", {}, t=sp.TMap(sp.TNat, sp.TNat)) + user_balances =sp.local("user_balances", {}, t=sp.TMap(sp.TNat, sp.TNat)) + + i = sp.local("i", sp.nat(0)) + sp.for item in params.coin_names: + balance= sp.view("balance_of", sp.self_address, + sp.record(owner=params.owner, coin_name=item)).open_some() + usable_balances.value[i.value] = balance.usable_balance + locked_balances.value[i.value] = balance.locked_balance + refundable_balances.value[i.value] = balance.refundable_balance + user_balances.value[i.value] = balance.user_balance + i.value += sp.nat(1) + sp.result(sp.record(usable_balances=usable_balances.value, locked_balances=locked_balances.value, + refundable_balances=refundable_balances.value, user_balances=user_balances.value)) + + @sp.onchain_view() + def get_accumulated_fees(self): + """ + Return a map with record of accumulated Fees. + :return: An map of Asset + """ + + accumulated_fees = sp.local("accumulated_fees", sp.map(tkey=sp.TNat, tvalue=types.Types.Asset)) + i = sp.local("i", sp.nat(0)) + sp.for item in self.data.coins_name: + accumulated_fees.value[i.value] = sp.record(coin_name=item, value=self.data.aggregation_fee.get(item)) + i.value += sp.nat(1) + sp.result(accumulated_fees.value) + + @sp.entry_point(check_no_incoming_transfer=False) + def transfer_native_coin(self, to): + """ + Allow users to deposit `sp.amount` native coin into a BTSCore contract. + :param to: An address that a user expects to receive an amount of tokens. + :return: + """ + sp.set_type(to, sp.TString) + + amount_in_nat = sp.local("amount_in_nat", sp.utils.mutez_to_nat(sp.amount), t=sp.TNat) + # call check_transfer_restrictions on bts_periphery + check_transfer = sp.view("check_transfer_restrictions", self.data.bts_periphery_address.open_some("Address not set"), + sp.record(coin_name=self.data.native_coin_name, user=sp.sender, value=amount_in_nat.value), + t=sp.TBool).open_some() + sp.verify(check_transfer == True, "FailCheckTransfer") + + charge_amt = amount_in_nat.value * self.data.coin_details[self.data.native_coin_name].fee_numerator / self.FEE_DENOMINATOR + self.data.coin_details[self.data.native_coin_name].fixed_fee + #Confirm the type for this calculation + + self._send_service_message(sp.sender, to, self.data.native_coin_name, amount_in_nat.value, charge_amt) + + @sp.entry_point + def transfer(self, coin_name, value, to): + """ + Allow users to deposit an amount of wrapped native coin `coin_name` from the `sp.sender` address into the BTSCore contract. + :param coin_name: A given name of a wrapped coin + :param value: An amount request to transfer from a Requester (include fee) + :param to: Target BTP address. + :return: + """ + sp.set_type(coin_name, sp.TString) + sp.set_type(value, sp.TNat) + sp.set_type(to, sp.TString) + + sp.verify(coin_name != self.data.native_coin_name, message="InvalidWrappedCoin") + sp.verify(self.data.coins.contains(coin_name), message= "CoinNotRegistered") + fa2_address = self.data.coins[coin_name] + + # call check_transfer_restrictions on bts_periphery + check_transfer = sp.view("check_transfer_restrictions", self.data.bts_periphery_address.open_some("Address not set"), + sp.record(coin_name=coin_name, user=sp.sender, value=value), + t=sp.TBool).open_some() + sp.verify(check_transfer == True, "FailCheckTransfer") + + charge_amt = value * self.data.coin_details[coin_name].fee_numerator / self.FEE_DENOMINATOR + self.data.coin_details[coin_name].fixed_fee + + # call transfer from in FA2 + transfer_args_type = sp.TList(sp.TRecord(from_=sp.TAddress, txs=sp.TList(sp.TRecord( + to_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout(("to_", ("token_id", "amount")))) + ).layout(("from_", "txs"))) + transfer_entry_point = sp.contract(transfer_args_type, fa2_address, "transfer").open_some() + transfer_args = [sp.record(from_=sp.sender, txs=[sp.record(to_=sp.self_address, token_id=sp.nat(0), amount=value)])] + sp.transfer(transfer_args, sp.tez(0), transfer_entry_point) + + self._send_service_message(sp.sender, to, coin_name, value, charge_amt) + + def _send_service_message(self, _from, to, coin_name, value, charge_amt): + """ + This private function handles overlapping procedure before sending a service message to BTSPeriphery + :param _from: An address of a Requester + :param to: BTP address of of Receiver on another chain + :param coin_name: A given name of a requested coin + :param value: A requested amount to transfer from a Requester (include fee) + :param charge_amt: An amount being charged for this request + :return: + """ + sp.set_type(_from, sp.TAddress) + sp.set_type(to, sp.TString) + sp.set_type(coin_name, sp.TString) + sp.set_type(value, sp.TNat) + sp.set_type(charge_amt, sp.TNat) + + sp.verify(value > charge_amt, message = "ValueGreaterThan0") + self._lock_balance(_from, coin_name, value) + + coins = sp.local("coins", {sp.nat(0) : coin_name}, t=sp.TMap(sp.TNat, sp.TString)) + amounts = sp.local("amounts", {sp.nat(0) : sp.as_nat(value - charge_amt)}, t=sp.TMap(sp.TNat, sp.TNat)) + fees = sp.local("fees", {sp.nat(0): charge_amt}, t=sp.TMap(sp.TNat, sp.TNat)) + + # call send_service_message on bts_periphery + send_service_message_args_type = sp.TRecord(_from = sp.TAddress, to = sp.TString, coin_names = sp.TMap(sp.TNat, sp.TString), values = sp.TMap(sp.TNat, sp.TNat), fees = sp.TMap(sp.TNat, sp.TNat)) + send_service_message_entry_point = sp.contract(send_service_message_args_type, self.data.bts_periphery_address.open_some("Address not set"), "send_service_message").open_some() + send_service_message_args = sp.record(_from = _from, to = to, coin_names = coins.value, values = amounts.value, fees = fees.value) + sp.transfer(send_service_message_args, sp.tez(0), send_service_message_entry_point) + + @sp.entry_point(check_no_incoming_transfer=False) + def transfer_batch(self, coin_names, values, to): + """ + Allow users to transfer multiple coins/wrapped coins to another chain. + It MUST revert if the balance of the holder for token `_coinName` is lower than the `_value` sent. + In case of transferring a native coin, it also checks `msg.value` + The number of requested coins MUST be as the same as the number of requested values + The requested coins and values MUST be matched respectively + :param coin_names: A list of requested transferring wrapped coins + :param values: A list of requested transferring values respectively with its coin name + :param to: Target BTP address. + :return: + """ + sp.set_type(coin_names, sp.TMap(sp.TNat, sp.TString)) + sp.set_type(values, sp.TMap(sp.TNat, sp.TNat)) + sp.set_type(to, sp.TString) + + sp.verify(sp.len(coin_names) == sp.len(values), message ="InvalidRequest") + sp.verify(sp.len(coin_names) > sp.nat(0), message = "Zero length arguments") + + amount_in_nat = sp.local("amount_in_nat", sp.utils.mutez_to_nat(sp.amount), t=sp.TNat) + size = sp.local("size", sp.nat(0), t=sp.TNat) + with sp.if_(amount_in_nat.value != sp.nat(0)): + size.value = sp.len(coin_names) + sp.nat(1) + with sp.else_(): + size.value = sp.len(coin_names) + sp.verify(size.value <= self.MAX_BATCH_SIZE, message ="Batch maxSize Exceeds") + + coins = sp.local("_coins", {}, t=sp.TMap(sp.TNat, sp.TString)) + amounts = sp.local("_amounts", {}, t=sp.TMap(sp.TNat, sp.TNat)) + charge_amts = sp.local("_charge_amts", {}, t=sp.TMap(sp.TNat, sp.TNat)) + + # coin = sp.TRecord(addr=sp.TAddress, fee_numerator=sp.TNat, fixed_fee=sp.TNat, coin_type=sp.TNat) + coin_name = sp.local("coin_name", "", t= sp.TString) + value = sp.local("value", sp.nat(0), t= sp.TNat) + + sp.for i in sp.range(sp.nat(0), sp.len(coin_names)): + sp.verify(coin_names[i] != self.data.native_coin_name, message="InvalidCoin") + sp.verify(self.data.coins.contains(coin_names[i]), message= "CoinNotRegistered") + fa2_address = self.data.coins[coin_names[i]] + + coin_name.value = coin_names[i] + value.value = values[i] + sp.verify(value.value > sp.nat(0), message ="ZeroOrLess") + + # call check_transfer_restrictions on bts_periphery + check_transfer = sp.view("check_transfer_restrictions", self.data.bts_periphery_address.open_some("Address not set"), + sp.record(coin_name=coin_name.value, user=sp.sender, value=value.value), + t=sp.TBool).open_some() + sp.verify(check_transfer == True, "FailCheckTransfer") + + # call transfer from in FA2 + transfer_args_type = sp.TList(sp.TRecord(from_=sp.TAddress, txs=sp.TList(sp.TRecord( + to_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout(("to_", ("token_id", "amount")))) + ).layout(("from_", "txs"))) + transfer_entry_point = sp.contract(transfer_args_type, fa2_address, "transfer").open_some() + transfer_args = [ + sp.record(from_=sp.sender, txs=[sp.record(to_=sp.self_address, token_id=sp.nat(0), amount=value.value)])] + sp.transfer(transfer_args, sp.tez(0), transfer_entry_point) + + coin = sp.local("coin", self.data.coin_details[coin_name.value], t=Coin) + coins.value[i] = coin_name.value + charge_amts.value[i] = value.value * coin.value.fee_numerator / self.FEE_DENOMINATOR + coin.value.fixed_fee + amounts.value[i] = sp.as_nat(value.value - charge_amts.value[i]) + + self._lock_balance(sp.sender, coin_name.value, value.value) + + sp.if amount_in_nat.value !=sp.nat(0): + # call check_transfer_restrictions on bts_periphery + check_transfer = sp.view("check_transfer_restrictions", self.data.bts_periphery_address.open_some("Address not set"), + sp.record(coin_name=self.data.native_coin_name, user=sp.sender, value=amount_in_nat.value), + t=sp.TBool).open_some() + sp.verify(check_transfer == True, "FailCheckTransfer") + + coins.value[sp.as_nat(size.value - 1)] = self.data.native_coin_name + charge_amts.value[sp.as_nat(size.value - 1)] = amount_in_nat.value * self.data.coin_details[coin_name.value].fee_numerator\ + / self.FEE_DENOMINATOR + self.data.coin_details[coin_name.value].fixed_fee + amounts.value[sp.as_nat(size.value - 1)] = sp.as_nat(sp.utils.mutez_to_nat(sp.amount) - charge_amts.value[sp.as_nat(size.value - 1)]) + + self._lock_balance(sp.sender, self.data.native_coin_name, sp.utils.mutez_to_nat(sp.amount)) + + # call send_service_message on bts_periphery + send_service_message_args_type = sp.TRecord(_from=sp.TAddress, to=sp.TString, + coin_names=sp.TMap(sp.TNat, sp.TString), + values=sp.TMap(sp.TNat, sp.TNat), + fees=sp.TMap(sp.TNat, sp.TNat)) + send_service_message_entry_point = sp.contract(send_service_message_args_type, + self.data.bts_periphery_address.open_some("Address not set"), + "send_service_message").open_some() + send_service_message_args = sp.record(_from=sp.sender, to=to, coin_names=coins.value, values=amounts.value, + fees=charge_amts.value) + sp.transfer(send_service_message_args, sp.tez(0), send_service_message_entry_point) + + @sp.entry_point + #TODO: implement nonReentrant + def reclaim(self, coin_name, value): + """ + Reclaim the token's refundable balance by an owner. + The amount to claim must be smaller or equal than refundable balance + :param coin_name: A given name of coin + :param value: An amount of re-claiming tokens + :return: + """ + sp.set_type(coin_name, sp.TString) + sp.set_type(value, sp.TNat) + + sp.verify(self.data.balances[sp.record(address=sp.sender,coin_name=coin_name)].refundable_balance >= value, message="Imbalance") + self.data.balances[sp.record(address=sp.sender,coin_name=coin_name)].refundable_balance = sp.as_nat(self.data.balances[sp.record(address=sp.sender,coin_name=coin_name)].refundable_balance - value) + self.refund(sp.sender, coin_name, value) + + def refund(self, to, coin_name, value): + """ + + :param to: + :param coin_name: + :param value: + :return: + """ + sp.set_type(to, sp.TAddress) + sp.set_type(coin_name, sp.TString) + sp.set_type(value, sp.TNat) + + sp.verify(sp.sender == sp.self_address, message="Unauthorized") + + with sp.if_(coin_name == self.data.native_coin_name): + self.payment_transfer(to, value) + with sp.else_(): + # call transfer in FA2 + transfer_args_type = sp.TList(sp.TRecord(from_=sp.TAddress, txs=sp.TList(sp.TRecord( + to_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout(("to_", ("token_id", "amount")))) + ).layout(("from_", "txs"))) + transfer_entry_point = sp.contract(transfer_args_type, self.data.coins[coin_name], "transfer").open_some() + transfer_args = [sp.record(from_=sp.sender, txs=[sp.record(to_=to, token_id=sp.nat(0), amount=value)])] + sp.transfer(transfer_args, sp.tez(0), transfer_entry_point) + + def payment_transfer(self, to, amount): + sp.set_type(to, sp.TAddress) + sp.set_type(amount, sp.TNat) + + sp.send(to, sp.utils.nat_to_mutez(amount), message="PaymentFailed") + + @sp.entry_point + def mint(self, to, coin_name, value, callback): + """ + mint the wrapped coin. + + :param to: the account receive the minted coin + :param coin_name: coin name + :param value: the minted amount + :param callback: callback function type in bts_periphery + :return: + """ + sp.set_type(to, sp.TAddress) + sp.set_type(coin_name, sp.TString) + sp.set_type(value, sp.TNat) + sp.set_type(callback, sp.TContract(sp.TOption(sp.TString))) + + self.only_bts_periphery() + with sp.if_(coin_name == self.data.native_coin_name): + self.payment_transfer(to, value) + with sp.else_(): + with sp.if_(self.data.coin_details[coin_name].coin_type == self.NATIVE_WRAPPED_COIN_TYPE): + # call mint in FA2 + mint_args_type = sp.TList(sp.TRecord(to_=sp.TAddress, amount=sp.TNat).layout(("to_", "amount"))) + mint_entry_point = sp.contract(mint_args_type, self.data.coins[coin_name], "mint").open_some() + mint_args = [sp.record(to_=to, amount=value)] + sp.transfer(mint_args, sp.tez(0), mint_entry_point) + with sp.else_(): + sp.if self.data.coin_details[coin_name].coin_type == self.NON_NATIVE_TOKEN_TYPE: + # call transfer in FA2 + transfer_args_type = sp.TList(sp.TRecord(from_=sp.TAddress, txs=sp.TList(sp.TRecord( + to_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout(("to_", ("token_id", "amount")))) + ).layout(("from_", "txs"))) + transfer_entry_point = sp.contract(transfer_args_type, self.data.coins[coin_name], "transfer").open_some() + transfer_args = [sp.record(from_=sp.sender, txs=[sp.record(to_=to, token_id=sp.nat(0), amount=value)])] + sp.transfer(transfer_args, sp.tez(0), transfer_entry_point) + + sp.transfer(sp.some("success"), sp.tez(0), callback) + + @sp.entry_point + def callback(self, string, requester, coin_name, value): + sp.set_type(string, sp.TOption(sp.TString)) + sp.set_type(requester, sp.TAddress) + sp.set_type(coin_name, sp.TString) + sp.set_type(value, sp.TNat) + + sp.verify(sp.sender == self.data.coins[coin_name], "Unauthorized") + self.data.transfer_status = string + + with sp.if_(self.data.transfer_status.open_some() == "success"): + pass + with sp.else_(): + self.data.balances[sp.record(address=requester, coin_name=coin_name)].refundable_balance = \ + self.data.balances.get(sp.record(address=requester, coin_name=coin_name), + default_value=sp.record(locked_balance=sp.nat(0),refundable_balance=sp.nat(0)) + ).refundable_balance + value + self.data.transfer_status = sp.none + + @sp.entry_point + def handle_response_service(self, requester, coin_name, value, fee, rsp_code): + """ + Handle a response of a requested service. + :param requester: An address of originator of a requested service + :param coin_name: A name of requested coin + :param value: An amount to receive on a destination chain + :param fee: An amount of charged fee + :param rsp_code: + :return: + """ + sp.set_type(requester, sp.TAddress) + sp.set_type(coin_name, sp.TString) + sp.set_type(value, sp.TNat) + sp.set_type(fee, sp.TNat) + sp.set_type(rsp_code, sp.TNat) + + self.only_bts_periphery() + return_flag = sp.local("return_flag", False, t=sp.TBool) + sp.if requester == sp.self_address: + sp.if rsp_code == self.RC_ERR: + self.data.aggregation_fee[coin_name] = self.data.aggregation_fee.get(coin_name, + default_value=sp.nat(0)) + value + return_flag.value = True + + sp.if return_flag.value == False: + amount = sp.local("amount", value + fee, t=sp.TNat) + sp.if self.data.balances.contains(sp.record(address=requester, coin_name=coin_name)): + self.data.balances[sp.record(address=requester, coin_name=coin_name)].locked_balance = \ + sp.as_nat(self.data.balances.get(sp.record(address=requester, coin_name=coin_name), + default_value=sp.record(locked_balance=sp.nat(0), refundable_balance=sp.nat(0))).locked_balance - amount.value) + + sp.if rsp_code == self.RC_ERR: + with sp.if_(coin_name == self.data.native_coin_name): + with sp.if_(sp.utils.mutez_to_nat(sp.balance) >= value): + self.payment_transfer(requester, value) + with sp.else_(): + self.data.balances[sp.record(address=requester, coin_name=coin_name)].refundable_balance = self.data.balances.get( + sp.record(address=requester, coin_name=coin_name), + default_value=sp.record(locked_balance=sp.nat(0), refundable_balance=sp.nat(0))).refundable_balance + value + with sp.else_(): + # call transfer in FA2 + transfer_args_type = sp.TList(sp.TRecord( + callback=sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), requester=sp.TAddress, coin_name=sp.TString, value=sp.TNat)), + from_=sp.TAddress, + coin_name=sp.TString, + txs=sp.TList(sp.TRecord(to_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout(("to_", ("token_id", "amount")))) + ).layout((("from_", "coin_name"), ("callback", "txs")))) + transfer_entry_point = sp.contract(transfer_args_type, self.data.coins[coin_name], + "transfer_bts").open_some() + transfer_args = [ + sp.record(callback=sp.self_entry_point("callback"), from_=sp.self_address, coin_name=coin_name, txs=[sp.record(to_=requester, token_id=sp.nat(0), amount=value)])] + sp.transfer(transfer_args, sp.tez(0), transfer_entry_point) + + sp.if rsp_code == self.RC_OK: + fa2_address = self.data.coins[coin_name] + sp.if (coin_name != self.data.native_coin_name) & (self.data.coin_details[coin_name].coin_type == self.NATIVE_WRAPPED_COIN_TYPE): + # call burn in FA2 + burn_args_type = sp.TList(sp.TRecord(from_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout(("from_", ("token_id", "amount")))) + burn_entry_point = sp.contract(burn_args_type, fa2_address, "burn").open_some() + burn_args = [sp.record(from_=sp.self_address, token_id=sp.nat(0), amount=value)] + sp.transfer(burn_args, sp.tez(0), burn_entry_point) + + self.data.aggregation_fee[coin_name] = self.data.aggregation_fee.get(coin_name, default_value=sp.nat(0)) + fee + + @sp.entry_point + def transfer_fees(self, fa): + """ + Handle a request of Fee Gathering. Usage: Copy all charged fees to an array + :param fa: + :return: + """ + sp.set_type(fa, sp.TString) + + self.only_bts_periphery() + l = sp.local("l", sp.nat(0)) + sp.for item in self.data.coins_name: + sp.if self.data.aggregation_fee.get(item, default_value=sp.nat(0)) != sp.nat(0): + self.data.charged_coins[l.value] = item + self.data.charged_amounts[l.value] = self.data.aggregation_fee.get(item) + del self.data.aggregation_fee[item] + l.value += sp.nat(1) + + # call send_service_message on bts_periphery + send_service_message_args_type = sp.TRecord(_from=sp.TAddress, to=sp.TString, + coin_names=sp.TMap(sp.TNat, sp.TString), + values=sp.TMap(sp.TNat, sp.TNat), + fees=sp.TMap(sp.TNat, sp.TNat)) + send_service_message_entry_point = sp.contract(send_service_message_args_type, + self.data.bts_periphery_address.open_some("Address not set"), + "send_service_message").open_some() + send_service_message_args = sp.record(_from=sp.self_address, to=fa, coin_names=self.data.charged_coins, + values=self.data.charged_amounts, + fees=sp.map({})) + sp.transfer(send_service_message_args, sp.tez(0), send_service_message_entry_point) + + sp.for i in sp.range(0, sp.len(self.data.charged_coins)): + del self.data.charged_coins[i] + + sp.for i in sp.range(0, sp.len(self.data.charged_amounts)): + del self.data.charged_amounts[i] + + def _lock_balance(self, to, coin_name, value): + new_balance = self.data.balances.get(sp.record(address=to, coin_name=coin_name), + default_value=sp.record(locked_balance=sp.nat(0), + refundable_balance=sp.nat(0))) + self.data.balances[sp.record(address=to, coin_name=coin_name)] = sp.record( + locked_balance=new_balance.locked_balance + value, refundable_balance=new_balance.refundable_balance) + + @sp.entry_point + def update_coin_db(self): + self.only_owner() + self.data.coins[self.data.native_coin_name] = self.NATIVE_COIN_ADDRESS + self.data.coins_address[self.NATIVE_COIN_ADDRESS] = self.data.native_coin_name + self.data.coin_details[self.data.native_coin_name].addr = self.NATIVE_COIN_ADDRESS + + sp.for item in self.data.coins_name: + sp.if item != self.data.native_coin_name: + self.data.coins_address[self.data.coin_details[item].addr] = item + + @sp.entry_point + def set_bts_owner_manager(self, owner_manager): + sp.set_type(owner_manager, sp.TAddress) + + sp.verify(self.data.owners.get(sp.sender) == True , message= "Unauthorized") + self.data.bts_owner_manager = owner_manager + + +sp.add_compilation_target("bts_core", BTSCore( + owner_manager=sp.address("KT1MxuVecS7HRRRZrJM7juddJg1HZZ4SGA5B"), + _native_coin_name="btp-NetXnHfVqm9iesp.tezos-XTZ", + _fee_numerator=sp.nat(100), + _fixed_fee=sp.nat(450) +)) + + + + + + diff --git a/smartpy/bts/contracts/src/bts_owner_manager.py b/smartpy/bts/contracts/src/bts_owner_manager.py new file mode 100644 index 00000000..63429ba8 --- /dev/null +++ b/smartpy/bts/contracts/src/bts_owner_manager.py @@ -0,0 +1,70 @@ +import smartpy as sp + + +class BTSOwnerManager(sp.Contract): + def __init__(self, owner): + self.init( + owners=sp.map({owner: True}), + set_of_owners=sp.set([owner]) + ) + self.init_type(sp.TRecord( + owners=sp.TMap(sp.TAddress, sp.TBool), + set_of_owners=sp.TSet(sp.TAddress) + )) + + def only_owner(self): + sp.verify(self.data.owners[sp.sender] == True, message="Unauthorized") + + @sp.entry_point + def add_owner(self, owner): + """ + :param owner: address to set as owner + :return: + """ + sp.set_type(owner, sp.TAddress) + + self.only_owner() + sp.verify(self.data.owners[owner] == False, message="ExistedOwner") + + self.data.owners[owner] = True + self.data.set_of_owners.add(owner) + sp.emit(sp.record(sender=sp.sender, owner=owner), tag="NewOwnerAdded") + + @sp.entry_point + def remove_owner(self, owner): + """ + :param owner: address to remove as owner + :return: + """ + sp.set_type(owner, sp.TAddress) + + sp.verify(sp.len(self.data.set_of_owners.elements()) > 1, message="CannotRemoveMinOwner") + sp.verify(self.data.owners[owner] == True, message="NotOwner") + + del self.data.owners[owner] + self.data.set_of_owners.remove(owner) + sp.emit(sp.record(sender=sp.sender, owner=owner), tag="OwnerRemoved") + + @sp.onchain_view() + def is_owner(self, owner): + sp.result(self.data.owners[owner]) + + @sp.onchain_view() + def get_owners(self): + sp.result(self.data.set_of_owners.elements()) + + +@sp.add_test(name="BTSOwnerManager") +def test(): + alice = sp.test_account("Alice") + c1 = BTSOwnerManager(alice.address) + scenario = sp.test_scenario() + scenario.h1("BTSOwnerManager") + scenario += c1 + + scenario.verify(c1.is_owner(alice.address) == True) + + +sp.add_compilation_target("bts_owner_manager", BTSOwnerManager(owner=sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP"))) + + diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py new file mode 100644 index 00000000..a35cd555 --- /dev/null +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -0,0 +1,606 @@ +import smartpy as sp + +types = sp.io.import_script_from_url("file:./contracts/src/Types.py") +strings = sp.io.import_script_from_url("file:./contracts/src/String.py") +rlp_encode = sp.io.import_script_from_url("file:./contracts/src/RLP_encode_struct.py") +rlp_decode = sp.io.import_script_from_url("file:./contracts/src/RLP_decode_struct.py") + + +class BTPPreiphery(sp.Contract, rlp_decode.DecodeLibrary, rlp_encode.EncodeLibrary): + service_name = sp.string("bts") + + RC_OK = sp.nat(0) + RC_ERR = sp.nat(1) + UINT_CAP = sp.nat(115792089237316195423570985008687907853269984665640564039457584007913129639935) + + MAX_BATCH_SIZE = sp.nat(15) + + def __init__(self, bmc_address, bts_core_address, helper_contract, parse_address, native_coin_name, owner_address): + self.update_initial_storage( + bmc=bmc_address, + owner=owner_address, + bts_core=bts_core_address, + blacklist=sp.map(tkey=sp.TAddress, tvalue=sp.TBool), + token_limit=sp.map({native_coin_name : self.UINT_CAP}, tkey=sp.TString, tvalue=sp.TNat), + requests=sp.big_map(tkey=sp.TInt, tvalue=types.Types.PendingTransferCoin), + serial_no = sp.int(0), + number_of_pending_requests = sp.nat(0), + helper=helper_contract, + parse_contract=parse_address, + mint_status=sp.none + ) + + def only_bmc(self): + check_access = sp.local("check_access", "Unauthorized") + with sp.if_(sp.sender == self.data.bmc): + check_access.value = "Authorized" + return check_access.value + + def only_owner(self): + sp.verify(sp.sender == self.data.owner, "Unauthorized") + + def only_bts_core(self): + sp.verify(sp.sender == self.data.bts_core, "Unauthorized") + + @sp.entry_point + def set_helper_address(self, address): + sp.set_type(address, sp.TAddress) + self.only_owner() + self.data.helper = address + + @sp.entry_point + def set_parse_address(self, address): + sp.set_type(address, sp.TAddress) + self.only_owner() + self.data.parse_contract = address + + @sp.entry_point + def set_bmc_address(self, params): + sp.set_type(params, sp.TAddress) + self.only_owner() + self.data.bmc = params + + @sp.entry_point + def set_bts_core_address(self, params): + sp.set_type(params, sp.TAddress) + self.only_owner() + self.data.bts_core = params + + @sp.onchain_view() + def has_pending_request(self): + """ + + :return: boolean + """ + sp.result(self.data.number_of_pending_requests != sp.nat(0)) + + @sp.entry_point + def add_to_blacklist(self, params): + """ + + :param params: List of addresses to be blacklisted + :return: + """ + sp.set_type(params, sp.TMap(sp.TNat, sp.TString)) + sp.verify(sp.sender == sp.self_address, "Unauthorized") + sp.verify(sp.len(params) <= self.MAX_BATCH_SIZE, "BatchMaxSizeExceed") + + sp.for i in sp.range(sp.nat(0), sp.len(params)): + parsed_addr = sp.view("str_to_addr", self.data.parse_contract, params.get(i), t=sp.TAddress).open_some() + with sp.if_(parsed_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): + self.data.blacklist[parsed_addr] = True + with sp.else_(): + sp.failwith("InvalidAddress") + + # private function to return the tx status made from handle_btp_message + def _add_to_blacklist(self, params): + """ + :param params: List of addresses to be blacklisted + :return: + """ + sp.set_type(params, sp.TMap(sp.TNat, sp.TString)) + + add_blacklist_status = sp.local("add_blacklist_status", "") + with sp.if_(sp.len(params) <= self.MAX_BATCH_SIZE): + sp.for i in sp.range(sp.nat(0), sp.len(params)): + parsed_addr = sp.view("str_to_addr", self.data.parse_contract, params.get(i), t=sp.TAddress).open_some() + with sp.if_(parsed_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): + self.data.blacklist[parsed_addr] = True + add_blacklist_status.value = "success" + with sp.else_(): + add_blacklist_status.value = "InvalidAddress" + with sp.else_(): + add_blacklist_status.value = "error" + return add_blacklist_status.value + + @sp.entry_point + def remove_from_blacklist(self, params): + """ + :param params: list of address strings + :return: + """ + sp.set_type(params, sp.TMap(sp.TNat, sp.TString)) + + sp.verify(sp.sender == sp.self_address, "Unauthorized") + sp.verify(sp.len(params) <= self.MAX_BATCH_SIZE, "BatchMaxSizeExceed") + + sp.for i in sp.range(sp.nat(0), sp.len(params)): + parsed_addr = sp.view("str_to_addr", self.data.parse_contract, params.get(i), t=sp.TAddress).open_some() + with sp.if_(parsed_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): + sp.verify(self.data.blacklist.contains(parsed_addr), "UserNotFound") + sp.verify(self.data.blacklist.get(parsed_addr) == True, "UserNotBlacklisted") + del self.data.blacklist[parsed_addr] + with sp.else_(): + sp.failwith("InvalidAddress") + + # private function to return the tx status made from handle_btp_message + def _remove_from_blacklist(self, params): + """ + :param params: list of address strings + :return: + """ + sp.set_type(params, sp.TMap(sp.TNat, sp.TString)) + + remove_blacklist_status = sp.local("remove_blacklist_status", "") + with sp.if_(sp.len(params) <= self.MAX_BATCH_SIZE): + sp.for i in sp.range(sp.nat(0), sp.len(params)): + parsed_addr = sp.view("str_to_addr", self.data.parse_contract, params.get(i), t=sp.TAddress).open_some() + with sp.if_(parsed_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): + with sp.if_(self.data.blacklist.contains(parsed_addr)): + del self.data.blacklist[parsed_addr] + remove_blacklist_status.value = "success" + with sp.else_(): + remove_blacklist_status.value = "UserNotBlacklisted" + with sp.else_(): + remove_blacklist_status.value = "InvalidAddress" + with sp.else_(): + remove_blacklist_status.value = "error" + return remove_blacklist_status.value + + @sp.entry_point + def set_token_limit(self, coin_names, token_limit): + """ + :param coin_names: list of coin names + :param token_limit: list of token limits + :return: + """ + sp.set_type(coin_names, sp.TMap(sp.TNat, sp.TString)) + sp.set_type(token_limit, sp.TMap(sp.TNat, sp.TNat)) + + sp.verify((sp.sender == sp.self_address )| (sp.sender == self.data.bts_core), "Unauthorized") + sp.verify(sp.len(coin_names) == sp.len(token_limit), "InvalidParams") + sp.verify(sp.len(coin_names) <= self.MAX_BATCH_SIZE, "BatchMaxSizeExceed") + + sp.for i in sp.range(0, sp.len(coin_names)): + self.data.token_limit[coin_names[i]] = token_limit.get(i) + + # private function to return the tx status made from handle_btp_message + def _set_token_limit(self, coin_names, token_limit): + """ + :param coin_names: list of coin names + :param token_limit: list of token limits + :return: + """ + sp.set_type(coin_names, sp.TMap(sp.TNat, sp.TString)) + sp.set_type(token_limit, sp.TMap(sp.TNat, sp.TNat)) + + set_limit_status = sp.local("set_limit_status", "") + with sp.if_((sp.len(coin_names) == sp.len(token_limit)) & (sp.len(coin_names) <= self.MAX_BATCH_SIZE)): + sp.for i in sp.range(0, sp.len(coin_names)): + self.data.token_limit[coin_names[i]] = token_limit.get(i) + set_limit_status.value = "success" + with sp.else_(): + set_limit_status.value = "error" + return set_limit_status.value + + @sp.entry_point + def send_service_message(self, _from, to, coin_names, values, fees): + """ + Send service message to BMC + :param _from: from address + :param to: to address + :param coin_names: + :param values: + :param fees: + :return: + """ + + sp.set_type(_from, sp.TAddress) + sp.set_type(to, sp.TString) + sp.set_type(coin_names, sp.TMap(sp.TNat, sp.TString)) + sp.set_type(values, sp.TMap(sp.TNat, sp.TNat)) + sp.set_type(fees, sp.TMap(sp.TNat, sp.TNat)) + + self.only_bts_core() + + to_network, to_address = sp.match_pair(strings.split_btp_address(to)) + + assets = sp.compute(sp.map(tkey=sp.TNat, tvalue=types.Types.Asset)) + assets_details = sp.compute(sp.map(tkey=sp.TNat, tvalue=types.Types.AssetTransferDetail)) + sp.for i in sp.range(sp.nat(0), sp.len(coin_names)): + assets[i]=sp.record( + coin_name=coin_names[i], + value=values[i] + ) + assets_details[i] = sp.record( + coin_name=coin_names[i], + value=values[i], + fee=fees[i] + ) + + self.data.serial_no += 1 + + start_from = sp.view("add_to_str", self.data.parse_contract, _from, t=sp.TString).open_some() + + send_message_args_type = sp.TRecord(to=sp.TString, svc=sp.TString, sn=sp.TInt, msg=sp.TBytes) + send_message_entry_point = sp.contract(send_message_args_type, self.data.bmc, "send_message").open_some() + send_message_args = sp.record( + to=to_network, svc=self.service_name, sn=self.data.serial_no, + msg=self.encode_service_message(sp.compute(sp.record(service_type_value=sp.nat(0), + data=self.encode_transfer_coin_msg(sp.compute(sp.record(from_addr=start_from, to=to_address, assets=assets))) + ) + ) + ) + ) + sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) + + # push pending tx into record list + self.data.requests[self.data.serial_no] = sp.record( + from_=start_from, to=to, coin_names=coin_names, amounts=values, fees=fees + ) + self.data.number_of_pending_requests +=sp.nat(1) + sp.emit(sp.record(from_address=_from, to=to, serial_no=self.data.serial_no, assets_details=assets_details), tag="TransferStart") + + + @sp.entry_point + def handle_btp_message(self, _from, svc, sn, msg, callback, bsh_addr, prev, callback_msg): + """ + BSH handle BTP message from BMC contract + :param _from: An originated network address of a request + :param svc: A service name of BSH contract + :param sn: A serial number of a service request + :param msg: An RLP message of a service request/service response + :param callback: callback function type in bmc_periphery + :param bsh_addr: param for callback function in bmc_periphery + :param prev: param for callback function in bmc_periphery + :param callback_msg: param for callback function in bmc_periphery + :return: + """ + + sp.set_type(_from, sp.TString) + sp.set_type(svc, sp.TString) + sp.set_type(sn, sp.TInt) + sp.set_type(msg, sp.TBytes) + sp.set_type(callback, sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress, prev=sp.TString, callback_msg=sp.TRecord( + src=sp.TString, dst=sp.TString, svc=sp.TString, sn=sp.TInt, message=sp.TBytes) + ))) + sp.set_type(bsh_addr, sp.TAddress) + + check_caller = self.only_bmc() + + callback_string = sp.local("callback_string", "") + with sp.if_((svc == self.service_name) & (check_caller == "Authorized")): + err_msg = sp.local("error", "") + sm = self.decode_service_message(msg) + + service_type_variant_match = sp.local("serviceType_variant", False, t=sp.TBool) + with sm.serviceType.match_cases() as arg: + with arg.match("REQUEST_COIN_TRANSFER") as a1: + service_type_variant_match.value = True + callback_string.value = "success" + tc = self.decode_transfer_coin_msg(sm.data) + parsed_addr = sp.view("str_to_addr", self.data.parse_contract, tc.to, t=sp.TAddress).open_some() + + with sp.if_(parsed_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): + handle_request_call = self._handle_request_service(tc.to, tc.assets) + with sp.if_(handle_request_call == "success"): + self.send_response_message(sp.variant("RESPONSE_HANDLE_SERVICE", 2), sp.nat(2), _from, sn, "", self.RC_OK) + sp.emit(sp.record(from_address=_from, to=parsed_addr, serial_no=self.data.serial_no, assets_details=tc.assets), tag="TransferReceived") + with sp.else_(): + err_msg.value = handle_request_call + self.send_response_message(sp.variant("RESPONSE_HANDLE_SERVICE", 2), sp.nat(2), _from, sn, err_msg.value, + self.RC_ERR) + with sp.else_(): + err_msg.value = "InvalidAddress" + self.send_response_message(sp.variant("RESPONSE_HANDLE_SERVICE", 2), sp.nat(2), _from, sn, err_msg.value, self.RC_ERR) + + with arg.match("BLACKLIST_MESSAGE") as a2: + service_type_variant_match.value = True + callback_string.value = "success" + bm = self.decode_blacklist_msg(sm.data) + addresses = bm.addrs + + blacklist_service_called = sp.local("blacklist_service", False, t=sp.TBool) + with bm.serviceType.match_cases() as b_agr: + with b_agr.match("ADD_TO_BLACKLIST") as b_val_1: + blacklist_service_called.value = True + + add_blacklist_call = self._add_to_blacklist(addresses) + with sp.if_(add_blacklist_call == "success"): + self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, sn, "AddedToBlacklist", self.RC_OK) + with sp.else_(): + self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, sn, "ErrorAddToBlackList", self.RC_ERR) + + with b_agr.match("REMOVE_FROM_BLACKLIST") as b_val_2: + blacklist_service_called.value = True + + remove_blacklist_call = self._remove_from_blacklist(addresses) + with sp.if_(remove_blacklist_call == "success"): + self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, sn, "RemovedFromBlacklist", self.RC_OK) + with sp.else_(): + self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, sn, "ErrorRemoveFromBlackList", self.RC_ERR) + + sp.if blacklist_service_called.value == False: + self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, sn, "BlacklistServiceTypeErr", self.RC_ERR) + + with arg.match("CHANGE_TOKEN_LIMIT") as a3: + service_type_variant_match.value = True + callback_string.value = "success" + tl = self.decode_token_limit_msg(sm.data) + coin_names = tl.coin_name + token_limits = tl.token_limit + + set_limit_call = self._set_token_limit(coin_names, token_limits) + with sp.if_(set_limit_call == "success"): + self.send_response_message(sp.variant("CHANGE_TOKEN_LIMIT", 4), sp.nat(4), _from, sn, "ChangeTokenLimit", self.RC_OK) + with sp.else_(): + self.send_response_message(sp.variant("CHANGE_TOKEN_LIMIT", 4), sp.nat(4), _from, sn, "ErrorChangeTokenLimit", self.RC_ERR) + + with arg.match("RESPONSE_HANDLE_SERVICE") as a4: + service_type_variant_match.value = True + with sp.if_(sp.len(sp.pack(self.data.requests.get(sn).from_)) != 0): + response = self.decode_response(sm.data) + handle_response = self.handle_response_service(sn, response.code, response.message) + with sp.if_(handle_response == "success"): + callback_string.value = "success" + with sp.else_(): + callback_string.value = "fail" + with sp.else_(): + callback_string.value = "InvalidSN" + with arg.match("UNKNOWN_TYPE") as a5: + service_type_variant_match.value = True + callback_string.value = "success" + sp.emit(sp.record(_from=_from, sn=sn), tag= "UnknownResponse") + + sp.if service_type_variant_match.value == False: + callback_string.value = "success" + self.send_response_message(sp.variant("UNKNOWN_TYPE", 5), sp.nat(5), _from, sn, "Unknown",self.RC_ERR) + with sp.else_(): + callback_string.value = "fail" + + return_value = sp.record(string=sp.some(callback_string.value), bsh_addr=bsh_addr, prev=prev, + callback_msg=callback_msg) + sp.transfer(return_value, sp.tez(0), callback) + + @sp.entry_point + def handle_btp_error(self, svc, sn, code, msg, callback, bsh_addr): + """ + BSH handle BTP Error from BMC contract + :param svc: A service name of BSH contract + :param sn: A serial number of a service request + :param code: A response code of a message (RC_OK / RC_ERR) + :param msg: A response message + :param callback: callback function type in bmc_periphery + :param bsh_addr: param for callback function in bmc_periphery + :return: + """ + + sp.set_type(svc, sp.TString) + sp.set_type(sn, sp.TInt) + sp.set_type(code, sp.TNat) + sp.set_type(msg, sp.TString) + sp.set_type(callback, sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress,svc=sp.TString, sn=sp.TInt, code=sp.TNat, msg=sp.TString))) + sp.set_type(bsh_addr, sp.TAddress) + + check_caller = self.only_bmc() + handle_btp_error_status = sp.local("handle_btp_error_statue", "") + with sp.if_((svc == self.service_name) & (check_caller == "Authorized") & (sp.len(sp.pack(self.data.requests.get(sn).from_)) != 0)): + emit_msg= sp.concat(["errCode: ", sp.view("string_of_int", self.data.parse_contract, sp.to_int(code), t=sp.TString).open_some(),", errMsg: ", msg]) + handle_response_serv = self.handle_response_service(sn, self.RC_ERR, emit_msg) + with sp.if_(handle_response_serv == "success"): + handle_btp_error_status.value = "success" + with sp.else_(): + handle_btp_error_status.value = "fail" + + return_value = sp.record(string=sp.some(handle_btp_error_status.value), bsh_addr=bsh_addr, svc=svc, sn=sn, code=code, msg=msg) + sp.transfer(return_value, sp.tez(0), callback) + + def handle_response_service(self, sn, code, msg): + """ + + :param sn: + :param code: + :param msg: + :return: + """ + sp.set_type(sn, sp.TInt) + sp.set_type(code, sp.TNat) + sp.set_type(msg, sp.TString) + + caller = sp.local("caller", sp.view("str_to_addr", self.data.parse_contract, self.data.requests.get(sn).from_, t=sp.TAddress).open_some() + , sp.TAddress).value + loop = sp.local("loop", sp.len(self.data.requests.get(sn).coin_names), sp.TNat).value + response_call_status = sp.local("response_call_status", "") + with sp.if_(loop <= self.MAX_BATCH_SIZE): + sp.for i in sp.range(0, loop): + # inter score call + handle_response_service_args_type = sp.TRecord( + requester=sp.TAddress, coin_name=sp.TString, value=sp.TNat, fee=sp.TNat, rsp_code=sp.TNat + ) + handle_response_service_entry_point = sp.contract(handle_response_service_args_type, self.data.bts_core, "handle_response_service").open_some("invalid call") + handle_response_service_args = sp.record( + requester=caller, coin_name=self.data.requests.get(sn).coin_names.get(i), value=self.data.requests.get(sn).amounts.get(i), + fee=self.data.requests.get(sn).fees.get(i), rsp_code=code + ) + sp.transfer(handle_response_service_args, sp.tez(0), handle_response_service_entry_point) + + del self.data.requests[sn] + self.data.number_of_pending_requests = sp.as_nat(self.data.number_of_pending_requests-1) + + sp.emit(sp.record(caller=caller, sn=sn, code=code, msg=msg), tag="TransferEnd") + response_call_status.value = "success" + with sp.else_(): + response_call_status.value = "BatchMaxSizeExceed" + return response_call_status.value + + @sp.entry_point + def callback_mint(self, string): + sp.set_type(string, sp.TOption(sp.TString)) + + sp.verify(sp.sender == self.data.bts_core, "Unauthorized") + self.data.mint_status = string + + sp.verify(self.data.mint_status.open_some() == "success", "TransferFailed") + self.data.mint_status = sp.none + + def _handle_request_service(self, to, assets): + """ + Handle a list of minting/transferring coins/tokens + :param to: An address to receive coins/tokens + :param assets: A list of requested coin respectively with an amount + :return: + """ + sp.set_type(to, sp.TString) + sp.set_type(assets, sp.TMap(sp.TNat, types.Types.Asset)) + + status = sp.local("status", "error") + with sp.if_(sp.len(assets) <= self.MAX_BATCH_SIZE): + parsed_to = sp.view("str_to_addr", self.data.parse_contract, to, t=sp.TAddress).open_some() + sp.for i in sp.range(0, sp.len(assets)): + valid_coin = sp.view("is_valid_coin", self.data.bts_core, assets[i].coin_name, t=sp.TBool).open_some() + + with sp.if_(valid_coin == True): + check_transfer = sp.view("check_transfer_restrictions", sp.self_address, sp.record( + coin_name=assets[i].coin_name, user=parsed_to, value=assets[i].value), t=sp.TBool).open_some() + with sp.if_(check_transfer == True): + # inter score call + mint_args_type = sp.TRecord(callback=sp.TContract(sp.TOption(sp.TString)), + to=sp.TAddress, coin_name=sp.TString, value=sp.TNat + ) + mint_args_type_entry_point = sp.contract(mint_args_type, self.data.bts_core, "mint").open_some() + mint_args = sp.record(callback=sp.self_entry_point("callback_mint"), + to=parsed_to, coin_name=assets[i].coin_name, value=assets[i].value + ) + sp.transfer(mint_args, sp.tez(0), mint_args_type_entry_point) + status.value = "success" + with sp.else_(): + status.value = "FailCheckTransfer" + with sp.else_(): + status.value = "UnregisteredCoin" + with sp.else_(): + status.value = "BatchMaxSizeExceed" + + return status.value + + @sp.entry_point + def handle_request_service(self, to, assets): + """ + Handle a list of minting/transferring coins/tokens + :param to: An address to receive coins/tokens + :param assets: A list of requested coin respectively with an amount + :return: + """ + sp.set_type(to, sp.TString) + sp.set_type(assets, sp.TMap(sp.TNat, types.Types.Asset)) + + sp.verify(sp.sender == sp.self_address, "Unauthorized") + sp.verify(sp.len(assets) <= self.MAX_BATCH_SIZE, "BatchMaxSizeExceed") + + parsed_to = sp.view("str_to_addr", self.data.parse_contract, to, t=sp.TAddress).open_some() + sp.for i in sp.range(0, sp.len(assets)): + valid_coin = sp.view("is_valid_coin", self.data.bts_core, assets[i].coin_name, t=sp.TBool).open_some() + sp.verify(valid_coin == True, "UnregisteredCoin") + + check_transfer = sp.view("check_transfer_restrictions", sp.self_address, sp.record( + coin_name=assets[i].coin_name,user=parsed_to, value=assets[i].value), t=sp.TBool).open_some() + sp.verify(check_transfer == True, "FailCheckTransfer") + + # inter score call + mint_args_type = sp.TRecord(to=sp.TAddress, coin_name=sp.TString, value=sp.TNat + ) + mint_args_type_entry_point = sp.contract(mint_args_type, self.data.bts_core, "mint").open_some() + mint_args = sp.record( + to=parsed_to, coin_name=assets[i].coin_name, value=assets[i].value + ) + sp.transfer(mint_args, sp.tez(0), mint_args_type_entry_point) + + + def send_response_message(self, service_type, service_type_val, to, sn, msg, code): + """ + + :param service_type: + :param service_type_val: value of service_type variant + :param to: + :param sn: + :param msg: + :param code: + :return: + """ + sp.set_type(service_type, types.Types.ServiceType) + sp.set_type(service_type_val, sp.TNat) + sp.set_type(to, sp.TString) + sp.set_type(sn, sp.TInt) + sp.set_type(msg, sp.TString) + sp.set_type(code, sp.TNat) + + send_message_args_type = sp.TRecord( + to=sp.TString, svc=sp.TString, sn=sp.TInt, msg=sp.TBytes + ) + send_message_entry_point = sp.contract(send_message_args_type, self.data.bmc, "send_message").open_some() + send_message_args = sp.record(to=to, svc=self.service_name, sn=sn, + msg=self.encode_service_message(sp.record(service_type_value=service_type_val, data=self.encode_response(sp.record(code=code, message=msg)))) + ) + sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) + + + @sp.entry_point + def handle_fee_gathering(self, fa, svc, callback, bsh_addr): + """ + BSH handle Gather Fee Message request from BMC contract + :param fa: A BTP address of fee aggregator + :param svc: A name of the service + :param callback: callback function type in bmc_periphery + :param bsh_addr: address of bts_periphery + :return: + """ + sp.set_type(fa, sp.TString) + sp.set_type(svc, sp.TString) + sp.set_type(callback, sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress))) + sp.set_type(bsh_addr, sp.TAddress) + + check_caller = self.only_bmc() + with sp.if_((svc == self.service_name) & (check_caller == "Authorized")): + strings.split_btp_address(fa) + + # call transfer_fees of BTS_Core + transfer_fees_args_type = sp.TString + transfer_fees_entry_point = sp.contract(transfer_fees_args_type, self.data.bts_core, "transfer_fees").open_some() + sp.transfer(fa, sp.tez(0), transfer_fees_entry_point) + + sp.transfer(sp.record(string=sp.some("success"), bsh_addr=bsh_addr), sp.tez(0), callback) + with sp.else_(): + sp.transfer(sp.record(string=sp.some("fail"), bsh_addr=bsh_addr), sp.tez(0), callback) + + @sp.onchain_view() + def check_transfer_restrictions(self, params): + """ + + :param params: Record of coin transfer details + :return: + """ + sp.set_type(params, sp.TRecord(coin_name=sp.TString, user=sp.TAddress, value=sp.TNat)) + + with sp.if_((self.data.blacklist.contains(params.user) == False) & + (self.data.token_limit.get(params.coin_name, default_value=sp.nat(0)) >= params.value)): + sp.result(True) + with sp.else_(): + sp.result(False) + + + +sp.add_compilation_target("bts_periphery", BTPPreiphery(bmc_address=sp.address("KT1UrLqhQHDC3mJw9BUrqsiix7JRbxTsvWJu"), + bts_core_address=sp.address("KT1JAippuMfS6Bso8DGmigmTdkgEZUxQxYyX"), + helper_contract=sp.address("KT1HwFJmndBWRn3CLbvhUjdupfEomdykL5a6"), + parse_address=sp.address("KT1EKPrSLWjWViZQogFgbc1QmztkR5UGXEWa"), + native_coin_name="btp-NetXnHfVqm9iesp.tezos-XTZ", + owner_address = sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP")) ) \ No newline at end of file diff --git a/smartpy/bts/contracts/src/helper.py b/smartpy/bts/contracts/src/helper.py new file mode 100644 index 00000000..94d220c8 --- /dev/null +++ b/smartpy/bts/contracts/src/helper.py @@ -0,0 +1,77 @@ +import smartpy as sp + +Utils = sp.io.import_script_from_url("https://raw.githubusercontent.com/Acurast/acurast-hyperdrive/main/contracts/tezos/libs/utils.py") + + +class Helper(sp.Contract): + def __init__(self): + self.init() + + @sp.onchain_view() + def decode_string(self, params): + sp.set_type(params, sp.TBytes) + decode_string = sp.build_lambda(Utils.RLP.Decoder.decode_string) + sp.result(decode_string(params)) + + @sp.onchain_view() + def prefix_length(self, params): + sp.set_type(params, sp.TBytes) + prefix_length = sp.build_lambda(Utils.RLP.Decoder.prefix_length) + sp.result(prefix_length(params)) + + @sp.onchain_view() + def decode_list(self, params): + sp.set_type(params, sp.TBytes) + decode_list = sp.build_lambda(Utils.RLP.Decoder.decode_list) + sp.result(decode_list(params)) + + @sp.onchain_view() + def is_list(self, params): + sp.set_type(params, sp.TBytes) + is_list = sp.build_lambda(Utils.RLP.Decoder.is_list) + sp.result(is_list(params)) + + @sp.onchain_view() + def of_string(self, params): + sp.set_type(params, sp.TString) + encode_string_packed = sp.build_lambda(Utils.Bytes.of_string) + sp.result(encode_string_packed(params)) + + @sp.onchain_view() + def encode_string(self, params): + sp.set_type(params, sp.TString) + encode_string_packed = sp.build_lambda(Utils.RLP.Encoder.encode_string) + sp.result(encode_string_packed(params)) + + @sp.onchain_view() + def encode_nat(self, params): + sp.set_type(params, sp.TNat) + encode_nat_packed = sp.build_lambda(Utils.RLP.Encoder.encode_nat) + sp.result(encode_nat_packed(params)) + + @sp.onchain_view() + def of_nat(self, params): + sp.set_type(params, sp.TNat) + encode_nat_packed = sp.build_lambda(Utils.Bytes.of_nat) + sp.result(encode_nat_packed(params)) + + @sp.onchain_view() + def with_length_prefix(self, params): + sp.set_type(params, sp.TBytes) + encode_length_packed = sp.build_lambda(Utils.RLP.Encoder.with_length_prefix) + sp.result(encode_length_packed(params)) + + @sp.onchain_view() + def without_length_prefix(self, params): + sp.set_type(params, sp.TBytes) + decode = sp.build_lambda(Utils.RLP.Decoder.without_length_prefix) + sp.result(decode(params)) + + @sp.onchain_view() + def encode_list(self, params): + sp.set_type(params, sp.TList(sp.TBytes)) + encode_list_packed = sp.build_lambda(Utils.RLP.Encoder.encode_list) + sp.result(encode_list_packed(params)) + + +sp.add_compilation_target("helper", Helper()) \ No newline at end of file diff --git a/smartpy/bts/contracts/src/parse_address.py b/smartpy/bts/contracts/src/parse_address.py new file mode 100644 index 00000000..60a631ab --- /dev/null +++ b/smartpy/bts/contracts/src/parse_address.py @@ -0,0 +1,192 @@ +import smartpy as sp +Utils = sp.io.import_script_from_url("https://raw.githubusercontent.com/RomarQ/tezos-sc-utils/main/smartpy/utils.py") + + +class ParseAddress(sp.Contract): + tz_prefixes = sp.map({ + sp.bytes('0x0000'): sp.string('tz1'), + sp.bytes('0x0001'): sp.string('tz2'), + sp.bytes('0x0002'): sp.string('tz3'), + sp.bytes('0x0003'): sp.string('tz4') + }) + base58_encodings = sp.list([ + sp.map({"prefix": "tz1", "elem1": "6", "elem2": "161", "elem3": "159", "len": "20"}), + sp.map({"prefix": "tz2", "elem1": "6", "elem2": "161", "elem3": "161", "len": "20"}), + sp.map({"prefix": "tz3", "elem1": "6", "elem2": "161", "elem3": "164", "len": "20"}), + sp.map({"prefix": "tz4", "elem1": "6", "elem2": "161", "elem3": "16", "len": "20"}), + sp.map({"prefix": "KT1", "elem1": "2", "elem2": "90", "elem3": "121", "len": "20"}), + ]) + + def __init__(self): + self.init() + + def unforge_address(self, data): + """Decode address or key_hash from bytes. + + :param data: encoded address or key_hash + :returns: base58 encoded address + """ + sp.set_type(data, sp.TBytes) + byt = sp.slice(data, 6, 22).open_some() + prefix = sp.slice(byt, 0, 2).open_some() + starts_with = sp.slice(byt, 0, 1).open_some() + ends_with = sp.slice(byt, 21, 1).open_some() + sliced_byte = sp.slice(byt, 1, 20).open_some() + local_byte = sp.local("local_byte", sp.bytes("0x")) + return_value = sp.local("return_value", "tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg", sp.TString) + + sp.for item in self.tz_prefixes.items(): + sp.if item.key == prefix: + return_value.value = self.base58_encode(sp.slice(byt, 2, 20).open_some(), Utils.Bytes.of_string(item.value), local_byte) + + sp.if (starts_with == sp.bytes("0x01")) & (ends_with == sp.bytes("0x00")): + return_value.value = self.base58_encode(sliced_byte, Utils.Bytes.of_string("KT1"), local_byte) + sp.if (starts_with == sp.bytes("0x02")) & (ends_with == sp.bytes("0x00")): + return_value.value = self.base58_encode(sliced_byte, Utils.Bytes.of_string("txr1"), local_byte) + sp.if (starts_with == sp.bytes("0x03")) & (ends_with == sp.bytes("0x00")): + return_value.value = self.base58_encode(sliced_byte, Utils.Bytes.of_string("sr1"), local_byte) + + return return_value.value + + def tb(self, _list): + byte_str = sp.local("byte_str", sp.bytes("0x")) + sp.for num in _list: + byte_str.value += Utils.Bytes.of_nat(num) + return byte_str.value + + def base58_encode(self, byt_array, prefix, _byte): + """ + Encode data using Base58 with checksum and add an according binary prefix in the end. + :param byt_array: Array of bytes + :param prefix: Human-readable prefix (use b'') e.g. b'tz', b'KT', etc + :param local_byte: local variable + + :returns: bytes (use string.decode()) + """ + length_v = sp.to_int(sp.len(byt_array)) + encoding = sp.local("encode", sp.map({})) + byte_from_tbl = sp.local("byte_from_tbl", sp.bytes("0x")) + byte_value = _byte + + sp.for enc in self.base58_encodings: + sp.if (length_v == Utils.Int.of_string(enc["len"])) & (prefix == Utils.Bytes.of_string(enc["prefix"])): + encoding.value = enc + byte_from_tbl.value = self.tb([sp.as_nat(Utils.Int.of_string(enc["elem1"])), + sp.as_nat(Utils.Int.of_string(enc["elem2"])), + sp.as_nat(Utils.Int.of_string(enc["elem3"]))]) + sha256_encoding = sp.sha256(sp.sha256(byte_from_tbl.value + byt_array)) + sha256_encoding = byte_from_tbl.value + byt_array + sp.slice(sha256_encoding, 0, 4).open_some() + acc = sp.local("for_while_loop", Utils.Int.of_bytes(sha256_encoding)) + alphabet = Utils.Bytes.of_string("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") + base = 58 + sp.while acc.value > 0: + (acc.value, idx) = sp.match_pair(sp.ediv(acc.value, base).open_some()) + byte_value.value = sp.slice(alphabet, idx, 1).open_some() + byte_value.value + + return sp.unpack(sp.bytes("0x050100000024") + byte_value.value, sp.TString).open_some() + + @sp.onchain_view() + def add_to_str(self, params): + sp.set_type(params, sp.TAddress) + sp.result(self.unforge_address(sp.pack(params))) + + def _to_addr(self, params): + string_in_bytes = sp.pack(params) + actual_prefix = sp.local("actual_prefix", "") + addr = sp.local("addr", sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")) + alphabet = Utils.Bytes.of_string("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") + sp.if sp.len(string_in_bytes) == sp.nat(42): + string_in_bytes = sp.slice(string_in_bytes, 6, 36).open_some() + element_list = sp.range(0, sp.len(alphabet), 1) + temp_map = sp.local("temp_map", {}) + temp_var = sp.local("y", 0) + sp.for elem in element_list: + temp_var.value = elem + temp_map.value[sp.slice(alphabet, temp_var.value, 1).open_some()] = temp_var.value + decimal = sp.local("decimal", 0) + base = sp.len(alphabet) + element_list_2 = sp.range(0, sp.len(string_in_bytes), 1) + + sp.for elem in element_list_2: + decimal.value = decimal.value * base + temp_map.value[sp.slice(string_in_bytes, elem, 1).open_some()] + byt_value = Utils.Bytes.of_nat(sp.as_nat(sp.to_int(decimal.value))) + new_byt_value = sp.slice(byt_value, 0, sp.as_nat(sp.len(byt_value) - 4)).open_some() + prefix = sp.slice(new_byt_value, 0, 3).open_some() + prefix_len = sp.range(0, sp.len(prefix), 1) + temp_var3 = sp.local("z", 0) + list_string = sp.local("list_string", []) + sp.for x in prefix_len: + temp_var3.value = x + list_string.value.push(Utils.Int.of_bytes(sp.slice(prefix, temp_var3.value, 1).open_some())) + value = sp.slice(new_byt_value, 3, sp.as_nat(sp.len(new_byt_value) - 3)) + byte_local = sp.local("byt_old", sp.bytes("0x")) + + sp.for enc in self.base58_encodings: + byte_local.value = self.tb([sp.as_nat(Utils.Int.of_string(enc["elem1"])), + sp.as_nat(Utils.Int.of_string(enc["elem2"])), + sp.as_nat(Utils.Int.of_string(enc["elem3"]))]) + sp.if byte_local.value == prefix: + actual_prefix.value = enc["prefix"] + + sp.for item in self.tz_prefixes.items(): + sp.if item.value == actual_prefix.value: + decoded_address = sp.unpack(sp.bytes("0x050a00000016") + item.key + value.open_some(), + sp.TAddress) + addr.value = decoded_address.open_some() + sp.if actual_prefix.value == "KT1": + decoded_address = sp.unpack( + sp.bytes("0x050a00000016") + sp.bytes("0x01") + value.open_some() + sp.bytes("0x00"), + sp.TAddress) + addr.value = decoded_address.open_some() + sp.if actual_prefix.value == "txr1": + decoded_address = sp.unpack( + sp.bytes("0x050a00000016") + sp.bytes("0x02") + value.open_some() + sp.bytes("0x00"), + sp.TAddress) + addr.value = decoded_address.open_some() + sp.if actual_prefix.value == "sr1": + decoded_address = sp.unpack( + sp.bytes("0x050a00000016") + sp.bytes("0x03") + value.open_some() + sp.bytes("0x00"), + sp.TAddress) + addr.value = decoded_address.open_some() + + sp.if actual_prefix.value == "": + addr.value = sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg") + with sp.else_(): + addr.value = sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg") + + return addr.value + + @sp.onchain_view() + def str_to_addr(self, params): + sp.set_type(params, sp.TString) + sp.result(self._to_addr(params)) + + @sp.onchain_view() + def string_of_int(self, params): + sp.set_type(params, sp.TInt) + sp.result(Utils.String.of_int(params)) + + +@sp.add_test(name="Conversion") +def test(): + alice=sp.test_account("Alice") + c1 = ParseAddress() + scenario = sp.test_scenario() + scenario.h1("Conversion") + scenario += c1 + c1.add_to_str(sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP")) + scenario.verify(c1.add_to_str(sp.address("KT1FfkTSts5DnvyJp2qZbPMeqm2XpMYES7Vr")) == "KT1FfkTSts5DnvyJp2qZbPMeqm2XpMYES7Vr") + scenario.verify(c1.add_to_str(sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP")) == "tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP") + + c1.str_to_addr("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP") + c1.str_to_addr("KT1FfkTSts5DnvyJp2qZbPMeqm2XpMYES7Vr") + scenario.verify(c1.str_to_addr("KT1FfkTSts5DnvyJp2qZbPMeqm2XpMYES7Vr") == sp.address("KT1FfkTSts5DnvyJp2qZbPMeqm2XpMYES7Vr")) + scenario.verify(c1.str_to_addr("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP") == sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP")) + # invalid address + scenario.verify(c1.str_to_addr("tz1g3pJZPifxhN") == sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")) + + + +sp.add_compilation_target("parse_address", ParseAddress()) + + diff --git a/smartpy/bts/contracts/tests/bts_periphery_test.py b/smartpy/bts/contracts/tests/bts_periphery_test.py new file mode 100644 index 00000000..a91e7e0c --- /dev/null +++ b/smartpy/bts/contracts/tests/bts_periphery_test.py @@ -0,0 +1,172 @@ +import smartpy as sp +BTSPeriphery = sp.io.import_script_from_url("file:./contracts/src/bts_periphery.py") +BTSCore = sp.io.import_script_from_url("file:./contracts/src/bts_core.py") +BTSOwnerManager = sp.io.import_script_from_url("file:./contracts/src/bts_owner_manager.py") +ParseAddress = sp.io.import_script_from_url("file:./contracts/src/parse_address.py") +Helper= sp.io.import_script_from_url("file:./contracts/src/helper.py") + + +@sp.add_test("BTSPeripheryTest") +def test(): + sc = sp.test_scenario() + + # test account + alice=sp.test_account("Alice") + bmc_address = sp.test_account('bmc') + admin=sp.test_account('admin') + helper = sp.test_account("Helper") + + + def deploy_btsperiphery_contract(): + btsperiphery_contract = BTSPeriphery.BTPPreiphery(bmc_address.address,btscore_contract.address,btshelpercontract.address,btsparsecontract.address,'NativeCoin',admin.address) + return btsperiphery_contract + + def deploy_parsecontract(): + btsparsecontract = ParseAddress.ParseAddress() + return btsparsecontract + + def deploy_helper(): + btshelper = Helper.Helper() + return btshelper + + + + def deploy_btscore_contract(): + btscore_contract= BTSCore.BTSCore( + owner_manager= bts_OwnerManager_contract.address, + _native_coin_name="Tok1", + _fee_numerator=sp.nat(1000), + _fixed_fee=sp.nat(10)) + return btscore_contract + + def deploy_btsOwnerManager_Contract(): + bts_OwnerManager_Contract = BTSOwnerManager.BTSOwnerManager(sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + return bts_OwnerManager_Contract + + bts_OwnerManager_contract = deploy_btsOwnerManager_Contract() + sc+= bts_OwnerManager_contract + + btscore_contract = deploy_btscore_contract() + sc+= btscore_contract + + btshelpercontract = deploy_helper() + sc+= btshelpercontract + + btsparsecontract = deploy_parsecontract() + sc+= btsparsecontract + + # deploy btsperiphery contract + btsperiphery_contract = deploy_btsperiphery_contract() + sc += btsperiphery_contract + + btscore_contract.update_bts_periphery(btsperiphery_contract.address).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + + + + + #test 1: Test of add to blacklist function + btsperiphery_contract.add_to_blacklist({0:"notaaddress"}).run(sender=btsperiphery_contract.address,valid=False, exception="InvalidAddress") # invalid address + btsperiphery_contract.add_to_blacklist({0:"tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"}).run(sender=btsperiphery_contract.address,valid=True) #add a address to blacklist + btsperiphery_contract.add_to_blacklist({0:"tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"}).run(sender=btsperiphery_contract.address,valid=True) # can be called twice + btsperiphery_contract.add_to_blacklist({0:"tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"}) .run(sender=admin.address,valid=False,exception ="Unauthorized")# only btsperiphery contract call this function + btsperiphery_contract.add_to_blacklist({0:'tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg'}).run(sender=btsperiphery_contract.address,valid=False,exception='InvalidAddress')#invalid address + sc.verify(btsperiphery_contract.data.blacklist[sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW")] == True) # checking the blacklist[] map + + + #test 2 : Test of remove from blacklist function + btsperiphery_contract.remove_from_blacklist({0:'notaaddress'}).run(sender=btsperiphery_contract.address,valid=False, exception="InvalidAddress") # invalid address + btsperiphery_contract.remove_from_blacklist({0:'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=btsperiphery_contract.address,valid=False, exception="UserNotFound") # address not black-listed + btsperiphery_contract.add_to_blacklist({0:'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=btsperiphery_contract.address) # adding to blacklist + btsperiphery_contract.remove_from_blacklist({0:'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=btsperiphery_contract.address) # valid process + btsperiphery_contract.remove_from_blacklist({0:'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=btsperiphery_contract.address,valid=False ,exception ='UserNotFound') # cannot remove from blacklist twice + btsperiphery_contract.add_to_blacklist({0:'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=btsperiphery_contract.address) # adding to blacklist + btsperiphery_contract.remove_from_blacklist({0:'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=btsperiphery_contract.address) # can only be called from btseperiphery contract + btsperiphery_contract.remove_from_blacklist({0:'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=admin.address, valid=False, exception ="Unauthorized") # can only be called from btseperiphery contract + + + #test 3 : set token limit + btsperiphery_contract.set_token_limit(sp.record(coin_names = {0:"Tok2" , 1:'BB'} ,token_limit ={0:sp.nat(5),1:sp.nat(2)})).run(sender=admin.address,valid=False,exception='Unauthorized') #can only be called from btsperiphery contract + btsperiphery_contract.set_token_limit(sp.record(coin_names = {0:"Tok2" , 1:'BB'} ,token_limit ={0:sp.nat(5),1:sp.nat(2)})).run(sender=btsperiphery_contract.address) #set token limit for Tok2 coin to 5 and BB coin to 2 + sc.verify(btsperiphery_contract.data.token_limit["Tok2"] == sp.nat(5))#test of token_limit for tok2 token + btsperiphery_contract.set_token_limit(sp.record(coin_names = {0:"Tok2" , 1:'BB'} ,token_limit ={0:sp.nat(5)} )).run(valid=False,exception='InvalidParams',sender=btsperiphery_contract.address) #invalid parameters + #cannot set more than 15 token limit at once + btsperiphery_contract.set_token_limit(sp.record(coin_names = {0:"Tok2" , 1:'BB'} ,token_limit ={0:sp.nat(15),1:sp.nat(22)})).run(sender=btsperiphery_contract.address) #can modify already set data + sc.verify(btsperiphery_contract.data.token_limit["BB"] == sp.nat(22))#test of token_limit for tok2 token + + + #test 4 :send service message + + btsperiphery_contract.send_service_message(sp.record(_from=sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), to="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW",coin_names={0:"Tok1"}, values={0:sp.nat(10)}, fees={0:sp.nat(2)})).run(sender=btscore_contract.address ) + btsperiphery_contract.send_service_message(sp.record(_from=sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), to="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW",coin_names={0:"Tok1"}, values={0:sp.nat(10)}, fees={0:sp.nat(2)})).run( sender=btscore_contract.address ) # test of function + btsperiphery_contract.send_service_message(sp.record(_from=sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), to="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW",coin_names={0:"Tok1"}, values={0:sp.nat(10)}, fees={0:sp.nat(2)})).run( sender= admin,valid=False, exception='Unauthorized' ) # only message from bts-core is authorized + sc.show(btsperiphery_contract.data.requests[1])#test to verify if request message is correct + sc.verify_equal(btsperiphery_contract.data.requests[1] ,sp.record(amounts = {0 : 10}, coin_names = {0 : 'Tok1'}, fees = {0 : 2}, from_ = 'tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW', to = 'btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW')) # request data verified + sc.verify(btsperiphery_contract.data.number_of_pending_requests == 2)#2 pending request + sc.verify(btsperiphery_contract.data.serial_no == 2) #serial no of request increased to 2 + + + #Test 5: handle btp message + # btsperiphery_contract.handle_btp_message(sp.record(_from="tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", svc="bts", sn=sp.nat(4),msg=sp.bytes("0xf8cfb83d6274703a2f2f30783232382e6172637469632f307831313131313131313131313131313131313131313131313131313131313131313131313131313131b8396274703a2f2f3078312e69636f6e2f637830303030303030303030303030303030303030303030303030303030303030303030303030303036836274730ab84ef84cb83d6274703a2f2f30783232382e6172637469632f307861313434326339303132304138393163336465393739336361433730393638436162313133323335cc8b627470206d657373616765") )).run(sender=bmc_address) #test of handle_btp_message function + # btsperiphery_contract.handle_btp_message(sp.record(_from="tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", svc="btc", sn=sp.nat(4),msg=sp.bytes("0xf8cfb83d6274703a2f2f30783232382e6172637469632f307831313131313131313131313131313131313131313131313131313131313131313131313131313131b8396274703a2f2f3078312e69636f6e2f637830303030303030303030303030303030303030303030303030303030303030303030303030303036836274730ab84ef84cb83d6274703a2f2f30783232382e6172637469632f307861313434326339303132304138393163336465393739336361433730393638436162313133323335cc8b627470206d657373616765") )).run(sender=bmc_address,valid=False, exception='InvalidSvc') #svc name must match hardcoded service name "btc" + # btsperiphery_contract.handle_btp_message(sp.record(_from="tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", svc="btc", sn=sp.nat(4),msg=sp.bytes("0xf8cfb83d6274703a2f2f30783232382e6172637469632f307831313131313131313131313131313131313131313131313131313131313131313131313131313131b8396274703a2f2f3078312e69636f6e2f637830303030303030303030303030303030303030303030303030303030303030303030303030303036836274730ab84ef84cb83d6274703a2f2f30783232382e6172637469632f307861313434326339303132304138393163336465393739336361433730393638436162313133323335cc8b627470206d657373616765") )).run(sender=btsperiphery_contract.address,valid=False, exception='Unauthorized') #can only be called from bmc contract + + + + + + + + + + + + #Test : handle btp error + # sc.verify(btsperiphery_contract.data.number_of_pending_requests == 2)#pending request is 2 here + # btsperiphery_contract.handle_btp_error(sp.record(svc= "bts", code=sp.nat(2), sn=sp.nat(1), msg="test 1")).run(sender=bmc_address) + # btsperiphery_contract.handle_btp_error(sp.record(svc= "btc", code=sp.nat(2), sn=sp.nat(1), msg="test 1")).run(sender=bmc_address,valid=False,exception='InvalidSvc') #Invalid Svc + # btsperiphery_contract.handle_btp_error(sp.record(svc= "bts", code=sp.nat(2), sn=sp.nat(111), msg="test 1")).run(sender=bmc_address,valid=False,exception='Missing item in map') # Invalid sn , sn must be serial number of service request + # btsperiphery_contract.handle_btp_error(sp.record(svc= "bts", code=sp.nat(2), sn=sp.nat(1), msg="test 1")).run(sender=btsperiphery_contract.address,valid=False,exception='Unauthorized')#Only bmc contract can call this fucntion + # sc.verify(btsperiphery_contract.data.number_of_pending_requests == 0) #pending request decreased + + + #Test : handle request service + btsperiphery_contract.handle_request_service(sp.record(to= "tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc", assets={0: sp.record(coin_name="BB", value=sp.nat(4))})).run(sender=btsperiphery_contract.address,valid=False,exception='UnregisteredCoin') + + + #Test : handle fee gathering + # btsperiphery_contract.handle_fee_gathering(sp.record(fa="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", svc="bts")).run(sender=bmc_address) # handle_fee_gathering function call + # btsperiphery_contract.handle_fee_gathering(sp.record(fa="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", svc="btc")).run(sender=bmc_address, valid=False, exception='InvalidSvc') # svc must match hardcoded service name 'bts' + # btsperiphery_contract.handle_fee_gathering(sp.record(fa="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", svc="bts")).run(sender=btsperiphery_contract.address, valid=False, exception='Unauthorized') # can only be called from bmc contract + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/smartpy/bts/contracts/tests/btscore_test.py b/smartpy/bts/contracts/tests/btscore_test.py new file mode 100644 index 00000000..bd35fada --- /dev/null +++ b/smartpy/bts/contracts/tests/btscore_test.py @@ -0,0 +1,291 @@ +import smartpy as sp + + +BTSCore = sp.io.import_script_from_url("file:./contracts/src/bts_core.py") +BTSOwnerManager = sp.io.import_script_from_url("file:./contracts/src/bts_owner_manager.py") +BTSPeriphery = sp.io.import_script_from_url("file:./contracts/src/bts_periphery.py") +BMCHelper = sp.io.import_script_from_url("file:./contracts/src/helper.py") +ParseAddress = sp.io.import_script_from_url("file:./contracts/src/parse_address.py") + + + +@sp.add_test("BTSCoreTest") +def test(): + sc = sp.test_scenario() + sc.h1("BTSCore") + + + # test account + alice = sp.test_account("Alice") + jack = sp.test_account("Jack") + bob = sp.test_account("Bob") + creator = sp.test_account("Creator") + + # deploy BTSCore contract + bts_owner_manager = deploy_btsOwnerManager_Contract() + sc += bts_owner_manager + btsCore_contract = deploy_btsCore_contract(bts_owner_manager.address) + sc += btsCore_contract + + helper_contract = deploy_helper_contract() + sc += helper_contract + + parse_address = deploy_parse_address() + sc += parse_address + + + bts_periphery = deploy_btsPeriphery_Contract(btsCore_contract.address, helper_contract.address, parse_address.address) + sc += bts_periphery + fa2 = deploy_fa2_Contract(bts_periphery.address) + sc += fa2 + + + + + bts_owner_manager.is_owner(sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + + + # test case 1: check the name of coin + sc.verify_equal(btsCore_contract.get_native_coin_name(), "BTSCOIN") + + + # test case 2: check the owner manager of the contract + sc.verify_equal(btsCore_contract.data.bts_owner_manager, bts_owner_manager.address) + + + # test case 3: update_bts_periphery function + btsCore_contract.update_bts_periphery(bts_periphery.address).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + sc.verify_equal(btsCore_contract.data.bts_periphery_address,sp.some(bts_periphery.address)) + + # test case 4: set_fee_ratio function + #throws error if coin name is different + btsCore_contract.set_fee_ratio(name=sp.string("coindiff"),fee_numerator=sp.nat(100),fixed_fee=sp.nat(10)).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), valid=False, exception='TokenNotExists') + #throws error when fee numerator is greater than denominator + btsCore_contract.set_fee_ratio(name=sp.string("BTSCOIN"),fee_numerator=sp.nat(10000),fixed_fee=sp.nat(10)).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), valid=False, exception='InvalidSetting') + # throws error when fixed fee is less than 0 + btsCore_contract.set_fee_ratio(name=sp.string("BTSCOIN"),fee_numerator=sp.nat(100),fixed_fee=sp.nat(0)).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), valid=False, exception='LessThan0') + #works + btsCore_contract.set_fee_ratio(name=sp.string("BTSCOIN"),fee_numerator=sp.nat(100),fixed_fee=sp.nat(10)).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + #checking value + sc.verify_equal(btsCore_contract.data.coin_details["BTSCOIN"].fee_numerator, 100) + sc.verify_equal(btsCore_contract.data.coin_details["BTSCOIN"].fixed_fee, 10) + + + # test case 5: register function + # name shouldn't be native coin name + btsCore_contract.register( + name=sp.string("BTSCOIN"), + fee_numerator=sp.nat(10), + fixed_fee=sp.nat(2), + addr=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), + token_metadata=sp.map({"ff": sp.bytes("0x0dae11")}), + metadata=sp.big_map({"ff": sp.bytes("0x0dae11")}) + ).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), valid=False, exception='ExistNativeCoin') + #throws error when fee numerator is greater than denominator + btsCore_contract.register( + name=sp.string("new_coin1"), + fee_numerator=sp.nat(100000), + fixed_fee=sp.nat(2), + addr=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), + token_metadata=sp.map({"ff": sp.bytes("0x0dae11")}), + metadata=sp.big_map({"ff": sp.bytes("0x0dae11")}) + ).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), valid=False, exception='InvalidSetting') + # works + btsCore_contract.register( + name=sp.string("new_coin"), + fee_numerator=sp.nat(10), + fixed_fee=sp.nat(2), + addr=fa2.address, + token_metadata=sp.map({"ff": sp.bytes("0x0dae11")}), + metadata=sp.big_map({"ff": sp.bytes("0x0dae11")}) + ).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + + # verifying the value + sc.verify_equal(btsCore_contract.data.coins_name, ['new_coin', 'BTSCOIN']) + sc.verify_equal(btsCore_contract.data.coin_details['new_coin'], sp.record(addr = fa2.address, coin_type = 2, fee_numerator = 10, fixed_fee = 2)) + # throws error when existed coin name is given + btsCore_contract.register( + name=sp.string("new_coin"), + fee_numerator=sp.nat(10), + fixed_fee=sp.nat(2), + addr=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), + token_metadata=sp.map({"ff": sp.bytes("0x0dae11")}), + metadata=sp.big_map({"ff": sp.bytes("0x0dae11")}) + ).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), valid=False, exception="ExistCoin") + # throws error when existed address is given + btsCore_contract.register( + name=sp.string("new_coin2"), + fee_numerator=sp.nat(10), + fixed_fee=sp.nat(2), + addr=fa2.address, + token_metadata=sp.map({"ff": sp.bytes("0x0dae11")}), + metadata=sp.big_map({"ff": sp.bytes("0x0dae11")}) + ).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), valid=False, exception="AddressExists") + + + # test case 6: coin_names function + sc.verify_equal(btsCore_contract.coin_names(), ['new_coin', 'BTSCOIN']) + + # test case 7: coin_id function + sc.verify_equal(btsCore_contract.coin_id('new_coin'), fa2.address) + + # test case 8: is_valid_coin function + sc.verify_equal(btsCore_contract.is_valid_coin('new_coin'), True) + sc.verify_equal(btsCore_contract.is_valid_coin('not_valid'), False) + + + # test case 9: fee_ratio function + sc.verify_equal(btsCore_contract.fee_ratio('new_coin'), sp.record(fee_numerator=10, fixed_fee=2)) + + + #test case 10: balance_of function + sc.verify_equal( + btsCore_contract.balance_of( + sp.record(owner=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), coin_name='new_coin') + ), + sp.record(usable_balance=0, locked_balance=0, refundable_balance=0, user_balance=0) + ) + + #test case 11: balance_of_batch function + btsCore_contract.balance_of_batch( + sp.record(owner=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), coin_names=['new_coin', 'BTSCOIN']) + ) + sc.verify_equal( + btsCore_contract.balance_of_batch( + sp.record(owner=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), coin_names=['new_coin', 'BTSCOIN']) + ), + sp.record(locked_balances = {0 : 0, 1 : 0}, refundable_balances = {0 : 0, 1 : 0}, usable_balances = {0 : 0, 1 : 0}, user_balances = {0 : 0, 1 : 0})) + + + # #test case 13: get_accumulated_fees function + # # sc.verify_equal(btsCore_contract.get_accumulated_fees(), {}) + + + # #test case 14: transfer_native_coin function + bts_periphery.set_token_limit( + sp.record( + coin_names=sp.map({0: "BTSCOIN"}), + token_limit=sp.map({0: 115792089237316195423570985008687907853269984665640564039457584007913129639935}) + ) + ).run(sender = btsCore_contract.address) + btsCore_contract.transfer_native_coin("tz1eZMrKqCNPrHzykdTuqKRyySoDv4QRSo7d").run(sender= sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), amount=sp.tez(30)) + + + + # # test case 15: transfer function + # fa2.mint([sp.record(to_=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), amount=sp.nat(100))]).run(sender=bts_periphery.address) + # fa2.set_allowance([sp.record(spender=btsCore_contract.address, amount=sp.nat(100))]).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + # fa2.update_operators( + # [sp.variant("add_operator", sp.record(owner=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), operator=btsCore_contract.address, token_id=0))]).run( + # sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + + + # btsCore_contract.transfer(coin_name='new_coin', value=10, to="tz1eZMrKqCNPrHzykdTuqKRyySoDv4QRSo7d").run(sender = sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + + # sc.verify_equal( + # btsCore_contract.balance_of( + # sp.record(owner=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), coin_name='new_coin') + # ), + # sp.record(usable_balance=90, locked_balance=10, refundable_balance=0, user_balance=90) + # ) + + #test case 12: minting and checking balance + # mint for native coin + # btsCore_contract.mint(to=sp.address("tz1UHiurbSsDFXnTfMQkeni4GWCuMpq6JFRB"), coin_name="BTSCOIN", value=1000).run(sender = bts_periphery.address) + # sc.verify_equal( + # btsCore_contract.balance_of( + # sp.record(owner=sp.address("tz1UHiurbSsDFXnTfMQkeni4GWCuMpq6JFRB"), coin_name='BTSCOIN') + # ), + # sp.record(usable_balance=0, locked_balance=0, refundable_balance=0, user_balance=1000) + # ) + # error balance_of native_coin balance ma halne condition + + # for NON_NATIVE_TOKEN_TYPE + # fa2.mint([sp.record(to_=bts_periphery.address, amount=sp.nat(2000))]).run( + # sender=bts_periphery.address) + # fa2.update_operators( + # [sp.variant("add_operator", sp.record(owner=bts_periphery.address, operator=btsCore_contract.address, token_id=0))]).run( + # sender=bts_periphery.address) + # fa2.set_allowance([sp.record(spender=btsCore_contract.address, amount=sp.nat(1000))]).run( + # sender=bts_periphery.address) + + # btsCore_contract.mint(to=sp.address("tz1UHiurbSsDFXnTfMQkeni4GWCuMpq6JFRB"), coin_name="new_coin", value=1000).run(sender = bts_periphery.address) + # sc.verify_equal( + # btsCore_contract.balance_of( + # sp.record(owner=sp.address("tz1UHiurbSsDFXnTfMQkeni4GWCuMpq6JFRB"), coin_name='new_coin') + # ), + # sp.record(usable_balance=0, locked_balance=0, refundable_balance=0, user_balance=1000) + # ) + + + # # test case 16: transfer_batch function + # btsCore_contract.transfer_batch( + # coin_names={0: 'new_coin', 1: 'new_coin'}, + # values={0: 10, 1: 10}, + # to="tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP" + # ).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + + # sc.verify_equal( + # btsCore_contract.balance_of( + # sp.record(owner=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), coin_name='new_coin') + # ), + # sp.record(usable_balance=70, locked_balance=30, refundable_balance=0, user_balance=70) + # ) + + # # test case 17: handle_response_service function + # btsCore_contract.handle_response_service(sp.record(requester=sp.address("KT1VCbyNieUsQsCShkxtTz9ZbLmE9oowmJPm"), coin_name="BTSCOIN",value=sp.nat(44), fee=sp.nat(3), rsp_code=sp.nat(1))).run(sender=bts_periphery.address) + + + + + +# +# # +# # # test case 16: reclaim function +# # +# # # btsCore_contract.reclaim(coin_name="new_coin", value=25).run(sender = sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) +# # +# # +# # # btsCore_contract.refund(to=sp.address("tz1UHiurbSsDFXnTfMQkeni4GWCuMpq6JFRB"), coin_name="new_coin", value=30).run(sender = sp.address("tz1UHiurbSsDFXnTfMQkeni4GWCuMpq6JFRB")) +# # +# # +# # +# # +# # +# + +# +# +# + +def deploy_btsCore_contract(bts_OwnerManager_Contract): + btsCore_contract = BTSCore.BTSCore( + owner_manager=bts_OwnerManager_Contract, + _native_coin_name="BTSCOIN", + _fee_numerator=sp.nat(1000), + _fixed_fee=sp.nat(10) + ) + return btsCore_contract + +def deploy_btsOwnerManager_Contract(): + bts_OwnerManager_Contract = BTSOwnerManager.BTSOwnerManager(sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + return bts_OwnerManager_Contract + +def deploy_btsPeriphery_Contract(core_address, helper, parse): + bmc = sp.test_account("bmc") + btsPeriphery_Contract = BTSPeriphery.BTPPreiphery(bmc_address= bmc.address, bts_core_address=core_address, helper_contract=helper, parse_address=parse,native_coin_name= 'BTSCoin',owner_address=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + return btsPeriphery_Contract + +def deploy_fa2_Contract(admin_address): + fa2_contract = BTSCore.FA2_contract.SingleAssetToken(admin=admin_address, metadata=sp.big_map({"ss": sp.bytes("0x0dae11")}), token_metadata=sp.map({"ff": sp.bytes("0x0dae11")})) + return fa2_contract + +def deploy_helper_contract(): + helper_contract = BMCHelper.Helper() + return helper_contract + +def deploy_parse_address(): + parse_address = ParseAddress.ParseAddress() + return parse_address + + diff --git a/smartpy/bts/contracts/tests/integration_test.py b/smartpy/bts/contracts/tests/integration_test.py new file mode 100644 index 00000000..030e8b7b --- /dev/null +++ b/smartpy/bts/contracts/tests/integration_test.py @@ -0,0 +1,309 @@ +import smartpy as sp + +BMCManagement = sp.io.import_script_from_url("file:./bmc/contracts/src/bmc_management.py") +BMCPeriphery = sp.io.import_script_from_url("file:./bmc/contracts/src/bmc_periphery.py") +BMCHelper = sp.io.import_script_from_url("file:./bmc//contracts/src/helper.py") +ParseAddress = sp.io.import_script_from_url("file:./contracts/src/parse_address.py") + +BTSCore = sp.io.import_script_from_url("file:./contracts/src/bts_core.py") +BTSOwnerManager = sp.io.import_script_from_url("file:./contracts/src/bts_owner_manager.py") +BTSPeriphery = sp.io.import_script_from_url("file:./contracts/src/bts_periphery.py") + + + + + +@sp.add_test("BMCManagementTest") +def test(): + sc = sp.test_scenario() + + # test account + alice = sp.test_account("Alice") + creator = sp.test_account("Creator") + jack = sp.test_account("Jack") + bob = sp.test_account("Bob") + creator2 = sp.test_account("creator2") + service1_address = sp.test_account("service1_address") + service2_address = sp.test_account("service2_address") + + + # deploy BMCManagement contract + + helper_contract = deploy_helper_contract() + sc += helper_contract + + bmcManagement_contract = deploy_bmcManagement_contract(creator.address, helper_contract.address) + sc += bmcManagement_contract + + parse_address = deploy_parse_address() + sc += parse_address + + bmcPeriphery_contract = deploy_bmcPeriphery_contract(bmcManagement_contract.address, helper_contract.address, parse_address.address,creator.address) + sc += bmcPeriphery_contract + + bts_owner_manager = deploy_btsOwnerManager_Contract(creator.address) + sc += bts_owner_manager + + btsCore_contract = deploy_btsCore_contract(bts_owner_manager.address) + sc += btsCore_contract + + + bts_periphery = deploy_btsPeriphery_Contract(btsCore_contract.address, helper_contract.address, parse_address.address, bmcPeriphery_contract.address,creator.address) + sc += bts_periphery + + fa2 = deploy_fa2_Contract(bts_periphery.address) + sc += fa2 + + #set bmc periphery + bmcManagement_contract.set_bmc_periphery(bmcPeriphery_contract.address).run(sender=creator.address) + #set bmc_btp_address(netwrk address) + bmcManagement_contract.set_bmc_btp_address("NetXnHfVqm9iesp.tezos").run(sender=creator.address) + #update_bts_periphery + btsCore_contract.update_bts_periphery(bts_periphery.address).run(sender=creator.address) + + #add_service + svc1 = sp.string("bts") + bmcManagement_contract.add_service(sp.record(addr=bts_periphery.address, svc=svc1)).run(sender=creator.address) + + #add_route + dst = "btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258dest" + next_link = "btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b" + bmcManagement_contract.add_route(sp.record(dst=dst, link=next_link)).run(sender=creator.address) + + #add_link + bmcManagement_contract.add_link("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b").run(sender=creator.address) + + + #set_link_rx_height + # link = sp.string('btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b') + # height = sp.nat(2) + # bmcManagement_contract.set_link_rx_height(link=link, height=height).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + + # #add_relay + # bmcManagement_contract.add_relay(sp.record(link=link, addr=sp.set([sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")]))).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + + #test 1: Test of add to blacklist function + # bts_periphery.add_to_blacklist({0:"notaaddress"}).run(sender=bts_periphery.address,valid=False, exception="InvalidAddress") # invalid address + bts_periphery.add_to_blacklist({0:"tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"}).run(sender=bts_periphery.address,valid=True) #add a address to blacklist + # bts_periphery.add_to_blacklist({0:"tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"}).run(sender=bts_periphery.address,valid=True) # can be called twice + # bts_periphery.add_to_blacklist({0:"tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"}) .run(sender=alice.address,valid=False,exception ="Unauthorized")# only btsperiphery contract call this function + # bts_periphery.add_to_blacklist({0:'tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg'}).run(sender=bts_periphery.address,valid=False,exception='InvalidAddress')#invalid address + # sc.verify(bts_periphery.data.blacklist[sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW")] == True) # checking the blacklist[] map + + # transfer_native_coin + bts_periphery.set_token_limit( + sp.record( + coin_names=sp.map({0: "btp-NetXnHfVqm9iesp.tezos-XTZ"}), + token_limit=sp.map({0: 115792089237316195423570985008687907853269984665640564039457584007913129639935}) + ) + ).run(sender = btsCore_contract.address) + btsCore_contract.transfer_native_coin("btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d").run(sender= sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), amount=sp.tez(30), valid=False, exception="Blacklisted") + + + + + #test 2 : Test of remove from blacklist function + # bts_periphery.remove_from_blacklist({0:'notaaddress'}).run(sender=bts_periphery.address,valid=False, exception="InvalidAddress") # invalid address + # bts_periphery.remove_from_blacklist({0:'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=bts_periphery.address,valid=False, exception="UserNotFound") # address not black-listed + # bts_periphery.add_to_blacklist({0:'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=bts_periphery.address) # adding to blacklist + bts_periphery.remove_from_blacklist({0:'tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=bts_periphery.address) # valid process + btsCore_contract.transfer_native_coin("btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d").run(sender= bts_periphery.address, amount=sp.tez(30)) + + # bts_periphery.remove_from_blacklist({0:'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=bts_periphery.address,valid=False ,exception ='UserNotFound') # cannot remove from blacklist twice + # bts_periphery.add_to_blacklist({0:'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=bts_periphery.address) # adding to blacklist + # bts_periphery.remove_from_blacklist({0:'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=bts_periphery.address) # can only be called from btseperiphery contract + # bts_periphery.remove_from_blacklist({0:'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=alice.address, valid=False, exception ="Unauthorized") # can only be called from btseperiphery contract + + # transfer_native_coin + bts_periphery.set_token_limit( + sp.record( + coin_names=sp.map({0: "btp-NetXnHfVqm9iesp.tezos-XTZ"}), + token_limit=sp.map({0: 115792089237316195423570985008687907853269984665640564039457584007913129639935}) + ) + ).run(sender = btsCore_contract.address) + btsCore_contract.transfer_native_coin("btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d").run(sender= bmcManagement_contract.address, amount=sp.tez(30)) + + sc.verify_equal( + btsCore_contract.balance_of( + sp.record(owner=bmcManagement_contract.address, coin_name='btp-NetXnHfVqm9iesp.tezos-XTZ') + ),sp.record(usable_balance=0, locked_balance=30000000, refundable_balance=0, user_balance=0)) + + + + # transfer_native_coin + + + #bts core function test + + #test of transfer native coin + sc.verify(bts_periphery.data.number_of_pending_requests == 2)#2 pending request + sc.verify(bts_periphery.data.serial_no == 2) + btsCore_contract.transfer_native_coin("btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d").run(sender= bmcManagement_contract.address, amount=sp.tez(30)) + #this calls send service message of bts core + # in send service message function locked balance is called + sc.show(btsCore_contract.balance_of( + sp.record(owner=bmcManagement_contract.address, coin_name='btp-NetXnHfVqm9iesp.tezos-XTZ') + )) + sc.verify_equal( + btsCore_contract.balance_of( + sp.record(owner=bmcManagement_contract.address, coin_name='btp-NetXnHfVqm9iesp.tezos-XTZ') + ),sp.record(usable_balance=0, locked_balance=60000000, refundable_balance=0, user_balance=0)) + + #this calls btsperiphery sendservice message + #inside bts periphery send service message serial_no is incremented by 1 ,no of pending request is increased by 1, bmc send message is called + sc.verify(bts_periphery.data.number_of_pending_requests == 3)#2 pending request + sc.verify(bts_periphery.data.serial_no == 3) + #bmc management update link tx sq is called links[prev].tx_seq += sp.nat(1) + + + #test of non native coin transfer + btsCore_contract.register( + name=sp.string("new_coin"), + fee_numerator=sp.nat(10), + fixed_fee=sp.nat(2), + addr=fa2.address, + token_metadata=sp.map({"ff": sp.bytes("0x0dae11")}), + metadata=sp.big_map({"ff": sp.bytes("0x0dae11")}) + ).run(sender=creator.address) + + fa2.mint([sp.record(to_=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), amount=sp.nat(100))]).run(sender=bts_periphery.address) + fa2.set_allowance([sp.record(spender=btsCore_contract.address, amount=sp.nat(100))]).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + + fa2.update_operators( + [sp.variant("add_operator", sp.record(owner=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), operator=btsCore_contract.address, token_id=0))]).run( + sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + sc.verify_equal(btsCore_contract.is_valid_coin('new_coin'), True) + btsCore_contract.transfer(coin_name='new_coin', value=10, to="btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d").run(sender = sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + sc.verify_equal( + btsCore_contract.balance_of( + sp.record(owner=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), coin_name='new_coin') + ), + sp.record(usable_balance=90, locked_balance=10, refundable_balance=0, user_balance=90) + ) + + #transfer batch + # test case 16: transfer_batch function + btsCore_contract.transfer_batch( + coin_names={0: 'new_coin', 1: 'new_coin'}, + values={0: 10, 1: 10}, + to="btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d" + ).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + + sc.verify_equal( + btsCore_contract.balance_of( + sp.record(owner=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), coin_name='new_coin') + ), + sp.record(usable_balance=70, locked_balance=30, refundable_balance=0, user_balance=70) + ) + + + + bts_periphery.handle_request_service(sp.record(to= "tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc", assets={0: sp.record(coin_name="btp-NetXnHfVqm9iesp.tezos-XTZ", value=sp.nat(4))})).run(sender=bts_periphery.address) + #core's mint is called + # sc.verify_equal( + # btsCore_contract.balance_of( + # sp.record(owner=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), coin_name="btp-NetXnHfVqm9iesp.tezos-XTZ") + # ), + # sp.record(usable_balance=0, locked_balance=0, refundable_balance=0, user_balance=0) + # ) + + + + + + bts_periphery.set_token_limit( + sp.record( + coin_names=sp.map({0: "btp-NetXnHfVqm9iesp.tezos-XTZ"}), + token_limit=sp.map({0: 5}) + ) + ).run(sender = btsCore_contract.address) + btsCore_contract.transfer_native_coin("btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d").run(sender=bmcManagement_contract.address, amount=sp.tez(30), valid=False, exception="LimitExceed") + + + #Test : handle fee gathering + #this calls transfer fees of btscore + # bts_periphery.handle_fee_gathering(sp.record(fa="btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258dest", svc="bts")).run(sender=bmcPeriphery_contract.address) # handle_fee_gathering function call + # bts_periphery.handle_fee_gathering(sp.record(fa="btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258dest", svc="btc")).run(sender=bmcPeriphery_contract.address, valid=False, exception='InvalidSvc') # svc must match hardcoded service name 'bts' + # bts_periphery.handle_fee_gathering(sp.record(fa="btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258dest", svc="bts")).run(sender=bts_periphery.address, valid=False, exception='Unauthorized') # can only be called from bmc contract + + + + # #test 3 : set token limit + # bts_periphery.set_token_limit(sp.record(coin_names = {0:"Tok2" , 1:'BB'} ,token_limit ={0:sp.nat(5),1:sp.nat(2)})).run(sender=alice.address,valid=False,exception='Unauthorized') #can only be called from btsperiphery contract + # bts_periphery.set_token_limit(sp.record(coin_names = {0:"Tok2" , 1:'BB'} ,token_limit ={0:sp.nat(5),1:sp.nat(2)})).run(sender=bts_periphery.address) #set token limit for Tok2 coin to 5 and BB coin to 2 + # sc.verify(bts_periphery.data.token_limit["Tok2"] == sp.nat(5))#test of token_limit for tok2 token + # bts_periphery.set_token_limit(sp.record(coin_names = {0:"Tok2" , 1:'BB'} ,token_limit ={0:sp.nat(5)} )).run(valid=False,exception='InvalidParams',sender=bts_periphery.address) #invalid parameters + # #cannot set more than 15 token limit at once + # bts_periphery.set_token_limit(sp.record(coin_names = {0:"Tok2" , 1:'BB'} ,token_limit ={0:sp.nat(15),1:sp.nat(22)})).run(sender=bts_periphery.address) #can modify already set data + # sc.verify(bts_periphery.data.token_limit["BB"] == sp.nat(22))#test of token_limit for tok2 token + + # # handle_relay_message + # msg=sp.bytes("0xf90236f90233b8ddf8db01b8d3f8d1f8cfb8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5431417259755046465a596341766f396b71793251673167327667465965676f52714a04b88af888b8396274703a2f2f3078372e69636f6e2f637831666637646432636639373836316262653462666536386232663463313834376562666132663534b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5431417259755046465a596341766f396b71793251673167327667465965676f52714a8362747381ff84c300f80084008449a0b90151f9014e01b90145f90142f9013fb8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5431417259755046465a596341766f396b71793251673167327667465965676f52714a05b8faf8f8b8396274703a2f2f3078372e69636f6e2f637831666637646432636639373836316262653462666536386232663463313834376562666132663534b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5431417259755046465a596341766f396b71793251673167327667465965676f52714a8362747303b874f87200b86ff86daa687839643138316431336634376335616165353535623730393831346336623232393738373937363139a4747a3157615078716f375868556e56344c346669324457424e4e51384a6231777445716edcdb906274702d3078372e69636f6e2d4943588900d71b0fe0a28e000084008449bf") + # prev=sp.string("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b") + # bmcPeriphery_contract.handle_relay_message(sp.record(prev=prev, msg=msg)).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + + # #set_fee_ratio + # btsCore_contract.set_fee_ratio(name=sp.string("btp-NetXnHfVqm9iesp.tezos-XTZ"),fee_numerator=sp.nat(100),fixed_fee=sp.nat(450)).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + + + + +def deploy_bmcManagement_contract(owner, helper): + bmcManagement_contract = BMCManagement.BMCManagement(owner, helper) + return bmcManagement_contract + +def deploy_bmcPeriphery_contract(bmc_addres, helper, parse,owner): + bmcPeriphery_contract = BMCPeriphery.BMCPreiphery(bmc_addres, helper,helper, parse, owner) + return bmcPeriphery_contract + +def deploy_helper_contract(): + helper_contract = BMCHelper.Helper() + return helper_contract + + +def deploy_parse_address(): + parse_address = ParseAddress.ParseAddress() + return parse_address + + +def deploy_btsCore_contract(bts_OwnerManager_Contract): + btsCore_contract = BTSCore.BTSCore( + owner_manager=bts_OwnerManager_Contract, + _native_coin_name="btp-NetXnHfVqm9iesp.tezos-XTZ", + _fee_numerator=sp.nat(100), + _fixed_fee=sp.nat(450) + ) + return btsCore_contract + +def deploy_btsOwnerManager_Contract(owner): + bts_OwnerManager_Contract = BTSOwnerManager.BTSOwnerManager(owner) + return bts_OwnerManager_Contract + +def deploy_btsPeriphery_Contract(core_address, helper, parse, bmc,owner): + btsPeriphery_Contract = BTSPeriphery.BTPPreiphery(bmc_address= bmc, bts_core_address=core_address, helper_contract=helper, parse_address=parse, owner_address=owner, native_coin_name="btp-NetXnHfVqm9iesp.tezos-XTZ") + return btsPeriphery_Contract + +def deploy_fa2_Contract(creator): + fa2_contract = BTSCore.FA2_contract.SingleAssetToken(admin=creator, metadata=sp.big_map({"ss": sp.bytes("0x0dae11")}), token_metadata=sp.map({"ff": sp.bytes("0x0dae11")})) + return fa2_contract + + +#Core - function with interscore call + +# Transfer_fees - called from bts_periphery - checked from bts periphery handle fee gathering +# Handle_response_service- called from bts_periphery +# Mint - called from bts_periphery +# Refund - refunds +# Transfer batch - +# Send service message +# Transfer +# Transfer native coin + +# Periphery +# Send service message - bts core +# Handle btp message - only bmc - done +# Handle btp error- only bmc -calls handle response service of periphery - done +# Handle response service -called from handle_btp_message-calls core handle response service +# Handle fee gathering - only bmc - calls core transfer_fees +# Send response message - called from handle btp message/ calls bmc send message +# –Handle request service - called from handle btp message /calls core mint - can be called for mint \ No newline at end of file diff --git a/smartpy/bts/package-lock.json b/smartpy/bts/package-lock.json new file mode 100644 index 00000000..13756c6c --- /dev/null +++ b/smartpy/bts/package-lock.json @@ -0,0 +1,1429 @@ +{ + "name": "create-tezos-app", + "version": "1.0.3", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "create-tezos-app", + "version": "1.0.3", + "license": "MIT", + "dependencies": { + "@taquito/signer": "^14.0.0", + "@taquito/taquito": "^14.0.0", + "dotenv": "^16.0.3", + "ts-node": "^10.9.1" + }, + "bin": { + "create-tezos-app": "bin/cli.js" + }, + "devDependencies": { + "typescript": "^4.8.4" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@stablelib/binary": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/binary/-/binary-1.0.1.tgz", + "integrity": "sha512-ClJWvmL6UBM/wjkvv/7m5VP3GMr9t0osr4yVgLZsLCOz4hGN9gIAFEqnJ0TsSMAN+n840nf2cHZnA5/KFqHC7Q==", + "dependencies": { + "@stablelib/int": "^1.0.1" + } + }, + "node_modules/@stablelib/blake2b": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/blake2b/-/blake2b-1.0.1.tgz", + "integrity": "sha512-B3KyKoBAjkIFeH7romcF96i+pVFYk7K2SBQ1pZvaxV+epSBXJ+n0C66esUhyz6FF+5FbdQVm77C5fzGFcEZpKA==", + "dependencies": { + "@stablelib/binary": "^1.0.1", + "@stablelib/hash": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@stablelib/bytes": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/bytes/-/bytes-1.0.1.tgz", + "integrity": "sha512-Kre4Y4kdwuqL8BR2E9hV/R5sOrUj6NanZaZis0V6lX5yzqC3hBuVSDXUIBqQv/sCpmuWRiHLwqiT1pqqjuBXoQ==" + }, + "node_modules/@stablelib/constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/constant-time/-/constant-time-1.0.1.tgz", + "integrity": "sha512-tNOs3uD0vSJcK6z1fvef4Y+buN7DXhzHDPqRLSXUel1UfqMB1PWNsnnAezrKfEwTLpN0cGH2p9NNjs6IqeD0eg==" + }, + "node_modules/@stablelib/ed25519": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@stablelib/ed25519/-/ed25519-1.0.3.tgz", + "integrity": "sha512-puIMWaX9QlRsbhxfDc5i+mNPMY+0TmQEskunY1rZEBPi1acBCVQAhnsk/1Hk50DGPtVsZtAWQg4NHGlVaO9Hqg==", + "dependencies": { + "@stablelib/random": "^1.0.2", + "@stablelib/sha512": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@stablelib/hash": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/hash/-/hash-1.0.1.tgz", + "integrity": "sha512-eTPJc/stDkdtOcrNMZ6mcMK1e6yBbqRBaNW55XA1jU8w/7QdnCF0CmMmOD1m7VSkBR44PWrMHU2l6r8YEQHMgg==" + }, + "node_modules/@stablelib/int": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/int/-/int-1.0.1.tgz", + "integrity": "sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w==" + }, + "node_modules/@stablelib/keyagreement": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/keyagreement/-/keyagreement-1.0.1.tgz", + "integrity": "sha512-VKL6xBwgJnI6l1jKrBAfn265cspaWBPAPEc62VBQrWHLqVgNRE09gQ/AnOEyKUWrrqfD+xSQ3u42gJjLDdMDQg==", + "dependencies": { + "@stablelib/bytes": "^1.0.1" + } + }, + "node_modules/@stablelib/nacl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@stablelib/nacl/-/nacl-1.0.4.tgz", + "integrity": "sha512-PJ2U/MrkXSKUM8C4qFs87WeCNxri7KQwR8Cdwm9q2sweGuAtTvOJGuW0F3N+zn+ySLPJA98SYWSSpogMJ1gCmw==", + "dependencies": { + "@stablelib/poly1305": "^1.0.1", + "@stablelib/random": "^1.0.2", + "@stablelib/wipe": "^1.0.1", + "@stablelib/x25519": "^1.0.3", + "@stablelib/xsalsa20": "^1.0.2" + } + }, + "node_modules/@stablelib/poly1305": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/poly1305/-/poly1305-1.0.1.tgz", + "integrity": "sha512-1HlG3oTSuQDOhSnLwJRKeTRSAdFNVB/1djy2ZbS35rBSJ/PFqx9cf9qatinWghC2UbfOYD8AcrtbUQl8WoxabA==", + "dependencies": { + "@stablelib/constant-time": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@stablelib/random": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@stablelib/random/-/random-1.0.2.tgz", + "integrity": "sha512-rIsE83Xpb7clHPVRlBj8qNe5L8ISQOzjghYQm/dZ7VaM2KHYwMW5adjQjrzTZCchFnNCNhkwtnOBa9HTMJCI8w==", + "dependencies": { + "@stablelib/binary": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@stablelib/salsa20": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@stablelib/salsa20/-/salsa20-1.0.2.tgz", + "integrity": "sha512-nfjKzw0KTKrrKBasEP+j7UP4I8Xudom8lVZIBCp0kQNARXq72IlSic0oabg2FC1NU68L4RdHrNJDd8bFwrphYA==", + "dependencies": { + "@stablelib/binary": "^1.0.1", + "@stablelib/constant-time": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@stablelib/sha512": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/sha512/-/sha512-1.0.1.tgz", + "integrity": "sha512-13gl/iawHV9zvDKciLo1fQ8Bgn2Pvf7OV6amaRVKiq3pjQ3UmEpXxWiAfV8tYjUpeZroBxtyrwtdooQT/i3hzw==", + "dependencies": { + "@stablelib/binary": "^1.0.1", + "@stablelib/hash": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@stablelib/wipe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/wipe/-/wipe-1.0.1.tgz", + "integrity": "sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg==" + }, + "node_modules/@stablelib/x25519": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@stablelib/x25519/-/x25519-1.0.3.tgz", + "integrity": "sha512-KnTbKmUhPhHavzobclVJQG5kuivH+qDLpe84iRqX3CLrKp881cF160JvXJ+hjn1aMyCwYOKeIZefIH/P5cJoRw==", + "dependencies": { + "@stablelib/keyagreement": "^1.0.1", + "@stablelib/random": "^1.0.2", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@stablelib/xsalsa20": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@stablelib/xsalsa20/-/xsalsa20-1.0.2.tgz", + "integrity": "sha512-7XdBGbcNgBShmuhDXv1G1WPVCkjZdkb1oPMzSidO7Fve0MHntH6TjFkj5bfLI+aRE+61weO076vYpP/jmaAYog==", + "dependencies": { + "@stablelib/binary": "^1.0.1", + "@stablelib/salsa20": "^1.0.2", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@taquito/http-utils": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/http-utils/-/http-utils-14.0.0.tgz", + "integrity": "sha512-ZWZzod/+/OEE26b9CnDRjHGfUKBJft3aXv/e/A9bTHAtvRNJqGIhofHcDg/jTaolBMarCF2b3XBYw35aOOSk4A==", + "dependencies": { + "axios": "^0.26.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@taquito/local-forging": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/local-forging/-/local-forging-14.0.0.tgz", + "integrity": "sha512-Nm0xGmS1Jzd+tU0a/8Y8XuTghbiPBgHDLo+e4141TK3OAwTzOw0an+w3xK9QVfzvxfIcZBSMjeMZzOwDdiqkJQ==", + "dependencies": { + "@taquito/utils": "^14.0.0", + "bignumber.js": "^9.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@taquito/michel-codec": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/michel-codec/-/michel-codec-14.0.0.tgz", + "integrity": "sha512-ftnBvUVddlHBqvQbGPHEb26KrS4lIcaZ1eIpYJWiz+akb4Pcfyq7j/OEsDZbB7Pl2FP9hqu7ZygOF34zY6Lrtw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@taquito/michelson-encoder": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/michelson-encoder/-/michelson-encoder-14.0.0.tgz", + "integrity": "sha512-KIS+xl4rKfnd6hf9LUr6W+Pb7gv8F/Qsx0fho9CtM2PodKvdef3YlvkpScBUM9QZntAlvq2XQXUVXcZkbvxygw==", + "dependencies": { + "@taquito/rpc": "^14.0.0", + "@taquito/utils": "^14.0.0", + "bignumber.js": "^9.0.2", + "fast-json-stable-stringify": "^2.1.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@taquito/rpc": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/rpc/-/rpc-14.0.0.tgz", + "integrity": "sha512-FMfb80sA+VJwNx8OTNN07boDAt2roISqLLCUgmOIwy/cFDqhII7gdS4aYWJWqlKbdPKCPqh3a3ZQD1X/jyQHOA==", + "dependencies": { + "@taquito/http-utils": "^14.0.0", + "@taquito/utils": "^14.0.0", + "bignumber.js": "^9.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@taquito/signer": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/signer/-/signer-14.0.0.tgz", + "integrity": "sha512-vDqp/quzAsOiVikUt5MYUKhHI3S9qlasazyXs99xK9qpGLotbx6aseKcfb/dkaTo4/eoMzP4XzTVdnk0AqcCkw==", + "dependencies": { + "@stablelib/blake2b": "^1.0.1", + "@stablelib/ed25519": "^1.0.2", + "@stablelib/nacl": "^1.0.3", + "@taquito/taquito": "^14.0.0", + "@taquito/utils": "^14.0.0", + "elliptic": "^6.5.4", + "pbkdf2": "^3.1.2", + "typedarray-to-buffer": "^4.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@taquito/taquito": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/taquito/-/taquito-14.0.0.tgz", + "integrity": "sha512-JaXfvqOCF3dkwXxhe00Ravb8WLMC2VqJxerf4GrGUEpJw+NAkwbGEb8k/52+MQQdlxMPepZdPPru/HM3nFG0Tw==", + "hasInstallScript": true, + "dependencies": { + "@taquito/http-utils": "^14.0.0", + "@taquito/local-forging": "^14.0.0", + "@taquito/michel-codec": "^14.0.0", + "@taquito/michelson-encoder": "^14.0.0", + "@taquito/rpc": "^14.0.0", + "@taquito/utils": "^14.0.0", + "bignumber.js": "^9.0.2", + "rxjs": "^6.6.3" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@taquito/utils": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/utils/-/utils-14.0.0.tgz", + "integrity": "sha512-0RSHn/CzbcbMdldJJIlXyxOvAajwmL6iPKJ6NaRyYJqqLM2CxYjG72KpXVv716pCMV1MbIWsOAr9FKbxW73PsA==", + "dependencies": { + "@stablelib/blake2b": "^1.0.1", + "@stablelib/ed25519": "^1.0.2", + "@types/bs58check": "^2.1.0", + "bignumber.js": "^9.0.2", + "blakejs": "^1.2.1", + "bs58check": "^2.1.2", + "buffer": "^6.0.3", + "elliptic": "^6.5.4", + "typedarray-to-buffer": "^4.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==" + }, + "node_modules/@types/bs58check": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/bs58check/-/bs58check-2.1.0.tgz", + "integrity": "sha512-OxsysnJQh82vy9DRbOcw9m2j/WiyqZLn0YBhKxdQ+aCwoHj+tWzyCgpwAkr79IfDXZKxc6h7k89T9pwS78CqTQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "18.11.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", + "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==" + }, + "node_modules/acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "node_modules/axios": { + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "dependencies": { + "follow-redirects": "^1.14.8" + } + }, + "node_modules/base-x": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", + "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bignumber.js": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.0.tgz", + "integrity": "sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==", + "engines": { + "node": "*" + } + }, + "node_modules/blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==" + }, + "node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + }, + "node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "dependencies": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/typedarray-to-buffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-4.0.0.tgz", + "integrity": "sha512-6dOYeZfS3O9RtRD1caom0sMxgK59b27+IwoNy8RDPsmslSGOyU+mpTamlaIW7aNKi90ZQZ9DFaZL3YRoiSCULQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/typescript": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "engines": { + "node": ">=6" + } + } + }, + "dependencies": { + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "requires": { + "@jridgewell/trace-mapping": "0.3.9" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + }, + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@stablelib/binary": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/binary/-/binary-1.0.1.tgz", + "integrity": "sha512-ClJWvmL6UBM/wjkvv/7m5VP3GMr9t0osr4yVgLZsLCOz4hGN9gIAFEqnJ0TsSMAN+n840nf2cHZnA5/KFqHC7Q==", + "requires": { + "@stablelib/int": "^1.0.1" + } + }, + "@stablelib/blake2b": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/blake2b/-/blake2b-1.0.1.tgz", + "integrity": "sha512-B3KyKoBAjkIFeH7romcF96i+pVFYk7K2SBQ1pZvaxV+epSBXJ+n0C66esUhyz6FF+5FbdQVm77C5fzGFcEZpKA==", + "requires": { + "@stablelib/binary": "^1.0.1", + "@stablelib/hash": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "@stablelib/bytes": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/bytes/-/bytes-1.0.1.tgz", + "integrity": "sha512-Kre4Y4kdwuqL8BR2E9hV/R5sOrUj6NanZaZis0V6lX5yzqC3hBuVSDXUIBqQv/sCpmuWRiHLwqiT1pqqjuBXoQ==" + }, + "@stablelib/constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/constant-time/-/constant-time-1.0.1.tgz", + "integrity": "sha512-tNOs3uD0vSJcK6z1fvef4Y+buN7DXhzHDPqRLSXUel1UfqMB1PWNsnnAezrKfEwTLpN0cGH2p9NNjs6IqeD0eg==" + }, + "@stablelib/ed25519": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@stablelib/ed25519/-/ed25519-1.0.3.tgz", + "integrity": "sha512-puIMWaX9QlRsbhxfDc5i+mNPMY+0TmQEskunY1rZEBPi1acBCVQAhnsk/1Hk50DGPtVsZtAWQg4NHGlVaO9Hqg==", + "requires": { + "@stablelib/random": "^1.0.2", + "@stablelib/sha512": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "@stablelib/hash": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/hash/-/hash-1.0.1.tgz", + "integrity": "sha512-eTPJc/stDkdtOcrNMZ6mcMK1e6yBbqRBaNW55XA1jU8w/7QdnCF0CmMmOD1m7VSkBR44PWrMHU2l6r8YEQHMgg==" + }, + "@stablelib/int": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/int/-/int-1.0.1.tgz", + "integrity": "sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w==" + }, + "@stablelib/keyagreement": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/keyagreement/-/keyagreement-1.0.1.tgz", + "integrity": "sha512-VKL6xBwgJnI6l1jKrBAfn265cspaWBPAPEc62VBQrWHLqVgNRE09gQ/AnOEyKUWrrqfD+xSQ3u42gJjLDdMDQg==", + "requires": { + "@stablelib/bytes": "^1.0.1" + } + }, + "@stablelib/nacl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@stablelib/nacl/-/nacl-1.0.4.tgz", + "integrity": "sha512-PJ2U/MrkXSKUM8C4qFs87WeCNxri7KQwR8Cdwm9q2sweGuAtTvOJGuW0F3N+zn+ySLPJA98SYWSSpogMJ1gCmw==", + "requires": { + "@stablelib/poly1305": "^1.0.1", + "@stablelib/random": "^1.0.2", + "@stablelib/wipe": "^1.0.1", + "@stablelib/x25519": "^1.0.3", + "@stablelib/xsalsa20": "^1.0.2" + } + }, + "@stablelib/poly1305": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/poly1305/-/poly1305-1.0.1.tgz", + "integrity": "sha512-1HlG3oTSuQDOhSnLwJRKeTRSAdFNVB/1djy2ZbS35rBSJ/PFqx9cf9qatinWghC2UbfOYD8AcrtbUQl8WoxabA==", + "requires": { + "@stablelib/constant-time": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "@stablelib/random": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@stablelib/random/-/random-1.0.2.tgz", + "integrity": "sha512-rIsE83Xpb7clHPVRlBj8qNe5L8ISQOzjghYQm/dZ7VaM2KHYwMW5adjQjrzTZCchFnNCNhkwtnOBa9HTMJCI8w==", + "requires": { + "@stablelib/binary": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "@stablelib/salsa20": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@stablelib/salsa20/-/salsa20-1.0.2.tgz", + "integrity": "sha512-nfjKzw0KTKrrKBasEP+j7UP4I8Xudom8lVZIBCp0kQNARXq72IlSic0oabg2FC1NU68L4RdHrNJDd8bFwrphYA==", + "requires": { + "@stablelib/binary": "^1.0.1", + "@stablelib/constant-time": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "@stablelib/sha512": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/sha512/-/sha512-1.0.1.tgz", + "integrity": "sha512-13gl/iawHV9zvDKciLo1fQ8Bgn2Pvf7OV6amaRVKiq3pjQ3UmEpXxWiAfV8tYjUpeZroBxtyrwtdooQT/i3hzw==", + "requires": { + "@stablelib/binary": "^1.0.1", + "@stablelib/hash": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "@stablelib/wipe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/wipe/-/wipe-1.0.1.tgz", + "integrity": "sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg==" + }, + "@stablelib/x25519": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@stablelib/x25519/-/x25519-1.0.3.tgz", + "integrity": "sha512-KnTbKmUhPhHavzobclVJQG5kuivH+qDLpe84iRqX3CLrKp881cF160JvXJ+hjn1aMyCwYOKeIZefIH/P5cJoRw==", + "requires": { + "@stablelib/keyagreement": "^1.0.1", + "@stablelib/random": "^1.0.2", + "@stablelib/wipe": "^1.0.1" + } + }, + "@stablelib/xsalsa20": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@stablelib/xsalsa20/-/xsalsa20-1.0.2.tgz", + "integrity": "sha512-7XdBGbcNgBShmuhDXv1G1WPVCkjZdkb1oPMzSidO7Fve0MHntH6TjFkj5bfLI+aRE+61weO076vYpP/jmaAYog==", + "requires": { + "@stablelib/binary": "^1.0.1", + "@stablelib/salsa20": "^1.0.2", + "@stablelib/wipe": "^1.0.1" + } + }, + "@taquito/http-utils": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/http-utils/-/http-utils-14.0.0.tgz", + "integrity": "sha512-ZWZzod/+/OEE26b9CnDRjHGfUKBJft3aXv/e/A9bTHAtvRNJqGIhofHcDg/jTaolBMarCF2b3XBYw35aOOSk4A==", + "requires": { + "axios": "^0.26.0" + } + }, + "@taquito/local-forging": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/local-forging/-/local-forging-14.0.0.tgz", + "integrity": "sha512-Nm0xGmS1Jzd+tU0a/8Y8XuTghbiPBgHDLo+e4141TK3OAwTzOw0an+w3xK9QVfzvxfIcZBSMjeMZzOwDdiqkJQ==", + "requires": { + "@taquito/utils": "^14.0.0", + "bignumber.js": "^9.0.2" + } + }, + "@taquito/michel-codec": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/michel-codec/-/michel-codec-14.0.0.tgz", + "integrity": "sha512-ftnBvUVddlHBqvQbGPHEb26KrS4lIcaZ1eIpYJWiz+akb4Pcfyq7j/OEsDZbB7Pl2FP9hqu7ZygOF34zY6Lrtw==" + }, + "@taquito/michelson-encoder": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/michelson-encoder/-/michelson-encoder-14.0.0.tgz", + "integrity": "sha512-KIS+xl4rKfnd6hf9LUr6W+Pb7gv8F/Qsx0fho9CtM2PodKvdef3YlvkpScBUM9QZntAlvq2XQXUVXcZkbvxygw==", + "requires": { + "@taquito/rpc": "^14.0.0", + "@taquito/utils": "^14.0.0", + "bignumber.js": "^9.0.2", + "fast-json-stable-stringify": "^2.1.0" + } + }, + "@taquito/rpc": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/rpc/-/rpc-14.0.0.tgz", + "integrity": "sha512-FMfb80sA+VJwNx8OTNN07boDAt2roISqLLCUgmOIwy/cFDqhII7gdS4aYWJWqlKbdPKCPqh3a3ZQD1X/jyQHOA==", + "requires": { + "@taquito/http-utils": "^14.0.0", + "@taquito/utils": "^14.0.0", + "bignumber.js": "^9.0.2" + } + }, + "@taquito/signer": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/signer/-/signer-14.0.0.tgz", + "integrity": "sha512-vDqp/quzAsOiVikUt5MYUKhHI3S9qlasazyXs99xK9qpGLotbx6aseKcfb/dkaTo4/eoMzP4XzTVdnk0AqcCkw==", + "requires": { + "@stablelib/blake2b": "^1.0.1", + "@stablelib/ed25519": "^1.0.2", + "@stablelib/nacl": "^1.0.3", + "@taquito/taquito": "^14.0.0", + "@taquito/utils": "^14.0.0", + "elliptic": "^6.5.4", + "pbkdf2": "^3.1.2", + "typedarray-to-buffer": "^4.0.0" + } + }, + "@taquito/taquito": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/taquito/-/taquito-14.0.0.tgz", + "integrity": "sha512-JaXfvqOCF3dkwXxhe00Ravb8WLMC2VqJxerf4GrGUEpJw+NAkwbGEb8k/52+MQQdlxMPepZdPPru/HM3nFG0Tw==", + "requires": { + "@taquito/http-utils": "^14.0.0", + "@taquito/local-forging": "^14.0.0", + "@taquito/michel-codec": "^14.0.0", + "@taquito/michelson-encoder": "^14.0.0", + "@taquito/rpc": "^14.0.0", + "@taquito/utils": "^14.0.0", + "bignumber.js": "^9.0.2", + "rxjs": "^6.6.3" + } + }, + "@taquito/utils": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@taquito/utils/-/utils-14.0.0.tgz", + "integrity": "sha512-0RSHn/CzbcbMdldJJIlXyxOvAajwmL6iPKJ6NaRyYJqqLM2CxYjG72KpXVv716pCMV1MbIWsOAr9FKbxW73PsA==", + "requires": { + "@stablelib/blake2b": "^1.0.1", + "@stablelib/ed25519": "^1.0.2", + "@types/bs58check": "^2.1.0", + "bignumber.js": "^9.0.2", + "blakejs": "^1.2.1", + "bs58check": "^2.1.2", + "buffer": "^6.0.3", + "elliptic": "^6.5.4", + "typedarray-to-buffer": "^4.0.0" + } + }, + "@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" + }, + "@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" + }, + "@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" + }, + "@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==" + }, + "@types/bs58check": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/bs58check/-/bs58check-2.1.0.tgz", + "integrity": "sha512-OxsysnJQh82vy9DRbOcw9m2j/WiyqZLn0YBhKxdQ+aCwoHj+tWzyCgpwAkr79IfDXZKxc6h7k89T9pwS78CqTQ==", + "requires": { + "@types/node": "*" + } + }, + "@types/node": { + "version": "18.11.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", + "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==" + }, + "acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==" + }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==" + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "axios": { + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "requires": { + "follow-redirects": "^1.14.8" + } + }, + "base-x": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", + "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "bignumber.js": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.0.tgz", + "integrity": "sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==" + }, + "blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==" + }, + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + }, + "bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "requires": { + "base-x": "^3.0.2" + } + }, + "bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "requires": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" + }, + "dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==" + }, + "elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + }, + "pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "requires": { + "tslib": "^1.9.0" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "requires": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "typedarray-to-buffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-4.0.0.tgz", + "integrity": "sha512-6dOYeZfS3O9RtRD1caom0sMxgK59b27+IwoNy8RDPsmslSGOyU+mpTamlaIW7aNKi90ZQZ9DFaZL3YRoiSCULQ==" + }, + "typescript": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" + } + } +} diff --git a/smartpy/bts/package.json b/smartpy/bts/package.json new file mode 100644 index 00000000..e24aa957 --- /dev/null +++ b/smartpy/bts/package.json @@ -0,0 +1,26 @@ +{ + "name": "create-tezos-app", + "version": "1.0.3", + "description": "A Tezos Dapp Starter using Typescript and Taquito.", + "bin": "./bin/cli.js", + "scripts": { + "compile": "bash ./compile.sh", + "deploy": "npx ts-node scripts/deploy.ts", + "test" : "bash ./test.sh" + }, + "author": "Roshan Parajuli", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/0xrpj/create-tezos-dapp" + }, + "dependencies": { + "@taquito/signer": "^14.0.0", + "@taquito/taquito": "^14.0.0", + "dotenv": "^16.0.3", + "ts-node": "^10.9.1" + }, + "devDependencies": { + "typescript": "^4.8.4" + } +} \ No newline at end of file diff --git a/smartpy/bts/scripts/deploy.ts b/smartpy/bts/scripts/deploy.ts new file mode 100644 index 00000000..9b50353a --- /dev/null +++ b/smartpy/bts/scripts/deploy.ts @@ -0,0 +1,62 @@ +import * as dotenv from "dotenv"; +import { TezosToolkit } from "@taquito/taquito"; +import { InMemorySigner } from "@taquito/signer"; +import { NETWORK } from "../config/config"; + +dotenv.config(); + +const deploy = async () => { + type networkTypes = keyof typeof NETWORK; + + const { ORIGINATOR_PRIVATE_KEY } = process.env; + let file = process.argv[2]; + let rpcType: networkTypes = process.argv[3] + ?.toUpperCase() + .slice(1) as networkTypes; + + console.info("Staring validation..."); + + if (!ORIGINATOR_PRIVATE_KEY) { + console.error("Private key missing in the environment."); + return; + } + + if (!file) { + console.log("Pass filename to deploy! Read the docs."); + return; + } + + if (!rpcType || !Object.keys(NETWORK).includes(rpcType)) { + console.log("Valid networks:", Object.keys(NETWORK)); + console.error("Invalid network"); + return; + } + + file = file.toLowerCase(); + + const signer = await InMemorySigner.fromSecretKey(ORIGINATOR_PRIVATE_KEY); + const Tezos = new TezosToolkit(NETWORK[rpcType].url); + Tezos.setProvider({ signer: signer }); + + console.log(`Validation checks out... \nDeploying the ${file} contract..\n`); + try { + const { hash, contractAddress } = await Tezos.contract.originate({ + code: require(`../contracts/build/${file}.json`), + init: require(`../contracts/build/${file}_storage.json`), + }); + + console.log("Successfully deployed contract"); + console.log(`>> Transaction hash: ${hash}`); + console.log(`>> Contract address: ${contractAddress}`); + } catch (error) { + console.log( + `Oops... Deployment faced an issue.\nHere's the detailed info about the error,\n${error}` + ); + + console.log( + "Make sure of these things. \n1. Compiled contracts are inside the build folder.\n2. You have enough Tezos balance in the wallet for deployment." + ); + } +}; + +deploy(); diff --git a/smartpy/bts/test.sh b/smartpy/bts/test.sh new file mode 100644 index 00000000..34a7156e --- /dev/null +++ b/smartpy/bts/test.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash + +set -e -o pipefail + +echo "----------------------------------------" +echo "Compiling contracts ... " +echo "----------------------------------------" + +# Expected location of SmartPy CLI. +SMART_PY_CLI=~/smartpy-cli/SmartPy.sh + +# Build artifact directory. +TEST_OUT_DIR=./contracts/build/.contract_build/test + +# Array of SmartPy files to compile. +# CONTRACTS_ARRAY=(counter) + +# Exit if SmartPy is not installed. +if [ ! -f "$SMART_PY_CLI" ]; then + echo "Fatal: Please install SmartPy CLI at $SMART_PY_CLI" && exit +fi + +function processContract { + CONTRACT_NAME=$1 + TEST_OUT_DIR=$2 + CONTRACT_IN_TEST="./contracts/tests/${CONTRACT_NAME}.py" + CONTRACT_OUT="${CONTRACT_NAME}.json" + STORAGE_OUT="${CONTRACT_NAME}_storage.json" + CONTRACT_COMPILED="${CONTRACT_NAME}/step_000_cont_0_contract.json" + STORAGE_COMPILED="${CONTRACT_NAME}/step_000_cont_0_storage.json" + + echo ">> Processing ${CONTRACT_NAME}" + + # Ensure file exists. + if [ ! -f "$CONTRACT_IN_TEST" ]; then + echo "Fatal: $CONTRACT_IN_TEST not found. Running from wrong dir?" && exit + fi + + echo ">>> Commencing the tests ${CONTRACT_NAME} ... " + $SMART_PY_CLI test $CONTRACT_IN_TEST $TEST_OUT_DIR --html +} + +export PYTHONPATH=$PWD + + +# Use if you want to pass a contract or more as arguments. +for n in $(seq 1 $#); do + processContract $1 $TEST_OUT_DIR + shift +done + + +echo "> Test Complete." \ No newline at end of file From 827ca2e72e592e31b3fb5c3b8b2a2e1f3ea354d9 Mon Sep 17 00:00:00 2001 From: simusud Date: Mon, 5 Jun 2023 18:28:09 +0545 Subject: [PATCH 084/211] fix(bts:library): fixed decode_transfer_coin_msg function --- .../bts/contracts/src/RLP_decode_struct.py | 38 +++++++++++-------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/smartpy/bts/contracts/src/RLP_decode_struct.py b/smartpy/bts/contracts/src/RLP_decode_struct.py index 213ad7df..2cb8a901 100644 --- a/smartpy/bts/contracts/src/RLP_decode_struct.py +++ b/smartpy/bts/contracts/src/RLP_decode_struct.py @@ -110,36 +110,42 @@ def decode_transfer_coin_msg(self, rlp): counter.value = 0 new_temp_byt = sp.local("new_temp_byt", sp.bytes("0x")) rv_assets = sp.local("assets", {}, sp.TMap(sp.TNat, types.Types.Asset)) + nsl3_tcm = sp.local("nsl3_bts_tcm", sp.map(tkey=sp.TNat)) + view_value = sp.local("view_value", sp.map(tkey=sp.TNat)) + counter_nested = sp.local("counter_nested", sp.nat(0), t=sp.TNat) + temp_byt = sp.local("tempByt2", sp.bytes("0x")) + temp_byt_nested = sp.local("tempByt2nested", sp.bytes("0x")) sp.for x in new_sub_list.items(): new_temp_byt.value = x.value # sp.if sp.slice(new_temp_byt.value, 0, 2).open_some() == sp.bytes("0xb846"): # new_temp_byt.value = sp.slice(new_temp_byt.value, 2, sp.as_nat(sp.len(new_temp_byt.value) - 2)).open_some() - temp_byt = sp.local("tempByt2", sp.bytes("0x")) - temp_int = sp.local("tempInt", sp.nat(0)) - counter.value = 0 - nsl3_tcm = sp.local("nsl3_bts_tcm", sp.map(tkey=sp.TNat)) is_list_lambda = sp.view("is_list", self.data.helper, new_temp_byt.value, t=sp.TBool).open_some() with sp.if_(is_list_lambda): nsl3_tcm.value = sp.view("decode_list", self.data.helper, new_temp_byt.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, new_temp_byt.value, t=sp.TBytes).open_some() + decode_len = sp.view("without_length_prefix", self.data.helper, new_temp_byt.value, + t=sp.TBytes).open_some() nsl3_tcm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - view_value = nsl3_tcm.value - sp.for i in view_value.items(): - sp.if counter.value == 1: + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + view_value.value = nsl3_tcm.value + counter_nested.value = sp.nat(0) + sp.for i in view_value.value.items(): + sp.if counter_nested.value == 1: # check_length = sp.view("prefix_length", self.data.helper, i.value, t=sp.TNat).open_some() # with sp.if_ (check_length > 0): - i.value = sp.view("without_length_prefix", self.data.helper, i.value, - t=sp.TBytes).open_some() - temp_int.value = Utils2.Int.of_bytes(i.value) - sp.if counter.value == 0: + temp_byt_nested.value = sp.view("without_length_prefix", self.data.helper, i.value, + t=sp.TBytes).open_some() + sp.if counter_nested.value == 0: temp_byt.value = i.value - rv_assets.value[counter.value] = sp.record(coin_name=sp.view("decode_string", self.data.helper, temp_byt.value, t=sp.TString).open_some() - , value=temp_int.value) - counter.value = counter.value + 1 + counter_nested.value += 1 + + rv_assets.value[counter.value] = sp.record(coin_name=sp.view("decode_string", self.data.helper, temp_byt.value, t=sp.TString).open_some() + , value=Utils2.Int.of_bytes(temp_byt_nested.value)) + + counter.value = counter.value + 1 + rv1 = sp.view("decode_string", self.data.helper, rv1_byt.value, t=sp.TString).open_some() rv2 = sp.view("decode_string", self.data.helper, rv2_byt.value, t=sp.TString).open_some() return sp.record(from_= rv1, to = rv2 , assets = rv_assets.value) From ece3793ac736b755995aa3416720cd59d42c2222 Mon Sep 17 00:00:00 2001 From: simusud Date: Mon, 5 Jun 2023 21:01:03 +0545 Subject: [PATCH 085/211] fix(bts:library): fixed encode_transfer_coin_msg function --- smartpy/bts/contracts/src/RLP_encode_struct.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/smartpy/bts/contracts/src/RLP_encode_struct.py b/smartpy/bts/contracts/src/RLP_encode_struct.py index 17b15135..daa180b6 100644 --- a/smartpy/bts/contracts/src/RLP_encode_struct.py +++ b/smartpy/bts/contracts/src/RLP_encode_struct.py @@ -18,20 +18,20 @@ def encode_transfer_coin_msg(self, data): sp.set_type(data, types.Types.TransferCoin) rlp = sp.local("rlp", sp.bytes("0x")) + rlp_list = sp.local("rlp_list", [], t=sp.TList(sp.TBytes)) temp = sp.local("temp", sp.bytes("0x")) coin_name = sp.local("coin_name", sp.bytes("0x")) - encode_lis_byte = sp.local("encode_lis_byte", sp.bytes("0x")) sp.for i in sp.range(0, sp.len(data.assets)): coin_name.value = sp.view("encode_string", self.data.helper, data.assets.get(i, default_value=sp.record(coin_name="",value=sp.nat(0))).coin_name, t=sp.TBytes).open_some() temp.value = sp.view("encode_nat", self.data.helper, data.assets.get(i, default_value=sp.record(coin_name="",value=sp.nat(0))).value, t=sp.TBytes).open_some() - encode_lis_byte.value = sp.view("encode_list", self.data.helper, [rlp.value, coin_name.value, temp.value], t=sp.TBytes).open_some() - rlp.value = sp.view("encode_list", self.data.helper, [encode_lis_byte.value], t=sp.TBytes).open_some() + rlp_list.value.push(sp.view("encode_list", self.data.helper, [coin_name.value, temp.value], t=sp.TBytes).open_some()) # rlp.value = sp.view("with_length_prefix", self.data.helper, rlp.value, # t=sp.TBytes).open_some() + assets_list = sp.view("encode_list", self.data.helper, rlp_list.value, t=sp.TBytes).open_some() from_addr_encoded = sp.view("encode_string", self.data.helper, data.from_addr, t=sp.TBytes).open_some() to_addr_encoded = sp.view("encode_string", self.data.helper, data.to, t=sp.TBytes).open_some() - rlp.value = sp.view("encode_list", self.data.helper, [from_addr_encoded, to_addr_encoded, rlp.value], t=sp.TBytes).open_some() + rlp.value = sp.view("encode_list", self.data.helper, [from_addr_encoded, to_addr_encoded, assets_list], t=sp.TBytes).open_some() final_rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp.value, t=sp.TBytes).open_some() return final_rlp_bytes_with_prefix From 82ce583277f025a950e9359ab09086c8f9f0e1b0 Mon Sep 17 00:00:00 2001 From: simusud Date: Fri, 9 Jun 2023 14:41:59 +0545 Subject: [PATCH 086/211] fix(bts): fixed transfer fees function and added default value while reading from maps --- smartpy/bts/contracts/src/bts_core.py | 13 ++++++++----- smartpy/bts/contracts/src/bts_periphery.py | 14 +++++++------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/smartpy/bts/contracts/src/bts_core.py b/smartpy/bts/contracts/src/bts_core.py index 584f89cf..a05d035e 100644 --- a/smartpy/bts/contracts/src/bts_core.py +++ b/smartpy/bts/contracts/src/bts_core.py @@ -285,7 +285,7 @@ def get_accumulated_fees(self): accumulated_fees = sp.local("accumulated_fees", sp.map(tkey=sp.TNat, tvalue=types.Types.Asset)) i = sp.local("i", sp.nat(0)) sp.for item in self.data.coins_name: - accumulated_fees.value[i.value] = sp.record(coin_name=item, value=self.data.aggregation_fee.get(item)) + accumulated_fees.value[i.value] = sp.record(coin_name=item, value=self.data.aggregation_fee.get(item, default_value=sp.nat(0))) i.value += sp.nat(1) sp.result(accumulated_fees.value) @@ -651,9 +651,12 @@ def transfer_fees(self, fa): sp.for item in self.data.coins_name: sp.if self.data.aggregation_fee.get(item, default_value=sp.nat(0)) != sp.nat(0): self.data.charged_coins[l.value] = item - self.data.charged_amounts[l.value] = self.data.aggregation_fee.get(item) + self.data.charged_amounts[l.value] = self.data.aggregation_fee.get(item, default_value=sp.nat(0)) del self.data.aggregation_fee[item] - l.value += sp.nat(1) + l.value += sp.nat(1) + + _charged_coins = sp.local("_charged_coins", self.data.charged_coins) + _charged_amounts = sp.local("_charged_amounts", self.data.charged_amounts) # call send_service_message on bts_periphery send_service_message_args_type = sp.TRecord(_from=sp.TAddress, to=sp.TString, @@ -663,8 +666,8 @@ def transfer_fees(self, fa): send_service_message_entry_point = sp.contract(send_service_message_args_type, self.data.bts_periphery_address.open_some("Address not set"), "send_service_message").open_some() - send_service_message_args = sp.record(_from=sp.self_address, to=fa, coin_names=self.data.charged_coins, - values=self.data.charged_amounts, + send_service_message_args = sp.record(_from=sp.self_address, to=fa, coin_names=_charged_coins.value, + values=_charged_amounts.value, fees=sp.map({})) sp.transfer(send_service_message_args, sp.tez(0), send_service_message_entry_point) diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index a35cd555..f67b85af 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -219,13 +219,13 @@ def send_service_message(self, _from, to, coin_names, values, fees): assets_details = sp.compute(sp.map(tkey=sp.TNat, tvalue=types.Types.AssetTransferDetail)) sp.for i in sp.range(sp.nat(0), sp.len(coin_names)): assets[i]=sp.record( - coin_name=coin_names[i], - value=values[i] + coin_name=coin_names.get(i, default_value=sp.string("CoinNotFound")), + value=values.get(i, default_value=sp.nat(0)) ) assets_details[i] = sp.record( - coin_name=coin_names[i], - value=values[i], - fee=fees[i] + coin_name=coin_names.get(i, default_value=sp.string("CoinNotFound")), + value=values.get(i, default_value=sp.nat(0)), + fee=fees.get(i, default_value=sp.nat(0)) ) self.data.serial_no += 1 @@ -429,8 +429,8 @@ def handle_response_service(self, sn, code, msg): ) handle_response_service_entry_point = sp.contract(handle_response_service_args_type, self.data.bts_core, "handle_response_service").open_some("invalid call") handle_response_service_args = sp.record( - requester=caller, coin_name=self.data.requests.get(sn).coin_names.get(i), value=self.data.requests.get(sn).amounts.get(i), - fee=self.data.requests.get(sn).fees.get(i), rsp_code=code + requester=caller, coin_name=self.data.requests.get(sn).coin_names.get(i, default_value=sp.string("CoinNotFound")), + value=self.data.requests.get(sn).amounts.get(i, default_value=sp.nat(0)),fee=self.data.requests.get(sn).fees.get(i, default_value=sp.nat(0)), rsp_code=code ) sp.transfer(handle_response_service_args, sp.tez(0), handle_response_service_entry_point) From f6dbc5ee0f53b5e080ceb2ec7f78383c0d96674a Mon Sep 17 00:00:00 2001 From: simusud Date: Mon, 12 Jun 2023 21:35:55 +0545 Subject: [PATCH 087/211] perf(bmc): improved performance by splitting rlp encode and decode into separate contracts --- .../bmc/contracts/src/RLP_decode_struct.py | 67 +++++++++++++---- .../bmc/contracts/src/RLP_encode_struct.py | 36 ++++++++-- smartpy/bmc/contracts/src/bmc_management.py | 30 +++++--- smartpy/bmc/contracts/src/bmc_periphery.py | 72 ++++++++++++------- 4 files changed, 153 insertions(+), 52 deletions(-) diff --git a/smartpy/bmc/contracts/src/RLP_decode_struct.py b/smartpy/bmc/contracts/src/RLP_decode_struct.py index 926fd4d5..36303b8a 100644 --- a/smartpy/bmc/contracts/src/RLP_decode_struct.py +++ b/smartpy/bmc/contracts/src/RLP_decode_struct.py @@ -2,11 +2,21 @@ Utils2 = sp.io.import_script_from_url("https://raw.githubusercontent.com/RomarQ/tezos-sc-utils/main/smartpy/utils.py") types = sp.io.import_script_from_url("file:./contracts/src/Types.py") +helper_file = sp.io.import_script_from_url("file:./contracts/src/helper.py") -class DecodeLibrary: +class DecodeLibrary(sp.Contract): + def __init__(self, helper_contract, helper_negative_address): + self.init( + helper=helper_contract, + helper_parse_negative=helper_negative_address + ) + + @sp.onchain_view() def decode_bmc_message(self, rlp): + sp.set_type(rlp, sp.TBytes) + rlp_bm = sp.local("rlp_bm", sp.map(tkey=sp.TNat)) is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() with sp.if_(is_list_lambda): @@ -34,15 +44,17 @@ def decode_bmc_message(self, rlp): temp_byt.value = k.value counter.value = counter.value + 1 temp_byt.value = sp.view("without_length_prefix", self.data.helper, temp_byt.value, t=sp.TBytes).open_some() - return sp.record(src=temp_map_string.get("src"), + sp.result(sp.record(src=temp_map_string.get("src"), dst=temp_map_string.get("dst"), svc=temp_map_string.get("svc"), sn=temp_int.value, - message=temp_byt.value) - + message=temp_byt.value)) + @sp.onchain_view() def decode_response(self, rlp): - temp_int = sp.local("int1", 0) + sp.set_type(rlp, sp.TBytes) + + temp_int = sp.local("int1", sp.nat(0)) temp_byt = sp.local("byt1", sp.bytes("0x")) rlp_dr = sp.local("rlp_dr", sp.map(tkey=sp.TNat)) is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() @@ -61,9 +73,12 @@ def decode_response(self, rlp): temp_byt.value = m.value counter.value = counter.value + 1 - return sp.record(code=temp_int.value, message=sp.view("decode_string", self.data.helper, temp_byt.value, t=sp.TString).open_some()) + sp.result(sp.record(code=temp_int.value, message=sp.view("decode_string", self.data.helper, temp_byt.value, t=sp.TString).open_some())) + @sp.onchain_view() def decode_propagate_message(self, rlp): + sp.set_type(rlp, sp.TBytes) + rlp_pm = sp.local("rlp_pm", sp.map(tkey=sp.TNat)) is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() with sp.if_(is_list_lambda): @@ -79,9 +94,12 @@ def decode_propagate_message(self, rlp): sp.if counter.value == 0: temp_string.value = sp.view("decode_string", self.data.helper, d.value, t=sp.TString).open_some() counter.value = counter.value + 1 - return temp_string.value + sp.result(temp_string.value) + @sp.onchain_view() def decode_init_message(self, rlp): + sp.set_type(rlp, sp.TBytes) + rlp_im = sp.local("rlp_im", sp.map(tkey=sp.TNat)) is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() with sp.if_(is_list_lambda): @@ -115,9 +133,12 @@ def decode_init_message(self, rlp): sp.for x in new_sub_list.items(): _links.value.push(sp.view("decode_string", self.data.helper, x.value, t=sp.TString).open_some()) counter.value = counter.value + 1 - return _links.value + sp.result(_links.value) + @sp.onchain_view() def decode_bmc_service(self, rlp): + sp.set_type(rlp, sp.TBytes) + rlp_bs = sp.local("rlp_bs", sp.map(tkey=sp.TNat)) is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() with sp.if_(is_list_lambda): @@ -137,10 +158,13 @@ def decode_bmc_service(self, rlp): temp_byt.value = b.value counter.value = counter.value + 1 temp_byt.value = sp.view("without_length_prefix", self.data.helper, temp_byt.value, t=sp.TBytes).open_some() - return sp.record(serviceType=temp_string.value, - payload=temp_byt.value) + sp.result(sp.record(serviceType=temp_string.value, + payload=temp_byt.value)) + @sp.onchain_view() def decode_gather_fee_message(self, rlp): + sp.set_type(rlp, sp.TBytes) + rlp_gm = sp.local("rlp_gm", sp.map(tkey=sp.TNat)) is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() with sp.if_(is_list_lambda): @@ -176,8 +200,8 @@ def decode_gather_fee_message(self, rlp): sp.for x in new_sub_list.items(): _svcs.value[counter.value] = sp.view("decode_string", self.data.helper, x.value, t=sp.TString).open_some() counter.value = counter.value + 1 - return sp.record(fa=temp_str.value, - svcs=_svcs.value) + sp.result(sp.record(fa=temp_str.value, + svcs=_svcs.value)) def to_message_event(self, rlp): rlp_me = sp.local("rlp_me", sp.map(tkey=sp.TNat)) @@ -251,7 +275,10 @@ def decode_receipt_proof(self, rlp): return sp.record(index = rv_int.value, events = events.value, height = rv_int2.value) + @sp.onchain_view() def decode_receipt_proofs(self, rlp): + sp.set_type(rlp, sp.TBytes) + rlp_rps = sp.local("rlp_rps", sp.map(tkey=sp.TNat)) is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() with sp.if_(is_list_lambda): @@ -289,5 +316,19 @@ def decode_receipt_proofs(self, rlp): sp.for x in new_sub_list.items(): receipt_proofs.value[counter.value] = self.decode_receipt_proof(x.value) counter.value = counter.value + 1 - return receipt_proofs.value + sp.result(receipt_proofs.value) + +@sp.add_test(name="Decoder") +def test(): + helper_nev= sp.test_account("Helper Negative") + scenario = sp.test_scenario() + + helper=helper_file.Helper() + scenario += helper + + c1 = DecodeLibrary(helper.address, helper_nev.address) + scenario += c1 + +sp.add_compilation_target("RLP_decode_struct", DecodeLibrary(helper_contract=sp.address("KT1HwFJmndBWRn3CLbvhUjdupfEomdykL5a6"), + helper_negative_address=sp.address("KT1DHptHqSovffZ7qqvSM9dy6uZZ8juV88gP"))) \ No newline at end of file diff --git a/smartpy/bmc/contracts/src/RLP_encode_struct.py b/smartpy/bmc/contracts/src/RLP_encode_struct.py index 9ec9bbe0..a3fb0b08 100644 --- a/smartpy/bmc/contracts/src/RLP_encode_struct.py +++ b/smartpy/bmc/contracts/src/RLP_encode_struct.py @@ -1,9 +1,17 @@ import smartpy as sp +helper_file = sp.io.import_script_from_url("file:./contracts/src/helper.py") -class EncodeLibrary: - LIST_SHORT_START = sp.bytes("0xc0") +class EncodeLibrary(sp.Contract): + + def __init__(self, helper_contract, helper_negative_address): + self.init( + helper=helper_contract, + helper_parse_negative=helper_negative_address + ) + + @sp.onchain_view() def encode_bmc_service(self, params): sp.set_type(params, sp.TRecord(serviceType=sp.TString, payload=sp.TBytes)) @@ -16,8 +24,9 @@ def encode_bmc_service(self, params): t=sp.TBytes).open_some() rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp_bytes_with_prefix, t=sp.TBytes).open_some() - return rlp_bytes_with_prefix + sp.result(rlp_bytes_with_prefix) + @sp.onchain_view() def encode_bmc_message(self, params): sp.set_type(params, sp.TRecord(src=sp.TString, dst=sp.TString, svc=sp.TString, sn=sp.TInt, message=sp.TBytes)) @@ -27,8 +36,9 @@ def encode_bmc_message(self, params): encode_sn = sp.view("to_byte", self.data.helper_parse_negative, params.sn, t=sp.TBytes).open_some() rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [encode_src, encode_dst, encode_svc, encode_sn, params.message], t=sp.TBytes).open_some() - return rlp_bytes_with_prefix + sp.result(rlp_bytes_with_prefix) + @sp.onchain_view() def encode_response(self, params): sp.set_type(params, sp.TRecord(code=sp.TNat, message=sp.TString)) @@ -37,4 +47,20 @@ def encode_response(self, params): rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [encode_code, encode_message], t=sp.TBytes).open_some() final_rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp_bytes_with_prefix, t=sp.TBytes).open_some() - return final_rlp_bytes_with_prefix + sp.result(final_rlp_bytes_with_prefix) + + +@sp.add_test(name="Encoder") +def test(): + helper_nev = sp.test_account("Helper Negative") + scenario = sp.test_scenario() + + helper = helper_file.Helper() + scenario += helper + + c1 = EncodeLibrary(helper.address, helper_nev.address) + scenario += c1 + + +sp.add_compilation_target("RLP_encode_struct", EncodeLibrary(helper_contract=sp.address("KT1HwFJmndBWRn3CLbvhUjdupfEomdykL5a6"), + helper_negative_address=sp.address("KT1DHptHqSovffZ7qqvSM9dy6uZZ8juV88gP"))) \ No newline at end of file diff --git a/smartpy/bmc/contracts/src/bmc_management.py b/smartpy/bmc/contracts/src/bmc_management.py index 39cfa101..658ca903 100644 --- a/smartpy/bmc/contracts/src/bmc_management.py +++ b/smartpy/bmc/contracts/src/bmc_management.py @@ -2,13 +2,13 @@ types = sp.io.import_script_from_url("file:./contracts/src/Types.py") strings = sp.io.import_script_from_url("file:./contracts/src/String.py") -rlp_encode = sp.io.import_script_from_url("file:./contracts/src/RLP_encode_struct.py") -class BMCManagement(sp.Contract, rlp_encode.EncodeLibrary): +class BMCManagement(sp.Contract): BLOCK_INTERVAL_MSEC = sp.nat(1000) + LIST_SHORT_START = sp.bytes("0xc0") - def __init__(self, owner_address, helper_contract): + def __init__(self, owner_address, helper_contract, rlp_encode_contract): self.init( owners=sp.map(l={owner_address:True}), number_of_owners=sp.nat(1), @@ -25,7 +25,8 @@ def __init__(self, owner_address, helper_contract): get_route_dst_from_net=sp.map(), get_link_from_net=sp.map(), get_link_from_reachable_net=sp.map(), - helper=helper_contract + helper=helper_contract, + rlp_encode_struct=rlp_encode_contract ) self.init_type(sp.TRecord( @@ -44,7 +45,8 @@ def __init__(self, owner_address, helper_contract): get_route_dst_from_net=sp.TMap(sp.TString, sp.TString), get_link_from_net=sp.TMap(sp.TString, sp.TString), get_link_from_reachable_net=sp.TMap(sp.TString, types.Types.Tuple), - helper=sp.TAddress + helper=sp.TAddress, + rlp_encode_struct=sp.TAddress )) def only_owner(self): @@ -86,6 +88,12 @@ def set_bmc_btp_address(self, network): "set_bmc_btp_address").open_some() sp.transfer(network, sp.tez(0), set_btp_address_entry_point) + @sp.entry_point + def set_rlp_encode_address(self, param): + sp.set_type(param, sp.TAddress) + self.only_owner() + self.data.rlp_encode_struct = param + @sp.entry_point def add_owner(self, owner): """ @@ -302,8 +310,9 @@ def _propagate_internal(self, service_type, link): send_message_entry_point = sp.contract(send_message_args_type, self.data.bmc_periphery.open_some("Address not set"), "send_message").open_some() - send_message_args = sp.record(to=net, svc="bmc", sn=sp.int(0), msg=self.encode_bmc_service( - sp.record(serviceType=service_type, payload=final_rlp_bytes_with_prefix))) + send_message_args = sp.record(to=net, svc="bmc", sn=sp.int(0), msg=sp.view("encode_bmc_service", self.data.rlp_encode_struct, + sp.record(serviceType=service_type,payload=final_rlp_bytes_with_prefix), + t=sp.TBytes).open_some()) sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) def _send_internal(self, target, service_type, links): @@ -329,8 +338,8 @@ def _send_internal(self, target, service_type, links): send_message_entry_point = sp.contract(send_message_args_type, self.data.bmc_periphery.open_some("Address not set"), "send_message").open_some() - send_message_args = sp.record(to=net, svc="bmc", sn=sp.int(0), msg=self.encode_bmc_service( - sp.record(serviceType=service_type, payload=rlp_bytes.value))) + send_message_args = sp.record(to=net, svc="bmc", sn=sp.int(0), msg=sp.view("encode_bmc_service", self.data.rlp_encode_struct, + sp.record(serviceType=service_type, payload=rlp_bytes.value), t=sp.TBytes).open_some()) sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) @@ -568,4 +577,5 @@ def resolve_route(self, dst_net): sp.add_compilation_target("bmc_management", BMCManagement(owner_address=sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP"), - helper_contract=sp.address("KT1HwFJmndBWRn3CLbvhUjdupfEomdykL5a6"))) + helper_contract=sp.address("KT1HwFJmndBWRn3CLbvhUjdupfEomdykL5a6"), + rlp_encode_contract=sp.address("KT19eEe2CwtzYpuB3A5um6mJRMNMj8ek9BsT"))) diff --git a/smartpy/bmc/contracts/src/bmc_periphery.py b/smartpy/bmc/contracts/src/bmc_periphery.py index 10440568..386abbe7 100644 --- a/smartpy/bmc/contracts/src/bmc_periphery.py +++ b/smartpy/bmc/contracts/src/bmc_periphery.py @@ -2,11 +2,9 @@ types = sp.io.import_script_from_url("file:./contracts/src/Types.py") strings = sp.io.import_script_from_url("file:./contracts/src/String.py") -rlp_encode = sp.io.import_script_from_url("file:./contracts/src/RLP_encode_struct.py") -rlp_decode = sp.io.import_script_from_url("file:./contracts/src/RLP_decode_struct.py") -class BMCPreiphery(sp.Contract, rlp_decode.DecodeLibrary, rlp_encode.EncodeLibrary): +class BMCPreiphery(sp.Contract): BMC_ERR = sp.nat(10) BSH_ERR = sp.nat(40) UNKNOWN_ERR = sp.nat(0) @@ -21,7 +19,7 @@ class BMCPreiphery(sp.Contract, rlp_decode.DecodeLibrary, rlp_encode.EncodeLibra BMCRevertUnknownHandleBTPError = sp.string("UnknownHandleBTPError") BMCRevertUnknownHandleBTPMessage = sp.string("UnknownHandleBTPMessage") - def __init__(self, bmc_management_addr, helper_contract, helper_parse_neg_contract, parse_address, owner_address): + def __init__(self, bmc_management_addr, helper_contract, helper_parse_neg_contract, parse_address, owner_address, rlp_decode_struct, rlp_encode_struct): self.init( helper=helper_contract, helper_parse_negative=helper_parse_neg_contract, @@ -31,7 +29,9 @@ def __init__(self, bmc_management_addr, helper_contract, helper_parse_neg_contra handle_btp_message_status=sp.none, handle_btp_error_status=sp.none, handle_fee_gathering_status=sp.none, - owner_address = owner_address + owner_address = owner_address, + rlp_decode_struct=rlp_decode_struct, + rlp_encode_struct=rlp_encode_struct ) def only_owner(self): @@ -71,6 +71,18 @@ def set_bmc_btp_address(self, network): with sp.else_(): sp.failwith("Address already set") + @sp.entry_point + def set_rlp_decode_address(self, param): + sp.set_type(param, sp.TAddress) + self.only_owner() + self.data.rlp_decode_struct = param + + @sp.entry_point + def set_rlp_encode_address(self, param): + sp.set_type(param, sp.TAddress) + self.only_owner() + self.data.rlp_encode_struct = param + @sp.onchain_view() def get_bmc_btp_address(self): sp.result(self.data.bmc_btp_address.open_some("Address not set")) @@ -136,7 +148,11 @@ def callback_handle_fee_gathering(self, string, bsh_addr): pass self.data.handle_fee_gathering_status = sp.none - @sp.entry_point + @sp.entry_point(lazify=False) + def update_handle_relay_message(self, ep): + sp.set_entry_point("handle_relay_message", ep) + + @sp.entry_point(lazify=True) def handle_relay_message(self, prev, msg): sp.set_type(prev, sp.TString) sp.set_type(msg, sp.TBytes) @@ -148,7 +164,7 @@ def handle_relay_message(self, prev, msg): rx_seq = sp.local("rx_seq", link_rx_seq, t=sp.TNat) rx_height = sp.local("rx_height", link_rx_height, t=sp.TNat) - rps = self.decode_receipt_proofs(msg) + rps = sp.view("decode_receipt_proofs", self.data.rlp_decode_struct, msg, t=sp.TMap(sp.TNat, types.Types.ReceiptProof)).open_some() bmc_msg = sp.local("bmc_msg", sp.record(src="", dst="", svc="", sn=sp.int(0), message=sp.bytes("0x")), t=types.Types.BMCMessage) ev = sp.local("ev", sp.record(next_bmc="", seq=sp.nat(0), message=sp.bytes("0x")), t=types.Types.MessageEvent) sp.for i in sp.range(sp.nat(0), sp.len(rps)): @@ -166,7 +182,7 @@ def handle_relay_message(self, prev, msg): sp.if ev.value.seq > rx_seq.value: sp.failwith(self.BMCRevertInvalidSeqNumber) - _decoded = self.decode_bmc_message(ev.value.message) + _decoded = sp.view("decode_bmc_message", self.data.rlp_decode_struct, ev.value.message, t=types.Types.BMCMessage).open_some() bmc_msg.value = _decoded sp.if bmc_msg.value.src != "": @@ -212,13 +228,13 @@ def _handle_message(self, prev, msg): # bsh_addr = sp.local("bsh_addr",sp.TAddress) with sp.if_(msg.svc == "bmc"): sm = sp.local("sm", sp.record(serviceType="", payload=sp.bytes("0x"))) - sm.value = self.decode_bmc_service(msg.message) + sm.value = sp.view("decode_bmc_service", self.data.rlp_decode_struct, msg.message, t=types.Types.BMCService).open_some() with sp.if_(sm.value.serviceType == ""): self._send_error(prev, msg, self.BMC_ERR, self.BMCRevertParseFailure) with sp.else_(): sp.if sm.value.serviceType == "FeeGathering": gather_fee =sp.local("gather_fee", sp.record(fa="", svcs=sp.map({0:""}))) - gather_fee.value = self.decode_gather_fee_message(sm.value.payload) + gather_fee.value = sp.view("decode_gather_fee_message", self.data.rlp_decode_struct, sm.value.payload, t=types.Types.GatherFeeMessage).open_some() with sp.if_(gather_fee.value.fa == ""): self._send_error(prev, msg, self.BMC_ERR, self.BMCRevertParseFailure) @@ -233,11 +249,13 @@ def _handle_message(self, prev, msg): handle_fee_gathering_entry_point = sp.contract(handle_fee_gathering_args_type, bsh_addr, "handle_fee_gathering").open_some() - handle_fee_gathering_args = sp.record(callback=sp.self_entry_point("callback_handle_fee_gathering"), bsh_addr=bsh_addr, fa=gather_fee.value.fa, svc=gather_fee.value.svcs[c]) + t = sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress) + callback = sp.contract(t, sp.self_address, "callback_handle_fee_gathering") + handle_fee_gathering_args = sp.record(callback=callback.open_some(), bsh_addr=bsh_addr, fa=gather_fee.value.fa, svc=gather_fee.value.svcs[c]) sp.transfer(handle_fee_gathering_args, sp.tez(0), handle_fee_gathering_entry_point) sp.if sm.value.serviceType == "Link": - to = self.decode_propagate_message(sm.value.payload) + to= sp.view("decode_propagate_message", self.data.rlp_decode_struct, sm.value.payload, t=sp.TString).open_some() link = sp.view("get_link", self.data.bmc_management, prev, t=types.Types.Link).open_some() check = sp.local("check", False) @@ -259,7 +277,7 @@ def _handle_message(self, prev, msg): sp.transfer(update_link_reachable_args, sp.tez(0), update_link_reachable_entry_point) sp.if sm.value.serviceType == "Unlink": - to = self.decode_propagate_message(sm.value.payload) + to = sp.view("decode_propagate_message", self.data.rlp_decode_struct, sm.value.payload, t=sp.TString).open_some() link = sp.view("get_link", self.data.bmc_management, prev, t=types.Types.Link).open_some() sp.if link.is_connected: @@ -277,7 +295,7 @@ def _handle_message(self, prev, msg): f.value += sp.nat(1) sp.if sm.value.serviceType == "Init": - links = self.decode_init_message(sm.value.payload) + links = sp.view("decode_init_message", self.data.rlp_decode_struct, sm.value.payload, t=sp.TList(sp.TString)).open_some() # call update_link_reachable on BMCManagement update_link_reachable_args_type = sp.TRecord(prev=sp.TString, to=sp.TList(sp.TString)) update_link_reachable_entry_point = sp.contract(update_link_reachable_args_type, @@ -301,11 +319,14 @@ def _handle_message(self, prev, msg): handle_btp_message_entry_point = sp.contract(handle_btp_message_args_type, bsh_addr, "handle_btp_message").open_some() - handle_btp_message_args = sp.record(callback=sp.self_entry_point("callback_btp_message"), bsh_addr=bsh_addr, prev=prev, callback_msg=msg, _from=net, svc=msg.svc, sn=msg.sn, msg=msg.message) + t = sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress, prev=sp.TString, callback_msg=types.Types.BMCMessage ) + callback = sp.contract(t, sp.self_address, "callback_btp_message") + + handle_btp_message_args = sp.record(callback=callback.open_some(), bsh_addr=bsh_addr, prev=prev, callback_msg=msg, _from=net, svc=msg.svc, sn=msg.sn, msg=msg.message) sp.transfer(handle_btp_message_args, sp.tez(0), handle_btp_message_entry_point) with sp.else_(): - res = self.decode_response(msg.message) + res = sp.view("decode_response", self.data.rlp_decode_struct, msg.message, t=types.Types.Response).open_some() # implemented callback # call handle_btp_error on bts periphery handle_btp_error_args_type = sp.TRecord(callback=sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress, svc=sp.TString, sn=sp.TInt, code=sp.TNat, msg=sp.TString)), @@ -313,7 +334,10 @@ def _handle_message(self, prev, msg): handle_btp_error_entry_point = sp.contract(handle_btp_error_args_type, bsh_addr, "handle_btp_error").open_some() - handle_btp_error_args = sp.record(callback=sp.self_entry_point("callback_btp_error"), bsh_addr=bsh_addr, + + t = sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress, svc=sp.TString, sn=sp.TInt, code=sp.TNat, msg=sp.TString) + callback = sp.contract(t, sp.self_address, "callback_btp_error") + handle_btp_error_args = sp.record(callback=callback.open_some(), bsh_addr=bsh_addr, svc=msg.svc, sn=msg.sn * -1, code=res.code, msg="error") sp.transfer(handle_btp_error_args, sp.tez(0), handle_btp_error_entry_point) @@ -334,13 +358,12 @@ def _send_error(self, prev, message, err_code, err_msg): sp.set_type(err_msg, sp.TString) sp.if message.sn > sp.int(0): - serialized_msg = self.encode_bmc_message(sp.record( + serialized_msg = sp.view("encode_bmc_message", self.data.rlp_encode_struct, sp.record( src=self.data.bmc_btp_address.open_some("Address not set"), dst=message.src, svc=message.svc, sn=message.sn * -1, - message=self.encode_response(sp.record(code=err_code, message=err_msg)) - )) + message=sp.view("encode_response", self.data.rlp_encode_struct, sp.record(code=err_code, message=err_msg), t=sp.TBytes).open_some()), t=sp.TBytes).open_some() self._send_message(prev, serialized_msg) @sp.entry_point @@ -365,13 +388,12 @@ def send_message(self, to, svc, sn, msg): next_link, dst = sp.match_pair(sp.view("resolve_route", self.data.bmc_management, to, t=sp.TPair(sp.TString, sp.TString)).open_some()) - rlp = self.encode_bmc_message(sp.record( + rlp = sp.view("encode_bmc_message", self.data.rlp_encode_struct, sp.record( src=self.data.bmc_btp_address.open_some("Address not set"), dst=dst, svc=svc, sn=sn, - message=msg - )) + message=msg), t=sp.TBytes).open_some() self._send_message(next_link, rlp) @sp.onchain_view() @@ -398,4 +420,6 @@ def get_status(self, _link): helper_contract=sp.address("KT1HwFJmndBWRn3CLbvhUjdupfEomdykL5a6"), helper_parse_neg_contract=sp.address("KT1DHptHqSovffZ7qqvSM9dy6uZZ8juV88gP"), parse_address=sp.address("KT1XgRyjQPfpfwNrvYYpgERpYpCrGh24aoPX"), - owner_address=sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP"))) + owner_address=sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP"), + rlp_decode_struct=sp.address("KT1WGckGaUsKZs8PHskmGCDQX5CiSzwj3akH"), + rlp_encode_struct=sp.address("KT19eEe2CwtzYpuB3A5um6mJRMNMj8ek9BsT"))) From 2e24bed1359d064ab19707fbc42acaaf90db724f Mon Sep 17 00:00:00 2001 From: simusud Date: Mon, 12 Jun 2023 22:08:55 +0545 Subject: [PATCH 088/211] perf(bts): improved performance by splitting rlp encode and decode into separate contracts --- .../bts/contracts/src/RLP_decode_struct.py | 62 ++++++++++++++++--- .../bts/contracts/src/RLP_encode_struct.py | 36 +++++++++-- smartpy/bts/contracts/src/bts_periphery.py | 50 +++++++++------ 3 files changed, 115 insertions(+), 33 deletions(-) diff --git a/smartpy/bts/contracts/src/RLP_decode_struct.py b/smartpy/bts/contracts/src/RLP_decode_struct.py index 2cb8a901..f214c915 100644 --- a/smartpy/bts/contracts/src/RLP_decode_struct.py +++ b/smartpy/bts/contracts/src/RLP_decode_struct.py @@ -2,10 +2,21 @@ Utils2 = sp.io.import_script_from_url("https://raw.githubusercontent.com/RomarQ/tezos-sc-utils/main/smartpy/utils.py") types = sp.io.import_script_from_url("file:./contracts/src/Types.py") +helper_file = sp.io.import_script_from_url("file:./contracts/src/helper.py") -class DecodeLibrary: +class DecodeLibrary(sp.Contract): + + def __init__(self, helper_contract): + self.init( + helper=helper_contract, + ) + + + @sp.onchain_view() def decode_response(self, rlp): + sp.set_type(rlp, sp.TBytes) + temp_int = sp.local("int1", 0) temp_byt = sp.local("byt1", sp.bytes("0x")) rlp_dr = sp.local("rlp_dr_bts", sp.map(tkey=sp.TNat)) @@ -29,9 +40,13 @@ def decode_response(self, rlp): temp_byt.value = i.value counter.value = counter.value + 1 - return sp.record(code=temp_int.value, message=sp.view("decode_string", self.data.helper, temp_byt.value, t=sp.TString).open_some()) + sp.result(sp.record(code=temp_int.value, message=sp.view("decode_string", self.data.helper, temp_byt.value, t=sp.TString).open_some())) + + @sp.onchain_view() def decode_service_message(self, rlp): + sp.set_type(rlp, sp.TBytes) + rlp_sm = sp.local("rlp_sm_bts", sp.map(tkey=sp.TNat)) is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() with sp.if_(is_list_lambda): @@ -55,7 +70,7 @@ def decode_service_message(self, rlp): temp_byt.value = i.value counter.value = counter.value + 1 - _service_type = sp.local("_service_type", sp.variant("", 10)) + _service_type = sp.local("_service_type", sp.variant("ERROR", 10)) sp.if temp_int.value == 0: _service_type.value = sp.variant("REQUEST_COIN_TRANSFER", temp_int.value) sp.if temp_int.value == 1: @@ -70,10 +85,13 @@ def decode_service_message(self, rlp): _service_type.value = sp.variant("UNKNOWN_TYPE", temp_int.value) temp_byt.value = sp.view("without_length_prefix", self.data.helper, temp_byt.value, t=sp.TBytes).open_some() - return sp.record(serviceType=_service_type.value, - data=temp_byt.value) + sp.result(sp.record(serviceType=_service_type.value, + data=temp_byt.value)) + @sp.onchain_view() def decode_transfer_coin_msg(self, rlp): + sp.set_type(rlp, sp.TBytes) + rlp_tcm = sp.local("rlp_tcm_bts", sp.map(tkey=sp.TNat)) is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() with sp.if_(is_list_lambda): @@ -148,9 +166,13 @@ def decode_transfer_coin_msg(self, rlp): rv1 = sp.view("decode_string", self.data.helper, rv1_byt.value, t=sp.TString).open_some() rv2 = sp.view("decode_string", self.data.helper, rv2_byt.value, t=sp.TString).open_some() - return sp.record(from_= rv1, to = rv2 , assets = rv_assets.value) + sp.result(sp.record(from_= rv1, to = rv2 , assets = rv_assets.value)) + + @sp.onchain_view() def decode_blacklist_msg(self, rlp): + sp.set_type(rlp, sp.TBytes) + rlp_bm = sp.local("rlp_bm_bts", sp.map(tkey=sp.TNat)) is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() with sp.if_(is_list_lambda): @@ -213,14 +235,18 @@ def decode_blacklist_msg(self, rlp): t=sp.TBytes).open_some() rv1 = Utils2.Int.of_bytes(rv1_byt.value) rv2 = sp.view("decode_string", self.data.helper, rv2_byt.value, t=sp.TString).open_some() - _service_type = sp.local("_service_type_blacklist", sp.variant("", 10)) + _service_type = sp.local("_service_type_blacklist", sp.variant("ERROR", 10)) with sp.if_(rv1 == 0): _service_type.value = sp.variant("ADD_TO_BLACKLIST", rv1) with sp.else_(): _service_type.value = sp.variant("REMOVE_FROM_BLACKLIST", rv1) - return sp.record(serviceType = _service_type.value , addrs = rv_blacklist_address.value , net = rv2) + sp.result(sp.record(serviceType = _service_type.value , addrs = rv_blacklist_address.value , net = rv2)) + + @sp.onchain_view() def decode_token_limit_msg(self, rlp): + sp.set_type(rlp, sp.TBytes) + rlp_tlm = sp.local("rlp_tlm_bts", sp.map(tkey=sp.TNat)) is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() with sp.if_(is_list_lambda): @@ -280,5 +306,21 @@ def decode_token_limit_msg(self, rlp): t=sp.TBytes).open_some() rv_limit.value[counter.value] = Utils2.Int.of_bytes(limit.value) counter.value += 1 - return sp.record(coin_name = rv_names.value, token_limit = rv_limit.value , - net = sp.view("decode_string", self.data.helper, rv1_byt.value, t=sp.TString).open_some()) \ No newline at end of file + sp.result(sp.record(coin_name = rv_names.value, token_limit = rv_limit.value , + net = sp.view("decode_string", self.data.helper, rv1_byt.value, t=sp.TString).open_some())) + + +@sp.add_test(name="Decoder") +def test(): + scenario = sp.test_scenario() + + helper = helper_file.Helper() + scenario += helper + + c1 = DecodeLibrary(helper.address) + scenario += c1 + + +sp.add_compilation_target("RLP_decode_struct", + DecodeLibrary(helper_contract=sp.address("KT1HwFJmndBWRn3CLbvhUjdupfEomdykL5a6"))) + diff --git a/smartpy/bts/contracts/src/RLP_encode_struct.py b/smartpy/bts/contracts/src/RLP_encode_struct.py index daa180b6..fea6c9e9 100644 --- a/smartpy/bts/contracts/src/RLP_encode_struct.py +++ b/smartpy/bts/contracts/src/RLP_encode_struct.py @@ -1,9 +1,18 @@ import smartpy as sp types = sp.io.import_script_from_url("file:./contracts/src/Types.py") +helper_file = sp.io.import_script_from_url("file:./contracts/src/helper.py") -class EncodeLibrary: +class EncodeLibrary(sp.Contract): + + def __init__(self, helper_contract): + self.init( + helper=helper_contract + ) + + + @sp.onchain_view() def encode_service_message(self, params): sp.set_type(params, sp.TRecord(service_type_value = sp.TNat, data = sp.TBytes)) @@ -11,9 +20,10 @@ def encode_service_message(self, params): rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [encode_service_type, params.data], t=sp.TBytes).open_some() final_rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp_bytes_with_prefix, t=sp.TBytes).open_some() - return final_rlp_bytes_with_prefix + sp.result(final_rlp_bytes_with_prefix) + @sp.onchain_view() def encode_transfer_coin_msg(self, data): sp.set_type(data, types.Types.TransferCoin) @@ -34,8 +44,10 @@ def encode_transfer_coin_msg(self, data): rlp.value = sp.view("encode_list", self.data.helper, [from_addr_encoded, to_addr_encoded, assets_list], t=sp.TBytes).open_some() final_rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp.value, t=sp.TBytes).open_some() - return final_rlp_bytes_with_prefix + sp.result(final_rlp_bytes_with_prefix) + + @sp.onchain_view() def encode_response(self, params): sp.set_type(params, sp.TRecord(code=sp.TNat, message=sp.TString)) @@ -45,4 +57,20 @@ def encode_response(self, params): rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [encode_code, encode_message], t=sp.TBytes).open_some() final_rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp_bytes_with_prefix, t=sp.TBytes).open_some() - return final_rlp_bytes_with_prefix + + sp.result(final_rlp_bytes_with_prefix) + + +@sp.add_test(name="Encoder") +def test(): + scenario = sp.test_scenario() + + helper = helper_file.Helper() + scenario += helper + + c1 = EncodeLibrary(helper.address) + scenario += c1 + + +sp.add_compilation_target("RLP_encode_struct", + EncodeLibrary(helper_contract=sp.address("KT1HwFJmndBWRn3CLbvhUjdupfEomdykL5a6"))) diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index f67b85af..eb5cd834 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -2,11 +2,9 @@ types = sp.io.import_script_from_url("file:./contracts/src/Types.py") strings = sp.io.import_script_from_url("file:./contracts/src/String.py") -rlp_encode = sp.io.import_script_from_url("file:./contracts/src/RLP_encode_struct.py") -rlp_decode = sp.io.import_script_from_url("file:./contracts/src/RLP_decode_struct.py") -class BTPPreiphery(sp.Contract, rlp_decode.DecodeLibrary, rlp_encode.EncodeLibrary): +class BTPPreiphery(sp.Contract): service_name = sp.string("bts") RC_OK = sp.nat(0) @@ -15,7 +13,7 @@ class BTPPreiphery(sp.Contract, rlp_decode.DecodeLibrary, rlp_encode.EncodeLibra MAX_BATCH_SIZE = sp.nat(15) - def __init__(self, bmc_address, bts_core_address, helper_contract, parse_address, native_coin_name, owner_address): + def __init__(self, bmc_address, bts_core_address, helper_contract, parse_address, native_coin_name, owner_address, rlp_decode_struct, rlp_encode_struct): self.update_initial_storage( bmc=bmc_address, owner=owner_address, @@ -27,7 +25,9 @@ def __init__(self, bmc_address, bts_core_address, helper_contract, parse_address number_of_pending_requests = sp.nat(0), helper=helper_contract, parse_contract=parse_address, - mint_status=sp.none + mint_status=sp.none, + rlp_decode_struct=rlp_decode_struct, + rlp_encode_struct=rlp_encode_struct ) def only_bmc(self): @@ -66,6 +66,18 @@ def set_bts_core_address(self, params): self.only_owner() self.data.bts_core = params + @sp.entry_point + def set_rlp_decode_address(self, param): + sp.set_type(param, sp.TAddress) + self.only_owner() + self.data.rlp_decode_struct = param + + @sp.entry_point + def set_rlp_encode_address(self, param): + sp.set_type(param, sp.TAddress) + self.only_owner() + self.data.rlp_encode_struct = param + @sp.onchain_view() def has_pending_request(self): """ @@ -236,12 +248,10 @@ def send_service_message(self, _from, to, coin_names, values, fees): send_message_entry_point = sp.contract(send_message_args_type, self.data.bmc, "send_message").open_some() send_message_args = sp.record( to=to_network, svc=self.service_name, sn=self.data.serial_no, - msg=self.encode_service_message(sp.compute(sp.record(service_type_value=sp.nat(0), - data=self.encode_transfer_coin_msg(sp.compute(sp.record(from_addr=start_from, to=to_address, assets=assets))) - ) - ) - ) - ) + msg = sp.view("encode_service_message", self.data.rlp_encode_struct, sp.record(service_type_value=sp.nat(0), + data=sp.view("encode_transfer_coin_msg", self.data.rlp_encode_struct, sp.record(from_addr=start_from, to=to_address, assets=assets), + t=sp.TBytes).open_some()), t=sp.TBytes).open_some()) + sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) # push pending tx into record list @@ -281,14 +291,14 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, bsh_addr, prev, call callback_string = sp.local("callback_string", "") with sp.if_((svc == self.service_name) & (check_caller == "Authorized")): err_msg = sp.local("error", "") - sm = self.decode_service_message(msg) + sm = sp.view("decode_service_message", self.data.rlp_decode_struct, msg, t=types.Types.ServiceMessage).open_some() service_type_variant_match = sp.local("serviceType_variant", False, t=sp.TBool) with sm.serviceType.match_cases() as arg: with arg.match("REQUEST_COIN_TRANSFER") as a1: service_type_variant_match.value = True callback_string.value = "success" - tc = self.decode_transfer_coin_msg(sm.data) + tc = sp.view("decode_transfer_coin_msg", self.data.rlp_decode_struct, sm.data, t=types.Types.TransferCoin).open_some() parsed_addr = sp.view("str_to_addr", self.data.parse_contract, tc.to, t=sp.TAddress).open_some() with sp.if_(parsed_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): @@ -307,7 +317,7 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, bsh_addr, prev, call with arg.match("BLACKLIST_MESSAGE") as a2: service_type_variant_match.value = True callback_string.value = "success" - bm = self.decode_blacklist_msg(sm.data) + bm = sp.view("decode_blacklist_msg", self.data.rlp_decode_struct, sm.data, t=types.Types.BlacklistMessage).open_some() addresses = bm.addrs blacklist_service_called = sp.local("blacklist_service", False, t=sp.TBool) @@ -336,7 +346,7 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, bsh_addr, prev, call with arg.match("CHANGE_TOKEN_LIMIT") as a3: service_type_variant_match.value = True callback_string.value = "success" - tl = self.decode_token_limit_msg(sm.data) + tl = sp.view("decode_token_limit_msg", self.data.rlp_decode_struct, sm.data, t=types.Types.TokenLimitMessage).open_some() coin_names = tl.coin_name token_limits = tl.token_limit @@ -349,7 +359,7 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, bsh_addr, prev, call with arg.match("RESPONSE_HANDLE_SERVICE") as a4: service_type_variant_match.value = True with sp.if_(sp.len(sp.pack(self.data.requests.get(sn).from_)) != 0): - response = self.decode_response(sm.data) + response = sp.view("decode_response", self.data.rlp_decode_struct, sm.data, t=types.Types.Response).open_some() handle_response = self.handle_response_service(sn, response.code, response.message) with sp.if_(handle_response == "success"): callback_string.value = "success" @@ -548,8 +558,8 @@ def send_response_message(self, service_type, service_type_val, to, sn, msg, cod ) send_message_entry_point = sp.contract(send_message_args_type, self.data.bmc, "send_message").open_some() send_message_args = sp.record(to=to, svc=self.service_name, sn=sn, - msg=self.encode_service_message(sp.record(service_type_value=service_type_val, data=self.encode_response(sp.record(code=code, message=msg)))) - ) + msg=sp.view("encode_service_message", self.data.rlp_encode_struct, sp.record(service_type_value=service_type_val, data=sp.view("encode_response", + self.data.rlp_encode_struct, sp.record(code=code, message=msg), t=sp.TBytes).open_some()), t=sp.TBytes).open_some()) sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) @@ -603,4 +613,6 @@ def check_transfer_restrictions(self, params): helper_contract=sp.address("KT1HwFJmndBWRn3CLbvhUjdupfEomdykL5a6"), parse_address=sp.address("KT1EKPrSLWjWViZQogFgbc1QmztkR5UGXEWa"), native_coin_name="btp-NetXnHfVqm9iesp.tezos-XTZ", - owner_address = sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP")) ) \ No newline at end of file + owner_address = sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP"), + rlp_decode_struct=sp.address("KT1HfeUF15X4TaaaDVsdX8ZZaybu42EdpwW1"), + rlp_encode_struct=sp.address("KT1AjjdjRFpV52LUgrV1KCVaKZ4eH6rm7ejG"))) \ No newline at end of file From c94d35e259433b885b011eb1a47025da8b9bb46c Mon Sep 17 00:00:00 2001 From: suyogadhikari Date: Tue, 13 Jun 2023 10:50:58 +0545 Subject: [PATCH 089/211] perf(bmc): rlp encoder and decoder merged into one contract. --- .../bmc/contracts/src/RLP_encode_struct.py | 66 ------------------- .../{RLP_decode_struct.py => RLP_struct.py} | 45 ++++++++++++- smartpy/bmc/contracts/src/bmc_management.py | 16 ++--- smartpy/bmc/contracts/src/bmc_periphery.py | 40 +++++------ 4 files changed, 68 insertions(+), 99 deletions(-) delete mode 100644 smartpy/bmc/contracts/src/RLP_encode_struct.py rename smartpy/bmc/contracts/src/{RLP_decode_struct.py => RLP_struct.py} (87%) diff --git a/smartpy/bmc/contracts/src/RLP_encode_struct.py b/smartpy/bmc/contracts/src/RLP_encode_struct.py deleted file mode 100644 index a3fb0b08..00000000 --- a/smartpy/bmc/contracts/src/RLP_encode_struct.py +++ /dev/null @@ -1,66 +0,0 @@ -import smartpy as sp - -helper_file = sp.io.import_script_from_url("file:./contracts/src/helper.py") - - -class EncodeLibrary(sp.Contract): - - def __init__(self, helper_contract, helper_negative_address): - self.init( - helper=helper_contract, - helper_parse_negative=helper_negative_address - ) - - @sp.onchain_view() - def encode_bmc_service(self, params): - sp.set_type(params, sp.TRecord(serviceType=sp.TString, payload=sp.TBytes)) - - encode_service_type = sp.view("encode_string", self.data.helper, params.serviceType, t=sp.TBytes).open_some() - - payload_rlp = sp.view("encode_list", self.data.helper, [params.payload], t=sp.TBytes).open_some() - payload_rlp = sp.view("with_length_prefix", self.data.helper, payload_rlp, t=sp.TBytes).open_some() - - rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [encode_service_type, payload_rlp], - t=sp.TBytes).open_some() - rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp_bytes_with_prefix, - t=sp.TBytes).open_some() - sp.result(rlp_bytes_with_prefix) - - @sp.onchain_view() - def encode_bmc_message(self, params): - sp.set_type(params, sp.TRecord(src=sp.TString, dst=sp.TString, svc=sp.TString, sn=sp.TInt, message=sp.TBytes)) - - encode_src = sp.view("encode_string", self.data.helper, params.src, t=sp.TBytes).open_some() - encode_dst = sp.view("encode_string", self.data.helper, params.dst, t=sp.TBytes).open_some() - encode_svc = sp.view("encode_string", self.data.helper, params.svc, t=sp.TBytes).open_some() - encode_sn = sp.view("to_byte", self.data.helper_parse_negative, params.sn, t=sp.TBytes).open_some() - - rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [encode_src, encode_dst, encode_svc, encode_sn, params.message], t=sp.TBytes).open_some() - sp.result(rlp_bytes_with_prefix) - - @sp.onchain_view() - def encode_response(self, params): - sp.set_type(params, sp.TRecord(code=sp.TNat, message=sp.TString)) - - encode_code = sp.view("encode_nat", self.data.helper, params.code, t=sp.TBytes).open_some() - encode_message = sp.view("encode_string", self.data.helper, params.message, t=sp.TBytes).open_some() - - rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [encode_code, encode_message], t=sp.TBytes).open_some() - final_rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp_bytes_with_prefix, t=sp.TBytes).open_some() - sp.result(final_rlp_bytes_with_prefix) - - -@sp.add_test(name="Encoder") -def test(): - helper_nev = sp.test_account("Helper Negative") - scenario = sp.test_scenario() - - helper = helper_file.Helper() - scenario += helper - - c1 = EncodeLibrary(helper.address, helper_nev.address) - scenario += c1 - - -sp.add_compilation_target("RLP_encode_struct", EncodeLibrary(helper_contract=sp.address("KT1HwFJmndBWRn3CLbvhUjdupfEomdykL5a6"), - helper_negative_address=sp.address("KT1DHptHqSovffZ7qqvSM9dy6uZZ8juV88gP"))) \ No newline at end of file diff --git a/smartpy/bmc/contracts/src/RLP_decode_struct.py b/smartpy/bmc/contracts/src/RLP_struct.py similarity index 87% rename from smartpy/bmc/contracts/src/RLP_decode_struct.py rename to smartpy/bmc/contracts/src/RLP_struct.py index 36303b8a..5886c85c 100644 --- a/smartpy/bmc/contracts/src/RLP_decode_struct.py +++ b/smartpy/bmc/contracts/src/RLP_struct.py @@ -318,6 +318,49 @@ def decode_receipt_proofs(self, rlp): counter.value = counter.value + 1 sp.result(receipt_proofs.value) + # rlp encoding starts here + @sp.onchain_view() + def encode_bmc_service(self, params): + sp.set_type(params, sp.TRecord(serviceType=sp.TString, payload=sp.TBytes)) + + encode_service_type = sp.view("encode_string", self.data.helper, params.serviceType, t=sp.TBytes).open_some() + + payload_rlp = sp.view("encode_list", self.data.helper, [params.payload], t=sp.TBytes).open_some() + payload_rlp = sp.view("with_length_prefix", self.data.helper, payload_rlp, t=sp.TBytes).open_some() + + rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [encode_service_type, payload_rlp], + t=sp.TBytes).open_some() + rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp_bytes_with_prefix, + t=sp.TBytes).open_some() + sp.result(rlp_bytes_with_prefix) + + @sp.onchain_view() + def encode_bmc_message(self, params): + sp.set_type(params, sp.TRecord(src=sp.TString, dst=sp.TString, svc=sp.TString, sn=sp.TInt, message=sp.TBytes)) + + encode_src = sp.view("encode_string", self.data.helper, params.src, t=sp.TBytes).open_some() + encode_dst = sp.view("encode_string", self.data.helper, params.dst, t=sp.TBytes).open_some() + encode_svc = sp.view("encode_string", self.data.helper, params.svc, t=sp.TBytes).open_some() + encode_sn = sp.view("to_byte", self.data.helper_parse_negative, params.sn, t=sp.TBytes).open_some() + + rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, + [encode_src, encode_dst, encode_svc, encode_sn, params.message], + t=sp.TBytes).open_some() + sp.result(rlp_bytes_with_prefix) + + @sp.onchain_view() + def encode_response(self, params): + sp.set_type(params, sp.TRecord(code=sp.TNat, message=sp.TString)) + + encode_code = sp.view("encode_nat", self.data.helper, params.code, t=sp.TBytes).open_some() + encode_message = sp.view("encode_string", self.data.helper, params.message, t=sp.TBytes).open_some() + + rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [encode_code, encode_message], + t=sp.TBytes).open_some() + final_rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp_bytes_with_prefix, + t=sp.TBytes).open_some() + sp.result(final_rlp_bytes_with_prefix) + @sp.add_test(name="Decoder") def test(): helper_nev= sp.test_account("Helper Negative") @@ -330,5 +373,5 @@ def test(): scenario += c1 -sp.add_compilation_target("RLP_decode_struct", DecodeLibrary(helper_contract=sp.address("KT1HwFJmndBWRn3CLbvhUjdupfEomdykL5a6"), +sp.add_compilation_target("RLP_struct", DecodeLibrary(helper_contract=sp.address("KT1HwFJmndBWRn3CLbvhUjdupfEomdykL5a6"), helper_negative_address=sp.address("KT1DHptHqSovffZ7qqvSM9dy6uZZ8juV88gP"))) \ No newline at end of file diff --git a/smartpy/bmc/contracts/src/bmc_management.py b/smartpy/bmc/contracts/src/bmc_management.py index 658ca903..d502c83e 100644 --- a/smartpy/bmc/contracts/src/bmc_management.py +++ b/smartpy/bmc/contracts/src/bmc_management.py @@ -8,7 +8,7 @@ class BMCManagement(sp.Contract): BLOCK_INTERVAL_MSEC = sp.nat(1000) LIST_SHORT_START = sp.bytes("0xc0") - def __init__(self, owner_address, helper_contract, rlp_encode_contract): + def __init__(self, owner_address, helper_contract, rlp_contract): self.init( owners=sp.map(l={owner_address:True}), number_of_owners=sp.nat(1), @@ -26,7 +26,7 @@ def __init__(self, owner_address, helper_contract, rlp_encode_contract): get_link_from_net=sp.map(), get_link_from_reachable_net=sp.map(), helper=helper_contract, - rlp_encode_struct=rlp_encode_contract + rlp_contract=rlp_contract ) self.init_type(sp.TRecord( @@ -46,7 +46,7 @@ def __init__(self, owner_address, helper_contract, rlp_encode_contract): get_link_from_net=sp.TMap(sp.TString, sp.TString), get_link_from_reachable_net=sp.TMap(sp.TString, types.Types.Tuple), helper=sp.TAddress, - rlp_encode_struct=sp.TAddress + rlp_contract=sp.TAddress )) def only_owner(self): @@ -89,10 +89,10 @@ def set_bmc_btp_address(self, network): sp.transfer(network, sp.tez(0), set_btp_address_entry_point) @sp.entry_point - def set_rlp_encode_address(self, param): + def set_rlp_contract_address(self, param): sp.set_type(param, sp.TAddress) self.only_owner() - self.data.rlp_encode_struct = param + self.data.rlp_contract = param @sp.entry_point def add_owner(self, owner): @@ -310,7 +310,7 @@ def _propagate_internal(self, service_type, link): send_message_entry_point = sp.contract(send_message_args_type, self.data.bmc_periphery.open_some("Address not set"), "send_message").open_some() - send_message_args = sp.record(to=net, svc="bmc", sn=sp.int(0), msg=sp.view("encode_bmc_service", self.data.rlp_encode_struct, + send_message_args = sp.record(to=net, svc="bmc", sn=sp.int(0), msg=sp.view("encode_bmc_service", self.data.rlp_contract, sp.record(serviceType=service_type,payload=final_rlp_bytes_with_prefix), t=sp.TBytes).open_some()) sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) @@ -338,7 +338,7 @@ def _send_internal(self, target, service_type, links): send_message_entry_point = sp.contract(send_message_args_type, self.data.bmc_periphery.open_some("Address not set"), "send_message").open_some() - send_message_args = sp.record(to=net, svc="bmc", sn=sp.int(0), msg=sp.view("encode_bmc_service", self.data.rlp_encode_struct, + send_message_args = sp.record(to=net, svc="bmc", sn=sp.int(0), msg=sp.view("encode_bmc_service", self.data.rlp_contract, sp.record(serviceType=service_type, payload=rlp_bytes.value), t=sp.TBytes).open_some()) sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) @@ -578,4 +578,4 @@ def resolve_route(self, dst_net): sp.add_compilation_target("bmc_management", BMCManagement(owner_address=sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP"), helper_contract=sp.address("KT1HwFJmndBWRn3CLbvhUjdupfEomdykL5a6"), - rlp_encode_contract=sp.address("KT19eEe2CwtzYpuB3A5um6mJRMNMj8ek9BsT"))) + rlp_contract=sp.address("KT1CC7TVGvvouvPcBe5wK7MYk1y9j7G7VYgz"))) diff --git a/smartpy/bmc/contracts/src/bmc_periphery.py b/smartpy/bmc/contracts/src/bmc_periphery.py index 386abbe7..01cd3e27 100644 --- a/smartpy/bmc/contracts/src/bmc_periphery.py +++ b/smartpy/bmc/contracts/src/bmc_periphery.py @@ -19,7 +19,7 @@ class BMCPreiphery(sp.Contract): BMCRevertUnknownHandleBTPError = sp.string("UnknownHandleBTPError") BMCRevertUnknownHandleBTPMessage = sp.string("UnknownHandleBTPMessage") - def __init__(self, bmc_management_addr, helper_contract, helper_parse_neg_contract, parse_address, owner_address, rlp_decode_struct, rlp_encode_struct): + def __init__(self, bmc_management_addr, helper_contract, helper_parse_neg_contract, parse_address, owner_address, rlp_contract): self.init( helper=helper_contract, helper_parse_negative=helper_parse_neg_contract, @@ -30,8 +30,7 @@ def __init__(self, bmc_management_addr, helper_contract, helper_parse_neg_contra handle_btp_error_status=sp.none, handle_fee_gathering_status=sp.none, owner_address = owner_address, - rlp_decode_struct=rlp_decode_struct, - rlp_encode_struct=rlp_encode_struct + rlp_contract=rlp_contract, ) def only_owner(self): @@ -72,16 +71,10 @@ def set_bmc_btp_address(self, network): sp.failwith("Address already set") @sp.entry_point - def set_rlp_decode_address(self, param): + def set_rlp_contract_address(self, param): sp.set_type(param, sp.TAddress) self.only_owner() - self.data.rlp_decode_struct = param - - @sp.entry_point - def set_rlp_encode_address(self, param): - sp.set_type(param, sp.TAddress) - self.only_owner() - self.data.rlp_encode_struct = param + self.data.rlp_contract = param @sp.onchain_view() def get_bmc_btp_address(self): @@ -164,7 +157,7 @@ def handle_relay_message(self, prev, msg): rx_seq = sp.local("rx_seq", link_rx_seq, t=sp.TNat) rx_height = sp.local("rx_height", link_rx_height, t=sp.TNat) - rps = sp.view("decode_receipt_proofs", self.data.rlp_decode_struct, msg, t=sp.TMap(sp.TNat, types.Types.ReceiptProof)).open_some() + rps = sp.view("decode_receipt_proofs", self.data.rlp_contract, msg, t=sp.TMap(sp.TNat, types.Types.ReceiptProof)).open_some() bmc_msg = sp.local("bmc_msg", sp.record(src="", dst="", svc="", sn=sp.int(0), message=sp.bytes("0x")), t=types.Types.BMCMessage) ev = sp.local("ev", sp.record(next_bmc="", seq=sp.nat(0), message=sp.bytes("0x")), t=types.Types.MessageEvent) sp.for i in sp.range(sp.nat(0), sp.len(rps)): @@ -182,7 +175,7 @@ def handle_relay_message(self, prev, msg): sp.if ev.value.seq > rx_seq.value: sp.failwith(self.BMCRevertInvalidSeqNumber) - _decoded = sp.view("decode_bmc_message", self.data.rlp_decode_struct, ev.value.message, t=types.Types.BMCMessage).open_some() + _decoded = sp.view("decode_bmc_message", self.data.rlp_contract, ev.value.message, t=types.Types.BMCMessage).open_some() bmc_msg.value = _decoded sp.if bmc_msg.value.src != "": @@ -228,13 +221,13 @@ def _handle_message(self, prev, msg): # bsh_addr = sp.local("bsh_addr",sp.TAddress) with sp.if_(msg.svc == "bmc"): sm = sp.local("sm", sp.record(serviceType="", payload=sp.bytes("0x"))) - sm.value = sp.view("decode_bmc_service", self.data.rlp_decode_struct, msg.message, t=types.Types.BMCService).open_some() + sm.value = sp.view("decode_bmc_service", self.data.rlp_contract, msg.message, t=types.Types.BMCService).open_some() with sp.if_(sm.value.serviceType == ""): self._send_error(prev, msg, self.BMC_ERR, self.BMCRevertParseFailure) with sp.else_(): sp.if sm.value.serviceType == "FeeGathering": gather_fee =sp.local("gather_fee", sp.record(fa="", svcs=sp.map({0:""}))) - gather_fee.value = sp.view("decode_gather_fee_message", self.data.rlp_decode_struct, sm.value.payload, t=types.Types.GatherFeeMessage).open_some() + gather_fee.value = sp.view("decode_gather_fee_message", self.data.rlp_contract, sm.value.payload, t=types.Types.GatherFeeMessage).open_some() with sp.if_(gather_fee.value.fa == ""): self._send_error(prev, msg, self.BMC_ERR, self.BMCRevertParseFailure) @@ -255,7 +248,7 @@ def _handle_message(self, prev, msg): sp.transfer(handle_fee_gathering_args, sp.tez(0), handle_fee_gathering_entry_point) sp.if sm.value.serviceType == "Link": - to= sp.view("decode_propagate_message", self.data.rlp_decode_struct, sm.value.payload, t=sp.TString).open_some() + to= sp.view("decode_propagate_message", self.data.rlp_contract, sm.value.payload, t=sp.TString).open_some() link = sp.view("get_link", self.data.bmc_management, prev, t=types.Types.Link).open_some() check = sp.local("check", False) @@ -277,7 +270,7 @@ def _handle_message(self, prev, msg): sp.transfer(update_link_reachable_args, sp.tez(0), update_link_reachable_entry_point) sp.if sm.value.serviceType == "Unlink": - to = sp.view("decode_propagate_message", self.data.rlp_decode_struct, sm.value.payload, t=sp.TString).open_some() + to = sp.view("decode_propagate_message", self.data.rlp_contract, sm.value.payload, t=sp.TString).open_some() link = sp.view("get_link", self.data.bmc_management, prev, t=types.Types.Link).open_some() sp.if link.is_connected: @@ -295,7 +288,7 @@ def _handle_message(self, prev, msg): f.value += sp.nat(1) sp.if sm.value.serviceType == "Init": - links = sp.view("decode_init_message", self.data.rlp_decode_struct, sm.value.payload, t=sp.TList(sp.TString)).open_some() + links = sp.view("decode_init_message", self.data.rlp_contract, sm.value.payload, t=sp.TList(sp.TString)).open_some() # call update_link_reachable on BMCManagement update_link_reachable_args_type = sp.TRecord(prev=sp.TString, to=sp.TList(sp.TString)) update_link_reachable_entry_point = sp.contract(update_link_reachable_args_type, @@ -326,7 +319,7 @@ def _handle_message(self, prev, msg): sp.transfer(handle_btp_message_args, sp.tez(0), handle_btp_message_entry_point) with sp.else_(): - res = sp.view("decode_response", self.data.rlp_decode_struct, msg.message, t=types.Types.Response).open_some() + res = sp.view("decode_response", self.data.rlp_contract, msg.message, t=types.Types.Response).open_some() # implemented callback # call handle_btp_error on bts periphery handle_btp_error_args_type = sp.TRecord(callback=sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress, svc=sp.TString, sn=sp.TInt, code=sp.TNat, msg=sp.TString)), @@ -358,12 +351,12 @@ def _send_error(self, prev, message, err_code, err_msg): sp.set_type(err_msg, sp.TString) sp.if message.sn > sp.int(0): - serialized_msg = sp.view("encode_bmc_message", self.data.rlp_encode_struct, sp.record( + serialized_msg = sp.view("encode_bmc_message", self.data.rlp_contract, sp.record( src=self.data.bmc_btp_address.open_some("Address not set"), dst=message.src, svc=message.svc, sn=message.sn * -1, - message=sp.view("encode_response", self.data.rlp_encode_struct, sp.record(code=err_code, message=err_msg), t=sp.TBytes).open_some()), t=sp.TBytes).open_some() + message=sp.view("encode_response", self.data.rlp_contract, sp.record(code=err_code, message=err_msg), t=sp.TBytes).open_some()), t=sp.TBytes).open_some() self._send_message(prev, serialized_msg) @sp.entry_point @@ -388,7 +381,7 @@ def send_message(self, to, svc, sn, msg): next_link, dst = sp.match_pair(sp.view("resolve_route", self.data.bmc_management, to, t=sp.TPair(sp.TString, sp.TString)).open_some()) - rlp = sp.view("encode_bmc_message", self.data.rlp_encode_struct, sp.record( + rlp = sp.view("encode_bmc_message", self.data.rlp_contract, sp.record( src=self.data.bmc_btp_address.open_some("Address not set"), dst=dst, svc=svc, @@ -421,5 +414,4 @@ def get_status(self, _link): helper_parse_neg_contract=sp.address("KT1DHptHqSovffZ7qqvSM9dy6uZZ8juV88gP"), parse_address=sp.address("KT1XgRyjQPfpfwNrvYYpgERpYpCrGh24aoPX"), owner_address=sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP"), - rlp_decode_struct=sp.address("KT1WGckGaUsKZs8PHskmGCDQX5CiSzwj3akH"), - rlp_encode_struct=sp.address("KT19eEe2CwtzYpuB3A5um6mJRMNMj8ek9BsT"))) + rlp_contract=sp.address("KT1CC7TVGvvouvPcBe5wK7MYk1y9j7G7VYgz"))) From d62e4ad48a55215648947e15ebed56277eaf3e7b Mon Sep 17 00:00:00 2001 From: suyogadhikari Date: Tue, 13 Jun 2023 10:51:16 +0545 Subject: [PATCH 090/211] perf(bts): rlp encoder and decoder merged into a single contract. --- .../bts/contracts/src/RLP_encode_struct.py | 76 ------------------- .../{RLP_decode_struct.py => RLP_struct.py} | 59 +++++++++++++- smartpy/bts/contracts/src/bts_periphery.py | 36 ++++----- 3 files changed, 72 insertions(+), 99 deletions(-) delete mode 100644 smartpy/bts/contracts/src/RLP_encode_struct.py rename smartpy/bts/contracts/src/{RLP_decode_struct.py => RLP_struct.py} (84%) diff --git a/smartpy/bts/contracts/src/RLP_encode_struct.py b/smartpy/bts/contracts/src/RLP_encode_struct.py deleted file mode 100644 index fea6c9e9..00000000 --- a/smartpy/bts/contracts/src/RLP_encode_struct.py +++ /dev/null @@ -1,76 +0,0 @@ -import smartpy as sp - -types = sp.io.import_script_from_url("file:./contracts/src/Types.py") -helper_file = sp.io.import_script_from_url("file:./contracts/src/helper.py") - - -class EncodeLibrary(sp.Contract): - - def __init__(self, helper_contract): - self.init( - helper=helper_contract - ) - - - @sp.onchain_view() - def encode_service_message(self, params): - sp.set_type(params, sp.TRecord(service_type_value = sp.TNat, data = sp.TBytes)) - - encode_service_type = sp.view("encode_nat", self.data.helper, params.service_type_value, t=sp.TBytes).open_some() - rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [encode_service_type, params.data], t=sp.TBytes).open_some() - final_rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp_bytes_with_prefix, t=sp.TBytes).open_some() - - sp.result(final_rlp_bytes_with_prefix) - - - @sp.onchain_view() - def encode_transfer_coin_msg(self, data): - sp.set_type(data, types.Types.TransferCoin) - - rlp = sp.local("rlp", sp.bytes("0x")) - rlp_list = sp.local("rlp_list", [], t=sp.TList(sp.TBytes)) - temp = sp.local("temp", sp.bytes("0x")) - coin_name = sp.local("coin_name", sp.bytes("0x")) - sp.for i in sp.range(0, sp.len(data.assets)): - coin_name.value = sp.view("encode_string", self.data.helper, data.assets.get(i, default_value=sp.record(coin_name="",value=sp.nat(0))).coin_name, t=sp.TBytes).open_some() - temp.value = sp.view("encode_nat", self.data.helper, data.assets.get(i, default_value=sp.record(coin_name="",value=sp.nat(0))).value, t=sp.TBytes).open_some() - rlp_list.value.push(sp.view("encode_list", self.data.helper, [coin_name.value, temp.value], t=sp.TBytes).open_some()) - # rlp.value = sp.view("with_length_prefix", self.data.helper, rlp.value, - # t=sp.TBytes).open_some() - - assets_list = sp.view("encode_list", self.data.helper, rlp_list.value, t=sp.TBytes).open_some() - from_addr_encoded = sp.view("encode_string", self.data.helper, data.from_addr, t=sp.TBytes).open_some() - to_addr_encoded = sp.view("encode_string", self.data.helper, data.to, t=sp.TBytes).open_some() - rlp.value = sp.view("encode_list", self.data.helper, [from_addr_encoded, to_addr_encoded, assets_list], t=sp.TBytes).open_some() - final_rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp.value, t=sp.TBytes).open_some() - - sp.result(final_rlp_bytes_with_prefix) - - - @sp.onchain_view() - def encode_response(self, params): - sp.set_type(params, sp.TRecord(code=sp.TNat, message=sp.TString)) - - encode_code = sp.view("encode_nat", self.data.helper, params.code, t=sp.TBytes).open_some() - encode_message = sp.view("encode_string", self.data.helper, params.message, t=sp.TBytes).open_some() - - rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [encode_code, encode_message], - t=sp.TBytes).open_some() - final_rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp_bytes_with_prefix, t=sp.TBytes).open_some() - - sp.result(final_rlp_bytes_with_prefix) - - -@sp.add_test(name="Encoder") -def test(): - scenario = sp.test_scenario() - - helper = helper_file.Helper() - scenario += helper - - c1 = EncodeLibrary(helper.address) - scenario += c1 - - -sp.add_compilation_target("RLP_encode_struct", - EncodeLibrary(helper_contract=sp.address("KT1HwFJmndBWRn3CLbvhUjdupfEomdykL5a6"))) diff --git a/smartpy/bts/contracts/src/RLP_decode_struct.py b/smartpy/bts/contracts/src/RLP_struct.py similarity index 84% rename from smartpy/bts/contracts/src/RLP_decode_struct.py rename to smartpy/bts/contracts/src/RLP_struct.py index f214c915..67a83f6a 100644 --- a/smartpy/bts/contracts/src/RLP_decode_struct.py +++ b/smartpy/bts/contracts/src/RLP_struct.py @@ -309,6 +309,63 @@ def decode_token_limit_msg(self, rlp): sp.result(sp.record(coin_name = rv_names.value, token_limit = rv_limit.value , net = sp.view("decode_string", self.data.helper, rv1_byt.value, t=sp.TString).open_some())) + # encoding starts here + @sp.onchain_view() + def encode_service_message(self, params): + sp.set_type(params, sp.TRecord(service_type_value=sp.TNat, data=sp.TBytes)) + + encode_service_type = sp.view("encode_nat", self.data.helper, params.service_type_value, + t=sp.TBytes).open_some() + rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [encode_service_type, params.data], + t=sp.TBytes).open_some() + final_rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp_bytes_with_prefix, + t=sp.TBytes).open_some() + + sp.result(final_rlp_bytes_with_prefix) + + @sp.onchain_view() + def encode_transfer_coin_msg(self, data): + sp.set_type(data, types.Types.TransferCoin) + + rlp = sp.local("rlp", sp.bytes("0x")) + rlp_list = sp.local("rlp_list", [], t=sp.TList(sp.TBytes)) + temp = sp.local("temp", sp.bytes("0x")) + coin_name = sp.local("coin_name", sp.bytes("0x")) + sp.for i in sp.range(0, sp.len(data.assets)): + coin_name.value = sp.view("encode_string", self.data.helper, data.assets.get(i, default_value=sp.record( + coin_name="", value=sp.nat(0))).coin_name, t=sp.TBytes).open_some() + temp.value = sp.view("encode_nat", self.data.helper, + data.assets.get(i, default_value=sp.record(coin_name="", value=sp.nat(0))).value, + t=sp.TBytes).open_some() + rlp_list.value.push( + sp.view("encode_list", self.data.helper, [coin_name.value, temp.value], t=sp.TBytes).open_some()) + # rlp.value = sp.view("with_length_prefix", self.data.helper, rlp.value, + # t=sp.TBytes).open_some() + + assets_list = sp.view("encode_list", self.data.helper, rlp_list.value, t=sp.TBytes).open_some() + from_addr_encoded = sp.view("encode_string", self.data.helper, data.from_addr, t=sp.TBytes).open_some() + to_addr_encoded = sp.view("encode_string", self.data.helper, data.to, t=sp.TBytes).open_some() + rlp.value = sp.view("encode_list", self.data.helper, [from_addr_encoded, to_addr_encoded, assets_list], + t=sp.TBytes).open_some() + final_rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp.value, + t=sp.TBytes).open_some() + + sp.result(final_rlp_bytes_with_prefix) + + @sp.onchain_view() + def encode_response(self, params): + sp.set_type(params, sp.TRecord(code=sp.TNat, message=sp.TString)) + + encode_code = sp.view("encode_nat", self.data.helper, params.code, t=sp.TBytes).open_some() + encode_message = sp.view("encode_string", self.data.helper, params.message, t=sp.TBytes).open_some() + + rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [encode_code, encode_message], + t=sp.TBytes).open_some() + final_rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp_bytes_with_prefix, + t=sp.TBytes).open_some() + + sp.result(final_rlp_bytes_with_prefix) + @sp.add_test(name="Decoder") def test(): @@ -321,6 +378,6 @@ def test(): scenario += c1 -sp.add_compilation_target("RLP_decode_struct", +sp.add_compilation_target("RLP_struct", DecodeLibrary(helper_contract=sp.address("KT1HwFJmndBWRn3CLbvhUjdupfEomdykL5a6"))) diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index eb5cd834..8d22e99d 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -13,7 +13,7 @@ class BTPPreiphery(sp.Contract): MAX_BATCH_SIZE = sp.nat(15) - def __init__(self, bmc_address, bts_core_address, helper_contract, parse_address, native_coin_name, owner_address, rlp_decode_struct, rlp_encode_struct): + def __init__(self, bmc_address, bts_core_address, helper_contract, parse_address, native_coin_name, owner_address, rlp_contract): self.update_initial_storage( bmc=bmc_address, owner=owner_address, @@ -26,8 +26,7 @@ def __init__(self, bmc_address, bts_core_address, helper_contract, parse_address helper=helper_contract, parse_contract=parse_address, mint_status=sp.none, - rlp_decode_struct=rlp_decode_struct, - rlp_encode_struct=rlp_encode_struct + rlp_contract=rlp_contract ) def only_bmc(self): @@ -67,16 +66,10 @@ def set_bts_core_address(self, params): self.data.bts_core = params @sp.entry_point - def set_rlp_decode_address(self, param): + def set_rlp_contract_address(self, param): sp.set_type(param, sp.TAddress) self.only_owner() - self.data.rlp_decode_struct = param - - @sp.entry_point - def set_rlp_encode_address(self, param): - sp.set_type(param, sp.TAddress) - self.only_owner() - self.data.rlp_encode_struct = param + self.data.rlp_contract = param @sp.onchain_view() def has_pending_request(self): @@ -248,8 +241,8 @@ def send_service_message(self, _from, to, coin_names, values, fees): send_message_entry_point = sp.contract(send_message_args_type, self.data.bmc, "send_message").open_some() send_message_args = sp.record( to=to_network, svc=self.service_name, sn=self.data.serial_no, - msg = sp.view("encode_service_message", self.data.rlp_encode_struct, sp.record(service_type_value=sp.nat(0), - data=sp.view("encode_transfer_coin_msg", self.data.rlp_encode_struct, sp.record(from_addr=start_from, to=to_address, assets=assets), + msg = sp.view("encode_service_message", self.data.rlp_contract, sp.record(service_type_value=sp.nat(0), + data=sp.view("encode_transfer_coin_msg", self.data.rlp_contract, sp.record(from_addr=start_from, to=to_address, assets=assets), t=sp.TBytes).open_some()), t=sp.TBytes).open_some()) sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) @@ -291,14 +284,14 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, bsh_addr, prev, call callback_string = sp.local("callback_string", "") with sp.if_((svc == self.service_name) & (check_caller == "Authorized")): err_msg = sp.local("error", "") - sm = sp.view("decode_service_message", self.data.rlp_decode_struct, msg, t=types.Types.ServiceMessage).open_some() + sm = sp.view("decode_service_message", self.data.rlp_contract, msg, t=types.Types.ServiceMessage).open_some() service_type_variant_match = sp.local("serviceType_variant", False, t=sp.TBool) with sm.serviceType.match_cases() as arg: with arg.match("REQUEST_COIN_TRANSFER") as a1: service_type_variant_match.value = True callback_string.value = "success" - tc = sp.view("decode_transfer_coin_msg", self.data.rlp_decode_struct, sm.data, t=types.Types.TransferCoin).open_some() + tc = sp.view("decode_transfer_coin_msg", self.data.rlp_contract, sm.data, t=types.Types.TransferCoin).open_some() parsed_addr = sp.view("str_to_addr", self.data.parse_contract, tc.to, t=sp.TAddress).open_some() with sp.if_(parsed_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): @@ -317,7 +310,7 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, bsh_addr, prev, call with arg.match("BLACKLIST_MESSAGE") as a2: service_type_variant_match.value = True callback_string.value = "success" - bm = sp.view("decode_blacklist_msg", self.data.rlp_decode_struct, sm.data, t=types.Types.BlacklistMessage).open_some() + bm = sp.view("decode_blacklist_msg", self.data.rlp_contract, sm.data, t=types.Types.BlacklistMessage).open_some() addresses = bm.addrs blacklist_service_called = sp.local("blacklist_service", False, t=sp.TBool) @@ -346,7 +339,7 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, bsh_addr, prev, call with arg.match("CHANGE_TOKEN_LIMIT") as a3: service_type_variant_match.value = True callback_string.value = "success" - tl = sp.view("decode_token_limit_msg", self.data.rlp_decode_struct, sm.data, t=types.Types.TokenLimitMessage).open_some() + tl = sp.view("decode_token_limit_msg", self.data.rlp_contract, sm.data, t=types.Types.TokenLimitMessage).open_some() coin_names = tl.coin_name token_limits = tl.token_limit @@ -359,7 +352,7 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, bsh_addr, prev, call with arg.match("RESPONSE_HANDLE_SERVICE") as a4: service_type_variant_match.value = True with sp.if_(sp.len(sp.pack(self.data.requests.get(sn).from_)) != 0): - response = sp.view("decode_response", self.data.rlp_decode_struct, sm.data, t=types.Types.Response).open_some() + response = sp.view("decode_response", self.data.rlp_contract, sm.data, t=types.Types.Response).open_some() handle_response = self.handle_response_service(sn, response.code, response.message) with sp.if_(handle_response == "success"): callback_string.value = "success" @@ -558,8 +551,8 @@ def send_response_message(self, service_type, service_type_val, to, sn, msg, cod ) send_message_entry_point = sp.contract(send_message_args_type, self.data.bmc, "send_message").open_some() send_message_args = sp.record(to=to, svc=self.service_name, sn=sn, - msg=sp.view("encode_service_message", self.data.rlp_encode_struct, sp.record(service_type_value=service_type_val, data=sp.view("encode_response", - self.data.rlp_encode_struct, sp.record(code=code, message=msg), t=sp.TBytes).open_some()), t=sp.TBytes).open_some()) + msg=sp.view("encode_service_message", self.data.rlp_contract, sp.record(service_type_value=service_type_val, data=sp.view("encode_response", + self.data.rlp_contract, sp.record(code=code, message=msg), t=sp.TBytes).open_some()), t=sp.TBytes).open_some()) sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) @@ -614,5 +607,4 @@ def check_transfer_restrictions(self, params): parse_address=sp.address("KT1EKPrSLWjWViZQogFgbc1QmztkR5UGXEWa"), native_coin_name="btp-NetXnHfVqm9iesp.tezos-XTZ", owner_address = sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP"), - rlp_decode_struct=sp.address("KT1HfeUF15X4TaaaDVsdX8ZZaybu42EdpwW1"), - rlp_encode_struct=sp.address("KT1AjjdjRFpV52LUgrV1KCVaKZ4eH6rm7ejG"))) \ No newline at end of file + rlp_contract=sp.address("KT1BuF4ZtTK9gTSa7jQa8Byt8TrjKxtbcs26"))) \ No newline at end of file From 77d96322d1c3298cd99b0d81804b58dea6e4257d Mon Sep 17 00:00:00 2001 From: simusud Date: Tue, 13 Jun 2023 13:46:53 +0545 Subject: [PATCH 091/211] feat(bmc): added upgradable feature in contract functions --- smartpy/bmc/contracts/src/bmc_management.py | 52 +++++++++++++++++---- smartpy/bmc/contracts/src/bmc_periphery.py | 36 ++++++++++++-- 2 files changed, 73 insertions(+), 15 deletions(-) diff --git a/smartpy/bmc/contracts/src/bmc_management.py b/smartpy/bmc/contracts/src/bmc_management.py index d502c83e..830fdef4 100644 --- a/smartpy/bmc/contracts/src/bmc_management.py +++ b/smartpy/bmc/contracts/src/bmc_management.py @@ -171,7 +171,12 @@ def get_services(self): i.value += 1 sp.result(services) - @sp.entry_point + @sp.entry_point(lazify=False) + def update_add_link(self, ep): + self.only_owner() + sp.set_entry_point("add_link", ep) + + @sp.entry_point(lazify=True) def add_link(self, link): """ Initializes status information for the link. @@ -208,7 +213,12 @@ def add_link(self, link): self.data.get_link_from_net[net] = link self._send_internal(link, "Init", links) - @sp.entry_point + @sp.entry_point(lazify=False) + def update_remove_link(self, ep): + self.only_owner() + sp.set_entry_point("remove_link", ep) + + @sp.entry_point(lazify=True) def remove_link(self, link): """ Removes the link and status information. @@ -342,8 +352,12 @@ def _send_internal(self, target, service_type, links): sp.record(serviceType=service_type, payload=rlp_bytes.value), t=sp.TBytes).open_some()) sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) + @sp.entry_point(lazify=False) + def update_add_route(self, ep): + self.only_owner() + sp.set_entry_point("add_route", ep) - @sp.entry_point + @sp.entry_point(lazify=True) def add_route(self, dst, link): """ Add route to the BMC. @@ -357,14 +371,18 @@ def add_route(self, dst, link): self.only_owner() sp.verify(self.data.routes.contains(dst) == False, "AlreadyExistRoute") net, addr= sp.match_pair(strings.split_btp_address(dst, "prev_idx", "result", "my_list", "last", "penultimate")) - # TODO: need to verify link is only split never used - # strings.split_btp_address(link) + strings.split_btp_address(link, "prev_idx1", "result1", "my_list1", "last1", "penultimate1") self.data.routes[dst] = link self.data.list_route_keys.add(dst) self.data.get_route_dst_from_net[net] = dst - @sp.entry_point + @sp.entry_point(lazify=False) + def update_remove_route(self, ep): + self.only_owner() + sp.set_entry_point("remove_route", ep) + + @sp.entry_point(lazify=True) def remove_route(self, dst): """ Remove route to the BMC. @@ -394,7 +412,12 @@ def get_routes(self): i.value += 1 sp.result(_routes) - @sp.entry_point + @sp.entry_point(lazify=False) + def update_add_relay(self, ep): + self.only_owner() + sp.set_entry_point("add_relay", ep) + + @sp.entry_point(lazify=True) def add_relay(self, link, addr): """ Registers relay for the network. @@ -412,7 +435,12 @@ def add_relay(self, link, addr): sp.for item in addr.elements(): self.data.relay_stats[item] = sp.record(addr=item, block_count=sp.nat(0), msg_count=sp.nat(0)) - @sp.entry_point + @sp.entry_point(lazify=False) + def update_remove_relay(self, ep): + self.only_owner() + sp.set_entry_point("remove_relay", ep) + + @sp.entry_point(lazify=True) def remove_relay(self, link, addr): """ Unregisters Relay for the network. @@ -438,7 +466,6 @@ def remove_relay(self, link, addr): sp.for ele in self.data.addrs.elements(): self.data.addrs.remove(ele) - @sp.onchain_view() def get_relays(self, link): """ @@ -499,7 +526,12 @@ def update_link_rx_seq(self, prev, val): self.only_bmc_periphery() self.data.links[prev].rx_seq += val - @sp.entry_point + @sp.entry_point(lazify=False) + def update_update_link_tx_seq(self, ep): + self.only_owner() + sp.set_entry_point("update_link_tx_seq", ep) + + @sp.entry_point(lazify=True) def update_link_tx_seq(self, prev, serialized_msg): sp.set_type(prev, sp.TString) sp.set_type(serialized_msg, sp.TBytes) diff --git a/smartpy/bmc/contracts/src/bmc_periphery.py b/smartpy/bmc/contracts/src/bmc_periphery.py index 01cd3e27..f99834a1 100644 --- a/smartpy/bmc/contracts/src/bmc_periphery.py +++ b/smartpy/bmc/contracts/src/bmc_periphery.py @@ -60,7 +60,12 @@ def set_bmc_management_addr(self, params): self.only_owner() self.data.bmc_management = params - @sp.entry_point + @sp.entry_point(lazify=False) + def update_set_bmc_btp_address(self, ep): + self.only_owner() + sp.set_entry_point("set_bmc_btp_address", ep) + + @sp.entry_point(lazify=True) def set_bmc_btp_address(self, network): sp.set_type(network, sp.TString) @@ -94,7 +99,12 @@ def _require_registered_relay(self, prev): valid.value = True sp.verify(valid.value, self.BMCRevertUnauthorized) - @sp.entry_point + @sp.entry_point(lazify=False) + def update_callback_btp_message(self, ep): + self.only_owner() + sp.set_entry_point("callback_btp_message", ep) + + @sp.entry_point(lazify=True) def callback_btp_message(self, string, bsh_addr, prev, callback_msg): sp.set_type(string, sp.TOption(sp.TString)) sp.set_type(bsh_addr, sp.TAddress) @@ -110,7 +120,12 @@ def callback_btp_message(self, string, bsh_addr, prev, callback_msg): self._send_error(prev, callback_msg, self.BSH_ERR, self.BMCRevertUnknownHandleBTPMessage) self.data.handle_btp_message_status = sp.none - @sp.entry_point + @sp.entry_point(lazify=False) + def update_callback_btp_error(self, ep): + self.only_owner() + sp.set_entry_point("callback_btp_error", ep) + + @sp.entry_point(lazify=True) def callback_btp_error(self, string, bsh_addr, svc, sn, code, msg): sp.set_type(string, sp.TOption(sp.TString)) sp.set_type(bsh_addr, sp.TAddress) @@ -130,7 +145,12 @@ def callback_btp_error(self, string, bsh_addr, svc, sn, code, msg): sp.emit(sp.record(svc=svc, sn=sn * -1, code=code, msg=msg, err_code=error_code, err_msg=err_msg), tag="ErrorOnBTPError") self.data.handle_btp_error_status = sp.none - @sp.entry_point + @sp.entry_point(lazify=False) + def update_callback_handle_fee_gathering(self, ep): + self.only_owner() + sp.set_entry_point("callback_handle_fee_gathering", ep) + + @sp.entry_point(lazify=True) def callback_handle_fee_gathering(self, string, bsh_addr): sp.set_type(string, sp.TOption(sp.TString)) sp.set_type(bsh_addr, sp.TAddress) @@ -143,6 +163,7 @@ def callback_handle_fee_gathering(self, string, bsh_addr): @sp.entry_point(lazify=False) def update_handle_relay_message(self, ep): + self.only_owner() sp.set_entry_point("handle_relay_message", ep) @sp.entry_point(lazify=True) @@ -359,7 +380,12 @@ def _send_error(self, prev, message, err_code, err_msg): message=sp.view("encode_response", self.data.rlp_contract, sp.record(code=err_code, message=err_msg), t=sp.TBytes).open_some()), t=sp.TBytes).open_some() self._send_message(prev, serialized_msg) - @sp.entry_point + @sp.entry_point(lazify=False) + def update_send_message(self, ep): + self.only_owner() + sp.set_entry_point("send_message", ep) + + @sp.entry_point(lazify=True) def send_message(self, to, svc, sn, msg): """ Send the message to a specific network From be0cc10277e852086582c33c48883c4b13de74fb Mon Sep 17 00:00:00 2001 From: simusud Date: Tue, 13 Jun 2023 13:47:16 +0545 Subject: [PATCH 092/211] feat(bts): added upgradable feature in contract functions --- smartpy/bts/contracts/src/bts_core.py | 57 ++++++++++--- smartpy/bts/contracts/src/bts_periphery.py | 97 +++++----------------- 2 files changed, 66 insertions(+), 88 deletions(-) diff --git a/smartpy/bts/contracts/src/bts_core.py b/smartpy/bts/contracts/src/bts_core.py index a05d035e..6cb563ac 100644 --- a/smartpy/bts/contracts/src/bts_core.py +++ b/smartpy/bts/contracts/src/bts_core.py @@ -48,9 +48,7 @@ def __init__(self, _native_coin_name, _fee_numerator, _fixed_fee, owner_manager) transfer_status=sp.none ) - #is this necessary? can we check against owners map in line 37? def only_owner(self): - # call Owner Manager Contract for checking owner is_owner = sp.view("is_owner", self.data.bts_owner_manager, sp.sender, t=sp.TBool).open_some( "OwnerNotFound") sp.verify(is_owner == True, message="Unauthorized") @@ -102,7 +100,12 @@ def set_fee_ratio(self, name, fee_numerator, fixed_fee): self.data.coin_details[name].fee_numerator = fee_numerator self.data.coin_details[name].fixed_fee = fixed_fee - @sp.entry_point + @sp.entry_point(lazify=False) + def update_register(self, ep): + self.only_owner() + sp.set_entry_point("register", ep) + + @sp.entry_point(lazify=True) def register(self, name, fee_numerator, fixed_fee, addr, token_metadata, metadata): """ Registers a wrapped coin and id number of a supporting coin. @@ -289,7 +292,12 @@ def get_accumulated_fees(self): i.value += sp.nat(1) sp.result(accumulated_fees.value) - @sp.entry_point(check_no_incoming_transfer=False) + @sp.entry_point(lazify=False) + def update_transfer_native_coin(self, ep): + self.only_owner() + sp.set_entry_point("transfer_native_coin", ep) + + @sp.entry_point(check_no_incoming_transfer=False, lazify=True) def transfer_native_coin(self, to): """ Allow users to deposit `sp.amount` native coin into a BTSCore contract. @@ -310,7 +318,12 @@ def transfer_native_coin(self, to): self._send_service_message(sp.sender, to, self.data.native_coin_name, amount_in_nat.value, charge_amt) - @sp.entry_point + @sp.entry_point(lazify=False) + def update_transfer(self, ep): + self.only_owner() + sp.set_entry_point("transfer", ep) + + @sp.entry_point(lazify=True) def transfer(self, coin_name, value, to): """ Allow users to deposit an amount of wrapped native coin `coin_name` from the `sp.sender` address into the BTSCore contract. @@ -374,7 +387,12 @@ def _send_service_message(self, _from, to, coin_name, value, charge_amt): send_service_message_args = sp.record(_from = _from, to = to, coin_names = coins.value, values = amounts.value, fees = fees.value) sp.transfer(send_service_message_args, sp.tez(0), send_service_message_entry_point) - @sp.entry_point(check_no_incoming_transfer=False) + @sp.entry_point(lazify=False) + def update_transfer_batch(self, ep): + self.only_owner() + sp.set_entry_point("transfer_batch", ep) + + @sp.entry_point(check_no_incoming_transfer=False, lazify=True) def transfer_batch(self, coin_names, values, to): """ Allow users to transfer multiple coins/wrapped coins to another chain. @@ -515,7 +533,12 @@ def payment_transfer(self, to, amount): sp.send(to, sp.utils.nat_to_mutez(amount), message="PaymentFailed") - @sp.entry_point + @sp.entry_point(lazify=False) + def update_mint(self, ep): + self.only_owner() + sp.set_entry_point("mint", ep) + + @sp.entry_point(lazify=True) def mint(self, to, coin_name, value, callback): """ mint the wrapped coin. @@ -554,7 +577,7 @@ def mint(self, to, coin_name, value, callback): sp.transfer(sp.some("success"), sp.tez(0), callback) @sp.entry_point - def callback(self, string, requester, coin_name, value): + def transfer_callback(self, string, requester, coin_name, value): sp.set_type(string, sp.TOption(sp.TString)) sp.set_type(requester, sp.TAddress) sp.set_type(coin_name, sp.TString) @@ -572,7 +595,12 @@ def callback(self, string, requester, coin_name, value): ).refundable_balance + value self.data.transfer_status = sp.none - @sp.entry_point + @sp.entry_point(lazify=False) + def update_handle_response_service(self, ep): + self.only_owner() + sp.set_entry_point("handle_response_service", ep) + + @sp.entry_point(lazify=True) def handle_response_service(self, requester, coin_name, value, fee, rsp_code): """ Handle a response of a requested service. @@ -622,8 +650,10 @@ def handle_response_service(self, requester, coin_name, value, fee, rsp_code): ).layout((("from_", "coin_name"), ("callback", "txs")))) transfer_entry_point = sp.contract(transfer_args_type, self.data.coins[coin_name], "transfer_bts").open_some() + t = sp.TRecord(string=sp.TOption(sp.TString), requester=sp.TAddress, coin_name=sp.TString, value=sp.TNat) + callback = sp.contract(t, sp.self_address, "transfer_callback") transfer_args = [ - sp.record(callback=sp.self_entry_point("callback"), from_=sp.self_address, coin_name=coin_name, txs=[sp.record(to_=requester, token_id=sp.nat(0), amount=value)])] + sp.record(callback=callback.open_some(), from_=sp.self_address, coin_name=coin_name, txs=[sp.record(to_=requester, token_id=sp.nat(0), amount=value)])] sp.transfer(transfer_args, sp.tez(0), transfer_entry_point) sp.if rsp_code == self.RC_OK: @@ -637,7 +667,12 @@ def handle_response_service(self, requester, coin_name, value, fee, rsp_code): self.data.aggregation_fee[coin_name] = self.data.aggregation_fee.get(coin_name, default_value=sp.nat(0)) + fee - @sp.entry_point + @sp.entry_point(lazify=False) + def update_transfer_fees(self, ep): + self.only_owner() + sp.set_entry_point("transfer_fees", ep) + + @sp.entry_point(lazify=True) def transfer_fees(self, fa): """ Handle a request of Fee Gathering. Usage: Copy all charged fees to an array diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index 8d22e99d..d23bcbf3 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -74,29 +74,10 @@ def set_rlp_contract_address(self, param): @sp.onchain_view() def has_pending_request(self): """ - :return: boolean """ sp.result(self.data.number_of_pending_requests != sp.nat(0)) - @sp.entry_point - def add_to_blacklist(self, params): - """ - - :param params: List of addresses to be blacklisted - :return: - """ - sp.set_type(params, sp.TMap(sp.TNat, sp.TString)) - sp.verify(sp.sender == sp.self_address, "Unauthorized") - sp.verify(sp.len(params) <= self.MAX_BATCH_SIZE, "BatchMaxSizeExceed") - - sp.for i in sp.range(sp.nat(0), sp.len(params)): - parsed_addr = sp.view("str_to_addr", self.data.parse_contract, params.get(i), t=sp.TAddress).open_some() - with sp.if_(parsed_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): - self.data.blacklist[parsed_addr] = True - with sp.else_(): - sp.failwith("InvalidAddress") - # private function to return the tx status made from handle_btp_message def _add_to_blacklist(self, params): """ @@ -118,26 +99,6 @@ def _add_to_blacklist(self, params): add_blacklist_status.value = "error" return add_blacklist_status.value - @sp.entry_point - def remove_from_blacklist(self, params): - """ - :param params: list of address strings - :return: - """ - sp.set_type(params, sp.TMap(sp.TNat, sp.TString)) - - sp.verify(sp.sender == sp.self_address, "Unauthorized") - sp.verify(sp.len(params) <= self.MAX_BATCH_SIZE, "BatchMaxSizeExceed") - - sp.for i in sp.range(sp.nat(0), sp.len(params)): - parsed_addr = sp.view("str_to_addr", self.data.parse_contract, params.get(i), t=sp.TAddress).open_some() - with sp.if_(parsed_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): - sp.verify(self.data.blacklist.contains(parsed_addr), "UserNotFound") - sp.verify(self.data.blacklist.get(parsed_addr) == True, "UserNotBlacklisted") - del self.data.blacklist[parsed_addr] - with sp.else_(): - sp.failwith("InvalidAddress") - # private function to return the tx status made from handle_btp_message def _remove_from_blacklist(self, params): """ @@ -198,7 +159,12 @@ def _set_token_limit(self, coin_names, token_limit): set_limit_status.value = "error" return set_limit_status.value - @sp.entry_point + @sp.entry_point(lazify=False) + def update_send_service_message(self, ep): + self.only_owner() + sp.set_entry_point("send_service_message", ep) + + @sp.entry_point(lazify=True) def send_service_message(self, _from, to, coin_names, values, fees): """ Send service message to BMC @@ -254,8 +220,12 @@ def send_service_message(self, _from, to, coin_names, values, fees): self.data.number_of_pending_requests +=sp.nat(1) sp.emit(sp.record(from_address=_from, to=to, serial_no=self.data.serial_no, assets_details=assets_details), tag="TransferStart") + @sp.entry_point(lazify=False) + def update_handle_btp_message(self, ep): + self.only_owner() + sp.set_entry_point("handle_btp_message", ep) - @sp.entry_point + @sp.entry_point(lazify=True) def handle_btp_message(self, _from, svc, sn, msg, callback, bsh_addr, prev, callback_msg): """ BSH handle BTP message from BMC contract @@ -375,7 +345,12 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, bsh_addr, prev, call callback_msg=callback_msg) sp.transfer(return_value, sp.tez(0), callback) - @sp.entry_point + @sp.entry_point(lazify=False) + def update_handle_btp_error(self, ep): + self.only_owner() + sp.set_entry_point("handle_btp_error", ep) + + @sp.entry_point(lazify=True) def handle_btp_error(self, svc, sn, code, msg, callback, bsh_addr): """ BSH handle BTP Error from BMC contract @@ -481,7 +456,9 @@ def _handle_request_service(self, to, assets): to=sp.TAddress, coin_name=sp.TString, value=sp.TNat ) mint_args_type_entry_point = sp.contract(mint_args_type, self.data.bts_core, "mint").open_some() - mint_args = sp.record(callback=sp.self_entry_point("callback_mint"), + t = sp.TOption(sp.TString) + callback = sp.contract(t, sp.self_address, "callback_mint") + mint_args = sp.record(callback=callback.open_some(), to=parsed_to, coin_name=assets[i].coin_name, value=assets[i].value ) sp.transfer(mint_args, sp.tez(0), mint_args_type_entry_point) @@ -495,39 +472,6 @@ def _handle_request_service(self, to, assets): return status.value - @sp.entry_point - def handle_request_service(self, to, assets): - """ - Handle a list of minting/transferring coins/tokens - :param to: An address to receive coins/tokens - :param assets: A list of requested coin respectively with an amount - :return: - """ - sp.set_type(to, sp.TString) - sp.set_type(assets, sp.TMap(sp.TNat, types.Types.Asset)) - - sp.verify(sp.sender == sp.self_address, "Unauthorized") - sp.verify(sp.len(assets) <= self.MAX_BATCH_SIZE, "BatchMaxSizeExceed") - - parsed_to = sp.view("str_to_addr", self.data.parse_contract, to, t=sp.TAddress).open_some() - sp.for i in sp.range(0, sp.len(assets)): - valid_coin = sp.view("is_valid_coin", self.data.bts_core, assets[i].coin_name, t=sp.TBool).open_some() - sp.verify(valid_coin == True, "UnregisteredCoin") - - check_transfer = sp.view("check_transfer_restrictions", sp.self_address, sp.record( - coin_name=assets[i].coin_name,user=parsed_to, value=assets[i].value), t=sp.TBool).open_some() - sp.verify(check_transfer == True, "FailCheckTransfer") - - # inter score call - mint_args_type = sp.TRecord(to=sp.TAddress, coin_name=sp.TString, value=sp.TNat - ) - mint_args_type_entry_point = sp.contract(mint_args_type, self.data.bts_core, "mint").open_some() - mint_args = sp.record( - to=parsed_to, coin_name=assets[i].coin_name, value=assets[i].value - ) - sp.transfer(mint_args, sp.tez(0), mint_args_type_entry_point) - - def send_response_message(self, service_type, service_type_val, to, sn, msg, code): """ @@ -600,7 +544,6 @@ def check_transfer_restrictions(self, params): sp.result(False) - sp.add_compilation_target("bts_periphery", BTPPreiphery(bmc_address=sp.address("KT1UrLqhQHDC3mJw9BUrqsiix7JRbxTsvWJu"), bts_core_address=sp.address("KT1JAippuMfS6Bso8DGmigmTdkgEZUxQxYyX"), helper_contract=sp.address("KT1HwFJmndBWRn3CLbvhUjdupfEomdykL5a6"), From 4e233d3d439a960fa86e9da0a201479c1344e83b Mon Sep 17 00:00:00 2001 From: simusud Date: Tue, 13 Jun 2023 15:22:35 +0545 Subject: [PATCH 093/211] fix(bmc): added default value while reading value from map --- smartpy/bmc/contracts/src/bmc_management.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/smartpy/bmc/contracts/src/bmc_management.py b/smartpy/bmc/contracts/src/bmc_management.py index 830fdef4..08a07478 100644 --- a/smartpy/bmc/contracts/src/bmc_management.py +++ b/smartpy/bmc/contracts/src/bmc_management.py @@ -591,16 +591,16 @@ def update_relay_stats(self, relay, block_count_val, msg_count_val): def resolve_route(self, dst_net): sp.set_type(dst_net, sp.TString) - dst = sp.local("dst", self.data.get_route_dst_from_net.get(dst_net), t=sp.TString) + dst = sp.local("dst", self.data.get_route_dst_from_net.get(dst_net, default_value=sp.string("")), t=sp.TString) with sp.if_(sp.len(sp.pack(dst.value))!= sp.nat(0)): sp.result(sp.pair(self.data.routes.get(dst.value), dst.value)) with sp.else_(): - dst_link = sp.local("dst_link", self.data.get_link_from_net.get(dst_net), t=sp.TString) + dst_link = sp.local("dst_link", self.data.get_link_from_net.get(dst_net, default_value=sp.string("")), t=sp.TString) with sp.if_(sp.len(sp.pack(dst_link.value)) != sp.nat(0)): sp.result(sp.pair(dst_link.value, dst_link.value)) with sp.else_(): - res = sp.local("res", self.data.get_link_from_reachable_net.get(dst_net), t=types.Types.Tuple) + res = sp.local("res", self.data.get_link_from_reachable_net.get(dst_net, default_value=sp.record(prev="", to="")), t=types.Types.Tuple) # sp.verify(sp.len(sp.pack(res.value.to)) > sp.nat(0), "Unreachable: " + dst_net + " is unreachable") with sp.if_(sp.len(sp.pack(res.value.to)) > sp.nat(0)): sp.result(sp.pair(res.value.prev, res.value.to)) From 1dac42983fd585d3bfa05a5fe3b5fff4e83ea3e1 Mon Sep 17 00:00:00 2001 From: simusud Date: Tue, 13 Jun 2023 15:23:55 +0545 Subject: [PATCH 094/211] fix(bts): fixes in reclaim and mint functions --- smartpy/bts/contracts/src/bts_core.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/smartpy/bts/contracts/src/bts_core.py b/smartpy/bts/contracts/src/bts_core.py index 6cb563ac..4c57e9b5 100644 --- a/smartpy/bts/contracts/src/bts_core.py +++ b/smartpy/bts/contracts/src/bts_core.py @@ -498,9 +498,12 @@ def reclaim(self, coin_name, value): sp.set_type(coin_name, sp.TString) sp.set_type(value, sp.TNat) - sp.verify(self.data.balances[sp.record(address=sp.sender,coin_name=coin_name)].refundable_balance >= value, message="Imbalance") - self.data.balances[sp.record(address=sp.sender,coin_name=coin_name)].refundable_balance = sp.as_nat(self.data.balances[sp.record(address=sp.sender,coin_name=coin_name)].refundable_balance - value) - self.refund(sp.sender, coin_name, value) + with sp.if_(self.data.balances.contains(sp.record(address=sp.sender,coin_name=coin_name))): + sp.verify(self.data.balances[sp.record(address=sp.sender,coin_name=coin_name)].refundable_balance >= value, message="Imbalance") + self.data.balances[sp.record(address=sp.sender,coin_name=coin_name)].refundable_balance = sp.as_nat(self.data.balances[sp.record(address=sp.sender,coin_name=coin_name)].refundable_balance - value) + self.refund(sp.sender, coin_name, value) + with sp.else_(): + sp.failwith("NoRefundableBalance") def refund(self, to, coin_name, value): """ @@ -571,7 +574,7 @@ def mint(self, to, coin_name, value, callback): to_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout(("to_", ("token_id", "amount")))) ).layout(("from_", "txs"))) transfer_entry_point = sp.contract(transfer_args_type, self.data.coins[coin_name], "transfer").open_some() - transfer_args = [sp.record(from_=sp.sender, txs=[sp.record(to_=to, token_id=sp.nat(0), amount=value)])] + transfer_args = [sp.record(from_=sp.self_address, txs=[sp.record(to_=to, token_id=sp.nat(0), amount=value)])] sp.transfer(transfer_args, sp.tez(0), transfer_entry_point) sp.transfer(sp.some("success"), sp.tez(0), callback) From 4cb8e77c9ba469c9bde8e6677d51fa47756d78f0 Mon Sep 17 00:00:00 2001 From: simusud Date: Tue, 13 Jun 2023 16:56:26 +0545 Subject: [PATCH 095/211] fix(bts): fixes bts_core.py file size issue by removing some onchain views --- smartpy/bts/contracts/src/bts_core.py | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/smartpy/bts/contracts/src/bts_core.py b/smartpy/bts/contracts/src/bts_core.py index 4c57e9b5..d80ee508 100644 --- a/smartpy/bts/contracts/src/bts_core.py +++ b/smartpy/bts/contracts/src/bts_core.py @@ -22,8 +22,6 @@ class BTSCore(sp.Contract): # Nat:(TWO.pow256 - 1) UINT_CAP = sp.nat(115792089237316195423570985008687907853269984665640564039457584007913129639935) - # TODO: change the native coin addr - def __init__(self, _native_coin_name, _fee_numerator, _fixed_fee, owner_manager): self.update_initial_storage( bts_owner_manager=owner_manager, @@ -56,14 +54,6 @@ def only_owner(self): def only_bts_periphery(self): sp.verify(sp.sender == self.data.bts_periphery_address.open_some("Address not set"), "Unauthorized") - @sp.onchain_view() - def get_native_coin_name(self): - """ - Get name of nativecoin - :return: Name of nativecoin - """ - sp.result(self.data.native_coin_name) - @sp.entry_point def update_bts_periphery(self, bts_periphery): """ @@ -165,14 +155,6 @@ def register(self, name, fee_numerator, fixed_fee, addr, token_metadata, metadat set_token_limit_args = sp.record(coin_names=token_map, token_limit=val_map) sp.transfer(set_token_limit_args, sp.tez(0), set_token_limit_entry_point) - @sp.onchain_view() - def coin_names(self): - """ - Return all supported coins names - :return: An array of strings. - """ - sp.result(self.data.coins_name) - @sp.onchain_view() def coin_id(self, coin_name): """ @@ -314,7 +296,6 @@ def transfer_native_coin(self, to): sp.verify(check_transfer == True, "FailCheckTransfer") charge_amt = amount_in_nat.value * self.data.coin_details[self.data.native_coin_name].fee_numerator / self.FEE_DENOMINATOR + self.data.coin_details[self.data.native_coin_name].fixed_fee - #Confirm the type for this calculation self._send_service_message(sp.sender, to, self.data.native_coin_name, amount_in_nat.value, charge_amt) @@ -424,7 +405,6 @@ def transfer_batch(self, coin_names, values, to): amounts = sp.local("_amounts", {}, t=sp.TMap(sp.TNat, sp.TNat)) charge_amts = sp.local("_charge_amts", {}, t=sp.TMap(sp.TNat, sp.TNat)) - # coin = sp.TRecord(addr=sp.TAddress, fee_numerator=sp.TNat, fixed_fee=sp.TNat, coin_type=sp.TNat) coin_name = sp.local("coin_name", "", t= sp.TString) value = sp.local("value", sp.nat(0), t= sp.TNat) @@ -507,7 +487,6 @@ def reclaim(self, coin_name, value): def refund(self, to, coin_name, value): """ - :param to: :param coin_name: :param value: @@ -545,7 +524,6 @@ def update_mint(self, ep): def mint(self, to, coin_name, value, callback): """ mint the wrapped coin. - :param to: the account receive the minted coin :param coin_name: coin name :param value: the minted amount @@ -576,7 +554,6 @@ def mint(self, to, coin_name, value, callback): transfer_entry_point = sp.contract(transfer_args_type, self.data.coins[coin_name], "transfer").open_some() transfer_args = [sp.record(from_=sp.self_address, txs=[sp.record(to_=to, token_id=sp.nat(0), amount=value)])] sp.transfer(transfer_args, sp.tez(0), transfer_entry_point) - sp.transfer(sp.some("success"), sp.tez(0), callback) @sp.entry_point From 0f969ab12fde7226d41176b1bca87c0fd4536a87 Mon Sep 17 00:00:00 2001 From: simusud Date: Wed, 14 Jun 2023 13:27:14 +0545 Subject: [PATCH 096/211] fix(bts): fixed variant issue in bts_periphery.py --- smartpy/bts/contracts/src/RLP_struct.py | 8 ++++---- smartpy/bts/contracts/src/Types.py | 6 ++++-- smartpy/bts/contracts/src/bts_periphery.py | 22 ++++++---------------- 3 files changed, 14 insertions(+), 22 deletions(-) diff --git a/smartpy/bts/contracts/src/RLP_struct.py b/smartpy/bts/contracts/src/RLP_struct.py index 67a83f6a..9179d67c 100644 --- a/smartpy/bts/contracts/src/RLP_struct.py +++ b/smartpy/bts/contracts/src/RLP_struct.py @@ -70,7 +70,7 @@ def decode_service_message(self, rlp): temp_byt.value = i.value counter.value = counter.value + 1 - _service_type = sp.local("_service_type", sp.variant("ERROR", 10)) + _service_type = sp.local("_service_type", sp.variant("ERROR", sp.nat(10))) sp.if temp_int.value == 0: _service_type.value = sp.variant("REQUEST_COIN_TRANSFER", temp_int.value) sp.if temp_int.value == 1: @@ -186,7 +186,7 @@ def decode_blacklist_msg(self, rlp): temp_byt = sp.local("byt_transfer", sp.bytes("0x")) rv1_byt = sp.local("rv1_byt", sp.bytes("0x")) rv2_byt = sp.local("rv2_byt", sp.bytes("0x")) - counter = sp.local("counter_blacklist", 0) + counter = sp.local("counter_blacklist", sp.nat(0)) sp.for i in rlp_.items(): sp.if counter.value == 2: rv2_byt.value = i.value @@ -235,7 +235,7 @@ def decode_blacklist_msg(self, rlp): t=sp.TBytes).open_some() rv1 = Utils2.Int.of_bytes(rv1_byt.value) rv2 = sp.view("decode_string", self.data.helper, rv2_byt.value, t=sp.TString).open_some() - _service_type = sp.local("_service_type_blacklist", sp.variant("ERROR", 10)) + _service_type = sp.local("_service_type_blacklist", sp.variant("ERROR", sp.nat(10))) with sp.if_(rv1 == 0): _service_type.value = sp.variant("ADD_TO_BLACKLIST", rv1) with sp.else_(): @@ -260,7 +260,7 @@ def decode_token_limit_msg(self, rlp): temp_byt = sp.local("byt_transfer", sp.bytes("0x")) temp_byt1 = sp.local("byt_transfer_temp1", sp.bytes("0x")) rv1_byt = sp.local("rv1_byt", sp.bytes("0x")) - counter = sp.local("counter_token_limit", 0) + counter = sp.local("counter_token_limit", sp.nat(0)) sp.for i in rlp_.items(): sp.if counter.value == 0: temp_byt.value = i.value diff --git a/smartpy/bts/contracts/src/Types.py b/smartpy/bts/contracts/src/Types.py index dfba1591..6c127186 100644 --- a/smartpy/bts/contracts/src/Types.py +++ b/smartpy/bts/contracts/src/Types.py @@ -25,12 +25,14 @@ class Types: RESPONSE_HANDLE_SERVICE=sp.TNat, BLACKLIST_MESSAGE=sp.TNat, CHANGE_TOKEN_LIMIT=sp.TNat, - UNKNOWN_TYPE=sp.TNat + UNKNOWN_TYPE=sp.TNat, + ERROR=sp.TNat ) BlacklistService = sp.TVariant( ADD_TO_BLACKLIST=sp.TNat, - REMOVE_FROM_BLACKLIST=sp.TNat + REMOVE_FROM_BLACKLIST=sp.TNat, + ERROR=sp.TNat ) ServiceMessage = sp.TRecord( diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index d23bcbf3..6ce5f560 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -256,10 +256,8 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, bsh_addr, prev, call err_msg = sp.local("error", "") sm = sp.view("decode_service_message", self.data.rlp_contract, msg, t=types.Types.ServiceMessage).open_some() - service_type_variant_match = sp.local("serviceType_variant", False, t=sp.TBool) with sm.serviceType.match_cases() as arg: with arg.match("REQUEST_COIN_TRANSFER") as a1: - service_type_variant_match.value = True callback_string.value = "success" tc = sp.view("decode_transfer_coin_msg", self.data.rlp_contract, sm.data, t=types.Types.TransferCoin).open_some() parsed_addr = sp.view("str_to_addr", self.data.parse_contract, tc.to, t=sp.TAddress).open_some() @@ -278,16 +276,12 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, bsh_addr, prev, call self.send_response_message(sp.variant("RESPONSE_HANDLE_SERVICE", 2), sp.nat(2), _from, sn, err_msg.value, self.RC_ERR) with arg.match("BLACKLIST_MESSAGE") as a2: - service_type_variant_match.value = True callback_string.value = "success" bm = sp.view("decode_blacklist_msg", self.data.rlp_contract, sm.data, t=types.Types.BlacklistMessage).open_some() addresses = bm.addrs - blacklist_service_called = sp.local("blacklist_service", False, t=sp.TBool) with bm.serviceType.match_cases() as b_agr: with b_agr.match("ADD_TO_BLACKLIST") as b_val_1: - blacklist_service_called.value = True - add_blacklist_call = self._add_to_blacklist(addresses) with sp.if_(add_blacklist_call == "success"): self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, sn, "AddedToBlacklist", self.RC_OK) @@ -295,19 +289,16 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, bsh_addr, prev, call self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, sn, "ErrorAddToBlackList", self.RC_ERR) with b_agr.match("REMOVE_FROM_BLACKLIST") as b_val_2: - blacklist_service_called.value = True - remove_blacklist_call = self._remove_from_blacklist(addresses) with sp.if_(remove_blacklist_call == "success"): self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, sn, "RemovedFromBlacklist", self.RC_OK) with sp.else_(): self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, sn, "ErrorRemoveFromBlackList", self.RC_ERR) - sp.if blacklist_service_called.value == False: - self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, sn, "BlacklistServiceTypeErr", self.RC_ERR) + with b_agr.match("ERROR") as b_val_2: + self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, sn, "BlacklistServiceTypeErr", self.RC_ERR) with arg.match("CHANGE_TOKEN_LIMIT") as a3: - service_type_variant_match.value = True callback_string.value = "success" tl = sp.view("decode_token_limit_msg", self.data.rlp_contract, sm.data, t=types.Types.TokenLimitMessage).open_some() coin_names = tl.coin_name @@ -320,7 +311,6 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, bsh_addr, prev, call self.send_response_message(sp.variant("CHANGE_TOKEN_LIMIT", 4), sp.nat(4), _from, sn, "ErrorChangeTokenLimit", self.RC_ERR) with arg.match("RESPONSE_HANDLE_SERVICE") as a4: - service_type_variant_match.value = True with sp.if_(sp.len(sp.pack(self.data.requests.get(sn).from_)) != 0): response = sp.view("decode_response", self.data.rlp_contract, sm.data, t=types.Types.Response).open_some() handle_response = self.handle_response_service(sn, response.code, response.message) @@ -330,14 +320,14 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, bsh_addr, prev, call callback_string.value = "fail" with sp.else_(): callback_string.value = "InvalidSN" + with arg.match("UNKNOWN_TYPE") as a5: - service_type_variant_match.value = True callback_string.value = "success" sp.emit(sp.record(_from=_from, sn=sn), tag= "UnknownResponse") - sp.if service_type_variant_match.value == False: - callback_string.value = "success" - self.send_response_message(sp.variant("UNKNOWN_TYPE", 5), sp.nat(5), _from, sn, "Unknown",self.RC_ERR) + with arg.match("ERROR") as a5: + callback_string.value = "success" + self.send_response_message(sp.variant("UNKNOWN_TYPE", 5), sp.nat(5), _from, sn, "Unknown",self.RC_ERR) with sp.else_(): callback_string.value = "fail" From ad26a67be474a93cb1381f333918d5327ffe9641 Mon Sep 17 00:00:00 2001 From: simusud Date: Wed, 14 Jun 2023 16:23:43 +0545 Subject: [PATCH 097/211] refactor(bmc): updated rlp contract address --- smartpy/bmc/contracts/src/bmc_management.py | 2 +- smartpy/bmc/contracts/src/bmc_periphery.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/smartpy/bmc/contracts/src/bmc_management.py b/smartpy/bmc/contracts/src/bmc_management.py index 08a07478..88ffa2be 100644 --- a/smartpy/bmc/contracts/src/bmc_management.py +++ b/smartpy/bmc/contracts/src/bmc_management.py @@ -610,4 +610,4 @@ def resolve_route(self, dst_net): sp.add_compilation_target("bmc_management", BMCManagement(owner_address=sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP"), helper_contract=sp.address("KT1HwFJmndBWRn3CLbvhUjdupfEomdykL5a6"), - rlp_contract=sp.address("KT1CC7TVGvvouvPcBe5wK7MYk1y9j7G7VYgz"))) + rlp_contract=sp.address("KT1KmVm99HRaeikmV9myiEh99G1h3cH4Erqn"))) diff --git a/smartpy/bmc/contracts/src/bmc_periphery.py b/smartpy/bmc/contracts/src/bmc_periphery.py index f99834a1..c38fca5d 100644 --- a/smartpy/bmc/contracts/src/bmc_periphery.py +++ b/smartpy/bmc/contracts/src/bmc_periphery.py @@ -440,4 +440,4 @@ def get_status(self, _link): helper_parse_neg_contract=sp.address("KT1DHptHqSovffZ7qqvSM9dy6uZZ8juV88gP"), parse_address=sp.address("KT1XgRyjQPfpfwNrvYYpgERpYpCrGh24aoPX"), owner_address=sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP"), - rlp_contract=sp.address("KT1CC7TVGvvouvPcBe5wK7MYk1y9j7G7VYgz"))) + rlp_contract=sp.address("KT1KmVm99HRaeikmV9myiEh99G1h3cH4Erqn"))) From 364f31714e42ce1e95137c73a33da1b16c31d614 Mon Sep 17 00:00:00 2001 From: simusud Date: Wed, 14 Jun 2023 16:24:08 +0545 Subject: [PATCH 098/211] refactor(bts): updated rlp contract address --- smartpy/bts/contracts/src/bts_periphery.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index 6ce5f560..c7c7f2f5 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -540,4 +540,4 @@ def check_transfer_restrictions(self, params): parse_address=sp.address("KT1EKPrSLWjWViZQogFgbc1QmztkR5UGXEWa"), native_coin_name="btp-NetXnHfVqm9iesp.tezos-XTZ", owner_address = sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP"), - rlp_contract=sp.address("KT1BuF4ZtTK9gTSa7jQa8Byt8TrjKxtbcs26"))) \ No newline at end of file + rlp_contract=sp.address("KT1Sm1Yqg8hNoB1SN7q3krSKZHgQxAyhg9hF"))) \ No newline at end of file From 75f311693d2ae948fec3ab98cb3ed2c3847d6a24 Mon Sep 17 00:00:00 2001 From: simusud Date: Thu, 15 Jun 2023 11:54:17 +0545 Subject: [PATCH 099/211] refactor(bts): changed record key name in RLP_struct.py --- smartpy/bts/contracts/src/RLP_struct.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smartpy/bts/contracts/src/RLP_struct.py b/smartpy/bts/contracts/src/RLP_struct.py index 9179d67c..337a7ae0 100644 --- a/smartpy/bts/contracts/src/RLP_struct.py +++ b/smartpy/bts/contracts/src/RLP_struct.py @@ -166,7 +166,7 @@ def decode_transfer_coin_msg(self, rlp): rv1 = sp.view("decode_string", self.data.helper, rv1_byt.value, t=sp.TString).open_some() rv2 = sp.view("decode_string", self.data.helper, rv2_byt.value, t=sp.TString).open_some() - sp.result(sp.record(from_= rv1, to = rv2 , assets = rv_assets.value)) + sp.result(sp.record(from_addr= rv1, to = rv2 , assets = rv_assets.value)) @sp.onchain_view() From d5f28c91a15796972aadc47a5efd949b90be7509 Mon Sep 17 00:00:00 2001 From: simusud Date: Thu, 15 Jun 2023 11:58:38 +0545 Subject: [PATCH 100/211] refactor(bts): updated rlp contract address in bts_periphery.py --- smartpy/bts/contracts/src/bts_periphery.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index c7c7f2f5..ca7f660a 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -540,4 +540,4 @@ def check_transfer_restrictions(self, params): parse_address=sp.address("KT1EKPrSLWjWViZQogFgbc1QmztkR5UGXEWa"), native_coin_name="btp-NetXnHfVqm9iesp.tezos-XTZ", owner_address = sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP"), - rlp_contract=sp.address("KT1Sm1Yqg8hNoB1SN7q3krSKZHgQxAyhg9hF"))) \ No newline at end of file + rlp_contract=sp.address("KT19Q5aWgR79HcZKWJwQDJ6TXbdxARMdj4Vv"))) \ No newline at end of file From 15e6ee5c50fc059d96ae16b4542423e8f4899e43 Mon Sep 17 00:00:00 2001 From: simusud Date: Thu, 15 Jun 2023 14:56:38 +0545 Subject: [PATCH 101/211] fix(bmc): decode_response fixed in case of error tx --- smartpy/bmc/contracts/src/RLP_struct.py | 3 ++- smartpy/bmc/contracts/src/bmc_periphery.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/smartpy/bmc/contracts/src/RLP_struct.py b/smartpy/bmc/contracts/src/RLP_struct.py index 5886c85c..2f610d3f 100644 --- a/smartpy/bmc/contracts/src/RLP_struct.py +++ b/smartpy/bmc/contracts/src/RLP_struct.py @@ -73,7 +73,8 @@ def decode_response(self, rlp): temp_byt.value = m.value counter.value = counter.value + 1 - sp.result(sp.record(code=temp_int.value, message=sp.view("decode_string", self.data.helper, temp_byt.value, t=sp.TString).open_some())) + # message in case of error is null which cannot be decoded into string + sp.result(sp.record(code=temp_int.value, message="Error")) @sp.onchain_view() def decode_propagate_message(self, rlp): diff --git a/smartpy/bmc/contracts/src/bmc_periphery.py b/smartpy/bmc/contracts/src/bmc_periphery.py index c38fca5d..d418ab49 100644 --- a/smartpy/bmc/contracts/src/bmc_periphery.py +++ b/smartpy/bmc/contracts/src/bmc_periphery.py @@ -352,7 +352,7 @@ def _handle_message(self, prev, msg): t = sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress, svc=sp.TString, sn=sp.TInt, code=sp.TNat, msg=sp.TString) callback = sp.contract(t, sp.self_address, "callback_btp_error") handle_btp_error_args = sp.record(callback=callback.open_some(), bsh_addr=bsh_addr, - svc=msg.svc, sn=msg.sn * -1, code=res.code, msg="error") + svc=msg.svc, sn=msg.sn * -1, code=res.code, msg=res.message) sp.transfer(handle_btp_error_args, sp.tez(0), handle_btp_error_entry_point) def _send_message(self, to ,serialized_msg): From fa10f8ae6f01136a19f878178cef8b07cd2d40d5 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Mon, 19 Jun 2023 09:32:55 +0545 Subject: [PATCH 102/211] feat: added GetBMCManagement() for getting bmc_management address --- cmd/iconbridge/chain/tezos/client.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/cmd/iconbridge/chain/tezos/client.go b/cmd/iconbridge/chain/tezos/client.go index 7414bb65..dc98df60 100644 --- a/cmd/iconbridge/chain/tezos/client.go +++ b/cmd/iconbridge/chain/tezos/client.go @@ -282,6 +282,15 @@ func (c *Client) GetBalance(ctx context.Context, connection *rpc.Client, account return balance.Big(), nil } +func (c *Client) GetBMCManangement(ctx context.Context, contr *contract.Contract, account tezos.Address) (string, error){ + fmt.Println("reached in getting bmc Management") + result, err := contr.RunView(ctx, "get_bmc_periphery", micheline.Prim{}) + if err != nil { + return "", err + } + return result.String, nil +} + func (c *Client) GetStatus(ctx context.Context, contr *contract.Contract, link string) (TypesLinkStats, error) { fmt.Println("reached in get status of tezos") From e85ba7a93c497d913fb16d3e14ce7b95bb4e0b73 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Mon, 19 Jun 2023 09:33:52 +0545 Subject: [PATCH 103/211] feat: tezos wallet creation script --- devnet/docker/icon-tezos/scripts/config.sh | 8 +++---- devnet/docker/icon-tezos/scripts/keystore.sh | 22 +++++++++++++++++++- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/devnet/docker/icon-tezos/scripts/config.sh b/devnet/docker/icon-tezos/scripts/config.sh index 72f5d650..918841b4 100644 --- a/devnet/docker/icon-tezos/scripts/config.sh +++ b/devnet/docker/icon-tezos/scripts/config.sh @@ -50,10 +50,10 @@ export TZ_NATIVE_TOKEN_NAME=("btp-$TZ_BMC_NET-BUSD" "btp-$TZ_BMC_NET-USDT" "btp- export TZ_WRAPPED_COIN_SYM=("ICX" "sICX" "bnUSD" "ICZ") export TZ_WRAPPED_COIN_NAME=("btp-$ICON_BMC_NET-ICX" "btp-$ICON_BMC_NET-sICX" "btp-$ICON_BMC_NET-bnUSD" "btp-$SNOW_BMC_NET-ICZ") -export TZ_NATIVE_COIN_FIXED_FEE=(450) -export TZ_NATIVE_COIN_FEE_NUMERATOR=(100) +export TZ_NATIVE_COIN_FIXED_FEE=(0) +export TZ_NATIVE_COIN_FEE_NUMERATOR=(0) export TZ_NATIVE_COIN_DECIMALS=(6) -export TZ_NATIVE_TOKEN_FIXED_FEE=(450 1500000000000000000 1500000000000000000 62500000000000 750000000000000) +export TZ_NATIVE_TOKEN_FIXED_FEE=(0 1500000000000000000 1500000000000000000 62500000000000 750000000000000) export TZ_NATIVE_TOKEN_FEE_NUMERATOR=(100 100 100 100 100) export TZ_NATIVE_TOKEN_DECIMALS=(18 18 18 18 18) export TZ_WRAPPED_COIN_FIXED_FEE=(4300000000000000000 3900000000000000000 1500000000000000000 4300000000000000000) @@ -71,6 +71,6 @@ export GOLOOP_RPC_URI=$ICON_ENDPOINT export GOLOOP_RPC_KEY_STORE=$ICON_KEY_STORE export GOLOOP_RPC_KEY_SECRET=$ICON_SECRET -export TZ_RPC_URI=$BSC_ENDPOINT +export TZ_RPC_URI=$TZ_ENDPOINT export TZ_KEY_STORE=$ICONBRIDGE_CONFIG_DIR/keystore/tz.god.wallet.json # export BSC_SECRET=$ICONBRIDGE_CONFIG_DIR/keystore/bsc.god.wallet.secret diff --git a/devnet/docker/icon-tezos/scripts/keystore.sh b/devnet/docker/icon-tezos/scripts/keystore.sh index 8f2b8659..a9dd6e38 100644 --- a/devnet/docker/icon-tezos/scripts/keystore.sh +++ b/devnet/docker/icon-tezos/scripts/keystore.sh @@ -1,4 +1,5 @@ #!/bin/bash +source config.sh ensure_key_secret() { if [ $# -lt 1 ] ; then @@ -52,6 +53,21 @@ ensure_bsc_key_store() { echo ${KEY_STORE_PATH} } +ensure_tezos_address() { + echo ensuring tezos address + local KEY_STORE=$1 + local wallet=$(echo $(octez-client list known addresses | grep $KEY_STORE)) + wallet=${wallet%:*} + ensure_key_secret $CONFIG_DIR/keystore/$wallet + if [ $wallet ]; then + echo found so deleting + octez-client forget address $wallet --force + fi + octez-client gen keys $KEY_STORE + wallet_info=$(echo $(octez-client show address $KEY_STORE -S)) + echo $wallet_info > $CONFIG_DIR/keystore/$KEY_STORE +} + ensure_empty_key_secret() { if [ $# -lt 1 ] ; then echo "Usage: ensure_key_secret SECRET_PATH" @@ -63,4 +79,8 @@ ensure_empty_key_secret() { echo -n '' > ${KEY_SECRET} fi echo ${KEY_SECRET} -} \ No newline at end of file +} + +ensure_tezos_address bmcOwner +ensure_tezos_address bmrOwner +ensure_tezos_address btsOwner \ No newline at end of file From 5bad7c4f5e6fd98e09841da0c3405a2780a46aa4 Mon Sep 17 00:00:00 2001 From: simusud Date: Mon, 19 Jun 2023 11:34:21 +0545 Subject: [PATCH 104/211] refactor(bmc): rlp_contract address update --- smartpy/bmc/contracts/src/bmc_management.py | 2 +- smartpy/bmc/contracts/src/bmc_periphery.py | 46 ++------------------- 2 files changed, 4 insertions(+), 44 deletions(-) diff --git a/smartpy/bmc/contracts/src/bmc_management.py b/smartpy/bmc/contracts/src/bmc_management.py index 88ffa2be..4a4b2134 100644 --- a/smartpy/bmc/contracts/src/bmc_management.py +++ b/smartpy/bmc/contracts/src/bmc_management.py @@ -610,4 +610,4 @@ def resolve_route(self, dst_net): sp.add_compilation_target("bmc_management", BMCManagement(owner_address=sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP"), helper_contract=sp.address("KT1HwFJmndBWRn3CLbvhUjdupfEomdykL5a6"), - rlp_contract=sp.address("KT1KmVm99HRaeikmV9myiEh99G1h3cH4Erqn"))) + rlp_contract=sp.address("KT1A4Ad5jTHaz1W7TvTbqKoBtRa2DnnXbFBn"))) diff --git a/smartpy/bmc/contracts/src/bmc_periphery.py b/smartpy/bmc/contracts/src/bmc_periphery.py index d418ab49..a46035b4 100644 --- a/smartpy/bmc/contracts/src/bmc_periphery.py +++ b/smartpy/bmc/contracts/src/bmc_periphery.py @@ -247,10 +247,10 @@ def _handle_message(self, prev, msg): self._send_error(prev, msg, self.BMC_ERR, self.BMCRevertParseFailure) with sp.else_(): sp.if sm.value.serviceType == "FeeGathering": - gather_fee =sp.local("gather_fee", sp.record(fa="", svcs=sp.map({0:""}))) + gather_fee =sp.local("gather_fee", sp.record(fa="error", svcs=sp.map({0:""}))) gather_fee.value = sp.view("decode_gather_fee_message", self.data.rlp_contract, sm.value.payload, t=types.Types.GatherFeeMessage).open_some() - with sp.if_(gather_fee.value.fa == ""): + with sp.if_(gather_fee.value.fa == "error"): self._send_error(prev, msg, self.BMC_ERR, self.BMCRevertParseFailure) with sp.else_(): @@ -268,46 +268,6 @@ def _handle_message(self, prev, msg): handle_fee_gathering_args = sp.record(callback=callback.open_some(), bsh_addr=bsh_addr, fa=gather_fee.value.fa, svc=gather_fee.value.svcs[c]) sp.transfer(handle_fee_gathering_args, sp.tez(0), handle_fee_gathering_entry_point) - sp.if sm.value.serviceType == "Link": - to= sp.view("decode_propagate_message", self.data.rlp_contract, sm.value.payload, t=sp.TString).open_some() - link = sp.view("get_link", self.data.bmc_management, prev, t=types.Types.Link).open_some() - - check = sp.local("check", False) - sp.if link.is_connected: - sp.for e in link.reachable.elements(): - sp.if check.value == False: - sp.if to == e: - check.value = True - - sp.if check.value == False: - links = sp.list([to], t=sp.TString) - - # call update_link_reachable on BMCManagement - update_link_reachable_args_type = sp.TRecord(prev=sp.TString, to=sp.TList(sp.TString)) - update_link_reachable_entry_point = sp.contract(update_link_reachable_args_type, - self.data.bmc_management, - "update_link_reachable").open_some() - update_link_reachable_args = sp.record(prev=prev, to=links) - sp.transfer(update_link_reachable_args, sp.tez(0), update_link_reachable_entry_point) - - sp.if sm.value.serviceType == "Unlink": - to = sp.view("decode_propagate_message", self.data.rlp_contract, sm.value.payload, t=sp.TString).open_some() - link = sp.view("get_link", self.data.bmc_management, prev, t=types.Types.Link).open_some() - - sp.if link.is_connected: - f = sp.local("f", sp.nat(0)) - sp.for itm in link.reachable.elements(): - sp.if to == itm: - - # call delete_link_reachable on BMCManagement - delete_link_reachable_args_type = sp.TRecord(prev=sp.TString, index=sp.TNat) - delete_link_reachable_entry_point = sp.contract(delete_link_reachable_args_type, - self.data.bmc_management, - "delete_link_reachable").open_some() - delete_link_reachable_args = sp.record(prev=prev, index=f.value) - sp.transfer(delete_link_reachable_args, sp.tez(0), delete_link_reachable_entry_point) - f.value += sp.nat(1) - sp.if sm.value.serviceType == "Init": links = sp.view("decode_init_message", self.data.rlp_contract, sm.value.payload, t=sp.TList(sp.TString)).open_some() # call update_link_reachable on BMCManagement @@ -440,4 +400,4 @@ def get_status(self, _link): helper_parse_neg_contract=sp.address("KT1DHptHqSovffZ7qqvSM9dy6uZZ8juV88gP"), parse_address=sp.address("KT1XgRyjQPfpfwNrvYYpgERpYpCrGh24aoPX"), owner_address=sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP"), - rlp_contract=sp.address("KT1KmVm99HRaeikmV9myiEh99G1h3cH4Erqn"))) + rlp_contract=sp.address("KT1A4Ad5jTHaz1W7TvTbqKoBtRa2DnnXbFBn"))) From 703848d6fcba5f114d471525b3909bf8803cdb94 Mon Sep 17 00:00:00 2001 From: simusud Date: Mon, 19 Jun 2023 11:40:10 +0545 Subject: [PATCH 105/211] fix(bts): removed callback from transfer in bts_core.py and checked tx validity in bts_periphery.py --- smartpy/bts/contracts/src/FA2_contract.py | 44 ++++----------- smartpy/bts/contracts/src/bts_core.py | 66 ++++++++++------------ smartpy/bts/contracts/src/bts_periphery.py | 42 +++++++------- 3 files changed, 64 insertions(+), 88 deletions(-) diff --git a/smartpy/bts/contracts/src/FA2_contract.py b/smartpy/bts/contracts/src/FA2_contract.py index db8dfb09..fbdcff60 100644 --- a/smartpy/bts/contracts/src/FA2_contract.py +++ b/smartpy/bts/contracts/src/FA2_contract.py @@ -52,38 +52,18 @@ def get_allowance(self, allowance): sp.set_type(allowance, sp.TRecord(spender=sp.TAddress, owner=sp.TAddress)) sp.result(self.data.allowances.get(allowance, default_value=0)) - @sp.entry_point - def transfer_bts(self, batch): - """Accept a list of transfer operations between a source and multiple - destinations. - Custom version with allowance system with callback implementation. - - `transfer_tx_` must be defined in the child class. - """ - sp.set_type(batch, t_transfer_params) - - if self.policy.supports_transfer: - with sp.for_("transfer", batch) as transfer: - with sp.for_("tx", transfer.txs) as tx: - # The ordering of sp.verify is important: 1) token_undefined, 2) transfer permission 3) balance - sp.verify(self.is_defined(tx.token_id), "FA2_TOKEN_UNDEFINED") - self.policy.check_tx_transfer_permissions( - self, transfer.from_, tx.to_, tx.token_id - ) - with sp.if_(sp.sender != transfer.from_): - self.update_allowance_(sp.sender, transfer.from_, tx.token_id, tx.amount) - with sp.if_(tx.amount > 0): - self.transfer_tx_(transfer.from_, tx) - - return_value = sp.record(string=sp.some("success"), requester=tx.to_, - coin_name=transfer.coin_name, value=tx.amount) - sp.transfer(return_value, sp.tez(0), transfer.callback) - else: - with sp.for_("transfer", batch) as transfer: - with sp.for_("tx", transfer.txs) as tx: - return_value = sp.record(string=sp.some("FA2_TX_DENIED"), requester=tx.to_, - coin_name=transfer.coin_name, value=tx.amount) - sp.transfer(return_value, sp.tez(0), transfer.callback) + @sp.onchain_view() + def transfer_permissions(self, params): + sp.set_type(params, sp.TRecord(from_=sp.TAddress, token_id=sp.TNat)) + + with sp.if_((self.policy.supports_transfer) & (self.is_defined(params.token_id))): + with sp.if_((sp.sender == params.from_) | (self.data.operators.contains( + sp.record(owner=params.from_, operator=sp.sender, token_id=params.token_id)))): + sp.result(True) + with sp.else_(): + sp.result(False) + with sp.else_(): + sp.result(False) @sp.entry_point def transfer(self, batch): diff --git a/smartpy/bts/contracts/src/bts_core.py b/smartpy/bts/contracts/src/bts_core.py index d80ee508..1bd02b8e 100644 --- a/smartpy/bts/contracts/src/bts_core.py +++ b/smartpy/bts/contracts/src/bts_core.py @@ -42,8 +42,7 @@ def __init__(self, _native_coin_name, _fee_numerator, _fixed_fee, owner_manager) fixed_fee=_fixed_fee, coin_type=self.NATIVE_COIN_TYPE)}, tkey=sp.TString, tvalue=Coin), - coins_address=sp.map({}, tkey=sp.TAddress, tvalue=sp.TString), - transfer_status=sp.none + coins_address=sp.map({}, tkey=sp.TAddress, tvalue=sp.TString) ) def only_owner(self): @@ -556,25 +555,6 @@ def mint(self, to, coin_name, value, callback): sp.transfer(transfer_args, sp.tez(0), transfer_entry_point) sp.transfer(sp.some("success"), sp.tez(0), callback) - @sp.entry_point - def transfer_callback(self, string, requester, coin_name, value): - sp.set_type(string, sp.TOption(sp.TString)) - sp.set_type(requester, sp.TAddress) - sp.set_type(coin_name, sp.TString) - sp.set_type(value, sp.TNat) - - sp.verify(sp.sender == self.data.coins[coin_name], "Unauthorized") - self.data.transfer_status = string - - with sp.if_(self.data.transfer_status.open_some() == "success"): - pass - with sp.else_(): - self.data.balances[sp.record(address=requester, coin_name=coin_name)].refundable_balance = \ - self.data.balances.get(sp.record(address=requester, coin_name=coin_name), - default_value=sp.record(locked_balance=sp.nat(0),refundable_balance=sp.nat(0)) - ).refundable_balance + value - self.data.transfer_status = sp.none - @sp.entry_point(lazify=False) def update_handle_response_service(self, ep): self.only_owner() @@ -621,20 +601,36 @@ def handle_response_service(self, requester, coin_name, value, fee, rsp_code): sp.record(address=requester, coin_name=coin_name), default_value=sp.record(locked_balance=sp.nat(0), refundable_balance=sp.nat(0))).refundable_balance + value with sp.else_(): - # call transfer in FA2 - transfer_args_type = sp.TList(sp.TRecord( - callback=sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), requester=sp.TAddress, coin_name=sp.TString, value=sp.TNat)), - from_=sp.TAddress, - coin_name=sp.TString, - txs=sp.TList(sp.TRecord(to_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout(("to_", ("token_id", "amount")))) - ).layout((("from_", "coin_name"), ("callback", "txs")))) - transfer_entry_point = sp.contract(transfer_args_type, self.data.coins[coin_name], - "transfer_bts").open_some() - t = sp.TRecord(string=sp.TOption(sp.TString), requester=sp.TAddress, coin_name=sp.TString, value=sp.TNat) - callback = sp.contract(t, sp.self_address, "transfer_callback") - transfer_args = [ - sp.record(callback=callback.open_some(), from_=sp.self_address, coin_name=coin_name, txs=[sp.record(to_=requester, token_id=sp.nat(0), amount=value)])] - sp.transfer(transfer_args, sp.tez(0), transfer_entry_point) + with sp.if_(self.data.coin_details[coin_name].coin_type == self.NON_NATIVE_TOKEN_TYPE): + # call transfer in NON_NATIVE_TOKEN_TYPE FA2 + transfer_args_type = sp.TList(sp.TRecord(from_=sp.TAddress, txs=sp.TList(sp.TRecord( + to_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout(("to_", ("token_id", "amount")))) + ).layout(("from_", "txs"))) + transfer_entry_point = sp.contract(transfer_args_type, self.data.coins[coin_name], "transfer").open_some() + transfer_args = [sp.record(from_=sp.self_address, txs=[ + sp.record(to_=requester, token_id=sp.nat(0), amount=value)])] + sp.transfer(transfer_args, sp.tez(0), transfer_entry_point) + with sp.else_(): + _fa2_address = self.data.coins[coin_name] + transfer_permissions = sp.view("transfer_permissions", _fa2_address, sp.record( + from_=sp.self_address, token_id=sp.nat(0)), t=sp.TBool).open_some() + + with sp.if_(transfer_permissions): + # call transfer in NATIVE_WRAPPED_COIN_TYPE FA2 + transfer_args_type = sp.TList(sp.TRecord( + from_=sp.TAddress, + txs=sp.TList(sp.TRecord(to_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout(("to_", ("token_id", "amount")))) + ).layout(("from_", "txs"))) + transfer_entry_point = sp.contract(transfer_args_type, _fa2_address, "transfer").open_some() + transfer_args = [ + sp.record(from_=sp.self_address, txs=[sp.record(to_=requester, token_id=sp.nat(0), amount=value)])] + sp.transfer(transfer_args, sp.tez(0), transfer_entry_point) + with sp.else_(): + self.data.balances[sp.record(address=requester, coin_name=coin_name)].refundable_balance = \ + self.data.balances.get(sp.record(address=requester, coin_name=coin_name), + default_value=sp.record(locked_balance=sp.nat(0), + refundable_balance=sp.nat(0)) + ).refundable_balance + value sp.if rsp_code == self.RC_OK: fa2_address = self.data.coins[coin_name] diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index ca7f660a..2d0a0adc 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -432,31 +432,31 @@ def _handle_request_service(self, to, assets): sp.set_type(assets, sp.TMap(sp.TNat, types.Types.Asset)) status = sp.local("status", "error") + check_validity = sp.local("check_validity", False) with sp.if_(sp.len(assets) <= self.MAX_BATCH_SIZE): parsed_to = sp.view("str_to_addr", self.data.parse_contract, to, t=sp.TAddress).open_some() sp.for i in sp.range(0, sp.len(assets)): valid_coin = sp.view("is_valid_coin", self.data.bts_core, assets[i].coin_name, t=sp.TBool).open_some() - - with sp.if_(valid_coin == True): - check_transfer = sp.view("check_transfer_restrictions", sp.self_address, sp.record( - coin_name=assets[i].coin_name, user=parsed_to, value=assets[i].value), t=sp.TBool).open_some() - with sp.if_(check_transfer == True): - # inter score call - mint_args_type = sp.TRecord(callback=sp.TContract(sp.TOption(sp.TString)), - to=sp.TAddress, coin_name=sp.TString, value=sp.TNat - ) - mint_args_type_entry_point = sp.contract(mint_args_type, self.data.bts_core, "mint").open_some() - t = sp.TOption(sp.TString) - callback = sp.contract(t, sp.self_address, "callback_mint") - mint_args = sp.record(callback=callback.open_some(), - to=parsed_to, coin_name=assets[i].coin_name, value=assets[i].value - ) - sp.transfer(mint_args, sp.tez(0), mint_args_type_entry_point) - status.value = "success" - with sp.else_(): - status.value = "FailCheckTransfer" - with sp.else_(): - status.value = "UnregisteredCoin" + check_transfer = sp.view("check_transfer_restrictions", sp.self_address, sp.record( + coin_name=assets[i].coin_name, user=parsed_to, value=assets[i].value), t=sp.TBool).open_some() + sp.if (check_transfer == True) & (valid_coin == True): + check_validity.value = True + sp.if check_validity.value == True: + sp.for i in sp.range(0, sp.len(assets)): + # inter score call + mint_args_type = sp.TRecord(callback=sp.TContract(sp.TOption(sp.TString)), + to=sp.TAddress, coin_name=sp.TString, value=sp.TNat + ) + mint_args_type_entry_point = sp.contract(mint_args_type, self.data.bts_core, "mint").open_some() + t = sp.TOption(sp.TString) + callback = sp.contract(t, sp.self_address, "callback_mint") + mint_args = sp.record(callback=callback.open_some(), + to=parsed_to, coin_name=assets[i].coin_name, value=assets[i].value + ) + sp.transfer(mint_args, sp.tez(0), mint_args_type_entry_point) + status.value = "success" + with sp.else_(): + status.value = "UnregisteredCoin" with sp.else_(): status.value = "BatchMaxSizeExceed" From 6380df927fd22ffa55742ba31dfff54184175d2c Mon Sep 17 00:00:00 2001 From: icondev22 Date: Tue, 20 Jun 2023 07:21:03 +0545 Subject: [PATCH 106/211] fix: inclusion of newer packages --- go.mod | 4 +-- go.sum | 78 ++++++++++++++++++++++++++++++++++++---------------------- 2 files changed, 50 insertions(+), 32 deletions(-) diff --git a/go.mod b/go.mod index 064ba877..2d172c29 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/icon-project/icon-bridge go 1.13 require ( - blockwatch.cc/tzgo v1.16.0 // indirect + blockwatch.cc/tzgo v1.17.0 github.com/MuhammedIrfan/testify-mock v0.0.0-20220912121829-185fc90cd1b6 github.com/algorand/go-algorand-sdk v1.22.0 github.com/aws/aws-sdk-go v1.44.76 @@ -35,7 +35,7 @@ require ( github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/tinylib/msgp v1.1.2 // indirect github.com/vmihailenco/msgpack/v4 v4.3.11 - golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa + golang.org/x/crypto v0.10.0 gopkg.in/natefinch/lumberjack.v2 v2.0.0 ) diff --git a/go.sum b/go.sum index 05385bac..4f1c8b77 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -blockwatch.cc/tzgo v1.16.0 h1:nvKlXqDyDtq7/pmCotWr0d7xpcZ9cEbqFdROFVjiseI= -blockwatch.cc/tzgo v1.16.0/go.mod h1:Bm3ZfCsqnJtpsAdwBQmhsoz4n8qc9qL4uJhsDoLArR8= +blockwatch.cc/tzgo v1.17.0 h1:2PTRGFtw//7Szo7B8Xn9sgPzIXnsnbRWRX+9CqaT1sc= +blockwatch.cc/tzgo v1.17.0/go.mod h1:tTgPzOH1pMhQod2sh2/jjOLabdCQegb8FZG23+fv1XE= cloud.google.com/go v0.16.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= @@ -161,6 +161,7 @@ github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chrismcguire/gobberish v0.0.0-20150821175641-1d8adb509a0e h1:CHPYEbz71w8DqJ7DRIq+MXyCQsdibK08vdcQTY4ufas= github.com/chrismcguire/gobberish v0.0.0-20150821175641-1d8adb509a0e/go.mod h1:6Xhs0ZlsRjXLIiSMLKafbZxML/j30pg9Z1priLuha5s= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= @@ -206,12 +207,9 @@ github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vs github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4= github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= -github.com/decred/dcrd/chaincfg/chainhash v1.0.2/go.mod h1:BpbrGgrPTr3YJYRN3Bm+D9NuaFd+zGyNeIKgrhCXK60= -github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= -github.com/decred/dcrd/dcrec/secp256k1 v1.0.3 h1:u4XpHqlscRolxPxt2YHrFBDVZYY1AK+KMV02H1r+HmU= -github.com/decred/dcrd/dcrec/secp256k1 v1.0.3/go.mod h1:eCL8H4MYYjRvsw2TuANvEOcVMFbmi9rt/6hJUWU5wlU= -github.com/decred/dcrd/dcrec/secp256k1/v2 v2.0.0 h1:3GIJYXQDAKpLEFriGFN8SbSffak10UXHGdIcFaMPykY= -github.com/decred/dcrd/dcrec/secp256k1/v2 v2.0.0/go.mod h1:3s92l0paYkZoIHuj4X93Teg/HB7eGM9x/zokGw+u4mY= +github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= @@ -248,8 +246,8 @@ github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1 github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/echa/bson v0.0.0-20220430141917-c0fbdf7f8b79 h1:J+/tX7s5mN1aoeQi2ySzix7+zyEhnymkudOxn7VMze4= github.com/echa/bson v0.0.0-20220430141917-c0fbdf7f8b79/go.mod h1:Ih8Pfj34Z/kOmaLua+KtFWFK3AviGsH5siipj6Gmoa8= -github.com/echa/log v1.2.2 h1:tL0IxLI1SqreYWvnkpdE1exilCq9sCOp+aPZWWtwtFU= -github.com/echa/log v1.2.2/go.mod h1:MuBQcNxMgV0eT5iL3yvSZyu4wh40FKfmwJQs1RDUqcQ= +github.com/echa/log v1.2.4 h1:+3+WEqutIBUbASYnuk9zz6HKlm6o8WsFxlOMbA3BcAA= +github.com/echa/log v1.2.4/go.mod h1:KYs5YtFCgL4yHBBqhPmTBhz5ETI1A8q+qbiDPPF1MiM= github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw= @@ -271,8 +269,9 @@ github.com/evalphobia/logrus_fluent v0.5.4/go.mod h1:hasyj+CXm3BDP1YhFk/rnTcjleg github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= -github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg= +github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= +github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/fjl/memsize v0.0.0-20180929194037-2a09253e352a/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= @@ -851,8 +850,6 @@ github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVc github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHRmPYs= github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= @@ -868,10 +865,11 @@ github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2y github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= @@ -1261,6 +1259,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= @@ -1320,10 +1319,9 @@ golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1358,8 +1356,10 @@ golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hM golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1402,8 +1402,11 @@ golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210913180222-943fd674d43e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20170912212905-13449ad91cb2/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1420,8 +1423,10 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180903190138-2b024373dcd9/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1490,17 +1495,23 @@ golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8 h1:h+EGohizhe9XlX18rfpa8k8RAc5XyaeamM+0VHRd4lc= -golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 h1:Q5284mrmYTpACcm+eAKjKJH48BBwSyfJqmmGDTtT8Vc= -golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28= +golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1509,8 +1520,11 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= +golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20170424234030-8be79e1e0910/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1577,8 +1591,10 @@ golang.org/x/tools v0.0.0-20200729181040-64cdafbe085c/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200731060945-b5fad4ed8dd6/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools/gopls v0.4.4/go.mod h1:zhyGzA+CAtREUwwq/btQxEx2FHnGzDwJvGs5YqdVCbE= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1651,6 +1667,7 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/bson.v2 v2.0.0-20171018101713-d8c8987b8862 h1:l7JQszYQzJc0GspaN+sivv8wScShqfkhS3nsgID8ees= gopkg.in/bson.v2 v2.0.0-20171018101713-d8c8987b8862/go.mod h1:VN8wuk/3Ksp8lVZ82HHf/MI1FHOBDt5bPK9VZ8DvymM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1667,6 +1684,7 @@ gopkg.in/go-playground/validator.v9 v9.28.0 h1:6pzvnzx1RWaaQiAmv6e1DvCFULRaz5cKo gopkg.in/go-playground/validator.v9 v9.28.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 h1:VpOs+IwYnYBaFnrNAeB8UUWtL3vEUnzSCL1nVjPhqrw= gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= From 906dd0bc01d829cb89c48ace266f4e295e83baa7 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Tue, 20 Jun 2023 07:23:40 +0545 Subject: [PATCH 107/211] fix: added CustomCall() for fixing the incorrect simulated gas and storage limit in tezos nodes --- cmd/iconbridge/chain/tezos/client.go | 35 +++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/cmd/iconbridge/chain/tezos/client.go b/cmd/iconbridge/chain/tezos/client.go index dc98df60..c86eeec2 100644 --- a/cmd/iconbridge/chain/tezos/client.go +++ b/cmd/iconbridge/chain/tezos/client.go @@ -12,6 +12,7 @@ import ( "github.com/icon-project/icon-bridge/common/log" + "blockwatch.cc/tzgo/codec" "blockwatch.cc/tzgo/contract" "blockwatch.cc/tzgo/micheline" "blockwatch.cc/tzgo/rpc" @@ -282,13 +283,13 @@ func (c *Client) GetBalance(ctx context.Context, connection *rpc.Client, account return balance.Big(), nil } -func (c *Client) GetBMCManangement(ctx context.Context, contr *contract.Contract, account tezos.Address) (string, error){ +func (c *Client) GetBMCManangement(ctx context.Context, contr *contract.Contract, account tezos.Address) (string, error) { fmt.Println("reached in getting bmc Management") result, err := contr.RunView(ctx, "get_bmc_periphery", micheline.Prim{}) if err != nil { return "", err } - return result.String, nil + return result.String, nil } func (c *Client) GetStatus(ctx context.Context, contr *contract.Contract, link string) (TypesLinkStats, error) { @@ -332,7 +333,7 @@ func (c *Client) GetOperationByHash(ctx context.Context, clinet *rpc.Client, blo func (c *Client) HandleRelayMessage(ctx context.Context, callArgs contract.CallArguments, opts *rpc.CallOptions) (*rpc.Receipt, error) { fmt.Println("handling relay message") PrintU() - result, err := c.Contract.Call(ctx, callArgs, opts) + result, err := c.CustomCall(ctx, []contract.CallArguments{callArgs}, opts) if err != nil { fmt.Println(err) fmt.Println("because error") @@ -342,6 +343,34 @@ func (c *Client) HandleRelayMessage(ctx context.Context, callArgs contract.CallA return result, nil } +func (c *Client) CustomCall(ctx context.Context, args []contract.CallArguments, opts *rpc.CallOptions) (*rpc.Receipt, error) { + if opts == nil { + opts = &rpc.DefaultOptions + } + + // assemble batch transaction + op := codec.NewOp().WithTTL(opts.TTL) + for _, arg := range args { + if arg == nil { + continue + } + op.WithContents(arg.Encode()) + } + + var limits []tezos.Limits + limit := tezos.Limits{ + GasLimit: tezos.MumbainetParams.HardGasLimitPerOperation, + StorageLimit: tezos.MumbainetParams.HardStorageLimitPerOperation, + } + + limits = append(limits, limit) + + op.WithLimits(limits, 0).WithMinFee() + + // prepare, sign and broadcast + return c.Cl.Send(ctx, op, opts) +} + func NewClient(uri string, src tezos.Address, l log.Logger) (*Client, error) { fmt.Println("uri is : " + uri) From edb574f9909d54165699d1866b31428b50e54129 Mon Sep 17 00:00:00 2001 From: simusud Date: Wed, 21 Jun 2023 10:44:15 +0545 Subject: [PATCH 108/211] refactor(bmc): updated library addresses --- smartpy/bts/contracts/src/bts_periphery.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index 2d0a0adc..45ccac44 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -534,10 +534,10 @@ def check_transfer_restrictions(self, params): sp.result(False) -sp.add_compilation_target("bts_periphery", BTPPreiphery(bmc_address=sp.address("KT1UrLqhQHDC3mJw9BUrqsiix7JRbxTsvWJu"), +sp.add_compilation_target("bts_periphery", BTPPreiphery(bmc_address=sp.address("KT1VFtWq2dZDH1rTfLtgMaASMt4UX78omMs2"), bts_core_address=sp.address("KT1JAippuMfS6Bso8DGmigmTdkgEZUxQxYyX"), helper_contract=sp.address("KT1HwFJmndBWRn3CLbvhUjdupfEomdykL5a6"), - parse_address=sp.address("KT1EKPrSLWjWViZQogFgbc1QmztkR5UGXEWa"), + parse_address=sp.address("KT1Ha8LzZa7ku1F8eytY7hgNKFJ2BKFRqSDh"), native_coin_name="btp-NetXnHfVqm9iesp.tezos-XTZ", owner_address = sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP"), - rlp_contract=sp.address("KT19Q5aWgR79HcZKWJwQDJ6TXbdxARMdj4Vv"))) \ No newline at end of file + rlp_contract=sp.address("KT1NAsyT4Xdkg8tFAQnmCbxKYqyMLgoWrTaq"))) \ No newline at end of file From cac9040e978aae7eb090d968e0efd55fde04b2ca Mon Sep 17 00:00:00 2001 From: simusud Date: Wed, 21 Jun 2023 10:46:02 +0545 Subject: [PATCH 109/211] fix(bmc): encode_bmc_message fix for negative encoding --- smartpy/bmc/contracts/src/RLP_struct.py | 9 +++++++-- smartpy/bmc/contracts/src/bmc_management.py | 2 +- smartpy/bmc/contracts/src/bmc_periphery.py | 8 ++++---- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/smartpy/bmc/contracts/src/RLP_struct.py b/smartpy/bmc/contracts/src/RLP_struct.py index 2f610d3f..51b831db 100644 --- a/smartpy/bmc/contracts/src/RLP_struct.py +++ b/smartpy/bmc/contracts/src/RLP_struct.py @@ -339,13 +339,18 @@ def encode_bmc_service(self, params): def encode_bmc_message(self, params): sp.set_type(params, sp.TRecord(src=sp.TString, dst=sp.TString, svc=sp.TString, sn=sp.TInt, message=sp.TBytes)) + rlp = sp.local("rlp_sn", sp.bytes("0x")) encode_src = sp.view("encode_string", self.data.helper, params.src, t=sp.TBytes).open_some() encode_dst = sp.view("encode_string", self.data.helper, params.dst, t=sp.TBytes).open_some() encode_svc = sp.view("encode_string", self.data.helper, params.svc, t=sp.TBytes).open_some() - encode_sn = sp.view("to_byte", self.data.helper_parse_negative, params.sn, t=sp.TBytes).open_some() + rlp.value = sp.view("to_byte", self.data.helper_parse_negative, params.sn, t=sp.TBytes).open_some() + + sp.if params.sn < sp.int(0): + encode_sn = sp.view("with_length_prefix", self.data.helper, rlp.value, t=sp.TBytes).open_some() + rlp.value = encode_sn rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, - [encode_src, encode_dst, encode_svc, encode_sn, params.message], + [encode_src, encode_dst, encode_svc, rlp.value, params.message], t=sp.TBytes).open_some() sp.result(rlp_bytes_with_prefix) diff --git a/smartpy/bmc/contracts/src/bmc_management.py b/smartpy/bmc/contracts/src/bmc_management.py index 4a4b2134..44c9aeb5 100644 --- a/smartpy/bmc/contracts/src/bmc_management.py +++ b/smartpy/bmc/contracts/src/bmc_management.py @@ -610,4 +610,4 @@ def resolve_route(self, dst_net): sp.add_compilation_target("bmc_management", BMCManagement(owner_address=sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP"), helper_contract=sp.address("KT1HwFJmndBWRn3CLbvhUjdupfEomdykL5a6"), - rlp_contract=sp.address("KT1A4Ad5jTHaz1W7TvTbqKoBtRa2DnnXbFBn"))) + rlp_contract=sp.address("KT1VyqgqhrcJZwML1WbgHYeUK6WSGt4qyj8Z"))) diff --git a/smartpy/bmc/contracts/src/bmc_periphery.py b/smartpy/bmc/contracts/src/bmc_periphery.py index a46035b4..32b337fc 100644 --- a/smartpy/bmc/contracts/src/bmc_periphery.py +++ b/smartpy/bmc/contracts/src/bmc_periphery.py @@ -142,7 +142,7 @@ def callback_btp_error(self, string, bsh_addr, svc, sn, code, msg): with sp.else_(): error_code = self.UNKNOWN_ERR err_msg = self.BMCRevertUnknownHandleBTPError - sp.emit(sp.record(svc=svc, sn=sn * -1, code=code, msg=msg, err_code=error_code, err_msg=err_msg), tag="ErrorOnBTPError") + sp.emit(sp.record(svc=svc, sn=sn, code=code, msg=msg, err_code=error_code, err_msg=err_msg), tag="ErrorOnBTPError") self.data.handle_btp_error_status = sp.none @sp.entry_point(lazify=False) @@ -395,9 +395,9 @@ def get_status(self, _link): )) -sp.add_compilation_target("bmc_periphery", BMCPreiphery(bmc_management_addr=sp.address("KT1Uiycjx4iXdjKFfR2kAo2NUdEtQ6PmDX4Y"), +sp.add_compilation_target("bmc_periphery", BMCPreiphery(bmc_management_addr=sp.address("KT1G3R9VqESejtsFnvjHSjzXYfuKuHMeaiE3"), helper_contract=sp.address("KT1HwFJmndBWRn3CLbvhUjdupfEomdykL5a6"), helper_parse_neg_contract=sp.address("KT1DHptHqSovffZ7qqvSM9dy6uZZ8juV88gP"), - parse_address=sp.address("KT1XgRyjQPfpfwNrvYYpgERpYpCrGh24aoPX"), + parse_address=sp.address("KT1VJn3WNXDsyFxeSExjSWKBs9JYqRCJ1LFN"), owner_address=sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP"), - rlp_contract=sp.address("KT1A4Ad5jTHaz1W7TvTbqKoBtRa2DnnXbFBn"))) + rlp_contract=sp.address("KT1VyqgqhrcJZwML1WbgHYeUK6WSGt4qyj8Z"))) From 964ff2237744b169e184938f522fa01ab06645d2 Mon Sep 17 00:00:00 2001 From: simusud Date: Fri, 23 Jun 2023 10:56:08 +0545 Subject: [PATCH 110/211] revert(bmc): changed RLP contract back to a library --- smartpy/bmc/contracts/src/RLP_struct.py | 61 +++++---------------- smartpy/bmc/contracts/src/bmc_management.py | 30 ++++------ smartpy/bmc/contracts/src/bmc_periphery.py | 40 ++++++-------- 3 files changed, 43 insertions(+), 88 deletions(-) diff --git a/smartpy/bmc/contracts/src/RLP_struct.py b/smartpy/bmc/contracts/src/RLP_struct.py index 51b831db..4b9a060c 100644 --- a/smartpy/bmc/contracts/src/RLP_struct.py +++ b/smartpy/bmc/contracts/src/RLP_struct.py @@ -2,18 +2,10 @@ Utils2 = sp.io.import_script_from_url("https://raw.githubusercontent.com/RomarQ/tezos-sc-utils/main/smartpy/utils.py") types = sp.io.import_script_from_url("file:./contracts/src/Types.py") -helper_file = sp.io.import_script_from_url("file:./contracts/src/helper.py") -class DecodeLibrary(sp.Contract): +class DecodeEncodeLibrary: - def __init__(self, helper_contract, helper_negative_address): - self.init( - helper=helper_contract, - helper_parse_negative=helper_negative_address - ) - - @sp.onchain_view() def decode_bmc_message(self, rlp): sp.set_type(rlp, sp.TBytes) @@ -44,13 +36,12 @@ def decode_bmc_message(self, rlp): temp_byt.value = k.value counter.value = counter.value + 1 temp_byt.value = sp.view("without_length_prefix", self.data.helper, temp_byt.value, t=sp.TBytes).open_some() - sp.result(sp.record(src=temp_map_string.get("src"), + return sp.record(src=temp_map_string.get("src"), dst=temp_map_string.get("dst"), svc=temp_map_string.get("svc"), sn=temp_int.value, - message=temp_byt.value)) + message=temp_byt.value) - @sp.onchain_view() def decode_response(self, rlp): sp.set_type(rlp, sp.TBytes) @@ -74,9 +65,8 @@ def decode_response(self, rlp): counter.value = counter.value + 1 # message in case of error is null which cannot be decoded into string - sp.result(sp.record(code=temp_int.value, message="Error")) + return sp.record(code=temp_int.value, message="Error") - @sp.onchain_view() def decode_propagate_message(self, rlp): sp.set_type(rlp, sp.TBytes) @@ -95,9 +85,8 @@ def decode_propagate_message(self, rlp): sp.if counter.value == 0: temp_string.value = sp.view("decode_string", self.data.helper, d.value, t=sp.TString).open_some() counter.value = counter.value + 1 - sp.result(temp_string.value) + return temp_string.value - @sp.onchain_view() def decode_init_message(self, rlp): sp.set_type(rlp, sp.TBytes) @@ -134,9 +123,8 @@ def decode_init_message(self, rlp): sp.for x in new_sub_list.items(): _links.value.push(sp.view("decode_string", self.data.helper, x.value, t=sp.TString).open_some()) counter.value = counter.value + 1 - sp.result(_links.value) + return _links.value - @sp.onchain_view() def decode_bmc_service(self, rlp): sp.set_type(rlp, sp.TBytes) @@ -159,10 +147,9 @@ def decode_bmc_service(self, rlp): temp_byt.value = b.value counter.value = counter.value + 1 temp_byt.value = sp.view("without_length_prefix", self.data.helper, temp_byt.value, t=sp.TBytes).open_some() - sp.result(sp.record(serviceType=temp_string.value, - payload=temp_byt.value)) + return sp.record(serviceType=temp_string.value, + payload=temp_byt.value) - @sp.onchain_view() def decode_gather_fee_message(self, rlp): sp.set_type(rlp, sp.TBytes) @@ -201,8 +188,8 @@ def decode_gather_fee_message(self, rlp): sp.for x in new_sub_list.items(): _svcs.value[counter.value] = sp.view("decode_string", self.data.helper, x.value, t=sp.TString).open_some() counter.value = counter.value + 1 - sp.result(sp.record(fa=temp_str.value, - svcs=_svcs.value)) + return sp.record(fa=temp_str.value, + svcs=_svcs.value) def to_message_event(self, rlp): rlp_me = sp.local("rlp_me", sp.map(tkey=sp.TNat)) @@ -275,8 +262,6 @@ def decode_receipt_proof(self, rlp): counter.value = counter.value + 1 return sp.record(index = rv_int.value, events = events.value, height = rv_int2.value) - - @sp.onchain_view() def decode_receipt_proofs(self, rlp): sp.set_type(rlp, sp.TBytes) @@ -317,10 +302,10 @@ def decode_receipt_proofs(self, rlp): sp.for x in new_sub_list.items(): receipt_proofs.value[counter.value] = self.decode_receipt_proof(x.value) counter.value = counter.value + 1 - sp.result(receipt_proofs.value) + return receipt_proofs.value # rlp encoding starts here - @sp.onchain_view() + def encode_bmc_service(self, params): sp.set_type(params, sp.TRecord(serviceType=sp.TString, payload=sp.TBytes)) @@ -333,9 +318,8 @@ def encode_bmc_service(self, params): t=sp.TBytes).open_some() rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp_bytes_with_prefix, t=sp.TBytes).open_some() - sp.result(rlp_bytes_with_prefix) + return rlp_bytes_with_prefix - @sp.onchain_view() def encode_bmc_message(self, params): sp.set_type(params, sp.TRecord(src=sp.TString, dst=sp.TString, svc=sp.TString, sn=sp.TInt, message=sp.TBytes)) @@ -352,9 +336,8 @@ def encode_bmc_message(self, params): rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [encode_src, encode_dst, encode_svc, rlp.value, params.message], t=sp.TBytes).open_some() - sp.result(rlp_bytes_with_prefix) + return rlp_bytes_with_prefix - @sp.onchain_view() def encode_response(self, params): sp.set_type(params, sp.TRecord(code=sp.TNat, message=sp.TString)) @@ -365,19 +348,5 @@ def encode_response(self, params): t=sp.TBytes).open_some() final_rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp_bytes_with_prefix, t=sp.TBytes).open_some() - sp.result(final_rlp_bytes_with_prefix) - -@sp.add_test(name="Decoder") -def test(): - helper_nev= sp.test_account("Helper Negative") - scenario = sp.test_scenario() - - helper=helper_file.Helper() - scenario += helper - - c1 = DecodeLibrary(helper.address, helper_nev.address) - scenario += c1 - + return final_rlp_bytes_with_prefix -sp.add_compilation_target("RLP_struct", DecodeLibrary(helper_contract=sp.address("KT1HwFJmndBWRn3CLbvhUjdupfEomdykL5a6"), - helper_negative_address=sp.address("KT1DHptHqSovffZ7qqvSM9dy6uZZ8juV88gP"))) \ No newline at end of file diff --git a/smartpy/bmc/contracts/src/bmc_management.py b/smartpy/bmc/contracts/src/bmc_management.py index 44c9aeb5..77b1f5fe 100644 --- a/smartpy/bmc/contracts/src/bmc_management.py +++ b/smartpy/bmc/contracts/src/bmc_management.py @@ -2,13 +2,14 @@ types = sp.io.import_script_from_url("file:./contracts/src/Types.py") strings = sp.io.import_script_from_url("file:./contracts/src/String.py") +rlp = sp.io.import_script_from_url("file:./contracts/src/RLP_struct.py") -class BMCManagement(sp.Contract): +class BMCManagement(sp.Contract, rlp.DecodeEncodeLibrary): BLOCK_INTERVAL_MSEC = sp.nat(1000) LIST_SHORT_START = sp.bytes("0xc0") - def __init__(self, owner_address, helper_contract, rlp_contract): + def __init__(self, owner_address, helper_contract): self.init( owners=sp.map(l={owner_address:True}), number_of_owners=sp.nat(1), @@ -25,8 +26,7 @@ def __init__(self, owner_address, helper_contract, rlp_contract): get_route_dst_from_net=sp.map(), get_link_from_net=sp.map(), get_link_from_reachable_net=sp.map(), - helper=helper_contract, - rlp_contract=rlp_contract + helper=helper_contract ) self.init_type(sp.TRecord( @@ -45,8 +45,7 @@ def __init__(self, owner_address, helper_contract, rlp_contract): get_route_dst_from_net=sp.TMap(sp.TString, sp.TString), get_link_from_net=sp.TMap(sp.TString, sp.TString), get_link_from_reachable_net=sp.TMap(sp.TString, types.Types.Tuple), - helper=sp.TAddress, - rlp_contract=sp.TAddress + helper=sp.TAddress )) def only_owner(self): @@ -88,12 +87,6 @@ def set_bmc_btp_address(self, network): "set_bmc_btp_address").open_some() sp.transfer(network, sp.tez(0), set_btp_address_entry_point) - @sp.entry_point - def set_rlp_contract_address(self, param): - sp.set_type(param, sp.TAddress) - self.only_owner() - self.data.rlp_contract = param - @sp.entry_point def add_owner(self, owner): """ @@ -320,9 +313,8 @@ def _propagate_internal(self, service_type, link): send_message_entry_point = sp.contract(send_message_args_type, self.data.bmc_periphery.open_some("Address not set"), "send_message").open_some() - send_message_args = sp.record(to=net, svc="bmc", sn=sp.int(0), msg=sp.view("encode_bmc_service", self.data.rlp_contract, - sp.record(serviceType=service_type,payload=final_rlp_bytes_with_prefix), - t=sp.TBytes).open_some()) + send_message_args = sp.record(to=net, svc="bmc", sn=sp.int(0), msg=self.encode_bmc_service( + sp.record(serviceType=service_type,payload=final_rlp_bytes_with_prefix))) sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) def _send_internal(self, target, service_type, links): @@ -348,8 +340,8 @@ def _send_internal(self, target, service_type, links): send_message_entry_point = sp.contract(send_message_args_type, self.data.bmc_periphery.open_some("Address not set"), "send_message").open_some() - send_message_args = sp.record(to=net, svc="bmc", sn=sp.int(0), msg=sp.view("encode_bmc_service", self.data.rlp_contract, - sp.record(serviceType=service_type, payload=rlp_bytes.value), t=sp.TBytes).open_some()) + send_message_args = sp.record(to=net, svc="bmc", sn=sp.int(0), msg=self.encode_bmc_service( + sp.record(serviceType=service_type, payload=rlp_bytes.value))) sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) @sp.entry_point(lazify=False) @@ -609,5 +601,5 @@ def resolve_route(self, dst_net): sp.add_compilation_target("bmc_management", BMCManagement(owner_address=sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP"), - helper_contract=sp.address("KT1HwFJmndBWRn3CLbvhUjdupfEomdykL5a6"), - rlp_contract=sp.address("KT1VyqgqhrcJZwML1WbgHYeUK6WSGt4qyj8Z"))) + helper_contract=sp.address("KT1HwFJmndBWRn3CLbvhUjdupfEomdykL5a6") + )) diff --git a/smartpy/bmc/contracts/src/bmc_periphery.py b/smartpy/bmc/contracts/src/bmc_periphery.py index 32b337fc..99948625 100644 --- a/smartpy/bmc/contracts/src/bmc_periphery.py +++ b/smartpy/bmc/contracts/src/bmc_periphery.py @@ -2,9 +2,10 @@ types = sp.io.import_script_from_url("file:./contracts/src/Types.py") strings = sp.io.import_script_from_url("file:./contracts/src/String.py") +rlp = sp.io.import_script_from_url("file:./contracts/src/RLP_struct.py") -class BMCPreiphery(sp.Contract): +class BMCPreiphery(sp.Contract, rlp.DecodeEncodeLibrary): BMC_ERR = sp.nat(10) BSH_ERR = sp.nat(40) UNKNOWN_ERR = sp.nat(0) @@ -19,7 +20,7 @@ class BMCPreiphery(sp.Contract): BMCRevertUnknownHandleBTPError = sp.string("UnknownHandleBTPError") BMCRevertUnknownHandleBTPMessage = sp.string("UnknownHandleBTPMessage") - def __init__(self, bmc_management_addr, helper_contract, helper_parse_neg_contract, parse_address, owner_address, rlp_contract): + def __init__(self, bmc_management_addr, helper_contract, helper_parse_neg_contract, parse_address, owner_address): self.init( helper=helper_contract, helper_parse_negative=helper_parse_neg_contract, @@ -29,8 +30,7 @@ def __init__(self, bmc_management_addr, helper_contract, helper_parse_neg_contra handle_btp_message_status=sp.none, handle_btp_error_status=sp.none, handle_fee_gathering_status=sp.none, - owner_address = owner_address, - rlp_contract=rlp_contract, + owner_address = owner_address ) def only_owner(self): @@ -75,12 +75,6 @@ def set_bmc_btp_address(self, network): with sp.else_(): sp.failwith("Address already set") - @sp.entry_point - def set_rlp_contract_address(self, param): - sp.set_type(param, sp.TAddress) - self.only_owner() - self.data.rlp_contract = param - @sp.onchain_view() def get_bmc_btp_address(self): sp.result(self.data.bmc_btp_address.open_some("Address not set")) @@ -178,7 +172,7 @@ def handle_relay_message(self, prev, msg): rx_seq = sp.local("rx_seq", link_rx_seq, t=sp.TNat) rx_height = sp.local("rx_height", link_rx_height, t=sp.TNat) - rps = sp.view("decode_receipt_proofs", self.data.rlp_contract, msg, t=sp.TMap(sp.TNat, types.Types.ReceiptProof)).open_some() + rps = self.decode_receipt_proofs(msg) bmc_msg = sp.local("bmc_msg", sp.record(src="", dst="", svc="", sn=sp.int(0), message=sp.bytes("0x")), t=types.Types.BMCMessage) ev = sp.local("ev", sp.record(next_bmc="", seq=sp.nat(0), message=sp.bytes("0x")), t=types.Types.MessageEvent) sp.for i in sp.range(sp.nat(0), sp.len(rps)): @@ -196,7 +190,7 @@ def handle_relay_message(self, prev, msg): sp.if ev.value.seq > rx_seq.value: sp.failwith(self.BMCRevertInvalidSeqNumber) - _decoded = sp.view("decode_bmc_message", self.data.rlp_contract, ev.value.message, t=types.Types.BMCMessage).open_some() + _decoded = self.decode_bmc_message(ev.value.message) bmc_msg.value = _decoded sp.if bmc_msg.value.src != "": @@ -242,13 +236,13 @@ def _handle_message(self, prev, msg): # bsh_addr = sp.local("bsh_addr",sp.TAddress) with sp.if_(msg.svc == "bmc"): sm = sp.local("sm", sp.record(serviceType="", payload=sp.bytes("0x"))) - sm.value = sp.view("decode_bmc_service", self.data.rlp_contract, msg.message, t=types.Types.BMCService).open_some() + sm.value = self.decode_bmc_service(msg.message) with sp.if_(sm.value.serviceType == ""): self._send_error(prev, msg, self.BMC_ERR, self.BMCRevertParseFailure) with sp.else_(): sp.if sm.value.serviceType == "FeeGathering": gather_fee =sp.local("gather_fee", sp.record(fa="error", svcs=sp.map({0:""}))) - gather_fee.value = sp.view("decode_gather_fee_message", self.data.rlp_contract, sm.value.payload, t=types.Types.GatherFeeMessage).open_some() + gather_fee.value = self.decode_gather_fee_message(sm.value.payload) with sp.if_(gather_fee.value.fa == "error"): self._send_error(prev, msg, self.BMC_ERR, self.BMCRevertParseFailure) @@ -269,7 +263,7 @@ def _handle_message(self, prev, msg): sp.transfer(handle_fee_gathering_args, sp.tez(0), handle_fee_gathering_entry_point) sp.if sm.value.serviceType == "Init": - links = sp.view("decode_init_message", self.data.rlp_contract, sm.value.payload, t=sp.TList(sp.TString)).open_some() + links = self.decode_init_message(sm.value.payload) # call update_link_reachable on BMCManagement update_link_reachable_args_type = sp.TRecord(prev=sp.TString, to=sp.TList(sp.TString)) update_link_reachable_entry_point = sp.contract(update_link_reachable_args_type, @@ -300,7 +294,7 @@ def _handle_message(self, prev, msg): sp.transfer(handle_btp_message_args, sp.tez(0), handle_btp_message_entry_point) with sp.else_(): - res = sp.view("decode_response", self.data.rlp_contract, msg.message, t=types.Types.Response).open_some() + res = self.decode_response(msg.message) # implemented callback # call handle_btp_error on bts periphery handle_btp_error_args_type = sp.TRecord(callback=sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress, svc=sp.TString, sn=sp.TInt, code=sp.TNat, msg=sp.TString)), @@ -332,12 +326,12 @@ def _send_error(self, prev, message, err_code, err_msg): sp.set_type(err_msg, sp.TString) sp.if message.sn > sp.int(0): - serialized_msg = sp.view("encode_bmc_message", self.data.rlp_contract, sp.record( + serialized_msg = self.encode_bmc_message(sp.record( src=self.data.bmc_btp_address.open_some("Address not set"), dst=message.src, svc=message.svc, sn=message.sn * -1, - message=sp.view("encode_response", self.data.rlp_contract, sp.record(code=err_code, message=err_msg), t=sp.TBytes).open_some()), t=sp.TBytes).open_some() + message=self.encode_response(sp.record(code=err_code, message=err_msg)))) self._send_message(prev, serialized_msg) @sp.entry_point(lazify=False) @@ -367,13 +361,13 @@ def send_message(self, to, svc, sn, msg): next_link, dst = sp.match_pair(sp.view("resolve_route", self.data.bmc_management, to, t=sp.TPair(sp.TString, sp.TString)).open_some()) - rlp = sp.view("encode_bmc_message", self.data.rlp_contract, sp.record( + _rlp = self.encode_bmc_message(sp.record( src=self.data.bmc_btp_address.open_some("Address not set"), dst=dst, svc=svc, sn=sn, - message=msg), t=sp.TBytes).open_some() - self._send_message(next_link, rlp) + message=msg)) + self._send_message(next_link, _rlp) @sp.onchain_view() def get_status(self, _link): @@ -399,5 +393,5 @@ def get_status(self, _link): helper_contract=sp.address("KT1HwFJmndBWRn3CLbvhUjdupfEomdykL5a6"), helper_parse_neg_contract=sp.address("KT1DHptHqSovffZ7qqvSM9dy6uZZ8juV88gP"), parse_address=sp.address("KT1VJn3WNXDsyFxeSExjSWKBs9JYqRCJ1LFN"), - owner_address=sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP"), - rlp_contract=sp.address("KT1VyqgqhrcJZwML1WbgHYeUK6WSGt4qyj8Z"))) + owner_address=sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP") + )) From 63a3e94a26fbc9563d2cd24a4fc1fc1ba87be252 Mon Sep 17 00:00:00 2001 From: simusud Date: Fri, 23 Jun 2023 11:03:09 +0545 Subject: [PATCH 111/211] revert(bts): changed RLP contract back to a library --- smartpy/bts/contracts/src/RLP_struct.py | 57 +++++----------------- smartpy/bts/contracts/src/bts_periphery.py | 40 +++++++-------- 2 files changed, 29 insertions(+), 68 deletions(-) diff --git a/smartpy/bts/contracts/src/RLP_struct.py b/smartpy/bts/contracts/src/RLP_struct.py index 337a7ae0..defd0451 100644 --- a/smartpy/bts/contracts/src/RLP_struct.py +++ b/smartpy/bts/contracts/src/RLP_struct.py @@ -2,18 +2,10 @@ Utils2 = sp.io.import_script_from_url("https://raw.githubusercontent.com/RomarQ/tezos-sc-utils/main/smartpy/utils.py") types = sp.io.import_script_from_url("file:./contracts/src/Types.py") -helper_file = sp.io.import_script_from_url("file:./contracts/src/helper.py") -class DecodeLibrary(sp.Contract): +class DecodeEncodeLibrary: - def __init__(self, helper_contract): - self.init( - helper=helper_contract, - ) - - - @sp.onchain_view() def decode_response(self, rlp): sp.set_type(rlp, sp.TBytes) @@ -40,10 +32,8 @@ def decode_response(self, rlp): temp_byt.value = i.value counter.value = counter.value + 1 - sp.result(sp.record(code=temp_int.value, message=sp.view("decode_string", self.data.helper, temp_byt.value, t=sp.TString).open_some())) + return sp.record(code=temp_int.value, message=sp.view("decode_string", self.data.helper, temp_byt.value, t=sp.TString).open_some()) - - @sp.onchain_view() def decode_service_message(self, rlp): sp.set_type(rlp, sp.TBytes) @@ -85,10 +75,9 @@ def decode_service_message(self, rlp): _service_type.value = sp.variant("UNKNOWN_TYPE", temp_int.value) temp_byt.value = sp.view("without_length_prefix", self.data.helper, temp_byt.value, t=sp.TBytes).open_some() - sp.result(sp.record(serviceType=_service_type.value, - data=temp_byt.value)) + return sp.record(serviceType=_service_type.value, + data=temp_byt.value) - @sp.onchain_view() def decode_transfer_coin_msg(self, rlp): sp.set_type(rlp, sp.TBytes) @@ -166,10 +155,8 @@ def decode_transfer_coin_msg(self, rlp): rv1 = sp.view("decode_string", self.data.helper, rv1_byt.value, t=sp.TString).open_some() rv2 = sp.view("decode_string", self.data.helper, rv2_byt.value, t=sp.TString).open_some() - sp.result(sp.record(from_addr= rv1, to = rv2 , assets = rv_assets.value)) - + return sp.record(from_addr= rv1, to = rv2 , assets = rv_assets.value) - @sp.onchain_view() def decode_blacklist_msg(self, rlp): sp.set_type(rlp, sp.TBytes) @@ -240,10 +227,8 @@ def decode_blacklist_msg(self, rlp): _service_type.value = sp.variant("ADD_TO_BLACKLIST", rv1) with sp.else_(): _service_type.value = sp.variant("REMOVE_FROM_BLACKLIST", rv1) - sp.result(sp.record(serviceType = _service_type.value , addrs = rv_blacklist_address.value , net = rv2)) + return sp.record(serviceType = _service_type.value , addrs = rv_blacklist_address.value , net = rv2) - - @sp.onchain_view() def decode_token_limit_msg(self, rlp): sp.set_type(rlp, sp.TBytes) @@ -306,11 +291,11 @@ def decode_token_limit_msg(self, rlp): t=sp.TBytes).open_some() rv_limit.value[counter.value] = Utils2.Int.of_bytes(limit.value) counter.value += 1 - sp.result(sp.record(coin_name = rv_names.value, token_limit = rv_limit.value , - net = sp.view("decode_string", self.data.helper, rv1_byt.value, t=sp.TString).open_some())) + return sp.record(coin_name = rv_names.value, token_limit = rv_limit.value , + net = sp.view("decode_string", self.data.helper, rv1_byt.value, t=sp.TString).open_some()) # encoding starts here - @sp.onchain_view() + def encode_service_message(self, params): sp.set_type(params, sp.TRecord(service_type_value=sp.TNat, data=sp.TBytes)) @@ -321,9 +306,8 @@ def encode_service_message(self, params): final_rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp_bytes_with_prefix, t=sp.TBytes).open_some() - sp.result(final_rlp_bytes_with_prefix) + return final_rlp_bytes_with_prefix - @sp.onchain_view() def encode_transfer_coin_msg(self, data): sp.set_type(data, types.Types.TransferCoin) @@ -350,9 +334,8 @@ def encode_transfer_coin_msg(self, data): final_rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp.value, t=sp.TBytes).open_some() - sp.result(final_rlp_bytes_with_prefix) + return final_rlp_bytes_with_prefix - @sp.onchain_view() def encode_response(self, params): sp.set_type(params, sp.TRecord(code=sp.TNat, message=sp.TString)) @@ -364,20 +347,4 @@ def encode_response(self, params): final_rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp_bytes_with_prefix, t=sp.TBytes).open_some() - sp.result(final_rlp_bytes_with_prefix) - - -@sp.add_test(name="Decoder") -def test(): - scenario = sp.test_scenario() - - helper = helper_file.Helper() - scenario += helper - - c1 = DecodeLibrary(helper.address) - scenario += c1 - - -sp.add_compilation_target("RLP_struct", - DecodeLibrary(helper_contract=sp.address("KT1HwFJmndBWRn3CLbvhUjdupfEomdykL5a6"))) - + return final_rlp_bytes_with_prefix \ No newline at end of file diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index 45ccac44..3b0dac03 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -2,9 +2,10 @@ types = sp.io.import_script_from_url("file:./contracts/src/Types.py") strings = sp.io.import_script_from_url("file:./contracts/src/String.py") +rlp = sp.io.import_script_from_url("file:./contracts/src/RLP_struct.py") -class BTPPreiphery(sp.Contract): +class BTSPeriphery(sp.Contract, rlp.DecodeEncodeLibrary): service_name = sp.string("bts") RC_OK = sp.nat(0) @@ -13,7 +14,7 @@ class BTPPreiphery(sp.Contract): MAX_BATCH_SIZE = sp.nat(15) - def __init__(self, bmc_address, bts_core_address, helper_contract, parse_address, native_coin_name, owner_address, rlp_contract): + def __init__(self, bmc_address, bts_core_address, helper_contract, parse_address, native_coin_name, owner_address): self.update_initial_storage( bmc=bmc_address, owner=owner_address, @@ -25,8 +26,7 @@ def __init__(self, bmc_address, bts_core_address, helper_contract, parse_address number_of_pending_requests = sp.nat(0), helper=helper_contract, parse_contract=parse_address, - mint_status=sp.none, - rlp_contract=rlp_contract + mint_status=sp.none ) def only_bmc(self): @@ -65,12 +65,6 @@ def set_bts_core_address(self, params): self.only_owner() self.data.bts_core = params - @sp.entry_point - def set_rlp_contract_address(self, param): - sp.set_type(param, sp.TAddress) - self.only_owner() - self.data.rlp_contract = param - @sp.onchain_view() def has_pending_request(self): """ @@ -207,9 +201,9 @@ def send_service_message(self, _from, to, coin_names, values, fees): send_message_entry_point = sp.contract(send_message_args_type, self.data.bmc, "send_message").open_some() send_message_args = sp.record( to=to_network, svc=self.service_name, sn=self.data.serial_no, - msg = sp.view("encode_service_message", self.data.rlp_contract, sp.record(service_type_value=sp.nat(0), - data=sp.view("encode_transfer_coin_msg", self.data.rlp_contract, sp.record(from_addr=start_from, to=to_address, assets=assets), - t=sp.TBytes).open_some()), t=sp.TBytes).open_some()) + msg = self.encode_service_message(sp.record(service_type_value=sp.nat(0), + data=self.encode_transfer_coin_msg(sp.record(from_addr=start_from, to=to_address, assets=assets)))) + ) sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) @@ -254,12 +248,12 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, bsh_addr, prev, call callback_string = sp.local("callback_string", "") with sp.if_((svc == self.service_name) & (check_caller == "Authorized")): err_msg = sp.local("error", "") - sm = sp.view("decode_service_message", self.data.rlp_contract, msg, t=types.Types.ServiceMessage).open_some() + sm = self.decode_service_message(msg) with sm.serviceType.match_cases() as arg: with arg.match("REQUEST_COIN_TRANSFER") as a1: callback_string.value = "success" - tc = sp.view("decode_transfer_coin_msg", self.data.rlp_contract, sm.data, t=types.Types.TransferCoin).open_some() + tc = self.decode_transfer_coin_msg(sm.data) parsed_addr = sp.view("str_to_addr", self.data.parse_contract, tc.to, t=sp.TAddress).open_some() with sp.if_(parsed_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): @@ -277,7 +271,7 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, bsh_addr, prev, call with arg.match("BLACKLIST_MESSAGE") as a2: callback_string.value = "success" - bm = sp.view("decode_blacklist_msg", self.data.rlp_contract, sm.data, t=types.Types.BlacklistMessage).open_some() + bm = self.decode_blacklist_msg(sm.data) addresses = bm.addrs with bm.serviceType.match_cases() as b_agr: @@ -300,7 +294,7 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, bsh_addr, prev, call with arg.match("CHANGE_TOKEN_LIMIT") as a3: callback_string.value = "success" - tl = sp.view("decode_token_limit_msg", self.data.rlp_contract, sm.data, t=types.Types.TokenLimitMessage).open_some() + tl = self.decode_token_limit_msg(sm.data) coin_names = tl.coin_name token_limits = tl.token_limit @@ -312,7 +306,7 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, bsh_addr, prev, call with arg.match("RESPONSE_HANDLE_SERVICE") as a4: with sp.if_(sp.len(sp.pack(self.data.requests.get(sn).from_)) != 0): - response = sp.view("decode_response", self.data.rlp_contract, sm.data, t=types.Types.Response).open_some() + response = self.decode_response(sm.data) handle_response = self.handle_response_service(sn, response.code, response.message) with sp.if_(handle_response == "success"): callback_string.value = "success" @@ -485,8 +479,8 @@ def send_response_message(self, service_type, service_type_val, to, sn, msg, cod ) send_message_entry_point = sp.contract(send_message_args_type, self.data.bmc, "send_message").open_some() send_message_args = sp.record(to=to, svc=self.service_name, sn=sn, - msg=sp.view("encode_service_message", self.data.rlp_contract, sp.record(service_type_value=service_type_val, data=sp.view("encode_response", - self.data.rlp_contract, sp.record(code=code, message=msg), t=sp.TBytes).open_some()), t=sp.TBytes).open_some()) + msg=self.encode_service_message(sp.record(service_type_value=service_type_val, data=self.encode_response( + sp.record(code=code, message=msg))))) sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) @@ -534,10 +528,10 @@ def check_transfer_restrictions(self, params): sp.result(False) -sp.add_compilation_target("bts_periphery", BTPPreiphery(bmc_address=sp.address("KT1VFtWq2dZDH1rTfLtgMaASMt4UX78omMs2"), +sp.add_compilation_target("bts_periphery", BTSPeriphery(bmc_address=sp.address("KT1VFtWq2dZDH1rTfLtgMaASMt4UX78omMs2"), bts_core_address=sp.address("KT1JAippuMfS6Bso8DGmigmTdkgEZUxQxYyX"), helper_contract=sp.address("KT1HwFJmndBWRn3CLbvhUjdupfEomdykL5a6"), parse_address=sp.address("KT1Ha8LzZa7ku1F8eytY7hgNKFJ2BKFRqSDh"), native_coin_name="btp-NetXnHfVqm9iesp.tezos-XTZ", - owner_address = sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP"), - rlp_contract=sp.address("KT1NAsyT4Xdkg8tFAQnmCbxKYqyMLgoWrTaq"))) \ No newline at end of file + owner_address = sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP") + )) \ No newline at end of file From 2a41a78305c71da1d04e1f2381783b891a0edb29 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Fri, 23 Jun 2023 12:53:11 +0545 Subject: [PATCH 112/211] fix: event filter for events present in the same blocks --- cmd/iconbridge/chain/tezos/client.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/iconbridge/chain/tezos/client.go b/cmd/iconbridge/chain/tezos/client.go index c86eeec2..1826fd15 100644 --- a/cmd/iconbridge/chain/tezos/client.go +++ b/cmd/iconbridge/chain/tezos/client.go @@ -242,18 +242,18 @@ func returnTxMetadata(tx *rpc.Transaction, contractAddress tezos.Address) ([]*ch func returnTxMetadata3(tx *rpc.Transaction, contractAddress tezos.Address, height uint64) (*chain.Receipt, error) { fmt.Println("reache to return tx metadata3", height) receipt := &chain.Receipt{} + var events []*chain.Event for i := 0; i < len(tx.Metadata.InternalResults); i++ { fmt.Println("reached in for") internalResults := tx.Metadata.InternalResults[i] - if internalResults.Kind.String() == "event" && internalResults.Source.ContractAddress() == "KT1CYbCyejjPcB7qKhoXqd45UbUMfZRFcbTk" { + if internalResults.Kind.String() == "event" && internalResults.Source.ContractAddress() == "KT1GE5sE73hThhRwaokB3yqxypiVHpoFZcjj" { fmt.Println("Address matched") if internalResults.Tag == "Message" { message := internalResults.Payload.Args[0].Bytes next := internalResults.Payload.Args[1].Args[0].String seq := internalResults.Payload.Args[1].Args[1].Int - var events []*chain.Event events = append(events, &chain.Event{ Message: message, Next: chain.BTPAddress(next), From 086e0fcc4cec98a1553f99a805bfcbd24720aa0b Mon Sep 17 00:00:00 2001 From: icondev22 Date: Fri, 23 Jun 2023 12:54:39 +0545 Subject: [PATCH 113/211] feat: syncverifier and receiveloop in same function --- cmd/iconbridge/chain/tezos/receiver.go | 221 ++++++++++++++++++++++++- 1 file changed, 216 insertions(+), 5 deletions(-) diff --git a/cmd/iconbridge/chain/tezos/receiver.go b/cmd/iconbridge/chain/tezos/receiver.go index 5f679559..2a89db6f 100644 --- a/cmd/iconbridge/chain/tezos/receiver.go +++ b/cmd/iconbridge/chain/tezos/receiver.go @@ -92,7 +92,6 @@ func (r *receiver) Subscribe(ctx context.Context, msgCh chan<- *chain.Message, o fmt.Println(receipts[0].Height) msgCh <- &chain.Message{Receipts: receipts} } - fmt.Println("returned nill") lastHeight++ return nil }); err != nil { @@ -285,7 +284,7 @@ func (r *receiver) SyncVerifier(ctx context.Context, vr IVerifier, height int64, } q.res.Height = q.height q.res.Header, q.err = r.client.GetBlockHeaderByHeight(ctx, r.client.Cl, q.height) - if q.err != nil { + if q.err != nil { q.err = errors.Wrapf(q.err, "syncVerifier: getBlockHeader: %v", q.err) return } @@ -517,8 +516,8 @@ func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback fu q.err = errors.Wrapf(err, "GetHeaderByHeight: %v", err) return } - q.v.Header = header // change accordingly - q.v.Hash = q.v.Hash // change accordingly + q.v.Header = header // change accordingly + q.v.Hash = header.Hash // change accordingly } block, err := r.client.GetBlockByHeight(ctx, r.client.Cl, q.v.Height.Int64()) @@ -528,7 +527,7 @@ func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback fu } q.v.Block = block fmt.Println("Getting for header: ", block.Header.Level) - if q.v.HasBTPMessage == nil { + if q.v.HasBTPMessage == nil && q.v.Height.Int64() >= opts.StartHeight { // fmt.Println("height: ", q.v.Height.Int64()) if err != nil { @@ -586,3 +585,215 @@ func PrintSync() { fmt.Println("realyer synced") } } + +// merging the syncing and receiving function + +func (r *receiver) receiveLoop2(ctx context.Context, opts *BnOptions, callback func(v *types.BlockNotification) error) (err error) { + fmt.Println("reached to receivelopp") + if opts == nil { + return errors.New("receiveLoop: invalid options: ") + } + + var vr IVerifier + + if r.opts.Verifier != nil { + vr, err = r.NewVerifier(ctx, r.opts.Verifier.BlockHeight) + if err != nil { + return err + } + + // fmt.Println("The start height is: ", opts.StartHeight) + // err = r.SyncVerifier(ctx, vr, opts.StartHeight + 1, func(r []*chain.Receipt) error { return nil }) + // if err != nil { + // return err + // } + } + bnch := make(chan *types.BlockNotification, r.opts.SyncConcurrency) + heightTicker := time.NewTicker(BlockInterval) + defer heightTicker.Stop() + + heightPoller := time.NewTicker(BlockHeightPollInterval) + defer heightPoller.Stop() + + latestHeight := func() int64 { + block, err := r.client.GetLastBlock(ctx, r.client.Cl) + if err != nil { + return 0 + } + return block.GetLevel() + } + next, latest := opts.StartHeight+1, latestHeight() + + var lbn *types.BlockNotification + + for { + select { + case <-ctx.Done(): + return nil + case <-heightTicker.C: + latest++ + case <-heightPoller.C: + if height := latestHeight(); height > 0 { + latest = height + // r.log.WithFields(log.Fields{"latest": latest, "next": next}).Debug("poll height") + } + case bn := <-bnch: + // process all notifications + for ; bn != nil; next++ { + if lbn != nil { + if bn.Height.Cmp(lbn.Height) == 0 { + if bn.Header.Predecessor != lbn.Header.Predecessor { + r.log.WithFields(log.Fields{"lbnParentHash": lbn.Header.Predecessor, "bnParentHash": bn.Header.Predecessor}).Error("verification failed on retry ") + break + } + } else { + if vr != nil { + if err := vr.Verify(ctx, lbn.Header, lbn.Block, bn.Proposer, r.client.Cl, bn.Header); err != nil { // change accordingly + r.log.WithFields(log.Fields{ + "height": lbn.Height, + "lbnHash": lbn.Hash, + "nextHeight": next, + "bnHash": bn.Hash}).Error("verification failed. refetching block ", err) + fmt.Println(err) + fmt.Println("error in verifying ") + time.Sleep(5 * time.Second) + next-- + break + } + if err := vr.Update(ctx, lbn.Header, lbn.Block); err != nil { + return errors.Wrapf(err, "receiveLoop: vr.Update: %v", err) + } + } + if lbn.Header.Level >= opts.StartHeight { + if err := callback(lbn); err != nil { + return errors.Wrapf(err, "receiveLoop: callback: %v", err) + } + } + } + } + if lbn, bn = bn, nil; len(bnch) > 0 { + bn = <-bnch + } + } + // remove unprocessed notifications + for len(bnch) > 0 { + <-bnch + //r.log.WithFields(log.Fields{"lenBnch": len(bnch), "height": t.Height}).Info("remove unprocessed block noitification") + } + + default: + if next >= latest { + time.Sleep(10 * time.Second) + continue + } + + type bnq struct { + h int64 + v *types.BlockNotification + err error + retry int + } + + qch := make(chan *bnq, cap(bnch)) + + for i := next; i < latest && len(qch) < cap(qch); i++ { + qch <- &bnq{i, nil, nil, RPCCallRetry} + } + + if len(qch) == 0 { + r.log.Error("Fatal: Zero length of query channel. Avoiding deadlock") + continue + } + bns := make([]*types.BlockNotification, 0, len(qch)) + for q := range qch { + switch { + case q.err != nil: + if q.retry > 0 { + q.retry-- + q.v, q.err = nil, nil + qch <- q + continue + } + case q.v != nil: + bns = append(bns, q.v) + if len(bns) == cap(bns) { + close(qch) + } + default: + go func(q *bnq) { + defer func() { + time.Sleep(500 * time.Millisecond) + qch <- q + }() + + if q.v == nil { + q.v = &types.BlockNotification{} + } + q.v.Height = (&big.Int{}).SetInt64(q.h) + + if q.v.Header == nil { + header, err := r.client.GetBlockHeaderByHeight(ctx, r.client.Cl, q.v.Height.Int64()) + if err != nil { + q.err = errors.Wrapf(err, "GetHeaderByHeight: %v", err) + return + } + q.v.Header = header // change accordingly + q.v.Hash = header.Hash // change accordingly + } + + block, err := r.client.GetBlockByHeight(ctx, r.client.Cl, q.v.Height.Int64()) + if err != nil { + q.err = errors.Wrapf(err, "GetBlockByHeight: %v", err) + return + } + q.v.Block = block + + if q.v.HasBTPMessage == nil { + if err != nil { + return + } + q.v.Proposer = block.Metadata.Proposer + + hasBTPMessage, receipt, err := returnTxMetadata2(block, r.client.Contract.Address(), q.v.Height.Int64(), r.client) + + if err != nil { + q.err = errors.Wrapf(err, "hasBTPMessage: %v", err) + return + } + q.v.HasBTPMessage = &hasBTPMessage + + if receipt != nil { + fmt.Println("should reach here for block", q.v.Height.Uint64()) + q.v.Receipts = receipt + } + } + if !*q.v.HasBTPMessage { + return + } + }(q) + } + } + // filtering nil + _bns_, bns := bns, bns[:0] + + for _, v := range _bns_ { + if v != nil { + bns = append(bns, v) + } + } + + if len(bns) > 0 { + sort.SliceStable(bns, func(i, j int) bool { + return bns[i].Height.Int64() < bns[j].Height.Int64() + }) + for i, v := range bns { + if v.Height.Int64() == next+int64(i) { + bnch <- v + } + } + } + + } + + } +} From 17cc1240919bdc98d4b81bdae103ca5d26cd74d9 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Fri, 23 Jun 2023 12:55:10 +0545 Subject: [PATCH 114/211] fix: endorsement threshold calculation --- cmd/iconbridge/chain/tezos/verifier.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/cmd/iconbridge/chain/tezos/verifier.go b/cmd/iconbridge/chain/tezos/verifier.go index 977bc4d7..5bad00b8 100644 --- a/cmd/iconbridge/chain/tezos/verifier.go +++ b/cmd/iconbridge/chain/tezos/verifier.go @@ -52,9 +52,7 @@ func (vr *Verifier) Verify(ctx context.Context, header *rpc.BlockHeader, block * if currentFittness < vr.parentFittness { return fmt.Errorf("Invalid block fittness", currentFittness) } - fmt.Println(header.Level) - fmt.Println(header.Predecessor) - fmt.Println(vr.parentHash.String()) + previousHashInBlock := header.Predecessor if previousHashInBlock.String() != vr.parentHash.String() { @@ -188,7 +186,7 @@ func (vr *Verifier) updateValidatorsAndCycle(ctx context.Context, blockHeight in func (vr *Verifier) verifyEndorsement(op [][]*rpc.Operation, c *rpc.Client, blockHeight int64) (error) { endorsementPower := 0 - threshold := 7000 * (2 / 3) + threshold := 7000 * float32(2) / float32(3) endorsers := make(map[tezos.Address]bool) for i := 0; i < len(op); i++ { for j := 0; j < len(op[i]); j++ { @@ -210,7 +208,7 @@ func (vr *Verifier) verifyEndorsement(op [][]*rpc.Operation, c *rpc.Client, bloc } fmt.Println(len(endorsers)) - if endorsementPower > threshold && len(endorsers) * 100 / len(vr.validators) > 66 { + if endorsementPower > int(threshold) && len(endorsers) * 100 / len(vr.validators) > 66 { return nil } return errors.New("endorsement verification failed") From 21d920c84d7474b1f791d6146fb8e7905ca38e75 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Fri, 23 Jun 2023 12:55:38 +0545 Subject: [PATCH 115/211] fix: type of tezos blockhash --- cmd/iconbridge/chain/tezos/types/types.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/iconbridge/chain/tezos/types/types.go b/cmd/iconbridge/chain/tezos/types/types.go index 38a91721..4c324765 100644 --- a/cmd/iconbridge/chain/tezos/types/types.go +++ b/cmd/iconbridge/chain/tezos/types/types.go @@ -2,15 +2,15 @@ package types import ( "math/big" - "github.com/ethereum/go-ethereum/common" "github.com/icon-project/icon-bridge/cmd/iconbridge/chain" "blockwatch.cc/tzgo/rpc" "blockwatch.cc/tzgo/tezos" + ) type BlockNotification struct { - Hash common.Hash + Hash tezos.BlockHash Height *big.Int Header *rpc.BlockHeader Receipts []*chain.Receipt From 25ea9b4c2c3a545419a3a7a374436b2ad9c776da Mon Sep 17 00:00:00 2001 From: icondev22 Date: Fri, 23 Jun 2023 12:56:14 +0545 Subject: [PATCH 116/211] fix: new config for new env --- cmd/iconbridge/example.config.json | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/cmd/iconbridge/example.config.json b/cmd/iconbridge/example.config.json index fc5ad1fa..6f214f1e 100644 --- a/cmd/iconbridge/example.config.json +++ b/cmd/iconbridge/example.config.json @@ -17,20 +17,20 @@ { "name": "t2i", "src": { - "address": "btp://NetXnHfVqm9iesp.tezos/KT1XQ9qNQgHMGq5h5uvvXaZFtj7vGerQ8yga", + "address": "btp://NetXnHfVqm9iesp.tezos/KT1Ut8DFpvKxNtic368hwHRqxZLW7bN54ier", "endpoint": [ - "https://ghostnet.tezos.marigold.dev" + "https://rpc.ghost.tzstats.com/" ], "options": { "verifier": { - "blockHeight": 2792278 - }, + "blockHeight": 3032011 + }, "syncConcurrency": 100 }, - "offset": 2792278 + "offset": 3032011 }, "dst": { - "address": "btp://0x7.icon/cx152b8c1fe4f377443df0e643ab066ea219c1086a", + "address": "btp://0x7.icon/cxdf6dbbac0eb75618a2c8ba0f92c71341158734bd", "endpoint": [ "https://berlin.net.solidwallet.io/api/v3" ], @@ -65,23 +65,23 @@ { "name": "i2t", "src": { - "address": "btp://0x7.icon/cx152b8c1fe4f377443df0e643ab066ea219c1086a", + "address": "btp://0x7.icon/cxdf6dbbac0eb75618a2c8ba0f92c71341158734bd", "endpoint": [ "https://berlin.net.solidwallet.io/api/v3/icon_dex" ], "options": { "verifier": { - "blockHeight": 8857590, + "blockHeight": 9922000, "validatorsHash": "0x04b56f3fc8d396cc7eb8124da8a554800b8758c9e2fff0802aa9682948e65447" }, "syncConcurrency": 100 }, - "offset": 8857590 + "offset": 9922000 }, "dst": { - "address": "btp://NetXnHfVqm9iesp.tezos/KT1XQ9qNQgHMGq5h5uvvXaZFtj7vGerQ8yga", + "address": "btp://NetXnHfVqm9iesp.tezos/KT1Ut8DFpvKxNtic368hwHRqxZLW7bN54ier", "endpoint": [ - "https://ghostnet.tezos.marigold.dev" + "https://rpc.ghost.tzstats.com/" ], "options": { "gas_limit": 1040000, From fffcd2447dfe506e628e3e45cc9e1e32574fedfa Mon Sep 17 00:00:00 2001 From: simusud Date: Fri, 23 Jun 2023 16:29:28 +0545 Subject: [PATCH 117/211] feat(bts): implemented callback in balance_of --- smartpy/bts/contracts/src/bts_core.py | 70 ++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 13 deletions(-) diff --git a/smartpy/bts/contracts/src/bts_core.py b/smartpy/bts/contracts/src/bts_core.py index 1bd02b8e..3fc519b5 100644 --- a/smartpy/bts/contracts/src/bts_core.py +++ b/smartpy/bts/contracts/src/bts_core.py @@ -42,7 +42,10 @@ def __init__(self, _native_coin_name, _fee_numerator, _fixed_fee, owner_manager) fixed_fee=_fixed_fee, coin_type=self.NATIVE_COIN_TYPE)}, tkey=sp.TString, tvalue=Coin), - coins_address=sp.map({}, tkey=sp.TAddress, tvalue=sp.TString) + coins_address=sp.map({}, tkey=sp.TAddress, tvalue=sp.TString), + callback_coin_name=sp.string(""), + callback_value=sp.nat(0), + callback_to=sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg") ) def only_owner(self): @@ -273,12 +276,12 @@ def get_accumulated_fees(self): i.value += sp.nat(1) sp.result(accumulated_fees.value) - @sp.entry_point(lazify=False) - def update_transfer_native_coin(self, ep): - self.only_owner() - sp.set_entry_point("transfer_native_coin", ep) + # @sp.entry_point(lazify=False) + # def update_transfer_native_coin(self, ep): + # self.only_owner() + # sp.set_entry_point("transfer_native_coin", ep) - @sp.entry_point(check_no_incoming_transfer=False, lazify=True) + @sp.entry_point(check_no_incoming_transfer=False) def transfer_native_coin(self, to): """ Allow users to deposit `sp.amount` native coin into a BTSCore contract. @@ -514,6 +517,37 @@ def payment_transfer(self, to, amount): sp.send(to, sp.utils.nat_to_mutez(amount), message="PaymentFailed") + @sp.entry_point + def callback_balance_of(self, param): + t_balance_of_request = sp.TRecord(owner=sp.TAddress, token_id=sp.TNat).layout(("owner", "token_id")) + t_balance_of_response = sp.TRecord(request=t_balance_of_request, balance=sp.TNat).layout(("request", "balance")) + sp.set_type(param, sp.TList(t_balance_of_response)) + + return_string = sp.local("return_string_", sp.string("")) + bts_core_balance = sp.local("bts_core_balance", sp.nat(0)) + sp.for item in param: + bts_core_balance.value = item.balance + with sp.if_(bts_core_balance.value >= self.data.callback_value): + # call transfer in FA2 + transfer_args_type = sp.TList(sp.TRecord(from_=sp.TAddress, txs=sp.TList(sp.TRecord( + to_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout(("to_", ("token_id", "amount")))) + ).layout(("from_", "txs"))) + transfer_entry_point = sp.contract(transfer_args_type, self.data.coins[self.data.callback_coin_name], "transfer").open_some() + transfer_args = [ + sp.record(from_=sp.self_address, txs=[sp.record(to_=self.data.callback_to, token_id=sp.nat(0), + amount=self.data.callback_value)])] + sp.transfer(transfer_args, sp.tez(0), transfer_entry_point) + return_string.value = "success" + with sp.else_(): + return_string.value = "fail" + + self.data.callback_coin_name = sp.string("") + self.data.callback_value = sp.nat(0) + self.data.callback_to = sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg") + + temp_callback = sp.contract(sp.TOption(sp.TString), self.data.bts_periphery_address.open_some("Address not set"), "callback_mint") + sp.transfer(sp.some(return_string.value), sp.tez(0), temp_callback.open_some()) + @sp.entry_point(lazify=False) def update_mint(self, ep): self.only_owner() @@ -537,6 +571,7 @@ def mint(self, to, coin_name, value, callback): self.only_bts_periphery() with sp.if_(coin_name == self.data.native_coin_name): self.payment_transfer(to, value) + sp.transfer(sp.some("success"), sp.tez(0), callback) with sp.else_(): with sp.if_(self.data.coin_details[coin_name].coin_type == self.NATIVE_WRAPPED_COIN_TYPE): # call mint in FA2 @@ -544,16 +579,25 @@ def mint(self, to, coin_name, value, callback): mint_entry_point = sp.contract(mint_args_type, self.data.coins[coin_name], "mint").open_some() mint_args = [sp.record(to_=to, amount=value)] sp.transfer(mint_args, sp.tez(0), mint_entry_point) + sp.transfer(sp.some("success"), sp.tez(0), callback) with sp.else_(): sp.if self.data.coin_details[coin_name].coin_type == self.NON_NATIVE_TOKEN_TYPE: - # call transfer in FA2 - transfer_args_type = sp.TList(sp.TRecord(from_=sp.TAddress, txs=sp.TList(sp.TRecord( - to_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout(("to_", ("token_id", "amount")))) - ).layout(("from_", "txs"))) - transfer_entry_point = sp.contract(transfer_args_type, self.data.coins[coin_name], "transfer").open_some() - transfer_args = [sp.record(from_=sp.self_address, txs=[sp.record(to_=to, token_id=sp.nat(0), amount=value)])] + # call balance_of FA2 + t_balance_of_request = sp.TRecord(owner=sp.TAddress, token_id=sp.TNat).layout(("owner", "token_id")) + t_balance_of_response = sp.TRecord(request=t_balance_of_request, balance=sp.TNat).layout(("request", "balance")) + t_balance_of_params = sp.TRecord(callback=sp.TContract(sp.TList(t_balance_of_response)), + requests=sp.TList(t_balance_of_request),).layout(("requests", "callback")) + + transfer_args_type = t_balance_of_params + transfer_entry_point = sp.contract(transfer_args_type, self.data.coins[coin_name], + "balance_of").open_some() + _callback = sp.contract(sp.TList(t_balance_of_response), sp.self_address, "callback_balance_of") + transfer_args = sp.record(callback=_callback.open_some(), requests=[sp.record(owner=sp.self_address, token_id=sp.nat(0))]) sp.transfer(transfer_args, sp.tez(0), transfer_entry_point) - sp.transfer(sp.some("success"), sp.tez(0), callback) + + self.data.callback_coin_name = coin_name + self.data.callback_value = value + self.data.callback_to = to @sp.entry_point(lazify=False) def update_handle_response_service(self, ep): From 7c15d6293686f375e9c15e6db0c3ae96289b0230 Mon Sep 17 00:00:00 2001 From: suyogadhikari Date: Mon, 26 Jun 2023 15:33:02 +0545 Subject: [PATCH 118/211] perf(bmc): try catch added on rlp decoding --- smartpy/bmc/contracts/src/RLP_struct.py | 415 ++++++++++++--------- smartpy/bmc/contracts/src/bmc_periphery.py | 75 ++-- 2 files changed, 276 insertions(+), 214 deletions(-) diff --git a/smartpy/bmc/contracts/src/RLP_struct.py b/smartpy/bmc/contracts/src/RLP_struct.py index 4b9a060c..aee0a67d 100644 --- a/smartpy/bmc/contracts/src/RLP_struct.py +++ b/smartpy/bmc/contracts/src/RLP_struct.py @@ -10,37 +10,46 @@ def decode_bmc_message(self, rlp): sp.set_type(rlp, sp.TBytes) rlp_bm = sp.local("rlp_bm", sp.map(tkey=sp.TNat)) + is_error = sp.local("error_in_bmc_message", sp.string("Success")) is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() with sp.if_(is_list_lambda): rlp_bm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() with sp.else_(): decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - rlp_bm.value = sp.view("decode_list", self.data.helper, decode_len, + is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_bm.value = sp.view("decode_list", self.data.helper, decode_len, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - rlp_ = rlp_bm.value + with sp.else_(): + is_error.value = "ErrorInBMCMessageDecoding" temp_map_string = sp.compute(sp.map(tkey=sp.TString, tvalue=sp.TString)) temp_int = sp.local("int_value", 0) temp_byt = sp.local("byt_value", sp.bytes("0x")) - counter = sp.local("counter", 0) - sp.for k in rlp_.items(): - sp.if counter.value == 0: - temp_map_string["src"] = sp.view("decode_string", self.data.helper, k.value, t=sp.TString).open_some() - sp.if counter.value == 1: - temp_map_string["dst"] = sp.view("decode_string", self.data.helper, k.value, t=sp.TString).open_some() - sp.if counter.value == 2: - temp_map_string["svc"] = sp.view("decode_string", self.data.helper, k.value, t=sp.TString).open_some() - sp.if counter.value == 3: - sn_in_bytes = sp.view("without_length_prefix", self.data.helper, k.value, t=sp.TBytes).open_some() - temp_int.value = sp.view("to_int", self.data.helper_parse_negative, sn_in_bytes, t=sp.TInt).open_some() - sp.if counter.value == 4: - temp_byt.value = k.value - counter.value = counter.value + 1 - temp_byt.value = sp.view("without_length_prefix", self.data.helper, temp_byt.value, t=sp.TBytes).open_some() - return sp.record(src=temp_map_string.get("src"), - dst=temp_map_string.get("dst"), - svc=temp_map_string.get("svc"), + with sp.if_(is_error.value == "Success"): + rlp_ = rlp_bm.value + counter = sp.local("counter", 0) + sp.for k in rlp_.items(): + sp.if counter.value == 0: + temp_map_string["src"] = sp.view("decode_string", self.data.helper, k.value, t=sp.TString).open_some() + sp.if counter.value == 1: + temp_map_string["dst"] = sp.view("decode_string", self.data.helper, k.value, t=sp.TString).open_some() + sp.if counter.value == 2: + temp_map_string["svc"] = sp.view("decode_string", self.data.helper, k.value, t=sp.TString).open_some() + sp.if counter.value == 3: + sn_in_bytes = sp.view("without_length_prefix", self.data.helper, k.value, t=sp.TBytes).open_some() + temp_int.value = sp.view("to_int", self.data.helper_parse_negative, sn_in_bytes, t=sp.TInt).open_some() + sp.if counter.value == 4: + temp_byt.value = k.value + counter.value = counter.value + 1 + with sp.if_(is_error.value == "Success"): + temp_byt.value = sp.view("without_length_prefix", self.data.helper, temp_byt.value, t=sp.TBytes).open_some() + + return sp.record(bmc_dec_rv = sp.record(src=temp_map_string.get("src", default_value = "NoKey"), + dst=temp_map_string.get("dst", default_value = "NoKey"), + svc=temp_map_string.get("svc", default_value = "NoKey"), sn=temp_int.value, - message=temp_byt.value) + message=temp_byt.value), + status = is_error.value) def decode_response(self, rlp): sp.set_type(rlp, sp.TBytes) @@ -48,230 +57,272 @@ def decode_response(self, rlp): temp_int = sp.local("int1", sp.nat(0)) temp_byt = sp.local("byt1", sp.bytes("0x")) rlp_dr = sp.local("rlp_dr", sp.map(tkey=sp.TNat)) + is_error = sp.local("error_in_bmc_decode_response", sp.string("Success")) is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() with sp.if_(is_list_lambda): rlp_dr.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - rlp_dr.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_dr.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + is_error.value = "ErrorInDecodingBMCResponse" rlp_ = rlp_dr.value counter = sp.local("counter_response", 0) - sp.for m in rlp_.items(): - sp.if counter.value == 0: - temp_int.value = Utils2.Int.of_bytes(m.value) - sp.if counter.value == 1: - temp_byt.value = m.value - counter.value = counter.value + 1 - - # message in case of error is null which cannot be decoded into string - return sp.record(code=temp_int.value, message="Error") - - def decode_propagate_message(self, rlp): - sp.set_type(rlp, sp.TBytes) + with sp.if_(is_error.value == "Success"): + sp.for m in rlp_.items(): + sp.if counter.value == 0: + temp_int.value = Utils2.Int.of_bytes(m.value) + sp.if counter.value == 1: + temp_byt.value = m.value + counter.value = counter.value + 1 - rlp_pm = sp.local("rlp_pm", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - rlp_pm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - rlp_pm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - rlp_ = rlp_pm.value - counter = sp.local("counter_propagate", 0) - temp_string = sp.local("temp_string", "") - sp.for d in rlp_.items(): - sp.if counter.value == 0: - temp_string.value = sp.view("decode_string", self.data.helper, d.value, t=sp.TString).open_some() - counter.value = counter.value + 1 - return temp_string.value + # message in case of error is null which cannot be decoded into string + return sp.record(code=temp_int.value, message="Error", status = is_error.value) def decode_init_message(self, rlp): sp.set_type(rlp, sp.TBytes) rlp_im = sp.local("rlp_im", sp.map(tkey=sp.TNat)) + is_error = sp.local("error_in_bmc_decode_init_message", sp.string("Success")) is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() with sp.if_(is_list_lambda): rlp_im.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - rlp_im.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - rlp_ = rlp_im.value - counter = sp.local("counter_init", 0) - temp_bytes = sp.local("byt_init", sp.bytes("0x")) - sp.for g in rlp_.items(): - sp.if counter.value == 0: - temp_bytes.value = g.value - counter.value = counter.value + 1 - - sub_list = sp.local("sub_list_init", temp_bytes.value) - nsl_im = sp.local("nsl_im", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - nsl_im.value = sp.view("decode_list", self.data.helper, sub_list.value, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() - nsl_im.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - new_sub_list = nsl_im.value - + decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_im.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + is_error.value = "ErrorInDecodingIniteMessage" _links = sp.local("links_init", [], sp.TList(sp.TString)) - counter.value = 0 - sp.for x in new_sub_list.items(): - _links.value.push(sp.view("decode_string", self.data.helper, x.value, t=sp.TString).open_some()) - counter.value = counter.value + 1 - return _links.value + with sp.if_(is_error.value == "Success"): + rlp_ = rlp_im.value + counter = sp.local("counter_init", 0) + temp_bytes = sp.local("byt_init", sp.bytes("0x")) + sp.for g in rlp_.items(): + sp.if counter.value == 0: + temp_bytes.value = g.value + counter.value = counter.value + 1 + + sub_list = sp.local("sub_list_init", temp_bytes.value) + nsl_im = sp.local("nsl_im", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + nsl_im.value = sp.view("decode_list", self.data.helper, sub_list.value, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, + t=sp.TBytes).open_some() + is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + nsl_im.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + is_error.value = "ErrorInDecodingInitMessage" + + with sp.if_(is_error.value == "Success"): + new_sub_list = nsl_im.value + + counter.value = 0 + sp.for x in new_sub_list.items(): + _links.value.push(sp.view("decode_string", self.data.helper, x.value, t=sp.TString).open_some()) + counter.value = counter.value + 1 + return sp.record(links_list = _links.value, status = is_error.value) def decode_bmc_service(self, rlp): sp.set_type(rlp, sp.TBytes) rlp_bs = sp.local("rlp_bs", sp.map(tkey=sp.TNat)) + is_error = sp.local("error_in_bmc_decode_service", sp.string("Success")) is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() with sp.if_(is_list_lambda): rlp_bs.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() with sp.else_(): decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - rlp_bs.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - rlp_ = rlp_bs.value + is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_bs.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + is_error.value = "ErrorInDecodingBMCService" + temp_string = sp.local("str_value", "") temp_byt = sp.local("byt_value_bmc", sp.bytes("0x")) - counter = sp.local("counter_service", 0) - sp.for b in rlp_.items(): - sp.if counter.value == 0: - temp_string.value = sp.view("decode_string", self.data.helper, b.value, t=sp.TString).open_some() - sp.if counter.value == 1: - temp_byt.value = b.value - counter.value = counter.value + 1 - temp_byt.value = sp.view("without_length_prefix", self.data.helper, temp_byt.value, t=sp.TBytes).open_some() - return sp.record(serviceType=temp_string.value, - payload=temp_byt.value) + with sp.if_(is_error.value == "Success"): + rlp_ = rlp_bs.value + counter = sp.local("counter_service", 0) + sp.for b in rlp_.items(): + sp.if counter.value == 0: + temp_string.value = sp.view("decode_string", self.data.helper, b.value, t=sp.TString).open_some() + sp.if counter.value == 1: + temp_byt.value = b.value + counter.value = counter.value + 1 + temp_byt.value = sp.view("without_length_prefix", self.data.helper, temp_byt.value, t=sp.TBytes).open_some() + return sp.record(bmc_service_rv=sp.record(serviceType=temp_string.value, + payload=temp_byt.value), status = is_error.value) def decode_gather_fee_message(self, rlp): sp.set_type(rlp, sp.TBytes) rlp_gm = sp.local("rlp_gm", sp.map(tkey=sp.TNat)) + is_error = sp.local("error_in_bmc_fee_message", sp.string("Success")) is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() with sp.if_(is_list_lambda): rlp_gm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() with sp.else_(): decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - rlp_gm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - rlp_ = rlp_gm.value - temp_byt = sp.local("byt4", sp.bytes("0x")) - counter = sp.local("counter_gather", 0) + is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_gm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + is_error.value = "ErrorInDecodingFeeMessage" temp_str = sp.local("str_gather", "") - sp.for c in rlp_.items(): - sp.if counter.value == 1: - temp_byt.value = c.value - sp.if counter.value == 0: - temp_str.value = sp.view("decode_string", self.data.helper, c.value, t=sp.TString).open_some() - counter.value = counter.value + 1 - sub_list = sp.local("sub_list", temp_byt.value) - nsl_gm = sp.local("nsl_gm", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - nsl_gm.value = sp.view("decode_list", self.data.helper, sub_list.value, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() - nsl_gm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - new_sub_list = nsl_gm.value - _svcs = sp.local("_svcs", {}, sp.TMap(sp.TNat, sp.TString)) - counter.value = 0 - sp.for x in new_sub_list.items(): - _svcs.value[counter.value] = sp.view("decode_string", self.data.helper, x.value, t=sp.TString).open_some() - counter.value = counter.value + 1 - return sp.record(fa=temp_str.value, - svcs=_svcs.value) + with sp.if_(is_error.value == "Success"): + rlp_ = rlp_gm.value + temp_byt = sp.local("byt4", sp.bytes("0x")) + counter = sp.local("counter_gather", 0) + sp.for c in rlp_.items(): + sp.if counter.value == 1: + temp_byt.value = c.value + sp.if counter.value == 0: + temp_str.value = sp.view("decode_string", self.data.helper, c.value, t=sp.TString).open_some() + counter.value = counter.value + 1 + sub_list = sp.local("sub_list", temp_byt.value) + nsl_gm = sp.local("nsl_gm", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + nsl_gm.value = sp.view("decode_list", self.data.helper, sub_list.value, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() + is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + nsl_gm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + is_error.value = "ErrorInDecodingFeeMessage" + with sp.if_(is_error.value == "Success"): + new_sub_list = nsl_gm.value + + counter.value = 0 + sp.for x in new_sub_list.items(): + _svcs.value[counter.value] = sp.view("decode_string", self.data.helper, x.value, t=sp.TString).open_some() + counter.value = counter.value + 1 + return sp.record(fee_decode_rv = sp.record(fa=temp_str.value, + svcs=_svcs.value), status = is_error.value) def to_message_event(self, rlp): rlp_me = sp.local("rlp_me", sp.map(tkey=sp.TNat)) is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() + is_error = sp.local("error_in_Event_message", sp.string("Success")) with sp.if_(is_list_lambda): rlp_me.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() with sp.else_(): decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - rlp_me.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - rlp_ = rlp_me.value - counter = sp.local("counter_event", 0) + is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_me.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + is_error.value = "ErrorInDecoding" rv1 = sp.local("rv1_event", "") rv2 = sp.local("rv2_event", sp.nat(0)) rv3 = sp.local("rv3_event", sp.bytes("0x")) - sp.for i in rlp_.items(): - sp.if counter.value == 2: - rv3.value = i.value - sp.if counter.value == 0: - rv1.value = sp.view("decode_string", self.data.helper, i.value, t=sp.TString).open_some() - sp.if counter.value == 1: - rv2.value = Utils2.Int.of_bytes(i.value) - counter.value = counter.value + 1 - rv3.value = sp.view("without_length_prefix", self.data.helper, rv3.value, t=sp.TBytes).open_some() - return sp.record(next_bmc= rv1.value, seq= rv2.value, message = rv3.value) + with sp.if_(is_error.value == "Success"): + rlp_ = rlp_me.value + counter = sp.local("counter_event", 0) + sp.for i in rlp_.items(): + sp.if counter.value == 2: + rv3.value = i.value + sp.if counter.value == 0: + rv1.value = sp.view("decode_string", self.data.helper, i.value, t=sp.TString).open_some() + sp.if counter.value == 1: + rv2.value = Utils2.Int.of_bytes(i.value) + counter.value = counter.value + 1 + rv3.value = sp.view("without_length_prefix", self.data.helper, rv3.value, t=sp.TBytes).open_some() + return sp.record(event_rv=sp.record(next_bmc= rv1.value, seq= rv2.value, message = rv3.value), status = is_error.value) def decode_receipt_proof(self, rlp): rlp_rp = sp.local("rlp_rp", sp.map(tkey=sp.TNat)) is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() + is_error = sp.local("error_in_receipt_proof", sp.string("Success")) with sp.if_(is_list_lambda): rlp_rp.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() with sp.else_(): decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - rlp_rp.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - rlp_ = rlp_rp.value - temp_byt = sp.local("byt_receipt", sp.bytes("0x")) + is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_rp.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + is_error.value = "ErrorInDecoding" rv_int = sp.local("rv_int_receipt", 0) rv_int2 = sp.local("rv_int2_receipt", 0) - counter = sp.local("counter", 0) - sp.for i in rlp_.items(): - sp.if counter.value == 1: - temp_byt.value = sp.view("without_length_prefix", self.data.helper, i.value, t=sp.TBytes).open_some() - sp.if counter.value == 0: - rv_int.value = Utils2.Int.of_bytes(i.value) - sp.if counter.value == 2: - wl_prefix = sp.view("without_length_prefix", self.data.helper, i.value, t=sp.TBytes).open_some() - rv_int2.value =Utils2.Int.of_bytes(wl_prefix) - counter.value = counter.value + 1 - - sub_list = sp.local("sub_list", temp_byt.value) - - nsl_rp = sp.local("nsl_rp", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - nsl_rp.value = sp.view("decode_list", self.data.helper, sub_list.value, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() - nsl_rp.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - new_sub_list = nsl_rp.value - counter.value = 0 events = sp.local("events_receipt", sp.map({}, tkey=sp.TNat, - tvalue=sp.TRecord(next_bmc= sp.TString, - seq= sp.TNat, - message = sp.TBytes))) - sp.for z in new_sub_list.items(): - events.value[counter.value] = self.to_message_event(z.value) - counter.value = counter.value + 1 - return sp.record(index = rv_int.value, events = events.value, height = rv_int2.value) + tvalue=sp.TRecord(next_bmc=sp.TString, + seq=sp.TNat,message=sp.TBytes))) + with sp.if_(is_error.value == "Success"): + rlp_ = rlp_rp.value + temp_byt = sp.local("byt_receipt", sp.bytes("0x")) + counter = sp.local("counter", 0) + sp.for i in rlp_.items(): + sp.if counter.value == 1: + temp_byt.value = sp.view("without_length_prefix", self.data.helper, i.value, t=sp.TBytes).open_some() + sp.if counter.value == 0: + rv_int.value = Utils2.Int.of_bytes(i.value) + sp.if counter.value == 2: + wl_prefix = sp.view("without_length_prefix", self.data.helper, i.value, t=sp.TBytes).open_some() + rv_int2.value =Utils2.Int.of_bytes(wl_prefix) + counter.value = counter.value + 1 + + sub_list = sp.local("sub_list", temp_byt.value) + + nsl_rp = sp.local("nsl_rp", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + nsl_rp.value = sp.view("decode_list", self.data.helper, sub_list.value, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() + is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + nsl_rp.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + is_error.value = "ErrorInDecoding" + with sp.if_(is_error.value == "Success"): + new_sub_list = nsl_rp.value + counter.value = 0 + + sp.for z in new_sub_list.items(): + from_event = self.to_message_event(z.value) + with sp.if_(from_event.status == "Success"): + events.value[counter.value] = from_event.event_rv + counter.value = counter.value + 1 + with sp.else_(): + is_error.value = "ErrorInDecoding" + return sp.record(rv = sp.record(index = rv_int.value, events = events.value, height = rv_int2.value), status = is_error.value) def decode_receipt_proofs(self, rlp): sp.set_type(rlp, sp.TBytes) - + is_error = sp.local("error_in_receipt_proofs", sp.string("Success")) rlp_rps = sp.local("rlp_rps", sp.map(tkey=sp.TNat)) is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() with sp.if_(is_list_lambda): rlp_rps.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() with sp.else_(): decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - rlp_rps.value = sp.view("decode_list", self.data.helper, decode_len, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_rps.value = sp.view("decode_list", self.data.helper, decode_len, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + is_error.value = "ErrorInDecoding" rlp_ = rlp_rps.value counter = sp.local("counter_receipt_proofs", 0) receipt_proofs = sp.local("events_receipt_proofs", sp.map({}, tkey=sp.TNat, @@ -294,15 +345,23 @@ def decode_receipt_proofs(self, rlp): nsl_rps.value = sp.view("decode_list", self.data.helper, sub_list.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() with sp.else_(): decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() - nsl_rps.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + nsl_rps.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + is_error.value = "ErrorInDecoding" new_sub_list = nsl_rps.value counter.value = 0 sp.if sp.len(new_sub_list) > 0: sp.for x in new_sub_list.items(): - receipt_proofs.value[counter.value] = self.decode_receipt_proof(x.value) - counter.value = counter.value + 1 - return receipt_proofs.value + from_receipt_proofs = self.decode_receipt_proof(x.value) + with sp.if_(from_receipt_proofs.status == "Success"): + receipt_proofs.value[counter.value] = from_receipt_proofs.rv + counter.value = counter.value + 1 + with sp.else_(): + is_error.value = "ErrorInDecoding" + return sp.record(receipt_proof = receipt_proofs.value, status = is_error.value) # rlp encoding starts here diff --git a/smartpy/bmc/contracts/src/bmc_periphery.py b/smartpy/bmc/contracts/src/bmc_periphery.py index 99948625..7c78e675 100644 --- a/smartpy/bmc/contracts/src/bmc_periphery.py +++ b/smartpy/bmc/contracts/src/bmc_periphery.py @@ -172,37 +172,39 @@ def handle_relay_message(self, prev, msg): rx_seq = sp.local("rx_seq", link_rx_seq, t=sp.TNat) rx_height = sp.local("rx_height", link_rx_height, t=sp.TNat) - rps = self.decode_receipt_proofs(msg) - bmc_msg = sp.local("bmc_msg", sp.record(src="", dst="", svc="", sn=sp.int(0), message=sp.bytes("0x")), t=types.Types.BMCMessage) - ev = sp.local("ev", sp.record(next_bmc="", seq=sp.nat(0), message=sp.bytes("0x")), t=types.Types.MessageEvent) - sp.for i in sp.range(sp.nat(0), sp.len(rps)): - with sp.if_(rps[i].height < rx_height.value): - pass - with sp.else_(): - rx_height.value = rps[i].height - sp.for j in sp.range(sp.nat(0), sp.len(rps[i].events)): - ev.value = rps[i].events[j] - sp.verify(ev.value.next_bmc == self.data.bmc_btp_address.open_some("Address not set"), "Invalid Next BMC") - rx_seq.value +=sp.nat(1) - with sp.if_(ev.value.seq < rx_seq.value): - rx_seq.value = sp.as_nat(rx_seq.value-sp.nat(1)) - with sp.else_(): - sp.if ev.value.seq > rx_seq.value: - sp.failwith(self.BMCRevertInvalidSeqNumber) - - _decoded = self.decode_bmc_message(ev.value.message) - bmc_msg.value = _decoded - - sp.if bmc_msg.value.src != "": - with sp.if_(bmc_msg.value.dst == self.data.bmc_btp_address.open_some("Address not set")): - self._handle_message(prev, bmc_msg.value) - with sp.else_(): - net, addr = sp.match_pair(strings.split_btp_address(bmc_msg.value.dst, "prev_idx", "result", "my_list", "last", "penultimate")) - next_link, prev_link = sp.match_pair(sp.view("resolve_route", self.data.bmc_management, net, t=sp.TPair(sp.TString, sp.TString)).open_some("Invalid Call")) - with sp.if_(next_link != "Unreachable"): - self._send_message(next_link, ev.value.message) + rps_decode = self.decode_receipt_proofs(msg) + with sp.if_(rps_decode.status == "Success"): + rps = rps_decode.receipt_proof + bmc_msg = sp.local("bmc_msg", sp.record(src="", dst="", svc="", sn=sp.int(0), message=sp.bytes("0x")), t=types.Types.BMCMessage) + ev = sp.local("ev", sp.record(next_bmc="", seq=sp.nat(0), message=sp.bytes("0x")), t=types.Types.MessageEvent) + sp.for i in sp.range(sp.nat(0), sp.len(rps)): + with sp.if_(rps[i].height < rx_height.value): + pass + with sp.else_(): + rx_height.value = rps[i].height + sp.for j in sp.range(sp.nat(0), sp.len(rps[i].events)): + ev.value = rps[i].events[j] + sp.verify(ev.value.next_bmc == self.data.bmc_btp_address.open_some("Address not set"), "Invalid Next BMC") + rx_seq.value +=sp.nat(1) + with sp.if_(ev.value.seq < rx_seq.value): + rx_seq.value = sp.as_nat(rx_seq.value-sp.nat(1)) + with sp.else_(): + sp.if ev.value.seq > rx_seq.value: + sp.failwith(self.BMCRevertInvalidSeqNumber) + + _decoded = self.decode_bmc_message(ev.value.message) + bmc_msg.value = _decoded.bmc_dec_rv + with sp.if_(_decoded.status == sp.string("Success")): + with sp.if_(bmc_msg.value.dst == self.data.bmc_btp_address.open_some("Address not set")): + self._handle_message(prev, bmc_msg.value) with sp.else_(): - self._send_error(prev, bmc_msg.value, self.BMC_ERR, "Unreachable_"+ net) + net, addr = sp.match_pair(strings.split_btp_address(bmc_msg.value.dst, "prev_idx", "result", "my_list", "last", "penultimate")) + next_link, prev_link = sp.match_pair(sp.view("resolve_route", self.data.bmc_management, net, t=sp.TPair(sp.TString, sp.TString)).open_some("Invalid Call")) + with sp.if_(next_link != "Unreachable"): + self._send_message(next_link, ev.value.message) + with sp.else_(): + self._send_error(prev, bmc_msg.value, self.BMC_ERR, "Unreachable_"+ net) + # call update_link_rx_seq on BMCManagement update_link_rx_seq_args_type = sp.TRecord(prev=sp.TString, val=sp.TNat) update_link_rx_seq_entry_point = sp.contract(update_link_rx_seq_args_type, @@ -236,17 +238,18 @@ def _handle_message(self, prev, msg): # bsh_addr = sp.local("bsh_addr",sp.TAddress) with sp.if_(msg.svc == "bmc"): sm = sp.local("sm", sp.record(serviceType="", payload=sp.bytes("0x"))) - sm.value = self.decode_bmc_service(msg.message) - with sp.if_(sm.value.serviceType == ""): + _decoded = self.decode_bmc_service(msg.message) + sm.value = _decoded.bmc_service_rv + with sp.if_(_decoded.status != "Success"): self._send_error(prev, msg, self.BMC_ERR, self.BMCRevertParseFailure) with sp.else_(): sp.if sm.value.serviceType == "FeeGathering": gather_fee =sp.local("gather_fee", sp.record(fa="error", svcs=sp.map({0:""}))) - gather_fee.value = self.decode_gather_fee_message(sm.value.payload) + _decoded_value = self.decode_gather_fee_message(sm.value.payload) + gather_fee.value = _decoded_value.fee_decode_rv - with sp.if_(gather_fee.value.fa == "error"): + with sp.if_(_decoded_value.status != "Success"): self._send_error(prev, msg, self.BMC_ERR, self.BMCRevertParseFailure) - with sp.else_(): sp.for c in sp.range(sp.nat(0), sp.len(gather_fee.value.svcs)): bsh_addr = sp.view("get_bsh_service_by_name", self.data.bmc_management, gather_fee.value.svcs[c], t=sp.TAddress).open_some("Invalid Call") @@ -269,7 +272,7 @@ def _handle_message(self, prev, msg): update_link_reachable_entry_point = sp.contract(update_link_reachable_args_type, self.data.bmc_management, "update_link_reachable").open_some() - update_link_reachable_args = sp.record(prev=prev, to=links) + update_link_reachable_args = sp.record(prev=prev, to=links.links_list) sp.transfer(update_link_reachable_args, sp.tez(0), update_link_reachable_entry_point) with sp.else_(): bsh_addr = sp.view("get_bsh_service_by_name", self.data.bmc_management, msg.svc, t=sp.TAddress).open_some("Invalid view") From 63d86a4f7a1805ea62ff642b7709ef45ef86d76a Mon Sep 17 00:00:00 2001 From: suyogadhikari Date: Mon, 26 Jun 2023 15:34:41 +0545 Subject: [PATCH 119/211] perf(bts): try catch added on rlp decoding --- smartpy/bts/contracts/src/RLP_struct.py | 459 +++++++++++---------- smartpy/bts/contracts/src/bts_periphery.py | 158 +++---- 2 files changed, 341 insertions(+), 276 deletions(-) diff --git a/smartpy/bts/contracts/src/RLP_struct.py b/smartpy/bts/contracts/src/RLP_struct.py index defd0451..1404fa6c 100644 --- a/smartpy/bts/contracts/src/RLP_struct.py +++ b/smartpy/bts/contracts/src/RLP_struct.py @@ -11,288 +11,333 @@ def decode_response(self, rlp): temp_int = sp.local("int1", 0) temp_byt = sp.local("byt1", sp.bytes("0x")) + is_error = sp.local("error_in_bts_decode_response", sp.string("Success")) rlp_dr = sp.local("rlp_dr_bts", sp.map(tkey=sp.TNat)) is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() with sp.if_(is_list_lambda): rlp_dr.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() with sp.else_(): decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - rlp_dr.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_dr.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + is_error.value = "ErrorInBTSDecoding" rlp_ = rlp_dr.value counter = sp.local("counter_response", 0) - sp.for i in rlp_.items(): - sp.if counter.value == 0: - # check_length = sp.view("prefix_length", self.data.helper, i.value, t=sp.TNat).open_some() - # with sp.if_(check_length > 0): - # i.value = sp.view("without_length_prefix", self.data.helper, i.value, - # t=sp.TBytes).open_some() - temp_int.value = Utils2.Int.of_bytes(i.value) - sp.if counter.value == 1: - temp_byt.value = i.value - counter.value = counter.value + 1 - - return sp.record(code=temp_int.value, message=sp.view("decode_string", self.data.helper, temp_byt.value, t=sp.TString).open_some()) + msg = sp.local("message_in_bts", sp.string("")) + with sp.if_(is_error.value == "Success"): + sp.for i in rlp_.items(): + sp.if counter.value == 0: + temp_int.value = Utils2.Int.of_bytes(i.value) + sp.if counter.value == 1: + temp_byt.value = i.value + counter.value = counter.value + 1 + msg.value = sp.view("decode_string", self.data.helper, temp_byt.value, t=sp.TString).open_some() + return sp.record(rv = sp.record(code=temp_int.value, message = msg.value),status = is_error.value) def decode_service_message(self, rlp): sp.set_type(rlp, sp.TBytes) rlp_sm = sp.local("rlp_sm_bts", sp.map(tkey=sp.TNat)) + is_error = sp.local("error_in_bts_decode_service_message", sp.string("Success")) is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() with sp.if_(is_list_lambda): rlp_sm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() with sp.else_(): decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - rlp_sm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - rlp_ = rlp_sm.value - temp_int = sp.local("int2", 0) - temp_byt = sp.local("byte1", sp.bytes("0x")) - counter = sp.local("counter", 0) - sp.for i in rlp_.items(): - sp.if counter.value == 0: - # check_length = sp.view("prefix_length", self.data.helper, i.value, t=sp.TNat).open_some() - # with sp.if_(check_length > 0): - # i.value = sp.view("without_length_prefix", self.data.helper, i.value, - # t=sp.TBytes).open_some() - temp_int.value = Utils2.Int.of_bytes(i.value) - sp.if counter.value == 1: - temp_byt.value = i.value - counter.value = counter.value + 1 - + is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_sm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + is_error.value = "ErrorInBTSDecoding" _service_type = sp.local("_service_type", sp.variant("ERROR", sp.nat(10))) - sp.if temp_int.value == 0: - _service_type.value = sp.variant("REQUEST_COIN_TRANSFER", temp_int.value) - sp.if temp_int.value == 1: - _service_type.value = sp.variant("REQUEST_COIN_REGISTER", temp_int.value) - sp.if temp_int.value == 2: - _service_type.value = sp.variant("RESPONSE_HANDLE_SERVICE", temp_int.value) - sp.if temp_int.value == 3: - _service_type.value = sp.variant("BLACKLIST_MESSAGE", temp_int.value) - sp.if temp_int.value == 4: - _service_type.value = sp.variant("CHANGE_TOKEN_LIMIT", temp_int.value) - sp.if temp_int.value == 5: - _service_type.value = sp.variant("UNKNOWN_TYPE", temp_int.value) - temp_byt.value = sp.view("without_length_prefix", self.data.helper, temp_byt.value, t=sp.TBytes).open_some() - - return sp.record(serviceType=_service_type.value, - data=temp_byt.value) + temp_byt = sp.local("byte1", sp.bytes("0x")) + with sp.if_(is_error.value == "Success"): + rlp_ = rlp_sm.value + temp_int = sp.local("int2", 0) + counter = sp.local("counter", 0) + sp.for i in rlp_.items(): + sp.if counter.value == 0: + temp_int.value = Utils2.Int.of_bytes(i.value) + sp.if counter.value == 1: + temp_byt.value = i.value + counter.value = counter.value + 1 + + sp.if temp_int.value == 0: + _service_type.value = sp.variant("REQUEST_COIN_TRANSFER", temp_int.value) + sp.if temp_int.value == 1: + _service_type.value = sp.variant("REQUEST_COIN_REGISTER", temp_int.value) + sp.if temp_int.value == 2: + _service_type.value = sp.variant("RESPONSE_HANDLE_SERVICE", temp_int.value) + sp.if temp_int.value == 3: + _service_type.value = sp.variant("BLACKLIST_MESSAGE", temp_int.value) + sp.if temp_int.value == 4: + _service_type.value = sp.variant("CHANGE_TOKEN_LIMIT", temp_int.value) + sp.if temp_int.value == 5: + _service_type.value = sp.variant("UNKNOWN_TYPE", temp_int.value) + temp_byt.value = sp.view("without_length_prefix", self.data.helper, temp_byt.value, t=sp.TBytes).open_some() + + return sp.record(rv=sp.record(serviceType=_service_type.value, + data=temp_byt.value), status=is_error.value) def decode_transfer_coin_msg(self, rlp): sp.set_type(rlp, sp.TBytes) + is_error = sp.local("error_in_bts_decode_transfer_coin_msg", sp.string("Success")) rlp_tcm = sp.local("rlp_tcm_bts", sp.map(tkey=sp.TNat)) is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() with sp.if_(is_list_lambda): rlp_tcm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() with sp.else_(): decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - rlp_tcm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_tcm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + is_error.value = "ErrorInBTSDecoding" rlp_ = rlp_tcm.value temp_byt = sp.local("byt_transfer", sp.bytes("0x")) rv1_byt = sp.local("rv1_byt", sp.bytes("0x")) rv2_byt = sp.local("rv2_byt", sp.bytes("0x")) counter = sp.local("counter_coin", sp.nat(0)) - sp.for i in rlp_.items(): - sp.if counter.value == 2: - temp_byt.value = i.value - sp.if counter.value == 0: - rv1_byt.value = i.value - sp.if counter.value == 1: - rv2_byt.value = i.value - counter.value = counter.value + 1 - sub_list = sp.local("sub_list", temp_byt.value) - nsl_tcm = sp.local("nsl_bts_tcm", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - nsl_tcm.value = sp.view("decode_list", self.data.helper, sub_list.value, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() - nsl_tcm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - new_sub_list = nsl_tcm.value - counter.value = 0 - new_temp_byt = sp.local("new_temp_byt", sp.bytes("0x")) + rv1 = sp.local("rv1_bts_transfer_coin", sp.string("")) + rv2 = sp.local("rv2_bts_transfer_coin", sp.string("")) rv_assets = sp.local("assets", {}, sp.TMap(sp.TNat, types.Types.Asset)) - nsl3_tcm = sp.local("nsl3_bts_tcm", sp.map(tkey=sp.TNat)) - view_value = sp.local("view_value", sp.map(tkey=sp.TNat)) - counter_nested = sp.local("counter_nested", sp.nat(0), t=sp.TNat) - temp_byt = sp.local("tempByt2", sp.bytes("0x")) - temp_byt_nested = sp.local("tempByt2nested", sp.bytes("0x")) - sp.for x in new_sub_list.items(): - new_temp_byt.value = x.value - # sp.if sp.slice(new_temp_byt.value, 0, 2).open_some() == sp.bytes("0xb846"): - # new_temp_byt.value = sp.slice(new_temp_byt.value, 2, sp.as_nat(sp.len(new_temp_byt.value) - 2)).open_some() - is_list_lambda = sp.view("is_list", self.data.helper, new_temp_byt.value, - t=sp.TBool).open_some() + with sp.if_(is_error.value == "Success"): + sp.for i in rlp_.items(): + sp.if counter.value == 2: + temp_byt.value = i.value + sp.if counter.value == 0: + rv1_byt.value = i.value + sp.if counter.value == 1: + rv2_byt.value = i.value + counter.value = counter.value + 1 + sub_list = sp.local("sub_list", temp_byt.value) + nsl_tcm = sp.local("nsl_bts_tcm", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() with sp.if_(is_list_lambda): - nsl3_tcm.value = sp.view("decode_list", self.data.helper, new_temp_byt.value, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + nsl_tcm.value = sp.view("decode_list", self.data.helper, sub_list.value, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, new_temp_byt.value, - t=sp.TBytes).open_some() - nsl3_tcm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - view_value.value = nsl3_tcm.value - counter_nested.value = sp.nat(0) - sp.for i in view_value.value.items(): - sp.if counter_nested.value == 1: - # check_length = sp.view("prefix_length", self.data.helper, i.value, t=sp.TNat).open_some() - # with sp.if_ (check_length > 0): - temp_byt_nested.value = sp.view("without_length_prefix", self.data.helper, i.value, - t=sp.TBytes).open_some() - sp.if counter_nested.value == 0: - temp_byt.value = i.value - counter_nested.value += 1 - - rv_assets.value[counter.value] = sp.record(coin_name=sp.view("decode_string", self.data.helper, temp_byt.value, t=sp.TString).open_some() - , value=Utils2.Int.of_bytes(temp_byt_nested.value)) - - counter.value = counter.value + 1 - - rv1 = sp.view("decode_string", self.data.helper, rv1_byt.value, t=sp.TString).open_some() - rv2 = sp.view("decode_string", self.data.helper, rv2_byt.value, t=sp.TString).open_some() - return sp.record(from_addr= rv1, to = rv2 , assets = rv_assets.value) + decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() + is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + nsl_tcm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + is_error.value = "ErrorInBTSDecoding" + with sp.if_(is_error.value == "Success"): + new_sub_list = nsl_tcm.value + counter.value = 0 + new_temp_byt = sp.local("new_temp_byt", sp.bytes("0x")) + nsl3_tcm = sp.local("nsl3_bts_tcm", sp.map(tkey=sp.TNat)) + view_value = sp.local("view_value", sp.map(tkey=sp.TNat)) + counter_nested = sp.local("counter_nested", sp.nat(0), t=sp.TNat) + temp_byt = sp.local("tempByt2", sp.bytes("0x")) + temp_byt_nested = sp.local("tempByt2nested", sp.bytes("0x")) + sp.for x in new_sub_list.items(): + new_temp_byt.value = x.value + is_list_lambda = sp.view("is_list", self.data.helper, new_temp_byt.value, + t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + nsl3_tcm.value = sp.view("decode_list", self.data.helper, new_temp_byt.value, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, new_temp_byt.value, + t=sp.TBytes).open_some() + is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + nsl3_tcm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + is_error.value = "ErrorInBTSDecoding" + with sp.if_(is_error.value == "Success"): + view_value.value = nsl3_tcm.value + counter_nested.value = sp.nat(0) + sp.for i in view_value.value.items(): + sp.if counter_nested.value == 1: + temp_byt_nested.value = sp.view("without_length_prefix", self.data.helper, i.value, + t=sp.TBytes).open_some() + sp.if counter_nested.value == 0: + temp_byt.value = i.value + counter_nested.value += 1 + + rv_assets.value[counter.value] = sp.record(coin_name=sp.view("decode_string", self.data.helper, temp_byt.value, t=sp.TString).open_some() + , value=Utils2.Int.of_bytes(temp_byt_nested.value)) + + counter.value = counter.value + 1 + + rv1.value = sp.view("decode_string", self.data.helper, rv1_byt.value, t=sp.TString).open_some() + rv2.value = sp.view("decode_string", self.data.helper, rv2_byt.value, t=sp.TString).open_some() + return sp.record(value=sp.record(from_addr= rv1.value, to = rv2.value, assets = rv_assets.value), status = is_error.value) def decode_blacklist_msg(self, rlp): sp.set_type(rlp, sp.TBytes) rlp_bm = sp.local("rlp_bm_bts", sp.map(tkey=sp.TNat)) + is_error = sp.local("error_in_bts_decode_blacklist_message", sp.string("Success")) is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() + _service_type = sp.local("_service_type_blacklist", sp.variant("ERROR", sp.nat(10))) + rv_blacklist_address = sp.local("blacklist_data", {}, sp.TMap(sp.TNat, sp.TString)) with sp.if_(is_list_lambda): rlp_bm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() with sp.else_(): decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - rlp_bm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_bm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + is_error.value = "ErrorInBTSDecoding" rlp_ = rlp_bm.value temp_byt = sp.local("byt_transfer", sp.bytes("0x")) rv1_byt = sp.local("rv1_byt", sp.bytes("0x")) rv2_byt = sp.local("rv2_byt", sp.bytes("0x")) counter = sp.local("counter_blacklist", sp.nat(0)) - sp.for i in rlp_.items(): - sp.if counter.value == 2: - rv2_byt.value = i.value - sp.if counter.value == 0: - rv1_byt.value = i.value - sp.if counter.value == 1: - temp_byt.value = i.value - counter.value = counter.value + 1 - sub_list = sp.local("sub_list", temp_byt.value) - nsl_bm = sp.local("nsl_bts_bm", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - nsl_bm.value = sp.view("decode_list", self.data.helper, sub_list.value, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() - nsl_bm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - new_sub_list = nsl_bm.value - counter.value = 0 - new_temp_byt = sp.local("new_temp_byt", sp.bytes("0x")) - rv_blacklist_address = sp.local("blacklist_data", {}, sp.TMap(sp.TNat, sp.TString)) - addr_string = sp.local("addr_string", "") - nsl2_bm = sp.local("nsl2_bts_bm", sp.map(tkey=sp.TNat)) - counter.value = 0 - sp.for x in new_sub_list.items(): - new_temp_byt.value = x.value - # sp.if sp.slice(new_temp_byt.value, 0, 2).open_some() == sp.bytes("0xb846"): - # new_temp_byt.value = sp.slice(new_temp_byt.value, 2, sp.as_nat(sp.len(new_temp_byt.value) - 2)).open_some() - is_list_lambda = sp.view("is_list", self.data.helper, new_temp_byt.value, - t=sp.TBool).open_some() + with sp.if_(is_error.value == "Success"): + sp.for i in rlp_.items(): + sp.if counter.value == 2: + rv2_byt.value = i.value + sp.if counter.value == 0: + rv1_byt.value = i.value + sp.if counter.value == 1: + temp_byt.value = i.value + counter.value = counter.value + 1 + sub_list = sp.local("sub_list", temp_byt.value) + nsl_bm = sp.local("nsl_bts_bm", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() with sp.if_(is_list_lambda): - nsl2_bm.value = sp.view("decode_list", self.data.helper, new_temp_byt.value, + nsl_bm.value = sp.view("decode_list", self.data.helper, sub_list.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, new_temp_byt.value, t=sp.TBytes).open_some() - addr_string.value = sp.view("decode_string", self.data.helper, decode_len, - t=sp.TString).open_some() - # _decode_list = nsl2_bm.value - # sp.for j in _decode_list.items(): - rv_blacklist_address.value[counter.value] = addr_string.value - counter.value = counter.value + 1 - check_length = sp.view("prefix_length", self.data.helper, rv1_byt.value, t=sp.TNat).open_some() - with sp.if_(check_length > 0): - rv1_byt.value = sp.view("without_length_prefix", self.data.helper, rv1_byt.value, - t=sp.TBytes).open_some() - rv1 = Utils2.Int.of_bytes(rv1_byt.value) - rv2 = sp.view("decode_string", self.data.helper, rv2_byt.value, t=sp.TString).open_some() - _service_type = sp.local("_service_type_blacklist", sp.variant("ERROR", sp.nat(10))) - with sp.if_(rv1 == 0): - _service_type.value = sp.variant("ADD_TO_BLACKLIST", rv1) - with sp.else_(): - _service_type.value = sp.variant("REMOVE_FROM_BLACKLIST", rv1) - return sp.record(serviceType = _service_type.value , addrs = rv_blacklist_address.value , net = rv2) + decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() + is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + nsl_bm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + is_error.value = "ErrorInBTSDecoding" + with sp.if_(is_error.value == "Success"): + new_sub_list = nsl_bm.value + counter.value = 0 + new_temp_byt = sp.local("new_temp_byt", sp.bytes("0x")) + addr_string = sp.local("addr_string", "") + # nsl2_bm = sp.local("nsl2_bts_bm", sp.map(tkey=sp.TNat)) + counter.value = 0 + sp.for x in new_sub_list.items(): + new_temp_byt.value = x.value + # is_list_lambda = sp.view("is_list", self.data.helper, new_temp_byt.value, + # t=sp.TBool).open_some() + # with sp.if_(is_list_lambda): + # nsl2_bm.value = sp.view("decode_list", self.data.helper, new_temp_byt.value, + # t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + # with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, new_temp_byt.value, t=sp.TBytes).open_some() + addr_string.value = sp.view("decode_string", self.data.helper, decode_len, + t=sp.TString).open_some() + rv_blacklist_address.value[counter.value] = addr_string.value + counter.value = counter.value + 1 + # check_length = sp.view("prefix_length", self.data.helper, rv1_byt.value, t=sp.TNat).open_some() + # with sp.if_(check_length > 0): + rv1_byt.value = sp.view("without_length_prefix", self.data.helper, rv1_byt.value, + t=sp.TBytes).open_some() + rv1 = Utils2.Int.of_bytes(rv1_byt.value) + rv2 = sp.view("decode_string", self.data.helper, rv2_byt.value, t=sp.TString).open_some() + with sp.if_(rv1 == 0): + _service_type.value = sp.variant("ADD_TO_BLACKLIST", rv1) + with sp.else_(): + _service_type.value = sp.variant("REMOVE_FROM_BLACKLIST", rv1) + return sp.record(rv=sp.record(serviceType = _service_type.value , addrs = rv_blacklist_address.value , + net = rv2), status = is_error.value) def decode_token_limit_msg(self, rlp): sp.set_type(rlp, sp.TBytes) rlp_tlm = sp.local("rlp_tlm_bts", sp.map(tkey=sp.TNat)) is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() + is_error = sp.local("error_in_bts_decode_token_limit_msg", sp.string("Success")) with sp.if_(is_list_lambda): rlp_tlm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() with sp.else_(): decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - rlp_tlm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + rlp_tlm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + is_error.value = "ErrorInBTSDecoding" rlp_ = rlp_tlm.value temp_byt = sp.local("byt_transfer", sp.bytes("0x")) temp_byt1 = sp.local("byt_transfer_temp1", sp.bytes("0x")) rv1_byt = sp.local("rv1_byt", sp.bytes("0x")) counter = sp.local("counter_token_limit", sp.nat(0)) - sp.for i in rlp_.items(): - sp.if counter.value == 0: - temp_byt.value = i.value - sp.if counter.value == 1: - temp_byt1.value = i.value - sp.if counter.value == 2: - rv1_byt.value = i.value - counter.value = counter.value + 1 - sub_list = sp.local("sub_list", temp_byt.value) - sub_list_limit = sp.local("sub_list_limit", temp_byt1.value) - nsl1_dtlm = sp.local("nsl1_bts_dtlm", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - nsl1_dtlm.value = sp.view("decode_list", self.data.helper, sub_list.value, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() - nsl1_dtlm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - new_sub_list = nsl1_dtlm.value - counter.value = 0 + net = sp.local("network", sp.string("")) rv_names = sp.local("names", {}, sp.TMap(sp.TNat, sp.TString)) rv_limit = sp.local("limit", {}, sp.TMap(sp.TNat, sp.TNat)) - sp.for x in new_sub_list.items(): - rv_names.value[counter.value] = sp.view("decode_string", self.data.helper, x.value, t=sp.TString).open_some() - counter.value += 1 - nsl_dtlm = sp.local("nsl_bts_dtlm", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() - counter.value = 0 - with sp.if_(is_list_lambda): - nsl_dtlm.value = sp.view("decode_list", self.data.helper, sub_list_limit.value, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, sub_list_limit.value, t=sp.TBytes).open_some() - nsl_dtlm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - new_sub_list1 = nsl_dtlm.value - limit = sp.local("limit_val", sp.bytes("0x"), t=sp.TBytes) - sp.for y in new_sub_list1.items(): - check_length = sp.view("prefix_length", self.data.helper, y.value, t=sp.TNat).open_some() - with sp.if_(check_length > 0): - limit.value = sp.view("without_length_prefix", self.data.helper, y.value, - t=sp.TBytes).open_some() - rv_limit.value[counter.value] = Utils2.Int.of_bytes(limit.value) - counter.value += 1 - return sp.record(coin_name = rv_names.value, token_limit = rv_limit.value , - net = sp.view("decode_string", self.data.helper, rv1_byt.value, t=sp.TString).open_some()) + with sp.if_(is_error.value == "Success"): + sp.for i in rlp_.items(): + sp.if counter.value == 0: + temp_byt.value = i.value + sp.if counter.value == 1: + temp_byt1.value = i.value + sp.if counter.value == 2: + rv1_byt.value = i.value + counter.value = counter.value + 1 + sub_list = sp.local("sub_list", temp_byt.value) + net.value = sp.view("decode_string", self.data.helper, rv1_byt.value, t=sp.TString).open_some() + sub_list_limit = sp.local("sub_list_limit", temp_byt1.value) + nsl1_dtlm = sp.local("nsl1_bts_dtlm", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + nsl1_dtlm.value = sp.view("decode_list", self.data.helper, sub_list.value, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() + is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + nsl1_dtlm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + is_error.value = "ErrorInBTSDecoding" + new_sub_list = nsl1_dtlm.value + counter.value = 0 + with sp.if_(is_error.value == "Success"): + sp.for x in new_sub_list.items(): + rv_names.value[counter.value] = sp.view("decode_string", self.data.helper, x.value, t=sp.TString).open_some() + counter.value += 1 + nsl_dtlm = sp.local("nsl_bts_dtlm", sp.map(tkey=sp.TNat)) + is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() + counter.value = 0 + with sp.if_(is_list_lambda): + nsl_dtlm.value = sp.view("decode_list", self.data.helper, sub_list_limit.value, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + decode_len = sp.view("without_length_prefix", self.data.helper, sub_list_limit.value, t=sp.TBytes).open_some() + is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() + with sp.if_(is_list_lambda): + nsl_dtlm.value = sp.view("decode_list", self.data.helper, decode_len, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + with sp.else_(): + is_error.value = "ErrorInBTSDecoding" + with sp.if_(is_error.value == "Success"): + new_sub_list1 = nsl_dtlm.value + limit = sp.local("limit_val", sp.bytes("0x"), t=sp.TBytes) + sp.for y in new_sub_list1.items(): + # check_length = sp.view("prefix_length", self.data.helper, y.value, t=sp.TNat).open_some() + # with sp.if_(check_length > 0): + limit.value = sp.view("without_length_prefix", self.data.helper, y.value, + t=sp.TBytes).open_some() + rv_limit.value[counter.value] = Utils2.Int.of_bytes(limit.value) + counter.value += 1 + return sp.record(rv = sp.record(coin_name = rv_names.value, token_limit = rv_limit.value , + net = net.value), status = is_error.value) # encoding starts here diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index 3b0dac03..9569f175 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -248,82 +248,102 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, bsh_addr, prev, call callback_string = sp.local("callback_string", "") with sp.if_((svc == self.service_name) & (check_caller == "Authorized")): err_msg = sp.local("error", "") - sm = self.decode_service_message(msg) - - with sm.serviceType.match_cases() as arg: - with arg.match("REQUEST_COIN_TRANSFER") as a1: - callback_string.value = "success" - tc = self.decode_transfer_coin_msg(sm.data) - parsed_addr = sp.view("str_to_addr", self.data.parse_contract, tc.to, t=sp.TAddress).open_some() - - with sp.if_(parsed_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): - handle_request_call = self._handle_request_service(tc.to, tc.assets) - with sp.if_(handle_request_call == "success"): - self.send_response_message(sp.variant("RESPONSE_HANDLE_SERVICE", 2), sp.nat(2), _from, sn, "", self.RC_OK) - sp.emit(sp.record(from_address=_from, to=parsed_addr, serial_no=self.data.serial_no, assets_details=tc.assets), tag="TransferReceived") + decode_call = self.decode_service_message(msg) + with sp.if_(decode_call.status == "Success"): + sm = decode_call.rv + + with sm.serviceType.match_cases() as arg: + with arg.match("REQUEST_COIN_TRANSFER") as a1: + callback_string.value = "success" + tc_call = self.decode_transfer_coin_msg(sm.data) + with sp.if_(tc_call.status == "Success"): + tc = tc_call.value + parsed_addr = sp.view("str_to_addr", self.data.parse_contract, tc.to, t=sp.TAddress).open_some() + + with sp.if_(parsed_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): + handle_request_call = self._handle_request_service(tc.to, tc.assets) + with sp.if_(handle_request_call == "success"): + self.send_response_message(sp.variant("RESPONSE_HANDLE_SERVICE", 2), sp.nat(2), _from, sn, "", self.RC_OK) + sp.emit(sp.record(from_address=_from, to=parsed_addr, serial_no=self.data.serial_no, assets_details=tc.assets), tag="TransferReceived") + with sp.else_(): + err_msg.value = handle_request_call + self.send_response_message(sp.variant("RESPONSE_HANDLE_SERVICE", 2), sp.nat(2), _from, sn, err_msg.value, + self.RC_ERR) + with sp.else_(): + err_msg.value = "InvalidAddress" + self.send_response_message(sp.variant("RESPONSE_HANDLE_SERVICE", 2), sp.nat(2), _from, sn, err_msg.value, self.RC_ERR) with sp.else_(): - err_msg.value = handle_request_call - self.send_response_message(sp.variant("RESPONSE_HANDLE_SERVICE", 2), sp.nat(2), _from, sn, err_msg.value, - self.RC_ERR) - with sp.else_(): - err_msg.value = "InvalidAddress" - self.send_response_message(sp.variant("RESPONSE_HANDLE_SERVICE", 2), sp.nat(2), _from, sn, err_msg.value, self.RC_ERR) - - with arg.match("BLACKLIST_MESSAGE") as a2: - callback_string.value = "success" - bm = self.decode_blacklist_msg(sm.data) - addresses = bm.addrs - - with bm.serviceType.match_cases() as b_agr: - with b_agr.match("ADD_TO_BLACKLIST") as b_val_1: - add_blacklist_call = self._add_to_blacklist(addresses) - with sp.if_(add_blacklist_call == "success"): - self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, sn, "AddedToBlacklist", self.RC_OK) + callback_string.value = "ErrorInDecodingTransferCoin" + + with arg.match("BLACKLIST_MESSAGE") as a2: + callback_string.value = "success" + bm_call = self.decode_blacklist_msg(sm.data) + with sp.if_(bm_call.status == "Success"): + bm = bm_call.rv + addresses = bm.addrs + + with bm.serviceType.match_cases() as b_agr: + with b_agr.match("ADD_TO_BLACKLIST") as b_val_1: + add_blacklist_call = self._add_to_blacklist(addresses) + with sp.if_(add_blacklist_call == "success"): + self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, sn, "AddedToBlacklist", self.RC_OK) + with sp.else_(): + self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, sn, "ErrorAddToBlackList", self.RC_ERR) + + with b_agr.match("REMOVE_FROM_BLACKLIST") as b_val_2: + remove_blacklist_call = self._remove_from_blacklist(addresses) + with sp.if_(remove_blacklist_call == "success"): + self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, sn, "RemovedFromBlacklist", self.RC_OK) + with sp.else_(): + self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, sn, "ErrorRemoveFromBlackList", self.RC_ERR) + + with b_agr.match("ERROR") as b_val_2: + self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, sn, "BlacklistServiceTypeErr", self.RC_ERR) + with sp.else_(): + callback_string.value = "ErrorInDecodingBlacklist" + + with arg.match("CHANGE_TOKEN_LIMIT") as a3: + callback_string.value = "success" + tl_call = self.decode_token_limit_msg(sm.data) + with sp.if_(tl_call.status == "Success"): + tl = tl_call.rv + coin_names = tl.coin_name + token_limits = tl.token_limit + + set_limit_call = self._set_token_limit(coin_names, token_limits) + with sp.if_(set_limit_call == "success"): + self.send_response_message(sp.variant("CHANGE_TOKEN_LIMIT", 4), sp.nat(4), _from, sn, "ChangeTokenLimit", self.RC_OK) with sp.else_(): - self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, sn, "ErrorAddToBlackList", self.RC_ERR) - - with b_agr.match("REMOVE_FROM_BLACKLIST") as b_val_2: - remove_blacklist_call = self._remove_from_blacklist(addresses) - with sp.if_(remove_blacklist_call == "success"): - self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, sn, "RemovedFromBlacklist", self.RC_OK) + self.send_response_message(sp.variant("CHANGE_TOKEN_LIMIT", 4), sp.nat(4), _from, sn, "ErrorChangeTokenLimit", self.RC_ERR) + with sp.else_(): + callback_string.value = "ErrorInDecodingTokenLimit" + + with arg.match("RESPONSE_HANDLE_SERVICE") as a4: + with sp.if_(sp.len(sp.pack(self.data.requests.get(sn).from_)) != 0): + fn_call = self.decode_response(sm.data) + response = fn_call.rv + with sp.if_(fn_call.status == "Success"): + handle_response = self.handle_response_service(sn, response.code, response.message) + with sp.if_(handle_response == "success"): + callback_string.value = "success" + with sp.else_(): + callback_string.value = "fail" with sp.else_(): - self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, sn, "ErrorRemoveFromBlackList", self.RC_ERR) - - with b_agr.match("ERROR") as b_val_2: - self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, sn, "BlacklistServiceTypeErr", self.RC_ERR) - - with arg.match("CHANGE_TOKEN_LIMIT") as a3: - callback_string.value = "success" - tl = self.decode_token_limit_msg(sm.data) - coin_names = tl.coin_name - token_limits = tl.token_limit - - set_limit_call = self._set_token_limit(coin_names, token_limits) - with sp.if_(set_limit_call == "success"): - self.send_response_message(sp.variant("CHANGE_TOKEN_LIMIT", 4), sp.nat(4), _from, sn, "ChangeTokenLimit", self.RC_OK) - with sp.else_(): - self.send_response_message(sp.variant("CHANGE_TOKEN_LIMIT", 4), sp.nat(4), _from, sn, "ErrorChangeTokenLimit", self.RC_ERR) - - with arg.match("RESPONSE_HANDLE_SERVICE") as a4: - with sp.if_(sp.len(sp.pack(self.data.requests.get(sn).from_)) != 0): - response = self.decode_response(sm.data) - handle_response = self.handle_response_service(sn, response.code, response.message) - with sp.if_(handle_response == "success"): - callback_string.value = "success" + callback_string.value = "ErrorInDecoding" with sp.else_(): - callback_string.value = "fail" - with sp.else_(): - callback_string.value = "InvalidSN" + callback_string.value = "InvalidSN" - with arg.match("UNKNOWN_TYPE") as a5: - callback_string.value = "success" - sp.emit(sp.record(_from=_from, sn=sn), tag= "UnknownResponse") + with arg.match("UNKNOWN_TYPE") as a5: + callback_string.value = "success" + sp.emit(sp.record(_from=_from, sn=sn), tag= "UnknownResponse") - with arg.match("ERROR") as a5: - callback_string.value = "success" - self.send_response_message(sp.variant("UNKNOWN_TYPE", 5), sp.nat(5), _from, sn, "Unknown",self.RC_ERR) + with arg.match("ERROR") as a5: + callback_string.value = "success" + self.send_response_message(sp.variant("UNKNOWN_TYPE", 5), sp.nat(5), _from, sn, "Unknown",self.RC_ERR) + with sp.else_(): + callback_string.value = "ErrorInDecoding" with sp.else_(): - callback_string.value = "fail" + callback_string.value = "UnAuthorized" return_value = sp.record(string=sp.some(callback_string.value), bsh_addr=bsh_addr, prev=prev, callback_msg=callback_msg) From 1eb70e00a396d18fa9f4213c160afc2052bbf179 Mon Sep 17 00:00:00 2001 From: suyogadhikari Date: Mon, 26 Jun 2023 15:35:26 +0545 Subject: [PATCH 120/211] fix(bts): get_balance_of used instead of balance_of --- smartpy/bts/contracts/src/bts_core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smartpy/bts/contracts/src/bts_core.py b/smartpy/bts/contracts/src/bts_core.py index 3fc519b5..17c6a975 100644 --- a/smartpy/bts/contracts/src/bts_core.py +++ b/smartpy/bts/contracts/src/bts_core.py @@ -222,7 +222,7 @@ def balance_of(self, params): user_balance=sp.nat(0))) with sp.else_(): fa2_address = self.data.coins.get(params.coin_name) - user_balance= sp.view("balance_of", fa2_address, sp.record(owner=params.owner, token_id=sp.nat(0)), t=sp.TNat).open_some("Invalid view") + user_balance= sp.view("get_balance_of", fa2_address, [sp.record(owner=params.owner, token_id=sp.nat(0))], t=sp.TNat).open_some("Invalid view") allowance = sp.view("get_allowance", fa2_address, sp.record(spender=sp.self_address, owner=params.owner), t=sp.TNat).open_some("Invalid view") usable_balance = sp.local("usable_balance", allowance, t=sp.TNat) From ebcc23e43543bac2ac1128d42ddecbec70ff4722 Mon Sep 17 00:00:00 2001 From: suyogadhikari Date: Mon, 26 Jun 2023 15:35:45 +0545 Subject: [PATCH 121/211] fix(bts): removed balance_of function --- smartpy/bts/contracts/src/FA2_contract.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/smartpy/bts/contracts/src/FA2_contract.py b/smartpy/bts/contracts/src/FA2_contract.py index fbdcff60..151f4e8c 100644 --- a/smartpy/bts/contracts/src/FA2_contract.py +++ b/smartpy/bts/contracts/src/FA2_contract.py @@ -32,11 +32,6 @@ def __init__(self, admin, metadata, token_metadata): def is_admin(self, address): sp.result(address == self.data.administrator) - @sp.onchain_view() - def balance_of(self, param): - sp.set_type(param, sp.TRecord(owner=sp.TAddress, token_id=sp.TNat)) - sp.result(self.balance_(param.owner, param.token_id)) - @sp.entry_point def set_allowance(self, batch): sp.set_type(batch, sp.TList(sp.TRecord(spender=sp.TAddress, amount=sp.TNat))) From 3c5bd9bb8ced3cbc188f3e0c0ff6b148d0bf657f Mon Sep 17 00:00:00 2001 From: icondev22 Date: Tue, 27 Jun 2023 12:31:54 +0545 Subject: [PATCH 122/211] feat: added consensus key getter for alternate wallets --- cmd/iconbridge/chain/tezos/verifier.go | 109 +++++++++++++++---------- 1 file changed, 64 insertions(+), 45 deletions(-) diff --git a/cmd/iconbridge/chain/tezos/verifier.go b/cmd/iconbridge/chain/tezos/verifier.go index 5bad00b8..de07f1f2 100644 --- a/cmd/iconbridge/chain/tezos/verifier.go +++ b/cmd/iconbridge/chain/tezos/verifier.go @@ -3,6 +3,8 @@ package tezos import ( "errors" "fmt" + "io/ioutil" + "net/http" "sync" "context" @@ -19,7 +21,7 @@ type IVerifier interface { Update(ctx context.Context, header *rpc.BlockHeader, block *rpc.Block) error ParentHash() tezos.BlockHash IsValidator(proposer tezos.Address, height int64) bool - Height() int64 + Height() int64 } type Verifier struct{ @@ -34,7 +36,7 @@ type Verifier struct{ c *rpc.Client } -func (vr *Verifier) Next() int64{ +func (vr *Verifier) Next() int64 { vr.mu.RLock() defer vr.mu.RUnlock() return vr.next @@ -52,27 +54,26 @@ func (vr *Verifier) Verify(ctx context.Context, header *rpc.BlockHeader, block * if currentFittness < vr.parentFittness { return fmt.Errorf("Invalid block fittness", currentFittness) } - + previousHashInBlock := header.Predecessor if previousHashInBlock.String() != vr.parentHash.String() { return fmt.Errorf("Invalid block hash", header.Level) } - - // isValidSignature, err := vr.VerifySignature(ctx, proposer, header.Signature, header.Level, header, c) + isValidSignature, err := vr.VerifySignature(ctx, proposer, header.Signature, header.Level, header, c) + + if !isValidSignature { + return fmt.Errorf("Invalid block hash. Signature mismatch") + } - // if !isValidSignature { - // return fmt.Errorf("Invalid block hash. Signature mismatch") - // } - // err = vr.verifyEndorsement(block.Operations, vr.c, block.GetLevel()) // if err != nil { - // return err + // return err // } - return nil + return nil } func (vr *Verifier) Update(ctx context.Context, header *rpc.BlockHeader, block *rpc.Block) error { @@ -97,7 +98,7 @@ func (vr *Verifier) Update(ctx context.Context, header *rpc.BlockHeader, block * vr.updateValidatorsAndCycle(ctx, block.Header.Level, block.Metadata.LevelInfo.Cycle) } - return nil + return nil } func (vr *Verifier) ParentHash() tezos.BlockHash { @@ -119,34 +120,33 @@ func (vr *Verifier) IsValidator(proposer tezos.Address, height int64) bool { } func (vr *Verifier) VerifySignature(ctx context.Context, proposer tezos.Address, signature tezos.Signature, blockLevel int64, header *rpc.BlockHeader, c *rpc.Client) (bool, error) { - exposedPublicKey, err := c.GetManagerKey(ctx, proposer, rpc.BlockLevel(blockLevel)) + exposedPublicKey, err := vr.GetConsensusKey(ctx, c, proposer) + if err != nil { - return false, err + return false, err } // c.ListBakingRights() blockHeader := codec.BlockHeader{ - Level: int32(header.Level), - Proto: byte(header.Proto), - Predecessor: header.Predecessor, - Timestamp: header.Timestamp, - ValidationPass: byte(header.ValidationPass), - OperationsHash: header.OperationsHash, - Fitness: header.Fitness, - Context: header.Context, - PayloadHash: header.PayloadHash, - PayloadRound: header.PayloadRound, - ProofOfWorkNonce: header.ProofOfWorkNonce, - LbToggleVote: header.LbVote(), - // SeedNonceHash: block.Metadata.NonceHash, - ChainId: &header.ChainId, + Level: int32(header.Level), + Proto: byte(header.Proto), + Predecessor: header.Predecessor, + Timestamp: header.Timestamp, + ValidationPass: byte(header.ValidationPass), + OperationsHash: header.OperationsHash, + Fitness: header.Fitness, + Context: header.Context, + PayloadHash: header.PayloadHash, + PayloadRound: header.PayloadRound, + ProofOfWorkNonce: header.ProofOfWorkNonce, + LbToggleVote: header.LbVote(), + // SeedNonceHash: block.Metadata.NonceHash, + ChainId: &header.ChainId, } - digestedHash := blockHeader.Digest() - err = exposedPublicKey.Verify(digestedHash[:], header.Signature) if err != nil { @@ -154,12 +154,31 @@ func (vr *Verifier) VerifySignature(ctx context.Context, proposer tezos.Address, return false, err } - return true, nil + return true, nil +} + +func (vr *Verifier) GetConsensusKey(ctx context.Context, c *rpc.Client, bakerConsensusKey tezos.Address) (tezos.Key, error){ + url := c.BaseURL.String() + "/chains/main/blocks/head/context/raw/json/contracts/index/" + bakerConsensusKey.String() + "/consensus_key/active" + + fmt.Println(c.BaseURL) + + resp, err := http.Get(url) + fmt.Println(resp.Body) + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return tezos.Key{}, err + } + //Convert the body to type string + sb := string(body) + + exposedPublicKey := tezos.MustParseKey(sb) + return exposedPublicKey, nil } func (vr *Verifier) updateValidatorsAndCycle(ctx context.Context, blockHeight int64, cycle int64) error { - if true{ + if true { return nil } @@ -169,21 +188,21 @@ func (vr *Verifier) updateValidatorsAndCycle(ctx context.Context, blockHeight in fmt.Println("error here?", err) return err } - // remove all validators + // remove all validators for a := range vr.validators { delete(vr.validators, a) } vr.validators = make(map[tezos.Address]bool) - // add new validators - for _, validator := range(validatorsList){ + // add new validators + for _, validator := range validatorsList { vr.validators[validator.Delegate] = true } vr.cycle = cycle fmt.Println("reached to updating cycle") - return nil + return nil } -func (vr *Verifier) verifyEndorsement(op [][]*rpc.Operation, c *rpc.Client, blockHeight int64) (error) { +func (vr *Verifier) verifyEndorsement(op [][]*rpc.Operation, c *rpc.Client, blockHeight int64) error { endorsementPower := 0 threshold := 7000 * float32(2) / float32(3) @@ -199,7 +218,7 @@ func (vr *Verifier) verifyEndorsement(op [][]*rpc.Operation, c *rpc.Client, bloc endorsers[tx.Metadata.Delegate] = true endorsementPower += tx.Metadata.EndorsementPower } - }else { + } else { fmt.Println(vr.validators[tx.Metadata.Delegate]) } } @@ -208,14 +227,14 @@ func (vr *Verifier) verifyEndorsement(op [][]*rpc.Operation, c *rpc.Client, bloc } fmt.Println(len(endorsers)) - if endorsementPower > int(threshold) && len(endorsers) * 100 / len(vr.validators) > 66 { - return nil - } -return errors.New("endorsement verification failed") + if endorsementPower > int(threshold) && len(endorsers)*100/len(vr.validators) > 66 { + return nil + } + return errors.New("endorsement verification failed") } type VerifierOptions struct { - BlockHeight int64 `json:"blockHeight"` - BlockHash tezos.BlockHash `json:"parentHash"` -} \ No newline at end of file + BlockHeight int64 `json:"blockHeight"` + BlockHash tezos.BlockHash `json:"parentHash"` +} From 88a604093140aa837e09e4e511080d2589c91a88 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Tue, 27 Jun 2023 12:32:27 +0545 Subject: [PATCH 123/211] fix: icon - tezos bridge integration --- cmd/iconbridge/chain/tezos/client.go | 4 ++-- cmd/iconbridge/chain/tezos/receiver.go | 6 +++--- cmd/iconbridge/example.config.json | 16 ++++++++-------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/cmd/iconbridge/chain/tezos/client.go b/cmd/iconbridge/chain/tezos/client.go index 1826fd15..915fd432 100644 --- a/cmd/iconbridge/chain/tezos/client.go +++ b/cmd/iconbridge/chain/tezos/client.go @@ -247,7 +247,7 @@ func returnTxMetadata3(tx *rpc.Transaction, contractAddress tezos.Address, heigh for i := 0; i < len(tx.Metadata.InternalResults); i++ { fmt.Println("reached in for") internalResults := tx.Metadata.InternalResults[i] - if internalResults.Kind.String() == "event" && internalResults.Source.ContractAddress() == "KT1GE5sE73hThhRwaokB3yqxypiVHpoFZcjj" { + if internalResults.Kind.String() == "event" && internalResults.Source.ContractAddress() == "KT1LCyXGWTv2VctSrFL74h8nMNXMcBRNk6oR" { fmt.Println("Address matched") if internalResults.Tag == "Message" { message := internalResults.Payload.Args[0].Bytes @@ -333,7 +333,7 @@ func (c *Client) GetOperationByHash(ctx context.Context, clinet *rpc.Client, blo func (c *Client) HandleRelayMessage(ctx context.Context, callArgs contract.CallArguments, opts *rpc.CallOptions) (*rpc.Receipt, error) { fmt.Println("handling relay message") PrintU() - result, err := c.CustomCall(ctx, []contract.CallArguments{callArgs}, opts) + result, err := c.Contract.Call(ctx, callArgs, opts) if err != nil { fmt.Println(err) fmt.Println("because error") diff --git a/cmd/iconbridge/chain/tezos/receiver.go b/cmd/iconbridge/chain/tezos/receiver.go index 2a89db6f..d9c6e497 100644 --- a/cmd/iconbridge/chain/tezos/receiver.go +++ b/cmd/iconbridge/chain/tezos/receiver.go @@ -327,7 +327,7 @@ func (r *receiver) SyncVerifier(ctx context.Context, vr IVerifier, height int64, fmt.Println("has it reached to verification") fmt.Println(next.Header.Level) - err := vr.Verify(ctx, prevHeader, prevBlock, next.Block.Metadata.Baker, r.client.Cl, next.Header) + err := vr.Verify(ctx, prevHeader, prevBlock, next.Block.Metadata.BakerConsensusKey, r.client.Cl, next.Header) if err != nil { cursor = vr.Height() + 1 @@ -428,7 +428,7 @@ func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback fu if vr != nil { fmt.Println("vr is not nil for block heiht ", lbn.Header.Level) // header := bn.Header - if err := vr.Verify(ctx, lbn.Header, lbn.Block, bn.Proposer, r.client.Cl, bn.Header); err != nil { // change accordingly + if err := vr.Verify(ctx, lbn.Header, lbn.Block, bn.Block.Metadata.BakerConsensusKey, r.client.Cl, bn.Header); err != nil { // change accordingly // r.log.WithFields(log.Fields{ // "height": lbn.Height, // "lbnHash": lbn.Hash, @@ -648,7 +648,7 @@ func (r *receiver) receiveLoop2(ctx context.Context, opts *BnOptions, callback f } } else { if vr != nil { - if err := vr.Verify(ctx, lbn.Header, lbn.Block, bn.Proposer, r.client.Cl, bn.Header); err != nil { // change accordingly + if err := vr.Verify(ctx, lbn.Header, lbn.Block, bn.Block.Metadata.BakerConsensusKey, r.client.Cl, bn.Header); err != nil { // change accordingly r.log.WithFields(log.Fields{ "height": lbn.Height, "lbnHash": lbn.Hash, diff --git a/cmd/iconbridge/example.config.json b/cmd/iconbridge/example.config.json index 6f214f1e..863c394b 100644 --- a/cmd/iconbridge/example.config.json +++ b/cmd/iconbridge/example.config.json @@ -17,20 +17,20 @@ { "name": "t2i", "src": { - "address": "btp://NetXnHfVqm9iesp.tezos/KT1Ut8DFpvKxNtic368hwHRqxZLW7bN54ier", + "address": "btp://NetXnHfVqm9iesp.tezos/KT1TjAbAKfNeHyUViBHqgbeikUh26cWW7r6o", "endpoint": [ "https://rpc.ghost.tzstats.com/" ], "options": { "verifier": { - "blockHeight": 3032011 + "blockHeight": 3033078 }, "syncConcurrency": 100 }, - "offset": 3032011 + "offset": 3033078 }, "dst": { - "address": "btp://0x7.icon/cxdf6dbbac0eb75618a2c8ba0f92c71341158734bd", + "address": "btp://0x7.icon/cxa0d7311d391126a148cda2ac48f9cbb932195d7f", "endpoint": [ "https://berlin.net.solidwallet.io/api/v3" ], @@ -65,21 +65,21 @@ { "name": "i2t", "src": { - "address": "btp://0x7.icon/cxdf6dbbac0eb75618a2c8ba0f92c71341158734bd", + "address": "btp://0x7.icon/cxa0d7311d391126a148cda2ac48f9cbb932195d7f", "endpoint": [ "https://berlin.net.solidwallet.io/api/v3/icon_dex" ], "options": { "verifier": { - "blockHeight": 9922000, + "blockHeight": 9925882, "validatorsHash": "0x04b56f3fc8d396cc7eb8124da8a554800b8758c9e2fff0802aa9682948e65447" }, "syncConcurrency": 100 }, - "offset": 9922000 + "offset": 9925882 }, "dst": { - "address": "btp://NetXnHfVqm9iesp.tezos/KT1Ut8DFpvKxNtic368hwHRqxZLW7bN54ier", + "address": "btp://NetXnHfVqm9iesp.tezos/KT1TjAbAKfNeHyUViBHqgbeikUh26cWW7r6o", "endpoint": [ "https://rpc.ghost.tzstats.com/" ], From 87cd646693b73d0d4a3148fd07aefe73782f8b18 Mon Sep 17 00:00:00 2001 From: simusud Date: Tue, 27 Jun 2023 13:47:49 +0545 Subject: [PATCH 124/211] fix(bts): unregistered coin handled --- smartpy/bts/contracts/src/bts_periphery.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index 9569f175..850e2188 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -446,15 +446,15 @@ def _handle_request_service(self, to, assets): sp.set_type(assets, sp.TMap(sp.TNat, types.Types.Asset)) status = sp.local("status", "error") - check_validity = sp.local("check_validity", False) + check_validity = sp.local("check_validity", True) with sp.if_(sp.len(assets) <= self.MAX_BATCH_SIZE): parsed_to = sp.view("str_to_addr", self.data.parse_contract, to, t=sp.TAddress).open_some() sp.for i in sp.range(0, sp.len(assets)): valid_coin = sp.view("is_valid_coin", self.data.bts_core, assets[i].coin_name, t=sp.TBool).open_some() check_transfer = sp.view("check_transfer_restrictions", sp.self_address, sp.record( coin_name=assets[i].coin_name, user=parsed_to, value=assets[i].value), t=sp.TBool).open_some() - sp.if (check_transfer == True) & (valid_coin == True): - check_validity.value = True + sp.if (check_transfer == False) | (valid_coin == False): + check_validity.value = False sp.if check_validity.value == True: sp.for i in sp.range(0, sp.len(assets)): # inter score call From 6f4bfb4a8831610806e5cac7746e1a7fb8eb2ad5 Mon Sep 17 00:00:00 2001 From: simusud Date: Fri, 30 Jun 2023 18:57:10 +0545 Subject: [PATCH 125/211] perf(bmc): internal review changes --- smartpy/bmc/contracts/src/bmc_periphery.py | 130 ++++++++++----------- 1 file changed, 60 insertions(+), 70 deletions(-) diff --git a/smartpy/bmc/contracts/src/bmc_periphery.py b/smartpy/bmc/contracts/src/bmc_periphery.py index 7c78e675..50b7d84e 100644 --- a/smartpy/bmc/contracts/src/bmc_periphery.py +++ b/smartpy/bmc/contracts/src/bmc_periphery.py @@ -27,9 +27,6 @@ def __init__(self, bmc_management_addr, helper_contract, helper_parse_neg_contra bmc_btp_address=sp.none, bmc_management=bmc_management_addr, parse_contract=parse_address, - handle_btp_message_status=sp.none, - handle_btp_error_status=sp.none, - handle_fee_gathering_status=sp.none, owner_address = owner_address ) @@ -87,18 +84,13 @@ def _require_registered_relay(self, prev): sp.set_type(prev, sp.TString) relays = sp.view("get_link_relays", self.data.bmc_management, prev, t=sp.TList(sp.TAddress)).open_some() - valid = sp.local("valid", False) - sp.for x in relays: - sp.if sp.sender == x: - valid.value = True - sp.verify(valid.value, self.BMCRevertUnauthorized) + check_relay = sp.local("valid_relay_check", False) + sp.for relay in relays: + sp.if sp.sender == relay: + check_relay.value = True + sp.verify(check_relay.value, self.BMCRevertUnauthorized) - @sp.entry_point(lazify=False) - def update_callback_btp_message(self, ep): - self.only_owner() - sp.set_entry_point("callback_btp_message", ep) - - @sp.entry_point(lazify=True) + @sp.entry_point def callback_btp_message(self, string, bsh_addr, prev, callback_msg): sp.set_type(string, sp.TOption(sp.TString)) sp.set_type(bsh_addr, sp.TAddress) @@ -106,20 +98,11 @@ def callback_btp_message(self, string, bsh_addr, prev, callback_msg): sp.set_type(callback_msg, types.Types.BMCMessage) sp.verify(sp.sender == bsh_addr, "Unauthorized") - self.data.handle_btp_message_status = string - with sp.if_(self.data.handle_btp_message_status.open_some() == "success"): - pass - with sp.else_(): + with sp.if_(string.open_some() != "success"): self._send_error(prev, callback_msg, self.BSH_ERR, self.BMCRevertUnknownHandleBTPMessage) - self.data.handle_btp_message_status = sp.none - @sp.entry_point(lazify=False) - def update_callback_btp_error(self, ep): - self.only_owner() - sp.set_entry_point("callback_btp_error", ep) - - @sp.entry_point(lazify=True) + @sp.entry_point def callback_btp_error(self, string, bsh_addr, svc, sn, code, msg): sp.set_type(string, sp.TOption(sp.TString)) sp.set_type(bsh_addr, sp.TAddress) @@ -129,31 +112,11 @@ def callback_btp_error(self, string, bsh_addr, svc, sn, code, msg): sp.set_type(msg, sp.TString) sp.verify(sp.sender == bsh_addr, "Unauthorized") - self.data.handle_btp_error_status = string - with sp.if_(self.data.handle_btp_error_status.open_some() == "success"): - pass - with sp.else_(): + with sp.if_(string.open_some() != "success"): error_code = self.UNKNOWN_ERR err_msg = self.BMCRevertUnknownHandleBTPError sp.emit(sp.record(svc=svc, sn=sn, code=code, msg=msg, err_code=error_code, err_msg=err_msg), tag="ErrorOnBTPError") - self.data.handle_btp_error_status = sp.none - - @sp.entry_point(lazify=False) - def update_callback_handle_fee_gathering(self, ep): - self.only_owner() - sp.set_entry_point("callback_handle_fee_gathering", ep) - - @sp.entry_point(lazify=True) - def callback_handle_fee_gathering(self, string, bsh_addr): - sp.set_type(string, sp.TOption(sp.TString)) - sp.set_type(bsh_addr, sp.TAddress) - - sp.verify(sp.sender == bsh_addr, "Unauthorized") - self.data.handle_fee_gathering_status = string - with sp.if_(self.data.handle_fee_gathering_status.open_some() == "success"): - pass - self.data.handle_fee_gathering_status = sp.none @sp.entry_point(lazify=False) def update_handle_relay_message(self, ep): @@ -172,20 +135,25 @@ def handle_relay_message(self, prev, msg): rx_seq = sp.local("rx_seq", link_rx_seq, t=sp.TNat) rx_height = sp.local("rx_height", link_rx_height, t=sp.TNat) + # decode rlp message rps_decode = self.decode_receipt_proofs(msg) with sp.if_(rps_decode.status == "Success"): rps = rps_decode.receipt_proof - bmc_msg = sp.local("bmc_msg", sp.record(src="", dst="", svc="", sn=sp.int(0), message=sp.bytes("0x")), t=types.Types.BMCMessage) - ev = sp.local("ev", sp.record(next_bmc="", seq=sp.nat(0), message=sp.bytes("0x")), t=types.Types.MessageEvent) + bmc_msg = sp.local("bmc_msg", sp.record(src="", dst="", svc="", sn=sp.int(0), message=sp.bytes("0x")), + t=types.Types.BMCMessage) + ev = sp.local("ev", sp.record(next_bmc="", seq=sp.nat(0), message=sp.bytes("0x")), + t=types.Types.MessageEvent) sp.for i in sp.range(sp.nat(0), sp.len(rps)): with sp.if_(rps[i].height < rx_height.value): pass with sp.else_(): rx_height.value = rps[i].height sp.for j in sp.range(sp.nat(0), sp.len(rps[i].events)): + #stored events received by decoding in local variable ev.value = rps[i].events[j] - sp.verify(ev.value.next_bmc == self.data.bmc_btp_address.open_some("Address not set"), "Invalid Next BMC") - rx_seq.value +=sp.nat(1) + sp.verify(ev.value.next_bmc == self.data.bmc_btp_address.open_some("Address not set"), + "Invalid Next BMC") + rx_seq.value += sp.nat(1) with sp.if_(ev.value.seq < rx_seq.value): rx_seq.value = sp.as_nat(rx_seq.value-sp.nat(1)) with sp.else_(): @@ -195,11 +163,16 @@ def handle_relay_message(self, prev, msg): _decoded = self.decode_bmc_message(ev.value.message) bmc_msg.value = _decoded.bmc_dec_rv with sp.if_(_decoded.status == sp.string("Success")): - with sp.if_(bmc_msg.value.dst == self.data.bmc_btp_address.open_some("Address not set")): + with sp.if_(bmc_msg.value.dst == self.data.bmc_btp_address.open_some("AddressNotSet")): self._handle_message(prev, bmc_msg.value) with sp.else_(): - net, addr = sp.match_pair(strings.split_btp_address(bmc_msg.value.dst, "prev_idx", "result", "my_list", "last", "penultimate")) - next_link, prev_link = sp.match_pair(sp.view("resolve_route", self.data.bmc_management, net, t=sp.TPair(sp.TString, sp.TString)).open_some("Invalid Call")) + net, addr = sp.match_pair(strings.split_btp_address(bmc_msg.value.dst, "prev_idx", + "result", "my_list", "last", + "penultimate")) + next_link, prev_link = sp.match_pair(sp.view("resolve_route", + self.data.bmc_management,net, t=sp.TPair(sp.TString, + sp.TString)).open_some("Invalid Call")) + with sp.if_(next_link != "Unreachable"): self._send_message(next_link, ev.value.message) with sp.else_(): @@ -218,7 +191,8 @@ def handle_relay_message(self, prev, msg): update_relay_stats_entry_point = sp.contract(update_relay_stats_args_type, self.data.bmc_management, "update_relay_stats").open_some() - update_relay_stats_args = sp.record(relay=sp.sender, block_count_val=sp.nat(0), msg_count_val=sp.as_nat(rx_seq.value - link_rx_seq)) + update_relay_stats_args = sp.record(relay=sp.sender, block_count_val=sp.nat(0), + msg_count_val=sp.as_nat(rx_seq.value - link_rx_seq)) sp.transfer(update_relay_stats_args, sp.tez(0), update_relay_stats_entry_point) # call update_link_rx_height on BMCManagement @@ -235,7 +209,6 @@ def _handle_message(self, prev, msg): sp.set_type(prev, sp.TString) sp.set_type(msg, types.Types.BMCMessage) - # bsh_addr = sp.local("bsh_addr",sp.TAddress) with sp.if_(msg.svc == "bmc"): sm = sp.local("sm", sp.record(serviceType="", payload=sp.bytes("0x"))) _decoded = self.decode_bmc_service(msg.message) @@ -245,24 +218,26 @@ def _handle_message(self, prev, msg): with sp.else_(): sp.if sm.value.serviceType == "FeeGathering": gather_fee =sp.local("gather_fee", sp.record(fa="error", svcs=sp.map({0:""}))) - _decoded_value = self.decode_gather_fee_message(sm.value.payload) - gather_fee.value = _decoded_value.fee_decode_rv + fee_msg_decoded = self.decode_gather_fee_message(sm.value.payload) + gather_fee.value = fee_msg_decoded.fee_decode_rv - with sp.if_(_decoded_value.status != "Success"): + with sp.if_(fee_msg_decoded.status != "Success"): self._send_error(prev, msg, self.BMC_ERR, self.BMCRevertParseFailure) with sp.else_(): - sp.for c in sp.range(sp.nat(0), sp.len(gather_fee.value.svcs)): - bsh_addr = sp.view("get_bsh_service_by_name", self.data.bmc_management, gather_fee.value.svcs[c], t=sp.TAddress).open_some("Invalid Call") + sp.for k in sp.range(sp.nat(0), sp.len(gather_fee.value.svcs)): + bsh_addr = sp.view("get_bsh_service_by_name", self.data.bmc_management, + gather_fee.value.svcs[k], t=sp.TAddress).open_some("Invalid Call") sp.if bsh_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg"): # call handle_fee_gathering of bts periphery - handle_fee_gathering_args_type = sp.TRecord(callback=sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress)), bsh_addr=sp.TAddress, fa=sp.TString, svc=sp.TString) + handle_fee_gathering_args_type = sp.TRecord(bsh_addr=sp.TAddress, fa=sp.TString, + svc=sp.TString) handle_fee_gathering_entry_point = sp.contract(handle_fee_gathering_args_type, bsh_addr, "handle_fee_gathering").open_some() - t = sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress) - callback = sp.contract(t, sp.self_address, "callback_handle_fee_gathering") - handle_fee_gathering_args = sp.record(callback=callback.open_some(), bsh_addr=bsh_addr, fa=gather_fee.value.fa, svc=gather_fee.value.svcs[c]) + + handle_fee_gathering_args = sp.record(bsh_addr=bsh_addr, + fa=gather_fee.value.fa, svc=gather_fee.value.svcs[k]) sp.transfer(handle_fee_gathering_args, sp.tez(0), handle_fee_gathering_entry_point) sp.if sm.value.serviceType == "Init": @@ -272,6 +247,7 @@ def _handle_message(self, prev, msg): update_link_reachable_entry_point = sp.contract(update_link_reachable_args_type, self.data.bmc_management, "update_link_reachable").open_some() + update_link_reachable_args = sp.record(prev=prev, to=links.links_list) sp.transfer(update_link_reachable_args, sp.tez(0), update_link_reachable_entry_point) with sp.else_(): @@ -285,29 +261,43 @@ def _handle_message(self, prev, msg): net, addr = sp.match_pair(strings.split_btp_address(msg.src, "prev_idx", "result", "my_list", "last", "penultimate")) # implemented callback # call handle_btp_message on bts periphery - handle_btp_message_args_type = sp.TRecord(callback=sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress, prev=sp.TString, callback_msg=types.Types.BMCMessage)), - bsh_addr=sp.TAddress, prev=sp.TString, callback_msg=types.Types.BMCMessage, _from=sp.TString, svc=sp.TString, sn=sp.TInt, msg=sp.TBytes) + handle_btp_message_args_type = sp.TRecord( + callback=sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), + bsh_addr=sp.TAddress, prev=sp.TString, + callback_msg=types.Types.BMCMessage)), + bsh_addr=sp.TAddress, prev=sp.TString, + callback_msg=types.Types.BMCMessage, _from=sp.TString, + svc=sp.TString, sn=sp.TInt, msg=sp.TBytes) + handle_btp_message_entry_point = sp.contract(handle_btp_message_args_type, bsh_addr, "handle_btp_message").open_some() - t = sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress, prev=sp.TString, callback_msg=types.Types.BMCMessage ) + t = sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress, prev=sp.TString, + callback_msg=types.Types.BMCMessage ) callback = sp.contract(t, sp.self_address, "callback_btp_message") - handle_btp_message_args = sp.record(callback=callback.open_some(), bsh_addr=bsh_addr, prev=prev, callback_msg=msg, _from=net, svc=msg.svc, sn=msg.sn, msg=msg.message) + handle_btp_message_args = sp.record(callback=callback.open_some(), + bsh_addr=bsh_addr, prev=prev, + callback_msg=msg, _from=net, svc=msg.svc, + sn=msg.sn, msg=msg.message) sp.transfer(handle_btp_message_args, sp.tez(0), handle_btp_message_entry_point) with sp.else_(): res = self.decode_response(msg.message) # implemented callback # call handle_btp_error on bts periphery - handle_btp_error_args_type = sp.TRecord(callback=sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress, svc=sp.TString, sn=sp.TInt, code=sp.TNat, msg=sp.TString)), + handle_btp_error_args_type = sp.TRecord( + callback=sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), + bsh_addr=sp.TAddress, svc=sp.TString, sn=sp.TInt, code=sp.TNat, msg=sp.TString)), bsh_addr=sp.TAddress, svc=sp.TString, sn=sp.TInt, code=sp.TNat, msg=sp.TString) handle_btp_error_entry_point = sp.contract(handle_btp_error_args_type, bsh_addr, "handle_btp_error").open_some() - t = sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress, svc=sp.TString, sn=sp.TInt, code=sp.TNat, msg=sp.TString) + t = sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress, + svc=sp.TString, sn=sp.TInt, code=sp.TNat, msg=sp.TString) callback = sp.contract(t, sp.self_address, "callback_btp_error") + handle_btp_error_args = sp.record(callback=callback.open_some(), bsh_addr=bsh_addr, svc=msg.svc, sn=msg.sn * -1, code=res.code, msg=res.message) sp.transfer(handle_btp_error_args, sp.tez(0), handle_btp_error_entry_point) From f24321404f55871a678fcefa3ac737b8d76a5a9a Mon Sep 17 00:00:00 2001 From: simusud Date: Fri, 30 Jun 2023 18:57:57 +0545 Subject: [PATCH 126/211] perf(bts): internal review changes --- smartpy/bts/contracts/src/RLP_struct.py | 21 +- smartpy/bts/contracts/src/Types.py | 12 +- smartpy/bts/contracts/src/bts_core.py | 390 ++++++++---------- .../bts/contracts/src/bts_owner_manager.py | 12 +- smartpy/bts/contracts/src/bts_periphery.py | 327 ++++++++------- 5 files changed, 371 insertions(+), 391 deletions(-) diff --git a/smartpy/bts/contracts/src/RLP_struct.py b/smartpy/bts/contracts/src/RLP_struct.py index 1404fa6c..04f30e9e 100644 --- a/smartpy/bts/contracts/src/RLP_struct.py +++ b/smartpy/bts/contracts/src/RLP_struct.py @@ -183,7 +183,7 @@ def decode_blacklist_msg(self, rlp): is_error = sp.local("error_in_bts_decode_blacklist_message", sp.string("Success")) is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() _service_type = sp.local("_service_type_blacklist", sp.variant("ERROR", sp.nat(10))) - rv_blacklist_address = sp.local("blacklist_data", {}, sp.TMap(sp.TNat, sp.TString)) + rv_blacklist_address = sp.local("blacklist_data", [], sp.TList(sp.TString)) with sp.if_(is_list_lambda): rlp_bm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() with sp.else_(): @@ -241,7 +241,7 @@ def decode_blacklist_msg(self, rlp): decode_len = sp.view("without_length_prefix", self.data.helper, new_temp_byt.value, t=sp.TBytes).open_some() addr_string.value = sp.view("decode_string", self.data.helper, decode_len, t=sp.TString).open_some() - rv_blacklist_address.value[counter.value] = addr_string.value + rv_blacklist_address.value.push(addr_string.value) counter.value = counter.value + 1 # check_length = sp.view("prefix_length", self.data.helper, rv1_byt.value, t=sp.TNat).open_some() # with sp.if_(check_length > 0): @@ -281,6 +281,7 @@ def decode_token_limit_msg(self, rlp): net = sp.local("network", sp.string("")) rv_names = sp.local("names", {}, sp.TMap(sp.TNat, sp.TString)) rv_limit = sp.local("limit", {}, sp.TMap(sp.TNat, sp.TNat)) + coin_name_limit = sp.local("coin_name_limit", {}, sp.TMap(sp.TString, sp.TNat)) with sp.if_(is_error.value == "Success"): sp.for i in rlp_.items(): sp.if counter.value == 0: @@ -336,7 +337,9 @@ def decode_token_limit_msg(self, rlp): t=sp.TBytes).open_some() rv_limit.value[counter.value] = Utils2.Int.of_bytes(limit.value) counter.value += 1 - return sp.record(rv = sp.record(coin_name = rv_names.value, token_limit = rv_limit.value , + sp.for elem in sp.range(sp.nat(0), sp.len(rv_names.value)): + coin_name_limit.value[rv_names.value.get(elem)] = rv_limit.value.get(elem) + return sp.record(rv = sp.record(coin_name_limit = coin_name_limit.value, net = net.value), status = is_error.value) # encoding starts here @@ -354,18 +357,16 @@ def encode_service_message(self, params): return final_rlp_bytes_with_prefix def encode_transfer_coin_msg(self, data): - sp.set_type(data, types.Types.TransferCoin) + sp.set_type(data, sp.TRecord(from_addr=sp.TString, to=sp.TString, + assets=sp.TList(sp.TRecord(coin_name=sp.TString, value=sp.TNat, fee=sp.TNat)))) rlp = sp.local("rlp", sp.bytes("0x")) rlp_list = sp.local("rlp_list", [], t=sp.TList(sp.TBytes)) temp = sp.local("temp", sp.bytes("0x")) coin_name = sp.local("coin_name", sp.bytes("0x")) - sp.for i in sp.range(0, sp.len(data.assets)): - coin_name.value = sp.view("encode_string", self.data.helper, data.assets.get(i, default_value=sp.record( - coin_name="", value=sp.nat(0))).coin_name, t=sp.TBytes).open_some() - temp.value = sp.view("encode_nat", self.data.helper, - data.assets.get(i, default_value=sp.record(coin_name="", value=sp.nat(0))).value, - t=sp.TBytes).open_some() + sp.for item in data.assets: + coin_name.value = sp.view("encode_string", self.data.helper, item.coin_name, t=sp.TBytes).open_some() + temp.value = sp.view("encode_nat", self.data.helper, item.value, t=sp.TBytes).open_some() rlp_list.value.push( sp.view("encode_list", self.data.helper, [coin_name.value, temp.value], t=sp.TBytes).open_some()) # rlp.value = sp.view("with_length_prefix", self.data.helper, rlp.value, diff --git a/smartpy/bts/contracts/src/Types.py b/smartpy/bts/contracts/src/Types.py index 6c127186..1a36f6cf 100644 --- a/smartpy/bts/contracts/src/Types.py +++ b/smartpy/bts/contracts/src/Types.py @@ -3,6 +3,12 @@ class Types: + Coin = sp.TRecord(addr=sp.TAddress, + fee_numerator=sp.TNat, + fixed_fee=sp.TNat, + coin_type=sp.TNat + ) + Asset = sp.TRecord( coin_name=sp.TString, value=sp.TNat @@ -43,15 +49,13 @@ class Types: TransferCoin = sp.TRecord( from_addr=sp.TString, to=sp.TString, - assets=sp.TMap(sp.TNat, Asset) + assets=sp.TList(Asset) ) PendingTransferCoin = sp.TRecord( from_=sp.TString, to=sp.TString, - coin_names=sp.TMap(sp.TNat, sp.TString), - amounts=sp.TMap(sp.TNat, sp.TNat), - fees=sp.TMap(sp.TNat, sp.TNat) + coin_details=sp.TList(sp.TRecord(coin_name=sp.TString, value=sp.TNat, fee=sp.TNat)) ) BlacklistMessage = sp.TRecord( diff --git a/smartpy/bts/contracts/src/bts_core.py b/smartpy/bts/contracts/src/bts_core.py index 17c6a975..2ef6b076 100644 --- a/smartpy/bts/contracts/src/bts_core.py +++ b/smartpy/bts/contracts/src/bts_core.py @@ -3,10 +3,6 @@ types = sp.io.import_script_from_url("file:./contracts/src/Types.py") FA2_contract = sp.io.import_script_from_url("file:./contracts/src/FA2_contract.py") -Coin = sp.TRecord(addr=sp.TAddress, - fee_numerator=sp.TNat, - fixed_fee=sp.TNat, - coin_type=sp.TNat) class BTSCore(sp.Contract): FEE_DENOMINATOR = sp.nat(10000) @@ -17,6 +13,7 @@ class BTSCore(sp.Contract): NON_NATIVE_TOKEN_TYPE = sp.nat(2) MAX_BATCH_SIZE = sp.nat(15) + # TODO: set NATIVE_COIN_ADDRESS to governance address NATIVE_COIN_ADDRESS = sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc") ZERO_ADDRESS = sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg") # Nat:(TWO.pow256 - 1) @@ -28,12 +25,10 @@ def __init__(self, _native_coin_name, _fee_numerator, _fixed_fee, owner_manager) bts_periphery_address=sp.none, native_coin_name=_native_coin_name, - list_of_owners=sp.list(t=sp.TAddress), - charged_amounts=sp.map(tkey=sp.TNat, tvalue=sp.TNat), + # charged_amounts=sp.map(tkey=sp.TNat, tvalue=sp.TNat), coins_name=sp.list([_native_coin_name], t=sp.TString), - charged_coins=sp.map(tkey=sp.TNat, tvalue=sp.TString), + # charged_coins=sp.map(tkey=sp.TNat, tvalue=sp.TString), - owners=sp.map({}, tkey=sp.TAddress, tvalue=sp.TBool), aggregation_fee=sp.map({}, tkey=sp.TString, tvalue=sp.TNat), balances=sp.big_map(tkey=sp.TRecord(address=sp.TAddress, coin_name=sp.TString), tvalue= types.Types.Balance), coins=sp.map({_native_coin_name: self.NATIVE_COIN_ADDRESS}, tkey=sp.TString, tvalue=sp.TAddress), @@ -41,11 +36,8 @@ def __init__(self, _native_coin_name, _fee_numerator, _fixed_fee, owner_manager) fee_numerator=_fee_numerator, fixed_fee=_fixed_fee, coin_type=self.NATIVE_COIN_TYPE)}, - tkey=sp.TString, tvalue=Coin), - coins_address=sp.map({}, tkey=sp.TAddress, tvalue=sp.TString), - callback_coin_name=sp.string(""), - callback_value=sp.nat(0), - callback_to=sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg") + tkey=sp.TString, tvalue=types.Types.Coin), + coins_address=sp.map({self.NATIVE_COIN_ADDRESS: _native_coin_name}, tkey=sp.TAddress, tvalue=sp.TString) ) def only_owner(self): @@ -67,7 +59,7 @@ def update_bts_periphery(self, bts_periphery): self.only_owner() sp.if self.data.bts_periphery_address.is_some(): - has_requests = sp.view("has_pending_request", self.data.bts_periphery_address.open_some("Address not set"), sp.unit, t=sp.TBool).open_some("OwnerNotFound") + has_requests = sp.view("has_pending_request", self.data.bts_periphery_address.open_some("Address not set"), sp.unit, t=sp.TBool).open_some("has_pending_request not found") sp.verify(has_requests == False, "HasPendingRequest") self.data.bts_periphery_address = sp.some(bts_periphery) @@ -115,7 +107,7 @@ def register(self, name, fee_numerator, fixed_fee, addr, token_metadata, metadat sp.set_type(addr, sp.TAddress) sp.set_type(token_metadata, sp.TMap(sp.TString, sp.TBytes)) sp.set_type(metadata, sp.TBigMap(sp.TString, sp.TBytes)) - + # TODO: use symbol and decimals self.only_owner() sp.verify(name != self.data.native_coin_name, message="ExistNativeCoin") sp.verify(self.data.coins.contains(name) == False, message= "ExistCoin") @@ -123,9 +115,11 @@ def register(self, name, fee_numerator, fixed_fee, addr, token_metadata, metadat sp.verify(fee_numerator <= self.FEE_DENOMINATOR, message="InvalidSetting") sp.verify((fixed_fee >= sp.nat(0)) & (fee_numerator >= sp.nat(0)), message="LessThan0") with sp.if_(addr == self.ZERO_ADDRESS): - deployed_fa2 = sp.create_contract_operation(contract=FA2_contract.SingleAssetToken(admin=sp.self_address, metadata=metadata, - token_metadata=token_metadata - )) + deployed_fa2 = sp.create_contract_operation( + contract=FA2_contract.SingleAssetToken(admin=sp.self_address, + metadata=metadata, + token_metadata=token_metadata + )) sp.operations().push(deployed_fa2.operation) self.data.coins[name] = deployed_fa2.address self.data.coins_name.push(name) @@ -147,15 +141,13 @@ def register(self, name, fee_numerator, fixed_fee, addr, token_metadata, metadat coin_type = self.NON_NATIVE_TOKEN_TYPE ) - token_map = sp.map({0:name}, tkey=sp.TNat, tvalue=sp.TString) - val_map = sp.map({0:self.UINT_CAP}, tkey=sp.TNat, tvalue=sp.TNat) + # token_map = sp.map({0:name}, tkey=sp.TNat, tvalue=sp.TString) + token_limit_map = sp.map({name:self.UINT_CAP}, tkey=sp.TString, tvalue=sp.TNat) # call set_token_limit on bts_periphery - set_token_limit_args_type = sp.TRecord(coin_names=sp.TMap(sp.TNat, sp.TString), token_limit=sp.TMap(sp.TNat, sp.TNat)) - set_token_limit_entry_point = sp.contract(set_token_limit_args_type, self.data.bts_periphery_address.open_some("Address not set"), - "set_token_limit").open_some("ErrorINCALL") - set_token_limit_args = sp.record(coin_names=token_map, token_limit=val_map) - sp.transfer(set_token_limit_args, sp.tez(0), set_token_limit_entry_point) + set_token_limit_entry_point = sp.contract(sp.TMap(sp.TString, sp.TNat), self.data.bts_periphery_address.open_some("Address not set"), + "set_token_limit").open_some("Error in set_token_limit call") + sp.transfer(token_limit_map, sp.tez(0), set_token_limit_entry_point) @sp.onchain_view() def coin_id(self, coin_name): @@ -168,6 +160,23 @@ def coin_id(self, coin_name): sp.result(self.data.coins.get(coin_name)) + @sp.onchain_view() + def native_coin_balance_of(self): + """ + Return balance of Native Coin . + :return: A Balance of native coin. + """ + sp.result(sp.pair(self.data.native_coin_name, sp.balance)) + + @sp.onchain_view() + def coin_type(self, coin_name): + """ + Return balance of Native Coin . + :return: A Balance of native coin. + """ + sp.set_type(coin_name, sp.TString) + sp.result(self.data.coin_details.get(coin_name).coin_type) + @sp.onchain_view() def is_valid_coin(self, coin_name): """ @@ -177,7 +186,7 @@ def is_valid_coin(self, coin_name): """ sp.set_type(coin_name, sp.TString) - sp.result((self.data.coins.contains(coin_name))|( coin_name == self.data.native_coin_name)) + sp.result(self.data.coins.contains(coin_name)) @sp.onchain_view() def fee_ratio(self, coin_name): @@ -222,13 +231,15 @@ def balance_of(self, params): user_balance=sp.nat(0))) with sp.else_(): fa2_address = self.data.coins.get(params.coin_name) - user_balance= sp.view("get_balance_of", fa2_address, [sp.record(owner=params.owner, token_id=sp.nat(0))], t=sp.TNat).open_some("Invalid view") - - allowance = sp.view("get_allowance", fa2_address, sp.record(spender=sp.self_address, owner=params.owner), t=sp.TNat).open_some("Invalid view") - usable_balance = sp.local("usable_balance", allowance, t=sp.TNat) - sp.if allowance > user_balance: - usable_balance.value = user_balance - + usable_balance = sp.local("usable_balance", sp.nat(0), t=sp.TNat) + user_balance= sp.view("get_balance_of", fa2_address, [sp.record(owner=params.owner, token_id=sp.nat(0))], + t=sp.TNat).open_some("Invalid view") + sp.if self.data.coin_details.get(params.coin_name).coin_type == self.NATIVE_WRAPPED_COIN_TYPE: + allowance = sp.view("get_allowance", fa2_address, sp.record(spender=sp.self_address, owner=params.owner), t=sp.TNat).open_some("Invalid view") + usable_balance.value = allowance + sp.if allowance > user_balance: + usable_balance.value = user_balance + # TODO: allowance for NON_NATIVE_TOKEN_TYPE also check allowance for bts core sp.result(sp.record(usable_balance=usable_balance.value, locked_balance=locked_balance.value, refundable_balance=refundable_balance.value, @@ -244,23 +255,16 @@ def balance_of_batch(self, params): sp.set_type(params, sp.TRecord(owner=sp.TAddress, coin_names=sp.TList(sp.TString))) - sp.verify((sp.len(params.coin_names) > sp.nat(0)) & (sp.len(params.coin_names) <= self.MAX_BATCH_SIZE), message = "BatchMaxSizeExceed") - usable_balances =sp.local("usable_balances", {}, t=sp.TMap(sp.TNat, sp.TNat)) - locked_balances =sp.local("locked_balances", {}, t=sp.TMap(sp.TNat, sp.TNat)) - refundable_balances =sp.local("refundable_balances", {}, t=sp.TMap(sp.TNat, sp.TNat)) - user_balances =sp.local("user_balances", {}, t=sp.TMap(sp.TNat, sp.TNat)) + sp.verify((sp.len(params.coin_names) > sp.nat(0)) & (sp.len(params.coin_names) <= self.MAX_BATCH_SIZE), + message = "BatchMaxSizeExceed") - i = sp.local("i", sp.nat(0)) + balances= sp.local("balances_list", [], t=sp.TList(sp.TRecord(usable_balance=sp.TNat,locked_balance=sp.TNat, + refundable_balance=sp.TNat, user_balance=sp.TNat))) sp.for item in params.coin_names: balance= sp.view("balance_of", sp.self_address, sp.record(owner=params.owner, coin_name=item)).open_some() - usable_balances.value[i.value] = balance.usable_balance - locked_balances.value[i.value] = balance.locked_balance - refundable_balances.value[i.value] = balance.refundable_balance - user_balances.value[i.value] = balance.user_balance - i.value += sp.nat(1) - sp.result(sp.record(usable_balances=usable_balances.value, locked_balances=locked_balances.value, - refundable_balances=refundable_balances.value, user_balances=user_balances.value)) + balances.value.push(balance) + sp.result(balances.value) @sp.onchain_view() def get_accumulated_fees(self): @@ -268,13 +272,13 @@ def get_accumulated_fees(self): Return a map with record of accumulated Fees. :return: An map of Asset """ + # accumulated_fees = sp.local("accumulated_fees", sp.map(tkey=sp.TString, tvalue=sp.TNat)) + # i = sp.local("i", sp.nat(0)) - accumulated_fees = sp.local("accumulated_fees", sp.map(tkey=sp.TNat, tvalue=types.Types.Asset)) - i = sp.local("i", sp.nat(0)) - sp.for item in self.data.coins_name: - accumulated_fees.value[i.value] = sp.record(coin_name=item, value=self.data.aggregation_fee.get(item, default_value=sp.nat(0))) - i.value += sp.nat(1) - sp.result(accumulated_fees.value) + # sp.for item in self.data.coins_name: + # accumulated_fees.value[item] = sp.record(coin_name=item, value=self.data.aggregation_fee.get(item, default_value=sp.nat(0))) + # # i.value += sp.nat(1) + sp.result(self.data.aggregation_fee) # @sp.entry_point(lazify=False) # def update_transfer_native_coin(self, ep): @@ -301,6 +305,18 @@ def transfer_native_coin(self, to): self._send_service_message(sp.sender, to, self.data.native_coin_name, amount_in_nat.value, charge_amt) + # # TODO:to be discussed + # @sp.entry_point + # def allow_bts(self, token_addr, value): + # + # sp.set_type(token_addr, sp.TAddress) + # sp.set_type(value, sp.TNat) + # + # allowance = sp.compute(sp.record(spender=sp.self_address, owner=sp.sender)) + # current_allowance = self.data.allowances.get(allowance, default_value=0) + # current_allowance += value + # self.data.allowances[sp.record(sender=sp.sender, token_addr=token_addr)] = value + @sp.entry_point(lazify=False) def update_transfer(self, ep): self.only_owner() @@ -359,15 +375,16 @@ def _send_service_message(self, _from, to, coin_name, value, charge_amt): sp.verify(value > charge_amt, message = "ValueGreaterThan0") self._lock_balance(_from, coin_name, value) - - coins = sp.local("coins", {sp.nat(0) : coin_name}, t=sp.TMap(sp.TNat, sp.TString)) - amounts = sp.local("amounts", {sp.nat(0) : sp.as_nat(value - charge_amt)}, t=sp.TMap(sp.TNat, sp.TNat)) - fees = sp.local("fees", {sp.nat(0): charge_amt}, t=sp.TMap(sp.TNat, sp.TNat)) + coin_details = sp.local("coin_details_", [], t=sp.TList(sp.TRecord(coin_name=sp.TString, value=sp.TNat, + fee=sp.TNat))) + coin_details.value.push(sp.record(coin_name=coin_name, value=sp.as_nat(value - charge_amt), fee=charge_amt)) # call send_service_message on bts_periphery - send_service_message_args_type = sp.TRecord(_from = sp.TAddress, to = sp.TString, coin_names = sp.TMap(sp.TNat, sp.TString), values = sp.TMap(sp.TNat, sp.TNat), fees = sp.TMap(sp.TNat, sp.TNat)) - send_service_message_entry_point = sp.contract(send_service_message_args_type, self.data.bts_periphery_address.open_some("Address not set"), "send_service_message").open_some() - send_service_message_args = sp.record(_from = _from, to = to, coin_names = coins.value, values = amounts.value, fees = fees.value) + send_service_message_args_type = sp.TRecord(_from=sp.TAddress, to=sp.TString, coin_details=sp.TList( + sp.TRecord(coin_name=sp.TString, value=sp.TNat, fee=sp.TNat))) + send_service_message_entry_point = sp.contract(send_service_message_args_type, + self.data.bts_periphery_address.open_some("Address not set"), "send_service_message").open_some() + send_service_message_args = sp.record(_from = _from, to = to, coin_details = coin_details.value) sp.transfer(send_service_message_args, sp.tez(0), send_service_message_entry_point) @sp.entry_point(lazify=False) @@ -376,52 +393,43 @@ def update_transfer_batch(self, ep): sp.set_entry_point("transfer_batch", ep) @sp.entry_point(check_no_incoming_transfer=False, lazify=True) - def transfer_batch(self, coin_names, values, to): + def transfer_batch(self, coin_names_values, to): """ Allow users to transfer multiple coins/wrapped coins to another chain. It MUST revert if the balance of the holder for token `_coinName` is lower than the `_value` sent. In case of transferring a native coin, it also checks `msg.value` The number of requested coins MUST be as the same as the number of requested values The requested coins and values MUST be matched respectively - :param coin_names: A list of requested transferring wrapped coins - :param values: A list of requested transferring values respectively with its coin name + :param coin_names_values: A map of requested transferring wrapped coins and values :param to: Target BTP address. :return: """ - sp.set_type(coin_names, sp.TMap(sp.TNat, sp.TString)) - sp.set_type(values, sp.TMap(sp.TNat, sp.TNat)) + sp.set_type(coin_names_values, sp.TMap(sp.TString, sp.TNat)) sp.set_type(to, sp.TString) - - sp.verify(sp.len(coin_names) == sp.len(values), message ="InvalidRequest") - sp.verify(sp.len(coin_names) > sp.nat(0), message = "Zero length arguments") + sp.verify(sp.len(coin_names_values) > sp.nat(0), message = "Zero length arguments") amount_in_nat = sp.local("amount_in_nat", sp.utils.mutez_to_nat(sp.amount), t=sp.TNat) - size = sp.local("size", sp.nat(0), t=sp.TNat) + size = sp.local("size", sp.len(coin_names_values), t=sp.TNat) with sp.if_(amount_in_nat.value != sp.nat(0)): - size.value = sp.len(coin_names) + sp.nat(1) - with sp.else_(): - size.value = sp.len(coin_names) + size.value = size.value + sp.nat(1) + sp.verify(size.value <= self.MAX_BATCH_SIZE, message ="Batch maxSize Exceeds") - coins = sp.local("_coins", {}, t=sp.TMap(sp.TNat, sp.TString)) - amounts = sp.local("_amounts", {}, t=sp.TMap(sp.TNat, sp.TNat)) - charge_amts = sp.local("_charge_amts", {}, t=sp.TMap(sp.TNat, sp.TNat)) - - coin_name = sp.local("coin_name", "", t= sp.TString) - value = sp.local("value", sp.nat(0), t= sp.TNat) - - sp.for i in sp.range(sp.nat(0), sp.len(coin_names)): - sp.verify(coin_names[i] != self.data.native_coin_name, message="InvalidCoin") - sp.verify(self.data.coins.contains(coin_names[i]), message= "CoinNotRegistered") - fa2_address = self.data.coins[coin_names[i]] + batch_coin_details = sp.local("batch_coin_details", [], t=sp.TList(sp.TRecord(coin_name=sp.TString, + value=sp.TNat, fee=sp.TNat))) + charge_amt = sp.local("charge_amt__", sp.nat(0), t=sp.TNat) + amount = sp.local("amount__", sp.nat(0), t=sp.TNat) + sp.for item in coin_names_values.items(): + sp.verify(item.key != self.data.native_coin_name, message="InvalidCoin") + sp.verify(self.data.coins.contains(item.key), message="CoinNotRegistered") + fa2_address = self.data.coins[item.key] - coin_name.value = coin_names[i] - value.value = values[i] - sp.verify(value.value > sp.nat(0), message ="ZeroOrLess") + sp.verify(item.value > sp.nat(0), message="Cannot transfer less than or equal to zero") # call check_transfer_restrictions on bts_periphery - check_transfer = sp.view("check_transfer_restrictions", self.data.bts_periphery_address.open_some("Address not set"), - sp.record(coin_name=coin_name.value, user=sp.sender, value=value.value), + check_transfer = sp.view("check_transfer_restrictions", + self.data.bts_periphery_address.open_some("Address not set"), + sp.record(coin_name=item.key, user=sp.sender, value=item.value), t=sp.TBool).open_some() sp.verify(check_transfer == True, "FailCheckTransfer") @@ -431,15 +439,16 @@ def transfer_batch(self, coin_names, values, to): ).layout(("from_", "txs"))) transfer_entry_point = sp.contract(transfer_args_type, fa2_address, "transfer").open_some() transfer_args = [ - sp.record(from_=sp.sender, txs=[sp.record(to_=sp.self_address, token_id=sp.nat(0), amount=value.value)])] + sp.record(from_=sp.sender, + txs=[sp.record(to_=sp.self_address, token_id=sp.nat(0), amount=item.value)])] sp.transfer(transfer_args, sp.tez(0), transfer_entry_point) - coin = sp.local("coin", self.data.coin_details[coin_name.value], t=Coin) - coins.value[i] = coin_name.value - charge_amts.value[i] = value.value * coin.value.fee_numerator / self.FEE_DENOMINATOR + coin.value.fixed_fee - amounts.value[i] = sp.as_nat(value.value - charge_amts.value[i]) + charge_amt.value = item.value * self.data.coin_details[item.key].fee_numerator / self.FEE_DENOMINATOR + \ + self.data.coin_details[item.key].fixed_fee + amount.value = sp.as_nat(item.value - charge_amt.value) + batch_coin_details.value.push(sp.record(coin_name=item.key, value=amount.value, fee=charge_amt.value)) - self._lock_balance(sp.sender, coin_name.value, value.value) + self._lock_balance(sp.sender, item.key, item.value) sp.if amount_in_nat.value !=sp.nat(0): # call check_transfer_restrictions on bts_periphery @@ -448,23 +457,22 @@ def transfer_batch(self, coin_names, values, to): t=sp.TBool).open_some() sp.verify(check_transfer == True, "FailCheckTransfer") - coins.value[sp.as_nat(size.value - 1)] = self.data.native_coin_name - charge_amts.value[sp.as_nat(size.value - 1)] = amount_in_nat.value * self.data.coin_details[coin_name.value].fee_numerator\ - / self.FEE_DENOMINATOR + self.data.coin_details[coin_name.value].fixed_fee - amounts.value[sp.as_nat(size.value - 1)] = sp.as_nat(sp.utils.mutez_to_nat(sp.amount) - charge_amts.value[sp.as_nat(size.value - 1)]) + charge_amt.value = amount_in_nat.value * self.data.coin_details[self.data.native_coin_name].fee_numerator \ + / self.FEE_DENOMINATOR + self.data.coin_details[self.data.native_coin_name].fixed_fee + amount.value = sp.as_nat(amount_in_nat.value - charge_amt.value) + batch_coin_details.value.push(sp.record(coin_name=self.data.native_coin_name, value=amount.value, + fee=charge_amt.value)) self._lock_balance(sp.sender, self.data.native_coin_name, sp.utils.mutez_to_nat(sp.amount)) # call send_service_message on bts_periphery send_service_message_args_type = sp.TRecord(_from=sp.TAddress, to=sp.TString, - coin_names=sp.TMap(sp.TNat, sp.TString), - values=sp.TMap(sp.TNat, sp.TNat), - fees=sp.TMap(sp.TNat, sp.TNat)) + coin_details=sp.TList(sp.TRecord(coin_name=sp.TString, + value=sp.TNat, fee=sp.TNat))) send_service_message_entry_point = sp.contract(send_service_message_args_type, self.data.bts_periphery_address.open_some("Address not set"), "send_service_message").open_some() - send_service_message_args = sp.record(_from=sp.sender, to=to, coin_names=coins.value, values=amounts.value, - fees=charge_amts.value) + send_service_message_args = sp.record(_from=sp.sender, to=to, coin_details=batch_coin_details.value) sp.transfer(send_service_message_args, sp.tez(0), send_service_message_entry_point) @sp.entry_point @@ -479,10 +487,11 @@ def reclaim(self, coin_name, value): """ sp.set_type(coin_name, sp.TString) sp.set_type(value, sp.TNat) - - with sp.if_(self.data.balances.contains(sp.record(address=sp.sender,coin_name=coin_name))): - sp.verify(self.data.balances[sp.record(address=sp.sender,coin_name=coin_name)].refundable_balance >= value, message="Imbalance") - self.data.balances[sp.record(address=sp.sender,coin_name=coin_name)].refundable_balance = sp.as_nat(self.data.balances[sp.record(address=sp.sender,coin_name=coin_name)].refundable_balance - value) + record = sp.record(address=sp.sender,coin_name=coin_name) + with sp.if_(self.data.balances.contains(record)): + sp.verify(self.data.balances[record].refundable_balance >= value, message="Imbalance") + self.data.balances[record].refundable_balance = \ + sp.as_nat(self.data.balances[record].refundable_balance - value) self.refund(sp.sender, coin_name, value) with sp.else_(): sp.failwith("NoRefundableBalance") @@ -517,88 +526,47 @@ def payment_transfer(self, to, amount): sp.send(to, sp.utils.nat_to_mutez(amount), message="PaymentFailed") - @sp.entry_point - def callback_balance_of(self, param): - t_balance_of_request = sp.TRecord(owner=sp.TAddress, token_id=sp.TNat).layout(("owner", "token_id")) - t_balance_of_response = sp.TRecord(request=t_balance_of_request, balance=sp.TNat).layout(("request", "balance")) - sp.set_type(param, sp.TList(t_balance_of_response)) - - return_string = sp.local("return_string_", sp.string("")) - bts_core_balance = sp.local("bts_core_balance", sp.nat(0)) - sp.for item in param: - bts_core_balance.value = item.balance - with sp.if_(bts_core_balance.value >= self.data.callback_value): - # call transfer in FA2 - transfer_args_type = sp.TList(sp.TRecord(from_=sp.TAddress, txs=sp.TList(sp.TRecord( - to_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout(("to_", ("token_id", "amount")))) - ).layout(("from_", "txs"))) - transfer_entry_point = sp.contract(transfer_args_type, self.data.coins[self.data.callback_coin_name], "transfer").open_some() - transfer_args = [ - sp.record(from_=sp.self_address, txs=[sp.record(to_=self.data.callback_to, token_id=sp.nat(0), - amount=self.data.callback_value)])] - sp.transfer(transfer_args, sp.tez(0), transfer_entry_point) - return_string.value = "success" - with sp.else_(): - return_string.value = "fail" - - self.data.callback_coin_name = sp.string("") - self.data.callback_value = sp.nat(0) - self.data.callback_to = sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg") - - temp_callback = sp.contract(sp.TOption(sp.TString), self.data.bts_periphery_address.open_some("Address not set"), "callback_mint") - sp.transfer(sp.some(return_string.value), sp.tez(0), temp_callback.open_some()) - @sp.entry_point(lazify=False) def update_mint(self, ep): self.only_owner() sp.set_entry_point("mint", ep) @sp.entry_point(lazify=True) - def mint(self, to, coin_name, value, callback): + def mint(self, to, coin_name, value): """ mint the wrapped coin. :param to: the account receive the minted coin :param coin_name: coin name :param value: the minted amount - :param callback: callback function type in bts_periphery :return: """ sp.set_type(to, sp.TAddress) sp.set_type(coin_name, sp.TString) sp.set_type(value, sp.TNat) - sp.set_type(callback, sp.TContract(sp.TOption(sp.TString))) self.only_bts_periphery() with sp.if_(coin_name == self.data.native_coin_name): self.payment_transfer(to, value) - sp.transfer(sp.some("success"), sp.tez(0), callback) with sp.else_(): - with sp.if_(self.data.coin_details[coin_name].coin_type == self.NATIVE_WRAPPED_COIN_TYPE): + _coin_type = self.data.coin_details[coin_name].coin_type + _coin_address = self.data.coins[coin_name] + with sp.if_(_coin_type == self.NATIVE_WRAPPED_COIN_TYPE): # call mint in FA2 mint_args_type = sp.TList(sp.TRecord(to_=sp.TAddress, amount=sp.TNat).layout(("to_", "amount"))) - mint_entry_point = sp.contract(mint_args_type, self.data.coins[coin_name], "mint").open_some() + mint_entry_point = sp.contract(mint_args_type, _coin_address, "mint").open_some() mint_args = [sp.record(to_=to, amount=value)] sp.transfer(mint_args, sp.tez(0), mint_entry_point) - sp.transfer(sp.some("success"), sp.tez(0), callback) with sp.else_(): - sp.if self.data.coin_details[coin_name].coin_type == self.NON_NATIVE_TOKEN_TYPE: - # call balance_of FA2 - t_balance_of_request = sp.TRecord(owner=sp.TAddress, token_id=sp.TNat).layout(("owner", "token_id")) - t_balance_of_response = sp.TRecord(request=t_balance_of_request, balance=sp.TNat).layout(("request", "balance")) - t_balance_of_params = sp.TRecord(callback=sp.TContract(sp.TList(t_balance_of_response)), - requests=sp.TList(t_balance_of_request),).layout(("requests", "callback")) - - transfer_args_type = t_balance_of_params - transfer_entry_point = sp.contract(transfer_args_type, self.data.coins[coin_name], - "balance_of").open_some() - _callback = sp.contract(sp.TList(t_balance_of_response), sp.self_address, "callback_balance_of") - transfer_args = sp.record(callback=_callback.open_some(), requests=[sp.record(owner=sp.self_address, token_id=sp.nat(0))]) + sp.if _coin_type == self.NON_NATIVE_TOKEN_TYPE: + transfer_args_type = sp.TList(sp.TRecord(from_=sp.TAddress, txs=sp.TList(sp.TRecord( + to_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout(( + "to_", ("token_id", "amount"))))).layout(("from_", "txs")) + ) + transfer_entry_point = sp.contract(transfer_args_type, _coin_address, "transfer").open_some() + transfer_args = [ + sp.record(from_=sp.self_address, txs=[sp.record(to_=to, token_id=sp.nat(0), amount=value)])] sp.transfer(transfer_args, sp.tez(0), transfer_entry_point) - self.data.callback_coin_name = coin_name - self.data.callback_value = value - self.data.callback_to = to - @sp.entry_point(lazify=False) def update_handle_response_service(self, ep): self.only_owner() @@ -631,31 +599,39 @@ def handle_response_service(self, requester, coin_name, value, fee, rsp_code): sp.if return_flag.value == False: amount = sp.local("amount", value + fee, t=sp.TNat) - sp.if self.data.balances.contains(sp.record(address=requester, coin_name=coin_name)): - self.data.balances[sp.record(address=requester, coin_name=coin_name)].locked_balance = \ - sp.as_nat(self.data.balances.get(sp.record(address=requester, coin_name=coin_name), - default_value=sp.record(locked_balance=sp.nat(0), refundable_balance=sp.nat(0))).locked_balance - amount.value) + user= sp.record(address=requester, coin_name=coin_name) + _user_balances=self.data.balances.get(user,default_value=sp.record(locked_balance=sp.nat(0), + refundable_balance=sp.nat(0))) + + self.data.balances[user].locked_balance = sp.as_nat(_user_balances.locked_balance - amount.value) sp.if rsp_code == self.RC_ERR: with sp.if_(coin_name == self.data.native_coin_name): + # NATIVE COIN CASE with sp.if_(sp.utils.mutez_to_nat(sp.balance) >= value): self.payment_transfer(requester, value) with sp.else_(): - self.data.balances[sp.record(address=requester, coin_name=coin_name)].refundable_balance = self.data.balances.get( - sp.record(address=requester, coin_name=coin_name), - default_value=sp.record(locked_balance=sp.nat(0), refundable_balance=sp.nat(0))).refundable_balance + value + self.data.balances[user].refundable_balance = _user_balances.refundable_balance + value with sp.else_(): + _fa2_address = self.data.coins[coin_name] with sp.if_(self.data.coin_details[coin_name].coin_type == self.NON_NATIVE_TOKEN_TYPE): # call transfer in NON_NATIVE_TOKEN_TYPE FA2 - transfer_args_type = sp.TList(sp.TRecord(from_=sp.TAddress, txs=sp.TList(sp.TRecord( - to_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout(("to_", ("token_id", "amount")))) - ).layout(("from_", "txs"))) - transfer_entry_point = sp.contract(transfer_args_type, self.data.coins[coin_name], "transfer").open_some() - transfer_args = [sp.record(from_=sp.self_address, txs=[ - sp.record(to_=requester, token_id=sp.nat(0), amount=value)])] - sp.transfer(transfer_args, sp.tez(0), transfer_entry_point) + bts_core_fa2_balance = sp.view("get_balance_of", _fa2_address, + [sp.record(owner=sp.self_address, token_id=sp.nat(0))], + t=sp.TNat).open_some("Invalid view") + with sp.if_(bts_core_fa2_balance >= value): + transfer_args_type = sp.TList(sp.TRecord(from_=sp.TAddress, txs=sp.TList(sp.TRecord( + to_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout( + ("to_", ("token_id", "amount"))))).layout(("from_", "txs")) + ) + transfer_entry_point = sp.contract(transfer_args_type, _fa2_address, "transfer").open_some() + transfer_args = [sp.record(from_=sp.self_address, txs=[ + sp.record(to_=requester, token_id=sp.nat(0), amount=value)])] + sp.transfer(transfer_args, sp.tez(0), transfer_entry_point) + with sp.else_(): + self.data.balances[user].refundable_balance = _user_balances.refundable_balance + value with sp.else_(): - _fa2_address = self.data.coins[coin_name] + # Case of NATIVE_WRAPPED_COIN_TYPE transfer_permissions = sp.view("transfer_permissions", _fa2_address, sp.record( from_=sp.self_address, token_id=sp.nat(0)), t=sp.TBool).open_some() @@ -663,29 +639,30 @@ def handle_response_service(self, requester, coin_name, value, fee, rsp_code): # call transfer in NATIVE_WRAPPED_COIN_TYPE FA2 transfer_args_type = sp.TList(sp.TRecord( from_=sp.TAddress, - txs=sp.TList(sp.TRecord(to_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout(("to_", ("token_id", "amount")))) - ).layout(("from_", "txs"))) + txs=sp.TList(sp.TRecord(to_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout( + ("to_", ("token_id", "amount"))))).layout(("from_", "txs")) + ) transfer_entry_point = sp.contract(transfer_args_type, _fa2_address, "transfer").open_some() transfer_args = [ - sp.record(from_=sp.self_address, txs=[sp.record(to_=requester, token_id=sp.nat(0), amount=value)])] + sp.record(from_=sp.self_address, txs=[sp.record(to_=requester, token_id=sp.nat(0), + amount=value)])] sp.transfer(transfer_args, sp.tez(0), transfer_entry_point) with sp.else_(): - self.data.balances[sp.record(address=requester, coin_name=coin_name)].refundable_balance = \ - self.data.balances.get(sp.record(address=requester, coin_name=coin_name), - default_value=sp.record(locked_balance=sp.nat(0), - refundable_balance=sp.nat(0)) - ).refundable_balance + value + self.data.balances[user].refundable_balance = _user_balances.refundable_balance + value sp.if rsp_code == self.RC_OK: fa2_address = self.data.coins[coin_name] - sp.if (coin_name != self.data.native_coin_name) & (self.data.coin_details[coin_name].coin_type == self.NATIVE_WRAPPED_COIN_TYPE): + with sp.if_((coin_name != self.data.native_coin_name) &\ + (self.data.coin_details[coin_name].coin_type == self.NATIVE_WRAPPED_COIN_TYPE)): # call burn in FA2 - burn_args_type = sp.TList(sp.TRecord(from_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout(("from_", ("token_id", "amount")))) + burn_args_type = sp.TList(sp.TRecord(from_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout( + ("from_", ("token_id", "amount")))) burn_entry_point = sp.contract(burn_args_type, fa2_address, "burn").open_some() burn_args = [sp.record(from_=sp.self_address, token_id=sp.nat(0), amount=value)] sp.transfer(burn_args, sp.tez(0), burn_entry_point) - self.data.aggregation_fee[coin_name] = self.data.aggregation_fee.get(coin_name, default_value=sp.nat(0)) + fee + self.data.aggregation_fee[coin_name] = self.data.aggregation_fee.get(coin_name, default_value=sp.nat(0))\ + + fee @sp.entry_point(lazify=False) def update_transfer_fees(self, ep): @@ -702,35 +679,25 @@ def transfer_fees(self, fa): sp.set_type(fa, sp.TString) self.only_bts_periphery() - l = sp.local("l", sp.nat(0)) + + transfer_fes_details = sp.local("transfer_fes_details", [], t=sp.TList(sp.TRecord(coin_name=sp.TString, + value=sp.TNat, fee=sp.TNat))) sp.for item in self.data.coins_name: sp.if self.data.aggregation_fee.get(item, default_value=sp.nat(0)) != sp.nat(0): - self.data.charged_coins[l.value] = item - self.data.charged_amounts[l.value] = self.data.aggregation_fee.get(item, default_value=sp.nat(0)) + transfer_fes_details.value.push(sp.record(coin_name=item, value=self.data.aggregation_fee.get( + item, default_value=sp.nat(0)), fee=sp.nat(0))) del self.data.aggregation_fee[item] - l.value += sp.nat(1) - - _charged_coins = sp.local("_charged_coins", self.data.charged_coins) - _charged_amounts = sp.local("_charged_amounts", self.data.charged_amounts) # call send_service_message on bts_periphery send_service_message_args_type = sp.TRecord(_from=sp.TAddress, to=sp.TString, - coin_names=sp.TMap(sp.TNat, sp.TString), - values=sp.TMap(sp.TNat, sp.TNat), - fees=sp.TMap(sp.TNat, sp.TNat)) + coin_details=sp.TList(sp.TRecord(coin_name=sp.TString, + value=sp.TNat, fee=sp.TNat))) send_service_message_entry_point = sp.contract(send_service_message_args_type, self.data.bts_periphery_address.open_some("Address not set"), "send_service_message").open_some() - send_service_message_args = sp.record(_from=sp.self_address, to=fa, coin_names=_charged_coins.value, - values=_charged_amounts.value, - fees=sp.map({})) + send_service_message_args = sp.record(_from=sp.self_address, to=fa, coin_details=transfer_fes_details.value) sp.transfer(send_service_message_args, sp.tez(0), send_service_message_entry_point) - sp.for i in sp.range(0, sp.len(self.data.charged_coins)): - del self.data.charged_coins[i] - - sp.for i in sp.range(0, sp.len(self.data.charged_amounts)): - del self.data.charged_amounts[i] def _lock_balance(self, to, coin_name, value): new_balance = self.data.balances.get(sp.record(address=to, coin_name=coin_name), @@ -739,22 +706,11 @@ def _lock_balance(self, to, coin_name, value): self.data.balances[sp.record(address=to, coin_name=coin_name)] = sp.record( locked_balance=new_balance.locked_balance + value, refundable_balance=new_balance.refundable_balance) - @sp.entry_point - def update_coin_db(self): - self.only_owner() - self.data.coins[self.data.native_coin_name] = self.NATIVE_COIN_ADDRESS - self.data.coins_address[self.NATIVE_COIN_ADDRESS] = self.data.native_coin_name - self.data.coin_details[self.data.native_coin_name].addr = self.NATIVE_COIN_ADDRESS - - sp.for item in self.data.coins_name: - sp.if item != self.data.native_coin_name: - self.data.coins_address[self.data.coin_details[item].addr] = item - @sp.entry_point def set_bts_owner_manager(self, owner_manager): sp.set_type(owner_manager, sp.TAddress) - - sp.verify(self.data.owners.get(sp.sender) == True , message= "Unauthorized") + self.only_owner() + # sp.verify(self.data.owners.get(sp.sender) == True , message= "Unauthorized") self.data.bts_owner_manager = owner_manager diff --git a/smartpy/bts/contracts/src/bts_owner_manager.py b/smartpy/bts/contracts/src/bts_owner_manager.py index 63429ba8..68e98a08 100644 --- a/smartpy/bts/contracts/src/bts_owner_manager.py +++ b/smartpy/bts/contracts/src/bts_owner_manager.py @@ -5,11 +5,9 @@ class BTSOwnerManager(sp.Contract): def __init__(self, owner): self.init( owners=sp.map({owner: True}), - set_of_owners=sp.set([owner]) ) self.init_type(sp.TRecord( owners=sp.TMap(sp.TAddress, sp.TBool), - set_of_owners=sp.TSet(sp.TAddress) )) def only_owner(self): @@ -27,7 +25,6 @@ def add_owner(self, owner): sp.verify(self.data.owners[owner] == False, message="ExistedOwner") self.data.owners[owner] = True - self.data.set_of_owners.add(owner) sp.emit(sp.record(sender=sp.sender, owner=owner), tag="NewOwnerAdded") @sp.entry_point @@ -38,20 +35,21 @@ def remove_owner(self, owner): """ sp.set_type(owner, sp.TAddress) - sp.verify(sp.len(self.data.set_of_owners.elements()) > 1, message="CannotRemoveMinOwner") + self.only_owner() + sp.verify(sp.len(self.data.owners) > 1, message="CannotRemoveMinOwner") sp.verify(self.data.owners[owner] == True, message="NotOwner") del self.data.owners[owner] - self.data.set_of_owners.remove(owner) sp.emit(sp.record(sender=sp.sender, owner=owner), tag="OwnerRemoved") @sp.onchain_view() def is_owner(self, owner): - sp.result(self.data.owners[owner]) + sp.set_type(owner, sp.TAddress) + sp.result(self.data.owners.get(owner, default_value=False)) @sp.onchain_view() def get_owners(self): - sp.result(self.data.set_of_owners.elements()) + sp.result(self.data.owners.keys()) @sp.add_test(name="BTSOwnerManager") diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index 850e2188..c2f7e05b 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -25,8 +25,7 @@ def __init__(self, bmc_address, bts_core_address, helper_contract, parse_address serial_no = sp.int(0), number_of_pending_requests = sp.nat(0), helper=helper_contract, - parse_contract=parse_address, - mint_status=sp.none + parse_contract=parse_address ) def only_bmc(self): @@ -72,43 +71,41 @@ def has_pending_request(self): """ sp.result(self.data.number_of_pending_requests != sp.nat(0)) - # private function to return the tx status made from handle_btp_message + # private function for adding blacklist address def _add_to_blacklist(self, params): """ :param params: List of addresses to be blacklisted :return: """ - sp.set_type(params, sp.TMap(sp.TNat, sp.TString)) + sp.set_type(params, sp.TList(sp.TString)) - add_blacklist_status = sp.local("add_blacklist_status", "") + add_blacklist_status = sp.local("add_blacklist_status", "success") with sp.if_(sp.len(params) <= self.MAX_BATCH_SIZE): - sp.for i in sp.range(sp.nat(0), sp.len(params)): - parsed_addr = sp.view("str_to_addr", self.data.parse_contract, params.get(i), t=sp.TAddress).open_some() + sp.for item in params: + parsed_addr = sp.view("str_to_addr", self.data.parse_contract, item, t=sp.TAddress).open_some() with sp.if_(parsed_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): self.data.blacklist[parsed_addr] = True - add_blacklist_status.value = "success" with sp.else_(): add_blacklist_status.value = "InvalidAddress" with sp.else_(): add_blacklist_status.value = "error" return add_blacklist_status.value - # private function to return the tx status made from handle_btp_message + # private function for removing blacklist address def _remove_from_blacklist(self, params): """ :param params: list of address strings :return: """ - sp.set_type(params, sp.TMap(sp.TNat, sp.TString)) + sp.set_type(params, sp.TList(sp.TString)) - remove_blacklist_status = sp.local("remove_blacklist_status", "") + remove_blacklist_status = sp.local("remove_blacklist_status", "success") with sp.if_(sp.len(params) <= self.MAX_BATCH_SIZE): - sp.for i in sp.range(sp.nat(0), sp.len(params)): - parsed_addr = sp.view("str_to_addr", self.data.parse_contract, params.get(i), t=sp.TAddress).open_some() + sp.for item in params: + parsed_addr = sp.view("str_to_addr", self.data.parse_contract, item, t=sp.TAddress).open_some() with sp.if_(parsed_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): with sp.if_(self.data.blacklist.contains(parsed_addr)): del self.data.blacklist[parsed_addr] - remove_blacklist_status.value = "success" with sp.else_(): remove_blacklist_status.value = "UserNotBlacklisted" with sp.else_(): @@ -118,37 +115,35 @@ def _remove_from_blacklist(self, params): return remove_blacklist_status.value @sp.entry_point - def set_token_limit(self, coin_names, token_limit): + def set_token_limit(self, coin_names_limit): """ - :param coin_names: list of coin names - :param token_limit: list of token limits + :param coin_names_limit: map of coin names and its limits :return: """ - sp.set_type(coin_names, sp.TMap(sp.TNat, sp.TString)) - sp.set_type(token_limit, sp.TMap(sp.TNat, sp.TNat)) + sp.set_type(coin_names_limit, sp.TMap(sp.TString, sp.TNat)) + # sp.set_type(token_limit, sp.TMap(sp.TNat, sp.TNat)) sp.verify((sp.sender == sp.self_address )| (sp.sender == self.data.bts_core), "Unauthorized") - sp.verify(sp.len(coin_names) == sp.len(token_limit), "InvalidParams") - sp.verify(sp.len(coin_names) <= self.MAX_BATCH_SIZE, "BatchMaxSizeExceed") + # sp.verify(sp.len(coin_names_limits) == sp.len(token_limit), "InvalidParams") + sp.verify(sp.len(coin_names_limit) <= self.MAX_BATCH_SIZE, "BatchMaxSizeExceed") - sp.for i in sp.range(0, sp.len(coin_names)): - self.data.token_limit[coin_names[i]] = token_limit.get(i) + coin_names_limit_items = coin_names_limit.items() + sp.for item in coin_names_limit_items: + self.data.token_limit[item.key] = item.value # private function to return the tx status made from handle_btp_message - def _set_token_limit(self, coin_names, token_limit): + def _set_token_limit(self, coin_name_limit): """ :param coin_names: list of coin names :param token_limit: list of token limits :return: """ - sp.set_type(coin_names, sp.TMap(sp.TNat, sp.TString)) - sp.set_type(token_limit, sp.TMap(sp.TNat, sp.TNat)) - - set_limit_status = sp.local("set_limit_status", "") - with sp.if_((sp.len(coin_names) == sp.len(token_limit)) & (sp.len(coin_names) <= self.MAX_BATCH_SIZE)): - sp.for i in sp.range(0, sp.len(coin_names)): - self.data.token_limit[coin_names[i]] = token_limit.get(i) - set_limit_status.value = "success" + sp.set_type(coin_name_limit, sp.TMap(sp.TString, sp.TNat)) + + set_limit_status = sp.local("set_limit_status", "success") + with sp.if_(sp.len(coin_name_limit) <= self.MAX_BATCH_SIZE): + sp.for item in coin_name_limit.items(): + self.data.token_limit[item.key] = item.value with sp.else_(): set_limit_status.value = "error" return set_limit_status.value @@ -159,39 +154,29 @@ def update_send_service_message(self, ep): sp.set_entry_point("send_service_message", ep) @sp.entry_point(lazify=True) - def send_service_message(self, _from, to, coin_names, values, fees): + def send_service_message(self, _from, to, coin_details): """ Send service message to BMC :param _from: from address :param to: to address - :param coin_names: - :param values: - :param fees: + :param coin_details: :return: """ sp.set_type(_from, sp.TAddress) sp.set_type(to, sp.TString) - sp.set_type(coin_names, sp.TMap(sp.TNat, sp.TString)) - sp.set_type(values, sp.TMap(sp.TNat, sp.TNat)) - sp.set_type(fees, sp.TMap(sp.TNat, sp.TNat)) + sp.set_type(coin_details, sp.TList(sp.TRecord(coin_name=sp.TString, value=sp.TNat, fee=sp.TNat))) self.only_bts_core() to_network, to_address = sp.match_pair(strings.split_btp_address(to)) - assets = sp.compute(sp.map(tkey=sp.TNat, tvalue=types.Types.Asset)) assets_details = sp.compute(sp.map(tkey=sp.TNat, tvalue=types.Types.AssetTransferDetail)) - sp.for i in sp.range(sp.nat(0), sp.len(coin_names)): - assets[i]=sp.record( - coin_name=coin_names.get(i, default_value=sp.string("CoinNotFound")), - value=values.get(i, default_value=sp.nat(0)) - ) - assets_details[i] = sp.record( - coin_name=coin_names.get(i, default_value=sp.string("CoinNotFound")), - value=values.get(i, default_value=sp.nat(0)), - fee=fees.get(i, default_value=sp.nat(0)) - ) + + i=sp.local("i_", sp.nat(0)) + sp.for item in coin_details: + assets_details[i.value]= item + i.value += sp.nat(1) self.data.serial_no += 1 @@ -202,17 +187,20 @@ def send_service_message(self, _from, to, coin_names, values, fees): send_message_args = sp.record( to=to_network, svc=self.service_name, sn=self.data.serial_no, msg = self.encode_service_message(sp.record(service_type_value=sp.nat(0), - data=self.encode_transfer_coin_msg(sp.record(from_addr=start_from, to=to_address, assets=assets)))) + data=self.encode_transfer_coin_msg(sp.record(from_addr=start_from, to=to_address, + assets=coin_details)) + ) + ) ) sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) # push pending tx into record list self.data.requests[self.data.serial_no] = sp.record( - from_=start_from, to=to, coin_names=coin_names, amounts=values, fees=fees - ) - self.data.number_of_pending_requests +=sp.nat(1) - sp.emit(sp.record(from_address=_from, to=to, serial_no=self.data.serial_no, assets_details=assets_details), tag="TransferStart") + from_=start_from, to=to, coin_details=coin_details) + self.data.number_of_pending_requests += sp.nat(1) + sp.emit(sp.record(from_address=_from, to=to, serial_no=self.data.serial_no, + assets_details=assets_details), tag="TransferStart") @sp.entry_point(lazify=False) def update_handle_btp_message(self, ep): @@ -238,45 +226,45 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, bsh_addr, prev, call sp.set_type(svc, sp.TString) sp.set_type(sn, sp.TInt) sp.set_type(msg, sp.TBytes) - sp.set_type(callback, sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress, prev=sp.TString, callback_msg=sp.TRecord( - src=sp.TString, dst=sp.TString, svc=sp.TString, sn=sp.TInt, message=sp.TBytes) + sp.set_type(callback, sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress, + prev=sp.TString, callback_msg=sp.TRecord(src=sp.TString, + dst=sp.TString, svc=sp.TString, sn=sp.TInt, message=sp.TBytes) ))) sp.set_type(bsh_addr, sp.TAddress) check_caller = self.only_bmc() - callback_string = sp.local("callback_string", "") + callback_string = sp.local("callback_string", "success") with sp.if_((svc == self.service_name) & (check_caller == "Authorized")): - err_msg = sp.local("error", "") decode_call = self.decode_service_message(msg) with sp.if_(decode_call.status == "Success"): sm = decode_call.rv with sm.serviceType.match_cases() as arg: with arg.match("REQUEST_COIN_TRANSFER") as a1: - callback_string.value = "success" tc_call = self.decode_transfer_coin_msg(sm.data) with sp.if_(tc_call.status == "Success"): tc = tc_call.value - parsed_addr = sp.view("str_to_addr", self.data.parse_contract, tc.to, t=sp.TAddress).open_some() + parsed_addr = sp.view("str_to_addr", self.data.parse_contract, + tc.to, t=sp.TAddress).open_some() with sp.if_(parsed_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): - handle_request_call = self._handle_request_service(tc.to, tc.assets) + handle_request_call= self._handle_request_service(parsed_addr, tc.assets) with sp.if_(handle_request_call == "success"): - self.send_response_message(sp.variant("RESPONSE_HANDLE_SERVICE", 2), sp.nat(2), _from, sn, "", self.RC_OK) - sp.emit(sp.record(from_address=_from, to=parsed_addr, serial_no=self.data.serial_no, assets_details=tc.assets), tag="TransferReceived") + self.send_response_message(sp.variant("RESPONSE_HANDLE_SERVICE", 2), sp.nat(2), + _from, sn, "", self.RC_OK) + sp.emit(sp.record(from_address=_from, to=parsed_addr, serial_no=self.data.serial_no, + assets_details=tc.assets), tag="TransferReceived") with sp.else_(): - err_msg.value = handle_request_call - self.send_response_message(sp.variant("RESPONSE_HANDLE_SERVICE", 2), sp.nat(2), _from, sn, err_msg.value, - self.RC_ERR) + self.send_response_message(sp.variant("RESPONSE_HANDLE_SERVICE", 2), sp.nat(2), + _from, sn, handle_request_call, self.RC_ERR) with sp.else_(): - err_msg.value = "InvalidAddress" - self.send_response_message(sp.variant("RESPONSE_HANDLE_SERVICE", 2), sp.nat(2), _from, sn, err_msg.value, self.RC_ERR) + self.send_response_message(sp.variant("RESPONSE_HANDLE_SERVICE", 2), sp.nat(2), _from, + sn, "InvalidAddress", self.RC_ERR) with sp.else_(): callback_string.value = "ErrorInDecodingTransferCoin" with arg.match("BLACKLIST_MESSAGE") as a2: - callback_string.value = "success" bm_call = self.decode_blacklist_msg(sm.data) with sp.if_(bm_call.status == "Success"): bm = bm_call.rv @@ -286,35 +274,40 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, bsh_addr, prev, call with b_agr.match("ADD_TO_BLACKLIST") as b_val_1: add_blacklist_call = self._add_to_blacklist(addresses) with sp.if_(add_blacklist_call == "success"): - self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, sn, "AddedToBlacklist", self.RC_OK) + self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, + sn, "AddedToBlacklist", self.RC_OK) with sp.else_(): - self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, sn, "ErrorAddToBlackList", self.RC_ERR) + self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, + sn, "ErrorAddToBlackList", self.RC_ERR) with b_agr.match("REMOVE_FROM_BLACKLIST") as b_val_2: remove_blacklist_call = self._remove_from_blacklist(addresses) with sp.if_(remove_blacklist_call == "success"): - self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, sn, "RemovedFromBlacklist", self.RC_OK) + self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, + sn, "RemovedFromBlacklist", self.RC_OK) with sp.else_(): - self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, sn, "ErrorRemoveFromBlackList", self.RC_ERR) + self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, + sn, "ErrorRemoveFromBlackList", self.RC_ERR) with b_agr.match("ERROR") as b_val_2: - self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, sn, "BlacklistServiceTypeErr", self.RC_ERR) + self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, sn, + "BlacklistServiceTypeErr", self.RC_ERR) with sp.else_(): callback_string.value = "ErrorInDecodingBlacklist" with arg.match("CHANGE_TOKEN_LIMIT") as a3: - callback_string.value = "success" tl_call = self.decode_token_limit_msg(sm.data) with sp.if_(tl_call.status == "Success"): tl = tl_call.rv - coin_names = tl.coin_name - token_limits = tl.token_limit + coin_name_limit = tl.coin_name_limit - set_limit_call = self._set_token_limit(coin_names, token_limits) + set_limit_call = self._set_token_limit(coin_name_limit) with sp.if_(set_limit_call == "success"): - self.send_response_message(sp.variant("CHANGE_TOKEN_LIMIT", 4), sp.nat(4), _from, sn, "ChangeTokenLimit", self.RC_OK) + self.send_response_message(sp.variant("CHANGE_TOKEN_LIMIT", 4), sp.nat(4), _from, sn, + "ChangeTokenLimit", self.RC_OK) with sp.else_(): - self.send_response_message(sp.variant("CHANGE_TOKEN_LIMIT", 4), sp.nat(4), _from, sn, "ErrorChangeTokenLimit", self.RC_ERR) + self.send_response_message(sp.variant("CHANGE_TOKEN_LIMIT", 4), sp.nat(4), _from, sn, + "ErrorChangeTokenLimit", self.RC_ERR) with sp.else_(): callback_string.value = "ErrorInDecodingTokenLimit" @@ -324,9 +317,7 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, bsh_addr, prev, call response = fn_call.rv with sp.if_(fn_call.status == "Success"): handle_response = self.handle_response_service(sn, response.code, response.message) - with sp.if_(handle_response == "success"): - callback_string.value = "success" - with sp.else_(): + with sp.if_(handle_response != "success"): callback_string.value = "fail" with sp.else_(): callback_string.value = "ErrorInDecoding" @@ -334,12 +325,11 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, bsh_addr, prev, call callback_string.value = "InvalidSN" with arg.match("UNKNOWN_TYPE") as a5: - callback_string.value = "success" sp.emit(sp.record(_from=_from, sn=sn), tag= "UnknownResponse") with arg.match("ERROR") as a5: - callback_string.value = "success" - self.send_response_message(sp.variant("UNKNOWN_TYPE", 5), sp.nat(5), _from, sn, "Unknown",self.RC_ERR) + self.send_response_message(sp.variant("UNKNOWN_TYPE", 5), sp.nat(5), _from, sn, + "Unknown",self.RC_ERR) with sp.else_(): callback_string.value = "ErrorInDecoding" with sp.else_(): @@ -371,25 +361,28 @@ def handle_btp_error(self, svc, sn, code, msg, callback, bsh_addr): sp.set_type(sn, sp.TInt) sp.set_type(code, sp.TNat) sp.set_type(msg, sp.TString) - sp.set_type(callback, sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress,svc=sp.TString, sn=sp.TInt, code=sp.TNat, msg=sp.TString))) + sp.set_type(callback, sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress, + svc=sp.TString, sn=sp.TInt, code=sp.TNat, msg=sp.TString))) sp.set_type(bsh_addr, sp.TAddress) check_caller = self.only_bmc() - handle_btp_error_status = sp.local("handle_btp_error_statue", "") - with sp.if_((svc == self.service_name) & (check_caller == "Authorized") & (sp.len(sp.pack(self.data.requests.get(sn).from_)) != 0)): - emit_msg= sp.concat(["errCode: ", sp.view("string_of_int", self.data.parse_contract, sp.to_int(code), t=sp.TString).open_some(),", errMsg: ", msg]) + handle_btp_error_status = sp.local("handle_btp_error_status", "success") + with sp.if_((svc == self.service_name) & (check_caller == "Authorized") & (sp.len(sp.pack( + self.data.requests.get(sn).from_)) != 0)): + emit_msg= sp.concat(["errCode: ", sp.view("string_of_int", self.data.parse_contract, sp.to_int(code), + t=sp.TString).open_some(),", errMsg: ", msg]) handle_response_serv = self.handle_response_service(sn, self.RC_ERR, emit_msg) - with sp.if_(handle_response_serv == "success"): - handle_btp_error_status.value = "success" + with sp.if_(handle_response_serv != "success"): + handle_btp_error_status.value = "fail" with sp.else_(): - handle_btp_error_status.value = "fail" + handle_btp_error_status.value = "UnAuthorized" - return_value = sp.record(string=sp.some(handle_btp_error_status.value), bsh_addr=bsh_addr, svc=svc, sn=sn, code=code, msg=msg) + return_value = sp.record(string=sp.some(handle_btp_error_status.value), bsh_addr=bsh_addr, svc=svc, sn=sn, + code=code, msg=msg) sp.transfer(return_value, sp.tez(0), callback) def handle_response_service(self, sn, code, msg): """ - :param sn: :param code: :param msg: @@ -399,41 +392,62 @@ def handle_response_service(self, sn, code, msg): sp.set_type(code, sp.TNat) sp.set_type(msg, sp.TString) - caller = sp.local("caller", sp.view("str_to_addr", self.data.parse_contract, self.data.requests.get(sn).from_, t=sp.TAddress).open_some() - , sp.TAddress).value - loop = sp.local("loop", sp.len(self.data.requests.get(sn).coin_names), sp.TNat).value - response_call_status = sp.local("response_call_status", "") - with sp.if_(loop <= self.MAX_BATCH_SIZE): - sp.for i in sp.range(0, loop): - # inter score call - handle_response_service_args_type = sp.TRecord( - requester=sp.TAddress, coin_name=sp.TString, value=sp.TNat, fee=sp.TNat, rsp_code=sp.TNat - ) - handle_response_service_entry_point = sp.contract(handle_response_service_args_type, self.data.bts_core, "handle_response_service").open_some("invalid call") - handle_response_service_args = sp.record( - requester=caller, coin_name=self.data.requests.get(sn).coin_names.get(i, default_value=sp.string("CoinNotFound")), - value=self.data.requests.get(sn).amounts.get(i, default_value=sp.nat(0)),fee=self.data.requests.get(sn).fees.get(i, default_value=sp.nat(0)), rsp_code=code - ) - sp.transfer(handle_response_service_args, sp.tez(0), handle_response_service_entry_point) - - del self.data.requests[sn] - self.data.number_of_pending_requests = sp.as_nat(self.data.number_of_pending_requests-1) - - sp.emit(sp.record(caller=caller, sn=sn, code=code, msg=msg), tag="TransferEnd") - response_call_status.value = "success" + caller = sp.local("caller", sp.view("str_to_addr", self.data.parse_contract, + self.data.requests.get(sn).from_, + t=sp.TAddress).open_some(), sp.TAddress) + loop = sp.local("loop", sp.len(self.data.requests.get(sn).coin_details), sp.TNat) + response_call_status = sp.local("response_call_status", "success") + check_valid = sp.local("check_valid", True) + + with sp.if_(loop.value <= self.MAX_BATCH_SIZE): + sp.for item in self.data.requests.get(sn).coin_details: + bts_core_address = self.data.bts_core + coin_name = item.coin_name + value = item.value + fee = item.fee + amount = value + fee + bts_core_balance = sp.view("balance_of", bts_core_address, + sp.record(owner=caller.value, coin_name=coin_name), t= + sp.TRecord(usable_balance=sp.TNat, locked_balance=sp.TNat, + refundable_balance=sp.TNat, user_balance=sp.TNat) + ).open_some() + # check if caller has enough locked in bts_core + with sp.if_(bts_core_balance.locked_balance < amount): + check_valid.value = False + coin_type = sp.view("coin_type", bts_core_address, coin_name, t=sp.TNat).open_some() + with sp.if_(coin_type == sp.nat(1)): + coin_address = sp.view("coin_id", bts_core_address, coin_name, t=sp.TAddress).open_some() + bts_core_fa2_balance = sp.view("get_balance_of", coin_address, + [sp.record(owner=bts_core_address, token_id=sp.nat(0))], + t=sp.TNat).open_some("Invalid view") + # check if bts_core has enough NATIVE_WRAPPED_COIN_TYPE to burn + with sp.if_(bts_core_fa2_balance < value): + check_valid.value = False + + with sp.if_(check_valid.value == True): + sp.for _item in self.data.requests.get(sn).coin_details: + # inter score call + handle_response_service_args_type = sp.TRecord( + requester=sp.TAddress, coin_name=sp.TString, value=sp.TNat, fee=sp.TNat, rsp_code=sp.TNat) + handle_response_service_entry_point = sp.contract(handle_response_service_args_type, + self.data.bts_core, "handle_response_service").open_some("invalid call") + handle_response_service_args = sp.record( + requester=caller.value, coin_name=_item.coin_name, + value=_item.value, + fee=_item.fee, rsp_code=code + ) + sp.transfer(handle_response_service_args, sp.tez(0), handle_response_service_entry_point) + + del self.data.requests[sn] + self.data.number_of_pending_requests = sp.as_nat(self.data.number_of_pending_requests-1) + + sp.emit(sp.record(caller=caller.value, sn=sn, code=code, msg=msg), tag="TransferEnd") + with sp.else_(): + response_call_status.value = "Error in bts handle_response_service" with sp.else_(): response_call_status.value = "BatchMaxSizeExceed" - return response_call_status.value - - @sp.entry_point - def callback_mint(self, string): - sp.set_type(string, sp.TOption(sp.TString)) - sp.verify(sp.sender == self.data.bts_core, "Unauthorized") - self.data.mint_status = string - - sp.verify(self.data.mint_status.open_some() == "success", "TransferFailed") - self.data.mint_status = sp.none + return response_call_status.value def _handle_request_service(self, to, assets): """ @@ -442,33 +456,43 @@ def _handle_request_service(self, to, assets): :param assets: A list of requested coin respectively with an amount :return: """ - sp.set_type(to, sp.TString) + sp.set_type(to, sp.TAddress) sp.set_type(assets, sp.TMap(sp.TNat, types.Types.Asset)) - status = sp.local("status", "error") + status = sp.local("status", "success") check_validity = sp.local("check_validity", True) + bts_core_address = self.data.bts_core with sp.if_(sp.len(assets) <= self.MAX_BATCH_SIZE): - parsed_to = sp.view("str_to_addr", self.data.parse_contract, to, t=sp.TAddress).open_some() + parsed_to = to sp.for i in sp.range(0, sp.len(assets)): - valid_coin = sp.view("is_valid_coin", self.data.bts_core, assets[i].coin_name, t=sp.TBool).open_some() + coin_name = assets[i].coin_name + transferred_amount = assets[i].value + valid_coin = sp.view("is_valid_coin", bts_core_address, coin_name, t=sp.TBool).open_some() check_transfer = sp.view("check_transfer_restrictions", sp.self_address, sp.record( - coin_name=assets[i].coin_name, user=parsed_to, value=assets[i].value), t=sp.TBool).open_some() - sp.if (check_transfer == False) | (valid_coin == False): + coin_name=coin_name, user=parsed_to, value=transferred_amount), t=sp.TBool).open_some() + + native_coin_name, bts_core_balance = sp.match_pair(sp.view("native_coin_balance_of", bts_core_address, + sp.unit, t=sp.TPair(sp.TString, sp.TNat)).open_some("Invalid view")) + with sp.if_(native_coin_name == coin_name): + with sp.if_(bts_core_balance < transferred_amount): + check_validity.value = False + with sp.else_(): + coin_address = sp.view("coin_id", bts_core_address, coin_name, t=sp.TAddress).open_some() + bts_core_fa2_balance = sp.view("get_balance_of", coin_address, + [sp.record(owner=bts_core_address, token_id=sp.nat(0))], + t=sp.TNat).open_some("Invalid view") + with sp.if_(bts_core_fa2_balance < transferred_amount): + check_validity.value = False + + with sp.if_((check_transfer == False) | (valid_coin == False)) : check_validity.value = False - sp.if check_validity.value == True: + with sp.if_(check_validity.value == True): sp.for i in sp.range(0, sp.len(assets)): # inter score call - mint_args_type = sp.TRecord(callback=sp.TContract(sp.TOption(sp.TString)), - to=sp.TAddress, coin_name=sp.TString, value=sp.TNat - ) - mint_args_type_entry_point = sp.contract(mint_args_type, self.data.bts_core, "mint").open_some() - t = sp.TOption(sp.TString) - callback = sp.contract(t, sp.self_address, "callback_mint") - mint_args = sp.record(callback=callback.open_some(), - to=parsed_to, coin_name=assets[i].coin_name, value=assets[i].value - ) + mint_args_type = sp.TRecord(to=sp.TAddress, coin_name=sp.TString, value=sp.TNat) + mint_args_type_entry_point = sp.contract(mint_args_type, bts_core_address, "mint").open_some() + mint_args = sp.record(to=parsed_to, coin_name=assets[i].coin_name, value=assets[i].value) sp.transfer(mint_args, sp.tez(0), mint_args_type_entry_point) - status.value = "success" with sp.else_(): status.value = "UnregisteredCoin" with sp.else_(): @@ -499,13 +523,14 @@ def send_response_message(self, service_type, service_type_val, to, sn, msg, cod ) send_message_entry_point = sp.contract(send_message_args_type, self.data.bmc, "send_message").open_some() send_message_args = sp.record(to=to, svc=self.service_name, sn=sn, - msg=self.encode_service_message(sp.record(service_type_value=service_type_val, data=self.encode_response( + msg=self.encode_service_message(sp.record(service_type_value=service_type_val, + data=self.encode_response( sp.record(code=code, message=msg))))) sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) @sp.entry_point - def handle_fee_gathering(self, fa, svc, callback, bsh_addr): + def handle_fee_gathering(self, fa, svc, bsh_addr): """ BSH handle Gather Fee Message request from BMC contract :param fa: A BTP address of fee aggregator @@ -516,7 +541,6 @@ def handle_fee_gathering(self, fa, svc, callback, bsh_addr): """ sp.set_type(fa, sp.TString) sp.set_type(svc, sp.TString) - sp.set_type(callback, sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress))) sp.set_type(bsh_addr, sp.TAddress) check_caller = self.only_bmc() @@ -525,13 +549,10 @@ def handle_fee_gathering(self, fa, svc, callback, bsh_addr): # call transfer_fees of BTS_Core transfer_fees_args_type = sp.TString - transfer_fees_entry_point = sp.contract(transfer_fees_args_type, self.data.bts_core, "transfer_fees").open_some() + transfer_fees_entry_point = sp.contract(transfer_fees_args_type, self.data.bts_core, + "transfer_fees").open_some() sp.transfer(fa, sp.tez(0), transfer_fees_entry_point) - sp.transfer(sp.record(string=sp.some("success"), bsh_addr=bsh_addr), sp.tez(0), callback) - with sp.else_(): - sp.transfer(sp.record(string=sp.some("fail"), bsh_addr=bsh_addr), sp.tez(0), callback) - @sp.onchain_view() def check_transfer_restrictions(self, params): """ From f98461e093eeedc6bf9270c4a20595e06893ad4f Mon Sep 17 00:00:00 2001 From: suyogadhikari Date: Mon, 3 Jul 2023 09:38:55 +0545 Subject: [PATCH 127/211] fix(bts): onchain view return type fixed --- smartpy/bts/contracts/src/bts_core.py | 30 +++++++++++++----- smartpy/bts/contracts/src/bts_periphery.py | 36 +++++++++++++++------- 2 files changed, 47 insertions(+), 19 deletions(-) diff --git a/smartpy/bts/contracts/src/bts_core.py b/smartpy/bts/contracts/src/bts_core.py index 2ef6b076..200fed68 100644 --- a/smartpy/bts/contracts/src/bts_core.py +++ b/smartpy/bts/contracts/src/bts_core.py @@ -2,6 +2,13 @@ types = sp.io.import_script_from_url("file:./contracts/src/Types.py") FA2_contract = sp.io.import_script_from_url("file:./contracts/src/FA2_contract.py") +t_balance_of_request = sp.TRecord(owner=sp.TAddress, token_id=sp.TNat).layout( + ("owner", "token_id") +) + +t_balance_of_response = sp.TRecord( + request=t_balance_of_request, balance=sp.TNat +).layout(("request", "balance")) class BTSCore(sp.Contract): @@ -231,19 +238,22 @@ def balance_of(self, params): user_balance=sp.nat(0))) with sp.else_(): fa2_address = self.data.coins.get(params.coin_name) + user_balance = sp.local("user_balance_onchain_view", sp.nat(0)) usable_balance = sp.local("usable_balance", sp.nat(0), t=sp.TNat) - user_balance= sp.view("get_balance_of", fa2_address, [sp.record(owner=params.owner, token_id=sp.nat(0))], - t=sp.TNat).open_some("Invalid view") + user_balance_of= sp.view("get_balance_of", fa2_address, [sp.record(owner=params.owner, token_id=sp.nat(0))], + t=sp.TList(t_balance_of_response)).open_some("Invalid view") + sp.for elem in user_balance_of: + user_balance.value = elem.balance sp.if self.data.coin_details.get(params.coin_name).coin_type == self.NATIVE_WRAPPED_COIN_TYPE: allowance = sp.view("get_allowance", fa2_address, sp.record(spender=sp.self_address, owner=params.owner), t=sp.TNat).open_some("Invalid view") usable_balance.value = allowance - sp.if allowance > user_balance: - usable_balance.value = user_balance + sp.if allowance > user_balance.value: + usable_balance.value = user_balance.value # TODO: allowance for NON_NATIVE_TOKEN_TYPE also check allowance for bts core sp.result(sp.record(usable_balance=usable_balance.value, locked_balance=locked_balance.value, refundable_balance=refundable_balance.value, - user_balance=user_balance)) + user_balance=user_balance.value)) @sp.onchain_view() def balance_of_batch(self, params): @@ -591,6 +601,8 @@ def handle_response_service(self, requester, coin_name, value, fee, rsp_code): self.only_bts_periphery() return_flag = sp.local("return_flag", False, t=sp.TBool) + bts_core_fa2_balance = sp.local("fa2_token_balance_core", sp.nat(0)) + sp.if requester == sp.self_address: sp.if rsp_code == self.RC_ERR: self.data.aggregation_fee[coin_name] = self.data.aggregation_fee.get(coin_name, @@ -616,10 +628,12 @@ def handle_response_service(self, requester, coin_name, value, fee, rsp_code): _fa2_address = self.data.coins[coin_name] with sp.if_(self.data.coin_details[coin_name].coin_type == self.NON_NATIVE_TOKEN_TYPE): # call transfer in NON_NATIVE_TOKEN_TYPE FA2 - bts_core_fa2_balance = sp.view("get_balance_of", _fa2_address, + bts_core_fa2 = sp.view("get_balance_of", _fa2_address, [sp.record(owner=sp.self_address, token_id=sp.nat(0))], - t=sp.TNat).open_some("Invalid view") - with sp.if_(bts_core_fa2_balance >= value): + t=sp.TList(t_balance_of_response)).open_some("Invalid view") + sp.for elem in bts_core_fa2: + bts_core_fa2_balance.value = elem.balance + with sp.if_(bts_core_fa2_balance.value >= value): transfer_args_type = sp.TList(sp.TRecord(from_=sp.TAddress, txs=sp.TList(sp.TRecord( to_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout( ("to_", ("token_id", "amount"))))).layout(("from_", "txs")) diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index c2f7e05b..c15be7bb 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -3,7 +3,13 @@ types = sp.io.import_script_from_url("file:./contracts/src/Types.py") strings = sp.io.import_script_from_url("file:./contracts/src/String.py") rlp = sp.io.import_script_from_url("file:./contracts/src/RLP_struct.py") +t_balance_of_request = sp.TRecord(owner=sp.TAddress, token_id=sp.TNat).layout( + ("owner", "token_id") +) +t_balance_of_response = sp.TRecord( + request=t_balance_of_request, balance=sp.TNat +).layout(("request", "balance")) class BTSPeriphery(sp.Contract, rlp.DecodeEncodeLibrary): service_name = sp.string("bts") @@ -398,6 +404,7 @@ def handle_response_service(self, sn, code, msg): loop = sp.local("loop", sp.len(self.data.requests.get(sn).coin_details), sp.TNat) response_call_status = sp.local("response_call_status", "success") check_valid = sp.local("check_valid", True) + bts_core_fa2_balance = sp.local("fa2_token_balance_response_service", sp.nat(0)) with sp.if_(loop.value <= self.MAX_BATCH_SIZE): sp.for item in self.data.requests.get(sn).coin_details: @@ -417,11 +424,13 @@ def handle_response_service(self, sn, code, msg): coin_type = sp.view("coin_type", bts_core_address, coin_name, t=sp.TNat).open_some() with sp.if_(coin_type == sp.nat(1)): coin_address = sp.view("coin_id", bts_core_address, coin_name, t=sp.TAddress).open_some() - bts_core_fa2_balance = sp.view("get_balance_of", coin_address, + bts_core_fa2 = sp.view("get_balance_of", coin_address, [sp.record(owner=bts_core_address, token_id=sp.nat(0))], - t=sp.TNat).open_some("Invalid view") + t=sp.TList(t_balance_of_response)).open_some("Invalid view") + sp.for elem in bts_core_fa2: + bts_core_fa2_balance.value = elem.balance # check if bts_core has enough NATIVE_WRAPPED_COIN_TYPE to burn - with sp.if_(bts_core_fa2_balance < value): + with sp.if_(bts_core_fa2_balance.value < value): check_valid.value = False with sp.if_(check_valid.value == True): @@ -461,6 +470,7 @@ def _handle_request_service(self, to, assets): status = sp.local("status", "success") check_validity = sp.local("check_validity", True) + bts_core_fa2_balance = sp.local("fa2_token_balance", sp.nat(0)) bts_core_address = self.data.bts_core with sp.if_(sp.len(assets) <= self.MAX_BATCH_SIZE): parsed_to = to @@ -472,17 +482,21 @@ def _handle_request_service(self, to, assets): coin_name=coin_name, user=parsed_to, value=transferred_amount), t=sp.TBool).open_some() native_coin_name, bts_core_balance = sp.match_pair(sp.view("native_coin_balance_of", bts_core_address, - sp.unit, t=sp.TPair(sp.TString, sp.TNat)).open_some("Invalid view")) + sp.unit, t=sp.TPair(sp.TString, sp.TMutez)).open_some("Invalid view")) with sp.if_(native_coin_name == coin_name): - with sp.if_(bts_core_balance < transferred_amount): + with sp.if_(sp.utils.mutez_to_nat(bts_core_balance) < transferred_amount): check_validity.value = False with sp.else_(): - coin_address = sp.view("coin_id", bts_core_address, coin_name, t=sp.TAddress).open_some() - bts_core_fa2_balance = sp.view("get_balance_of", coin_address, - [sp.record(owner=bts_core_address, token_id=sp.nat(0))], - t=sp.TNat).open_some("Invalid view") - with sp.if_(bts_core_fa2_balance < transferred_amount): - check_validity.value = False + coin_type = sp.view("coin_type", bts_core_address, coin_name, t=sp.TNat).open_some() + with sp.if_((valid_coin == True) & (coin_type == sp.nat(2))): + coin_address = sp.view("coin_id", bts_core_address, coin_name, t=sp.TAddress).open_some() + bts_core_fa2 = sp.view("get_balance_of", coin_address, + [sp.record(owner=bts_core_address, token_id=sp.nat(0))], + t=sp.TList(t_balance_of_response)).open_some("Invalid view") + sp.for elem in bts_core_fa2: + bts_core_fa2_balance.value = elem.balance + with sp.if_(bts_core_fa2_balance.value < transferred_amount): + check_validity.value = False with sp.if_((check_transfer == False) | (valid_coin == False)) : check_validity.value = False From 88594d98d96235ec0184fae2e7e5e8d22be456a6 Mon Sep 17 00:00:00 2001 From: suyogadhikari Date: Mon, 3 Jul 2023 13:06:48 +0545 Subject: [PATCH 128/211] fix(bts): negative amount check skipped if caller is bts core . --- smartpy/bts/contracts/src/bts_periphery.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index c15be7bb..fa09b9f3 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -324,7 +324,7 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, bsh_addr, prev, call with sp.if_(fn_call.status == "Success"): handle_response = self.handle_response_service(sn, response.code, response.message) with sp.if_(handle_response != "success"): - callback_string.value = "fail" + callback_string.value = handle_response with sp.else_(): callback_string.value = "ErrorInDecoding" with sp.else_(): @@ -379,7 +379,7 @@ def handle_btp_error(self, svc, sn, code, msg, callback, bsh_addr): t=sp.TString).open_some(),", errMsg: ", msg]) handle_response_serv = self.handle_response_service(sn, self.RC_ERR, emit_msg) with sp.if_(handle_response_serv != "success"): - handle_btp_error_status.value = "fail" + handle_btp_error_status.value = handle_response_serv with sp.else_(): handle_btp_error_status.value = "UnAuthorized" @@ -419,7 +419,7 @@ def handle_response_service(self, sn, code, msg): refundable_balance=sp.TNat, user_balance=sp.TNat) ).open_some() # check if caller has enough locked in bts_core - with sp.if_(bts_core_balance.locked_balance < amount): + with sp.if_((bts_core_balance.locked_balance < amount) & (caller.value != bts_core_address)): check_valid.value = False coin_type = sp.view("coin_type", bts_core_address, coin_name, t=sp.TNat).open_some() with sp.if_(coin_type == sp.nat(1)): From 8efd9ca26e2c9b3e7db3443b983e6f174f7f8f1f Mon Sep 17 00:00:00 2001 From: simusud Date: Tue, 4 Jul 2023 17:18:04 +0545 Subject: [PATCH 129/211] style(bts): code formatting --- smartpy/bts/contracts/src/bts_core.py | 101 +++++++++------------ smartpy/bts/contracts/src/bts_periphery.py | 28 ++---- 2 files changed, 54 insertions(+), 75 deletions(-) diff --git a/smartpy/bts/contracts/src/bts_core.py b/smartpy/bts/contracts/src/bts_core.py index 200fed68..7d5f4e3e 100644 --- a/smartpy/bts/contracts/src/bts_core.py +++ b/smartpy/bts/contracts/src/bts_core.py @@ -2,14 +2,8 @@ types = sp.io.import_script_from_url("file:./contracts/src/Types.py") FA2_contract = sp.io.import_script_from_url("file:./contracts/src/FA2_contract.py") -t_balance_of_request = sp.TRecord(owner=sp.TAddress, token_id=sp.TNat).layout( - ("owner", "token_id") -) - -t_balance_of_response = sp.TRecord( - request=t_balance_of_request, balance=sp.TNat -).layout(("request", "balance")) - +t_balance_of_request = sp.TRecord(owner=sp.TAddress, token_id=sp.TNat).layout(("owner", "token_id")) +t_balance_of_response = sp.TRecord(request=t_balance_of_request, balance=sp.TNat).layout(("request", "balance")) class BTSCore(sp.Contract): FEE_DENOMINATOR = sp.nat(10000) @@ -65,8 +59,9 @@ def update_bts_periphery(self, bts_periphery): sp.set_type(bts_periphery, sp.TAddress) self.only_owner() - sp.if self.data.bts_periphery_address.is_some(): - has_requests = sp.view("has_pending_request", self.data.bts_periphery_address.open_some("Address not set"), sp.unit, t=sp.TBool).open_some("has_pending_request not found") + with sp.if_(self.data.bts_periphery_address.is_some()): + has_requests = sp.view("has_pending_request", self.data.bts_periphery_address.open_some("Address not set"), + sp.unit, t=sp.TBool).open_some("has_pending_request not found") sp.verify(has_requests == False, "HasPendingRequest") self.data.bts_periphery_address = sp.some(bts_periphery) @@ -152,7 +147,8 @@ def register(self, name, fee_numerator, fixed_fee, addr, token_metadata, metadat token_limit_map = sp.map({name:self.UINT_CAP}, tkey=sp.TString, tvalue=sp.TNat) # call set_token_limit on bts_periphery - set_token_limit_entry_point = sp.contract(sp.TMap(sp.TString, sp.TNat), self.data.bts_periphery_address.open_some("Address not set"), + set_token_limit_entry_point = sp.contract(sp.TMap(sp.TString, sp.TNat), + self.data.bts_periphery_address.open_some("Address not set"), "set_token_limit").open_some("Error in set_token_limit call") sp.transfer(token_limit_map, sp.tez(0), set_token_limit_entry_point) @@ -225,7 +221,7 @@ def balance_of(self, params): locked_balance = sp.local("locked_balance", sp.nat(0)) refundable_balance = sp.local("refundable_balance", sp.nat(0)) - sp.if self.data.balances.contains(sp.record(address=params.owner, coin_name=params.coin_name)): + with sp.if_(self.data.balances.contains(sp.record(address=params.owner, coin_name=params.coin_name))): locked_balance.value = self.data.balances[ sp.record(address=params.owner, coin_name=params.coin_name)].locked_balance refundable_balance.value = self.data.balances[ @@ -244,12 +240,13 @@ def balance_of(self, params): t=sp.TList(t_balance_of_response)).open_some("Invalid view") sp.for elem in user_balance_of: user_balance.value = elem.balance - sp.if self.data.coin_details.get(params.coin_name).coin_type == self.NATIVE_WRAPPED_COIN_TYPE: - allowance = sp.view("get_allowance", fa2_address, sp.record(spender=sp.self_address, owner=params.owner), t=sp.TNat).open_some("Invalid view") + with sp.if_(self.data.coin_details.get(params.coin_name).coin_type == self.NATIVE_WRAPPED_COIN_TYPE): + allowance = sp.view("get_allowance", fa2_address, + sp.record(spender=sp.self_address, owner=params.owner), t=sp.TNat).open_some("Invalid view") usable_balance.value = allowance - sp.if allowance > user_balance.value: + with sp.if_(allowance > user_balance.value): usable_balance.value = user_balance.value - # TODO: allowance for NON_NATIVE_TOKEN_TYPE also check allowance for bts core + sp.result(sp.record(usable_balance=usable_balance.value, locked_balance=locked_balance.value, refundable_balance=refundable_balance.value, @@ -264,7 +261,6 @@ def balance_of_batch(self, params): """ sp.set_type(params, sp.TRecord(owner=sp.TAddress, coin_names=sp.TList(sp.TString))) - sp.verify((sp.len(params.coin_names) > sp.nat(0)) & (sp.len(params.coin_names) <= self.MAX_BATCH_SIZE), message = "BatchMaxSizeExceed") @@ -282,20 +278,14 @@ def get_accumulated_fees(self): Return a map with record of accumulated Fees. :return: An map of Asset """ - # accumulated_fees = sp.local("accumulated_fees", sp.map(tkey=sp.TString, tvalue=sp.TNat)) - # i = sp.local("i", sp.nat(0)) - - # sp.for item in self.data.coins_name: - # accumulated_fees.value[item] = sp.record(coin_name=item, value=self.data.aggregation_fee.get(item, default_value=sp.nat(0))) - # # i.value += sp.nat(1) sp.result(self.data.aggregation_fee) - # @sp.entry_point(lazify=False) - # def update_transfer_native_coin(self, ep): - # self.only_owner() - # sp.set_entry_point("transfer_native_coin", ep) + @sp.entry_point(lazify=False) + def update_transfer_native_coin(self, ep): + self.only_owner() + sp.set_entry_point("transfer_native_coin", ep) - @sp.entry_point(check_no_incoming_transfer=False) + @sp.entry_point(check_no_incoming_transfer=False, lazify=True) def transfer_native_coin(self, to): """ Allow users to deposit `sp.amount` native coin into a BTSCore contract. @@ -306,27 +296,18 @@ def transfer_native_coin(self, to): amount_in_nat = sp.local("amount_in_nat", sp.utils.mutez_to_nat(sp.amount), t=sp.TNat) # call check_transfer_restrictions on bts_periphery - check_transfer = sp.view("check_transfer_restrictions", self.data.bts_periphery_address.open_some("Address not set"), - sp.record(coin_name=self.data.native_coin_name, user=sp.sender, value=amount_in_nat.value), + check_transfer = sp.view("check_transfer_restrictions", + self.data.bts_periphery_address.open_some("Address not set"), + sp.record(coin_name=self.data.native_coin_name, user=sp.sender, + value=amount_in_nat.value), t=sp.TBool).open_some() sp.verify(check_transfer == True, "FailCheckTransfer") - charge_amt = amount_in_nat.value * self.data.coin_details[self.data.native_coin_name].fee_numerator / self.FEE_DENOMINATOR + self.data.coin_details[self.data.native_coin_name].fixed_fee + charge_amt = amount_in_nat.value * self.data.coin_details[self.data.native_coin_name].fee_numerator / \ + self.FEE_DENOMINATOR + self.data.coin_details[self.data.native_coin_name].fixed_fee self._send_service_message(sp.sender, to, self.data.native_coin_name, amount_in_nat.value, charge_amt) - # # TODO:to be discussed - # @sp.entry_point - # def allow_bts(self, token_addr, value): - # - # sp.set_type(token_addr, sp.TAddress) - # sp.set_type(value, sp.TNat) - # - # allowance = sp.compute(sp.record(spender=sp.self_address, owner=sp.sender)) - # current_allowance = self.data.allowances.get(allowance, default_value=0) - # current_allowance += value - # self.data.allowances[sp.record(sender=sp.sender, token_addr=token_addr)] = value - @sp.entry_point(lazify=False) def update_transfer(self, ep): self.only_owner() @@ -335,7 +316,8 @@ def update_transfer(self, ep): @sp.entry_point(lazify=True) def transfer(self, coin_name, value, to): """ - Allow users to deposit an amount of wrapped native coin `coin_name` from the `sp.sender` address into the BTSCore contract. + Allow users to deposit an amount of wrapped native coin `coin_name` from the `sp.sender` address into + the BTSCore contract. :param coin_name: A given name of a wrapped coin :param value: An amount request to transfer from a Requester (include fee) :param to: Target BTP address. @@ -350,19 +332,22 @@ def transfer(self, coin_name, value, to): fa2_address = self.data.coins[coin_name] # call check_transfer_restrictions on bts_periphery - check_transfer = sp.view("check_transfer_restrictions", self.data.bts_periphery_address.open_some("Address not set"), + check_transfer = sp.view("check_transfer_restrictions", + self.data.bts_periphery_address.open_some("Address not set"), sp.record(coin_name=coin_name, user=sp.sender, value=value), t=sp.TBool).open_some() sp.verify(check_transfer == True, "FailCheckTransfer") - charge_amt = value * self.data.coin_details[coin_name].fee_numerator / self.FEE_DENOMINATOR + self.data.coin_details[coin_name].fixed_fee + charge_amt = value * self.data.coin_details[coin_name].fee_numerator / self.FEE_DENOMINATOR +\ + self.data.coin_details[coin_name].fixed_fee # call transfer from in FA2 transfer_args_type = sp.TList(sp.TRecord(from_=sp.TAddress, txs=sp.TList(sp.TRecord( to_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout(("to_", ("token_id", "amount")))) ).layout(("from_", "txs"))) transfer_entry_point = sp.contract(transfer_args_type, fa2_address, "transfer").open_some() - transfer_args = [sp.record(from_=sp.sender, txs=[sp.record(to_=sp.self_address, token_id=sp.nat(0), amount=value)])] + transfer_args = [sp.record(from_=sp.sender, txs=[sp.record(to_=sp.self_address, token_id=sp.nat(0), + amount=value)])] sp.transfer(transfer_args, sp.tez(0), transfer_entry_point) self._send_service_message(sp.sender, to, coin_name, value, charge_amt) @@ -460,10 +445,12 @@ def transfer_batch(self, coin_names_values, to): self._lock_balance(sp.sender, item.key, item.value) - sp.if amount_in_nat.value !=sp.nat(0): + with sp.if_(amount_in_nat.value !=sp.nat(0)): # call check_transfer_restrictions on bts_periphery - check_transfer = sp.view("check_transfer_restrictions", self.data.bts_periphery_address.open_some("Address not set"), - sp.record(coin_name=self.data.native_coin_name, user=sp.sender, value=amount_in_nat.value), + check_transfer = sp.view("check_transfer_restrictions", + self.data.bts_periphery_address.open_some("Address not set"), + sp.record(coin_name=self.data.native_coin_name, user=sp.sender, + value=amount_in_nat.value), t=sp.TBool).open_some() sp.verify(check_transfer == True, "FailCheckTransfer") @@ -567,7 +554,7 @@ def mint(self, to, coin_name, value): mint_args = [sp.record(to_=to, amount=value)] sp.transfer(mint_args, sp.tez(0), mint_entry_point) with sp.else_(): - sp.if _coin_type == self.NON_NATIVE_TOKEN_TYPE: + with sp.if_(_coin_type == self.NON_NATIVE_TOKEN_TYPE): transfer_args_type = sp.TList(sp.TRecord(from_=sp.TAddress, txs=sp.TList(sp.TRecord( to_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout(( "to_", ("token_id", "amount"))))).layout(("from_", "txs")) @@ -603,13 +590,13 @@ def handle_response_service(self, requester, coin_name, value, fee, rsp_code): return_flag = sp.local("return_flag", False, t=sp.TBool) bts_core_fa2_balance = sp.local("fa2_token_balance_core", sp.nat(0)) - sp.if requester == sp.self_address: - sp.if rsp_code == self.RC_ERR: + with sp.if_(requester == sp.self_address): + with sp.if_(rsp_code == self.RC_ERR): self.data.aggregation_fee[coin_name] = self.data.aggregation_fee.get(coin_name, default_value=sp.nat(0)) + value return_flag.value = True - sp.if return_flag.value == False: + with sp.if_(return_flag.value == False): amount = sp.local("amount", value + fee, t=sp.TNat) user= sp.record(address=requester, coin_name=coin_name) _user_balances=self.data.balances.get(user,default_value=sp.record(locked_balance=sp.nat(0), @@ -617,7 +604,7 @@ def handle_response_service(self, requester, coin_name, value, fee, rsp_code): self.data.balances[user].locked_balance = sp.as_nat(_user_balances.locked_balance - amount.value) - sp.if rsp_code == self.RC_ERR: + with sp.if_(rsp_code == self.RC_ERR): with sp.if_(coin_name == self.data.native_coin_name): # NATIVE COIN CASE with sp.if_(sp.utils.mutez_to_nat(sp.balance) >= value): @@ -664,7 +651,7 @@ def handle_response_service(self, requester, coin_name, value, fee, rsp_code): with sp.else_(): self.data.balances[user].refundable_balance = _user_balances.refundable_balance + value - sp.if rsp_code == self.RC_OK: + with sp.if_(rsp_code == self.RC_OK): fa2_address = self.data.coins[coin_name] with sp.if_((coin_name != self.data.native_coin_name) &\ (self.data.coin_details[coin_name].coin_type == self.NATIVE_WRAPPED_COIN_TYPE)): @@ -697,7 +684,7 @@ def transfer_fees(self, fa): transfer_fes_details = sp.local("transfer_fes_details", [], t=sp.TList(sp.TRecord(coin_name=sp.TString, value=sp.TNat, fee=sp.TNat))) sp.for item in self.data.coins_name: - sp.if self.data.aggregation_fee.get(item, default_value=sp.nat(0)) != sp.nat(0): + with sp.if_(self.data.aggregation_fee.get(item, default_value=sp.nat(0)) != sp.nat(0)): transfer_fes_details.value.push(sp.record(coin_name=item, value=self.data.aggregation_fee.get( item, default_value=sp.nat(0)), fee=sp.nat(0))) del self.data.aggregation_fee[item] diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index fa09b9f3..c69e1983 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -3,13 +3,8 @@ types = sp.io.import_script_from_url("file:./contracts/src/Types.py") strings = sp.io.import_script_from_url("file:./contracts/src/String.py") rlp = sp.io.import_script_from_url("file:./contracts/src/RLP_struct.py") -t_balance_of_request = sp.TRecord(owner=sp.TAddress, token_id=sp.TNat).layout( - ("owner", "token_id") -) - -t_balance_of_response = sp.TRecord( - request=t_balance_of_request, balance=sp.TNat -).layout(("request", "balance")) +t_balance_of_request = sp.TRecord(owner=sp.TAddress, token_id=sp.TNat).layout(("owner", "token_id")) +t_balance_of_response = sp.TRecord(request=t_balance_of_request, balance=sp.TNat).layout(("request", "balance")) class BTSPeriphery(sp.Contract, rlp.DecodeEncodeLibrary): service_name = sp.string("bts") @@ -214,7 +209,7 @@ def update_handle_btp_message(self, ep): sp.set_entry_point("handle_btp_message", ep) @sp.entry_point(lazify=True) - def handle_btp_message(self, _from, svc, sn, msg, callback, bsh_addr, prev, callback_msg): + def handle_btp_message(self, _from, svc, sn, msg, callback, prev, callback_msg): """ BSH handle BTP message from BMC contract :param _from: An originated network address of a request @@ -222,7 +217,6 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, bsh_addr, prev, call :param sn: A serial number of a service request :param msg: An RLP message of a service request/service response :param callback: callback function type in bmc_periphery - :param bsh_addr: param for callback function in bmc_periphery :param prev: param for callback function in bmc_periphery :param callback_msg: param for callback function in bmc_periphery :return: @@ -232,11 +226,10 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, bsh_addr, prev, call sp.set_type(svc, sp.TString) sp.set_type(sn, sp.TInt) sp.set_type(msg, sp.TBytes) - sp.set_type(callback, sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress, + sp.set_type(callback, sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), prev=sp.TString, callback_msg=sp.TRecord(src=sp.TString, dst=sp.TString, svc=sp.TString, sn=sp.TInt, message=sp.TBytes) - ))) - sp.set_type(bsh_addr, sp.TAddress) + ))) check_caller = self.only_bmc() @@ -341,7 +334,7 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, bsh_addr, prev, call with sp.else_(): callback_string.value = "UnAuthorized" - return_value = sp.record(string=sp.some(callback_string.value), bsh_addr=bsh_addr, prev=prev, + return_value = sp.record(string=sp.some(callback_string.value), prev=prev, callback_msg=callback_msg) sp.transfer(return_value, sp.tez(0), callback) @@ -351,7 +344,7 @@ def update_handle_btp_error(self, ep): sp.set_entry_point("handle_btp_error", ep) @sp.entry_point(lazify=True) - def handle_btp_error(self, svc, sn, code, msg, callback, bsh_addr): + def handle_btp_error(self, svc, sn, code, msg, callback): """ BSH handle BTP Error from BMC contract :param svc: A service name of BSH contract @@ -359,7 +352,6 @@ def handle_btp_error(self, svc, sn, code, msg, callback, bsh_addr): :param code: A response code of a message (RC_OK / RC_ERR) :param msg: A response message :param callback: callback function type in bmc_periphery - :param bsh_addr: param for callback function in bmc_periphery :return: """ @@ -367,9 +359,8 @@ def handle_btp_error(self, svc, sn, code, msg, callback, bsh_addr): sp.set_type(sn, sp.TInt) sp.set_type(code, sp.TNat) sp.set_type(msg, sp.TString) - sp.set_type(callback, sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress, + sp.set_type(callback, sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), svc=sp.TString, sn=sp.TInt, code=sp.TNat, msg=sp.TString))) - sp.set_type(bsh_addr, sp.TAddress) check_caller = self.only_bmc() handle_btp_error_status = sp.local("handle_btp_error_status", "success") @@ -383,7 +374,7 @@ def handle_btp_error(self, svc, sn, code, msg, callback, bsh_addr): with sp.else_(): handle_btp_error_status.value = "UnAuthorized" - return_value = sp.record(string=sp.some(handle_btp_error_status.value), bsh_addr=bsh_addr, svc=svc, sn=sn, + return_value = sp.record(string=sp.some(handle_btp_error_status.value), svc=svc, sn=sn, code=code, msg=msg) sp.transfer(return_value, sp.tez(0), callback) @@ -488,6 +479,7 @@ def _handle_request_service(self, to, assets): check_validity.value = False with sp.else_(): coin_type = sp.view("coin_type", bts_core_address, coin_name, t=sp.TNat).open_some() + # check balance_of in case of NON-NATIVE-COIN-TYPE with sp.if_((valid_coin == True) & (coin_type == sp.nat(2))): coin_address = sp.view("coin_id", bts_core_address, coin_name, t=sp.TAddress).open_some() bts_core_fa2 = sp.view("get_balance_of", coin_address, From 3c7451653afdacff77575650cbb635ca9d6e351f Mon Sep 17 00:00:00 2001 From: simusud Date: Tue, 4 Jul 2023 17:19:34 +0545 Subject: [PATCH 130/211] style(bmc): code formatting --- smartpy/bmc/contracts/src/bmc_management.py | 35 ++++++++++++--------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/smartpy/bmc/contracts/src/bmc_management.py b/smartpy/bmc/contracts/src/bmc_management.py index 77b1f5fe..75b38da7 100644 --- a/smartpy/bmc/contracts/src/bmc_management.py +++ b/smartpy/bmc/contracts/src/bmc_management.py @@ -72,7 +72,7 @@ def set_bmc_periphery(self, addr): """ sp.set_type(addr, sp.TAddress) self.only_owner() - sp.if self.data.bmc_periphery.is_some(): + with sp.if_(self.data.bmc_periphery.is_some()): sp.verify(addr != self.data.bmc_periphery.open_some("Address not set"), "AlreadyExistsBMCPeriphery") self.data.bmc_periphery = sp.some(addr) @@ -303,10 +303,12 @@ def _propagate_internal(self, service_type, link): rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [_bytes, rlp_bytes] , t=sp.TBytes).open_some() #encode payload - final_rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [rlp_bytes_with_prefix], t=sp.TBytes).open_some() + final_rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [rlp_bytes_with_prefix], + t=sp.TBytes).open_some() sp.for item in self.data.list_link_names.elements(): - sp.if self.data.links.get(item).is_connected: - net, addr = sp.match_pair(strings.split_btp_address(item, "prev_idx1", "result1", "my_list1", "last1", "penultimate1")) + with sp.if_(self.data.links.get(item).is_connected): + net, addr = sp.match_pair(strings.split_btp_address(item, "prev_idx1", "result1", + "my_list1", "last1", "penultimate1")) # call send_message on BMCPeriphery send_message_args_type = sp.TRecord(to=sp.TString, svc=sp.TString, sn=sp.TInt, msg=sp.TBytes) @@ -329,7 +331,8 @@ def _send_internal(self, target, service_type, links): sp.for item in links: _bytes = sp.bytes("0x") # can be any bytes _rlp_bytes = _bytes + sp.view("encode_string", self.data.helper, item, t=sp.TBytes).open_some() - rlp_bytes.value = sp.view("encode_list", self.data.helper, [rlp_bytes.value, _rlp_bytes], t=sp.TBytes).open_some() + rlp_bytes.value = sp.view("encode_list", self.data.helper, [rlp_bytes.value, _rlp_bytes], + t=sp.TBytes).open_some() #encode payload # final_rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp_bytes.value, t=sp.TBytes).open_some() net, addr = sp.match_pair( @@ -340,8 +343,9 @@ def _send_internal(self, target, service_type, links): send_message_entry_point = sp.contract(send_message_args_type, self.data.bmc_periphery.open_some("Address not set"), "send_message").open_some() - send_message_args = sp.record(to=net, svc="bmc", sn=sp.int(0), msg=self.encode_bmc_service( - sp.record(serviceType=service_type, payload=rlp_bytes.value))) + send_message_args = sp.record(to=net, svc="bmc", sn=sp.int(0), + msg=self.encode_bmc_service(sp.record(serviceType=service_type, + payload=rlp_bytes.value))) sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) @sp.entry_point(lazify=False) @@ -445,11 +449,11 @@ def remove_relay(self, link, addr): self.only_owner() sp.verify(self.data.links.contains(link), "NotExistsLink") - sp.verify((self.data.links.get(link).is_connected == True) & (sp.len(self.data.links.get(link).relays.elements()) != sp.nat(0)), - "Unauthorized") + sp.verify((self.data.links.get(link).is_connected == True) & + (sp.len(self.data.links.get(link).relays.elements()) != sp.nat(0)), "Unauthorized") sp.for item in self.data.links.get(link).relays.elements(): - sp.if item != addr: + with sp.if_(item != addr): self.data.addrs.add(item) self.data.links[link].relays = self.data.addrs @@ -472,7 +476,8 @@ def get_relays(self, link): @sp.onchain_view() def get_bsh_service_by_name(self, service_name): sp.set_type(service_name, sp.TString) - sp.result(self.data.bsh_services.get(service_name, default_value=sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg"))) + sp.result(self.data.bsh_services.get(service_name, + default_value=sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg"))) @sp.onchain_view() def get_link(self, to): @@ -561,7 +566,7 @@ def delete_link_reachable(self, prev, index): self.only_bmc_periphery() i = sp.local("i", sp.nat(0)) sp.for item in self.data.links.get(prev).reachable.elements(): - sp.if i.value == index: + with sp.if_(i.value == index): net, addr = sp.match_pair( strings.split_btp_address(item, "prev_idx", "result", "my_list", "last", "penultimate")) @@ -588,11 +593,13 @@ def resolve_route(self, dst_net): with sp.if_(sp.len(sp.pack(dst.value))!= sp.nat(0)): sp.result(sp.pair(self.data.routes.get(dst.value), dst.value)) with sp.else_(): - dst_link = sp.local("dst_link", self.data.get_link_from_net.get(dst_net, default_value=sp.string("")), t=sp.TString) + dst_link = sp.local("dst_link", self.data.get_link_from_net.get(dst_net, + default_value=sp.string("")), t=sp.TString) with sp.if_(sp.len(sp.pack(dst_link.value)) != sp.nat(0)): sp.result(sp.pair(dst_link.value, dst_link.value)) with sp.else_(): - res = sp.local("res", self.data.get_link_from_reachable_net.get(dst_net, default_value=sp.record(prev="", to="")), t=types.Types.Tuple) + res = sp.local("res", self.data.get_link_from_reachable_net.get(dst_net, default_value= + sp.record(prev="", to="")), t=types.Types.Tuple) # sp.verify(sp.len(sp.pack(res.value.to)) > sp.nat(0), "Unreachable: " + dst_net + " is unreachable") with sp.if_(sp.len(sp.pack(res.value.to)) > sp.nat(0)): sp.result(sp.pair(res.value.prev, res.value.to)) From b8fdb2118b161cc2b4e82fbf7bedafe93a080c69 Mon Sep 17 00:00:00 2001 From: simusud Date: Tue, 4 Jul 2023 17:22:43 +0545 Subject: [PATCH 131/211] fix(bmc): code review changes --- smartpy/bmc/contracts/src/bmc_periphery.py | 87 +++++++++++++--------- 1 file changed, 50 insertions(+), 37 deletions(-) diff --git a/smartpy/bmc/contracts/src/bmc_periphery.py b/smartpy/bmc/contracts/src/bmc_periphery.py index 50b7d84e..22149f37 100644 --- a/smartpy/bmc/contracts/src/bmc_periphery.py +++ b/smartpy/bmc/contracts/src/bmc_periphery.py @@ -24,7 +24,7 @@ def __init__(self, bmc_management_addr, helper_contract, helper_parse_neg_contra self.init( helper=helper_contract, helper_parse_negative=helper_parse_neg_contract, - bmc_btp_address=sp.none, + bmc_btp_address=sp.string(""), bmc_management=bmc_management_addr, parse_contract=parse_address, owner_address = owner_address @@ -67,14 +67,15 @@ def set_bmc_btp_address(self, network): sp.set_type(network, sp.TString) sp.verify(sp.sender == self.data.bmc_management, "Unauthorized") - with sp.if_(self.data.bmc_btp_address == sp.none): - self.data.bmc_btp_address = sp.some(sp.string("btp://") + network + "/" + sp.view("add_to_str", self.data.parse_contract, sp.self_address, t=sp.TString).open_some()) + with sp.if_(self.data.bmc_btp_address == sp.string("")): + self.data.bmc_btp_address = sp.string("btp://") + network + "/" + \ + sp.view("add_to_str", self.data.parse_contract, sp.self_address, t=sp.TString).open_some() with sp.else_(): sp.failwith("Address already set") @sp.onchain_view() def get_bmc_btp_address(self): - sp.result(self.data.bmc_btp_address.open_some("Address not set")) + sp.result(self.data.bmc_btp_address) @sp.onchain_view() def get_bmc_management_address(self): @@ -86,37 +87,39 @@ def _require_registered_relay(self, prev): relays = sp.view("get_link_relays", self.data.bmc_management, prev, t=sp.TList(sp.TAddress)).open_some() check_relay = sp.local("valid_relay_check", False) sp.for relay in relays: - sp.if sp.sender == relay: + with sp.if_(sp.sender == relay): check_relay.value = True sp.verify(check_relay.value, self.BMCRevertUnauthorized) @sp.entry_point - def callback_btp_message(self, string, bsh_addr, prev, callback_msg): + def callback_btp_message(self, string, prev, callback_msg): sp.set_type(string, sp.TOption(sp.TString)) - sp.set_type(bsh_addr, sp.TAddress) sp.set_type(prev, sp.TString) sp.set_type(callback_msg, types.Types.BMCMessage) - + bsh_addr = sp.view("get_bsh_service_by_name", self.data.bmc_management, "bts", t=sp.TAddress).open_some( + "Invalid view") sp.verify(sp.sender == bsh_addr, "Unauthorized") with sp.if_(string.open_some() != "success"): self._send_error(prev, callback_msg, self.BSH_ERR, self.BMCRevertUnknownHandleBTPMessage) @sp.entry_point - def callback_btp_error(self, string, bsh_addr, svc, sn, code, msg): + def callback_btp_error(self, string, svc, sn, code, msg): sp.set_type(string, sp.TOption(sp.TString)) - sp.set_type(bsh_addr, sp.TAddress) sp.set_type(svc, sp.TString) sp.set_type(sn, sp.TInt) sp.set_type(code, sp.TNat) sp.set_type(msg, sp.TString) + bsh_addr = sp.view("get_bsh_service_by_name", self.data.bmc_management, "bts", t=sp.TAddress).open_some( + "Invalid view") sp.verify(sp.sender == bsh_addr, "Unauthorized") with sp.if_(string.open_some() != "success"): error_code = self.UNKNOWN_ERR err_msg = self.BMCRevertUnknownHandleBTPError - sp.emit(sp.record(svc=svc, sn=sn, code=code, msg=msg, err_code=error_code, err_msg=err_msg), tag="ErrorOnBTPError") + sp.emit(sp.record(svc=svc, sn=sn, code=code, msg=msg, err_code=error_code, err_msg=err_msg), + tag="ErrorOnBTPError") @sp.entry_point(lazify=False) def update_handle_relay_message(self, ep): @@ -128,6 +131,8 @@ def handle_relay_message(self, prev, msg): sp.set_type(prev, sp.TString) sp.set_type(msg, sp.TBytes) + with sp.if_(self.data.bmc_btp_address == sp.string("")): + sp.failwith("bmc_btp_address not set") self._require_registered_relay(prev) link_rx_seq = sp.view("get_link_rx_seq", self.data.bmc_management, prev, t=sp.TNat).open_some() @@ -151,19 +156,18 @@ def handle_relay_message(self, prev, msg): sp.for j in sp.range(sp.nat(0), sp.len(rps[i].events)): #stored events received by decoding in local variable ev.value = rps[i].events[j] - sp.verify(ev.value.next_bmc == self.data.bmc_btp_address.open_some("Address not set"), - "Invalid Next BMC") + sp.verify(ev.value.next_bmc == self.data.bmc_btp_address, "Invalid Next BMC") rx_seq.value += sp.nat(1) with sp.if_(ev.value.seq < rx_seq.value): rx_seq.value = sp.as_nat(rx_seq.value-sp.nat(1)) with sp.else_(): - sp.if ev.value.seq > rx_seq.value: + with sp.if_(ev.value.seq > rx_seq.value): sp.failwith(self.BMCRevertInvalidSeqNumber) _decoded = self.decode_bmc_message(ev.value.message) bmc_msg.value = _decoded.bmc_dec_rv with sp.if_(_decoded.status == sp.string("Success")): - with sp.if_(bmc_msg.value.dst == self.data.bmc_btp_address.open_some("AddressNotSet")): + with sp.if_(bmc_msg.value.dst == self.data.bmc_btp_address): self._handle_message(prev, bmc_msg.value) with sp.else_(): net, addr = sp.match_pair(strings.split_btp_address(bmc_msg.value.dst, "prev_idx", @@ -216,19 +220,20 @@ def _handle_message(self, prev, msg): with sp.if_(_decoded.status != "Success"): self._send_error(prev, msg, self.BMC_ERR, self.BMCRevertParseFailure) with sp.else_(): - sp.if sm.value.serviceType == "FeeGathering": - gather_fee =sp.local("gather_fee", sp.record(fa="error", svcs=sp.map({0:""}))) + bool_value = sp.local("bool_value", False) + with sp.if_(sm.value.serviceType == "FeeGathering"): + gather_fee =sp.local("gather_fee", sp.record(fa="__error__", svcs=sp.map({0:""}))) fee_msg_decoded = self.decode_gather_fee_message(sm.value.payload) - gather_fee.value = fee_msg_decoded.fee_decode_rv with sp.if_(fee_msg_decoded.status != "Success"): self._send_error(prev, msg, self.BMC_ERR, self.BMCRevertParseFailure) with sp.else_(): + gather_fee.value = fee_msg_decoded.fee_decode_rv sp.for k in sp.range(sp.nat(0), sp.len(gather_fee.value.svcs)): bsh_addr = sp.view("get_bsh_service_by_name", self.data.bmc_management, gather_fee.value.svcs[k], t=sp.TAddress).open_some("Invalid Call") - sp.if bsh_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg"): + with sp.if_(bsh_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): # call handle_fee_gathering of bts periphery handle_fee_gathering_args_type = sp.TRecord(bsh_addr=sp.TAddress, fa=sp.TString, svc=sp.TString) @@ -239,8 +244,9 @@ def _handle_message(self, prev, msg): handle_fee_gathering_args = sp.record(bsh_addr=bsh_addr, fa=gather_fee.value.fa, svc=gather_fee.value.svcs[k]) sp.transfer(handle_fee_gathering_args, sp.tez(0), handle_fee_gathering_entry_point) + bool_value.value = True - sp.if sm.value.serviceType == "Init": + with sp.if_(sm.value.serviceType == "Init"): links = self.decode_init_message(sm.value.payload) # call update_link_reachable on BMCManagement update_link_reachable_args_type = sp.TRecord(prev=sp.TString, to=sp.TList(sp.TString)) @@ -250,34 +256,39 @@ def _handle_message(self, prev, msg): update_link_reachable_args = sp.record(prev=prev, to=links.links_list) sp.transfer(update_link_reachable_args, sp.tez(0), update_link_reachable_entry_point) + bool_value.value = True + + with sp.if_(bool_value.value == False): + sp.failwith(self.BMCRevertNotExistsInternalHandler) + with sp.else_(): - bsh_addr = sp.view("get_bsh_service_by_name", self.data.bmc_management, msg.svc, t=sp.TAddress).open_some("Invalid view") + bsh_addr = sp.view("get_bsh_service_by_name", self.data.bmc_management, msg.svc, + t=sp.TAddress).open_some("Invalid view") with sp.if_(bsh_addr == sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): self._send_error(prev, msg, self.BMC_ERR, self.BMCRevertNotExistsBSH) with sp.else_(): with sp.if_(msg.sn >= sp.int(0)): - net, addr = sp.match_pair(strings.split_btp_address(msg.src, "prev_idx", "result", "my_list", "last", "penultimate")) + net, addr = sp.match_pair(strings.split_btp_address(msg.src, "prev_idx", "result", + "my_list", "last", "penultimate")) # implemented callback # call handle_btp_message on bts periphery handle_btp_message_args_type = sp.TRecord( callback=sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), - bsh_addr=sp.TAddress, prev=sp.TString, - callback_msg=types.Types.BMCMessage)), - bsh_addr=sp.TAddress, prev=sp.TString, - callback_msg=types.Types.BMCMessage, _from=sp.TString, + prev=sp.TString, callback_msg=types.Types.BMCMessage)), + prev=sp.TString, callback_msg=types.Types.BMCMessage, _from=sp.TString, svc=sp.TString, sn=sp.TInt, msg=sp.TBytes) handle_btp_message_entry_point = sp.contract(handle_btp_message_args_type, bsh_addr, "handle_btp_message").open_some() - t = sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress, prev=sp.TString, + t = sp.TRecord(string=sp.TOption(sp.TString), prev=sp.TString, callback_msg=types.Types.BMCMessage ) callback = sp.contract(t, sp.self_address, "callback_btp_message") handle_btp_message_args = sp.record(callback=callback.open_some(), - bsh_addr=bsh_addr, prev=prev, + prev=prev, callback_msg=msg, _from=net, svc=msg.svc, sn=msg.sn, msg=msg.message) sp.transfer(handle_btp_message_args, sp.tez(0), handle_btp_message_entry_point) @@ -288,17 +299,17 @@ def _handle_message(self, prev, msg): # call handle_btp_error on bts periphery handle_btp_error_args_type = sp.TRecord( callback=sp.TContract(sp.TRecord(string=sp.TOption(sp.TString), - bsh_addr=sp.TAddress, svc=sp.TString, sn=sp.TInt, code=sp.TNat, msg=sp.TString)), - bsh_addr=sp.TAddress, svc=sp.TString, sn=sp.TInt, code=sp.TNat, msg=sp.TString) + svc=sp.TString, sn=sp.TInt, code=sp.TNat, msg=sp.TString)), + svc=sp.TString, sn=sp.TInt, code=sp.TNat, msg=sp.TString) handle_btp_error_entry_point = sp.contract(handle_btp_error_args_type, bsh_addr, "handle_btp_error").open_some() - t = sp.TRecord(string=sp.TOption(sp.TString), bsh_addr=sp.TAddress, + t = sp.TRecord(string=sp.TOption(sp.TString), svc=sp.TString, sn=sp.TInt, code=sp.TNat, msg=sp.TString) callback = sp.contract(t, sp.self_address, "callback_btp_error") - handle_btp_error_args = sp.record(callback=callback.open_some(), bsh_addr=bsh_addr, + handle_btp_error_args = sp.record(callback=callback.open_some(), svc=msg.svc, sn=msg.sn * -1, code=res.code, msg=res.message) sp.transfer(handle_btp_error_args, sp.tez(0), handle_btp_error_entry_point) @@ -318,9 +329,9 @@ def _send_error(self, prev, message, err_code, err_msg): sp.set_type(err_code, sp.TNat) sp.set_type(err_msg, sp.TString) - sp.if message.sn > sp.int(0): + with sp.if_(message.sn > sp.int(0)): serialized_msg = self.encode_bmc_message(sp.record( - src=self.data.bmc_btp_address.open_some("Address not set"), + src=self.data.bmc_btp_address, dst=message.src, svc=message.svc, sn=message.sn * -1, @@ -348,14 +359,16 @@ def send_message(self, to, svc, sn, msg): sp.set_type(msg, sp.TBytes) sp.verify((sp.sender == self.data.bmc_management) | - (sp.view("get_bsh_service_by_name", self.data.bmc_management, svc, t=sp.TAddress).open_some() == sp.sender), + (sp.view("get_bsh_service_by_name", self.data.bmc_management, svc, + t=sp.TAddress).open_some() == sp.sender), self.BMCRevertUnauthorized) sp.verify(sn >= sp.int(0), self.BMCRevertInvalidSn) - next_link, dst = sp.match_pair(sp.view("resolve_route", self.data.bmc_management, to, t=sp.TPair(sp.TString, sp.TString)).open_some()) + next_link, dst = sp.match_pair(sp.view("resolve_route", self.data.bmc_management, + to, t=sp.TPair(sp.TString, sp.TString)).open_some()) _rlp = self.encode_bmc_message(sp.record( - src=self.data.bmc_btp_address.open_some("Address not set"), + src=self.data.bmc_btp_address, dst=dst, svc=svc, sn=sn, From bec8a4c0a9b21beeaf372d016a36d26139f1ca66 Mon Sep 17 00:00:00 2001 From: simusud Date: Wed, 5 Jul 2023 12:35:59 +0545 Subject: [PATCH 132/211] fix(bmc): removed pack --- smartpy/bmc/contracts/src/bmc_management.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/smartpy/bmc/contracts/src/bmc_management.py b/smartpy/bmc/contracts/src/bmc_management.py index 75b38da7..133e87a6 100644 --- a/smartpy/bmc/contracts/src/bmc_management.py +++ b/smartpy/bmc/contracts/src/bmc_management.py @@ -80,7 +80,7 @@ def set_bmc_periphery(self, addr): def set_bmc_btp_address(self, network): sp.set_type(network, sp.TString) - sp.verify(self.data.owners[sp.sender] == True, "Unauthorized") + self.only_owner() # call set_btp_address on BMCPeriphery set_btp_address_entry_point = sp.contract(sp.TString, self.data.bmc_periphery.open_some("Address not set"), @@ -589,19 +589,17 @@ def resolve_route(self, dst_net): sp.set_type(dst_net, sp.TString) dst = sp.local("dst", self.data.get_route_dst_from_net.get(dst_net, default_value=sp.string("")), t=sp.TString) - - with sp.if_(sp.len(sp.pack(dst.value))!= sp.nat(0)): + with sp.if_(sp.len(dst.value)!= sp.nat(0)): sp.result(sp.pair(self.data.routes.get(dst.value), dst.value)) with sp.else_(): dst_link = sp.local("dst_link", self.data.get_link_from_net.get(dst_net, default_value=sp.string("")), t=sp.TString) - with sp.if_(sp.len(sp.pack(dst_link.value)) != sp.nat(0)): + with sp.if_(sp.len(dst_link.value) != sp.nat(0)): sp.result(sp.pair(dst_link.value, dst_link.value)) with sp.else_(): res = sp.local("res", self.data.get_link_from_reachable_net.get(dst_net, default_value= sp.record(prev="", to="")), t=types.Types.Tuple) - # sp.verify(sp.len(sp.pack(res.value.to)) > sp.nat(0), "Unreachable: " + dst_net + " is unreachable") - with sp.if_(sp.len(sp.pack(res.value.to)) > sp.nat(0)): + with sp.if_(sp.len(res.value.to) > sp.nat(0)): sp.result(sp.pair(res.value.prev, res.value.to)) with sp.else_(): sp.result(sp.pair("Unreachable", "Unreachable: " + dst_net + " is unreachable")) From 8192012105ea35bed86c7303b5e7bbc03c01c0f7 Mon Sep 17 00:00:00 2001 From: simusud Date: Wed, 5 Jul 2023 12:36:15 +0545 Subject: [PATCH 133/211] fix(bts): removed pack --- smartpy/bts/contracts/src/bts_periphery.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index c69e1983..59dc3a47 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -311,7 +311,7 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, prev, callback_msg): callback_string.value = "ErrorInDecodingTokenLimit" with arg.match("RESPONSE_HANDLE_SERVICE") as a4: - with sp.if_(sp.len(sp.pack(self.data.requests.get(sn).from_)) != 0): + with sp.if_(sp.len(self.data.requests.get(sn).from_) != 0): fn_call = self.decode_response(sm.data) response = fn_call.rv with sp.if_(fn_call.status == "Success"): @@ -364,8 +364,8 @@ def handle_btp_error(self, svc, sn, code, msg, callback): check_caller = self.only_bmc() handle_btp_error_status = sp.local("handle_btp_error_status", "success") - with sp.if_((svc == self.service_name) & (check_caller == "Authorized") & (sp.len(sp.pack( - self.data.requests.get(sn).from_)) != 0)): + with sp.if_((svc == self.service_name) & (check_caller == "Authorized") & (sp.len( + self.data.requests.get(sn).from_) != 0)): emit_msg= sp.concat(["errCode: ", sp.view("string_of_int", self.data.parse_contract, sp.to_int(code), t=sp.TString).open_some(),", errMsg: ", msg]) handle_response_serv = self.handle_response_service(sn, self.RC_ERR, emit_msg) From 76476b4e23d78ebd07967db8e0ccd0ab074e6eb4 Mon Sep 17 00:00:00 2001 From: simusud Date: Wed, 5 Jul 2023 14:55:23 +0545 Subject: [PATCH 134/211] docs(bmc): added comment in string split --- smartpy/bmc/contracts/src/bmc_periphery.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/smartpy/bmc/contracts/src/bmc_periphery.py b/smartpy/bmc/contracts/src/bmc_periphery.py index 22149f37..f6a2f74f 100644 --- a/smartpy/bmc/contracts/src/bmc_periphery.py +++ b/smartpy/bmc/contracts/src/bmc_periphery.py @@ -270,6 +270,10 @@ def _handle_message(self, prev, msg): with sp.else_(): with sp.if_(msg.sn >= sp.int(0)): + # strings send in split_btp_address are the name of local variables used in + # split_btp_address which should be unique while calling it multiple times + # in a function. But this works in case of loop as it won't be defined multiple + # as its scope exists throughout the loop net, addr = sp.match_pair(strings.split_btp_address(msg.src, "prev_idx", "result", "my_list", "last", "penultimate")) # implemented callback From ea18b395367ea02ed98a69830fd4a8d32a88ec5c Mon Sep 17 00:00:00 2001 From: simusud Date: Wed, 5 Jul 2023 15:23:55 +0545 Subject: [PATCH 135/211] test(bmc): unit test fixes --- .../contracts/tests/bmc_management_test.py | 352 +++++++++++------- .../bmc/contracts/tests/bmc_periphery_test.py | 69 ++-- 2 files changed, 258 insertions(+), 163 deletions(-) diff --git a/smartpy/bmc/contracts/tests/bmc_management_test.py b/smartpy/bmc/contracts/tests/bmc_management_test.py index 1e79b780..c1080e42 100644 --- a/smartpy/bmc/contracts/tests/bmc_management_test.py +++ b/smartpy/bmc/contracts/tests/bmc_management_test.py @@ -32,190 +32,243 @@ def test(): bmc_periphery_address = bmc_periphery_address.address - # Test case 1: bmc_periphery - sc.h1("Test case 1: set bmc_periphery to a valid address") + # Scenario 1: Contract setters + + # Test cases: + # 1: set_bmc_periphery address sc.verify(bmc_management_contract.data.bmc_periphery.is_some() == False) bmc_management_contract.set_bmc_periphery(bmc_periphery_address).run(sender=creator) - # sender should be owner + + # 2: sender non-owner bmc_management_contract.set_bmc_periphery(bob.address).run(sender=alice, valid=False, exception="Unauthorized") - # repeated bmc_periphery should throw error + + # 3: bmc_periphery already set bmc_management_contract.set_bmc_periphery(bmc_periphery_address).run(sender=creator, valid=False, exception="AlreadyExistsBMCPeriphery") - # Verify that bmc_periphery is set to the valid address + # 4: Verify valid bmc_periphery address sc.verify(bmc_management_contract.data.bmc_periphery.is_some() == True) sc.verify(bmc_management_contract.data.bmc_periphery.open_some() == bmc_periphery_address) - # set_bmc_btp_address + # # 5: sender non-owner for set_bmc_btp_address + # bmc_management_contract.set_bmc_btp_address("tezos.77").run(sender=alice, valid=False, exception="Unauthorized") + + # 6: sender is owner for set_bmc_btp_address bmc_management_contract.set_bmc_btp_address("tezos.77").run(sender=creator) - # Test case 2: add_owner - # throw error when adding owner by random address + # 7 : setting helper address by non-owner + bmc_management_contract.set_helper_address(helper_contract.address).run(sender=jack, valid=False, + exception="Unauthorized") + + # 8 : setting helper address by owner + bmc_management_contract.set_helper_address(helper_contract.address).run(sender=creator) + + # 9: verifying address + sc.verify(bmc_management_contract.data.helper == helper_contract.address) + + # Scenario 2: add / remove owner + + # Test cases: + # 1: set owner by non-owner bmc_management_contract.add_owner(alice.address).run(sender=bob, valid=False, exception="Unauthorized") - # successfully added new owner + + # 2: set new owner by owner bmc_management_contract.add_owner(alice.address).run(sender=creator) sc.verify(bmc_management_contract.data.owners[alice.address] == True) - # Test case 3: remove owner - # throw error when removing owner by random address + # 3: remove owner by non-owner bmc_management_contract.remove_owner(alice.address).run(sender=bob, valid=False, exception="Unauthorized") - # working + + # 4: remove owner by owner bmc_management_contract.remove_owner(alice.address).run(sender=creator) sc.verify(~bmc_management_contract.data.owners.contains(jack.address)) - # Test case 4: is_owner - # Add an owner + # 5: add owner bmc_management_contract.add_owner(creator2.address).run(sender=creator) - # Test the is_owner view function + + # 6: verify is_owner sc.verify(bmc_management_contract.is_owner(creator2.address) == True) - # Test case 5: add_service function - svc1 = sp.string("service1") - svc2 = sp.string("service2") - svc3 = sp.string("service3") - # add service by random address should fail - bmc_management_contract.add_service(sp.record(addr=service1_address.address, svc=svc1)).run(sender=bob, valid=False, - exception="Unauthorized") - # adding service + # Scenario 3: add / remove services and get_services + + # Test cases: + svc1 = sp.string("bmc") + svc2 = sp.string("bts") + # 1: add service by non-owner + bmc_management_contract.add_service( + sp.record(addr=service1_address.address, svc=svc1)).run(sender=bob, valid=False, exception="Unauthorized") + # 2: adding service by owner bmc_management_contract.add_service(sp.record(addr=service1_address.address, svc=svc1)).run(sender=creator) - # shouldn't add same service twice - bmc_management_contract.add_service(sp.record(addr=service1_address.address, svc=svc1)).run(sender=creator, - valid=False, - exception="AlreadyExistsBSH") - # Test case 6: remove_service function - # remove service by random address should fail + # 3: adding same service + bmc_management_contract.add_service( + sp.record(addr=service1_address.address, svc=svc1)).run(sender=creator, valid=False, + exception="AlreadyExistsBSH") + + # 4: remove service by non-owner bmc_management_contract.remove_service(svc2).run(sender=bob, valid=False, exception="Unauthorized") - # removing unregistered should throw error - bmc_management_contract.remove_service(svc3).run(sender=creator, valid=False) - # removing service + + # 5: remove unregistered service + bmc_management_contract.remove_service(svc2).run(sender=creator, valid=False) + + # 6: removing service bmc_management_contract.add_service(sp.record(addr=service2_address.address, svc=svc2)).run(sender=creator) bmc_management_contract.remove_service(svc2).run(sender=creator) - # test case 7: get_services function + # 7: verify get_services services = bmc_management_contract.get_services() sc.verify_equal(services, sp.map({0: sp.record(svc=svc1, addr=service1_address.address)})) - # test case 8: add_route function + # Scenario 4: add / remove route and get_routes + + # Test case: dst = "btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258dest" next_link = "btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b" - # only owner can add routes + # 1: adding route by non-owner bmc_management_contract.add_route(sp.record(dst=dst, link=next_link)).run(sender=bob, valid=False, exception="Unauthorized") - # should work + + # 2: adding route by owner bmc_management_contract.add_route(sp.record(dst=dst, link=next_link)).run(sender=creator) - # cannot add already existed route + + # 3: adding same routes bmc_management_contract.add_route(sp.record(dst=dst, link=next_link)).run(sender=creator, valid=False, exception="AlreadyExistRoute") - # test case 9: remove_route function dst1 = "btp://78.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5DEST1" next_link1 = "btp://78.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5LINK1" - # only owner can remove routes + # 4: removing routes by non-owner bmc_management_contract.remove_route(dst).run(sender=bob, valid=False, exception="Unauthorized") - # throw error when non-exist route is given & this should throw error but not thrown + + # 5: removing non-exist routes bmc_management_contract.remove_route(dst1).run(sender=creator, valid=False, exception="NotExistRoute") - # should work + + # 6: removing existed routes by owner bmc_management_contract.add_route(sp.record(dst=dst1, link=next_link1)).run(sender=creator) bmc_management_contract.remove_route(dst1).run(sender=creator) - # test case 10: get_routes function + # 7: verify get_routes get_routes = bmc_management_contract.get_routes() sc.verify_equal(get_routes, sp.map({0: sp.record( dst=sp.string("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258dest"), next=sp.string("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b"))})) - # test case 11: add_link function - # add_link by random address should fail - bmc_management_contract.add_link("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b").run(sender=bob, - valid=False, - exception="Unauthorized") - # should work + # Scenario 5: add / remove link and get_links + + # Test case: + # 1: adding link by non-owner + bmc_management_contract.add_link( + "btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b").run(sender=bob, valid=False, + exception="Unauthorized") + + # 2: adding link by owner bmc_management_contract.add_link("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b").run(sender=creator) - # add_link by of same link should fail - bmc_management_contract.add_link("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b").run(sender=creator, - valid=False, - exception="AlreadyExistsLink") - - # test case 12: remove_link function - # remove_link by random address should fail - bmc_management_contract.remove_link("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258dead").run(sender=bob, - valid=False, - exception="Unauthorized") - # remove_link should throw error when removing non-existing link - bmc_management_contract.remove_link("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258dead").run(sender=creator, - valid=False, - exception="NotExistsLink") - # should work + + # 3: adding existed link + bmc_management_contract.add_link( + "btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b").run(sender=creator, valid=False, + exception="AlreadyExistsLink") + + # 4: removing link by non-owner + bmc_management_contract.remove_link( + "btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258dead").run(sender=bob, valid=False, + exception="Unauthorized") + + # 5: removing non-exist link + bmc_management_contract.remove_link( + "btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258dead").run(sender=creator, valid=False, + exception="NotExistsLink") + + # 6: removing existed link by owner bmc_management_contract.add_link("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258dead").run(sender=creator) bmc_management_contract.remove_link("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258dead").run(sender=creator) - # test case 13: get_links function + # 7: verify get_links link_to_compare = bmc_management_contract.get_links() added_link = sp.list(['btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b']) sc.verify_equal(link_to_compare, added_link) - # test case 14: set_link_rx_height + # Scenario 6: set_link_rx_height + + # Test case: link = sp.string('btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b') height = sp.nat(2) - # error when not exist link is given + # 1: non-exist link is given bmc_management_contract.set_link_rx_height(link="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnA", - height=height).run(sender=creator, valid=False, exception="NotExistsKey") - # error when not invalid height is given + height=height).run(sender=creator, + valid=False, exception="NotExistsKey") + # 2: invalid height is given bmc_management_contract.set_link_rx_height(link=link, height=sp.nat(0)).run(sender=creator, valid=False, exception="InvalidRxHeight") - # should work + + # 3: set_link_rx_height by non-owner + bmc_management_contract.set_link_rx_height(link=link, height=height).run(sender=bob, valid=False, + exception="Unauthorized") + + # 4: set_link_rx_height by owner bmc_management_contract.set_link_rx_height(link=link, height=height).run(sender=creator) + + # 5: verify rx_height value sc.verify_equal(bmc_management_contract.data.links[link].rx_height, 2) - # test case 15: set_link function + # Scenario 7: set_link + + # Test case: block_interval = sp.nat(2) _max_aggregation = sp.nat(3) delay_limit = sp.nat(2) - # only owner should set link + # 1: setting link by non-owner bmc_management_contract.set_link( sp.record(_link=link, block_interval=block_interval, _max_aggregation=_max_aggregation, delay_limit=delay_limit)).run(sender=bob, valid=False, exception="Unauthorized") - # error when link doesnt exist + + # 2: setting non-exist link bmc_management_contract.set_link( sp.record(_link="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnZ", block_interval=block_interval, _max_aggregation=_max_aggregation, delay_limit=delay_limit)).run(sender=creator, valid=False, exception="NotExistsLink") - # error when invalid paramters were given + # 3: setting link with invalid paramter bmc_management_contract.set_link( - sp.record(_link=link, block_interval=block_interval, _max_aggregation=sp.nat(0), delay_limit=delay_limit)).run( + sp.record(_link=link, block_interval=block_interval, _max_aggregation=sp.nat(0), + delay_limit=delay_limit)).run( sender=creator, valid=False, exception="InvalidParam") bmc_management_contract.set_link( sp.record(_link=link, block_interval=block_interval, _max_aggregation=_max_aggregation, delay_limit=sp.nat(0))).run(sender=creator, valid=False, exception="InvalidParam") - # should work + + # 4: setting link with valid paramter by owner bmc_management_contract.set_link( sp.record(_link=link, block_interval=block_interval, _max_aggregation=_max_aggregation, delay_limit=delay_limit)).run(sender=creator) - # test case 16: add_relay function - # only owner should add relay + # Scenario 8: add / remove relay and get_relays + + # Test case: + # 1: adding relay by non-owner bmc_management_contract.add_relay( - sp.record(link=link, addr=sp.set([sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiADD")]))).run(sender=bob, - valid=False, - exception="Unauthorized") - # fail when non-exist link is given + sp.record(link=link, addr=sp.set( + [sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiADD")]))).run(sender=bob, valid=False, + exception="Unauthorized") + + # 2: adding relay to non-exist link bmc_management_contract.add_relay(sp.record(link="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUNONLINK", addr=sp.set([sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiADD")]))).run( sender=creator, valid=False, exception="NotExistsLink") - # should work + + # 3: adding relay by owner bmc_management_contract.add_relay( sp.record(link=link, addr=sp.set([sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")]))).run(sender=creator) - # test case 17: remove_relay function - # only owner should remove relay + # 4: remove relay by non-owner bmc_management_contract.remove_relay( sp.record(link=link, addr=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"))).run(sender=bob, valid=False, exception="Unauthorized") - # fail when non-exist link is given + + # 5: removing relay with non-exist link bmc_management_contract.remove_relay(sp.record(link="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUNONLINK", addr=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiADD"))).run( sender=creator, valid=False, exception="NotExistsLink") - # should work + + # 6: removing relay by owner next_link1 = sp.string("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a625link1") bmc_management_contract.add_link(next_link1).run(sender=creator) bmc_management_contract.add_relay( @@ -224,16 +277,19 @@ def test(): bmc_management_contract.remove_relay( sp.record(link=next_link1, addr=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxADD1"))).run(sender=creator) - # test case 18: get_relays function + # 7: verify get_relays compared_to = sp.list([sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")]) get_relays = bmc_management_contract.get_relays(link) sc.verify_equal(get_relays, compared_to) - # test case 19: get_bsh_service_by_name function + # Scenario 9: Contract getters + + # Test cases: + # 1: verify get_bsh_service_by_name get_bsh_service_by_name = bmc_management_contract.get_bsh_service_by_name(svc1) sc.verify_equal(get_bsh_service_by_name, service1_address.address) - # test case 20: get_link function + # 2: verify get_link get_link = bmc_management_contract.get_link(link) data = sp.record( relays=sp.set([sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")]), @@ -252,114 +308,128 @@ def test(): ) sc.verify_equal(get_link, data) - # test case 21: get_link_rx_seq function + # 3: verify get_link_rx_seq get_link_rx_seq = bmc_management_contract.get_link_rx_seq(link) sc.verify_equal(get_link_rx_seq, 0) - # test case 22: get_link_tx_seq function + # 4: verify get_link_tx_seq get_link_tx_seq = bmc_management_contract.get_link_tx_seq(link) sc.verify_equal(get_link_tx_seq, 0) - # test case 23: get_link_rx_height function + # 5: verify get_link_rx_height get_link_rx_height = bmc_management_contract.get_link_rx_height(link) sc.verify_equal(get_link_rx_height, 0) - # test case 24: get_link_relays function + # 6: verify get_link_relays get_link_relays = bmc_management_contract.get_link_relays(link) sc.verify_equal(get_link_relays, compared_to) - # test case 25: get_relay_status_by_link function + # 7: verify get_relay_status_by_link get_link_relays = bmc_management_contract.get_relay_status_by_link(link) sc.verify_equal(get_link_relays, sp.map( {0: sp.record(addr=sp.address('tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9'), block_count=0, msg_count=0)})) - # test case 26: update_link_rx_seq function - # only bmc periphery address can run other users should get error - bmc_management_contract.update_link_rx_seq(sp.record(prev=next_link1, val=sp.nat(3))).run(sender=creator, - valid=False, - exception="Unauthorized") - # working + # Scenario 10: update_link_rx_seq function + + # Test cases: + # 1: update_link_rx_seq by non-owner + bmc_management_contract.update_link_rx_seq( + sp.record(prev=next_link1, val=sp.nat(3))).run(sender=creator, valid=False, exception="Unauthorized") + + # 2: update_link_rx_seq by owner bmc_management_contract.update_link_rx_seq(sp.record(prev=next_link1, val=sp.nat(3))).run( sender=bmc_periphery_address) - # Check that the value of rx_seq is updated correctly + + # 3: verifying value sc.verify_equal(bmc_management_contract.data.links[next_link1].rx_seq, 3) - # test case 27: update_link_tx_seq function - # only bmc periphery address can run other users should get error + # Scenario 11: update_link_tx_seq function + + # Test cases: + # 1: update_link_tx_seq by non-bmc_periphery bmc_management_contract.update_link_tx_seq(sp.record(prev=next_link1, serialized_msg=sp.bytes("0x64"))).run( sender=creator, valid=False, exception="Unauthorized") - # working + + # 2: update_link_tx_seq by bmc_periphery bmc_management_contract.update_link_tx_seq(sp.record(prev=next_link1, serialized_msg=sp.bytes("0x64"))).run( sender=bmc_periphery_address) - # Check that the value of tx_seq is updated correctly + + # 3: verifying value sc.verify_equal(bmc_management_contract.data.links[next_link1].tx_seq, 1) - # test case 28: update_link_rx_height function - # only bmc periphery address can run other users should get error - bmc_management_contract.update_link_rx_height(sp.record(prev=next_link1, val=sp.nat(3))).run(sender=creator, - valid=False, - exception="Unauthorized") - # working + # Scenario 12: update_link_rx_height function + + # Test cases: + # 1: update_link_rx_height by non-bmc_periphery + bmc_management_contract.update_link_rx_height( + sp.record(prev=next_link1, val=sp.nat(3))).run(sender=creator, valid=False, exception="Unauthorized") + + # 2: update_link_rx_height by bmc_periphery bmc_management_contract.update_link_rx_height(sp.record(prev=next_link1, val=sp.nat(4))).run( sender=bmc_periphery_address) - # Check that the value of rx_seq is updated correctly + + # 3: verifying value sc.verify_equal(bmc_management_contract.data.links[next_link1].rx_height, 4) - # test case 29: update_link_reachable function + # Scenario 13: update_link_reachable and delete_link_reachable function + + # Test cases: to = sp.list(["btp://net1/addr1", "btp://net2/addr2"]) - # only bmc periphery address can run other users should get error + # 1: update_link_reachable by non-bmc_periphery bmc_management_contract.update_link_reachable(sp.record(prev=next_link1, to=to)).run(sender=creator, valid=False, exception="Unauthorized") - # should work + + # 2: update_link_reachable by bmc_periphery bmc_management_contract.update_link_reachable(sp.record(prev=next_link1, to=to)).run(sender=bmc_periphery_address) - # value checking + + # 3: verifying value sc.verify_equal(bmc_management_contract.data.links[next_link1].reachable, sp.set(['btp://net1/addr1', 'btp://net2/addr2'])) - # test case 30: delete_link_reachable function - # only bmc periphery address can run other users should get error - bmc_management_contract.delete_link_reachable(sp.record(prev=next_link1, index=sp.nat(0))).run(sender=creator, - valid=False, - exception="Unauthorized") - # working + # 4: delete_link_reachable by non-bmc_periphery + bmc_management_contract.delete_link_reachable( + sp.record(prev=next_link1, index=sp.nat(0))).run(sender=creator, valid=False, exception="Unauthorized") + + # 5: delete_link_reachable by bmc_periphery bmc_management_contract.delete_link_reachable(sp.record(prev=next_link1, index=sp.nat(0))).run( sender=bmc_periphery_address) - # value checking + + # 6: verifying value sc.verify_equal(bmc_management_contract.data.links[next_link1].reachable, sp.set(['btp://net2/addr2'])) - # test case 31: update_relay_stats function - # only bmc periphery address can run other users should get error + # # 7: delete non-exist link + # next_link2 = sp.string("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a625link2") + # bmc_management_contract.delete_link_reachable(sp.record(prev=next_link2, index=sp.nat(0))).run( + # sender=bmc_periphery_address) + + # Scenario 13: update_relay_stats and resolve_route function + + # Test cases: + # 1: update_relay_stats by non-bmc_periphery bmc_management_contract.update_relay_stats( sp.record(relay=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiADD"), block_count_val=sp.nat(2), msg_count_val=sp.nat(2))).run(sender=creator, valid=False, exception="Unauthorized") - # working + + # 2: update_relay_stats by bmc_periphery bmc_management_contract.update_relay_stats( sp.record(relay=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), block_count_val=sp.nat(2), msg_count_val=sp.nat(2))).run(sender=bmc_periphery_address) - # value checking + + # 3: verifying value sc.verify_equal( bmc_management_contract.data.relay_stats[sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")].block_count, 2) sc.verify_equal( bmc_management_contract.data.relay_stats[sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")].msg_count, 2) - # test case 32: resolve_route function + # 4: verifying value of resolve_route function sc.verify_equal(bmc_management_contract.resolve_route(sp.string('0x7.icon')), sp.pair('btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b', 'btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258dest')) - # test case 33: set_helper_address test - bmc_management_contract.set_helper_address(sp.address("KT1EXYXNGdbh4uvdKc8hh7ETQXCXPzhelper")).run(sender=jack, - valid=False, - exception="Unauthorized") - bmc_management_contract.set_helper_address(sp.address("KT1EXYXNGdbh4uvdKc8hh7ETQXCXPzhelper")).run(sender=creator) - sc.verify(bmc_management_contract.data.helper == sp.address("KT1EXYXNGdbh4uvdKc8hh7ETQXCXPzhelper")) - - # test case 34: set_bmc_periphery test - bmc_management_contract.set_bmc_periphery(sp.address("KT1EXYXNGdbh4uvdKc8hh7ETQXCperiphery")).run(sender=jack, - valid=False, - exception="Unauthorized") - bmc_management_contract.set_bmc_periphery(sp.address("KT1EXYXNGdbh4uvdKc8hh7ETQXCperiphery")).run(sender=creator) - sc.verify(bmc_management_contract.data.bmc_periphery == sp.some(sp.address("KT1EXYXNGdbh4uvdKc8hh7ETQXCperiphery"))) + # 4: non-exist link resolve_route + sc.verify_equal(bmc_management_contract.resolve_route(sp.string('0x8.icon')), + sp.pair('Unreachable', + 'Unreachable: 0x8.icon is unreachable')) def deploy_bmc_management_contract(owner, helper): diff --git a/smartpy/bmc/contracts/tests/bmc_periphery_test.py b/smartpy/bmc/contracts/tests/bmc_periphery_test.py index 10aa7a53..839047ce 100644 --- a/smartpy/bmc/contracts/tests/bmc_periphery_test.py +++ b/smartpy/bmc/contracts/tests/bmc_periphery_test.py @@ -6,52 +6,77 @@ ParseAddress = sp.io.import_script_from_url("file:../bts/contracts/src/parse_address.py") -@sp.add_test("BMCManagementTest") +@sp.add_test("BMCPeripheryTest") def test(): sc = sp.test_scenario() # test account alice = sp.test_account("Alice") jack = sp.test_account("Jack") - bob = sp.test_account("Bob") helper2 = sp.test_account("Helper2") - owner = sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9") + owner = sp.test_account("owner") helper_contract = deploy_helper_contract() sc += helper_contract # deploy BMCManagement contract - bmc_management_contract = deploy_bmc_management_contract(sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), helper_contract.address) + bmc_management_contract = deploy_bmc_management_contract(owner.address, helper_contract.address) sc += bmc_management_contract parse_address = deploy_parse_address() sc += parse_address - bmc_periphery_contract = deploy_bmc_periphery_contract(bmc_management_contract.address, helper_contract.address, helper2.address, parse_address.address, owner) + bmc_periphery_contract = deploy_bmc_periphery_contract( + bmc_management_contract.address, helper_contract.address, helper2.address, parse_address.address, owner.address) sc += bmc_periphery_contract - # set_bmc_btp_address + # Scenario 1: Contract setters + + # Test cases: + # 1: set_bmc_btp_address by non-owner bmc_periphery_contract.set_bmc_btp_address("tezos.77").run(sender=alice, valid=False, exception="Unauthorized") + + # 2: set_bmc_btp_address by owner bmc_periphery_contract.set_bmc_btp_address("tezos.77").run(sender=bmc_management_contract.address) - sc.verify(bmc_periphery_contract.data.bmc_btp_address == sp.some(sp.string("btp://tezos.77/KT1Tezooo3zzSmartPyzzSTATiCzzzseJjWC"))) - # get_bmc_btp_address - sc.verify_equal(bmc_periphery_contract.get_bmc_btp_address(), sp.string("btp://tezos.77/KT1Tezooo3zzSmartPyzzSTATiCzzzseJjWC")) + # 3: verify value for bmc_btp_address + sc.verify(bmc_periphery_contract.data.bmc_btp_address == + sp.string("btp://tezos.77/KT1Tezooo3zzSmartPyzzSTATiCzzzseJjWC")) + + # 4: verify value for get_bmc_btp_address + sc.verify_equal(bmc_periphery_contract.get_bmc_btp_address(), + sp.string("btp://tezos.77/KT1Tezooo3zzSmartPyzzSTATiCzzzseJjWC")) + + # 5: set_helper_address by non-owner + bmc_periphery_contract.set_helper_address(helper_contract.address).run(sender=jack, valid=False, + exception="Unauthorized") + + # 6: set_helper_address by non-owner + bmc_periphery_contract.set_helper_address(helper_contract.address).run(sender=owner.address) + + # 7: verify helper address + sc.verify(bmc_periphery_contract.data.helper == helper_contract.address) + + # 8: set_parse_address by non-owner + bmc_periphery_contract.set_parse_address(parse_address.address).run(sender=jack, valid=False, + exception="Unauthorized") + + # 8: set_parse_address by owner + bmc_periphery_contract.set_parse_address(parse_address.address).run(sender=owner.address) + + # 9: verify parse_contract address + sc.verify(bmc_periphery_contract.data.parse_contract == parse_address.address) - # set_helper_address - bmc_periphery_contract.set_helper_address(sp.address("KT1EXYXNGdbh4uvdKc8hh7ETQXCXPzhelper")).run(sender=jack, valid=False, exception="Unauthorized") - bmc_periphery_contract.set_helper_address(sp.address("KT1EXYXNGdbh4uvdKc8hh7ETQXCXPzhelper")).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) - sc.verify(bmc_periphery_contract.data.helper == sp.address("KT1EXYXNGdbh4uvdKc8hh7ETQXCXPzhelper")) + # 10: set_bmc_management_addr by non-owner + bmc_periphery_contract.set_bmc_management_addr(bmc_management_contract.address).run(sender=jack, valid=False, + exception="Unauthorized") - # set_parse_address - bmc_periphery_contract.set_parse_address(sp.address("KT1EXYXNGdbh4uvdKc8hh7ETQXCXPzhparse")).run(sender=jack, valid=False, exception="Unauthorized") - bmc_periphery_contract.set_parse_address(sp.address("KT1EXYXNGdbh4uvdKc8hh7ETQXCXPzhparse")).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) - sc.verify(bmc_periphery_contract.data.parse_contract == sp.address("KT1EXYXNGdbh4uvdKc8hh7ETQXCXPzhparse")) + # 11: set_bmc_management_addr by owner + bmc_periphery_contract.set_bmc_management_addr(bmc_management_contract.address).run( + sender=owner.address) - # set_bmc_management_addr - bmc_periphery_contract.set_bmc_management_addr(sp.address("KT1EXYXNGdbh4uvdKc8hh7ETQXmanagement")).run(sender=jack, valid=False, exception="Unauthorized") - bmc_periphery_contract.set_bmc_management_addr(sp.address("KT1EXYXNGdbh4uvdKc8hh7ETQXmanagement")).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) - sc.verify(bmc_periphery_contract.data.bmc_management == sp.address("KT1EXYXNGdbh4uvdKc8hh7ETQXmanagement")) + # 9: verifying bmc_management address + sc.verify(bmc_periphery_contract.data.bmc_management == bmc_management_contract.address) def deploy_bmc_management_contract(owner, helper): @@ -59,7 +84,7 @@ def deploy_bmc_management_contract(owner, helper): return bmc_management_contract -def deploy_bmc_periphery_contract(bmc_address, helper,helper2, parse, owner): +def deploy_bmc_periphery_contract(bmc_address, helper, helper2, parse, owner): bmc_periphery_contract = BMCPeriphery.BMCPreiphery(bmc_address, helper, helper2, parse, owner) return bmc_periphery_contract From c2dd79bd83e28092375b81301521fe1b45be86c2 Mon Sep 17 00:00:00 2001 From: simusud Date: Wed, 5 Jul 2023 15:24:12 +0545 Subject: [PATCH 136/211] test(bts): unit test fixes --- .../bts/contracts/tests/bts_periphery_test.py | 267 ++++++--------- smartpy/bts/contracts/tests/btscore_test.py | 322 +++++++----------- 2 files changed, 238 insertions(+), 351 deletions(-) diff --git a/smartpy/bts/contracts/tests/bts_periphery_test.py b/smartpy/bts/contracts/tests/bts_periphery_test.py index a91e7e0c..6fb4e083 100644 --- a/smartpy/bts/contracts/tests/bts_periphery_test.py +++ b/smartpy/bts/contracts/tests/bts_periphery_test.py @@ -1,9 +1,10 @@ import smartpy as sp + BTSPeriphery = sp.io.import_script_from_url("file:./contracts/src/bts_periphery.py") BTSCore = sp.io.import_script_from_url("file:./contracts/src/bts_core.py") BTSOwnerManager = sp.io.import_script_from_url("file:./contracts/src/bts_owner_manager.py") ParseAddress = sp.io.import_script_from_url("file:./contracts/src/parse_address.py") -Helper= sp.io.import_script_from_url("file:./contracts/src/helper.py") +Helper = sp.io.import_script_from_url("file:./contracts/src/helper.py") @sp.add_test("BTSPeripheryTest") @@ -11,162 +12,114 @@ def test(): sc = sp.test_scenario() # test account - alice=sp.test_account("Alice") - bmc_address = sp.test_account('bmc') - admin=sp.test_account('admin') - helper = sp.test_account("Helper") - - - def deploy_btsperiphery_contract(): - btsperiphery_contract = BTSPeriphery.BTPPreiphery(bmc_address.address,btscore_contract.address,btshelpercontract.address,btsparsecontract.address,'NativeCoin',admin.address) - return btsperiphery_contract - - def deploy_parsecontract(): - btsparsecontract = ParseAddress.ParseAddress() - return btsparsecontract - - def deploy_helper(): - btshelper = Helper.Helper() - return btshelper - - - - def deploy_btscore_contract(): - btscore_contract= BTSCore.BTSCore( - owner_manager= bts_OwnerManager_contract.address, - _native_coin_name="Tok1", - _fee_numerator=sp.nat(1000), - _fixed_fee=sp.nat(10)) - return btscore_contract - - def deploy_btsOwnerManager_Contract(): - bts_OwnerManager_Contract = BTSOwnerManager.BTSOwnerManager(sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) - return bts_OwnerManager_Contract - - bts_OwnerManager_contract = deploy_btsOwnerManager_Contract() - sc+= bts_OwnerManager_contract - - btscore_contract = deploy_btscore_contract() - sc+= btscore_contract - - btshelpercontract = deploy_helper() - sc+= btshelpercontract - - btsparsecontract = deploy_parsecontract() - sc+= btsparsecontract - - # deploy btsperiphery contract - btsperiphery_contract = deploy_btsperiphery_contract() - sc += btsperiphery_contract - - btscore_contract.update_bts_periphery(btsperiphery_contract.address).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) - - - - - #test 1: Test of add to blacklist function - btsperiphery_contract.add_to_blacklist({0:"notaaddress"}).run(sender=btsperiphery_contract.address,valid=False, exception="InvalidAddress") # invalid address - btsperiphery_contract.add_to_blacklist({0:"tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"}).run(sender=btsperiphery_contract.address,valid=True) #add a address to blacklist - btsperiphery_contract.add_to_blacklist({0:"tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"}).run(sender=btsperiphery_contract.address,valid=True) # can be called twice - btsperiphery_contract.add_to_blacklist({0:"tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"}) .run(sender=admin.address,valid=False,exception ="Unauthorized")# only btsperiphery contract call this function - btsperiphery_contract.add_to_blacklist({0:'tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg'}).run(sender=btsperiphery_contract.address,valid=False,exception='InvalidAddress')#invalid address - sc.verify(btsperiphery_contract.data.blacklist[sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW")] == True) # checking the blacklist[] map - - - #test 2 : Test of remove from blacklist function - btsperiphery_contract.remove_from_blacklist({0:'notaaddress'}).run(sender=btsperiphery_contract.address,valid=False, exception="InvalidAddress") # invalid address - btsperiphery_contract.remove_from_blacklist({0:'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=btsperiphery_contract.address,valid=False, exception="UserNotFound") # address not black-listed - btsperiphery_contract.add_to_blacklist({0:'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=btsperiphery_contract.address) # adding to blacklist - btsperiphery_contract.remove_from_blacklist({0:'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=btsperiphery_contract.address) # valid process - btsperiphery_contract.remove_from_blacklist({0:'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=btsperiphery_contract.address,valid=False ,exception ='UserNotFound') # cannot remove from blacklist twice - btsperiphery_contract.add_to_blacklist({0:'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=btsperiphery_contract.address) # adding to blacklist - btsperiphery_contract.remove_from_blacklist({0:'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=btsperiphery_contract.address) # can only be called from btseperiphery contract - btsperiphery_contract.remove_from_blacklist({0:'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=admin.address, valid=False, exception ="Unauthorized") # can only be called from btseperiphery contract - - - #test 3 : set token limit - btsperiphery_contract.set_token_limit(sp.record(coin_names = {0:"Tok2" , 1:'BB'} ,token_limit ={0:sp.nat(5),1:sp.nat(2)})).run(sender=admin.address,valid=False,exception='Unauthorized') #can only be called from btsperiphery contract - btsperiphery_contract.set_token_limit(sp.record(coin_names = {0:"Tok2" , 1:'BB'} ,token_limit ={0:sp.nat(5),1:sp.nat(2)})).run(sender=btsperiphery_contract.address) #set token limit for Tok2 coin to 5 and BB coin to 2 - sc.verify(btsperiphery_contract.data.token_limit["Tok2"] == sp.nat(5))#test of token_limit for tok2 token - btsperiphery_contract.set_token_limit(sp.record(coin_names = {0:"Tok2" , 1:'BB'} ,token_limit ={0:sp.nat(5)} )).run(valid=False,exception='InvalidParams',sender=btsperiphery_contract.address) #invalid parameters - #cannot set more than 15 token limit at once - btsperiphery_contract.set_token_limit(sp.record(coin_names = {0:"Tok2" , 1:'BB'} ,token_limit ={0:sp.nat(15),1:sp.nat(22)})).run(sender=btsperiphery_contract.address) #can modify already set data - sc.verify(btsperiphery_contract.data.token_limit["BB"] == sp.nat(22))#test of token_limit for tok2 token - - - #test 4 :send service message - - btsperiphery_contract.send_service_message(sp.record(_from=sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), to="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW",coin_names={0:"Tok1"}, values={0:sp.nat(10)}, fees={0:sp.nat(2)})).run(sender=btscore_contract.address ) - btsperiphery_contract.send_service_message(sp.record(_from=sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), to="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW",coin_names={0:"Tok1"}, values={0:sp.nat(10)}, fees={0:sp.nat(2)})).run( sender=btscore_contract.address ) # test of function - btsperiphery_contract.send_service_message(sp.record(_from=sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), to="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW",coin_names={0:"Tok1"}, values={0:sp.nat(10)}, fees={0:sp.nat(2)})).run( sender= admin,valid=False, exception='Unauthorized' ) # only message from bts-core is authorized - sc.show(btsperiphery_contract.data.requests[1])#test to verify if request message is correct - sc.verify_equal(btsperiphery_contract.data.requests[1] ,sp.record(amounts = {0 : 10}, coin_names = {0 : 'Tok1'}, fees = {0 : 2}, from_ = 'tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW', to = 'btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW')) # request data verified - sc.verify(btsperiphery_contract.data.number_of_pending_requests == 2)#2 pending request - sc.verify(btsperiphery_contract.data.serial_no == 2) #serial no of request increased to 2 - - - #Test 5: handle btp message - # btsperiphery_contract.handle_btp_message(sp.record(_from="tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", svc="bts", sn=sp.nat(4),msg=sp.bytes("0xf8cfb83d6274703a2f2f30783232382e6172637469632f307831313131313131313131313131313131313131313131313131313131313131313131313131313131b8396274703a2f2f3078312e69636f6e2f637830303030303030303030303030303030303030303030303030303030303030303030303030303036836274730ab84ef84cb83d6274703a2f2f30783232382e6172637469632f307861313434326339303132304138393163336465393739336361433730393638436162313133323335cc8b627470206d657373616765") )).run(sender=bmc_address) #test of handle_btp_message function - # btsperiphery_contract.handle_btp_message(sp.record(_from="tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", svc="btc", sn=sp.nat(4),msg=sp.bytes("0xf8cfb83d6274703a2f2f30783232382e6172637469632f307831313131313131313131313131313131313131313131313131313131313131313131313131313131b8396274703a2f2f3078312e69636f6e2f637830303030303030303030303030303030303030303030303030303030303030303030303030303036836274730ab84ef84cb83d6274703a2f2f30783232382e6172637469632f307861313434326339303132304138393163336465393739336361433730393638436162313133323335cc8b627470206d657373616765") )).run(sender=bmc_address,valid=False, exception='InvalidSvc') #svc name must match hardcoded service name "btc" - # btsperiphery_contract.handle_btp_message(sp.record(_from="tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", svc="btc", sn=sp.nat(4),msg=sp.bytes("0xf8cfb83d6274703a2f2f30783232382e6172637469632f307831313131313131313131313131313131313131313131313131313131313131313131313131313131b8396274703a2f2f3078312e69636f6e2f637830303030303030303030303030303030303030303030303030303030303030303030303030303036836274730ab84ef84cb83d6274703a2f2f30783232382e6172637469632f307861313434326339303132304138393163336465393739336361433730393638436162313133323335cc8b627470206d657373616765") )).run(sender=btsperiphery_contract.address,valid=False, exception='Unauthorized') #can only be called from bmc contract - - - - - - - - - - - - #Test : handle btp error - # sc.verify(btsperiphery_contract.data.number_of_pending_requests == 2)#pending request is 2 here - # btsperiphery_contract.handle_btp_error(sp.record(svc= "bts", code=sp.nat(2), sn=sp.nat(1), msg="test 1")).run(sender=bmc_address) - # btsperiphery_contract.handle_btp_error(sp.record(svc= "btc", code=sp.nat(2), sn=sp.nat(1), msg="test 1")).run(sender=bmc_address,valid=False,exception='InvalidSvc') #Invalid Svc - # btsperiphery_contract.handle_btp_error(sp.record(svc= "bts", code=sp.nat(2), sn=sp.nat(111), msg="test 1")).run(sender=bmc_address,valid=False,exception='Missing item in map') # Invalid sn , sn must be serial number of service request - # btsperiphery_contract.handle_btp_error(sp.record(svc= "bts", code=sp.nat(2), sn=sp.nat(1), msg="test 1")).run(sender=btsperiphery_contract.address,valid=False,exception='Unauthorized')#Only bmc contract can call this fucntion - # sc.verify(btsperiphery_contract.data.number_of_pending_requests == 0) #pending request decreased - - - #Test : handle request service - btsperiphery_contract.handle_request_service(sp.record(to= "tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc", assets={0: sp.record(coin_name="BB", value=sp.nat(4))})).run(sender=btsperiphery_contract.address,valid=False,exception='UnregisteredCoin') - + admin = sp.test_account('admin') - #Test : handle fee gathering - # btsperiphery_contract.handle_fee_gathering(sp.record(fa="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", svc="bts")).run(sender=bmc_address) # handle_fee_gathering function call - # btsperiphery_contract.handle_fee_gathering(sp.record(fa="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", svc="btc")).run(sender=bmc_address, valid=False, exception='InvalidSvc') # svc must match hardcoded service name 'bts' - # btsperiphery_contract.handle_fee_gathering(sp.record(fa="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", svc="bts")).run(sender=btsperiphery_contract.address, valid=False, exception='Unauthorized') # can only be called from bmc contract - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + def deploy_bts_periphery_contract(core_address, helper, parse): + bmc = sp.test_account("bmc") + _bts_periphery_contract = BTSPeriphery.BTSPeriphery( + bmc_address=bmc.address, bts_core_address=core_address, helper_contract=helper, parse_address=parse, + native_coin_name='NativeCoin', owner_address=admin.address) + return _bts_periphery_contract + def deploy_parse_contract(): + _bts_parse_contract = ParseAddress.ParseAddress() + return _bts_parse_contract + def deploy_helper(): + _bts_helper = Helper.Helper() + return _bts_helper + + def deploy_bts_core_contract(_bts_owner_manager_contract): + _bts_core_contract = BTSCore.BTSCore( + owner_manager=_bts_owner_manager_contract, + _native_coin_name="Tok1", + _fee_numerator=sp.nat(1000), + _fixed_fee=sp.nat(10)) + return _bts_core_contract + + def deploy_bts_owner_manager_contract(): + _bts_owner_manager_contract = BTSOwnerManager.BTSOwnerManager(admin.address) + return _bts_owner_manager_contract + + bts_owner_manager_contract = deploy_bts_owner_manager_contract() + sc += bts_owner_manager_contract + + bts_core_contract = deploy_bts_core_contract(bts_owner_manager_contract.address) + sc += bts_core_contract + + bts_helper_contract = deploy_helper() + sc += bts_helper_contract + + bts_parse_contract = deploy_parse_contract() + sc += bts_parse_contract + + # deploy bts_periphery contract + bts_periphery_contract = deploy_bts_periphery_contract(bts_core_contract.address, bts_helper_contract.address, + bts_parse_contract.address) + sc += bts_periphery_contract + + bts_core_contract.update_bts_periphery(bts_periphery_contract.address).run(sender=admin.address) + + # Scenario 1: set token limit + + # Test cases: + # 1: set_token_limit from non-bts_periphery contract + bts_periphery_contract.set_token_limit(sp.map({"Tok2": sp.nat(5), "BB": sp.nat(2)})).run(sender=admin.address, + valid=False, + exception='Unauthorized') + + # 2: set token limit for Tok2 coin to 5 and BB coin to 2 from bts_periphery_contract + bts_periphery_contract.set_token_limit(sp.map({"Tok2": sp.nat(5), "BB": sp.nat(2)})).run( + sender=bts_periphery_contract.address) + + # 3: verifying the value of token limit + sc.verify(bts_periphery_contract.data.token_limit["Tok2"] == sp.nat(5)) + + # 4: modify already set data + bts_periphery_contract.set_token_limit(sp.map({"Tok2": sp.nat(15), "BB": sp.nat(22)})).run( + sender=bts_periphery_contract.address) + + # 5: verifying the value of token limit after change + sc.verify(bts_periphery_contract.data.token_limit["BB"] == sp.nat(22)) + + # Scenario 2: send service message + + # Test cases: + # 1 : send_service_message called by bts-core + bts_periphery_contract.send_service_message( + sp.record( + _from=sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), + to="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", + coin_details=[ + sp.record(coin_name="Tok1", value=sp.nat(10), fee=sp.nat(2)) + ] + )).run(sender=bts_core_contract.address).run(sender=bts_core_contract.address) + + # 2 : send_service_message called by non-bts-core + bts_periphery_contract.send_service_message( + sp.record( + _from=sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), + to="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW", + coin_details=[ + sp.record(coin_name="Tok1", value=sp.nat(10), fee=sp.nat(2)) + ] + )).run(sender=admin, valid=False, exception='Unauthorized') + + # 3: verify if request message is correct + sc.show(bts_periphery_contract.data.requests[1]) + sc.verify_equal( + bts_periphery_contract.data.requests[1], + sp.record( + coin_details=[ + sp.record( + coin_name='Tok1', + value=10, + fee=2 + ) + ], + from_='tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW', + to='btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW')) + + # 4: verify request data + sc.verify(bts_periphery_contract.data.number_of_pending_requests == 1) + sc.verify(bts_periphery_contract.data.serial_no == 1) diff --git a/smartpy/bts/contracts/tests/btscore_test.py b/smartpy/bts/contracts/tests/btscore_test.py index bd35fada..9df53bea 100644 --- a/smartpy/bts/contracts/tests/btscore_test.py +++ b/smartpy/bts/contracts/tests/btscore_test.py @@ -1,6 +1,5 @@ import smartpy as sp - BTSCore = sp.io.import_script_from_url("file:./contracts/src/bts_core.py") BTSOwnerManager = sp.io.import_script_from_url("file:./contracts/src/bts_owner_manager.py") BTSPeriphery = sp.io.import_script_from_url("file:./contracts/src/bts_periphery.py") @@ -8,24 +7,20 @@ ParseAddress = sp.io.import_script_from_url("file:./contracts/src/parse_address.py") - @sp.add_test("BTSCoreTest") def test(): sc = sp.test_scenario() sc.h1("BTSCore") - # test account - alice = sp.test_account("Alice") - jack = sp.test_account("Jack") bob = sp.test_account("Bob") - creator = sp.test_account("Creator") + owner = sp.test_account("owner") # deploy BTSCore contract - bts_owner_manager = deploy_btsOwnerManager_Contract() + bts_owner_manager = deploy_bts_owner_manager_contract(owner.address) sc += bts_owner_manager - btsCore_contract = deploy_btsCore_contract(bts_owner_manager.address) - sc += btsCore_contract + bts_core_contract = deploy_bts_core_contract(bts_owner_manager.address) + sc += bts_core_contract helper_contract = deploy_helper_contract() sc += helper_contract @@ -33,259 +28,198 @@ def test(): parse_address = deploy_parse_address() sc += parse_address - - bts_periphery = deploy_btsPeriphery_Contract(btsCore_contract.address, helper_contract.address, parse_address.address) + bts_periphery = deploy_bts_periphery_contract(bts_core_contract.address, helper_contract.address, + parse_address.address, owner.address) sc += bts_periphery - fa2 = deploy_fa2_Contract(bts_periphery.address) + fa2 = deploy_fa2_contract(bts_periphery.address) sc += fa2 + # Scenario 1: BTSCore Scenario + # Test cases: + # 1: verify owner manager + sc.verify_equal(bts_core_contract.data.bts_owner_manager, bts_owner_manager.address) + # 2: verify update_bts_periphery function + bts_core_contract.update_bts_periphery(bts_periphery.address).run(sender=owner.address) + sc.verify_equal(bts_core_contract.data.bts_periphery_address, sp.some(bts_periphery.address)) - bts_owner_manager.is_owner(sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) - + # Scenario 2: set_fee_ratio - # test case 1: check the name of coin - sc.verify_equal(btsCore_contract.get_native_coin_name(), "BTSCOIN") + # Test cases: + # 1: token doesn't exist + bts_core_contract.set_fee_ratio(name=sp.string("ABC"), fee_numerator=sp.nat(100), fixed_fee=sp.nat(10)).run( + sender=owner.address, valid=False, exception='TokenNotExists') + # 2: fee numerator is greater than denominator + bts_core_contract.set_fee_ratio(name=sp.string("BTSCOIN"), fee_numerator=sp.nat(10000), fixed_fee=sp.nat(10)).run( + sender=owner.address, valid=False, exception='InvalidSetting') - # test case 2: check the owner manager of the contract - sc.verify_equal(btsCore_contract.data.bts_owner_manager, bts_owner_manager.address) + # 3: fixed fee is 0 + bts_core_contract.set_fee_ratio(name=sp.string("BTSCOIN"), fee_numerator=sp.nat(100), fixed_fee=sp.nat(0)).run( + sender=owner.address, valid=False, exception='LessThan0') + # 4: valid condition + bts_core_contract.set_fee_ratio(name=sp.string("BTSCOIN"), fee_numerator=sp.nat(100), fixed_fee=sp.nat(10)).run( + sender=owner.address) - # test case 3: update_bts_periphery function - btsCore_contract.update_bts_periphery(bts_periphery.address).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) - sc.verify_equal(btsCore_contract.data.bts_periphery_address,sp.some(bts_periphery.address)) + # 5: set_fee_ratio called by non-owner + bts_core_contract.set_fee_ratio(name=sp.string("BTSCOIN"), fee_numerator=sp.nat(100), fixed_fee=sp.nat(10)).run( + sender=bob.address, valid=False, exception='Unauthorized') - # test case 4: set_fee_ratio function - #throws error if coin name is different - btsCore_contract.set_fee_ratio(name=sp.string("coindiff"),fee_numerator=sp.nat(100),fixed_fee=sp.nat(10)).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), valid=False, exception='TokenNotExists') - #throws error when fee numerator is greater than denominator - btsCore_contract.set_fee_ratio(name=sp.string("BTSCOIN"),fee_numerator=sp.nat(10000),fixed_fee=sp.nat(10)).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), valid=False, exception='InvalidSetting') - # throws error when fixed fee is less than 0 - btsCore_contract.set_fee_ratio(name=sp.string("BTSCOIN"),fee_numerator=sp.nat(100),fixed_fee=sp.nat(0)).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), valid=False, exception='LessThan0') - #works - btsCore_contract.set_fee_ratio(name=sp.string("BTSCOIN"),fee_numerator=sp.nat(100),fixed_fee=sp.nat(10)).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) - #checking value - sc.verify_equal(btsCore_contract.data.coin_details["BTSCOIN"].fee_numerator, 100) - sc.verify_equal(btsCore_contract.data.coin_details["BTSCOIN"].fixed_fee, 10) + # 5: verify fees + sc.verify_equal(bts_core_contract.data.coin_details["BTSCOIN"].fee_numerator, 100) + sc.verify_equal(bts_core_contract.data.coin_details["BTSCOIN"].fixed_fee, 10) + # Scenario 2: register - # test case 5: register function - # name shouldn't be native coin name - btsCore_contract.register( + # Test cases: + # 1: native coin (native_coin = BTSCOIN) + bts_core_contract.register( name=sp.string("BTSCOIN"), fee_numerator=sp.nat(10), fixed_fee=sp.nat(2), addr=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), - token_metadata=sp.map({"ff": sp.bytes("0x0dae11")}), - metadata=sp.big_map({"ff": sp.bytes("0x0dae11")}) - ).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), valid=False, exception='ExistNativeCoin') - #throws error when fee numerator is greater than denominator - btsCore_contract.register( + token_metadata=sp.map({"token_metadata": sp.bytes("0x0dae11")}), + metadata=sp.big_map({"metadata": sp.bytes("0x0dae11")}) + ).run(sender=owner.address, valid=False, exception='ExistNativeCoin') + + # 2: fee numerator is greater than denominator + bts_core_contract.register( name=sp.string("new_coin1"), fee_numerator=sp.nat(100000), fixed_fee=sp.nat(2), - addr=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), - token_metadata=sp.map({"ff": sp.bytes("0x0dae11")}), - metadata=sp.big_map({"ff": sp.bytes("0x0dae11")}) - ).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), valid=False, exception='InvalidSetting') - # works - btsCore_contract.register( + addr=fa2.address, + token_metadata=sp.map({"token_metadata": sp.bytes("0x0dae11")}), + metadata=sp.big_map({"metadata": sp.bytes("0x0dae11")}) + ).run(sender=owner.address, valid=False, exception='InvalidSetting') + + # 3: valid case + bts_core_contract.register( name=sp.string("new_coin"), fee_numerator=sp.nat(10), fixed_fee=sp.nat(2), addr=fa2.address, + token_metadata=sp.map({"token_metadata": sp.bytes("0x0dae11")}), + metadata=sp.big_map({"metadata": sp.bytes("0x0dae11")}) + ).run(sender=owner.address) + + # 4: verify the registered value + sc.verify_equal(bts_core_contract.data.coins_name, ['new_coin', 'BTSCOIN']) + sc.verify_equal(bts_core_contract.data.coin_details['new_coin'], + sp.record(addr=fa2.address, coin_type=2, fee_numerator=10, fixed_fee=2)) + + # 5: existing coin name + bts_core_contract.register( + name=sp.string("new_coin"), + fee_numerator=sp.nat(10), + fixed_fee=sp.nat(2), + addr=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), token_metadata=sp.map({"ff": sp.bytes("0x0dae11")}), metadata=sp.big_map({"ff": sp.bytes("0x0dae11")}) - ).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + ).run(sender=owner.address, valid=False, exception="ExistCoin") - # verifying the value - sc.verify_equal(btsCore_contract.data.coins_name, ['new_coin', 'BTSCOIN']) - sc.verify_equal(btsCore_contract.data.coin_details['new_coin'], sp.record(addr = fa2.address, coin_type = 2, fee_numerator = 10, fixed_fee = 2)) - # throws error when existed coin name is given - btsCore_contract.register( + # 6: registered NON-NATIVE COIN_TYPE by non-owner + bts_core_contract.register( name=sp.string("new_coin"), fee_numerator=sp.nat(10), fixed_fee=sp.nat(2), addr=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), token_metadata=sp.map({"ff": sp.bytes("0x0dae11")}), metadata=sp.big_map({"ff": sp.bytes("0x0dae11")}) - ).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), valid=False, exception="ExistCoin") - # throws error when existed address is given - btsCore_contract.register( + ).run(sender=bob.address, valid=False, exception="Unauthorized") + + # 7: register NON-NATIVE COIN_TYPE + bts_core_contract.register( name=sp.string("new_coin2"), fee_numerator=sp.nat(10), fixed_fee=sp.nat(2), addr=fa2.address, token_metadata=sp.map({"ff": sp.bytes("0x0dae11")}), metadata=sp.big_map({"ff": sp.bytes("0x0dae11")}) - ).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), valid=False, exception="AddressExists") - - - # test case 6: coin_names function - sc.verify_equal(btsCore_contract.coin_names(), ['new_coin', 'BTSCOIN']) + ).run(sender=owner.address, valid=False, exception="AddressExists") - # test case 7: coin_id function - sc.verify_equal(btsCore_contract.coin_id('new_coin'), fa2.address) + # 8: register NATIVE WRAPPED COIN_TYPE + bts_core_contract.register( + name=sp.string("wrapped-coin"), + fee_numerator=sp.nat(10), + fixed_fee=sp.nat(2), + addr=sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg"), + token_metadata=sp.map({"token_metadata": sp.bytes("0x0dae11")}), + metadata=sp.big_map({"metadata": sp.bytes("0x0dae11")}) + ).run(sender=owner.address) - # test case 8: is_valid_coin function - sc.verify_equal(btsCore_contract.is_valid_coin('new_coin'), True) - sc.verify_equal(btsCore_contract.is_valid_coin('not_valid'), False) + # Scenario 3: contract getters + # Test cases: + # 1: verify coin_id functio + sc.verify_equal(bts_core_contract.coin_id('new_coin'), fa2.address) - # test case 9: fee_ratio function - sc.verify_equal(btsCore_contract.fee_ratio('new_coin'), sp.record(fee_numerator=10, fixed_fee=2)) + # 2: verify is_valid_coin function + sc.verify_equal(bts_core_contract.is_valid_coin('new_coin'), True) + sc.verify_equal(bts_core_contract.is_valid_coin('not_valid'), False) + # 3: verify fee_ratio function + sc.verify_equal(bts_core_contract.fee_ratio('new_coin'), sp.record(fee_numerator=10, fixed_fee=2)) - #test case 10: balance_of function + # 4: verify balance_of function sc.verify_equal( - btsCore_contract.balance_of( - sp.record(owner=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), coin_name='new_coin') + bts_core_contract.balance_of( + sp.record(owner=owner.address, coin_name='new_coin') ), sp.record(usable_balance=0, locked_balance=0, refundable_balance=0, user_balance=0) ) - #test case 11: balance_of_batch function - btsCore_contract.balance_of_batch( - sp.record(owner=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), coin_names=['new_coin', 'BTSCOIN']) + # 5: verify balance_of_batch function + bts_core_contract.balance_of_batch( + sp.record(owner=owner.address, coin_names=['new_coin', 'BTSCOIN']) ) sc.verify_equal( - btsCore_contract.balance_of_batch( - sp.record(owner=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), coin_names=['new_coin', 'BTSCOIN']) + bts_core_contract.balance_of_batch( + sp.record(owner=owner.address, coin_names=['new_coin', 'BTSCOIN']) ), - sp.record(locked_balances = {0 : 0, 1 : 0}, refundable_balances = {0 : 0, 1 : 0}, usable_balances = {0 : 0, 1 : 0}, user_balances = {0 : 0, 1 : 0})) - - - # #test case 13: get_accumulated_fees function - # # sc.verify_equal(btsCore_contract.get_accumulated_fees(), {}) - - - # #test case 14: transfer_native_coin function - bts_periphery.set_token_limit( - sp.record( - coin_names=sp.map({0: "BTSCOIN"}), - token_limit=sp.map({0: 115792089237316195423570985008687907853269984665640564039457584007913129639935}) - ) - ).run(sender = btsCore_contract.address) - btsCore_contract.transfer_native_coin("tz1eZMrKqCNPrHzykdTuqKRyySoDv4QRSo7d").run(sender= sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), amount=sp.tez(30)) - - - - # # test case 15: transfer function - # fa2.mint([sp.record(to_=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), amount=sp.nat(100))]).run(sender=bts_periphery.address) - # fa2.set_allowance([sp.record(spender=btsCore_contract.address, amount=sp.nat(100))]).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) - # fa2.update_operators( - # [sp.variant("add_operator", sp.record(owner=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), operator=btsCore_contract.address, token_id=0))]).run( - # sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) - - - # btsCore_contract.transfer(coin_name='new_coin', value=10, to="tz1eZMrKqCNPrHzykdTuqKRyySoDv4QRSo7d").run(sender = sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) - - # sc.verify_equal( - # btsCore_contract.balance_of( - # sp.record(owner=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), coin_name='new_coin') - # ), - # sp.record(usable_balance=90, locked_balance=10, refundable_balance=0, user_balance=90) - # ) - - #test case 12: minting and checking balance - # mint for native coin - # btsCore_contract.mint(to=sp.address("tz1UHiurbSsDFXnTfMQkeni4GWCuMpq6JFRB"), coin_name="BTSCOIN", value=1000).run(sender = bts_periphery.address) - # sc.verify_equal( - # btsCore_contract.balance_of( - # sp.record(owner=sp.address("tz1UHiurbSsDFXnTfMQkeni4GWCuMpq6JFRB"), coin_name='BTSCOIN') - # ), - # sp.record(usable_balance=0, locked_balance=0, refundable_balance=0, user_balance=1000) - # ) - # error balance_of native_coin balance ma halne condition - - # for NON_NATIVE_TOKEN_TYPE - # fa2.mint([sp.record(to_=bts_periphery.address, amount=sp.nat(2000))]).run( - # sender=bts_periphery.address) - # fa2.update_operators( - # [sp.variant("add_operator", sp.record(owner=bts_periphery.address, operator=btsCore_contract.address, token_id=0))]).run( - # sender=bts_periphery.address) - # fa2.set_allowance([sp.record(spender=btsCore_contract.address, amount=sp.nat(1000))]).run( - # sender=bts_periphery.address) - - # btsCore_contract.mint(to=sp.address("tz1UHiurbSsDFXnTfMQkeni4GWCuMpq6JFRB"), coin_name="new_coin", value=1000).run(sender = bts_periphery.address) - # sc.verify_equal( - # btsCore_contract.balance_of( - # sp.record(owner=sp.address("tz1UHiurbSsDFXnTfMQkeni4GWCuMpq6JFRB"), coin_name='new_coin') - # ), - # sp.record(usable_balance=0, locked_balance=0, refundable_balance=0, user_balance=1000) - # ) - - - # # test case 16: transfer_batch function - # btsCore_contract.transfer_batch( - # coin_names={0: 'new_coin', 1: 'new_coin'}, - # values={0: 10, 1: 10}, - # to="tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP" - # ).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) - - # sc.verify_equal( - # btsCore_contract.balance_of( - # sp.record(owner=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), coin_name='new_coin') - # ), - # sp.record(usable_balance=70, locked_balance=30, refundable_balance=0, user_balance=70) - # ) - - # # test case 17: handle_response_service function - # btsCore_contract.handle_response_service(sp.record(requester=sp.address("KT1VCbyNieUsQsCShkxtTz9ZbLmE9oowmJPm"), coin_name="BTSCOIN",value=sp.nat(44), fee=sp.nat(3), rsp_code=sp.nat(1))).run(sender=bts_periphery.address) - - - - - -# -# # -# # # test case 16: reclaim function -# # -# # # btsCore_contract.reclaim(coin_name="new_coin", value=25).run(sender = sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) -# # -# # -# # # btsCore_contract.refund(to=sp.address("tz1UHiurbSsDFXnTfMQkeni4GWCuMpq6JFRB"), coin_name="new_coin", value=30).run(sender = sp.address("tz1UHiurbSsDFXnTfMQkeni4GWCuMpq6JFRB")) -# # -# # -# # -# # -# # -# - -# -# -# - -def deploy_btsCore_contract(bts_OwnerManager_Contract): - btsCore_contract = BTSCore.BTSCore( - owner_manager=bts_OwnerManager_Contract, + [ + sp.record(locked_balance=0, refundable_balance=0, usable_balance=0, user_balance=0), + sp.record(locked_balance=0, refundable_balance=0, usable_balance=0, user_balance=0) + ] + ) + + +def deploy_bts_core_contract(bts_owner_manager_contract): + bts_core_contract = BTSCore.BTSCore( + owner_manager=bts_owner_manager_contract, _native_coin_name="BTSCOIN", _fee_numerator=sp.nat(1000), _fixed_fee=sp.nat(10) ) - return btsCore_contract + return bts_core_contract + -def deploy_btsOwnerManager_Contract(): - bts_OwnerManager_Contract = BTSOwnerManager.BTSOwnerManager(sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) - return bts_OwnerManager_Contract +def deploy_bts_owner_manager_contract(owner): + bts_owner_manager_contract = BTSOwnerManager.BTSOwnerManager(owner) + return bts_owner_manager_contract -def deploy_btsPeriphery_Contract(core_address, helper, parse): + +def deploy_bts_periphery_contract(core_address, helper, parse, owner): bmc = sp.test_account("bmc") - btsPeriphery_Contract = BTSPeriphery.BTPPreiphery(bmc_address= bmc.address, bts_core_address=core_address, helper_contract=helper, parse_address=parse,native_coin_name= 'BTSCoin',owner_address=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) - return btsPeriphery_Contract + bts_periphery_contract = BTSPeriphery.BTSPeriphery( + bmc_address=bmc.address, bts_core_address=core_address, helper_contract=helper, parse_address=parse, + native_coin_name='BTSCoin', owner_address=owner) + return bts_periphery_contract + -def deploy_fa2_Contract(admin_address): - fa2_contract = BTSCore.FA2_contract.SingleAssetToken(admin=admin_address, metadata=sp.big_map({"ss": sp.bytes("0x0dae11")}), token_metadata=sp.map({"ff": sp.bytes("0x0dae11")})) +def deploy_fa2_contract(admin_address): + fa2_contract = BTSCore.FA2_contract.SingleAssetToken(admin=admin_address, + metadata=sp.big_map({"ss": sp.bytes("0x0dae11")}), + token_metadata=sp.map({"ff": sp.bytes("0x0dae11")})) return fa2_contract + def deploy_helper_contract(): helper_contract = BMCHelper.Helper() return helper_contract + def deploy_parse_address(): parse_address = ParseAddress.ParseAddress() return parse_address - - From 2d81c9e4442e090edc38e2a345760f7658ff4bc0 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Thu, 6 Jul 2023 12:08:30 +0545 Subject: [PATCH 137/211] fix: tezos to icon bridge integraton changes --- cmd/iconbridge/chain/icon/receiver.go | 8 - cmd/iconbridge/chain/tezos/client.go | 48 +- cmd/iconbridge/chain/tezos/receiver.go | 802 +++++++++++----------- cmd/iconbridge/chain/tezos/sender.go | 10 +- cmd/iconbridge/chain/tezos/types/types.go | 1 + cmd/iconbridge/chain/tezos/verifier.go | 165 ++--- cmd/iconbridge/example.config.json | 26 +- cmd/iconbridge/relay/relay.go | 28 +- 8 files changed, 557 insertions(+), 531 deletions(-) diff --git a/cmd/iconbridge/chain/icon/receiver.go b/cmd/iconbridge/chain/icon/receiver.go index 3da94ef4..6f7113eb 100644 --- a/cmd/iconbridge/chain/icon/receiver.go +++ b/cmd/iconbridge/chain/icon/receiver.go @@ -154,12 +154,8 @@ func NewReceiver(src, dst chain.BTPAddress, } func (r *Receiver) newVerifier(opts *types.VerifierOptions) (*Verifier, error) { - fmt.Println("reached in new Validator of icon") - fmt.Println(opts.ValidatorsHash) validators, err := r.Client.GetValidatorsByHash(opts.ValidatorsHash) - fmt.Println("validator hash is", validators) if err != nil { - fmt.Println("error in validators", err) return nil, err } vr := Verifier{ @@ -178,10 +174,8 @@ func (r *Receiver) newVerifier(opts *types.VerifierOptions) (*Verifier, error) { if err != nil { return nil, err } - fmt.Println("has gotten the headers and votes") ok, err := vr.Verify(header, votes) - fmt.Println("has verified the header ", ok) if !ok { err = errors.New("verification failed") } @@ -311,14 +305,12 @@ func handleVerifierBlockRequests(requestCh chan *verifierBlockRequest, client IC } func (r *Receiver) receiveLoop(ctx context.Context, startHeight, startSeq uint64, callback func(rs []*chain.Receipt) error) (err error) { - fmt.Println("reached in icons reveive loop in reveiveloop") blockReq, logFilter := r.blockReq, r.logFilter // copy blockReq.Height, logFilter.seq = types.NewHexInt(int64(startHeight)), startSeq var vr IVerifier if r.opts.Verifier != nil { - fmt.Println("should reach in not nil case") vr, err = r.newVerifier(r.opts.Verifier) if err != nil { return err diff --git a/cmd/iconbridge/chain/tezos/client.go b/cmd/iconbridge/chain/tezos/client.go index 915fd432..c6ce79f3 100644 --- a/cmd/iconbridge/chain/tezos/client.go +++ b/cmd/iconbridge/chain/tezos/client.go @@ -5,7 +5,9 @@ import ( "context" "encoding/json" "fmt" + "io/ioutil" "math/big" + "net/http" // "io" "time" @@ -56,9 +58,10 @@ type TypesLinkStats struct { type Client struct { Log log.Logger // Ctx context.Context - Cl *rpc.Client - Contract *contract.Contract - blockLevel int64 + Cl *rpc.Client + Contract *contract.Contract + blockLevel int64 + BmcManagement tezos.Address } func (c *Client) SignTransaction() rpc.CallOptions { @@ -247,7 +250,9 @@ func returnTxMetadata3(tx *rpc.Transaction, contractAddress tezos.Address, heigh for i := 0; i < len(tx.Metadata.InternalResults); i++ { fmt.Println("reached in for") internalResults := tx.Metadata.InternalResults[i] - if internalResults.Kind.String() == "event" && internalResults.Source.ContractAddress() == "KT1LCyXGWTv2VctSrFL74h8nMNXMcBRNk6oR" { + fmt.Println("internal results", internalResults.Source.ContractAddress()) + fmt.Println("bmc address", contractAddress.ContractAddress()) + if internalResults.Kind.String() == "event" && internalResults.Source.ContractAddress() == contractAddress.ContractAddress() { fmt.Println("Address matched") if internalResults.Tag == "Message" { message := internalResults.Payload.Args[0].Bytes @@ -330,6 +335,35 @@ func (c *Client) GetOperationByHash(ctx context.Context, clinet *rpc.Client, blo return operation, nil } +func (c *Client) GetConsensusKey(ctx context.Context, bakerConsensusKey tezos.Address) (tezos.Key, error) { + fmt.Println("baker consensus key", bakerConsensusKey.String()) + var exposedPublicKey tezos.Key + for i := 0; i < 5; i++ { + url := c.Cl.BaseURL.String() + "/chains/main/blocks/head/context/raw/json/contracts/index/" + bakerConsensusKey.String() + "/consensus_key/active" + + resp, err := http.Get(url) + if err != nil { + return tezos.Key{}, err + } + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return tezos.Key{}, err + } + //Convert the body to type string + sb := string(body) + + exposedPublicKey, err = tezos.ParseKey(sb[1 : len(sb)-2]) + if err != nil { + fmt.Println("continued to refetch again") + time.Sleep(2 * time.Second) + continue + } + break + } + return exposedPublicKey, nil +} + func (c *Client) HandleRelayMessage(ctx context.Context, callArgs contract.CallArguments, opts *rpc.CallOptions) (*rpc.Receipt, error) { fmt.Println("handling relay message") PrintU() @@ -371,7 +405,7 @@ func (c *Client) CustomCall(ctx context.Context, args []contract.CallArguments, return c.Cl.Send(ctx, op, opts) } -func NewClient(uri string, src tezos.Address, l log.Logger) (*Client, error) { +func NewClient(uri string, src tezos.Address, bmcManagement tezos.Address, l log.Logger) (*Client, error) { fmt.Println("uri is : " + uri) @@ -383,7 +417,7 @@ func NewClient(uri string, src tezos.Address, l log.Logger) (*Client, error) { return nil, err } - return &Client{Log: l, Cl: c, Contract: conn}, nil + return &Client{Log: l, Cl: c, Contract: conn, BmcManagement: bmcManagement}, nil } func PrettyEncode(data interface{}) error { @@ -408,7 +442,7 @@ func returnTxMetadata2(block *rpc.Block, contractAddress tezos.Address, blockHei switch operation.Kind() { case tezos.OpTypeTransaction: tx = operation.(*rpc.Transaction) - r, err := returnTxMetadata3(tx, contractAddress, uint64(blockHeight)) + r, err := returnTxMetadata3(tx, cl.BmcManagement, uint64(blockHeight)) if err != nil { return false, nil, err } diff --git a/cmd/iconbridge/chain/tezos/receiver.go b/cmd/iconbridge/chain/tezos/receiver.go index d9c6e497..5c750acd 100644 --- a/cmd/iconbridge/chain/tezos/receiver.go +++ b/cmd/iconbridge/chain/tezos/receiver.go @@ -4,13 +4,14 @@ import ( "context" "encoding/json" "fmt" - "github.com/icon-project/icon-bridge/cmd/iconbridge/chain" "math/big" "sort" "strconv" "sync" "time" + "github.com/icon-project/icon-bridge/cmd/iconbridge/chain" + // "github.com/ethereum/go-ethereum/common" "github.com/icon-project/icon-bridge/common/log" @@ -38,6 +39,8 @@ type receiver struct { client *Client } +var RelaySyncStatusLog bool + func (r *receiver) Subscribe(ctx context.Context, msgCh chan<- *chain.Message, opts chain.SubscribeOptions) (errCh <-chan error, err error) { fmt.Println("reached to subscribe") src := tezos.MustParseAddress(r.src.ContractAddress()) @@ -59,9 +62,9 @@ func (r *receiver) Subscribe(ctx context.Context, msgCh chan<- *chain.Message, o StartHeight: int64(opts.Height), Concurrnecy: r.opts.SyncConcurrency, } - if err := r.receiveLoop(ctx, bn, + if err := r.receiveLoop2(ctx, bn, func(blN *types.BlockNotification) error { - fmt.Println("has to reach in this callback ", blN.Height.Uint64()) + r.log.WithFields(log.Fields{"height": blN.Height}).Debug("block notification") if blN.Height.Uint64() != lastHeight { return fmt.Errorf( @@ -78,14 +81,13 @@ func (r *receiver) Subscribe(ctx context.Context, msgCh chan<- *chain.Message, o events = append(events, event) opts.Seq++ case event.Sequence > opts.Seq: - return fmt.Errorf("invalid event seq") - //TODO to be removed + r.log.Errorf("expected v.Height == %d, got %d", lastHeight+1, blN.Height.Uint64()) + return fmt.Errorf( + "block notification: expected=%d, got=%d", + lastHeight+1, blN.Height.Uint64()) } } receipt.Events = events - fmt.Println(receipt.Height) - fmt.Println("appending") - // vCP = append(vCP, &chain.Receipt{Events: receipt.Events}) } if len(receipts) > 0 { fmt.Println("reached to sending message") @@ -98,8 +100,6 @@ func (r *receiver) Subscribe(ctx context.Context, msgCh chan<- *chain.Message, o fmt.Println(err) _errCh <- err } - - fmt.Println("Printing from inside the receiver") }() return _errCh, nil @@ -147,8 +147,11 @@ func NewReceiver(src, dst chain.BTPAddress, urls []string, rawOpts json.RawMessa } srcAddr := tezos.MustParseAddress(src.ContractAddress()) + bmcManagement := tezos.MustParseAddress(receiver.opts.BMCManagment) + + fmt.Println("bmcManagement receiver", bmcManagement) - newClient, err = NewClient(urls[0], srcAddr, receiver.log) + newClient, err = NewClient(urls[0], srcAddr, bmcManagement, receiver.log) if err != nil { return nil, err @@ -161,25 +164,21 @@ func NewReceiver(src, dst chain.BTPAddress, urls []string, rawOpts json.RawMessa type ReceiverOptions struct { SyncConcurrency uint64 `json:"syncConcurrency"` Verifier *VerifierOptions `json:"verifier"` + BMCManagment string `json:"bmcManagement"` } func (r *receiver) NewVerifier(ctx context.Context, previousHeight int64) (vri IVerifier, err error) { - fmt.Println("reached to verifyer") - header, err := r.client.GetBlockHeaderByHeight(ctx, r.client.Cl, previousHeight) - block, err := r.client.GetBlockByHeight(ctx, r.client.Cl, previousHeight) - fmt.Println("reached to after block header ") if err != nil { fmt.Println(err) return nil, err } - fmt.Println("returned from here?") - fittness, err := strconv.ParseInt(string(header.Fitness[1].String()), 16, 64) + + fittness, err := strconv.ParseInt(string(block.Header.Fitness[1].String()), 16, 64) if err != nil { return nil, err } - fmt.Println("before chain id") chainIdHash, err := r.client.Cl.GetChainId(ctx) if err != nil { return nil, err @@ -191,13 +190,18 @@ func (r *receiver) NewVerifier(ctx context.Context, previousHeight int64) (vri I return nil, err } + fmt.Println("header hash", block.Header.Hash) + fmt.Println("blockHeaderhash", block.Header.Hash) + vr := &Verifier{ mu: sync.RWMutex{}, - next: header.Level + 1, - parentHash: header.Hash, + next: block.Header.Level + 1, + parentHash: block.Hash, parentFittness: fittness, chainID: id, - c: r.client.Cl, + cl: r.client, + validators: make(map[tezos.Address]bool), + validatorsPublicKey: make(map[tezos.Address]tezos.Key), } vr.updateValidatorsAndCycle(ctx, previousHeight, block.Metadata.LevelInfo.Cycle) @@ -205,380 +209,382 @@ func (r *receiver) NewVerifier(ctx context.Context, previousHeight int64) (vri I return vr, nil } -func (r *receiver) SyncVerifier(ctx context.Context, vr IVerifier, height int64, callback func([]*chain.Receipt) error) error { - if height == vr.Next() { - fmt.Println("returned from here") - return nil - } - - if vr.Next() > height { - return fmt.Errorf("Invalida target height: Verifier height (%d) > target height (%d)", vr.Next(), height) - } - - type res struct { - Height int64 - Header *rpc.BlockHeader - Block *rpc.Block - Votes int64 - } - - type req struct { - height int64 - err error - res *res - retry int64 - } - fmt.Println("reached before starting to log") - // r.log.WithFields(log.Fields{"height": vr.Next(), "target": height}).Info("syncVerifier: start") - - fmt.Println("reached in sync verifier") - var prevHeader *rpc.BlockHeader - var prevBlock *rpc.Block - - cursor := vr.Next() - - for cursor <= height { - fmt.Println("reached inside for") - fmt.Println(r.opts.SyncConcurrency) +// func (r *receiver) SyncVerifier(ctx context.Context, vr IVerifier, height int64, callback func([]*chain.Receipt) error) error { +// if height == vr.Next() { +// fmt.Println("returned from here") +// return nil +// } - rqch := make(chan *req, r.opts.SyncConcurrency) - fmt.Println(len(rqch)) - fmt.Println(cap(rqch)) - for i := cursor; len(rqch) < cap(rqch); i++ { - rqch <- &req{height: i, retry: 5} - } - sres := make([]*res, 0, len(rqch)) - fmt.Println("reached here after sres") - for q := range rqch { - switch { - case q.err != nil: - if q.retry > 0 { - q.retry-- - q.res, q.err = nil, nil - rqch <- q - continue - } - // r.log.WithFields(log.Fields{"height": q.height, "error": q.err.Error()}).Debug("syncVerifier: req error") - sres = append(sres, nil) - if len(sres) == cap(sres) { - close(rqch) - } - case q.res != nil: - fmt.Println("should reach here in the second loop ") - sres = append(sres, q.res) - fmt.Println(cap(sres)) - if len(sres) == cap(sres) { - fmt.Println("closes channel") - close(rqch) - } - default: - fmt.Println("has to reach in this default ") - go func(q *req) { - defer func() { - time.Sleep(500 * time.Millisecond) - rqch <- q - }() - if q.res == nil { - fmt.Println("should reach here in nil portion") - q.res = &res{} - } - q.res.Height = q.height - q.res.Header, q.err = r.client.GetBlockHeaderByHeight(ctx, r.client.Cl, q.height) - if q.err != nil { - q.err = errors.Wrapf(q.err, "syncVerifier: getBlockHeader: %v", q.err) - return - } - q.res.Block, q.err = r.client.GetBlockByHeight(ctx, r.client.Cl, q.height) - if q.err != nil { - q.err = errors.Wrapf(q.err, "syncVerifier: getBlock: %v", q.err) - return - } - }(q) - } +// if vr.Next() > height { +// return fmt.Errorf("Invalida target height: Verifier height (%d) > target height (%d)", vr.Next(), height) +// } - } - _sres, sres := sres, sres[:0] - for _, v := range _sres { - if v != nil { - fmt.Println("should reach in eliminating the null ", v.Height) - sres = append(sres, v) - } - } +// type res struct { +// Height int64 +// Header *rpc.BlockHeader +// Block *rpc.Block +// Votes int64 +// } - fmt.Printf("The lenght of sres is %d\n", len(sres)) - - if len(sres) > 0 { - sort.SliceStable(sres, func(i, j int) bool { - return sres[i].Height < sres[j].Height - }) - for i := range sres { - cursor++ - next := sres[i] - if prevHeader == nil { - prevHeader = next.Header - prevBlock = next.Block - continue - } - if vr.Next() >= height { - fmt.Println("did it just break") - break - } +// type req struct { +// height int64 +// err error +// res *res +// retry int64 +// } +// fmt.Println("reached before starting to log") +// // r.log.WithFields(log.Fields{"height": vr.Next(), "target": height}).Info("syncVerifier: start") - fmt.Println("has it reached to verification") - fmt.Println(next.Header.Level) +// fmt.Println("reached in sync verifier") +// var prevHeader *rpc.BlockHeader +// var prevBlock *rpc.Block - err := vr.Verify(ctx, prevHeader, prevBlock, next.Block.Metadata.BakerConsensusKey, r.client.Cl, next.Header) +// cursor := vr.Next() - if err != nil { - cursor = vr.Height() + 1 - prevHeader = nil - fmt.Println(cursor) - fmt.Println("when some verification is failed prompts it to get the data again from that point") - time.Sleep(15 * time.Second) - break - // return errors.Wrapf(err, "syncVerifier: Verify: %v", err) - } +// for cursor <= height { +// fmt.Println("reached inside for") +// fmt.Println(r.opts.SyncConcurrency) - fmt.Println("verified block now updating ") +// rqch := make(chan *req, r.opts.SyncConcurrency) +// fmt.Println(len(rqch)) +// fmt.Println(cap(rqch)) +// for i := cursor; len(rqch) < cap(rqch); i++ { +// rqch <- &req{height: i, retry: 5} +// } +// sres := make([]*res, 0, len(rqch)) +// fmt.Println("reached here after sres") +// for q := range rqch { +// switch { +// case q.err != nil: +// if q.retry > 0 { +// q.retry-- +// q.res, q.err = nil, nil +// rqch <- q +// continue +// } +// // r.log.WithFields(log.Fields{"height": q.height, "error": q.err.Error()}).Debug("syncVerifier: req error") +// sres = append(sres, nil) +// if len(sres) == cap(sres) { +// close(rqch) +// } +// case q.res != nil: +// fmt.Println("should reach here in the second loop ") +// sres = append(sres, q.res) +// fmt.Println(cap(sres)) +// if len(sres) == cap(sres) { +// fmt.Println("closes channel") +// close(rqch) +// } +// default: +// fmt.Println("has to reach in this default ") +// go func(q *req) { +// defer func() { +// time.Sleep(500 * time.Millisecond) +// rqch <- q +// }() +// if q.res == nil { +// fmt.Println("should reach here in nil portion") +// q.res = &res{} +// } +// q.res.Height = q.height +// q.res.Header, q.err = r.client.GetBlockHeaderByHeight(ctx, r.client.Cl, q.height) +// if q.err != nil { +// q.err = errors.Wrapf(q.err, "syncVerifier: getBlockHeader: %v", q.err) +// return +// } +// q.res.Block, q.err = r.client.GetBlockByHeight(ctx, r.client.Cl, q.height) +// if q.err != nil { +// q.err = errors.Wrapf(q.err, "syncVerifier: getBlock: %v", q.err) +// return +// } +// }(q) +// } - err = vr.Update(ctx, prevHeader, prevBlock) - if err != nil { - return errors.Wrapf(err, "syncVerifier: Update: %v", err) - } +// } +// _sres, sres := sres, sres[:0] +// for _, v := range _sres { +// if v != nil { +// fmt.Println("should reach in eliminating the null ", v.Height) +// sres = append(sres, v) +// } +// } - prevHeader = next.Header - prevBlock = next.Block - } +// fmt.Printf("The lenght of sres is %d\n", len(sres)) + +// if len(sres) > 0 { +// sort.SliceStable(sres, func(i, j int) bool { +// return sres[i].Height < sres[j].Height +// }) +// for i := range sres { +// cursor++ +// next := sres[i] +// if prevHeader == nil { +// prevHeader = next.Header +// prevBlock = next.Block +// continue +// } +// if vr.Next() >= height { +// fmt.Println("did it just break") +// break +// } + +// fmt.Println("has it reached to verification") +// fmt.Println(next.Header.Level) + +// err := vr.Verify(ctx, prevHeader, prevBlock, prevBlock.Metadata.Baker, r.client.Cl, next.Header) + +// if err != nil { +// cursor = vr.Height() + 1 +// prevHeader = nil +// fmt.Println(cursor) +// fmt.Println("when some verification is failed prompts it to get the data again from that point") +// time.Sleep(15 * time.Second) +// break +// // return errors.Wrapf(err, "syncVerifier: Verify: %v", err) +// } + +// fmt.Println("verified block now updating ") + +// err = vr.Update(ctx, prevHeader, prevBlock) +// if err != nil { +// return errors.Wrapf(err, "syncVerifier: Update: %v", err) +// } + +// prevHeader = next.Header +// prevBlock = next.Block +// } - } - // r.log.WithFields(log.Fields{"height": vr.Next(), "target": height}).Debug("syncVerifier: syncing") - } - // r.log.WithFields(log.Fields{"height": vr.Next()}).Info("syncVerifier: complete") +// } +// // r.log.WithFields(log.Fields{"height": vr.Next(), "target": height}).Debug("syncVerifier: syncing") +// } +// // r.log.WithFields(log.Fields{"height": vr.Next()}).Info("syncVerifier: complete") - fmt.Println("sync complete") - PrintSync() - return nil -} +// fmt.Println("sync complete") +// PrintSync() +// return nil +// } type BnOptions struct { StartHeight int64 Concurrnecy uint64 } -func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback func(v *types.BlockNotification) error) (err error) { - fmt.Println("reached to receivelopp") - if opts == nil { - return errors.New("receiveLoop: invalid options: ") - } - - var vr IVerifier - - if r.opts.Verifier != nil { - vr, err = r.NewVerifier(ctx, r.opts.Verifier.BlockHeight) - if err != nil { - return err - } - - fmt.Println("The start height is: ", opts.StartHeight) - err = r.SyncVerifier(ctx, vr, opts.StartHeight + 1, func(r []*chain.Receipt) error { return nil }) - if err != nil { - return err - } - } - bnch := make(chan *types.BlockNotification, r.opts.SyncConcurrency) - heightTicker := time.NewTicker(BlockInterval) - defer heightTicker.Stop() - - heightPoller := time.NewTicker(BlockHeightPollInterval) - defer heightPoller.Stop() - - latestHeight := func() int64 { - block, err := r.client.GetLastBlock(ctx, r.client.Cl) - if err != nil { - return 0 - } - return block.GetLevel() - } - next, latest := opts.StartHeight + 1, latestHeight() - - var lbn *types.BlockNotification - - for { - select { - case <-ctx.Done(): - return nil - case <-heightTicker.C: - latest++ - case <-heightPoller.C: - if height := latestHeight(); height > 0 { - latest = height - // r.log.WithFields(log.Fields{"latest": latest, "next": next}).Debug("poll height") - } - case bn := <-bnch: - fmt.Println("has it reached in the block notification channel") - // process all notifications - for ; bn != nil; next++ { - if lbn != nil { - if bn.Height.Cmp(lbn.Height) == 0 { - if bn.Header.Predecessor != lbn.Header.Predecessor { - // r.log.WithFields(log.Fields{"lbnParentHash": lbn.Header.Predecessor, "bnParentHash": bn.Header.Predecessor}).Error("verification failed on retry ") - break - } - } else { - if vr != nil { - fmt.Println("vr is not nil for block heiht ", lbn.Header.Level) - // header := bn.Header - if err := vr.Verify(ctx, lbn.Header, lbn.Block, bn.Block.Metadata.BakerConsensusKey, r.client.Cl, bn.Header); err != nil { // change accordingly - // r.log.WithFields(log.Fields{ - // "height": lbn.Height, - // "lbnHash": lbn.Hash, - // "nextHeight": next, - // "bnHash": bn.Hash}).Error("verification failed. refetching block ", err) - fmt.Println(err) - fmt.Println("error in verifying ") - time.Sleep(5 * time.Second) - next-- - break - } - if err := vr.Update(ctx, lbn.Header, lbn.Block); err != nil { - return errors.Wrapf(err, "receiveLoop: vr.Update: %v", err) - } - } - if err := callback(lbn); err != nil { - return errors.Wrapf(err, "receiveLoop: callback: %v", err) - } - } - } - if lbn, bn = bn, nil; len(bnch) > 0 { - bn = <-bnch - } - } - // remove unprocessed notifications - for len(bnch) > 0 { - <-bnch - //r.log.WithFields(log.Fields{"lenBnch": len(bnch), "height": t.Height}).Info("remove unprocessed block noitification") - } - - default: - if next >= latest { - time.Sleep(10 * time.Second) - continue - } - - type bnq struct { - h int64 - v *types.BlockNotification - err error - retry int - } - - qch := make(chan *bnq, cap(bnch)) - - for i := next; i < latest && len(qch) < cap(qch); i++ { - qch <- &bnq{i, nil, nil, RPCCallRetry} - } - - if len(qch) == 0 { - // r.log.Error("Fatal: Zero length of query channel. Avoiding deadlock") - continue - } - bns := make([]*types.BlockNotification, 0, len(qch)) - for q := range qch { - switch { - case q.err != nil: - if q.retry > 0 { - q.retry-- - q.v, q.err = nil, nil - qch <- q - continue - } - case q.v != nil: - bns = append(bns, q.v) - if len(bns) == cap(bns) { - close(qch) - } - default: - // fmt.Println("reached in default of receive loop") - go func(q *bnq) { - defer func() { - time.Sleep(500 * time.Millisecond) - qch <- q - }() - - if q.v == nil { - q.v = &types.BlockNotification{} - } - q.v.Height = (&big.Int{}).SetInt64(q.h) - - if q.v.Header == nil { - header, err := r.client.GetBlockHeaderByHeight(ctx, r.client.Cl, q.v.Height.Int64()) - if err != nil { - q.err = errors.Wrapf(err, "GetHeaderByHeight: %v", err) - return - } - q.v.Header = header // change accordingly - q.v.Hash = header.Hash // change accordingly - } - - block, err := r.client.GetBlockByHeight(ctx, r.client.Cl, q.v.Height.Int64()) - if err != nil { - q.err = errors.Wrapf(err, "GetBlockByHeight: %v", err) - return - } - q.v.Block = block - fmt.Println("Getting for header: ", block.Header.Level) - if q.v.HasBTPMessage == nil && q.v.Height.Int64() >= opts.StartHeight { - // fmt.Println("height: ", q.v.Height.Int64()) - - if err != nil { - return - } - q.v.Proposer = block.Metadata.Proposer +// func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback func(v *types.BlockNotification) error) (err error) { +// fmt.Println("reached to receivelopp") +// if opts == nil { +// return errors.New("receiveLoop: invalid options: ") +// } - hasBTPMessage, receipt, err := returnTxMetadata2(block, r.client.Contract.Address(), q.v.Height.Int64(), r.client) - fmt.Println("has btp message", hasBTPMessage, q.v.Height.Uint64()) +// var vr IVerifier - if err != nil { - q.err = errors.Wrapf(err, "hasBTPMessage: %v", err) - return - } - q.v.HasBTPMessage = &hasBTPMessage +// if r.opts.Verifier != nil { +// vr, err = r.NewVerifier(ctx, r.opts.Verifier.BlockHeight) +// if err != nil { +// return err +// } - if receipt != nil { - fmt.Println("should reach here for block", q.v.Height.Uint64()) - q.v.Receipts = receipt - } - } - if !*q.v.HasBTPMessage { - return - } - }(q) - } - } - // filtering nil - _bns_, bns := bns, bns[:0] +// // fmt.Println("The start height is: ", opts.StartHeight) +// // err = r.SyncVerifier(ctx, vr, opts.StartHeight+1, func(r []*chain.Receipt) error { return nil }) +// // if err != nil { +// // return err +// // } +// } +// bnch := make(chan *types.BlockNotification, r.opts.SyncConcurrency) +// heightTicker := time.NewTicker(BlockInterval) +// defer heightTicker.Stop() - for _, v := range _bns_ { - if v != nil { - bns = append(bns, v) - } - } +// heightPoller := time.NewTicker(BlockHeightPollInterval) +// defer heightPoller.Stop() - if len(bns) > 0 { - sort.SliceStable(bns, func(i, j int) bool { - return bns[i].Height.Int64() < bns[j].Height.Int64() - }) - for i, v := range bns { - if v.Height.Int64() == next+int64(i) { - bnch <- v - } - } - } +// latestHeight := func() int64 { +// block, err := r.client.GetLastBlock(ctx, r.client.Cl) +// if err != nil { +// return 0 +// } +// return block.GetLevel() +// } +// next, latest := opts.StartHeight+1, latestHeight() + +// var lbn *types.BlockNotification + +// for { +// select { +// case <-ctx.Done(): +// return nil +// case <-heightTicker.C: +// latest++ +// case <-heightPoller.C: +// if height := latestHeight(); height > 0 { +// latest = height +// r.log.WithFields(log.Fields{"latest": latest, "next": next}).Debug("poll height") +// } +// case bn := <-bnch: +// fmt.Println("has it reached in the block notification channel") +// // process all notifications +// for ; bn != nil; next++ { +// if lbn != nil { +// if bn.Height.Cmp(lbn.Height) == 0 { +// if bn.Header.Predecessor != lbn.Header.Predecessor { +// r.log.WithFields(log.Fields{"lbnParentHash": lbn.Header.Predecessor, "bnParentHash": bn.Header.Predecessor}).Error("verification failed on retry ") +// break +// } +// } else { +// if vr != nil { +// if err := vr.Verify(ctx, lbn); err != nil { // change accordingly +// r.log.WithFields(log.Fields{ +// "height": lbn.Height, +// "lbnHash": lbn.Hash, +// "nextHeight": next, +// "bnHash": bn.Hash}).Error("verification failed. refetching block ", err) +// fmt.Println(err) +// fmt.Println("error in verifying ") +// time.Sleep(5 * time.Second) +// next-- +// break +// } +// if err := vr.Update(ctx, lbn); err != nil { +// return errors.Wrapf(err, "receiveLoop: vr.Update: %v", err) +// } +// } +// if err := callback(lbn); err != nil { +// return errors.Wrapf(err, "receiveLoop: callback: %v", err) +// } +// } +// } +// if lbn, bn = bn, nil; len(bnch) > 0 { +// bn = <-bnch +// } +// } +// // remove unprocessed notifications +// for len(bnch) > 0 { +// <-bnch +// // r.log.WithFields(log.Fields{"lenBnch": len(bnch), "height": t.Height}).Info("remove unprocessed block noitification") +// } + +// default: +// if next >= latest { +// time.Sleep(10 * time.Second) +// continue +// } + +// type bnq struct { +// h int64 +// v *types.BlockNotification +// err error +// retry int +// } + +// qch := make(chan *bnq, cap(bnch)) + +// for i := next; i < latest && len(qch) < cap(qch); i++ { +// qch <- &bnq{i, nil, nil, RPCCallRetry} +// } + +// if len(qch) == 0 { +// // r.log.Error("Fatal: Zero length of query channel. Avoiding deadlock") +// continue +// } +// bns := make([]*types.BlockNotification, 0, len(qch)) +// for q := range qch { +// switch { +// case q.err != nil: +// if q.retry > 0 { +// q.retry-- +// q.v, q.err = nil, nil +// qch <- q +// continue +// } +// case q.v != nil: +// bns = append(bns, q.v) +// if len(bns) == cap(bns) { +// close(qch) +// } +// default: +// // fmt.Println("reached in default of receive loop") +// go func(q *bnq) { +// defer func() { +// time.Sleep(500 * time.Millisecond) +// qch <- q +// }() + +// if q.v == nil { +// q.v = &types.BlockNotification{} +// } +// q.v.Height = (&big.Int{}).SetInt64(q.h) + +// if q.v.Header == nil { +// header, err := r.client.GetBlockHeaderByHeight(ctx, r.client.Cl, q.v.Height.Int64()) +// if err != nil { +// q.err = errors.Wrapf(err, "GetHeaderByHeight: %v", err) +// return +// } +// q.v.Header = header // change accordingly +// q.v.Hash = header.Hash // change accordingly +// } + +// block, err := r.client.GetBlockByHeight(ctx, r.client.Cl, q.v.Height.Int64()) +// if err != nil { +// q.err = errors.Wrapf(err, "GetBlockByHeight: %v", err) +// return +// } + +// consensusKey, err := r.client.GetConsensusKey(ctx, block.Metadata.Baker) +// if err != nil { +// q.err = errors.Wrapf(err, "GetConsensusKey: %v", err) +// return +// } +// q.v.Block = block +// q.v.BakerConsensusKey = consensusKey +// if q.v.HasBTPMessage == nil && q.v.Height.Int64() >= opts.StartHeight { +// if err != nil { +// return +// } +// q.v.Proposer = block.Metadata.Baker + +// hasBTPMessage, receipt, err := returnTxMetadata2(block, r.client.Contract.Address(), q.v.Height.Int64(), r.client) +// fmt.Println("has btp message", hasBTPMessage, q.v.Height.Uint64()) + +// if err != nil { +// q.err = errors.Wrapf(err, "hasBTPMessage: %v", err) +// return +// } +// q.v.HasBTPMessage = &hasBTPMessage + +// if receipt != nil { +// fmt.Println("should reach here for block", q.v.Height.Uint64()) +// q.v.Receipts = receipt +// } +// } +// if !*q.v.HasBTPMessage { +// return +// } +// }(q) +// } +// } +// // filtering nil +// _bns_, bns := bns, bns[:0] + +// for _, v := range _bns_ { +// if v != nil { +// bns = append(bns, v) +// } +// } + +// if len(bns) > 0 { +// sort.SliceStable(bns, func(i, j int) bool { +// return bns[i].Height.Int64() < bns[j].Height.Int64() +// }) +// for i, v := range bns { +// if v.Height.Int64() == next+int64(i) { +// bnch <- v +// } +// } +// } - } +// } - } -} +// } +// } func PrintSync() { for i := 0; i < 100; i++ { @@ -586,14 +592,22 @@ func PrintSync() { } } +func PrintError() { + for i := 0; i < 20; i++ { + fmt.Println("signature unverified") + } +} + // merging the syncing and receiving function func (r *receiver) receiveLoop2(ctx context.Context, opts *BnOptions, callback func(v *types.BlockNotification) error) (err error) { - fmt.Println("reached to receivelopp") + fmt.Println("reached to receivelopp2") if opts == nil { return errors.New("receiveLoop: invalid options: ") } + RelaySyncStatusLog = false + var vr IVerifier if r.opts.Verifier != nil { @@ -601,12 +615,6 @@ func (r *receiver) receiveLoop2(ctx context.Context, opts *BnOptions, callback f if err != nil { return err } - - // fmt.Println("The start height is: ", opts.StartHeight) - // err = r.SyncVerifier(ctx, vr, opts.StartHeight + 1, func(r []*chain.Receipt) error { return nil }) - // if err != nil { - // return err - // } } bnch := make(chan *types.BlockNotification, r.opts.SyncConcurrency) heightTicker := time.NewTicker(BlockInterval) @@ -622,7 +630,7 @@ func (r *receiver) receiveLoop2(ctx context.Context, opts *BnOptions, callback f } return block.GetLevel() } - next, latest := opts.StartHeight+1, latestHeight() + next, latest := r.opts.Verifier.BlockHeight+1, latestHeight() var lbn *types.BlockNotification @@ -635,7 +643,7 @@ func (r *receiver) receiveLoop2(ctx context.Context, opts *BnOptions, callback f case <-heightPoller.C: if height := latestHeight(); height > 0 { latest = height - // r.log.WithFields(log.Fields{"latest": latest, "next": next}).Debug("poll height") + r.log.WithFields(log.Fields{"latest": latest, "next": next}).Debug("poll height") } case bn := <-bnch: // process all notifications @@ -648,7 +656,7 @@ func (r *receiver) receiveLoop2(ctx context.Context, opts *BnOptions, callback f } } else { if vr != nil { - if err := vr.Verify(ctx, lbn.Header, lbn.Block, bn.Block.Metadata.BakerConsensusKey, r.client.Cl, bn.Header); err != nil { // change accordingly + if err := vr.Verify(ctx, lbn); err != nil { // change accordingly r.log.WithFields(log.Fields{ "height": lbn.Height, "lbnHash": lbn.Hash, @@ -660,14 +668,21 @@ func (r *receiver) receiveLoop2(ctx context.Context, opts *BnOptions, callback f next-- break } - if err := vr.Update(ctx, lbn.Header, lbn.Block); err != nil { + if err := vr.Update(ctx, lbn); err != nil { return errors.Wrapf(err, "receiveLoop: vr.Update: %v", err) } } - if lbn.Header.Level >= opts.StartHeight { - if err := callback(lbn); err != nil { + if lbn.Header.Level > opts.StartHeight { + if !RelaySyncStatusLog { + r.log.WithFields(log.Fields{"height": vr.Next()}).Info("syncVerifier: complete") + RelaySyncStatusLog = true + } + + if err := callback(vr.LastVerifiedBn()); err != nil { return errors.Wrapf(err, "receiveLoop: callback: %v", err) } + } else { + r.log.WithFields(log.Fields{"height": vr.Next(), "target": opts.StartHeight}).Debug("syncVerifier: syncing") } } } @@ -730,25 +745,21 @@ func (r *receiver) receiveLoop2(ctx context.Context, opts *BnOptions, callback f q.v = &types.BlockNotification{} } q.v.Height = (&big.Int{}).SetInt64(q.h) + block := &rpc.Block{} if q.v.Header == nil { - header, err := r.client.GetBlockHeaderByHeight(ctx, r.client.Cl, q.v.Height.Int64()) + block, err := r.client.GetBlockByHeight(ctx, r.client.Cl, q.v.Height.Int64()) if err != nil { q.err = errors.Wrapf(err, "GetHeaderByHeight: %v", err) return } - q.v.Header = header // change accordingly - q.v.Hash = header.Hash // change accordingly + q.v.Header = &block.Header // change accordingly + q.v.Hash = block.Hash // change accordingly + q.v.Block = block } - block, err := r.client.GetBlockByHeight(ctx, r.client.Cl, q.v.Height.Int64()) - if err != nil { - q.err = errors.Wrapf(err, "GetBlockByHeight: %v", err) - return - } - q.v.Block = block - if q.v.HasBTPMessage == nil { + if q.v.HasBTPMessage == nil && q.v.Height.Int64() > opts.StartHeight { if err != nil { return } @@ -766,7 +777,10 @@ func (r *receiver) receiveLoop2(ctx context.Context, opts *BnOptions, callback f fmt.Println("should reach here for block", q.v.Height.Uint64()) q.v.Receipts = receipt } + } else { + return } + if !*q.v.HasBTPMessage { return } diff --git a/cmd/iconbridge/chain/tezos/sender.go b/cmd/iconbridge/chain/tezos/sender.go index 9dcc0a5b..00d54b16 100644 --- a/cmd/iconbridge/chain/tezos/sender.go +++ b/cmd/iconbridge/chain/tezos/sender.go @@ -35,6 +35,7 @@ type senderOptions struct { StepLimit uint64 `json:"step_limit"` TxDataSizeLimit uint64 `json:"tx_data_size_limit"` BalanceThreshold uint64 `json:"balance_threshold"` + BMCManagment string `json:"bmcManagement"` } type sender struct { @@ -64,12 +65,19 @@ func NewSender( dst: dstAddr, w: w, } + + json.Unmarshal(rawOpts, &s.opts) + PrintPlus() fmt.Println(w.Address()) if len(urls) == 0 { return nil, fmt.Errorf("Empty url") } - s.cls, err = NewClient(urls[0], dstAddr, l) + + bmcManaement := tezos.MustParseAddress(s.opts.BMCManagment) + fmt.Println("bmc Management sender", bmcManaement) + + s.cls, err = NewClient(urls[0], dstAddr, bmcManaement, l) if err != nil { return nil, err } diff --git a/cmd/iconbridge/chain/tezos/types/types.go b/cmd/iconbridge/chain/tezos/types/types.go index 4c324765..a1f87ef4 100644 --- a/cmd/iconbridge/chain/tezos/types/types.go +++ b/cmd/iconbridge/chain/tezos/types/types.go @@ -17,5 +17,6 @@ type BlockNotification struct { HasBTPMessage *bool Proposer tezos.Address Block *rpc.Block + BakerConsensusKey tezos.Key } diff --git a/cmd/iconbridge/chain/tezos/verifier.go b/cmd/iconbridge/chain/tezos/verifier.go index de07f1f2..8324ae5f 100644 --- a/cmd/iconbridge/chain/tezos/verifier.go +++ b/cmd/iconbridge/chain/tezos/verifier.go @@ -1,10 +1,7 @@ package tezos import ( - "errors" "fmt" - "io/ioutil" - "net/http" "sync" "context" @@ -13,27 +10,35 @@ import ( "blockwatch.cc/tzgo/codec" "blockwatch.cc/tzgo/rpc" "blockwatch.cc/tzgo/tezos" + "github.com/icon-project/icon-bridge/cmd/iconbridge/chain/tezos/types" ) type IVerifier interface { Next() int64 - Verify(ctx context.Context, header *rpc.BlockHeader, block *rpc.Block, proposer tezos.Address, c *rpc.Client, nextHeader *rpc.BlockHeader) error - Update(ctx context.Context, header *rpc.BlockHeader, block *rpc.Block) error + Verify(ctx context.Context, lbn *types.BlockNotification) error + Update(ctx context.Context, lbn *types.BlockNotification) error ParentHash() tezos.BlockHash IsValidator(proposer tezos.Address, height int64) bool Height() int64 + LastVerifiedBn() *types.BlockNotification } -type Verifier struct{ - chainID uint32 - mu sync.RWMutex - validators map[tezos.Address]bool - next int64 - parentHash tezos.BlockHash - parentFittness int64 - height int64 - cycle int64 - c *rpc.Client +const ( + threshold = 4667 +) + +type Verifier struct { + chainID uint32 + mu sync.RWMutex + validators map[tezos.Address]bool + validatorsPublicKey map[tezos.Address]tezos.Key + next int64 + parentHash tezos.BlockHash + parentFittness int64 + height int64 + cycle int64 + lastVerifiedBn *types.BlockNotification + cl *Client } func (vr *Verifier) Next() int64 { @@ -42,44 +47,45 @@ func (vr *Verifier) Next() int64 { return vr.next } -func (vr *Verifier) Verify(ctx context.Context, header *rpc.BlockHeader, block *rpc.Block, proposer tezos.Address, c *rpc.Client, nextHeader *rpc.BlockHeader) error { +func (vr *Verifier) Verify(ctx context.Context, lbn *types.BlockNotification) error { vr.mu.RLock() defer vr.mu.RUnlock() - blockFittness := header.Fitness + blockFittness := lbn.Header.Fitness currentFittness, err := strconv.ParseInt(string(blockFittness[1].String()), 16, 64) if err != nil { return err } if currentFittness < vr.parentFittness { - return fmt.Errorf("Invalid block fittness", currentFittness) + return fmt.Errorf("invalid block fittness %d", currentFittness) } - previousHashInBlock := header.Predecessor + previousHashInBlock := lbn.Block.Header.Predecessor if previousHashInBlock.String() != vr.parentHash.String() { - return fmt.Errorf("Invalid block hash", header.Level) + return fmt.Errorf("invalid block hash %d", lbn.Header.Level) } - isValidSignature, err := vr.VerifySignature(ctx, proposer, header.Signature, header.Level, header, c) + isValidSignature, _ := vr.VerifySignature(ctx, lbn) if !isValidSignature { - return fmt.Errorf("Invalid block hash. Signature mismatch") + return fmt.Errorf("invalid block signature. signature mismatch") } - // err = vr.verifyEndorsement(block.Operations, vr.c, block.GetLevel()) - - // if err != nil { - // return err - // } + err = vr.verifyEndorsement(lbn.Block, lbn.Header.ChainId) + if err != nil { + return fmt.Errorf("invlid endorsement") + } return nil } -func (vr *Verifier) Update(ctx context.Context, header *rpc.BlockHeader, block *rpc.Block) error { +func (vr *Verifier) Update(ctx context.Context, lbn *types.BlockNotification) error { vr.mu.Lock() defer vr.mu.Unlock() - fmt.Println("updating for block ????", header.Level) + + header := lbn.Header + block := lbn.Block blockFittness := header.Fitness currentFittness, err := strconv.ParseInt(string(blockFittness[1].String()), 16, 64) @@ -88,16 +94,15 @@ func (vr *Verifier) Update(ctx context.Context, header *rpc.BlockHeader, block * } vr.parentFittness = currentFittness - - vr.parentHash = header.Hash + vr.parentHash = block.Hash vr.height = header.Level vr.next = header.Level + 1 if vr.cycle != block.Metadata.LevelInfo.Cycle { - fmt.Println("reached in updating validators and cycle") vr.updateValidatorsAndCycle(ctx, block.Header.Level, block.Metadata.LevelInfo.Cycle) } + vr.lastVerifiedBn = lbn return nil } @@ -107,6 +112,12 @@ func (vr *Verifier) ParentHash() tezos.BlockHash { return vr.parentHash } +func (vr *Verifier) LastVerifiedBn() *types.BlockNotification { + vr.mu.RLock() + defer vr.mu.RUnlock() + return vr.lastVerifiedBn +} + func (vr *Verifier) Height() int64 { vr.mu.RLock() defer vr.mu.RUnlock() @@ -119,14 +130,8 @@ func (vr *Verifier) IsValidator(proposer tezos.Address, height int64) bool { return true } -func (vr *Verifier) VerifySignature(ctx context.Context, proposer tezos.Address, signature tezos.Signature, blockLevel int64, header *rpc.BlockHeader, c *rpc.Client) (bool, error) { - exposedPublicKey, err := vr.GetConsensusKey(ctx, c, proposer) - - if err != nil { - return false, err - } - - // c.ListBakingRights() +func (vr *Verifier) VerifySignature(ctx context.Context, lbn *types.BlockNotification) (bool, error) { + header := lbn.Block.Header blockHeader := codec.BlockHeader{ Level: int32(header.Level), @@ -141,51 +146,27 @@ func (vr *Verifier) VerifySignature(ctx context.Context, proposer tezos.Address, PayloadRound: header.PayloadRound, ProofOfWorkNonce: header.ProofOfWorkNonce, LbToggleVote: header.LbVote(), - // SeedNonceHash: block.Metadata.NonceHash, - ChainId: &header.ChainId, + SeedNonceHash: lbn.Block.Metadata.NonceHash, + ChainId: &lbn.Block.ChainId, } digestedHash := blockHeader.Digest() - err = exposedPublicKey.Verify(digestedHash[:], header.Signature) + err := vr.validatorsPublicKey[lbn.Block.Metadata.Baker].Verify(digestedHash[:], header.Signature) if err != nil { - fmt.Println(err) - return false, err + panic("signature failed") + // return false, err } return true, nil } -func (vr *Verifier) GetConsensusKey(ctx context.Context, c *rpc.Client, bakerConsensusKey tezos.Address) (tezos.Key, error){ - url := c.BaseURL.String() + "/chains/main/blocks/head/context/raw/json/contracts/index/" + bakerConsensusKey.String() + "/consensus_key/active" - - fmt.Println(c.BaseURL) - - resp, err := http.Get(url) - fmt.Println(resp.Body) - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return tezos.Key{}, err - } - //Convert the body to type string - sb := string(body) - - exposedPublicKey := tezos.MustParseKey(sb) - return exposedPublicKey, nil -} - func (vr *Verifier) updateValidatorsAndCycle(ctx context.Context, blockHeight int64, cycle int64) error { - - if true { - return nil - } - - fmt.Println("reached update validators") - validatorsList, err := vr.c.ListEndorsingRights(ctx, rpc.BlockLevel(blockHeight)) + PrintSync() + validatorsList, err := vr.cl.Cl.ListEndorsingRights(ctx, rpc.BlockLevel(blockHeight)) + var validatorsPublicKey tezos.Key if err != nil { - fmt.Println("error here?", err) return err } // remove all validators @@ -196,41 +177,61 @@ func (vr *Verifier) updateValidatorsAndCycle(ctx context.Context, blockHeight in // add new validators for _, validator := range validatorsList { vr.validators[validator.Delegate] = true + validatorsPublicKey, err = vr.cl.GetConsensusKey(ctx, validator.Delegate) + if err != nil { + return err + } + vr.validatorsPublicKey[validator.Delegate] = validatorsPublicKey } vr.cycle = cycle - fmt.Println("reached to updating cycle") return nil } -func (vr *Verifier) verifyEndorsement(op [][]*rpc.Operation, c *rpc.Client, blockHeight int64) error { +func (vr *Verifier) verifyEndorsement(block *rpc.Block, chainID tezos.ChainIdHash) error { endorsementPower := 0 - - threshold := 7000 * float32(2) / float32(3) endorsers := make(map[tezos.Address]bool) + op := block.Operations for i := 0; i < len(op); i++ { for j := 0; j < len(op[i]); j++ { for _, operation := range op[i][j].Contents { + signature := op[i][j].Signature + branch := op[i][j].Branch switch operation.Kind() { case tezos.OpTypeEndorsement: tx := operation.(*rpc.Endorsement) + if _, isDelegate := vr.validators[tx.Metadata.Delegate]; isDelegate { + endorsement := codec.TenderbakeEndorsement{ + Slot: int16(tx.Slot), + Level: int32(tx.Level), + Round: int32(tx.Round), + BlockPayloadHash: tx.PayloadHash, + } + digested := codec.NewOp().WithContentsFront(&endorsement).WithChainId(block.ChainId).WithBranch(branch).Digest() + + managerKey := vr.validatorsPublicKey[tx.Metadata.Delegate] + + err := managerKey.Verify(digested[:], signature) + + if err != nil { + panic("signature unverified") + // return err + } + if _, ok := endorsers[tx.Metadata.Delegate]; !ok { endorsers[tx.Metadata.Delegate] = true endorsementPower += tx.Metadata.EndorsementPower } - } else { - fmt.Println(vr.validators[tx.Metadata.Delegate]) } } } } } - fmt.Println(len(endorsers)) - - if endorsementPower > int(threshold) && len(endorsers)*100/len(vr.validators) > 66 { + if endorsementPower > int(threshold) { // && len(endorsers)*100/len(vr.validators) >= 66 { return nil } - return errors.New("endorsement verification failed") + panic("threshold didnot meet") + // return errors.New("endorsement verification failed") } diff --git a/cmd/iconbridge/example.config.json b/cmd/iconbridge/example.config.json index 863c394b..558aeb67 100644 --- a/cmd/iconbridge/example.config.json +++ b/cmd/iconbridge/example.config.json @@ -17,20 +17,21 @@ { "name": "t2i", "src": { - "address": "btp://NetXnHfVqm9iesp.tezos/KT1TjAbAKfNeHyUViBHqgbeikUh26cWW7r6o", + "address": "btp://NetXnHfVqm9iesp.tezos/KT1M8ZMiYHJRFRsRLTsTLvVjQp9JXUy9FMDU", "endpoint": [ - "https://rpc.ghost.tzstats.com/" + "http://localhost:8732" ], "options": { "verifier": { - "blockHeight": 3033078 + "blockHeight": 3162000 }, - "syncConcurrency": 100 + "syncConcurrency": 100, + "bmcManagement": "KT1NEy9DbjpCZW6u59iHiu6iMa2jvCizmtU2" }, - "offset": 3033078 + "offset": 3162000 }, "dst": { - "address": "btp://0x7.icon/cxa0d7311d391126a148cda2ac48f9cbb932195d7f", + "address": "btp://0x7.icon/cxa2905b9177941c92841a80e5efe1ca6f49dcc90e", "endpoint": [ "https://berlin.net.solidwallet.io/api/v3" ], @@ -65,28 +66,29 @@ { "name": "i2t", "src": { - "address": "btp://0x7.icon/cxa0d7311d391126a148cda2ac48f9cbb932195d7f", + "address": "btp://0x7.icon/cxa2905b9177941c92841a80e5efe1ca6f49dcc90e", "endpoint": [ "https://berlin.net.solidwallet.io/api/v3/icon_dex" ], "options": { "verifier": { - "blockHeight": 9925882, + "blockHeight": 10137924, "validatorsHash": "0x04b56f3fc8d396cc7eb8124da8a554800b8758c9e2fff0802aa9682948e65447" }, "syncConcurrency": 100 }, - "offset": 9925882 + "offset": 10137924 }, "dst": { - "address": "btp://NetXnHfVqm9iesp.tezos/KT1TjAbAKfNeHyUViBHqgbeikUh26cWW7r6o", + "address": "btp://NetXnHfVqm9iesp.tezos/KT1M8ZMiYHJRFRsRLTsTLvVjQp9JXUy9FMDU", "endpoint": [ - "https://rpc.ghost.tzstats.com/" + "http://localhost:8732" ], "options": { "gas_limit": 1040000, "boost_gas_price": 1.5, - "tx_data_size_limit": 65536 + "tx_data_size_limit": 65536, + "bmcManagement": "KT1NEy9DbjpCZW6u59iHiu6iMa2jvCizmtU2" }, "key_store": { "address": "tz1ZPVxKiybvbV1GvELRJJpyE1xj1UpNpXMv", diff --git a/cmd/iconbridge/relay/relay.go b/cmd/iconbridge/relay/relay.go index aac86adc..8ac35bd3 100644 --- a/cmd/iconbridge/relay/relay.go +++ b/cmd/iconbridge/relay/relay.go @@ -78,18 +78,13 @@ func (r *relay) Start(ctx context.Context) error { } filterSrcMsg := func(rxHeight, rxSeq uint64) (missingRxSeq uint64) { - fmt.Println("reached to srcMsg. receipts") receipts := srcMsg.Receipts[:0] for _, receipt := range srcMsg.Receipts { - fmt.Println("receipt.height", receipt.Height) - fmt.Println("rx_height", rxHeight) if receipt.Height < rxHeight { continue } events := receipt.Events[:0] for _, event := range receipt.Events { - fmt.Println("event.seq: ", event.Sequence) - fmt.Println("rx_seq:", rxSeq) if event.Sequence > rxSeq { rxSeq++ if event.Sequence != rxSeq { @@ -104,7 +99,6 @@ func (r *relay) Start(ctx context.Context) error { } } srcMsg.Receipts = receipts - fmt.Println(len(srcMsg.Receipts)) return 0 } @@ -156,7 +150,6 @@ func (r *relay) Start(ctx context.Context) error { for _, receipt := range msg.Receipts { if len(receipt.Events) > 0 { if seqBegin == 0 { - fmt.Println(receipt.Events[0], receipt.Height, receipt.Index) seqBegin = receipt.Events[0].Sequence } seqEnd = receipt.Events[len(receipt.Events)-1].Sequence @@ -164,55 +157,36 @@ func (r *relay) Start(ctx context.Context) error { } } msg.Receipts = receipts - fmt.Println("length of msg.Receipts is ", len(msg.Receipts)) if len(msg.Receipts) > 0 { r.log.WithFields(log.Fields{ "seq": []uint64{seqBegin, seqEnd}}).Debug("srcMsg added") srcMsg.Receipts = append(srcMsg.Receipts, msg.Receipts...) - fmt.Println(len(srcMsg.Receipts)) - fmt.Println(srcMsg.Receipts[0].Height) if len(srcMsg.Receipts) > relayTriggerReceiptsCount { relaySignal() } } case <-relayCh: - - fmt.Println("reached in status") - fmt.Println(r.cfg.Name) - link, err = r.dst.Status(ctx) - fmt.Println("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx") - fmt.Println(link) if err != nil { r.log.WithFields(log.Fields{"error": err}).Debug("dst.Status: failed") if errors.Is(err, context.Canceled) { r.log.WithFields(log.Fields{"error": err}).Error("dst.Status: failed, Context Cancelled") return err } - fmt.Println("continued from getting status") // TODO decide whether to ignore error or not continue } if link.CurrentHeight < txBlockHeight { - fmt.Println("continued from here") continue // skip until dst.Status is updated } - fmt.Println("before filtering the message") - fmt.Println(len(srcMsg.Receipts)) - if missing := filterSrcMsg(link.RxHeight, link.RxSeq); missing > 0 { - fmt.Println("did this filter the messages") r.log.WithFields(log.Fields{"rxSeq": missing}).Error("missing event sequence") return fmt.Errorf("missing event sequence") } - - fmt.Println("reached before sequence") - fmt.Println("*****************************************************************") - fmt.Println(len(srcMsg.Receipts)) - // fmt.Println(srcMsg.Receipts[0].Height) + tx, newMsg, err := r.dst.Segment(ctx, srcMsg) if err != nil { return err From 0d9d1ebbb200e83c341657fbadb310083dcd0090 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Thu, 6 Jul 2023 12:58:53 +0545 Subject: [PATCH 138/211] fix: tezos icon bridge integration fixes --- cmd/iconbridge/chain/tezos/sender.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cmd/iconbridge/chain/tezos/sender.go b/cmd/iconbridge/chain/tezos/sender.go index 00d54b16..c1ccbb38 100644 --- a/cmd/iconbridge/chain/tezos/sender.go +++ b/cmd/iconbridge/chain/tezos/sender.go @@ -25,9 +25,9 @@ import ( ) const ( - txMaxDataSize = 32 * 1024 * 4 // 8 KB + txMaxDataSize = 1024 // 1 KB txOverheadScale = 0.01 - defaultTxSizeLimit = txMaxDataSize / (1 + txOverheadScale) + defaultTxSizeLimit = txMaxDataSize / (1 + txOverheadScale) // with the rlp overhead defaultSendTxTimeOut = 30 * time.Second // 30 seconds is the block time for tezos ) @@ -35,7 +35,7 @@ type senderOptions struct { StepLimit uint64 `json:"step_limit"` TxDataSizeLimit uint64 `json:"tx_data_size_limit"` BalanceThreshold uint64 `json:"balance_threshold"` - BMCManagment string `json:"bmcManagement"` + BMCManagment string `json:"bmcManagement"` } type sender struct { @@ -122,7 +122,7 @@ func (s *sender) Segment(ctx context.Context, msg *chain.Message) (tx chain.Rela From: msg.From, Receipts: msg.Receipts, } - + for i, receipt := range msg.Receipts { rlpEvents, err := codec.RLP.MarshalToBytes(receipt.Events) //json.Marshal(receipt.Events) // change to rlp bytes if err != nil { @@ -223,7 +223,7 @@ func (tx *relayTx) Send(ctx context.Context) (err error) { in := "{ \"prim\": \"Pair\", \"args\": [ { \"bytes\": \"" + messageHex + "\" }, { \"string\": \"" + tx.Prev + "\" } ] }" fmt.Println(in) - + if err := prim.UnmarshalJSON([]byte(in)); err != nil { fmt.Println("couldnot unmarshall empty string") fmt.Println(err) From bb60dc2430a5bad76e489008b9d7eb0324963f37 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Thu, 6 Jul 2023 13:59:02 +0545 Subject: [PATCH 139/211] fix: tezos icon bridge integration --- cmd/iconbridge/chain/tezos/client.go | 168 +-------------------- cmd/iconbridge/chain/tezos/receiver.go | 23 ++- cmd/iconbridge/chain/tezos/sender.go | 3 +- cmd/iconbridge/example.config.json | 20 +-- smartpy/bmc/package-lock.json | 4 +- smartpy/bts/contracts/src/bts_periphery.py | 9 -- smartpy/bts/package-lock.json | 4 +- 7 files changed, 32 insertions(+), 199 deletions(-) diff --git a/cmd/iconbridge/chain/tezos/client.go b/cmd/iconbridge/chain/tezos/client.go index c6ce79f3..b6542b51 100644 --- a/cmd/iconbridge/chain/tezos/client.go +++ b/cmd/iconbridge/chain/tezos/client.go @@ -18,7 +18,6 @@ import ( "blockwatch.cc/tzgo/contract" "blockwatch.cc/tzgo/micheline" "blockwatch.cc/tzgo/rpc" - "blockwatch.cc/tzgo/signer" "blockwatch.cc/tzgo/tezos" "github.com/icon-project/icon-bridge/cmd/iconbridge/chain" "github.com/icon-project/icon-bridge/cmd/iconbridge/chain/tezos/types" @@ -31,19 +30,12 @@ const ( ) type IClient interface { - // Call(ctx context.Context, callArgs contract.CallArguments, opts *rpc.CallOptions) GetBalance(ctx context.Context, connection *rpc.Client, account tezos.Address, blockLevel int64) GetBlockByHeight(ctx context.Context, connection *rpc.Client, blockLevel int64) (*rpc.Block, error) GetBlockHeightByHash(ctx context.Context, connection *rpc.Client, hash tezos.BlockHash) (int64, error) - // GetBlockHeaderByHeight(ctx context.Context, connection *rpc.Client, blockLevel int64) - // GetBlockMetadataByHash(ctx context.Context, connection *rpc.Client, blockHash tezos.Hash) - MonitorBlock(ctx context.Context, client *rpc.Client, connection *contract.Contract, blockLevel int64, callback func(v *types.BlockNotification) error) (*rpc.Block, error) - // MonitorEvent(ctx context.Context, connection *rpc.Client, blockLevel int64) - GetLastBlock(ctx context.Context, connection *rpc.Client) (*rpc.Block, error) GetStatus(ctx context.Context, contr *contract.Contract) (TypesLinkStats, error) - HandleRelayMessage(ctx context.Context, callArgs contract.CallArguments) (*rpc.Receipt, error) } @@ -64,36 +56,6 @@ type Client struct { BmcManagement tezos.Address } -func (c *Client) SignTransaction() rpc.CallOptions { - pK := tezos.MustParsePrivateKey("edskRz1HoD3cWkmWhCNS5LjBrJNWChGuKWB4HnVoN5UqVsUCpcNJR67ZxKs965u8RgRwptrtGc2ufYZoeECgB77RKm1gTbQ6eB") - opts := rpc.DefaultOptions - opts.Signer = signer.NewFromKey(pK) - return opts -} - -func (c *Client) SendTransaction(ctx context.Context, connection *contract.Contract, parameters micheline.Parameters, sender tezos.Address) (*rpc.Receipt, error) { - args := contract.NewTxArgs() - - args.WithParameters(parameters) - - opts := c.SignTransaction() - - argument := args.WithSource(sender).WithDestination(connection.Address()) - - result, err := connection.Call(ctx, argument, &opts) - - if err != nil { - return nil, err - } - - err = PrettyEncode(result) - - if err != nil { - return nil, err - } - return result, nil -} - func (c *Client) GetLastBlock(ctx context.Context, connection *rpc.Client) (*rpc.Block, error) { block, err := connection.GetHeadBlock(ctx) if err != nil { @@ -126,134 +88,13 @@ func (c *Client) GetBlockHeaderByHeight(ctx context.Context, connection *rpc.Cli return block, nil } -// func (c *Client) MonitorBlock(ctx context.Context, blockLevel int64, verifier IVerifier, callback func(v []*chain.Receipt) error) error { -// fmt.Println("reached in monitor block") -// relayTicker := time.NewTicker(DefaultBlockWaitInterval) -// defer relayTicker.Stop() - -// for { -// select { -// case <-ctx.Done(): -// return fmt.Errorf("Context done") -// case <-relayTicker.C: -// fmt.Println("*************************************************************") -// fmt.Print("Trying to fetch block for blockLevel ") -// fmt.Println(blockLevel) - -// block, err := c.GetBlockByHeight(ctx, c.Cl, blockLevel) - -// if err != nil { -// fmt.Println(err) -// fmt.Println("reducing the block level") -// blockLevel-- -// fmt.Print("Trying to Fetch for block level ") -// fmt.Println(blockLevel) -// continue -// } - -// header, err := c.GetBlockHeaderByHeight(ctx, c.Cl, blockLevel) -// if err != nil { -// return err -// } -// fmt.Println(block.Metadata.ProposerConsensusKey) - -// err = verifier.Verify(ctx, header, block.Metadata.ProposerConsensusKey, c.Cl, header) - -// if err != nil { -// fmt.Println(err) -// return err -// } -// c.blockLevel = blockLevel - -// // err = verifier.Update(header, ) - -// if err != nil { -// fmt.Println(err) -// return err -// } - -// PrettyEncode(header) - -// blockOperations := block.Operations - -// for i := 0; i < len(blockOperations); i++ { -// for j := 0; j < len(blockOperations[i]); j++ { -// for _, operation := range blockOperations[i][j].Contents { -// switch operation.Kind() { -// case tezos.OpTypeTransaction: -// tx := operation.(*rpc.Transaction) -// receipt, err := returnTxMetadata(tx, c.Contract.Address()) -// if err != nil { -// return err -// } -// if len(receipt) != 0 { -// fmt.Println("found for block level ", block.Header.Level) -// fmt.Println("callback start") -// err := callback(receipt) -// fmt.Println("call back end") -// if err != nil { -// return err -// } -// } -// } -// } -// } -// } -// } -// blockLevel++ -// } -// } - -func returnTxMetadata(tx *rpc.Transaction, contractAddress tezos.Address) ([]*chain.Receipt, error) { - // _, err := fmt.Println(tx.Destination) - // if err != nil { - // return nil, err - // } - address := tx.Destination - - var receipts []*chain.Receipt - if address.ContractAddress() == contractAddress.ContractAddress() { - fmt.Println("Address matched") - fmt.Println("****************") - fmt.Println("****************") - fmt.Println("****") - fmt.Println("****") - fmt.Println("****") - fmt.Println("****************") - fmt.Println("****************") - fmt.Println("****") - fmt.Println("****") - fmt.Println("****") - fmt.Println("****") - fmt.Println("****") - fmt.Println("****") - - if tx.Metadata.InternalResults[0].Tag == "TransferStart" { - var events []*chain.Event - - events = append(events, &chain.Event{ - Message: []byte(tx.Metadata.InternalResults[0].Payload.String), - }) - receipts = append(receipts, &chain.Receipt{ - Events: events, - }) - } - } - return receipts, nil -} - -func returnTxMetadata3(tx *rpc.Transaction, contractAddress tezos.Address, height uint64) (*chain.Receipt, error) { - fmt.Println("reache to return tx metadata3", height) +func filterMessageEvents(tx *rpc.Transaction, contractAddress tezos.Address, height uint64) (*chain.Receipt, error) { receipt := &chain.Receipt{} var events []*chain.Event for i := 0; i < len(tx.Metadata.InternalResults); i++ { - fmt.Println("reached in for") internalResults := tx.Metadata.InternalResults[i] - fmt.Println("internal results", internalResults.Source.ContractAddress()) - fmt.Println("bmc address", contractAddress.ContractAddress()) if internalResults.Kind.String() == "event" && internalResults.Source.ContractAddress() == contractAddress.ContractAddress() { - fmt.Println("Address matched") if internalResults.Tag == "Message" { message := internalResults.Payload.Args[0].Bytes next := internalResults.Payload.Args[1].Args[0].String @@ -361,7 +202,7 @@ func (c *Client) GetConsensusKey(ctx context.Context, bakerConsensusKey tezos.Ad } break } - return exposedPublicKey, nil + return exposedPublicKey, nil } func (c *Client) HandleRelayMessage(ctx context.Context, callArgs contract.CallArguments, opts *rpc.CallOptions) (*rpc.Receipt, error) { @@ -431,9 +272,8 @@ func PrettyEncode(data interface{}) error { return nil } -func returnTxMetadata2(block *rpc.Block, contractAddress tezos.Address, blockHeight int64, cl *Client) (bool, []*chain.Receipt, error) { +func filterTransactionOperations(block *rpc.Block, contractAddress tezos.Address, blockHeight int64, cl *Client) (bool, []*chain.Receipt, error) { blockOperations := block.Operations - var tx *rpc.Transaction var receipt []*chain.Receipt for i := 0; i < len(blockOperations); i++ { @@ -442,7 +282,7 @@ func returnTxMetadata2(block *rpc.Block, contractAddress tezos.Address, blockHei switch operation.Kind() { case tezos.OpTypeTransaction: tx = operation.(*rpc.Transaction) - r, err := returnTxMetadata3(tx, cl.BmcManagement, uint64(blockHeight)) + r, err := filterMessageEvents(tx, cl.BmcManagement, uint64(blockHeight)) if err != nil { return false, nil, err } diff --git a/cmd/iconbridge/chain/tezos/receiver.go b/cmd/iconbridge/chain/tezos/receiver.go index 5c750acd..f6950570 100644 --- a/cmd/iconbridge/chain/tezos/receiver.go +++ b/cmd/iconbridge/chain/tezos/receiver.go @@ -24,7 +24,7 @@ import ( ) const ( - BlockInterval = 30 * time.Second + BlockInterval = 15 * time.Second BlockHeightPollInterval = BlockInterval * 5 BlockFinalityConfirmations = 2 MonitorBlockMaxConcurrency = 300 // number of concurrent requests to synchronize older blocks from source chain @@ -194,13 +194,13 @@ func (r *receiver) NewVerifier(ctx context.Context, previousHeight int64) (vri I fmt.Println("blockHeaderhash", block.Header.Hash) vr := &Verifier{ - mu: sync.RWMutex{}, - next: block.Header.Level + 1, - parentHash: block.Hash, - parentFittness: fittness, - chainID: id, - cl: r.client, - validators: make(map[tezos.Address]bool), + mu: sync.RWMutex{}, + next: block.Header.Level + 1, + parentHash: block.Hash, + parentFittness: fittness, + chainID: id, + cl: r.client, + validators: make(map[tezos.Address]bool), validatorsPublicKey: make(map[tezos.Address]tezos.Key), } @@ -753,19 +753,18 @@ func (r *receiver) receiveLoop2(ctx context.Context, opts *BnOptions, callback f q.err = errors.Wrapf(err, "GetHeaderByHeight: %v", err) return } - q.v.Header = &block.Header // change accordingly - q.v.Hash = block.Hash // change accordingly + q.v.Header = &block.Header // change accordingly + q.v.Hash = block.Hash // change accordingly q.v.Block = block } - if q.v.HasBTPMessage == nil && q.v.Height.Int64() > opts.StartHeight { if err != nil { return } q.v.Proposer = block.Metadata.Proposer - hasBTPMessage, receipt, err := returnTxMetadata2(block, r.client.Contract.Address(), q.v.Height.Int64(), r.client) + hasBTPMessage, receipt, err := filterTransactionOperations(q.v.Block, r.client.Contract.Address(), q.v.Height.Int64(), r.client) if err != nil { q.err = errors.Wrapf(err, "hasBTPMessage: %v", err) diff --git a/cmd/iconbridge/chain/tezos/sender.go b/cmd/iconbridge/chain/tezos/sender.go index c1ccbb38..d2da149a 100644 --- a/cmd/iconbridge/chain/tezos/sender.go +++ b/cmd/iconbridge/chain/tezos/sender.go @@ -107,9 +107,8 @@ func (s *sender) Segment(ctx context.Context, msg *chain.Message) (tx chain.Rela limit := defaultTxSizeLimit s.opts.TxDataSizeLimit = uint64(limit) } - fmt.Println("reached upto here") + if len(msg.Receipts) == 0 { - fmt.Println("Probably gone from here") return nil, msg, nil } rm := &chain.RelayMessage{ diff --git a/cmd/iconbridge/example.config.json b/cmd/iconbridge/example.config.json index 558aeb67..f1716c75 100644 --- a/cmd/iconbridge/example.config.json +++ b/cmd/iconbridge/example.config.json @@ -17,21 +17,21 @@ { "name": "t2i", "src": { - "address": "btp://NetXnHfVqm9iesp.tezos/KT1M8ZMiYHJRFRsRLTsTLvVjQp9JXUy9FMDU", + "address": "btp://NetXnHfVqm9iesp.tezos/KT19Q5h8vrGKX7SF5rGU45v25GM8cMCKf9Y4", "endpoint": [ "http://localhost:8732" ], "options": { "verifier": { - "blockHeight": 3162000 + "blockHeight": 3170453 }, "syncConcurrency": 100, - "bmcManagement": "KT1NEy9DbjpCZW6u59iHiu6iMa2jvCizmtU2" + "bmcManagement": "KT1RPVCXSm1pRUomhYodvSF1nwGQSo2oteUy" }, - "offset": 3162000 + "offset": 3170453 }, "dst": { - "address": "btp://0x7.icon/cxa2905b9177941c92841a80e5efe1ca6f49dcc90e", + "address": "btp://0x7.icon/cxf155d986258446ea587a44dc96ecc2b991a273fc", "endpoint": [ "https://berlin.net.solidwallet.io/api/v3" ], @@ -66,21 +66,21 @@ { "name": "i2t", "src": { - "address": "btp://0x7.icon/cxa2905b9177941c92841a80e5efe1ca6f49dcc90e", + "address": "btp://0x7.icon/cxf155d986258446ea587a44dc96ecc2b991a273fc", "endpoint": [ "https://berlin.net.solidwallet.io/api/v3/icon_dex" ], "options": { "verifier": { - "blockHeight": 10137924, + "blockHeight": 10489565, "validatorsHash": "0x04b56f3fc8d396cc7eb8124da8a554800b8758c9e2fff0802aa9682948e65447" }, "syncConcurrency": 100 }, - "offset": 10137924 + "offset": 10489565 }, "dst": { - "address": "btp://NetXnHfVqm9iesp.tezos/KT1M8ZMiYHJRFRsRLTsTLvVjQp9JXUy9FMDU", + "address": "btp://NetXnHfVqm9iesp.tezos/KT19Q5h8vrGKX7SF5rGU45v25GM8cMCKf9Y4", "endpoint": [ "http://localhost:8732" ], @@ -88,7 +88,7 @@ "gas_limit": 1040000, "boost_gas_price": 1.5, "tx_data_size_limit": 65536, - "bmcManagement": "KT1NEy9DbjpCZW6u59iHiu6iMa2jvCizmtU2" + "bmcManagement": "KT1RPVCXSm1pRUomhYodvSF1nwGQSo2oteUy" }, "key_store": { "address": "tz1ZPVxKiybvbV1GvELRJJpyE1xj1UpNpXMv", diff --git a/smartpy/bmc/package-lock.json b/smartpy/bmc/package-lock.json index 13756c6c..2bec67e4 100644 --- a/smartpy/bmc/package-lock.json +++ b/smartpy/bmc/package-lock.json @@ -786,6 +786,7 @@ "version": "4.8.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -1408,7 +1409,8 @@ "typescript": { "version": "4.8.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==" + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "dev": true }, "util-deprecate": { "version": "1.0.2", diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index 31395353..0cc38aa7 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -574,15 +574,6 @@ def check_transfer_restrictions(self, params): with sp.else_(): sp.result(False) - -sp.add_compilation_target("bts_periphery", BTSPeriphery(bmc_address=sp.address("KT1VFtWq2dZDH1rTfLtgMaASMt4UX78omMs2"), - bts_core_address=sp.address("KT1JAippuMfS6Bso8DGmigmTdkgEZUxQxYyX"), - helper_contract=sp.address("KT1HwFJmndBWRn3CLbvhUjdupfEomdykL5a6"), - parse_address=sp.address("KT1Ha8LzZa7ku1F8eytY7hgNKFJ2BKFRqSDh"), - native_coin_name="btp-NetXnHfVqm9iesp.tezos-XTZ", - owner_address = sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP") - )) - sp.add_compilation_target("bts_periphery", BTSPeriphery(bmc_address=sp.address("KT1VFtWq2dZDH1rTfLtgMaASMt4UX78omMs2"), bts_core_address=sp.address("KT1JAippuMfS6Bso8DGmigmTdkgEZUxQxYyX"), helper_contract=sp.address("KT1HwFJmndBWRn3CLbvhUjdupfEomdykL5a6"), diff --git a/smartpy/bts/package-lock.json b/smartpy/bts/package-lock.json index 13756c6c..2bec67e4 100644 --- a/smartpy/bts/package-lock.json +++ b/smartpy/bts/package-lock.json @@ -786,6 +786,7 @@ "version": "4.8.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -1408,7 +1409,8 @@ "typescript": { "version": "4.8.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==" + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "dev": true }, "util-deprecate": { "version": "1.0.2", From 1c84b0b3df45570c64eaf053c1f7bf9d92cc22b3 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Fri, 7 Jul 2023 11:25:07 +0545 Subject: [PATCH 140/211] fix: tezos icon integration fixes --- cmd/iconbridge/example.config.json | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/cmd/iconbridge/example.config.json b/cmd/iconbridge/example.config.json index f1716c75..b8d56892 100644 --- a/cmd/iconbridge/example.config.json +++ b/cmd/iconbridge/example.config.json @@ -17,21 +17,21 @@ { "name": "t2i", "src": { - "address": "btp://NetXnHfVqm9iesp.tezos/KT19Q5h8vrGKX7SF5rGU45v25GM8cMCKf9Y4", + "address": "btp://NetXnHfVqm9iesp.tezos/KT1VTmeVTccqv3opzkbRVrYwaoSZTTEzfJ8b", "endpoint": [ - "http://localhost:8732" + "https://ghostnet.smartpy.io" ], "options": { "verifier": { - "blockHeight": 3170453 + "blockHeight": 3170705 }, "syncConcurrency": 100, - "bmcManagement": "KT1RPVCXSm1pRUomhYodvSF1nwGQSo2oteUy" + "bmcManagement": "KT1HHnV7zzxUkDMXTaNveLQHntLfSWNqJsZk" }, - "offset": 3170453 + "offset": 3170705 }, "dst": { - "address": "btp://0x7.icon/cxf155d986258446ea587a44dc96ecc2b991a273fc", + "address": "btp://0x7.icon/cxb7de63db8c1fa2d9dfb6c531e6bc19402572cc23", "endpoint": [ "https://berlin.net.solidwallet.io/api/v3" ], @@ -66,29 +66,29 @@ { "name": "i2t", "src": { - "address": "btp://0x7.icon/cxf155d986258446ea587a44dc96ecc2b991a273fc", + "address": "btp://0x7.icon/cxb7de63db8c1fa2d9dfb6c531e6bc19402572cc23", "endpoint": [ "https://berlin.net.solidwallet.io/api/v3/icon_dex" ], "options": { "verifier": { - "blockHeight": 10489565, + "blockHeight": 10490872, "validatorsHash": "0x04b56f3fc8d396cc7eb8124da8a554800b8758c9e2fff0802aa9682948e65447" }, "syncConcurrency": 100 }, - "offset": 10489565 + "offset": 10490872 }, "dst": { - "address": "btp://NetXnHfVqm9iesp.tezos/KT19Q5h8vrGKX7SF5rGU45v25GM8cMCKf9Y4", + "address": "btp://NetXnHfVqm9iesp.tezos/KT1VTmeVTccqv3opzkbRVrYwaoSZTTEzfJ8b", "endpoint": [ - "http://localhost:8732" + "https://ghostnet.smartpy.io" ], "options": { "gas_limit": 1040000, "boost_gas_price": 1.5, "tx_data_size_limit": 65536, - "bmcManagement": "KT1RPVCXSm1pRUomhYodvSF1nwGQSo2oteUy" + "bmcManagement": "KT1HHnV7zzxUkDMXTaNveLQHntLfSWNqJsZk" }, "key_store": { "address": "tz1ZPVxKiybvbV1GvELRJJpyE1xj1UpNpXMv", From 656ef0efb1a889e6d787b766ec56d43d943bd8c8 Mon Sep 17 00:00:00 2001 From: simusud Date: Fri, 7 Jul 2023 16:45:51 +0545 Subject: [PATCH 141/211] fix(bmc): removed redundant params --- smartpy/bmc/contracts/src/bmc_periphery.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/smartpy/bmc/contracts/src/bmc_periphery.py b/smartpy/bmc/contracts/src/bmc_periphery.py index f6a2f74f..64e8c567 100644 --- a/smartpy/bmc/contracts/src/bmc_periphery.py +++ b/smartpy/bmc/contracts/src/bmc_periphery.py @@ -235,13 +235,13 @@ def _handle_message(self, prev, msg): with sp.if_(bsh_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): # call handle_fee_gathering of bts periphery - handle_fee_gathering_args_type = sp.TRecord(bsh_addr=sp.TAddress, fa=sp.TString, + handle_fee_gathering_args_type = sp.TRecord(fa=sp.TString, svc=sp.TString) handle_fee_gathering_entry_point = sp.contract(handle_fee_gathering_args_type, bsh_addr, "handle_fee_gathering").open_some() - handle_fee_gathering_args = sp.record(bsh_addr=bsh_addr, + handle_fee_gathering_args = sp.record( fa=gather_fee.value.fa, svc=gather_fee.value.svcs[k]) sp.transfer(handle_fee_gathering_args, sp.tez(0), handle_fee_gathering_entry_point) bool_value.value = True From 6f20dab722c948bdf32f58f5463a98e802351f12 Mon Sep 17 00:00:00 2001 From: simusud Date: Fri, 7 Jul 2023 16:46:28 +0545 Subject: [PATCH 142/211] perf(bmc): review changes --- smartpy/bts/contracts/src/String.py | 2 +- smartpy/bts/contracts/src/bts_periphery.py | 153 +++++++++++---------- 2 files changed, 81 insertions(+), 74 deletions(-) diff --git a/smartpy/bts/contracts/src/String.py b/smartpy/bts/contracts/src/String.py index c9c55e17..7968041c 100644 --- a/smartpy/bts/contracts/src/String.py +++ b/smartpy/bts/contracts/src/String.py @@ -34,7 +34,7 @@ def split_btp_address(base): penultimate.value = l.head # with sp.else_(): # sp.failwith("Only one element") - + # TODO: should return true false return sp.pair(penultimate.value, last.value) diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index 59dc3a47..99298496 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -81,13 +81,20 @@ def _add_to_blacklist(self, params): sp.set_type(params, sp.TList(sp.TString)) add_blacklist_status = sp.local("add_blacklist_status", "success") + addr_list = sp.ocal("addr_list", [], sp.TList(sp.TAddress)) with sp.if_(sp.len(params) <= self.MAX_BATCH_SIZE): sp.for item in params: parsed_addr = sp.view("str_to_addr", self.data.parse_contract, item, t=sp.TAddress).open_some() - with sp.if_(parsed_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): - self.data.blacklist[parsed_addr] = True - with sp.else_(): - add_blacklist_status.value = "InvalidAddress" + with sp.if_(add_blacklist_status.value == "success"): + with sp.if_(parsed_addr == sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): + add_blacklist_status.value = "InvalidAddress" + with sp.else_(): + addr_list.value.push(parsed_addr) + with sp.if_(add_blacklist_status.value == "success"): + sp.for _item in addr_list.value: + self.data.blacklist[_item] = True + with sp.else_(): + add_blacklist_status.value = "InvalidAddress" with sp.else_(): add_blacklist_status.value = "error" return add_blacklist_status.value @@ -101,16 +108,22 @@ def _remove_from_blacklist(self, params): sp.set_type(params, sp.TList(sp.TString)) remove_blacklist_status = sp.local("remove_blacklist_status", "success") + addr_list = sp.ocal("addr_list", [], sp.TList(sp.TAddress)) + with sp.if_(sp.len(params) <= self.MAX_BATCH_SIZE): sp.for item in params: parsed_addr = sp.view("str_to_addr", self.data.parse_contract, item, t=sp.TAddress).open_some() - with sp.if_(parsed_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): - with sp.if_(self.data.blacklist.contains(parsed_addr)): - del self.data.blacklist[parsed_addr] + with sp.if_(remove_blacklist_status.value == "success"): + with sp.if_(parsed_addr == sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg") | + self.data.blacklist.contains(parsed_addr) == False): + remove_blacklist_status.value = "InvalidAddress" with sp.else_(): - remove_blacklist_status.value = "UserNotBlacklisted" - with sp.else_(): - remove_blacklist_status.value = "InvalidAddress" + addr_list.push(parsed_addr) + with sp.if_(remove_blacklist_status.value == "success"): + sp.for _item in addr_list: + del self.data.blacklist[_item] + with sp.else_(): + remove_blacklist_status.value = "InvalidAddress" with sp.else_(): remove_blacklist_status.value = "error" return remove_blacklist_status.value @@ -249,16 +262,17 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, prev, callback_msg): with sp.if_(parsed_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): handle_request_call= self._handle_request_service(parsed_addr, tc.assets) + # first param of send_response_message is service type value with sp.if_(handle_request_call == "success"): - self.send_response_message(sp.variant("RESPONSE_HANDLE_SERVICE", 2), sp.nat(2), + self.send_response_message(sp.nat(2), _from, sn, "", self.RC_OK) sp.emit(sp.record(from_address=_from, to=parsed_addr, serial_no=self.data.serial_no, assets_details=tc.assets), tag="TransferReceived") with sp.else_(): - self.send_response_message(sp.variant("RESPONSE_HANDLE_SERVICE", 2), sp.nat(2), + self.send_response_message(sp.nat(2), _from, sn, handle_request_call, self.RC_ERR) with sp.else_(): - self.send_response_message(sp.variant("RESPONSE_HANDLE_SERVICE", 2), sp.nat(2), _from, + self.send_response_message(sp.nat(2), _from, sn, "InvalidAddress", self.RC_ERR) with sp.else_(): callback_string.value = "ErrorInDecodingTransferCoin" @@ -273,23 +287,23 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, prev, callback_msg): with b_agr.match("ADD_TO_BLACKLIST") as b_val_1: add_blacklist_call = self._add_to_blacklist(addresses) with sp.if_(add_blacklist_call == "success"): - self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, + self.send_response_message(sp.nat(3), _from, sn, "AddedToBlacklist", self.RC_OK) with sp.else_(): - self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, + self.send_response_message(sp.nat(3), _from, sn, "ErrorAddToBlackList", self.RC_ERR) with b_agr.match("REMOVE_FROM_BLACKLIST") as b_val_2: remove_blacklist_call = self._remove_from_blacklist(addresses) with sp.if_(remove_blacklist_call == "success"): - self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, + self.send_response_message(sp.nat(3), _from, sn, "RemovedFromBlacklist", self.RC_OK) with sp.else_(): - self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, + self.send_response_message(sp.nat(3), _from, sn, "ErrorRemoveFromBlackList", self.RC_ERR) with b_agr.match("ERROR") as b_val_2: - self.send_response_message(sp.variant("BLACKLIST_MESSAGE", 3), sp.nat(3), _from, sn, + self.send_response_message(sp.nat(3), _from, sn, "BlacklistServiceTypeErr", self.RC_ERR) with sp.else_(): callback_string.value = "ErrorInDecodingBlacklist" @@ -302,10 +316,10 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, prev, callback_msg): set_limit_call = self._set_token_limit(coin_name_limit) with sp.if_(set_limit_call == "success"): - self.send_response_message(sp.variant("CHANGE_TOKEN_LIMIT", 4), sp.nat(4), _from, sn, + self.send_response_message(sp.nat(4), _from, sn, "ChangeTokenLimit", self.RC_OK) with sp.else_(): - self.send_response_message(sp.variant("CHANGE_TOKEN_LIMIT", 4), sp.nat(4), _from, sn, + self.send_response_message(sp.nat(4), _from, sn, "ErrorChangeTokenLimit", self.RC_ERR) with sp.else_(): callback_string.value = "ErrorInDecodingTokenLimit" @@ -327,7 +341,7 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, prev, callback_msg): sp.emit(sp.record(_from=_from, sn=sn), tag= "UnknownResponse") with arg.match("ERROR") as a5: - self.send_response_message(sp.variant("UNKNOWN_TYPE", 5), sp.nat(5), _from, sn, + self.send_response_message(sp.nat(5), _from, sn, "Unknown",self.RC_ERR) with sp.else_(): callback_string.value = "ErrorInDecoding" @@ -397,33 +411,29 @@ def handle_response_service(self, sn, code, msg): check_valid = sp.local("check_valid", True) bts_core_fa2_balance = sp.local("fa2_token_balance_response_service", sp.nat(0)) - with sp.if_(loop.value <= self.MAX_BATCH_SIZE): + bts_core_address = self.data.bts_core + with sp.if_((loop.value <= self.MAX_BATCH_SIZE) & (caller.value == bts_core_address)): sp.for item in self.data.requests.get(sn).coin_details: - bts_core_address = self.data.bts_core - coin_name = item.coin_name - value = item.value - fee = item.fee - amount = value + fee - bts_core_balance = sp.view("balance_of", bts_core_address, - sp.record(owner=caller.value, coin_name=coin_name), t= - sp.TRecord(usable_balance=sp.TNat, locked_balance=sp.TNat, - refundable_balance=sp.TNat, user_balance=sp.TNat) - ).open_some() - # check if caller has enough locked in bts_core - with sp.if_((bts_core_balance.locked_balance < amount) & (caller.value != bts_core_address)): - check_valid.value = False - coin_type = sp.view("coin_type", bts_core_address, coin_name, t=sp.TNat).open_some() - with sp.if_(coin_type == sp.nat(1)): - coin_address = sp.view("coin_id", bts_core_address, coin_name, t=sp.TAddress).open_some() - bts_core_fa2 = sp.view("get_balance_of", coin_address, - [sp.record(owner=bts_core_address, token_id=sp.nat(0))], - t=sp.TList(t_balance_of_response)).open_some("Invalid view") - sp.for elem in bts_core_fa2: - bts_core_fa2_balance.value = elem.balance - # check if bts_core has enough NATIVE_WRAPPED_COIN_TYPE to burn - with sp.if_(bts_core_fa2_balance.value < value): + with sp.if_(check_valid.value == True): + coin_name = item.coin_name + value = item.value + fee = item.fee + amount = value + fee + bts_core_balance = sp.view("balance_of", bts_core_address, + sp.record(owner=caller.value, coin_name=coin_name), t= + sp.TRecord(usable_balance=sp.TNat, locked_balance=sp.TNat, + refundable_balance=sp.TNat, user_balance=sp.TNat) + ).open_some() + # check if caller has enough locked in bts_core + with sp.if_(bts_core_balance.locked_balance < amount): check_valid.value = False + coin_type = sp.view("coin_type", bts_core_address, coin_name, t=sp.TNat).open_some() + with sp.if_(coin_type == sp.nat(1)): + # check if bts_core has enough NATIVE_WRAPPED_COIN_TYPE to burn + with sp.if_(bts_core_balance.user_balance < value): + check_valid.value = False + with sp.if_(check_valid.value == True): sp.for _item in self.data.requests.get(sn).coin_details: # inter score call @@ -469,26 +479,27 @@ def _handle_request_service(self, to, assets): coin_name = assets[i].coin_name transferred_amount = assets[i].value valid_coin = sp.view("is_valid_coin", bts_core_address, coin_name, t=sp.TBool).open_some() - check_transfer = sp.view("check_transfer_restrictions", sp.self_address, sp.record( - coin_name=coin_name, user=parsed_to, value=transferred_amount), t=sp.TBool).open_some() - - native_coin_name, bts_core_balance = sp.match_pair(sp.view("native_coin_balance_of", bts_core_address, - sp.unit, t=sp.TPair(sp.TString, sp.TMutez)).open_some("Invalid view")) - with sp.if_(native_coin_name == coin_name): - with sp.if_(sp.utils.mutez_to_nat(bts_core_balance) < transferred_amount): - check_validity.value = False - with sp.else_(): - coin_type = sp.view("coin_type", bts_core_address, coin_name, t=sp.TNat).open_some() - # check balance_of in case of NON-NATIVE-COIN-TYPE - with sp.if_((valid_coin == True) & (coin_type == sp.nat(2))): - coin_address = sp.view("coin_id", bts_core_address, coin_name, t=sp.TAddress).open_some() - bts_core_fa2 = sp.view("get_balance_of", coin_address, - [sp.record(owner=bts_core_address, token_id=sp.nat(0))], - t=sp.TList(t_balance_of_response)).open_some("Invalid view") - sp.for elem in bts_core_fa2: - bts_core_fa2_balance.value = elem.balance - with sp.if_(bts_core_fa2_balance.value < transferred_amount): - check_validity.value = False + with sp.if_(valid_coin == True): + check_transfer = sp.view("check_transfer_restrictions", sp.self_address, sp.record( + coin_name=coin_name, user=parsed_to, value=transferred_amount), t=sp.TBool).open_some() + with sp.if_(check_transfer == True): + native_coin_name, bts_core_balance = sp.match_pair(sp.view("native_coin_balance_of", bts_core_address, + sp.unit, t=sp.TPair(sp.TString, sp.TMutez)).open_some("Invalid view")) + with sp.if_(native_coin_name == coin_name): + with sp.if_(sp.utils.mutez_to_nat(bts_core_balance) < transferred_amount): + check_validity.value = False + with sp.else_(): + coin_type = sp.view("coin_type", bts_core_address, coin_name, t=sp.TNat).open_some() + # check balance_of in case of NON-NATIVE-COIN-TYPE + with sp.if_(coin_type == sp.nat(2)): + coin_address = sp.view("coin_id", bts_core_address, coin_name, t=sp.TAddress).open_some() + bts_core_fa2 = sp.view("get_balance_of", coin_address, + [sp.record(owner=bts_core_address, token_id=sp.nat(0))], + t=sp.TList(t_balance_of_response)).open_some("Invalid view") + sp.for elem in bts_core_fa2: + bts_core_fa2_balance.value = elem.balance + with sp.if_(bts_core_fa2_balance.value < transferred_amount): + check_validity.value = False with sp.if_((check_transfer == False) | (valid_coin == False)) : check_validity.value = False @@ -506,10 +517,9 @@ def _handle_request_service(self, to, assets): return status.value - def send_response_message(self, service_type, service_type_val, to, sn, msg, code): + def send_response_message(self, service_type_val, to, sn, msg, code): """ - :param service_type: :param service_type_val: value of service_type variant :param to: :param sn: @@ -517,7 +527,6 @@ def send_response_message(self, service_type, service_type_val, to, sn, msg, cod :param code: :return: """ - sp.set_type(service_type, types.Types.ServiceType) sp.set_type(service_type_val, sp.TNat) sp.set_type(to, sp.TString) sp.set_type(sn, sp.TInt) @@ -536,22 +545,20 @@ def send_response_message(self, service_type, service_type_val, to, sn, msg, cod @sp.entry_point - def handle_fee_gathering(self, fa, svc, bsh_addr): + def handle_fee_gathering(self, fa, svc): """ BSH handle Gather Fee Message request from BMC contract :param fa: A BTP address of fee aggregator :param svc: A name of the service - :param callback: callback function type in bmc_periphery - :param bsh_addr: address of bts_periphery :return: """ sp.set_type(fa, sp.TString) sp.set_type(svc, sp.TString) - sp.set_type(bsh_addr, sp.TAddress) check_caller = self.only_bmc() + strings.split_btp_address(fa) + # TODO: CHECK VALID ADDRESS with sp.if_((svc == self.service_name) & (check_caller == "Authorized")): - strings.split_btp_address(fa) # call transfer_fees of BTS_Core transfer_fees_args_type = sp.TString From feacc97b35ffb52f41bc5926694ad0664431db5c Mon Sep 17 00:00:00 2001 From: simusud Date: Fri, 7 Jul 2023 16:46:55 +0545 Subject: [PATCH 143/211] test(bmc): integration test update --- .../bmc/contracts/tests/integration_test.py | 492 ++++++++++++------ 1 file changed, 342 insertions(+), 150 deletions(-) diff --git a/smartpy/bmc/contracts/tests/integration_test.py b/smartpy/bmc/contracts/tests/integration_test.py index a928adaf..78b73181 100644 --- a/smartpy/bmc/contracts/tests/integration_test.py +++ b/smartpy/bmc/contracts/tests/integration_test.py @@ -1,9 +1,108 @@ +import subprocess + import smartpy as sp +FA2 = sp.io.import_script_from_url("https://legacy.smartpy.io/templates/fa2_lib.py") BMCManagement = sp.io.import_script_from_url("file:./contracts/src/bmc_management.py") BMCPeriphery = sp.io.import_script_from_url("file:./contracts/src/bmc_periphery.py") -BMCHelper = sp.io.import_script_from_url("file:../bts/contracts/src/helper.py") +BMCHelper = sp.io.import_script_from_url("file:./contracts/src/helper.py") ParseAddress = sp.io.import_script_from_url("file:../bts/contracts/src/parse_address.py") +fa2_dummy_file = sp.io.import_script_from_url("file:./contracts/tests/fa2_dummy.py") + +path = {"bts_core": [ + {"types": ['types = sp.io.import_script_from_url("file:../bts/contracts/src/Types.py")', + 'types = sp.io.import_script_from_url("file:./contracts/src/Types.py")']}, + {"FA2_contract": [ + 'FA2_contract = sp.io.import_script_from_url("file:../bts/contracts/src/FA2_contract.py")', + 'FA2_contract = sp.io.import_script_from_url("file:./contracts/src/FA2_contract.py")']} +], + "bts_periphery": [ + {"types": ['types = sp.io.import_script_from_url("file:../bts/contracts/src/Types.py")', + 'types = sp.io.import_script_from_url("file:./contracts/src/Types.py")']}, + {"strings": ['strings = sp.io.import_script_from_url("file:../bts/contracts/src/String.py")', + 'strings = sp.io.import_script_from_url("file:./contracts/src/String.py")']}, + {"rlp": ['rlp = sp.io.import_script_from_url("file:../bts/contracts/src/RLP_struct.py")', + 'rlp = sp.io.import_script_from_url("file:./contracts/src/RLP_struct.py")']}, + + ], + + "RLP_struct": [ + {"types": ['types = sp.io.import_script_from_url("file:../bts/contracts/src/Types.py")', + 'types = sp.io.import_script_from_url("file:./contracts/src/Types.py")']}, + + ] +} + +path2 = { + # "RLP_struct": [ + # {'yy': + # [' yy = sp.view("encode_nat", self.data.helper, params.sn, t=sp.TBytes).open_some()', + # ' yy = sp.view("to_byte", self.data.helper_parse_negative, params.sn,' + # ' t=sp.TBytes).open_some()']}, + # {'xx': + # [' xx = Utils2.Int.of_bytes(sn_in_bytes)', + # ' xx = sp.view("to_int", self.data.helper_parse_negative, sn_in_bytes, t=sp.TInt)' + # '.open_some()'] + # + # } + # ], + "bmc_periphery": [ + {'_self_address': + [' _self_address = "KT1VTmeVTccqv3opzkbRVrYwaoSZTTEzfJ8b"', + ' _self_address = sp.self_address' + ] + } + ] +} + + +def patch_file_path(file_name, old_value, new_value): + subprocess.call("sed -i -e 's#.*" + old_value + " =.*#" + new_value + "#' " + file_name, shell=True) + + +def bts_core_contract_deploy_setup(): + for key, value in path.items(): + for i in value: + lis1 = [] + for x, y in i.items(): + lis1.append(x) + # lis1.append(y) + patch_file_path("../bts/contracts/src/" + key + ".py", lis1[0], y[0]) + + +def bmc_periphery_contract_deploy_setup(): + for key, value in path2.items(): + for i in value: + lis1 = [] + for x, y in i.items(): + lis1.append(x) + # lis1.append(y) + patch_file_path("./contracts/src/" + key + ".py", lis1[0], y[0]) + + +def tear_down(): + for key, value in path.items(): + for i in value: + lis1 = [] + for x, y in i.items(): + lis1.append(x) + # lis1.append(y) + patch_file_path("../bts/contracts/src/" + key + ".py", lis1[0], y[1]) + + +def tear_down_bmc(): + for key, value in path2.items(): + for i in value: + lis1 = [] + for x, y in i.items(): + lis1.append(x) + # lis1.append(y) + patch_file_path("./contracts/src/" + key + ".py", lis1[0], y[1]) + + +# import changes in bts_core for testing +bts_core_contract_deploy_setup() +bmc_periphery_contract_deploy_setup() BTSCore = sp.io.import_script_from_url("file:../bts/contracts/src/bts_core.py") BTSOwnerManager = sp.io.import_script_from_url("file:../bts/contracts/src/bts_owner_manager.py") @@ -16,179 +115,272 @@ def test(): # test account alice = sp.test_account("Alice") - creator = sp.test_account("Creator") + owner = sp.test_account("Owner") jack = sp.test_account("Jack") bob = sp.test_account("Bob") creator2 = sp.test_account("creator2") service1_address = sp.test_account("service1_address") service2_address = sp.test_account("service2_address") + relay = sp.test_account("Relay") + helper_parse_neg_contract = sp.test_account("helper_parse_neg_contract") + + # Change icon_bmc_address for new environment + icon_bmc_address = "cxb7de63db8c1fa2d9dfb6c531e6bc19402572cc23" + icon_bmc_block_height = 10445602 # deploy BMCManagement contract helper_contract = deploy_helper_contract() sc += helper_contract - bmc_management_contract = deploy_bmc_management_contract(sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), - helper_contract.address) - sc += bmc_management_contract + bmc_management = deploy_bmc_management(owner.address, helper_contract.address) + sc += bmc_management parse_address = deploy_parse_address() sc += parse_address - bmc_periphery_contract = deploy_bmc_periphery_contract(bmc_management_contract.address, helper_contract.address, - parse_address.address) - sc += bmc_periphery_contract + bmc_periphery = deploy_bmc_periphery(bmc_management.address, helper_contract.address, + helper_parse_neg_contract.address, parse_address.address, owner.address) + sc += bmc_periphery - bts_owner_manager = deploy_bts_owner_manager_contract() + bts_owner_manager = deploy_bts_owner_manager_contract(owner.address) sc += bts_owner_manager - bts_core_contract = deploy_bts_core_contract(bts_owner_manager.address) - sc += bts_core_contract - bts_periphery = deploy_bts_periphery_contract(bts_core_contract.address, helper_contract.address, - parse_address.address, bmc_periphery_contract.address) + bts_core = deploy_bts_core(bts_owner_manager.address) + sc += bts_core + + bts_periphery = deploy_bts_periphery(bts_core.address, helper_contract.address, + parse_address.address, bmc_periphery.address, + owner.address) sc += bts_periphery + fa2_dummy = fa2_dummy_file.SingleAssetToken(admin=owner.address, + metadata=sp.utils.metadata_of_url( + "ipfs://example"), + token_metadata=FA2.make_metadata(name="NativeWrappedCoin", decimals=6, + symbol="wTEZ")) + sc += fa2_dummy + + # BMC_MANAGEMENT SETTERS # set bmc periphery - bmc_management_contract.set_bmc_periphery(bmc_periphery_contract.address).run( - sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) - # set bmc_btp_address(netwrk address) - bmc_management_contract.set_bmc_btp_address("NetXnHfVqm9iesp.tezos").run( - sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) - # update_bts_periphery - bts_core_contract.update_bts_periphery(bts_periphery.address).run( - sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + bmc_management.set_bmc_periphery(bmc_periphery.address).run( + sender=owner.address) + + # set bmc_btp_address + bmc_management.set_bmc_btp_address("NetXnHfVqm9iesp.tezos").run( + sender=owner.address) + + # tear down changes after bmc btp address is set + tear_down_bmc() + # revert the path changes made in bts_core for testing + tear_down() # add_service svc1 = sp.string("bts") - bmc_management_contract.add_service(sp.record(addr=bts_periphery.address, svc=svc1)).run( - sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + bmc_management.add_service(sp.record(addr=bts_periphery.address, svc=svc1)).run( + sender=owner.address) # add_route - dst = "btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258dest" - next_link = "btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b" - bmc_management_contract.add_route(sp.record(dst=dst, link=next_link)).run( - sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) - - # # add_link - # bmc_management_contract.add_link("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b").run( - # sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) - - # # add_relay - # bmc_management_contract.add_relay(sp.record(link="btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b", - # addr=sp.set([sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")]))).run( - # sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) - - # test 1: Test of add to blacklist function - bts_periphery.add_to_blacklist({0: "notaaddress"}).run(sender=bts_periphery.address, valid=False, - exception="InvalidAddress") - bts_periphery.add_to_blacklist({0: "tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"}).run(sender=bts_periphery.address, - valid=True) - bts_periphery.add_to_blacklist({0: "tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"}).run(sender=bts_periphery.address, - valid=True) - bts_periphery.add_to_blacklist({0: "tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"}).run(sender=alice.address, valid=False, - exception="Unauthorized") - bts_periphery.add_to_blacklist({0: 'tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg'}).run(sender=bts_periphery.address, - valid=False, - exception='InvalidAddress') - sc.verify(bts_periphery.data.blacklist[ - sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW")] == True) - - # # transfer_native_coin + dst = "btp://0x7.icon/" + icon_bmc_address + next_link = "btp://0x7.icon/" + icon_bmc_address + bmc_management.add_route(sp.record(dst=dst, link=next_link)).run( + sender=owner.address) + + # add_link + bmc_management.add_link("btp://0x7.icon/" + icon_bmc_address).run( + sender=owner.address) + + # set_link_rx_height + bmc_management.set_link_rx_height(sp.record(height=icon_bmc_block_height, + link="btp://0x7.icon/" + icon_bmc_address)).run( + sender=owner.address) + + # add_relay + bmc_management.add_relay(sp.record(link="btp://0x7.icon/" + icon_bmc_address, + addr=sp.set([relay.address]))).run( + sender=owner.address) + + # BTS_CORE SETTERS + # update_bts_periphery + bts_core.update_bts_periphery(bts_periphery.address).run(sender=owner.address) + + # set_fee_ratio + bts_core.set_fee_ratio(name=sp.string("btp-NetXnHfVqm9iesp.tezos-XTZ"), fee_numerator=sp.nat(100), + fixed_fee=sp.nat(450)).run(sender=owner.address) + + prev = "btp://0x7.icon/" + icon_bmc_address + + # 1: Init message from relay + msg_byte = sp.bytes( + "0xf8e5f8e3b8e1f8df01b8d7f8d5f8d3b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b54315" + "6546d65565463637176336f707a6b625256725977616f535a5454457a664a386201b88ef88cb8396274703a2f2f3078372" + "e69636f6e2f637862376465363364623863316661326439646662366335333165366263313934303235373263633233b840" + "6274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b543156546d65565463637176336f707a6b6252567" + "25977616f535a5454457a664a386283626d630089c884496e697482c1c084009f639c") + bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) + + # # 2: Transfer 100 native coin + # bts_core.transfer_native_coin("btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d").run( + # sender=alice.address, amount=sp.tez(100)) + # + # # 3: relay msg for transfer end of step 2 with fee gathering + # msg_byte = sp.bytes( + # "0xf90218f90215b90212f9020f01b90206f90203f8e0b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b" + # "543156546d65565463637176336f707a6b625256725977616f535a5454457a664a386202b89bf899b8396274703a2f2f3078372e69636" + # "f6e2f637862376465363364623863316661326439646662366335333165366263313934303235373263633233b8406274703a2f2f4e657" + # "4586e486656716d39696573702e74657a6f732f4b543156546d65565463637176336f707a6b625256725977616f535a5454457a664a38" + # "62836274730196d50293d200905472616e736665722053756363657373f9011eb8406274703a2f2f4e6574586e486656716d396965737" + # "02e74657a6f732f4b543156546d65565463637176336f707a6b625256725977616f535a5454457a664a386203b8d9f8d7b8396274703a" + # "2f2f3078372e69636f6e2f637862376465363364623863316661326439646662366335333165366263313934303235373263633233b8" + # "406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b543156546d65565463637176336f707a6b62525672597761" + # "6f535a5454457a664a386283626d6300b853f8518c466565476174686572696e67b842f840b8396274703a2f2f3078372e69636f6e2f" + # "687866383061643730393832643637636437363438396665613966653036343239626362306266646531c4836274738400a01441") + # + # bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) + + # # transfer end of fee gathering + # msg_byte = sp.bytes("0xf8f2f8f0b8eef8ec01b8e4f8e2f8e0b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f" + # "4b543156546d65565463637176336f707a6b625256725977616f535a5454457a664a386204b89bf899b8396274703" + # "a2f2f3078372e69636f6e2f63786237646536336462386331666132643964666236633533316536626331393430323" + # "5373263633233b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b543156546d655654636" + # "37176336f707a6b625256725977616f535a5454457a664a3862836274730296d50293d200905472616e73666572205" + # "37563636573738400a01489") + # + # bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) + # + # # mint fa2 dummy + # fa2_dummy.mint([sp.record(to_=alice.address, amount=sp.nat(200000000))]).run(sender=owner.address) + # + # # add operator + # fa2_dummy.update_operators( + # [sp.variant("add_operator", sp.record(owner=alice.address, operator=bts_core.address, token_id=0))]).run( + # sender=alice.address) + # + # # register fa2 + # bts_core.register( + # name=sp.string("test"), + # fee_numerator=sp.nat(100), + # fixed_fee=sp.nat(450), + # addr=fa2_dummy.address, + # token_metadata=sp.map({"token_metadata": sp.bytes("0x0dae11")}), + # metadata=sp.big_map({"metadata": sp.bytes("0x0dae11")}) + # ).run(sender=owner.address) + # + # # 4: transfer fa2 token + # bts_core.transfer(sp.record( + # coin_name="test", value=50000000, to="btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d")).run( + # sender=alice.address) + + # 5: relay msg for transfer end of transfer fa2 + # msg_byte = sp.bytes( + # "") + + + # # test 1: Test of add to blacklist function + # bts_periphery.add_to_blacklist({0: "notaaddress"}).run(sender=bts_periphery.address, valid=False, + # exception="InvalidAddress") + # bts_periphery.add_to_blacklist({0: "tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"}).run(sender=bts_periphery.address, + # valid=True) + # bts_periphery.add_to_blacklist({0: "tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"}).run(sender=bts_periphery.address, + # valid=True) + # bts_periphery.add_to_blacklist({0: "tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"}).run(sender=alice.address, valid=False, + # exception="Unauthorized") + # bts_periphery.add_to_blacklist({0: 'tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg'}).run(sender=bts_periphery.address, + # valid=False, + # exception='InvalidAddress') + # sc.verify(bts_periphery.data.blacklist[ + # sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW")] == True) + # + # # # transfer_native_coin + # # bts_periphery.set_token_limit( + # # sp.record( + # # coin_names=sp.map({0: "btp-NetXnHfVqm9iesp.tezos-XTZ"}), + # # token_limit=sp.map({0: 115792089237316195423570985008687907853269984665640564039457584007913129639935}) + # # ) + # # ).run(sender = bts_core.address) + # # bts_core.transfer_native_coin("btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d").run(sender= sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), amount=sp.tez(30), valid=False, exception="FailCheckTransfer") + # # bts_core.transfer_native_coin("btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d").run( + # # sender=sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), amount=sp.tez(30)) + # + # # # handle_relay_message + # # msg = sp.bytes( + # # "0xf8e1f8dfb8ddf8db01b8d3f8d1f8cfb8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b54314657446a4338435941777268424a6d43355554596d594a544a6457776f3447676203b88af888b8396274703a2f2f3078372e69636f6e2f637833643436306163643535356336373034303566396562323934333833356366643132326662323938b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b54314657446a4338435941777268424a6d43355554596d594a544a6457776f344767628362747381ff84c328f8008400886513") + # # prev = sp.string("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b") + # # bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg)).run( + # # sender=owner.address) + # + # # test 2 : Test of remove from blacklist function + # bts_periphery.remove_from_blacklist({0: 'notaaddress'}).run(sender=bts_periphery.address, valid=False, + # exception="InvalidAddress") # invalid address + # bts_periphery.remove_from_blacklist({0: 'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=bts_periphery.address, + # valid=False, + # exception="UserNotFound") # address not black-listed + # bts_periphery.add_to_blacklist({0: 'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run( + # sender=bts_periphery.address) # adding to blacklist + # bts_periphery.remove_from_blacklist({0: 'tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run( + # sender=bts_periphery.address) # valid process + # bts_periphery.remove_from_blacklist({0: 'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=bts_periphery.address, + # valid=False, + # exception='UserNotFound') # cannot remove from blacklist twice + # bts_periphery.add_to_blacklist({0: 'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run( + # sender=bts_periphery.address) # adding to blacklist + # bts_periphery.remove_from_blacklist({0: 'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run( + # sender=bts_periphery.address) # can only be called from btseperiphery contract + # bts_periphery.remove_from_blacklist({0: 'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=alice.address, + # valid=False, + # exception="Unauthorized") # can only be called from btseperiphery contract + # + # # # transfer_native_coin + # # bts_periphery.set_token_limit( + # # sp.record( + # # coin_names=sp.map({0: "btp-NetXnHfVqm9iesp.tezos-XTZ"}), + # # token_limit=sp.map({0: 115792089237316195423570985008687907853269984665640564039457584007913129639935}) + # # ) + # # ).run(sender = bts_core.address) + # # bts_core.transfer_native_coin("btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d").run(sender= sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), amount=sp.tez(30)) + # + # # # transfer_native_coin + # # bts_periphery.set_token_limit( + # # sp.record( + # # coin_names=sp.map({0: "btp-NetXnHfVqm9iesp.tezos-XTZ"}), + # # token_limit=sp.map({0: 5}) + # # ) + # # ).run(sender = bts_core.address) + # # bts_core.transfer_native_coin("btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d").run(sender= sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), amount=sp.tez(30), valid=False, exception="FailCheckTransfer") + # + # # # bmc_periphery get_status + # # sc.verify_equal(bmc_periphery.get_status("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b"), sp.record(current_height = 0, rx_height = 2, rx_seq = 0, tx_seq = 6)) + # + # # test 3 : set token limit # bts_periphery.set_token_limit( - # sp.record( - # coin_names=sp.map({0: "btp-NetXnHfVqm9iesp.tezos-XTZ"}), - # token_limit=sp.map({0: 115792089237316195423570985008687907853269984665640564039457584007913129639935}) - # ) - # ).run(sender = bts_core_contract.address) - # bts_core_contract.transfer_native_coin("btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d").run(sender= sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), amount=sp.tez(30), valid=False, exception="FailCheckTransfer") - # bts_core_contract.transfer_native_coin("btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d").run( - # sender=sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), amount=sp.tez(30)) - - # # handle_relay_message - # msg = sp.bytes( - # "0xf8e1f8dfb8ddf8db01b8d3f8d1f8cfb8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b54314657446a4338435941777268424a6d43355554596d594a544a6457776f3447676203b88af888b8396274703a2f2f3078372e69636f6e2f637833643436306163643535356336373034303566396562323934333833356366643132326662323938b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b54314657446a4338435941777268424a6d43355554596d594a544a6457776f344767628362747381ff84c328f8008400886513") - # prev = sp.string("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b") - # bmc_periphery_contract.handle_relay_message(sp.record(prev=prev, msg=msg)).run( - # sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) - - # test 2 : Test of remove from blacklist function - bts_periphery.remove_from_blacklist({0: 'notaaddress'}).run(sender=bts_periphery.address, valid=False, - exception="InvalidAddress") # invalid address - bts_periphery.remove_from_blacklist({0: 'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=bts_periphery.address, - valid=False, - exception="UserNotFound") # address not black-listed - bts_periphery.add_to_blacklist({0: 'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run( - sender=bts_periphery.address) # adding to blacklist - bts_periphery.remove_from_blacklist({0: 'tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run( - sender=bts_periphery.address) # valid process - bts_periphery.remove_from_blacklist({0: 'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=bts_periphery.address, - valid=False, - exception='UserNotFound') # cannot remove from blacklist twice - bts_periphery.add_to_blacklist({0: 'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run( - sender=bts_periphery.address) # adding to blacklist - bts_periphery.remove_from_blacklist({0: 'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run( - sender=bts_periphery.address) # can only be called from btseperiphery contract - bts_periphery.remove_from_blacklist({0: 'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=alice.address, - valid=False, - exception="Unauthorized") # can only be called from btseperiphery contract - - # # transfer_native_coin + # sp.record(coin_names={0: "Tok2", 1: 'BB'}, token_limit={0: sp.nat(5), 1: sp.nat(2)})).run(sender=alice.address, + # valid=False, + # exception='Unauthorized') # can only be called from btsperiphery contract # bts_periphery.set_token_limit( - # sp.record( - # coin_names=sp.map({0: "btp-NetXnHfVqm9iesp.tezos-XTZ"}), - # token_limit=sp.map({0: 115792089237316195423570985008687907853269984665640564039457584007913129639935}) - # ) - # ).run(sender = bts_core_contract.address) - # bts_core_contract.transfer_native_coin("btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d").run(sender= sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), amount=sp.tez(30)) - - # # transfer_native_coin + # sp.record(coin_names={0: "Tok2", 1: 'BB'}, token_limit={0: sp.nat(5), 1: sp.nat(2)})).run( + # sender=bts_periphery.address) # set token limit for Tok2 coin to 5 and BB coin to 2 + # sc.verify(bts_periphery.data.token_limit["Tok2"] == sp.nat(5)) # test of token_limit for tok2 token + # bts_periphery.set_token_limit(sp.record(coin_names={0: "Tok2", 1: 'BB'}, token_limit={0: sp.nat(5)})).run( + # valid=False, exception='InvalidParams', sender=bts_periphery.address) # invalid parameters + # # cannot set more than 15 token limit at once # bts_periphery.set_token_limit( - # sp.record( - # coin_names=sp.map({0: "btp-NetXnHfVqm9iesp.tezos-XTZ"}), - # token_limit=sp.map({0: 5}) - # ) - # ).run(sender = bts_core_contract.address) - # bts_core_contract.transfer_native_coin("btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d").run(sender= sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), amount=sp.tez(30), valid=False, exception="FailCheckTransfer") - - # # bmc_periphery get_status - # sc.verify_equal(bmc_periphery_contract.get_status("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b"), sp.record(current_height = 0, rx_height = 2, rx_seq = 0, tx_seq = 6)) - - # test 3 : set token limit - bts_periphery.set_token_limit( - sp.record(coin_names={0: "Tok2", 1: 'BB'}, token_limit={0: sp.nat(5), 1: sp.nat(2)})).run(sender=alice.address, - valid=False, - exception='Unauthorized') # can only be called from btsperiphery contract - bts_periphery.set_token_limit( - sp.record(coin_names={0: "Tok2", 1: 'BB'}, token_limit={0: sp.nat(5), 1: sp.nat(2)})).run( - sender=bts_periphery.address) # set token limit for Tok2 coin to 5 and BB coin to 2 - sc.verify(bts_periphery.data.token_limit["Tok2"] == sp.nat(5)) # test of token_limit for tok2 token - bts_periphery.set_token_limit(sp.record(coin_names={0: "Tok2", 1: 'BB'}, token_limit={0: sp.nat(5)})).run( - valid=False, exception='InvalidParams', sender=bts_periphery.address) # invalid parameters - # cannot set more than 15 token limit at once - bts_periphery.set_token_limit( - sp.record(coin_names={0: "Tok2", 1: 'BB'}, token_limit={0: sp.nat(15), 1: sp.nat(22)})).run( - sender=bts_periphery.address) # can modify already set data - sc.verify(bts_periphery.data.token_limit["BB"] == sp.nat(22)) # test of token_limit for tok2 token - - # # handle_relay_message - # msg=sp.bytes("0xf90157f90154b90151f9014e01b90145f90142f9013fb8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5431454e5a76546f507838374c68756f774a315669786a6a715168536e597263594c6907b8faf8f8b8396274703a2f2f3078372e69636f6e2f637864633238393434343037363539393733666539393438376437356335646433326337396265303533b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5431454e5a76546f507838374c68756f774a315669786a6a715168536e597263594c698362747303b874f87200b86ff86daa687839643138316431336634376335616165353535623730393831346336623232393738373937363139a4747a3165703766664b7351434e64676e6b504443566e566b67626d465a50386d464e3147dcdb906274702d3078372e69636f6e2d4943588900d71b0fe0a28e000084008502ba") - # prev=sp.string("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b") - # bmc_periphery_contract.handle_relay_message(sp.record(prev=prev, msg=msg)).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) - - # set_fee_ratio - bts_core_contract.set_fee_ratio(name=sp.string("btp-NetXnHfVqm9iesp.tezos-XTZ"), fee_numerator=sp.nat(100), - fixed_fee=sp.nat(450)).run( - sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) + # sp.record(coin_names={0: "Tok2", 1: 'BB'}, token_limit={0: sp.nat(15), 1: sp.nat(22)})).run( + # sender=bts_periphery.address) # can modify already set data + # sc.verify(bts_periphery.data.token_limit["BB"] == sp.nat(22)) # test of token_limit for tok2 token + # + # # # handle_relay_message + # # msg=sp.bytes("0xf90157f90154b90151f9014e01b90145f90142f9013fb8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5431454e5a76546f507838374c68756f774a315669786a6a715168536e597263594c6907b8faf8f8b8396274703a2f2f3078372e69636f6e2f637864633238393434343037363539393733666539393438376437356335646433326337396265303533b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5431454e5a76546f507838374c68756f774a315669786a6a715168536e597263594c698362747303b874f87200b86ff86daa687839643138316431336634376335616165353535623730393831346336623232393738373937363139a4747a3165703766664b7351434e64676e6b504443566e566b67626d465a50386d464e3147dcdb906274702d3078372e69636f6e2d4943588900d71b0fe0a28e000084008502ba") + # # prev=sp.string("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b") + # # bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg)).run(sender=owner.address) -def deploy_bmc_management_contract(owner, helper): - bmc_management_contract = BMCManagement.BMCManagement(owner, helper) - return bmc_management_contract +def deploy_bmc_management(owner, helper): + bmc_management = BMCManagement.BMCManagement(owner, helper) + return bmc_management -def deploy_bmc_periphery_contract(bmc_addres, helper, parse): - owner = sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9") - bmc_periphery_contract = BMCPeriphery.BMCPreiphery(bmc_addres, helper, parse, owner) - return bmc_periphery_contract +def deploy_bmc_periphery(bmc_address, helper, helper_parse_neg_contract, parse, owner): + bmc_periphery = BMCPeriphery.BMCPreiphery(bmc_address, helper, helper_parse_neg_contract, parse, owner) + return bmc_periphery def deploy_helper_contract(): @@ -201,24 +393,24 @@ def deploy_parse_address(): return parse_address -def deploy_bts_core_contract(bts_owner_manager_contract): - bts_core_contract = BTSCore.BTSCore( +def deploy_bts_core(bts_owner_manager_contract): + bts_core = BTSCore.BTSCore( owner_manager=bts_owner_manager_contract, _native_coin_name="btp-NetXnHfVqm9iesp.tezos-XTZ", _fee_numerator=sp.nat(100), _fixed_fee=sp.nat(450) ) - return bts_core_contract + return bts_core -def deploy_bts_owner_manager_contract(): - bts_owner_manager_contract = BTSOwnerManager.BTSOwnerManager(sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) +def deploy_bts_owner_manager_contract(owner): + bts_owner_manager_contract = BTSOwnerManager.BTSOwnerManager(owner) return bts_owner_manager_contract -def deploy_bts_periphery_contract(core_address, helper, parse, bmc): - bts_periphery_contract = BTSPeriphery.BTPPreiphery(bmc_address=bmc, bts_core_address=core_address, +def deploy_bts_periphery(core_address, helper, parse, bmc, owner): + bts_periphery_contract = BTSPeriphery.BTSPeriphery(bmc_address=bmc, bts_core_address=core_address, helper_contract=helper, parse_address=parse, - owner_address=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), + owner_address=owner, native_coin_name="btp-NetXnHfVqm9iesp.tezos-XTZ") return bts_periphery_contract From 2df18311cd7977a589827569991f23475485b008 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Sun, 9 Jul 2023 09:02:01 +0545 Subject: [PATCH 144/211] fix: tezos verifier turned off --- cmd/iconbridge/chain/tezos/receiver.go | 30 +++++++++++++------------- cmd/iconbridge/chain/tezos/verifier.go | 6 +++--- cmd/iconbridge/example.config.json | 4 ++-- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/cmd/iconbridge/chain/tezos/receiver.go b/cmd/iconbridge/chain/tezos/receiver.go index f6950570..311a04a0 100644 --- a/cmd/iconbridge/chain/tezos/receiver.go +++ b/cmd/iconbridge/chain/tezos/receiver.go @@ -190,8 +190,8 @@ func (r *receiver) NewVerifier(ctx context.Context, previousHeight int64) (vri I return nil, err } - fmt.Println("header hash", block.Header.Hash) - fmt.Println("blockHeaderhash", block.Header.Hash) + // fmt.Println("header hash", block.Header.Hash) + // fmt.Println("blockHeaderhash", block.Header.Hash) vr := &Verifier{ mu: sync.RWMutex{}, @@ -204,7 +204,7 @@ func (r *receiver) NewVerifier(ctx context.Context, previousHeight int64) (vri I validatorsPublicKey: make(map[tezos.Address]tezos.Key), } - vr.updateValidatorsAndCycle(ctx, previousHeight, block.Metadata.LevelInfo.Cycle) + // vr.updateValidatorsAndCycle(ctx, previousHeight, block.Metadata.LevelInfo.Cycle) fmt.Println("cycle is ", vr.cycle) return vr, nil } @@ -656,18 +656,18 @@ func (r *receiver) receiveLoop2(ctx context.Context, opts *BnOptions, callback f } } else { if vr != nil { - if err := vr.Verify(ctx, lbn); err != nil { // change accordingly - r.log.WithFields(log.Fields{ - "height": lbn.Height, - "lbnHash": lbn.Hash, - "nextHeight": next, - "bnHash": bn.Hash}).Error("verification failed. refetching block ", err) - fmt.Println(err) - fmt.Println("error in verifying ") - time.Sleep(5 * time.Second) - next-- - break - } + // if err := vr.Verify(ctx, lbn); err != nil { // change accordingly + // r.log.WithFields(log.Fields{ + // "height": lbn.Height, + // "lbnHash": lbn.Hash, + // "nextHeight": next, + // "bnHash": bn.Hash}).Error("verification failed. refetching block ", err) + // fmt.Println(err) + // fmt.Println("error in verifying ") + // time.Sleep(5 * time.Second) + // next-- + // break + // } if err := vr.Update(ctx, lbn); err != nil { return errors.Wrapf(err, "receiveLoop: vr.Update: %v", err) } diff --git a/cmd/iconbridge/chain/tezos/verifier.go b/cmd/iconbridge/chain/tezos/verifier.go index 8324ae5f..4a8d7446 100644 --- a/cmd/iconbridge/chain/tezos/verifier.go +++ b/cmd/iconbridge/chain/tezos/verifier.go @@ -98,9 +98,9 @@ func (vr *Verifier) Update(ctx context.Context, lbn *types.BlockNotification) er vr.height = header.Level vr.next = header.Level + 1 - if vr.cycle != block.Metadata.LevelInfo.Cycle { - vr.updateValidatorsAndCycle(ctx, block.Header.Level, block.Metadata.LevelInfo.Cycle) - } + // if vr.cycle != block.Metadata.LevelInfo.Cycle { + // vr.updateValidatorsAndCycle(ctx, block.Header.Level, block.Metadata.LevelInfo.Cycle) + // } vr.lastVerifiedBn = lbn return nil diff --git a/cmd/iconbridge/example.config.json b/cmd/iconbridge/example.config.json index b8d56892..add30c31 100644 --- a/cmd/iconbridge/example.config.json +++ b/cmd/iconbridge/example.config.json @@ -19,7 +19,7 @@ "src": { "address": "btp://NetXnHfVqm9iesp.tezos/KT1VTmeVTccqv3opzkbRVrYwaoSZTTEzfJ8b", "endpoint": [ - "https://ghostnet.smartpy.io" + "https://rpc.ghost.tzstats.com" ], "options": { "verifier": { @@ -82,7 +82,7 @@ "dst": { "address": "btp://NetXnHfVqm9iesp.tezos/KT1VTmeVTccqv3opzkbRVrYwaoSZTTEzfJ8b", "endpoint": [ - "https://ghostnet.smartpy.io" + "https://rpc.ghost.tzstats.com" ], "options": { "gas_limit": 1040000, From 0d87810c2679833464b9e0c23b3300c16f6d012d Mon Sep 17 00:00:00 2001 From: simusud Date: Sun, 9 Jul 2023 16:21:16 +0545 Subject: [PATCH 145/211] test(bmc): variable name change and integration test update --- smartpy/bmc/contracts/src/RLP_struct.py | 6 +- smartpy/bmc/contracts/src/bmc_periphery.py | 3 +- .../bmc/contracts/tests/integration_test.py | 167 +++++++++--------- 3 files changed, 89 insertions(+), 87 deletions(-) diff --git a/smartpy/bmc/contracts/src/RLP_struct.py b/smartpy/bmc/contracts/src/RLP_struct.py index aee0a67d..28aeba3e 100644 --- a/smartpy/bmc/contracts/src/RLP_struct.py +++ b/smartpy/bmc/contracts/src/RLP_struct.py @@ -37,7 +37,8 @@ def decode_bmc_message(self, rlp): temp_map_string["svc"] = sp.view("decode_string", self.data.helper, k.value, t=sp.TString).open_some() sp.if counter.value == 3: sn_in_bytes = sp.view("without_length_prefix", self.data.helper, k.value, t=sp.TBytes).open_some() - temp_int.value = sp.view("to_int", self.data.helper_parse_negative, sn_in_bytes, t=sp.TInt).open_some() + _to_int = sp.view("to_int", self.data.helper_parse_negative, sn_in_bytes, t=sp.TInt).open_some() + temp_int.value = _to_int sp.if counter.value == 4: temp_byt.value = k.value counter.value = counter.value + 1 @@ -386,7 +387,8 @@ def encode_bmc_message(self, params): encode_src = sp.view("encode_string", self.data.helper, params.src, t=sp.TBytes).open_some() encode_dst = sp.view("encode_string", self.data.helper, params.dst, t=sp.TBytes).open_some() encode_svc = sp.view("encode_string", self.data.helper, params.svc, t=sp.TBytes).open_some() - rlp.value = sp.view("to_byte", self.data.helper_parse_negative, params.sn, t=sp.TBytes).open_some() + _to_byte = sp.view("to_byte", self.data.helper_parse_negative, params.sn, t=sp.TBytes).open_some() + rlp.value = _to_byte sp.if params.sn < sp.int(0): encode_sn = sp.view("with_length_prefix", self.data.helper, rlp.value, t=sp.TBytes).open_some() diff --git a/smartpy/bmc/contracts/src/bmc_periphery.py b/smartpy/bmc/contracts/src/bmc_periphery.py index 64e8c567..e83f5b82 100644 --- a/smartpy/bmc/contracts/src/bmc_periphery.py +++ b/smartpy/bmc/contracts/src/bmc_periphery.py @@ -66,10 +66,11 @@ def update_set_bmc_btp_address(self, ep): def set_bmc_btp_address(self, network): sp.set_type(network, sp.TString) + _self_address = sp.self_address sp.verify(sp.sender == self.data.bmc_management, "Unauthorized") with sp.if_(self.data.bmc_btp_address == sp.string("")): self.data.bmc_btp_address = sp.string("btp://") + network + "/" + \ - sp.view("add_to_str", self.data.parse_contract, sp.self_address, t=sp.TString).open_some() + sp.view("add_to_str", self.data.parse_contract, _self_address, t=sp.TString).open_some() with sp.else_(): sp.failwith("Address already set") diff --git a/smartpy/bmc/contracts/tests/integration_test.py b/smartpy/bmc/contracts/tests/integration_test.py index 78b73181..badca4a3 100644 --- a/smartpy/bmc/contracts/tests/integration_test.py +++ b/smartpy/bmc/contracts/tests/integration_test.py @@ -1,21 +1,13 @@ import subprocess - import smartpy as sp -FA2 = sp.io.import_script_from_url("https://legacy.smartpy.io/templates/fa2_lib.py") -BMCManagement = sp.io.import_script_from_url("file:./contracts/src/bmc_management.py") -BMCPeriphery = sp.io.import_script_from_url("file:./contracts/src/bmc_periphery.py") -BMCHelper = sp.io.import_script_from_url("file:./contracts/src/helper.py") -ParseAddress = sp.io.import_script_from_url("file:../bts/contracts/src/parse_address.py") -fa2_dummy_file = sp.io.import_script_from_url("file:./contracts/tests/fa2_dummy.py") - path = {"bts_core": [ {"types": ['types = sp.io.import_script_from_url("file:../bts/contracts/src/Types.py")', 'types = sp.io.import_script_from_url("file:./contracts/src/Types.py")']}, {"FA2_contract": [ 'FA2_contract = sp.io.import_script_from_url("file:../bts/contracts/src/FA2_contract.py")', 'FA2_contract = sp.io.import_script_from_url("file:./contracts/src/FA2_contract.py")']} -], + ], "bts_periphery": [ {"types": ['types = sp.io.import_script_from_url("file:../bts/contracts/src/Types.py")', 'types = sp.io.import_script_from_url("file:./contracts/src/Types.py")']}, @@ -25,32 +17,32 @@ 'rlp = sp.io.import_script_from_url("file:./contracts/src/RLP_struct.py")']}, ], - "RLP_struct": [ {"types": ['types = sp.io.import_script_from_url("file:../bts/contracts/src/Types.py")', 'types = sp.io.import_script_from_url("file:./contracts/src/Types.py")']}, - ] } path2 = { - # "RLP_struct": [ - # {'yy': - # [' yy = sp.view("encode_nat", self.data.helper, params.sn, t=sp.TBytes).open_some()', - # ' yy = sp.view("to_byte", self.data.helper_parse_negative, params.sn,' - # ' t=sp.TBytes).open_some()']}, - # {'xx': - # [' xx = Utils2.Int.of_bytes(sn_in_bytes)', - # ' xx = sp.view("to_int", self.data.helper_parse_negative, sn_in_bytes, t=sp.TInt)' - # '.open_some()'] - # - # } - # ], + "RLP_struct": [ + {'_to_byte': + [' _to_byte = sp.view("encode_nat", self.data.helper, sp.as_nat(params.sn), t=sp.TBytes).open_some()', + ' _to_byte = sp.view("to_byte", self.data.helper_parse_negative, params.sn,' + ' t=sp.TBytes).open_some()' + ] + }, + {'_to_int': + [' _to_int = sp.to_int(Utils2.Int.of_bytes(sn_in_bytes))', + ' _to_int = sp.view("to_int", self.data.helper_parse_negative, sn_in_bytes, t=sp.TInt)' + '.open_some()' + ] + } + ], "bmc_periphery": [ {'_self_address': - [' _self_address = "KT1VTmeVTccqv3opzkbRVrYwaoSZTTEzfJ8b"', - ' _self_address = sp.self_address' - ] + [' _self_address = sp.address("KT1VTmeVTccqv3opzkbRVrYwaoSZTTEzfJ8b")', + ' _self_address = sp.self_address' + ] } ] } @@ -80,7 +72,7 @@ def bmc_periphery_contract_deploy_setup(): patch_file_path("./contracts/src/" + key + ".py", lis1[0], y[0]) -def tear_down(): +def tear_down_bts_changes(): for key, value in path.items(): for i in value: lis1 = [] @@ -90,7 +82,7 @@ def tear_down(): patch_file_path("../bts/contracts/src/" + key + ".py", lis1[0], y[1]) -def tear_down_bmc(): +def tear_down_bmc_changes(): for key, value in path2.items(): for i in value: lis1 = [] @@ -108,8 +100,18 @@ def tear_down_bmc(): BTSOwnerManager = sp.io.import_script_from_url("file:../bts/contracts/src/bts_owner_manager.py") BTSPeriphery = sp.io.import_script_from_url("file:../bts/contracts/src/bts_periphery.py") +FA2 = sp.io.import_script_from_url("https://legacy.smartpy.io/templates/fa2_lib.py") +BMCManagement = sp.io.import_script_from_url("file:./contracts/src/bmc_management.py") +BMCPeriphery = sp.io.import_script_from_url("file:./contracts/src/bmc_periphery.py") +BMCHelper = sp.io.import_script_from_url("file:./contracts/src/helper.py") +ParseAddress = sp.io.import_script_from_url("file:../bts/contracts/src/parse_address.py") +fa2_dummy_file = sp.io.import_script_from_url("file:./contracts/tests/fa2_dummy.py") -@sp.add_test("BMCManagementTest") +# revert the path changes made in bts_core for testing +tear_down_bts_changes() + + +@sp.add_test("IntegrationTest") def test(): sc = sp.test_scenario() @@ -170,9 +172,7 @@ def test(): sender=owner.address) # tear down changes after bmc btp address is set - tear_down_bmc() - # revert the path changes made in bts_core for testing - tear_down() + tear_down_bmc_changes() # add_service svc1 = sp.string("bts") @@ -218,63 +218,62 @@ def test(): "25977616f535a5454457a664a386283626d630089c884496e697482c1c084009f639c") bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) - # # 2: Transfer 100 native coin - # bts_core.transfer_native_coin("btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d").run( - # sender=alice.address, amount=sp.tez(100)) - # - # # 3: relay msg for transfer end of step 2 with fee gathering - # msg_byte = sp.bytes( - # "0xf90218f90215b90212f9020f01b90206f90203f8e0b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b" - # "543156546d65565463637176336f707a6b625256725977616f535a5454457a664a386202b89bf899b8396274703a2f2f3078372e69636" - # "f6e2f637862376465363364623863316661326439646662366335333165366263313934303235373263633233b8406274703a2f2f4e657" - # "4586e486656716d39696573702e74657a6f732f4b543156546d65565463637176336f707a6b625256725977616f535a5454457a664a38" - # "62836274730196d50293d200905472616e736665722053756363657373f9011eb8406274703a2f2f4e6574586e486656716d396965737" - # "02e74657a6f732f4b543156546d65565463637176336f707a6b625256725977616f535a5454457a664a386203b8d9f8d7b8396274703a" - # "2f2f3078372e69636f6e2f637862376465363364623863316661326439646662366335333165366263313934303235373263633233b8" - # "406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b543156546d65565463637176336f707a6b62525672597761" - # "6f535a5454457a664a386283626d6300b853f8518c466565476174686572696e67b842f840b8396274703a2f2f3078372e69636f6e2f" - # "687866383061643730393832643637636437363438396665613966653036343239626362306266646531c4836274738400a01441") - # - # bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) - - # # transfer end of fee gathering - # msg_byte = sp.bytes("0xf8f2f8f0b8eef8ec01b8e4f8e2f8e0b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f" - # "4b543156546d65565463637176336f707a6b625256725977616f535a5454457a664a386204b89bf899b8396274703" - # "a2f2f3078372e69636f6e2f63786237646536336462386331666132643964666236633533316536626331393430323" - # "5373263633233b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b543156546d655654636" - # "37176336f707a6b625256725977616f535a5454457a664a3862836274730296d50293d200905472616e73666572205" - # "37563636573738400a01489") - # - # bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) - # - # # mint fa2 dummy - # fa2_dummy.mint([sp.record(to_=alice.address, amount=sp.nat(200000000))]).run(sender=owner.address) - # - # # add operator - # fa2_dummy.update_operators( - # [sp.variant("add_operator", sp.record(owner=alice.address, operator=bts_core.address, token_id=0))]).run( - # sender=alice.address) - # - # # register fa2 - # bts_core.register( - # name=sp.string("test"), - # fee_numerator=sp.nat(100), - # fixed_fee=sp.nat(450), - # addr=fa2_dummy.address, - # token_metadata=sp.map({"token_metadata": sp.bytes("0x0dae11")}), - # metadata=sp.big_map({"metadata": sp.bytes("0x0dae11")}) - # ).run(sender=owner.address) - # - # # 4: transfer fa2 token - # bts_core.transfer(sp.record( - # coin_name="test", value=50000000, to="btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d")).run( - # sender=alice.address) + # 2: Transfer 100 native coin + bts_core.transfer_native_coin("btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d").run( + sender=alice.address, amount=sp.tez(100)) + + # 3: relay msg for transfer end of step 2 with fee gathering + msg_byte = sp.bytes( + "0xf90218f90215b90212f9020f01b90206f90203f8e0b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b" + "543156546d65565463637176336f707a6b625256725977616f535a5454457a664a386202b89bf899b8396274703a2f2f3078372e69636" + "f6e2f637862376465363364623863316661326439646662366335333165366263313934303235373263633233b8406274703a2f2f4e657" + "4586e486656716d39696573702e74657a6f732f4b543156546d65565463637176336f707a6b625256725977616f535a5454457a664a38" + "62836274730196d50293d200905472616e736665722053756363657373f9011eb8406274703a2f2f4e6574586e486656716d396965737" + "02e74657a6f732f4b543156546d65565463637176336f707a6b625256725977616f535a5454457a664a386203b8d9f8d7b8396274703a" + "2f2f3078372e69636f6e2f637862376465363364623863316661326439646662366335333165366263313934303235373263633233b8" + "406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b543156546d65565463637176336f707a6b62525672597761" + "6f535a5454457a664a386283626d6300b853f8518c466565476174686572696e67b842f840b8396274703a2f2f3078372e69636f6e2f" + "687866383061643730393832643637636437363438396665613966653036343239626362306266646531c4836274738400a01441") + + bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) + + # transfer end of fee gathering + msg_byte = sp.bytes("0xf8f2f8f0b8eef8ec01b8e4f8e2f8e0b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f" + "4b543156546d65565463637176336f707a6b625256725977616f535a5454457a664a386204b89bf899b8396274703" + "a2f2f3078372e69636f6e2f63786237646536336462386331666132643964666236633533316536626331393430323" + "5373263633233b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b543156546d655654636" + "37176336f707a6b625256725977616f535a5454457a664a3862836274730296d50293d200905472616e73666572205" + "37563636573738400a01489") + + bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) + + # mint fa2 dummy + fa2_dummy.mint([sp.record(to_=alice.address, amount=sp.nat(200000000))]).run(sender=owner.address) + + # add operator + fa2_dummy.update_operators( + [sp.variant("add_operator", sp.record(owner=alice.address, operator=bts_core.address, token_id=0))]).run( + sender=alice.address) + + # register fa2 + bts_core.register( + name=sp.string("test"), + fee_numerator=sp.nat(100), + fixed_fee=sp.nat(450), + addr=fa2_dummy.address, + token_metadata=sp.map({"token_metadata": sp.bytes("0x0dae11")}), + metadata=sp.big_map({"metadata": sp.bytes("0x0dae11")}) + ).run(sender=owner.address) + + # 4: transfer fa2 token + bts_core.transfer(sp.record( + coin_name="test", value=50000000, to="btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d")).run( + sender=alice.address) # 5: relay msg for transfer end of transfer fa2 # msg_byte = sp.bytes( # "") - # # test 1: Test of add to blacklist function # bts_periphery.add_to_blacklist({0: "notaaddress"}).run(sender=bts_periphery.address, valid=False, # exception="InvalidAddress") From ba527acd678cba3120e19b3db49d1dbf44ce260f Mon Sep 17 00:00:00 2001 From: simusud Date: Sun, 9 Jul 2023 16:22:41 +0545 Subject: [PATCH 146/211] style(bts): typo fix --- smartpy/bts/contracts/src/bts_periphery.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index 99298496..b09c3c7d 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -81,7 +81,7 @@ def _add_to_blacklist(self, params): sp.set_type(params, sp.TList(sp.TString)) add_blacklist_status = sp.local("add_blacklist_status", "success") - addr_list = sp.ocal("addr_list", [], sp.TList(sp.TAddress)) + addr_list = sp.local("addr_list", [], sp.TList(sp.TAddress)) with sp.if_(sp.len(params) <= self.MAX_BATCH_SIZE): sp.for item in params: parsed_addr = sp.view("str_to_addr", self.data.parse_contract, item, t=sp.TAddress).open_some() @@ -108,19 +108,19 @@ def _remove_from_blacklist(self, params): sp.set_type(params, sp.TList(sp.TString)) remove_blacklist_status = sp.local("remove_blacklist_status", "success") - addr_list = sp.ocal("addr_list", [], sp.TList(sp.TAddress)) + addr_list = sp.local("addr_list", [], sp.TList(sp.TAddress)) with sp.if_(sp.len(params) <= self.MAX_BATCH_SIZE): sp.for item in params: parsed_addr = sp.view("str_to_addr", self.data.parse_contract, item, t=sp.TAddress).open_some() with sp.if_(remove_blacklist_status.value == "success"): - with sp.if_(parsed_addr == sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg") | - self.data.blacklist.contains(parsed_addr) == False): + with sp.if_((parsed_addr == sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")) | + (self.data.blacklist.contains(parsed_addr) == False)): remove_blacklist_status.value = "InvalidAddress" with sp.else_(): - addr_list.push(parsed_addr) + addr_list.value.push(parsed_addr) with sp.if_(remove_blacklist_status.value == "success"): - sp.for _item in addr_list: + sp.for _item in addr_list.value: del self.data.blacklist[_item] with sp.else_(): remove_blacklist_status.value = "InvalidAddress" @@ -412,7 +412,7 @@ def handle_response_service(self, sn, code, msg): bts_core_fa2_balance = sp.local("fa2_token_balance_response_service", sp.nat(0)) bts_core_address = self.data.bts_core - with sp.if_((loop.value <= self.MAX_BATCH_SIZE) & (caller.value == bts_core_address)): + with sp.if_(loop.value <= self.MAX_BATCH_SIZE): sp.for item in self.data.requests.get(sn).coin_details: with sp.if_(check_valid.value == True): coin_name = item.coin_name @@ -425,7 +425,8 @@ def handle_response_service(self, sn, code, msg): refundable_balance=sp.TNat, user_balance=sp.TNat) ).open_some() # check if caller has enough locked in bts_core - with sp.if_(bts_core_balance.locked_balance < amount): + # this case is for transfer fees + with sp.if_((bts_core_balance.locked_balance < amount) & (caller.value != bts_core_address)): check_valid.value = False coin_type = sp.view("coin_type", bts_core_address, coin_name, t=sp.TNat).open_some() From 214a8cb1709216eb4354237a0f98706828364270 Mon Sep 17 00:00:00 2001 From: suyogadhikari Date: Mon, 10 Jul 2023 11:14:38 +0545 Subject: [PATCH 147/211] fix(bts): verifying bts core token balance before burning token. --- smartpy/bts/contracts/src/bts_periphery.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index b09c3c7d..65471440 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -409,7 +409,6 @@ def handle_response_service(self, sn, code, msg): loop = sp.local("loop", sp.len(self.data.requests.get(sn).coin_details), sp.TNat) response_call_status = sp.local("response_call_status", "success") check_valid = sp.local("check_valid", True) - bts_core_fa2_balance = sp.local("fa2_token_balance_response_service", sp.nat(0)) bts_core_address = self.data.bts_core with sp.if_(loop.value <= self.MAX_BATCH_SIZE): @@ -431,8 +430,14 @@ def handle_response_service(self, sn, code, msg): coin_type = sp.view("coin_type", bts_core_address, coin_name, t=sp.TNat).open_some() with sp.if_(coin_type == sp.nat(1)): + # finding the balance of bts core to verify if bts core has enough tokens to burn + bts_core_fa2_balance = sp.view("balance_of", bts_core_address, + sp.record(owner=bts_core_address, coin_name=coin_name), t= + sp.TRecord(usable_balance=sp.TNat, locked_balance=sp.TNat, + refundable_balance=sp.TNat, user_balance=sp.TNat) + ).open_some() # check if bts_core has enough NATIVE_WRAPPED_COIN_TYPE to burn - with sp.if_(bts_core_balance.user_balance < value): + with sp.if_(bts_core_fa2_balance.user_balance < value): check_valid.value = False with sp.if_(check_valid.value == True): From 4711088b474b329efccdb91e1eec0272297fc1d3 Mon Sep 17 00:00:00 2001 From: simusud Date: Tue, 11 Jul 2023 14:30:20 +0545 Subject: [PATCH 148/211] test(bmc): updated integration test and added fa2 dummy contract --- smartpy/bmc/contracts/tests/fa2_dummy.py | 33 + .../bmc/contracts/tests/integration_test.py | 584 +++++++++++++----- 2 files changed, 456 insertions(+), 161 deletions(-) create mode 100644 smartpy/bmc/contracts/tests/fa2_dummy.py diff --git a/smartpy/bmc/contracts/tests/fa2_dummy.py b/smartpy/bmc/contracts/tests/fa2_dummy.py new file mode 100644 index 00000000..84d9915d --- /dev/null +++ b/smartpy/bmc/contracts/tests/fa2_dummy.py @@ -0,0 +1,33 @@ +import smartpy as sp + +FA2 = sp.io.import_script_from_url("https://legacy.smartpy.io/templates/fa2_lib.py") + + +class SingleAssetToken(FA2.Admin, FA2.Fa2SingleAsset, FA2.MintSingleAsset, FA2.BurnSingleAsset, + FA2.OnchainviewBalanceOf): + def __init__(self, admin, metadata, token_metadata): + FA2.Fa2SingleAsset.__init__(self, metadata=metadata, token_metadata=token_metadata) + FA2.Admin.__init__(self, admin) + + @sp.onchain_view() + def is_admin(self, address): + sp.result(address == self.data.administrator) + + +# @sp.add_test(name="FA2DummyContract") +# def test(): +# alice = sp.test_account("Alice") +# +# c1 = SingleAssetToken(admin=alice.address, metadata=sp.big_map({"ss": sp.bytes("0x0dae11")}), +# token_metadata=sp.map({"ff": sp.bytes("0x0dae11")})) +# +# scenario = sp.test_scenario() +# scenario += c1 + + +sp.add_compilation_target("fa2_dummy", + SingleAssetToken( + admin=sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP"), + metadata=sp.utils.metadata_of_url( + "ipfs://example"), + token_metadata=FA2.make_metadata(name="NativeWrappedCoin", decimals=6, symbol="WTEZ"))) diff --git a/smartpy/bmc/contracts/tests/integration_test.py b/smartpy/bmc/contracts/tests/integration_test.py index badca4a3..b785cc17 100644 --- a/smartpy/bmc/contracts/tests/integration_test.py +++ b/smartpy/bmc/contracts/tests/integration_test.py @@ -1,13 +1,16 @@ import subprocess import smartpy as sp -path = {"bts_core": [ +t_balance_of_request = sp.TRecord(owner=sp.TAddress, token_id=sp.TNat).layout(("owner", "token_id")) +t_balance_of_response = sp.TRecord(request=t_balance_of_request, balance=sp.TNat).layout(("request", "balance")) + +path_bts = {"bts_core": [ {"types": ['types = sp.io.import_script_from_url("file:../bts/contracts/src/Types.py")', 'types = sp.io.import_script_from_url("file:./contracts/src/Types.py")']}, {"FA2_contract": [ 'FA2_contract = sp.io.import_script_from_url("file:../bts/contracts/src/FA2_contract.py")', 'FA2_contract = sp.io.import_script_from_url("file:./contracts/src/FA2_contract.py")']} - ], +], "bts_periphery": [ {"types": ['types = sp.io.import_script_from_url("file:../bts/contracts/src/Types.py")', 'types = sp.io.import_script_from_url("file:./contracts/src/Types.py")']}, @@ -23,37 +26,40 @@ ] } -path2 = { +path_bmc = { "RLP_struct": [ {'_to_byte': - [' _to_byte = sp.view("encode_nat", self.data.helper, sp.as_nat(params.sn), t=sp.TBytes).open_some()', - ' _to_byte = sp.view("to_byte", self.data.helper_parse_negative, params.sn,' - ' t=sp.TBytes).open_some()' - ] - }, + [ + ' _to_byte = sp.view("encode_nat", self.data.helper, sp.as_nat(params.sn), t=sp.TBytes).open_some()', + ' _to_byte = sp.view("to_byte", self.data.helper_parse_negative, params.sn,' + ' t=sp.TBytes).open_some()' + ] + }, {'_to_int': - [' _to_int = sp.to_int(Utils2.Int.of_bytes(sn_in_bytes))', - ' _to_int = sp.view("to_int", self.data.helper_parse_negative, sn_in_bytes, t=sp.TInt)' - '.open_some()' - ] + [' _to_int = sp.to_int(Utils2.Int.of_bytes(sn_in_bytes))', + ' _to_int = sp.view("to_int", self.data.helper_parse_negative, sn_in_bytes, t=sp.TInt)' + '.open_some()' + ] } ], "bmc_periphery": [ {'_self_address': - [' _self_address = sp.address("KT1VTmeVTccqv3opzkbRVrYwaoSZTTEzfJ8b")', - ' _self_address = sp.self_address' - ] + [' _self_address = sp.address("KT1WKBHLFbgL8QJWGySf5CK2hK3iCLEM9ZiT")', + ' _self_address = sp.self_address' + ] } ] } +# in cas of new env: change above _self_address to bmc_periphery address of new env + def patch_file_path(file_name, old_value, new_value): subprocess.call("sed -i -e 's#.*" + old_value + " =.*#" + new_value + "#' " + file_name, shell=True) def bts_core_contract_deploy_setup(): - for key, value in path.items(): + for key, value in path_bts.items(): for i in value: lis1 = [] for x, y in i.items(): @@ -63,7 +69,7 @@ def bts_core_contract_deploy_setup(): def bmc_periphery_contract_deploy_setup(): - for key, value in path2.items(): + for key, value in path_bmc.items(): for i in value: lis1 = [] for x, y in i.items(): @@ -73,7 +79,7 @@ def bmc_periphery_contract_deploy_setup(): def tear_down_bts_changes(): - for key, value in path.items(): + for key, value in path_bts.items(): for i in value: lis1 = [] for x, y in i.items(): @@ -83,7 +89,7 @@ def tear_down_bts_changes(): def tear_down_bmc_changes(): - for key, value in path2.items(): + for key, value in path_bmc.items(): for i in value: lis1 = [] for x, y in i.items(): @@ -116,21 +122,20 @@ def test(): sc = sp.test_scenario() # test account - alice = sp.test_account("Alice") owner = sp.test_account("Owner") - jack = sp.test_account("Jack") - bob = sp.test_account("Bob") - creator2 = sp.test_account("creator2") - service1_address = sp.test_account("service1_address") - service2_address = sp.test_account("service2_address") + alice = sp.address("tz1ep7ffKsQCNdgnkPDCVnVkgbmFZP8mFN1G") + bob = sp.address("tz1euHP1ntD4r3rv8BsE5pXpTRBnUFu69wYP") + jack = sp.address("tz1UUvTndciyJJXuPHBEvWxuM9qgECMV31eA") + sam = sp.address("tz1MrAHP91XLXJXBoB3WL52zQ8VDcnH5PeMp") relay = sp.test_account("Relay") helper_parse_neg_contract = sp.test_account("helper_parse_neg_contract") - # Change icon_bmc_address for new environment - icon_bmc_address = "cxb7de63db8c1fa2d9dfb6c531e6bc19402572cc23" - icon_bmc_block_height = 10445602 + # in cas of new env: change icon_bmc_address and its block height of new environment + icon_bmc_address = "cx51e0bb85839e0e3fffb4c0140ae0f083e898464d" + icon_bmc_block_height = 10660605 + + # deploy contracts - # deploy BMCManagement contract helper_contract = deploy_helper_contract() sc += helper_contract @@ -162,6 +167,14 @@ def test(): symbol="wTEZ")) sc += fa2_dummy + fa2_dummy_second = fa2_dummy_file.SingleAssetToken(admin=owner.address, + metadata=sp.utils.metadata_of_url( + "ipfs://example"), + token_metadata=FA2.make_metadata(name="Dummy", + decimals=6, + symbol="PEPE")) + sc += fa2_dummy_second + # BMC_MANAGEMENT SETTERS # set bmc periphery bmc_management.set_bmc_periphery(bmc_periphery.address).run( @@ -209,167 +222,416 @@ def test(): prev = "btp://0x7.icon/" + icon_bmc_address - # 1: Init message from relay + # Tests + # Scenario 1: Init message from relay + msg_byte = sp.bytes( + "0xf8e5f8e3b8e1f8df01b8d7f8d5f8d3b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5431574b42484c" + "4662674c38514a574779536635434b32684b3369434c454d395a695401b88ef88cb8396274703a2f2f3078372e69636f6e2f63783531" + "6530626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f2f4e6574586e486656" + "716d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a695483626d63" + "0089c884496e697482c1c08400a2aba8") + bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) + + # Scenario 2: Add to blacklist called from icon + # add bob and tz1bPkYCh5rTTGL7DuPLB66J8zqnUD8cMRq1 + msg_byte = sp.bytes( + "0xf9014df9014ab90147f9014401b9013bf90138f90135b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5" + "431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a695402b8f0f8eeb8396274703a2f2f3078372e69636" + "f6e2f637835316530626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f2f4e6" + "574586e486656716d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395" + "a69548362747301b86af86803b865f86300f84aa4747a3165754850316e7444347233727638427345357058705452426e55467536397" + "75950a4747a3162506b59436835725454474c374475504c4236364a387a716e554438634d527131954e6574586e486656716d3969657" + "3702e74657a6f738400a2ac69") + bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) + # verify blacklisted address + sc.verify_equal(bts_periphery.data.blacklist, {sp.address("tz1euHP1ntD4r3rv8BsE5pXpTRBnUFu69wYP"): True, + sp.address("tz1bPkYCh5rTTGL7DuPLB66J8zqnUD8cMRq1"): True}) + + # Scenario 3: Remove from blacklist called from icon + # remove bob + msg_byte = sp.bytes( + "0xf90127f90124b90121f9011e01b90115f90112f9010fb8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b" + "5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a695403b8caf8c8b8396274703a2f2f3078372e6963" + "6f6e2f637835316530626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f2f4e" + "6574586e486656716d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d39" + "5a69548362747302b844f84203b83ff83d01e5a4747a3165754850316e7444347233727638427345357058705452426e554675363977" + "5950954e6574586e486656716d39696573702e74657a6f738400a2ac8c") + bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) + # verify one blacklisted address is removed + sc.verify(bts_periphery.data.blacklist.get(sp.address("tz1bPkYCh5rTTGL7DuPLB66J8zqnUD8cMRq1")) == True) + + # Scenario 4: Transfer native coin from icon to tezos + # transferred: ICX: 25*10**18 + # fee deducted on icon: 4550000000000000000 + # receiver address: bob + + # register icon native coin + bts_core.register( + name=sp.string("btp-0x7.icon-ICX"), + fee_numerator=sp.nat(100), + fixed_fee=sp.nat(4300000000000000000), + addr=sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg"), + token_metadata=sp.map({"token_metadata": sp.bytes("0x0dae11")}), + metadata=sp.big_map({"metadata": sp.bytes("0x0dae11")}) + ).run(sender=owner.address) + + msg_byte = sp.bytes( + "0xf90157f90154b90151f9014e01b90145f90142f9013fb8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5" + "431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a695404b8faf8f8b8396274703a2f2f3078372e69636f" + "6e2f637835316530626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f2f4e657" + "4586e486656716d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a69" + "548362747303b874f87200b86ff86daa68783964313831643133663437633561616535353562373039383134633662323239373837393" + "7363139a4747a3165754850316e7444347233727638427345357058705452426e5546753639775950dcdb906274702d3078372e69636f" + "6e2d49435889011bccfea6b8bd00008400a2acd5") + bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) + # verify native coin balance + coin_address = bts_core.data.coins.get("btp-0x7.icon-ICX") + user_balance = sp.view("get_balance_of", coin_address, + [sp.record(owner=bob, token_id=sp.nat(0))], + t=sp.TList(t_balance_of_response)).open_some("Invalid view") + + sc.verify_equal(user_balance, [sp.record(request=sp.record(owner=bob, + token_id=sp.nat(0)), + balance=sp.nat(20450000000000000000))]) + + # Scenario 5: Transfer ICON IRC2 coin bnUSD4 from icon to tezos without registering on tezos + # transferred: bnUSD4: 50*10**18 + # receiver address: jack + msg_byte = sp.bytes( + "0xf9015af90157b90154f9015101b90148f90145f90142b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b" + "5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a695405b8fdf8fbb8396274703a2f2f3078372e6963" + "6f6e2f637835316530626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f2f4e" + "6574586e486656716d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d39" + "5a69548362747304b877f87500b872f870aa687839643138316431336634376335616165353535623730393831346336623232393738" + "373937363139a4747a31555576546e646369794a4a587550484245765778754d39716745434d5633316541dfde936274702d3078372e" + "69636f6e2d626e555344348902b5e3af16b18800008400a2ad38") + bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) + # no changes happen on tezos so no need to assert + + # Scenario 6: Transfer ICON IRC2 coin bnUSD4 from icon to tezos + # transferred: bnUSD4: 50*10**18 + # receiver address: jack + # register icon coin bnUSD4 + bts_core.register( + name=sp.string("btp-0x7.icon-bnUSD4"), + fee_numerator=sp.nat(0), + fixed_fee=sp.nat(0), + addr=sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg"), + token_metadata=sp.map({"token_metadata": sp.bytes("0x0dae11")}), + metadata=sp.big_map({"metadata": sp.bytes("0x0dae11")}) + ).run(sender=owner.address) + + msg_byte = sp.bytes( + "0xf9015af90157b90154f9015101b90148f90145f90142b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5" + "431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a695406b8fdf8fbb8396274703a2f2f3078372e69636f" + "6e2f637835316530626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f2f4e657" + "4586e486656716d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a69" + "548362747305b877f87500b872f870aa68783964313831643133663437633561616535353562373039383134633662323239373837393" + "7363139a4747a31555576546e646369794a4a587550484245765778754d39716745434d5633316541dfde936274702d3078372e69636f" + "6e2d626e555344348902b5e3af16b18800008400a2b0cd") + bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) + # verify bnUSD4 coin balance + coin_address = bts_core.data.coins.get("btp-0x7.icon-bnUSD4") + user_balance = sp.view("get_balance_of", coin_address, + [sp.record(owner=jack, token_id=sp.nat(0))], + t=sp.TList(t_balance_of_response)).open_some("Invalid view") + + sc.verify_equal(user_balance, [sp.record(request=sp.record(owner=jack, + token_id=sp.nat(0)), + balance=sp.nat(50000000000000000000))]) + + # Scenario 7: Transfer batch from icon to tezos + # transferred: icon native coin: 20*10**18 and bnUSD4:14*10**18 + # receiver address: alice + msg_byte = sp.bytes( + "0xf90179f90176b90173f9017001b90167f90164f90161b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b" + "5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a695407b9011bf90118b8396274703a2f2f3078372e" + "69636f6e2f637835316530626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f" + "2f4e6574586e486656716d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c45" + "4d395a69548362747306b894f89200b88ff88daa68783964313831643133663437633561616535353562373039383134633662323239" + "3738373937363139a4747a3165703766664b7351434e64676e6b504443566e566b67626d465a50386d464e3147f83bdb906274702d30" + "78372e69636f6e2d4943588900d71b0fe0a28e0000de936274702d3078372e69636f6e2d626e555344348900c249fdd3277800008400" + "a2b1a7") + bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) + # verify native coin balance + coin_address = bts_core.data.coins.get("btp-0x7.icon-ICX") + user_balance = sp.view("get_balance_of", coin_address, + [sp.record(owner=alice, token_id=sp.nat(0))], + t=sp.TList(t_balance_of_response)).open_some("Invalid view") + + sc.verify_equal(user_balance, [sp.record(request=sp.record(owner=alice, + token_id=sp.nat(0)), + balance=sp.nat(15500000000000000000))]) + + # verify bnUSD4 coin balance + coin_address = bts_core.data.coins.get("btp-0x7.icon-bnUSD4") + user_balance = sp.view("get_balance_of", coin_address, + [sp.record(owner=alice, token_id=sp.nat(0))], + t=sp.TList(t_balance_of_response)).open_some("Invalid view") + + sc.verify_equal(user_balance, [sp.record(request=sp.record(owner=alice, + token_id=sp.nat(0)), + balance=sp.nat(14000000000000000000))]) + + # Scenario 8: Transfer batch from icon to tezos + # transferred 20 *10**18 bnUSD4 + # receiver address: alice msg_byte = sp.bytes( - "0xf8e5f8e3b8e1f8df01b8d7f8d5f8d3b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b54315" - "6546d65565463637176336f707a6b625256725977616f535a5454457a664a386201b88ef88cb8396274703a2f2f3078372" - "e69636f6e2f637862376465363364623863316661326439646662366335333165366263313934303235373263633233b840" - "6274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b543156546d65565463637176336f707a6b6252567" - "25977616f535a5454457a664a386283626d630089c884496e697482c1c084009f639c") + "0xf9015af90157b90154f9015101b90148f90145f90142b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b" + "5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a695408b8fdf8fbb8396274703a2f2f3078372e6963" + "6f6e2f637835316530626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f2f4e" + "6574586e486656716d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d39" + "5a69548362747307b877f87500b872f870aa687839643138316431336634376335616165353535623730393831346336623232393738" + "373937363139a4747a3165703766664b7351434e64676e6b504443566e566b67626d465a50386d464e3147dfde936274702d3078372e" + "69636f6e2d626e555344348901158e460913d000008400a2b1de") bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) - # 2: Transfer 100 native coin - bts_core.transfer_native_coin("btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d").run( - sender=alice.address, amount=sp.tez(100)) + # verify bnUSD4 coin balance + # alice had 14*10**18 bnUSD4 initially + coin_address = bts_core.data.coins.get("btp-0x7.icon-bnUSD4") + user_balance = sp.view("get_balance_of", coin_address, + [sp.record(owner=alice, token_id=sp.nat(0))], + t=sp.TList(t_balance_of_response)).open_some("Invalid view") - # 3: relay msg for transfer end of step 2 with fee gathering + sc.verify_equal(user_balance, [sp.record(request=sp.record(owner=alice, + token_id=sp.nat(0)), + balance=sp.nat(14000000000000000000 + 20000000000000000000))]) + + # Scenario 9: Set token limit of bnUSD4 from icon + # token limit of bnUSD4: 21 * 10**18 msg_byte = sp.bytes( - "0xf90218f90215b90212f9020f01b90206f90203f8e0b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b" - "543156546d65565463637176336f707a6b625256725977616f535a5454457a664a386202b89bf899b8396274703a2f2f3078372e69636" - "f6e2f637862376465363364623863316661326439646662366335333165366263313934303235373263633233b8406274703a2f2f4e657" - "4586e486656716d39696573702e74657a6f732f4b543156546d65565463637176336f707a6b625256725977616f535a5454457a664a38" - "62836274730196d50293d200905472616e736665722053756363657373f9011eb8406274703a2f2f4e6574586e486656716d396965737" - "02e74657a6f732f4b543156546d65565463637176336f707a6b625256725977616f535a5454457a664a386203b8d9f8d7b8396274703a" - "2f2f3078372e69636f6e2f637862376465363364623863316661326439646662366335333165366263313934303235373263633233b8" - "406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b543156546d65565463637176336f707a6b62525672597761" - "6f535a5454457a664a386283626d6300b853f8518c466565476174686572696e67b842f840b8396274703a2f2f3078372e69636f6e2f" - "687866383061643730393832643637636437363438396665613966653036343239626362306266646531c4836274738400a01441") + "0xf9011ef9011bb90118f9011501b9010cf90109f90106b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b" + "5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a695409b8c1f8bfb8396274703a2f2f3078372e6963" + "6f6e2f637835316530626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f2f4e" + "6574586e486656716d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d39" + "5a69548362747308b83bf83904b7f6d4936274702d3078372e69636f6e2d626e55534434ca8901236efcbcbb340000954e6574586e48" + "6656716d39696573702e74657a6f738400a2b1fb") + bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) + # verify token limit + sc.verify(bts_periphery.data.token_limit.get("btp-0x7.icon-bnUSD4") == sp.nat(21000000000000000000)) + + # Scenario 10: Set token limit of btp-0x7.icon-bnUSD4 and btp-0x7.icon-ICX from icon + # token limit of btp-0x7.icon-ICX: 43*10**18 + # token limit of btp-0x7.icon-bnUSD4: 32*10**18 + msg_byte = sp.bytes( + "0xf9013bf90138b90135f9013201b90129f90126f90123b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b" + "5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a69540ab8def8dcb8396274703a2f2f3078372e696" + "36f6e2f637835316530626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f2f" + "4e6574586e486656716d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454" + "d395a69548362747309b858f85604b853f851e5936274702d3078372e69636f6e2d626e55534434906274702d3078372e69636f6e2d" + "494358d48901bc16d674ec800000890254beb02d1dcc0000954e6574586e486656716d39696573702e74657a6f738400a2b21a") + bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) + # verify token limits + sc.verify(bts_periphery.data.token_limit.get("btp-0x7.icon-ICX") == sp.nat(43000000000000000000)) + sc.verify(bts_periphery.data.token_limit.get("btp-0x7.icon-bnUSD4") == sp.nat(32000000000000000000)) + # Scenario 11: Transfer btp-0x7.icon-bnUSD4 from icon to tezos + # transferred btp-0x7.icon-bnUSD4: 32*10**18 + # receiver address: sam + msg_byte = sp.bytes( + "0xf9015af90157b90154f9015101b90148f90145f90142b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b" + "5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a69540bb8fdf8fbb8396274703a2f2f3078372e6963" + "6f6e2f637835316530626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f2f4e" + "6574586e486656716d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d39" + "5a6954836274730ab877f87500b872f870aa687839643138316431336634376335616165353535623730393831346336623232393738" + "373937363139a4747a314d724148503931584c584a58426f4233574c35327a51385644636e483550654d70dfde936274702d3078372e" + "69636f6e2d626e555344348901bc16d674ec8000008400a2b246") bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) + # verify bnUSD4 coin balance + coin_address = bts_core.data.coins.get("btp-0x7.icon-bnUSD4") + user_balance = sp.view("get_balance_of", coin_address, + [sp.record(owner=sam, token_id=sp.nat(0))], + t=sp.TList(t_balance_of_response)).open_some("Invalid view") + + sc.verify_equal(user_balance, [sp.record(request=sp.record(owner=sam, + token_id=sp.nat(0)), + balance=sp.nat(32000000000000000000))]) + + # Tezos to icon scenarios + + # Scenario 12: Transfer native coin from tezos to icon + # transferred btp-NetXnHfVqm9iesp.tezos-XTZ: 9000000 + # fee deducted on tezos: 90450 + + bts_core.transfer_native_coin("btp://0x7.icon/hx9d181d13f47c5aae555b709814c6b22978797619").run( + sender=alice, amount=sp.tez(9000000)) - # transfer end of fee gathering - msg_byte = sp.bytes("0xf8f2f8f0b8eef8ec01b8e4f8e2f8e0b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f" - "4b543156546d65565463637176336f707a6b625256725977616f535a5454457a664a386204b89bf899b8396274703" - "a2f2f3078372e69636f6e2f63786237646536336462386331666132643964666236633533316536626331393430323" - "5373263633233b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b543156546d655654636" - "37176336f707a6b625256725977616f535a5454457a664a3862836274730296d50293d200905472616e73666572205" - "37563636573738400a01489") + # relay msg for transfer end + msg_byte = sp.bytes( + "0xf8f2f8f0b8eef8ec01b8e4f8e2f8e0b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5431574b42484c4" + "662674c38514a574779536635434b32684b3369434c454d395a69540eb89bf899b8396274703a2f2f3078372e69636f6e2f6378353165" + "30626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f2f4e6574586e486656716" + "d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a6954836274730396" + "d50293d200905472616e7366657220537563636573738400a2b6aa") bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) + # verify aggregation fee + sc.verify(bts_core.data.aggregation_fee.get("btp-NetXnHfVqm9iesp.tezos-XTZ") == sp.nat(90450)) + + # Scenario 13: Transfer wrapped token of btp-NetXnHfVqm9iesp.tezos-XTZ from icon to tezos + # receiver address: tz1MrAHP91XLXJXBoB3WL52zQ8VDcnH5PeMp + # received amount: 3*10**6 + + msg_byte = sp.bytes("0xf9015ff9015cb90159f9015601b9014df9014af90147b8406274703a2f2f4e6574586e486656716d39696573702" + "e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a69540fb9010" + "1f8ffb8396274703a2f2f3078372e69636f6e2f63783531653062623835383339653065336666666234633031343" + "0616530663038336538393834363464b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4" + "b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a6954836274730bb87bf87900b" + "876f874aa68783964313831643133663437633561616535353562373039383134633662323239373837393736313" + "9a4747a314d724148503931584c584a58426f4233574c35327a51385644636e483550654d70e3e29d6274702d4e6" + "574586e486656716d39696573702e74657a6f732d58545a832dc6c08400a2b839") + bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) + # Scenario 14: Transfer fa2 token from tezos to icon # mint fa2 dummy - fa2_dummy.mint([sp.record(to_=alice.address, amount=sp.nat(200000000))]).run(sender=owner.address) + fa2_dummy.mint([sp.record(to_=alice, amount=sp.nat(1000000000))]).run(sender=owner.address) # add operator fa2_dummy.update_operators( - [sp.variant("add_operator", sp.record(owner=alice.address, operator=bts_core.address, token_id=0))]).run( - sender=alice.address) + [sp.variant("add_operator", sp.record(owner=alice, operator=bts_core.address, token_id=0))]).run( + sender=alice) # register fa2 bts_core.register( - name=sp.string("test"), - fee_numerator=sp.nat(100), - fixed_fee=sp.nat(450), + name=sp.string("btp-0x7.tezos-fa2"), + fee_numerator=sp.nat(0), + fixed_fee=sp.nat(0), addr=fa2_dummy.address, token_metadata=sp.map({"token_metadata": sp.bytes("0x0dae11")}), metadata=sp.big_map({"metadata": sp.bytes("0x0dae11")}) ).run(sender=owner.address) - # 4: transfer fa2 token + # transfer fa2 token bts_core.transfer(sp.record( - coin_name="test", value=50000000, to="btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d")).run( - sender=alice.address) + coin_name="btp-0x7.tezos-fa2", value=10000000, + to="btp://0x7.icon/hx9d181d13f47c5aae555b709814c6b22978797619")).run(sender=alice) - # 5: relay msg for transfer end of transfer fa2 - # msg_byte = sp.bytes( - # "") - - # # test 1: Test of add to blacklist function - # bts_periphery.add_to_blacklist({0: "notaaddress"}).run(sender=bts_periphery.address, valid=False, - # exception="InvalidAddress") - # bts_periphery.add_to_blacklist({0: "tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"}).run(sender=bts_periphery.address, - # valid=True) - # bts_periphery.add_to_blacklist({0: "tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"}).run(sender=bts_periphery.address, - # valid=True) - # bts_periphery.add_to_blacklist({0: "tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"}).run(sender=alice.address, valid=False, - # exception="Unauthorized") - # bts_periphery.add_to_blacklist({0: 'tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg'}).run(sender=bts_periphery.address, - # valid=False, - # exception='InvalidAddress') - # sc.verify(bts_periphery.data.blacklist[ - # sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW")] == True) - # - # # # transfer_native_coin - # # bts_periphery.set_token_limit( - # # sp.record( - # # coin_names=sp.map({0: "btp-NetXnHfVqm9iesp.tezos-XTZ"}), - # # token_limit=sp.map({0: 115792089237316195423570985008687907853269984665640564039457584007913129639935}) - # # ) - # # ).run(sender = bts_core.address) - # # bts_core.transfer_native_coin("btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d").run(sender= sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), amount=sp.tez(30), valid=False, exception="FailCheckTransfer") - # # bts_core.transfer_native_coin("btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d").run( - # # sender=sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), amount=sp.tez(30)) - # - # # # handle_relay_message - # # msg = sp.bytes( - # # "0xf8e1f8dfb8ddf8db01b8d3f8d1f8cfb8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b54314657446a4338435941777268424a6d43355554596d594a544a6457776f3447676203b88af888b8396274703a2f2f3078372e69636f6e2f637833643436306163643535356336373034303566396562323934333833356366643132326662323938b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b54314657446a4338435941777268424a6d43355554596d594a544a6457776f344767628362747381ff84c328f8008400886513") - # # prev = sp.string("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b") - # # bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg)).run( - # # sender=owner.address) - # - # # test 2 : Test of remove from blacklist function - # bts_periphery.remove_from_blacklist({0: 'notaaddress'}).run(sender=bts_periphery.address, valid=False, - # exception="InvalidAddress") # invalid address - # bts_periphery.remove_from_blacklist({0: 'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=bts_periphery.address, - # valid=False, - # exception="UserNotFound") # address not black-listed - # bts_periphery.add_to_blacklist({0: 'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run( - # sender=bts_periphery.address) # adding to blacklist - # bts_periphery.remove_from_blacklist({0: 'tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run( - # sender=bts_periphery.address) # valid process - # bts_periphery.remove_from_blacklist({0: 'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=bts_periphery.address, - # valid=False, - # exception='UserNotFound') # cannot remove from blacklist twice - # bts_periphery.add_to_blacklist({0: 'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run( - # sender=bts_periphery.address) # adding to blacklist - # bts_periphery.remove_from_blacklist({0: 'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run( - # sender=bts_periphery.address) # can only be called from btseperiphery contract - # bts_periphery.remove_from_blacklist({0: 'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=alice.address, - # valid=False, - # exception="Unauthorized") # can only be called from btseperiphery contract - # - # # # transfer_native_coin - # # bts_periphery.set_token_limit( - # # sp.record( - # # coin_names=sp.map({0: "btp-NetXnHfVqm9iesp.tezos-XTZ"}), - # # token_limit=sp.map({0: 115792089237316195423570985008687907853269984665640564039457584007913129639935}) - # # ) - # # ).run(sender = bts_core.address) - # # bts_core.transfer_native_coin("btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d").run(sender= sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), amount=sp.tez(30)) + # relay msg for end of transfer fa2 + msg_byte = sp.bytes( + "0xF8f2f8f0b8eef8ec01b8e4f8e2f8e0b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5431574b42484c" + "4662674c38514a574779536635434b32684b3369434c454d395a695410b89bf899b8396274703a2f2f3078372e69636f6e2f63783531" + "6530626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f2f4e6574586e486656" + "716d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a695483627473" + "0496d50293d200905472616e7366657220537563636573738400a2bada") + bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) + # verify aggregation fee + sc.verify(bts_core.data.aggregation_fee.get("btp-0x7.tezos-fa2") == sp.nat(0)) + + # Scenario 15: Transfer batch fa2 token and native token from tezos to icon + bts_core.transfer_batch(sp.record(coin_names_values={"btp-0x7.tezos-fa2": 20000000}, + to="btp://0x7.icon/hx9d181d13f47c5aae555b709814c6b22978797619")).run( + sender=alice, amount=60000000) + # relay msg for end of transfer batch + msg_byte = sp.bytes( + "0xf8f2f8f0b8eef8ec01b8e4f8e2f8e0b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5431574b42484c" + "4662674c38514a574779536635434b32684b3369434c454d395a695411b89bf899b8396274703a2f2f3078372e69636f6e2f63783531" + "6530626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f2f4e6574586e486656" + "716d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a695483627473" + "0596d50293d200905472616e7366657220537563636573738400a2bc29") + bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) + # verify aggregation fee + # existing fee of btp-NetXnHfVqm9iesp.tezos-XTZ: 90450 + sc.verify(bts_core.data.aggregation_fee.get("btp-0x7.tezos-fa2") == sp.nat(0)) + sc.verify(bts_core.data.aggregation_fee.get("btp-NetXnHfVqm9iesp.tezos-XTZ") == sp.nat(600450 + 90450)) + + # Scenario 16: Transfer native coin from icon to tezos + # receiving address: tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP + msg_byte = sp.bytes( + "0xf90157f90154b90151f9014e01b90145f90142f9013fb8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b" + "5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a695412b8faf8f8b8396274703a2f2f3078372e6963" + "6f6e2f637835316530626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f2f4e" + "6574586e486656716d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d39" + "5a6954836274730cb874f87200b86ff86daa687839643138316431336634376335616165353535623730393831346336623232393738" + "373937363139a4747a316733704a5a50696678684e3439756b435a6a644551747957675832455264667150dcdb906274702d3078372e" + "69636f6e2d49435889011bccfea6b8bd00008400a2bc6f") + bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) + + # Scenario 17: Transfer batch native coin and one fa2 tokens from tezos to icon + bts_core.transfer_batch(sp.record(coin_names_values={"btp-0x7.tezos-fa2": 10000000}, + to="btp://0x7.icon/hx9d181d13f47c5aae555b709814c6b22978797619")).run( + sender=alice, amount=30000000) + # relay msg for end of transfer batch + msg_byte = sp.bytes( + "0xf8f2f8f0b8eef8ec01b8e4f8e2f8e0b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5431574b42484c" + "4662674c38514a574779536635434b32684b3369434c454d395a695413b89bf899b8396274703a2f2f3078372e69636f6e2f63783531" + "6530626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f2f4e6574586e486656" + "716d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a695483627473" + "0696d50293d200905472616e7366657220537563636573738400a2bdaf") + bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) + # verify aggregation fee + # existing fee of btp-NetXnHfVqm9iesp.tezos-XTZ: 690900 + sc.verify(bts_core.data.aggregation_fee.get("btp-0x7.tezos-fa2") == sp.nat(0)) + sc.verify(bts_core.data.aggregation_fee.get("btp-NetXnHfVqm9iesp.tezos-XTZ") == sp.nat(690900 + 300450)) + + # Scenario 18: Transfer fa2 token not registered on icon from tezos + # mint fa2 dummy second + fa2_dummy_second.mint([sp.record(to_=bob, amount=sp.nat(1000000000))]).run(sender=owner.address) + + # add operator + fa2_dummy_second.update_operators( + [sp.variant("add_operator", sp.record(owner=bob, operator=bts_core.address, token_id=0))]).run( + sender=bob) + + # register fa2 + bts_core.register( + name=sp.string("btp-0x7.tezos-fa2-second"), + fee_numerator=sp.nat(0), + fixed_fee=sp.nat(0), + addr=fa2_dummy_second.address, + token_metadata=sp.map({"token_metadata": sp.bytes("0x0dae11")}), + metadata=sp.big_map({"metadata": sp.bytes("0x0dae11")}) + ).run(sender=owner.address) + + # transfer fa2 token + bts_core.transfer(sp.record( + coin_name="btp-0x7.tezos-fa2-second", value=10000000, + to="btp://0x7.icon/hx9d181d13f47c5aae555b709814c6b22978797619")).run(sender=bob) + + # relay msg for end of transfer fa2 + msg_byte = sp.bytes( + "0xf8e1f8dfb8ddf8db01b8d3f8d1f8cfb8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5431574b42484" + "c4662674c38514a574779536635434b32684b3369434c454d395a695414b88af888b8396274703a2f2f3078372e69636f6e2f637835" + "316530626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f2f4e6574586e486" + "656716d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a69548362" + "747381f984c328f8008400a2c0fd") + bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) + + # these case cannot be tested in integration test due to limitation on tezos + # # Scenario 12: Transferred btp-0x7.icon-ICX wrapped coin from tezos to icon + # coin_address = bts_core.data.coins.get("btp-0x7.icon-ICX") + # # contract = sp.contract(sp.TRecord(spender=sp.TAddress, amount=sp.TNat), coin_address, "set_allowance").open_some() # - # # # transfer_native_coin - # # bts_periphery.set_token_limit( - # # sp.record( - # # coin_names=sp.map({0: "btp-NetXnHfVqm9iesp.tezos-XTZ"}), - # # token_limit=sp.map({0: 5}) - # # ) - # # ).run(sender = bts_core.address) - # # bts_core.transfer_native_coin("btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d").run(sender= sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), amount=sp.tez(30), valid=False, exception="FailCheckTransfer") + # # set allowance for bts_core + # coin_address.set_allowance([sp.record(spender=bts_core.address, + # amount=sp.nat(1000000000000000000000))]) + # sc.verify(sp.view("get_allowance", coin_address, sp.record(spender=bts_core.address, owner=alice), + # t=sp.TNat).open_some("Invalid view") == sp.nat(0)) + # # update operator + # coin_address.update_operators( + # [sp.variant("add_operator", sp.record(owner=alice, operator=bts_core.address, token_id=0))]) # - # # # bmc_periphery get_status - # # sc.verify_equal(bmc_periphery.get_status("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b"), sp.record(current_height = 0, rx_height = 2, rx_seq = 0, tx_seq = 6)) + # bts_balance_before = sp.view("get_balance_of", coin_address, + # [sp.record(owner=bts_core.address, token_id=sp.nat(0))], + # t=sp.TList(t_balance_of_response)).open_some("Invalid view") # - # # test 3 : set token limit - # bts_periphery.set_token_limit( - # sp.record(coin_names={0: "Tok2", 1: 'BB'}, token_limit={0: sp.nat(5), 1: sp.nat(2)})).run(sender=alice.address, - # valid=False, - # exception='Unauthorized') # can only be called from btsperiphery contract - # bts_periphery.set_token_limit( - # sp.record(coin_names={0: "Tok2", 1: 'BB'}, token_limit={0: sp.nat(5), 1: sp.nat(2)})).run( - # sender=bts_periphery.address) # set token limit for Tok2 coin to 5 and BB coin to 2 - # sc.verify(bts_periphery.data.token_limit["Tok2"] == sp.nat(5)) # test of token_limit for tok2 token - # bts_periphery.set_token_limit(sp.record(coin_names={0: "Tok2", 1: 'BB'}, token_limit={0: sp.nat(5)})).run( - # valid=False, exception='InvalidParams', sender=bts_periphery.address) # invalid parameters - # # cannot set more than 15 token limit at once - # bts_periphery.set_token_limit( - # sp.record(coin_names={0: "Tok2", 1: 'BB'}, token_limit={0: sp.nat(15), 1: sp.nat(22)})).run( - # sender=bts_periphery.address) # can modify already set data - # sc.verify(bts_periphery.data.token_limit["BB"] == sp.nat(22)) # test of token_limit for tok2 token + # # transfer wrapped coin + # bts_core.transfer(sp.record(coin_name="btp-0x7.icon-ICX", value=sp.nat(13000000000000000000), + # to=" btp://0x7.icon/hx9d181d13f47c5aae555b709814c6b22978797619")).run(sender=alice) + # # transfer end message from relay + # msg_byte = sp.bytes( + # "0xf8f2f8f0b8eef8ec01b8e4f8e2f8e0b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5431574b42484c" + # "4662674c38514a574779536635434b32684b3369434c454d395a69540cb89bf899b8396274703a2f2f3078372e69636f6e2f63783531" + # "6530626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f2f4e6574586e486656" + # "716d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a695483627473" + # "0196d50293d200905472616e7366657220537563636573738400a2b2de") + # bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) # - # # # handle_relay_message - # # msg=sp.bytes("0xf90157f90154b90151f9014e01b90145f90142f9013fb8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5431454e5a76546f507838374c68756f774a315669786a6a715168536e597263594c6907b8faf8f8b8396274703a2f2f3078372e69636f6e2f637864633238393434343037363539393733666539393438376437356335646433326337396265303533b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5431454e5a76546f507838374c68756f774a315669786a6a715168536e597263594c698362747303b874f87200b86ff86daa687839643138316431336634376335616165353535623730393831346336623232393738373937363139a4747a3165703766664b7351434e64676e6b504443566e566b67626d465a50386d464e3147dcdb906274702d3078372e69636f6e2d4943588900d71b0fe0a28e000084008502ba") - # # prev=sp.string("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b") - # # bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg)).run(sender=owner.address) + # bts_balance_after = sp.view("get_balance_of", coin_address, + # [sp.record(owner=bts_core.address, token_id=sp.nat(0))], + # t=sp.TList(t_balance_of_response)).open_some("Invalid view") + # verify burnt amount + + # Scenario 13: Transferred btp-0x7.icon-ICX wrapped coin from tezos to icon def deploy_bmc_management(owner, helper): From dabb6d767d6729f8f2d4ac480c87597fb049985f Mon Sep 17 00:00:00 2001 From: suyogadhikari Date: Thu, 13 Jul 2023 06:24:51 +0545 Subject: [PATCH 149/211] perf(bts): rlp struct library optimized. --- smartpy/bts/contracts/src/RLP_struct.py | 231 ++++++++---------------- 1 file changed, 75 insertions(+), 156 deletions(-) diff --git a/smartpy/bts/contracts/src/RLP_struct.py b/smartpy/bts/contracts/src/RLP_struct.py index 04f30e9e..9c826ffa 100644 --- a/smartpy/bts/contracts/src/RLP_struct.py +++ b/smartpy/bts/contracts/src/RLP_struct.py @@ -9,137 +9,109 @@ class DecodeEncodeLibrary: def decode_response(self, rlp): sp.set_type(rlp, sp.TBytes) - temp_int = sp.local("int1", 0) - temp_byt = sp.local("byt1", sp.bytes("0x")) + code = sp.local("code_bts_decode_response", 0) is_error = sp.local("error_in_bts_decode_response", sp.string("Success")) - rlp_dr = sp.local("rlp_dr_bts", sp.map(tkey=sp.TNat)) + rlp_message_list = sp.local("rlp_message_list_bts", sp.map(tkey=sp.TNat)) is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() with sp.if_(is_list_lambda): - rlp_dr.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_message_list.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - rlp_dr.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - is_error.value = "ErrorInBTSDecoding" - rlp_ = rlp_dr.value - counter = sp.local("counter_response", 0) + is_error.value = "ErrorInBTSDecoding" + rlp_ = rlp_message_list.value + counter = sp.local("counter_response_bts", 0) msg = sp.local("message_in_bts", sp.string("")) with sp.if_(is_error.value == "Success"): sp.for i in rlp_.items(): sp.if counter.value == 0: - temp_int.value = Utils2.Int.of_bytes(i.value) + code.value = Utils2.Int.of_bytes(i.value) sp.if counter.value == 1: - temp_byt.value = i.value + msg.value = sp.view("decode_string", self.data.helper, i.value, t=sp.TString).open_some() counter.value = counter.value + 1 - msg.value = sp.view("decode_string", self.data.helper, temp_byt.value, t=sp.TString).open_some() - return sp.record(rv = sp.record(code=temp_int.value, message = msg.value),status = is_error.value) + return sp.record(rv = sp.record(code=code.value, message = msg.value),status = is_error.value) def decode_service_message(self, rlp): sp.set_type(rlp, sp.TBytes) - rlp_sm = sp.local("rlp_sm_bts", sp.map(tkey=sp.TNat)) - is_error = sp.local("error_in_bts_decode_service_message", sp.string("Success")) + rlp_service_message = sp.local("rlp_decode_service_message_bts", sp.map(tkey=sp.TNat)) + is_error = sp.local("error_in_bts_decode_service_message_bts", sp.string("Success")) is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() with sp.if_(is_list_lambda): - rlp_sm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_service_message.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - rlp_sm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - is_error.value = "ErrorInBTSDecoding" - _service_type = sp.local("_service_type", sp.variant("ERROR", sp.nat(10))) - temp_byt = sp.local("byte1", sp.bytes("0x")) + is_error.value = "ErrorInBTSDecoding" + _service_type = sp.local("_service_type_decode_service_message_bts", sp.variant("ERROR", sp.nat(10))) + data = sp.local("data_decode_service_message_bts", sp.bytes("0x")) with sp.if_(is_error.value == "Success"): - rlp_ = rlp_sm.value - temp_int = sp.local("int2", 0) - counter = sp.local("counter", 0) + rlp_ = rlp_service_message.value + temp_int = sp.local("temp_int_decode_service_message_bts", 0) + counter = sp.local("counter_decode_service_message_bts", 0) sp.for i in rlp_.items(): sp.if counter.value == 0: temp_int.value = Utils2.Int.of_bytes(i.value) sp.if counter.value == 1: - temp_byt.value = i.value + data.value = sp.view("without_length_prefix", self.data.helper, i.value, + t=sp.TBytes).open_some() counter.value = counter.value + 1 - sp.if temp_int.value == 0: + with sp.if_ (temp_int.value == 0): _service_type.value = sp.variant("REQUEST_COIN_TRANSFER", temp_int.value) - sp.if temp_int.value == 1: + with sp.if_ (temp_int.value == 1): _service_type.value = sp.variant("REQUEST_COIN_REGISTER", temp_int.value) - sp.if temp_int.value == 2: + with sp.if_ (temp_int.value == 2): _service_type.value = sp.variant("RESPONSE_HANDLE_SERVICE", temp_int.value) - sp.if temp_int.value == 3: + with sp.if_ (temp_int.value == 3): _service_type.value = sp.variant("BLACKLIST_MESSAGE", temp_int.value) - sp.if temp_int.value == 4: + with sp.if_ (temp_int.value == 4): _service_type.value = sp.variant("CHANGE_TOKEN_LIMIT", temp_int.value) - sp.if temp_int.value == 5: + with sp.if_ (temp_int.value == 5): _service_type.value = sp.variant("UNKNOWN_TYPE", temp_int.value) - temp_byt.value = sp.view("without_length_prefix", self.data.helper, temp_byt.value, t=sp.TBytes).open_some() return sp.record(rv=sp.record(serviceType=_service_type.value, - data=temp_byt.value), status=is_error.value) + data=data.value), status=is_error.value) def decode_transfer_coin_msg(self, rlp): sp.set_type(rlp, sp.TBytes) is_error = sp.local("error_in_bts_decode_transfer_coin_msg", sp.string("Success")) - rlp_tcm = sp.local("rlp_tcm_bts", sp.map(tkey=sp.TNat)) + rlp_transfer_coin = sp.local("rlp_transfer_coin_msg_bts", sp.map(tkey=sp.TNat)) is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() with sp.if_(is_list_lambda): - rlp_tcm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_transfer_coin.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - rlp_tcm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - is_error.value = "ErrorInBTSDecoding" - rlp_ = rlp_tcm.value + is_error.value = "ErrorInBTSDecoding" + rlp_ = rlp_transfer_coin.value - temp_byt = sp.local("byt_transfer", sp.bytes("0x")) - rv1_byt = sp.local("rv1_byt", sp.bytes("0x")) - rv2_byt = sp.local("rv2_byt", sp.bytes("0x")) - counter = sp.local("counter_coin", sp.nat(0)) - rv1 = sp.local("rv1_bts_transfer_coin", sp.string("")) - rv2 = sp.local("rv2_bts_transfer_coin", sp.string("")) + temp_byt = sp.local("byt_transfer_coin_msg_bts", sp.bytes("0x")) + counter = sp.local("counter_transfer_coin_msg_bts", sp.nat(0)) + from_address = sp.local("from_address_transfer_coin_msg_bts", sp.string("")) + to_address = sp.local("to_address_transfer_coin_msg_bts", sp.string("")) rv_assets = sp.local("assets", {}, sp.TMap(sp.TNat, types.Types.Asset)) with sp.if_(is_error.value == "Success"): sp.for i in rlp_.items(): - sp.if counter.value == 2: + with sp.if_ (counter.value == 2): temp_byt.value = i.value - sp.if counter.value == 0: - rv1_byt.value = i.value - sp.if counter.value == 1: - rv2_byt.value = i.value + with sp.if_ (counter.value == 0): + from_address.value = sp.view("decode_string", self.data.helper, i.value, t=sp.TString).open_some() + with sp.if_ (counter.value == 1): + to_address.value = sp.view("decode_string", self.data.helper, i.value, t=sp.TString).open_some() counter.value = counter.value + 1 - sub_list = sp.local("sub_list", temp_byt.value) - nsl_tcm = sp.local("nsl_bts_tcm", sp.map(tkey=sp.TNat)) + sub_list = sp.local("sub_list_transfer_coin_msg_bts", temp_byt.value) + new_sub_list_tcm = sp.local("nsl_transfer_coin_msg_bts", sp.map(tkey=sp.TNat)) is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() with sp.if_(is_list_lambda): - nsl_tcm.value = sp.view("decode_list", self.data.helper, sub_list.value, + new_sub_list_tcm.value = sp.view("decode_list", self.data.helper, sub_list.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() - is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - nsl_tcm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - is_error.value = "ErrorInBTSDecoding" + is_error.value = "ErrorInBTSDecoding" with sp.if_(is_error.value == "Success"): - new_sub_list = nsl_tcm.value + new_sub_list = new_sub_list_tcm.value counter.value = 0 - new_temp_byt = sp.local("new_temp_byt", sp.bytes("0x")) - nsl3_tcm = sp.local("nsl3_bts_tcm", sp.map(tkey=sp.TNat)) - view_value = sp.local("view_value", sp.map(tkey=sp.TNat)) - counter_nested = sp.local("counter_nested", sp.nat(0), t=sp.TNat) - temp_byt = sp.local("tempByt2", sp.bytes("0x")) - temp_byt_nested = sp.local("tempByt2nested", sp.bytes("0x")) + new_temp_byt = sp.local("new_temp_byt_transfer_coin_msg_bts", sp.bytes("0x")) + nsl3_tcm = sp.local("nsl3_transfer_coin_msg_bts", sp.map(tkey=sp.TNat)) + view_value = sp.local("view_value_transfer_coin_msg_bts", sp.map(tkey=sp.TNat)) + counter_nested = sp.local("counter_nested_transfer_coin_msg_bts", sp.nat(0), t=sp.TNat) + temp_byt = sp.local("temp_byte2_transfer_coin_msg_bts", sp.bytes("0x")) + temp_byt_nested = sp.local("temp_byte_nested_transfer_coin_msg_bts", sp.bytes("0x")) sp.for x in new_sub_list.items(): new_temp_byt.value = x.value is_list_lambda = sp.view("is_list", self.data.helper, new_temp_byt.value, @@ -148,22 +120,15 @@ def decode_transfer_coin_msg(self, rlp): nsl3_tcm.value = sp.view("decode_list", self.data.helper, new_temp_byt.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, new_temp_byt.value, - t=sp.TBytes).open_some() - is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - nsl3_tcm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - is_error.value = "ErrorInBTSDecoding" + is_error.value = "ErrorInBTSDecoding" with sp.if_(is_error.value == "Success"): view_value.value = nsl3_tcm.value counter_nested.value = sp.nat(0) sp.for i in view_value.value.items(): - sp.if counter_nested.value == 1: + with sp.if_ (counter_nested.value == 1): temp_byt_nested.value = sp.view("without_length_prefix", self.data.helper, i.value, t=sp.TBytes).open_some() - sp.if counter_nested.value == 0: + with sp.if_ (counter_nested.value == 0): temp_byt.value = i.value counter_nested.value += 1 @@ -172,29 +137,21 @@ def decode_transfer_coin_msg(self, rlp): counter.value = counter.value + 1 - rv1.value = sp.view("decode_string", self.data.helper, rv1_byt.value, t=sp.TString).open_some() - rv2.value = sp.view("decode_string", self.data.helper, rv2_byt.value, t=sp.TString).open_some() - return sp.record(value=sp.record(from_addr= rv1.value, to = rv2.value, assets = rv_assets.value), status = is_error.value) + return sp.record(value=sp.record(from_addr= from_address.value, to = to_address.value, assets = rv_assets.value), status = is_error.value) def decode_blacklist_msg(self, rlp): sp.set_type(rlp, sp.TBytes) - rlp_bm = sp.local("rlp_bm_bts", sp.map(tkey=sp.TNat)) + rlp_blacklist_msg = sp.local("rlp_blacklist_msg_bts", sp.map(tkey=sp.TNat)) is_error = sp.local("error_in_bts_decode_blacklist_message", sp.string("Success")) is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() - _service_type = sp.local("_service_type_blacklist", sp.variant("ERROR", sp.nat(10))) + _service_type = sp.local("_service_type_blacklist_msg_bts", sp.variant("ERROR", sp.nat(10))) rv_blacklist_address = sp.local("blacklist_data", [], sp.TList(sp.TString)) with sp.if_(is_list_lambda): - rlp_bm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_blacklist_msg.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - rlp_bm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - is_error.value = "ErrorInBTSDecoding" - rlp_ = rlp_bm.value + is_error.value = "ErrorInBTSDecoding" + rlp_ = rlp_blacklist_msg.value temp_byt = sp.local("byt_transfer", sp.bytes("0x")) rv1_byt = sp.local("rv1_byt", sp.bytes("0x")) @@ -204,8 +161,15 @@ def decode_blacklist_msg(self, rlp): sp.for i in rlp_.items(): sp.if counter.value == 2: rv2_byt.value = i.value + rv2 = sp.view("decode_string", self.data.helper, rv2_byt.value, t=sp.TString).open_some() sp.if counter.value == 0: - rv1_byt.value = i.value + rv1_byt.value = sp.view("without_length_prefix", self.data.helper, i.value, + t=sp.TBytes).open_some() + rv1 = Utils2.Int.of_bytes(rv1_byt.value) + with sp.if_(rv1 == 0): + _service_type.value = sp.variant("ADD_TO_BLACKLIST", rv1) + with sp.else_(): + _service_type.value = sp.variant("REMOVE_FROM_BLACKLIST", rv1) sp.if counter.value == 1: temp_byt.value = i.value counter.value = counter.value + 1 @@ -216,43 +180,18 @@ def decode_blacklist_msg(self, rlp): nsl_bm.value = sp.view("decode_list", self.data.helper, sub_list.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() - is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - nsl_bm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - is_error.value = "ErrorInBTSDecoding" + is_error.value = "ErrorInBTSDecoding" with sp.if_(is_error.value == "Success"): new_sub_list = nsl_bm.value counter.value = 0 - new_temp_byt = sp.local("new_temp_byt", sp.bytes("0x")) addr_string = sp.local("addr_string", "") - # nsl2_bm = sp.local("nsl2_bts_bm", sp.map(tkey=sp.TNat)) counter.value = 0 sp.for x in new_sub_list.items(): - new_temp_byt.value = x.value - # is_list_lambda = sp.view("is_list", self.data.helper, new_temp_byt.value, - # t=sp.TBool).open_some() - # with sp.if_(is_list_lambda): - # nsl2_bm.value = sp.view("decode_list", self.data.helper, new_temp_byt.value, - # t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - # with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, new_temp_byt.value, t=sp.TBytes).open_some() - addr_string.value = sp.view("decode_string", self.data.helper, decode_len, + addr_string.value = sp.view("decode_string", self.data.helper, x.value, t=sp.TString).open_some() rv_blacklist_address.value.push(addr_string.value) counter.value = counter.value + 1 - # check_length = sp.view("prefix_length", self.data.helper, rv1_byt.value, t=sp.TNat).open_some() - # with sp.if_(check_length > 0): - rv1_byt.value = sp.view("without_length_prefix", self.data.helper, rv1_byt.value, - t=sp.TBytes).open_some() - rv1 = Utils2.Int.of_bytes(rv1_byt.value) - rv2 = sp.view("decode_string", self.data.helper, rv2_byt.value, t=sp.TString).open_some() - with sp.if_(rv1 == 0): - _service_type.value = sp.variant("ADD_TO_BLACKLIST", rv1) - with sp.else_(): - _service_type.value = sp.variant("REMOVE_FROM_BLACKLIST", rv1) + return sp.record(rv=sp.record(serviceType = _service_type.value , addrs = rv_blacklist_address.value , net = rv2), status = is_error.value) @@ -265,13 +204,7 @@ def decode_token_limit_msg(self, rlp): with sp.if_(is_list_lambda): rlp_tlm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - rlp_tlm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - is_error.value = "ErrorInBTSDecoding" + is_error.value = "ErrorInBTSDecoding" rlp_ = rlp_tlm.value temp_byt = sp.local("byt_transfer", sp.bytes("0x")) @@ -300,13 +233,7 @@ def decode_token_limit_msg(self, rlp): nsl1_dtlm.value = sp.view("decode_list", self.data.helper, sub_list.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() - is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - nsl1_dtlm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - is_error.value = "ErrorInBTSDecoding" + is_error.value = "ErrorInBTSDecoding" new_sub_list = nsl1_dtlm.value counter.value = 0 with sp.if_(is_error.value == "Success"): @@ -314,25 +241,17 @@ def decode_token_limit_msg(self, rlp): rv_names.value[counter.value] = sp.view("decode_string", self.data.helper, x.value, t=sp.TString).open_some() counter.value += 1 nsl_dtlm = sp.local("nsl_bts_dtlm", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() + is_list_lambda = sp.view("is_list", self.data.helper, sub_list_limit.value, t=sp.TBool).open_some() counter.value = 0 with sp.if_(is_list_lambda): nsl_dtlm.value = sp.view("decode_list", self.data.helper, sub_list_limit.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, sub_list_limit.value, t=sp.TBytes).open_some() - is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - nsl_dtlm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - is_error.value = "ErrorInBTSDecoding" + is_error.value = "ErrorInBTSDecoding" with sp.if_(is_error.value == "Success"): new_sub_list1 = nsl_dtlm.value limit = sp.local("limit_val", sp.bytes("0x"), t=sp.TBytes) sp.for y in new_sub_list1.items(): - # check_length = sp.view("prefix_length", self.data.helper, y.value, t=sp.TNat).open_some() - # with sp.if_(check_length > 0): limit.value = sp.view("without_length_prefix", self.data.helper, y.value, t=sp.TBytes).open_some() rv_limit.value[counter.value] = Utils2.Int.of_bytes(limit.value) From 2092c4acffd999f3ed83ac1970cd4ff88750296c Mon Sep 17 00:00:00 2001 From: suyogadhikari Date: Thu, 13 Jul 2023 06:25:09 +0545 Subject: [PATCH 150/211] perf(bmc): rlp struct library optimized. --- smartpy/bmc/contracts/src/RLP_struct.py | 419 +++++++-------------- smartpy/bmc/contracts/src/bmc_periphery.py | 75 ++-- 2 files changed, 181 insertions(+), 313 deletions(-) diff --git a/smartpy/bmc/contracts/src/RLP_struct.py b/smartpy/bmc/contracts/src/RLP_struct.py index 28aeba3e..726ac68a 100644 --- a/smartpy/bmc/contracts/src/RLP_struct.py +++ b/smartpy/bmc/contracts/src/RLP_struct.py @@ -9,322 +9,205 @@ class DecodeEncodeLibrary: def decode_bmc_message(self, rlp): sp.set_type(rlp, sp.TBytes) - rlp_bm = sp.local("rlp_bm", sp.map(tkey=sp.TNat)) - is_error = sp.local("error_in_bmc_message", sp.string("Success")) + rlp_bmc_message = sp.local("rlp_decode_bmc_message", sp.map(tkey=sp.TNat)) + is_error = sp.local("error_in_decode_bmc_message", sp.string("Success")) is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() with sp.if_(is_list_lambda): - rlp_bm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_bmc_message.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - rlp_bm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - is_error.value = "ErrorInBMCMessageDecoding" - temp_map_string = sp.compute(sp.map(tkey=sp.TString, tvalue=sp.TString)) - temp_int = sp.local("int_value", 0) - temp_byt = sp.local("byt_value", sp.bytes("0x")) + is_error.value = "ErrorInBMCMessageDecoding" + return_value_map = sp.compute(sp.map(tkey=sp.TString, tvalue=sp.TString)) + sn_no = sp.local("sn_no_decode_bmc_message", 0) + decoded_message = sp.local("message_decode_bmc_message", sp.bytes("0x")) with sp.if_(is_error.value == "Success"): - rlp_ = rlp_bm.value + rlp_ = rlp_bmc_message.value counter = sp.local("counter", 0) sp.for k in rlp_.items(): - sp.if counter.value == 0: - temp_map_string["src"] = sp.view("decode_string", self.data.helper, k.value, t=sp.TString).open_some() - sp.if counter.value == 1: - temp_map_string["dst"] = sp.view("decode_string", self.data.helper, k.value, t=sp.TString).open_some() - sp.if counter.value == 2: - temp_map_string["svc"] = sp.view("decode_string", self.data.helper, k.value, t=sp.TString).open_some() - sp.if counter.value == 3: + with sp.if_ (counter.value == 0): + return_value_map["src"] = sp.view("decode_string", self.data.helper, k.value, t=sp.TString).open_some() + with sp.if_ (counter.value == 1): + return_value_map["dst"] = sp.view("decode_string", self.data.helper, k.value, t=sp.TString).open_some() + with sp.if_ (counter.value == 2): + return_value_map["svc"] = sp.view("decode_string", self.data.helper, k.value, t=sp.TString).open_some() + with sp.if_ (counter.value == 3): sn_in_bytes = sp.view("without_length_prefix", self.data.helper, k.value, t=sp.TBytes).open_some() - _to_int = sp.view("to_int", self.data.helper_parse_negative, sn_in_bytes, t=sp.TInt).open_some() - temp_int.value = _to_int - sp.if counter.value == 4: - temp_byt.value = k.value + sn_no.value = sp.view("to_int", self.data.helper_parse_negative, sn_in_bytes, t=sp.TInt).open_some() + with sp.if_ (counter.value == 4): + decoded_message.value = sp.view("without_length_prefix", self.data.helper, k.value, + t=sp.TBytes).open_some() counter.value = counter.value + 1 - with sp.if_(is_error.value == "Success"): - temp_byt.value = sp.view("without_length_prefix", self.data.helper, temp_byt.value, t=sp.TBytes).open_some() - - return sp.record(bmc_dec_rv = sp.record(src=temp_map_string.get("src", default_value = "NoKey"), - dst=temp_map_string.get("dst", default_value = "NoKey"), - svc=temp_map_string.get("svc", default_value = "NoKey"), - sn=temp_int.value, - message=temp_byt.value), + return sp.record(bmc_dec_rv = sp.record(src=return_value_map.get("src", default_value = "NoKey"), + dst=return_value_map.get("dst", default_value = "NoKey"), + svc=return_value_map.get("svc", default_value = "NoKey"), + sn=sn_no.value, + message=decoded_message.value), status = is_error.value) def decode_response(self, rlp): sp.set_type(rlp, sp.TBytes) - temp_int = sp.local("int1", sp.nat(0)) - temp_byt = sp.local("byt1", sp.bytes("0x")) - rlp_dr = sp.local("rlp_dr", sp.map(tkey=sp.TNat)) - is_error = sp.local("error_in_bmc_decode_response", sp.string("Success")) - is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - rlp_dr.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - rlp_dr.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - is_error.value = "ErrorInDecodingBMCResponse" - rlp_ = rlp_dr.value - counter = sp.local("counter_response", 0) - with sp.if_(is_error.value == "Success"): - sp.for m in rlp_.items(): - sp.if counter.value == 0: - temp_int.value = Utils2.Int.of_bytes(m.value) - sp.if counter.value == 1: - temp_byt.value = m.value - counter.value = counter.value + 1 + code_num = sp.local("code_decode_response", sp.nat(0)) + rlp_ = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + counter = sp.local("counter_decode_response", 0) + sp.for m in rlp_.items(): + with sp.if_ (counter.value == 0): + code_num.value = Utils2.Int.of_bytes(m.value) + counter.value = counter.value + 1 # message in case of error is null which cannot be decoded into string - return sp.record(code=temp_int.value, message="Error", status = is_error.value) + return sp.record(code=code_num.value, message="Error") def decode_init_message(self, rlp): sp.set_type(rlp, sp.TBytes) - rlp_im = sp.local("rlp_im", sp.map(tkey=sp.TNat)) - is_error = sp.local("error_in_bmc_decode_init_message", sp.string("Success")) - is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - rlp_im.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - rlp_im.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - is_error.value = "ErrorInDecodingIniteMessage" - _links = sp.local("links_init", [], sp.TList(sp.TString)) - with sp.if_(is_error.value == "Success"): - rlp_ = rlp_im.value - counter = sp.local("counter_init", 0) - temp_bytes = sp.local("byt_init", sp.bytes("0x")) - sp.for g in rlp_.items(): - sp.if counter.value == 0: - temp_bytes.value = g.value - counter.value = counter.value + 1 - - sub_list = sp.local("sub_list_init", temp_bytes.value) - nsl_im = sp.local("nsl_im", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - nsl_im.value = sp.view("decode_list", self.data.helper, sub_list.value, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, - t=sp.TBytes).open_some() - is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - nsl_im.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - is_error.value = "ErrorInDecodingInitMessage" + rlp_init = sp.local("rlp_init_message", sp.map(tkey=sp.TNat)) + rlp_init.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + _links = sp.local("links_init_message", [], sp.TList(sp.TString)) + rlp_ = rlp_init.value + counter = sp.local("counter_init_message", 0) + bytes_message = sp.local("byte_init_message", sp.bytes("0x")) + sp.for g in rlp_.items(): + with sp.if_ (counter.value == 0): + bytes_message.value = g.value + counter.value = counter.value + 1 - with sp.if_(is_error.value == "Success"): - new_sub_list = nsl_im.value + sub_list = sp.local("sub_list_init_message", bytes_message.value) + nsl_init = sp.local("nsl_init_message", sp.map(tkey=sp.TNat)) + nsl_init.value = sp.view("decode_list", self.data.helper, sub_list.value, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + new_sub_list = nsl_init.value - counter.value = 0 - sp.for x in new_sub_list.items(): - _links.value.push(sp.view("decode_string", self.data.helper, x.value, t=sp.TString).open_some()) - counter.value = counter.value + 1 - return sp.record(links_list = _links.value, status = is_error.value) + counter.value = 0 + sp.for x in new_sub_list.items(): + _links.value.push(sp.view("decode_string", self.data.helper, x.value, t=sp.TString).open_some()) + counter.value = counter.value + 1 + return sp.record(links_list = _links.value) def decode_bmc_service(self, rlp): sp.set_type(rlp, sp.TBytes) - rlp_bs = sp.local("rlp_bs", sp.map(tkey=sp.TNat)) - is_error = sp.local("error_in_bmc_decode_service", sp.string("Success")) + rlp_bmc_message = sp.local("rlp_decode_bmc_service", sp.map(tkey=sp.TNat)) + is_error = sp.local("error_in_decode_bmc_service", sp.string("Success")) is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() with sp.if_(is_list_lambda): - rlp_bs.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_bmc_message.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - rlp_bs.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - is_error.value = "ErrorInDecodingBMCService" + is_error.value = "ErrorInDecodingBMCService" - temp_string = sp.local("str_value", "") - temp_byt = sp.local("byt_value_bmc", sp.bytes("0x")) + service_type = sp.local("str_value_decode_bmc_service", "") + payload = sp.local("byt_value_decode_bmc_service", sp.bytes("0x")) with sp.if_(is_error.value == "Success"): - rlp_ = rlp_bs.value + rlp_ = rlp_bmc_message.value counter = sp.local("counter_service", 0) sp.for b in rlp_.items(): - sp.if counter.value == 0: - temp_string.value = sp.view("decode_string", self.data.helper, b.value, t=sp.TString).open_some() - sp.if counter.value == 1: - temp_byt.value = b.value + with sp.if_ (counter.value == 0): + service_type.value = sp.view("decode_string", self.data.helper, b.value, t=sp.TString).open_some() + with sp.if_ (counter.value == 1): + payload.value = sp.view("without_length_prefix", self.data.helper, b.value, + t=sp.TBytes).open_some() counter.value = counter.value + 1 - temp_byt.value = sp.view("without_length_prefix", self.data.helper, temp_byt.value, t=sp.TBytes).open_some() - return sp.record(bmc_service_rv=sp.record(serviceType=temp_string.value, - payload=temp_byt.value), status = is_error.value) + return sp.record(bmc_service_rv=sp.record(serviceType=service_type.value, + payload=payload.value), status = is_error.value) def decode_gather_fee_message(self, rlp): sp.set_type(rlp, sp.TBytes) - rlp_gm = sp.local("rlp_gm", sp.map(tkey=sp.TNat)) + rlp_gather_message = sp.local("rlp_gather_message", sp.map(tkey=sp.TNat)) is_error = sp.local("error_in_bmc_fee_message", sp.string("Success")) is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() with sp.if_(is_list_lambda): - rlp_gm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_gather_message.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - rlp_gm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - is_error.value = "ErrorInDecodingFeeMessage" - temp_str = sp.local("str_gather", "") + is_error.value = "ErrorInDecodingFeeMessage" + fa = sp.local("fee_aggregator_gather_message", "") _svcs = sp.local("_svcs", {}, sp.TMap(sp.TNat, sp.TString)) with sp.if_(is_error.value == "Success"): - rlp_ = rlp_gm.value - temp_byt = sp.local("byt4", sp.bytes("0x")) - counter = sp.local("counter_gather", 0) + rlp_ = rlp_gather_message.value + byte_message = sp.local("byte_gather_fee", sp.bytes("0x")) + counter = sp.local("counter_gather_message", 0) sp.for c in rlp_.items(): - sp.if counter.value == 1: - temp_byt.value = c.value - sp.if counter.value == 0: - temp_str.value = sp.view("decode_string", self.data.helper, c.value, t=sp.TString).open_some() + with sp.if_ (counter.value == 1): + byte_message.value = c.value + with sp.if_ (counter.value == 0): + fa.value = sp.view("decode_string", self.data.helper, c.value, t=sp.TString).open_some() counter.value = counter.value + 1 - sub_list = sp.local("sub_list", temp_byt.value) - nsl_gm = sp.local("nsl_gm", sp.map(tkey=sp.TNat)) + sub_list = sp.local("sub_list_gather_message", byte_message.value) + new_sub_list_gather = sp.local("new_sub_list_gather_message", sp.map(tkey=sp.TNat)) is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() with sp.if_(is_list_lambda): - nsl_gm.value = sp.view("decode_list", self.data.helper, sub_list.value, + new_sub_list_gather.value = sp.view("decode_list", self.data.helper, sub_list.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() - is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - nsl_gm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - is_error.value = "ErrorInDecodingFeeMessage" + is_error.value = "ErrorInDecodingFeeMessage" with sp.if_(is_error.value == "Success"): - new_sub_list = nsl_gm.value + new_sub_list = new_sub_list_gather.value counter.value = 0 sp.for x in new_sub_list.items(): _svcs.value[counter.value] = sp.view("decode_string", self.data.helper, x.value, t=sp.TString).open_some() counter.value = counter.value + 1 - return sp.record(fee_decode_rv = sp.record(fa=temp_str.value, + return sp.record(fee_decode_rv = sp.record(fa=fa.value, svcs=_svcs.value), status = is_error.value) def to_message_event(self, rlp): - rlp_me = sp.local("rlp_me", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() - is_error = sp.local("error_in_Event_message", sp.string("Success")) - with sp.if_(is_list_lambda): - rlp_me.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - rlp_me.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - is_error.value = "ErrorInDecoding" - rv1 = sp.local("rv1_event", "") - rv2 = sp.local("rv2_event", sp.nat(0)) - rv3 = sp.local("rv3_event", sp.bytes("0x")) - with sp.if_(is_error.value == "Success"): - rlp_ = rlp_me.value - counter = sp.local("counter_event", 0) - sp.for i in rlp_.items(): - sp.if counter.value == 2: - rv3.value = i.value - sp.if counter.value == 0: - rv1.value = sp.view("decode_string", self.data.helper, i.value, t=sp.TString).open_some() - sp.if counter.value == 1: - rv2.value = Utils2.Int.of_bytes(i.value) - counter.value = counter.value + 1 - rv3.value = sp.view("without_length_prefix", self.data.helper, rv3.value, t=sp.TBytes).open_some() - return sp.record(event_rv=sp.record(next_bmc= rv1.value, seq= rv2.value, message = rv3.value), status = is_error.value) + rlp_message_event = sp.local("rlp_message_event", sp.map(tkey=sp.TNat)) + rlp_message_event.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + next_bmc = sp.local("next_bmc_message_event", "") + seq = sp.local("seq_bmc_message_event", sp.nat(0)) + message = sp.local("message_bmc_message_event", sp.bytes("0x")) + rlp_ = rlp_message_event.value + counter = sp.local("counter_message_event", 0) + sp.for i in rlp_.items(): + with sp.if_ (counter.value == 2): + message.value = sp.view("without_length_prefix", self.data.helper, i.value, t=sp.TBytes).open_some() + with sp.if_ (counter.value == 0): + next_bmc.value = sp.view("decode_string", self.data.helper, i.value, t=sp.TString).open_some() + with sp.if_ (counter.value == 1): + seq.value = Utils2.Int.of_bytes(i.value) + counter.value = counter.value + 1 + return sp.record(event_rv=sp.record(next_bmc= next_bmc.value, seq= seq.value, message = message.value)) def decode_receipt_proof(self, rlp): - rlp_rp = sp.local("rlp_rp", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() - is_error = sp.local("error_in_receipt_proof", sp.string("Success")) - with sp.if_(is_list_lambda): - rlp_rp.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - rlp_rp.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - is_error.value = "ErrorInDecoding" - rv_int = sp.local("rv_int_receipt", 0) - rv_int2 = sp.local("rv_int2_receipt", 0) - events = sp.local("events_receipt", sp.map({}, tkey=sp.TNat, + rlp_receipt_proof = sp.local("rlp_receipt_proof", sp.map(tkey=sp.TNat)) + without_prefix = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() + rlp_receipt_proof.value = sp.view("decode_list", self.data.helper, without_prefix, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + index = sp.local("index_receipt_proof", 0) + height = sp.local("height_receipt_proof", 0) + events = sp.local("events_receipt_proof", sp.map({}, tkey=sp.TNat, tvalue=sp.TRecord(next_bmc=sp.TString, seq=sp.TNat,message=sp.TBytes))) - with sp.if_(is_error.value == "Success"): - rlp_ = rlp_rp.value - temp_byt = sp.local("byt_receipt", sp.bytes("0x")) - counter = sp.local("counter", 0) - sp.for i in rlp_.items(): - sp.if counter.value == 1: - temp_byt.value = sp.view("without_length_prefix", self.data.helper, i.value, t=sp.TBytes).open_some() - sp.if counter.value == 0: - rv_int.value = Utils2.Int.of_bytes(i.value) - sp.if counter.value == 2: - wl_prefix = sp.view("without_length_prefix", self.data.helper, i.value, t=sp.TBytes).open_some() - rv_int2.value =Utils2.Int.of_bytes(wl_prefix) - counter.value = counter.value + 1 + rlp_ = rlp_receipt_proof.value + byte_message_receipt_proof = sp.local("byte_message_receipt_proof", sp.bytes("0x")) + counter = sp.local("counter", 0) + sp.for i in rlp_.items(): + with sp.if_ (counter.value == 1): + byte_message_receipt_proof.value = sp.view("without_length_prefix", self.data.helper, i.value, t=sp.TBytes).open_some() + with sp.if_ (counter.value == 0): + index.value = Utils2.Int.of_bytes(i.value) + with sp.if_ (counter.value == 2): + wl_prefix = sp.view("without_length_prefix", self.data.helper, i.value, t=sp.TBytes).open_some() + height.value =Utils2.Int.of_bytes(wl_prefix) + counter.value = counter.value + 1 - sub_list = sp.local("sub_list", temp_byt.value) + sub_list = sp.local("sub_list_receipt_proof", byte_message_receipt_proof.value) - nsl_rp = sp.local("nsl_rp", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - nsl_rp.value = sp.view("decode_list", self.data.helper, sub_list.value, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() - is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - nsl_rp.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - is_error.value = "ErrorInDecoding" - with sp.if_(is_error.value == "Success"): - new_sub_list = nsl_rp.value - counter.value = 0 + new_sub_list_receipt_proof = sp.local("new_sub_list_receipt_proof", sp.map(tkey=sp.TNat)) + new_sub_list_receipt_proof.value = sp.view("decode_list", self.data.helper, sub_list.value, + t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + new_sub_list = new_sub_list_receipt_proof.value + counter.value = 0 - sp.for z in new_sub_list.items(): - from_event = self.to_message_event(z.value) - with sp.if_(from_event.status == "Success"): - events.value[counter.value] = from_event.event_rv - counter.value = counter.value + 1 - with sp.else_(): - is_error.value = "ErrorInDecoding" - return sp.record(rv = sp.record(index = rv_int.value, events = events.value, height = rv_int2.value), status = is_error.value) + sp.for z in new_sub_list.items(): + from_event = self.to_message_event(z.value) + events.value[counter.value] = from_event.event_rv + counter.value = counter.value + 1 + return sp.record(rv = sp.record(index = index.value, events = events.value, height = height.value)) def decode_receipt_proofs(self, rlp): sp.set_type(rlp, sp.TBytes) - is_error = sp.local("error_in_receipt_proofs", sp.string("Success")) - rlp_rps = sp.local("rlp_rps", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - rlp_rps.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - rlp_rps.value = sp.view("decode_list", self.data.helper, decode_len, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - is_error.value = "ErrorInDecoding" - rlp_ = rlp_rps.value + rlp_receipt_proofs = sp.local("rlp_receipt_proofs", sp.map(tkey=sp.TNat)) + rlp_receipt_proofs.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + rlp_ = rlp_receipt_proofs.value counter = sp.local("counter_receipt_proofs", 0) receipt_proofs = sp.local("events_receipt_proofs", sp.map({}, tkey=sp.TNat, tvalue=sp.TRecord(index = sp.TNat, @@ -333,36 +216,23 @@ def decode_receipt_proofs(self, rlp): ) ) ) - temp_byt = sp.local("temp_byt_proofs", sp.bytes("0x")) + message_byte_receipt_proofs = sp.local("message_byte_receipt_proofs", sp.bytes("0x")) sp.for i in rlp_.items(): - sp.if counter.value == 0: - temp_byt.value = i.value + with sp.if_ (counter.value == 0): + message_byte_receipt_proofs.value = i.value counter.value = counter.value + 1 - sub_list = sp.local("sub_list_proofs", temp_byt.value) + sub_list = sp.local("sub_list_receipt_proofs", message_byte_receipt_proofs.value) - nsl_rps = sp.local("nsl_rps", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - nsl_rps.value = sp.view("decode_list", self.data.helper, sub_list.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() - is_list_lambda = sp.view("is_list", self.data.helper, decode_len, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - nsl_rps.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - is_error.value = "ErrorInDecoding" - new_sub_list = nsl_rps.value + new_sub_list_receipt_proofs = sp.local("new_sub_list_receipt_proofs", sp.map(tkey=sp.TNat)) + new_sub_list_receipt_proofs.value = sp.view("decode_list", self.data.helper, sub_list.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() + new_sub_list = new_sub_list_receipt_proofs.value counter.value = 0 - sp.if sp.len(new_sub_list) > 0: + with sp.if_ (sp.len(new_sub_list) > 0): sp.for x in new_sub_list.items(): from_receipt_proofs = self.decode_receipt_proof(x.value) - with sp.if_(from_receipt_proofs.status == "Success"): - receipt_proofs.value[counter.value] = from_receipt_proofs.rv - counter.value = counter.value + 1 - with sp.else_(): - is_error.value = "ErrorInDecoding" - return sp.record(receipt_proof = receipt_proofs.value, status = is_error.value) + receipt_proofs.value[counter.value] = from_receipt_proofs.rv + counter.value = counter.value + 1 + return sp.record(receipt_proof = receipt_proofs.value) # rlp encoding starts here @@ -387,10 +257,9 @@ def encode_bmc_message(self, params): encode_src = sp.view("encode_string", self.data.helper, params.src, t=sp.TBytes).open_some() encode_dst = sp.view("encode_string", self.data.helper, params.dst, t=sp.TBytes).open_some() encode_svc = sp.view("encode_string", self.data.helper, params.svc, t=sp.TBytes).open_some() - _to_byte = sp.view("to_byte", self.data.helper_parse_negative, params.sn, t=sp.TBytes).open_some() - rlp.value = _to_byte + rlp.value = sp.view("to_byte", self.data.helper_parse_negative, params.sn, t=sp.TBytes).open_some() - sp.if params.sn < sp.int(0): + with sp.if_ (params.sn < sp.int(0)): encode_sn = sp.view("with_length_prefix", self.data.helper, rlp.value, t=sp.TBytes).open_some() rlp.value = encode_sn diff --git a/smartpy/bmc/contracts/src/bmc_periphery.py b/smartpy/bmc/contracts/src/bmc_periphery.py index e83f5b82..815dccb4 100644 --- a/smartpy/bmc/contracts/src/bmc_periphery.py +++ b/smartpy/bmc/contracts/src/bmc_periphery.py @@ -143,45 +143,44 @@ def handle_relay_message(self, prev, msg): rx_height = sp.local("rx_height", link_rx_height, t=sp.TNat) # decode rlp message rps_decode = self.decode_receipt_proofs(msg) - with sp.if_(rps_decode.status == "Success"): - rps = rps_decode.receipt_proof - bmc_msg = sp.local("bmc_msg", sp.record(src="", dst="", svc="", sn=sp.int(0), message=sp.bytes("0x")), - t=types.Types.BMCMessage) - ev = sp.local("ev", sp.record(next_bmc="", seq=sp.nat(0), message=sp.bytes("0x")), - t=types.Types.MessageEvent) - sp.for i in sp.range(sp.nat(0), sp.len(rps)): - with sp.if_(rps[i].height < rx_height.value): - pass - with sp.else_(): - rx_height.value = rps[i].height - sp.for j in sp.range(sp.nat(0), sp.len(rps[i].events)): - #stored events received by decoding in local variable - ev.value = rps[i].events[j] - sp.verify(ev.value.next_bmc == self.data.bmc_btp_address, "Invalid Next BMC") - rx_seq.value += sp.nat(1) - with sp.if_(ev.value.seq < rx_seq.value): - rx_seq.value = sp.as_nat(rx_seq.value-sp.nat(1)) - with sp.else_(): - with sp.if_(ev.value.seq > rx_seq.value): - sp.failwith(self.BMCRevertInvalidSeqNumber) - - _decoded = self.decode_bmc_message(ev.value.message) - bmc_msg.value = _decoded.bmc_dec_rv - with sp.if_(_decoded.status == sp.string("Success")): - with sp.if_(bmc_msg.value.dst == self.data.bmc_btp_address): - self._handle_message(prev, bmc_msg.value) + rps = rps_decode.receipt_proof + bmc_msg = sp.local("bmc_msg", sp.record(src="", dst="", svc="", sn=sp.int(0), message=sp.bytes("0x")), + t=types.Types.BMCMessage) + ev = sp.local("ev", sp.record(next_bmc="", seq=sp.nat(0), message=sp.bytes("0x")), + t=types.Types.MessageEvent) + sp.for i in sp.range(sp.nat(0), sp.len(rps)): + with sp.if_(rps[i].height < rx_height.value): + pass + with sp.else_(): + rx_height.value = rps[i].height + sp.for j in sp.range(sp.nat(0), sp.len(rps[i].events)): + #stored events received by decoding in local variable + ev.value = rps[i].events[j] + sp.verify(ev.value.next_bmc == self.data.bmc_btp_address, "Invalid Next BMC") + rx_seq.value += sp.nat(1) + with sp.if_(ev.value.seq < rx_seq.value): + rx_seq.value = sp.as_nat(rx_seq.value-sp.nat(1)) + with sp.else_(): + with sp.if_(ev.value.seq > rx_seq.value): + sp.failwith(self.BMCRevertInvalidSeqNumber) + + _decoded = self.decode_bmc_message(ev.value.message) + bmc_msg.value = _decoded.bmc_dec_rv + with sp.if_(_decoded.status == sp.string("Success")): + with sp.if_(bmc_msg.value.dst == self.data.bmc_btp_address): + self._handle_message(prev, bmc_msg.value) + with sp.else_(): + net, addr = sp.match_pair(strings.split_btp_address(bmc_msg.value.dst, "prev_idx", + "result", "my_list", "last", + "penultimate")) + next_link, prev_link = sp.match_pair(sp.view("resolve_route", + self.data.bmc_management,net, t=sp.TPair(sp.TString, + sp.TString)).open_some("Invalid Call")) + + with sp.if_(next_link != "Unreachable"): + self._send_message(next_link, ev.value.message) with sp.else_(): - net, addr = sp.match_pair(strings.split_btp_address(bmc_msg.value.dst, "prev_idx", - "result", "my_list", "last", - "penultimate")) - next_link, prev_link = sp.match_pair(sp.view("resolve_route", - self.data.bmc_management,net, t=sp.TPair(sp.TString, - sp.TString)).open_some("Invalid Call")) - - with sp.if_(next_link != "Unreachable"): - self._send_message(next_link, ev.value.message) - with sp.else_(): - self._send_error(prev, bmc_msg.value, self.BMC_ERR, "Unreachable_"+ net) + self._send_error(prev, bmc_msg.value, self.BMC_ERR, "Unreachable_"+ net) # call update_link_rx_seq on BMCManagement update_link_rx_seq_args_type = sp.TRecord(prev=sp.TString, val=sp.TNat) From 26a8d1b5d95928327efc651462eca1440914c2d8 Mon Sep 17 00:00:00 2001 From: simusud Date: Thu, 13 Jul 2023 14:27:41 +0545 Subject: [PATCH 151/211] perf(bts): added update functions and removed integration test file --- smartpy/bts/contracts/src/bts_core.py | 27 +- .../bts/contracts/tests/integration_test.py | 309 ------------------ 2 files changed, 17 insertions(+), 319 deletions(-) delete mode 100644 smartpy/bts/contracts/tests/integration_test.py diff --git a/smartpy/bts/contracts/src/bts_core.py b/smartpy/bts/contracts/src/bts_core.py index 7d5f4e3e..80745fdc 100644 --- a/smartpy/bts/contracts/src/bts_core.py +++ b/smartpy/bts/contracts/src/bts_core.py @@ -26,9 +26,7 @@ def __init__(self, _native_coin_name, _fee_numerator, _fixed_fee, owner_manager) bts_periphery_address=sp.none, native_coin_name=_native_coin_name, - # charged_amounts=sp.map(tkey=sp.TNat, tvalue=sp.TNat), coins_name=sp.list([_native_coin_name], t=sp.TString), - # charged_coins=sp.map(tkey=sp.TNat, tvalue=sp.TString), aggregation_fee=sp.map({}, tkey=sp.TString, tvalue=sp.TNat), balances=sp.big_map(tkey=sp.TRecord(address=sp.TAddress, coin_name=sp.TString), tvalue= types.Types.Balance), @@ -49,7 +47,12 @@ def only_owner(self): def only_bts_periphery(self): sp.verify(sp.sender == self.data.bts_periphery_address.open_some("Address not set"), "Unauthorized") - @sp.entry_point + @sp.entry_point(lazify=False) + def update_update_bts_periphery(self, ep): + self.only_owner() + sp.set_entry_point("update_bts_periphery", ep) + + @sp.entry_point(lazify=True) def update_bts_periphery(self, bts_periphery): """ update BTS Periphery address. @@ -117,17 +120,16 @@ def register(self, name, fee_numerator, fixed_fee, addr, token_metadata, metadat sp.verify(fee_numerator <= self.FEE_DENOMINATOR, message="InvalidSetting") sp.verify((fixed_fee >= sp.nat(0)) & (fee_numerator >= sp.nat(0)), message="LessThan0") with sp.if_(addr == self.ZERO_ADDRESS): - deployed_fa2 = sp.create_contract_operation( + deployed_fa2 = sp.create_contract( contract=FA2_contract.SingleAssetToken(admin=sp.self_address, metadata=metadata, token_metadata=token_metadata )) - sp.operations().push(deployed_fa2.operation) - self.data.coins[name] = deployed_fa2.address + self.data.coins[name] = deployed_fa2 self.data.coins_name.push(name) - self.data.coins_address[deployed_fa2.address] = name + self.data.coins_address[deployed_fa2] = name self.data.coin_details[name] = sp.record( - addr = deployed_fa2.address, + addr = deployed_fa2, fee_numerator = fee_numerator, fixed_fee = fixed_fee, coin_type = self.NATIVE_WRAPPED_COIN_TYPE @@ -472,7 +474,12 @@ def transfer_batch(self, coin_names_values, to): send_service_message_args = sp.record(_from=sp.sender, to=to, coin_details=batch_coin_details.value) sp.transfer(send_service_message_args, sp.tez(0), send_service_message_entry_point) - @sp.entry_point + @sp.entry_point(lazify=False) + def update_reclaim(self, ep): + self.only_owner() + sp.set_entry_point("reclaim", ep) + + @sp.entry_point(lazify=True) #TODO: implement nonReentrant def reclaim(self, coin_name, value): """ @@ -710,8 +717,8 @@ def _lock_balance(self, to, coin_name, value): @sp.entry_point def set_bts_owner_manager(self, owner_manager): sp.set_type(owner_manager, sp.TAddress) + self.only_owner() - # sp.verify(self.data.owners.get(sp.sender) == True , message= "Unauthorized") self.data.bts_owner_manager = owner_manager diff --git a/smartpy/bts/contracts/tests/integration_test.py b/smartpy/bts/contracts/tests/integration_test.py deleted file mode 100644 index 030e8b7b..00000000 --- a/smartpy/bts/contracts/tests/integration_test.py +++ /dev/null @@ -1,309 +0,0 @@ -import smartpy as sp - -BMCManagement = sp.io.import_script_from_url("file:./bmc/contracts/src/bmc_management.py") -BMCPeriphery = sp.io.import_script_from_url("file:./bmc/contracts/src/bmc_periphery.py") -BMCHelper = sp.io.import_script_from_url("file:./bmc//contracts/src/helper.py") -ParseAddress = sp.io.import_script_from_url("file:./contracts/src/parse_address.py") - -BTSCore = sp.io.import_script_from_url("file:./contracts/src/bts_core.py") -BTSOwnerManager = sp.io.import_script_from_url("file:./contracts/src/bts_owner_manager.py") -BTSPeriphery = sp.io.import_script_from_url("file:./contracts/src/bts_periphery.py") - - - - - -@sp.add_test("BMCManagementTest") -def test(): - sc = sp.test_scenario() - - # test account - alice = sp.test_account("Alice") - creator = sp.test_account("Creator") - jack = sp.test_account("Jack") - bob = sp.test_account("Bob") - creator2 = sp.test_account("creator2") - service1_address = sp.test_account("service1_address") - service2_address = sp.test_account("service2_address") - - - # deploy BMCManagement contract - - helper_contract = deploy_helper_contract() - sc += helper_contract - - bmcManagement_contract = deploy_bmcManagement_contract(creator.address, helper_contract.address) - sc += bmcManagement_contract - - parse_address = deploy_parse_address() - sc += parse_address - - bmcPeriphery_contract = deploy_bmcPeriphery_contract(bmcManagement_contract.address, helper_contract.address, parse_address.address,creator.address) - sc += bmcPeriphery_contract - - bts_owner_manager = deploy_btsOwnerManager_Contract(creator.address) - sc += bts_owner_manager - - btsCore_contract = deploy_btsCore_contract(bts_owner_manager.address) - sc += btsCore_contract - - - bts_periphery = deploy_btsPeriphery_Contract(btsCore_contract.address, helper_contract.address, parse_address.address, bmcPeriphery_contract.address,creator.address) - sc += bts_periphery - - fa2 = deploy_fa2_Contract(bts_periphery.address) - sc += fa2 - - #set bmc periphery - bmcManagement_contract.set_bmc_periphery(bmcPeriphery_contract.address).run(sender=creator.address) - #set bmc_btp_address(netwrk address) - bmcManagement_contract.set_bmc_btp_address("NetXnHfVqm9iesp.tezos").run(sender=creator.address) - #update_bts_periphery - btsCore_contract.update_bts_periphery(bts_periphery.address).run(sender=creator.address) - - #add_service - svc1 = sp.string("bts") - bmcManagement_contract.add_service(sp.record(addr=bts_periphery.address, svc=svc1)).run(sender=creator.address) - - #add_route - dst = "btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258dest" - next_link = "btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b" - bmcManagement_contract.add_route(sp.record(dst=dst, link=next_link)).run(sender=creator.address) - - #add_link - bmcManagement_contract.add_link("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b").run(sender=creator.address) - - - #set_link_rx_height - # link = sp.string('btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b') - # height = sp.nat(2) - # bmcManagement_contract.set_link_rx_height(link=link, height=height).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) - - # #add_relay - # bmcManagement_contract.add_relay(sp.record(link=link, addr=sp.set([sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")]))).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) - - #test 1: Test of add to blacklist function - # bts_periphery.add_to_blacklist({0:"notaaddress"}).run(sender=bts_periphery.address,valid=False, exception="InvalidAddress") # invalid address - bts_periphery.add_to_blacklist({0:"tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"}).run(sender=bts_periphery.address,valid=True) #add a address to blacklist - # bts_periphery.add_to_blacklist({0:"tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"}).run(sender=bts_periphery.address,valid=True) # can be called twice - # bts_periphery.add_to_blacklist({0:"tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"}) .run(sender=alice.address,valid=False,exception ="Unauthorized")# only btsperiphery contract call this function - # bts_periphery.add_to_blacklist({0:'tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg'}).run(sender=bts_periphery.address,valid=False,exception='InvalidAddress')#invalid address - # sc.verify(bts_periphery.data.blacklist[sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW")] == True) # checking the blacklist[] map - - # transfer_native_coin - bts_periphery.set_token_limit( - sp.record( - coin_names=sp.map({0: "btp-NetXnHfVqm9iesp.tezos-XTZ"}), - token_limit=sp.map({0: 115792089237316195423570985008687907853269984665640564039457584007913129639935}) - ) - ).run(sender = btsCore_contract.address) - btsCore_contract.transfer_native_coin("btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d").run(sender= sp.address("tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW"), amount=sp.tez(30), valid=False, exception="Blacklisted") - - - - - #test 2 : Test of remove from blacklist function - # bts_periphery.remove_from_blacklist({0:'notaaddress'}).run(sender=bts_periphery.address,valid=False, exception="InvalidAddress") # invalid address - # bts_periphery.remove_from_blacklist({0:'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=bts_periphery.address,valid=False, exception="UserNotFound") # address not black-listed - # bts_periphery.add_to_blacklist({0:'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=bts_periphery.address) # adding to blacklist - bts_periphery.remove_from_blacklist({0:'tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=bts_periphery.address) # valid process - btsCore_contract.transfer_native_coin("btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d").run(sender= bts_periphery.address, amount=sp.tez(30)) - - # bts_periphery.remove_from_blacklist({0:'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=bts_periphery.address,valid=False ,exception ='UserNotFound') # cannot remove from blacklist twice - # bts_periphery.add_to_blacklist({0:'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=bts_periphery.address) # adding to blacklist - # bts_periphery.remove_from_blacklist({0:'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=bts_periphery.address) # can only be called from btseperiphery contract - # bts_periphery.remove_from_blacklist({0:'tz1d2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnW'}).run(sender=alice.address, valid=False, exception ="Unauthorized") # can only be called from btseperiphery contract - - # transfer_native_coin - bts_periphery.set_token_limit( - sp.record( - coin_names=sp.map({0: "btp-NetXnHfVqm9iesp.tezos-XTZ"}), - token_limit=sp.map({0: 115792089237316195423570985008687907853269984665640564039457584007913129639935}) - ) - ).run(sender = btsCore_contract.address) - btsCore_contract.transfer_native_coin("btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d").run(sender= bmcManagement_contract.address, amount=sp.tez(30)) - - sc.verify_equal( - btsCore_contract.balance_of( - sp.record(owner=bmcManagement_contract.address, coin_name='btp-NetXnHfVqm9iesp.tezos-XTZ') - ),sp.record(usable_balance=0, locked_balance=30000000, refundable_balance=0, user_balance=0)) - - - - # transfer_native_coin - - - #bts core function test - - #test of transfer native coin - sc.verify(bts_periphery.data.number_of_pending_requests == 2)#2 pending request - sc.verify(bts_periphery.data.serial_no == 2) - btsCore_contract.transfer_native_coin("btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d").run(sender= bmcManagement_contract.address, amount=sp.tez(30)) - #this calls send service message of bts core - # in send service message function locked balance is called - sc.show(btsCore_contract.balance_of( - sp.record(owner=bmcManagement_contract.address, coin_name='btp-NetXnHfVqm9iesp.tezos-XTZ') - )) - sc.verify_equal( - btsCore_contract.balance_of( - sp.record(owner=bmcManagement_contract.address, coin_name='btp-NetXnHfVqm9iesp.tezos-XTZ') - ),sp.record(usable_balance=0, locked_balance=60000000, refundable_balance=0, user_balance=0)) - - #this calls btsperiphery sendservice message - #inside bts periphery send service message serial_no is incremented by 1 ,no of pending request is increased by 1, bmc send message is called - sc.verify(bts_periphery.data.number_of_pending_requests == 3)#2 pending request - sc.verify(bts_periphery.data.serial_no == 3) - #bmc management update link tx sq is called links[prev].tx_seq += sp.nat(1) - - - #test of non native coin transfer - btsCore_contract.register( - name=sp.string("new_coin"), - fee_numerator=sp.nat(10), - fixed_fee=sp.nat(2), - addr=fa2.address, - token_metadata=sp.map({"ff": sp.bytes("0x0dae11")}), - metadata=sp.big_map({"ff": sp.bytes("0x0dae11")}) - ).run(sender=creator.address) - - fa2.mint([sp.record(to_=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), amount=sp.nat(100))]).run(sender=bts_periphery.address) - fa2.set_allowance([sp.record(spender=btsCore_contract.address, amount=sp.nat(100))]).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) - - fa2.update_operators( - [sp.variant("add_operator", sp.record(owner=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), operator=btsCore_contract.address, token_id=0))]).run( - sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) - sc.verify_equal(btsCore_contract.is_valid_coin('new_coin'), True) - btsCore_contract.transfer(coin_name='new_coin', value=10, to="btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d").run(sender = sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) - sc.verify_equal( - btsCore_contract.balance_of( - sp.record(owner=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), coin_name='new_coin') - ), - sp.record(usable_balance=90, locked_balance=10, refundable_balance=0, user_balance=90) - ) - - #transfer batch - # test case 16: transfer_batch function - btsCore_contract.transfer_batch( - coin_names={0: 'new_coin', 1: 'new_coin'}, - values={0: 10, 1: 10}, - to="btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d" - ).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) - - sc.verify_equal( - btsCore_contract.balance_of( - sp.record(owner=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9"), coin_name='new_coin') - ), - sp.record(usable_balance=70, locked_balance=30, refundable_balance=0, user_balance=70) - ) - - - - bts_periphery.handle_request_service(sp.record(to= "tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc", assets={0: sp.record(coin_name="btp-NetXnHfVqm9iesp.tezos-XTZ", value=sp.nat(4))})).run(sender=bts_periphery.address) - #core's mint is called - # sc.verify_equal( - # btsCore_contract.balance_of( - # sp.record(owner=sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc"), coin_name="btp-NetXnHfVqm9iesp.tezos-XTZ") - # ), - # sp.record(usable_balance=0, locked_balance=0, refundable_balance=0, user_balance=0) - # ) - - - - - - bts_periphery.set_token_limit( - sp.record( - coin_names=sp.map({0: "btp-NetXnHfVqm9iesp.tezos-XTZ"}), - token_limit=sp.map({0: 5}) - ) - ).run(sender = btsCore_contract.address) - btsCore_contract.transfer_native_coin("btp://0x7.icon/cx4419cb43f1c53db85c4647e4ef0707880309726d").run(sender=bmcManagement_contract.address, amount=sp.tez(30), valid=False, exception="LimitExceed") - - - #Test : handle fee gathering - #this calls transfer fees of btscore - # bts_periphery.handle_fee_gathering(sp.record(fa="btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258dest", svc="bts")).run(sender=bmcPeriphery_contract.address) # handle_fee_gathering function call - # bts_periphery.handle_fee_gathering(sp.record(fa="btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258dest", svc="btc")).run(sender=bmcPeriphery_contract.address, valid=False, exception='InvalidSvc') # svc must match hardcoded service name 'bts' - # bts_periphery.handle_fee_gathering(sp.record(fa="btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258dest", svc="bts")).run(sender=bts_periphery.address, valid=False, exception='Unauthorized') # can only be called from bmc contract - - - - # #test 3 : set token limit - # bts_periphery.set_token_limit(sp.record(coin_names = {0:"Tok2" , 1:'BB'} ,token_limit ={0:sp.nat(5),1:sp.nat(2)})).run(sender=alice.address,valid=False,exception='Unauthorized') #can only be called from btsperiphery contract - # bts_periphery.set_token_limit(sp.record(coin_names = {0:"Tok2" , 1:'BB'} ,token_limit ={0:sp.nat(5),1:sp.nat(2)})).run(sender=bts_periphery.address) #set token limit for Tok2 coin to 5 and BB coin to 2 - # sc.verify(bts_periphery.data.token_limit["Tok2"] == sp.nat(5))#test of token_limit for tok2 token - # bts_periphery.set_token_limit(sp.record(coin_names = {0:"Tok2" , 1:'BB'} ,token_limit ={0:sp.nat(5)} )).run(valid=False,exception='InvalidParams',sender=bts_periphery.address) #invalid parameters - # #cannot set more than 15 token limit at once - # bts_periphery.set_token_limit(sp.record(coin_names = {0:"Tok2" , 1:'BB'} ,token_limit ={0:sp.nat(15),1:sp.nat(22)})).run(sender=bts_periphery.address) #can modify already set data - # sc.verify(bts_periphery.data.token_limit["BB"] == sp.nat(22))#test of token_limit for tok2 token - - # # handle_relay_message - # msg=sp.bytes("0xf90236f90233b8ddf8db01b8d3f8d1f8cfb8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5431417259755046465a596341766f396b71793251673167327667465965676f52714a04b88af888b8396274703a2f2f3078372e69636f6e2f637831666637646432636639373836316262653462666536386232663463313834376562666132663534b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5431417259755046465a596341766f396b71793251673167327667465965676f52714a8362747381ff84c300f80084008449a0b90151f9014e01b90145f90142f9013fb8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5431417259755046465a596341766f396b71793251673167327667465965676f52714a05b8faf8f8b8396274703a2f2f3078372e69636f6e2f637831666637646432636639373836316262653462666536386232663463313834376562666132663534b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5431417259755046465a596341766f396b71793251673167327667465965676f52714a8362747303b874f87200b86ff86daa687839643138316431336634376335616165353535623730393831346336623232393738373937363139a4747a3157615078716f375868556e56344c346669324457424e4e51384a6231777445716edcdb906274702d3078372e69636f6e2d4943588900d71b0fe0a28e000084008449bf") - # prev=sp.string("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a6258d67b") - # bmcPeriphery_contract.handle_relay_message(sp.record(prev=prev, msg=msg)).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) - - # #set_fee_ratio - # btsCore_contract.set_fee_ratio(name=sp.string("btp-NetXnHfVqm9iesp.tezos-XTZ"),fee_numerator=sp.nat(100),fixed_fee=sp.nat(450)).run(sender=sp.address("tz1XGbmLYhqcigxFuBCJrgyJejnwkySE4Sk9")) - - - - -def deploy_bmcManagement_contract(owner, helper): - bmcManagement_contract = BMCManagement.BMCManagement(owner, helper) - return bmcManagement_contract - -def deploy_bmcPeriphery_contract(bmc_addres, helper, parse,owner): - bmcPeriphery_contract = BMCPeriphery.BMCPreiphery(bmc_addres, helper,helper, parse, owner) - return bmcPeriphery_contract - -def deploy_helper_contract(): - helper_contract = BMCHelper.Helper() - return helper_contract - - -def deploy_parse_address(): - parse_address = ParseAddress.ParseAddress() - return parse_address - - -def deploy_btsCore_contract(bts_OwnerManager_Contract): - btsCore_contract = BTSCore.BTSCore( - owner_manager=bts_OwnerManager_Contract, - _native_coin_name="btp-NetXnHfVqm9iesp.tezos-XTZ", - _fee_numerator=sp.nat(100), - _fixed_fee=sp.nat(450) - ) - return btsCore_contract - -def deploy_btsOwnerManager_Contract(owner): - bts_OwnerManager_Contract = BTSOwnerManager.BTSOwnerManager(owner) - return bts_OwnerManager_Contract - -def deploy_btsPeriphery_Contract(core_address, helper, parse, bmc,owner): - btsPeriphery_Contract = BTSPeriphery.BTPPreiphery(bmc_address= bmc, bts_core_address=core_address, helper_contract=helper, parse_address=parse, owner_address=owner, native_coin_name="btp-NetXnHfVqm9iesp.tezos-XTZ") - return btsPeriphery_Contract - -def deploy_fa2_Contract(creator): - fa2_contract = BTSCore.FA2_contract.SingleAssetToken(admin=creator, metadata=sp.big_map({"ss": sp.bytes("0x0dae11")}), token_metadata=sp.map({"ff": sp.bytes("0x0dae11")})) - return fa2_contract - - -#Core - function with interscore call - -# Transfer_fees - called from bts_periphery - checked from bts periphery handle fee gathering -# Handle_response_service- called from bts_periphery -# Mint - called from bts_periphery -# Refund - refunds -# Transfer batch - -# Send service message -# Transfer -# Transfer native coin - -# Periphery -# Send service message - bts core -# Handle btp message - only bmc - done -# Handle btp error- only bmc -calls handle response service of periphery - done -# Handle response service -called from handle_btp_message-calls core handle response service -# Handle fee gathering - only bmc - calls core transfer_fees -# Send response message - called from handle btp message/ calls bmc send message -# –Handle request service - called from handle btp message /calls core mint - can be called for mint \ No newline at end of file From e92afd23d99773c97f369fa02000bb91c87d2eb0 Mon Sep 17 00:00:00 2001 From: simusud Date: Thu, 13 Jul 2023 14:29:37 +0545 Subject: [PATCH 152/211] perf(bmc): review changes and removed parse address file --- smartpy/bmc/contracts/src/RLP_struct.py | 6 +- smartpy/bmc/contracts/src/bmc_management.py | 88 +++++++---------- smartpy/bmc/contracts/src/bmc_periphery.py | 10 +- smartpy/bmc/contracts/src/parse_address.py | 104 -------------------- 4 files changed, 46 insertions(+), 162 deletions(-) delete mode 100644 smartpy/bmc/contracts/src/parse_address.py diff --git a/smartpy/bmc/contracts/src/RLP_struct.py b/smartpy/bmc/contracts/src/RLP_struct.py index 726ac68a..dd01f8bc 100644 --- a/smartpy/bmc/contracts/src/RLP_struct.py +++ b/smartpy/bmc/contracts/src/RLP_struct.py @@ -31,7 +31,8 @@ def decode_bmc_message(self, rlp): return_value_map["svc"] = sp.view("decode_string", self.data.helper, k.value, t=sp.TString).open_some() with sp.if_ (counter.value == 3): sn_in_bytes = sp.view("without_length_prefix", self.data.helper, k.value, t=sp.TBytes).open_some() - sn_no.value = sp.view("to_int", self.data.helper_parse_negative, sn_in_bytes, t=sp.TInt).open_some() + _to_int = sp.view("to_int", self.data.helper_parse_negative, sn_in_bytes, t=sp.TInt).open_some() + sn_no.value = _to_int with sp.if_ (counter.value == 4): decoded_message.value = sp.view("without_length_prefix", self.data.helper, k.value, t=sp.TBytes).open_some() @@ -257,7 +258,8 @@ def encode_bmc_message(self, params): encode_src = sp.view("encode_string", self.data.helper, params.src, t=sp.TBytes).open_some() encode_dst = sp.view("encode_string", self.data.helper, params.dst, t=sp.TBytes).open_some() encode_svc = sp.view("encode_string", self.data.helper, params.svc, t=sp.TBytes).open_some() - rlp.value = sp.view("to_byte", self.data.helper_parse_negative, params.sn, t=sp.TBytes).open_some() + _to_byte = sp.view("to_byte", self.data.helper_parse_negative, params.sn, t=sp.TBytes).open_some() + rlp.value = _to_byte with sp.if_ (params.sn < sp.int(0)): encode_sn = sp.view("with_length_prefix", self.data.helper, rlp.value, t=sp.TBytes).open_some() diff --git a/smartpy/bmc/contracts/src/bmc_management.py b/smartpy/bmc/contracts/src/bmc_management.py index 133e87a6..e53b0db4 100644 --- a/smartpy/bmc/contracts/src/bmc_management.py +++ b/smartpy/bmc/contracts/src/bmc_management.py @@ -6,23 +6,22 @@ class BMCManagement(sp.Contract, rlp.DecodeEncodeLibrary): - BLOCK_INTERVAL_MSEC = sp.nat(1000) + BLOCK_INTERVAL_MSEC = sp.nat(30000) LIST_SHORT_START = sp.bytes("0xc0") + ZERO_ADDRESS = sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg") def __init__(self, owner_address, helper_contract): self.init( - owners=sp.map(l={owner_address:True}), + owners=sp.map(l={owner_address:Tue}), number_of_owners=sp.nat(1), bsh_services=sp.map(), relay_stats=sp.map(), routes=sp.map(), links=sp.map(), - list_bsh_names=sp.set(), list_route_keys=sp.set(), list_link_names=sp.set(), - bmc_periphery=sp.none, + bmc_periphery=self.ZERO_ADDRESS, serial_no=sp.nat(0), - addrs=sp.set(), get_route_dst_from_net=sp.map(), get_link_from_net=sp.map(), get_link_from_reachable_net=sp.map(), @@ -36,12 +35,10 @@ def __init__(self, owner_address, helper_contract): relay_stats=sp.TMap(sp.TAddress, types.Types.RelayStats), routes=sp.TMap(sp.TString, sp.TString), links=sp.TMap(sp.TString, types.Types.Link), - list_bsh_names=sp.TSet(sp.TString), list_route_keys=sp.TSet(sp.TString), list_link_names=sp.TSet(sp.TString), - bmc_periphery=sp.TOption(sp.TAddress), + bmc_periphery=sp.TAddress, serial_no=sp.TNat, - addrs=sp.TSet(sp.TAddress), get_route_dst_from_net=sp.TMap(sp.TString, sp.TString), get_link_from_net=sp.TMap(sp.TString, sp.TString), get_link_from_reachable_net=sp.TMap(sp.TString, types.Types.Tuple), @@ -55,7 +52,7 @@ def only_owner(self): sp.failwith("Unauthorized") def only_bmc_periphery(self): - sp.verify(sp.sender == self.data.bmc_periphery.open_some("BMCAddressNotSet"), "Unauthorized") + sp.verify(sp.sender == self.data.bmc_periphery, "Unauthorized") @sp.entry_point def set_helper_address(self, address): @@ -66,15 +63,15 @@ def set_helper_address(self, address): @sp.entry_point def set_bmc_periphery(self, addr): """ - :param addr: address of bmc_periphery :return: """ sp.set_type(addr, sp.TAddress) + self.only_owner() - with sp.if_(self.data.bmc_periphery.is_some()): - sp.verify(addr != self.data.bmc_periphery.open_some("Address not set"), "AlreadyExistsBMCPeriphery") - self.data.bmc_periphery = sp.some(addr) + sp.verify(addr != self.ZERO_ADDRESS, "Invalid Address") + sp.verify(addr != self.data.bmc_periphery, "AlreadyExistsBMCPeriphery") + self.data.bmc_periphery = addr @sp.entry_point def set_bmc_btp_address(self, network): @@ -83,7 +80,7 @@ def set_bmc_btp_address(self, network): self.only_owner() # call set_btp_address on BMCPeriphery set_btp_address_entry_point = sp.contract(sp.TString, - self.data.bmc_periphery.open_some("Address not set"), + self.data.bmc_periphery, "set_bmc_btp_address").open_some() sp.transfer(network, sp.tez(0), set_btp_address_entry_point) @@ -98,7 +95,6 @@ def add_owner(self, owner): self.only_owner() sp.verify(self.data.owners.contains(owner) == False, "Already Exists") self.data.owners[owner] = True - self.data.number_of_owners += sp.nat(1) @sp.entry_point def remove_owner(self, owner): @@ -110,18 +106,17 @@ def remove_owner(self, owner): sp.set_type(owner, sp.TAddress) self.only_owner() - sp.verify(self.data.number_of_owners > sp.nat(1), "LastOwner") + sp.verify(sp.len(self.data.owners) > sp.nat(1), "LastOwner") sp.verify(self.data.owners[owner] == True, "NotExistsPermission") del self.data.owners[owner] - self.data.number_of_owners = sp.as_nat(self.data.number_of_owners - sp.nat(1)) @sp.onchain_view() def is_owner(self, owner): """ - :param owner: address to check :return: """ + sp.set_type(owner, sp.TAddress) sp.result(self.data.owners.get(owner)) @sp.entry_point @@ -132,11 +127,13 @@ def add_service(self, svc, addr): :param addr: Service's contract address :return: """ + sp.set_type(svc, sp.TString) + sp.set_type(addr, sp.TAddress) + self.only_owner() sp.verify(addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg"), "InvalidAddress") sp.verify(self.data.bsh_services.contains(svc) == False, "AlreadyExistsBSH") self.data.bsh_services[svc] = addr - self.data.list_bsh_names.add(svc) @sp.entry_point def remove_service(self, svc): @@ -145,10 +142,11 @@ def remove_service(self, svc): :param svc: Name of the service :return: """ + sp.set_type(svc, sp.TString) + self.only_owner() sp.verify(self.data.bsh_services.contains(svc), "NotExistsBSH") del self.data.bsh_services[svc] - self.data.list_bsh_names.remove(svc) @sp.onchain_view() def get_services(self): @@ -156,13 +154,7 @@ def get_services(self): Get registered services. :return: An array of Service. """ - - services = sp.compute(sp.map(tkey=sp.TNat, tvalue=types.Types.Service)) - i = sp.local("i", sp.nat(0)) - sp.for item in self.data.list_bsh_names.elements(): - services[i.value] = sp.record(svc=item, addr=self.data.bsh_services.get(item)) - i.value += 1 - sp.result(services) + sp.result(self.data.bsh_services) @sp.entry_point(lazify=False) def update_add_link(self, ep): @@ -225,10 +217,11 @@ def remove_link(self, link): sp.verify(self.data.links.get(link).is_connected == True, "NotExistsLink") with sp.else_(): sp.failwith("NotExistsLink") - self._propagate_internal("Unlink", link) + del self.data.links[link] net, addr= sp.match_pair(strings.split_btp_address(link, "prev_idx", "result", "my_list", "last", "penultimate")) del self.data.get_link_from_net[net] + self._propagate_internal("Unlink", link) self.data.list_link_names.remove(link) @sp.onchain_view() @@ -242,7 +235,6 @@ def get_links(self): @sp.entry_point def set_link_rx_height(self, link, height): """ - :param link: :param height: :return: @@ -306,18 +298,19 @@ def _propagate_internal(self, service_type, link): final_rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [rlp_bytes_with_prefix], t=sp.TBytes).open_some() sp.for item in self.data.list_link_names.elements(): - with sp.if_(self.data.links.get(item).is_connected): - net, addr = sp.match_pair(strings.split_btp_address(item, "prev_idx1", "result1", - "my_list1", "last1", "penultimate1")) - - # call send_message on BMCPeriphery - send_message_args_type = sp.TRecord(to=sp.TString, svc=sp.TString, sn=sp.TInt, msg=sp.TBytes) - send_message_entry_point = sp.contract(send_message_args_type, - self.data.bmc_periphery.open_some("Address not set"), - "send_message").open_some() - send_message_args = sp.record(to=net, svc="bmc", sn=sp.int(0), msg=self.encode_bmc_service( - sp.record(serviceType=service_type,payload=final_rlp_bytes_with_prefix))) - sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) + with sp.if_(self.data.links.contains(item)): + with sp.if_(self.data.links.get(item).is_connected): + net, addr = sp.match_pair(strings.split_btp_address(item, "prev_idx1", "result1", + "my_list1", "last1", "penultimate1")) + + # call send_message on BMCPeriphery + send_message_args_type = sp.TRecord(to=sp.TString, svc=sp.TString, sn=sp.TInt, msg=sp.TBytes) + send_message_entry_point = sp.contract(send_message_args_type, + self.data.bmc_periphery, + "send_message").open_some() + send_message_args = sp.record(to=net, svc="bmc", sn=sp.int(0), msg=self.encode_bmc_service( + sp.record(serviceType=service_type,payload=final_rlp_bytes_with_prefix))) + sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) def _send_internal(self, target, service_type, links): sp.set_type(target, sp.TString) @@ -334,14 +327,13 @@ def _send_internal(self, target, service_type, links): rlp_bytes.value = sp.view("encode_list", self.data.helper, [rlp_bytes.value, _rlp_bytes], t=sp.TBytes).open_some() #encode payload - # final_rlp_bytes_with_prefix = sp.view("with_length_prefix", self.data.helper, rlp_bytes.value, t=sp.TBytes).open_some() net, addr = sp.match_pair( strings.split_btp_address(target, "prev_idx2", "result2", "my_list2", "last2", "penultimate2")) # call send_message on BMCPeriphery send_message_args_type = sp.TRecord(to=sp.TString, svc=sp.TString, sn=sp.TInt, msg=sp.TBytes) send_message_entry_point = sp.contract(send_message_args_type, - self.data.bmc_periphery.open_some("Address not set"), + self.data.bmc_periphery, "send_message").open_some() send_message_args = sp.record(to=net, svc="bmc", sn=sp.int(0), msg=self.encode_bmc_service(sp.record(serviceType=service_type, @@ -451,16 +443,12 @@ def remove_relay(self, link, addr): sp.verify(self.data.links.contains(link), "NotExistsLink") sp.verify((self.data.links.get(link).is_connected == True) & (sp.len(self.data.links.get(link).relays.elements()) != sp.nat(0)), "Unauthorized") - + addr_set = sp.local("addr_set", sp.set(), t=sp.TSet(sp.TAddress)) sp.for item in self.data.links.get(link).relays.elements(): with sp.if_(item != addr): - self.data.addrs.add(item) - - self.data.links[link].relays = self.data.addrs + addr_set.value.add(item) - # delete all items from addrs set - sp.for ele in self.data.addrs.elements(): - self.data.addrs.remove(ele) + self.data.links[link].relays = addr_set.value @sp.onchain_view() def get_relays(self, link): diff --git a/smartpy/bmc/contracts/src/bmc_periphery.py b/smartpy/bmc/contracts/src/bmc_periphery.py index 815dccb4..919c8aca 100644 --- a/smartpy/bmc/contracts/src/bmc_periphery.py +++ b/smartpy/bmc/contracts/src/bmc_periphery.py @@ -20,18 +20,18 @@ class BMCPreiphery(sp.Contract, rlp.DecodeEncodeLibrary): BMCRevertUnknownHandleBTPError = sp.string("UnknownHandleBTPError") BMCRevertUnknownHandleBTPMessage = sp.string("UnknownHandleBTPMessage") - def __init__(self, bmc_management_addr, helper_contract, helper_parse_neg_contract, parse_address, owner_address): + def __init__(self, bmc_management_addr, helper_contract, helper_parse_neg_contract, parse_address): self.init( helper=helper_contract, helper_parse_negative=helper_parse_neg_contract, bmc_btp_address=sp.string(""), bmc_management=bmc_management_addr, parse_contract=parse_address, - owner_address = owner_address ) def only_owner(self): - sp.verify(sp.sender == self.data.owner_address, "Unauthorized") + owner = sp.view("is_owner", self.data.bmc_management, sp.sender, t=sp.TBool) + sp.verify(owner == True, "Unauthorized") @sp.entry_point def set_helper_address(self, address): @@ -402,6 +402,4 @@ def get_status(self, _link): sp.add_compilation_target("bmc_periphery", BMCPreiphery(bmc_management_addr=sp.address("KT1G3R9VqESejtsFnvjHSjzXYfuKuHMeaiE3"), helper_contract=sp.address("KT1HwFJmndBWRn3CLbvhUjdupfEomdykL5a6"), helper_parse_neg_contract=sp.address("KT1DHptHqSovffZ7qqvSM9dy6uZZ8juV88gP"), - parse_address=sp.address("KT1VJn3WNXDsyFxeSExjSWKBs9JYqRCJ1LFN"), - owner_address=sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP") - )) + parse_address=sp.address("KT1VJn3WNXDsyFxeSExjSWKBs9JYqRCJ1LFN") )) diff --git a/smartpy/bmc/contracts/src/parse_address.py b/smartpy/bmc/contracts/src/parse_address.py deleted file mode 100644 index 57ced093..00000000 --- a/smartpy/bmc/contracts/src/parse_address.py +++ /dev/null @@ -1,104 +0,0 @@ -import smartpy as sp -Utils = sp.io.import_script_from_url("https://raw.githubusercontent.com/RomarQ/tezos-sc-utils/main/smartpy/utils.py") - - -class ParseAddress(sp.Contract): - tz_prefixes = sp.map({ - sp.bytes('0x0000'): sp.string('tz1'), - sp.bytes('0x0001'): sp.string('tz2'), - sp.bytes('0x0002'): sp.string('tz3'), - sp.bytes('0x0003'): sp.string('tz4') - }) - base58_encodings = sp.list([ - sp.map({"prefix": "tz1", "elem1": "6", "elem2": "161", "elem3": "159", "len": "20"}), - sp.map({"prefix": "tz2", "elem1": "6", "elem2": "161", "elem3": "161", "len": "20"}), - sp.map({"prefix": "tz3", "elem1": "6", "elem2": "161", "elem3": "164", "len": "20"}), - sp.map({"prefix": "tz4", "elem1": "6", "elem2": "161", "elem3": "16", "len": "20"}), - sp.map({"prefix": "KT1", "elem1": "2", "elem2": "90", "elem3": "121", "len": "20"}), - ]) - - def __init__(self): - self.init() - - def unforge_address(self, data): - """Decode address or key_hash from bytes. - - :param data: encoded address or key_hash - :returns: base58 encoded address - """ - sp.set_type(data, sp.TBytes) - byt = sp.slice(data, 6, 22).open_some() - prefix = sp.slice(byt, 0, 2).open_some() - starts_with = sp.slice(byt, 0, 1).open_some() - ends_with = sp.slice(byt, 21, 1).open_some() - sliced_byte = sp.slice(byt, 1, 20).open_some() - local_byte = sp.local("local_byte", sp.bytes("0x")) - return_value = sp.local("return_value", "tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg", sp.TString) - - sp.for item in self.tz_prefixes.items(): - sp.if item.key == prefix: - return_value.value = self.base58_encode(sp.slice(byt, 2, 20).open_some(), Utils.Bytes.of_string(item.value), local_byte) - - sp.if (starts_with == sp.bytes("0x01")) & (ends_with == sp.bytes("0x00")): - return_value.value = self.base58_encode(sliced_byte, Utils.Bytes.of_string("KT1"), local_byte) - sp.if (starts_with == sp.bytes("0x02")) & (ends_with == sp.bytes("0x00")): - return_value.value = self.base58_encode(sliced_byte, Utils.Bytes.of_string("txr1"), local_byte) - sp.if (starts_with == sp.bytes("0x03")) & (ends_with == sp.bytes("0x00")): - return_value.value = self.base58_encode(sliced_byte, Utils.Bytes.of_string("sr1"), local_byte) - - return return_value.value - - def tb(self, _list): - byte_str = sp.local("byte_str", sp.bytes("0x")) - sp.for num in _list: - byte_str.value += Utils.Bytes.of_nat(num) - return byte_str.value - - def base58_encode(self, byt_array, prefix, _byte): - """ - Encode data using Base58 with checksum and add an according binary prefix in the end. - :param byt_array: Array of bytes - :param prefix: Human-readable prefix (use b'') e.g. b'tz', b'KT', etc - :param local_byte: local variable - - :returns: bytes (use string.decode()) - """ - length_v = sp.to_int(sp.len(byt_array)) - encoding = sp.local("encode", sp.map({})) - byte_from_tbl = sp.local("byte_from_tbl", sp.bytes("0x")) - byte_value = _byte - - sp.for enc in self.base58_encodings: - sp.if (length_v == Utils.Int.of_string(enc["len"])) & (prefix == Utils.Bytes.of_string(enc["prefix"])): - encoding.value = enc - byte_from_tbl.value = self.tb([sp.as_nat(Utils.Int.of_string(enc["elem1"])), - sp.as_nat(Utils.Int.of_string(enc["elem2"])), - sp.as_nat(Utils.Int.of_string(enc["elem3"]))]) - sha256_encoding = sp.sha256(sp.sha256(byte_from_tbl.value + byt_array)) - sha256_encoding = byte_from_tbl.value + byt_array + sp.slice(sha256_encoding, 0, 4).open_some() - acc = sp.local("for_while_loop", Utils.Int.of_bytes(sha256_encoding)) - alphabet = Utils.Bytes.of_string("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") - base = 58 - sp.while acc.value > 0: - (acc.value, idx) = sp.match_pair(sp.ediv(acc.value, base).open_some()) - byte_value.value = sp.slice(alphabet, idx, 1).open_some() + byte_value.value - - return sp.unpack(sp.bytes("0x050100000024") + byte_value.value, sp.TString).open_some() - - @sp.onchain_view() - def add_to_str(self, params): - sp.set_type(params, sp.TAddress) - sp.result(self.unforge_address(sp.pack(params))) - - -@sp.add_test(name="Conversion") -def test(): - c1 = ParseAddress() - scenario = sp.test_scenario() - scenario.h1("Conversion") - scenario += c1 - c1.add_to_str(sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP")) - scenario.verify(c1.add_to_str(sp.address("KT1FfkTSts5DnvyJp2qZbPMeqm2XpMYES7Vr")) == "KT1FfkTSts5DnvyJp2qZbPMeqm2XpMYES7Vr") - scenario.verify(c1.add_to_str(sp.address("tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP")) == "tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP") - -sp.add_compilation_target("parse_address", ParseAddress()) \ No newline at end of file From d33c50b6ff8cca0537981cb511be5b444c1ef3c5 Mon Sep 17 00:00:00 2001 From: suyogadhikari Date: Thu, 13 Jul 2023 19:54:57 +0545 Subject: [PATCH 153/211] test(bmc): message modified in integration test. --- .../bmc/contracts/tests/integration_test.py | 280 ++++++++++-------- 1 file changed, 160 insertions(+), 120 deletions(-) diff --git a/smartpy/bmc/contracts/tests/integration_test.py b/smartpy/bmc/contracts/tests/integration_test.py index b785cc17..6c661d15 100644 --- a/smartpy/bmc/contracts/tests/integration_test.py +++ b/smartpy/bmc/contracts/tests/integration_test.py @@ -44,7 +44,7 @@ ], "bmc_periphery": [ {'_self_address': - [' _self_address = sp.address("KT1WKBHLFbgL8QJWGySf5CK2hK3iCLEM9ZiT")', + [' _self_address = sp.address("KT1T7kJERDbURCeZGBpTVq6yUR6pkWFJcfRG")', ' _self_address = sp.self_address' ] } @@ -131,8 +131,8 @@ def test(): helper_parse_neg_contract = sp.test_account("helper_parse_neg_contract") # in cas of new env: change icon_bmc_address and its block height of new environment - icon_bmc_address = "cx51e0bb85839e0e3fffb4c0140ae0f083e898464d" - icon_bmc_block_height = 10660605 + icon_bmc_address = "cx674dbf2aae08b31ecb8174e755b2f0fa42a81298" + icon_bmc_block_height = 10785336 # deploy contracts @@ -225,23 +225,26 @@ def test(): # Tests # Scenario 1: Init message from relay msg_byte = sp.bytes( - "0xf8e5f8e3b8e1f8df01b8d7f8d5f8d3b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5431574b42484c" - "4662674c38514a574779536635434b32684b3369434c454d395a695401b88ef88cb8396274703a2f2f3078372e69636f6e2f63783531" - "6530626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f2f4e6574586e486656" - "716d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a695483626d63" - "0089c884496e697482c1c08400a2aba8") + "0xf8e5f8e3b8e1f8df01b8d7f8d5f8d3b8406274703a2f2f4e6574586e486656716" + "d39696573702e74657a6f732f4b543154376b4a45524462555243655a47427054567136" + "79555236706b57464a6366524701b88ef88cb8396274703a2f2f3078372e69636f6e2f6378363734646" + "26632616165303862333165636238313734653735356232663066613432613831323938b8406274703a2f2f4e6" + "574586e486656716d39696573702e74657a6f732f4b543154376b4a45524462555243655a47427054567136795552" + "36706b57464a6366524783626d630089c884496e697482c1c08400a4927b") bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) # Scenario 2: Add to blacklist called from icon # add bob and tz1bPkYCh5rTTGL7DuPLB66J8zqnUD8cMRq1 msg_byte = sp.bytes( - "0xf9014df9014ab90147f9014401b9013bf90138f90135b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5" - "431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a695402b8f0f8eeb8396274703a2f2f3078372e69636" - "f6e2f637835316530626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f2f4e6" - "574586e486656716d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395" - "a69548362747301b86af86803b865f86300f84aa4747a3165754850316e7444347233727638427345357058705452426e55467536397" - "75950a4747a3162506b59436835725454474c374475504c4236364a387a716e554438634d527131954e6574586e486656716d3969657" - "3702e74657a6f738400a2ac69") + "0xf9014df9014ab90147f9014401b9013bf90138f90135b8406274703a2f2f4e6574586e" + "486656716d39696573702e74657a6f732f4b543154376b4a45524462555243655a47427054" + "56713679555236706b57464a6366524702b8f0f8eeb8396274703a2f2f3078372e69636f6e2f63" + "7836373464626632616165303862333165636238313734653735356232663066613432613831323938" + "b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b543154376b4a45524462" + "555243655a4742705456713679555236706b57464a636652478362747301b86af86803b865f86300f84" + "aa4747a3165754850316e7444347233727638427345357058705452426e5546753639775950a4747a3162" + "506b59436835725454474c3" + "74475504c4236364a387a716e554438634d527131954e6574586e486656716d39696573702e74657a6f738400a4934b") bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) # verify blacklisted address sc.verify_equal(bts_periphery.data.blacklist, {sp.address("tz1euHP1ntD4r3rv8BsE5pXpTRBnUFu69wYP"): True, @@ -250,12 +253,12 @@ def test(): # Scenario 3: Remove from blacklist called from icon # remove bob msg_byte = sp.bytes( - "0xf90127f90124b90121f9011e01b90115f90112f9010fb8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b" - "5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a695403b8caf8c8b8396274703a2f2f3078372e6963" - "6f6e2f637835316530626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f2f4e" - "6574586e486656716d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d39" - "5a69548362747302b844f84203b83ff83d01e5a4747a3165754850316e7444347233727638427345357058705452426e554675363977" - "5950954e6574586e486656716d39696573702e74657a6f738400a2ac8c") + "0xf90127f90124b90121f9011e01b90115f90112f9010fb8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732" + "f4b543154376b4a45524462555243655a4742705456713679555236706b57464a6366524703b8caf8c8b8396274703" + "a2f2f3078372e69636f6e2f637836373464626632616165303862333165636238313734653735356232663066613432613831323" + "938b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b543154376b4a45524462555243655a47427054" + "56713679555236706b57464a636652478362747302b844f84203b83ff83d01e5a4747a3165754850316e744434723372763842734" + "5357058705452426e5546753639775950954e6574586e486656716d39696573702e74657a6f738400a49366") bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) # verify one blacklisted address is removed sc.verify(bts_periphery.data.blacklist.get(sp.address("tz1bPkYCh5rTTGL7DuPLB66J8zqnUD8cMRq1")) == True) @@ -276,13 +279,15 @@ def test(): ).run(sender=owner.address) msg_byte = sp.bytes( - "0xf90157f90154b90151f9014e01b90145f90142f9013fb8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5" - "431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a695404b8faf8f8b8396274703a2f2f3078372e69636f" - "6e2f637835316530626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f2f4e657" - "4586e486656716d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a69" - "548362747303b874f87200b86ff86daa68783964313831643133663437633561616535353562373039383134633662323239373837393" - "7363139a4747a3165754850316e7444347233727638427345357058705452426e5546753639775950dcdb906274702d3078372e69636f" - "6e2d49435889011bccfea6b8bd00008400a2acd5") + "0xf90157f90154b90151f9014e01b90145f90142f9013fb8406274703a2f2f4e6574586e486656716d39" + "696573702e74657a6f732f4b543154376b4a45524462555243655a4742705456713679555236706b57" + "464a6366524704b8faf8f8b8396274703a2f2f3078372e69636f6e2f63783637346462663261616530" + "3862333165636238313734653735356232663066613432613831323938b8406274703a2f2f4e6574586e" + "486656716d39696573702e74657a6f732f4b543154376b4a45524462555243655a4742705456713679555" + "236706b57464a636652478362747303b874f87200b86ff86daa6878396431383164313366343763356161" + "65353535623730393831346336623232393738373937363139a4747a3165754850316e7444347233727638" + "427345357058705" + "452426e5546753639775950dcdb906274702d3078372e69636f6e2d49435889011bccfea6b8bd00008400a493c0") bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) # verify native coin balance coin_address = bts_core.data.coins.get("btp-0x7.icon-ICX") @@ -298,13 +303,15 @@ def test(): # transferred: bnUSD4: 50*10**18 # receiver address: jack msg_byte = sp.bytes( - "0xf9015af90157b90154f9015101b90148f90145f90142b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b" - "5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a695405b8fdf8fbb8396274703a2f2f3078372e6963" - "6f6e2f637835316530626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f2f4e" - "6574586e486656716d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d39" - "5a69548362747304b877f87500b872f870aa687839643138316431336634376335616165353535623730393831346336623232393738" - "373937363139a4747a31555576546e646369794a4a587550484245765778754d39716745434d5633316541dfde936274702d3078372e" - "69636f6e2d626e555344348902b5e3af16b18800008400a2ad38") + "0xf9015af90157b90154f9015101b90148f90145f90142b8406274703a2f2f4e6574586e48665" + "6716d39696573702e74657a6f732f4b543154376b4a45524462555243655a4742705456713679555" + "236706b57464a6366524705b8fdf8fbb8396274703a2f2f3078372e69636f6e2f6378363734646266" + "32616165303862333165636238313734653735356232663066613432613831323938b8406274703a2" + "f2f4e6574586e486656716d39696573702e74657a6f732f4b543154376b4a45524462555243655a47" + "42705456713679555236706b57464a636652478362747304b877f87500b872f870aa687839643138316" + "431336634376335616165353535623730393831346336623232393738373937363139a4747a314d724" + "148503931584c584a58426f4233574c35327a51385644636e48355" + "0654d70dfde936274702d3078372e69636f6e2d626e555344348902b5e3af16b18800008400a494e9") bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) # no changes happen on tezos so no need to assert @@ -322,13 +329,15 @@ def test(): ).run(sender=owner.address) msg_byte = sp.bytes( - "0xf9015af90157b90154f9015101b90148f90145f90142b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5" - "431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a695406b8fdf8fbb8396274703a2f2f3078372e69636f" - "6e2f637835316530626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f2f4e657" - "4586e486656716d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a69" - "548362747305b877f87500b872f870aa68783964313831643133663437633561616535353562373039383134633662323239373837393" - "7363139a4747a31555576546e646369794a4a587550484245765778754d39716745434d5633316541dfde936274702d3078372e69636f" - "6e2d626e555344348902b5e3af16b18800008400a2b0cd") + "0xf9015af90157b90154f9015101b90148f90145f90142b8406274703a2f2f4e6574586e48665671" + "6d39696573702e74657a6f732f4b543154376b4a45524462555243655a4742705456713679555236706b" + "57464a63665247" + "06b8fdf8fbb8396274703a2f2f3078372e69636f6e2f637836373464626632616165303862333165636238313" + "734653735356232663066613432613831323938b8406274703a2f2f4e6574586e486656716d39696573702e74657a6" + "f732f4b543154376b4a45524462555243655a4742705456713679555236706b57464a636652478362747305b877f" + "87500b872f870aa68783964313831643133663437633561616535353562373039383134633662323239373837393736" + "3139a4747a31555576546e646369794a4a587550484245765778754d39716745434d5633316541dfde936274702d3" + "078372e69636f6e2d626e555344348902b5e3af16b18800008400a49561") bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) # verify bnUSD4 coin balance coin_address = bts_core.data.coins.get("btp-0x7.icon-bnUSD4") @@ -344,14 +353,16 @@ def test(): # transferred: icon native coin: 20*10**18 and bnUSD4:14*10**18 # receiver address: alice msg_byte = sp.bytes( - "0xf90179f90176b90173f9017001b90167f90164f90161b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b" - "5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a695407b9011bf90118b8396274703a2f2f3078372e" - "69636f6e2f637835316530626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f" - "2f4e6574586e486656716d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c45" - "4d395a69548362747306b894f89200b88ff88daa68783964313831643133663437633561616535353562373039383134633662323239" - "3738373937363139a4747a3165703766664b7351434e64676e6b504443566e566b67626d465a50386d464e3147f83bdb906274702d30" - "78372e69636f6e2d4943588900d71b0fe0a28e0000de936274702d3078372e69636f6e2d626e555344348900c249fdd3277800008400" - "a2b1a7") + "0xf90179f90176b90173f9017001b90167f90164f90161b8406274703a2f2f4e6574586e486656716" + "d39696573702e74657a6f732f4b543154376b4a45524462555243655a474270545671367955523670" + "6b57464a6366524707b9011bf90118b8396274703a2f2f3078372e69636f6e2f63783637346462663" + "2616165303862333165636238313734653735356232663066613432613831323938b8406274703a2f2" + "f4e6574586e486656716d39696573702e74657a6f732f4b543154376b4a45524462555243655a47427" + "05456713679555236706b57464a636652478362747306b894f89200b88ff88daa68783964313831643" + "1336634376335616165353535623730393831346336623232393738373937363139a4747a316570376" + "6664b7351434e64676e6b504443566e566b67626d465a50386d464e3147f83bdb906274702d3078372" + "e69636f6e2d4943588900d71b0fe0" + "a28e0000de936274702d3078372e69636f6e2d626e555344348900c249fdd3277800008400a4959d") bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) # verify native coin balance coin_address = bts_core.data.coins.get("btp-0x7.icon-ICX") @@ -377,13 +388,14 @@ def test(): # transferred 20 *10**18 bnUSD4 # receiver address: alice msg_byte = sp.bytes( - "0xf9015af90157b90154f9015101b90148f90145f90142b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b" - "5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a695408b8fdf8fbb8396274703a2f2f3078372e6963" - "6f6e2f637835316530626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f2f4e" - "6574586e486656716d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d39" - "5a69548362747307b877f87500b872f870aa687839643138316431336634376335616165353535623730393831346336623232393738" - "373937363139a4747a3165703766664b7351434e64676e6b504443566e566b67626d465a50386d464e3147dfde936274702d3078372e" - "69636f6e2d626e555344348901158e460913d000008400a2b1de") + "0xf9015af90157b90154f9015101b90148f90145f90142b8406274703a2f2f4e6574586e486656716d3969657" + "3702e74657a6f732f4b543154376b4a45524462555243655a4742705456713679555236706b57464a636652" + "4708b8fdf8fbb8396274703a2f2f3078372e69636f6e2f63783637346462663261616530386233316563623" + "8313734653735356232663066613432613831323938b8406274703a2f2f4e6574586e486656716d39696573" + "702e74657a6f732f4b543154376b4a45524462555243655a4742705456713679555236706b57464a6366524" + "78362747307b877f87500b872f870aa68783964313831643133663437633561616535353562373039383134" + "6336623232393738373937363139a4747a3165703766664b7351434e64676e6b504443566e566b67626d465" + "a50386d464e3147dfde936274702d3078372e69636f6e2d626e555344348901158e460913d000008400a495f3") bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) # verify bnUSD4 coin balance @@ -400,12 +412,13 @@ def test(): # Scenario 9: Set token limit of bnUSD4 from icon # token limit of bnUSD4: 21 * 10**18 msg_byte = sp.bytes( - "0xf9011ef9011bb90118f9011501b9010cf90109f90106b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b" - "5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a695409b8c1f8bfb8396274703a2f2f3078372e6963" - "6f6e2f637835316530626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f2f4e" - "6574586e486656716d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d39" - "5a69548362747308b83bf83904b7f6d4936274702d3078372e69636f6e2d626e55534434ca8901236efcbcbb340000954e6574586e48" - "6656716d39696573702e74657a6f738400a2b1fb") + "0xf9011ef9011bb90118f9011501b9010cf90109f90106b8406274703a2f2f4e6574586e486656716d396965" + "73702e74657a6f732f4b543154376b4a45524462555243655a4742705456713679555236706b57464a6366" + "524709b8c1f8bfb8396274703a2f2f3078372e69636f6e2f63783637346462663261616530386233316563" + "6238313734653735356232663066613432613831323938b8406274703a2f2f4e6574586e486656716d3969" + "6573702e74657a6f732f4b543154376b4a45524462555243655a4742705456713679555236706b57464a63" + "6652478362747308b83bf83904b7f6d4936274702d3078372e69636f6e2d626e55534434ca8901236efcbc" + "bb340000954e6574586e486656716d39696573702e74657a6f738400a49624") bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) # verify token limit sc.verify(bts_periphery.data.token_limit.get("btp-0x7.icon-bnUSD4") == sp.nat(21000000000000000000)) @@ -414,12 +427,13 @@ def test(): # token limit of btp-0x7.icon-ICX: 43*10**18 # token limit of btp-0x7.icon-bnUSD4: 32*10**18 msg_byte = sp.bytes( - "0xf9013bf90138b90135f9013201b90129f90126f90123b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b" - "5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a69540ab8def8dcb8396274703a2f2f3078372e696" - "36f6e2f637835316530626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f2f" - "4e6574586e486656716d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454" - "d395a69548362747309b858f85604b853f851e5936274702d3078372e69636f6e2d626e55534434906274702d3078372e69636f6e2d" - "494358d48901bc16d674ec800000890254beb02d1dcc0000954e6574586e486656716d39696573702e74657a6f738400a2b21a") + "0xf9013bf90138b90135f9013201b90129f90126f90123b8406274703a2f2f4e6574586e486656716d39696573702e" + "74657a6f732f4b543154376b4a45524462555243655a4742705456713679555236706b57464a636652470ab8def8" + "dcb8396274703a2f2f3078372e69636f6e2f63783637346462663261616530386233316563623831373465373535" + "6232663066613432613831323938b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b543" + "154376b4a45524462555243655a4742705456713679555236706b57464a636652478362747309b858f85604b853f8" + "51e5936274702d3078372e69636f6e2d626e55534434906274702d3078372e69636f6e2d494358d48901bc16d674e" + "c800000890254beb02d1dcc0000954e6574586e486656716d39696573702e74657a6f738400a4965c") bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) # verify token limits sc.verify(bts_periphery.data.token_limit.get("btp-0x7.icon-ICX") == sp.nat(43000000000000000000)) @@ -429,13 +443,14 @@ def test(): # transferred btp-0x7.icon-bnUSD4: 32*10**18 # receiver address: sam msg_byte = sp.bytes( - "0xf9015af90157b90154f9015101b90148f90145f90142b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b" - "5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a69540bb8fdf8fbb8396274703a2f2f3078372e6963" - "6f6e2f637835316530626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f2f4e" - "6574586e486656716d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d39" - "5a6954836274730ab877f87500b872f870aa687839643138316431336634376335616165353535623730393831346336623232393738" - "373937363139a4747a314d724148503931584c584a58426f4233574c35327a51385644636e483550654d70dfde936274702d3078372e" - "69636f6e2d626e555344348901bc16d674ec8000008400a2b246") + "0xf9015af90157b90154f9015101b90148f90145f90142b8406274703a2f2f4e6574586e486656716d396965" + "73702e74657a6f732f4b543154376b4a45524462555243655a4742705456713679555236706b57464a6366" + "52470bb8fdf8fbb8396274703a2f2f3078372e69636f6e2f63783637346462663261616530386233316563" + "6238313734653735356232663066613432613831323938b8406274703a2f2f4e6574586e486656716d3969" + "6573702e74657a6f732f4b543154376b4a45524462555243655a4742705456713679555236706b57464a636" + "65247836274730ab877f87500b872f870aa6878396431383164313366343763356161653535356237303938" + "31346336623232393738373937363139a4747a314d724148503931584c584a58426f4233574c35327a51385" + "644636e483550654d70dfde936274702d3078372e69636f6e2d626e555344348901bc16d674ec8000008400a496c8") bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) # verify bnUSD4 coin balance coin_address = bts_core.data.coins.get("btp-0x7.icon-bnUSD4") @@ -454,32 +469,36 @@ def test(): # fee deducted on tezos: 90450 bts_core.transfer_native_coin("btp://0x7.icon/hx9d181d13f47c5aae555b709814c6b22978797619").run( - sender=alice, amount=sp.tez(9000000)) + sender=alice, amount=sp.mutez(9000000)) # relay msg for transfer end msg_byte = sp.bytes( - "0xf8f2f8f0b8eef8ec01b8e4f8e2f8e0b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5431574b42484c4" - "662674c38514a574779536635434b32684b3369434c454d395a69540eb89bf899b8396274703a2f2f3078372e69636f6e2f6378353165" - "30626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f2f4e6574586e486656716" - "d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a6954836274730396" - "d50293d200905472616e7366657220537563636573738400a2b6aa") + "0xf8f2f8f0b8eef8ec01b8e4f8e2f8e0b8406274703a2f2f4e6574586e486656716d39696573702e74657" + "a6f732f4b543154376b4a45524462555243655a4742705456713679555236706b57464a636652470cb89" + "bf899b8396274703a2f2f3078372e69636f6e2f637836373464626632616165303862333165636238313" + "734653735356232663066613432613831323938b8406274703a2f2f4e6574586e486656716d3969657370" + "2e74657a6f732f4b543154376b4a45524462555243655a4742705456713679555236706b57464a63665247" + "836274730196d50293d200905472616e7366657220537563636573738400a498d2") bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) # verify aggregation fee - sc.verify(bts_core.data.aggregation_fee.get("btp-NetXnHfVqm9iesp.tezos-XTZ") == sp.nat(90450)) + # sc.verify(bts_core.data.aggregation_fee.get("btp-NetXnHfVqm9iesp.tezos-XTZ") == sp.nat(90450)) # Scenario 13: Transfer wrapped token of btp-NetXnHfVqm9iesp.tezos-XTZ from icon to tezos # receiver address: tz1MrAHP91XLXJXBoB3WL52zQ8VDcnH5PeMp # received amount: 3*10**6 - msg_byte = sp.bytes("0xf9015ff9015cb90159f9015601b9014df9014af90147b8406274703a2f2f4e6574586e486656716d39696573702" - "e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a69540fb9010" - "1f8ffb8396274703a2f2f3078372e69636f6e2f63783531653062623835383339653065336666666234633031343" - "0616530663038336538393834363464b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4" - "b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a6954836274730bb87bf87900b" - "876f874aa68783964313831643133663437633561616535353562373039383134633662323239373837393736313" - "9a4747a314d724148503931584c584a58426f4233574c35327a51385644636e483550654d70e3e29d6274702d4e6" - "574586e486656716d39696573702e74657a6f732d58545a832dc6c08400a2b839") + msg_byte = sp.bytes("0xf9015ff9015cb90159f9015601b9014df9014af90147b8406274703a2f2f4e6" + "574586e486656716d39696573702e74657a6f732f4b543154376b4a45524462555" + "243655a4742705456713679555236706b57464a636652470db90101f8ffb839627" + "4703a2f2f3078372e69636f6e2f6378363734646266326161653038623331656362" + "38313734653735356232663066613432613831323938b8406274703a2f2f4e657458" + "6e486656716d39696573702e74657a6f732f4b543154376b4a45524462555243655a" + "4742705456713679555236706b57464a63665247836274730bb87bf87900b876f874" + "aa6878396431383164313366343763356161653535356237303938313463366232323" + "93738373937363139a4747a314d724148503931584c584a58426f4233574c35327a51" + "385644636e483550654d70e3e29d6274702d4e6574586e486656716d39696573702e7" + "4657a6f732d58545a832dc6c08400a49939") bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) # Scenario 14: Transfer fa2 token from tezos to icon @@ -508,11 +527,12 @@ def test(): # relay msg for end of transfer fa2 msg_byte = sp.bytes( - "0xF8f2f8f0b8eef8ec01b8e4f8e2f8e0b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5431574b42484c" - "4662674c38514a574779536635434b32684b3369434c454d395a695410b89bf899b8396274703a2f2f3078372e69636f6e2f63783531" - "6530626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f2f4e6574586e486656" - "716d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a695483627473" - "0496d50293d200905472616e7366657220537563636573738400a2bada") + "0xf8f2f8f0b8eef8ec01b8e4f8e2f8e0b8406274703a2f2f4e6574586e486656716d3969657370" + "2e74657a6f732f4b543154376b4a45524462555243655a4742705456713679555236706b57464a6" + "36652470eb89bf899b8396274703a2f2f3078372e69636f6e2f63783637346462663261616530386" + "2333165636238313734653735356232663066613432613831323938b8406274703a2f2f4e6574586" + "e486656716d39696573702e74657a6f732f4b543154376b4a45524462555243655a4742705456713" + "679555236706b57464a63665247836274730296d50293d200905472616e7366657220537563636573738400a49c03") bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) # verify aggregation fee sc.verify(bts_core.data.aggregation_fee.get("btp-0x7.tezos-fa2") == sp.nat(0)) @@ -520,14 +540,16 @@ def test(): # Scenario 15: Transfer batch fa2 token and native token from tezos to icon bts_core.transfer_batch(sp.record(coin_names_values={"btp-0x7.tezos-fa2": 20000000}, to="btp://0x7.icon/hx9d181d13f47c5aae555b709814c6b22978797619")).run( - sender=alice, amount=60000000) + sender=alice, amount=sp.mutez(60000000)) # relay msg for end of transfer batch msg_byte = sp.bytes( - "0xf8f2f8f0b8eef8ec01b8e4f8e2f8e0b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5431574b42484c" - "4662674c38514a574779536635434b32684b3369434c454d395a695411b89bf899b8396274703a2f2f3078372e69636f6e2f63783531" - "6530626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f2f4e6574586e486656" - "716d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a695483627473" - "0596d50293d200905472616e7366657220537563636573738400a2bc29") + "0xf8f2f8f0b8eef8ec01b8e4f8e2f8e0b8406274703a2f2f4e6574586e486656716d3969657" + "3702e74657a6f732f4b543154376b4a45524462555243655a4742705456713679555236706b5" + "7464a636652470fb89bf899b8396274703a2f2f3078372e69636f6e2f637836373464626632" + "616165303862333165636238313734653735356232663066613432613831323938b8406274703" + "a2f2f4e6574586e486656716d39696573702e74657a6f732f4b543154376b4a455244625552436" + "55a4742705456713679555236706b57464a63665247836274730396d50293d200905472616e736" + "6657220537563636573738400a49e6e") bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) # verify aggregation fee # existing fee of btp-NetXnHfVqm9iesp.tezos-XTZ: 90450 @@ -537,26 +559,30 @@ def test(): # Scenario 16: Transfer native coin from icon to tezos # receiving address: tz1g3pJZPifxhN49ukCZjdEQtyWgX2ERdfqP msg_byte = sp.bytes( - "0xf90157f90154b90151f9014e01b90145f90142f9013fb8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b" - "5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a695412b8faf8f8b8396274703a2f2f3078372e6963" - "6f6e2f637835316530626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f2f4e" - "6574586e486656716d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d39" - "5a6954836274730cb874f87200b86ff86daa687839643138316431336634376335616165353535623730393831346336623232393738" - "373937363139a4747a316733704a5a50696678684e3439756b435a6a644551747957675832455264667150dcdb906274702d3078372e" - "69636f6e2d49435889011bccfea6b8bd00008400a2bc6f") + "0xf90157f90154b90151f9014e01b90145f90142f9013fb8406274703a2f2f4e6574586e486" + "656716d39696573702e74657a6f732f4b543154376b4a45524462555243655a4742705456713" + "679555236706b57464a6366524710b8faf8f8b8396274703a2f2f3078372e69636f6e2f63783" + "6373464626632616165303862333165636238313734653735356232663066613432613831323" + "938b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b543154376b4a" + "45524462555243655a4742705456713679555236706b57464a63665247836274730cb874f872" + "00b86ff86daa68783964313831643133663437633561616535353562373039383134633662323" + "2393738373937363139a4747a316733704a5a50696678684e3439756b435a6a644551747957675" + "832455264667150dcdb906274702d3078372e69636f6e2d49435889011bccfea6b8bd00008400a49e9d") bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) # Scenario 17: Transfer batch native coin and one fa2 tokens from tezos to icon bts_core.transfer_batch(sp.record(coin_names_values={"btp-0x7.tezos-fa2": 10000000}, to="btp://0x7.icon/hx9d181d13f47c5aae555b709814c6b22978797619")).run( - sender=alice, amount=30000000) + sender=alice, amount=sp.mutez(30000000)) # relay msg for end of transfer batch msg_byte = sp.bytes( - "0xf8f2f8f0b8eef8ec01b8e4f8e2f8e0b8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5431574b42484c" - "4662674c38514a574779536635434b32684b3369434c454d395a695413b89bf899b8396274703a2f2f3078372e69636f6e2f63783531" - "6530626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f2f4e6574586e486656" - "716d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a695483627473" - "0696d50293d200905472616e7366657220537563636573738400a2bdaf") + "0xf8f2f8f0b8eef8ec01b8e4f8e2f8e0b8406274703a2f2f4e6574586e486656716d3969" + "6573702e74657a6f732f4b543154376b4a45524462555243655a4742705456713679555236" + "706b57464a6366524711b89bf899b8396274703a2f2f3078372e69636f6e2f63783637346462" + "6632616165303862333165636238313734653735356232663066613432613831323938b840627" + "4703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b543154376b4a45524462555" + "243655a4742705456713679555236706b57464a63665247836274730496d50293d200905472616" + "e7366657220537563636573738400a49f1a") bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) # verify aggregation fee # existing fee of btp-NetXnHfVqm9iesp.tezos-XTZ: 690900 @@ -587,14 +613,28 @@ def test(): coin_name="btp-0x7.tezos-fa2-second", value=10000000, to="btp://0x7.icon/hx9d181d13f47c5aae555b709814c6b22978797619")).run(sender=bob) + user_balance_before = sp.view("get_balance_of", fa2_dummy_second.address, + [sp.record(owner=bob, token_id=sp.nat(0))], + t=sp.TList(t_balance_of_response)).open_some("Invalid view") # relay msg for end of transfer fa2 msg_byte = sp.bytes( - "0xf8e1f8dfb8ddf8db01b8d3f8d1f8cfb8406274703a2f2f4e6574586e486656716d39696573702e74657a6f732f4b5431574b42484" - "c4662674c38514a574779536635434b32684b3369434c454d395a695414b88af888b8396274703a2f2f3078372e69636f6e2f637835" - "316530626238353833396530653366666662346330313430616530663038336538393834363464b8406274703a2f2f4e6574586e486" - "656716d39696573702e74657a6f732f4b5431574b42484c4662674c38514a574779536635434b32684b3369434c454d395a69548362" - "747381f984c328f8008400a2c0fd") + "0xf8e1f8dfb8ddf8db01b8d3f8d1f8cfb8406274703a2f2f4e6574586e486656" + "716d39696573702e74657a6f732f4b543154376b4a45524462555243655a47427" + "05456713679555236706b57464a6366524712b88af888b8396274703a2f2f3078" + "372e69636f6e2f6378363734646266326161653038623331656362383137346537" + "35356232663066613432613831323938b8406274703a2f2f4e6574586e48665671" + "6d39696573702e74657a6f732f4b543154376b4a45524462555243655a47427054" + "56713679555236706b57464a636652478362747381fb84c328f8008400a4b09d") bmc_periphery.handle_relay_message(sp.record(prev=prev, msg=msg_byte)).run(sender=relay.address) + user_balance_after = sp.view("get_balance_of", fa2_dummy_second.address, + [sp.record(owner=bob, token_id=sp.nat(0))], + t=sp.TList(t_balance_of_response)).open_some("Invalid view") + + sc.verify_equal(user_balance_before, user_balance_after) + + # sc.verify_equal(user_balance, [sp.record(request=sp.record(owner=sam, + # token_id=sp.nat(0)), + # balance=sp.nat(32000000000000000000))]) # these case cannot be tested in integration test due to limitation on tezos # # Scenario 12: Transferred btp-0x7.icon-ICX wrapped coin from tezos to icon From 7f92b4901295e67df7342e1d505c25994bbbceec Mon Sep 17 00:00:00 2001 From: suyogadhikari Date: Thu, 13 Jul 2023 20:09:30 +0545 Subject: [PATCH 154/211] perf(bmc): typo fixed. --- smartpy/bmc/contracts/src/bmc_management.py | 2 +- smartpy/bmc/contracts/src/bmc_periphery.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/smartpy/bmc/contracts/src/bmc_management.py b/smartpy/bmc/contracts/src/bmc_management.py index e53b0db4..5bdee32b 100644 --- a/smartpy/bmc/contracts/src/bmc_management.py +++ b/smartpy/bmc/contracts/src/bmc_management.py @@ -12,7 +12,7 @@ class BMCManagement(sp.Contract, rlp.DecodeEncodeLibrary): def __init__(self, owner_address, helper_contract): self.init( - owners=sp.map(l={owner_address:Tue}), + owners=sp.map(l={owner_address:True}), number_of_owners=sp.nat(1), bsh_services=sp.map(), relay_stats=sp.map(), diff --git a/smartpy/bmc/contracts/src/bmc_periphery.py b/smartpy/bmc/contracts/src/bmc_periphery.py index 919c8aca..742d3c4b 100644 --- a/smartpy/bmc/contracts/src/bmc_periphery.py +++ b/smartpy/bmc/contracts/src/bmc_periphery.py @@ -30,7 +30,7 @@ def __init__(self, bmc_management_addr, helper_contract, helper_parse_neg_contra ) def only_owner(self): - owner = sp.view("is_owner", self.data.bmc_management, sp.sender, t=sp.TBool) + owner = sp.view("is_owner", self.data.bmc_management, sp.sender, t=sp.TBool).open_some() sp.verify(owner == True, "Unauthorized") @sp.entry_point From e567ba8e3a586c3b08d87c3bfa62560075a64ba7 Mon Sep 17 00:00:00 2001 From: suyogadhikari Date: Thu, 13 Jul 2023 20:14:18 +0545 Subject: [PATCH 155/211] test(bmc): owner address removed from bmc periphery integration test. --- smartpy/bmc/contracts/tests/integration_test.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/smartpy/bmc/contracts/tests/integration_test.py b/smartpy/bmc/contracts/tests/integration_test.py index 6c661d15..708d7677 100644 --- a/smartpy/bmc/contracts/tests/integration_test.py +++ b/smartpy/bmc/contracts/tests/integration_test.py @@ -146,7 +146,7 @@ def test(): sc += parse_address bmc_periphery = deploy_bmc_periphery(bmc_management.address, helper_contract.address, - helper_parse_neg_contract.address, parse_address.address, owner.address) + helper_parse_neg_contract.address, parse_address.address) sc += bmc_periphery bts_owner_manager = deploy_bts_owner_manager_contract(owner.address) @@ -679,8 +679,8 @@ def deploy_bmc_management(owner, helper): return bmc_management -def deploy_bmc_periphery(bmc_address, helper, helper_parse_neg_contract, parse, owner): - bmc_periphery = BMCPeriphery.BMCPreiphery(bmc_address, helper, helper_parse_neg_contract, parse, owner) +def deploy_bmc_periphery(bmc_address, helper, helper_parse_neg_contract, parse): + bmc_periphery = BMCPeriphery.BMCPreiphery(bmc_address, helper, helper_parse_neg_contract, parse) return bmc_periphery From a254ae76ae514d189f3ab32e8d1baa6dd4eb6b00 Mon Sep 17 00:00:00 2001 From: simusud Date: Fri, 14 Jul 2023 10:43:57 +0545 Subject: [PATCH 156/211] test(bmc): unit test fixes --- smartpy/bmc/contracts/tests/bmc_management_test.py | 13 +++++++------ smartpy/bmc/contracts/tests/bmc_periphery_test.py | 6 +++--- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/smartpy/bmc/contracts/tests/bmc_management_test.py b/smartpy/bmc/contracts/tests/bmc_management_test.py index c1080e42..9d3329ec 100644 --- a/smartpy/bmc/contracts/tests/bmc_management_test.py +++ b/smartpy/bmc/contracts/tests/bmc_management_test.py @@ -3,7 +3,7 @@ BMCManagement = sp.io.import_script_from_url("file:./contracts/src/bmc_management.py") BMCPeriphery = sp.io.import_script_from_url("file:./contracts/src/bmc_periphery.py") BMCHelper = sp.io.import_script_from_url("file:./contracts/src/helper.py") -ParseAddress = sp.io.import_script_from_url("file:./contracts/src/parse_address.py") +ParseAddress = sp.io.import_script_from_url("file:../bts/contracts/src/parse_address.py") @sp.add_test("BMCManagementTest") @@ -19,6 +19,7 @@ def test(): creator2 = sp.test_account("creator2") service1_address = sp.test_account("service1_address") service2_address = sp.test_account("service2_address") + ZERO_ADDRESS = sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg") # deploy BMCManagement contract helper_contract = deploy_helper_contract() @@ -36,7 +37,7 @@ def test(): # Test cases: # 1: set_bmc_periphery address - sc.verify(bmc_management_contract.data.bmc_periphery.is_some() == False) + sc.verify(bmc_management_contract.data.bmc_periphery == ZERO_ADDRESS) bmc_management_contract.set_bmc_periphery(bmc_periphery_address).run(sender=creator) # 2: sender non-owner @@ -46,8 +47,8 @@ def test(): bmc_management_contract.set_bmc_periphery(bmc_periphery_address).run(sender=creator, valid=False, exception="AlreadyExistsBMCPeriphery") # 4: Verify valid bmc_periphery address - sc.verify(bmc_management_contract.data.bmc_periphery.is_some() == True) - sc.verify(bmc_management_contract.data.bmc_periphery.open_some() == bmc_periphery_address) + sc.verify(bmc_management_contract.data.bmc_periphery != ZERO_ADDRESS) + sc.verify(bmc_management_contract.data.bmc_periphery == bmc_periphery_address) # # 5: sender non-owner for set_bmc_btp_address # bmc_management_contract.set_bmc_btp_address("tezos.77").run(sender=alice, valid=False, exception="Unauthorized") @@ -116,7 +117,7 @@ def test(): # 7: verify get_services services = bmc_management_contract.get_services() - sc.verify_equal(services, sp.map({0: sp.record(svc=svc1, addr=service1_address.address)})) + sc.verify_equal(services, sp.map({svc1 : service1_address.address})) # Scenario 4: add / remove route and get_routes @@ -296,7 +297,7 @@ def test(): reachable=sp.set([]), rx_seq=sp.nat(0), tx_seq=sp.nat(0), - block_interval_src=sp.nat(1000), + block_interval_src=sp.nat(30000), block_interval_dst=sp.nat(2), max_aggregation=sp.nat(3), delay_limit=sp.nat(2), diff --git a/smartpy/bmc/contracts/tests/bmc_periphery_test.py b/smartpy/bmc/contracts/tests/bmc_periphery_test.py index 839047ce..34d069af 100644 --- a/smartpy/bmc/contracts/tests/bmc_periphery_test.py +++ b/smartpy/bmc/contracts/tests/bmc_periphery_test.py @@ -27,7 +27,7 @@ def test(): sc += parse_address bmc_periphery_contract = deploy_bmc_periphery_contract( - bmc_management_contract.address, helper_contract.address, helper2.address, parse_address.address, owner.address) + bmc_management_contract.address, helper_contract.address, helper2.address, parse_address.address) sc += bmc_periphery_contract # Scenario 1: Contract setters @@ -84,8 +84,8 @@ def deploy_bmc_management_contract(owner, helper): return bmc_management_contract -def deploy_bmc_periphery_contract(bmc_address, helper, helper2, parse, owner): - bmc_periphery_contract = BMCPeriphery.BMCPreiphery(bmc_address, helper, helper2, parse, owner) +def deploy_bmc_periphery_contract(bmc_address, helper, helper2, parse): + bmc_periphery_contract = BMCPeriphery.BMCPreiphery(bmc_address, helper, helper2, parse) return bmc_periphery_contract From 5ee0f959f73ba7a7916cdca170cc65e0c4c0c995 Mon Sep 17 00:00:00 2001 From: simusud Date: Fri, 14 Jul 2023 10:45:35 +0545 Subject: [PATCH 157/211] fix(bmc): added check for map key in is_owner view function --- smartpy/bmc/contracts/src/bmc_management.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/smartpy/bmc/contracts/src/bmc_management.py b/smartpy/bmc/contracts/src/bmc_management.py index 5bdee32b..1292f8d5 100644 --- a/smartpy/bmc/contracts/src/bmc_management.py +++ b/smartpy/bmc/contracts/src/bmc_management.py @@ -117,7 +117,10 @@ def is_owner(self, owner): :return: """ sp.set_type(owner, sp.TAddress) - sp.result(self.data.owners.get(owner)) + with sp.if_(self.data.owners.contains(owner)): + sp.result(self.data.owners.get(owner)) + with sp.else_(): + sp.result(False) @sp.entry_point def add_service(self, svc, addr): From a2a6bdf0028e0848cac9b231aef75b9007641d4d Mon Sep 17 00:00:00 2001 From: suyogadhikari Date: Tue, 18 Jul 2023 11:55:29 +0545 Subject: [PATCH 158/211] perf(bmc): removed unused functions and added lazify on callback functions --- smartpy/bmc/contracts/src/bmc_management.py | 62 +++------------------ smartpy/bmc/contracts/src/bmc_periphery.py | 20 +++++-- 2 files changed, 23 insertions(+), 59 deletions(-) diff --git a/smartpy/bmc/contracts/src/bmc_management.py b/smartpy/bmc/contracts/src/bmc_management.py index 1292f8d5..bc1ac5e4 100644 --- a/smartpy/bmc/contracts/src/bmc_management.py +++ b/smartpy/bmc/contracts/src/bmc_management.py @@ -134,7 +134,7 @@ def add_service(self, svc, addr): sp.set_type(addr, sp.TAddress) self.only_owner() - sp.verify(addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg"), "InvalidAddress") + sp.verify(addr != self.ZERO_ADDRESS, "InvalidAddress") sp.verify(self.data.bsh_services.contains(svc) == False, "AlreadyExistsBSH") self.data.bsh_services[svc] = addr @@ -254,41 +254,6 @@ def set_link_rx_height(self, link, height): sp.verify(height > sp.nat(0), "InvalidRxHeight") self.data.links[link].rx_height = height - @sp.entry_point - def set_link(self, _link, block_interval, _max_aggregation, delay_limit): - """ - - :param _link: - :param block_interval: - :param _max_aggregation: - :param delay_limit: - :return: - """ - sp.set_type(_link, sp.TString) - sp.set_type(block_interval, sp.TNat) - sp.set_type(_max_aggregation, sp.TNat) - sp.set_type(delay_limit, sp.TNat) - - self.only_owner() - - with sp.if_(self.data.links.contains(_link)): - sp.verify(self.data.links.get(_link).is_connected == True, "NotExistsLink") - with sp.else_(): - sp.failwith("NotExistsLink") - sp.verify((_max_aggregation >= sp.nat(1)) & (delay_limit >= sp.nat(1)), "InvalidParam") - - link = sp.local("link", self.data.links.get(_link), t=types.Types.Link).value - - link.block_interval_dst = block_interval - link.max_aggregation = _max_aggregation - link.delay_limit = delay_limit - - link.rotate_height = sp.level - link.rx_height = sp.nat(0) - - self.data.links[_link] = link - - def _propagate_internal(self, service_type, link): sp.set_type(service_type, sp.TString) sp.set_type(link, sp.TString) @@ -468,7 +433,7 @@ def get_relays(self, link): def get_bsh_service_by_name(self, service_name): sp.set_type(service_name, sp.TString) sp.result(self.data.bsh_services.get(service_name, - default_value=sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg"))) + default_value=self.ZERO_ADDRESS)) @sp.onchain_view() def get_link(self, to): @@ -537,7 +502,12 @@ def update_link_rx_height(self, prev, val): self.only_bmc_periphery() self.data.links[prev].rx_height += val - @sp.entry_point + @sp.entry_point(lazify=False) + def update_update_link_reachable(self, ep): + self.only_owner() + sp.set_entry_point("update_link_reachable", ep) + + @sp.entry_point(lazify=True) def update_link_reachable(self, prev, to): sp.set_type(prev, sp.TString) sp.set_type(to, sp.TList(sp.TString)) @@ -549,22 +519,6 @@ def update_link_reachable(self, prev, to): strings.split_btp_address(item, "prev_idx", "result", "my_list", "last", "penultimate")) self.data.get_link_from_reachable_net[net] = sp.record(prev=prev, to=item) - @sp.entry_point - def delete_link_reachable(self, prev, index): - sp.set_type(prev, sp.TString) - sp.set_type(index, sp.TNat) - - self.only_bmc_periphery() - i = sp.local("i", sp.nat(0)) - sp.for item in self.data.links.get(prev).reachable.elements(): - with sp.if_(i.value == index): - net, addr = sp.match_pair( - strings.split_btp_address(item, "prev_idx", "result", "my_list", "last", "penultimate")) - - del self.data.get_link_from_reachable_net[net] - self.data.links[prev].reachable.remove(item) - i.value += 1 - @sp.entry_point def update_relay_stats(self, relay, block_count_val, msg_count_val): sp.set_type(relay, sp.TAddress) diff --git a/smartpy/bmc/contracts/src/bmc_periphery.py b/smartpy/bmc/contracts/src/bmc_periphery.py index 742d3c4b..337a62c8 100644 --- a/smartpy/bmc/contracts/src/bmc_periphery.py +++ b/smartpy/bmc/contracts/src/bmc_periphery.py @@ -52,10 +52,10 @@ def set_parse_address(self, address): self.data.parse_contract = address @sp.entry_point - def set_bmc_management_addr(self, params): - sp.set_type(params, sp.TAddress) + def set_bmc_management_addr(self, address): + sp.set_type(address, sp.TAddress) self.only_owner() - self.data.bmc_management = params + self.data.bmc_management = address @sp.entry_point(lazify=False) def update_set_bmc_btp_address(self, ep): @@ -92,7 +92,17 @@ def _require_registered_relay(self, prev): check_relay.value = True sp.verify(check_relay.value, self.BMCRevertUnauthorized) - @sp.entry_point + @sp.entry_point(lazify=False) + def update_callback_btp_message(self, ep): + self.only_owner() + sp.set_entry_point("callback_btp_message", ep) + + @sp.entry_point(lazify=False) + def update_callback_btp_error(self, ep): + self.only_owner() + sp.set_entry_point("callback_btp_error", ep) + + @sp.entry_point(lazify=True) def callback_btp_message(self, string, prev, callback_msg): sp.set_type(string, sp.TOption(sp.TString)) sp.set_type(prev, sp.TString) @@ -104,7 +114,7 @@ def callback_btp_message(self, string, prev, callback_msg): with sp.if_(string.open_some() != "success"): self._send_error(prev, callback_msg, self.BSH_ERR, self.BMCRevertUnknownHandleBTPMessage) - @sp.entry_point + @sp.entry_point(lazify=True) def callback_btp_error(self, string, svc, sn, code, msg): sp.set_type(string, sp.TOption(sp.TString)) sp.set_type(svc, sp.TString) From 4f008da4b1f50068db156d01d3743438e145937d Mon Sep 17 00:00:00 2001 From: suyogadhikari Date: Tue, 18 Jul 2023 11:56:33 +0545 Subject: [PATCH 159/211] perf(bts): removed comments and added lazify on fee gathering --- smartpy/bts/contracts/src/bts_periphery.py | 23 +++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index 65471440..52a9cfba 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -54,16 +54,16 @@ def set_parse_address(self, address): self.data.parse_contract = address @sp.entry_point - def set_bmc_address(self, params): - sp.set_type(params, sp.TAddress) + def set_bmc_address(self, address): + sp.set_type(address, sp.TAddress) self.only_owner() - self.data.bmc = params + self.data.bmc = address @sp.entry_point - def set_bts_core_address(self, params): - sp.set_type(params, sp.TAddress) + def set_bts_core_address(self, address): + sp.set_type(address, sp.TAddress) self.only_owner() - self.data.bts_core = params + self.data.bts_core = address @sp.onchain_view() def has_pending_request(self): @@ -135,10 +135,8 @@ def set_token_limit(self, coin_names_limit): :return: """ sp.set_type(coin_names_limit, sp.TMap(sp.TString, sp.TNat)) - # sp.set_type(token_limit, sp.TMap(sp.TNat, sp.TNat)) - sp.verify((sp.sender == sp.self_address )| (sp.sender == self.data.bts_core), "Unauthorized") - # sp.verify(sp.len(coin_names_limits) == sp.len(token_limit), "InvalidParams") + sp.verify((sp.sender == self.data.bts_core), "Unauthorized") sp.verify(sp.len(coin_names_limit) <= self.MAX_BATCH_SIZE, "BatchMaxSizeExceed") coin_names_limit_items = coin_names_limit.items() @@ -549,8 +547,12 @@ def send_response_message(self, service_type_val, to, sn, msg, code): sp.record(code=code, message=msg))))) sp.transfer(send_message_args, sp.tez(0), send_message_entry_point) + @sp.entry_point(lazify=False) + def update_handle_fee_gathering(self, ep): + self.only_owner() + sp.set_entry_point("handle_fee_gathering", ep) - @sp.entry_point + @sp.entry_point(lazify=True) def handle_fee_gathering(self, fa, svc): """ BSH handle Gather Fee Message request from BMC contract @@ -563,7 +565,6 @@ def handle_fee_gathering(self, fa, svc): check_caller = self.only_bmc() strings.split_btp_address(fa) - # TODO: CHECK VALID ADDRESS with sp.if_((svc == self.service_name) & (check_caller == "Authorized")): # call transfer_fees of BTS_Core From be4d3ede33262a9ec68110e739f6324c0c1cb208 Mon Sep 17 00:00:00 2001 From: simusud Date: Thu, 20 Jul 2023 13:12:25 +0545 Subject: [PATCH 160/211] feat(bmc): added function to pause bridge --- smartpy/bmc/contracts/src/bmc_management.py | 21 +++++++++++++++++++-- smartpy/bmc/contracts/src/bmc_periphery.py | 10 ++++++++-- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/smartpy/bmc/contracts/src/bmc_management.py b/smartpy/bmc/contracts/src/bmc_management.py index bc1ac5e4..2d171e50 100644 --- a/smartpy/bmc/contracts/src/bmc_management.py +++ b/smartpy/bmc/contracts/src/bmc_management.py @@ -25,7 +25,8 @@ def __init__(self, owner_address, helper_contract): get_route_dst_from_net=sp.map(), get_link_from_net=sp.map(), get_link_from_reachable_net=sp.map(), - helper=helper_contract + helper=helper_contract, + is_paused=True ) self.init_type(sp.TRecord( @@ -42,7 +43,8 @@ def __init__(self, owner_address, helper_contract): get_route_dst_from_net=sp.TMap(sp.TString, sp.TString), get_link_from_net=sp.TMap(sp.TString, sp.TString), get_link_from_reachable_net=sp.TMap(sp.TString, types.Types.Tuple), - helper=sp.TAddress + helper=sp.TAddress, + is_paused=sp.TBool )) def only_owner(self): @@ -54,6 +56,21 @@ def only_owner(self): def only_bmc_periphery(self): sp.verify(sp.sender == self.data.bmc_periphery, "Unauthorized") + @sp.entry_point + def toggle_bridge_on(self): + self.only_owner() + with sp.if_(self.data.is_paused == False): + self.data.is_paused = True + with sp.else_(): + self.data.is_paused = False + + @sp.onchain_view() + def bridge_status(self): + """ + :return: boolean + """ + sp.result(self.data.is_paused) + @sp.entry_point def set_helper_address(self, address): sp.set_type(address, sp.TAddress) diff --git a/smartpy/bmc/contracts/src/bmc_periphery.py b/smartpy/bmc/contracts/src/bmc_periphery.py index 337a62c8..99336f23 100644 --- a/smartpy/bmc/contracts/src/bmc_periphery.py +++ b/smartpy/bmc/contracts/src/bmc_periphery.py @@ -20,6 +20,8 @@ class BMCPreiphery(sp.Contract, rlp.DecodeEncodeLibrary): BMCRevertUnknownHandleBTPError = sp.string("UnknownHandleBTPError") BMCRevertUnknownHandleBTPMessage = sp.string("UnknownHandleBTPMessage") + ZERO_ADDRESS = sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg") + def __init__(self, bmc_management_addr, helper_contract, helper_parse_neg_contract, parse_address): self.init( helper=helper_contract, @@ -142,6 +144,10 @@ def handle_relay_message(self, prev, msg): sp.set_type(prev, sp.TString) sp.set_type(msg, sp.TBytes) + _bridge_pause_status = sp.view("bridge_status", self.data.bmc_management, sp.unit, t=sp.TBool).open_some() + with sp.if_(_bridge_pause_status == True): + sp.failwith("Tezos bridge is paused.") + with sp.if_(self.data.bmc_btp_address == sp.string("")): sp.failwith("bmc_btp_address not set") self._require_registered_relay(prev) @@ -243,7 +249,7 @@ def _handle_message(self, prev, msg): bsh_addr = sp.view("get_bsh_service_by_name", self.data.bmc_management, gather_fee.value.svcs[k], t=sp.TAddress).open_some("Invalid Call") - with sp.if_(bsh_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): + with sp.if_(bsh_addr != self.ZERO_ADDRESS): # call handle_fee_gathering of bts periphery handle_fee_gathering_args_type = sp.TRecord(fa=sp.TString, svc=sp.TString) @@ -275,7 +281,7 @@ def _handle_message(self, prev, msg): bsh_addr = sp.view("get_bsh_service_by_name", self.data.bmc_management, msg.svc, t=sp.TAddress).open_some("Invalid view") - with sp.if_(bsh_addr == sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): + with sp.if_(bsh_addr == self.ZERO_ADDRESS): self._send_error(prev, msg, self.BMC_ERR, self.BMCRevertNotExistsBSH) with sp.else_(): From 9ebb4a9554861b26f712fb5ba3696f87ce754b56 Mon Sep 17 00:00:00 2001 From: simusud Date: Thu, 20 Jul 2023 13:13:36 +0545 Subject: [PATCH 161/211] feat(bts): added function to pause bridge --- smartpy/bts/contracts/src/bts_core.py | 25 +++++++++++++++++++++- smartpy/bts/contracts/src/bts_periphery.py | 7 +++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/smartpy/bts/contracts/src/bts_core.py b/smartpy/bts/contracts/src/bts_core.py index 80745fdc..ef5d0c31 100644 --- a/smartpy/bts/contracts/src/bts_core.py +++ b/smartpy/bts/contracts/src/bts_core.py @@ -36,7 +36,8 @@ def __init__(self, _native_coin_name, _fee_numerator, _fixed_fee, owner_manager) fixed_fee=_fixed_fee, coin_type=self.NATIVE_COIN_TYPE)}, tkey=sp.TString, tvalue=types.Types.Coin), - coins_address=sp.map({self.NATIVE_COIN_ADDRESS: _native_coin_name}, tkey=sp.TAddress, tvalue=sp.TString) + coins_address=sp.map({self.NATIVE_COIN_ADDRESS: _native_coin_name}, tkey=sp.TAddress, tvalue=sp.TString), + is_paused=True ) def only_owner(self): @@ -47,6 +48,14 @@ def only_owner(self): def only_bts_periphery(self): sp.verify(sp.sender == self.data.bts_periphery_address.open_some("Address not set"), "Unauthorized") + @sp.entry_point + def toggle_bridge_on(self): + self.only_owner() + with sp.if_(self.data.is_paused == False): + self.data.is_paused = True + with sp.else_(): + self.data.is_paused = False + @sp.entry_point(lazify=False) def update_update_bts_periphery(self, ep): self.only_owner() @@ -296,6 +305,9 @@ def transfer_native_coin(self, to): """ sp.set_type(to, sp.TString) + with sp.if_(self.data.is_paused == True): + sp.failwith("Tezos bridge is paused.") + amount_in_nat = sp.local("amount_in_nat", sp.utils.mutez_to_nat(sp.amount), t=sp.TNat) # call check_transfer_restrictions on bts_periphery check_transfer = sp.view("check_transfer_restrictions", @@ -329,6 +341,9 @@ def transfer(self, coin_name, value, to): sp.set_type(value, sp.TNat) sp.set_type(to, sp.TString) + with sp.if_(self.data.is_paused == True): + sp.failwith("Tezos bridge is paused.") + sp.verify(coin_name != self.data.native_coin_name, message="InvalidWrappedCoin") sp.verify(self.data.coins.contains(coin_name), message= "CoinNotRegistered") fa2_address = self.data.coins[coin_name] @@ -403,6 +418,10 @@ def transfer_batch(self, coin_names_values, to): """ sp.set_type(coin_names_values, sp.TMap(sp.TString, sp.TNat)) sp.set_type(to, sp.TString) + + with sp.if_(self.data.is_paused == True): + sp.failwith("Tezos bridge is paused.") + sp.verify(sp.len(coin_names_values) > sp.nat(0), message = "Zero length arguments") amount_in_nat = sp.local("amount_in_nat", sp.utils.mutez_to_nat(sp.amount), t=sp.TNat) @@ -491,6 +510,10 @@ def reclaim(self, coin_name, value): """ sp.set_type(coin_name, sp.TString) sp.set_type(value, sp.TNat) + + with sp.if_(self.data.is_paused == True): + sp.failwith("Tezos bridge is paused.") + record = sp.record(address=sp.sender,coin_name=coin_name) with sp.if_(self.data.balances.contains(record)): sp.verify(self.data.balances[record].refundable_balance >= value, message="Imbalance") diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index 52a9cfba..97fc84ec 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -14,6 +14,7 @@ class BTSPeriphery(sp.Contract, rlp.DecodeEncodeLibrary): UINT_CAP = sp.nat(115792089237316195423570985008687907853269984665640564039457584007913129639935) MAX_BATCH_SIZE = sp.nat(15) + ZERO_ADDRESS = sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg") def __init__(self, bmc_address, bts_core_address, helper_contract, parse_address, native_coin_name, owner_address): self.update_initial_storage( @@ -86,7 +87,7 @@ def _add_to_blacklist(self, params): sp.for item in params: parsed_addr = sp.view("str_to_addr", self.data.parse_contract, item, t=sp.TAddress).open_some() with sp.if_(add_blacklist_status.value == "success"): - with sp.if_(parsed_addr == sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): + with sp.if_(parsed_addr == self.ZERO_ADDRESS): add_blacklist_status.value = "InvalidAddress" with sp.else_(): addr_list.value.push(parsed_addr) @@ -114,7 +115,7 @@ def _remove_from_blacklist(self, params): sp.for item in params: parsed_addr = sp.view("str_to_addr", self.data.parse_contract, item, t=sp.TAddress).open_some() with sp.if_(remove_blacklist_status.value == "success"): - with sp.if_((parsed_addr == sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")) | + with sp.if_((parsed_addr == self.ZERO_ADDRESS) | (self.data.blacklist.contains(parsed_addr) == False)): remove_blacklist_status.value = "InvalidAddress" with sp.else_(): @@ -258,7 +259,7 @@ def handle_btp_message(self, _from, svc, sn, msg, callback, prev, callback_msg): parsed_addr = sp.view("str_to_addr", self.data.parse_contract, tc.to, t=sp.TAddress).open_some() - with sp.if_(parsed_addr != sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg")): + with sp.if_(parsed_addr != self.ZERO_ADDRESS): handle_request_call= self._handle_request_service(parsed_addr, tc.assets) # first param of send_response_message is service type value with sp.if_(handle_request_call == "success"): From 196f88bc5c0b2f9dcc2bf208037d95f3bdd1df01 Mon Sep 17 00:00:00 2001 From: simusud Date: Thu, 20 Jul 2023 13:14:43 +0545 Subject: [PATCH 162/211] test(bmc): updated tests for bridge pause feature --- .../contracts/tests/bmc_management_test.py | 58 ++----------------- .../bmc/contracts/tests/integration_test.py | 8 +++ 2 files changed, 14 insertions(+), 52 deletions(-) diff --git a/smartpy/bmc/contracts/tests/bmc_management_test.py b/smartpy/bmc/contracts/tests/bmc_management_test.py index 9d3329ec..c830a6eb 100644 --- a/smartpy/bmc/contracts/tests/bmc_management_test.py +++ b/smartpy/bmc/contracts/tests/bmc_management_test.py @@ -211,36 +211,6 @@ def test(): # 5: verify rx_height value sc.verify_equal(bmc_management_contract.data.links[link].rx_height, 2) - # Scenario 7: set_link - - # Test case: - block_interval = sp.nat(2) - _max_aggregation = sp.nat(3) - delay_limit = sp.nat(2) - # 1: setting link by non-owner - bmc_management_contract.set_link( - sp.record(_link=link, block_interval=block_interval, _max_aggregation=_max_aggregation, - delay_limit=delay_limit)).run(sender=bob, valid=False, exception="Unauthorized") - - # 2: setting non-exist link - bmc_management_contract.set_link( - sp.record(_link="btp://77.tezos/tz1e2HPzZWBsuExFSM4XDBtQiFnaUB5hiPnZ", block_interval=block_interval, - _max_aggregation=_max_aggregation, delay_limit=delay_limit)).run(sender=creator, valid=False, - exception="NotExistsLink") - # 3: setting link with invalid paramter - bmc_management_contract.set_link( - sp.record(_link=link, block_interval=block_interval, _max_aggregation=sp.nat(0), - delay_limit=delay_limit)).run( - sender=creator, valid=False, exception="InvalidParam") - bmc_management_contract.set_link( - sp.record(_link=link, block_interval=block_interval, _max_aggregation=_max_aggregation, - delay_limit=sp.nat(0))).run(sender=creator, valid=False, exception="InvalidParam") - - # 4: setting link with valid paramter by owner - bmc_management_contract.set_link( - sp.record(_link=link, block_interval=block_interval, _max_aggregation=_max_aggregation, - delay_limit=delay_limit)).run(sender=creator) - # Scenario 8: add / remove relay and get_relays # Test case: @@ -298,12 +268,12 @@ def test(): rx_seq=sp.nat(0), tx_seq=sp.nat(0), block_interval_src=sp.nat(30000), - block_interval_dst=sp.nat(2), - max_aggregation=sp.nat(3), - delay_limit=sp.nat(2), + block_interval_dst=sp.nat(0), + max_aggregation=sp.nat(10), + delay_limit=sp.nat(3), relay_idx=sp.nat(0), rotate_height=sp.nat(0), - rx_height=sp.nat(0), + rx_height=sp.nat(2), rx_height_src=sp.nat(0), is_connected=True ) @@ -319,7 +289,7 @@ def test(): # 5: verify get_link_rx_height get_link_rx_height = bmc_management_contract.get_link_rx_height(link) - sc.verify_equal(get_link_rx_height, 0) + sc.verify_equal(get_link_rx_height, 2) # 6: verify get_link_relays get_link_relays = bmc_management_contract.get_link_relays(link) @@ -372,7 +342,7 @@ def test(): # 3: verifying value sc.verify_equal(bmc_management_contract.data.links[next_link1].rx_height, 4) - # Scenario 13: update_link_reachable and delete_link_reachable function + # Scenario 13: update_link_reachable # Test cases: to = sp.list(["btp://net1/addr1", "btp://net2/addr2"]) @@ -387,22 +357,6 @@ def test(): sc.verify_equal(bmc_management_contract.data.links[next_link1].reachable, sp.set(['btp://net1/addr1', 'btp://net2/addr2'])) - # 4: delete_link_reachable by non-bmc_periphery - bmc_management_contract.delete_link_reachable( - sp.record(prev=next_link1, index=sp.nat(0))).run(sender=creator, valid=False, exception="Unauthorized") - - # 5: delete_link_reachable by bmc_periphery - bmc_management_contract.delete_link_reachable(sp.record(prev=next_link1, index=sp.nat(0))).run( - sender=bmc_periphery_address) - - # 6: verifying value - sc.verify_equal(bmc_management_contract.data.links[next_link1].reachable, sp.set(['btp://net2/addr2'])) - - # # 7: delete non-exist link - # next_link2 = sp.string("btp://0x7.icon/cxff8a87fde8971a1d10d93dfed3416b0a625link2") - # bmc_management_contract.delete_link_reachable(sp.record(prev=next_link2, index=sp.nat(0))).run( - # sender=bmc_periphery_address) - # Scenario 13: update_relay_stats and resolve_route function # Test cases: diff --git a/smartpy/bmc/contracts/tests/integration_test.py b/smartpy/bmc/contracts/tests/integration_test.py index 708d7677..c789986e 100644 --- a/smartpy/bmc/contracts/tests/integration_test.py +++ b/smartpy/bmc/contracts/tests/integration_test.py @@ -176,6 +176,10 @@ def test(): sc += fa2_dummy_second # BMC_MANAGEMENT SETTERS + + # set pause status to false + bmc_management.toggle_bridge_on().run(sender=owner.address) + # set bmc periphery bmc_management.set_bmc_periphery(bmc_periphery.address).run( sender=owner.address) @@ -213,6 +217,10 @@ def test(): sender=owner.address) # BTS_CORE SETTERS + + # set pause status to false + bts_core.toggle_bridge_on().run(sender=owner.address) + # update_bts_periphery bts_core.update_bts_periphery(bts_periphery.address).run(sender=owner.address) From c35dcadd259c4b8bb2c70681f20130ea32fb015f Mon Sep 17 00:00:00 2001 From: simusud Date: Thu, 20 Jul 2023 13:15:19 +0545 Subject: [PATCH 163/211] test(bts): updated test for set token limit --- smartpy/bts/contracts/tests/bts_periphery_test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/smartpy/bts/contracts/tests/bts_periphery_test.py b/smartpy/bts/contracts/tests/bts_periphery_test.py index 6fb4e083..0b152471 100644 --- a/smartpy/bts/contracts/tests/bts_periphery_test.py +++ b/smartpy/bts/contracts/tests/bts_periphery_test.py @@ -70,14 +70,14 @@ def deploy_bts_owner_manager_contract(): # 2: set token limit for Tok2 coin to 5 and BB coin to 2 from bts_periphery_contract bts_periphery_contract.set_token_limit(sp.map({"Tok2": sp.nat(5), "BB": sp.nat(2)})).run( - sender=bts_periphery_contract.address) + sender=bts_core_contract.address) # 3: verifying the value of token limit sc.verify(bts_periphery_contract.data.token_limit["Tok2"] == sp.nat(5)) # 4: modify already set data bts_periphery_contract.set_token_limit(sp.map({"Tok2": sp.nat(15), "BB": sp.nat(22)})).run( - sender=bts_periphery_contract.address) + sender=bts_core_contract.address) # 5: verifying the value of token limit after change sc.verify(bts_periphery_contract.data.token_limit["BB"] == sp.nat(22)) From 51dbaf9706972cde7107ee3c3ff3256d4b9e94cf Mon Sep 17 00:00:00 2001 From: icondev22 Date: Fri, 21 Jul 2023 10:16:35 +0545 Subject: [PATCH 164/211] fix: icon tezos bridge integration --- cmd/iconbridge/chain/tezos/receiver.go | 7 ++++--- cmd/iconbridge/chain/tezos/verifier.go | 9 ++++++++- cmd/iconbridge/example.config.json | 4 ++-- cmd/iconbridge/relay/multi_relay.go | 4 +--- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/cmd/iconbridge/chain/tezos/receiver.go b/cmd/iconbridge/chain/tezos/receiver.go index 311a04a0..d86c56ac 100644 --- a/cmd/iconbridge/chain/tezos/receiver.go +++ b/cmd/iconbridge/chain/tezos/receiver.go @@ -677,9 +677,10 @@ func (r *receiver) receiveLoop2(ctx context.Context, opts *BnOptions, callback f r.log.WithFields(log.Fields{"height": vr.Next()}).Info("syncVerifier: complete") RelaySyncStatusLog = true } - - if err := callback(vr.LastVerifiedBn()); err != nil { - return errors.Wrapf(err, "receiveLoop: callback: %v", err) + if vr.LastVerifiedBn() != nil { + if err := callback(vr.LastVerifiedBn()); err != nil { + return errors.Wrapf(err, "receiveLoop: callback: %v", err) + } } } else { r.log.WithFields(log.Fields{"height": vr.Next(), "target": opts.StartHeight}).Debug("syncVerifier: syncing") diff --git a/cmd/iconbridge/chain/tezos/verifier.go b/cmd/iconbridge/chain/tezos/verifier.go index 4a8d7446..a347f407 100644 --- a/cmd/iconbridge/chain/tezos/verifier.go +++ b/cmd/iconbridge/chain/tezos/verifier.go @@ -38,6 +38,7 @@ type Verifier struct { height int64 cycle int64 lastVerifiedBn *types.BlockNotification + updatedBn *types.BlockNotification cl *Client } @@ -102,7 +103,13 @@ func (vr *Verifier) Update(ctx context.Context, lbn *types.BlockNotification) er // vr.updateValidatorsAndCycle(ctx, block.Header.Level, block.Metadata.LevelInfo.Cycle) // } - vr.lastVerifiedBn = lbn + if vr.updatedBn == nil { + fmt.Println("should return from here first") + vr.updatedBn = lbn + return nil + } + vr.lastVerifiedBn = vr.updatedBn + vr.updatedBn = lbn return nil } diff --git a/cmd/iconbridge/example.config.json b/cmd/iconbridge/example.config.json index add30c31..bc1ca1ae 100644 --- a/cmd/iconbridge/example.config.json +++ b/cmd/iconbridge/example.config.json @@ -23,12 +23,12 @@ ], "options": { "verifier": { - "blockHeight": 3170705 + "blockHeight": 3289000 }, "syncConcurrency": 100, "bmcManagement": "KT1HHnV7zzxUkDMXTaNveLQHntLfSWNqJsZk" }, - "offset": 3170705 + "offset": 3289000 }, "dst": { "address": "btp://0x7.icon/cxb7de63db8c1fa2d9dfb6c531e6bc19402572cc23", diff --git a/cmd/iconbridge/relay/multi_relay.go b/cmd/iconbridge/relay/multi_relay.go index 04e3cd69..ed53399c 100644 --- a/cmd/iconbridge/relay/multi_relay.go +++ b/cmd/iconbridge/relay/multi_relay.go @@ -45,9 +45,7 @@ func NewMultiRelay(cfg *Config, l log.Logger) (Relay, error) { w, err := rc.Dst.Wallet() if err != nil { - fmt.Println(err) - - // return nil, fmt.Errorf("dst.wallet chain %v err %v", rc.Name, err) + return nil, fmt.Errorf("dst.wallet chain %v err %v", rc.Name, err) } chainName := rc.Dst.Address.BlockChain() srvName := "BMR-" From 98b92d2832eaef67f71951b495efe1648adf24ac Mon Sep 17 00:00:00 2001 From: simusud Date: Fri, 21 Jul 2023 11:26:29 +0545 Subject: [PATCH 165/211] refactor(bmc): removed unused db --- smartpy/bmc/contracts/src/bmc_management.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/smartpy/bmc/contracts/src/bmc_management.py b/smartpy/bmc/contracts/src/bmc_management.py index 2d171e50..00871106 100644 --- a/smartpy/bmc/contracts/src/bmc_management.py +++ b/smartpy/bmc/contracts/src/bmc_management.py @@ -13,7 +13,6 @@ class BMCManagement(sp.Contract, rlp.DecodeEncodeLibrary): def __init__(self, owner_address, helper_contract): self.init( owners=sp.map(l={owner_address:True}), - number_of_owners=sp.nat(1), bsh_services=sp.map(), relay_stats=sp.map(), routes=sp.map(), @@ -31,7 +30,6 @@ def __init__(self, owner_address, helper_contract): self.init_type(sp.TRecord( owners=sp.TMap(sp.TAddress, sp.TBool), - number_of_owners=sp.TNat, bsh_services=sp.TMap(sp.TString, sp.TAddress), relay_stats=sp.TMap(sp.TAddress, types.Types.RelayStats), routes=sp.TMap(sp.TString, sp.TString), From 0e441a3187e11d0e73dba76b3b130e92219c3c67 Mon Sep 17 00:00:00 2001 From: simusud Date: Fri, 21 Jul 2023 12:15:27 +0545 Subject: [PATCH 166/211] refactor(bts): resolved todo --- smartpy/bts/contracts/src/bts_core.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/smartpy/bts/contracts/src/bts_core.py b/smartpy/bts/contracts/src/bts_core.py index ef5d0c31..df52fd6a 100644 --- a/smartpy/bts/contracts/src/bts_core.py +++ b/smartpy/bts/contracts/src/bts_core.py @@ -14,8 +14,7 @@ class BTSCore(sp.Contract): NON_NATIVE_TOKEN_TYPE = sp.nat(2) MAX_BATCH_SIZE = sp.nat(15) - # TODO: set NATIVE_COIN_ADDRESS to governance address - NATIVE_COIN_ADDRESS = sp.address("tz1VA29GwaSA814BVM7AzeqVzxztEjjxiMEc") + NATIVE_COIN_ADDRESS = sp.address("tz1burnburnburnburnburnburnburjAYjjX") ZERO_ADDRESS = sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg") # Nat:(TWO.pow256 - 1) UINT_CAP = sp.nat(115792089237316195423570985008687907853269984665640564039457584007913129639935) @@ -121,7 +120,6 @@ def register(self, name, fee_numerator, fixed_fee, addr, token_metadata, metadat sp.set_type(addr, sp.TAddress) sp.set_type(token_metadata, sp.TMap(sp.TString, sp.TBytes)) sp.set_type(metadata, sp.TBigMap(sp.TString, sp.TBytes)) - # TODO: use symbol and decimals self.only_owner() sp.verify(name != self.data.native_coin_name, message="ExistNativeCoin") sp.verify(self.data.coins.contains(name) == False, message= "ExistCoin") From 107c67dada2b558eae954d4530c67bca467be622 Mon Sep 17 00:00:00 2001 From: simusud Date: Mon, 24 Jul 2023 13:45:43 +0545 Subject: [PATCH 167/211] refactor(bmc): renamed entrypoint in bmc_periphery.py and updated check_negative.py --- smartpy/bmc/contracts/src/bmc_periphery.py | 2 +- smartpy/bmc/contracts/src/check_negative.py | 63 +++++++-------------- 2 files changed, 22 insertions(+), 43 deletions(-) diff --git a/smartpy/bmc/contracts/src/bmc_periphery.py b/smartpy/bmc/contracts/src/bmc_periphery.py index 99336f23..18233270 100644 --- a/smartpy/bmc/contracts/src/bmc_periphery.py +++ b/smartpy/bmc/contracts/src/bmc_periphery.py @@ -42,7 +42,7 @@ def set_helper_address(self, address): self.data.helper = address @sp.entry_point - def set_helper_parse_negative_address(self, address): + def set_parse_negative_addr(self, address): sp.set_type(address, sp.TAddress) self.only_owner() self.data.helper_parse_negative = address diff --git a/smartpy/bmc/contracts/src/check_negative.py b/smartpy/bmc/contracts/src/check_negative.py index 604fb6f2..de00342f 100644 --- a/smartpy/bmc/contracts/src/check_negative.py +++ b/smartpy/bmc/contracts/src/check_negative.py @@ -1,48 +1,27 @@ import smartpy as sp -Utils2 = sp.io.import_script_from_url("https://raw.githubusercontent.com/RomarQ/tezos-sc-utils/main/smartpy/utils.py") -# -# @sp.module -# def main(): -# class C(sp.Contract): -# -# @sp.onchain_view() -# def check_negative(self, x): -# sp.cast(x, sp.bytes) -# return (sp.to_int(x) < 0) -# -# @sp.onchain_view() -# def to_int(self, x): -# sp.cast(x, sp.bytes) -# return (sp.to_int(x)) -# -# @sp.onchain_view() -# def to_byte(self, x): -# return (sp.to_bytes(x)) -# -# -# @sp.add_test(name="test") -# def test(): -# scenario = sp.test_scenario(main) -# c = main.C() -# scenario += c -class Sample(sp.Contract): - def __init__(self): - self.init( - tf = False - ) +@sp.module +def main(): + class Convert(sp.Contract): - @sp.entry_point - def test(self, addr): - sp.set_type(addr, sp.TAddress) - x = sp.view("check_negative", addr, sp.bytes("0xf6"), t=sp.TBool).open_some() - self.data.tf = x + @sp.onchain_view() + def check_negative(self, x): + sp.cast(x, sp.bytes) + return sp.to_int(x) < 0 -@sp.add_test("Tests") -def test(): - sc = sp.test_scenario() - c = Sample() - sc += c + @sp.onchain_view() + def to_int(self, x): + sp.cast(x, sp.bytes) + return sp.to_int(x) + + @sp.onchain_view() + def to_byte(self, x): + return sp.to_bytes(x) -sp.add_compilation_target("check_negative", Sample()) \ No newline at end of file + +@sp.add_test(name="test") +def test(): + scenario = sp.test_scenario(main) + c = main.Convert() + scenario += c From 6e395047e4ac73c381ebde4c1b687ea3b7236f47 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Mon, 24 Jul 2023 15:25:33 +0545 Subject: [PATCH 168/211] fix: tezos icon bridge integration --- cmd/iconbridge/chain/tezos/client.go | 29 +++---- cmd/iconbridge/chain/tezos/receiver.go | 4 +- cmd/iconbridge/example.config.json | 70 ++++++++--------- .../icon-tezos/scripts/token.smartpy.sh | 75 +++++++++++++++++-- 4 files changed, 123 insertions(+), 55 deletions(-) diff --git a/cmd/iconbridge/chain/tezos/client.go b/cmd/iconbridge/chain/tezos/client.go index b6542b51..c2af2536 100644 --- a/cmd/iconbridge/chain/tezos/client.go +++ b/cmd/iconbridge/chain/tezos/client.go @@ -88,7 +88,7 @@ func (c *Client) GetBlockHeaderByHeight(ctx context.Context, connection *rpc.Cli return block, nil } -func filterMessageEvents(tx *rpc.Transaction, contractAddress tezos.Address, height uint64) (*chain.Receipt, error) { +func filterMessageEvents(tx *rpc.Transaction, contractAddress tezos.Address, height uint64, dst string) (*chain.Receipt, error) { receipt := &chain.Receipt{} var events []*chain.Event @@ -100,16 +100,19 @@ func filterMessageEvents(tx *rpc.Transaction, contractAddress tezos.Address, hei next := internalResults.Payload.Args[1].Args[0].String seq := internalResults.Payload.Args[1].Args[1].Int - events = append(events, &chain.Event{ - Message: message, - Next: chain.BTPAddress(next), - Sequence: seq.Uint64(), - }) - - receipt.Index = uint64(i) - receipt.Height = height - receipt.Events = events - fmt.Println(message, next, seq) + if next == dst { + fmt.Println("found it") + events = append(events, &chain.Event{ + Message: message, + Next: chain.BTPAddress(next), + Sequence: seq.Uint64(), + }) + + receipt.Index = uint64(i) + receipt.Height = height + receipt.Events = events + fmt.Println(message, next, seq) + } } } @@ -272,7 +275,7 @@ func PrettyEncode(data interface{}) error { return nil } -func filterTransactionOperations(block *rpc.Block, contractAddress tezos.Address, blockHeight int64, cl *Client) (bool, []*chain.Receipt, error) { +func filterTransactionOperations(block *rpc.Block, contractAddress tezos.Address, blockHeight int64, cl *Client, dst string) (bool, []*chain.Receipt, error) { blockOperations := block.Operations var tx *rpc.Transaction var receipt []*chain.Receipt @@ -282,7 +285,7 @@ func filterTransactionOperations(block *rpc.Block, contractAddress tezos.Address switch operation.Kind() { case tezos.OpTypeTransaction: tx = operation.(*rpc.Transaction) - r, err := filterMessageEvents(tx, cl.BmcManagement, uint64(blockHeight)) + r, err := filterMessageEvents(tx, cl.BmcManagement, uint64(blockHeight), dst) if err != nil { return false, nil, err } diff --git a/cmd/iconbridge/chain/tezos/receiver.go b/cmd/iconbridge/chain/tezos/receiver.go index d86c56ac..7ff2e814 100644 --- a/cmd/iconbridge/chain/tezos/receiver.go +++ b/cmd/iconbridge/chain/tezos/receiver.go @@ -764,8 +764,8 @@ func (r *receiver) receiveLoop2(ctx context.Context, opts *BnOptions, callback f return } q.v.Proposer = block.Metadata.Proposer - - hasBTPMessage, receipt, err := filterTransactionOperations(q.v.Block, r.client.Contract.Address(), q.v.Height.Int64(), r.client) + + hasBTPMessage, receipt, err := filterTransactionOperations(q.v.Block, r.client.Contract.Address(), q.v.Height.Int64(), r.client, r.dst.String()) if err != nil { q.err = errors.Wrapf(err, "hasBTPMessage: %v", err) diff --git a/cmd/iconbridge/example.config.json b/cmd/iconbridge/example.config.json index bc1ca1ae..b07cd506 100644 --- a/cmd/iconbridge/example.config.json +++ b/cmd/iconbridge/example.config.json @@ -17,78 +17,78 @@ { "name": "t2i", "src": { - "address": "btp://NetXnHfVqm9iesp.tezos/KT1VTmeVTccqv3opzkbRVrYwaoSZTTEzfJ8b", + "address": "btp://NetXnHfVqm9iesp.tezos/KT19HT12Fn5iR9UXSddFDceFQPTYwiGKSg3o", "endpoint": [ - "https://rpc.ghost.tzstats.com" + "https://rpc.ghost.tzstats.com/" ], "options": { "verifier": { - "blockHeight": 3289000 + "blockHeight": 3348770 }, "syncConcurrency": 100, - "bmcManagement": "KT1HHnV7zzxUkDMXTaNveLQHntLfSWNqJsZk" + "bmcManagement": "KT1KX1JQQiJB1nmZdkfrhn9gdoZrKtHukKTq" }, - "offset": 3289000 + "offset": 3348770 }, "dst": { - "address": "btp://0x7.icon/cxb7de63db8c1fa2d9dfb6c531e6bc19402572cc23", + "address": "btp://0x2.icon/cx1543786ea1dbdd74d09e91d80e23ed0d23dcf34c", "endpoint": [ - "https://berlin.net.solidwallet.io/api/v3" + "https://lisbon.net.solidwallet.io/api/v3/icon_dex" ], "options": { "step_limit": 100000000 }, "key_store": { + "address": "hx11960605fc0743db062e9a9615a9f661e7c15578", + "id": "381886c6-52c6-4063-aa0e-1d9a9f162b83", "version": 3, - "id": "8dd706f6-9c0d-4bf2-b607-5c3caa4f9404", - "address": "hx0a1c14557fa891cdba8df495850d61704a2c90d7", + "coinType": "icx", "crypto": { - "ciphertext": "0958c7f79c5e3947f8b7c46f78482c735baa02e0cac339ee100c09c24b99b4f6", - "cipherparams": { - "iv": "3e6334b31b407772682bf909dda25a91" - }, - "cipher": "aes-128-ctr", - "kdf": "scrypt", - "kdfparams": { - "dklen": 32, - "salt": "87ee9d1105fabc001d1d3455d3937c1256d2d604fd910bd0ffe95bb221769694", - "n": 16384, - "r": 8, - "p": 1 - }, - "mac": "f33f666c2c699dd906fdec3a454c9170c6b68cabcaae4c67e22861acf316127c" - }, - "coinType": "icx" - }, - "key_password": "icon@123" + "cipher": "aes-128-ctr", + "cipherparams": { + "iv": "e1a97b2458c0ba69e7771722899eebd0" + }, + "ciphertext": "8a877c2c670835c856ed246daaa5bb08a389cf4d1a72a29da14971c4733635be", + "kdf": "scrypt", + "kdfparams": { + "dklen": 32, + "n": 65536, + "r": 8, + "p": 1, + "salt": "8a87cd38c38c1105" + }, + "mac": "125e6865b49cf32953028c705e48f083b8a31593bf9ec97872d72a7ef8e3a758" + } + }, + "key_password": "ce6277f79ba40a4d1f5f660ac7b92c3f66512098" } }, { "name": "i2t", "src": { - "address": "btp://0x7.icon/cxb7de63db8c1fa2d9dfb6c531e6bc19402572cc23", + "address": "btp://0x2.icon/cx1543786ea1dbdd74d09e91d80e23ed0d23dcf34c", "endpoint": [ - "https://berlin.net.solidwallet.io/api/v3/icon_dex" + "https://lisbon.net.solidwallet.io/api/v3/icon_dex" ], "options": { "verifier": { - "blockHeight": 10490872, - "validatorsHash": "0x04b56f3fc8d396cc7eb8124da8a554800b8758c9e2fff0802aa9682948e65447" + "blockHeight": 25615863, + "validatorsHash": "0x0dda3ad92691fbe592a26ce6ed4c3f6d872e1864fe7867a5e4115a3c9b943886" }, "syncConcurrency": 100 }, - "offset": 10490872 + "offset": 25615863 }, "dst": { - "address": "btp://NetXnHfVqm9iesp.tezos/KT1VTmeVTccqv3opzkbRVrYwaoSZTTEzfJ8b", + "address": "btp://NetXnHfVqm9iesp.tezos/KT19HT12Fn5iR9UXSddFDceFQPTYwiGKSg3o", "endpoint": [ - "https://rpc.ghost.tzstats.com" + "https://rpc.ghost.tzstats.com/" ], "options": { "gas_limit": 1040000, "boost_gas_price": 1.5, "tx_data_size_limit": 65536, - "bmcManagement": "KT1HHnV7zzxUkDMXTaNveLQHntLfSWNqJsZk" + "bmcManagement": "KT1KX1JQQiJB1nmZdkfrhn9gdoZrKtHukKTq" }, "key_store": { "address": "tz1ZPVxKiybvbV1GvELRJJpyE1xj1UpNpXMv", diff --git a/devnet/docker/icon-tezos/scripts/token.smartpy.sh b/devnet/docker/icon-tezos/scripts/token.smartpy.sh index b0e2549b..59c4bb96 100644 --- a/devnet/docker/icon-tezos/scripts/token.smartpy.sh +++ b/devnet/docker/icon-tezos/scripts/token.smartpy.sh @@ -6,7 +6,7 @@ # source keystore.sh export CONFIG_DIR=~/GoProjects/icon-bridge/smartpy -export TEZOS_SETTER=~/tezos-addresses +export TEZOS_SETTER=~/GoProjects/icon-bridge/tezos-addresses export TEZOS_BMC_NID=NetXnHfVqm9iesp.tezos export ICON_BMC_NID=0x7.icon export TZ_COIN_SYMBOL=XTZ @@ -146,6 +146,7 @@ configure_dotenv() { local secret_deployer=$(echo "secret_deployer=$(echo $env)") cd $(echo $TEZOS_SETTER) + go mod tidy if [ -f .env ]; then echo ".env exists so removing" rm .env @@ -154,7 +155,6 @@ configure_dotenv() { local output=.env - local TZ_NETWORK=$(echo "TZ_NETWORK=$(echo $TEZOS_BMC_NID)") local ICON_NETWORK=$(echo "ICON_NETWORK=$(echo $ICON_BMC_NID)") local TEZOS_NATIVE_COIN_NAME=$(echo "TZ_NATIVE_COIN_NAME=btp-$(echo $TEZOS_BMC_NID)-XTZ") @@ -214,11 +214,70 @@ run_tezos_setters(){ go run main.go } -# bts core -# bts owner manager + +configure_javascore_addLink() { + echo "BMC: Add Link to BSC BMC:" + cd $CONFIG_DIR/bmc + if [ ! -f icon.configure.addLink ]; then + goloop rpc sendtx call --to $(cat icon.addr.bmc) \ + --method addLink \ + --param _link=$(cat tz.addr.bmcperipherybtp) \ + --key_store ~/GoProjects/icon-bridge/wallet.json \ + --key_password icon@123 \ + --nid 0x7 \ + --step_limit 1000000000 \ + --uri https://berlin.net.solidwallet.io/api/v3 | jq -r . > addLink.icon + + sleep 3 + echo "addedLink" > icon.configure.addLink + fi +} + +configure_javascore_setLinkHeight() { + echo "BMC: SetLinkHeight" + cd $CONFIG_DIR/bmc + if [ ! -f icon.configure.setLink ]; then + goloop rpc sendtx call --to $(cat icon.addr.bmc) \ + --method setLinkRxHeight \ + --param _link=$(cat tz.addr.bmcperipherybtp) \ + --param _height=$(cat tz.chain.height) \ + --key_store ~/GoProjects/icon-bridge/wallet.json \ + --key_password icon@123 \ + --nid 0x7 \ + --step_limit 1000000000 \ + --uri https://berlin.net.solidwallet.io/api/v3 | jq -r . > setLinkRxHeight.icon + + sleep 3 + echo "setLink" > icon.configure.setLink + fi +} + +configure_bmc_javascore_addRelay() { + echo "Adding bsc Relay" + local icon_bmr_owner=$(cat ~/GoProjects/icon-bridge/wallet.json | jq -r .address) + echo $icon_bmr_owner + sleep 5 + echo "Starting" + cd $CONFIG_DIR/bmc + if [ ! -f icon.configure.addRelay ]; then + goloop rpc sendtx call --to $(cat icon.addr.bmc) \ + --method addRelay \ + --param _link=$(cat tz.addr.bmcperipherybtp) \ + --param _addr=${icon_bmr_owner} \ + --key_store ~/GoProjects/icon-bridge/wallet.json \ + --key_password icon@123 \ + --nid 0x7 \ + --step_limit 1000000000 \ + --uri https://berlin.net.solidwallet.io/api/v3 | jq -r . > addRelay.icon + + sleep 3 + echo "addRelay" > icon.configure.addRelay + fi +} + -# ensure_tezos_keystore +# tezos configuration deploy_smartpy_bmc_management deploy_smartpy_bmc_periphery deploy_smartpy_bts_periphery @@ -226,3 +285,9 @@ deploy_smartpy_bts_core deploy_smartpy_bts_owner_manager configure_dotenv run_tezos_setters + +# icon configuration of tezos +configure_javascore_addLink +configure_javascore_setLinkHeight +configure_bmc_javascore_addRelay + From 6d16afc8f298e8411f09422934186c5e486a0c93 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Mon, 24 Jul 2023 15:27:26 +0545 Subject: [PATCH 169/211] feat: added tezos score setters --- tezos-addresses/Dockerfile | 31 +++ tezos-addresses/go.mod | 21 ++ tezos-addresses/go.sum | 48 ++++ tezos-addresses/main.go | 454 +++++++++++++++++++++++++++++++++++++ 4 files changed, 554 insertions(+) create mode 100644 tezos-addresses/Dockerfile create mode 100644 tezos-addresses/go.mod create mode 100644 tezos-addresses/go.sum create mode 100755 tezos-addresses/main.go diff --git a/tezos-addresses/Dockerfile b/tezos-addresses/Dockerfile new file mode 100644 index 00000000..996e33dd --- /dev/null +++ b/tezos-addresses/Dockerfile @@ -0,0 +1,31 @@ +FROM golang:1.20-alpine +WORKDIR /app + +COPY . . +#RUN go mod download + +#RUN go get -u blockwatch.cc/tzgo + +#RUN go get blockwatch.cc/tzgo/contract + +#RUN go get blockwatch.cc/tzgo/micheline + +#RUN go get blockwatch.cc/tzgo/rpc + +#RUN go get blockwatch.cc/tzgo/signer + +#RUN go get blockwatch.cc/tzgo/tezos + +#RUN go get github.com/echa/log + +#RUN go get github.com/joho/godotenv + +RUN go mod tidy + +COPY *.go ./ + +RUN go build -o tezos-address + +EXPOSE 8080 + +CMD [ "./tezos-address" ] diff --git a/tezos-addresses/go.mod b/tezos-addresses/go.mod new file mode 100644 index 00000000..8aaf4a15 --- /dev/null +++ b/tezos-addresses/go.mod @@ -0,0 +1,21 @@ +module tezos-addresses + +go 1.20 + +require ( + blockwatch.cc/tzgo v1.16.6 + github.com/echa/log v1.2.2 + github.com/joho/godotenv v1.5.1 +) + +require ( + github.com/decred/dcrd/dcrec/secp256k1 v1.0.3 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v2 v2.0.0 // indirect + github.com/echa/bson v0.0.0-20220430141917-c0fbdf7f8b79 // indirect + github.com/fatih/color v1.13.0 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect + golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa // indirect + golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8 // indirect +) diff --git a/tezos-addresses/go.sum b/tezos-addresses/go.sum new file mode 100644 index 00000000..f787671e --- /dev/null +++ b/tezos-addresses/go.sum @@ -0,0 +1,48 @@ +blockwatch.cc/tzgo v1.16.6 h1:gh95gmFp4kJFFq6/qQzYbPbWjlrejyGFn2gmPa2J5C8= +blockwatch.cc/tzgo v1.16.6/go.mod h1:Bm3ZfCsqnJtpsAdwBQmhsoz4n8qc9qL4uJhsDoLArR8= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/decred/dcrd/chaincfg/chainhash v1.0.2 h1:rt5Vlq/jM3ZawwiacWjPa+smINyLRN07EO0cNBV6DGU= +github.com/decred/dcrd/chaincfg/chainhash v1.0.2/go.mod h1:BpbrGgrPTr3YJYRN3Bm+D9NuaFd+zGyNeIKgrhCXK60= +github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/dcrec/secp256k1 v1.0.3 h1:u4XpHqlscRolxPxt2YHrFBDVZYY1AK+KMV02H1r+HmU= +github.com/decred/dcrd/dcrec/secp256k1 v1.0.3/go.mod h1:eCL8H4MYYjRvsw2TuANvEOcVMFbmi9rt/6hJUWU5wlU= +github.com/decred/dcrd/dcrec/secp256k1/v2 v2.0.0 h1:3GIJYXQDAKpLEFriGFN8SbSffak10UXHGdIcFaMPykY= +github.com/decred/dcrd/dcrec/secp256k1/v2 v2.0.0/go.mod h1:3s92l0paYkZoIHuj4X93Teg/HB7eGM9x/zokGw+u4mY= +github.com/echa/bson v0.0.0-20220430141917-c0fbdf7f8b79 h1:J+/tX7s5mN1aoeQi2ySzix7+zyEhnymkudOxn7VMze4= +github.com/echa/bson v0.0.0-20220430141917-c0fbdf7f8b79/go.mod h1:Ih8Pfj34Z/kOmaLua+KtFWFK3AviGsH5siipj6Gmoa8= +github.com/echa/log v1.2.2 h1:tL0IxLI1SqreYWvnkpdE1exilCq9sCOp+aPZWWtwtFU= +github.com/echa/log v1.2.2/go.mod h1:MuBQcNxMgV0eT5iL3yvSZyu4wh40FKfmwJQs1RDUqcQ= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8 h1:h+EGohizhe9XlX18rfpa8k8RAc5XyaeamM+0VHRd4lc= +golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +gopkg.in/bson.v2 v2.0.0-20171018101713-d8c8987b8862 h1:l7JQszYQzJc0GspaN+sivv8wScShqfkhS3nsgID8ees= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 h1:VpOs+IwYnYBaFnrNAeB8UUWtL3vEUnzSCL1nVjPhqrw= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= diff --git a/tezos-addresses/main.go b/tezos-addresses/main.go new file mode 100755 index 00000000..1ae7c99c --- /dev/null +++ b/tezos-addresses/main.go @@ -0,0 +1,454 @@ +package main + +import ( + "context" + "fmt" + "os" + + "blockwatch.cc/tzgo/contract" + "blockwatch.cc/tzgo/micheline" + "blockwatch.cc/tzgo/rpc" + "blockwatch.cc/tzgo/signer" + "blockwatch.cc/tzgo/tezos" + "github.com/echa/log" + "github.com/joho/godotenv" +) + +const ( + tzZeroAddress = "tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg" +) + +func main() { + rpc.UseLogger(log.Log) + + err := godotenv.Load(".env") + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + c, err := rpc.NewClient("https://ghostnet.tezos.marigold.dev", nil) + fmt.Println("new client") + + fmt.Println(c.ChainId) + + if err != nil { + fmt.Println(err) + return + } + + err = c.Init(ctx) + + if err != nil { + fmt.Println(err) + return + } + + c.Listen() + + // deployment options + opts := rpc.DefaultOptions + opts.Signer = signer.NewFromKey(tezos.MustParsePrivateKey(os.Getenv("secret_deployer"))) + fmt.Println(os.Getenv("secret_deployer")) + + bmc_periphery := os.Getenv("BMC_PERIPHERY") + bmc_management := os.Getenv("BMC_MANAGEMENT") + btsCore := os.Getenv("BTS_CORE") + btsPeriphery := os.Getenv("BTS_PERIPHERY") + prim := micheline.Prim{} + + // bmc_periphery + + contractAddress := tezos.MustParseAddress(bmc_periphery) + bmcPeripheryClient := contract.NewContract(contractAddress, c) + + in := "{\"string\": \"" + bmc_management + "\" }" + if err := prim.UnmarshalJSON([]byte(in)); err != nil { + fmt.Println("couldnot unmarshall empty string") + fmt.Println(err) + return + } + + args := contract.NewTxArgs() + + entrypoint := "set_bmc_management_addr" + + args.WithParameters(micheline.Parameters{Entrypoint: entrypoint, Value: prim}) + + from := tezos.MustParseAddress("tz1ZPVxKiybvbV1GvELRJJpyE1xj1UpNpXMv") + + argument := args.WithSource(from).WithDestination(contractAddress) + + fmt.Println("setting bmc management address in periphery....") + + res, err := bmcPeripheryClient.Call(ctx, argument, &opts) + + if err != nil { + fmt.Println("error while calling") + fmt.Println(err) + } + // ************************************************************************************************************************************* + // bts periphery + + contractAddress = tezos.MustParseAddress(btsPeriphery) + + btsPeripheryClient := contract.NewContract(contractAddress, c) + + in = "{\"string\": \"" + bmc_periphery + "\" }" + if err := prim.UnmarshalJSON([]byte(in)); err != nil { + fmt.Println("couldnot unmarshall empty string") + fmt.Println(err) + return + } + + args = contract.NewTxArgs() + + entrypoint = "set_bmc_address" + + args.WithParameters(micheline.Parameters{Entrypoint: entrypoint, Value: prim}) + + from = tezos.MustParseAddress("tz1ZPVxKiybvbV1GvELRJJpyE1xj1UpNpXMv") + + argument = args.WithSource(from).WithDestination(contractAddress) + + fmt.Println("setting bmc periphery in bts core....") + + res, err = btsPeripheryClient.Call(ctx, argument, &opts) + + if err != nil { + fmt.Println("error while calling") + fmt.Println(err) + } + + fmt.Println(res) + + // ************************************************************************************************************************************* + // bts periphery + + in = "{\"string\": \"" + btsCore + "\" }" + if err := prim.UnmarshalJSON([]byte(in)); err != nil { + fmt.Println("couldnot unmarshall empty string") + fmt.Println(err) + return + } + + args = contract.NewTxArgs() + + entrypoint = "set_bts_core_address" + + args.WithParameters(micheline.Parameters{Entrypoint: entrypoint, Value: prim}) + + from = tezos.MustParseAddress("tz1ZPVxKiybvbV1GvELRJJpyE1xj1UpNpXMv") + + argument = args.WithSource(from).WithDestination(contractAddress) + + fmt.Println("setting setting bts core in bts periphery....") + + res, err = btsPeripheryClient.Call(ctx, argument, &opts) + + if err != nil { + fmt.Println("error while calling") + fmt.Println(err) + } + + fmt.Println(res) + + // ************************************************************************************************************************************* + // bmc management + + contractAddress = tezos.MustParseAddress(bmc_management) + + bmcManagementClient := contract.NewContract(contractAddress, c) + + in = "{\"string\": \"" + bmc_periphery + "\" }" + if err := prim.UnmarshalJSON([]byte(in)); err != nil { + fmt.Println("couldnot unmarshall empty string") + fmt.Println(err) + return + } + + args = contract.NewTxArgs() + + entrypoint = "set_bmc_periphery" + + args.WithParameters(micheline.Parameters{Entrypoint: entrypoint, Value: prim}) + + from = tezos.MustParseAddress("tz1ZPVxKiybvbV1GvELRJJpyE1xj1UpNpXMv") + + argument = args.WithSource(from).WithDestination(contractAddress) + + fmt.Println("setting bmc periphery in bmc management....") + + res, err = bmcManagementClient.Call(ctx, argument, &opts) + + if err != nil { + fmt.Println("error while calling") + fmt.Println(err) + } + + fmt.Println(res) + + // ************************************************************************************************************************************* + // set btp address + + prim = micheline.Prim{} + + in = "{ \"string\": \"" + os.Getenv("TZ_NETWORK") + "\" }" + + if err := prim.UnmarshalJSON([]byte(in)); err != nil { + fmt.Println("couldnot unmarshall empty string") + fmt.Println(err) + return + } + + fmt.Println("setting bmcBTP address in bmcManagement...") + + args = contract.NewTxArgs() + + entrypoint = "set_bmc_btp_address" + + args.WithParameters(micheline.Parameters{Entrypoint: entrypoint, Value: prim}) + + argument = args.WithSource(from).WithDestination(contractAddress) + + res, err = bmcManagementClient.Call(ctx, argument, &opts) + + if err != nil { + fmt.Println("error while calling") + fmt.Println(err) + } + + fmt.Println(res) + + //*********************************************************************************************************************************** + // update bts periphery + + contractAddress = tezos.MustParseAddress(btsCore) + btsCoreClient := contract.NewContract(contractAddress, c) + + prim = micheline.Prim{} + + in = "{ \"string\": \"" + btsPeriphery + "\" }" + + if err := prim.UnmarshalJSON([]byte(in)); err != nil { + fmt.Println("couldnot unmarshall empty string") + fmt.Println(err) + return + } + + fmt.Println("setting bts periphery in btsCoreClient...") + + args = contract.NewTxArgs() + + entrypoint = "update_bts_periphery" + + args.WithParameters(micheline.Parameters{Entrypoint: entrypoint, Value: prim}) + + argument = args.WithSource(from).WithDestination(contractAddress) + + res, err = btsCoreClient.Call(ctx, argument, &opts) + + if err != nil { + fmt.Println("error while calling") + fmt.Println(err) + } + + fmt.Println(res) + + //*********************************************************************************************************************************** + // add service + + prim = micheline.Prim{} + + in = "{ \"prim\": \"Pair\", \"args\": [ { \"string\": \"" + btsPeriphery + "\" }, { \"string\": \"bts\" } ] }" + + contractAddress = tezos.MustParseAddress(bmc_management) + if err := prim.UnmarshalJSON([]byte(in)); err != nil { + fmt.Println("couldnot unmarshall empty string") + fmt.Println(err) + return + } + + args = contract.NewTxArgs() + + entrypoint = "add_service" + + args.WithParameters(micheline.Parameters{Entrypoint: entrypoint, Value: prim}) + + argument = args.WithSource(from).WithDestination(contractAddress) + fmt.Println("adding service...") + + res, err = bmcManagementClient.Call(ctx, argument, &opts) + + if err != nil { + fmt.Println("error while calling") + fmt.Println(err) + } + + fmt.Println(res) + + //*********************************************************************************************************************************** + // set fee ratio + + prim = micheline.Prim{} + contractAddress = tezos.MustParseAddress(btsCore) + + in = "{ \"prim\": \"Pair\", \"args\": [ { \"int\": \"100\" }, { \"prim\": \"Pair\", \"args\": [ { \"int\": \"450\" }, { \"string\": \"" + os.Getenv("TZ_NATIVE_COIN_NAME") + "\" } ] } ] }" + + if err := prim.UnmarshalJSON([]byte(in)); err != nil { + fmt.Println("couldnot unmarshall empty string") + fmt.Println(err) + return + } + + args = contract.NewTxArgs() + + entrypoint = "set_fee_ratio" + + args.WithParameters(micheline.Parameters{Entrypoint: entrypoint, Value: prim}) + + argument = args.WithSource(from).WithDestination(contractAddress) + + fmt.Println("setting fee ratio...") + res, err = btsCoreClient.Call(ctx, argument, &opts) + + if err != nil { + fmt.Println("error while calling") + fmt.Println(err) + } + + fmt.Println(res) + + //*********************************************************************************************************************************** + // add route + + prim = micheline.Prim{} + + link := "btp://" + os.Getenv("ICON_NETWORK") + "/" + os.Getenv("ICON_BMC") + fmt.Println(link) + + in = "{ \"prim\": \"Pair\", \"args\": [ { \"string\": \"" + link + "\" }, { \"string\": \"" + link + "\" } ] }" + + if err := prim.UnmarshalJSON([]byte(in)); err != nil { + fmt.Println("couldnot unmarshall empty string") + fmt.Println(err) + return + } + + args = contract.NewTxArgs() + + entrypoint = "add_route" + + args.WithParameters(micheline.Parameters{Entrypoint: entrypoint, Value: prim}) + + argument = args.WithSource(from).WithDestination(bmcManagementClient.Address()) + + fmt.Println("adding route...") + res, err = bmcManagementClient.Call(ctx, argument, &opts) + + if err != nil { + fmt.Println("error while calling") + fmt.Println(err) + } + + fmt.Println(res) + + //*********************************************************************************************************************************** + // add link + + prim = micheline.Prim{} + + fmt.Println(link) + + in = "{ \"string\": \"" + link + "\" }" + + if err := prim.UnmarshalJSON([]byte(in)); err != nil { + fmt.Println("couldnot unmarshall empty string") + fmt.Println(err) + return + } + + args = contract.NewTxArgs() + + entrypoint = "add_link" + + args.WithParameters(micheline.Parameters{Entrypoint: entrypoint, Value: prim}) + + argument = args.WithSource(from).WithDestination(bmcManagementClient.Address()) + + fmt.Println("adding link....") + + res, err = bmcManagementClient.Call(ctx, argument, &opts) + + if err != nil { + fmt.Println("error while calling") + fmt.Println(err) + } + + fmt.Println(res) + + //*********************************************************************************************************************************** + // set link rx height + + prim = micheline.Prim{} + + fmt.Println(os.Getenv("ICON_RX_HEIGHT")) + + in = "{ \"prim\": \"Pair\", \"args\": [ { \"int\": \"" + os.Getenv("ICON_RX_HEIGHT") + "\" }, { \"string\": \"" + link + "\" } ] }" + + if err := prim.UnmarshalJSON([]byte(in)); err != nil { + fmt.Println("couldnot unmarshall empty string") + fmt.Println(err) + return + } + + args = contract.NewTxArgs() + + entrypoint = "set_link_rx_height" + + args.WithParameters(micheline.Parameters{Entrypoint: entrypoint, Value: prim}) + + argument = args.WithSource(from).WithDestination(bmcManagementClient.Address()) + + fmt.Println("setting link_rx_height...") + res, err = bmcManagementClient.Call(ctx, argument, &opts) + + if err != nil { + fmt.Println("error while calling") + fmt.Println(err) + } + + fmt.Println(res) + + //*********************************************************************************************************************************** + // add relay + + prim = micheline.Prim{} + + fmt.Println(os.Getenv("RELAYER_ADDRESS")) + + in = "{ \"prim\": \"Pair\", \"args\": [ [ { \"string\": \"" + os.Getenv("RELAYER_ADDRESS") + "\" } ], { \"string\": \"" + link + "\" } ] }" + + if err := prim.UnmarshalJSON([]byte(in)); err != nil { + fmt.Println("couldnot unmarshall empty string") + fmt.Println(err) + return + } + + args = contract.NewTxArgs() + + entrypoint = "add_relay" + + args.WithParameters(micheline.Parameters{Entrypoint: entrypoint, Value: prim}) + + argument = args.WithSource(from).WithDestination(bmcManagementClient.Address()) + + fmt.Println("adding relay...") + res, err = bmcManagementClient.Call(ctx, argument, &opts) + + if err != nil { + fmt.Println("error while calling") + fmt.Println(err) + } + + fmt.Println(res) +} From fa5419b20e0a4621631232fdedc5e30339853ddd Mon Sep 17 00:00:00 2001 From: icondev22 Date: Tue, 25 Jul 2023 10:29:59 +0545 Subject: [PATCH 170/211] fix: block processing logic --- cmd/iconbridge/chain/tezos/receiver.go | 2 +- cmd/iconbridge/example.config.json | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/cmd/iconbridge/chain/tezos/receiver.go b/cmd/iconbridge/chain/tezos/receiver.go index 7ff2e814..b5892104 100644 --- a/cmd/iconbridge/chain/tezos/receiver.go +++ b/cmd/iconbridge/chain/tezos/receiver.go @@ -677,7 +677,7 @@ func (r *receiver) receiveLoop2(ctx context.Context, opts *BnOptions, callback f r.log.WithFields(log.Fields{"height": vr.Next()}).Info("syncVerifier: complete") RelaySyncStatusLog = true } - if vr.LastVerifiedBn() != nil { + if vr.LastVerifiedBn() != nil && vr.LastVerifiedBn().Header.Level > opts.StartHeight{ if err := callback(vr.LastVerifiedBn()); err != nil { return errors.Wrapf(err, "receiveLoop: callback: %v", err) } diff --git a/cmd/iconbridge/example.config.json b/cmd/iconbridge/example.config.json index b07cd506..008c2c62 100644 --- a/cmd/iconbridge/example.config.json +++ b/cmd/iconbridge/example.config.json @@ -17,21 +17,21 @@ { "name": "t2i", "src": { - "address": "btp://NetXnHfVqm9iesp.tezos/KT19HT12Fn5iR9UXSddFDceFQPTYwiGKSg3o", + "address": "btp://NetXnHfVqm9iesp.tezos/KT1Wjpoh4jPanEMVh4qeSXbDecvjhxLhx8Ug", "endpoint": [ "https://rpc.ghost.tzstats.com/" ], "options": { "verifier": { - "blockHeight": 3348770 + "blockHeight": 3349666 }, "syncConcurrency": 100, - "bmcManagement": "KT1KX1JQQiJB1nmZdkfrhn9gdoZrKtHukKTq" + "bmcManagement": "KT1Ghih7orJHyUCQzRbKPEPixYw5YBvF7wHs" }, - "offset": 3348770 + "offset": 3349666 }, "dst": { - "address": "btp://0x2.icon/cx1543786ea1dbdd74d09e91d80e23ed0d23dcf34c", + "address": "btp://0x2.icon/cxcecf7a9edbba4da6fead6e4530b5a204af614867", "endpoint": [ "https://lisbon.net.solidwallet.io/api/v3/icon_dex" ], @@ -66,21 +66,21 @@ { "name": "i2t", "src": { - "address": "btp://0x2.icon/cx1543786ea1dbdd74d09e91d80e23ed0d23dcf34c", + "address": "btp://0x2.icon/cxcecf7a9edbba4da6fead6e4530b5a204af614867", "endpoint": [ "https://lisbon.net.solidwallet.io/api/v3/icon_dex" ], "options": { "verifier": { - "blockHeight": 25615863, + "blockHeight": 25618358, "validatorsHash": "0x0dda3ad92691fbe592a26ce6ed4c3f6d872e1864fe7867a5e4115a3c9b943886" }, "syncConcurrency": 100 }, - "offset": 25615863 + "offset": 25618358 }, "dst": { - "address": "btp://NetXnHfVqm9iesp.tezos/KT19HT12Fn5iR9UXSddFDceFQPTYwiGKSg3o", + "address": "btp://NetXnHfVqm9iesp.tezos/KT1Wjpoh4jPanEMVh4qeSXbDecvjhxLhx8Ug", "endpoint": [ "https://rpc.ghost.tzstats.com/" ], @@ -88,7 +88,7 @@ "gas_limit": 1040000, "boost_gas_price": 1.5, "tx_data_size_limit": 65536, - "bmcManagement": "KT1KX1JQQiJB1nmZdkfrhn9gdoZrKtHukKTq" + "bmcManagement": "KT1Ghih7orJHyUCQzRbKPEPixYw5YBvF7wHs" }, "key_store": { "address": "tz1ZPVxKiybvbV1GvELRJJpyE1xj1UpNpXMv", From e3a3e4f6068404a1625880cfff341aedda8c9d97 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Tue, 25 Jul 2023 10:42:59 +0545 Subject: [PATCH 171/211] fix: configure dot env for tezos setter --- devnet/docker/icon-tezos/scripts/token.smartpy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devnet/docker/icon-tezos/scripts/token.smartpy.sh b/devnet/docker/icon-tezos/scripts/token.smartpy.sh index 59c4bb96..719f9305 100644 --- a/devnet/docker/icon-tezos/scripts/token.smartpy.sh +++ b/devnet/docker/icon-tezos/scripts/token.smartpy.sh @@ -134,7 +134,7 @@ configure_dotenv() { local bmc_management=$(echo $(cat tz.addr.bmc_management)) local bmc_height=$(echo $(cat tz.chain.height)) local icon_bmc_height=$(echo $(cat iconbmcheight)) - local icon_bmc=$(echo $(cat iconbmc)) + local icon_bmc=$(echo $(cat icon.addr.bmc)) echo $bmc_periphery cd $(echo $CONFIG_DIR/bts) From 300644c3d4dd7addd6d3dd6ff0cb09ae030c7146 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Thu, 27 Jul 2023 11:42:13 +0545 Subject: [PATCH 172/211] fix: tezos icon bridge integration --- cmd/iconbridge/chain/tezos/client.go | 3 -- cmd/iconbridge/chain/tezos/receiver.go | 29 ++++++-------- cmd/iconbridge/chain/tezos/verifier.go | 35 ++++++++++++---- cmd/iconbridge/example.config.json | 55 ++++++++------------------ 4 files changed, 58 insertions(+), 64 deletions(-) diff --git a/cmd/iconbridge/chain/tezos/client.go b/cmd/iconbridge/chain/tezos/client.go index c2af2536..1f0de5c7 100644 --- a/cmd/iconbridge/chain/tezos/client.go +++ b/cmd/iconbridge/chain/tezos/client.go @@ -250,9 +250,6 @@ func (c *Client) CustomCall(ctx context.Context, args []contract.CallArguments, } func NewClient(uri string, src tezos.Address, bmcManagement tezos.Address, l log.Logger) (*Client, error) { - - fmt.Println("uri is : " + uri) - c, err := rpc.NewClient(uri, nil) conn := contract.NewContract(src, c) diff --git a/cmd/iconbridge/chain/tezos/receiver.go b/cmd/iconbridge/chain/tezos/receiver.go index b5892104..065b1237 100644 --- a/cmd/iconbridge/chain/tezos/receiver.go +++ b/cmd/iconbridge/chain/tezos/receiver.go @@ -149,8 +149,6 @@ func NewReceiver(src, dst chain.BTPAddress, urls []string, rawOpts json.RawMessa srcAddr := tezos.MustParseAddress(src.ContractAddress()) bmcManagement := tezos.MustParseAddress(receiver.opts.BMCManagment) - fmt.Println("bmcManagement receiver", bmcManagement) - newClient, err = NewClient(urls[0], srcAddr, bmcManagement, receiver.log) if err != nil { @@ -204,8 +202,7 @@ func (r *receiver) NewVerifier(ctx context.Context, previousHeight int64) (vri I validatorsPublicKey: make(map[tezos.Address]tezos.Key), } - // vr.updateValidatorsAndCycle(ctx, previousHeight, block.Metadata.LevelInfo.Cycle) - fmt.Println("cycle is ", vr.cycle) + vr.updateValidatorsAndCycle(ctx, previousHeight, block.Metadata.LevelInfo.Cycle) return vr, nil } @@ -656,18 +653,18 @@ func (r *receiver) receiveLoop2(ctx context.Context, opts *BnOptions, callback f } } else { if vr != nil { - // if err := vr.Verify(ctx, lbn); err != nil { // change accordingly - // r.log.WithFields(log.Fields{ - // "height": lbn.Height, - // "lbnHash": lbn.Hash, - // "nextHeight": next, - // "bnHash": bn.Hash}).Error("verification failed. refetching block ", err) - // fmt.Println(err) - // fmt.Println("error in verifying ") - // time.Sleep(5 * time.Second) - // next-- - // break - // } + if err := vr.Verify(ctx, lbn); err != nil { // change accordingly + r.log.WithFields(log.Fields{ + "height": lbn.Height, + "lbnHash": lbn.Hash, + "nextHeight": next, + "bnHash": bn.Hash}).Error("verification failed. refetching block ", err) + fmt.Println(err) + fmt.Println("error in verifying ") + time.Sleep(5 * time.Second) + next-- + break + } if err := vr.Update(ctx, lbn); err != nil { return errors.Wrapf(err, "receiveLoop: vr.Update: %v", err) } diff --git a/cmd/iconbridge/chain/tezos/verifier.go b/cmd/iconbridge/chain/tezos/verifier.go index a347f407..4e6f40e7 100644 --- a/cmd/iconbridge/chain/tezos/verifier.go +++ b/cmd/iconbridge/chain/tezos/verifier.go @@ -70,12 +70,14 @@ func (vr *Verifier) Verify(ctx context.Context, lbn *types.BlockNotification) er isValidSignature, _ := vr.VerifySignature(ctx, lbn) if !isValidSignature { - return fmt.Errorf("invalid block signature. signature mismatch") + panic("invalid signature") + // return fmt.Errorf("invalid block signature. signature mismatch") } err = vr.verifyEndorsement(lbn.Block, lbn.Header.ChainId) if err != nil { - return fmt.Errorf("invlid endorsement") + panic("endorsement unverified") + // return fmt.Errorf("invlid endorsement") } return nil @@ -99,9 +101,9 @@ func (vr *Verifier) Update(ctx context.Context, lbn *types.BlockNotification) er vr.height = header.Level vr.next = header.Level + 1 - // if vr.cycle != block.Metadata.LevelInfo.Cycle { - // vr.updateValidatorsAndCycle(ctx, block.Header.Level, block.Metadata.LevelInfo.Cycle) - // } + if vr.cycle != block.Metadata.LevelInfo.Cycle { + vr.updateValidatorsAndCycle(ctx, block.Header.Level, block.Metadata.LevelInfo.Cycle) + } if vr.updatedBn == nil { fmt.Println("should return from here first") @@ -159,23 +161,29 @@ func (vr *Verifier) VerifySignature(ctx context.Context, lbn *types.BlockNotific digestedHash := blockHeader.Digest() + fmt.Println(lbn.Block.Metadata.Baker) err := vr.validatorsPublicKey[lbn.Block.Metadata.Baker].Verify(digestedHash[:], header.Signature) if err != nil { panic("signature failed") // return false, err } - return true, nil } func (vr *Verifier) updateValidatorsAndCycle(ctx context.Context, blockHeight int64, cycle int64) error { PrintSync() validatorsList, err := vr.cl.Cl.ListEndorsingRights(ctx, rpc.BlockLevel(blockHeight)) - var validatorsPublicKey tezos.Key if err != nil { return err } + + bakersList, err := vr.cl.Cl.ListBakingRightsCycle(ctx, rpc.BlockLevel(blockHeight), cycle, 1) + if err != nil { + return err + } + + var validatorsPublicKey tezos.Key // remove all validators for a := range vr.validators { delete(vr.validators, a) @@ -190,6 +198,19 @@ func (vr *Verifier) updateValidatorsAndCycle(ctx context.Context, blockHeight in } vr.validatorsPublicKey[validator.Delegate] = validatorsPublicKey } + + for _, validator := range bakersList { + if !vr.validators[validator.Delegate] { + fmt.Println("also added the unlisted bakers") + vr.validators[validator.Delegate] = true + validatorsPublicKey, err = vr.cl.GetConsensusKey(ctx, validator.Delegate) + if err != nil { + return err + } + vr.validatorsPublicKey[validator.Delegate] = validatorsPublicKey + } + } + vr.cycle = cycle return nil } diff --git a/cmd/iconbridge/example.config.json b/cmd/iconbridge/example.config.json index 008c2c62..ace9eb5b 100644 --- a/cmd/iconbridge/example.config.json +++ b/cmd/iconbridge/example.config.json @@ -17,78 +17,57 @@ { "name": "t2i", "src": { - "address": "btp://NetXnHfVqm9iesp.tezos/KT1Wjpoh4jPanEMVh4qeSXbDecvjhxLhx8Ug", + "address": "btp://NetXnHfVqm9iesp.tezos/KT1TB59icBYsd35ace93ZUrUEWvfZ7TgqY61", "endpoint": [ - "https://rpc.ghost.tzstats.com/" + "http://localhost:8732" ], "options": { "verifier": { - "blockHeight": 3349666 + "blockHeight": 3368125 }, "syncConcurrency": 100, - "bmcManagement": "KT1Ghih7orJHyUCQzRbKPEPixYw5YBvF7wHs" + "bmcManagement": "KT1HDwVVLSsfQXdgQAJZuCm2DoXemapHjtiM" }, - "offset": 3349666 + "offset": 3368125 }, "dst": { - "address": "btp://0x2.icon/cxcecf7a9edbba4da6fead6e4530b5a204af614867", + "address": "btp://0x1.icon/cxb6c3f7f2618e33000dff26295468b53616df4640", "endpoint": [ - "https://lisbon.net.solidwallet.io/api/v3/icon_dex" + "https://ctz.solidwallet.io/api/v3" ], "options": { "step_limit": 100000000 }, - "key_store": { - "address": "hx11960605fc0743db062e9a9615a9f661e7c15578", - "id": "381886c6-52c6-4063-aa0e-1d9a9f162b83", - "version": 3, - "coinType": "icx", - "crypto": { - "cipher": "aes-128-ctr", - "cipherparams": { - "iv": "e1a97b2458c0ba69e7771722899eebd0" - }, - "ciphertext": "8a877c2c670835c856ed246daaa5bb08a389cf4d1a72a29da14971c4733635be", - "kdf": "scrypt", - "kdfparams": { - "dklen": 32, - "n": 65536, - "r": 8, - "p": 1, - "salt": "8a87cd38c38c1105" - }, - "mac": "125e6865b49cf32953028c705e48f083b8a31593bf9ec97872d72a7ef8e3a758" - } - }, - "key_password": "ce6277f79ba40a4d1f5f660ac7b92c3f66512098" + "key_store": {"version":3,"id":"208083ba-6500-48b3-8b72-4f3be5b7ef99","address":"hx3baf3eb77acc858db66c6b64c4394e5b8485c67c","crypto":{"ciphertext":"0c65ab452930e8c30fbd464af844312f59c84c51db7c9558a2109d1e2ff2fc71","cipherparams":{"iv":"bed35c38c82f33e904928760b102a278"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"7ac0551ba163f280c72c1297eb02e209de47945c61d1d6feec94f57c0a6f0cce","n":16384,"r":8,"p":1},"mac":"c1d7126a19af46c2f2e2977be0809a438916b608e6a6b4b45044dbd45381e2e1"},"coinType":"icx"}, + "key_password": "icon@123" } }, { "name": "i2t", "src": { - "address": "btp://0x2.icon/cxcecf7a9edbba4da6fead6e4530b5a204af614867", + "address": "btp://0x1.icon/cxb6c3f7f2618e33000dff26295468b53616df4640", "endpoint": [ - "https://lisbon.net.solidwallet.io/api/v3/icon_dex" + "https://ctz.solidwallet.io/api/v3" ], "options": { "verifier": { - "blockHeight": 25618358, - "validatorsHash": "0x0dda3ad92691fbe592a26ce6ed4c3f6d872e1864fe7867a5e4115a3c9b943886" + "blockHeight": 25700560, + "validatorsHash": "0xe15fd3392fae29a7f72168f408ab4085c5aa617e55fa42572f8ba24c0f771d85" }, "syncConcurrency": 100 }, - "offset": 25618358 + "offset": 25700560 }, "dst": { - "address": "btp://NetXnHfVqm9iesp.tezos/KT1Wjpoh4jPanEMVh4qeSXbDecvjhxLhx8Ug", + "address": "btp://NetXnHfVqm9iesp.tezos/KT1TB59icBYsd35ace93ZUrUEWvfZ7TgqY61", "endpoint": [ - "https://rpc.ghost.tzstats.com/" + "http://localhost:8732" ], "options": { "gas_limit": 1040000, "boost_gas_price": 1.5, "tx_data_size_limit": 65536, - "bmcManagement": "KT1Ghih7orJHyUCQzRbKPEPixYw5YBvF7wHs" + "bmcManagement": "KT1HDwVVLSsfQXdgQAJZuCm2DoXemapHjtiM" }, "key_store": { "address": "tz1ZPVxKiybvbV1GvELRJJpyE1xj1UpNpXMv", From 9ba9b68d08a8b9262de0f677fff7fcbb6e21ebeb Mon Sep 17 00:00:00 2001 From: icondev22 Date: Fri, 4 Aug 2023 08:52:50 +0545 Subject: [PATCH 173/211] fix: tezos icon bridge config --- cmd/iconbridge/chain/icon/sender.go | 2 +- cmd/iconbridge/chain/tezos/receiver.go | 2 +- cmd/iconbridge/example.config.json | 28 +- .../icon-tezos/scripts/token.smartpy.sh | 476 ++++++++++++++++-- 4 files changed, 448 insertions(+), 60 deletions(-) mode change 100644 => 100755 devnet/docker/icon-tezos/scripts/token.smartpy.sh diff --git a/cmd/iconbridge/chain/icon/sender.go b/cmd/iconbridge/chain/icon/sender.go index af5a60d6..23c8fdc1 100644 --- a/cmd/iconbridge/chain/icon/sender.go +++ b/cmd/iconbridge/chain/icon/sender.go @@ -44,7 +44,7 @@ const ( defaultTxSizeLimit = txMaxDataSize / (1 + txOverheadScale) defaultGetRelayResultInterval = time.Second defaultRelayReSendInterval = time.Second - defaultStepLimit = 13610920010 + defaultStepLimit = 300000000 ) // NewSender ... diff --git a/cmd/iconbridge/chain/tezos/receiver.go b/cmd/iconbridge/chain/tezos/receiver.go index 065b1237..23fb1225 100644 --- a/cmd/iconbridge/chain/tezos/receiver.go +++ b/cmd/iconbridge/chain/tezos/receiver.go @@ -639,7 +639,7 @@ func (r *receiver) receiveLoop2(ctx context.Context, opts *BnOptions, callback f latest++ case <-heightPoller.C: if height := latestHeight(); height > 0 { - latest = height + latest = height - 5 r.log.WithFields(log.Fields{"latest": latest, "next": next}).Debug("poll height") } case bn := <-bnch: diff --git a/cmd/iconbridge/example.config.json b/cmd/iconbridge/example.config.json index ace9eb5b..c02898ad 100644 --- a/cmd/iconbridge/example.config.json +++ b/cmd/iconbridge/example.config.json @@ -17,49 +17,49 @@ { "name": "t2i", "src": { - "address": "btp://NetXnHfVqm9iesp.tezos/KT1TB59icBYsd35ace93ZUrUEWvfZ7TgqY61", + "address": "btp://NetXdQprcVkpaWU.tezos/KT1WUCnwwVPee5szEygLaXfSCcUHz9MGbtYd", "endpoint": [ "http://localhost:8732" ], "options": { "verifier": { - "blockHeight": 3368125 + "blockHeight": 3953500 }, "syncConcurrency": 100, - "bmcManagement": "KT1HDwVVLSsfQXdgQAJZuCm2DoXemapHjtiM" + "bmcManagement": "KT1JsML1sT1G1bbJpKx8P3Q6eBNMpKXDTt6T" }, - "offset": 3368125 + "offset": 3953500 }, "dst": { - "address": "btp://0x1.icon/cxb6c3f7f2618e33000dff26295468b53616df4640", + "address": "btp://0x1.icon/cx5d70d870dcf1ce7858869811b66c8acfb8eb3112", "endpoint": [ - "https://ctz.solidwallet.io/api/v3" + "https://ctz.solidwallet.io/api/v3/" ], "options": { "step_limit": 100000000 }, - "key_store": {"version":3,"id":"208083ba-6500-48b3-8b72-4f3be5b7ef99","address":"hx3baf3eb77acc858db66c6b64c4394e5b8485c67c","crypto":{"ciphertext":"0c65ab452930e8c30fbd464af844312f59c84c51db7c9558a2109d1e2ff2fc71","cipherparams":{"iv":"bed35c38c82f33e904928760b102a278"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"7ac0551ba163f280c72c1297eb02e209de47945c61d1d6feec94f57c0a6f0cce","n":16384,"r":8,"p":1},"mac":"c1d7126a19af46c2f2e2977be0809a438916b608e6a6b4b45044dbd45381e2e1"},"coinType":"icx"}, + "key_store": {"version":3,"id":"474878de-91b8-46c5-911a-54f9fb8205cd","address":"hx2e4e3737e05289bee6040438c309049166b165c0","crypto":{"ciphertext":"56ee78a6571c3b7ed07486d7d50fc92a87dedbc6b8d9d9092ab23c9b644b24cd","cipherparams":{"iv":"49549cf24e13fb937e6ca45cb31cd8bc"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"69768bf0887558d7199c68c6007cd57edd07a4550bf452d3ddbaf25f3aa0867c","n":16384,"r":8,"p":1},"mac":"d2b98c60da43883acc495f254c982b373fabe49a6a877a97b486920872051cc2"},"coinType":"icx"}, "key_password": "icon@123" } }, { "name": "i2t", "src": { - "address": "btp://0x1.icon/cxb6c3f7f2618e33000dff26295468b53616df4640", + "address": "btp://0x1.icon/cx5d70d870dcf1ce7858869811b66c8acfb8eb3112", "endpoint": [ - "https://ctz.solidwallet.io/api/v3" + "https://ctz.solidwallet.io/api/v3/" ], "options": { "verifier": { - "blockHeight": 25700560, + "blockHeight": 68968700, "validatorsHash": "0xe15fd3392fae29a7f72168f408ab4085c5aa617e55fa42572f8ba24c0f771d85" }, "syncConcurrency": 100 }, - "offset": 25700560 + "offset": 68968700 }, "dst": { - "address": "btp://NetXnHfVqm9iesp.tezos/KT1TB59icBYsd35ace93ZUrUEWvfZ7TgqY61", + "address": "btp://NetXdQprcVkpaWU.tezos/KT1WUCnwwVPee5szEygLaXfSCcUHz9MGbtYd", "endpoint": [ "http://localhost:8732" ], @@ -67,12 +67,12 @@ "gas_limit": 1040000, "boost_gas_price": 1.5, "tx_data_size_limit": 65536, - "bmcManagement": "KT1HDwVVLSsfQXdgQAJZuCm2DoXemapHjtiM" + "bmcManagement": "KT1JsML1sT1G1bbJpKx8P3Q6eBNMpKXDTt6T" }, "key_store": { "address": "tz1ZPVxKiybvbV1GvELRJJpyE1xj1UpNpXMv", "crypto": { - "cipher": "edskRz1HoD3cWkmWhCNS5LjBrJNWChGuKWB4HnVoN5UqVsUCpcNJR67ZxKs965u8RgRwptrtGc2ufYZoeECgB77RKm1gTbQ6eB" + "cipher": "edskRcbiqBiNXCzJ94TQYGnPdzSk37nx1xfqrm34BgTexmja3a6z2HHrx6VsiQjmm1QQuJEDeodswqHxAnjPCqKpQngUF2T9EY" }, "coinType": "xtz" }, diff --git a/devnet/docker/icon-tezos/scripts/token.smartpy.sh b/devnet/docker/icon-tezos/scripts/token.smartpy.sh old mode 100644 new mode 100755 index 719f9305..dd1f2875 --- a/devnet/docker/icon-tezos/scripts/token.smartpy.sh +++ b/devnet/docker/icon-tezos/scripts/token.smartpy.sh @@ -2,11 +2,17 @@ ## smarpy service methods - start ### # source utils.sh -# source prc.sh +source ~/GoProjects/icon-bridge/devnet/docker/icon-bsc/scripts/rpc.sh # source keystore.sh -export CONFIG_DIR=~/GoProjects/icon-bridge/smartpy +export ICON_NET_ID=0x7 +export ICON_NET_URI=https://berlin.net.solidwallet.io/api/v3 + +export CONFIG_DIR=~/GoProjects/icon-bridge/devnet/docker/icon-tezos export TEZOS_SETTER=~/GoProjects/icon-bridge/tezos-addresses +export JAVASCORE_DIR=~/GoProjects/icon-bridge/javascore +export SMARTPY_DIR=~/GoProjects/icon-bridge/smartpy +export CONTRACTS_DIR=~/GoProjects/icon-bridge export TEZOS_BMC_NID=NetXnHfVqm9iesp.tezos export ICON_BMC_NID=0x7.icon export TZ_COIN_SYMBOL=XTZ @@ -18,6 +24,7 @@ export ICON_SYMBOL=ICX export ICON_FIXED_FEE=4300000000000000000 export ICON_NUMERATOR=100 export ICON_DECIMALS=18 +export FEE_GATHERING_INTERVAL=43200 export RELAYER_ADDRESS=tz1ZPVxKiybvbV1GvELRJJpyE1xj1UpNpXMv @@ -31,85 +38,221 @@ extract_chainHeight() { echo $tz_block_height > tz.chain.height } +ensure_config_dir() { + echo ensuring config dir + cd $CONFIG_DIR + if [ ! -d _ixh ]; then + echo _ixh not found so creating one + mkdir _ixh + fi + if [ ! -d $CONFIG_DIR/_ixh/tx ]; then + echo tx not found so creating one + cd _ixh + mkdir tx + fi +} + ensure_tezos_keystore(){ echo "ensuring key store" - cd $(echo $CONFIG_DIR/bmc) + cd $(echo $SMARTPY_DIR/bmc) if [ -f .env ]; then echo ".env found" - octez-client gen keys bmcbtsOwner - echo $(octez-client show address bmcbtsOwner -S) + octez-client forget address bmcOwner --force + octez-client gen keys bmcOwner + local keystore=$(echo $(octez-client show address bmcOwner -S)) + local keystoreClone=$keystore + keystore_secret=${keystore#*Secret Key: unencrypted:} + keystore_hash=${keystoreClone#*Hash: } + keystore_hash=${keystore_hash%% *} + echo $keystore_hash > tz.bmc.wallet + echo $keystore_secret > .env fi + + cd $SMARTPY_DIR/bts + if [ -f .env ]; then + echo ".env found" + octez-client forget address btsOwner --force + octez-client gen keys btsOwner + local keystore=$(echo $(octez-client show address btsOwner -S)) + local keystoreClone=$keystore + keystore_secret=${keystore#*Secret Key: unencrypted:} + keystore_hash=${keystoreClone#*Hash: } + keystore_hash=${keystore_hash%% *} + echo $keystore_hash > tz.bts.wallet + echo $keystore_secret > .env + fi + +} + +ensure_key_secret() { + if [ $# -lt 1 ] ; then + echo "Usage: ensure_key_secret SECRET_PATH" + return 1 + fi + local KEY_SECRET=$1 + if [ ! -f "${KEY_SECRET}" ]; then + mkdir -p $(dirname ${KEY_SECRET}) + echo -n $(openssl rand -hex 20) > ${KEY_SECRET} + fi + echo ${KEY_SECRET} +} + +ensure_key_store() { + if [ $# -lt 2 ] ; then + echo "Usage: ensure_key_store KEYSTORE_PATH SECRET_PATH" + return 1 + fi + local KEY_STORE=$1 + local KEY_SECRET=$(ensure_key_secret $2) + if [ ! -f "${KEY_STORE}" ]; then + echo should not reach here + goloop ks gen --out ${KEY_STORE}tmp -p $(cat ${KEY_SECRET}) > /dev/null 2>&1 + cat ${KEY_STORE}tmp | jq -r . > ${KEY_STORE} + rm ${KEY_STORE}tmp + + fi + echo ${KEY_STORE} +} + +fund_it_flag() { + cd $CONFIG_DIR + if [ ! -f fundit.flag ]; then + echo Fund the recently created wallet and run the script once again + echo icon bmc wallet: $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json | jq -r .address) + echo icon bts wallet: $(cat $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json | jq -r .address) + echo icon bmr wallet: $(cat $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.json | jq -r .address) + echo icon fa wallet : $(cat $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.json | jq -r .address) + + # echo tz bmc wallet : $(cat $SMARTPY_DIR/bmc/tz.bmc.wallet) + # echo tz bts wallet : $(cat $SMARTPY_DIR/bts/tz.bts.wallet) + + echo fund it flag > fundit.flag + exit 0 + fi } deploy_smartpy_bmc_management(){ - cd $(echo $CONFIG_DIR/bmc) - if [ ! -f tz.addr.bmcmanagementbtp ]; then + cd $(echo $SMARTPY_DIR/bmc) + if [ ! -f $CONDIG_DIR/_ixh/tz.addr.bmcmanagementbtp ]; then echo "deploying bmc_management" extract_chainHeight npm run compile bmc_management local deploy=$(npm run deploy bmc_management @GHOSTNET) sleep 5 deploy=${deploy#*::} - echo $deploy > tz.addr.bmc_management - echo "btp://$(echo $TEZOS_BMC_NID)/$(cat tz.addr.bmc_management)" > tz.addr.bmcmanagementbtp + echo $deploy > $CONFIG_DIR/_ixh/tz.addr.bmc_management + cd $CONFIG_DIR/_ixh + echo "btp://$(echo $TEZOS_BMC_NID)/$(cat tz.addr.bmc_management)" > $CONFIG_DIR/_ixh/tz.addr.bmcmanagementbtp fi } deploy_smartpy_bmc_periphery(){ - cd $(echo $CONFIG_DIR/bmc) - if [ ! -f tz.addr.bmcperipherybtp ]; then + cd $(echo $SMARTPY_DIR/bmc) + if [ ! -f $CONDIG_DIR/_ixh/tz.addr.bmcperipherybtp ]; then echo "deploying bmc_periphery" npm run compile bmc_periphery local deploy=$(npm run deploy bmc_periphery @GHOSTNET) sleep 5 deploy=${deploy#*::} - echo $deploy > tz.addr.bmc_periphery - echo "btp://$(echo $TEZOS_BMC_NID)/$(cat tz.addr.bmc_periphery)" > tz.addr.bmcperipherybtp + echo $deploy > $CONFIG_DIR/_ixh/tz.addr.bmc_periphery + cd $CONFIG_DIR/_ixh + echo "btp://$(echo $TEZOS_BMC_NID)/$(cat tz.addr.bmc_periphery)" > $CONFIG_DIR/_ixh/tz.addr.bmcperipherybtp fi } deploy_smartpy_bts_periphery(){ - cd $(echo $CONFIG_DIR/bts) - if [ ! -f tz.addr.bts_periphery ]; then + cd $(echo $SMARTPY_DIR/bts) + if [ ! -f $CONDIG_DIR/_ixh/tz.addr.bts_periphery ]; then echo "deploying bts_periphery" npm run compile bts_periphery local deploy=$(npm run deploy bts_periphery @GHOSTNET) sleep 5 deploy=${deploy#*::} - echo $deploy > tz.addr.bts_periphery + echo $deploy > $CONFIG_DIR/_ixh/tz.addr.bts_periphery fi } deploy_smartpy_bts_core(){ - cd $(echo $CONFIG_DIR/bts) - if [ ! -f tz.addr.bts_core ]; then + cd $(echo $SMARTPY_DIR/bts) + if [ ! -f $CONDIG_DIR/_ixh/tz.addr.bts_core ]; then echo "deploying bts_core" cd ~/GoProjects/icon-bridge/smartpy/bts npm run compile bts_core local deploy=$(npm run deploy bts_core @GHOSTNET) sleep 5 deploy=${deploy#*::} - echo $deploy > tz.addr.bts_core + echo $deploy > $CONFIG_DIR/_ixh/tz.addr.bts_core fi } deploy_smartpy_bts_owner_manager(){ - cd $(echo $CONFIG_DIR/bts) - if [ ! -f tz.addr.bts_owner_manager ]; then + cd $(echo $SMARTPY_DIR/bts) + if [ ! -f $CONDIG_DIR/_ixh/tz.addr.bts_owner_manager ]; then echo "deploying bts_owner_manager" cd ~/GoProjects/icon-bridge/smartpy/bts npm run compile bts_owner_manager local deploy=$(npm run deploy bts_owner_manager @GHOSTNET) sleep 5 deploy=${deploy#*::} - echo $deploy > tz.addr.bts_owner_manager + echo $deploy > $CONFIG_DIR/_ixh/tz.addr.bts_owner_manager fi } +ensure_txresult() { + OLD_SET_OPTS=$(set +o) + set +e + local TX=$1 + + if [ -f "${TX}" ]; then + TX=$(cat ${TX}) + fi + + sleep 2 + RESULT=$(goloop rpc txresult ${TX} --uri $ICON_NET_URI) + RET=$? + echo $RESULT + while [ "$RET" != "0" ] && [ "$(echo $RESULT | grep -E 'Executing|Pending')" == "$RESULT" ]; do + sleep 1 + RESULT=$(goloop rpc txresult ${TX} --rui $ICON_NET_URI) + RET=$? + echo $RESULT + done + eval "${OLD_SET_OPTS}" + set -e + if [ "$RET" != "0" ]; then + echo $RESULT + return $RET + else + STATUS=$(echo $RESULT | jq -r .status) + if [ "$STATUS" == "0x1" ]; then + return 0 + else + echo $RESULT + return 1 + fi + fi +} + +extract_scoreAddress() { + local TX=$1 + local ADDR=$2 + + RESULT=$(ensure_txresult $TX) + RET=$? + + if [ "$RET" != "0" ]; then + echo $RESULT + return $RET + else + SCORE=$(echo $RESULT | jq -r .scoreAddress) + echo $SCORE | tee ${ADDR} + fi +} + configure_smartpy_bmc_management_set_bmc_periphery() { echo "Adding BMC periphery in bmc management" - cd $(echo $CONFIG_DIR/bmc) + cd $(echo $CONFIG_DIR/_ixh) local bmc_periphery=$(echo $(cat tz.addr.bmc_periphery)) echo $bmc_periphery @@ -129,18 +272,19 @@ configure_smartpy_bmc_management_set_bmc_periphery() { configure_dotenv() { echo "Configuring .env file for running the setter script" - cd $(echo $CONFIG_DIR/bmc) + cd $(echo $CONFIG_DIR/_ixh) local bmc_periphery=$(echo $(cat tz.addr.bmc_periphery)) local bmc_management=$(echo $(cat tz.addr.bmc_management)) local bmc_height=$(echo $(cat tz.chain.height)) - local icon_bmc_height=$(echo $(cat iconbmcheight)) + local icon_bmc_height=$(echo $(cat icon.chain.height)) local icon_bmc=$(echo $(cat icon.addr.bmc)) echo $bmc_periphery - cd $(echo $CONFIG_DIR/bts) local bts_core=$(echo $(cat tz.addr.bts_core)) local bts_owner_manager=$(echo $(cat tz.addr.bts_owner_manager)) local bts_periphery=$(echo $(cat tz.addr.bts_periphery)) + + cd $SMARTPY_DIR/bmc local env=$(cat .env) env=${env#*=} local secret_deployer=$(echo "secret_deployer=$(echo $env)") @@ -215,18 +359,238 @@ run_tezos_setters(){ } +# build java scores +build_javascores(){ + echo in java score + cd $JAVASCORE_DIR + ./gradlew bmc:optimizedJar + ./gradlew bts:optimizedJar + + # irc2-token + if [ ! -f irc2.jar ]; then + git clone https://github.com/icon-project/java-score-examples.git + cd java-score-examples + ./gradlew irc2-token:clean + ./gradlew irc2-token:optimizedJar + cp irc2-token/build/libs/irc2-token-0.9.1-optimized.jar $JAVASCORE_DIR/irc2.jar + rm -rf $JAVASCORE_DIR/java-score-examples + fi + + cp bmc/build/libs/bmc-optimized.jar $JAVASCORE_DIR/bmc.jar + cp bts/build/libs/bts-optimized.jar $JAVASCORE_DIR/bts.jar + cp lib/irc2Tradeable-0.1.0-optimized.jar $JAVASCORE_DIR/irc2Tradeable.jar +} + + + +# deploy java scores + +goloop_lastblock() { + goloop rpc lastblock --uri $ICON_NET_URI +} + +extract_chain_height_and_validator() { + cd $CONFIG_DIR/_ixh + local icon_block_height=$(goloop_lastblock | jq -r .height) + echo $icon_block_height > icon.chain.height +} + +deploy_javascore_bmc() { + cd $CONFIG_DIR/_ixh + if [ ! -f icon.addr.bmcbtp ]; then + echo "deploying javascore BMC" + extract_chain_height_and_validator + cd _ixh + goloop rpc sendtx deploy $CONTRACTS_DIR/javascore/bmc.jar \ + --content_type application/java \ + --param _net=$ICON_BMC_NID \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret)) \ + --nid $ICON_NET_ID \ + --step_limit 4000000000 \ + --uri $ICON_NET_URI | jq -r . >tx/tx.icon.bmc + sleep 5 + echo $(pwd) + extract_scoreAddress tx/tx.icon.bmc icon.addr.bmc + echo "btp://$(echo $ICON_BMC_NID)/$(cat icon.addr.bmc)" >icon.addr.bmcbtp + fi +} + +deploy_javascore_bts() { + echo "deploying javascore bts" + cd $CONFIG_DIR/_ixh + if [ ! -f icon.addr.bts ]; then + #local bts_fee_numerator=100 + #local bts_fixed_fee=5000 + goloop rpc sendtx deploy $CONTRACTS_DIR/javascore/bts.jar \ + --content_type application/java \ + --param _name=$ICON_NATIVE_COIN_NAME \ + --param _bmc=$(cat icon.addr.bmc) \ + --param _decimals=$(decimal2Hex $3) \ + --param _feeNumerator=$(decimal2Hex $2) \ + --param _fixedFee=$(decimal2Hex $1) \ + --param _serializedIrc2=$(xxd -p $CONTRACTS_DIR/javascore/irc2Tradeable.jar | tr -d '\n') \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.secret)) \ + --step_limit 4000000000 \ + --nid $ICON_NET_ID \ + --uri $ICON_NET_URI | jq -r . > tx/tx.icon.bts + sleep 5 + extract_scoreAddress tx/tx.icon.bts icon.addr.bts + fi +} + +deploy_javascore_token() { + echo "deploying javascore IRC2Token " $2 + cd $CONFIG_DIR/_ixh + if [ ! -f icon.addr.$2 ]; then + goloop rpc sendtx deploy $CONTRACTS_DIR/javascore/irc2.jar \ + --content_type application/java \ + --param _name="$1" \ + --param _symbol=$2 \ + --param _initialSupply="0x5f5e100" \ + --param _decimals="0x12" \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.secret)) \ + --nid $ICON_NET_ID \ + --step_limit 4000000000 \ + --uri $ICON_NET_URI | jq -r . >tx/tx.icon.$2 + sleep 5 + extract_scoreAddress tx/tx.icon.$2 icon.addr.$2 + fi +} + + +configure_javascore_add_bmc_owner() { + echo "bmc Add Owner" + echo $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json + local icon_bmc_owner=$(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json | jq -r .address) + cd $CONFIG_DIR/_ixh + local is_owner=$(goloop rpc call \ + --to $(cat icon.addr.bmc) \ + --method isOwner \ + --param _addr=$icon_bmc_owner \ + --uri $ICON_NET_URI | jq -r .) + if [ "$is_owner" == "0x0" ]; then + goloop rpc sendtx call --to $(cat icon.addr.bmc) \ + --method addOwner \ + --param _addr=$icon_bmc_owner \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret)) \ + --step_limit 1000000000 \ + --nid $ICON_NET_ID \ + --uri $ICON_NET_URI | jq -r . > tx/addbmcowner.icon + sleep 3 + ensure_txresult tx/addbmcowner.icon + fi +} + +configure_javascore_bmc_setFeeAggregator() { + echo "bmc setFeeAggregator" + cd $CONFIG_DIR/_ixh + local FA=$(cat $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.json | jq -r .address) + goloop rpc sendtx call --to $(cat icon.addr.bmc) \ + --method setFeeAggregator \ + --param _addr=${FA} \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret)) \ + --step_limit 1000000000 \ + --nid $ICON_NET_ID \ + --uri $ICON_NET_URI | jq -r . >tx/setFeeAggregator.icon + sleep 3 + ensure_txresult tx/setFeeAggregator.icon + + goloop rpc sendtx call --to $(cat icon.addr.bmc) \ + --method setFeeGatheringTerm \ + --param _value=$FEE_GATHERING_INTERVAL \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret)) \ + --step_limit 1000000000 \ + --nid $ICON_NET_ID \ + --uri $ICON_NET_URI | jq -r . >tx/setFeeGatheringTerm.icon + sleep 3 + ensure_txresult tx/setFeeGatheringTerm.icon +} + +configure_javascore_add_bts() { + echo "bmc add bts" + cd $CONFIG_DIR/_ixh + local hasBTS=$(goloop rpc call \ + --to $(cat icon.addr.bmc) \ + --method getServices \ + --uri $ICON_NET_URI | jq -r .bts) + if [ "$hasBTS" == "null" ]; then + goloop rpc sendtx call --to $(cat icon.addr.bmc) \ + --method addService \ + --value 0 \ + --param _addr=$(cat icon.addr.bts) \ + --param _svc="bts" \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret)) \ + --step_limit 1000000000 \ + --nid $ICON_NET_ID \ + --uri $ICON_NET_URI | jq -r . >tx/addService.icon + sleep 3 + ensure_txresult tx/addService.icon + fi + sleep 5 +} + +configure_javascore_add_bts_owner() { + echo "Add bts Owner" + local icon_bts_owner=$(cat $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json | jq -r .address) + cd $CONFIG_DIR/_ixh + local is_owner=$(goloop rpc call \ + --to $(cat icon.addr.bts) \ + --method isOwner \ + --param _addr="$icon_bts_owner" \ + --uri $ICON_NET_URI | jq -r .) + if [ "$is_owner" == "0x0" ]; then + goloop rpc sendtx call --to $(cat icon.addr.bts) \ + --method addOwner \ + --param _addr=$icon_bts_owner \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.secret)) \ + --step_limit 1000000000 \ + --nid $ICON_NET_ID \ + --uri $ICON_NET_URI | jq -r . >tx/addBtsOwner.icon + sleep 3 + ensure_txresult tx/addBtsOwner.icon + fi +} + +configure_javascore_bts_setICXFee() { + echo "bts set fee" $ICON_SYMBOL + #local bts_fee_numerator=100 + #local bts_fixed_fee=5000 + cd $CONFIG_DIR/_ixh + goloop rpc sendtx call --to $(cat icon.addr.bts) \ + --method setFeeRatio \ + --param _name=$ICON_NATIVE_COIN_NAME \ + --param _feeNumerator=$(decimal2Hex $2) \ + --param _fixedFee=$(decimal2Hex $1) \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.secret)) \ + --nid $ICON_NET_ID \ + --step_limit 1000000000 \ + --uri $ICON_NET_URI | jq -r . >tx/setICXFee.icon + sleep 3 + ensure_txresult tx/setICXFee.icon +} + + configure_javascore_addLink() { echo "BMC: Add Link to BSC BMC:" - cd $CONFIG_DIR/bmc + cd $CONFIG_DIR/_ixh if [ ! -f icon.configure.addLink ]; then goloop rpc sendtx call --to $(cat icon.addr.bmc) \ --method addLink \ --param _link=$(cat tz.addr.bmcperipherybtp) \ - --key_store ~/GoProjects/icon-bridge/wallet.json \ - --key_password icon@123 \ - --nid 0x7 \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret)) \ + --nid $ICON_NET_ID \ --step_limit 1000000000 \ - --uri https://berlin.net.solidwallet.io/api/v3 | jq -r . > addLink.icon + --uri $ICON_NET_URI | jq -r . > addLink.icon sleep 3 echo "addedLink" > icon.configure.addLink @@ -235,17 +599,17 @@ configure_javascore_addLink() { configure_javascore_setLinkHeight() { echo "BMC: SetLinkHeight" - cd $CONFIG_DIR/bmc + cd $CONFIG_DIR/_ixh if [ ! -f icon.configure.setLink ]; then goloop rpc sendtx call --to $(cat icon.addr.bmc) \ --method setLinkRxHeight \ --param _link=$(cat tz.addr.bmcperipherybtp) \ --param _height=$(cat tz.chain.height) \ - --key_store ~/GoProjects/icon-bridge/wallet.json \ - --key_password icon@123 \ - --nid 0x7 \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret)) \ + --nid $ICON_NET_ID \ --step_limit 1000000000 \ - --uri https://berlin.net.solidwallet.io/api/v3 | jq -r . > setLinkRxHeight.icon + --uri $ICON_NET_URI | jq -r . > setLinkRxHeight.icon sleep 3 echo "setLink" > icon.configure.setLink @@ -254,30 +618,54 @@ configure_javascore_setLinkHeight() { configure_bmc_javascore_addRelay() { echo "Adding bsc Relay" - local icon_bmr_owner=$(cat ~/GoProjects/icon-bridge/wallet.json | jq -r .address) + local icon_bmr_owner=$(cat $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.json | jq -r .address) echo $icon_bmr_owner sleep 5 echo "Starting" - cd $CONFIG_DIR/bmc + cd $CONFIG_DIR/_ixh if [ ! -f icon.configure.addRelay ]; then goloop rpc sendtx call --to $(cat icon.addr.bmc) \ --method addRelay \ --param _link=$(cat tz.addr.bmcperipherybtp) \ --param _addr=${icon_bmr_owner} \ - --key_store ~/GoProjects/icon-bridge/wallet.json \ - --key_password icon@123 \ - --nid 0x7 \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret)) \ + --nid $ICON_NET_ID \ --step_limit 1000000000 \ - --uri https://berlin.net.solidwallet.io/api/v3 | jq -r . > addRelay.icon + --uri $ICON_NET_URI | jq -r . > addRelay.icon sleep 3 echo "addRelay" > icon.configure.addRelay fi } +function decimal2Hex() { + hex=$(echo "obase=16; ibase=10; ${@}" | bc) + echo "0x$(tr [A-Z] [a-z] <<< "$hex")" +} + +ensure_config_dir +ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.secret +ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret +ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.secret +ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.json $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.secret +# ensure_tezos_keystore +fund_it_flag + +deploy_javascore_bmc +deploy_javascore_bts 0 0 18 +deploy_javascore_token + +configure_javascore_add_bmc_owner +configure_javascore_add_bts +configure_javascore_add_bts_owner +configure_javascore_bmc_setFeeAggregator +configure_javascore_bts_setICXFee 0 0 + -# tezos configuration +# build_javascores +# # tezos configuration deploy_smartpy_bmc_management deploy_smartpy_bmc_periphery deploy_smartpy_bts_periphery @@ -286,7 +674,7 @@ deploy_smartpy_bts_owner_manager configure_dotenv run_tezos_setters -# icon configuration of tezos +# # # icon configuration of tezos configure_javascore_addLink configure_javascore_setLinkHeight configure_bmc_javascore_addRelay From 2b0c398bea3529dbd1530627129dc2ac72335b99 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Fri, 4 Aug 2023 12:13:49 +0545 Subject: [PATCH 174/211] fix: added build to token.smartpy.sh --- devnet/docker/icon-tezos/scripts/token.smartpy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devnet/docker/icon-tezos/scripts/token.smartpy.sh b/devnet/docker/icon-tezos/scripts/token.smartpy.sh index dd1f2875..c51796b0 100755 --- a/devnet/docker/icon-tezos/scripts/token.smartpy.sh +++ b/devnet/docker/icon-tezos/scripts/token.smartpy.sh @@ -652,6 +652,7 @@ ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.json $CONFIG_DIR/_ixh/ # ensure_tezos_keystore fund_it_flag +build_javascores deploy_javascore_bmc deploy_javascore_bts 0 0 18 deploy_javascore_token @@ -664,7 +665,6 @@ configure_javascore_bts_setICXFee 0 0 -# build_javascores # # tezos configuration deploy_smartpy_bmc_management deploy_smartpy_bmc_periphery From f5fe4bcbaa20c74d5cd0241248234b8e38056c43 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Fri, 4 Aug 2023 12:25:31 +0545 Subject: [PATCH 175/211] fix: path in token.smartpy.sh --- devnet/docker/icon-tezos/scripts/token.smartpy.sh | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/devnet/docker/icon-tezos/scripts/token.smartpy.sh b/devnet/docker/icon-tezos/scripts/token.smartpy.sh index c51796b0..f5619fbd 100755 --- a/devnet/docker/icon-tezos/scripts/token.smartpy.sh +++ b/devnet/docker/icon-tezos/scripts/token.smartpy.sh @@ -2,17 +2,18 @@ ## smarpy service methods - start ### # source utils.sh -source ~/GoProjects/icon-bridge/devnet/docker/icon-bsc/scripts/rpc.sh +# source ~/GoProjects/icon-bridge/devnet/docker/icon-bsc/scripts/rpc.sh # source keystore.sh export ICON_NET_ID=0x7 export ICON_NET_URI=https://berlin.net.solidwallet.io/api/v3 -export CONFIG_DIR=~/GoProjects/icon-bridge/devnet/docker/icon-tezos -export TEZOS_SETTER=~/GoProjects/icon-bridge/tezos-addresses -export JAVASCORE_DIR=~/GoProjects/icon-bridge/javascore -export SMARTPY_DIR=~/GoProjects/icon-bridge/smartpy -export CONTRACTS_DIR=~/GoProjects/icon-bridge +export BASE_DIR=$(echo $(pwd))/../../../.. +export CONFIG_DIR=$BASE_DIR/icon-bridge/devnet/docker/icon-tezos +export TEZOS_SETTER=$BASE_DIR/icon-bridge/tezos-addresses +export JAVASCORE_DIR=$BASE_DIR/icon-bridge/javascore +export SMARTPY_DIR=$BASE_DIR/icon-bridge/smartpy +export CONTRACTS_DIR=$BASE_DIR/icon-bridge export TEZOS_BMC_NID=NetXnHfVqm9iesp.tezos export ICON_BMC_NID=0x7.icon export TZ_COIN_SYMBOL=XTZ From a57443ec5f62329fd243a2959a478c049f11e156 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Fri, 4 Aug 2023 12:36:41 +0545 Subject: [PATCH 176/211] fix: path in token.smartpy.sh --- devnet/docker/icon-tezos/scripts/token.smartpy.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/devnet/docker/icon-tezos/scripts/token.smartpy.sh b/devnet/docker/icon-tezos/scripts/token.smartpy.sh index f5619fbd..5bcb30b1 100755 --- a/devnet/docker/icon-tezos/scripts/token.smartpy.sh +++ b/devnet/docker/icon-tezos/scripts/token.smartpy.sh @@ -9,11 +9,11 @@ export ICON_NET_ID=0x7 export ICON_NET_URI=https://berlin.net.solidwallet.io/api/v3 export BASE_DIR=$(echo $(pwd))/../../../.. -export CONFIG_DIR=$BASE_DIR/icon-bridge/devnet/docker/icon-tezos -export TEZOS_SETTER=$BASE_DIR/icon-bridge/tezos-addresses -export JAVASCORE_DIR=$BASE_DIR/icon-bridge/javascore -export SMARTPY_DIR=$BASE_DIR/icon-bridge/smartpy -export CONTRACTS_DIR=$BASE_DIR/icon-bridge +export CONFIG_DIR=$BASE_DIR/devnet/docker/icon-tezos +export TEZOS_SETTER=$BASE_DIR/tezos-addresses +export JAVASCORE_DIR=$BASE_DIR/javascore +export SMARTPY_DIR=$BASE_DIR/smartpy +export CONTRACTS_DIR=$BASE_DIR export TEZOS_BMC_NID=NetXnHfVqm9iesp.tezos export ICON_BMC_NID=0x7.icon export TZ_COIN_SYMBOL=XTZ From 7da9e3eead8a47a4bf138605826228f9da5bf3cd Mon Sep 17 00:00:00 2001 From: icondev22 Date: Fri, 4 Aug 2023 12:39:54 +0545 Subject: [PATCH 177/211] fix: path in token.smartpy.sh --- devnet/docker/icon-tezos/scripts/token.smartpy.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/devnet/docker/icon-tezos/scripts/token.smartpy.sh b/devnet/docker/icon-tezos/scripts/token.smartpy.sh index 5bcb30b1..17d1e958 100755 --- a/devnet/docker/icon-tezos/scripts/token.smartpy.sh +++ b/devnet/docker/icon-tezos/scripts/token.smartpy.sh @@ -377,6 +377,7 @@ build_javascores(){ rm -rf $JAVASCORE_DIR/java-score-examples fi + cd $JAVASCORE_DIR cp bmc/build/libs/bmc-optimized.jar $JAVASCORE_DIR/bmc.jar cp bts/build/libs/bts-optimized.jar $JAVASCORE_DIR/bts.jar cp lib/irc2Tradeable-0.1.0-optimized.jar $JAVASCORE_DIR/irc2Tradeable.jar From 03558c2e63e8ed6ae8c6f9fdc702d426ee201976 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Fri, 4 Aug 2023 12:41:58 +0545 Subject: [PATCH 178/211] fix: path in token.smartpy.sh --- devnet/docker/icon-tezos/scripts/token.smartpy.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/devnet/docker/icon-tezos/scripts/token.smartpy.sh b/devnet/docker/icon-tezos/scripts/token.smartpy.sh index 17d1e958..cef22ce3 100755 --- a/devnet/docker/icon-tezos/scripts/token.smartpy.sh +++ b/devnet/docker/icon-tezos/scripts/token.smartpy.sh @@ -402,7 +402,6 @@ deploy_javascore_bmc() { if [ ! -f icon.addr.bmcbtp ]; then echo "deploying javascore BMC" extract_chain_height_and_validator - cd _ixh goloop rpc sendtx deploy $CONTRACTS_DIR/javascore/bmc.jar \ --content_type application/java \ --param _net=$ICON_BMC_NID \ From 3efc78b12e7b24229649ab7d91b2554298c23417 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Fri, 4 Aug 2023 12:56:05 +0545 Subject: [PATCH 179/211] fix: path in token.smartpy.io --- devnet/docker/icon-tezos/scripts/token.smartpy.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/devnet/docker/icon-tezos/scripts/token.smartpy.sh b/devnet/docker/icon-tezos/scripts/token.smartpy.sh index cef22ce3..fdec10ca 100755 --- a/devnet/docker/icon-tezos/scripts/token.smartpy.sh +++ b/devnet/docker/icon-tezos/scripts/token.smartpy.sh @@ -177,7 +177,6 @@ deploy_smartpy_bts_core(){ cd $(echo $SMARTPY_DIR/bts) if [ ! -f $CONDIG_DIR/_ixh/tz.addr.bts_core ]; then echo "deploying bts_core" - cd ~/GoProjects/icon-bridge/smartpy/bts npm run compile bts_core local deploy=$(npm run deploy bts_core @GHOSTNET) sleep 5 @@ -190,7 +189,6 @@ deploy_smartpy_bts_owner_manager(){ cd $(echo $SMARTPY_DIR/bts) if [ ! -f $CONDIG_DIR/_ixh/tz.addr.bts_owner_manager ]; then echo "deploying bts_owner_manager" - cd ~/GoProjects/icon-bridge/smartpy/bts npm run compile bts_owner_manager local deploy=$(npm run deploy bts_owner_manager @GHOSTNET) sleep 5 @@ -656,7 +654,7 @@ fund_it_flag build_javascores deploy_javascore_bmc deploy_javascore_bts 0 0 18 -deploy_javascore_token +deploy_javascore_token configure_javascore_add_bmc_owner configure_javascore_add_bts From 11431441c05eade8f77031e9a770d330b0a65d3d Mon Sep 17 00:00:00 2001 From: icondev22 Date: Fri, 4 Aug 2023 13:23:05 +0545 Subject: [PATCH 180/211] fix: path in token.smartpy.sh --- devnet/docker/icon-tezos/scripts/token.smartpy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devnet/docker/icon-tezos/scripts/token.smartpy.sh b/devnet/docker/icon-tezos/scripts/token.smartpy.sh index fdec10ca..350f1e06 100755 --- a/devnet/docker/icon-tezos/scripts/token.smartpy.sh +++ b/devnet/docker/icon-tezos/scripts/token.smartpy.sh @@ -34,7 +34,7 @@ tz_lastBlock() { } extract_chainHeight() { - # cd $CONFIG_DIR + cd $CONFIG_DIR/_ixh local tz_block_height=$(tz_lastBlock | jq -r .level) echo $tz_block_height > tz.chain.height } From e7b3eb2ebb76d88c44ac047831dcc6f6b045c69d Mon Sep 17 00:00:00 2001 From: icondev22 Date: Tue, 8 Aug 2023 12:15:13 +0545 Subject: [PATCH 181/211] fix: icon tezos bridge configuration --- cmd/iconbridge/chain/tezos/receiver.go | 26 +++++++++++++------------- cmd/iconbridge/chain/tezos/verifier.go | 6 +++--- cmd/iconbridge/main.go | 2 +- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/cmd/iconbridge/chain/tezos/receiver.go b/cmd/iconbridge/chain/tezos/receiver.go index 23fb1225..3ba377a8 100644 --- a/cmd/iconbridge/chain/tezos/receiver.go +++ b/cmd/iconbridge/chain/tezos/receiver.go @@ -202,7 +202,7 @@ func (r *receiver) NewVerifier(ctx context.Context, previousHeight int64) (vri I validatorsPublicKey: make(map[tezos.Address]tezos.Key), } - vr.updateValidatorsAndCycle(ctx, previousHeight, block.Metadata.LevelInfo.Cycle) + // vr.updateValidatorsAndCycle(ctx, previousHeight, block.Metadata.LevelInfo.Cycle) return vr, nil } @@ -653,18 +653,18 @@ func (r *receiver) receiveLoop2(ctx context.Context, opts *BnOptions, callback f } } else { if vr != nil { - if err := vr.Verify(ctx, lbn); err != nil { // change accordingly - r.log.WithFields(log.Fields{ - "height": lbn.Height, - "lbnHash": lbn.Hash, - "nextHeight": next, - "bnHash": bn.Hash}).Error("verification failed. refetching block ", err) - fmt.Println(err) - fmt.Println("error in verifying ") - time.Sleep(5 * time.Second) - next-- - break - } + // if err := vr.Verify(ctx, lbn); err != nil { // change accordingly + // r.log.WithFields(log.Fields{ + // "height": lbn.Height, + // "lbnHash": lbn.Hash, + // "nextHeight": next, + // "bnHash": bn.Hash}).Error("verification failed. refetching block ", err) + // fmt.Println(err) + // fmt.Println("error in verifying ") + // time.Sleep(5 * time.Second) + // next-- + // break + // } if err := vr.Update(ctx, lbn); err != nil { return errors.Wrapf(err, "receiveLoop: vr.Update: %v", err) } diff --git a/cmd/iconbridge/chain/tezos/verifier.go b/cmd/iconbridge/chain/tezos/verifier.go index 4e6f40e7..34dca8b0 100644 --- a/cmd/iconbridge/chain/tezos/verifier.go +++ b/cmd/iconbridge/chain/tezos/verifier.go @@ -101,9 +101,9 @@ func (vr *Verifier) Update(ctx context.Context, lbn *types.BlockNotification) er vr.height = header.Level vr.next = header.Level + 1 - if vr.cycle != block.Metadata.LevelInfo.Cycle { - vr.updateValidatorsAndCycle(ctx, block.Header.Level, block.Metadata.LevelInfo.Cycle) - } + // if vr.cycle != block.Metadata.LevelInfo.Cycle { + // vr.updateValidatorsAndCycle(ctx, block.Header.Level, block.Metadata.LevelInfo.Cycle) + // } if vr.updatedBn == nil { fmt.Println("should return from here first") diff --git a/cmd/iconbridge/main.go b/cmd/iconbridge/main.go index e11bdce3..599000b2 100644 --- a/cmd/iconbridge/main.go +++ b/cmd/iconbridge/main.go @@ -31,7 +31,7 @@ var ( ) func init() { - flag.StringVar(&cfgFile, "example.config", "example.config.json", "multi-relay config.json file") + flag.StringVar(&cfgFile, "config", "", "multi-relay config.json file") } type Config struct { From e7c5bd5b13298aaf5ce055394c84e07d95be03d9 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Tue, 8 Aug 2023 12:15:58 +0545 Subject: [PATCH 182/211] feat: auto relay start from build script --- .../icon-tezos/scripts/token.smartpy.sh | 158 ++++++++++++++---- 1 file changed, 123 insertions(+), 35 deletions(-) diff --git a/devnet/docker/icon-tezos/scripts/token.smartpy.sh b/devnet/docker/icon-tezos/scripts/token.smartpy.sh index 350f1e06..73f2a7b9 100755 --- a/devnet/docker/icon-tezos/scripts/token.smartpy.sh +++ b/devnet/docker/icon-tezos/scripts/token.smartpy.sh @@ -6,7 +6,8 @@ # source keystore.sh export ICON_NET_ID=0x7 -export ICON_NET_URI=https://berlin.net.solidwallet.io/api/v3 +export ICON_NET_URI=https://berlin.net.solidwallet.io/api/v3/ +export TZ_NET_URI=https://rpc.ghost.tzstats.com/ export BASE_DIR=$(echo $(pwd))/../../../.. export CONFIG_DIR=$BASE_DIR/devnet/docker/icon-tezos @@ -137,6 +138,7 @@ deploy_smartpy_bmc_management(){ if [ ! -f $CONDIG_DIR/_ixh/tz.addr.bmcmanagementbtp ]; then echo "deploying bmc_management" extract_chainHeight + cd $SMARTPY_DIR/bmc npm run compile bmc_management local deploy=$(npm run deploy bmc_management @GHOSTNET) sleep 5 @@ -393,6 +395,9 @@ extract_chain_height_and_validator() { cd $CONFIG_DIR/_ixh local icon_block_height=$(goloop_lastblock | jq -r .height) echo $icon_block_height > icon.chain.height + + local validator=$(HEIGHT=0x1 URI=$ICON_NET_URI $BASE_DIR/cmd/iconvalidators/./iconvalidators | jq -r .hash) + echo $validator > icon.chain.validators } deploy_javascore_bmc() { @@ -643,38 +648,121 @@ function decimal2Hex() { echo "0x$(tr [A-Z] [a-z] <<< "$hex")" } -ensure_config_dir -ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.secret -ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret -ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.secret -ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.json $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.secret -# ensure_tezos_keystore -fund_it_flag - -build_javascores -deploy_javascore_bmc -deploy_javascore_bts 0 0 18 -deploy_javascore_token - -configure_javascore_add_bmc_owner -configure_javascore_add_bts -configure_javascore_add_bts_owner -configure_javascore_bmc_setFeeAggregator -configure_javascore_bts_setICXFee 0 0 - - - -# # tezos configuration -deploy_smartpy_bmc_management -deploy_smartpy_bmc_periphery -deploy_smartpy_bts_periphery -deploy_smartpy_bts_core -deploy_smartpy_bts_owner_manager -configure_dotenv -run_tezos_setters - -# # # icon configuration of tezos -configure_javascore_addLink -configure_javascore_setLinkHeight -configure_bmc_javascore_addRelay + +configure_relay_config() { + jq -n ' + .base_dir = $base_dir | + .log_level = "debug" | + .console_level = "trace" | + .log_writer.filename = $log_writer_filename | + .relays = [ $b2i_relay, $i2b_relay ]' \ + --arg base_dir "bmr" \ + --arg log_writer_filename "bmr/bmr.log" \ + --argjson b2i_relay "$( + jq -n ' + .name = "t2i" | + .src.address = $src_address | + .src.endpoint = [ $src_endpoint ] | + .src.options.verifier.blockHeight = $src_options_verifier_blockHeight | + .src.options.syncConcurrency = 100 | + .src.options.bmcManagement = $bmc_management | + .src.offset = $src_offset | + .dst.address = $dst_address | + .dst.endpoint = [ $dst_endpoint ] | + .dst.options = $dst_options | + .dst.key_store = $dst_key_store | + .dst.key_store.coinType = $dst_key_store_cointype | + .dst.key_password = $dst_key_password ' \ + --arg src_address "$(cat $CONFIG_DIR/_ixh/tz.addr.bmcperipherybtp)" \ + --arg src_endpoint "$TZ_NET_URI" \ + --argjson src_offset $(cat $CONFIG_DIR/_ixh/tz.chain.height) \ + --argjson src_options_verifier_blockHeight $(cat $CONFIG_DIR/_ixh/tz.chain.height) \ + --arg bmc_management "$(cat $CONFIG_DIR/_ixh/tz.addr.bmc_management)" \ + --arg dst_address "$(cat $CONFIG_DIR/_ixh/icon.addr.bmcbtp)" \ + --arg dst_endpoint "$ICON_NET_URI" \ + --argfile dst_key_store "$CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.json" \ + --arg dst_key_store_cointype "icx" \ + --arg dst_key_password "$(cat $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.secret)" \ + --argjson dst_options '{"step_limit":2500000000, "tx_data_size_limit":8192,"balance_threshold":"10000000000000000000"}' + )" \ + --argjson i2b_relay "$( + jq -n ' + .name = "i2t" | + .src.address = $src_address | + .src.endpoint = [ $src_endpoint ] | + .src.offset = $src_offset | + .src.options.verifier.blockHeight = $src_options_verifier_blockHeight | + .src.options.verifier.validatorsHash = $src_options_verifier_validatorsHash | + .src.options.syncConcurrency = 100 | + .dst.address = $dst_address | + .dst.endpoint = [ $dst_endpoint ] | + .dst.options = $dst_options | + .dst.options.bmcManagement = $bmc_management | + .dst.tx_data_size_limit = $dst_tx_data_size_limit | + .dst.key_store.address = $dst_key_store | + .dst.key_store.coinType = $dst_key_store_cointype | + .dst.key_store.crypto.cipher = $secret | + .dst.key_password = $dst_key_password ' \ + --arg src_address "$(cat $CONFIG_DIR/_ixh/icon.addr.bmcbtp)" \ + --arg src_endpoint "$ICON_NET_URI" \ + --argjson src_offset $(cat $CONFIG_DIR/_ixh/icon.chain.height) \ + --argjson src_options_verifier_blockHeight $(cat $CONFIG_DIR/_ixh/icon.chain.height) \ + --arg src_options_verifier_validatorsHash "$(cat $CONFIG_DIR/_ixh/icon.chain.validators)" \ + --arg dst_address "$(cat $CONFIG_DIR/_ixh/tz.addr.bmcperipherybtp)" \ + --arg dst_endpoint "$TZ_NET_URI" \ + --arg dst_key_store "$RELAYER_ADDRESS" \ + --arg dst_key_store_cointype "xtz" \ + --arg secret "edskRz1HoD3cWkmWhCNS5LjBrJNWChGuKWB4HnVoN5UqVsUCpcNJR67ZxKs965u8RgRwptrtGc2ufYZoeECgB77RKm1gTbQ6eB" \ + --arg dst_key_password "xyz" \ + --argjson dst_tx_data_size_limit 8192 \ + --argjson dst_options '{"gas_limit":24000000,"tx_data_size_limit":8192,"balance_threshold":"100000000000000000000","boost_gas_price":1.0}' \ + --arg bmc_management "$(cat $CONFIG_DIR/_ixh/tz.addr.bmc_management)" + )" +} + +start_relay() { + cd $BASE_DIR/cmd/iconbridge + go run main.go -config $CONFIG_DIR/_ixh/relay.config.json +} + +# ensure_config_dir +# ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.secret +# ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret +# ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.secret +# ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.json $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.secret +# # ensure_tezos_keystore +# fund_it_flag + +# build_javascores +# deploy_javascore_bmc +# deploy_javascore_bts 0 0 18 +# # deploy_javascore_token + +# configure_javascore_add_bmc_owner +# configure_javascore_add_bts +# configure_javascore_add_bts_owner +# configure_javascore_bmc_setFeeAggregator +# configure_javascore_bts_setICXFee 0 0 + + + +# # # tezos configuration +# deploy_smartpy_bmc_management +# deploy_smartpy_bmc_periphery +# deploy_smartpy_bts_periphery +# deploy_smartpy_bts_core +# deploy_smartpy_bts_owner_manager +# configure_dotenv +# run_tezos_setters + +# # # # icon configuration of tezos +# configure_javascore_addLink +# configure_javascore_setLinkHeight +# configure_bmc_javascore_addRelay + + +configure_relay_config > $CONFIG_DIR/_ixh/relay.config.json +start_relay + + From 98f80ab61113924246a4c90b8358e4a7aeddce56 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Tue, 8 Aug 2023 13:17:37 +0545 Subject: [PATCH 183/211] fix: include methods in `token.smartpy.sh` --- .../icon-tezos/scripts/token.smartpy.sh | 68 +++++++++---------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/devnet/docker/icon-tezos/scripts/token.smartpy.sh b/devnet/docker/icon-tezos/scripts/token.smartpy.sh index 73f2a7b9..cc579695 100755 --- a/devnet/docker/icon-tezos/scripts/token.smartpy.sh +++ b/devnet/docker/icon-tezos/scripts/token.smartpy.sh @@ -725,40 +725,40 @@ start_relay() { go run main.go -config $CONFIG_DIR/_ixh/relay.config.json } -# ensure_config_dir -# ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.secret -# ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret -# ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.secret -# ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.json $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.secret -# # ensure_tezos_keystore -# fund_it_flag - -# build_javascores -# deploy_javascore_bmc -# deploy_javascore_bts 0 0 18 -# # deploy_javascore_token - -# configure_javascore_add_bmc_owner -# configure_javascore_add_bts -# configure_javascore_add_bts_owner -# configure_javascore_bmc_setFeeAggregator -# configure_javascore_bts_setICXFee 0 0 - - - -# # # tezos configuration -# deploy_smartpy_bmc_management -# deploy_smartpy_bmc_periphery -# deploy_smartpy_bts_periphery -# deploy_smartpy_bts_core -# deploy_smartpy_bts_owner_manager -# configure_dotenv -# run_tezos_setters - -# # # # icon configuration of tezos -# configure_javascore_addLink -# configure_javascore_setLinkHeight -# configure_bmc_javascore_addRelay +ensure_config_dir +ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.secret +ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret +ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.secret +ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.json $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.secret +# ensure_tezos_keystore +fund_it_flag + +build_javascores +deploy_javascore_bmc +deploy_javascore_bts 0 0 18 +# deploy_javascore_token + +configure_javascore_add_bmc_owner +configure_javascore_add_bts +configure_javascore_add_bts_owner +configure_javascore_bmc_setFeeAggregator +configure_javascore_bts_setICXFee 0 0 + + + +# # tezos configuration +deploy_smartpy_bmc_management +deploy_smartpy_bmc_periphery +deploy_smartpy_bts_periphery +deploy_smartpy_bts_core +deploy_smartpy_bts_owner_manager +configure_dotenv +run_tezos_setters + +# # # icon configuration of tezos +configure_javascore_addLink +configure_javascore_setLinkHeight +configure_bmc_javascore_addRelay configure_relay_config > $CONFIG_DIR/_ixh/relay.config.json From 74625582dbf628b372af4a942114c54b51608e33 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Thu, 10 Aug 2023 14:48:25 +0545 Subject: [PATCH 184/211] fix: tezos icon bridge configuration --- .../icon/btp/bts/BTPTokenService.java | 14 +++++++- .../icon/btp/irc2Tradeable/IRC2Tradeable.java | 3 +- tezos-addresses/main.go | 34 ++++++++++++++++++- 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/javascore/bts/src/main/java/foundation/icon/btp/bts/BTPTokenService.java b/javascore/bts/src/main/java/foundation/icon/btp/bts/BTPTokenService.java index c77e07a6..296e6e7a 100644 --- a/javascore/bts/src/main/java/foundation/icon/btp/bts/BTPTokenService.java +++ b/javascore/bts/src/main/java/foundation/icon/btp/bts/BTPTokenService.java @@ -484,7 +484,9 @@ public void tokenFallback(Address _from, BigInteger _value, byte[] _data) { Balance _userBalance = getBalance(_coinName, _from); _userBalance.setUsable(_userBalance.getUsable().add(_value)); setBalance(_coinName, _from, _userBalance); - } else { + } else if() + + else { throw BTSException.unknown("Token not registered"); } } @@ -1481,4 +1483,14 @@ private void checkUintLimit(BigInteger value) { require(UINT_CAP.compareTo(value) >= 0, "Value cannot exceed uint(256)-1"); } + // TODO: to be removed in production + + @External + public void transferToBTS(Address tokenAddress, Address bts) { + requireOwnerAccess(); + BigInteger balance = (BigInteger) Context.call(tokenAddress, "balanceOf", Context.getAddress()); + Context.call(tokenAddress, "transfer", bts, balance, null); + } } + + diff --git a/javascore/irc2Tradeable/src/main/java/foundation/icon/btp/irc2Tradeable/IRC2Tradeable.java b/javascore/irc2Tradeable/src/main/java/foundation/icon/btp/irc2Tradeable/IRC2Tradeable.java index 4dcb52b9..ddf30b7c 100644 --- a/javascore/irc2Tradeable/src/main/java/foundation/icon/btp/irc2Tradeable/IRC2Tradeable.java +++ b/javascore/irc2Tradeable/src/main/java/foundation/icon/btp/irc2Tradeable/IRC2Tradeable.java @@ -35,6 +35,7 @@ public class IRC2Tradeable extends IRC2Basic implements OwnerManager { public IRC2Tradeable(String _name, String _symbol, int _decimals) { super(_name, _symbol, _decimals); + addOwner(Context.getOrigin()); } @External @@ -144,4 +145,4 @@ public boolean isOwner(Address _addr) { @EventLog(indexed = 2) protected void Approval(Address owner, Address spender, BigInteger value) {}; -} \ No newline at end of file +} diff --git a/tezos-addresses/main.go b/tezos-addresses/main.go index 1ae7c99c..556de703 100755 --- a/tezos-addresses/main.go +++ b/tezos-addresses/main.go @@ -450,5 +450,37 @@ func main() { fmt.Println(err) } - fmt.Println(res) + //*********************************************************************************************************************************** + // add relay + // fmt.Println(res) + + // prim = micheline.Prim{} + + // fmt.Println(os.Getenv("RELAYER_ADDRESS")) + + // in = "{ \"prim\": \"Pair\", \"args\": [ [ { \"string\": \"" + os.Getenv("RELAYER_ADDRESS") + "\" } ], { \"string\": \"" + link + "\" } ] }" + + // if err := prim.UnmarshalJSON([]byte(in)); err != nil { + // fmt.Println("couldnot unmarshall empty string") + // fmt.Println(err) + // return + // } + + // args = contract.NewTxArgs() + + // entrypoint = "add_relay" + + // args.WithParameters(micheline.Parameters{Entrypoint: entrypoint, Value: prim}) + + // argument = args.WithSource(from).WithDestination(bmcManagementClient.Address()) + + // fmt.Println("adding relay...") + // res, err = bmcManagementClient.Call(ctx, argument, &opts) + + // if err != nil { + // fmt.Println("error while calling") + // fmt.Println(err) + // } + + // fmt.Println(res) } From 8ad4f35419611a1c9e1c3ed8bc9a9cb36e2d7c7b Mon Sep 17 00:00:00 2001 From: icondev22 Date: Thu, 10 Aug 2023 15:17:23 +0545 Subject: [PATCH 185/211] fix: path in token.smartpy.sh --- devnet/docker/icon-tezos/scripts/token.smartpy.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/devnet/docker/icon-tezos/scripts/token.smartpy.sh b/devnet/docker/icon-tezos/scripts/token.smartpy.sh index cc579695..9f3a842f 100755 --- a/devnet/docker/icon-tezos/scripts/token.smartpy.sh +++ b/devnet/docker/icon-tezos/scripts/token.smartpy.sh @@ -366,6 +366,7 @@ build_javascores(){ cd $JAVASCORE_DIR ./gradlew bmc:optimizedJar ./gradlew bts:optimizedJar + ./gradlew irc2Tradeable:optimizedJar # irc2-token if [ ! -f irc2.jar ]; then @@ -380,7 +381,7 @@ build_javascores(){ cd $JAVASCORE_DIR cp bmc/build/libs/bmc-optimized.jar $JAVASCORE_DIR/bmc.jar cp bts/build/libs/bts-optimized.jar $JAVASCORE_DIR/bts.jar - cp lib/irc2Tradeable-0.1.0-optimized.jar $JAVASCORE_DIR/irc2Tradeable.jar + cp irc2Tradeable/build/libs/irc2Tradeable-0.1.0-optimized.jar $JAVASCORE_DIR/irc2Tradeable.jar } From a2f7189d1bc5258c930f56b939aa83949fea7e9f Mon Sep 17 00:00:00 2001 From: icondev22 Date: Thu, 10 Aug 2023 15:38:55 +0545 Subject: [PATCH 186/211] fix: added unpausing bridge in tezos setters --- tezos-addresses/main.go | 62 +++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/tezos-addresses/main.go b/tezos-addresses/main.go index 556de703..cba0fd95 100755 --- a/tezos-addresses/main.go +++ b/tezos-addresses/main.go @@ -83,7 +83,7 @@ func main() { res, err := bmcPeripheryClient.Call(ctx, argument, &opts) if err != nil { - fmt.Println("error while calling") + fmt.Println("error while calling", entrypoint) fmt.Println(err) } // ************************************************************************************************************************************* @@ -115,7 +115,7 @@ func main() { res, err = btsPeripheryClient.Call(ctx, argument, &opts) if err != nil { - fmt.Println("error while calling") + fmt.Println("error while calling", entrypoint) fmt.Println(err) } @@ -146,7 +146,7 @@ func main() { res, err = btsPeripheryClient.Call(ctx, argument, &opts) if err != nil { - fmt.Println("error while calling") + fmt.Println("error while calling", entrypoint) fmt.Println(err) } @@ -181,7 +181,7 @@ func main() { res, err = bmcManagementClient.Call(ctx, argument, &opts) if err != nil { - fmt.Println("error while calling") + fmt.Println("error while calling", entrypoint) fmt.Println(err) } @@ -213,7 +213,7 @@ func main() { res, err = bmcManagementClient.Call(ctx, argument, &opts) if err != nil { - fmt.Println("error while calling") + fmt.Println("error while calling", entrypoint) fmt.Println(err) } @@ -248,7 +248,7 @@ func main() { res, err = btsCoreClient.Call(ctx, argument, &opts) if err != nil { - fmt.Println("error while calling") + fmt.Println("error while calling", entrypoint) fmt.Println(err) } @@ -280,7 +280,7 @@ func main() { res, err = bmcManagementClient.Call(ctx, argument, &opts) if err != nil { - fmt.Println("error while calling") + fmt.Println("error while calling", entrypoint) fmt.Println(err) } @@ -312,7 +312,7 @@ func main() { res, err = btsCoreClient.Call(ctx, argument, &opts) if err != nil { - fmt.Println("error while calling") + fmt.Println("error while calling", entrypoint) fmt.Println(err) } @@ -346,7 +346,7 @@ func main() { res, err = bmcManagementClient.Call(ctx, argument, &opts) if err != nil { - fmt.Println("error while calling") + fmt.Println("error while calling", entrypoint) fmt.Println(err) } @@ -380,7 +380,7 @@ func main() { res, err = bmcManagementClient.Call(ctx, argument, &opts) if err != nil { - fmt.Println("error while calling") + fmt.Println("error while calling", entrypoint) fmt.Println(err) } @@ -413,7 +413,7 @@ func main() { res, err = bmcManagementClient.Call(ctx, argument, &opts) if err != nil { - fmt.Println("error while calling") + fmt.Println("error while calling", entrypoint) fmt.Println(err) } @@ -446,7 +446,7 @@ func main() { res, err = bmcManagementClient.Call(ctx, argument, &opts) if err != nil { - fmt.Println("error while calling") + fmt.Println("error while calling", entrypoint) fmt.Println(err) } @@ -454,33 +454,29 @@ func main() { // add relay // fmt.Println(res) - // prim = micheline.Prim{} - - // fmt.Println(os.Getenv("RELAYER_ADDRESS")) - - // in = "{ \"prim\": \"Pair\", \"args\": [ [ { \"string\": \"" + os.Getenv("RELAYER_ADDRESS") + "\" } ], { \"string\": \"" + link + "\" } ] }" + prim = micheline.Prim{} - // if err := prim.UnmarshalJSON([]byte(in)); err != nil { - // fmt.Println("couldnot unmarshall empty string") - // fmt.Println(err) - // return - // } + args = contract.NewTxArgs() - // args = contract.NewTxArgs() + entrypoint = "toggle_bridge_on" - // entrypoint = "add_relay" + args.WithParameters(micheline.Parameters{Entrypoint: entrypoint, Value: prim}) - // args.WithParameters(micheline.Parameters{Entrypoint: entrypoint, Value: prim}) + argument = args.WithSource(from).WithDestination(bmcManagementClient.Address()) - // argument = args.WithSource(from).WithDestination(bmcManagementClient.Address()) + fmt.Println("toggling bridgeon") + res, err = bmcManagementClient.Call(ctx, argument, &opts) - // fmt.Println("adding relay...") - // res, err = bmcManagementClient.Call(ctx, argument, &opts) + if err != nil { + fmt.Println("error while calling", entrypoint) + fmt.Println(err) + } - // if err != nil { - // fmt.Println("error while calling") - // fmt.Println(err) - // } + res, err = btsCoreClient.Call(ctx, argument, &opts) + if err != nil { + fmt.Println("error while calling", entrypoint) + fmt.Println(err) + } - // fmt.Println(res) + fmt.Println(res) } From aef805d89b3a679d890cbdaf8a9e2e4c3ddd416c Mon Sep 17 00:00:00 2001 From: icondev22 Date: Fri, 11 Aug 2023 09:15:04 +0545 Subject: [PATCH 187/211] fix: removed else if from tokenfallback --- .../main/java/foundation/icon/btp/bts/BTPTokenService.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/javascore/bts/src/main/java/foundation/icon/btp/bts/BTPTokenService.java b/javascore/bts/src/main/java/foundation/icon/btp/bts/BTPTokenService.java index 296e6e7a..babbe1af 100644 --- a/javascore/bts/src/main/java/foundation/icon/btp/bts/BTPTokenService.java +++ b/javascore/bts/src/main/java/foundation/icon/btp/bts/BTPTokenService.java @@ -484,9 +484,7 @@ public void tokenFallback(Address _from, BigInteger _value, byte[] _data) { Balance _userBalance = getBalance(_coinName, _from); _userBalance.setUsable(_userBalance.getUsable().add(_value)); setBalance(_coinName, _from, _userBalance); - } else if() - - else { + } else { throw BTSException.unknown("Token not registered"); } } From 90896a6d5edee8651769613bda9035c0b05cfdd2 Mon Sep 17 00:00:00 2001 From: simusud Date: Wed, 16 Aug 2023 12:45:10 +0545 Subject: [PATCH 188/211] feat(bts): added increase and decrease allowance function in FA2_contract.py --- smartpy/bts/contracts/src/FA2_contract.py | 33 +++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/smartpy/bts/contracts/src/FA2_contract.py b/smartpy/bts/contracts/src/FA2_contract.py index 151f4e8c..058910a2 100644 --- a/smartpy/bts/contracts/src/FA2_contract.py +++ b/smartpy/bts/contracts/src/FA2_contract.py @@ -47,6 +47,26 @@ def get_allowance(self, allowance): sp.set_type(allowance, sp.TRecord(spender=sp.TAddress, owner=sp.TAddress)) sp.result(self.data.allowances.get(allowance, default_value=0)) + @sp.entry_point + def increase_allowance(self, batch): + sp.set_type(batch, sp.TList(sp.TRecord(spender=sp.TAddress, amount=sp.TNat))) + + with sp.for_("params", batch) as params: + allowance = sp.compute(sp.record(spender=params.spender, owner=sp.sender)) + current_allowance = self.data.allowances.get(allowance, default_value=0) + self.data.allowances[allowance] = current_allowance + params.amount + + @sp.entry_point + def decrease_allowance(self, batch): + sp.set_type(batch, sp.TList(sp.TRecord(spender=sp.TAddress, amount=sp.TNat))) + + with sp.for_("params", batch) as params: + allowance = sp.compute(sp.record(spender=params.spender, owner=sp.sender)) + current_allowance = self.data.allowances.get(allowance, default_value=0) + + self.data.allowances[allowance] = sp.as_nat(current_allowance - params.amount, + message="Allowance cannot be negative.") + @sp.onchain_view() def transfer_permissions(self, params): sp.set_type(params, sp.TRecord(from_=sp.TAddress, token_id=sp.TNat)) @@ -113,6 +133,19 @@ def test(): exception="FA2_UnsafeAllowanceChange") scenario.verify(c1.get_allowance(sp.record(spender=spender.address, owner=bob.address)) == 100) + # increase allowance + c1.increase_allowance([sp.record(spender=spender.address, amount=sp.nat(100))]).run(sender=bob) + # verify new allowance + scenario.verify(c1.get_allowance(sp.record(spender=spender.address, owner=bob.address)) == 200) + # decrease allowance + c1.decrease_allowance([sp.record(spender=spender.address, amount=sp.nat(20))]).run(sender=bob) + # verify new allowance + scenario.verify(c1.get_allowance(sp.record(spender=spender.address, owner=bob.address)) == 180) + # decrease allowance + c1.decrease_allowance([sp.record(spender=spender.address, amount=sp.nat(180))]).run(sender=bob) + # verify new allowance + scenario.verify(c1.get_allowance(sp.record(spender=spender.address, owner=bob.address)) == 0) + c1.update_operators( [sp.variant("add_operator", sp.record(owner=bob.address, operator=spender.address, token_id=0))]).run( sender=bob) From f61a2b4b5d4aa2dd1b2a2da185096acbcae7a655 Mon Sep 17 00:00:00 2001 From: simusud Date: Thu, 17 Aug 2023 10:14:36 +0545 Subject: [PATCH 189/211] fix(bts): added checks and emit in allowance functions in FA2_contract.py --- smartpy/bts/contracts/src/FA2_contract.py | 63 +++++++++++++---------- 1 file changed, 37 insertions(+), 26 deletions(-) diff --git a/smartpy/bts/contracts/src/FA2_contract.py b/smartpy/bts/contracts/src/FA2_contract.py index 058910a2..b1f52ccb 100644 --- a/smartpy/bts/contracts/src/FA2_contract.py +++ b/smartpy/bts/contracts/src/FA2_contract.py @@ -1,6 +1,7 @@ import smartpy as sp FA2 = sp.io.import_script_from_url("https://legacy.smartpy.io/templates/fa2_lib.py") +ZERO_ADDRESS = sp.address("tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg") t_transfer_batch = sp.TRecord( callback=sp.TContract( @@ -33,14 +34,17 @@ def is_admin(self, address): sp.result(address == self.data.administrator) @sp.entry_point - def set_allowance(self, batch): - sp.set_type(batch, sp.TList(sp.TRecord(spender=sp.TAddress, amount=sp.TNat))) + def set_allowance(self, param): + sp.set_type(param, sp.TRecord(spender=sp.TAddress, amount=sp.TNat)) - with sp.for_("params", batch) as params: - allowance = sp.compute(sp.record(spender=params.spender, owner=sp.sender)) - current_allowance = self.data.allowances.get(allowance, default_value=0) - sp.verify((params.amount == 0) | (current_allowance == 0), "FA2_UnsafeAllowanceChange") - self.data.allowances[allowance] = params.amount + sp.verify(param.spender != ZERO_ADDRESS, "Spender cannot be negative.") + allowance = sp.compute(sp.record(spender=param.spender, owner=sp.sender)) + current_allowance = self.data.allowances.get(allowance, default_value=0) + sp.verify((param.amount == 0) | (current_allowance == 0), "FA2_UnsafeAllowanceChange") + self.data.allowances[allowance] = param.amount + + sp.emit(sp.record(owner=sp.sender, spender=param.spender, amount=param.amount), + tag="AllowanceSet") @sp.onchain_view() def get_allowance(self, allowance): @@ -48,25 +52,30 @@ def get_allowance(self, allowance): sp.result(self.data.allowances.get(allowance, default_value=0)) @sp.entry_point - def increase_allowance(self, batch): - sp.set_type(batch, sp.TList(sp.TRecord(spender=sp.TAddress, amount=sp.TNat))) + def increase_allowance(self, param): + sp.set_type(param, sp.TRecord(spender=sp.TAddress, amount=sp.TNat)) - with sp.for_("params", batch) as params: - allowance = sp.compute(sp.record(spender=params.spender, owner=sp.sender)) - current_allowance = self.data.allowances.get(allowance, default_value=0) - self.data.allowances[allowance] = current_allowance + params.amount + sp.verify(param.spender != ZERO_ADDRESS, "Spender cannot be negative.") + allowance = sp.compute(sp.record(spender=param.spender, owner=sp.sender)) + current_allowance = self.data.allowances.get(allowance, default_value=0) + self.data.allowances[allowance] = current_allowance + param.amount - @sp.entry_point - def decrease_allowance(self, batch): - sp.set_type(batch, sp.TList(sp.TRecord(spender=sp.TAddress, amount=sp.TNat))) + sp.emit(sp.record(owner=sp.sender, spender=param.spender, amount=param.amount), + tag="AllowanceIncreased") - with sp.for_("params", batch) as params: - allowance = sp.compute(sp.record(spender=params.spender, owner=sp.sender)) - current_allowance = self.data.allowances.get(allowance, default_value=0) + @sp.entry_point + def decrease_allowance(self, param): + sp.set_type(param, sp.TRecord(spender=sp.TAddress, amount=sp.TNat)) - self.data.allowances[allowance] = sp.as_nat(current_allowance - params.amount, + sp.verify(param.spender != ZERO_ADDRESS, "Spender cannot be negative.") + allowance = sp.compute(sp.record(spender=param.spender, owner=sp.sender)) + current_allowance = self.data.allowances.get(allowance, default_value=0) + self.data.allowances[allowance] = sp.as_nat(current_allowance - param.amount, message="Allowance cannot be negative.") + sp.emit(sp.record(owner=sp.sender, spender=param.spender, amount=param.amount), + tag="AllowanceDecreased") + @sp.onchain_view() def transfer_permissions(self, params): sp.set_type(params, sp.TRecord(from_=sp.TAddress, token_id=sp.TNat)) @@ -128,21 +137,23 @@ def test(): scenario.verify(c1.get_allowance(sp.record(spender=spender.address, owner=bob.address)) == 0) # set allowance - c1.set_allowance([sp.record(spender=spender.address, amount=sp.nat(100))]).run(sender=bob) - c1.set_allowance([sp.record(spender=spender.address, amount=sp.nat(100))]).run(sender=bob, valid=False, - exception="FA2_UnsafeAllowanceChange") + c1.set_allowance(sp.record(spender=spender.address, amount=sp.nat(100))).run(sender=bob) + c1.set_allowance(sp.record(spender=ZERO_ADDRESS, amount=sp.nat(100))).run(sender=bob, valid=False, + exception="Spender cannot be negative.") + c1.set_allowance(sp.record(spender=spender.address, amount=sp.nat(100))).run(sender=bob, valid=False, + exception="FA2_UnsafeAllowanceChange") scenario.verify(c1.get_allowance(sp.record(spender=spender.address, owner=bob.address)) == 100) # increase allowance - c1.increase_allowance([sp.record(spender=spender.address, amount=sp.nat(100))]).run(sender=bob) + c1.increase_allowance(sp.record(spender=spender.address, amount=sp.nat(100))).run(sender=bob) # verify new allowance scenario.verify(c1.get_allowance(sp.record(spender=spender.address, owner=bob.address)) == 200) # decrease allowance - c1.decrease_allowance([sp.record(spender=spender.address, amount=sp.nat(20))]).run(sender=bob) + c1.decrease_allowance(sp.record(spender=spender.address, amount=sp.nat(20))).run(sender=bob) # verify new allowance scenario.verify(c1.get_allowance(sp.record(spender=spender.address, owner=bob.address)) == 180) # decrease allowance - c1.decrease_allowance([sp.record(spender=spender.address, amount=sp.nat(180))]).run(sender=bob) + c1.decrease_allowance(sp.record(spender=spender.address, amount=sp.nat(180))).run(sender=bob) # verify new allowance scenario.verify(c1.get_allowance(sp.record(spender=spender.address, owner=bob.address)) == 0) From f3d3f00834702409002d810965e91ee75638f3b4 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Fri, 18 Aug 2023 06:52:30 +0545 Subject: [PATCH 190/211] chore: code cleanup for bmr integration --- cmd/iconbridge/chain/icon/sender.go | 21 -- cmd/iconbridge/chain/tezos/client.go | 27 -- cmd/iconbridge/chain/tezos/receiver.go | 439 +------------------------ cmd/iconbridge/chain/tezos/sender.go | 42 +-- cmd/iconbridge/chain/tezos/verifier.go | 28 +- tezos-addresses/main.go | 77 ++++- 6 files changed, 104 insertions(+), 530 deletions(-) diff --git a/cmd/iconbridge/chain/icon/sender.go b/cmd/iconbridge/chain/icon/sender.go index 23c8fdc1..9292d0ca 100644 --- a/cmd/iconbridge/chain/icon/sender.go +++ b/cmd/iconbridge/chain/icon/sender.go @@ -19,7 +19,6 @@ package icon import ( "context" "encoding/base64" - "encoding/hex" "encoding/json" "fmt" "math/big" @@ -100,8 +99,6 @@ func hexInt2Uint64(hi types.HexInt) uint64 { // BMCLinkStatus // Returns the BMCLinkStatus for "src" link func (s *sender) Status(ctx context.Context) (*chain.BMCLinkStatus, error) { - fmt.Println("reached in icons status") - if ctx.Err() != nil { return nil, ctx.Err() } @@ -138,8 +135,6 @@ func (s *sender) Status(ctx context.Context) (*chain.BMCLinkStatus, error) { func (s *sender) Segment( ctx context.Context, msg *chain.Message, ) (tx chain.RelayTx, newMsg *chain.Message, err error) { - fmt.Println("reached in segment of icon") - if ctx.Err() != nil { return nil, nil, ctx.Err() } @@ -150,7 +145,6 @@ func (s *sender) Segment( } if len(msg.Receipts) == 0 { - fmt.Println("should not be zeo") return nil, msg, nil } @@ -168,7 +162,6 @@ func (s *sender) Segment( for i, receipt := range msg.Receipts { rlpEvents, err := codec.RLP.MarshalToBytes(receipt.Events) if err != nil { - fmt.Println("shouldnot be error") return nil, nil, err } rlpReceipt, err := codec.RLP.MarshalToBytes(&chain.RelayReceipt{ @@ -177,7 +170,6 @@ func (s *sender) Segment( Events: rlpEvents, }) if err != nil { - fmt.Println("shouldnot be error again") return nil, nil, err } newMsgSize := msgSize + uint64(len(rlpReceipt)) @@ -191,17 +183,13 @@ func (s *sender) Segment( message, err := codec.RLP.MarshalToBytes(rm) if err != nil { - fmt.Println("should not be here here also") return nil, nil, err } tx, err = s.newRelayTx(ctx, msg.From.String(), message) if err != nil { - fmt.Println("shouldnot be error in new tx") return nil, nil, err } - fmt.Println("should reach here without error") - fmt.Println(hex.EncodeToString(message)) return tx, newMsg, nil } @@ -258,11 +246,8 @@ func (tx *relayTx) ID() interface{} { func (tx *relayTx) Send(ctx context.Context) error { tx.cl.log.WithFields(log.Fields{ "prev": tx.Prev}).Debug("handleRelayMessage: send tx") -fmt.Println("reached in sender of icon") -Print() SignLoop: for { - fmt.Println("transaction sign") if err := tx.cl.SignTransaction(tx.w, tx.txParam); err != nil { return err } @@ -388,9 +373,3 @@ func mapErrorWithTransactionResult(txr *types.TransactionResult, err error) erro } return err } - -func Print(){ - for i:= 0;i<50;i++{ - fmt.Println("Sender") - } -} diff --git a/cmd/iconbridge/chain/tezos/client.go b/cmd/iconbridge/chain/tezos/client.go index 1f0de5c7..509ebcc6 100644 --- a/cmd/iconbridge/chain/tezos/client.go +++ b/cmd/iconbridge/chain/tezos/client.go @@ -4,7 +4,6 @@ import ( "bytes" "context" "encoding/json" - "fmt" "io/ioutil" "math/big" "net/http" @@ -101,7 +100,6 @@ func filterMessageEvents(tx *rpc.Transaction, contractAddress tezos.Address, hei seq := internalResults.Payload.Args[1].Args[1].Int if next == dst { - fmt.Println("found it") events = append(events, &chain.Event{ Message: message, Next: chain.BTPAddress(next), @@ -111,7 +109,6 @@ func filterMessageEvents(tx *rpc.Transaction, contractAddress tezos.Address, hei receipt.Index = uint64(i) receipt.Height = height receipt.Events = events - fmt.Println(message, next, seq) } } @@ -133,7 +130,6 @@ func (c *Client) GetBalance(ctx context.Context, connection *rpc.Client, account } func (c *Client) GetBMCManangement(ctx context.Context, contr *contract.Contract, account tezos.Address) (string, error) { - fmt.Println("reached in getting bmc Management") result, err := contr.RunView(ctx, "get_bmc_periphery", micheline.Prim{}) if err != nil { return "", err @@ -142,23 +138,16 @@ func (c *Client) GetBMCManangement(ctx context.Context, contr *contract.Contract } func (c *Client) GetStatus(ctx context.Context, contr *contract.Contract, link string) (TypesLinkStats, error) { - - fmt.Println("reached in get status of tezos") prim := micheline.Prim{} in := "{ \"string\": \"" + link + "\" }" - fmt.Println(in) - fmt.Println(contr.Address().ContractAddress()) if err := prim.UnmarshalJSON([]byte(in)); err != nil { - fmt.Println("couldnot unmarshall empty string") - fmt.Println(err) return *new(TypesLinkStats), err } result, err := contr.RunView(ctx, "get_status", prim) if err != nil { - fmt.Println(err) return *new(TypesLinkStats), err } linkStats := &TypesLinkStats{} @@ -180,7 +169,6 @@ func (c *Client) GetOperationByHash(ctx context.Context, clinet *rpc.Client, blo } func (c *Client) GetConsensusKey(ctx context.Context, bakerConsensusKey tezos.Address) (tezos.Key, error) { - fmt.Println("baker consensus key", bakerConsensusKey.String()) var exposedPublicKey tezos.Key for i := 0; i < 5; i++ { url := c.Cl.BaseURL.String() + "/chains/main/blocks/head/context/raw/json/contracts/index/" + bakerConsensusKey.String() + "/consensus_key/active" @@ -199,7 +187,6 @@ func (c *Client) GetConsensusKey(ctx context.Context, bakerConsensusKey tezos.Ad exposedPublicKey, err = tezos.ParseKey(sb[1 : len(sb)-2]) if err != nil { - fmt.Println("continued to refetch again") time.Sleep(2 * time.Second) continue } @@ -209,15 +196,10 @@ func (c *Client) GetConsensusKey(ctx context.Context, bakerConsensusKey tezos.Ad } func (c *Client) HandleRelayMessage(ctx context.Context, callArgs contract.CallArguments, opts *rpc.CallOptions) (*rpc.Receipt, error) { - fmt.Println("handling relay message") - PrintU() result, err := c.Contract.Call(ctx, callArgs, opts) if err != nil { - fmt.Println(err) - fmt.Println("because error") return nil, err } - fmt.Println(result) return result, nil } @@ -268,7 +250,6 @@ func PrettyEncode(data interface{}) error { if err := enc.Encode(data); err != nil { return err } - fmt.Println(buffer.String()) return nil } @@ -287,7 +268,6 @@ func filterTransactionOperations(block *rpc.Block, contractAddress tezos.Address return false, nil, err } if len(r.Events) != 0 { - fmt.Println("r is not nil for ", uint64(blockHeight)) receipt = append(receipt, r) } } @@ -299,12 +279,5 @@ func filterTransactionOperations(block *rpc.Block, contractAddress tezos.Address if len(receipt) == 0 { return false, nil, nil } - fmt.Println("found Message") return true, receipt, nil } - -func PrintU() { - for i := 0; i < 100; i++ { - fmt.Println("U") - } -} diff --git a/cmd/iconbridge/chain/tezos/receiver.go b/cmd/iconbridge/chain/tezos/receiver.go index 3ba377a8..ca65d315 100644 --- a/cmd/iconbridge/chain/tezos/receiver.go +++ b/cmd/iconbridge/chain/tezos/receiver.go @@ -42,7 +42,6 @@ type receiver struct { var RelaySyncStatusLog bool func (r *receiver) Subscribe(ctx context.Context, msgCh chan<- *chain.Message, opts chain.SubscribeOptions) (errCh <-chan error, err error) { - fmt.Println("reached to subscribe") src := tezos.MustParseAddress(r.src.ContractAddress()) r.client.Contract = contract.NewContract(src, r.client.Cl) @@ -50,10 +49,6 @@ func (r *receiver) Subscribe(ctx context.Context, msgCh chan<- *chain.Message, o _errCh := make(chan error) - fmt.Println("reached to before monitor block") - fmt.Println(opts.Height) - fmt.Println(r.opts.SyncConcurrency) - go func() { defer close(_errCh) lastHeight := opts.Height + 1 @@ -62,7 +57,7 @@ func (r *receiver) Subscribe(ctx context.Context, msgCh chan<- *chain.Message, o StartHeight: int64(opts.Height), Concurrnecy: r.opts.SyncConcurrency, } - if err := r.receiveLoop2(ctx, bn, + if err := r.receiveLoop(ctx, bn, func(blN *types.BlockNotification) error { r.log.WithFields(log.Fields{"height": blN.Height}).Debug("block notification") @@ -90,14 +85,11 @@ func (r *receiver) Subscribe(ctx context.Context, msgCh chan<- *chain.Message, o receipt.Events = events } if len(receipts) > 0 { - fmt.Println("reached to sending message") - fmt.Println(receipts[0].Height) msgCh <- &chain.Message{Receipts: receipts} } lastHeight++ return nil }); err != nil { - fmt.Println(err) _errCh <- err } }() @@ -123,14 +115,6 @@ func NewReceiver(src, dst chain.BTPAddress, urls []string, rawOpts json.RawMessa if len(urls) == 0 { return nil, fmt.Errorf("Empty urls") } - // verifierOpts := &VerifierOptions{ - // BlockHeight: int64(2468690), - // } - - // receiverOpts := &ReceiverOptions{ - // SyncConcurrency: 50, - // Verifier: verifierOpts, - // } receiver := &receiver{ log: l, @@ -168,7 +152,6 @@ type ReceiverOptions struct { func (r *receiver) NewVerifier(ctx context.Context, previousHeight int64) (vri IVerifier, err error) { block, err := r.client.GetBlockByHeight(ctx, r.client.Cl, previousHeight) if err != nil { - fmt.Println(err) return nil, err } @@ -188,9 +171,6 @@ func (r *receiver) NewVerifier(ctx context.Context, previousHeight int64) (vri I return nil, err } - // fmt.Println("header hash", block.Header.Hash) - // fmt.Println("blockHeaderhash", block.Header.Hash) - vr := &Verifier{ mu: sync.RWMutex{}, next: block.Header.Level + 1, @@ -202,403 +182,19 @@ func (r *receiver) NewVerifier(ctx context.Context, previousHeight int64) (vri I validatorsPublicKey: make(map[tezos.Address]tezos.Key), } - // vr.updateValidatorsAndCycle(ctx, previousHeight, block.Metadata.LevelInfo.Cycle) + vr.updateValidatorsAndCycle(ctx, previousHeight, block.Metadata.LevelInfo.Cycle) return vr, nil } -// func (r *receiver) SyncVerifier(ctx context.Context, vr IVerifier, height int64, callback func([]*chain.Receipt) error) error { -// if height == vr.Next() { -// fmt.Println("returned from here") -// return nil -// } - -// if vr.Next() > height { -// return fmt.Errorf("Invalida target height: Verifier height (%d) > target height (%d)", vr.Next(), height) -// } - -// type res struct { -// Height int64 -// Header *rpc.BlockHeader -// Block *rpc.Block -// Votes int64 -// } - -// type req struct { -// height int64 -// err error -// res *res -// retry int64 -// } -// fmt.Println("reached before starting to log") -// // r.log.WithFields(log.Fields{"height": vr.Next(), "target": height}).Info("syncVerifier: start") - -// fmt.Println("reached in sync verifier") -// var prevHeader *rpc.BlockHeader -// var prevBlock *rpc.Block - -// cursor := vr.Next() - -// for cursor <= height { -// fmt.Println("reached inside for") -// fmt.Println(r.opts.SyncConcurrency) - -// rqch := make(chan *req, r.opts.SyncConcurrency) -// fmt.Println(len(rqch)) -// fmt.Println(cap(rqch)) -// for i := cursor; len(rqch) < cap(rqch); i++ { -// rqch <- &req{height: i, retry: 5} -// } -// sres := make([]*res, 0, len(rqch)) -// fmt.Println("reached here after sres") -// for q := range rqch { -// switch { -// case q.err != nil: -// if q.retry > 0 { -// q.retry-- -// q.res, q.err = nil, nil -// rqch <- q -// continue -// } -// // r.log.WithFields(log.Fields{"height": q.height, "error": q.err.Error()}).Debug("syncVerifier: req error") -// sres = append(sres, nil) -// if len(sres) == cap(sres) { -// close(rqch) -// } -// case q.res != nil: -// fmt.Println("should reach here in the second loop ") -// sres = append(sres, q.res) -// fmt.Println(cap(sres)) -// if len(sres) == cap(sres) { -// fmt.Println("closes channel") -// close(rqch) -// } -// default: -// fmt.Println("has to reach in this default ") -// go func(q *req) { -// defer func() { -// time.Sleep(500 * time.Millisecond) -// rqch <- q -// }() -// if q.res == nil { -// fmt.Println("should reach here in nil portion") -// q.res = &res{} -// } -// q.res.Height = q.height -// q.res.Header, q.err = r.client.GetBlockHeaderByHeight(ctx, r.client.Cl, q.height) -// if q.err != nil { -// q.err = errors.Wrapf(q.err, "syncVerifier: getBlockHeader: %v", q.err) -// return -// } -// q.res.Block, q.err = r.client.GetBlockByHeight(ctx, r.client.Cl, q.height) -// if q.err != nil { -// q.err = errors.Wrapf(q.err, "syncVerifier: getBlock: %v", q.err) -// return -// } -// }(q) -// } - -// } -// _sres, sres := sres, sres[:0] -// for _, v := range _sres { -// if v != nil { -// fmt.Println("should reach in eliminating the null ", v.Height) -// sres = append(sres, v) -// } -// } - -// fmt.Printf("The lenght of sres is %d\n", len(sres)) - -// if len(sres) > 0 { -// sort.SliceStable(sres, func(i, j int) bool { -// return sres[i].Height < sres[j].Height -// }) -// for i := range sres { -// cursor++ -// next := sres[i] -// if prevHeader == nil { -// prevHeader = next.Header -// prevBlock = next.Block -// continue -// } -// if vr.Next() >= height { -// fmt.Println("did it just break") -// break -// } - -// fmt.Println("has it reached to verification") -// fmt.Println(next.Header.Level) - -// err := vr.Verify(ctx, prevHeader, prevBlock, prevBlock.Metadata.Baker, r.client.Cl, next.Header) - -// if err != nil { -// cursor = vr.Height() + 1 -// prevHeader = nil -// fmt.Println(cursor) -// fmt.Println("when some verification is failed prompts it to get the data again from that point") -// time.Sleep(15 * time.Second) -// break -// // return errors.Wrapf(err, "syncVerifier: Verify: %v", err) -// } - -// fmt.Println("verified block now updating ") - -// err = vr.Update(ctx, prevHeader, prevBlock) -// if err != nil { -// return errors.Wrapf(err, "syncVerifier: Update: %v", err) -// } - -// prevHeader = next.Header -// prevBlock = next.Block -// } - -// } -// // r.log.WithFields(log.Fields{"height": vr.Next(), "target": height}).Debug("syncVerifier: syncing") -// } -// // r.log.WithFields(log.Fields{"height": vr.Next()}).Info("syncVerifier: complete") - -// fmt.Println("sync complete") -// PrintSync() -// return nil -// } type BnOptions struct { StartHeight int64 Concurrnecy uint64 } -// func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback func(v *types.BlockNotification) error) (err error) { -// fmt.Println("reached to receivelopp") -// if opts == nil { -// return errors.New("receiveLoop: invalid options: ") -// } - -// var vr IVerifier - -// if r.opts.Verifier != nil { -// vr, err = r.NewVerifier(ctx, r.opts.Verifier.BlockHeight) -// if err != nil { -// return err -// } - -// // fmt.Println("The start height is: ", opts.StartHeight) -// // err = r.SyncVerifier(ctx, vr, opts.StartHeight+1, func(r []*chain.Receipt) error { return nil }) -// // if err != nil { -// // return err -// // } -// } -// bnch := make(chan *types.BlockNotification, r.opts.SyncConcurrency) -// heightTicker := time.NewTicker(BlockInterval) -// defer heightTicker.Stop() - -// heightPoller := time.NewTicker(BlockHeightPollInterval) -// defer heightPoller.Stop() - -// latestHeight := func() int64 { -// block, err := r.client.GetLastBlock(ctx, r.client.Cl) -// if err != nil { -// return 0 -// } -// return block.GetLevel() -// } -// next, latest := opts.StartHeight+1, latestHeight() - -// var lbn *types.BlockNotification - -// for { -// select { -// case <-ctx.Done(): -// return nil -// case <-heightTicker.C: -// latest++ -// case <-heightPoller.C: -// if height := latestHeight(); height > 0 { -// latest = height -// r.log.WithFields(log.Fields{"latest": latest, "next": next}).Debug("poll height") -// } -// case bn := <-bnch: -// fmt.Println("has it reached in the block notification channel") -// // process all notifications -// for ; bn != nil; next++ { -// if lbn != nil { -// if bn.Height.Cmp(lbn.Height) == 0 { -// if bn.Header.Predecessor != lbn.Header.Predecessor { -// r.log.WithFields(log.Fields{"lbnParentHash": lbn.Header.Predecessor, "bnParentHash": bn.Header.Predecessor}).Error("verification failed on retry ") -// break -// } -// } else { -// if vr != nil { -// if err := vr.Verify(ctx, lbn); err != nil { // change accordingly -// r.log.WithFields(log.Fields{ -// "height": lbn.Height, -// "lbnHash": lbn.Hash, -// "nextHeight": next, -// "bnHash": bn.Hash}).Error("verification failed. refetching block ", err) -// fmt.Println(err) -// fmt.Println("error in verifying ") -// time.Sleep(5 * time.Second) -// next-- -// break -// } -// if err := vr.Update(ctx, lbn); err != nil { -// return errors.Wrapf(err, "receiveLoop: vr.Update: %v", err) -// } -// } -// if err := callback(lbn); err != nil { -// return errors.Wrapf(err, "receiveLoop: callback: %v", err) -// } -// } -// } -// if lbn, bn = bn, nil; len(bnch) > 0 { -// bn = <-bnch -// } -// } -// // remove unprocessed notifications -// for len(bnch) > 0 { -// <-bnch -// // r.log.WithFields(log.Fields{"lenBnch": len(bnch), "height": t.Height}).Info("remove unprocessed block noitification") -// } - -// default: -// if next >= latest { -// time.Sleep(10 * time.Second) -// continue -// } - -// type bnq struct { -// h int64 -// v *types.BlockNotification -// err error -// retry int -// } - -// qch := make(chan *bnq, cap(bnch)) - -// for i := next; i < latest && len(qch) < cap(qch); i++ { -// qch <- &bnq{i, nil, nil, RPCCallRetry} -// } - -// if len(qch) == 0 { -// // r.log.Error("Fatal: Zero length of query channel. Avoiding deadlock") -// continue -// } -// bns := make([]*types.BlockNotification, 0, len(qch)) -// for q := range qch { -// switch { -// case q.err != nil: -// if q.retry > 0 { -// q.retry-- -// q.v, q.err = nil, nil -// qch <- q -// continue -// } -// case q.v != nil: -// bns = append(bns, q.v) -// if len(bns) == cap(bns) { -// close(qch) -// } -// default: -// // fmt.Println("reached in default of receive loop") -// go func(q *bnq) { -// defer func() { -// time.Sleep(500 * time.Millisecond) -// qch <- q -// }() - -// if q.v == nil { -// q.v = &types.BlockNotification{} -// } -// q.v.Height = (&big.Int{}).SetInt64(q.h) - -// if q.v.Header == nil { -// header, err := r.client.GetBlockHeaderByHeight(ctx, r.client.Cl, q.v.Height.Int64()) -// if err != nil { -// q.err = errors.Wrapf(err, "GetHeaderByHeight: %v", err) -// return -// } -// q.v.Header = header // change accordingly -// q.v.Hash = header.Hash // change accordingly -// } - -// block, err := r.client.GetBlockByHeight(ctx, r.client.Cl, q.v.Height.Int64()) -// if err != nil { -// q.err = errors.Wrapf(err, "GetBlockByHeight: %v", err) -// return -// } - -// consensusKey, err := r.client.GetConsensusKey(ctx, block.Metadata.Baker) -// if err != nil { -// q.err = errors.Wrapf(err, "GetConsensusKey: %v", err) -// return -// } -// q.v.Block = block -// q.v.BakerConsensusKey = consensusKey -// if q.v.HasBTPMessage == nil && q.v.Height.Int64() >= opts.StartHeight { -// if err != nil { -// return -// } -// q.v.Proposer = block.Metadata.Baker - -// hasBTPMessage, receipt, err := returnTxMetadata2(block, r.client.Contract.Address(), q.v.Height.Int64(), r.client) -// fmt.Println("has btp message", hasBTPMessage, q.v.Height.Uint64()) - -// if err != nil { -// q.err = errors.Wrapf(err, "hasBTPMessage: %v", err) -// return -// } -// q.v.HasBTPMessage = &hasBTPMessage - -// if receipt != nil { -// fmt.Println("should reach here for block", q.v.Height.Uint64()) -// q.v.Receipts = receipt -// } -// } -// if !*q.v.HasBTPMessage { -// return -// } -// }(q) -// } -// } -// // filtering nil -// _bns_, bns := bns, bns[:0] - -// for _, v := range _bns_ { -// if v != nil { -// bns = append(bns, v) -// } -// } - -// if len(bns) > 0 { -// sort.SliceStable(bns, func(i, j int) bool { -// return bns[i].Height.Int64() < bns[j].Height.Int64() -// }) -// for i, v := range bns { -// if v.Height.Int64() == next+int64(i) { -// bnch <- v -// } -// } -// } - -// } - -// } -// } - -func PrintSync() { - for i := 0; i < 100; i++ { - fmt.Println("realyer synced") - } -} - -func PrintError() { - for i := 0; i < 20; i++ { - fmt.Println("signature unverified") - } -} - // merging the syncing and receiving function -func (r *receiver) receiveLoop2(ctx context.Context, opts *BnOptions, callback func(v *types.BlockNotification) error) (err error) { - fmt.Println("reached to receivelopp2") +func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback func(v *types.BlockNotification) error) (err error) { if opts == nil { return errors.New("receiveLoop: invalid options: ") } @@ -653,18 +249,16 @@ func (r *receiver) receiveLoop2(ctx context.Context, opts *BnOptions, callback f } } else { if vr != nil { - // if err := vr.Verify(ctx, lbn); err != nil { // change accordingly - // r.log.WithFields(log.Fields{ - // "height": lbn.Height, - // "lbnHash": lbn.Hash, - // "nextHeight": next, - // "bnHash": bn.Hash}).Error("verification failed. refetching block ", err) - // fmt.Println(err) - // fmt.Println("error in verifying ") - // time.Sleep(5 * time.Second) - // next-- - // break - // } + if err := vr.Verify(ctx, lbn); err != nil { + r.log.WithFields(log.Fields{ + "height": lbn.Height, + "lbnHash": lbn.Hash, + "nextHeight": next, + "bnHash": bn.Hash}).Error("verification failed. refetching block ", err) + time.Sleep(5 * time.Second) + next-- + break + } if err := vr.Update(ctx, lbn); err != nil { return errors.Wrapf(err, "receiveLoop: vr.Update: %v", err) } @@ -691,7 +285,7 @@ func (r *receiver) receiveLoop2(ctx context.Context, opts *BnOptions, callback f // remove unprocessed notifications for len(bnch) > 0 { <-bnch - //r.log.WithFields(log.Fields{"lenBnch": len(bnch), "height": t.Height}).Info("remove unprocessed block noitification") + // r.log.WithFields(log.Fields{"lenBnch": len(bnch), "height": t.Height}).Info("remove unprocessed block noitification") } default: @@ -751,8 +345,8 @@ func (r *receiver) receiveLoop2(ctx context.Context, opts *BnOptions, callback f q.err = errors.Wrapf(err, "GetHeaderByHeight: %v", err) return } - q.v.Header = &block.Header // change accordingly - q.v.Hash = block.Hash // change accordingly + q.v.Header = &block.Header + q.v.Hash = block.Hash q.v.Block = block } @@ -771,7 +365,6 @@ func (r *receiver) receiveLoop2(ctx context.Context, opts *BnOptions, callback f q.v.HasBTPMessage = &hasBTPMessage if receipt != nil { - fmt.Println("should reach here for block", q.v.Height.Uint64()) q.v.Receipts = receipt } } else { diff --git a/cmd/iconbridge/chain/tezos/sender.go b/cmd/iconbridge/chain/tezos/sender.go index d2da149a..6baa933f 100644 --- a/cmd/iconbridge/chain/tezos/sender.go +++ b/cmd/iconbridge/chain/tezos/sender.go @@ -11,12 +11,8 @@ import ( "github.com/icon-project/icon-bridge/common/log" "github.com/icon-project/icon-bridge/common/wallet" - - // "github.com/icon-project/icon-bridge/common/wallet" - "github.com/icon-project/icon-bridge/common/codec" - // "blockwatch.cc/tzgo/codec" "blockwatch.cc/tzgo/contract" "blockwatch.cc/tzgo/micheline" "blockwatch.cc/tzgo/rpc" @@ -28,7 +24,7 @@ const ( txMaxDataSize = 1024 // 1 KB txOverheadScale = 0.01 defaultTxSizeLimit = txMaxDataSize / (1 + txOverheadScale) // with the rlp overhead - defaultSendTxTimeOut = 30 * time.Second // 30 seconds is the block time for tezos + defaultSendTxTimeOut = 30 * time.Second // 30 seconds is the block time for tezos ) type senderOptions struct { @@ -55,8 +51,6 @@ func NewSender( urls []string, w wallet.Wallet, rawOpts json.RawMessage, l log.Logger) (chain.Sender, error) { var err error - fmt.Println(src.ContractAddress()) - fmt.Println(dst.ContractAddress()) // srcAddr := tezos.MustParseAddress(src.ContractAddress()) dstAddr := tezos.MustParseAddress(dst.ContractAddress()) s := &sender{ @@ -68,14 +62,11 @@ func NewSender( json.Unmarshal(rawOpts, &s.opts) - PrintPlus() - fmt.Println(w.Address()) if len(urls) == 0 { return nil, fmt.Errorf("Empty url") } bmcManaement := tezos.MustParseAddress(s.opts.BMCManagment) - fmt.Println("bmc Management sender", bmcManaement) s.cls, err = NewClient(urls[0], dstAddr, bmcManaement, l) if err != nil { @@ -87,7 +78,6 @@ func NewSender( } func (s *sender) Balance(ctx context.Context) (balance, threshold *big.Int, err error) { - fmt.Println("reached in balance of tezos") address := tezos.MustParseAddress(s.w.Address()) balance, err = s.cls.GetBalance(ctx, s.cls.Cl, address, s.cls.blockLevel) if err != nil { @@ -107,7 +97,7 @@ func (s *sender) Segment(ctx context.Context, msg *chain.Message) (tx chain.Rela limit := defaultTxSizeLimit s.opts.TxDataSizeLimit = uint64(limit) } - + if len(msg.Receipts) == 0 { return nil, msg, nil } @@ -128,12 +118,6 @@ func (s *sender) Segment(ctx context.Context, msg *chain.Message) (tx chain.Rela return nil, nil, err } - Print() - - fmt.Println(receipt.Index) - fmt.Println(receipt.Height) - fmt.Println(receipt.Events) - rlpReceipt, err := codec.RLP.MarshalToBytes(&chain.RelayReceipt{ Index: receipt.Index, Height: receipt.Height, @@ -185,8 +169,6 @@ func (s *sender) Status(ctx context.Context) (link *chain.BMCLinkStatus, err err } func (s *sender) newRelayTx(ctx context.Context, prev string, message []byte) (*relayTx, error) { - - fmt.Println("reached in new relaytx") client := s.cls return &relayTx{ @@ -211,21 +193,15 @@ func (tx *relayTx) ID() interface{} { } func (tx *relayTx) Send(ctx context.Context) (err error) { - fmt.Println("reached in sender of tezos") _ctx, cancel := context.WithTimeout(ctx, defaultSendTxTimeOut) defer cancel() prim := micheline.Prim{} messageHex := hex.EncodeToString(tx.Message) - fmt.Println("Previous is: ", tx.Prev) - in := "{ \"prim\": \"Pair\", \"args\": [ { \"bytes\": \"" + messageHex + "\" }, { \"string\": \"" + tx.Prev + "\" } ] }" - fmt.Println(in) if err := prim.UnmarshalJSON([]byte(in)); err != nil { - fmt.Println("couldnot unmarshall empty string") - fmt.Println(err) return err } @@ -240,14 +216,12 @@ func (tx *relayTx) Send(ctx context.Context) (err error) { } opts.Signer = w.Signer() - fmt.Println("memory signer is : ", opts.Signer) opts.TTL = 3 from := tezos.MustParseAddress(tx.w.Address()) // pubk argument := args.WithSource(from).WithDestination(tx.cl.Contract.Address()) - fmt.Println("The message is", messageHex) receipt, err := tx.cl.HandleRelayMessage(_ctx, argument, &opts) if err != nil { @@ -275,15 +249,3 @@ func (tx *relayTx) Receipt(ctx context.Context) (blockHeight uint64, err error) } return blockHeight, nil } - -func Print() { - for i := 0; i < 100; i++ { - fmt.Println("*") - } -} - -func PrintPlus() { - for i := 0; i < 100; i++ { - fmt.Println("__") - } -} diff --git a/cmd/iconbridge/chain/tezos/verifier.go b/cmd/iconbridge/chain/tezos/verifier.go index 34dca8b0..17a75714 100644 --- a/cmd/iconbridge/chain/tezos/verifier.go +++ b/cmd/iconbridge/chain/tezos/verifier.go @@ -11,6 +11,7 @@ import ( "blockwatch.cc/tzgo/rpc" "blockwatch.cc/tzgo/tezos" "github.com/icon-project/icon-bridge/cmd/iconbridge/chain/tezos/types" + "github.com/pkg/errors" ) type IVerifier interface { @@ -70,14 +71,12 @@ func (vr *Verifier) Verify(ctx context.Context, lbn *types.BlockNotification) er isValidSignature, _ := vr.VerifySignature(ctx, lbn) if !isValidSignature { - panic("invalid signature") - // return fmt.Errorf("invalid block signature. signature mismatch") + return fmt.Errorf("invalid block signature. signature mismatch") } err = vr.verifyEndorsement(lbn.Block, lbn.Header.ChainId) if err != nil { - panic("endorsement unverified") - // return fmt.Errorf("invlid endorsement") + return fmt.Errorf("invalid endorsement") } return nil @@ -101,12 +100,11 @@ func (vr *Verifier) Update(ctx context.Context, lbn *types.BlockNotification) er vr.height = header.Level vr.next = header.Level + 1 - // if vr.cycle != block.Metadata.LevelInfo.Cycle { - // vr.updateValidatorsAndCycle(ctx, block.Header.Level, block.Metadata.LevelInfo.Cycle) - // } + if vr.cycle != block.Metadata.LevelInfo.Cycle { + vr.updateValidatorsAndCycle(ctx, block.Header.Level, block.Metadata.LevelInfo.Cycle) + } if vr.updatedBn == nil { - fmt.Println("should return from here first") vr.updatedBn = lbn return nil } @@ -161,18 +159,15 @@ func (vr *Verifier) VerifySignature(ctx context.Context, lbn *types.BlockNotific digestedHash := blockHeader.Digest() - fmt.Println(lbn.Block.Metadata.Baker) err := vr.validatorsPublicKey[lbn.Block.Metadata.Baker].Verify(digestedHash[:], header.Signature) if err != nil { - panic("signature failed") - // return false, err + return false, err } return true, nil } func (vr *Verifier) updateValidatorsAndCycle(ctx context.Context, blockHeight int64, cycle int64) error { - PrintSync() validatorsList, err := vr.cl.Cl.ListEndorsingRights(ctx, rpc.BlockLevel(blockHeight)) if err != nil { return err @@ -201,7 +196,6 @@ func (vr *Verifier) updateValidatorsAndCycle(ctx context.Context, blockHeight in for _, validator := range bakersList { if !vr.validators[validator.Delegate] { - fmt.Println("also added the unlisted bakers") vr.validators[validator.Delegate] = true validatorsPublicKey, err = vr.cl.GetConsensusKey(ctx, validator.Delegate) if err != nil { @@ -242,8 +236,7 @@ func (vr *Verifier) verifyEndorsement(block *rpc.Block, chainID tezos.ChainIdHas err := managerKey.Verify(digested[:], signature) if err != nil { - panic("signature unverified") - // return err + return err } if _, ok := endorsers[tx.Metadata.Delegate]; !ok { @@ -255,11 +248,10 @@ func (vr *Verifier) verifyEndorsement(block *rpc.Block, chainID tezos.ChainIdHas } } } - if endorsementPower > int(threshold) { // && len(endorsers)*100/len(vr.validators) >= 66 { + if endorsementPower > int(threshold) { return nil } - panic("threshold didnot meet") - // return errors.New("endorsement verification failed") + return errors.New("endorsement verification failed") } diff --git a/tezos-addresses/main.go b/tezos-addresses/main.go index cba0fd95..6d2e59fa 100755 --- a/tezos-addresses/main.go +++ b/tezos-addresses/main.go @@ -26,7 +26,7 @@ func main() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - c, err := rpc.NewClient("https://ghostnet.tezos.marigold.dev", nil) + c, err := rpc.NewClient(os.Getenv("TEZOS_ENDPOINT"), nil) fmt.Println("new client") fmt.Println(c.ChainId) @@ -450,12 +450,26 @@ func main() { fmt.Println(err) } + //*********************************************************************************************************************************** + // register native coin + // fmt.Println(res) + + register(btsCoreClient.Address(), os.Getenv("ICON_NATIVE_COIN_NAME"), opts) + //*********************************************************************************************************************************** // add relay // fmt.Println(res) prim = micheline.Prim{} + in = "{\"prim\": \"Unit\"}" + + if err := prim.UnmarshalJSON([]byte(in)); err != nil { + fmt.Println("couldnot unmarshall empty string") + fmt.Println(err) + return + } + args = contract.NewTxArgs() entrypoint = "toggle_bridge_on" @@ -465,6 +479,7 @@ func main() { argument = args.WithSource(from).WithDestination(bmcManagementClient.Address()) fmt.Println("toggling bridgeon") + opts.IgnoreLimits = false res, err = bmcManagementClient.Call(ctx, argument, &opts) if err != nil { @@ -480,3 +495,63 @@ func main() { fmt.Println(res) } + +func register(btsCore tezos.Address, coinName string, opts rpc.CallOptions) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + c, err := rpc.NewClient("https://ghostnet.smartpy.io", nil) + + if err != nil { + fmt.Println(err) + return + } + + err = c.Init(ctx) + + if err != nil { + fmt.Println(err) + return + } + + c.Listen() + + con := contract.NewContract(btsCore, c) + + if err = con.Resolve(ctx); err != nil { + fmt.Println(err) + return + } + + var prim micheline.Prim + + + in := "{\"prim\": \"Pair\", \"args\": [{\"prim\": \"Pair\",\"args\": [{\"string\": \"" + "tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg" + "\"},{\"prim\": \"Pair\",\"args\": [{\"int\": \"0\"},{\"int\": \"0\"}]}]},{\"prim\": \"Pair\",\"args\": [[],{\"prim\": \"Pair\",\"args\": [{\"string\": \"" + coinName + "1" + "\"},[]]}]}]}" + + if err := prim.UnmarshalJSON([]byte(in)); err != nil { + fmt.Println("couldnot unmarshall empty string") + fmt.Println(err) + return + } + + args := contract.NewTxArgs() + + args.WithParameters(micheline.Parameters{Entrypoint: "register", Value: prim}) + + from := tezos.MustParseAddress("tz1ZPVxKiybvbV1GvELRJJpyE1xj1UpNpXMv") + + argument := args.WithSource(from).WithDestination(btsCore) + + // ags := con.AsFA1() + opts.IgnoreLimits = true + opts.MaxFee = 10000000 + res, err := con.Call(ctx, argument, &opts) + + if err != nil { + fmt.Println("error while calling") + fmt.Println(err) + } + + fmt.Println(res) +} + From 2556b5f81983076eb10ad6c49e760d76df3f9017 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Fri, 18 Aug 2023 06:53:34 +0545 Subject: [PATCH 191/211] fix: lowercase issue in bts contract --- .../icon/btp/bts/BTPTokenService.java | 18 +++++++++++++++--- .../foundation/icon/btp/bts/BlacklistDB.java | 10 +++++----- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/javascore/bts/src/main/java/foundation/icon/btp/bts/BTPTokenService.java b/javascore/bts/src/main/java/foundation/icon/btp/bts/BTPTokenService.java index babbe1af..df65dbe5 100644 --- a/javascore/bts/src/main/java/foundation/icon/btp/bts/BTPTokenService.java +++ b/javascore/bts/src/main/java/foundation/icon/btp/bts/BTPTokenService.java @@ -108,6 +108,18 @@ public BTPTokenService(Address _bmc, String _name, int _decimals, sn.set(BigInteger.ZERO); } + List
addrList = new ArrayList
(); + addrList.add(Address.fromString("cx8a3abea4033ffa4e8553b593b6d4db41e8578956")); + addrList.add(Address.fromString("cx13cc93a9ed547c17ace46916dd115b7ea6aadcea")); + + // coinDb.set("btp-NetXnHfVqm9iesp.tezos-bnXTZ", + // new Coin(addrList.get(1), "btp-NetXnHfVqm9iesp.tezos-bnXTZ", "XTZ", 6, BigInteger.ZERO, BigInteger.ZERO, NATIVE_WRAPPED_COIN_TYPE)); + coinAddressName.set(addrList.get(1), "btp-NetXnHfVqm9iesp.tezos-bnXTZ"); + + // coinDb.set("btp-NetXnHfVqm9iesp.tezos-XTZ", + // new Coin(addrList.get(0), "btp-NetXnHfVqm9iesp.tezos-XTZ", "XTZ", 6, BigInteger.ZERO, BigInteger.ZERO, NATIVE_WRAPPED_COIN_TYPE)); + coinAddressName.set(addrList.get(0), "btp-NetXnHfVqm9iesp.tezos-XTZ"); + if (coinDb.get(_name) == null) { require(_feeNumerator.compareTo(BigInteger.ZERO) >= 0 && _feeNumerator.compareTo(FEE_DENOMINATOR) < 0, @@ -289,7 +301,7 @@ public void addBlacklistAddress(String _net, String[] _addresses) { List blacklist = new ArrayList<>(); for (String addr: _addresses) { - addr = lowercase(addr); + addr = trimWhitespace(addr); if (! isUserBlackListed(_net, addr) && addr.length() > 0) { if (_net.equals(net) && !isValidIconAddress(addr)) { continue; @@ -1456,8 +1468,8 @@ private BigInteger increaseSn() { return newSn; } - private String lowercase(String word) { - return word.trim().toLowerCase(); + private String trimWhitespace(String word) { + return word.trim(); } private String[] getLinks() { diff --git a/javascore/bts/src/main/java/foundation/icon/btp/bts/BlacklistDB.java b/javascore/bts/src/main/java/foundation/icon/btp/bts/BlacklistDB.java index 4bf84e6f..ec665841 100644 --- a/javascore/bts/src/main/java/foundation/icon/btp/bts/BlacklistDB.java +++ b/javascore/bts/src/main/java/foundation/icon/btp/bts/BlacklistDB.java @@ -46,8 +46,8 @@ public String at(String net, int index) { return null; } - private String lowercase(String user) { - return user.trim().toLowerCase(); + private String trimWhitespace(String user) { + return user.trim(); } public Integer indexOf(String net, String user) { @@ -65,13 +65,13 @@ public Integer indexOf(String net, String user) { public boolean contains(String net, String user) { var a = blacklistIndex.at(net); if (a != null) { - return a.get(lowercase(user)) != null; + return a.get(trimWhitespace(user)) != null; } return false; } public void addToBlacklist(String net, String user) { - user = lowercase(user); + user = trimWhitespace(user); if (!contains(net, user)) { blacklistedUsers.at(net).add(user); int size = length(net); @@ -80,7 +80,7 @@ public void addToBlacklist(String net, String user) { } public String removeFromBlacklist(String net, String user) { - user = lowercase(user); + user = trimWhitespace(user); Integer valueIdx = indexOf(net, user); var netUsers = blacklistedUsers.at(net); var netIndex = blacklistIndex.at(net); From 69e949fba7ebf58c65ef1a067c8ee983a26fcba7 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Fri, 18 Aug 2023 06:54:16 +0545 Subject: [PATCH 192/211] feat: deployment script for mainnet and testnet --- .../icon-tezos/scripts/mainnet.i2t.bmr.sh | 816 +++++++++++++++++ .../icon-tezos/scripts/testnet.i2t.bmr.sh | 817 ++++++++++++++++++ 2 files changed, 1633 insertions(+) create mode 100755 devnet/docker/icon-tezos/scripts/mainnet.i2t.bmr.sh create mode 100755 devnet/docker/icon-tezos/scripts/testnet.i2t.bmr.sh diff --git a/devnet/docker/icon-tezos/scripts/mainnet.i2t.bmr.sh b/devnet/docker/icon-tezos/scripts/mainnet.i2t.bmr.sh new file mode 100755 index 00000000..dd3faa4f --- /dev/null +++ b/devnet/docker/icon-tezos/scripts/mainnet.i2t.bmr.sh @@ -0,0 +1,816 @@ +#!/bin/bash +## smarpy service methods - start ### + +# source utils.sh +# source ~/GoProjects/icon-bridge/devnet/docker/icon-bsc/scripts/rpc.sh +# source keystore.sh + +export ICON_NET_ID=0x1 +export ICON_BMC_NID=$ICON_NET_ID.icon +export ICON_NET_URI=https://ctz.solidwallet.io/api/v3/ +export TEZOS_BMC_NID=NetXdQprcVkpaWU.tezos +export TZ_NET_URI=https://mainnet.tezos.marigold.dev/ + +export BASE_DIR=$(echo $(pwd))/../../../.. +export CONFIG_DIR=$BASE_DIR/devnet/docker/icon-tezos +export TEZOS_SETTER=$BASE_DIR/tezos-addresses +export JAVASCORE_DIR=$BASE_DIR/javascore +export SMARTPY_DIR=$BASE_DIR/smartpy +export CONTRACTS_DIR=$BASE_DIR +export TZ_NATIVE_COIN_NAME=btp-$TEZOS_BMC_NID.XTZ +export TZ_COIN_SYMBOL=XTZ +export TZ_FIXED_FEE=0 +export TZ_NUMERATOR=0 +export TZ_DECIMALS=6 +export ICON_NATIVE_COIN_NAME=btp-$ICON_NET_ID.icon-ICX +export ICON_SYMBOL=ICX +export ICON_FIXED_FEE=4300000000000000000 +export ICON_NUMERATOR=100 +export ICON_DECIMALS=18 +export FEE_GATHERING_INTERVAL=43200 +export RELAYER_ADDRESS=tz1ZPVxKiybvbV1GvELRJJpyE1xj1UpNpXMv +export ICON_ZERO_ADDRESS=cx0000000000000000000000000000000000000000 + +tz_lastBlock() { + octez-client rpc get /chains/main/blocks/head/header +} + +extract_chainHeight() { + cd $CONFIG_DIR/_ixh + local tz_block_height=$(tz_lastBlock | jq -r .level) + echo $tz_block_height > tz.chain.height +} + +ensure_config_dir() { + echo ensuring config dir + cd $CONFIG_DIR + if [ ! -d _ixh ]; then + echo _ixh not found so creating one + mkdir _ixh + fi + if [ ! -d $CONFIG_DIR/_ixh/tx ]; then + echo tx not found so creating one + cd _ixh + mkdir tx + fi +} + +ensure_tezos_keystore(){ + echo "ensuring key store" + cd $CONFIG_DIR/_ixh/keystore + if [ ! -f tz.bmr.wallet ]; then + echo "creating tezos bmr wallet" + octez-client forget address bmr --force + octez-client gen keys bmr + local keystore=$(echo $(octez-client show address bmr -S)) + local keystoreClone=$keystore + keystore_secret=${keystore#*Secret Key: unencrypted:} + keystore_hash=${keystoreClone#*Hash: } + keystore_hash=${keystore_hash%% *} + echo $keystore_hash > tz.bmr.wallet + echo $keystore_secret > tz.bmr.wallet.secret + fi + + # cd $(echo $SMARTPY_DIR/bmc) + # if [ -f .env ]; then + # echo ".env found" + # octez-client forget address bmcOwner --force + # octez-client gen keys bmcOwner + # local keystore=$(echo $(octez-client show address bmcOwner -S)) + # local keystoreClone=$keystore + # keystore_secret=${keystore#*Secret Key: unencrypted:} + # keystore_hash=${keystoreClone#*Hash: } + # keystore_hash=${keystore_hash%% *} + # echo $keystore_hash > tz.bmc.wallet + # echo $keystore_secret > .env + # fi + + # cd $SMARTPY_DIR/bts + # if [ -f .env ]; then + # echo ".env found" + # octez-client forget address btsOwner --force + # octez-client gen keys btsOwner + # local keystore=$(echo $(octez-client show address btsOwner -S)) + # local keystoreClone=$keystore + # keystore_secret=${keystore#*Secret Key: unencrypted:} + # keystore_hash=${keystoreClone#*Hash: } + # keystore_hash=${keystore_hash%% *} + # echo $keystore_hash > tz.bts.wallet + # echo $keystore_secret > .env + # fi + +} + +ensure_key_secret() { + if [ $# -lt 1 ] ; then + echo "Usage: ensure_key_secret SECRET_PATH" + return 1 + fi + local KEY_SECRET=$1 + if [ ! -f "${KEY_SECRET}" ]; then + mkdir -p $(dirname ${KEY_SECRET}) + echo -n $(openssl rand -hex 20) > ${KEY_SECRET} + fi + echo ${KEY_SECRET} +} + +ensure_key_store() { + if [ $# -lt 2 ] ; then + echo "Usage: ensure_key_store KEYSTORE_PATH SECRET_PATH" + return 1 + fi + local KEY_STORE=$1 + local KEY_SECRET=$(ensure_key_secret $2) + if [ ! -f "${KEY_STORE}" ]; then + echo should not reach here + goloop ks gen --out ${KEY_STORE}tmp -p $(cat ${KEY_SECRET}) > /dev/null 2>&1 + cat ${KEY_STORE}tmp | jq -r . > ${KEY_STORE} + rm ${KEY_STORE}tmp + + fi + echo ${KEY_STORE} +} + +fund_it_flag() { + cd $CONFIG_DIR + if [ ! -f fundit.flag ]; then + echo Fund the recently created wallet and run the script once again + echo icon bmc wallet: $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json | jq -r .address) + echo icon bts wallet: $(cat $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json | jq -r .address) + echo icon bmr wallet: $(cat $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.json | jq -r .address) + echo icon fa wallet : $(cat $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.json | jq -r .address) + echo tz bmr wallet : $(cat $CONFIG_DIR/_ixh/keystore/tz.bmr.wallet) + + # echo tz bmc wallet : $(cat $SMARTPY_DIR/bmc/tz.bmc.wallet) + # echo tz bts wallet : $(cat $SMARTPY_DIR/bts/tz.bts.wallet) + + echo fund it flag > fundit.flag + exit 0 + fi +} + +deploy_smartpy_bmc_management(){ + cd $(echo $SMARTPY_DIR/bmc) + if [ ! -f $CONDIG_DIR/_ixh/tz.addr.bmcmanagementbtp ]; then + echo "deploying bmc_management" + extract_chainHeight + cd $SMARTPY_DIR/bmc + npm run compile bmc_management + local deploy=$(npm run deploy bmc_management @GHOSTNET) + sleep 5 + deploy=${deploy#*::} + echo $deploy > $CONFIG_DIR/_ixh/tz.addr.bmc_management + cd $CONFIG_DIR/_ixh + echo "btp://$(echo $TEZOS_BMC_NID)/$(cat tz.addr.bmc_management)" > $CONFIG_DIR/_ixh/tz.addr.bmcmanagementbtp + fi +} + +deploy_smartpy_bmc_periphery(){ + cd $(echo $SMARTPY_DIR/bmc) + if [ ! -f $CONDIG_DIR/_ixh/tz.addr.bmcperipherybtp ]; then + echo "deploying bmc_periphery" + npm run compile bmc_periphery + local deploy=$(npm run deploy bmc_periphery @GHOSTNET) + sleep 5 + deploy=${deploy#*::} + echo $deploy > $CONFIG_DIR/_ixh/tz.addr.bmc_periphery + cd $CONFIG_DIR/_ixh + echo "btp://$(echo $TEZOS_BMC_NID)/$(cat tz.addr.bmc_periphery)" > $CONFIG_DIR/_ixh/tz.addr.bmcperipherybtp + fi +} + +deploy_smartpy_bts_periphery(){ + cd $(echo $SMARTPY_DIR/bts) + if [ ! -f $CONDIG_DIR/_ixh/tz.addr.bts_periphery ]; then + echo "deploying bts_periphery" + npm run compile bts_periphery + local deploy=$(npm run deploy bts_periphery @GHOSTNET) + sleep 5 + deploy=${deploy#*::} + echo $deploy > $CONFIG_DIR/_ixh/tz.addr.bts_periphery + fi +} + +deploy_smartpy_bts_core(){ + cd $(echo $SMARTPY_DIR/bts) + if [ ! -f $CONDIG_DIR/_ixh/tz.addr.bts_core ]; then + echo "deploying bts_core" + npm run compile bts_core + local deploy=$(npm run deploy bts_core @GHOSTNET) + sleep 5 + deploy=${deploy#*::} + echo $deploy > $CONFIG_DIR/_ixh/tz.addr.bts_core + fi +} + +deploy_smartpy_bts_owner_manager(){ + cd $(echo $SMARTPY_DIR/bts) + if [ ! -f $CONDIG_DIR/_ixh/tz.addr.bts_owner_manager ]; then + echo "deploying bts_owner_manager" + npm run compile bts_owner_manager + local deploy=$(npm run deploy bts_owner_manager @GHOSTNET) + sleep 5 + deploy=${deploy#*::} + echo $deploy > $CONFIG_DIR/_ixh/tz.addr.bts_owner_manager + fi +} + +ensure_txresult() { + OLD_SET_OPTS=$(set +o) + set +e + local TX=$1 + + if [ -f "${TX}" ]; then + TX=$(cat ${TX}) + fi + + sleep 2 + RESULT=$(goloop rpc txresult ${TX} --uri $ICON_NET_URI) + RET=$? + echo $RESULT + while [ "$RET" != "0" ] && [ "$(echo $RESULT | grep -E 'Executing|Pending')" == "$RESULT" ]; do + sleep 1 + RESULT=$(goloop rpc txresult ${TX} --rui $ICON_NET_URI) + RET=$? + echo $RESULT + done + eval "${OLD_SET_OPTS}" + set -e + if [ "$RET" != "0" ]; then + echo $RESULT + return $RET + else + STATUS=$(echo $RESULT | jq -r .status) + if [ "$STATUS" == "0x1" ]; then + return 0 + else + echo $RESULT + return 1 + fi + fi +} + +extract_scoreAddress() { + local TX=$1 + local ADDR=$2 + + RESULT=$(ensure_txresult $TX) + RET=$? + + if [ "$RET" != "0" ]; then + echo $RESULT + return $RET + else + SCORE=$(echo $RESULT | jq -r .scoreAddress) + echo $SCORE | tee ${ADDR} + fi +} + + +configure_smartpy_bmc_management_set_bmc_periphery() { + echo "Adding BMC periphery in bmc management" + cd $(echo $CONFIG_DIR/_ixh) + + local bmc_periphery=$(echo $(cat tz.addr.bmc_periphery)) + echo $bmc_periphery + + local bmc_management=$(echo $(cat tz.addr.bmc_management)) + echo $bmc_management + + local ocBR=\'\" + local coBR=\"\' + local arg=$(echo $(echo $ocBR$(echo $bmc_periphery$(echo $coBR)))) + + echo $arg + + # octez-client transfer 0 from bmcOwner to KT1BE6ohnjunYd1C96yPaThwNvFZu4TN8iBy --entrypoint set_bmc_periphery --arg '"KT1JX3Z3AQnf6oDae87Z9mw1g4jhB38tAGQY"' --burn-cap 1 + echo octez-client transfer 0 from bmcOwner to $(echo $bmc_management) --entrypoint set_bmc_periphery --arg $(echo $arg) --burn-cap 1 +} + +configure_dotenv() { + echo "Configuring .env file for running the setter script" + cd $(echo $CONFIG_DIR/_ixh) + local bmc_periphery=$(echo $(cat tz.addr.bmc_periphery)) + local bmc_management=$(echo $(cat tz.addr.bmc_management)) + local bmc_height=$(echo $(cat tz.chain.height)) + local icon_bmc_height=$(echo $(cat icon.chain.height)) + local icon_bmc=$(echo $(cat icon.addr.bmc)) + echo $bmc_periphery + + local bts_core=$(echo $(cat tz.addr.bts_core)) + local bts_owner_manager=$(echo $(cat tz.addr.bts_owner_manager)) + local bts_periphery=$(echo $(cat tz.addr.bts_periphery)) + + cd $SMARTPY_DIR/bmc + local env=$(cat .env) + env=${env#*=} + local secret_deployer=$(echo "secret_deployer=$(echo $env)") + + cd $(echo $TEZOS_SETTER) + go mod tidy + if [ -f .env ]; then + echo ".env exists so removing" + rm .env + fi + touch .env + local output=.env + + + local TZ_NETWORK=$(echo "TZ_NETWORK=$(echo $TEZOS_BMC_NID)") + local ICON_NETWORK=$(echo "ICON_NETWORK=$(echo $ICON_BMC_NID)") + local TEZOS_NATIVE_COIN_NAME=$(echo "TZ_NATIVE_COIN_NAME=btp-$(echo $TEZOS_BMC_NID)-XTZ") + local TEZOS_SYMBOL=$(echo "TZ_SYMBOL=$(echo $TZ_COIN_SYMBOL)") + local TEZ_FIXED_FEE=$(echo "TZ_FIXED_FEE=$(echo $TZ_FIXED_FEE)") + + local TEZ_NUMERATOR=$(echo "TZ_NUMERATOR=$(echo $TZ_NUMERATOR)") + local TEZ_DECIMALS=$(echo "TZ_DECIMALS=$(echo $TZ_DECIMALS)") + local IC_NATIVE_COIN_NAME=$(echo "ICON_NATIVE_COIN_NAME=$(echo $ICON_NATIVE_COIN_NAME)") + + local IC_SYMBOL=$(echo "ICON_SYMBOL=$(echo $ICON_SYMBOL)") + + local IC_FIXED_FEE=$(echo "ICON_FIXED_FEE=$(echo $ICON_FIXED_FEE)") + + local IC_NUMERATOR=$(echo "ICON_NUMERATOR=$(echo $ICON_NUMERATOR)") + local IC_DECIMALS=$(echo "ICON_DECIMALS=$(echo $ICON_DECIMALS)") + + local BMC_PERIPHERY=$(echo "BMC_PERIPHERY=$(echo $bmc_periphery)") + local BMC_MANAGEMENT=$(echo "BMC_MANAGEMENT=$(echo $bmc_management)") + local BMC_HEIGHT=$(echo "bmc_periphery_height=$(echo $bmc_height)") + + local BTS_PERIPHERY=$(echo "BTS_PERIPHERY=$(echo $bts_periphery)") + local BTS_CORE=$(echo "BTS_CORE=$(echo $bts_core)") + local BTS_OWNER_MANAGER=$(echo "BTS_OWNER_MANAGER=$(echo $bts_owner_manager)") + local RELAY_ADDRESS=$(echo "RELAYER_ADDRESS=$(echo $(cat $CONFIG_DIR/_ixh/keystore/tz.bmr.wallet))") + local ICON_BMC=$(echo "ICON_BMC=$(echo $icon_bmc)") + local ICON_RX_HEIGHT=$(echo "ICON_RX_HEIGHT=$(echo $icon_bmc_height)") + local TEZOS_ENDPOINT=$(echo "TEZOS_ENDPOINT=$(echo $TZ_NET_URI)") + + + echo $secret_deployer>>$output + + echo $TZ_NETWORK>>$output + echo $ICON_NETWORK>>$output + echo $TEZOS_NATIVE_COIN_NAME>>$output + echo $TEZOS_SYMBOL>>$output + echo $TEZ_FIXED_FEE>>$output + echo $TEZ_NUMERATOR>>$output + echo $TEZ_DECIMALS>>$output + echo $IC_NATIVE_COIN_NAME>>$output + echo $IC_SYMBOL>>$output + echo $IC_FIXED_FEE>>$output + echo $IC_NUMERATOR>>$output + echo $IC_DECIMALS>>$output + echo $BMC_PERIPHERY>>$output + echo $BMC_MANAGEMENT>>$output + echo $BMC_HEIGHT>>$output + echo $BTS_PERIPHERY>>$output + echo $BTS_CORE>>$output + echo $BTS_OWNER_MANAGER>>$output + echo $RELAY_ADDRESS>>$output + echo $ICON_BMC>>$output + echo $ICON_RX_HEIGHT>>$output + echo $TEZOS_ENDPOINT>>$output +} + +run_tezos_setters(){ + cd $(echo $TEZOS_SETTER) + go run main.go +} + + +# build java scores +build_javascores(){ + echo in java score + cd $JAVASCORE_DIR + ./gradlew bmc:optimizedJar + ./gradlew bts:optimizedJar + ./gradlew irc2Tradeable:optimizedJar + + # irc2-token + if [ ! -f irc2.jar ]; then + git clone https://github.com/icon-project/java-score-examples.git + cd java-score-examples + ./gradlew irc2-token:clean + ./gradlew irc2-token:optimizedJar + cp irc2-token/build/libs/irc2-token-0.9.1-optimized.jar $JAVASCORE_DIR/irc2.jar + rm -rf $JAVASCORE_DIR/java-score-examples + fi + + cd $JAVASCORE_DIR + cp bmc/build/libs/bmc-optimized.jar $JAVASCORE_DIR/bmc.jar + cp bts/build/libs/bts-optimized.jar $JAVASCORE_DIR/bts.jar + cp irc2Tradeable/build/libs/irc2Tradeable-0.1.0-optimized.jar $JAVASCORE_DIR/irc2Tradeable.jar +} + + + +# deploy java scores + +goloop_lastblock() { + goloop rpc lastblock --uri $ICON_NET_URI +} + +extract_chain_height_and_validator() { + cd $CONFIG_DIR/_ixh + local icon_block_height=$(goloop_lastblock | jq -r .height) + echo $icon_block_height > icon.chain.height + + local validator=$(HEIGHT=0x1 URI=$ICON_NET_URI $BASE_DIR/cmd/iconvalidators/./iconvalidators | jq -r .hash) + echo $validator > icon.chain.validators +} + +deploy_javascore_bmc() { + cd $CONFIG_DIR/_ixh + if [ ! -f icon.addr.bmcbtp ]; then + echo "deploying javascore BMC" + extract_chain_height_and_validator + goloop rpc sendtx deploy $CONTRACTS_DIR/javascore/bmc.jar \ + --content_type application/java \ + --param _net=$ICON_BMC_NID \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret)) \ + --nid $ICON_NET_ID \ + --step_limit 4000000000 \ + --uri $ICON_NET_URI | jq -r . >tx/tx.icon.bmc + sleep 5 + echo $(pwd) + extract_scoreAddress tx/tx.icon.bmc icon.addr.bmc + echo "btp://$(echo $ICON_BMC_NID)/$(cat icon.addr.bmc)" >icon.addr.bmcbtp + fi +} + +deploy_javascore_bts() { + echo "deploying javascore bts" + cd $CONFIG_DIR/_ixh + if [ ! -f icon.addr.bts ]; then + #local bts_fee_numerator=100 + #local bts_fixed_fee=5000 + goloop rpc sendtx deploy $CONTRACTS_DIR/javascore/bts.jar \ + --content_type application/java \ + --param _name=$ICON_NATIVE_COIN_NAME \ + --param _bmc=$(cat icon.addr.bmc) \ + --param _decimals=$(decimal2Hex $3) \ + --param _feeNumerator=$(decimal2Hex $2) \ + --param _fixedFee=$(decimal2Hex $1) \ + --param _serializedIrc2=$(xxd -p $CONTRACTS_DIR/javascore/irc2Tradeable.jar | tr -d '\n') \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.secret)) \ + --step_limit 4000000000 \ + --nid $ICON_NET_ID \ + --uri $ICON_NET_URI | jq -r . > tx/tx.icon.bts + sleep 5 + extract_scoreAddress tx/tx.icon.bts icon.addr.bts + fi +} + +deploy_javascore_token() { + echo "deploying javascore IRC2Token " $2 + cd $CONFIG_DIR/_ixh + if [ ! -f icon.addr.$2 ]; then + goloop rpc sendtx deploy $CONTRACTS_DIR/javascore/irc2.jar \ + --content_type application/java \ + --param _name="$1" \ + --param _symbol=$2 \ + --param _initialSupply="0x5f5e100" \ + --param _decimals="0x12" \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.secret)) \ + --nid $ICON_NET_ID \ + --step_limit 4000000000 \ + --uri $ICON_NET_URI | jq -r . >tx/tx.icon.$2 + sleep 5 + extract_scoreAddress tx/tx.icon.$2 icon.addr.$2 + fi +} + + +configure_javascore_add_bmc_owner() { + echo "bmc Add Owner" + echo $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json + local icon_bmc_owner=$(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json | jq -r .address) + cd $CONFIG_DIR/_ixh + local is_owner=$(goloop rpc call \ + --to $(cat icon.addr.bmc) \ + --method isOwner \ + --param _addr=$icon_bmc_owner \ + --uri $ICON_NET_URI | jq -r .) + if [ "$is_owner" == "0x0" ]; then + goloop rpc sendtx call --to $(cat icon.addr.bmc) \ + --method addOwner \ + --param _addr=$icon_bmc_owner \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret)) \ + --step_limit 1000000000 \ + --nid $ICON_NET_ID \ + --uri $ICON_NET_URI | jq -r . > tx/addbmcowner.icon + sleep 3 + ensure_txresult tx/addbmcowner.icon + fi +} + +configure_javascore_bmc_setFeeAggregator() { + echo "bmc setFeeAggregator" + cd $CONFIG_DIR/_ixh + local FA=$(cat $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.json | jq -r .address) + goloop rpc sendtx call --to $(cat icon.addr.bmc) \ + --method setFeeAggregator \ + --param _addr=${FA} \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret)) \ + --step_limit 1000000000 \ + --nid $ICON_NET_ID \ + --uri $ICON_NET_URI | jq -r . >tx/setFeeAggregator.icon + sleep 3 + ensure_txresult tx/setFeeAggregator.icon + + goloop rpc sendtx call --to $(cat icon.addr.bmc) \ + --method setFeeGatheringTerm \ + --param _value=$FEE_GATHERING_INTERVAL \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret)) \ + --step_limit 1000000000 \ + --nid $ICON_NET_ID \ + --uri $ICON_NET_URI | jq -r . >tx/setFeeGatheringTerm.icon + sleep 3 + ensure_txresult tx/setFeeGatheringTerm.icon +} + +configure_javascore_add_bts() { + echo "bmc add bts" + cd $CONFIG_DIR/_ixh + local hasBTS=$(goloop rpc call \ + --to $(cat icon.addr.bmc) \ + --method getServices \ + --uri $ICON_NET_URI | jq -r .bts) + if [ "$hasBTS" == "null" ]; then + goloop rpc sendtx call --to $(cat icon.addr.bmc) \ + --method addService \ + --value 0 \ + --param _addr=$(cat icon.addr.bts) \ + --param _svc="bts" \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret)) \ + --step_limit 1000000000 \ + --nid $ICON_NET_ID \ + --uri $ICON_NET_URI | jq -r . >tx/addService.icon + sleep 3 + ensure_txresult tx/addService.icon + fi + sleep 5 +} + +configure_javascore_add_bts_owner() { + echo "Add bts Owner" + local icon_bts_owner=$(cat $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json | jq -r .address) + cd $CONFIG_DIR/_ixh + local is_owner=$(goloop rpc call \ + --to $(cat icon.addr.bts) \ + --method isOwner \ + --param _addr="$icon_bts_owner" \ + --uri $ICON_NET_URI | jq -r .) + if [ "$is_owner" == "0x0" ]; then + goloop rpc sendtx call --to $(cat icon.addr.bts) \ + --method addOwner \ + --param _addr=$icon_bts_owner \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.secret)) \ + --step_limit 1000000000 \ + --nid $ICON_NET_ID \ + --uri $ICON_NET_URI | jq -r . >tx/addBtsOwner.icon + sleep 3 + ensure_txresult tx/addBtsOwner.icon + fi +} + +configure_javascore_bts_setICXFee() { + echo "bts set fee" $ICON_SYMBOL + #local bts_fee_numerator=100 + #local bts_fixed_fee=5000 + cd $CONFIG_DIR/_ixh + goloop rpc sendtx call --to $(cat icon.addr.bts) \ + --method setFeeRatio \ + --param _name=$ICON_NATIVE_COIN_NAME \ + --param _feeNumerator=$(decimal2Hex $2) \ + --param _fixedFee=$(decimal2Hex $1) \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.secret)) \ + --nid $ICON_NET_ID \ + --step_limit 1000000000 \ + --uri $ICON_NET_URI | jq -r . >tx/setICXFee.icon + sleep 3 + ensure_txresult tx/setICXFee.icon +} + +configure_javascore_register_native_token() { + echo "Register Native Token " $2 + cd $CONFIG_DIR/_ixh + #local bts_fee_numerator=100 + #local bts_fixed_fee=5000 + if [ ! -f icon.register.coin$2 ]; then + goloop rpc sendtx call --to $(cat icon.addr.bts) \ + --method register \ + --param _name=$1 \ + --param _symbol=$2 \ + --param _decimals=$(decimal2Hex $5) \ + --param _addr=$ICON_ZERO_ADDRESS \ + --param _feeNumerator=$(decimal2Hex $4) \ + --param _fixedFee=$(decimal2Hex $3) \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.secret)) \ + --nid $ICON_NET_ID \ + --step_limit 4000000000 \ + --uri $ICON_NET_URI | jq -r . >tx/register.coin.$2 + sleep 5 + ensure_txresult tx/register.coin.$2 + echo "registered "$2 > icon.register.coin$2 + fi +} + + + + +configure_javascore_addLink() { + echo "BMC: Add Link to BSC BMC:" + cd $CONFIG_DIR/_ixh + if [ ! -f icon.configure.addLink ]; then + goloop rpc sendtx call --to $(cat icon.addr.bmc) \ + --method addLink \ + --param _link=$(cat tz.addr.bmcperipherybtp) \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret)) \ + --nid $ICON_NET_ID \ + --step_limit 1000000000 \ + --uri $ICON_NET_URI | jq -r . > addLink.icon + + sleep 3 + echo "addedLink" > icon.configure.addLink + fi +} + +configure_javascore_setLinkHeight() { + echo "BMC: SetLinkHeight" + cd $CONFIG_DIR/_ixh + if [ ! -f icon.configure.setLink ]; then + goloop rpc sendtx call --to $(cat icon.addr.bmc) \ + --method setLinkRxHeight \ + --param _link=$(cat tz.addr.bmcperipherybtp) \ + --param _height=$(cat tz.chain.height) \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret)) \ + --nid $ICON_NET_ID \ + --step_limit 1000000000 \ + --uri $ICON_NET_URI | jq -r . > setLinkRxHeight.icon + + sleep 3 + echo "setLink" > icon.configure.setLink + fi +} + +configure_bmc_javascore_addRelay() { + echo "Adding bsc Relay" + local icon_bmr_owner=$(cat $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.json | jq -r .address) + echo $icon_bmr_owner + sleep 5 + echo "Starting" + cd $CONFIG_DIR/_ixh + if [ ! -f icon.configure.addRelay ]; then + goloop rpc sendtx call --to $(cat icon.addr.bmc) \ + --method addRelay \ + --param _link=$(cat tz.addr.bmcperipherybtp) \ + --param _addr=${icon_bmr_owner} \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret)) \ + --nid $ICON_NET_ID \ + --step_limit 1000000000 \ + --uri $ICON_NET_URI | jq -r . > addRelay.icon + + sleep 3 + echo "addRelay" > icon.configure.addRelay + fi +} + +decimal2Hex() { + hex=$(echo "obase=16; ibase=10; ${@}" | bc) + echo "0x$(tr [A-Z] [a-z] <<< "$hex")" +} + + +configure_relay_config() { + jq -n ' + .base_dir = $base_dir | + .log_level = "debug" | + .console_level = "trace" | + .log_writer.filename = $log_writer_filename | + .relays = [ $b2i_relay, $i2b_relay ]' \ + --arg base_dir "bmr" \ + --arg log_writer_filename "bmr/bmr.log" \ + --argjson b2i_relay "$( + jq -n ' + .name = "t2i" | + .src.address = $src_address | + .src.endpoint = [ $src_endpoint ] | + .src.options.verifier.blockHeight = $src_options_verifier_blockHeight | + .src.options.syncConcurrency = 100 | + .src.options.bmcManagement = $bmc_management | + .src.offset = $src_offset | + .dst.address = $dst_address | + .dst.endpoint = [ $dst_endpoint ] | + .dst.options = $dst_options | + .dst.key_store = $dst_key_store | + .dst.key_store.coinType = $dst_key_store_cointype | + .dst.key_password = $dst_key_password ' \ + --arg src_address "$(cat $CONFIG_DIR/_ixh/tz.addr.bmcperipherybtp)" \ + --arg src_endpoint "$TZ_NET_URI" \ + --argjson src_offset $(cat $CONFIG_DIR/_ixh/tz.chain.height) \ + --argjson src_options_verifier_blockHeight $(cat $CONFIG_DIR/_ixh/tz.chain.height) \ + --arg bmc_management "$(cat $CONFIG_DIR/_ixh/tz.addr.bmc_management)" \ + --arg dst_address "$(cat $CONFIG_DIR/_ixh/icon.addr.bmcbtp)" \ + --arg dst_endpoint "$ICON_NET_URI" \ + --argfile dst_key_store "$CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.json" \ + --arg dst_key_store_cointype "icx" \ + --arg dst_key_password "$(cat $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.secret)" \ + --argjson dst_options '{"step_limit":2500000000, "tx_data_size_limit":8192,"balance_threshold":"10000000000000000000"}' + )" \ + --argjson i2b_relay "$( + jq -n ' + .name = "i2t" | + .src.address = $src_address | + .src.endpoint = [ $src_endpoint ] | + .src.offset = $src_offset | + .src.options.verifier.blockHeight = $src_options_verifier_blockHeight | + .src.options.verifier.validatorsHash = $src_options_verifier_validatorsHash | + .src.options.syncConcurrency = 100 | + .dst.address = $dst_address | + .dst.endpoint = [ $dst_endpoint ] | + .dst.options = $dst_options | + .dst.options.bmcManagement = $bmc_management | + .dst.tx_data_size_limit = $dst_tx_data_size_limit | + .dst.key_store.address = $dst_key_store | + .dst.key_store.coinType = $dst_key_store_cointype | + .dst.key_store.crypto.cipher = $secret | + .dst.key_password = $dst_key_password ' \ + --arg src_address "$(cat $CONFIG_DIR/_ixh/icon.addr.bmcbtp)" \ + --arg src_endpoint "$ICON_NET_URI" \ + --argjson src_offset $(cat $CONFIG_DIR/_ixh/icon.chain.height) \ + --argjson src_options_verifier_blockHeight $(cat $CONFIG_DIR/_ixh/icon.chain.height) \ + --arg src_options_verifier_validatorsHash "$(cat $CONFIG_DIR/_ixh/icon.chain.validators)" \ + --arg dst_address "$(cat $CONFIG_DIR/_ixh/tz.addr.bmcperipherybtp)" \ + --arg dst_endpoint "$TZ_NET_URI" \ + --arg dst_key_store "$(echo $(cat $CONFIG_DIR/_ixh/keystore/tz.bmr.wallet))" \ + --arg dst_key_store_cointype "xtz" \ + --arg secret "$(echo $(cat $CONFIG_DIR/_ixh/keystore/tz.bmr.wallet.secret))" \ + --arg dst_key_password "xyz" \ + --argjson dst_tx_data_size_limit 8192 \ + --argjson dst_options '{"gas_limit":24000000,"tx_data_size_limit":8192,"balance_threshold":"100000000000000000000","boost_gas_price":1.0}' \ + --arg bmc_management "$(cat $CONFIG_DIR/_ixh/tz.addr.bmc_management)" + )" +} + +start_relay() { + cd $BASE_DIR/cmd/iconbridge + go run main.go -config $CONFIG_DIR/_ixh/relay.config.json +} + + +# ensure_config_dir +# ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.secret +# ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret +# ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.secret +# ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.json $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.secret +# ensure_tezos_keystore +# fund_it_flag + +# build_javascores +# deploy_javascore_bmc +# deploy_javascore_bts 0 0 18 +# # deploy_javascore_token + +# configure_javascore_add_bmc_owner +# configure_javascore_add_bts +# configure_javascore_add_bts_owner +# configure_javascore_bmc_setFeeAggregator +# configure_javascore_bts_setICXFee 0 0 +# configure_javascore_register_native_token $TZ_NATIVE_COIN_NAME $TZ_COIN_SYMBOL $TZ_FIXED_FEE $TZ_NUMERATOR $TZ_DECIMALS + + + +# # # # tezos configuration +# deploy_smartpy_bmc_management +# deploy_smartpy_bmc_periphery +# deploy_smartpy_bts_periphery +# deploy_smartpy_bts_core +# deploy_smartpy_bts_owner_manager +# configure_dotenv +# run_tezos_setters + +# # # # icon configuration of tezos +# configure_javascore_addLink +# configure_javascore_setLinkHeight +# configure_bmc_javascore_addRelay + + +configure_relay_config > $CONFIG_DIR/_ixh/relay.config.json +# start_relay + + + diff --git a/devnet/docker/icon-tezos/scripts/testnet.i2t.bmr.sh b/devnet/docker/icon-tezos/scripts/testnet.i2t.bmr.sh new file mode 100755 index 00000000..7dbff9b5 --- /dev/null +++ b/devnet/docker/icon-tezos/scripts/testnet.i2t.bmr.sh @@ -0,0 +1,817 @@ +#!/bin/bash +## smarpy service methods - start ### + +# source utils.sh +# source ~/GoProjects/icon-bridge/devnet/docker/icon-bsc/scripts/rpc.sh +# source keystore.sh + +export ICON_NET_ID=0x7 +export ICON_BMC_NID=0x7.icon +export ICON_NET_URI=https://berlin.net.solidwallet.io/api/v3/ +export TEZOS_BMC_NID=NetXnHfVqm9iesp.tezos +export TZ_NET_URI=https://rpc.ghost.tzstats.com/ + +export BASE_DIR=$(echo $(pwd))/../../../.. +export CONFIG_DIR=$BASE_DIR/devnet/docker/icon-tezos +export TEZOS_SETTER=$BASE_DIR/tezos-addresses +export JAVASCORE_DIR=$BASE_DIR/javascore +export SMARTPY_DIR=$BASE_DIR/smartpy +export CONTRACTS_DIR=$BASE_DIR +export TZ_NATIVE_COIN_NAME=btp-$TEZOS_BMC_NID.XTZ +export TZ_COIN_SYMBOL=XTZ +export TZ_FIXED_FEE=0 +export TZ_NUMERATOR=0 +export TZ_DECIMALS=6 +export ICON_NATIVE_COIN_NAME=btp-$ICON_NET_ID.icon-ICX +export ICON_SYMBOL=ICX +export ICON_FIXED_FEE=4300000000000000000 +export ICON_NUMERATOR=100 +export ICON_DECIMALS=18 +export FEE_GATHERING_INTERVAL=43200 +export RELAYER_ADDRESS=tz1ZPVxKiybvbV1GvELRJJpyE1xj1UpNpXMv +export ICON_ZERO_ADDRESS=cx0000000000000000000000000000000000000000 + +tz_lastBlock() { + octez-client rpc get /chains/main/blocks/head/header +} + +extract_chainHeight() { + cd $CONFIG_DIR/_ixh + local tz_block_height=$(tz_lastBlock | jq -r .level) + echo $tz_block_height > tz.chain.height +} + +ensure_config_dir() { + echo ensuring config dir + cd $CONFIG_DIR + if [ ! -d _ixh ]; then + echo _ixh not found so creating one + mkdir _ixh + fi + if [ ! -d $CONFIG_DIR/_ixh/tx ]; then + echo tx not found so creating one + cd _ixh + mkdir tx + fi +} + +ensure_tezos_keystore(){ + echo "ensuring key store" + cd $CONFIG_DIR/_ixh/keystore + if [ ! -f tz.bmr.wallet ]; then + echo "creating tezos bmr wallet" + octez-client forget address bmr --force + octez-client gen keys bmr + local keystore=$(echo $(octez-client show address bmr -S)) + local keystoreClone=$keystore + keystore_secret=${keystore#*Secret Key: unencrypted:} + keystore_hash=${keystoreClone#*Hash: } + keystore_hash=${keystore_hash%% *} + echo $keystore_hash > tz.bmr.wallet + echo $keystore_secret > tz.bmr.wallet.secret + fi + + # cd $(echo $SMARTPY_DIR/bmc) + # if [ -f .env ]; then + # echo ".env found" + # octez-client forget address bmcOwner --force + # octez-client gen keys bmcOwner + # local keystore=$(echo $(octez-client show address bmcOwner -S)) + # local keystoreClone=$keystore + # keystore_secret=${keystore#*Secret Key: unencrypted:} + # keystore_hash=${keystoreClone#*Hash: } + # keystore_hash=${keystore_hash%% *} + # echo $keystore_hash > tz.bmc.wallet + # echo $keystore_secret > .env + # fi + + # cd $SMARTPY_DIR/bts + # if [ -f .env ]; then + # echo ".env found" + # octez-client forget address btsOwner --force + # octez-client gen keys btsOwner + # local keystore=$(echo $(octez-client show address btsOwner -S)) + # local keystoreClone=$keystore + # keystore_secret=${keystore#*Secret Key: unencrypted:} + # keystore_hash=${keystoreClone#*Hash: } + # keystore_hash=${keystore_hash%% *} + # echo $keystore_hash > tz.bts.wallet + # echo $keystore_secret > .env + # fi + +} + +ensure_key_secret() { + if [ $# -lt 1 ] ; then + echo "Usage: ensure_key_secret SECRET_PATH" + return 1 + fi + local KEY_SECRET=$1 + if [ ! -f "${KEY_SECRET}" ]; then + mkdir -p $(dirname ${KEY_SECRET}) + echo -n $(openssl rand -hex 20) > ${KEY_SECRET} + fi + echo ${KEY_SECRET} +} + +ensure_key_store() { + if [ $# -lt 2 ] ; then + echo "Usage: ensure_key_store KEYSTORE_PATH SECRET_PATH" + return 1 + fi + local KEY_STORE=$1 + local KEY_SECRET=$(ensure_key_secret $2) + if [ ! -f "${KEY_STORE}" ]; then + echo should not reach here + goloop ks gen --out ${KEY_STORE}tmp -p $(cat ${KEY_SECRET}) > /dev/null 2>&1 + cat ${KEY_STORE}tmp | jq -r . > ${KEY_STORE} + rm ${KEY_STORE}tmp + + fi + echo ${KEY_STORE} +} + +fund_it_flag() { + cd $CONFIG_DIR + if [ ! -f fundit.flag ]; then + echo Fund the recently created wallet and run the script once again + echo icon bmc wallet: $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json | jq -r .address) + echo icon bts wallet: $(cat $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json | jq -r .address) + echo icon bmr wallet: $(cat $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.json | jq -r .address) + echo icon fa wallet : $(cat $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.json | jq -r .address) + echo tz bmr wallet : $(cat $CONFIG_DIR/_ixh/keystore/tz.bmr.wallet) + + # echo tz bmc wallet : $(cat $SMARTPY_DIR/bmc/tz.bmc.wallet) + # echo tz bts wallet : $(cat $SMARTPY_DIR/bts/tz.bts.wallet) + + echo fund it flag > fundit.flag + exit 0 + fi +} + +deploy_smartpy_bmc_management(){ + cd $(echo $SMARTPY_DIR/bmc) + if [ ! -f $CONDIG_DIR/_ixh/tz.addr.bmcmanagementbtp ]; then + echo "deploying bmc_management" + extract_chainHeight + cd $SMARTPY_DIR/bmc + npm run compile bmc_management + local deploy=$(npm run deploy bmc_management @GHOSTNET) + sleep 5 + deploy=${deploy#*::} + echo $deploy > $CONFIG_DIR/_ixh/tz.addr.bmc_management + cd $CONFIG_DIR/_ixh + echo "btp://$(echo $TEZOS_BMC_NID)/$(cat tz.addr.bmc_management)" > $CONFIG_DIR/_ixh/tz.addr.bmcmanagementbtp + fi +} + +deploy_smartpy_bmc_periphery(){ + cd $(echo $SMARTPY_DIR/bmc) + if [ ! -f $CONDIG_DIR/_ixh/tz.addr.bmcperipherybtp ]; then + echo "deploying bmc_periphery" + npm run compile bmc_periphery + local deploy=$(npm run deploy bmc_periphery @GHOSTNET) + sleep 5 + deploy=${deploy#*::} + echo $deploy > $CONFIG_DIR/_ixh/tz.addr.bmc_periphery + cd $CONFIG_DIR/_ixh + echo "btp://$(echo $TEZOS_BMC_NID)/$(cat tz.addr.bmc_periphery)" > $CONFIG_DIR/_ixh/tz.addr.bmcperipherybtp + fi +} + +deploy_smartpy_bts_periphery(){ + cd $(echo $SMARTPY_DIR/bts) + if [ ! -f $CONDIG_DIR/_ixh/tz.addr.bts_periphery ]; then + echo "deploying bts_periphery" + npm run compile bts_periphery + local deploy=$(npm run deploy bts_periphery @GHOSTNET) + sleep 5 + deploy=${deploy#*::} + echo $deploy > $CONFIG_DIR/_ixh/tz.addr.bts_periphery + fi +} + +deploy_smartpy_bts_core(){ + cd $(echo $SMARTPY_DIR/bts) + if [ ! -f $CONDIG_DIR/_ixh/tz.addr.bts_core ]; then + echo "deploying bts_core" + npm run compile bts_core + local deploy=$(npm run deploy bts_core @GHOSTNET) + sleep 5 + deploy=${deploy#*::} + echo $deploy > $CONFIG_DIR/_ixh/tz.addr.bts_core + fi +} + +deploy_smartpy_bts_owner_manager(){ + cd $(echo $SMARTPY_DIR/bts) + if [ ! -f $CONDIG_DIR/_ixh/tz.addr.bts_owner_manager ]; then + echo "deploying bts_owner_manager" + npm run compile bts_owner_manager + local deploy=$(npm run deploy bts_owner_manager @GHOSTNET) + sleep 5 + deploy=${deploy#*::} + echo $deploy > $CONFIG_DIR/_ixh/tz.addr.bts_owner_manager + fi +} + +ensure_txresult() { + OLD_SET_OPTS=$(set +o) + set +e + local TX=$1 + + if [ -f "${TX}" ]; then + TX=$(cat ${TX}) + fi + + sleep 2 + RESULT=$(goloop rpc txresult ${TX} --uri $ICON_NET_URI) + RET=$? + echo $RESULT + while [ "$RET" != "0" ] && [ "$(echo $RESULT | grep -E 'Executing|Pending')" == "$RESULT" ]; do + sleep 1 + RESULT=$(goloop rpc txresult ${TX} --rui $ICON_NET_URI) + RET=$? + echo $RESULT + done + eval "${OLD_SET_OPTS}" + set -e + if [ "$RET" != "0" ]; then + echo $RESULT + return $RET + else + STATUS=$(echo $RESULT | jq -r .status) + if [ "$STATUS" == "0x1" ]; then + return 0 + else + echo $RESULT + return 1 + fi + fi +} + +extract_scoreAddress() { + local TX=$1 + local ADDR=$2 + + RESULT=$(ensure_txresult $TX) + RET=$? + + if [ "$RET" != "0" ]; then + echo $RESULT + return $RET + else + SCORE=$(echo $RESULT | jq -r .scoreAddress) + echo $SCORE | tee ${ADDR} + fi +} + + +configure_smartpy_bmc_management_set_bmc_periphery() { + echo "Adding BMC periphery in bmc management" + cd $(echo $CONFIG_DIR/_ixh) + + local bmc_periphery=$(echo $(cat tz.addr.bmc_periphery)) + echo $bmc_periphery + + local bmc_management=$(echo $(cat tz.addr.bmc_management)) + echo $bmc_management + + local ocBR=\'\" + local coBR=\"\' + local arg=$(echo $(echo $ocBR$(echo $bmc_periphery$(echo $coBR)))) + + echo $arg + + # octez-client transfer 0 from bmcOwner to KT1BE6ohnjunYd1C96yPaThwNvFZu4TN8iBy --entrypoint set_bmc_periphery --arg '"KT1JX3Z3AQnf6oDae87Z9mw1g4jhB38tAGQY"' --burn-cap 1 + echo octez-client transfer 0 from bmcOwner to $(echo $bmc_management) --entrypoint set_bmc_periphery --arg $(echo $arg) --burn-cap 1 +} + +configure_dotenv() { + echo "Configuring .env file for running the setter script" + cd $(echo $CONFIG_DIR/_ixh) + local bmc_periphery=$(echo $(cat tz.addr.bmc_periphery)) + local bmc_management=$(echo $(cat tz.addr.bmc_management)) + local bmc_height=$(echo $(cat tz.chain.height)) + local icon_bmc_height=$(echo $(cat icon.chain.height)) + local icon_bmc=$(echo $(cat icon.addr.bmc)) + echo $bmc_periphery + + local bts_core=$(echo $(cat tz.addr.bts_core)) + local bts_owner_manager=$(echo $(cat tz.addr.bts_owner_manager)) + local bts_periphery=$(echo $(cat tz.addr.bts_periphery)) + + cd $SMARTPY_DIR/bmc + local env=$(cat .env) + env=${env#*=} + local secret_deployer=$(echo "secret_deployer=$(echo $env)") + + cd $(echo $TEZOS_SETTER) + go mod tidy + if [ -f .env ]; then + echo ".env exists so removing" + rm .env + fi + touch .env + local output=.env + + + local TZ_NETWORK=$(echo "TZ_NETWORK=$(echo $TEZOS_BMC_NID)") + local ICON_NETWORK=$(echo "ICON_NETWORK=$(echo $ICON_BMC_NID)") + local TEZOS_NATIVE_COIN_NAME=$(echo "TZ_NATIVE_COIN_NAME=btp-$(echo $TEZOS_BMC_NID)-XTZ") + local TEZOS_SYMBOL=$(echo "TZ_SYMBOL=$(echo $TZ_COIN_SYMBOL)") + local TEZ_FIXED_FEE=$(echo "TZ_FIXED_FEE=$(echo $TZ_FIXED_FEE)") + + local TEZ_NUMERATOR=$(echo "TZ_NUMERATOR=$(echo $TZ_NUMERATOR)") + local TEZ_DECIMALS=$(echo "TZ_DECIMALS=$(echo $TZ_DECIMALS)") + local IC_NATIVE_COIN_NAME=$(echo "ICON_NATIVE_COIN_NAME=$(echo $ICON_NATIVE_COIN_NAME)") + + local IC_SYMBOL=$(echo "ICON_SYMBOL=$(echo $ICON_SYMBOL)") + + local IC_FIXED_FEE=$(echo "ICON_FIXED_FEE=$(echo $ICON_FIXED_FEE)") + + local IC_NUMERATOR=$(echo "ICON_NUMERATOR=$(echo $ICON_NUMERATOR)") + local IC_DECIMALS=$(echo "ICON_DECIMALS=$(echo $ICON_DECIMALS)") + + local BMC_PERIPHERY=$(echo "BMC_PERIPHERY=$(echo $bmc_periphery)") + local BMC_MANAGEMENT=$(echo "BMC_MANAGEMENT=$(echo $bmc_management)") + local BMC_HEIGHT=$(echo "bmc_periphery_height=$(echo $bmc_height)") + + local BTS_PERIPHERY=$(echo "BTS_PERIPHERY=$(echo $bts_periphery)") + local BTS_CORE=$(echo "BTS_CORE=$(echo $bts_core)") + local BTS_OWNER_MANAGER=$(echo "BTS_OWNER_MANAGER=$(echo $bts_owner_manager)") + local RELAY_ADDRESS=$(echo "RELAYER_ADDRESS=$(echo $(cat $CONFIG_DIR/_ixh/keystore/tz.bmr.wallet))") + local ICON_BMC=$(echo "ICON_BMC=$(echo $icon_bmc)") + local ICON_RX_HEIGHT=$(echo "ICON_RX_HEIGHT=$(echo $icon_bmc_height)") + local TEZOS_ENDPOINT=$(echo "TEZOS_ENDPOINT=$(echo $TZ_NET_URI)") + + + echo $secret_deployer>>$output + + echo $TZ_NETWORK>>$output + echo $ICON_NETWORK>>$output + echo $TEZOS_NATIVE_COIN_NAME>>$output + echo $TEZOS_SYMBOL>>$output + echo $TEZ_FIXED_FEE>>$output + echo $TEZ_NUMERATOR>>$output + echo $TEZ_DECIMALS>>$output + echo $IC_NATIVE_COIN_NAME>>$output + echo $IC_SYMBOL>>$output + echo $IC_FIXED_FEE>>$output + echo $IC_NUMERATOR>>$output + echo $IC_DECIMALS>>$output + echo $BMC_PERIPHERY>>$output + echo $BMC_MANAGEMENT>>$output + echo $BMC_HEIGHT>>$output + echo $BTS_PERIPHERY>>$output + echo $BTS_CORE>>$output + echo $BTS_OWNER_MANAGER>>$output + echo $RELAY_ADDRESS>>$output + echo $ICON_BMC>>$output + echo $ICON_RX_HEIGHT>>$output + echo $TEZOS_ENDPOINT>>$output +} + +run_tezos_setters(){ + cd $(echo $TEZOS_SETTER) + go run main.go +} + + +# build java scores +build_javascores(){ + echo in java score + cd $JAVASCORE_DIR + ./gradlew bmc:optimizedJar + ./gradlew bts:optimizedJar + ./gradlew irc2Tradeable:optimizedJar + + # irc2-token + if [ ! -f irc2.jar ]; then + git clone https://github.com/icon-project/java-score-examples.git + cd java-score-examples + ./gradlew irc2-token:clean + ./gradlew irc2-token:optimizedJar + cp irc2-token/build/libs/irc2-token-0.9.1-optimized.jar $JAVASCORE_DIR/irc2.jar + rm -rf $JAVASCORE_DIR/java-score-examples + fi + + cd $JAVASCORE_DIR + cp bmc/build/libs/bmc-optimized.jar $JAVASCORE_DIR/bmc.jar + cp bts/build/libs/bts-optimized.jar $JAVASCORE_DIR/bts.jar + cp irc2Tradeable/build/libs/irc2Tradeable-0.1.0-optimized.jar $JAVASCORE_DIR/irc2Tradeable.jar +} + + + +# deploy java scores + +goloop_lastblock() { + goloop rpc lastblock --uri $ICON_NET_URI +} + +extract_chain_height_and_validator() { + cd $CONFIG_DIR/_ixh + local icon_block_height=$(goloop_lastblock | jq -r .height) + echo $icon_block_height > icon.chain.height + + local validator=$(HEIGHT=0x1 URI=$ICON_NET_URI $BASE_DIR/cmd/iconvalidators/./iconvalidators | jq -r .hash) + echo $validator > icon.chain.validators +} + +deploy_javascore_bmc() { + cd $CONFIG_DIR/_ixh + if [ ! -f icon.addr.bmcbtp ]; then + echo "deploying javascore BMC" + extract_chain_height_and_validator + goloop rpc sendtx deploy $CONTRACTS_DIR/javascore/bmc.jar \ + --content_type application/java \ + --param _net=$ICON_BMC_NID \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret)) \ + --nid $ICON_NET_ID \ + --step_limit 4000000000 \ + --uri $ICON_NET_URI | jq -r . >tx/tx.icon.bmc + sleep 5 + echo $(pwd) + extract_scoreAddress tx/tx.icon.bmc icon.addr.bmc + echo "btp://$(echo $ICON_BMC_NID)/$(cat icon.addr.bmc)" >icon.addr.bmcbtp + fi +} + +deploy_javascore_bts() { + echo "deploying javascore bts" + cd $CONFIG_DIR/_ixh + if [ ! -f icon.addr.bts ]; then + #local bts_fee_numerator=100 + #local bts_fixed_fee=5000 + goloop rpc sendtx deploy $CONTRACTS_DIR/javascore/bts.jar \ + --content_type application/java \ + --param _name=$ICON_NATIVE_COIN_NAME \ + --param _bmc=$(cat icon.addr.bmc) \ + --param _decimals=$(decimal2Hex $3) \ + --param _feeNumerator=$(decimal2Hex $2) \ + --param _fixedFee=$(decimal2Hex $1) \ + --param _serializedIrc2=$(xxd -p $CONTRACTS_DIR/javascore/irc2Tradeable.jar | tr -d '\n') \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.secret)) \ + --step_limit 4000000000 \ + --nid $ICON_NET_ID \ + --uri $ICON_NET_URI | jq -r . > tx/tx.icon.bts + sleep 5 + extract_scoreAddress tx/tx.icon.bts icon.addr.bts + fi +} + +deploy_javascore_token() { + echo "deploying javascore IRC2Token " $2 + cd $CONFIG_DIR/_ixh + if [ ! -f icon.addr.$2 ]; then + goloop rpc sendtx deploy $CONTRACTS_DIR/javascore/irc2.jar \ + --content_type application/java \ + --param _name="$1" \ + --param _symbol=$2 \ + --param _initialSupply="0x5f5e100" \ + --param _decimals="0x12" \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.secret)) \ + --nid $ICON_NET_ID \ + --step_limit 4000000000 \ + --uri $ICON_NET_URI | jq -r . >tx/tx.icon.$2 + sleep 5 + extract_scoreAddress tx/tx.icon.$2 icon.addr.$2 + fi +} + + +configure_javascore_add_bmc_owner() { + echo "bmc Add Owner" + echo $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json + local icon_bmc_owner=$(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json | jq -r .address) + cd $CONFIG_DIR/_ixh + local is_owner=$(goloop rpc call \ + --to $(cat icon.addr.bmc) \ + --method isOwner \ + --param _addr=$icon_bmc_owner \ + --uri $ICON_NET_URI | jq -r .) + if [ "$is_owner" == "0x0" ]; then + goloop rpc sendtx call --to $(cat icon.addr.bmc) \ + --method addOwner \ + --param _addr=$icon_bmc_owner \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret)) \ + --step_limit 1000000000 \ + --nid $ICON_NET_ID \ + --uri $ICON_NET_URI | jq -r . > tx/addbmcowner.icon + sleep 3 + ensure_txresult tx/addbmcowner.icon + fi +} + +configure_javascore_bmc_setFeeAggregator() { + echo "bmc setFeeAggregator" + cd $CONFIG_DIR/_ixh + local FA=$(cat $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.json | jq -r .address) + goloop rpc sendtx call --to $(cat icon.addr.bmc) \ + --method setFeeAggregator \ + --param _addr=${FA} \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret)) \ + --step_limit 1000000000 \ + --nid $ICON_NET_ID \ + --uri $ICON_NET_URI | jq -r . >tx/setFeeAggregator.icon + sleep 3 + ensure_txresult tx/setFeeAggregator.icon + + goloop rpc sendtx call --to $(cat icon.addr.bmc) \ + --method setFeeGatheringTerm \ + --param _value=$FEE_GATHERING_INTERVAL \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret)) \ + --step_limit 1000000000 \ + --nid $ICON_NET_ID \ + --uri $ICON_NET_URI | jq -r . >tx/setFeeGatheringTerm.icon + sleep 3 + ensure_txresult tx/setFeeGatheringTerm.icon +} + +configure_javascore_add_bts() { + echo "bmc add bts" + cd $CONFIG_DIR/_ixh + local hasBTS=$(goloop rpc call \ + --to $(cat icon.addr.bmc) \ + --method getServices \ + --uri $ICON_NET_URI | jq -r .bts) + if [ "$hasBTS" == "null" ]; then + goloop rpc sendtx call --to $(cat icon.addr.bmc) \ + --method addService \ + --value 0 \ + --param _addr=$(cat icon.addr.bts) \ + --param _svc="bts" \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret)) \ + --step_limit 1000000000 \ + --nid $ICON_NET_ID \ + --uri $ICON_NET_URI | jq -r . >tx/addService.icon + sleep 3 + ensure_txresult tx/addService.icon + fi + sleep 5 +} + +configure_javascore_add_bts_owner() { + echo "Add bts Owner" + local icon_bts_owner=$(cat $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json | jq -r .address) + cd $CONFIG_DIR/_ixh + local is_owner=$(goloop rpc call \ + --to $(cat icon.addr.bts) \ + --method isOwner \ + --param _addr="$icon_bts_owner" \ + --uri $ICON_NET_URI | jq -r .) + if [ "$is_owner" == "0x0" ]; then + goloop rpc sendtx call --to $(cat icon.addr.bts) \ + --method addOwner \ + --param _addr=$icon_bts_owner \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.secret)) \ + --step_limit 1000000000 \ + --nid $ICON_NET_ID \ + --uri $ICON_NET_URI | jq -r . >tx/addBtsOwner.icon + sleep 3 + ensure_txresult tx/addBtsOwner.icon + fi +} + +configure_javascore_bts_setICXFee() { + echo "bts set fee" $ICON_SYMBOL + #local bts_fee_numerator=100 + #local bts_fixed_fee=5000 + cd $CONFIG_DIR/_ixh + goloop rpc sendtx call --to $(cat icon.addr.bts) \ + --method setFeeRatio \ + --param _name=$ICON_NATIVE_COIN_NAME \ + --param _feeNumerator=$(decimal2Hex $2) \ + --param _fixedFee=$(decimal2Hex $1) \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.secret)) \ + --nid $ICON_NET_ID \ + --step_limit 1000000000 \ + --uri $ICON_NET_URI | jq -r . >tx/setICXFee.icon + sleep 3 + ensure_txresult tx/setICXFee.icon +} + +configure_javascore_register_native_token() { + echo "Register Native Token " $2 + cd $CONFIG_DIR/_ixh + #local bts_fee_numerator=100 + #local bts_fixed_fee=5000 + if [ ! -f icon.register.coin$2 ]; then + goloop rpc sendtx call --to $(cat icon.addr.bts) \ + --method register \ + --param _name=$1 \ + --param _symbol=$2 \ + --param _decimals=$(decimal2Hex $5) \ + --param _addr=$ICON_ZERO_ADDRESS \ + --param _feeNumerator=$(decimal2Hex $4) \ + --param _fixedFee=$(decimal2Hex $3) \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.secret)) \ + --nid $ICON_NET_ID \ + --step_limit 4000000000 \ + --uri $ICON_NET_URI | jq -r . >tx/register.coin.$2 + sleep 5 + ensure_txresult tx/register.coin.$2 + echo "registered "$2 > icon.register.coin$2 + fi +} + + + + +configure_javascore_addLink() { + echo "BMC: Add Link to BSC BMC:" + cd $CONFIG_DIR/_ixh + if [ ! -f icon.configure.addLink ]; then + goloop rpc sendtx call --to $(cat icon.addr.bmc) \ + --method addLink \ + --param _link=$(cat tz.addr.bmcperipherybtp) \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret)) \ + --nid $ICON_NET_ID \ + --step_limit 1000000000 \ + --uri $ICON_NET_URI | jq -r . > addLink.icon + + sleep 3 + echo "addedLink" > icon.configure.addLink + fi +} + +configure_javascore_setLinkHeight() { + echo "BMC: SetLinkHeight" + cd $CONFIG_DIR/_ixh + if [ ! -f icon.configure.setLink ]; then + goloop rpc sendtx call --to $(cat icon.addr.bmc) \ + --method setLinkRxHeight \ + --param _link=$(cat tz.addr.bmcperipherybtp) \ + --param _height=$(cat tz.chain.height) \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret)) \ + --nid $ICON_NET_ID \ + --step_limit 1000000000 \ + --uri $ICON_NET_URI | jq -r . > setLinkRxHeight.icon + + sleep 3 + echo "setLink" > icon.configure.setLink + fi +} + +configure_bmc_javascore_addRelay() { + echo "Adding bsc Relay" + local icon_bmr_owner=$(cat $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.json | jq -r .address) + echo $icon_bmr_owner + sleep 5 + echo "Starting" + cd $CONFIG_DIR/_ixh + if [ ! -f icon.configure.addRelay ]; then + goloop rpc sendtx call --to $(cat icon.addr.bmc) \ + --method addRelay \ + --param _link=$(cat tz.addr.bmcperipherybtp) \ + --param _addr=${icon_bmr_owner} \ + --key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json \ + --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret)) \ + --nid $ICON_NET_ID \ + --step_limit 1000000000 \ + --uri $ICON_NET_URI | jq -r . > addRelay.icon + + sleep 3 + echo "addRelay" > icon.configure.addRelay + fi +} + +decimal2Hex() { + hex=$(echo "obase=16; ibase=10; ${@}" | bc) + echo "0x$(tr [A-Z] [a-z] <<< "$hex")" +} + + +configure_relay_config() { + jq -n ' + .base_dir = $base_dir | + .log_level = "debug" | + .console_level = "trace" | + .log_writer.filename = $log_writer_filename | + .relays = [ $b2i_relay, $i2b_relay ]' \ + --arg base_dir "bmr" \ + --arg log_writer_filename "bmr/bmr.log" \ + --argjson b2i_relay "$( + jq -n ' + .name = "t2i" | + .src.address = $src_address | + .src.endpoint = [ $src_endpoint ] | + .src.options.verifier.blockHeight = $src_options_verifier_blockHeight | + .src.options.syncConcurrency = 100 | + .src.options.bmcManagement = $bmc_management | + .src.offset = $src_offset | + .dst.address = $dst_address | + .dst.endpoint = [ $dst_endpoint ] | + .dst.options = $dst_options | + .dst.key_store = $dst_key_store | + .dst.key_store.coinType = $dst_key_store_cointype | + .dst.key_password = $dst_key_password ' \ + --arg src_address "$(cat $CONFIG_DIR/_ixh/tz.addr.bmcperipherybtp)" \ + --arg src_endpoint "$TZ_NET_URI" \ + --argjson src_offset $(cat $CONFIG_DIR/_ixh/tz.chain.height) \ + --argjson src_options_verifier_blockHeight $(cat $CONFIG_DIR/_ixh/tz.chain.height) \ + --arg bmc_management "$(cat $CONFIG_DIR/_ixh/tz.addr.bmc_management)" \ + --arg dst_address "$(cat $CONFIG_DIR/_ixh/icon.addr.bmcbtp)" \ + --arg dst_endpoint "$ICON_NET_URI" \ + --argfile dst_key_store "$CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.json" \ + --arg dst_key_store_cointype "icx" \ + --arg dst_key_password "$(cat $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.secret)" \ + --argjson dst_options '{"step_limit":2500000000, "tx_data_size_limit":8192,"balance_threshold":"10000000000000000000"}' + )" \ + --argjson i2b_relay "$( + jq -n ' + .name = "i2t" | + .src.address = $src_address | + .src.endpoint = [ $src_endpoint ] | + .src.offset = $src_offset | + .src.options.verifier.blockHeight = $src_options_verifier_blockHeight | + .src.options.verifier.validatorsHash = $src_options_verifier_validatorsHash | + .src.options.syncConcurrency = 100 | + .dst.address = $dst_address | + .dst.endpoint = [ $dst_endpoint ] | + .dst.options = $dst_options | + .dst.options.bmcManagement = $bmc_management | + .dst.tx_data_size_limit = $dst_tx_data_size_limit | + .dst.key_store.address = $dst_key_store | + .dst.key_store.coinType = $dst_key_store_cointype | + .dst.key_store.crypto.cipher = $secret | + .dst.key_password = $dst_key_password ' \ + --arg src_address "$(cat $CONFIG_DIR/_ixh/icon.addr.bmcbtp)" \ + --arg src_endpoint "$ICON_NET_URI" \ + --argjson src_offset $(cat $CONFIG_DIR/_ixh/icon.chain.height) \ + --argjson src_options_verifier_blockHeight $(cat $CONFIG_DIR/_ixh/icon.chain.height) \ + --arg src_options_verifier_validatorsHash "$(cat $CONFIG_DIR/_ixh/icon.chain.validators)" \ + --arg dst_address "$(cat $CONFIG_DIR/_ixh/tz.addr.bmcperipherybtp)" \ + --arg dst_endpoint "$TZ_NET_URI" \ + --arg dst_key_store "$RELAYER_ADDRESS" \ + --arg dst_key_store_cointype "xtz" \ + --arg secret "edskRz1HoD3cWkmWhCNS5LjBrJNWChGuKWB4HnVoN5UqVsUCpcNJR67ZxKs965u8RgRwptrtGc2ufYZoeECgB77RKm1gTbQ6eB" \ + --arg dst_key_password "xyz" \ + --argjson dst_tx_data_size_limit 8192 \ + --argjson dst_options '{"gas_limit":24000000,"tx_data_size_limit":8192,"balance_threshold":"100000000000000000000","boost_gas_price":1.0}' \ + --arg bmc_management "$(cat $CONFIG_DIR/_ixh/tz.addr.bmc_management)" + )" +} + +start_relay() { + cd $BASE_DIR/cmd/iconbridge + go run main.go -config $CONFIG_DIR/_ixh/relay.config.json +} + + +# ensure_config_dir +# ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.secret +# ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret +# ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.secret +# ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.json $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.secret +# ensure_tezos_keystore +# fund_it_flag + +# build_javascores +# deploy_javascore_bmc +# deploy_javascore_bts 0 0 18 +# # deploy_javascore_token + +# configure_javascore_add_bmc_owner +# configure_javascore_add_bts +# configure_javascore_add_bts_owner +# configure_javascore_bmc_setFeeAggregator +# configure_javascore_bts_setICXFee 0 0 +# configure_javascore_register_native_token $TZ_NATIVE_COIN_NAME $TZ_COIN_SYMBOL $TZ_FIXED_FEE $TZ_NUMERATOR $TZ_DECIMALS + + + +# # # # tezos configuration +# deploy_smartpy_bmc_management +# deploy_smartpy_bmc_periphery +# deploy_smartpy_bts_periphery +# deploy_smartpy_bts_core +# deploy_smartpy_bts_owner_manager +configure_dotenv +run_tezos_setters + +# # # # icon configuration of tezos +# configure_javascore_addLink +# configure_javascore_setLinkHeight +# configure_bmc_javascore_addRelay + + +# configure_relay_config > $CONFIG_DIR/_ixh/relay.config.json +# start_relay + + + + From ddddc7be4adf674cf49ecf36d7dd9b7f205b532f Mon Sep 17 00:00:00 2001 From: icondev22 Date: Fri, 18 Aug 2023 06:56:32 +0545 Subject: [PATCH 193/211] chore: added documentation for ICON Tezos bmr impl --- docs/getting-started.md | 1 + docs/icon-tezos/getting-started.md | 53 ++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 docs/icon-tezos/getting-started.md diff --git a/docs/getting-started.md b/docs/getting-started.md index 08d453ec..c9ef345e 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -25,6 +25,7 @@ Get familiar with some terminologies used in icon-bridge [here.](terminologies.m | /docker | Scripts to create docker containers (Some of it Obsolete) | | /javascore | javascore smart contracts | | /solidity | solidity smart contracts | +| /smartpy | tezos smart contracts | >TLDR version of deployment is available [here](#tdlr) diff --git a/docs/icon-tezos/getting-started.md b/docs/icon-tezos/getting-started.md new file mode 100644 index 00000000..f49a472b --- /dev/null +++ b/docs/icon-tezos/getting-started.md @@ -0,0 +1,53 @@ +# Getting Started +This section is for deployment of ICON-Tezos bridge in the testnet. This file also documents all the dependencies and prerequisits that are necessary for the bridge. + +## Setting up on ICON +Install `goloop` cli for interacting with the ICON chain. + +``` + https://github.com/icon-project/goloop/blob/master/doc/build.md +``` + +## Setting up on Tezos +Install `octez-client`, cli tool in tezos for interacting with the Tezos chain. + +``` +https://opentezos.com/tezos-basics/cli-and-rpc/ +``` +Once the `octez-client` is all set, you will have to change the network that your `octez-client` is connected to. + +```sh +octez-client --endpoint https://ghostnet.tezos.marigold.dev config update +``` + +## ICON Tezos Bridge Configuration(Testnet) +For the complete deployment, build and running the relay navigate to +```sh +$ cd $BASE_DIR/devnet/docker/icon-tezos/scripts +$ bash testnet.i2t.bmr.sh +``` +When running the script, first wallets are created and we wil have to fund the wallets using the faucet of the respective chains. + +For example you will get a message like this. +``` +Fund the recently created wallet and run the script once again +icon bmc wallet: hxbc77026b7c3823744d5746507ab5bdb570ef9ca3 +icon bts wallet: hx05256b36068144ec4523fd3943966ea018208ddb +icon bmr wallet: hx416d86b01f48ffe425a8a8a5f61182b1c17a339d +icon fa wallet : hxb7d5d680576de816459ad7b4af659886b2b0e4e3 +tz bmr wallet : tz1dxhHuEcZNXoFyX3PX5A8NNpWnJ3MKHDY2 +``` +Fund the icon wallets using the faucet +``` +https://faucet.iconosphere.io/ +``` +Fund the tezos wallets using the faucet +``` +https://faucet.marigold.dev/ +``` + +Rerun the script again and wait for the relay to start. This script will deploy the ICON smart contracts, Tezos smart contracts and register the native coin of the destination chains in its own chain. + +```sh +$ bash testnet.i2t.bmr.sh +``` \ No newline at end of file From e27f88771147d0edcbaa587b0efe4cc989e867b2 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Fri, 18 Aug 2023 06:57:49 +0545 Subject: [PATCH 194/211] fix: removed token.smartpy.sh --- .../icon-tezos/scripts/token.smartpy.sh | 769 ------------------ 1 file changed, 769 deletions(-) delete mode 100755 devnet/docker/icon-tezos/scripts/token.smartpy.sh diff --git a/devnet/docker/icon-tezos/scripts/token.smartpy.sh b/devnet/docker/icon-tezos/scripts/token.smartpy.sh deleted file mode 100755 index 9f3a842f..00000000 --- a/devnet/docker/icon-tezos/scripts/token.smartpy.sh +++ /dev/null @@ -1,769 +0,0 @@ -#!/bin/bash -## smarpy service methods - start ### - -# source utils.sh -# source ~/GoProjects/icon-bridge/devnet/docker/icon-bsc/scripts/rpc.sh -# source keystore.sh - -export ICON_NET_ID=0x7 -export ICON_NET_URI=https://berlin.net.solidwallet.io/api/v3/ -export TZ_NET_URI=https://rpc.ghost.tzstats.com/ - -export BASE_DIR=$(echo $(pwd))/../../../.. -export CONFIG_DIR=$BASE_DIR/devnet/docker/icon-tezos -export TEZOS_SETTER=$BASE_DIR/tezos-addresses -export JAVASCORE_DIR=$BASE_DIR/javascore -export SMARTPY_DIR=$BASE_DIR/smartpy -export CONTRACTS_DIR=$BASE_DIR -export TEZOS_BMC_NID=NetXnHfVqm9iesp.tezos -export ICON_BMC_NID=0x7.icon -export TZ_COIN_SYMBOL=XTZ -export TZ_FIXED_FEE=0 -export TZ_NUMERATOR=0 -export TZ_DECIMALS=6 -export ICON_NATIVE_COIN_NAME=btp-0x7.icon-ICX -export ICON_SYMBOL=ICX -export ICON_FIXED_FEE=4300000000000000000 -export ICON_NUMERATOR=100 -export ICON_DECIMALS=18 -export FEE_GATHERING_INTERVAL=43200 -export RELAYER_ADDRESS=tz1ZPVxKiybvbV1GvELRJJpyE1xj1UpNpXMv - - -tz_lastBlock() { - octez-client rpc get /chains/main/blocks/head/header -} - -extract_chainHeight() { - cd $CONFIG_DIR/_ixh - local tz_block_height=$(tz_lastBlock | jq -r .level) - echo $tz_block_height > tz.chain.height -} - -ensure_config_dir() { - echo ensuring config dir - cd $CONFIG_DIR - if [ ! -d _ixh ]; then - echo _ixh not found so creating one - mkdir _ixh - fi - if [ ! -d $CONFIG_DIR/_ixh/tx ]; then - echo tx not found so creating one - cd _ixh - mkdir tx - fi -} - -ensure_tezos_keystore(){ - echo "ensuring key store" - cd $(echo $SMARTPY_DIR/bmc) - if [ -f .env ]; then - echo ".env found" - octez-client forget address bmcOwner --force - octez-client gen keys bmcOwner - local keystore=$(echo $(octez-client show address bmcOwner -S)) - local keystoreClone=$keystore - keystore_secret=${keystore#*Secret Key: unencrypted:} - keystore_hash=${keystoreClone#*Hash: } - keystore_hash=${keystore_hash%% *} - echo $keystore_hash > tz.bmc.wallet - echo $keystore_secret > .env - fi - - cd $SMARTPY_DIR/bts - if [ -f .env ]; then - echo ".env found" - octez-client forget address btsOwner --force - octez-client gen keys btsOwner - local keystore=$(echo $(octez-client show address btsOwner -S)) - local keystoreClone=$keystore - keystore_secret=${keystore#*Secret Key: unencrypted:} - keystore_hash=${keystoreClone#*Hash: } - keystore_hash=${keystore_hash%% *} - echo $keystore_hash > tz.bts.wallet - echo $keystore_secret > .env - fi - -} - -ensure_key_secret() { - if [ $# -lt 1 ] ; then - echo "Usage: ensure_key_secret SECRET_PATH" - return 1 - fi - local KEY_SECRET=$1 - if [ ! -f "${KEY_SECRET}" ]; then - mkdir -p $(dirname ${KEY_SECRET}) - echo -n $(openssl rand -hex 20) > ${KEY_SECRET} - fi - echo ${KEY_SECRET} -} - -ensure_key_store() { - if [ $# -lt 2 ] ; then - echo "Usage: ensure_key_store KEYSTORE_PATH SECRET_PATH" - return 1 - fi - local KEY_STORE=$1 - local KEY_SECRET=$(ensure_key_secret $2) - if [ ! -f "${KEY_STORE}" ]; then - echo should not reach here - goloop ks gen --out ${KEY_STORE}tmp -p $(cat ${KEY_SECRET}) > /dev/null 2>&1 - cat ${KEY_STORE}tmp | jq -r . > ${KEY_STORE} - rm ${KEY_STORE}tmp - - fi - echo ${KEY_STORE} -} - -fund_it_flag() { - cd $CONFIG_DIR - if [ ! -f fundit.flag ]; then - echo Fund the recently created wallet and run the script once again - echo icon bmc wallet: $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json | jq -r .address) - echo icon bts wallet: $(cat $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json | jq -r .address) - echo icon bmr wallet: $(cat $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.json | jq -r .address) - echo icon fa wallet : $(cat $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.json | jq -r .address) - - # echo tz bmc wallet : $(cat $SMARTPY_DIR/bmc/tz.bmc.wallet) - # echo tz bts wallet : $(cat $SMARTPY_DIR/bts/tz.bts.wallet) - - echo fund it flag > fundit.flag - exit 0 - fi -} - -deploy_smartpy_bmc_management(){ - cd $(echo $SMARTPY_DIR/bmc) - if [ ! -f $CONDIG_DIR/_ixh/tz.addr.bmcmanagementbtp ]; then - echo "deploying bmc_management" - extract_chainHeight - cd $SMARTPY_DIR/bmc - npm run compile bmc_management - local deploy=$(npm run deploy bmc_management @GHOSTNET) - sleep 5 - deploy=${deploy#*::} - echo $deploy > $CONFIG_DIR/_ixh/tz.addr.bmc_management - cd $CONFIG_DIR/_ixh - echo "btp://$(echo $TEZOS_BMC_NID)/$(cat tz.addr.bmc_management)" > $CONFIG_DIR/_ixh/tz.addr.bmcmanagementbtp - fi -} - -deploy_smartpy_bmc_periphery(){ - cd $(echo $SMARTPY_DIR/bmc) - if [ ! -f $CONDIG_DIR/_ixh/tz.addr.bmcperipherybtp ]; then - echo "deploying bmc_periphery" - npm run compile bmc_periphery - local deploy=$(npm run deploy bmc_periphery @GHOSTNET) - sleep 5 - deploy=${deploy#*::} - echo $deploy > $CONFIG_DIR/_ixh/tz.addr.bmc_periphery - cd $CONFIG_DIR/_ixh - echo "btp://$(echo $TEZOS_BMC_NID)/$(cat tz.addr.bmc_periphery)" > $CONFIG_DIR/_ixh/tz.addr.bmcperipherybtp - fi -} - -deploy_smartpy_bts_periphery(){ - cd $(echo $SMARTPY_DIR/bts) - if [ ! -f $CONDIG_DIR/_ixh/tz.addr.bts_periphery ]; then - echo "deploying bts_periphery" - npm run compile bts_periphery - local deploy=$(npm run deploy bts_periphery @GHOSTNET) - sleep 5 - deploy=${deploy#*::} - echo $deploy > $CONFIG_DIR/_ixh/tz.addr.bts_periphery - fi -} - -deploy_smartpy_bts_core(){ - cd $(echo $SMARTPY_DIR/bts) - if [ ! -f $CONDIG_DIR/_ixh/tz.addr.bts_core ]; then - echo "deploying bts_core" - npm run compile bts_core - local deploy=$(npm run deploy bts_core @GHOSTNET) - sleep 5 - deploy=${deploy#*::} - echo $deploy > $CONFIG_DIR/_ixh/tz.addr.bts_core - fi -} - -deploy_smartpy_bts_owner_manager(){ - cd $(echo $SMARTPY_DIR/bts) - if [ ! -f $CONDIG_DIR/_ixh/tz.addr.bts_owner_manager ]; then - echo "deploying bts_owner_manager" - npm run compile bts_owner_manager - local deploy=$(npm run deploy bts_owner_manager @GHOSTNET) - sleep 5 - deploy=${deploy#*::} - echo $deploy > $CONFIG_DIR/_ixh/tz.addr.bts_owner_manager - fi -} - -ensure_txresult() { - OLD_SET_OPTS=$(set +o) - set +e - local TX=$1 - - if [ -f "${TX}" ]; then - TX=$(cat ${TX}) - fi - - sleep 2 - RESULT=$(goloop rpc txresult ${TX} --uri $ICON_NET_URI) - RET=$? - echo $RESULT - while [ "$RET" != "0" ] && [ "$(echo $RESULT | grep -E 'Executing|Pending')" == "$RESULT" ]; do - sleep 1 - RESULT=$(goloop rpc txresult ${TX} --rui $ICON_NET_URI) - RET=$? - echo $RESULT - done - eval "${OLD_SET_OPTS}" - set -e - if [ "$RET" != "0" ]; then - echo $RESULT - return $RET - else - STATUS=$(echo $RESULT | jq -r .status) - if [ "$STATUS" == "0x1" ]; then - return 0 - else - echo $RESULT - return 1 - fi - fi -} - -extract_scoreAddress() { - local TX=$1 - local ADDR=$2 - - RESULT=$(ensure_txresult $TX) - RET=$? - - if [ "$RET" != "0" ]; then - echo $RESULT - return $RET - else - SCORE=$(echo $RESULT | jq -r .scoreAddress) - echo $SCORE | tee ${ADDR} - fi -} - - -configure_smartpy_bmc_management_set_bmc_periphery() { - echo "Adding BMC periphery in bmc management" - cd $(echo $CONFIG_DIR/_ixh) - - local bmc_periphery=$(echo $(cat tz.addr.bmc_periphery)) - echo $bmc_periphery - - local bmc_management=$(echo $(cat tz.addr.bmc_management)) - echo $bmc_management - - local ocBR=\'\" - local coBR=\"\' - local arg=$(echo $(echo $ocBR$(echo $bmc_periphery$(echo $coBR)))) - - echo $arg - - # octez-client transfer 0 from bmcOwner to KT1BE6ohnjunYd1C96yPaThwNvFZu4TN8iBy --entrypoint set_bmc_periphery --arg '"KT1JX3Z3AQnf6oDae87Z9mw1g4jhB38tAGQY"' --burn-cap 1 - echo octez-client transfer 0 from bmcOwner to $(echo $bmc_management) --entrypoint set_bmc_periphery --arg $(echo $arg) --burn-cap 1 -} - -configure_dotenv() { - echo "Configuring .env file for running the setter script" - cd $(echo $CONFIG_DIR/_ixh) - local bmc_periphery=$(echo $(cat tz.addr.bmc_periphery)) - local bmc_management=$(echo $(cat tz.addr.bmc_management)) - local bmc_height=$(echo $(cat tz.chain.height)) - local icon_bmc_height=$(echo $(cat icon.chain.height)) - local icon_bmc=$(echo $(cat icon.addr.bmc)) - echo $bmc_periphery - - local bts_core=$(echo $(cat tz.addr.bts_core)) - local bts_owner_manager=$(echo $(cat tz.addr.bts_owner_manager)) - local bts_periphery=$(echo $(cat tz.addr.bts_periphery)) - - cd $SMARTPY_DIR/bmc - local env=$(cat .env) - env=${env#*=} - local secret_deployer=$(echo "secret_deployer=$(echo $env)") - - cd $(echo $TEZOS_SETTER) - go mod tidy - if [ -f .env ]; then - echo ".env exists so removing" - rm .env - fi - touch .env - local output=.env - - - local TZ_NETWORK=$(echo "TZ_NETWORK=$(echo $TEZOS_BMC_NID)") - local ICON_NETWORK=$(echo "ICON_NETWORK=$(echo $ICON_BMC_NID)") - local TEZOS_NATIVE_COIN_NAME=$(echo "TZ_NATIVE_COIN_NAME=btp-$(echo $TEZOS_BMC_NID)-XTZ") - local TEZOS_SYMBOL=$(echo "TZ_SYMBOL=$(echo $TZ_COIN_SYMBOL)") - local TEZ_FIXED_FEE=$(echo "TZ_FIXED_FEE=$(echo $TZ_FIXED_FEE)") - - local TEZ_NUMERATOR=$(echo "TZ_NUMERATOR=$(echo $TZ_NUMERATOR)") - local TEZ_DECIMALS=$(echo "TZ_DECIMALS=$(echo $TZ_DECIMALS)") - local IC_NATIVE_COIN_NAME=$(echo "ICON_NATIVE_COIN_NAME=$(echo $ICON_NATIVE_COIN_NAME)") - - local IC_SYMBOL=$(echo "ICON_SYMBOL=$(echo $ICON_SYMBOL)") - - local IC_FIXED_FEE=$(echo "ICON_FIXED_FEE=$(echo $ICON_FIXED_FEE)") - - local IC_NUMERATOR=$(echo "ICON_NUMERATOR=$(echo $ICON_NUMERATOR)") - local IC_DECIMALS=$(echo "ICON_DECIMALS=$(echo $ICON_DECIMALS)") - - local BMC_PERIPHERY=$(echo "BMC_PERIPHERY=$(echo $bmc_periphery)") - local BMC_MANAGEMENT=$(echo "BMC_MANAGEMENT=$(echo $bmc_management)") - local BMC_HEIGHT=$(echo "bmc_periphery_height=$(echo $bmc_height)") - - local BTS_PERIPHERY=$(echo "BTS_PERIPHERY=$(echo $bts_periphery)") - local BTS_CORE=$(echo "BTS_CORE=$(echo $bts_core)") - local BTS_OWNER_MANAGER=$(echo "BTS_OWNER_MANAGER=$(echo $bts_owner_manager)") - local RELAY_ADDRESS=$(echo "RELAYER_ADDRESS=$(echo $RELAYER_ADDRESS)") - local ICON_BMC=$(echo "ICON_BMC=$(echo $icon_bmc)") - local ICON_RX_HEIGHT=$(echo "ICON_RX_HEIGHT=$(echo $icon_bmc_height)") - - - echo $secret_deployer>>$output - - echo $TZ_NETWORK>>$output - echo $ICON_NETWORK>>$output - echo $TEZOS_NATIVE_COIN_NAME>>$output - echo $TEZOS_SYMBOL>>$output - echo $TEZ_FIXED_FEE>>$output - echo $TEZ_NUMERATOR>>$output - echo $TEZ_DECIMALS>>$output - echo $IC_NATIVE_COIN_NAME>>$output - echo $IC_SYMBOL>>$output - echo $IC_FIXED_FEE>>$output - echo $IC_NUMERATOR>>$output - echo $IC_DECIMALS>>$output - echo $BMC_PERIPHERY>>$output - echo $BMC_MANAGEMENT>>$output - echo $BMC_HEIGHT>>$output - echo $BTS_PERIPHERY>>$output - echo $BTS_CORE>>$output - echo $BTS_OWNER_MANAGER>>$output - echo $RELAY_ADDRESS>>$output - echo $ICON_BMC>>$output - echo $ICON_RX_HEIGHT>>$output -} - -run_tezos_setters(){ - cd $(echo $TEZOS_SETTER) - go run main.go -} - - -# build java scores -build_javascores(){ - echo in java score - cd $JAVASCORE_DIR - ./gradlew bmc:optimizedJar - ./gradlew bts:optimizedJar - ./gradlew irc2Tradeable:optimizedJar - - # irc2-token - if [ ! -f irc2.jar ]; then - git clone https://github.com/icon-project/java-score-examples.git - cd java-score-examples - ./gradlew irc2-token:clean - ./gradlew irc2-token:optimizedJar - cp irc2-token/build/libs/irc2-token-0.9.1-optimized.jar $JAVASCORE_DIR/irc2.jar - rm -rf $JAVASCORE_DIR/java-score-examples - fi - - cd $JAVASCORE_DIR - cp bmc/build/libs/bmc-optimized.jar $JAVASCORE_DIR/bmc.jar - cp bts/build/libs/bts-optimized.jar $JAVASCORE_DIR/bts.jar - cp irc2Tradeable/build/libs/irc2Tradeable-0.1.0-optimized.jar $JAVASCORE_DIR/irc2Tradeable.jar -} - - - -# deploy java scores - -goloop_lastblock() { - goloop rpc lastblock --uri $ICON_NET_URI -} - -extract_chain_height_and_validator() { - cd $CONFIG_DIR/_ixh - local icon_block_height=$(goloop_lastblock | jq -r .height) - echo $icon_block_height > icon.chain.height - - local validator=$(HEIGHT=0x1 URI=$ICON_NET_URI $BASE_DIR/cmd/iconvalidators/./iconvalidators | jq -r .hash) - echo $validator > icon.chain.validators -} - -deploy_javascore_bmc() { - cd $CONFIG_DIR/_ixh - if [ ! -f icon.addr.bmcbtp ]; then - echo "deploying javascore BMC" - extract_chain_height_and_validator - goloop rpc sendtx deploy $CONTRACTS_DIR/javascore/bmc.jar \ - --content_type application/java \ - --param _net=$ICON_BMC_NID \ - --key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json \ - --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret)) \ - --nid $ICON_NET_ID \ - --step_limit 4000000000 \ - --uri $ICON_NET_URI | jq -r . >tx/tx.icon.bmc - sleep 5 - echo $(pwd) - extract_scoreAddress tx/tx.icon.bmc icon.addr.bmc - echo "btp://$(echo $ICON_BMC_NID)/$(cat icon.addr.bmc)" >icon.addr.bmcbtp - fi -} - -deploy_javascore_bts() { - echo "deploying javascore bts" - cd $CONFIG_DIR/_ixh - if [ ! -f icon.addr.bts ]; then - #local bts_fee_numerator=100 - #local bts_fixed_fee=5000 - goloop rpc sendtx deploy $CONTRACTS_DIR/javascore/bts.jar \ - --content_type application/java \ - --param _name=$ICON_NATIVE_COIN_NAME \ - --param _bmc=$(cat icon.addr.bmc) \ - --param _decimals=$(decimal2Hex $3) \ - --param _feeNumerator=$(decimal2Hex $2) \ - --param _fixedFee=$(decimal2Hex $1) \ - --param _serializedIrc2=$(xxd -p $CONTRACTS_DIR/javascore/irc2Tradeable.jar | tr -d '\n') \ - --key_store $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json \ - --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.secret)) \ - --step_limit 4000000000 \ - --nid $ICON_NET_ID \ - --uri $ICON_NET_URI | jq -r . > tx/tx.icon.bts - sleep 5 - extract_scoreAddress tx/tx.icon.bts icon.addr.bts - fi -} - -deploy_javascore_token() { - echo "deploying javascore IRC2Token " $2 - cd $CONFIG_DIR/_ixh - if [ ! -f icon.addr.$2 ]; then - goloop rpc sendtx deploy $CONTRACTS_DIR/javascore/irc2.jar \ - --content_type application/java \ - --param _name="$1" \ - --param _symbol=$2 \ - --param _initialSupply="0x5f5e100" \ - --param _decimals="0x12" \ - --key_store $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.json \ - --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.secret)) \ - --nid $ICON_NET_ID \ - --step_limit 4000000000 \ - --uri $ICON_NET_URI | jq -r . >tx/tx.icon.$2 - sleep 5 - extract_scoreAddress tx/tx.icon.$2 icon.addr.$2 - fi -} - - -configure_javascore_add_bmc_owner() { - echo "bmc Add Owner" - echo $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json - local icon_bmc_owner=$(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json | jq -r .address) - cd $CONFIG_DIR/_ixh - local is_owner=$(goloop rpc call \ - --to $(cat icon.addr.bmc) \ - --method isOwner \ - --param _addr=$icon_bmc_owner \ - --uri $ICON_NET_URI | jq -r .) - if [ "$is_owner" == "0x0" ]; then - goloop rpc sendtx call --to $(cat icon.addr.bmc) \ - --method addOwner \ - --param _addr=$icon_bmc_owner \ - --key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json \ - --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret)) \ - --step_limit 1000000000 \ - --nid $ICON_NET_ID \ - --uri $ICON_NET_URI | jq -r . > tx/addbmcowner.icon - sleep 3 - ensure_txresult tx/addbmcowner.icon - fi -} - -configure_javascore_bmc_setFeeAggregator() { - echo "bmc setFeeAggregator" - cd $CONFIG_DIR/_ixh - local FA=$(cat $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.json | jq -r .address) - goloop rpc sendtx call --to $(cat icon.addr.bmc) \ - --method setFeeAggregator \ - --param _addr=${FA} \ - --key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json \ - --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret)) \ - --step_limit 1000000000 \ - --nid $ICON_NET_ID \ - --uri $ICON_NET_URI | jq -r . >tx/setFeeAggregator.icon - sleep 3 - ensure_txresult tx/setFeeAggregator.icon - - goloop rpc sendtx call --to $(cat icon.addr.bmc) \ - --method setFeeGatheringTerm \ - --param _value=$FEE_GATHERING_INTERVAL \ - --key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json \ - --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret)) \ - --step_limit 1000000000 \ - --nid $ICON_NET_ID \ - --uri $ICON_NET_URI | jq -r . >tx/setFeeGatheringTerm.icon - sleep 3 - ensure_txresult tx/setFeeGatheringTerm.icon -} - -configure_javascore_add_bts() { - echo "bmc add bts" - cd $CONFIG_DIR/_ixh - local hasBTS=$(goloop rpc call \ - --to $(cat icon.addr.bmc) \ - --method getServices \ - --uri $ICON_NET_URI | jq -r .bts) - if [ "$hasBTS" == "null" ]; then - goloop rpc sendtx call --to $(cat icon.addr.bmc) \ - --method addService \ - --value 0 \ - --param _addr=$(cat icon.addr.bts) \ - --param _svc="bts" \ - --key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json \ - --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret)) \ - --step_limit 1000000000 \ - --nid $ICON_NET_ID \ - --uri $ICON_NET_URI | jq -r . >tx/addService.icon - sleep 3 - ensure_txresult tx/addService.icon - fi - sleep 5 -} - -configure_javascore_add_bts_owner() { - echo "Add bts Owner" - local icon_bts_owner=$(cat $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json | jq -r .address) - cd $CONFIG_DIR/_ixh - local is_owner=$(goloop rpc call \ - --to $(cat icon.addr.bts) \ - --method isOwner \ - --param _addr="$icon_bts_owner" \ - --uri $ICON_NET_URI | jq -r .) - if [ "$is_owner" == "0x0" ]; then - goloop rpc sendtx call --to $(cat icon.addr.bts) \ - --method addOwner \ - --param _addr=$icon_bts_owner \ - --key_store $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json \ - --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.secret)) \ - --step_limit 1000000000 \ - --nid $ICON_NET_ID \ - --uri $ICON_NET_URI | jq -r . >tx/addBtsOwner.icon - sleep 3 - ensure_txresult tx/addBtsOwner.icon - fi -} - -configure_javascore_bts_setICXFee() { - echo "bts set fee" $ICON_SYMBOL - #local bts_fee_numerator=100 - #local bts_fixed_fee=5000 - cd $CONFIG_DIR/_ixh - goloop rpc sendtx call --to $(cat icon.addr.bts) \ - --method setFeeRatio \ - --param _name=$ICON_NATIVE_COIN_NAME \ - --param _feeNumerator=$(decimal2Hex $2) \ - --param _fixedFee=$(decimal2Hex $1) \ - --key_store $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json \ - --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.secret)) \ - --nid $ICON_NET_ID \ - --step_limit 1000000000 \ - --uri $ICON_NET_URI | jq -r . >tx/setICXFee.icon - sleep 3 - ensure_txresult tx/setICXFee.icon -} - - -configure_javascore_addLink() { - echo "BMC: Add Link to BSC BMC:" - cd $CONFIG_DIR/_ixh - if [ ! -f icon.configure.addLink ]; then - goloop rpc sendtx call --to $(cat icon.addr.bmc) \ - --method addLink \ - --param _link=$(cat tz.addr.bmcperipherybtp) \ - --key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json \ - --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret)) \ - --nid $ICON_NET_ID \ - --step_limit 1000000000 \ - --uri $ICON_NET_URI | jq -r . > addLink.icon - - sleep 3 - echo "addedLink" > icon.configure.addLink - fi -} - -configure_javascore_setLinkHeight() { - echo "BMC: SetLinkHeight" - cd $CONFIG_DIR/_ixh - if [ ! -f icon.configure.setLink ]; then - goloop rpc sendtx call --to $(cat icon.addr.bmc) \ - --method setLinkRxHeight \ - --param _link=$(cat tz.addr.bmcperipherybtp) \ - --param _height=$(cat tz.chain.height) \ - --key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json \ - --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret)) \ - --nid $ICON_NET_ID \ - --step_limit 1000000000 \ - --uri $ICON_NET_URI | jq -r . > setLinkRxHeight.icon - - sleep 3 - echo "setLink" > icon.configure.setLink - fi -} - -configure_bmc_javascore_addRelay() { - echo "Adding bsc Relay" - local icon_bmr_owner=$(cat $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.json | jq -r .address) - echo $icon_bmr_owner - sleep 5 - echo "Starting" - cd $CONFIG_DIR/_ixh - if [ ! -f icon.configure.addRelay ]; then - goloop rpc sendtx call --to $(cat icon.addr.bmc) \ - --method addRelay \ - --param _link=$(cat tz.addr.bmcperipherybtp) \ - --param _addr=${icon_bmr_owner} \ - --key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json \ - --key_password $(echo $(cat $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret)) \ - --nid $ICON_NET_ID \ - --step_limit 1000000000 \ - --uri $ICON_NET_URI | jq -r . > addRelay.icon - - sleep 3 - echo "addRelay" > icon.configure.addRelay - fi -} - -function decimal2Hex() { - hex=$(echo "obase=16; ibase=10; ${@}" | bc) - echo "0x$(tr [A-Z] [a-z] <<< "$hex")" -} - - -configure_relay_config() { - jq -n ' - .base_dir = $base_dir | - .log_level = "debug" | - .console_level = "trace" | - .log_writer.filename = $log_writer_filename | - .relays = [ $b2i_relay, $i2b_relay ]' \ - --arg base_dir "bmr" \ - --arg log_writer_filename "bmr/bmr.log" \ - --argjson b2i_relay "$( - jq -n ' - .name = "t2i" | - .src.address = $src_address | - .src.endpoint = [ $src_endpoint ] | - .src.options.verifier.blockHeight = $src_options_verifier_blockHeight | - .src.options.syncConcurrency = 100 | - .src.options.bmcManagement = $bmc_management | - .src.offset = $src_offset | - .dst.address = $dst_address | - .dst.endpoint = [ $dst_endpoint ] | - .dst.options = $dst_options | - .dst.key_store = $dst_key_store | - .dst.key_store.coinType = $dst_key_store_cointype | - .dst.key_password = $dst_key_password ' \ - --arg src_address "$(cat $CONFIG_DIR/_ixh/tz.addr.bmcperipherybtp)" \ - --arg src_endpoint "$TZ_NET_URI" \ - --argjson src_offset $(cat $CONFIG_DIR/_ixh/tz.chain.height) \ - --argjson src_options_verifier_blockHeight $(cat $CONFIG_DIR/_ixh/tz.chain.height) \ - --arg bmc_management "$(cat $CONFIG_DIR/_ixh/tz.addr.bmc_management)" \ - --arg dst_address "$(cat $CONFIG_DIR/_ixh/icon.addr.bmcbtp)" \ - --arg dst_endpoint "$ICON_NET_URI" \ - --argfile dst_key_store "$CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.json" \ - --arg dst_key_store_cointype "icx" \ - --arg dst_key_password "$(cat $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.secret)" \ - --argjson dst_options '{"step_limit":2500000000, "tx_data_size_limit":8192,"balance_threshold":"10000000000000000000"}' - )" \ - --argjson i2b_relay "$( - jq -n ' - .name = "i2t" | - .src.address = $src_address | - .src.endpoint = [ $src_endpoint ] | - .src.offset = $src_offset | - .src.options.verifier.blockHeight = $src_options_verifier_blockHeight | - .src.options.verifier.validatorsHash = $src_options_verifier_validatorsHash | - .src.options.syncConcurrency = 100 | - .dst.address = $dst_address | - .dst.endpoint = [ $dst_endpoint ] | - .dst.options = $dst_options | - .dst.options.bmcManagement = $bmc_management | - .dst.tx_data_size_limit = $dst_tx_data_size_limit | - .dst.key_store.address = $dst_key_store | - .dst.key_store.coinType = $dst_key_store_cointype | - .dst.key_store.crypto.cipher = $secret | - .dst.key_password = $dst_key_password ' \ - --arg src_address "$(cat $CONFIG_DIR/_ixh/icon.addr.bmcbtp)" \ - --arg src_endpoint "$ICON_NET_URI" \ - --argjson src_offset $(cat $CONFIG_DIR/_ixh/icon.chain.height) \ - --argjson src_options_verifier_blockHeight $(cat $CONFIG_DIR/_ixh/icon.chain.height) \ - --arg src_options_verifier_validatorsHash "$(cat $CONFIG_DIR/_ixh/icon.chain.validators)" \ - --arg dst_address "$(cat $CONFIG_DIR/_ixh/tz.addr.bmcperipherybtp)" \ - --arg dst_endpoint "$TZ_NET_URI" \ - --arg dst_key_store "$RELAYER_ADDRESS" \ - --arg dst_key_store_cointype "xtz" \ - --arg secret "edskRz1HoD3cWkmWhCNS5LjBrJNWChGuKWB4HnVoN5UqVsUCpcNJR67ZxKs965u8RgRwptrtGc2ufYZoeECgB77RKm1gTbQ6eB" \ - --arg dst_key_password "xyz" \ - --argjson dst_tx_data_size_limit 8192 \ - --argjson dst_options '{"gas_limit":24000000,"tx_data_size_limit":8192,"balance_threshold":"100000000000000000000","boost_gas_price":1.0}' \ - --arg bmc_management "$(cat $CONFIG_DIR/_ixh/tz.addr.bmc_management)" - )" -} - -start_relay() { - cd $BASE_DIR/cmd/iconbridge - go run main.go -config $CONFIG_DIR/_ixh/relay.config.json -} - -ensure_config_dir -ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.secret -ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret -ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.secret -ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.json $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.secret -# ensure_tezos_keystore -fund_it_flag - -build_javascores -deploy_javascore_bmc -deploy_javascore_bts 0 0 18 -# deploy_javascore_token - -configure_javascore_add_bmc_owner -configure_javascore_add_bts -configure_javascore_add_bts_owner -configure_javascore_bmc_setFeeAggregator -configure_javascore_bts_setICXFee 0 0 - - - -# # tezos configuration -deploy_smartpy_bmc_management -deploy_smartpy_bmc_periphery -deploy_smartpy_bts_periphery -deploy_smartpy_bts_core -deploy_smartpy_bts_owner_manager -configure_dotenv -run_tezos_setters - -# # # icon configuration of tezos -configure_javascore_addLink -configure_javascore_setLinkHeight -configure_bmc_javascore_addRelay - - -configure_relay_config > $CONFIG_DIR/_ixh/relay.config.json -start_relay - - - From 7d06aa1d4982894967581236fbcac2c3835c7d3e Mon Sep 17 00:00:00 2001 From: icondev22 Date: Fri, 18 Aug 2023 08:03:07 +0545 Subject: [PATCH 195/211] chore: file reformat to original --- smartpy/bts/contracts/src/bts_periphery.py | 1 + smartpy/bts/contracts/src/parse_address.py | 1 + 2 files changed, 2 insertions(+) diff --git a/smartpy/bts/contracts/src/bts_periphery.py b/smartpy/bts/contracts/src/bts_periphery.py index 448aa023..97fc84ec 100644 --- a/smartpy/bts/contracts/src/bts_periphery.py +++ b/smartpy/bts/contracts/src/bts_periphery.py @@ -589,6 +589,7 @@ def check_transfer_restrictions(self, params): with sp.else_(): sp.result(False) + sp.add_compilation_target("bts_periphery", BTSPeriphery(bmc_address=sp.address("KT1VFtWq2dZDH1rTfLtgMaASMt4UX78omMs2"), bts_core_address=sp.address("KT1JAippuMfS6Bso8DGmigmTdkgEZUxQxYyX"), helper_contract=sp.address("KT1HwFJmndBWRn3CLbvhUjdupfEomdykL5a6"), diff --git a/smartpy/bts/contracts/src/parse_address.py b/smartpy/bts/contracts/src/parse_address.py index 139b75e6..2410253a 100644 --- a/smartpy/bts/contracts/src/parse_address.py +++ b/smartpy/bts/contracts/src/parse_address.py @@ -106,6 +106,7 @@ def _to_addr(self, params): decimal = sp.local("decimal", 0) base = sp.len(alphabet) element_list_2 = sp.range(0, sp.len(string_in_bytes), 1) + sp.for elem in element_list_2: decimal.value = decimal.value * base + temp_map.value[sp.slice(string_in_bytes, elem, 1).open_some()] byt_value = Utils.Bytes.of_nat(sp.as_nat(sp.to_int(decimal.value))) From 80c7da3b1ddc150aacd2b42131e79d859a3562d4 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Fri, 18 Aug 2023 08:03:44 +0545 Subject: [PATCH 196/211] fix: file reverted to original --- .../icon/btp/bts/BTPTokenService.java | 24 +------------------ 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/javascore/bts/src/main/java/foundation/icon/btp/bts/BTPTokenService.java b/javascore/bts/src/main/java/foundation/icon/btp/bts/BTPTokenService.java index df65dbe5..ead18ad6 100644 --- a/javascore/bts/src/main/java/foundation/icon/btp/bts/BTPTokenService.java +++ b/javascore/bts/src/main/java/foundation/icon/btp/bts/BTPTokenService.java @@ -108,18 +108,6 @@ public BTPTokenService(Address _bmc, String _name, int _decimals, sn.set(BigInteger.ZERO); } - List
addrList = new ArrayList
(); - addrList.add(Address.fromString("cx8a3abea4033ffa4e8553b593b6d4db41e8578956")); - addrList.add(Address.fromString("cx13cc93a9ed547c17ace46916dd115b7ea6aadcea")); - - // coinDb.set("btp-NetXnHfVqm9iesp.tezos-bnXTZ", - // new Coin(addrList.get(1), "btp-NetXnHfVqm9iesp.tezos-bnXTZ", "XTZ", 6, BigInteger.ZERO, BigInteger.ZERO, NATIVE_WRAPPED_COIN_TYPE)); - coinAddressName.set(addrList.get(1), "btp-NetXnHfVqm9iesp.tezos-bnXTZ"); - - // coinDb.set("btp-NetXnHfVqm9iesp.tezos-XTZ", - // new Coin(addrList.get(0), "btp-NetXnHfVqm9iesp.tezos-XTZ", "XTZ", 6, BigInteger.ZERO, BigInteger.ZERO, NATIVE_WRAPPED_COIN_TYPE)); - coinAddressName.set(addrList.get(0), "btp-NetXnHfVqm9iesp.tezos-XTZ"); - if (coinDb.get(_name) == null) { require(_feeNumerator.compareTo(BigInteger.ZERO) >= 0 && _feeNumerator.compareTo(FEE_DENOMINATOR) < 0, @@ -1493,14 +1481,4 @@ private void checkUintLimit(BigInteger value) { require(UINT_CAP.compareTo(value) >= 0, "Value cannot exceed uint(256)-1"); } - // TODO: to be removed in production - - @External - public void transferToBTS(Address tokenAddress, Address bts) { - requireOwnerAccess(); - BigInteger balance = (BigInteger) Context.call(tokenAddress, "balanceOf", Context.getAddress()); - Context.call(tokenAddress, "transfer", bts, balance, null); - } -} - - +} \ No newline at end of file From d4524b590ddc0ef6ccba43a7bd745c7a33f41343 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Fri, 18 Aug 2023 08:04:48 +0545 Subject: [PATCH 197/211] fix: removed unnecessary files --- .../bmc/contracts/src/RLP_decode_struct.py | 307 ------------------ .../bmc/contracts/src/RLP_encode_struct.py | 33 -- .../bts/contracts/src/RLP_decode_struct.py | 263 --------------- .../bts/contracts/src/RLP_encode_struct.py | 32 -- 4 files changed, 635 deletions(-) delete mode 100644 smartpy/bmc/contracts/src/RLP_decode_struct.py delete mode 100644 smartpy/bmc/contracts/src/RLP_encode_struct.py delete mode 100644 smartpy/bts/contracts/src/RLP_decode_struct.py delete mode 100644 smartpy/bts/contracts/src/RLP_encode_struct.py diff --git a/smartpy/bmc/contracts/src/RLP_decode_struct.py b/smartpy/bmc/contracts/src/RLP_decode_struct.py deleted file mode 100644 index 103c25ef..00000000 --- a/smartpy/bmc/contracts/src/RLP_decode_struct.py +++ /dev/null @@ -1,307 +0,0 @@ -import smartpy as sp - -Utils2 = sp.io.import_script_from_url("https://raw.githubusercontent.com/RomarQ/tezos-sc-utils/main/smartpy/utils.py") -types = sp.io.import_script_from_url("file:./contracts/src/Types.py") - -# contract address to deal with negative values -#TODO: change to mainnet address -HELPER_CONTRACT_ADDRESS = sp.address("KT1W6dU9xpKwMwHXopVhW5PB1NdZFmVZPKbK") - -class DecodeLibrary: - - def decode_bmc_message(self, rlp): - rlp_bm = sp.local("rlp_bm", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - rlp_bm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - rlp_bm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - rlp_ = rlp_bm.value - temp_map_string = sp.compute(sp.map(tkey=sp.TString, tvalue=sp.TString)) - temp_int = sp.local("int_value", 0) - temp_byt = sp.local("byt_value", sp.bytes("0x")) - counter = sp.local("counter", 0) - sp.for k in rlp_.items(): - sp.if counter.value == 0: - temp_map_string["src"] = sp.view("decode_string", self.data.helper, k.value, t=sp.TString).open_some() - sp.if counter.value == 1: - temp_map_string["dst"] = sp.view("decode_string", self.data.helper, k.value, t=sp.TString).open_some() - sp.if counter.value == 2: - temp_map_string["svc"] = sp.view("decode_string", self.data.helper, k.value, t=sp.TString).open_some() - sp.if counter.value == 3: - sn_in_bytes = sp.view("without_length_prefix", self.data.helper, k.value, t=sp.TBytes).open_some() - temp_int.value = sp.view("to_int", HELPER_CONTRACT_ADDRESS, sn_in_bytes, t=sp.TInt).open_some() - sp.if counter.value == 4: - temp_byt.value = k.value - counter.value = counter.value + 1 - temp_byt.value = sp.view("without_length_prefix", self.data.helper, temp_byt.value, t=sp.TBytes).open_some() - return sp.record(src=temp_map_string.get("src"), - dst=temp_map_string.get("dst"), - svc=temp_map_string.get("svc"), - sn=temp_int.value, - message=temp_byt.value) - - - def decode_response(self, rlp): - temp_int = sp.local("int1", 0) - temp_byt = sp.local("byt1", sp.bytes("0x")) - rlp_dr = sp.local("rlp_dr", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - rlp_dr.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - rlp_dr.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - rlp_ = rlp_dr.value - counter = sp.local("counter_response", 0) - sp.for m in rlp_.items(): - sp.if counter.value == 0: - temp_int.value = Utils2.Int.of_bytes(m.value) - sp.if counter.value == 1: - temp_byt.value = m.value - counter.value = counter.value + 1 - - return sp.record(code=temp_int.value, message=sp.view("decode_string", self.data.helper, temp_byt.value, t=sp.TString).open_some()) - - def decode_propagate_message(self, rlp): - rlp_pm = sp.local("rlp_pm", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - rlp_pm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - rlp_pm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - rlp_ = rlp_pm.value - counter = sp.local("counter_propagate", 0) - temp_string = sp.local("temp_string", "") - sp.for d in rlp_.items(): - sp.if counter.value == 0: - temp_string.value = sp.view("decode_string", self.data.helper, d.value, t=sp.TString).open_some() - counter.value = counter.value + 1 - return temp_string.value - - def decode_init_message(self, rlp): - rlp_im = sp.local("rlp_im", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - rlp_im.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - rlp_im.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - rlp_ = rlp_im.value - counter = sp.local("counter_init", 0) - temp_bytes = sp.local("byt_init", sp.bytes("0x")) - sp.for g in rlp_.items(): - sp.if counter.value == 0: - temp_bytes.value = g.value - counter.value = counter.value + 1 - - starts_with = sp.slice(temp_bytes.value, 0, 2).open_some() - sub_list = sp.local("sub_list_init", temp_bytes.value) - sp.if starts_with == sp.bytes("0xb846"): - sub_list.value = sp.slice(temp_bytes.value, 2, sp.as_nat(sp.len(temp_bytes.value) - 2)).open_some() - nsl_im = sp.local("nsl_im", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - nsl_im.value = sp.view("decode_list", self.data.helper, sub_list.value, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() - nsl_im.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - new_sub_list = nsl_im.value - - _links = sp.local("links_init", [], sp.TList(sp.TString)) - counter.value = 0 - sp.for x in new_sub_list.items(): - _links.value.push(sp.view("decode_string", self.data.helper, x.value, t=sp.TString).open_some()) - counter.value = counter.value + 1 - return _links.value - - def decode_bmc_service(self, rlp): - rlp_bs = sp.local("rlp_bs", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - rlp_bs.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - rlp_bs.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - rlp_ = rlp_bs.value - temp_string = sp.local("str_value", "") - temp_byt = sp.local("byt_value_bmc", sp.bytes("0x")) - counter = sp.local("counter_service", 0) - sp.for b in rlp_.items(): - sp.if counter.value == 0: - temp_string.value = sp.view("decode_string", self.data.helper, b.value, t=sp.TString).open_some() - sp.if counter.value == 1: - temp_byt.value = b.value - counter.value = counter.value + 1 - temp_byt.value = sp.view("without_length_prefix", self.data.helper, temp_byt.value, t=sp.TBytes).open_some() - return sp.record(serviceType=temp_string.value, - payload=temp_byt.value) - - def decode_gather_fee_message(self, rlp): - rlp_gm = sp.local("rlp_gm", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - rlp_gm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - rlp_gm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - rlp_ = rlp_gm.value - temp_byt = sp.local("byt4", sp.bytes("0x")) - counter = sp.local("counter_gather", 0) - temp_str = sp.local("str_gather", "") - sp.for c in rlp_.items(): - sp.if counter.value == 1: - temp_byt.value = c.value - sp.if counter.value == 0: - temp_str.value = sp.view("decode_string", self.data.helper, c.value, t=sp.TString).open_some() - counter.value = counter.value + 1 - starts_with = sp.slice(temp_byt.value, 0, 2).open_some() - sub_list = sp.local("sub_list", temp_byt.value) - sp.if starts_with == sp.bytes("0xb846"): - sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() - nsl_gm = sp.local("nsl_gm", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - nsl_gm.value = sp.view("decode_list", self.data.helper, sub_list.value, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() - nsl_gm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - new_sub_list = nsl_gm.value - - _svcs = sp.local("_svcs", {}, sp.TMap(sp.TNat, sp.TString)) - counter.value = 0 - sp.for x in new_sub_list.items(): - _svcs.value[counter.value] = sp.view("decode_string", self.data.helper, x.value, t=sp.TString).open_some() - counter.value = counter.value + 1 - return sp.record(fa=temp_str.value, - svcs=_svcs.value) - - def to_message_event(self, rlp): - rlp_me = sp.local("rlp_me", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - rlp_me.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - rlp_me.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - rlp_ = rlp_me.value - counter = sp.local("counter_event", 0) - rv1 = sp.local("rv1_event", "") - rv2 = sp.local("rv2_event", sp.nat(0)) - rv3 = sp.local("rv3_event", sp.bytes("0x")) - sp.for i in rlp_.items(): - sp.if counter.value == 2: - rv3.value = i.value - sp.if counter.value == 0: - rv1.value = sp.view("decode_string", self.data.helper, i.value, t=sp.TString).open_some() - sp.if counter.value == 1: - rv2.value = Utils2.Int.of_bytes(i.value) - counter.value = counter.value + 1 - rv3.value = sp.view("without_length_prefix", self.data.helper, rv3.value, t=sp.TBytes).open_some() - return sp.record(next_bmc= rv1.value, seq= rv2.value, message = rv3.value) - - def decode_receipt_proof(self, rlp): - rlp_rp = sp.local("rlp_rp", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - rlp_rp.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - rlp_rp.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - rlp_ = rlp_rp.value - temp_byt = sp.local("byt_receipt", sp.bytes("0x")) - rv_int = sp.local("rv_int_receipt", 0) - rv_int2 = sp.local("rv_int2_receipt", 0) - counter = sp.local("counter", 0) - sp.for i in rlp_.items(): - sp.if counter.value == 1: - temp_byt.value = sp.view("without_length_prefix", self.data.helper, i.value, t=sp.TBytes).open_some() - sp.if counter.value == 0: - rv_int.value = Utils2.Int.of_bytes(i.value) - sp.if counter.value == 2: - rv_int2.value =Utils2.Int.of_bytes(i.value) - counter.value = counter.value + 1 - - starts_with = sp.slice(temp_byt.value, 0, 2).open_some() - sub_list = sp.local("sub_list", temp_byt.value) - sp.if starts_with == sp.bytes("0xb846"): - sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() - - nsl_rp = sp.local("nsl_rp", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - nsl_rp.value = sp.view("decode_list", self.data.helper, sub_list.value, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() - nsl_rp.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - new_sub_list = nsl_rp.value - counter.value = 0 - events = sp.local("events_receipt", sp.map({}, tkey=sp.TNat, - tvalue=sp.TRecord(next_bmc= sp.TString, - seq= sp.TNat, - message = sp.TBytes))) - sp.for z in new_sub_list.items(): - events.value[counter.value] = self.to_message_event(z.value) - counter.value = counter.value + 1 - return sp.record(index = rv_int.value, events = events.value, height = rv_int2.value) - - - def decode_receipt_proofs(self, rlp): - rlp_rps = sp.local("rlp_rps", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - rlp_rps.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - rlp_rps.value = sp.view("decode_list", self.data.helper, decode_len, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - rlp_ = rlp_rps.value - counter = sp.local("counter_receipt_proofs", 0) - receipt_proofs = sp.local("events_receipt_proofs", sp.map({}, tkey=sp.TNat, - tvalue=sp.TRecord(index = sp.TNat, - events = sp.TMap(sp.TNat, sp.TRecord(next_bmc=sp.TString, seq=sp.TNat, message=sp.TBytes)), - height = sp.TNat, - ) - ) - ) - temp_byt = sp.local("temp_byt_proofs", sp.bytes("0x")) - sp.for i in rlp_.items(): - sp.if counter.value == 0: - temp_byt.value = i.value - counter.value = counter.value + 1 - starts_with = sp.slice(temp_byt.value, 0, 2).open_some() - sub_list = sp.local("sub_list_proofs", temp_byt.value) - sp.if starts_with == sp.bytes("0xb846"): - sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() - - nsl_rps = sp.local("nsl_rps", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - nsl_rps.value = sp.view("decode_list", self.data.helper, sub_list.value, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() - nsl_rps.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - new_sub_list = nsl_rps.value - counter.value = 0 - sp.if sp.len(new_sub_list) > 0: - sp.for x in new_sub_list.items(): - receipt_proofs.value[counter.value] = self.decode_receipt_proof(x.value) - counter.value = counter.value + 1 - return receipt_proofs.value - diff --git a/smartpy/bmc/contracts/src/RLP_encode_struct.py b/smartpy/bmc/contracts/src/RLP_encode_struct.py deleted file mode 100644 index cc9ff814..00000000 --- a/smartpy/bmc/contracts/src/RLP_encode_struct.py +++ /dev/null @@ -1,33 +0,0 @@ -import smartpy as sp - - -class EncodeLibrary: - LIST_SHORT_START = sp.bytes("0xc0") - - def encode_bmc_service(self, params): - sp.set_type(params, sp.TRecord(serviceType=sp.TString, payload=sp.TBytes)) - - encode_service_type = sp.view("encode_string", self.data.helper, params.serviceType, t=sp.TBytes).open_some() - - rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [encode_service_type, params.payload], t=sp.TBytes).open_some() - return rlp_bytes_with_prefix - - def encode_bmc_message(self, params): - sp.set_type(params, sp.TRecord(src=sp.TString, dst=sp.TString, svc=sp.TString, sn=sp.TInt, message=sp.TBytes)) - - encode_src = sp.view("encode_string", self.data.helper, params.src, t=sp.TBytes).open_some() - encode_dst = sp.view("encode_string", self.data.helper, params.dst, t=sp.TBytes).open_some() - encode_svc = sp.view("encode_string", self.data.helper, params.svc, t=sp.TBytes).open_some() - nat_sn = sp.as_nat(params.sn) - encode_sn = sp.view("encode_nat", self.data.helper, nat_sn, t=sp.TBytes).open_some() - rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [encode_src, encode_dst, encode_svc, encode_sn, params.message], t=sp.TBytes).open_some() - return rlp_bytes_with_prefix - - def encode_response(self, params): - sp.set_type(params, sp.TRecord(code=sp.TNat, message=sp.TString)) - - encode_code = sp.view("encode_nat", self.data.helper, params.code, t=sp.TBytes).open_some() - encode_message = sp.view("encode_string", self.data.helper, params.message, t=sp.TBytes).open_some() - - rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [encode_code, encode_message], t=sp.TBytes).open_some() - return rlp_bytes_with_prefix diff --git a/smartpy/bts/contracts/src/RLP_decode_struct.py b/smartpy/bts/contracts/src/RLP_decode_struct.py deleted file mode 100644 index 9889e546..00000000 --- a/smartpy/bts/contracts/src/RLP_decode_struct.py +++ /dev/null @@ -1,263 +0,0 @@ -import smartpy as sp - -Utils2 = sp.io.import_script_from_url("https://raw.githubusercontent.com/RomarQ/tezos-sc-utils/main/smartpy/utils.py") -types = sp.io.import_script_from_url("file:./contracts/src/Types.py") - - -class DecodeLibrary: - def decode_response(self, rlp): - temp_int = sp.local("int1", 0) - temp_byt = sp.local("byt1", sp.bytes("0x")) - rlp_dr = sp.local("rlp_dr_bts", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - rlp_dr.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - rlp_dr.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - rlp_ = rlp_dr.value - counter = sp.local("counter_response", 0) - sp.for i in rlp_.items(): - sp.if counter.value == 0: - temp_int.value = Utils2.Int.of_bytes(i.value) - sp.if counter.value == 1: - temp_byt.value = i.value - counter.value = counter.value + 1 - - return sp.record(code=temp_int.value, message=sp.view("decode_string", self.data.helper, temp_byt.value, t=sp.TString).open_some()) - - def decode_service_message(self, rlp): - rlp_sm = sp.local("rlp_sm_bts", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - rlp_sm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - rlp_sm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - rlp_ = rlp_sm.value - temp_int = sp.local("int2", 0) - temp_byt = sp.local("byte1", sp.bytes("0x")) - counter = sp.local("counter", 0) - sp.for i in rlp_.items(): - sp.if counter.value == 0: - temp_int.value = Utils2.Int.of_bytes(i.value) - sp.if counter.value == 1: - temp_byt.value = i.value - counter.value = counter.value + 1 - - _service_type = sp.local("_service_type", sp.variant("", 10)) - sp.if temp_int.value == 0: - _service_type.value = sp.variant("REQUEST_COIN_TRANSFER", temp_int.value) - sp.if temp_int.value == 1: - _service_type.value = sp.variant("REQUEST_COIN_REGISTER", temp_int.value) - sp.if temp_int.value == 2: - _service_type.value = sp.variant("RESPONSE_HANDLE_SERVICE", temp_int.value) - sp.if temp_int.value == 3: - _service_type.value = sp.variant("BLACKLIST_MESSAGE", temp_int.value) - sp.if temp_int.value == 4: - _service_type.value = sp.variant("CHANGE_TOKEN_LIMIT", temp_int.value) - sp.if temp_int.value == 5: - _service_type.value = sp.variant("UNKNOWN_TYPE", temp_int.value) - temp_byt.value = sp.view("without_length_prefix", self.data.helper, temp_byt.value, t=sp.TBytes).open_some() - - return sp.record(serviceType=_service_type.value, - data=temp_byt.value) - - def decode_transfer_coin_msg(self, rlp): - rlp_tcm = sp.local("rlp_tcm_bts", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - rlp_tcm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - rlp_tcm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - rlp_ = rlp_tcm.value - - temp_byt = sp.local("byt_transfer", sp.bytes("0x")) - rv1_byt = sp.local("rv1_byt", sp.bytes("0x")) - rv2_byt = sp.local("rv2_byt", sp.bytes("0x")) - counter = sp.local("counter_coin", sp.nat(0)) - sp.for i in rlp_.items(): - sp.if counter.value == 2: - temp_byt.value = i.value - sp.if counter.value == 0: - rv1_byt.value = i.value - sp.if counter.value == 1: - rv2_byt.value = i.value - counter.value = counter.value + 1 - starts_with = sp.slice(temp_byt.value, 0, 2).open_some() - sub_list = sp.local("sub_list", temp_byt.value) - sp.if starts_with == sp.bytes("0xb846"): - sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() - nsl_tcm = sp.local("nsl_bts_tcm", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - nsl_tcm.value = sp.view("decode_list", self.data.helper, sub_list.value, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() - nsl_tcm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - new_sub_list = nsl_tcm.value - counter.value = 0 - new_temp_byt = sp.local("new_temp_byt", sp.bytes("0x")) - rv_assets = sp.local("assets", {}, sp.TMap(sp.TNat, types.Types.Asset)) - sp.for x in new_sub_list.items(): - new_temp_byt.value = x.value - sp.if sp.slice(new_temp_byt.value, 0, 2).open_some() == sp.bytes("0xb846"): - new_temp_byt.value = sp.slice(new_temp_byt.value, 2, sp.as_nat(sp.len(new_temp_byt.value) - 2)).open_some() - temp_byt = sp.local("tempByt2", sp.bytes("0x")) - temp_int = sp.local("tempInt", sp.nat(0)) - counter.value = 0 - nsl3_tcm = sp.local("nsl3_bts_tcm", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, new_temp_byt.value, - t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - nsl3_tcm.value = sp.view("decode_list", self.data.helper, new_temp_byt.value, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, new_temp_byt.value, t=sp.TBytes).open_some() - nsl3_tcm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - view_value = nsl3_tcm.value - sp.for i in view_value.items(): - sp.if counter.value == 1: - temp_int.value = Utils2.Int.of_bytes(i.value) - sp.if counter.value == 0: - temp_byt.value = i.value - rv_assets.value[counter.value] = sp.record(coin_name=sp.view("decode_string", self.data.helper, temp_byt.value, t=sp.TString).open_some() - , value=temp_int.value) - counter.value = counter.value + 1 - rv1 = sp.view("decode_string", self.data.helper, rv1_byt.value, t=sp.TString).open_some() - rv2 = sp.view("decode_string", self.data.helper, rv2_byt.value, t=sp.TString).open_some() - return sp.record(from_= rv1, to = rv2 , assets = rv_assets.value) - - def decode_blacklist_msg(self, rlp): - rlp_bm = sp.local("rlp_bm_bts", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - rlp_bm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - rlp_bm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - rlp_ = rlp_bm.value - - temp_byt = sp.local("byt_transfer", sp.bytes("0x")) - rv1_byt = sp.local("rv1_byt", sp.bytes("0x")) - rv2_byt = sp.local("rv2_byt", sp.bytes("0x")) - counter = sp.local("counter_blacklist", 0) - sp.for i in rlp_.items(): - sp.if counter.value == 2: - rv2_byt.value = i.value - sp.if counter.value == 0: - rv1_byt.value = i.value - sp.if counter.value == 1: - temp_byt.value = i.value - counter.value = counter.value + 1 - starts_with = sp.slice(temp_byt.value, 0, 2).open_some() - sub_list = sp.local("sub_list", temp_byt.value) - sp.if starts_with == sp.bytes("0xb846"): - sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() - nsl_bm = sp.local("nsl_bts_bm", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - nsl_bm.value = sp.view("decode_list", self.data.helper, sub_list.value, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() - nsl_bm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - new_sub_list = nsl_bm.value - counter.value = 0 - new_temp_byt = sp.local("new_temp_byt", sp.bytes("0x")) - rv_blacklist_address = sp.local("blacklist_data", {}, sp.TMap(sp.TNat, sp.TString)) - sp.for x in new_sub_list.items(): - new_temp_byt.value = x.value - sp.if sp.slice(new_temp_byt.value, 0, 2).open_some() == sp.bytes("0xb846"): - new_temp_byt.value = sp.slice(new_temp_byt.value, 2, sp.as_nat(sp.len(new_temp_byt.value) - 2)).open_some() - counter.value = 0 - nsl2_bm = sp.local("nsl2_bts_bm", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, new_temp_byt.value, - t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - nsl2_bm.value = sp.view("decode_list", self.data.helper, new_temp_byt.value, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, new_temp_byt.value, t=sp.TBytes).open_some() - nsl2_bm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - _decode_list = nsl2_bm.value - sp.for j in _decode_list.items(): - rv_blacklist_address.value[counter.value] = sp.view("decode_string", self.data.helper, j.value, t=sp.TString).open_some() - counter.value = counter.value + 1 - rv1 = Utils2.Int.of_bytes(rv1_byt.value) - rv2 = sp.view("decode_string", self.data.helper, rv2_byt.value, t=sp.TString).open_some() - _service_type = sp.local("_service_type_blacklist", sp.variant("", 10)) - with sp.if_(rv1 == 0): - _service_type.value = sp.variant("ADD_TO_BLACKLIST", rv1) - with sp.else_(): - _service_type.value = sp.variant("REMOVE_FROM_BLACKLIST", rv1) - return sp.record(serviceType = _service_type.value , addrs = rv_blacklist_address.value , - net = sp.view("decode_string", self.data.helper, rv2, t=sp.TString).open_some()) - - def decode_token_limit_msg(self, rlp): - rlp_tlm = sp.local("rlp_tlm_bts", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, rlp, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - rlp_tlm.value = sp.view("decode_list", self.data.helper, rlp, t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, rlp, t=sp.TBytes).open_some() - rlp_tlm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - rlp_ = rlp_tlm.value - - temp_byt = sp.local("byt_transfer", sp.bytes("0x")) - temp_byt1 = sp.local("byt_transfer_temp1", sp.bytes("0x")) - rv1_byt = sp.local("rv1_byt", sp.bytes("0x")) - counter = sp.local("counter_token_limit", 0) - sp.for i in rlp_.items(): - sp.if counter.value == 0: - temp_byt.value = i.value - sp.if counter.value == 1: - temp_byt1.value = i.value - sp.if counter.value == 2: - rv1_byt.value = i.value - counter.value = counter.value + 1 - starts_with = sp.slice(temp_byt.value, 0, 2).open_some() - sub_list = sp.local("sub_list", temp_byt.value) - sp.if starts_with == sp.bytes("0xb846"): - sub_list.value = sp.slice(temp_byt.value, 2, sp.as_nat(sp.len(temp_byt.value) - 2)).open_some() - nsl1_dtlm = sp.local("nsl1_bts_dtlm", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - nsl1_dtlm.value = sp.view("decode_list", self.data.helper, sub_list.value, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() - nsl1_dtlm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - new_sub_list = nsl1_dtlm.value - counter.value = 0 - rv_names = sp.local("names", {}, sp.TMap(sp.TNat, sp.TString)) - rv_limit = sp.local("limit", {}, sp.TMap(sp.TNat, sp.TNat)) - sp.for x in new_sub_list.items(): - rv_names.value[counter.value] = sp.view("decode_string", self.data.helper, x.value, t=sp.TString).open_some() - - nsl_dtlm = sp.local("nsl_bts_dtlm", sp.map(tkey=sp.TNat)) - is_list_lambda = sp.view("is_list", self.data.helper, sub_list.value, t=sp.TBool).open_some() - with sp.if_(is_list_lambda): - nsl_dtlm.value = sp.view("decode_list", self.data.helper, sub_list.value, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - with sp.else_(): - decode_len = sp.view("without_length_prefix", self.data.helper, sub_list.value, t=sp.TBytes).open_some() - nsl_dtlm.value = sp.view("decode_list", self.data.helper, decode_len, - t=sp.TMap(sp.TNat, sp.TBytes)).open_some() - new_sub_list1 = nsl_dtlm.value - sp.for y in new_sub_list1.items(): - rv_limit.value[counter.value] = Utils2.Int.of_bytes(y.value) - return sp.record(coin_name = rv_names.value, token_limit = rv_limit.value , - net = sp.view("decode_string", self.data.helper, rv1_byt.value, t=sp.TString).open_some()) \ No newline at end of file diff --git a/smartpy/bts/contracts/src/RLP_encode_struct.py b/smartpy/bts/contracts/src/RLP_encode_struct.py deleted file mode 100644 index dc0058b5..00000000 --- a/smartpy/bts/contracts/src/RLP_encode_struct.py +++ /dev/null @@ -1,32 +0,0 @@ -import smartpy as sp - -types = sp.io.import_script_from_url("file:./contracts/src/Types.py") - - -class EncodeLibrary: - def encode_service_message(self, params): - sp.set_type(params, sp.TRecord(service_type_value = sp.TNat, data = sp.TBytes)) - - encode_service_type = sp.view("encode_nat", self.data.helper, params.service_type_value, t=sp.TBytes).open_some() - rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [encode_service_type, params.data], t=sp.TBytes).open_some() - - return rlp_bytes_with_prefix - - - def encode_transfer_coin_msg(self, data): - sp.set_type(data, types.Types.TransferCoin) - - rlp = sp.local("rlp", sp.bytes("0x")) - temp = sp.local("temp", sp.bytes("0x")) - coin_name = sp.local("coin_name", sp.bytes("0x")) - - sp.for i in sp.range(0, sp.len(data.assets)): - coin_name.value = sp.view("encode_string", self.data.helper, data.assets.get(i, default_value=sp.record(coin_name="",value=sp.nat(0))).coin_name, t=sp.TBytes).open_some() - temp.value = sp.view("encode_nat", self.data.helper, data.assets.get(i, default_value=sp.record(coin_name="",value=sp.nat(0))).value, t=sp.TBytes).open_some() - rlp.value = sp.view("encode_list", self.data.helper, [rlp.value, coin_name.value, temp.value], t=sp.TBytes).open_some() - - from_addr_encoded = sp.view("encode_string", self.data.helper, data.from_addr, t=sp.TBytes).open_some() - to_addr_encoded = sp.view("encode_string", self.data.helper, data.to, t=sp.TBytes).open_some() - rlp.value = sp.view("encode_list", self.data.helper, [from_addr_encoded, to_addr_encoded, rlp.value], t=sp.TBytes).open_some() - - return rlp.value From b2a9af337ef9507743671aeb8ae54d1d64ea68c5 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Fri, 18 Aug 2023 08:15:02 +0545 Subject: [PATCH 198/211] fix: reformatted to original --- cmd/iconbridge/chain/bsc/sender.go | 6 ------ cmd/iconbridge/chain/icon/sender.go | 2 +- cmd/iconbridge/chain/icon/verifier.go | 7 ------- 3 files changed, 1 insertion(+), 14 deletions(-) diff --git a/cmd/iconbridge/chain/bsc/sender.go b/cmd/iconbridge/chain/bsc/sender.go index b7f85d67..9bb17754 100644 --- a/cmd/iconbridge/chain/bsc/sender.go +++ b/cmd/iconbridge/chain/bsc/sender.go @@ -335,9 +335,3 @@ func revertReason(data []byte) string { length := binary.BigEndian.Uint64(data[24:32]) return string(data[32 : 32+length]) } - -func Print(){ - for i:= 0;i<50;i++{ - fmt.Println("+") - } -} diff --git a/cmd/iconbridge/chain/icon/sender.go b/cmd/iconbridge/chain/icon/sender.go index 9292d0ca..d4c00dcb 100644 --- a/cmd/iconbridge/chain/icon/sender.go +++ b/cmd/iconbridge/chain/icon/sender.go @@ -43,7 +43,7 @@ const ( defaultTxSizeLimit = txMaxDataSize / (1 + txOverheadScale) defaultGetRelayResultInterval = time.Second defaultRelayReSendInterval = time.Second - defaultStepLimit = 300000000 + defaultStepLimit = 13610920010 ) // NewSender ... diff --git a/cmd/iconbridge/chain/icon/verifier.go b/cmd/iconbridge/chain/icon/verifier.go index b64c817f..94b3f9cb 100644 --- a/cmd/iconbridge/chain/icon/verifier.go +++ b/cmd/iconbridge/chain/icon/verifier.go @@ -91,14 +91,9 @@ func (vr *Verifier) Verify(blockHeader *types.BlockHeader, votes []byte) (ok boo numVotes := 0 validators := make(map[common.Address]struct{}) - // fmt.Printf("height: %d, votesHash: %v\n", blockHeader.Height, blockHeader.VotesHash) - // fmt.Printf("nextValidatorsHash: %v\n", nextValidatorsHash) - // fmt.Print("listValidators:") for _, val := range listValidators { - // fmt.Printf("%v, ", &val) validators[val] = struct{}{} } - // fmt.Println() for _, item := range cvl.Items { vote.Timestamp = item.Timestamp @@ -107,7 +102,6 @@ func (vr *Verifier) Verify(blockHeader *types.BlockHeader, votes []byte) (ok boo continue // skip error } address := common.NewAccountAddressFromPublicKey(pub) - // fmt.Printf("cvl.Items.address(%d):%v\n", i, address) if address == nil { continue } @@ -119,7 +113,6 @@ func (vr *Verifier) Verify(blockHeader *types.BlockHeader, votes []byte) (ok boo return true, nil } } - // fmt.Println("VotesCount:", numVotes) return true, nil // return false, fmt.Errorf("insufficient votes") From c75d312646cc198c00b947ce41de3c5709e94ca4 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Fri, 18 Aug 2023 08:22:06 +0545 Subject: [PATCH 199/211] fix: removed register token --- tezos-addresses/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tezos-addresses/main.go b/tezos-addresses/main.go index 6d2e59fa..46ca38d1 100755 --- a/tezos-addresses/main.go +++ b/tezos-addresses/main.go @@ -454,7 +454,7 @@ func main() { // register native coin // fmt.Println(res) - register(btsCoreClient.Address(), os.Getenv("ICON_NATIVE_COIN_NAME"), opts) + // register(btsCoreClient.Address(), os.Getenv("ICON_NATIVE_COIN_NAME"), opts) //*********************************************************************************************************************************** // add relay From 35a90a604979c9ade74bf49ccda10f024e39d466 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Fri, 18 Aug 2023 08:22:39 +0545 Subject: [PATCH 200/211] fix: uncommented build script --- .../icon-tezos/scripts/mainnet.i2t.bmr.sh | 60 +++++++++---------- .../icon-tezos/scripts/testnet.i2t.bmr.sh | 58 +++++++++--------- 2 files changed, 59 insertions(+), 59 deletions(-) diff --git a/devnet/docker/icon-tezos/scripts/mainnet.i2t.bmr.sh b/devnet/docker/icon-tezos/scripts/mainnet.i2t.bmr.sh index dd3faa4f..3071935b 100755 --- a/devnet/docker/icon-tezos/scripts/mainnet.i2t.bmr.sh +++ b/devnet/docker/icon-tezos/scripts/mainnet.i2t.bmr.sh @@ -772,41 +772,41 @@ start_relay() { } -# ensure_config_dir -# ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.secret -# ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret -# ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.secret -# ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.json $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.secret -# ensure_tezos_keystore -# fund_it_flag - -# build_javascores -# deploy_javascore_bmc -# deploy_javascore_bts 0 0 18 -# # deploy_javascore_token - -# configure_javascore_add_bmc_owner -# configure_javascore_add_bts -# configure_javascore_add_bts_owner -# configure_javascore_bmc_setFeeAggregator -# configure_javascore_bts_setICXFee 0 0 +ensure_config_dir +ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.secret +ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret +ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.secret +ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.json $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.secret +ensure_tezos_keystore +fund_it_flag + +build_javascores +deploy_javascore_bmc +deploy_javascore_bts 0 0 18 +# deploy_javascore_token + +configure_javascore_add_bmc_owner +configure_javascore_add_bts +configure_javascore_add_bts_owner +configure_javascore_bmc_setFeeAggregator +configure_javascore_bts_setICXFee 0 0 # configure_javascore_register_native_token $TZ_NATIVE_COIN_NAME $TZ_COIN_SYMBOL $TZ_FIXED_FEE $TZ_NUMERATOR $TZ_DECIMALS -# # # # tezos configuration -# deploy_smartpy_bmc_management -# deploy_smartpy_bmc_periphery -# deploy_smartpy_bts_periphery -# deploy_smartpy_bts_core -# deploy_smartpy_bts_owner_manager -# configure_dotenv -# run_tezos_setters +# # # tezos configuration +deploy_smartpy_bmc_management +deploy_smartpy_bmc_periphery +deploy_smartpy_bts_periphery +deploy_smartpy_bts_core +deploy_smartpy_bts_owner_manager +configure_dotenv +run_tezos_setters -# # # # icon configuration of tezos -# configure_javascore_addLink -# configure_javascore_setLinkHeight -# configure_bmc_javascore_addRelay +# # # icon configuration of tezos +configure_javascore_addLink +configure_javascore_setLinkHeight +configure_bmc_javascore_addRelay configure_relay_config > $CONFIG_DIR/_ixh/relay.config.json diff --git a/devnet/docker/icon-tezos/scripts/testnet.i2t.bmr.sh b/devnet/docker/icon-tezos/scripts/testnet.i2t.bmr.sh index 7dbff9b5..23bfa2ae 100755 --- a/devnet/docker/icon-tezos/scripts/testnet.i2t.bmr.sh +++ b/devnet/docker/icon-tezos/scripts/testnet.i2t.bmr.sh @@ -756,8 +756,8 @@ configure_relay_config() { --arg src_options_verifier_validatorsHash "$(cat $CONFIG_DIR/_ixh/icon.chain.validators)" \ --arg dst_address "$(cat $CONFIG_DIR/_ixh/tz.addr.bmcperipherybtp)" \ --arg dst_endpoint "$TZ_NET_URI" \ - --arg dst_key_store "$RELAYER_ADDRESS" \ - --arg dst_key_store_cointype "xtz" \ + --arg dst_key_store "$(echo $(cat $CONFIG_DIR/_ixh/keystore/tz.bmr.wallet))" \ + --arg secret "$(echo $(cat $CONFIG_DIR/_ixh/keystore/tz.bmr.wallet.secret))" \ --arg secret "edskRz1HoD3cWkmWhCNS5LjBrJNWChGuKWB4HnVoN5UqVsUCpcNJR67ZxKs965u8RgRwptrtGc2ufYZoeECgB77RKm1gTbQ6eB" \ --arg dst_key_password "xyz" \ --argjson dst_tx_data_size_limit 8192 \ @@ -772,45 +772,45 @@ start_relay() { } -# ensure_config_dir -# ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.secret -# ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret -# ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.secret -# ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.json $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.secret -# ensure_tezos_keystore -# fund_it_flag +ensure_config_dir +ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bts.wallet.secret +ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bmc.wallet.secret +ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.json $CONFIG_DIR/_ixh/keystore/icon.bmr.wallet.secret +ensure_key_store $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.json $CONFIG_DIR/_ixh/keystore/icon.fa.wallet.secret +ensure_tezos_keystore +fund_it_flag -# build_javascores -# deploy_javascore_bmc -# deploy_javascore_bts 0 0 18 -# # deploy_javascore_token +build_javascores +deploy_javascore_bmc +deploy_javascore_bts 0 0 18 +# deploy_javascore_token -# configure_javascore_add_bmc_owner -# configure_javascore_add_bts -# configure_javascore_add_bts_owner -# configure_javascore_bmc_setFeeAggregator -# configure_javascore_bts_setICXFee 0 0 +configure_javascore_add_bmc_owner +configure_javascore_add_bts +configure_javascore_add_bts_owner +configure_javascore_bmc_setFeeAggregator +configure_javascore_bts_setICXFee 0 0 # configure_javascore_register_native_token $TZ_NATIVE_COIN_NAME $TZ_COIN_SYMBOL $TZ_FIXED_FEE $TZ_NUMERATOR $TZ_DECIMALS # # # # tezos configuration -# deploy_smartpy_bmc_management -# deploy_smartpy_bmc_periphery -# deploy_smartpy_bts_periphery -# deploy_smartpy_bts_core -# deploy_smartpy_bts_owner_manager +deploy_smartpy_bmc_management +deploy_smartpy_bmc_periphery +deploy_smartpy_bts_periphery +deploy_smartpy_bts_core +deploy_smartpy_bts_owner_manager configure_dotenv run_tezos_setters -# # # # icon configuration of tezos -# configure_javascore_addLink -# configure_javascore_setLinkHeight -# configure_bmc_javascore_addRelay +# # # icon configuration of tezos +configure_javascore_addLink +configure_javascore_setLinkHeight +configure_bmc_javascore_addRelay -# configure_relay_config > $CONFIG_DIR/_ixh/relay.config.json -# start_relay +configure_relay_config > $CONFIG_DIR/_ixh/relay.config.json +start_relay From 9a6c9486d9823fcd5d2daa4b7e68cf1eba1ea296 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Fri, 18 Aug 2023 08:27:07 +0545 Subject: [PATCH 201/211] fix: remove unnecessary files --- devnet/docker/icon-tezos/scripts/config.sh | 76 ----- devnet/docker/icon-tezos/scripts/deploysc.sh | 258 ----------------- devnet/docker/icon-tezos/scripts/keystore.sh | 86 ------ .../icon-tezos/scripts/token.javascore.sh | 267 ------------------ 4 files changed, 687 deletions(-) delete mode 100644 devnet/docker/icon-tezos/scripts/config.sh delete mode 100644 devnet/docker/icon-tezos/scripts/deploysc.sh delete mode 100644 devnet/docker/icon-tezos/scripts/keystore.sh delete mode 100644 devnet/docker/icon-tezos/scripts/token.javascore.sh diff --git a/devnet/docker/icon-tezos/scripts/config.sh b/devnet/docker/icon-tezos/scripts/config.sh deleted file mode 100644 index 918841b4..00000000 --- a/devnet/docker/icon-tezos/scripts/config.sh +++ /dev/null @@ -1,76 +0,0 @@ -#!/bin/bash -#BUILD_DIR=$(echo "$(cd "$(dirname "../../../../../")"; pwd)"/build) -BASE_DIR=$(echo "$(cd "$(dirname "../../")"; pwd)") -BUILD_DIR=$BASE_DIR/build -export ICONBRIDGE_CONFIG_DIR=$BASE_DIR/_ixh -export ICONBRIDGE_CONTRACTS_DIR=$BUILD_DIR/contracts -export ICONBRIDGE_SCRIPTS_DIR=$BASE_DIR/scripts -export ICONBRIDGE_BIN_DIR=$BASE_DIR - -export CONFIG_DIR=${CONFIG_DIR:-${ICONBRIDGE_CONFIG_DIR}} -export CONTRACTS_DIR=${CONTRACTS_DIR:-${ICONBRIDGE_CONTRACTS_DIR}} -export SCRIPTS_DIR=${SCRIPTS_DIR:-${ICONBRIDGE_SCRIPTS_DIR}} - -################################################################################### -# testnet: begin -export TAG="ICON BSC TESTNET" -export BSC_BMC_NET="0x61.bsc" -export ICON_BMC_NET="0x2.icon" -export SNOW_BMC_NET="0x229.snow" -export TZ_BMC_NET="NetXnHfVqm9iesp.tezos" -export GOLOOP_RPC_NID="0x2" -export BSC_NID="97" -export TEZOS_NID="NetXnHfVqm9iesp" - -export ICON_ENDPOINT="https://lisbon.net.solidwallet.io/api/v3/icon_dex" -export ICON_NATIVE_COIN_SYM=("ICX") -export ICON_NATIVE_COIN_NAME=("btp-$ICON_BMC_NET-ICX") -export ICON_NATIVE_TOKEN_SYM=("sICX" "bnUSD") -export ICON_NATIVE_TOKEN_NAME=("btp-$ICON_BMC_NET-sICX" "btp-$ICON_BMC_NET-bnUSD") -export ICON_WRAPPED_COIN_SYM=("BNB" "BUSD" "USDT" "USDC" "BTCB" "ETH" "ICZ") -export ICON_WRAPPED_COIN_NAME=("btp-$BSC_BMC_NET-BNB" "btp-$BSC_BMC_NET-BUSD" "btp-$BSC_BMC_NET-USDT" "btp-$BSC_BMC_NET-USDC" "btp-$BSC_BMC_NET-BTCB" "btp-$BSC_BMC_NET-ETH" "btp-$SNOW_BMC_NET-ICZ") -export FEE_GATHERING_INTERVAL=21600 - - -export ICON_NATIVE_COIN_FIXED_FEE=(4300000000000000000) -export ICON_NATIVE_COIN_FEE_NUMERATOR=(100) -export ICON_NATIVE_COIN_DECIMALS=(18) -export ICON_NATIVE_TOKEN_FIXED_FEE=(3900000000000000000 1500000000000000000) -export ICON_NATIVE_TOKEN_FEE_NUMERATOR=(100 100) -export ICON_NATIVE_TOKEN_DECIMALS=(18 18) -export ICON_WRAPPED_COIN_FIXED_FEE=(5000000000000000 1500000000000000000 1500000000000000000 1500000000000000000 62500000000000 750000000000000 4300000000000000000) -export ICON_WRAPPED_COIN_FEE_NUMERATOR=(100 100 100 100 100 100 100) -export ICON_WRAPPED_COIN_DECIMALS=(18 18 18 18 18 18 18) - -export TZ_ENDPOINT="https://ghostnet.tezos.marigold.dev" -export TZ_NATIVE_COIN_SYM=("XTZ") -export TZ_NATIVE_COIN_NAME=("btp-$TZ_BMC_NET-XTZ") -export TZ_NATIVE_TOKEN_SYM=("BUSD" "USDT" "USDC" "BTCB" "ETH") -export TZ_NATIVE_TOKEN_NAME=("btp-$TZ_BMC_NET-BUSD" "btp-$TZ_BMC_NET-USDT" "btp-$TZ_BMC_NET-USDC" "btp-$TZ_BMC_NET-BTCB" "btp-$TZ_BMC_NET-ETH") -export TZ_WRAPPED_COIN_SYM=("ICX" "sICX" "bnUSD" "ICZ") -export TZ_WRAPPED_COIN_NAME=("btp-$ICON_BMC_NET-ICX" "btp-$ICON_BMC_NET-sICX" "btp-$ICON_BMC_NET-bnUSD" "btp-$SNOW_BMC_NET-ICZ") - -export TZ_NATIVE_COIN_FIXED_FEE=(0) -export TZ_NATIVE_COIN_FEE_NUMERATOR=(0) -export TZ_NATIVE_COIN_DECIMALS=(6) -export TZ_NATIVE_TOKEN_FIXED_FEE=(0 1500000000000000000 1500000000000000000 62500000000000 750000000000000) -export TZ_NATIVE_TOKEN_FEE_NUMERATOR=(100 100 100 100 100) -export TZ_NATIVE_TOKEN_DECIMALS=(18 18 18 18 18) -export TZ_WRAPPED_COIN_FIXED_FEE=(4300000000000000000 3900000000000000000 1500000000000000000 4300000000000000000) -export TZ_WRAPPED_COIN_FEE_NUMERATOR=(100 100 100 100) -export TZ_WRAPPED_COIN_DECIMALS=(18 18 18 18) - -# testnet: end -################################################################################### - -GOLOOPCHAIN=${GOLOOPCHAIN:-"goloop"} -export GOLOOP_RPC_STEP_LIMIT=5000000000 -export ICON_KEY_STORE=$ICONBRIDGE_CONFIG_DIR/keystore/icon.god.wallet.json -export ICON_SECRET=$ICONBRIDGE_CONFIG_DIR/keystore/icon.god.wallet.secret -export GOLOOP_RPC_URI=$ICON_ENDPOINT -export GOLOOP_RPC_KEY_STORE=$ICON_KEY_STORE -export GOLOOP_RPC_KEY_SECRET=$ICON_SECRET - -export TZ_RPC_URI=$TZ_ENDPOINT -export TZ_KEY_STORE=$ICONBRIDGE_CONFIG_DIR/keystore/tz.god.wallet.json -# export BSC_SECRET=$ICONBRIDGE_CONFIG_DIR/keystore/bsc.god.wallet.secret diff --git a/devnet/docker/icon-tezos/scripts/deploysc.sh b/devnet/docker/icon-tezos/scripts/deploysc.sh deleted file mode 100644 index 91513f34..00000000 --- a/devnet/docker/icon-tezos/scripts/deploysc.sh +++ /dev/null @@ -1,258 +0,0 @@ -#!/bin/bash -set -e - -# Parts of this code is adapted from https://github.com/icon-project/btp/blob/goloop2moonbeam/testnet/goloop2moonbeam/scripts -source config.sh -source keystore.sh -source rpc.sh -source generate_e2e_config.sh - -setup_account() { - echo "check god keys..." - if [ ! -f "${ICON_KEY_STORE}" ]; then - ensure_key_store $ICON_KEY_STORE $ICON_SECRET - echo "Do not Panic..." - echo "Missing ICON God Wallet on the required path. One has been created "$ICON_KEY_STORE - echo "Fund this newly created wallet and rerun the same command again" - exit 0 - fi - if [ ! -f "${BSC_KEY_STORE}" ]; then - ensure_bsc_key_store $BSC_KEY_STORE $BSC_SECRET - echo "Do not Panic..." - echo "Missing BSC God Wallet on the required path. One has been created "$BSC_KEY_STORE - echo "Fund this newly created wallet and rerun again " - exit 0 - fi - export PRIVATE_KEY="[\""$(cat $BSC_KEY_STORE.priv)"\"]" - # add owners - echo "List/Create user accounts" - ensure_key_store $CONFIG_DIR/keystore/icon.bts.wallet.json $CONFIG_DIR/keystore/icon.bts.wallet.secret - ensure_key_store $CONFIG_DIR/keystore/icon.bmc.wallet.json $CONFIG_DIR/keystore/icon.bmc.wallet.secret - ensure_key_store $CONFIG_DIR/keystore/icon.bmr.wallet.json $CONFIG_DIR/keystore/icon.bmr.wallet.secret - ensure_key_store $CONFIG_DIR/keystore/icon.fa.wallet.json $CONFIG_DIR/keystore/icon.fa.wallet.secret - - ensure_bsc_key_store $CONFIG_DIR/keystore/bsc.bts.wallet.json $CONFIG_DIR/keystore/bsc.bts.wallet.secret - ensure_bsc_key_store $CONFIG_DIR/keystore/bsc.bmc.wallet.json $CONFIG_DIR/keystore/bsc.bmc.wallet.secret - ensure_bsc_key_store $CONFIG_DIR/keystore/bsc.bmr.wallet.json $CONFIG_DIR/keystore/bsc.bmr.wallet.secret -} - -deploysc() { - if [ ! -d $BUILD_DIR ]; then - echo "Do not Panic..." - echo "Build Artifacts have not been created. Expected on path "$BUILD_DIR - echo "Run make buildsc to do so. Check README.md for more" - exit 0 - fi - echo "Start " - sleep 15 - echo "$GOLOOP_RPC_NID.icon" >$CONFIG_DIR/net.btp.icon #0x240fa7.icon - mkdir -p $CONFIG_DIR/tx - - source token.javascore.sh - source token.solidity.sh - - if [ ! -f $CONFIG_DIR/bsc.deploy.all ]; then - echo "Deploy solidity" - sleep 2 - deploy_solidity_bmc - deploy_solidity_bts "${BSC_NATIVE_COIN_FIXED_FEE[0]}" "${BSC_NATIVE_COIN_FEE_NUMERATOR[0]}" "${BSC_NATIVE_COIN_DECIMALS[0]}" - - if [ -n "${INIT_ADDRESS_PATH}" ]; then - if [ ! -f $INIT_ADDRESS_PATH ]; then - echo "No file found on "$INIT_ADDRESS_PATH - return 1 - fi - for i in "${!BSC_NATIVE_TOKEN_SYM[@]}"; do - addr=$(cat $INIT_ADDRESS_PATH | jq -r .solidity.${BSC_NATIVE_TOKEN_SYM[$i]}) - if [ "$addr" != "null" ]; then - echo -n $addr >$CONFIG_DIR/bsc.addr.${BSC_NATIVE_TOKEN_SYM[$i]} - else - echo "BSC Token does not exist on address file" ${BSC_NATIVE_TOKEN_SYM[$i]} - return 1 - fi - done - else - for i in "${!BSC_NATIVE_TOKEN_SYM[@]}"; do - deploy_solidity_token "${BSC_NATIVE_TOKEN_NAME[$i]}" "${BSC_NATIVE_TOKEN_SYM[$i]}" - done - fi - echo "CONFIGURE BSC" - configure_solidity_add_bmc_owner - configure_solidity_add_bts_service - configure_solidity_set_fee_ratio "${BSC_NATIVE_COIN_FIXED_FEE[0]}" "${BSC_NATIVE_COIN_FEE_NUMERATOR[0]}" - configure_solidity_add_bts_owner - echo "Register BSC Tokens" - for i in "${!BSC_NATIVE_TOKEN_SYM[@]}"; do - bsc_register_native_token "${BSC_NATIVE_TOKEN_NAME[$i]}" "${BSC_NATIVE_TOKEN_SYM[$i]}" "${BSC_NATIVE_TOKEN_FIXED_FEE[$i]}" "${BSC_NATIVE_TOKEN_FEE_NUMERATOR[$i]}" "${BSC_NATIVE_TOKEN_DECIMALS[$i]}" - get_coinID "${BSC_NATIVE_TOKEN_NAME[$i]}" "${BSC_NATIVE_TOKEN_SYM[$i]}" - done - for i in "${!BSC_WRAPPED_COIN_SYM[@]}"; do - bsc_register_wrapped_coin "${BSC_WRAPPED_COIN_NAME[$i]}" "${BSC_WRAPPED_COIN_SYM[$i]}" "${BSC_WRAPPED_COIN_FIXED_FEE[$i]}" "${BSC_WRAPPED_COIN_FEE_NUMERATOR[$i]}" "${BSC_WRAPPED_COIN_DECIMALS[$i]}" - get_coinID "${BSC_WRAPPED_COIN_NAME[$i]}" "${BSC_WRAPPED_COIN_SYM[$i]}" - done - echo "deployedSol" >$CONFIG_DIR/bsc.deploy.all - fi - - if [ ! -f $CONFIG_DIR/icon.deploy.all ]; then - echo "Deploy Javascore" - sleep 2 - deploy_javascore_bmc - deploy_javascore_bts "${ICON_NATIVE_COIN_FIXED_FEE[0]}" "${ICON_NATIVE_COIN_FEE_NUMERATOR[0]}" "${ICON_NATIVE_COIN_DECIMALS[0]}" - - if [ -n "${INIT_ADDRESS_PATH}" ]; then - if [ ! -f $INIT_ADDRESS_PATH ]; then - echo "No file found on "$INIT_ADDRESS_PATH - return 1 - fi - for i in "${!ICON_NATIVE_TOKEN_SYM[@]}"; do - addr=$(cat $INIT_ADDRESS_PATH | jq -r .javascore.${ICON_NATIVE_TOKEN_SYM[$i]}) - if [ "$addr" != "null" ]; then - echo -n $addr >$CONFIG_DIR/icon.addr.${ICON_NATIVE_TOKEN_SYM[$i]} - else - echo "ICON Token ${ICON_NATIVE_TOKEN_SYM[$i]} does not exist on address file" - return 1 - fi - done - else - for i in "${!ICON_NATIVE_TOKEN_SYM[@]}"; do - deploy_javascore_token "${ICON_NATIVE_TOKEN_NAME[$i]}" "${ICON_NATIVE_TOKEN_SYM[$i]}" - done - fi - echo "CONFIGURE ICON" - configure_javascore_add_bmc_owner - configure_javascore_bmc_setFeeAggregator - configure_javascore_add_bts - configure_javascore_add_bts_owner - configure_javascore_bts_setICXFee "${ICON_NATIVE_COIN_FIXED_FEE[0]}" "${ICON_NATIVE_COIN_FEE_NUMERATOR[0]}" - echo "Register ICON Tokens" - for i in "${!ICON_NATIVE_TOKEN_SYM[@]}"; do - configure_javascore_register_native_token "${ICON_NATIVE_TOKEN_NAME[$i]}" "${ICON_NATIVE_TOKEN_SYM[$i]}" "${ICON_NATIVE_TOKEN_FIXED_FEE[$i]}" "${ICON_NATIVE_TOKEN_FEE_NUMERATOR[$i]}" "${ICON_NATIVE_TOKEN_DECIMALS[$i]}" - get_btp_icon_coinId "${ICON_NATIVE_TOKEN_NAME[$i]}" "${ICON_NATIVE_TOKEN_SYM[$i]}" - done - for i in "${!ICON_WRAPPED_COIN_SYM[@]}"; do - configure_javascore_register_wrapped_coin "${ICON_WRAPPED_COIN_NAME[$i]}" "${ICON_WRAPPED_COIN_SYM[$i]}" "${ICON_WRAPPED_COIN_FIXED_FEE[$i]}" "${ICON_WRAPPED_COIN_FEE_NUMERATOR[$i]}" "${ICON_WRAPPED_COIN_DECIMALS[$i]}" - get_btp_icon_coinId "${ICON_WRAPPED_COIN_NAME[$i]}" "${ICON_WRAPPED_COIN_SYM[$i]}" - done - echo "deployedJavascore" >$CONFIG_DIR/icon.deploy.all - fi - - if [ ! -f $CONFIG_DIR/link.all ]; then - echo "LINK ICON" - configure_javascore_addLink - configure_javascore_setLinkHeight - configure_bmc_javascore_addRelay - echo "LINK BSC" - add_icon_link - set_link_height - add_icon_relay - echo "linked" >$CONFIG_DIR/link.all - fi - - generate_addresses_json >$CONFIG_DIR/addresses.json - generate_relay_config >$CONFIG_DIR/bmr.config.json - generate_e2e_config >$CONFIG_DIR/e2e.config.json - wait_for_file $CONFIG_DIR/bmr.config.json - - echo "Smart contracts have been deployed " - echo "You can now run the relay with make runrelaysrc OR make runrelayimg" -} - -wait_for_file() { - FILE_NAME=$1 - timeout=10 - while [ ! -f "$FILE_NAME" ]; do - if [ "$timeout" == 0 ]; then - echo "ERROR: Timeout while waiting for the file $FILE_NAME." - exit 1 - fi - sleep 1 - timeout=$(expr $timeout - 1) - - echo "waiting for the output file: $FILE_NAME" - done -} - -generate_relay_config() { - jq -n ' - .base_dir = $base_dir | - .log_level = "debug" | - .console_level = "trace" | - .log_writer.filename = $log_writer_filename | - .relays = [ $b2i_relay, $i2b_relay ]' \ - --arg base_dir "bmr" \ - --arg log_writer_filename "bmr/bmr.log" \ - --argjson b2i_relay "$( - jq -n ' - .name = "b2i" | - .src.address = $src_address | - .src.endpoint = [ $src_endpoint ] | - .src.options.verifier.blockHeight = $src_options_verifier_blockHeight | - .src.options.verifier.parentHash = $src_options_verifier_parentHash | - .src.options.verifier.validatorData = $src_options_verifier_validatorData | - .src.options.syncConcurrency = 100 | - .src.offset = $src_offset | - .dst.address = $dst_address | - .dst.endpoint = [ $dst_endpoint ] | - .dst.options = $dst_options | - .dst.key_store = $dst_key_store | - .dst.key_store.coinType = $dst_key_store_cointype | - .dst.key_password = $dst_key_password ' \ - --arg src_address "$(cat $CONFIG_DIR/bsc.addr.bmcbtp)" \ - --arg src_endpoint "$BSC_ENDPOINT" \ - --argjson src_offset "$(cat $CONFIG_DIR/bsc.chain.height)" \ - --argjson src_options_verifier_blockHeight "$(cat $CONFIG_DIR/bsc.chain.height)" \ - --arg src_options_verifier_parentHash "$(cat $CONFIG_DIR/bsc.chain.parentHash)" \ - --arg src_options_verifier_validatorData "$(cat $CONFIG_DIR/bsc.chain.validatorData)" \ - --arg dst_address "$(cat $CONFIG_DIR/icon.addr.bmcbtp)" \ - --arg dst_endpoint "$ICON_ENDPOINT" \ - --argfile dst_key_store "$CONFIG_DIR/keystore/icon.bmr.wallet.json" \ - --arg dst_key_store_cointype "icx" \ - --arg dst_key_password "$(cat $CONFIG_DIR/keystore/icon.bmr.wallet.secret)" \ - --argjson dst_options '{"step_limit":2500000000, "tx_data_size_limit":8192,"balance_threshold":"10000000000000000000"}' - )" \ - --argjson i2b_relay "$( - jq -n ' - .name = "i2b" | - .src.address = $src_address | - .src.endpoint = [ $src_endpoint ] | - .src.offset = $src_offset | - .src.options.verifier.blockHeight = $src_options_verifier_blockHeight | - .src.options.verifier.validatorsHash = $src_options_verifier_validatorsHash | - .src.options.syncConcurrency = 100 | - .dst.address = $dst_address | - .dst.endpoint = [ $dst_endpoint ] | - .dst.options = $dst_options | - .dst.tx_data_size_limit = $dst_tx_data_size_limit | - .dst.key_store = $dst_key_store | - .dst.key_store.coinType = $dst_key_store_cointype | - .dst.key_password = $dst_key_password ' \ - --arg src_address "$(cat $CONFIG_DIR/icon.addr.bmcbtp)" \ - --arg src_endpoint "$ICON_ENDPOINT" \ - --argjson src_offset "$(cat $CONFIG_DIR/icon.chain.height)" \ - --argjson src_options_verifier_blockHeight "$(cat $CONFIG_DIR/icon.chain.height)" \ - --arg src_options_verifier_validatorsHash "$(cat $CONFIG_DIR/icon.chain.validators)" \ - --arg dst_address "$(cat $CONFIG_DIR/bsc.addr.bmcbtp)" \ - --arg dst_endpoint "$BSC_ENDPOINT" \ - --argfile dst_key_store "$CONFIG_DIR/keystore/bsc.bmr.wallet.json" \ - --arg dst_key_store_cointype "evm" \ - --arg dst_key_password "$(cat $CONFIG_DIR/keystore/bsc.bmr.wallet.secret)" \ - --argjson dst_tx_data_size_limit 8192 \ - --argjson dst_options '{"gas_limit":24000000,"tx_data_size_limit":8192,"balance_threshold":"100000000000000000000","boost_gas_price":1.0}' - )" -} - -#wait-for-it.sh $GOLOOP_RPC_ADMIN_URI -# run provisioning -echo "start..." -echo "Load Configuration Files For : $TAG" - -read -p "Confirm? [y/N]: " proceed - -if [[ $proceed == "y" ]]; then - setup_account - deploysc - echo "Done deploying smart contracts" -else - echo "Exit" - exit 0 -fi \ No newline at end of file diff --git a/devnet/docker/icon-tezos/scripts/keystore.sh b/devnet/docker/icon-tezos/scripts/keystore.sh deleted file mode 100644 index a9dd6e38..00000000 --- a/devnet/docker/icon-tezos/scripts/keystore.sh +++ /dev/null @@ -1,86 +0,0 @@ -#!/bin/bash -source config.sh - -ensure_key_secret() { - if [ $# -lt 1 ] ; then - echo "Usage: ensure_key_secret SECRET_PATH" - return 1 - fi - local KEY_SECRET=$1 - if [ ! -f "${KEY_SECRET}" ]; then - mkdir -p $(dirname ${KEY_SECRET}) - echo -n $(openssl rand -hex 20) > ${KEY_SECRET} - fi - echo ${KEY_SECRET} -} - -ensure_key_store() { - if [ $# -lt 2 ] ; then - echo "Usage: ensure_key_store KEYSTORE_PATH SECRET_PATH" - return 1 - fi - local KEY_STORE=$1 - local KEY_SECRET=$(ensure_key_secret $2) - if [ ! -f "${KEY_STORE}" ]; then - goloop ks gen --out ${KEY_STORE}tmp -p $(cat ${KEY_SECRET}) > /dev/null 2>&1 - cat ${KEY_STORE}tmp | jq -r . > ${KEY_STORE} - rm ${KEY_STORE}tmp - - fi - echo ${KEY_STORE} -} - -ensure_bsc_key_store() { - if [ $# -lt 2 ] ; then - echo "Usage: ensure_key_store KEYSTORE_PATH SECRET_PATH" - return 1 - fi - - local KEY_STORE_PATH=$1 - local KEY_SECRET_PATH=$(ensure_key_secret $2) - if [ ! -f "${KEY_STORE_PATH}" ]; then - mkdir -p $ICONBRIDGE_CONFIG_DIR/keystore - ethkey generate --passwordfile $KEY_SECRET_PATH --json tmp - cat tmp | jq -r . > $KEY_STORE_PATH - ethkey inspect --json --private --passwordfile $KEY_SECRET_PATH $KEY_STORE_PATH | jq -r .PrivateKey > ${KEY_STORE_PATH}.priv - rm tmp - # tr -dc A-Fa-f0-9 $ICONBRIDGE_CONFIG_DIR/keystore/$(basename ${KEY_STORE_PATH}).priv - # tmpPath=$(geth account import --datadir $ICONBRIDGE_CONFIG_DIR --password $KEY_SECRET_PATH $ICONBRIDGE_CONFIG_DIR/keystore/$(basename ${KEY_STORE_PATH}).priv | sed -e "s/^Address: {//" -e "s/}//") - # fileMatch=$(find $ICONBRIDGE_CONFIG_DIR/keystore -type f -name '*'$tmpPath) - # cat $fileMatch | jq -r . > $KEY_STORE_PATH - # rm $fileMatch - fi - echo ${KEY_STORE_PATH} -} - -ensure_tezos_address() { - echo ensuring tezos address - local KEY_STORE=$1 - local wallet=$(echo $(octez-client list known addresses | grep $KEY_STORE)) - wallet=${wallet%:*} - ensure_key_secret $CONFIG_DIR/keystore/$wallet - if [ $wallet ]; then - echo found so deleting - octez-client forget address $wallet --force - fi - octez-client gen keys $KEY_STORE - wallet_info=$(echo $(octez-client show address $KEY_STORE -S)) - echo $wallet_info > $CONFIG_DIR/keystore/$KEY_STORE -} - -ensure_empty_key_secret() { - if [ $# -lt 1 ] ; then - echo "Usage: ensure_key_secret SECRET_PATH" - return 1 - fi - local KEY_SECRET=$1 - if [ ! -f "${KEY_SECRET}" ]; then - mkdir -p $(dirname ${KEY_SECRET}) - echo -n '' > ${KEY_SECRET} - fi - echo ${KEY_SECRET} -} - -ensure_tezos_address bmcOwner -ensure_tezos_address bmrOwner -ensure_tezos_address btsOwner \ No newline at end of file diff --git a/devnet/docker/icon-tezos/scripts/token.javascore.sh b/devnet/docker/icon-tezos/scripts/token.javascore.sh deleted file mode 100644 index 71e466d0..00000000 --- a/devnet/docker/icon-tezos/scripts/token.javascore.sh +++ /dev/null @@ -1,267 +0,0 @@ -#!/bin/bash -######################################## javascore service methods - start ###################################### -source utils.sh -source rpc.sh -source keystore.sh -goloop_lastblock() { - goloop rpc lastblock -} - -extract_chain_height_and_validator() { - cd $CONFIG_DIR - local icon_block_height=$(goloop_lastblock | jq -r .height) - echo $icon_block_height > icon.chain.height - echo $(URI=$ICON_ENDPOINT HEIGHT=$(decimal2Hex $(($icon_block_height - 1))) $ICONBRIDGE_BIN_DIR/iconvalidators | jq -r .hash) > icon.chain.validators -} - -deploy_javascore_bmc() { - cd $CONFIG_DIR - if [ ! -f icon.addr.bmcbtp ]; then - echo "deploying javascore BMC" - extract_chain_height_and_validator - goloop rpc sendtx deploy $CONTRACTS_DIR/javascore/bmc.jar \ - --content_type application/java \ - --param _net=$(cat net.btp.icon) | jq -r . >tx/tx.icon.bmc - sleep 5 - extract_scoreAddress tx/tx.icon.bmc icon.addr.bmc - echo "btp://$(cat net.btp.icon)/$(cat icon.addr.bmc)" >icon.addr.bmcbtp - fi -} - -deploy_javascore_bts() { - echo "deploying javascore bts" - cd $CONFIG_DIR - if [ ! -f icon.addr.bts ]; then - #local bts_fee_numerator=100 - #local bts_fixed_fee=5000 - goloop rpc sendtx deploy $CONTRACTS_DIR/javascore/bts.jar \ - --content_type application/java \ - --param _name="${ICON_NATIVE_COIN_NAME[0]}" \ - --param _bmc=$(cat icon.addr.bmc) \ - --param _decimals=$(decimal2Hex $3) \ - --param _feeNumerator=$(decimal2Hex $2) \ - --param _fixedFee=$(decimal2Hex $1) \ - --param _serializedIrc2=$(xxd -p $CONTRACTS_DIR/javascore/irc2Tradeable.jar | tr -d '\n') | jq -r . > tx/tx.icon.bts - sleep 5 - extract_scoreAddress tx/tx.icon.bts icon.addr.bts - fi -} - -deploy_javascore_token() { - echo "deploying javascore IRC2Token " $2 - cd $CONFIG_DIR - if [ ! -f icon.addr.$2 ]; then - goloop rpc sendtx deploy $CONTRACTS_DIR/javascore/irc2.jar \ - --content_type application/java \ - --param _name="$1" \ - --param _symbol=$2 \ - --param _initialSupply="0x5f5e100" \ - --param _decimals="0x12" | jq -r . >tx/tx.icon.$2 - sleep 5 - extract_scoreAddress tx/tx.icon.$2 icon.addr.$2 - fi -} - - -configure_javascore_add_bmc_owner() { - echo "bmc Add Owner" - echo $CONFIG_DIR/keystore/icon.bmc.wallet.json - local icon_bmc_owner=$(cat $CONFIG_DIR/keystore/icon.bmc.wallet.json | jq -r .address) - cd $CONFIG_DIR - local is_owner=$(goloop rpc call \ - --to $(cat icon.addr.bmc) \ - --method isOwner \ - --param _addr=$icon_bmc_owner | jq -r .) - if [ "$is_owner" == "0x0" ]; then - goloop rpc sendtx call --to $(cat icon.addr.bmc) \ - --method addOwner \ - --param _addr=$icon_bmc_owner | jq -r . > tx/addbmcowner.icon - sleep 3 - ensure_txresult tx/addbmcowner.icon - fi -} - -configure_javascore_bmc_setFeeAggregator() { - echo "bmc setFeeAggregator" - cd $CONFIG_DIR - local FA=$(cat $CONFIG_DIR/keystore/icon.fa.wallet.json | jq -r .address) - goloop rpc sendtx call --to $(cat icon.addr.bmc) \ - --method setFeeAggregator \ - --param _addr=${FA} | jq -r . >tx/setFeeAggregator.icon - sleep 3 - ensure_txresult tx/setFeeAggregator.icon - - goloop rpc sendtx call --to $(cat icon.addr.bmc) \ - --method setFeeGatheringTerm \ - --param _value=$FEE_GATHERING_INTERVAL | jq -r . >tx/setFeeGatheringTerm.icon - sleep 3 - ensure_txresult tx/setFeeGatheringTerm.icon -} - -configure_javascore_add_bts() { - echo "bmc add bts" - cd $CONFIG_DIR - local hasBTS=$(goloop rpc call \ - --to $(cat icon.addr.bmc) \ - --method getServices | jq -r .bts) - if [ "$hasBTS" == "null" ]; then - goloop rpc sendtx call --to $(cat icon.addr.bmc) \ - --method addService \ - --value 0 \ - --param _addr=$(cat icon.addr.bts) \ - --param _svc="bts" | jq -r . >tx/addService.icon - sleep 3 - ensure_txresult tx/addService.icon - fi - sleep 5 -} - -configure_javascore_add_bts_owner() { - echo "Add bts Owner" - local icon_bts_owner=$(cat $CONFIG_DIR/keystore/icon.bts.wallet.json | jq -r .address) - cd $CONFIG_DIR - local is_owner=$(goloop rpc call \ - --to $(cat icon.addr.bts) \ - --method isOwner \ - --param _addr="$icon_bts_owner" | jq -r .) - if [ "$is_owner" == "0x0" ]; then - goloop rpc sendtx call --to $(cat icon.addr.bts) \ - --method addOwner \ - --param _addr=$icon_bts_owner | jq -r . >tx/addBtsOwner.icon - sleep 3 - ensure_txresult tx/addBtsOwner.icon - fi -} - -configure_javascore_bts_setICXFee() { - echo "bts set fee" ${ICON_NATIVE_COIN_SYM[0]} - #local bts_fee_numerator=100 - #local bts_fixed_fee=5000 - cd $CONFIG_DIR - goloop rpc sendtx call --to $(cat icon.addr.bts) \ - --method setFeeRatio \ - --param _name="${ICON_NATIVE_COIN_NAME[0]}" \ - --param _feeNumerator=$(decimal2Hex $2) \ - --param _fixedFee=$(decimal2Hex $1) | jq -r . >tx/setICXFee.icon - sleep 3 - ensure_txresult tx/setICXFee.icon -} - -configure_javascore_addLink() { - echo "BMC: Add Link to BSC BMC:" - cd $CONFIG_DIR - if [ ! -f icon.configure.addLink ]; then - goloop rpc sendtx call --to $(cat icon.addr.bmc) \ - --method addLink \ - --param _link=$(cat bsc.addr.bmcbtp) | jq -r . >tx/addLink.icon - sleep 3 - ensure_txresult tx/addLink.icon - echo "addedLink" > icon.configure.addLink - fi -} - -configure_javascore_setLinkHeight() { - echo "BMC: SetLinkHeight" - cd $CONFIG_DIR - if [ ! -f icon.configure.setLink ]; then - goloop rpc sendtx call --to $(cat icon.addr.bmc) \ - --method setLinkRxHeight \ - --param _link=$(cat bsc.addr.bmcbtp) \ - --param _height=$(cat bsc.chain.height)| jq -r . >tx/setLinkRxHeight.icon - sleep 3 - ensure_txresult tx/setLinkRxHeight.icon - echo "setLink" > icon.configure.setLink - fi -} - -configure_bmc_javascore_addRelay() { - echo "Adding bsc Relay" - local icon_bmr_owner=$(cat $CONFIG_DIR/keystore/icon.bmr.wallet.json | jq -r .address) - echo $icon_bmr_owner - sleep 5 - echo "Starting" - cd $CONFIG_DIR - if [ ! -f icon.configure.addRelay ]; then - goloop rpc sendtx call --to $(cat icon.addr.bmc) \ - --method addRelay \ - --param _link=$(cat bsc.addr.bmcbtp) \ - --param _addr=${icon_bmr_owner} | jq -r . >tx/addRelay.icon - sleep 3 - ensure_txresult tx/addRelay.icon - echo "addRelay" > icon.configure.addRelay - fi -} - -configure_bmc_javascore_removeRelay() { - cd $CONFIG_DIR - echo "BMC BTP Address" - cat bsc.addr.bmcbtp - sleep 5 - echo "Starting.." - if [ ! -f icon.configure.removeRelay ]; then - goloop rpc sendtx call --to $(cat icon.addr.bmc) \ - --method removeRelay \ - --param _link=$(cat bsc.addr.bmcbtp) \ - --param _addr=$1 | jq -r . >tx/removeRelay.icon - sleep 3 - ensure_txresult tx/removeRelay.icon - echo "removeRelay" > icon.configure.removeRelay - fi -} - - -configure_javascore_register_native_token() { - echo "Register Native Token " $2 - cd $CONFIG_DIR - #local bts_fee_numerator=100 - #local bts_fixed_fee=5000 - if [ ! -f icon.register.coin$2 ]; then - goloop rpc sendtx call --to $(cat icon.addr.bts) \ - --method register \ - --param _name="$1" \ - --param _symbol=$2 \ - --param _decimals=$(decimal2Hex $5) \ - --param _addr=$(cat icon.addr.$2) \ - --param _feeNumerator=$(decimal2Hex $4) \ - --param _fixedFee=$(decimal2Hex $3) | jq -r . >tx/register.coin.$2 - sleep 5 - ensure_txresult tx/register.coin.$2 - echo "registered "$2 > icon.register.coin$2 - fi -} - - -configure_javascore_register_wrapped_coin() { - echo "Register Wrapped Coin " $2 - cd $CONFIG_DIR - #local bts_fee_numerator=100 - #local bts_fixed_fee=5000 - if [ ! -f icon.register.coin$2 ]; then - goloop rpc sendtx call --to $(cat icon.addr.bts) \ - --method register \ - --param _name="$1" \ - --param _symbol=$2 \ - --param _decimals=$(decimal2Hex $5) \ - --param _feeNumerator=$(decimal2Hex $4) \ - --param _fixedFee=$(decimal2Hex $3) | jq -r . >tx/register.coin.$2 - sleep 5 - ensure_txresult tx/register.coin.$2 - echo $2 > icon.register.coin$2 - fi -} - -get_btp_icon_coinId() { - echo "Get BTP Icon Addr " $2 - cd $CONFIG_DIR - goloop rpc call --to $(cat icon.addr.bts) \ - --method coinId \ - --param _coinName="$1" | jq -r . >tx/icon.coinId.$2 - if [ "$(cat $CONFIG_DIR/tx/icon.coinId.$2)" == "null" ]; - then - echo "Error Gettting CoinAddress icon."$2 - return 1 - else - cat $CONFIG_DIR/tx/icon.coinId.$2 >$CONFIG_DIR/icon.addr.coin$2 - fi - sleep 5 -} From 7cd7eba02fd6d44fed39bc4d7074e6161daf63a4 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Fri, 18 Aug 2023 08:35:58 +0545 Subject: [PATCH 202/211] fix: hardcoded values --- devnet/docker/icon-tezos/scripts/mainnet.i2t.bmr.sh | 6 +++--- devnet/docker/icon-tezos/scripts/testnet.i2t.bmr.sh | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/devnet/docker/icon-tezos/scripts/mainnet.i2t.bmr.sh b/devnet/docker/icon-tezos/scripts/mainnet.i2t.bmr.sh index 3071935b..90a0179a 100755 --- a/devnet/docker/icon-tezos/scripts/mainnet.i2t.bmr.sh +++ b/devnet/docker/icon-tezos/scripts/mainnet.i2t.bmr.sh @@ -24,8 +24,8 @@ export TZ_NUMERATOR=0 export TZ_DECIMALS=6 export ICON_NATIVE_COIN_NAME=btp-$ICON_NET_ID.icon-ICX export ICON_SYMBOL=ICX -export ICON_FIXED_FEE=4300000000000000000 -export ICON_NUMERATOR=100 +export ICON_FIXED_FEE=0 +export ICON_NUMERATOR=0 export ICON_DECIMALS=18 export FEE_GATHERING_INTERVAL=43200 export RELAYER_ADDRESS=tz1ZPVxKiybvbV1GvELRJJpyE1xj1UpNpXMv @@ -789,7 +789,7 @@ configure_javascore_add_bmc_owner configure_javascore_add_bts configure_javascore_add_bts_owner configure_javascore_bmc_setFeeAggregator -configure_javascore_bts_setICXFee 0 0 +configure_javascore_bts_setICXFee $ICON_FIXED_FEE $ICON_NUMERATOR # configure_javascore_register_native_token $TZ_NATIVE_COIN_NAME $TZ_COIN_SYMBOL $TZ_FIXED_FEE $TZ_NUMERATOR $TZ_DECIMALS diff --git a/devnet/docker/icon-tezos/scripts/testnet.i2t.bmr.sh b/devnet/docker/icon-tezos/scripts/testnet.i2t.bmr.sh index 23bfa2ae..04c5328c 100755 --- a/devnet/docker/icon-tezos/scripts/testnet.i2t.bmr.sh +++ b/devnet/docker/icon-tezos/scripts/testnet.i2t.bmr.sh @@ -24,8 +24,8 @@ export TZ_NUMERATOR=0 export TZ_DECIMALS=6 export ICON_NATIVE_COIN_NAME=btp-$ICON_NET_ID.icon-ICX export ICON_SYMBOL=ICX -export ICON_FIXED_FEE=4300000000000000000 -export ICON_NUMERATOR=100 +export ICON_FIXED_FEE=0 +export ICON_NUMERATOR=0 export ICON_DECIMALS=18 export FEE_GATHERING_INTERVAL=43200 export RELAYER_ADDRESS=tz1ZPVxKiybvbV1GvELRJJpyE1xj1UpNpXMv @@ -789,7 +789,7 @@ configure_javascore_add_bmc_owner configure_javascore_add_bts configure_javascore_add_bts_owner configure_javascore_bmc_setFeeAggregator -configure_javascore_bts_setICXFee 0 0 +configure_javascore_bts_setICXFee $ICON_FIXED_FEE $ICON_NUMERATOR # configure_javascore_register_native_token $TZ_NATIVE_COIN_NAME $TZ_COIN_SYMBOL $TZ_FIXED_FEE $TZ_NUMERATOR $TZ_DECIMALS From 0de533cf4edbec4bcf7aee5f6b87e4fd5acd9184 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Fri, 18 Aug 2023 08:38:22 +0545 Subject: [PATCH 203/211] fix: hardcoded values --- devnet/docker/icon-tezos/scripts/mainnet.i2t.bmr.sh | 2 +- devnet/docker/icon-tezos/scripts/testnet.i2t.bmr.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/devnet/docker/icon-tezos/scripts/mainnet.i2t.bmr.sh b/devnet/docker/icon-tezos/scripts/mainnet.i2t.bmr.sh index 90a0179a..a78b80fe 100755 --- a/devnet/docker/icon-tezos/scripts/mainnet.i2t.bmr.sh +++ b/devnet/docker/icon-tezos/scripts/mainnet.i2t.bmr.sh @@ -782,7 +782,7 @@ fund_it_flag build_javascores deploy_javascore_bmc -deploy_javascore_bts 0 0 18 +deploy_javascore_bts $ICON_FIXED_FEE $ICON_NUMERATOR $ICON_DECIMALS # deploy_javascore_token configure_javascore_add_bmc_owner diff --git a/devnet/docker/icon-tezos/scripts/testnet.i2t.bmr.sh b/devnet/docker/icon-tezos/scripts/testnet.i2t.bmr.sh index 04c5328c..300adb18 100755 --- a/devnet/docker/icon-tezos/scripts/testnet.i2t.bmr.sh +++ b/devnet/docker/icon-tezos/scripts/testnet.i2t.bmr.sh @@ -782,7 +782,7 @@ fund_it_flag build_javascores deploy_javascore_bmc -deploy_javascore_bts 0 0 18 +deploy_javascore_bts $ICON_FIXED_FEE $ICON_NUMERATOR $ICON_DECIMALS # deploy_javascore_token configure_javascore_add_bmc_owner From be1ef6a98085ac2e3a0459b180dc24e68059dfd3 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Fri, 18 Aug 2023 11:12:03 +0545 Subject: [PATCH 204/211] fix: tezos icon bridge implementation --- common/address.go | 3 -- common/wallet/keystore.go | 3 -- devnet/docker/icon-tezos/bmr.Dockerfile | 42 +++++++++++++++++++ .../docker/icon-tezos/docker-compose-bmr.yml | 15 +++++++ .../icon/btp/bmc/BTPMessageCenter.java | 2 +- .../icon/btp/bts/BTPTokenService.java | 2 +- 6 files changed, 59 insertions(+), 8 deletions(-) create mode 100644 devnet/docker/icon-tezos/bmr.Dockerfile create mode 100644 devnet/docker/icon-tezos/docker-compose-bmr.yml diff --git a/common/address.go b/common/address.go index fed7c388..bc1f455f 100644 --- a/common/address.go +++ b/common/address.go @@ -4,7 +4,6 @@ import ( "bytes" "encoding/hex" "encoding/json" - "fmt" "reflect" // "github.com/btcsuite/btcutil/base58" @@ -47,7 +46,6 @@ func (a *Address) UnmarshalJSON(b []byte) error { func (a *Address) SetString(s string) error { var isContract = false - fmt.Println("reached to set string") if len(s) >= 2 { var err error var bytes []byte @@ -55,7 +53,6 @@ func (a *Address) SetString(s string) error { switch { case prefix == "tz" || prefix == "KT": isContract = prefix == "KT" - fmt.Println("returned from here") // bytes, _, err = base58.CheckDecode(s[2:]) return nil case prefix == "cx" || prefix == "hx" || prefix == "0x": diff --git a/common/wallet/keystore.go b/common/wallet/keystore.go index 8e05d532..4041af3e 100644 --- a/common/wallet/keystore.go +++ b/common/wallet/keystore.go @@ -151,7 +151,6 @@ func ReadAddressFromKeyStore(data []byte) (*common.Address, error) { func DecryptKeyStore(data, pw []byte) (Wallet, error) { ksdata, err := NewKeyStoreData(data) if err != nil { - fmt.Println("from new key store data") return nil, err } @@ -181,8 +180,6 @@ func DecryptKeyStore(data, pw []byte) (Wallet, error) { } return NewNearwalletFromPrivateKey(key) case coinTypeXTZ: - fmt.Println("coin type is xtz") - fmt.Println(ksdata.Crypto.Cipher) key := tezos.MustParsePrivateKey(ksdata.Crypto.Cipher) return NewTezosWalletFromPrivateKey(key) diff --git a/devnet/docker/icon-tezos/bmr.Dockerfile b/devnet/docker/icon-tezos/bmr.Dockerfile new file mode 100644 index 00000000..992b8b1c --- /dev/null +++ b/devnet/docker/icon-tezos/bmr.Dockerfile @@ -0,0 +1,42 @@ +# dev build +FROM ubuntu:18.04 + +ARG TARGETARCH +ARG GOLANG_VERSION="1.20" + +SHELL ["/bin/bash", "-c"] + +ENV GOPATH=/root/go +ENV GO111MODULE=on +ENV GIMME_GO_VERSION=${GOLANG_VERSION} +ENV PATH="/root/bin:${PATH}" + +RUN apt update && apt upgrade -y && \ + apt install libgmp-dev libssl-dev curl git \ + psmisc dnsutils jq make gcc g++ bash tig tree sudo vim \ + silversearcher-ag unzip emacs-nox nano bash-completion -y + +RUN mkdir ~/bin && \ + curl -sL -o ~/bin/gimme \ + https://raw.githubusercontent.com/travis-ci/gimme/master/gimme && \ + chmod +x ~/bin/gimme + +RUN eval "$(~/bin/gimme ${GIMME_GO_VERSION})" +RUN touch /root/.bash_profile && \ + gimme ${GIMME_GO_VERSION} >> /root/.bash_profile && \ + echo "GIMME_GO_VERSION='${GIMME_GO_VERSION}'" >> /root/.bash_profile && \ + echo "GO111MODULE='on'" >> /root/.bash_profile && \ + echo ". ~/.bash_profile" >> /root/.profile && \ + echo ". ~/.bash_profile" >> /root/.bashrc +ENV PATH="/root/.gimme/versions/go${GIMME_GO_VERSION}.linux.${TARGETARCH:-amd64}/bin:${GOPATH}/bin:${PATH}" +RUN . ~/.bash_profile + +COPY . bmr +RUN cd bmr/cmd/iconbridge + +# prod build +FROM ubuntu:18.04 +SHELL ["/bin/bash", "-c"] +RUN apt update -y && apt install -y make ca-certificates libssl-dev +COPY --from=0 /bmr/cmd/iconbridge/iconbridge /bin/iconbridge +RUN rm -rf /var/lib/apt/lists/* \ No newline at end of file diff --git a/devnet/docker/icon-tezos/docker-compose-bmr.yml b/devnet/docker/icon-tezos/docker-compose-bmr.yml new file mode 100644 index 00000000..8a481692 --- /dev/null +++ b/devnet/docker/icon-tezos/docker-compose-bmr.yml @@ -0,0 +1,15 @@ +version: '3.3' +services: + bmr: + image: i2tbmr2:latest + container_name: bmr + network_mode: host + restart: unless-stopped + # ports: + # - 6060:6060 # golang pprof + entrypoint: ["/bin/iconbridge", "-config", "/config.json"] + volumes: + - /home/sheldor/GoProjects/icon-bridge/devnet/docker/icon-tezos/_ixh/relay.config.json:/config.json + #environment: + #AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID} + #AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY} diff --git a/javascore/bmc/src/main/java/foundation/icon/btp/bmc/BTPMessageCenter.java b/javascore/bmc/src/main/java/foundation/icon/btp/bmc/BTPMessageCenter.java index 52051761..f9664534 100644 --- a/javascore/bmc/src/main/java/foundation/icon/btp/bmc/BTPMessageCenter.java +++ b/javascore/bmc/src/main/java/foundation/icon/btp/bmc/BTPMessageCenter.java @@ -105,7 +105,7 @@ public void setProperties(BMCProperties properties) { @External(readonly = true) public String name() { - return "BTP Message Center"; + return "BTP Message Center-Tezos"; } @External(readonly = true) diff --git a/javascore/bts/src/main/java/foundation/icon/btp/bts/BTPTokenService.java b/javascore/bts/src/main/java/foundation/icon/btp/bts/BTPTokenService.java index ead18ad6..7127f908 100644 --- a/javascore/bts/src/main/java/foundation/icon/btp/bts/BTPTokenService.java +++ b/javascore/bts/src/main/java/foundation/icon/btp/bts/BTPTokenService.java @@ -121,7 +121,7 @@ public BTPTokenService(Address _bmc, String _name, int _decimals, @External(readonly = true) public String name() { - return "BTP Token Service"; + return "BTP Token Service-Tezos"; } /** From 5b7938b2db6f437220009c6c18d902fd023d5316 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Fri, 18 Aug 2023 12:04:17 +0545 Subject: [PATCH 205/211] fix:config change --- cmd/iconbridge/example.config.json | 83 ------------------------------ 1 file changed, 83 deletions(-) delete mode 100644 cmd/iconbridge/example.config.json diff --git a/cmd/iconbridge/example.config.json b/cmd/iconbridge/example.config.json deleted file mode 100644 index c02898ad..00000000 --- a/cmd/iconbridge/example.config.json +++ /dev/null @@ -1,83 +0,0 @@ -{ - "base_dir": "bmr", - "log_level": "debug", - "console_level": "trace", - "log_writer": { - "filename": "bmr/bmr.log" - }, - "stat_collector": { - "verbose": false - }, - "log_forwarder": { - "vendor": "slack", - "address": "https://hooks.slack.com/services/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", - "level": "info" - }, - "relays": [ - { - "name": "t2i", - "src": { - "address": "btp://NetXdQprcVkpaWU.tezos/KT1WUCnwwVPee5szEygLaXfSCcUHz9MGbtYd", - "endpoint": [ - "http://localhost:8732" - ], - "options": { - "verifier": { - "blockHeight": 3953500 - }, - "syncConcurrency": 100, - "bmcManagement": "KT1JsML1sT1G1bbJpKx8P3Q6eBNMpKXDTt6T" - }, - "offset": 3953500 - }, - "dst": { - "address": "btp://0x1.icon/cx5d70d870dcf1ce7858869811b66c8acfb8eb3112", - "endpoint": [ - "https://ctz.solidwallet.io/api/v3/" - ], - "options": { - "step_limit": 100000000 - }, - "key_store": {"version":3,"id":"474878de-91b8-46c5-911a-54f9fb8205cd","address":"hx2e4e3737e05289bee6040438c309049166b165c0","crypto":{"ciphertext":"56ee78a6571c3b7ed07486d7d50fc92a87dedbc6b8d9d9092ab23c9b644b24cd","cipherparams":{"iv":"49549cf24e13fb937e6ca45cb31cd8bc"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"69768bf0887558d7199c68c6007cd57edd07a4550bf452d3ddbaf25f3aa0867c","n":16384,"r":8,"p":1},"mac":"d2b98c60da43883acc495f254c982b373fabe49a6a877a97b486920872051cc2"},"coinType":"icx"}, - "key_password": "icon@123" - } - }, - { - "name": "i2t", - "src": { - "address": "btp://0x1.icon/cx5d70d870dcf1ce7858869811b66c8acfb8eb3112", - "endpoint": [ - "https://ctz.solidwallet.io/api/v3/" - ], - "options": { - "verifier": { - "blockHeight": 68968700, - "validatorsHash": "0xe15fd3392fae29a7f72168f408ab4085c5aa617e55fa42572f8ba24c0f771d85" - }, - "syncConcurrency": 100 - }, - "offset": 68968700 - }, - "dst": { - "address": "btp://NetXdQprcVkpaWU.tezos/KT1WUCnwwVPee5szEygLaXfSCcUHz9MGbtYd", - "endpoint": [ - "http://localhost:8732" - ], - "options": { - "gas_limit": 1040000, - "boost_gas_price": 1.5, - "tx_data_size_limit": 65536, - "bmcManagement": "KT1JsML1sT1G1bbJpKx8P3Q6eBNMpKXDTt6T" - }, - "key_store": { - "address": "tz1ZPVxKiybvbV1GvELRJJpyE1xj1UpNpXMv", - "crypto": { - "cipher": "edskRcbiqBiNXCzJ94TQYGnPdzSk37nx1xfqrm34BgTexmja3a6z2HHrx6VsiQjmm1QQuJEDeodswqHxAnjPCqKpQngUF2T9EY" - }, - "coinType": "xtz" - }, - "key_password": "xyz" - } - } - ] -} \ No newline at end of file From 79f7ce9cd6ba1a2214cd29778866e4aa82a0f118 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Fri, 18 Aug 2023 13:30:11 +0545 Subject: [PATCH 206/211] fix: path in build scripts --- devnet/docker/icon-tezos/scripts/mainnet.i2t.bmr.sh | 11 +++++------ devnet/docker/icon-tezos/scripts/testnet.i2t.bmr.sh | 11 +++++------ tezos-addresses/main.go | 9 ++++----- 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/devnet/docker/icon-tezos/scripts/mainnet.i2t.bmr.sh b/devnet/docker/icon-tezos/scripts/mainnet.i2t.bmr.sh index a78b80fe..b568c42b 100755 --- a/devnet/docker/icon-tezos/scripts/mainnet.i2t.bmr.sh +++ b/devnet/docker/icon-tezos/scripts/mainnet.i2t.bmr.sh @@ -28,7 +28,6 @@ export ICON_FIXED_FEE=0 export ICON_NUMERATOR=0 export ICON_DECIMALS=18 export FEE_GATHERING_INTERVAL=43200 -export RELAYER_ADDRESS=tz1ZPVxKiybvbV1GvELRJJpyE1xj1UpNpXMv export ICON_ZERO_ADDRESS=cx0000000000000000000000000000000000000000 tz_lastBlock() { @@ -151,7 +150,7 @@ fund_it_flag() { deploy_smartpy_bmc_management(){ cd $(echo $SMARTPY_DIR/bmc) - if [ ! -f $CONDIG_DIR/_ixh/tz.addr.bmcmanagementbtp ]; then + if [ ! -f $CONFIG_DIR/_ixh/tz.addr.bmcmanagementbtp ]; then echo "deploying bmc_management" extract_chainHeight cd $SMARTPY_DIR/bmc @@ -167,7 +166,7 @@ deploy_smartpy_bmc_management(){ deploy_smartpy_bmc_periphery(){ cd $(echo $SMARTPY_DIR/bmc) - if [ ! -f $CONDIG_DIR/_ixh/tz.addr.bmcperipherybtp ]; then + if [ ! -f $CONFIG_DIR/_ixh/tz.addr.bmcperipherybtp ]; then echo "deploying bmc_periphery" npm run compile bmc_periphery local deploy=$(npm run deploy bmc_periphery @GHOSTNET) @@ -181,7 +180,7 @@ deploy_smartpy_bmc_periphery(){ deploy_smartpy_bts_periphery(){ cd $(echo $SMARTPY_DIR/bts) - if [ ! -f $CONDIG_DIR/_ixh/tz.addr.bts_periphery ]; then + if [ ! -f $CONFIG_DIR/_ixh/tz.addr.bts_periphery ]; then echo "deploying bts_periphery" npm run compile bts_periphery local deploy=$(npm run deploy bts_periphery @GHOSTNET) @@ -193,7 +192,7 @@ deploy_smartpy_bts_periphery(){ deploy_smartpy_bts_core(){ cd $(echo $SMARTPY_DIR/bts) - if [ ! -f $CONDIG_DIR/_ixh/tz.addr.bts_core ]; then + if [ ! -f $CONFIG_DIR/_ixh/tz.addr.bts_core ]; then echo "deploying bts_core" npm run compile bts_core local deploy=$(npm run deploy bts_core @GHOSTNET) @@ -205,7 +204,7 @@ deploy_smartpy_bts_core(){ deploy_smartpy_bts_owner_manager(){ cd $(echo $SMARTPY_DIR/bts) - if [ ! -f $CONDIG_DIR/_ixh/tz.addr.bts_owner_manager ]; then + if [ ! -f $CONFIG_DIR/_ixh/tz.addr.bts_owner_manager ]; then echo "deploying bts_owner_manager" npm run compile bts_owner_manager local deploy=$(npm run deploy bts_owner_manager @GHOSTNET) diff --git a/devnet/docker/icon-tezos/scripts/testnet.i2t.bmr.sh b/devnet/docker/icon-tezos/scripts/testnet.i2t.bmr.sh index 300adb18..a22be536 100755 --- a/devnet/docker/icon-tezos/scripts/testnet.i2t.bmr.sh +++ b/devnet/docker/icon-tezos/scripts/testnet.i2t.bmr.sh @@ -28,7 +28,6 @@ export ICON_FIXED_FEE=0 export ICON_NUMERATOR=0 export ICON_DECIMALS=18 export FEE_GATHERING_INTERVAL=43200 -export RELAYER_ADDRESS=tz1ZPVxKiybvbV1GvELRJJpyE1xj1UpNpXMv export ICON_ZERO_ADDRESS=cx0000000000000000000000000000000000000000 tz_lastBlock() { @@ -151,7 +150,7 @@ fund_it_flag() { deploy_smartpy_bmc_management(){ cd $(echo $SMARTPY_DIR/bmc) - if [ ! -f $CONDIG_DIR/_ixh/tz.addr.bmcmanagementbtp ]; then + if [ ! -f $CONFIG_DIR/_ixh/tz.addr.bmcmanagementbtp ]; then echo "deploying bmc_management" extract_chainHeight cd $SMARTPY_DIR/bmc @@ -167,7 +166,7 @@ deploy_smartpy_bmc_management(){ deploy_smartpy_bmc_periphery(){ cd $(echo $SMARTPY_DIR/bmc) - if [ ! -f $CONDIG_DIR/_ixh/tz.addr.bmcperipherybtp ]; then + if [ ! -f $CONFIG_DIR/_ixh/tz.addr.bmcperipherybtp ]; then echo "deploying bmc_periphery" npm run compile bmc_periphery local deploy=$(npm run deploy bmc_periphery @GHOSTNET) @@ -181,7 +180,7 @@ deploy_smartpy_bmc_periphery(){ deploy_smartpy_bts_periphery(){ cd $(echo $SMARTPY_DIR/bts) - if [ ! -f $CONDIG_DIR/_ixh/tz.addr.bts_periphery ]; then + if [ ! -f $CONFIG_DIR/_ixh/tz.addr.bts_periphery ]; then echo "deploying bts_periphery" npm run compile bts_periphery local deploy=$(npm run deploy bts_periphery @GHOSTNET) @@ -193,7 +192,7 @@ deploy_smartpy_bts_periphery(){ deploy_smartpy_bts_core(){ cd $(echo $SMARTPY_DIR/bts) - if [ ! -f $CONDIG_DIR/_ixh/tz.addr.bts_core ]; then + if [ ! -f $CONFIG_DIR/_ixh/tz.addr.bts_core ]; then echo "deploying bts_core" npm run compile bts_core local deploy=$(npm run deploy bts_core @GHOSTNET) @@ -205,7 +204,7 @@ deploy_smartpy_bts_core(){ deploy_smartpy_bts_owner_manager(){ cd $(echo $SMARTPY_DIR/bts) - if [ ! -f $CONDIG_DIR/_ixh/tz.addr.bts_owner_manager ]; then + if [ ! -f $CONFIG_DIR/_ixh/tz.addr.bts_owner_manager ]; then echo "deploying bts_owner_manager" npm run compile bts_owner_manager local deploy=$(npm run deploy bts_owner_manager @GHOSTNET) diff --git a/tezos-addresses/main.go b/tezos-addresses/main.go index 46ca38d1..994edaa3 100755 --- a/tezos-addresses/main.go +++ b/tezos-addresses/main.go @@ -478,15 +478,16 @@ func main() { argument = args.WithSource(from).WithDestination(bmcManagementClient.Address()) - fmt.Println("toggling bridgeon") + fmt.Println("toggling bridge on bmc management") opts.IgnoreLimits = false res, err = bmcManagementClient.Call(ctx, argument, &opts) + fmt.Println(res) if err != nil { fmt.Println("error while calling", entrypoint) fmt.Println(err) } - + fmt.Println("toggling bridge on bts core") res, err = btsCoreClient.Call(ctx, argument, &opts) if err != nil { fmt.Println("error while calling", entrypoint) @@ -525,9 +526,8 @@ func register(btsCore tezos.Address, coinName string, opts rpc.CallOptions) { var prim micheline.Prim - in := "{\"prim\": \"Pair\", \"args\": [{\"prim\": \"Pair\",\"args\": [{\"string\": \"" + "tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg" + "\"},{\"prim\": \"Pair\",\"args\": [{\"int\": \"0\"},{\"int\": \"0\"}]}]},{\"prim\": \"Pair\",\"args\": [[],{\"prim\": \"Pair\",\"args\": [{\"string\": \"" + coinName + "1" + "\"},[]]}]}]}" - + if err := prim.UnmarshalJSON([]byte(in)); err != nil { fmt.Println("couldnot unmarshall empty string") fmt.Println(err) @@ -554,4 +554,3 @@ func register(btsCore tezos.Address, coinName string, opts rpc.CallOptions) { fmt.Println(res) } - From fd3e81963cfe788d96d771a004e12f61de2a9391 Mon Sep 17 00:00:00 2001 From: simusud Date: Fri, 18 Aug 2023 14:18:00 +0545 Subject: [PATCH 207/211] revert(bts): reverted previous commit due to storage issue --- smartpy/bts/contracts/src/FA2_contract.py | 41 +++-------------------- 1 file changed, 5 insertions(+), 36 deletions(-) diff --git a/smartpy/bts/contracts/src/FA2_contract.py b/smartpy/bts/contracts/src/FA2_contract.py index b1f52ccb..858ce9ba 100644 --- a/smartpy/bts/contracts/src/FA2_contract.py +++ b/smartpy/bts/contracts/src/FA2_contract.py @@ -39,8 +39,6 @@ def set_allowance(self, param): sp.verify(param.spender != ZERO_ADDRESS, "Spender cannot be negative.") allowance = sp.compute(sp.record(spender=param.spender, owner=sp.sender)) - current_allowance = self.data.allowances.get(allowance, default_value=0) - sp.verify((param.amount == 0) | (current_allowance == 0), "FA2_UnsafeAllowanceChange") self.data.allowances[allowance] = param.amount sp.emit(sp.record(owner=sp.sender, spender=param.spender, amount=param.amount), @@ -51,31 +49,6 @@ def get_allowance(self, allowance): sp.set_type(allowance, sp.TRecord(spender=sp.TAddress, owner=sp.TAddress)) sp.result(self.data.allowances.get(allowance, default_value=0)) - @sp.entry_point - def increase_allowance(self, param): - sp.set_type(param, sp.TRecord(spender=sp.TAddress, amount=sp.TNat)) - - sp.verify(param.spender != ZERO_ADDRESS, "Spender cannot be negative.") - allowance = sp.compute(sp.record(spender=param.spender, owner=sp.sender)) - current_allowance = self.data.allowances.get(allowance, default_value=0) - self.data.allowances[allowance] = current_allowance + param.amount - - sp.emit(sp.record(owner=sp.sender, spender=param.spender, amount=param.amount), - tag="AllowanceIncreased") - - @sp.entry_point - def decrease_allowance(self, param): - sp.set_type(param, sp.TRecord(spender=sp.TAddress, amount=sp.TNat)) - - sp.verify(param.spender != ZERO_ADDRESS, "Spender cannot be negative.") - allowance = sp.compute(sp.record(spender=param.spender, owner=sp.sender)) - current_allowance = self.data.allowances.get(allowance, default_value=0) - self.data.allowances[allowance] = sp.as_nat(current_allowance - param.amount, - message="Allowance cannot be negative.") - - sp.emit(sp.record(owner=sp.sender, spender=param.spender, amount=param.amount), - tag="AllowanceDecreased") - @sp.onchain_view() def transfer_permissions(self, params): sp.set_type(params, sp.TRecord(from_=sp.TAddress, token_id=sp.TNat)) @@ -138,22 +111,18 @@ def test(): scenario.verify(c1.get_allowance(sp.record(spender=spender.address, owner=bob.address)) == 0) # set allowance c1.set_allowance(sp.record(spender=spender.address, amount=sp.nat(100))).run(sender=bob) - c1.set_allowance(sp.record(spender=ZERO_ADDRESS, amount=sp.nat(100))).run(sender=bob, valid=False, - exception="Spender cannot be negative.") - c1.set_allowance(sp.record(spender=spender.address, amount=sp.nat(100))).run(sender=bob, valid=False, - exception="FA2_UnsafeAllowanceChange") scenario.verify(c1.get_allowance(sp.record(spender=spender.address, owner=bob.address)) == 100) # increase allowance - c1.increase_allowance(sp.record(spender=spender.address, amount=sp.nat(100))).run(sender=bob) + c1.set_allowance(sp.record(spender=spender.address, amount=sp.nat(100))).run(sender=bob) # verify new allowance - scenario.verify(c1.get_allowance(sp.record(spender=spender.address, owner=bob.address)) == 200) + scenario.verify(c1.get_allowance(sp.record(spender=spender.address, owner=bob.address)) == 100) # decrease allowance - c1.decrease_allowance(sp.record(spender=spender.address, amount=sp.nat(20))).run(sender=bob) + c1.set_allowance(sp.record(spender=spender.address, amount=sp.nat(20))).run(sender=bob) # verify new allowance - scenario.verify(c1.get_allowance(sp.record(spender=spender.address, owner=bob.address)) == 180) + scenario.verify(c1.get_allowance(sp.record(spender=spender.address, owner=bob.address)) == 20) # decrease allowance - c1.decrease_allowance(sp.record(spender=spender.address, amount=sp.nat(180))).run(sender=bob) + c1.set_allowance(sp.record(spender=spender.address, amount=sp.nat(0))).run(sender=bob) # verify new allowance scenario.verify(c1.get_allowance(sp.record(spender=spender.address, owner=bob.address)) == 0) From 524fcdc3fa1c738ee82befed0b9dc4b03e5efd0e Mon Sep 17 00:00:00 2001 From: icondev22 Date: Mon, 21 Aug 2023 08:55:36 +0545 Subject: [PATCH 208/211] fix: timeout fixes --- cmd/iconbridge/chain/tezos/receiver.go | 3 +- cmd/iconbridge/chain/tezos/sender.go | 44 +++++++++++++++++-- .../icon-tezos/scripts/testnet.i2t.bmr.sh | 2 +- 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/cmd/iconbridge/chain/tezos/receiver.go b/cmd/iconbridge/chain/tezos/receiver.go index ca65d315..9301b68a 100644 --- a/cmd/iconbridge/chain/tezos/receiver.go +++ b/cmd/iconbridge/chain/tezos/receiver.go @@ -255,7 +255,6 @@ func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback fu "lbnHash": lbn.Hash, "nextHeight": next, "bnHash": bn.Hash}).Error("verification failed. refetching block ", err) - time.Sleep(5 * time.Second) next-- break } @@ -290,7 +289,7 @@ func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback fu default: if next >= latest { - time.Sleep(10 * time.Second) + time.Sleep(10 * time.Millisecond) continue } diff --git a/cmd/iconbridge/chain/tezos/sender.go b/cmd/iconbridge/chain/tezos/sender.go index 6baa933f..b9480e73 100644 --- a/cmd/iconbridge/chain/tezos/sender.go +++ b/cmd/iconbridge/chain/tezos/sender.go @@ -21,12 +21,17 @@ import ( ) const ( - txMaxDataSize = 1024 // 1 KB + txMaxDataSize = 512 // 1 KB txOverheadScale = 0.01 defaultTxSizeLimit = txMaxDataSize / (1 + txOverheadScale) // with the rlp overhead defaultSendTxTimeOut = 30 * time.Second // 30 seconds is the block time for tezos ) +var ( + originalRxSeq = big.NewInt(0) + statusFlag = false +) + type senderOptions struct { StepLimit uint64 `json:"step_limit"` TxDataSizeLimit uint64 `json:"tx_data_size_limit"` @@ -176,6 +181,7 @@ func (s *sender) newRelayTx(ctx context.Context, prev string, message []byte) (* Message: message, cl: client, w: s.w, + link: s.src.String(), }, nil } @@ -186,6 +192,7 @@ type relayTx struct { cl *Client receipt *rpc.Receipt w wallet.Wallet + link string } func (tx *relayTx) ID() interface{} { @@ -199,6 +206,37 @@ func (tx *relayTx) Send(ctx context.Context) (err error) { prim := micheline.Prim{} messageHex := hex.EncodeToString(tx.Message) + fmt.Println("starting ma status flag is ", statusFlag) + + status, err := tx.cl.GetStatus(ctx, tx.cl.Contract, tx.link) + if err != nil { + return err + } + + if !statusFlag { + originalRxSeq = status.RxSeq + statusFlag = true + } + + if status.RxSeq.Cmp(originalRxSeq) > 0 { + statusFlag = false + hash, err := tx.cl.GetBlockByHeight(ctx, tx.cl.Cl, status.CurrentHeight.Int64()) + if err != nil { + return err + } + + tx.receipt = &rpc.Receipt{ + Pos: 0, + List: 0, + Block: hash.Hash, + } + return nil + } + + fmt.Println("status flag", statusFlag) + + fmt.Println(messageHex) + in := "{ \"prim\": \"Pair\", \"args\": [ { \"bytes\": \"" + messageHex + "\" }, { \"string\": \"" + tx.Prev + "\" } ] }" if err := prim.UnmarshalJSON([]byte(in)); err != nil { @@ -225,11 +263,11 @@ func (tx *relayTx) Send(ctx context.Context) (err error) { receipt, err := tx.cl.HandleRelayMessage(_ctx, argument, &opts) if err != nil { - return nil + return err } tx.receipt = receipt - + statusFlag = false return nil } diff --git a/devnet/docker/icon-tezos/scripts/testnet.i2t.bmr.sh b/devnet/docker/icon-tezos/scripts/testnet.i2t.bmr.sh index a22be536..f4dc7e07 100755 --- a/devnet/docker/icon-tezos/scripts/testnet.i2t.bmr.sh +++ b/devnet/docker/icon-tezos/scripts/testnet.i2t.bmr.sh @@ -757,7 +757,7 @@ configure_relay_config() { --arg dst_endpoint "$TZ_NET_URI" \ --arg dst_key_store "$(echo $(cat $CONFIG_DIR/_ixh/keystore/tz.bmr.wallet))" \ --arg secret "$(echo $(cat $CONFIG_DIR/_ixh/keystore/tz.bmr.wallet.secret))" \ - --arg secret "edskRz1HoD3cWkmWhCNS5LjBrJNWChGuKWB4HnVoN5UqVsUCpcNJR67ZxKs965u8RgRwptrtGc2ufYZoeECgB77RKm1gTbQ6eB" \ + --arg dst_key_store_cointype "xtz" \ --arg dst_key_password "xyz" \ --argjson dst_tx_data_size_limit 8192 \ --argjson dst_options '{"gas_limit":24000000,"tx_data_size_limit":8192,"balance_threshold":"100000000000000000000","boost_gas_price":1.0}' \ From 3f420699ab7badf5beabfe162d1bbe355dd0e3a7 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Mon, 21 Aug 2023 13:32:35 +0545 Subject: [PATCH 209/211] fix: sender fix --- cmd/iconbridge/chain/tezos/sender.go | 33 +++++++++++++++++++++++++++- cmd/iconbridge/relay/relay.go | 2 +- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/cmd/iconbridge/chain/tezos/sender.go b/cmd/iconbridge/chain/tezos/sender.go index b9480e73..ee6129e2 100644 --- a/cmd/iconbridge/chain/tezos/sender.go +++ b/cmd/iconbridge/chain/tezos/sender.go @@ -21,10 +21,11 @@ import ( ) const ( - txMaxDataSize = 512 // 1 KB + txMaxDataSize = 1024 // 1 KB txOverheadScale = 0.01 defaultTxSizeLimit = txMaxDataSize / (1 + txOverheadScale) // with the rlp overhead defaultSendTxTimeOut = 30 * time.Second // 30 seconds is the block time for tezos + maxEventPropagation = 5 ) var ( @@ -117,7 +118,22 @@ func (s *sender) Segment(ctx context.Context, msg *chain.Message) (tx chain.Rela Receipts: msg.Receipts, } + var newEvent []*chain.Event + var newReceipt *chain.Receipt + var newReceipts []*chain.Receipt + for i, receipt := range msg.Receipts { + fmt.Println("from segment of tezos: ", receipt.Events[0].Message) + fmt.Println("from segment of tezos: ", receipt.Events[0].Sequence) + fmt.Println("from segment of tezos: ", receipt.Events[0].Next) + fmt.Println("len of events", len(receipt.Events)) + fmt.Println("msg.receipts", len(msg.Receipts)) + + if len(receipt.Events) > maxEventPropagation { + newEvent = receipt.Events[maxEventPropagation:] + receipt.Events = receipt.Events[:maxEventPropagation] + } + rlpEvents, err := codec.RLP.MarshalToBytes(receipt.Events) //json.Marshal(receipt.Events) // change to rlp bytes if err != nil { return nil, nil, err @@ -132,13 +148,28 @@ func (s *sender) Segment(ctx context.Context, msg *chain.Message) (tx chain.Rela return nil, nil, err } + fmt.Println("Message size is initially", msgSize) + newMsgSize := msgSize + uint64(len(rlpReceipt)) + fmt.Println(newMsgSize) if newMsgSize > s.opts.TxDataSizeLimit { + fmt.Println("limit is", s.opts.TxDataSizeLimit) + fmt.Println("The value of i is", i) newMsg.Receipts = msg.Receipts[i:] break } msgSize = newMsgSize + fmt.Println("message size", msgSize) rm.Receipts = append(rm.Receipts, rlpReceipt) + + if newEvent != nil { + newReceipt = receipt + newReceipt.Events = newEvent + newReceipts = append(newReceipts, newReceipt) + newReceipts = append(newReceipts, msg.Receipts...) + msg.Receipts = newReceipts + break + } } message, err := codec.RLP.MarshalToBytes(rm) // json.Marshal(rm) if err != nil { diff --git a/cmd/iconbridge/relay/relay.go b/cmd/iconbridge/relay/relay.go index 8ac35bd3..423ce658 100644 --- a/cmd/iconbridge/relay/relay.go +++ b/cmd/iconbridge/relay/relay.go @@ -14,7 +14,7 @@ import ( const ( relayTickerInterval = 5 * time.Second relayBalanceCheckInterval = 60 * time.Second - relayTriggerReceiptsCount = 20 + relayTriggerReceiptsCount = 5 relayTxSendWaitInterval = time.Second / 2 relayTxReceiptWaitInterval = time.Second relayInsufficientBalanceWaitInterval = 30 * time.Second From 9f765cac386e90df084fa9b6bcfad00efe6bd782 Mon Sep 17 00:00:00 2001 From: icondev22 Date: Mon, 21 Aug 2023 13:39:11 +0545 Subject: [PATCH 210/211] chore: removed unnecessary prints --- cmd/iconbridge/chain/tezos/sender.go | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/cmd/iconbridge/chain/tezos/sender.go b/cmd/iconbridge/chain/tezos/sender.go index ee6129e2..87e3de4c 100644 --- a/cmd/iconbridge/chain/tezos/sender.go +++ b/cmd/iconbridge/chain/tezos/sender.go @@ -123,12 +123,6 @@ func (s *sender) Segment(ctx context.Context, msg *chain.Message) (tx chain.Rela var newReceipts []*chain.Receipt for i, receipt := range msg.Receipts { - fmt.Println("from segment of tezos: ", receipt.Events[0].Message) - fmt.Println("from segment of tezos: ", receipt.Events[0].Sequence) - fmt.Println("from segment of tezos: ", receipt.Events[0].Next) - fmt.Println("len of events", len(receipt.Events)) - fmt.Println("msg.receipts", len(msg.Receipts)) - if len(receipt.Events) > maxEventPropagation { newEvent = receipt.Events[maxEventPropagation:] receipt.Events = receipt.Events[:maxEventPropagation] @@ -148,18 +142,12 @@ func (s *sender) Segment(ctx context.Context, msg *chain.Message) (tx chain.Rela return nil, nil, err } - fmt.Println("Message size is initially", msgSize) - newMsgSize := msgSize + uint64(len(rlpReceipt)) - fmt.Println(newMsgSize) if newMsgSize > s.opts.TxDataSizeLimit { - fmt.Println("limit is", s.opts.TxDataSizeLimit) - fmt.Println("The value of i is", i) newMsg.Receipts = msg.Receipts[i:] break } msgSize = newMsgSize - fmt.Println("message size", msgSize) rm.Receipts = append(rm.Receipts, rlpReceipt) if newEvent != nil { @@ -237,8 +225,6 @@ func (tx *relayTx) Send(ctx context.Context) (err error) { prim := micheline.Prim{} messageHex := hex.EncodeToString(tx.Message) - fmt.Println("starting ma status flag is ", statusFlag) - status, err := tx.cl.GetStatus(ctx, tx.cl.Contract, tx.link) if err != nil { return err @@ -264,10 +250,6 @@ func (tx *relayTx) Send(ctx context.Context) (err error) { return nil } - fmt.Println("status flag", statusFlag) - - fmt.Println(messageHex) - in := "{ \"prim\": \"Pair\", \"args\": [ { \"bytes\": \"" + messageHex + "\" }, { \"string\": \"" + tx.Prev + "\" } ] }" if err := prim.UnmarshalJSON([]byte(in)); err != nil { @@ -292,7 +274,8 @@ func (tx *relayTx) Send(ctx context.Context) (err error) { argument := args.WithSource(from).WithDestination(tx.cl.Contract.Address()) receipt, err := tx.cl.HandleRelayMessage(_ctx, argument, &opts) - + tx.cl.Log.WithFields(log.Fields{ + "tx": messageHex}).Debug("handleRelayMessage: tx sent") if err != nil { return err } From 5b34a75f9ca39122f7460a81d3f612ca0f593df6 Mon Sep 17 00:00:00 2001 From: suyogadhikari Date: Mon, 21 Aug 2023 16:30:26 +0545 Subject: [PATCH 211/211] fix(bmc): fixed bmc sequence number decoding and encoding --- smartpy/bmc/contracts/src/RLP_struct.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/smartpy/bmc/contracts/src/RLP_struct.py b/smartpy/bmc/contracts/src/RLP_struct.py index dd01f8bc..e8bd389d 100644 --- a/smartpy/bmc/contracts/src/RLP_struct.py +++ b/smartpy/bmc/contracts/src/RLP_struct.py @@ -164,7 +164,8 @@ def to_message_event(self, rlp): with sp.if_ (counter.value == 0): next_bmc.value = sp.view("decode_string", self.data.helper, i.value, t=sp.TString).open_some() with sp.if_ (counter.value == 1): - seq.value = Utils2.Int.of_bytes(i.value) + wl_prefix_seq = sp.view("without_length_prefix", self.data.helper, i.value, t=sp.TBytes).open_some() + seq.value = Utils2.Int.of_bytes(wl_prefix_seq) counter.value = counter.value + 1 return sp.record(event_rv=sp.record(next_bmc= next_bmc.value, seq= seq.value, message = message.value)) @@ -261,9 +262,9 @@ def encode_bmc_message(self, params): _to_byte = sp.view("to_byte", self.data.helper_parse_negative, params.sn, t=sp.TBytes).open_some() rlp.value = _to_byte - with sp.if_ (params.sn < sp.int(0)): - encode_sn = sp.view("with_length_prefix", self.data.helper, rlp.value, t=sp.TBytes).open_some() - rlp.value = encode_sn + # with sp.if_ (params.sn < sp.int(0)): + encode_sn = sp.view("with_length_prefix", self.data.helper, rlp.value, t=sp.TBytes).open_some() + rlp.value = encode_sn rlp_bytes_with_prefix = sp.view("encode_list", self.data.helper, [encode_src, encode_dst, encode_svc, rlp.value, params.message],