Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Contract tester/improve testing script #33

Merged
merged 10 commits into from
Aug 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,7 @@ bash ./compile-contracts.sh

### Testing

You can optionally run extended tests inside a private testnet using the [contract tester](./contracts/compiled/contract_tester.py)
You can optionally run extended tests using the [tester](contracts/compiled/tester.py)

To run a test deployment on a public testnet you can run ```tester.py --testnet public```.
For the private testnet you can run ```tester.py --testnet private```.
7 changes: 6 additions & 1 deletion compile-contracts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,22 @@
root_dir=$(git rev-parse --show-toplevel)
contracts_dir="${root_dir}/contracts"
compiled_dir="${contracts_dir}/compiled"
checksum_dir="${compiled_dir}/checksum"

compile_contract() {
# Run tests
(cd ${contracts_dir}/$1; cargo unit-test)
(cd ${contracts_dir}/$1; cargo integration-test)
#(cd ${contracts_dir}/$1; cargo integration-test)
(cd ${compiled_dir}; rm $1.wasm.gz)
(cd ${contracts_dir}; cargo build --release --target wasm32-unknown-unknown --locked)
wasm-opt -Oz ./target/wasm32-unknown-unknown/release/$1.wasm -o ./$1.wasm
echo $(md5sum $1.wasm | cut -f 1 -d " ") >> ${checksum_dir}/$1.txt
cat ./$1.wasm | gzip -n -9 > ${compiled_dir}/$1.wasm.gz
rm -f ./$1.wasm
}

# There should be a cleaner way to do this
rm -r ${checksum_dir}
mkdir ${checksum_dir}
compile_contract "mint"
compile_contract "oracle"
Empty file removed contracts/compiled/__init__.py
Empty file.
1 change: 1 addition & 0 deletions contracts/compiled/checksum/mint.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0e69bd310d6f40a5887ce51816eb13cd
1 change: 1 addition & 0 deletions contracts/compiled/checksum/oracle.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
7d4dc9650c2121ae8d839f5598d6d09a
63 changes: 0 additions & 63 deletions contracts/compiled/contract_tester.py

This file was deleted.

33 changes: 23 additions & 10 deletions contracts/compiled/contractlib/oraclelib.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,42 @@
class Oracle(Contract):
def __init__(self, label, contract='oracle.wasm.gz', admin='a', uploader='a', gas='10000000', backend='test',
instantiated_contract=None):
init_msg = json.dumps({
'band': {
'address': 'secret1p0jtg47hhwuwgp4cjpc46m7qq6vyjhdsvy2nph',
'code_hash': '77c854ea110315d5103a42b88d3e7b296ca245d8b095e668c69997b265a75ac5',
}
})

if backend == 'test':
init_msg = json.dumps({})
else:
init_msg = json.dumps({
'band': {
'address': 'secret1p0jtg47hhwuwgp4cjpc46m7qq6vyjhdsvy2nph',
'code_hash': '77c854ea110315d5103a42b88d3e7b296ca245d8b095e668c69997b265a75ac5',
}
})

super().__init__(contract, init_msg, label, admin, uploader, gas, backend,
instantiated_contract=instantiated_contract)

def get_price(self, coin):
"""
Get current coin price
:param coin: Coin ticker
:return:
"""
msg = json.dumps({'get_price': {'symbol': coin}})

return self.query(msg)

def get_shade_price(self):
"""
Get current shade price
:return:
"""
msg = json.dumps({'get_price': {'symbol': 'SHD'}})

return self.query(msg)
return self.get_price('SHD')

def get_scrt_price(self):
"""
Get current scrt price
:return:
"""
msg = json.dumps({'get_price': {'symbol': 'SCRT'}})

return self.query(msg)
return self.get_price('SCRT')
Binary file modified contracts/compiled/mint.wasm.gz
Binary file not shown.
Binary file modified contracts/compiled/oracle.wasm.gz
Binary file not shown.
162 changes: 162 additions & 0 deletions contracts/compiled/tester.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
import copy
import json
import random
import argparse
from contractlib.contractlib import PreInstantiatedContract
from contractlib.secretlib import secretlib
from contractlib.snip20lib import SNIP20
from contractlib.mintlib import Mint
from contractlib.oraclelib import Oracle
from contractlib.utils import gen_label

parser = argparse.ArgumentParser(description='Automated smart contract tester')
parser.add_argument("--testnet", choices=["private", "public"], default="private", type=str, required=False,
help="Specify which deploy scenario to run")

args=parser.parse_args()

if args.testnet == "private":
account_key = 'a'
account = secretlib.run_command(['secretcli', 'keys', 'show', '-a', account_key]).rstrip()

print("Configuring sSCRT")
sscrt = SNIP20(gen_label(8), decimals=6, public_total_supply=True, enable_deposit=True)
sscrt_password = sscrt.set_view_key(account_key, "password")

sscrt_mint_amount = '100000000000000'
print(f"\tDepositing {sscrt_mint_amount} uSCRT")
sscrt.deposit(account, sscrt_mint_amount + "uscrt")
sscrt_minted = sscrt.get_balance(account, sscrt_password)
print(f"\tReceived {sscrt_minted} usSCRT")
assert sscrt_mint_amount == sscrt_minted, f"Minted {sscrt_minted}; expected {sscrt_mint_amount}"

print("Configuring silk")
silk = SNIP20(gen_label(8), decimals=6, public_total_supply=True, enable_mint=True)
silk_password = silk.set_view_key(account_key, "password")

print('Configuring Oracle')
oracle = Oracle(gen_label(8))
price = int(oracle.get_scrt_price()["rate"])
print(price / (10**18))

print("Configuring Mint contract")
mint = Mint(gen_label(8), silk, oracle)
silk.set_minters([mint.address])
mint.register_asset(sscrt)
assets = mint.get_supported_assets()['supported_assets']['assets'][0]
assert sscrt.address == assets, f"Got {assets}; expected {sscrt.address}"

print("Sending to mint contract")

total_amount = int(sscrt_mint_amount)
minimum_amount = 1000
total_tests = 5

total_sent = 0

for i in range(total_tests):
send_amount = random.randint(minimum_amount, int(total_amount/total_tests)-1)
total_sent += send_amount

print(f"\tSending {send_amount} usSCRT")
sscrt.send(account_key, mint.address, send_amount)
silk_minted = silk.get_balance(account, silk_password)
#assert total_sent == int(silk_minted), f"Total minted {silk_minted}; expected {total_sent}"

print(f"\tSilk balance: {silk_minted} uSILK")
burned_amount = mint.get_asset(sscrt)["asset"]["asset"]["burned_tokens"]
print(f"\tTotal burned: {burned_amount} usSCRT\n")
#assert total_sent == int(burned_amount), f"Burnt {burned_amount}; expected {total_sent}"

print("Testing migration")
new_mint = mint.migrate(gen_label(8), int(mint.contract_id), mint.code_hash)
assert mint.get_supported_assets() == new_mint.get_supported_assets(), "Contracts are not the same"

if args.testnet == "public":
account_key = 'admin'
account = secretlib.run_command(['secretcli', 'keys', 'show', '-a', account_key]).rstrip()

with open("testnet-contracts.json", "r") as json_file:
contracts_config = json.load(json_file)

print("Configuring silk")
silk_updated = False
silk_instantiated_contract = PreInstantiatedContract(
contract_id=contracts_config["silk"]["contract_id"],
address=contracts_config["silk"]["address"],
code_hash=contracts_config["silk"]["code_hash"])
silk = SNIP20(contracts_config["silk"]["label"], "silk", "SLK", decimals=6, public_total_supply=True, enable_mint=True,
admin=account, uploader=account, backend=None, instantiated_contract=silk_instantiated_contract)
silk_password = silk.set_view_key(account_key, "password")
silk.print()

print("Configuring sSCRT")
sscrt = copy.deepcopy(silk)
sscrt.label = contracts_config["sscrt"]["label"]
sscrt.address = contracts_config["sscrt"]["address"]
sscrt.code_hash = contracts_config["sscrt"]["code_hash"]
sscrt_password = sscrt.set_view_key(account_key, "password")
sscrt.print()

print("Configuring Oracle")
oracle_updated = False
with open("checksum/oracle.txt", 'r') as oracle_checksum:
if oracle_checksum.readline().strip() == contracts_config["oracle"]["checksum"].strip():
oracle_instantiated_contract = PreInstantiatedContract(
contract_id=contracts_config["oracle"]["contract_id"],
address=contracts_config["oracle"]["address"],
code_hash=contracts_config["oracle"]["code_hash"])
oracle = Oracle(contracts_config["oracle"]["label"], admin=account, uploader=account, backend=None,
instantiated_contract=oracle_instantiated_contract)
else:
print("Instantiating Oracle")
oracle_updated = True
contracts_config["oracle"]["label"] = f"oracle-{gen_label(8)}"
oracle = Oracle(contracts_config["oracle"]["label"], admin=account, uploader=account, backend=None)
contracts_config["oracle"]["contract_id"] = oracle.contract_id
contracts_config["oracle"]["address"] = oracle.address
contracts_config["oracle"]["code_hash"] = oracle.code_hash

print(oracle.get_silk_price())
oracle.print()

print("Configuring Mint")
mint_updated = False
with open("checksum/mint.txt", 'r') as mint_checksum:
mint_instantiated_contract = PreInstantiatedContract(
contract_id=contracts_config["mint"]["contract_id"],
address=contracts_config["mint"]["address"],
code_hash=contracts_config["mint"]["code_hash"])
mint = Mint(contracts_config["mint"]["label"], silk, oracle, admin=account, uploader=account, backend=None,
instantiated_contract=mint_instantiated_contract)

if mint_checksum.readline().strip() != contracts_config["mint"]["checksum"].strip():
print("Instantiating Mint")
mint_updated = True
label = f"mint-{gen_label(8)}"
# TODO: upload and get codehash + id of the contract without instantiating to call the mint.migrate
new_mint = Mint(label, silk, oracle, admin=account, uploader=account, backend=None)
# mint.migrate()
mint = copy.deepcopy(new_mint)
contracts_config["mint"]["label"] = label
contracts_config["mint"]["contract_id"] = mint.contract_id
contracts_config["mint"]["address"] = mint.address
contracts_config["mint"]["code_hash"] = mint.code_hash

if silk_updated or oracle_updated:
mint.update_config(silk=silk, oracle=oracle)

if silk_updated or mint_updated:
# TODO: reset minters if mint updated
silk.set_minters([mint.address])

if mint_updated:
mint.register_asset(sscrt)

assets = mint.get_supported_assets()['supported_assets']['assets'][0]
assert sscrt.address == assets, f"Got {assets}; expected {sscrt.address}"
mint.print()

# Save json data
with open('testnet-contracts.json', 'w', encoding='utf-8') as json_file:
json.dump(contracts_config, json_file, ensure_ascii=False, indent=4)
27 changes: 27 additions & 0 deletions contracts/compiled/testnet-contracts.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"mint": {
"label": "mint",
"contract_id": 30092,
"address": "secret1g9rfxe43my6w9h76422er5ckgp9cp9smgtqnx8",
"code_hash": "20D0B41DFB650E0773F9B8DB9516C651B8D3275ED66C3D6077C8102A1D6AD73E",
"checksum": "b217f26eae6d450570ee295b0d604663"
},
"oracle": {
"label": "oracle",
"contract_id": 30090,
"address": "secret12pfmer5e35ekup9r4cvdm6zzql7fwudzsnc7m7",
"code_hash": "10912DA31D27B8B6AAB3AED4A9B9A2F0BAB120C87156FCDDA3CC9F7DD0DAD8B7",
"checksum": "31c3ff776e85627bf77c00787a94a68b"
},
"silk": {
"label": "silk",
"contract_id": 30067,
"address": "secret1zccl8tccrhwru2mfwzmxqz6lvmp08y9359jurx",
"code_hash": "35F5DB2BC5CD56815D10C7A567D6827BECCB8EAF45BC3FA016930C4A8209EA69"
},
"sscrt": {
"label": "sSCRT",
"address": "secret1s7c6xp9wltthk5r6mmavql4xld5me3g37guhsx",
"code_hash": "CD400FB73F5C99EDBC6AAB22C2593332B8C9F2EA806BF9B42E3A523F3AD06F62"
}
}
Loading