├── .gitattributes ├── .github ├── CODEOWNERS └── workflows │ ├── automate-add-issue-in-project.yaml │ ├── backup.yml │ ├── chimney-and-blobber-tests.yaml │ ├── ci-dev-st.yml │ ├── ci.yml │ ├── enterprise-blobbers-tokenomics_ci.yml │ ├── network-check.yaml │ ├── nightly-challenge-sprint.yaml │ ├── nightly-current-sprint.yaml │ ├── nightly-cypress-run.yaml │ ├── nightly-staging-tenderly.yml │ ├── nightly-staging.yml │ └── tokenomics_ci.yml ├── .gitignore ├── .golangci.yml ├── LICENSE.txt ├── README.md ├── go.mod ├── go.sum ├── internal ├── api │ ├── model │ │ ├── api.go │ │ ├── errors.go │ │ ├── helper.go │ │ ├── zauth.go │ │ ├── zbox.go │ │ └── zvault.go │ └── util │ │ ├── client │ │ ├── api_client.go │ │ ├── errors.go │ │ ├── http_client.go │ │ ├── sdk.go │ │ ├── url_builder.go │ │ ├── zauth_client.go │ │ ├── zbox_client.go │ │ ├── zs3_client.go │ │ └── zvault_client.go │ │ ├── config │ │ └── config.go │ │ ├── crypto │ │ ├── bls.go │ │ ├── bls0chain_herumi.go │ │ ├── bls_herumi.go │ │ ├── crypto.go │ │ ├── ed255190chain.go │ │ ├── factory.go │ │ └── signature_scheme.go │ │ ├── endpoint │ │ └── constants.go │ │ ├── tenderly │ │ ├── errors.go │ │ └── tenderly.go │ │ ├── test │ │ └── system_test_framework.go │ │ ├── tokenomics │ │ └── units.go │ │ └── wait │ │ └── wait.go ├── cli │ ├── model │ │ └── model.go │ └── util │ │ ├── api_get_list.go │ │ ├── history.go │ │ ├── specific │ │ ├── posix_utils.go │ │ └── win_utils.go │ │ └── utils.go ├── currency │ └── currency.go ├── dummy_file │ └── five_MB_test_file_dowloaded └── tokenomics │ └── util │ └── config │ └── config.go ├── test-file └── tests ├── api_tests ├── 0box_aggregate_endpoints_test.go ├── 0box_allocation_test.go ├── 0box_dex_test.go ├── 0box_free_storage_test.go ├── 0box_jwt_test.go ├── 0box_nft_test.go ├── 0box_owner_test.go ├── 0box_referral_test.go ├── 0box_shareinfo_test.go ├── 0box_transactions._test.go ├── 0box_wallet_test.go ├── add_blobber_test.go ├── allocation_update_lock_amount_test.go ├── blobber_hashnode_test.go ├── blobber_objecttree_test.go ├── blobber_referencepath_test.go ├── challenge_timings_test.go ├── chimney_blobber_rewards_test.go ├── client_send_nonce_greater_than_some_nonce_test.go ├── config │ ├── api_tests_config.yaml │ ├── sc_owner_wallet.json │ └── wallets.json ├── create_allocation_test.go ├── flaky___broken_scenarios_test.go ├── get_blobberFileRef_test.go ├── get_blobbers_for_new_allocation_test.go ├── get_latest_finalized_magic_block_test.go ├── get_scstate_test.go ├── get_scstats_test.go ├── main_test.go ├── multi_download_test.go ├── multiop_rollback_test.go ├── multiop_test.go ├── open_challenges_test.go ├── postman │ ├── 0chain-api-system-tests.json │ ├── 0chain-smoke-test.json │ ├── Data │ │ ├── 0chain-dashboard-template.hbs │ │ └── test_file │ └── Environments │ │ ├── beta.postman_environment.json │ │ ├── custom.postman_environment.json │ │ ├── dev.postman_environment.json │ │ └── test.postman_environment.json ├── register_blobber_test.go ├── remove_blobber_test.go ├── repair_allocation_test.go ├── replace_blobber_test.go ├── split_key_wallet_mobile_test.go ├── test-file.txt ├── update_blobber_test.go ├── zauth_jwt_test.go ├── zauth_operations_test.go ├── zs3server_operations_test.go ├── zvault_jwt_test.go └── zvault_operations_test.go ├── cli_tests ├── 0_blobber_staked_capacity_test.go ├── 0_challenge_protocol_test.go ├── 0_dropboxmgrt_migrate_test.go ├── 0_expired_allocation_test.go ├── 0_free_read_test.go ├── 0_gdrivemgrt_migrate_test.go ├── 0_owner_update_config_test.go ├── 0_s3mgrt_migrate_alternate2_test.go ├── 0_s3mgrt_migrate_alternate_test.go ├── 0_s3mgrt_migrate_test.go ├── 0_tenderly_authorizer_rewards_test.go ├── 0_tenderly_validator_config_update_test.go ├── 0_tenderly_zcnbridge_add_and_rm_authorizer_test.go ├── 0_tenderly_zcnbridge_auth_replace_burn_mint_test.go ├── 0_tenderly_zcnbridge_burn_test.go ├── 0_tenderly_zcnbridge_ethereum-account-register_test.go ├── 0_tenderly_zcnbridge_list_authorizers_test.go ├── 0_tenderly_zcnbridge_mint_test.go ├── 0_tenderly_zcnbridge_settings_global_test.go ├── 0_tenderly_zcnbridge_verify_ethereum_test.go ├── 0_zboxcli_file_resume_upload_test.go ├── config │ ├── cli_tests_config.yaml │ ├── config.yaml │ ├── nodes.yaml │ ├── wallets │ │ ├── UTC--2022-11-13T22-51-36.015115000Z--d8c9156e782c68ee671c09b6b92de76c97948432 │ │ ├── UTC--2022-11-16T09-39-06.387907000Z--c49926c4124cee1cba0ea94ea31a6c12318df947 │ │ ├── UTC--2022-11-24T20-45-27.508229000Z--c49926c4124cee1cba0ea94ea31a6c12318df947 │ │ ├── UTC--2023-10-26T00-34-42.327566000Z--8e25cfd9bd6c0ca67a5522cd920b3c66d39d6e97 │ │ ├── blobber_owner_wallet.json │ │ ├── miner01_node_delegate_wallet.json │ │ ├── miner02_node_delegate_wallet.json │ │ ├── miner03_node_delegate_wallet.json │ │ ├── sc_owner_wallet.json │ │ ├── sharder01_node_delegate_wallet.json │ │ ├── sharder02_node_delegate_wallet.json │ │ ├── staking_wallet.json │ │ ├── wallets.json │ │ ├── zbox_team_wallet.json │ │ └── zcnsc_owner_wallet.json │ └── zbox_config.yaml ├── config2 │ ├── config.yaml │ └── wallet.json ├── list_stakable_providers_test.go ├── main_test.go ├── mc_tests │ ├── 1_basic_operations_test.go │ ├── 2_bucket_to_bucket_test.go │ ├── 3_replication_disaster_recovery_test.go │ └── mc_hosts.yaml ├── miner_block_rewards_test.go ├── miner_fee_rewards_test.go ├── sdk.go ├── sharder_block_rewards_test.go ├── sharder_fee_rewards_test.go ├── zboxcli_blobber_availability_test.go ├── zboxcli_blobber_config_update_test.go ├── zboxcli_cancel_allocation_test.go ├── zboxcli_common_user_functions_test.go ├── zboxcli_create_allocation_free_storage_test.go ├── zboxcli_create_allocation_test.go ├── zboxcli_create_dir_test.go ├── zboxcli_download_livestream_test.go ├── zboxcli_file_copy_test.go ├── zboxcli_file_delete_test.go ├── zboxcli_file_download_resume_test.go ├── zboxcli_file_download_test.go ├── zboxcli_file_meta_test.go ├── zboxcli_file_move_test.go ├── zboxcli_file_rename_test.go ├── zboxcli_file_stats_test.go ├── zboxcli_file_update_test.go ├── zboxcli_file_upload_test.go ├── zboxcli_finalize_allocation_test.go ├── zboxcli_kill_blobber_test.go ├── zboxcli_list_file_test.go ├── zboxcli_livestream_test.go ├── zboxcli_max_file_test.go ├── zboxcli_recent_refs_test.go ├── zboxcli_repair_test.go ├── zboxcli_restricted_blobber_test.go ├── zboxcli_rollback_test.go ├── zboxcli_share_file_test.go ├── zboxcli_stake_unstake_token_test.go ├── zboxcli_sync_test.go ├── zboxcli_update_allocation_test.go ├── zboxcli_upload_token_test.go ├── zboxcli_wp_lock_unlock_test.go ├── zs3server_tests │ ├── 1_mixed_test.go │ ├── 2_put_test.go │ ├── 3_fanout_test.go │ ├── 4_listing_purge_test.go │ ├── allocation.yaml │ ├── analyzing zst files.md │ ├── hosts.yaml │ ├── readme.md │ └── warp_analysis_test.go ├── zwalletcli_get_id_test.go ├── zwalletcli_miner_stake_test.go ├── zwalletcli_miner_update_config_test.go ├── zwalletcli_miner_update_settings_test.go ├── zwalletcli_minersc_pool_info_test.go ├── zwalletcli_mn_pool_info_test.go ├── zwalletcli_recover_wallet_test.go ├── zwalletcli_register_wallet_test.go ├── zwalletcli_send_and_balance_test.go ├── zwalletcli_sharder_stake_test.go ├── zwalletcli_sharder_update_settings_test.go ├── zwalletcli_storage_update_config_test.go ├── zwalletcli_update_global_config_test.go ├── zzwalletcli_kill_sharder_test.go ├── zzzwalletcli_kill_miner_test.go └── zzzzwalletcli_compare_stats_test.go └── tokenomics_tests ├── allocation_test.go ├── blobber_challenge_reward_test.go ├── blobber_read_test.go ├── blobber_slash_penalty_test.go ├── client_fileops_limits_test.go ├── config ├── bridge.yaml ├── cli_tests_config.yaml ├── config.yaml ├── nodes.yaml ├── owner.yaml ├── tokenomics_tests_config.yaml ├── wallets │ ├── blobber1_delegate1_wallet.json │ ├── blobber1_delegate2_wallet.json │ ├── blobber1_wallet.json │ ├── blobber2_delegate1_wallet.json │ ├── blobber2_delegate2_wallet.json │ ├── blobber2_wallet.json │ ├── blobber_owner_wallet.json │ ├── miner01_node_delegate_wallet.json │ ├── miner02_node_delegate_wallet.json │ ├── miner03_node_delegate_wallet.json │ ├── sc_owner_wallet.json │ ├── sharder01_node_delegate_wallet.json │ ├── sharder02_node_delegate_wallet.json │ ├── validator1_delegate1_wallet.json │ ├── validator1_delegate2_wallet.json │ ├── validator1_wallet.json │ ├── validator2_delegate1_wallet.json │ ├── validator2_delegate2_wallet.json │ ├── validator2_wallet.json │ ├── validator_owner_wallet.json │ └── zbox_team_wallet.json └── zbox_config.yaml ├── enterprise_blobber_cancel_allocation_test.go ├── enterprise_blobber_create_allocation_test.go ├── enterprise_blobber_finalize_allocation_test.go ├── enterprise_blobber_replace_allocation_test.go ├── enterprise_blobber_update_allocation_test.go ├── main_test.go ├── min_stake_test.go └── utils ├── allocation.go ├── blobbers.go ├── general.go ├── miners.go ├── sharders.go └── wallet.go /.gitattributes: -------------------------------------------------------------------------------- 1 | *minio filter=lfs diff=lfs merge=lfs -text 2 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # The following users own all code in the system_tests repo 2 | # Jayash 3 | * @Jayashsatolia403 -------------------------------------------------------------------------------- /.github/workflows/automate-add-issue-in-project.yaml: -------------------------------------------------------------------------------- 1 | name: Add Issue to Backend Issues Project Board 2 | 3 | on: 4 | issues: 5 | types: 6 | - opened 7 | 8 | jobs: 9 | add-to-project: 10 | name: Add Issue to Backend Issues Project Board 11 | runs-on: arc-runner 12 | steps: 13 | - uses: actions/add-to-project@v0.4.0 14 | with: 15 | project-url: https://github.com/orgs/0chain/projects/${{ secrets.PROJECT_NUMBER }} 16 | github-token: ${{ secrets.SVC_ACCOUNT_SECRET }} -------------------------------------------------------------------------------- /.github/workflows/backup.yml: -------------------------------------------------------------------------------- 1 | name: Mirror repo to S3 2 | 3 | on: 4 | schedule: 5 | # Runs everyday at 4:10 am 6 | - cron: '10 4 * * *' 7 | workflow_dispatch: 8 | 9 | jobs: 10 | s3Backup: 11 | runs-on: arc-runner 12 | steps: 13 | - uses: actions/checkout@v1 14 | 15 | - name: Get info 16 | id: get_info 17 | run: | 18 | GIT_COMMIT_DATE="$((`git log -n 1 --date-order --all | grep Date | awk '{ print $4 }'`))" 19 | YESTERDAY_DATE="$((`date | awk '{ print $3 }'`-1))" 20 | echo ::set-output name=GIT_COMMIT_DATE::${GIT_COMMIT_DATE} 21 | echo ::set-output name=YESTERDAY_DATE::${YESTERDAY_DATE} 22 | echo $GIT_COMMIT_DATE 23 | echo $YESTERDAY_DATE 24 | 25 | - name: Create backup 26 | if: steps.get_info.outputs.GIT_COMMIT_DATE == steps.get_info.outputs.YESTERDAY_DATE 27 | run: | 28 | sudo apt update && sudo apt install python3-pip -y 29 | sudo pip3 install github-backup 30 | sudo github-backup -O 0chain -P -t ${{ secrets.SVC_ACCOUNT_SECRET }} --output-directory=/github-backup/system_test --all -O -R system_test 31 | 32 | - name: Install AWS 33 | run: | 34 | curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" 35 | unzip awscliv2.zip 36 | sudo ./aws/install 37 | 38 | - name: Create zip 39 | if: steps.get_info.outputs.GIT_COMMIT_DATE == steps.get_info.outputs.YESTERDAY_DATE 40 | run: sudo zip -r system_test.zip /github-backup/system_test 41 | 42 | - name: Set AWS credentials 43 | if: steps.get_info.outputs.GIT_COMMIT_DATE == steps.get_info.outputs.YESTERDAY_DATE 44 | uses: aws-actions/configure-aws-credentials@v1 45 | with: 46 | aws-access-key-id: ${{ secrets.BACKUP_ACCESS_KEY_ID }} 47 | aws-secret-access-key: ${{ secrets.BACKUP_SECRET_KEY_ID }} 48 | aws-region: us-east-2 49 | 50 | - name: Backup to s3 51 | if: steps.get_info.outputs.GIT_COMMIT_DATE == steps.get_info.outputs.YESTERDAY_DATE 52 | run: | 53 | aws s3 cp system_test.zip s3://${{ secrets.MIRROR_TARGET }}/system_test.zip 54 | -------------------------------------------------------------------------------- /.github/workflows/chimney-and-blobber-tests.yaml: -------------------------------------------------------------------------------- 1 | name: "Manual 0Chain Chimney and Blobber Tests" 2 | concurrency: 3 | group: "manual-chimney-blobber-tests-${{ github.ref }}-${{ github.event_name }}" 4 | cancel-in-progress: true 5 | on: 6 | workflow_dispatch: 7 | inputs: 8 | NETWORK_URL: 9 | description: "Network to run system tests against. [example: dev.0chain.net]" 10 | default: demo.zus.network 11 | required: false 12 | 13 | jobs: 14 | system-tests: 15 | name: "System Tests" 16 | runs-on: [ tests-suite ] 17 | steps: 18 | - name: "Setup Go" 19 | shell: 'script --return --quiet --command "bash {0}"' 20 | run: | 21 | if ! go env &> /dev/null; then 22 | [ -f ./https://go.dev/dl/go1.20.3.linux-amd64.tar.gz ] || wget https://go.dev/dl/go1.20.3.linux-amd64.tar.gz 23 | [ -d /usr/local/go ] && rm -rf /usr/local/go 24 | [ -f /usr/local/bin/go ] && rm -rf /usr/local/bin/go 25 | tar -C /usr/local -xzf ./go1.20.3.linux-amd64.tar.gz 26 | else 27 | echo "go already exists" 28 | fi 29 | 30 | echo "PATH=$PATH:/usr/local/go/bin" >> $GITHUB_ENV 31 | export PATH=$PATH:/usr/local/go/bin 32 | export HOME="/root" 33 | which go 34 | go env 35 | 36 | - name: "Run System tests" 37 | uses: 0chain/actions/run-system-tests@master 38 | with: 39 | repo_snapshots_branch: "current-sprint" 40 | network: ${{ inputs.NETWORK_URL }} 41 | deploy_report_page: true 42 | archive_results: true 43 | run_flaky_tests: false 44 | run_api_system_tests: false 45 | run_cli_system_tests: false 46 | run_tokenomics_system_tests: false 47 | run_chimney_blobber_tests: true 48 | run_smoke_tests: false 49 | run_s3mgrt_system_tests: false 50 | run_challenge_system_tests: false 51 | TENDERLY_VIRTUAL_TESTNET_RPC_ID: "" 52 | svc_account_secret: ${{ secrets.SVC_ACCOUNT_SECRET }} 53 | -------------------------------------------------------------------------------- /.github/workflows/network-check.yaml: -------------------------------------------------------------------------------- 1 | name: 0Chain Network Health Check 2 | on: 3 | # schedule: 4 | # Runs every 3 hours 5 | # - cron: '0 */3 * * * 6 | workflow_dispatch: 7 | jobs: 8 | network-health-check: 9 | runs-on: self-hosted 10 | strategy: 11 | matrix: 12 | network: [ ] 13 | fail-fast: false 14 | steps: 15 | - name: "Checkout System Tests" 16 | uses: actions/checkout@v2 17 | 18 | - name: "Check 0dns Liveness" 19 | run: curl --silent --show-error --fail --max-time 10 https://${{ matrix.network }}/dns 20 | 21 | - name: "Check Explorer Liveness" 22 | run: curl --silent --show-error --fail --max-time 10 https://${{ matrix.network }} 23 | 24 | - name: "Install Node" 25 | uses: actions/setup-node@v1 26 | with: 27 | node-version: '12.x' 28 | 29 | - name: "Configure Node" 30 | run: | 31 | npm config set user 0 32 | npm config set unsafe-perm true 33 | 34 | - name: "Install Newman" 35 | run: | 36 | npm install -g newman 37 | npm install -g newman-reporter-htmlextra 38 | 39 | - name: "Run Smoke Tests" 40 | run: | 41 | cd tests/api_tests/postman 42 | custom_network=$(echo ${{ matrix.network }} | xargs | sed -E 's/^\s*.*:\/\///g' | sed 's:/*$::') && sed -i "0,/REPLACE/s//$custom_network/" './Environments/custom.postman_environment.json' 43 | 44 | counter=1; 45 | exit_code=1; 46 | while [ $counter -lt 6 ] && [ $exit_code -eq 1 ] 47 | do 48 | echo "Executing smoke tests attempt [$counter/5]" 49 | exit_code=0 50 | newman run "./0chain-smoke-test.json" -e "./Environments/custom.postman_environment.json" -r cli --color on --global-var "ITERATION=$counter" || { ((counter=counter+1)) && exit_code=1 && [ $counter -lt 6 ] && echo "TEST ATTEMPT FAILED. Sleeping for 30s" && sleep 30; } 51 | done 52 | 53 | if [ $counter -eq 6 ]; then 54 | echo "Smoke tests failed for network [${{ matrix.network }}]" 55 | exit 1 56 | fi 57 | 58 | - name: "Check if should send slack notification" 59 | if: failure() 60 | id: send-slack-notification 61 | uses: peter-murray/value-as-flag-action@0.0.1 62 | with: 63 | value: ${{ secrets.DEVOPS_CHANNEL_WEBHOOK_URL }} 64 | default: false 65 | 66 | - name: "Notify Slack" 67 | if: failure() && steps.send-slack-notification.outputs.value == 'true' 68 | run: | 69 | curl -X POST -H 'Content-type: application/json' --data '{"text":" [${{ matrix.network }}] network seems to be unhealthy. View the test results on Github: https://github.com/0chain/system_test/actions/runs/${{ github.run_id }}"}' ${{ secrets.DEVOPS_CHANNEL_WEBHOOK_URL }} 70 | -------------------------------------------------------------------------------- /.github/workflows/nightly-challenge-sprint.yaml: -------------------------------------------------------------------------------- 1 | name: "Challenge Protocol Nightly Tests - Sprint" 2 | concurrency: 3 | group: "challenge-nightly-tests-${{ github.ref }}-${{ github.event_name }}" 4 | cancel-in-progress: true 5 | on: 6 | schedule: 7 | # Runs every morning at 2am UTC 8 | - cron: '0 2 * * *' 9 | workflow_dispatch: 10 | inputs: 11 | repo_snapshots_branch: 12 | description: 'branch of repo-snapshots to derive images and branches from.' 13 | default: 'current-sprint' 14 | required: true 15 | 16 | jobs: 17 | system-tests: 18 | name: "Challenge System Tests" 19 | runs-on: [ tests-suite ] 20 | steps: 21 | - name: "Config: Deploy new 0Chain network then run challenge tests against it" 22 | run: | 23 | echo "NETWORK_URL=$(echo dev-${RUNNER_NAME:(-1)}.devnet-0chain.net)" >> $GITHUB_ENV 24 | echo "RUNNER_NUMBER=${RUNNER_NAME:(-1)}" >> $GITHUB_ENV 25 | echo "REPO_SNAPSHOTS_BRANCH=current-sprint" >> $GITHUB_ENV 26 | 27 | - name: 'Setup jq' 28 | uses: dcarbone/install-jq-action@v2.1.0 29 | with: 30 | version: '1.7' 31 | force: 'false' 32 | 33 | - name: "Deploy 0Chain" 34 | uses: 0chain/actions/deploy-0chain@master 35 | with: 36 | repo_snapshots_branch: "${{ env.REPO_SNAPSHOTS_BRANCH }}" 37 | kube_config: ${{ secrets[format('DEV{0}KC', env.RUNNER_NUMBER)] }} 38 | teardown_condition: "TESTS_PASSED" 39 | SUBGRAPH_API_URL: ${{ secrets.SUBGRAPH_API_URL }} 40 | TENDERLY_VIRTUAL_TESTNET_RPC_ID: "" 41 | graphnode_sc: ${{ secrets.GRAPHNODE_SC }} 42 | graphnode_network: ${{ secrets.GRAPHNODE_NETWORK }} 43 | graphnode_ethereum_node_url: "" 44 | svc_account_secret: ${{ secrets.SVC_ACCOUNT_SECRET }} 45 | 46 | - name: "Run Challenge System tests" 47 | uses: 0chain/actions/run-system-tests@master 48 | with: 49 | repo_snapshots_branch: "${{ env.REPO_SNAPSHOTS_BRANCH }}" 50 | network: ${{ env.NETWORK_URL }} 51 | svc_account_secret: ${{ secrets.SVC_ACCOUNT_SECRET }} 52 | deploy_report_page: true 53 | archive_results: true 54 | run_flaky_tests: false 55 | run_api_system_tests: false 56 | run_cli_system_tests: false 57 | run_tokenomics_system_tests: false 58 | run_smoke_tests: false 59 | run_tenderly_tests: false 60 | run_s3mgrt_system_tests: false 61 | run_challenge_system_tests: true 62 | test_file_filter: ${{ env.TEST_FILE_FILTER }} 63 | TENDERLY_VIRTUAL_TESTNET_RPC_ID: "" 64 | S3_ACCESS_KEY: ${{ secrets.S3_ACCESS_KEY }} 65 | S3_SECRET_KEY: ${{ secrets.S3_SECRET_KEY }} 66 | 67 | notify_slack_on_failure: 68 | runs-on: [self-hosted, arc-runner] 69 | needs: [system-tests] 70 | if: always() && (needs.system-tests.result == 'failure') 71 | steps: 72 | - name: "Notify Slack" 73 | run: | 74 | payload='{ 75 | "text": "'" Challenge Protocol Nightly Tests - Current Sprint FAILED on $(echo ${GITHUB_REF#refs/heads/})!.\n View the test results on Github: https://github.com/0chain/system_test/actions/runs/${{ github.run_id }}"'", 76 | "attachments": [ 77 | { 78 | "text": "Challenge Protocol Nightly Tests - Current sprint: FAILED ⚠️", 79 | "color": "#ff0000" 80 | } 81 | ] 82 | }' 83 | curl -X POST -H 'Content-type: application/json' --data "${payload}" ${{ secrets.DEVOPS_CHANNEL_WEBHOOK_URL }} 84 | 85 | notify_slack_on_success: 86 | runs-on: [self-hosted, arc-runner] 87 | needs: [system-tests] 88 | if: always() && (needs.system-tests.result == 'success') 89 | steps: 90 | - name: "Notify Slack" 91 | run: | 92 | payload='{ 93 | "text": "'" Challenge Protocol Nightly Tests - Current Sprint PASSING on $(echo ${GITHUB_REF#refs/heads/})!.\n View the test results on Github: https://github.com/0chain/system_test/actions/runs/${{ github.run_id }}"'", 94 | "attachments": [ 95 | { 96 | "text": "Challenge Protocol Nightly Tests - Current sprint: PASSED ✅", 97 | "color": "#22bb33" 98 | } 99 | ] 100 | }' 101 | curl -X POST -H 'Content-type: application/json' --data "${payload}" ${{ secrets.DEVOPS_CHANNEL_WEBHOOK_URL }} 102 | -------------------------------------------------------------------------------- /.github/workflows/nightly-current-sprint.yaml: -------------------------------------------------------------------------------- 1 | name: "0Chain Nightly Tests - Current Sprint" 2 | concurrency: 3 | group: "sprint-nightly-tests-${{ github.ref }}-${{ github.event_name }}" 4 | cancel-in-progress: true 5 | on: 6 | schedule: 7 | # Runs every morning at 4am UTC 8 | - cron: '0 4 * * *' 9 | workflow_dispatch: 10 | 11 | jobs: 12 | system-tests: 13 | name: "System Tests" 14 | runs-on: [ tests-suite ] 15 | steps: 16 | - name: "Config: Deploy new 0Chain network then run tests against it" 17 | run: | 18 | echo "NETWORK_URL=$(echo dev-${RUNNER_NAME:(-1)}.devnet-0chain.net)" >> $GITHUB_ENV 19 | echo "REPO_SNAPSHOTS_BRANCH=current-sprint" >> $GITHUB_ENV 20 | echo "RUNNER_NUMBER=${RUNNER_NAME:(-1)}" >> $GITHUB_ENV 21 | 22 | - name: 'Setup jq' 23 | uses: dcarbone/install-jq-action@v2.1.0 24 | with: 25 | version: '1.7' 26 | force: 'false' 27 | 28 | - name: "Deploy 0Chain" 29 | uses: 0chain/actions/deploy-0chain@master 30 | with: 31 | repo_snapshots_branch: "${{ env.REPO_SNAPSHOTS_BRANCH }}" 32 | kube_config: ${{ secrets[format('DEV{0}KC', env.RUNNER_NUMBER)] }} 33 | teardown_condition: "TESTS_PASSED" 34 | SUBGRAPH_API_URL: ${{ secrets.SUBGRAPH_API_URL }} 35 | TENDERLY_VIRTUAL_TESTNET_RPC_ID: "" 36 | graphnode_sc: ${{ secrets.GRAPHNODE_SC }} 37 | graphnode_network: ${{ secrets.GRAPHNODE_NETWORK }} 38 | graphnode_ethereum_node_url: "" 39 | svc_account_secret: ${{ secrets.SVC_ACCOUNT_SECRET }} 40 | 41 | - name: "Run System tests" 42 | uses: 0chain/actions/run-system-tests@master 43 | with: 44 | repo_snapshots_branch: "${{ env.REPO_SNAPSHOTS_BRANCH }}" 45 | network: ${{ env.NETWORK_URL }} 46 | svc_account_secret: ${{ secrets.SVC_ACCOUNT_SECRET }} 47 | deploy_report_page: true 48 | archive_results: true 49 | run_flaky_tests: true 50 | run_api_system_tests: true 51 | run_cli_system_tests: true 52 | run_tenderly_tests: false 53 | run_tokenomics_system_tests: false 54 | run_smoke_tests: false 55 | test_file_filter: ${{ env.TEST_FILE_FILTER }} 56 | TENDERLY_VIRTUAL_TESTNET_RPC_ID: "" 57 | S3_ACCESS_KEY: ${{ secrets.S3_ACCESS_KEY }} 58 | S3_SECRET_KEY: ${{ secrets.S3_SECRET_KEY }} 59 | 60 | - name: "Check if should send slack notification" 61 | if: failure() 62 | id: send-slack-notification 63 | uses: peter-murray/value-as-flag-action@0.0.1 64 | with: 65 | value: ${{ secrets.DEVOPS_CHANNEL_WEBHOOK_URL }} 66 | default: false 67 | 68 | notify_slack_on_failure: 69 | runs-on: [self-hosted, arc-runner] 70 | needs: [system-tests] 71 | if: always() && (needs.system-tests.result == 'failure') 72 | steps: 73 | - name: "Notify Slack" 74 | run: | 75 | payload='{ 76 | "text": "'" 0Chain Nightly Tests - Current Sprint FAILED on $(echo ${GITHUB_REF#refs/heads/})!.\n View the test results on Github: https://github.com/0chain/system_test/actions/runs/${{ github.run_id }}"'", 77 | "attachments": [ 78 | { 79 | "text": "0Chain Nightly Tests - Current Sprint FAILED ⚠️", 80 | "color": "#ff0000" 81 | } 82 | ] 83 | }' 84 | curl -X POST -H 'Content-type: application/json' --data "${payload}" ${{ secrets.DEVOPS_CHANNEL_WEBHOOK_URL }} 85 | 86 | notify_slack_on_success: 87 | runs-on: [self-hosted, arc-runner] 88 | needs: [system-tests] 89 | if: always() && (needs.system-tests.result == 'success') 90 | steps: 91 | - name: "Notify Slack" 92 | run: | 93 | payload='{ 94 | "text": "'" 0Chain Nightly Tests - Current Sprint PASSING on $(echo ${GITHUB_REF#refs/heads/})!.\n View the test results on Github: https://github.com/0chain/system_test/actions/runs/${{ github.run_id }}"'", 95 | "attachments": [ 96 | { 97 | "text": "0Chain Nightly Tests - Current Sprint PASSED ✅", 98 | "color": "#22bb33" 99 | } 100 | ] 101 | }' 102 | curl -X POST -H 'Content-type: application/json' --data "${payload}" ${{ secrets.DEVOPS_CHANNEL_WEBHOOK_URL }} 103 | -------------------------------------------------------------------------------- /.github/workflows/nightly-staging.yml: -------------------------------------------------------------------------------- 1 | name: "0Chain Nightly Tests - Staging" 2 | concurrency: 3 | group: "nightly-tests-${{ github.ref }}-${{ github.event_name }}" 4 | cancel-in-progress: true 5 | on: 6 | schedule: 7 | # Runs every morning at 2am UTC 8 | - cron: '0 2 * * *' 9 | workflow_dispatch: 10 | 11 | jobs: 12 | system-tests: 13 | name: "System Tests" 14 | runs-on: [ tests-suite ] 15 | steps: 16 | - name: "Config: Deploy new 0Chain network then run tests against it" 17 | run: | 18 | echo "NETWORK_URL=$(echo dev-${RUNNER_NAME:(-1)}.devnet-0chain.net)" >> $GITHUB_ENV 19 | echo "REPO_SNAPSHOTS_BRANCH=staging" >> $GITHUB_ENV 20 | echo "RUNNER_NUMBER=${RUNNER_NAME:(-1)}" >> $GITHUB_ENV 21 | 22 | - name: 'Setup jq' 23 | uses: dcarbone/install-jq-action@v2.1.0 24 | with: 25 | version: '1.7' 26 | force: 'false' 27 | 28 | - name: "Deploy 0Chain" 29 | uses: 0chain/actions/deploy-0chain@master 30 | with: 31 | repo_snapshots_branch: "${{ env.REPO_SNAPSHOTS_BRANCH }}" 32 | kube_config: ${{ secrets[format('DEV{0}KC', env.RUNNER_NUMBER)] }} 33 | teardown_condition: "TESTS_PASSED" 34 | SUBGRAPH_API_URL: ${{ secrets.SUBGRAPH_API_URL }} 35 | TENDERLY_VIRTUAL_TESTNET_RPC_ID: "" 36 | graphnode_sc: ${{ secrets.GRAPHNODE_SC }} 37 | graphnode_network: ${{ secrets.GRAPHNODE_NETWORK }} 38 | graphnode_ethereum_node_url: "" 39 | svc_account_secret: ${{ secrets.SVC_ACCOUNT_SECRET }} 40 | 41 | - name: "Run System tests" 42 | uses: 0chain/actions/run-system-tests@master 43 | with: 44 | repo_snapshots_branch: "${{ env.REPO_SNAPSHOTS_BRANCH }}" 45 | network: ${{ env.NETWORK_URL }} 46 | svc_account_secret: ${{ secrets.SVC_ACCOUNT_SECRET }} 47 | deploy_report_page: true 48 | archive_results: true 49 | run_flaky_tests: true 50 | run_api_system_tests: true 51 | run_cli_system_tests: true 52 | run_tenderly_tests: false 53 | run_tokenomics_system_tests: false 54 | run_smoke_tests: false 55 | test_file_filter: ${{ env.TEST_FILE_FILTER }} 56 | TENDERLY_VIRTUAL_TESTNET_RPC_ID: "" 57 | S3_ACCESS_KEY: ${{ secrets.S3_ACCESS_KEY }} 58 | S3_SECRET_KEY: ${{ secrets.S3_SECRET_KEY }} 59 | 60 | - name: "Check if should send slack notification" 61 | if: failure() 62 | id: send-slack-notification 63 | uses: peter-murray/value-as-flag-action@0.0.1 64 | with: 65 | value: ${{ secrets.DEVOPS_CHANNEL_WEBHOOK_URL }} 66 | default: false 67 | 68 | notify_slack_on_failure: 69 | runs-on: [ self-hosted, arc-runner ] 70 | needs: [ system-tests ] 71 | if: always() && (needs.system-tests.result == 'failure') 72 | steps: 73 | - name: "Notify Slack" 74 | run: | 75 | payload='{ 76 | "text": "'" 0Chain Nightly Tests - Staging FAILED on $(echo ${GITHUB_REF#refs/heads/})!.\n View the test results on Github: https://github.com/0chain/system_test/actions/runs/${{ github.run_id }}"'", 77 | "attachments": [ 78 | { 79 | "text": "0Chain Nightly Tests - Staging FAILED ⚠️", 80 | "color": "#ff0000" 81 | } 82 | ] 83 | }' 84 | curl -X POST -H 'Content-type: application/json' --data "${payload}" ${{ secrets.DEVOPS_CHANNEL_WEBHOOK_URL }} 85 | 86 | notify_slack_on_success: 87 | runs-on: [ self-hosted, arc-runner ] 88 | needs: [ system-tests ] 89 | if: always() && (needs.system-tests.result == 'success') 90 | steps: 91 | - name: "Notify Slack" 92 | run: | 93 | payload='{ 94 | "text": "'" 0Chain Nightly Tests - Staging PASSING on $(echo ${GITHUB_REF#refs/heads/})!.\n View the test results on Github: https://github.com/0chain/system_test/actions/runs/${{ github.run_id }}"'", 95 | "attachments": [ 96 | { 97 | "text": "0Chain Nightly Tests - Staging PASSED ✅", 98 | "color": "#22bb33" 99 | } 100 | ] 101 | }' 102 | curl -X POST -H 'Content-type: application/json' --data "${payload}" ${{ secrets.DEVOPS_CHANNEL_WEBHOOK_URL }} 103 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | 3 | *.exe 4 | *.exe~ 5 | *.dll 6 | *.so 7 | *.dylib 8 | 9 | # Test binary, built with `go test -c` 10 | 11 | *.test 12 | 13 | # Output of the go coverage tool, specifically when used with LiteIDE 14 | 15 | *.out 16 | 17 | # Dependency directories (remove the comment below to include it) 18 | 19 | vendor/ 20 | 21 | # Temp test output 22 | tests/cli_tests/config/*.json 23 | tests/cli_tests/config/*allocation.txt 24 | tests/cli/tmp/ 25 | **/cmdlog.log 26 | **/bridge.log 27 | **/zbox 28 | **/zwallet 29 | **/allocation.txt 30 | 31 | .DS_STORE 32 | .idea 33 | .vscode 34 | tests/cli/__debug_bin 35 | tests/cli_tests/*.png 36 | 37 | **/*.log 38 | 39 | .pre-commit-config.yaml 40 | warp-*.csv.zst 41 | warp-*_output.txt 42 | warp 43 | minio 44 | mc 45 | store -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Non-compete BSD-3-Clause 2 | 3 | Copyright © 2019 0Chain,LLC. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, are permitted provided 6 | that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors 16 | may be used to endorse or promote products derived from this software 17 | without specific prior written permission. 18 | 19 | 4. It is not permitted to provide any offering that competes with the source code and binary form 20 | or any other offering the licensor provides using the source code and binary form. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 23 | BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 24 | SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 27 | TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /internal/api/model/errors.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import "errors" 4 | 5 | var ErrNoKeyPair = errors.New("no keypairs are found in the wallet") 6 | -------------------------------------------------------------------------------- /internal/api/model/helper.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import "time" 4 | 5 | func DefaultBlobberRequirements(id, publicKey string) BlobberRequirements { 6 | return BlobberRequirements{ 7 | Size: 64 * 1024 * 4 * 50, 8 | DataShards: 3, 9 | ParityShards: 1, 10 | ExpirationDate: time.Now().Add(721 * time.Hour).Unix(), 11 | ReadPriceRange: PriceRange{ 12 | Min: 0, 13 | Max: 9223372036854775807, 14 | }, 15 | WritePriceRange: PriceRange{ 16 | Min: 0, 17 | Max: 9223372036854775807, 18 | }, 19 | OwnerId: id, 20 | OwnerPublicKey: publicKey, 21 | StorageVersion: 1, 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /internal/api/model/zauth.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | // SetupWallet represents wallet used to perform set up. 4 | type SetupWallet struct { 5 | UserID string `json:"user_id"` 6 | ClientID string `json:"client_id"` 7 | ClientKey string `json:"client_key"` 8 | PublicKey string `json:"public_key"` 9 | PrivateKey string `json:"private_key"` 10 | PeerPublicKey string `json:"peer_public_key"` 11 | Restrictions []string `json:"restrictions"` 12 | ExpiredAt int64 `json:"expired_at"` 13 | } 14 | 15 | // SignMessageRequest represents message requested to be signed. 16 | type SignMessageRequest struct { 17 | Hash string `json:"hash"` 18 | Signature string `json:"signature"` 19 | ClientID string `json:"client_id"` 20 | } 21 | 22 | // SignMessageResponse represents message sign operation response. 23 | type SignMessageResponse struct { 24 | Sig string `json:"sig"` 25 | } 26 | 27 | // KeyDetailsResponse represents split key details retrieval response. 28 | type KeyDetailsResponse struct { 29 | LastUsed int64 `json:"last_used"` 30 | } 31 | -------------------------------------------------------------------------------- /internal/api/model/zvault.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | // SplitWallet represents both split wallet and split key after generation operation. 4 | type SplitWallet struct { 5 | ClientID string `json:"client_id"` 6 | ClientKey string `json:"client_key"` 7 | PeerPublicKey string `json:"peer_public_key"` 8 | Keys []KeyPair `json:"keys"` 9 | Mnemonic string `json:"mnemonics"` 10 | Version string `json:"version"` 11 | DateCreated string `json:"date_created"` 12 | Nonce int64 `json:"nonce"` 13 | IsSplit bool `json:"is_split"` 14 | } 15 | 16 | // SplitKey represents retrieved split key. 17 | type SplitKey struct { 18 | UserID string `json:"user_id"` 19 | ClientID string `json:"client_id"` 20 | ClientKey string `json:"client_key"` 21 | PrivateKey string `gorm:"unique" json:"private_key"` 22 | PublicKey string `gorm:"unique" json:"public_key"` 23 | PeerPublicKey string `gorm:"unique" json:"peer_public_key"` 24 | Mnemonic string `json:"mnemonics"` 25 | SharedTo string `json:"shared_to"` 26 | IsRevoked bool `json:"is_revoked"` 27 | CreatedAt int64 `json:"created_at"` 28 | ExpiresAt int64 `json:"expires_at"` 29 | } 30 | 31 | // StoreRequest represents store request payload. 32 | type StoreRequest struct { 33 | Mnemonic string `json:"mnemonic"` 34 | PrivateKey string `json:"private_key"` 35 | } 36 | 37 | // UpdateRestrictionsRequest represents update restrictions request payload. 38 | type UpdateRestrictionsRequest struct { 39 | Restrictions []string `json:"restrictions"` 40 | } 41 | 42 | // ShareWalletRequest represents share wallet request payload. 43 | type ShareWalletRequest struct { 44 | PublicKey string `json:"public_key"` 45 | TargetUserID string `json:"target_user_id"` 46 | } 47 | 48 | // GenerateWalletResponse represents generate wallet response payload. 49 | type GenerateWalletResponse struct { 50 | ClientID string `json:"client_id"` 51 | } 52 | 53 | // GetKeyResponse represents retrieved set of split keys. 54 | type GetKeyResponse struct { 55 | Keys []*SplitKey `json:"keys"` 56 | } 57 | -------------------------------------------------------------------------------- /internal/api/util/client/errors.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import "errors" 4 | 5 | // Contains errors used for API client 6 | var ( 7 | ErrNetworkHealthy = errors.New("network seems to be unhealthy") 8 | 9 | ErrNoMinersHealthy = errors.New("all miners seem to be unhealthy") 10 | ErrNoShadersHealthy = errors.New("all shaders seem to be unhealthy") 11 | ErrNoBlobbersHealthy = errors.New("all blobbers seem to be unhealthy") 12 | 13 | ErrGetFromResource = errors.New("error happened during request") 14 | 15 | ErrExecutionConsensus = errors.New("execution consensus is not reached") 16 | ) 17 | 18 | // Contains errors used for SDK client 19 | var ( 20 | ErrInitStorageSDK = errors.New("error happened during SDK storage initialization") 21 | ) 22 | -------------------------------------------------------------------------------- /internal/api/util/client/http_client.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | 7 | "github.com/0chain/system_test/internal/api/util/test" 8 | 9 | "github.com/0chain/system_test/internal/api/model" 10 | resty "github.com/go-resty/resty/v2" 11 | ) 12 | 13 | // Statuses of http based responses 14 | const ( 15 | HttpOkStatus = 200 16 | HttpBadRequestStatus = 400 17 | HttpNotFoundStatus = 404 18 | HttpNotModifiedStatus = 304 19 | ) 20 | 21 | // Contains all methods used for http based requests 22 | const ( 23 | HttpPOSTMethod = iota + 1 24 | HttpGETMethod 25 | HttpPUTMethod 26 | HttpDELETEMethod 27 | HttpFileUploadMethod 28 | ) 29 | 30 | type BaseHttpClient struct { 31 | HttpClient *resty.Client //nolint 32 | } 33 | 34 | func (c *BaseHttpClient) executeForServiceProvider(t *test.SystemTest, url string, executionRequest model.ExecutionRequest, method int) (*resty.Response, error) { //nolint 35 | var ( 36 | resp *resty.Response 37 | err error 38 | ) 39 | 40 | switch method { 41 | case HttpPUTMethod: 42 | resp, err = c.HttpClient.R().SetHeaders(executionRequest.Headers).SetFormData(executionRequest.FormData).SetQueryParams(executionRequest.QueryParams).SetBody(executionRequest.Body).Put(url) 43 | case HttpPOSTMethod: 44 | resp, err = c.HttpClient.R().SetHeaders(executionRequest.Headers).SetFormData(executionRequest.FormData).SetBody(executionRequest.Body).Post(url) 45 | case HttpFileUploadMethod: 46 | resp, err = c.HttpClient.R().SetHeaders(executionRequest.Headers).SetFormData(executionRequest.FormData).SetFile(executionRequest.FileName, executionRequest.FilePath).Post(url) 47 | case HttpGETMethod: 48 | resp, err = c.HttpClient.R().SetHeaders(executionRequest.Headers).SetQueryParams(executionRequest.QueryParams).Get(url) 49 | case HttpDELETEMethod: 50 | resp, err = c.HttpClient.R().SetHeaders(executionRequest.Headers).SetFormData(executionRequest.FormData).SetQueryParams(executionRequest.QueryParams).SetBody(executionRequest.Body).Delete(url) 51 | } 52 | 53 | if err != nil { 54 | t.Errorf("%s error : %v", url, err) 55 | return nil, fmt.Errorf("%s: %w", url, ErrGetFromResource) 56 | } 57 | 58 | body := resp.Body() 59 | if executionRequest.Dst != nil { 60 | err = json.Unmarshal(body, executionRequest.Dst) 61 | if err != nil { 62 | t.Logf("%s returned %s with status %s", url, string(body), resp.Status()) 63 | return resp, err 64 | } 65 | } 66 | 67 | return resp, nil 68 | } 69 | -------------------------------------------------------------------------------- /internal/api/util/client/url_builder.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "fmt" 5 | "net/url" 6 | "path/filepath" 7 | "strings" 8 | ) 9 | 10 | type URLBuilder struct { 11 | formattedURL, shiftedURL url.URL 12 | queries url.Values 13 | } 14 | 15 | func (ub *URLBuilder) SetScheme(scheme string) *URLBuilder { 16 | ub.formattedURL.Scheme = scheme 17 | return ub 18 | } 19 | 20 | func (ub *URLBuilder) SetHost(host string) *URLBuilder { 21 | ub.formattedURL.Host = host 22 | return ub 23 | } 24 | 25 | func (ub *URLBuilder) SetPath(path string) *URLBuilder { 26 | ub.formattedURL.Path = filepath.Join(ub.formattedURL.Path, path) 27 | return ub 28 | } 29 | 30 | func (ub *URLBuilder) SetPathVariable(name, value string) *URLBuilder { 31 | ub.formattedURL.Path = strings.Replace(ub.formattedURL.Path, fmt.Sprintf(":%s", name), value, 1) 32 | return ub 33 | } 34 | 35 | func (ub *URLBuilder) AddParams(name, value string) *URLBuilder { 36 | ub.queries.Set(name, value) 37 | return ub 38 | } 39 | 40 | func (ub *URLBuilder) MustShiftParse(rawURL string) error { 41 | parsedURL, err := url.Parse(rawURL) 42 | if err != nil { 43 | return err 44 | } 45 | 46 | ub.shiftedURL = ub.formattedURL 47 | ub.formattedURL = *parsedURL 48 | 49 | ub.SetPath(ub.shiftedURL.Path) 50 | 51 | return nil 52 | } 53 | 54 | func (ub *URLBuilder) String() string { 55 | defer func() { 56 | ub.formattedURL = ub.shiftedURL 57 | }() 58 | ub.formattedURL.RawQuery = ub.queries.Encode() 59 | return ub.formattedURL.String() 60 | } 61 | 62 | func NewURLBuilder() *URLBuilder { 63 | return &URLBuilder{queries: make(url.Values)} 64 | } 65 | -------------------------------------------------------------------------------- /internal/api/util/client/zs3_client.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "bytes" 5 | "io" 6 | "mime/multipart" 7 | "os" 8 | "strings" 9 | 10 | "github.com/0chain/system_test/internal/api/util/test" 11 | resty "github.com/go-resty/resty/v2" 12 | ) 13 | 14 | const ( 15 | AccessKey = "rootroot" 16 | SecretAccessKey = "rootroot" 17 | ) 18 | 19 | type ZS3Client struct { 20 | BaseHttpClient 21 | zs3ServerUrl string 22 | } 23 | 24 | func NewZS3Client(zs3ServerUrl string) *ZS3Client { 25 | zs3Client := &ZS3Client{} 26 | zs3Client.HttpClient = resty.New() 27 | zs3Client.zs3ServerUrl = zs3ServerUrl 28 | return zs3Client 29 | } 30 | 31 | func (c *ZS3Client) BucketOperation(t *test.SystemTest, queryParams, formData map[string]string) (*resty.Response, error) { 32 | resp, err := c.BaseHttpClient.HttpClient.R().SetFiles(formData).SetQueryParams(queryParams).Post(c.zs3ServerUrl) 33 | if err != nil { 34 | t.Log(err) 35 | return nil, err 36 | } 37 | t.Logf("%s returned %s with status %s", c.zs3ServerUrl, resp.String(), resp.Status()) 38 | return resp, nil 39 | } 40 | 41 | func createForm(form map[string]string) (string, io.Reader, error) { 42 | body := new(bytes.Buffer) 43 | mp := multipart.NewWriter(body) 44 | defer mp.Close() 45 | for key, val := range form { 46 | if strings.HasPrefix(val, "@") { 47 | val = val[1:] 48 | file, err := os.Open(val) 49 | if err != nil { 50 | return "", nil, err 51 | } 52 | defer file.Close() //nolint:gocritic 53 | part, err := mp.CreateFormFile(key, val) 54 | if err != nil { 55 | return "", nil, err 56 | } 57 | _, err = io.Copy(part, file) 58 | if err != nil { 59 | return "", nil, err 60 | } 61 | } else { 62 | err := mp.WriteField(key, val) 63 | if err != nil { 64 | return "", nil, err 65 | } 66 | } 67 | } 68 | return mp.FormDataContentType(), body, nil 69 | } 70 | 71 | func (c *ZS3Client) Zs3ServerRequest(t *test.SystemTest, queryParams, formData map[string]string) (*resty.Response, error) { 72 | ct, body, err := createForm(formData) 73 | if err != nil { 74 | t.Log(err) 75 | return nil, err 76 | } 77 | resp, err := c.BaseHttpClient.HttpClient.R().SetBody(body).SetHeaders(map[string]string{"Content-Type": ct}).SetQueryParams(queryParams).Get(c.zs3ServerUrl) 78 | if err != nil { 79 | t.Log(err) 80 | return nil, err 81 | } 82 | t.Logf("%s returned %s with status %s", c.zs3ServerUrl, resp.String(), resp.Status()) 83 | return resp, nil 84 | } 85 | -------------------------------------------------------------------------------- /internal/api/util/config/config.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "encoding/hex" 5 | "encoding/json" 6 | "fmt" 7 | "log" 8 | "os" 9 | "time" 10 | 11 | "github.com/0chain/system_test/internal/api/model" 12 | "github.com/0chain/system_test/internal/api/util/crypto" 13 | "github.com/0chain/system_test/internal/api/util/test" 14 | "github.com/stretchr/testify/require" 15 | "gopkg.in/yaml.v3" //nolint 16 | ) 17 | 18 | // ConfigPathEnv contains name of env variable 19 | const ConfigPathEnv = "CONFIG_PATH" 20 | 21 | // DefaultConfigPath contains default value of ConfigPathEnv 22 | const DefaultConfigPath = "./config/api_tests_config.yaml" 23 | 24 | type Config struct { 25 | BlockWorker string `yaml:"block_worker"` 26 | ZboxUrl string `yaml:"0box_url"` 27 | DefaultTestCaseTimeout string `yaml:"default_test_case_timeout"` 28 | ZvaultUrl string `yaml:"zvault_url"` 29 | ZauthUrl string `yaml:"zauth_url"` 30 | ZS3ServerUrl string `yaml:"zs3_server_url"` 31 | ChimneyTestNetwork string `yaml:"chimney_test_network"` 32 | S3SecretKey string `yaml:"s3_secret_key"` 33 | S3AccessKey string `yaml:"s3_access_key"` 34 | EthereumAddress string `yaml:"ethereum_address"` 35 | S3BucketName string `yaml:"s3_bucket_name"` 36 | S3BucketNameAlternate string `yaml:"s3_bucket_name_alternate"` 37 | BlobberOwnerWalletMnemonics string `yaml:"blobber_owner_wallet_mnemonics"` 38 | OwnerWalletMnemonics string `yaml:"owner_wallet_mnemonics"` 39 | DropboxAccessToken string `yaml:"dropboxAccessToken"` 40 | GdriveAccessToken string `yaml:"gdriveAccessToken"` 41 | } 42 | 43 | func Parse(configPath string) *Config { 44 | var result *Config 45 | 46 | file, err := os.ReadFile(configPath) 47 | if err != nil { 48 | log.Fatalln("Failed to read config file! due to error: " + err.Error()) 49 | } 50 | err = yaml.Unmarshal(file, &result) //nolint 51 | if err != nil { 52 | log.Fatalln("failed to deserialise config file due to error: " + err.Error()) 53 | } 54 | 55 | return result 56 | } 57 | 58 | func GetHomeDir() (string, error) { 59 | homeDir, err := os.UserHomeDir() 60 | 61 | if err != nil { 62 | return "", err 63 | } 64 | return homeDir, nil 65 | } 66 | 67 | func CreateFreeStorageMarker( 68 | t *test.SystemTest, 69 | wallet *model.SdkWallet, 70 | assignerWallet *model.SdkWallet, 71 | ) string { 72 | freeToken := 5.0 73 | nonce := time.Now().Unix() 74 | marker := model.FreeStorageMarker{ 75 | Recipient: wallet.ClientID, 76 | FreeTokens: freeToken, 77 | Nonce: nonce, 78 | } 79 | 80 | reqmarker := fmt.Sprintf("%s:%f:%d", wallet.ClientID, freeToken, nonce) 81 | data := hex.EncodeToString([]byte(reqmarker)) 82 | 83 | rawHash, err := hex.DecodeString(data) 84 | require.Nil(t, err, "failed to decode hex %s", data) 85 | require.NotNil(t, rawHash, "failed to decode hex %s", data) 86 | secretKey := crypto.ToSecretKey(t, assignerWallet.ToCliModelWalletFile()) 87 | marker.Signature = crypto.Sign(t, string(rawHash), secretKey) 88 | marker.Assigner = assignerWallet.ClientID 89 | 90 | markerJson, err := json.Marshal(marker) 91 | require.Nil(t, err, "Could not marshal marker") 92 | 93 | return string(markerJson) 94 | } 95 | -------------------------------------------------------------------------------- /internal/api/util/crypto/bls.go: -------------------------------------------------------------------------------- 1 | package crypto 2 | 3 | import "io" 4 | 5 | var BlsSignerInstance BlsSigner 6 | 7 | type BlsSigner interface { 8 | SetRandFunc(randReader io.Reader) 9 | FrSub(out Fr, x Fr, y Fr) 10 | 11 | NewFr() Fr 12 | NewSecretKey() SecretKey 13 | NewPublicKey() PublicKey 14 | NewSignature() Signature 15 | NewID() ID 16 | } 17 | 18 | // Fr -- 19 | type Fr interface { 20 | Serialize() []byte 21 | 22 | SetLittleEndian(buf []byte) error 23 | } 24 | 25 | type SecretKey interface { 26 | SerializeToHexStr() string 27 | DeserializeHexStr(s string) error 28 | 29 | Serialize() []byte 30 | 31 | GetLittleEndian() []byte 32 | SetLittleEndian(buf []byte) error 33 | 34 | SetByCSPRNG() 35 | 36 | GetPublicKey() PublicKey 37 | 38 | Sign(m string) Signature 39 | Add(rhs SecretKey) 40 | 41 | GetMasterSecretKey(k int) (msk []SecretKey, err error) 42 | Set(msk []SecretKey, id ID) error 43 | } 44 | 45 | type PublicKey interface { 46 | SerializeToHexStr() string 47 | DeserializeHexStr(s string) error 48 | 49 | Serialize() []byte 50 | } 51 | 52 | type Signature interface { 53 | SerializeToHexStr() string 54 | DeserializeHexStr(s string) error 55 | 56 | Add(rhs Signature) 57 | 58 | Verify(pk PublicKey, m string) bool 59 | } 60 | 61 | type ID interface { 62 | SetHexString(s string) error 63 | GetHexString() string 64 | 65 | SetDecString(s string) error 66 | } 67 | -------------------------------------------------------------------------------- /internal/api/util/crypto/factory.go: -------------------------------------------------------------------------------- 1 | //go:build !js && !wasm 2 | // +build !js,!wasm 3 | 4 | package crypto 5 | 6 | import ( 7 | "encoding/hex" 8 | "encoding/json" 9 | "fmt" 10 | 11 | "github.com/0chain/errors" 12 | ) 13 | 14 | // NewSignatureScheme creates an instance for using signature functions 15 | func NewSignatureScheme(sigScheme string) (SignatureScheme, error) { 16 | switch sigScheme { 17 | case "ed25519": 18 | return NewED255190chainScheme(), nil 19 | case "bls0chain": 20 | return NewHerumiScheme(), nil 21 | default: 22 | return nil, errors.New("invalid_scheme", fmt.Sprintf("unknown signature scheme: %v", sigScheme)) 23 | } 24 | } 25 | 26 | // UnmarshalThresholdSignatureSchemes unmarshal SignatureScheme from json string 27 | func UnmarshalSignatureSchemes(sigScheme string, obj interface{}) ([]SignatureScheme, error) { 28 | switch sigScheme { 29 | case "bls0chain": 30 | 31 | if obj == nil { 32 | return nil, nil 33 | } 34 | 35 | buf, err := json.Marshal(obj) 36 | if err != nil { 37 | return nil, err 38 | } 39 | 40 | var list []*HerumiScheme 41 | 42 | if err := json.Unmarshal(buf, &list); err != nil { 43 | return nil, err 44 | } 45 | 46 | ss := make([]SignatureScheme, len(list)) 47 | 48 | for i, v := range list { 49 | // bls.ID from json 50 | err = v.SetID(v.Ids) 51 | if err != nil { 52 | return nil, err 53 | } 54 | ss[i] = v 55 | } 56 | 57 | return ss, nil 58 | 59 | default: 60 | return nil, errors.New("invalid_signature", fmt.Sprintf("unknown signature scheme: %v", sigScheme)) 61 | } 62 | } 63 | 64 | // GenerateThresholdKeyShares given a signature scheme will generate threshold sig keys 65 | func GenerateThresholdKeyShares(t, n int, originalKey SignatureScheme) ([]SignatureScheme, error) { 66 | b0ss, ok := originalKey.(*HerumiScheme) 67 | if !ok { 68 | return nil, errors.New("bls0_generate_threshold_key_shares", "Invalid encryption scheme") 69 | } 70 | 71 | b0original := BlsSignerInstance.NewSecretKey() 72 | b0PrivateKeyBytes, err := b0ss.GetPrivateKeyAsByteArray() 73 | if err != nil { 74 | return nil, err 75 | } 76 | 77 | err = b0original.SetLittleEndian(b0PrivateKeyBytes) 78 | if err != nil { 79 | return nil, err 80 | } 81 | 82 | polynomial, err := b0original.GetMasterSecretKey(t) 83 | if err != nil { 84 | return nil, err 85 | } 86 | 87 | var shares []SignatureScheme 88 | for i := 1; i <= n; i++ { 89 | id := BlsSignerInstance.NewID() 90 | err = id.SetDecString(fmt.Sprint(i)) 91 | if err != nil { 92 | return nil, err 93 | } 94 | 95 | sk := BlsSignerInstance.NewSecretKey() 96 | err = sk.Set(polynomial, id) 97 | if err != nil { 98 | return nil, err 99 | } 100 | 101 | share := &HerumiScheme{} 102 | share.PrivateKey = hex.EncodeToString(sk.GetLittleEndian()) 103 | share.PublicKey = sk.GetPublicKey().SerializeToHexStr() 104 | 105 | share.id = id 106 | share.Ids = id.GetHexString() 107 | 108 | shares = append(shares, share) 109 | } 110 | 111 | return shares, nil 112 | } 113 | -------------------------------------------------------------------------------- /internal/api/util/crypto/signature_scheme.go: -------------------------------------------------------------------------------- 1 | package crypto 2 | 3 | import ( 4 | "encoding/json" 5 | 6 | "github.com/0chain/errors" 7 | "github.com/0chain/gosdk/core/encryption" 8 | bip39 "github.com/tyler-smith/go-bip39" 9 | ) 10 | 11 | const CryptoVersion = "1.0" 12 | 13 | // KeyPair private and publickey 14 | type KeyPair struct { 15 | PublicKey string `json:"public_key"` 16 | PrivateKey string `json:"private_key"` 17 | } 18 | 19 | // Wallet structure 20 | type Wallet struct { 21 | ClientID string `json:"client_id"` 22 | ClientKey string `json:"client_key"` 23 | Keys []KeyPair `json:"keys"` 24 | Mnemonic string `json:"mnemonics"` 25 | Version string `json:"version"` 26 | DateCreated string `json:"date_created"` 27 | Nonce int64 `json:"nonce"` 28 | } 29 | 30 | // SignatureScheme - an encryption scheme for signing and verifying messages 31 | type SignatureScheme interface { 32 | // Generate fresh keys 33 | GenerateKeys() (*Wallet, error) 34 | // Generate fresh keys based on eth wallet 35 | GenerateKeysWithEth(mnemonic, password string) (*Wallet, error) 36 | 37 | // Generate keys from mnemonic for recovery 38 | RecoverKeys(mnemonic string) (*Wallet, error) 39 | GetMnemonic() string 40 | 41 | // Signing - Set private key to sign 42 | SetPrivateKey(privateKey string) error 43 | Sign(hash string) (string, error) 44 | 45 | // Signature verification - Set public key to verify 46 | SetPublicKey(publicKey string) error 47 | GetPublicKey() string 48 | GetPrivateKey() string 49 | Verify(signature string, msg string) (bool, error) 50 | 51 | // Combine signature for schemes BLS 52 | Add(signature, msg string) (string, error) 53 | 54 | // implement SplitSignatureScheme 55 | 56 | SplitKeys(numSplits int) (*Wallet, error) 57 | 58 | GetPrivateKeyAsByteArray() ([]byte, error) 59 | 60 | // // implement ThresholdSignatureScheme 61 | 62 | SetID(id string) error 63 | GetID() string 64 | } 65 | 66 | // Marshal returns json string 67 | func (w *Wallet) Marshal() (string, error) { 68 | ws, err := json.Marshal(w) 69 | if err != nil { 70 | return "", errors.New("wallet_marshal", "Invalid Wallet") 71 | } 72 | return string(ws), nil 73 | } 74 | 75 | func (w *Wallet) Sign(hash, scheme string) (string, error) { 76 | sigScheme, err := NewSignatureScheme(scheme) 77 | if err != nil { 78 | return "", err 79 | } 80 | err = sigScheme.SetPrivateKey(w.Keys[0].PrivateKey) 81 | if err != nil { 82 | return "", err 83 | } 84 | return sigScheme.Sign(hash) 85 | } 86 | 87 | func IsMnemonicValid(mnemonic string) bool { 88 | return bip39.IsMnemonicValid(mnemonic) 89 | } 90 | 91 | func Sha3Sum256(data string) string { 92 | return encryption.Hash(data) 93 | } 94 | -------------------------------------------------------------------------------- /internal/api/util/endpoint/constants.go: -------------------------------------------------------------------------------- 1 | package endpoint 2 | 3 | // Statuses of http based responses 4 | const ( 5 | HttpOkStatus = "200 OK" 6 | HttpNotFoundStatus = "400 Bad Request" 7 | ) 8 | 9 | // Addresses of SC 10 | const ( 11 | FaucetSmartContractAddress = "6dba10422e368813802877a85039d3985d96760ed844092319743fb3a76712d3" 12 | StorageSmartContractAddress = "6dba10422e368813802877a85039d3985d96760ed844092319743fb3a76712d7" 13 | ) 14 | 15 | // Statuses of transactions 16 | const ( 17 | TxSuccessfulStatus = iota + 1 18 | TxUnsuccessfulStatus 19 | ) 20 | -------------------------------------------------------------------------------- /internal/api/util/tenderly/errors.go: -------------------------------------------------------------------------------- 1 | package tenderly 2 | 3 | import "errors" 4 | 5 | var ( 6 | ErrConversion = errors.New("error happened during the conversion of response") 7 | ) 8 | -------------------------------------------------------------------------------- /internal/api/util/tenderly/tenderly.go: -------------------------------------------------------------------------------- 1 | // nolint:typecheck 2 | package tenderly 3 | 4 | import ( 5 | "context" 6 | "errors" 7 | 8 | "github.com/ybbus/jsonrpc/v3" 9 | ) 10 | 11 | const InitialBalance = "0x56BC75E2D63100000" // 100 ethers in hex 12 | 13 | // Client represents Ethereum client, which uses Tenderly fork node to perform snapshots and revert changes using requests 14 | // to EVM. 15 | type Client struct { 16 | client jsonrpc.RPCClient 17 | } 18 | 19 | func NewClient(tenderlyNodeURL string) *Client { 20 | client := jsonrpc.NewClient(tenderlyNodeURL) 21 | return &Client{ 22 | client: client, 23 | } 24 | } 25 | 26 | // InitBalance sets pre-defined initial balance for the given ethereum address 27 | func (c *Client) InitBalance(ethereumAddress string) error { 28 | resp, err := c.client.Call(context.Background(), "tenderly_setBalance", []string{ethereumAddress}, InitialBalance) 29 | if err != nil { 30 | return err 31 | } 32 | if resp.Error != nil { 33 | return errors.New(resp.Error.Error()) 34 | } 35 | return nil 36 | } 37 | 38 | // InitErc20Balance sets pre-defined initial balance for the given erc20 token address 39 | func (c *Client) InitErc20Balance(tokenAddress, ethereumAddress string) error { 40 | resp, err := c.client.Call(context.Background(), "tenderly_setErc20Balance", tokenAddress, []string{ethereumAddress}, InitialBalance) 41 | if err != nil { 42 | return err 43 | } 44 | if resp.Error != nil { 45 | return errors.New(resp.Error.Error()) 46 | } 47 | return nil 48 | } 49 | -------------------------------------------------------------------------------- /internal/api/util/tokenomics/units.go: -------------------------------------------------------------------------------- 1 | package tokenomics 2 | 3 | const tokenUnit = 1e+10 4 | 5 | func IntToZCN(num float64) *int64 { 6 | result := int64(num * tokenUnit) 7 | return &result 8 | } 9 | 10 | func ZcnToInt(num float64) int64 { 11 | return int64(num / tokenUnit) 12 | } 13 | -------------------------------------------------------------------------------- /internal/api/util/wait/wait.go: -------------------------------------------------------------------------------- 1 | package wait 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/0chain/system_test/internal/api/util/test" 7 | ) 8 | 9 | // PoolImmediately pools passed function for a certain amount of time 10 | func PoolImmediately(t *test.SystemTest, duration time.Duration, predicate func() bool) { 11 | backoffPeriod := time.Second * 2 12 | ticker := time.NewTicker(backoffPeriod) 13 | 14 | defer ticker.Stop() 15 | 16 | after := time.After(duration) 17 | 18 | for range ticker.C { 19 | select { 20 | case <-after: 21 | t.Fatal("Timed out waiting for wait condition to pass") 22 | default: 23 | if predicate() { 24 | t.Log("Wait condition has succeed") 25 | return 26 | } 27 | t.Logf("Wait condition failed. Waiting an additional [%v]...", backoffPeriod) 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /internal/cli/util/api_get_list.go: -------------------------------------------------------------------------------- 1 | package cliutils 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "io" 7 | "net/http" 8 | "strconv" 9 | 10 | "github.com/0chain/system_test/internal/api/util/test" 11 | "github.com/stretchr/testify/assert" 12 | "github.com/stretchr/testify/require" 13 | ) 14 | 15 | func ApiGetRetries[T any](t *test.SystemTest, url string, params map[string]string, retries int) *T { 16 | var err error 17 | var res *T 18 | for try := 1; try <= retries; try++ { 19 | res, err = ApiGetError[T](url, params) 20 | if err != nil { 21 | t.Logf("retry %d, %v", try, err) 22 | } else { 23 | break 24 | } 25 | } 26 | assert.NoError(t, err, "%s failed after %d retries", url, retries) 27 | 28 | return res 29 | } 30 | 31 | func ApiGetError[T any](url string, params map[string]string) (*T, error) { 32 | url = addParms(url, params) 33 | 34 | res, err := http.Get(url) //nolint:gosec 35 | if err != nil { 36 | return nil, fmt.Errorf("with request %s, %v", url, err) 37 | } 38 | 39 | defer res.Body.Close() 40 | if res.StatusCode < 200 && res.StatusCode >= 300 { 41 | return nil, fmt.Errorf("failed API request %s, status code: %d: %v", url, res.StatusCode, err) 42 | } 43 | if res.Body == nil { 44 | return nil, fmt.Errorf("request %s, API response must not be nil", url) 45 | } 46 | resBody, err := io.ReadAll(res.Body) 47 | if err != nil { 48 | return nil, fmt.Errorf("response %s, reading response body: %v", url, err) 49 | } 50 | 51 | var result = new(T) 52 | err = json.Unmarshal(resBody, &result) 53 | if err != nil { 54 | return nil, fmt.Errorf("deserializing JSON string `%s`: %v", string(resBody), err) 55 | } 56 | return result, nil 57 | } 58 | 59 | func ApiGet[T any](t *test.SystemTest, url string, params map[string]string) *T { 60 | url = addParms(url, params) 61 | 62 | res, err := http.Get(url) //nolint:gosec 63 | 64 | require.NoError(t, err, "with request", url) 65 | defer res.Body.Close() 66 | require.True(t, res.StatusCode >= 200 && res.StatusCode < 300, 67 | "failed API request %s, status code: %d", url, res.StatusCode) 68 | require.NotNil(t, res.Body, "API response must not be nil") 69 | 70 | resBody, err := io.ReadAll(res.Body) 71 | require.NoError(t, err, "reading response body: %v", err) 72 | 73 | var result = new(T) 74 | err = json.Unmarshal(resBody, &result) 75 | require.NoError(t, err, "deserializing JSON string `%s`: %v", string(resBody), err) 76 | return result 77 | } 78 | 79 | func ApiGetList[T any](t *test.SystemTest, url string, params map[string]string, from, to int64) []T { 80 | var out []T 81 | var offset int64 82 | for { 83 | var temp []T 84 | raw := getNext(t, url, from, to, MaxQueryLimit, offset, params) 85 | 86 | err := json.Unmarshal(raw, &temp) 87 | assert.NoError(t, err, "deserializing JSON string `%s`: %v", string(raw), err) 88 | out = append(out, temp...) 89 | if len(temp) < MaxQueryLimit { 90 | return out 91 | } 92 | 93 | offset += int64(len(temp)) 94 | } 95 | } 96 | 97 | func getNext(t *test.SystemTest, url string, from, to, limit, offset int64, params map[string]string) []byte { 98 | params["start"] = strconv.FormatInt(from, 10) 99 | params["end"] = strconv.FormatInt(to, 10) 100 | if limit > 0 { 101 | params["limit"] = strconv.FormatInt(limit, 10) 102 | } 103 | if offset > 0 { 104 | params["offset"] = strconv.FormatInt(offset, 10) 105 | } 106 | url = addParms(url, params) 107 | res, err := http.Get(url) //nolint:gosec 108 | 109 | require.NoError(t, err, "retrieving blocks %d to %d", from, to) 110 | defer res.Body.Close() 111 | require.True(t, res.StatusCode >= 200 && res.StatusCode < 300, 112 | "failed API request to get blocks %d to %d, status code: %d", from, to, res.StatusCode) 113 | require.NotNil(t, res.Body, "balance API response must not be nil") 114 | 115 | resBody, err := io.ReadAll(res.Body) 116 | require.NoError(t, err, "reading response body: %v", err) 117 | return resBody 118 | } 119 | 120 | func addParms(url string, params map[string]string) string { 121 | first := true 122 | for key, value := range params { 123 | if first { 124 | url += "?" 125 | first = false 126 | } else { 127 | url += "&" 128 | } 129 | url += key + "=" + value 130 | } 131 | return url 132 | } 133 | -------------------------------------------------------------------------------- /internal/cli/util/specific/posix_utils.go: -------------------------------------------------------------------------------- 1 | //go:build !windows 2 | // +build !windows 3 | 4 | package specific 5 | 6 | import ( 7 | "os/exec" 8 | "syscall" 9 | ) 10 | 11 | func Setpgid(cmd *exec.Cmd) { 12 | cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} 13 | } 14 | -------------------------------------------------------------------------------- /internal/cli/util/specific/win_utils.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | // +build windows 3 | 4 | package specific 5 | 6 | import ( 7 | "os/exec" 8 | "syscall" 9 | ) 10 | 11 | func Setpgid(cmd *exec.Cmd) { 12 | cmd.SysProcAttr = &syscall.SysProcAttr{CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP} 13 | } 14 | -------------------------------------------------------------------------------- /internal/dummy_file/five_MB_test_file_dowloaded: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0chain/system_test/706c66fc3ed6295296ac31adf0e1ff1a118ec8ec/internal/dummy_file/five_MB_test_file_dowloaded -------------------------------------------------------------------------------- /internal/tokenomics/util/config/config.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "log" 5 | "os" 6 | 7 | "gopkg.in/yaml.v3" //nolint 8 | ) 9 | 10 | // ConfigPathEnv contains name of env variable 11 | const ConfigPathEnv = "CONFIG_PATH" 12 | 13 | // DefaultConfigPath contains default value of ConfigPathEnv 14 | const DefaultConfigPath = "./config/tokenomics_tests_config.yaml" 15 | 16 | type Config struct { 17 | BlockWorker string `yaml:"block_worker"` 18 | ZboxUrl string `yaml:"0box_url"` 19 | ZboxPhoneNumber string `yaml:"0box_phone_number"` 20 | DefaultTestCaseTimeout string `yaml:"default_test_case_timeout"` 21 | ZS3ServerUrl string `yaml:"zs3_server_url"` 22 | ChimneyTestNetwork string `yaml:"chimney_test_network"` 23 | } 24 | 25 | func Parse(configPath string) *Config { 26 | var result *Config 27 | 28 | file, err := os.ReadFile(configPath) 29 | if err != nil { 30 | log.Fatalln("Failed to read config file! due to error: " + err.Error()) 31 | } 32 | err = yaml.Unmarshal(file, &result) //nolint 33 | if err != nil { 34 | log.Fatalln("failed to deserialise config file due to error: " + err.Error()) 35 | } 36 | 37 | return result 38 | } 39 | -------------------------------------------------------------------------------- /test-file: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0chain/system_test/706c66fc3ed6295296ac31adf0e1ff1a118ec8ec/test-file -------------------------------------------------------------------------------- /tests/api_tests/0box_dex_test.go: -------------------------------------------------------------------------------- 1 | package api_tests 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/0chain/system_test/internal/api/util/client" 7 | 8 | "github.com/0chain/system_test/internal/api/util/test" 9 | "github.com/stretchr/testify/require" 10 | ) 11 | 12 | func NewTestDex() map[string]string { 13 | return map[string]string{ 14 | "tx_hash": "165f0f8e557c430929784035df7eeacf7a3ff795f10d76c8707409bba31cb617", 15 | "stage": "mint", 16 | "reference": "test_reference", 17 | } 18 | } 19 | 20 | func Test0BoxDex(testSetup *testing.T) { 21 | t := test.NewSystemTest(testSetup) 22 | 23 | t.RunSequentially("Create dex should work", func(t *test.SystemTest) { 24 | headers := zboxClient.NewZboxHeaders(client.X_APP_BLIMP) 25 | Teardown(t, headers) 26 | 27 | err := Create0boxTestWallet(t, headers) 28 | require.NoError(t, err) 29 | 30 | dexData := NewTestDex() 31 | 32 | _, response, err := zboxClient.CreateDexState(t, headers, dexData) 33 | require.NoError(t, err) 34 | require.Equal(t, 201, response.StatusCode(), "Response status code does not match expected. Output: [%v]", response.String()) 35 | 36 | dex, response, err := zboxClient.GetDexState(t, headers) 37 | require.NoError(t, err) 38 | require.Equal(t, 200, response.StatusCode(), "Response status code does not match expected. Output: [%v]", response.String()) 39 | require.Equal(t, "mint", dex.Stage) 40 | }) 41 | 42 | t.RunSequentially("Update dex should work", func(t *test.SystemTest) { 43 | headers := zboxClient.NewZboxHeaders(client.X_APP_BLIMP) 44 | Teardown(t, headers) 45 | 46 | err := Create0boxTestWallet(t, headers) 47 | require.NoError(t, err) 48 | 49 | dexData := NewTestDex() 50 | 51 | _, response, err := zboxClient.CreateDexState(t, headers, dexData) 52 | require.NoError(t, err) 53 | require.Equal(t, 201, response.StatusCode(), "Response status code does not match expected. Output: [%v]", response.String()) 54 | 55 | dexData["stage"] = "burn" 56 | _, response, err = zboxClient.UpdateDexState(t, headers, dexData) 57 | require.NoError(t, err) 58 | require.Equal(t, 200, response.StatusCode(), "Response status code does not match expected. Output: [%v]", response.String()) 59 | 60 | dex, response, err := zboxClient.GetDexState(t, headers) 61 | require.NoError(t, err) 62 | require.Equal(t, 200, response.StatusCode(), "Response status code does not match expected. Output: [%v]", response.String()) 63 | require.Equal(t, "burn", dex.Stage) 64 | }) 65 | } 66 | -------------------------------------------------------------------------------- /tests/api_tests/0box_free_storage_test.go: -------------------------------------------------------------------------------- 1 | package api_tests 2 | 3 | import ( 4 | "encoding/base64" 5 | "encoding/json" 6 | "testing" 7 | "time" 8 | 9 | "github.com/0chain/system_test/internal/api/util/client" 10 | 11 | "github.com/0chain/system_test/internal/api/model" 12 | "gopkg.in/errgo.v2/errors" 13 | 14 | "github.com/0chain/system_test/internal/api/util/test" 15 | "github.com/stretchr/testify/require" 16 | ) 17 | 18 | func Test0BoxFreeStorage(testSetup *testing.T) { 19 | t := test.NewSystemTest(testSetup) 20 | t.Parallel() 21 | t.SetSmokeTests("List allocation with zero allocation should work") 22 | 23 | t.RunSequentiallyWithTimeout("Create FreeStorage should work", 3*time.Minute, func(t *test.SystemTest) { 24 | headers := zboxClient.NewZboxHeaders(client.X_APP_BLIMP) 25 | Teardown(t, headers) 26 | 27 | err := Create0boxTestWallet(t, headers) 28 | require.NoError(t, err) 29 | 30 | storageMarker, response, err := zboxClient.CreateFreeStorage(t, headers) 31 | require.NoError(t, err) 32 | require.Equal(t, 200, response.StatusCode(), "Response status code does not match expected. Output: [%v]", response.String()) 33 | 34 | marker, markerResponse, err := UnmarshalMarkerData(storageMarker) 35 | require.Nil(t, err) 36 | require.Equal(t, headers["X-App-Client-ID"], marker.Recipient) 37 | require.Equal(t, marker.Assigner, "0chain") 38 | require.Equal(t, markerResponse.RecipientPublicKey, headers["X-App-Client-Key"]) 39 | require.Positive(t, marker.FreeTokens) 40 | }) 41 | 42 | t.RunSequentially("Create FreeStorage without existing wallet should not work", func(t *test.SystemTest) { 43 | headers := zboxClient.NewZboxHeaders(client.X_APP_BLIMP) 44 | Teardown(t, headers) 45 | 46 | _, response, err := zboxClient.CreateFreeStorage(t, headers) 47 | require.NoError(t, err) 48 | require.Equal(t, 400, response.StatusCode(), "Response status code does not match expected. Output: [%v]", response.String()) 49 | }) 50 | } 51 | 52 | func UnmarshalMarkerData(storage *model.ZboxFreeStorage) (model.ZboxFreeStorageMarker, model.ZboxFreeStorageMarkerResponse, error) { 53 | decodedBytes, err := base64.StdEncoding.DecodeString(storage.Marker) 54 | if err != nil { 55 | return model.ZboxFreeStorageMarker{}, model.ZboxFreeStorageMarkerResponse{}, errors.New("error decode free storage response") 56 | } 57 | 58 | decodedString := string(decodedBytes) 59 | var markerResponse model.ZboxFreeStorageMarkerResponse 60 | err = json.Unmarshal([]byte(decodedString), &markerResponse) 61 | if err != nil { 62 | return model.ZboxFreeStorageMarker{}, model.ZboxFreeStorageMarkerResponse{}, errors.New("error unmarshaling storage response") 63 | } 64 | 65 | decodedBytes, err = base64.StdEncoding.DecodeString(markerResponse.Marker) 66 | if err != nil { 67 | return model.ZboxFreeStorageMarker{}, model.ZboxFreeStorageMarkerResponse{}, errors.New("error decoding marker") 68 | } 69 | decodedString = string(decodedBytes) // nolint 70 | var marker model.ZboxFreeStorageMarker 71 | err = json.Unmarshal([]byte(decodedString), &marker) 72 | if err != nil { 73 | return model.ZboxFreeStorageMarker{}, model.ZboxFreeStorageMarkerResponse{}, errors.New("error unmarshling marker") 74 | } 75 | return marker, markerResponse, nil 76 | } 77 | -------------------------------------------------------------------------------- /tests/api_tests/0box_jwt_test.go: -------------------------------------------------------------------------------- 1 | package api_tests 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/0chain/system_test/internal/api/util/client" 7 | "github.com/0chain/system_test/internal/api/util/test" 8 | "github.com/stretchr/testify/require" 9 | ) 10 | 11 | func Test0BoxJWT(testSetup *testing.T) { 12 | t := test.NewSystemTest(testSetup) 13 | 14 | t.RunSequentially("Create JWT token", func(t *test.SystemTest) { 15 | headers := zboxClient.NewZboxHeaders(client.X_APP_BLIMP) 16 | Teardown(t, headers) 17 | 18 | _, response, err := zboxClient.CreateJwtToken(t, headers) 19 | require.NoError(t, err) 20 | require.Equal(t, 200, response.StatusCode(), "Response status code does not match expected. Output: [%v]", response.String()) 21 | }) 22 | 23 | t.RunSequentially("Refresh JWT token with user id, which differs from the one used by the given old JWT token", func(t *test.SystemTest) { 24 | headers := zboxClient.NewZboxHeaders(client.X_APP_BLIMP) 25 | Teardown(t, headers) 26 | 27 | jwtToken, response, err := zboxClient.CreateJwtToken(t, headers) 28 | require.NoError(t, err) 29 | require.Equal(t, 200, response.StatusCode(), "Response status code does not match expected. Output: [%v]", response.String()) 30 | require.NotEmpty(t, jwtToken.JwtToken) 31 | 32 | headers["X-App-Client-ID"] = client.X_APP_CLIENT_ID_A 33 | headers["X-App-User-ID"] = client.X_APP_USER_ID_A 34 | headers["X-App-Client-Key"] = client.X_APP_CLIENT_KEY_A 35 | headers["X-App-Client-Signature"] = client.X_APP_CLIENT_SIGNATURE_A 36 | 37 | _, response, err = zboxClient.RefreshJwtToken(t, jwtToken.JwtToken, headers) 38 | require.NoError(t, err) 39 | require.Equal(t, 400, response.StatusCode(), "Response status code does not match expected. Output: [%v]", response.String()) 40 | }) 41 | 42 | t.RunSequentially("Refresh JWT token with incorrect old JWT token", func(t *test.SystemTest) { 43 | headers := zboxClient.NewZboxHeaders(client.X_APP_BLIMP) 44 | Teardown(t, headers) 45 | 46 | jwtToken, response, err := zboxClient.CreateJwtToken(t, headers) 47 | require.NoError(t, err) 48 | require.Equal(t, 200, response.StatusCode(), "Response status code does not match expected. Output: [%v]", response.String()) 49 | require.NotEmpty(t, jwtToken.JwtToken) 50 | 51 | _, response, err = zboxClient.RefreshJwtToken(t, "", headers) 52 | require.NoError(t, err) 53 | require.Equal(t, 500, response.StatusCode(), "Response status code does not match expected. Output: [%v]", response.String()) 54 | }) 55 | 56 | t.RunSequentially("Refresh JWT token with user id, which equals to the one used by the given old JWT token", func(t *test.SystemTest) { 57 | headers := zboxClient.NewZboxHeaders(client.X_APP_BLIMP) 58 | Teardown(t, headers) 59 | 60 | jwtToken, response, err := zboxClient.CreateJwtToken(t, headers) 61 | require.NoError(t, err) 62 | require.Equal(t, 200, response.StatusCode(), "Response status code does not match expected. Output: [%v]", response.String()) 63 | require.NotEmpty(t, jwtToken.JwtToken) 64 | 65 | jwtToken, response, err = zboxClient.RefreshJwtToken(t, jwtToken.JwtToken, headers) 66 | require.NoError(t, err) 67 | require.Equal(t, 200, response.StatusCode(), "Response status code does not match expected. Output: [%v]", response.String()) 68 | require.NotEmpty(t, jwtToken.JwtToken) 69 | }) 70 | } 71 | -------------------------------------------------------------------------------- /tests/api_tests/0box_owner_test.go: -------------------------------------------------------------------------------- 1 | package api_tests 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/0chain/system_test/internal/api/util/client" 7 | "github.com/0chain/system_test/internal/api/util/test" 8 | "github.com/stretchr/testify/require" 9 | ) 10 | 11 | func Teardown(t *test.SystemTest, headers map[string]string) { 12 | t.Logf("Tearing down existing data") 13 | message, response, err := zboxClient.DeleteOwner(t, headers) 14 | println(message, response, err) 15 | } 16 | 17 | func NewTestOwner() map[string]string { 18 | return map[string]string{ 19 | "username": "test_owner_1", 20 | "email": "test_email_1", 21 | "phone_number": "+919876543210", 22 | } 23 | } 24 | 25 | func NewVerifyOtpDetails() map[string]string { 26 | return map[string]string{ 27 | "username": "test_owner_1", 28 | "email": "test_email_1", 29 | "phone_number": "+919876543210", 30 | "otp": "123456", 31 | "firebase_token": "test_firebase_token", 32 | "user_id": client.X_APP_USER_ID, 33 | } 34 | } 35 | 36 | func Test0BoxOwner(testSetup *testing.T) { 37 | t := test.NewSystemTest(testSetup) 38 | 39 | t.RunSequentially("create owner without existing userID should work", func(t *test.SystemTest) { 40 | headers := zboxClient.NewZboxHeaders(client.X_APP_BLIMP) 41 | Teardown(t, headers) 42 | 43 | verifyOtpInput := NewVerifyOtpDetails() 44 | _, response, err := zboxClient.VerifyOtpDetails(t, headers, verifyOtpInput) 45 | require.NoError(t, err) 46 | require.Equal(t, 200, response.StatusCode(), "Response status code does not match expected. Output: [%v]", response.String()) 47 | 48 | owner, response, err := zboxClient.GetOwner(t, headers) 49 | require.NoError(t, err) 50 | require.Equal(t, 200, response.StatusCode(), "Response status code does not match expected. Output: [%v]", response.String()) 51 | require.Equal(t, verifyOtpInput["username"], owner.UserName) 52 | require.Equal(t, verifyOtpInput["email"], owner.Email) 53 | require.Equal(t, verifyOtpInput["phone_number"], owner.PhoneNumber) 54 | }) 55 | 56 | t.RunSequentially("create owner with existing userID should not work", func(t *test.SystemTest) { 57 | headers := zboxClient.NewZboxHeaders(client.X_APP_BLIMP) 58 | Teardown(t, headers) 59 | 60 | verifyOtpInput := NewVerifyOtpDetails() 61 | _, _, err := zboxClient.VerifyOtpDetails(t, headers, verifyOtpInput) 62 | require.NoError(t, err) 63 | 64 | _, response, err := zboxClient.VerifyOtpDetails(t, headers, verifyOtpInput) 65 | require.NoError(t, err) 66 | require.Equal(t, 400, response.StatusCode(), "Response status code does not match expected. Output: [%v]", response.String()) 67 | }) 68 | 69 | t.RunSequentially("update owner with existing owner should work", func(t *test.SystemTest) { 70 | headers := zboxClient.NewZboxHeaders(client.X_APP_BLIMP) 71 | Teardown(t, headers) 72 | 73 | verifyOtpInput := NewVerifyOtpDetails() 74 | _, _, err := zboxClient.VerifyOtpDetails(t, headers, verifyOtpInput) 75 | require.NoError(t, err) 76 | 77 | ownerInput := NewTestOwner() 78 | ownerInput["username"] = "new_user_name" 79 | ownerInput["biography"] = "new_biography" 80 | message, _, err := zboxClient.UpdateOwner(t, headers, ownerInput) 81 | require.NoError(t, err) 82 | require.Equal(t, "updated owner details successfully", message.Message) 83 | 84 | owner, response, err := zboxClient.GetOwner(t, headers) 85 | require.NoError(t, err) 86 | require.Equal(t, 200, response.StatusCode(), "Response status code does not match expected. Output: [%v]", response.String()) 87 | require.Equal(t, ownerInput["username"], owner.UserName) 88 | require.Equal(t, ownerInput["email"], owner.Email) 89 | require.Equal(t, ownerInput["phone_number"], owner.PhoneNumber) 90 | require.Equal(t, ownerInput["biography"], owner.Biography) 91 | }) 92 | 93 | t.RunSequentially("update owner without existing owner should not work", func(t *test.SystemTest) { 94 | headers := zboxClient.NewZboxHeaders(client.X_APP_BLIMP) 95 | Teardown(t, headers) 96 | 97 | ownerInput := NewTestOwner() 98 | message, _, err := zboxClient.UpdateOwner(t, headers, ownerInput) 99 | require.NoError(t, err) 100 | require.Equal(t, "No Data was updated", message.Message) 101 | }) 102 | } 103 | -------------------------------------------------------------------------------- /tests/api_tests/0box_shareinfo_test.go: -------------------------------------------------------------------------------- 1 | package api_tests 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/0chain/system_test/internal/api/util/client" 7 | 8 | "github.com/0chain/system_test/internal/api/util/test" 9 | "github.com/stretchr/testify/require" 10 | ) 11 | 12 | func NewTestShareinfo() map[string]string { 13 | return map[string]string{ 14 | "auth_ticket": "eyJjbGllbnRfaWQiOiIiLCJvd25lcl9pZCI6ImNhYWU1YTlkNDhiMWEwY2QwMWE1ZGE5ODI4MDdkN2FkNmZjYzhhODM2N2I3OWM2YWRiZTQ4ZTdjNjMyNTQ0ZjIiLCJhbGxvY2F0aW9uX2lkIjoiZTBjMmNkMmQ1ZmFhYWQxM2ZjNTM3MzNkZDc1OTc0OWYyYjJmMDFhZjQ2MzMyMDA5YzY3ODIyMWEyYzQ4ODE1MyIsImZpbGVfcGF0aF9oYXNoIjoiZTcyNGEyMjAxZTIyNjUzZDMyMTY3ZmNhMWJmMTJiMmU0NGJhYzYzMzdkM2ViZGI3NDI3ZmJhNGVlY2" + 15 | "FhNGM5ZCIsImFjdHVhbF9maWxlX2hhc2giOiIxZjExMjA4M2YyNDA1YzM5NWRlNTFiN2YxM2Y5Zjc5NWFhMTQxYzQwZjFkNDdkNzhjODNhNDk5MzBmMmI5YTM0IiwiZmlsZV9uYW1lIjoiSU1HXzQ4NzQuUE5HIiwicmVmZXJlbmNlX3R5cGUiOiJmIiwiZXhwaXJhdGlvbiI6MCwidGltZXN0YW1wIjoxNjY3MjE4MjcwLCJlbmNyeXB0ZWQiOmZhbHNlLCJzaWduYXR1cmUiOiIzMzllNTUyOTliNDhlMjI5ZGRlOTAyZjhjOTY1ZDE1YTk0MGIyNzc3YzVkOTMyN2E0Yzc5MTMxYjhhNzcxZTA3In0=", 16 | } 17 | } 18 | 19 | func Test0BoxShareinfo(testSetup *testing.T) { 20 | t := test.NewSystemTest(testSetup) 21 | 22 | t.RunSequentially("Create shareinfo valid auth ticket should work", func(t *test.SystemTest) { 23 | headers := zboxClient.NewZboxHeaders(client.X_APP_BLIMP) 24 | Teardown(t, headers) 25 | 26 | err := Create0boxTestWallet(t, headers) 27 | require.NoError(t, err) 28 | 29 | shareinfoData := NewTestShareinfo() 30 | 31 | shareinfoResponse, response, err := zboxClient.CreateShareInfo(t, headers, shareinfoData) 32 | require.NoError(t, err) 33 | require.Equal(t, 201, response.StatusCode(), "Response status code does not match expected. Output: [%v]", response.String()) 34 | require.Equal(t, "shareinfo added successfully", shareinfoResponse.Message) 35 | 36 | _, _, err = zboxClient.DeleteShareinfo(t, headers, shareinfoData["auth_ticket"]) 37 | require.NoError(t, err) 38 | }) 39 | 40 | t.RunSequentially("Create shareinfo invalid auth ticket should not work", func(t *test.SystemTest) { 41 | headers := zboxClient.NewZboxHeaders(client.X_APP_BLIMP) 42 | Teardown(t, headers) 43 | 44 | err := Create0boxTestWallet(t, headers) 45 | require.NoError(t, err) 46 | 47 | shareinfoData := NewTestShareinfo() 48 | shareinfoData["auth_ticket"] = "invalid_ticket" 49 | 50 | _, response, err := zboxClient.CreateShareInfo(t, headers, shareinfoData) 51 | require.NoError(t, err) 52 | require.Equal(t, 400, response.StatusCode(), "Response status code does not match expected. Output: [%v]", response.String()) 53 | }) 54 | 55 | t.RunSequentially("get shareinfo valid auth ticket should work", func(t *test.SystemTest) { 56 | headers := zboxClient.NewZboxHeaders(client.X_APP_BLIMP) 57 | Teardown(t, headers) 58 | 59 | err := Create0boxTestWallet(t, headers) 60 | require.NoError(t, err) 61 | 62 | shareinfoData := NewTestShareinfo() 63 | 64 | _, response, err := zboxClient.CreateShareInfo(t, headers, shareinfoData) 65 | require.NoError(t, err) 66 | require.Equal(t, 201, response.StatusCode(), "Response status code does not match expected. Output: [%v]", response.String()) 67 | 68 | shareinfoSharedResponse, response, err := zboxClient.GetShareInfoShared(t, headers) 69 | require.NoError(t, err) 70 | require.Equal(t, 200, response.StatusCode(), "Response status code does not match expected. Output: [%v]", response.String()) 71 | require.Equal(t, 1, len(shareinfoSharedResponse.Data)) 72 | require.Equal(t, client.X_APP_CLIENT_ID, shareinfoSharedResponse.Data[0].Receiver) 73 | 74 | hareinfoReceivedResponse, response, err := zboxClient.GetShareInfoReceived(t, headers) 75 | require.NoError(t, err) 76 | require.Equal(t, 200, response.StatusCode(), "Response status code does not match expected. Output: [%v]", response.String()) 77 | require.Equal(t, 1, len(hareinfoReceivedResponse.Data)) 78 | require.Equal(t, client.X_APP_CLIENT_ID, hareinfoReceivedResponse.Data[0].ClientID) 79 | 80 | _, _, err = zboxClient.DeleteShareinfo(t, headers, shareinfoData["auth_ticket"]) 81 | require.NoError(t, err) 82 | }) 83 | } 84 | -------------------------------------------------------------------------------- /tests/api_tests/config/api_tests_config.yaml: -------------------------------------------------------------------------------- 1 | block_worker: https://dev-st.devnet-0chain.net/dns 2 | 0box_url: http://0box.dev-st.devnet-0chain.net 3 | 0box_phone_number: +917696229925 4 | zvault_url: http://zvault.dev-st.devnet-0chain.net 5 | zauth_url: http://zauth.dev-st.devnet-0chain.net 6 | default_test_case_timeout: 45s 7 | zs3_server_url: https://dev-st.devnet-0chain.net/zs3server/ 8 | chimney_test_network: https://dev-st.devnet-0chain.net/dns 9 | blobber_owner_wallet_mnemonics: "economy day fan flower between rebuild valid bid catch bargain vivid hybrid room permit check manage mean twelve damage summer close churn boat either" 10 | owner_wallet_mnemonics: "cactus panther essence ability copper fox wise actual need cousin boat uncover ride diamond group jacket anchor current float rely tragic omit child payment" 11 | ethereum_address: 0xD8c9156e782C68EE671C09b6b92de76C97948432 12 | -------------------------------------------------------------------------------- /tests/api_tests/config/sc_owner_wallet.json: -------------------------------------------------------------------------------- 1 | { 2 | "client_id": "1746b06bb09f55ee01b33b5e2e055d6cc7a900cb57c0a3a5eaabb8a0e7745802", 3 | "client_key": "7b630ba670dac2f22d43c2399b70eff378689a53ee03ea20957bb7e73df016200fea410ba5102558b0c39617e5afd2c1843b161a1dedec15e1ab40543a78a518", 4 | "keys": [ 5 | { 6 | "public_key": "7b630ba670dac2f22d43c2399b70eff378689a53ee03ea20957bb7e73df016200fea410ba5102558b0c39617e5afd2c1843b161a1dedec15e1ab40543a78a518", 7 | "private_key": "c06b6f6945ba02d5a3be86b8779deca63bb636ce7e46804a479c50e53c864915" 8 | } 9 | ], 10 | "mnemonics": "cactus panther essence ability copper fox wise actual need cousin boat uncover ride diamond group jacket anchor current float rely tragic omit child payment", 11 | "version": "1.0", 12 | "date_created": "2023-11-26T01:23:58Z" 13 | } -------------------------------------------------------------------------------- /tests/api_tests/create_allocation_test.go: -------------------------------------------------------------------------------- 1 | package api_tests 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/0chain/system_test/internal/api/util/test" 7 | 8 | "github.com/0chain/system_test/internal/api/model" 9 | 10 | "github.com/0chain/system_test/internal/api/util/client" 11 | ) 12 | 13 | func TestCreateAllocation(testSetup *testing.T) { 14 | t := test.NewSystemTest(testSetup) 15 | t.SetSmokeTests("Create allocation API call should be successful given a valid request") 16 | 17 | t.Parallel() 18 | 19 | t.Run("Create allocation API call should be successful given a valid request", func(t *test.SystemTest) { 20 | wallet := createWallet(t) 21 | 22 | blobberRequirements := model.DefaultBlobberRequirements(wallet.Id, wallet.PublicKey) 23 | allocationBlobbers := apiClient.GetAllocationBlobbers(t, wallet, &blobberRequirements, client.HttpOkStatus) 24 | allocationID := apiClient.CreateAllocation(t, wallet, allocationBlobbers, client.TxSuccessfulStatus) 25 | apiClient.GetAllocation(t, allocationID, client.HttpOkStatus) 26 | }) 27 | } 28 | -------------------------------------------------------------------------------- /tests/api_tests/flaky___broken_scenarios_test.go: -------------------------------------------------------------------------------- 1 | //nolint:gocritic 2 | //nolint:gocyclo 3 | package api_tests 4 | 5 | import ( 6 | "encoding/hex" 7 | 8 | "github.com/0chain/system_test/internal/api/util/test" 9 | 10 | "testing" 11 | 12 | "github.com/0chain/system_test/internal/api/model" 13 | "github.com/0chain/system_test/internal/api/util/client" 14 | "github.com/0chain/system_test/internal/api/util/crypto" 15 | "github.com/stretchr/testify/require" 16 | ) 17 | 18 | /* 19 | Tests in here are skipped until the feature has been fixed 20 | */ 21 | func Test___BrokenScenariosRegisterWallet(testSetup *testing.T) { 22 | t := test.NewSystemTest(testSetup) 23 | 24 | t.Skip() 25 | t.Parallel() 26 | 27 | t.Run("Register wallet API call should be successful, ignoring invalid creation date", func(t *test.SystemTest) { 28 | mnemonic := crypto.GenerateMnemonics(t) 29 | expectedKeyPair := crypto.GenerateKeys(t, mnemonic) 30 | publicKeyBytes, _ := hex.DecodeString(expectedKeyPair.PublicKey.SerializeToHexStr()) 31 | expectedClientId := crypto.Sha3256(publicKeyBytes) 32 | invalidCreationDate := -1 33 | 34 | walletRequest := model.Wallet{Id: expectedClientId, PublicKey: expectedKeyPair.PublicKey.SerializeToHexStr(), CreationDate: &invalidCreationDate} 35 | 36 | registeredWallet, httpResponse, err := apiClient.V1ClientPut(t, walletRequest, client.HttpOkStatus) 37 | 38 | require.Nil(t, err, "Unexpected error [%s] occurred creating wallet with http response [%s]", err, httpResponse) 39 | require.NotNil(t, registeredWallet, "Registered wallet was unexpectedly nil! with http response [%s]", httpResponse) 40 | require.Equal(t, "200 OK", httpResponse.Status()) 41 | require.Equal(t, registeredWallet.Id, expectedClientId) 42 | require.Equal(t, registeredWallet.PublicKey, expectedKeyPair.PublicKey) 43 | require.Greater(t, *registeredWallet.CreationDate, 0, "Creation date is an invalid value!") 44 | require.NotNil(t, registeredWallet.Version) 45 | }) 46 | 47 | t.Run("Register wallet API call should be unsuccessful given an invalid request - client id invalid", func(t *test.SystemTest) { 48 | mnemonic := crypto.GenerateMnemonics(t) 49 | expectedKeyPair := crypto.GenerateKeys(t, mnemonic) 50 | walletRequest := model.Wallet{Id: "invalid", PublicKey: expectedKeyPair.PublicKey.SerializeToHexStr()} 51 | 52 | walletResponse, httpResponse, err := apiClient.V1ClientPut(t, walletRequest, client.HttpBadRequestStatus) 53 | 54 | require.Nil(t, walletResponse, "Expected returned wallet to be nil but was [%s] with http response [%s]", walletResponse, httpResponse) 55 | require.NotNil(t, err, "Expected error when creating wallet but was nil.") 56 | require.Equal(t, "400 Bad Request", httpResponse.Status()) 57 | }) 58 | 59 | t.Run("Register wallet API call should be unsuccessful given an invalid request - public key invalid", func(t *test.SystemTest) { 60 | mnemonic := crypto.GenerateMnemonics(t) 61 | expectedKeyPair := crypto.GenerateKeys(t, mnemonic) 62 | publicKeyBytes, _ := hex.DecodeString(expectedKeyPair.PublicKey.SerializeToHexStr()) 63 | clientId := crypto.Sha3256(publicKeyBytes) 64 | walletRequest := model.Wallet{Id: clientId, PublicKey: "invalid"} 65 | 66 | walletResponse, httpResponse, err := apiClient.V1ClientPut(t, walletRequest, client.HttpBadRequestStatus) 67 | 68 | require.Nil(t, walletResponse, "Expected returned wallet to be nil but was [%s] with http response [%s]", walletResponse, httpResponse) 69 | require.NotNil(t, err, "Expected error when creating wallet but was nil.") 70 | require.Equal(t, "400 Bad Request", httpResponse.Status()) 71 | }) 72 | 73 | t.Run("Register wallet API call should be unsuccessful given an invalid request - empty json body", func(t *test.SystemTest) { 74 | walletRequest := model.Wallet{} 75 | walletResponse, httpResponse, err := apiClient.V1ClientPut(t, walletRequest, client.HttpBadRequestStatus) 76 | 77 | require.Nil(t, walletResponse, "Expected returned wallet to be nil but was [%s] with http response [%s]", walletResponse, httpResponse) 78 | require.NotNil(t, err, "Expected error when creating wallet but was nil.") 79 | require.Equal(t, "400 Bad Request", httpResponse.Status()) 80 | }) 81 | } 82 | -------------------------------------------------------------------------------- /tests/api_tests/get_blobbers_for_new_allocation_test.go: -------------------------------------------------------------------------------- 1 | package api_tests 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/0chain/system_test/internal/api/util/test" 7 | 8 | "github.com/0chain/system_test/internal/api/model" 9 | "github.com/0chain/system_test/internal/api/util/client" 10 | "github.com/stretchr/testify/require" 11 | ) 12 | 13 | func TestGetBlobbersForNewAllocation(testSetup *testing.T) { 14 | t := test.NewSystemTest(testSetup) 15 | t.SetSmokeTests("Alloc blobbers API call should be successful given a valid request") 16 | 17 | t.Parallel() 18 | 19 | t.Run("Alloc blobbers API call should be successful given a valid request", func(t *test.SystemTest) { 20 | wallet := createWallet(t) 21 | 22 | blobberRequirements := model.DefaultBlobberRequirements(wallet.Id, wallet.PublicKey) 23 | allocationBlobbers := apiClient.GetAllocationBlobbers(t, wallet, &blobberRequirements, client.HttpOkStatus) 24 | 25 | require.NotNil(t, allocationBlobbers.Blobbers) 26 | require.Greater(t, len(*allocationBlobbers.Blobbers), 3) 27 | require.NotNil(t, allocationBlobbers.BlobberRequirements) 28 | }) 29 | 30 | t.Run("BROKEN Alloc blobbers API call should fail gracefully given valid request but does not see 0chain/issues/1319", func(t *test.SystemTest) { 31 | wallet := createWallet(t) 32 | 33 | allocationBlobbers := apiClient.GetAllocationBlobbers(t, wallet, &model.BlobberRequirements{}, client.HttpBadRequestStatus) 34 | 35 | require.NotNil(t, allocationBlobbers.Blobbers) 36 | }) 37 | } 38 | -------------------------------------------------------------------------------- /tests/api_tests/get_latest_finalized_magic_block_test.go: -------------------------------------------------------------------------------- 1 | package api_tests 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "net/http" 7 | "testing" 8 | 9 | "github.com/0chain/system_test/internal/api/util/test" 10 | "github.com/stretchr/testify/require" 11 | ) 12 | 13 | func TestGetLatestFinalizedMagicBlock(testSetup *testing.T) { 14 | t := test.NewSystemTest(testSetup) 15 | t.SetSmokeTests("Lfmb node hash not modified, should return http 304 and empty body") 16 | 17 | t.Parallel() 18 | 19 | t.Run("Lfmb node hash not modified, should return http 304 and empty body", func(t *test.SystemTest) { 20 | hash, err := getCurrentHash(t) 21 | require.Nil(t, err) 22 | 23 | resp, err := apiClient.V1BlockGetLatestFinalizedMagicBlock(t, hash, http.StatusNotModified) 24 | require.Equal(t, resp.RawResponse.StatusCode, http.StatusNotModified) 25 | require.Nil(t, err, string(resp.Body())) 26 | 27 | require.Empty(t, string(resp.Body())) 28 | }) 29 | 30 | t.Run("No param provided, should return http 200 and current return whole lfmb message as before", func(t *test.SystemTest) { 31 | hash, err := getCurrentHash(t) 32 | require.Nil(t, err) 33 | 34 | resp, err := apiClient.V1BlockGetLatestFinalizedMagicBlock(t, "", http.StatusOK) 35 | require.Equal(t, resp.RawResponse.StatusCode, http.StatusOK) 36 | require.Nil(t, err, string(resp.Body())) 37 | require.NotEmpty(t, string(resp.Body())) 38 | 39 | var res map[string]interface{} 40 | err = json.Unmarshal(resp.Body(), &res) 41 | require.Nil(t, err, res) 42 | require.Equal(t, hash, res["hash"]) 43 | }) 44 | 45 | t.Run("Different node-lfmb-hash provided, return http 200 and return the lfmb the sharder has", func(t *test.SystemTest) { 46 | false_hash := "ed79cae70d439c11258236da1dfa6fc550f7cc569768304623e8fbd7d70efae5" 47 | 48 | resp, err := apiClient.V1BlockGetLatestFinalizedMagicBlock(t, false_hash, http.StatusOK) 49 | require.Equal(t, resp.RawResponse.StatusCode, http.StatusOK) 50 | require.Nil(t, err, string(resp.Body())) 51 | 52 | require.NotEmpty(t, string(resp.Body())) 53 | 54 | var res map[string]interface{} 55 | err = json.Unmarshal(resp.Body(), &res) 56 | require.Nil(t, err, res) 57 | require.NotEqual(t, false_hash, res["hash"]) 58 | }) 59 | } 60 | 61 | func getCurrentHash(t *test.SystemTest) (string, error) { 62 | resp, err := http.Get(apiClient.HealthyServiceProviders.Sharders[0] + "/v1/block/get/latest_finalized_magic_block") 63 | require.Nil(t, err) 64 | defer resp.Body.Close() 65 | 66 | var res map[string]interface{} 67 | decoder := json.NewDecoder(resp.Body) 68 | err = decoder.Decode(&res) 69 | require.Nil(t, err, res) 70 | 71 | resultHash := res["hash"] 72 | 73 | strHash := fmt.Sprintf("%s", resultHash) 74 | 75 | return strHash, nil 76 | } 77 | -------------------------------------------------------------------------------- /tests/api_tests/get_scstate_test.go: -------------------------------------------------------------------------------- 1 | package api_tests 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/0chain/system_test/internal/api/util/test" 7 | 8 | "github.com/0chain/system_test/internal/api/model" 9 | "github.com/0chain/system_test/internal/api/util/client" 10 | "github.com/stretchr/testify/require" 11 | ) 12 | 13 | func TestGetSCState(testSetup *testing.T) { 14 | t := test.NewSystemTest(testSetup) 15 | t.Skip() 16 | t.SetSmokeTests("Get SCState of faucet SC, should work") 17 | 18 | t.Parallel() 19 | 20 | t.Run("Get SCState of faucet SC, should work", func(t *test.SystemTest) { 21 | wallet := createWallet(t) 22 | 23 | scStateGetResponse, resp, err := apiClient.V1SharderGetSCState( 24 | t, 25 | model.SCStateGetRequest{ 26 | SCAddress: client.FaucetSmartContractAddress, 27 | Key: wallet.Id, 28 | }, 29 | client.HttpOkStatus) 30 | require.Nil(t, err) 31 | require.NotNil(t, resp) 32 | require.NotNil(t, scStateGetResponse) 33 | }) 34 | 35 | t.Run("Get SCState of faucet SC, shouldn't work", func(t *test.SystemTest) { 36 | wallet := createWallet(t) 37 | 38 | scStateGetResponse, resp, err := apiClient.V1SharderGetSCState( 39 | t, 40 | model.SCStateGetRequest{ 41 | SCAddress: client.FaucetSmartContractAddress, 42 | Key: wallet.Id, 43 | }, 44 | client.HttpBadRequestStatus) 45 | 46 | require.Nil(t, err) 47 | require.NotNil(t, resp) 48 | require.NotNil(t, scStateGetResponse) 49 | require.Equal(t, resp.StatusCode(), client.HttpBadRequestStatus) 50 | }) 51 | } 52 | -------------------------------------------------------------------------------- /tests/api_tests/get_scstats_test.go: -------------------------------------------------------------------------------- 1 | package api_tests 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/0chain/system_test/internal/api/util/test" 7 | 8 | "github.com/0chain/system_test/internal/api/util/client" 9 | "github.com/stretchr/testify/require" 10 | ) 11 | 12 | func TestGetSCStats(testSetup *testing.T) { 13 | t := test.NewSystemTest(testSetup) 14 | t.SetSmokeTests("Get miner stats call should return successfully") 15 | 16 | t.Parallel() 17 | 18 | t.Run("Get miner stats call should return successfully", func(t *test.SystemTest) { 19 | minerGetStatsResponse, resp, err := apiClient.V1MinerGetStats(t, client.HttpOkStatus) 20 | require.Nil(t, err) 21 | require.NotNil(t, resp) 22 | require.NotNil(t, minerGetStatsResponse) 23 | require.NotZero(t, minerGetStatsResponse.BlockFinality) 24 | require.NotZero(t, minerGetStatsResponse.LastFinalizedRound) 25 | require.NotZero(t, minerGetStatsResponse.BlocksFinalized) 26 | require.GreaterOrEqual(t, minerGetStatsResponse.StateHealth, int64(-1)) 27 | require.NotZero(t, minerGetStatsResponse.CurrentRound) 28 | require.GreaterOrEqual(t, minerGetStatsResponse.RoundTimeout, int64(0)) 29 | require.GreaterOrEqual(t, minerGetStatsResponse.Timeouts, int64(0)) 30 | require.NotZero(t, minerGetStatsResponse.AverageBlockSize) 31 | require.NotNil(t, minerGetStatsResponse.NetworkTime) 32 | }) 33 | 34 | t.Run("Get sharder stats call should return successfully", func(t *test.SystemTest) { 35 | sharderGetStatsResponse, resp, err := apiClient.V1SharderGetStats(t, client.HttpOkStatus) 36 | require.Nil(t, err) 37 | require.NotNil(t, resp) 38 | require.NotNil(t, sharderGetStatsResponse) 39 | require.NotZero(t, sharderGetStatsResponse.LastFinalizedRound) 40 | require.GreaterOrEqual(t, sharderGetStatsResponse.StateHealth, int64(-1)) 41 | require.NotZero(t, sharderGetStatsResponse.AverageBlockSize) 42 | require.GreaterOrEqual(t, sharderGetStatsResponse.PrevInvocationCount, uint64(0)) 43 | require.NotZero(t, sharderGetStatsResponse.PrevInvocationScanTime) 44 | require.GreaterOrEqual(t, sharderGetStatsResponse.MeanScanBlockStatsTime, float64(0)) 45 | }) 46 | } 47 | -------------------------------------------------------------------------------- /tests/api_tests/multi_download_test.go: -------------------------------------------------------------------------------- 1 | package api_tests 2 | 3 | import ( 4 | "os" 5 | "sync" 6 | "testing" 7 | 8 | "github.com/0chain/gosdk/zboxcore/sdk" 9 | "github.com/0chain/system_test/internal/api/model" 10 | "github.com/0chain/system_test/internal/api/util/client" 11 | "github.com/0chain/system_test/internal/api/util/test" 12 | "github.com/stretchr/testify/require" 13 | ) 14 | 15 | func TestMultiDownload(testSetup *testing.T) { 16 | t := test.NewSystemTest(testSetup) 17 | t.Parallel() 18 | t.SetSmokeTests("Multi download should work") 19 | 20 | t.Run("Multi download should work", func(t *test.SystemTest) { 21 | wallet := createWallet(t) 22 | 23 | sdkClient.SetWallet(t, wallet) 24 | 25 | blobberRequirements := model.DefaultBlobberRequirements(wallet.Id, wallet.PublicKey) 26 | allocationBlobbers := apiClient.GetAllocationBlobbers(t, wallet, &blobberRequirements, client.HttpOkStatus) 27 | allocationID := apiClient.CreateAllocation(t, wallet, allocationBlobbers, client.TxSuccessfulStatus) 28 | 29 | ops := make([]sdk.OperationRequest, 0, 10) 30 | 31 | for i := 0; i < 10; i++ { 32 | op := sdkClient.AddUploadOperation(t, "", "") 33 | ops = append(ops, op) 34 | } 35 | sdkClient.MultiOperation(t, allocationID, ops) 36 | 37 | alloc, err := sdk.GetAllocation(allocationID) 38 | require.NoError(t, err, "error getting allocation") 39 | err = os.MkdirAll("temp_download", os.ModePerm) 40 | require.NoError(t, err, "error creating temp dir") 41 | defer func() { 42 | err = os.RemoveAll("temp_download") 43 | require.NoError(t, err, "error removing temp dir") 44 | }() 45 | wg := &sync.WaitGroup{} 46 | for i := 0; i < 9; i++ { 47 | sdkClient.DownloadFileWithParam(t, alloc, ops[i].FileMeta.RemotePath, "temp_download/", wg, false) 48 | } 49 | sdkClient.DownloadFileWithParam(t, alloc, ops[9].FileMeta.RemotePath, "temp_download/", wg, true) 50 | wg.Wait() 51 | files, err := os.ReadDir("temp_download") 52 | require.NoError(t, err, "error reading temp dir") 53 | require.Equal(t, 10, len(files), "files count mismatch expected %v actual %v", 10, len(files)) 54 | for _, file := range files { 55 | sz, err := file.Info() 56 | require.NoError(t, err, "error getting file info") 57 | require.Equal(t, int64(1024), sz.Size(), "file size mismatch expected %v actual %v", 1024, sz.Size()) 58 | } 59 | }) 60 | } 61 | -------------------------------------------------------------------------------- /tests/api_tests/open_challenges_test.go: -------------------------------------------------------------------------------- 1 | package api_tests 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/0chain/system_test/internal/api/util/test" 7 | 8 | "github.com/0chain/system_test/internal/api/model" 9 | "github.com/0chain/system_test/internal/api/util/client" 10 | "github.com/stretchr/testify/require" 11 | ) 12 | 13 | func TestOpenChallenges(testSetup *testing.T) { 14 | t := test.NewSystemTest(testSetup) 15 | t.SetSmokeTests("Open Challenges API response should be successful decode given a valid request") 16 | 17 | t.Parallel() 18 | 19 | t.Run("Open Challenges API response should be successful decode given a valid request", func(t *test.SystemTest) { 20 | wallet := createWallet(t) 21 | 22 | blobberRequirements := model.DefaultBlobberRequirements(wallet.Id, wallet.PublicKey) 23 | allocationBlobbers := apiClient.GetAllocationBlobbers(t, wallet, &blobberRequirements, client.HttpOkStatus) 24 | blobberId := (*allocationBlobbers.Blobbers)[0] 25 | 26 | scRestOpenChallengeResponse, resp, err := apiClient.V1SCRestOpenChallenge( 27 | t, 28 | model.SCRestOpenChallengeRequest{ 29 | BlobberID: blobberId, 30 | }, 31 | client.HttpOkStatus) 32 | require.Nil(t, err) 33 | require.NotNil(t, resp) 34 | require.NotNil(t, scRestOpenChallengeResponse) 35 | }) 36 | } 37 | -------------------------------------------------------------------------------- /tests/api_tests/postman/Data/test_file: -------------------------------------------------------------------------------- 1 | Hello! 2 | -------------------------------------------------------------------------------- /tests/api_tests/postman/Environments/beta.postman_environment.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "38a7b6df-837c-46ed-8cdc-96c1c388b380", 3 | "name": "0Chain Betanet", 4 | "values": [ 5 | { 6 | "key": "network", 7 | "value": "beta.0chain.net", 8 | "enabled": true 9 | }, 10 | { 11 | "key": "mnemonic", 12 | "value": "", 13 | "enabled": true 14 | }, 15 | { 16 | "key": "faucet_smart_contract_address", 17 | "value": "6dba10422e368813802877a85039d3985d96760ed844092319743fb3a76712d3", 18 | "enabled": true 19 | }, 20 | { 21 | "key": "interest_smart_contract_address", 22 | "value": "cf8d0df9bd8cc637a4ff4e792ffe3686da6220c45f0e1103baa609f3f1751ef4", 23 | "enabled": true 24 | }, 25 | { 26 | "key": "miner_smart_contract_address", 27 | "value": "6dba10422e368813802877a85039d3985d96760ed844092319743fb3a76712d9", 28 | "enabled": true 29 | }, 30 | { 31 | "key": "storage_smart_contract_address", 32 | "value": "6dba10422e368813802877a85039d3985d96760ed844092319743fb3a76712d7", 33 | "enabled": true 34 | }, 35 | { 36 | "key": "vesting_smart_contract_address", 37 | "value": "2bba5b05949ea59c80aed3ac3474d7379d3be737e8eb5a968c52295e48333ead", 38 | "enabled": true 39 | }, 40 | { 41 | "key": "miner", 42 | "value": "{{network}}/miner01", 43 | "enabled": true 44 | }, 45 | { 46 | "key": "blobber", 47 | "value": "{{network}}/blobber01", 48 | "enabled": true 49 | }, 50 | { 51 | "key": "sharder", 52 | "value": "{{network}}/sharder01", 53 | "enabled": true 54 | }, 55 | { 56 | "key": "0proxy", 57 | "value": "{{network}}/proxy", 58 | "enabled": true 59 | } 60 | ], 61 | "_postman_variable_scope": "environment", 62 | "_postman_exported_at": "2021-07-03T21:16:06.355Z", 63 | "_postman_exported_using": "Postman/8.6.1" 64 | } -------------------------------------------------------------------------------- /tests/api_tests/postman/Environments/custom.postman_environment.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "60ef9fc1-22d8-4ca2-a097-a060cdff582e", 3 | "name": "0Chain Custom Network", 4 | "values": [ 5 | { 6 | "key": "network", 7 | "value": "REPLACE", 8 | "enabled": true 9 | }, 10 | { 11 | "key": "mnemonic", 12 | "value": "", 13 | "enabled": true 14 | }, 15 | { 16 | "key": "faucet_smart_contract_address", 17 | "value": "6dba10422e368813802877a85039d3985d96760ed844092319743fb3a76712d3", 18 | "enabled": true 19 | }, 20 | { 21 | "key": "interest_smart_contract_address", 22 | "value": "cf8d0df9bd8cc637a4ff4e792ffe3686da6220c45f0e1103baa609f3f1751ef4", 23 | "enabled": true 24 | }, 25 | { 26 | "key": "miner_smart_contract_address", 27 | "value": "6dba10422e368813802877a85039d3985d96760ed844092319743fb3a76712d9", 28 | "enabled": true 29 | }, 30 | { 31 | "key": "storage_smart_contract_address", 32 | "value": "6dba10422e368813802877a85039d3985d96760ed844092319743fb3a76712d7", 33 | "enabled": true 34 | }, 35 | { 36 | "key": "vesting_smart_contract_address", 37 | "value": "2bba5b05949ea59c80aed3ac3474d7379d3be737e8eb5a968c52295e48333ead", 38 | "enabled": true 39 | }, 40 | { 41 | "key": "miner", 42 | "value": "{{network}}/miner01", 43 | "enabled": true 44 | }, 45 | { 46 | "key": "blobber", 47 | "value": "{{network}}/blobber01", 48 | "enabled": true 49 | }, 50 | { 51 | "key": "sharder", 52 | "value": "{{network}}/sharder01", 53 | "enabled": true 54 | }, 55 | { 56 | "key": "0proxy", 57 | "value": "{{network}}/proxy", 58 | "enabled": true 59 | } 60 | ], 61 | "_postman_variable_scope": "environment", 62 | "_postman_exported_at": "2021-07-24T21:10:08.801Z", 63 | "_postman_exported_using": "Postman/8.7.0" 64 | } -------------------------------------------------------------------------------- /tests/api_tests/postman/Environments/dev.postman_environment.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "803e3bd9-ade0-4753-b43a-8122bcd0de4a", 3 | "name": "0Chain Dev", 4 | "values": [ 5 | { 6 | "key": "network", 7 | "value": "dev.0chain.net", 8 | "enabled": true 9 | }, 10 | { 11 | "key": "mnemonic", 12 | "value": "", 13 | "enabled": true 14 | }, 15 | { 16 | "key": "faucet_smart_contract_address", 17 | "value": "6dba10422e368813802877a85039d3985d96760ed844092319743fb3a76712d3", 18 | "enabled": true 19 | }, 20 | { 21 | "key": "interest_smart_contract_address", 22 | "value": "cf8d0df9bd8cc637a4ff4e792ffe3686da6220c45f0e1103baa609f3f1751ef4", 23 | "enabled": true 24 | }, 25 | { 26 | "key": "miner_smart_contract_address", 27 | "value": "6dba10422e368813802877a85039d3985d96760ed844092319743fb3a76712d9", 28 | "enabled": true 29 | }, 30 | { 31 | "key": "storage_smart_contract_address", 32 | "value": "6dba10422e368813802877a85039d3985d96760ed844092319743fb3a76712d7", 33 | "enabled": true 34 | }, 35 | { 36 | "key": "vesting_smart_contract_address", 37 | "value": "2bba5b05949ea59c80aed3ac3474d7379d3be737e8eb5a968c52295e48333ead", 38 | "enabled": true 39 | }, 40 | { 41 | "key": "miner", 42 | "value": "{{network}}/miner01", 43 | "enabled": true 44 | }, 45 | { 46 | "key": "blobber", 47 | "value": "{{network}}/blobber01", 48 | "enabled": true 49 | }, 50 | { 51 | "key": "sharder", 52 | "value": "{{network}}/sharder01", 53 | "enabled": true 54 | }, 55 | { 56 | "key": "0proxy", 57 | "value": "{{network}}/proxy", 58 | "enabled": true 59 | } 60 | ], 61 | "_postman_variable_scope": "environment", 62 | "_postman_exported_at": "2021-07-18T15:42:29.267Z", 63 | "_postman_exported_using": "Postman/8.7.0" 64 | } -------------------------------------------------------------------------------- /tests/api_tests/postman/Environments/test.postman_environment.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "ed59a0f2-8e54-4d59-a247-558bd4a90edf", 3 | "name": "0Chain Testnet", 4 | "values": [ 5 | { 6 | "key": "network", 7 | "value": "test.0chain.net", 8 | "enabled": true 9 | }, 10 | { 11 | "key": "mnemonic", 12 | "value": "", 13 | "enabled": true 14 | }, 15 | { 16 | "key": "faucet_smart_contract_address", 17 | "value": "6dba10422e368813802877a85039d3985d96760ed844092319743fb3a76712d3", 18 | "enabled": true 19 | }, 20 | { 21 | "key": "interest_smart_contract_address", 22 | "value": "cf8d0df9bd8cc637a4ff4e792ffe3686da6220c45f0e1103baa609f3f1751ef4", 23 | "enabled": true 24 | }, 25 | { 26 | "key": "miner_smart_contract_address", 27 | "value": "6dba10422e368813802877a85039d3985d96760ed844092319743fb3a76712d9", 28 | "enabled": true 29 | }, 30 | { 31 | "key": "storage_smart_contract_address", 32 | "value": "6dba10422e368813802877a85039d3985d96760ed844092319743fb3a76712d7", 33 | "enabled": true 34 | }, 35 | { 36 | "key": "vesting_smart_contract_address", 37 | "value": "2bba5b05949ea59c80aed3ac3474d7379d3be737e8eb5a968c52295e48333ead", 38 | "enabled": true 39 | }, 40 | { 41 | "key": "miner", 42 | "value": "{{network}}/miner01", 43 | "enabled": true 44 | }, 45 | { 46 | "key": "blobber", 47 | "value": "{{network}}/blobber01", 48 | "enabled": true 49 | }, 50 | { 51 | "key": "sharder", 52 | "value": "{{network}}/sharder01", 53 | "enabled": true 54 | }, 55 | { 56 | "key": "0proxy", 57 | "value": "{{network}}/proxy", 58 | "enabled": true 59 | } 60 | ], 61 | "_postman_variable_scope": "environment", 62 | "_postman_exported_at": "2021-06-22T22:11:02.411Z", 63 | "_postman_exported_using": "Postman/8.6.1" 64 | } -------------------------------------------------------------------------------- /tests/api_tests/remove_blobber_test.go: -------------------------------------------------------------------------------- 1 | package api_tests 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | 7 | "github.com/0chain/system_test/internal/api/util/test" 8 | 9 | "github.com/0chain/system_test/internal/api/model" 10 | 11 | "github.com/0chain/system_test/internal/api/util/client" 12 | "github.com/0chain/system_test/internal/api/util/wait" 13 | "github.com/stretchr/testify/require" 14 | ) 15 | 16 | func TestRemoveBlobber(testSetup *testing.T) { 17 | t := test.NewSystemTest(testSetup) 18 | t.SetSmokeTests("Remove blobber in allocation, shouldn't work") 19 | 20 | t.Parallel() 21 | 22 | t.Run("Remove blobber in allocation, shouldn't work", func(t *test.SystemTest) { 23 | wallet := createWallet(t) 24 | 25 | blobberRequirements := model.DefaultBlobberRequirements(wallet.Id, wallet.PublicKey) 26 | allocationBlobbers := apiClient.GetAllocationBlobbers(t, wallet, &blobberRequirements, client.HttpOkStatus) 27 | allocationID := apiClient.CreateAllocation(t, wallet, allocationBlobbers, client.TxSuccessfulStatus) 28 | 29 | allocation := apiClient.GetAllocation(t, allocationID, client.HttpOkStatus) 30 | numberOfBlobbersBefore := len(allocation.Blobbers) 31 | 32 | oldBlobberID := getFirstUsedStorageNodeID(allocationBlobbers.Blobbers, allocation.Blobbers) 33 | require.NotZero(t, oldBlobberID, "Old blobber ID contains zero value") 34 | 35 | apiClient.UpdateAllocationBlobbers(t, wallet, "", oldBlobberID, allocationID, client.TxUnsuccessfulStatus) 36 | 37 | var numberOfBlobbersAfter int 38 | 39 | wait.PoolImmediately(t, time.Second*30, func() bool { 40 | allocation = apiClient.GetAllocation(t, allocationID, client.HttpOkStatus) 41 | numberOfBlobbersAfter = len(allocation.Blobbers) 42 | 43 | return numberOfBlobbersAfter == numberOfBlobbersBefore 44 | }) 45 | 46 | require.Equal(t, numberOfBlobbersAfter, numberOfBlobbersBefore) 47 | }) 48 | } 49 | -------------------------------------------------------------------------------- /tests/api_tests/split_key_wallet_mobile_test.go: -------------------------------------------------------------------------------- 1 | package api_tests 2 | 3 | import ( 4 | "encoding/base64" 5 | "encoding/json" 6 | "fmt" 7 | "testing" 8 | 9 | "github.com/0chain/gosdk/core/zcncrypto" 10 | "github.com/0chain/gosdk/mobilesdk/sdk" 11 | "github.com/0chain/system_test/internal/api/util/test" 12 | "github.com/stretchr/testify/require" 13 | ) 14 | 15 | func TestSplitKeyMobile(testSetup *testing.T) { 16 | t := test.NewSystemTest(testSetup) 17 | t.SetSmokeTests("Check if Splitkey handler is generating split keys or not") 18 | 19 | t.Run("Check if Splitkey handler is generating split keys or not", func(t *test.SystemTest) { 20 | wallet := createWallet(t) 21 | privateKey := wallet.Keys.PrivateKey 22 | serializedPrivateKey := privateKey.Serialize() 23 | stringPrivateKey := base64.StdEncoding.EncodeToString(serializedPrivateKey) 24 | // this represents number of split keys made from private key 25 | numSplit := 2 26 | signatureScheme := "bls0chain" 27 | wStr, err := sdk.SplitKeys(stringPrivateKey, signatureScheme, numSplit) 28 | if err != nil { 29 | fmt.Println("Error while spliting keys:", err) 30 | return 31 | } 32 | var splitKeyWallet zcncrypto.Wallet 33 | err = json.Unmarshal([]byte(wStr), &splitKeyWallet) 34 | if err != nil { 35 | fmt.Println("Error while unmarshalling split key wallet:", err) 36 | return 37 | } 38 | require.Nil(t, err) 39 | require.NotNil(t, splitKeyWallet) 40 | require.Equal(t, splitKeyWallet.ClientID, wallet.Id) 41 | require.NotNil(t, splitKeyWallet.Keys[0].PrivateKey) 42 | require.NotNil(t, splitKeyWallet.Keys[0].PublicKey) 43 | }) 44 | } 45 | -------------------------------------------------------------------------------- /tests/api_tests/test-file.txt: -------------------------------------------------------------------------------- 1 | This file is created to upload file for zs3server-test 2 | -------------------------------------------------------------------------------- /tests/api_tests/update_blobber_test.go: -------------------------------------------------------------------------------- 1 | package api_tests 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/0chain/system_test/internal/api/util/test" 7 | 8 | "github.com/0chain/system_test/internal/api/model" 9 | 10 | "github.com/0chain/system_test/internal/api/util/client" 11 | "github.com/stretchr/testify/require" 12 | ) 13 | 14 | func TestUpdateBlobber(testSetup *testing.T) { 15 | t := test.NewSystemTest(testSetup) 16 | t.SetSmokeTests("Update blobber in allocation without correct delegated client, shouldn't work") 17 | 18 | t.Parallel() 19 | 20 | t.Run("update blobber version should work", func(t *test.SystemTest) { 21 | wallet := createWallet(t) 22 | 23 | blobberRequirements := model.DefaultBlobberRequirements(wallet.Id, wallet.PublicKey) 24 | allocationBlobbers := apiClient.GetAllocationBlobbers(t, wallet, &blobberRequirements, client.HttpOkStatus) 25 | allocationID := apiClient.CreateAllocation(t, wallet, allocationBlobbers, client.TxSuccessfulStatus) 26 | 27 | allocation := apiClient.GetAllocation(t, allocationID, client.HttpOkStatus) 28 | 29 | blobberID := getFirstUsedStorageNodeID(allocationBlobbers.Blobbers, allocation.Blobbers) 30 | require.NotZero(t, blobberID) 31 | 32 | blobber := apiClient.GetBlobber(t, blobberID, client.HttpOkStatus) 33 | require.NotEqual(t, wallet.Id, blobber.StakePoolSettings.DelegateWallet) 34 | 35 | blobber.StorageVersion = 1 36 | 37 | apiClient.UpdateBlobber(t, wallet, blobber, client.TxUnsuccessfulStatus) 38 | 39 | blobber = apiClient.GetBlobber(t, blobberID, client.HttpOkStatus) 40 | require.NotEqual(t, wallet.Id, blobber.StakePoolSettings.DelegateWallet) 41 | 42 | require.Equal(t, int64(1), blobber.StorageVersion) 43 | }) 44 | 45 | t.Run("update blobber: degrade version should not work", func(t *test.SystemTest) { 46 | wallet := createWallet(t) 47 | 48 | blobberRequirements := model.DefaultBlobberRequirements(wallet.Id, wallet.PublicKey) 49 | allocationBlobbers := apiClient.GetAllocationBlobbers(t, wallet, &blobberRequirements, client.HttpOkStatus) 50 | 51 | allocationID := apiClient.CreateAllocation(t, wallet, allocationBlobbers, client.TxSuccessfulStatus) 52 | 53 | allocation := apiClient.GetAllocation(t, allocationID, client.HttpOkStatus) 54 | 55 | blobberID := getFirstUsedStorageNodeID(allocationBlobbers.Blobbers, allocation.Blobbers) 56 | require.NotZero(t, blobberID) 57 | 58 | blobber := apiClient.GetBlobber(t, blobberID, client.HttpOkStatus) 59 | require.NotEqual(t, wallet.Id, blobber.StakePoolSettings.DelegateWallet) 60 | 61 | blobber.StorageVersion = 0 62 | 63 | apiClient.UpdateBlobber(t, wallet, blobber, client.TxUnsuccessfulStatus) 64 | 65 | blobber = apiClient.GetBlobber(t, blobberID, client.HttpOkStatus) 66 | require.NotEqual(t, wallet.Id, blobber.StakePoolSettings.DelegateWallet) 67 | 68 | require.Equal(t, int64(1), blobber.StorageVersion) 69 | }) 70 | 71 | t.Run("Update blobber in allocation without correct delegated client, shouldn't work", func(t *test.SystemTest) { 72 | wallet := createWallet(t) 73 | 74 | blobberRequirements := model.DefaultBlobberRequirements(wallet.Id, wallet.PublicKey) 75 | allocationBlobbers := apiClient.GetAllocationBlobbers(t, wallet, &blobberRequirements, client.HttpOkStatus) 76 | allocationID := apiClient.CreateAllocation(t, wallet, allocationBlobbers, client.TxSuccessfulStatus) 77 | 78 | allocation := apiClient.GetAllocation(t, allocationID, client.HttpOkStatus) 79 | 80 | blobberID := getFirstUsedStorageNodeID(allocationBlobbers.Blobbers, allocation.Blobbers) 81 | require.NotZero(t, blobberID) 82 | 83 | blobber := apiClient.GetBlobber(t, blobberID, client.HttpOkStatus) 84 | require.NotEqual(t, wallet.Id, blobber.StakePoolSettings.DelegateWallet) 85 | 86 | apiClient.UpdateBlobber(t, wallet, blobber, client.TxUnsuccessfulStatus) 87 | }) 88 | } 89 | -------------------------------------------------------------------------------- /tests/cli_tests/0_tenderly_authorizer_rewards_test.go: -------------------------------------------------------------------------------- 1 | package cli_tests 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "io" 7 | "net/http" 8 | "net/url" 9 | "strings" 10 | "testing" 11 | "time" 12 | 13 | "github.com/0chain/system_test/internal/api/util/test" 14 | "github.com/0chain/system_test/internal/cli/model" 15 | "github.com/0chain/system_test/tests/tokenomics_tests/utils" 16 | "github.com/stretchr/testify/require" 17 | ) 18 | 19 | func Test0TenderlyAuthorizerRewards(testSetup *testing.T) { 20 | t := test.NewSystemTest(testSetup) 21 | 22 | if !tenderlyInitialized { 23 | t.Skip("Tenderly has not been initialized properly!") 24 | } 25 | 26 | t.Skip("Skip due to Tenderly rate throttling") 27 | 28 | t.RunSequentiallyWithTimeout("Verify Authorizer Rewards", time.Minute*10, func(t *test.SystemTest) { 29 | createWallet(t) 30 | 31 | feeRewardAuthorizerQuery := fmt.Sprintf("reward_type = %d", model.FeeRewardAuthorizer) 32 | feeRewardAuthorizer, err := getQueryRewards(t, feeRewardAuthorizerQuery) 33 | require.Nil(t, err) 34 | 35 | output, err := burnEth(t, "1000000000000", true) 36 | require.Nil(t, err) 37 | require.Greater(t, len(output), 0) 38 | require.Contains(t, output[len(output)-1], "Verification:") 39 | 40 | output, err = mintZcnTokens(t, true) 41 | require.Nil(t, err, "error: %s", strings.Join(output, "\n")) 42 | require.Greater(t, len(output), 0) 43 | require.Contains(t, output[len(output)-1], "Done.") 44 | 45 | time.Sleep(20 * time.Second) 46 | 47 | feeRewardAuthorizerAfterMint, err := getQueryRewards(t, feeRewardAuthorizerQuery) 48 | require.Nil(t, err) 49 | 50 | require.Equal(t, feeRewardAuthorizerAfterMint.TotalReward, feeRewardAuthorizer.TotalReward+33, "Fee reward authorizer should be increased by 33.33 ZCN") 51 | }) 52 | } 53 | 54 | func getQueryRewards(t *test.SystemTest, query string) (QueryRewardsResponse, error) { 55 | var result QueryRewardsResponse 56 | 57 | StorageScAddress := "6dba10422e368813802877a85039d3985d96760ed844092319743fb3a76712d7" 58 | sharderBaseUrl := utils.GetSharderUrl(t) 59 | requestURL := fmt.Sprintf("%s/v1/screst/%s/query-rewards?query=%s", 60 | sharderBaseUrl, StorageScAddress, url.QueryEscape(query)) 61 | 62 | res, _ := http.Get(requestURL) //nolint:gosec 63 | 64 | defer func(Body io.ReadCloser) { 65 | err := Body.Close() 66 | if err != nil { 67 | return 68 | } 69 | }(res.Body) 70 | 71 | body, _ := io.ReadAll(res.Body) 72 | 73 | err := json.Unmarshal(body, &result) 74 | if err != nil { 75 | return QueryRewardsResponse{}, err 76 | } 77 | 78 | return result, nil 79 | } 80 | 81 | type QueryRewardsResponse struct { 82 | TotalProviderReward float64 `json:"total_provider_reward"` 83 | TotalDelegateReward float64 `json:"total_delegate_reward"` 84 | TotalReward float64 `json:"total_reward"` 85 | } 86 | -------------------------------------------------------------------------------- /tests/cli_tests/0_tenderly_zcnbridge_ethereum-account-register_test.go: -------------------------------------------------------------------------------- 1 | package cli_tests 2 | 3 | import ( 4 | "fmt" 5 | "io/fs" 6 | "log" 7 | "os" 8 | "path" 9 | "path/filepath" 10 | "reflect" 11 | "strings" 12 | "testing" 13 | "time" 14 | 15 | "github.com/0chain/system_test/internal/api/util/test" 16 | 17 | "gopkg.in/errgo.v2/errors" 18 | 19 | cliutils "github.com/0chain/system_test/internal/cli/util" 20 | 21 | "github.com/stretchr/testify/require" 22 | ) 23 | 24 | const ( 25 | address = "C49926C4124cEe1cbA0Ea94Ea31a6c12318df947" 26 | mnemonic = "tag volcano eight thank tide danger coast health above argue embrace heavy" 27 | password = "password" 28 | ) 29 | 30 | func Test0TenderlyEthRegisterAccount(testSetup *testing.T) { 31 | t := test.NewSystemTest(testSetup) 32 | t.SetSmokeTests("Register ethereum account in local key storage") 33 | 34 | t.RunSequentially("Register ethereum account in local key storage", func(t *test.SystemTest) { 35 | deleteDefaultAccountInStorage(t, address) 36 | output, err := importAccount(t, password, mnemonic, false) 37 | require.Nil(t, err, "error trying to register ethereum account", strings.Join(output, "\n")) 38 | require.Greater(t, len(output), 0) 39 | require.Contains(t, output[len(output)-1], "Imported account 0x"+address) 40 | }) 41 | 42 | t.RunSequentially("List ethereum account registered in local key storage", func(t *test.SystemTest) { 43 | deleteDefaultAccountInStorage(t, address) 44 | output, err := importAccount(t, password, mnemonic, false) 45 | require.NoError(t, err, strings.Join(output, "\n")) 46 | require.Greater(t, len(output), 0) 47 | require.Contains(t, output[len(output)-1], "Imported account 0x"+address) 48 | 49 | output, err = listAccounts(t, false) 50 | require.Nil(t, err, "error trying to register ethereum account", strings.Join(output, "\n")) 51 | require.Greater(t, len(output), 0) 52 | require.Contains(t, output[len(output)-1], address) 53 | 54 | deleteDefaultAccountInStorage(t, address) 55 | }) 56 | } 57 | 58 | func importAccount(t *test.SystemTest, password, mnemonic string, retry bool) ([]string, error) { 59 | t.Logf("Register ethereum account using mnemonic and protected with password...") 60 | createWallet(t) 61 | 62 | cmd := fmt.Sprintf( 63 | "./zwallet bridge-import-account --password %s --mnemonic \"%s\" --silent "+ 64 | "--configDir ./config --config %s --wallet %s --path %s", 65 | password, 66 | mnemonic, 67 | configPath, 68 | escapedTestName(t)+"_wallet.json", 69 | configDir, 70 | ) 71 | 72 | if retry { 73 | return cliutils.RunCommand(t, cmd, 3, time.Second*2) 74 | } else { 75 | return cliutils.RunCommandWithoutRetry(cmd) 76 | } 77 | } 78 | 79 | func listAccounts(t *test.SystemTest, retry bool) ([]string, error) { 80 | t.Logf("List ethereum accounts...") 81 | cmd := fmt.Sprintf("./zwallet bridge-list-accounts --path %s", configDir) 82 | cmd += fmt.Sprintf(" --wallet %s --configDir ./config --config %s ", escapedTestName(t)+"_wallet.json", configPath) 83 | 84 | if retry { 85 | return cliutils.RunCommand(t, cmd, 3, time.Second*2) 86 | } else { 87 | return cliutils.RunCommandWithoutRetry(cmd) 88 | } 89 | } 90 | 91 | func deleteDefaultAccountInStorage(t *test.SystemTest, address string) { 92 | keyDir := path.Join(configDir, "wallets") 93 | if _, err := os.Stat(keyDir); err != nil { 94 | t.Skipf("wallets folder at location is missing: %s", keyDir) 95 | } 96 | 97 | err := filepath.Walk(keyDir, func(path string, info fs.FileInfo, err error) error { 98 | if e := IsNil(info); e != nil { 99 | t.Logf("path %s is nil", path) 100 | return nil 101 | } 102 | 103 | if !info.IsDir() { 104 | require.NoError(t, err) 105 | if strings.Contains(strings.ToLower(path), strings.ToLower(address)) { 106 | err = os.Remove(path) 107 | require.NoError(t, err) 108 | } 109 | } 110 | return nil 111 | }) 112 | 113 | require.NoError(t, err) 114 | } 115 | 116 | func getConfigDir() string { 117 | var configDir string 118 | curr, err := os.Getwd() 119 | if err != nil { 120 | log.Fatalln(err) 121 | } 122 | configDir = filepath.Join(curr, "config") 123 | return configDir 124 | } 125 | 126 | func IsNil(value interface{}) error { 127 | val := reflect.ValueOf(value) 128 | if val.Kind() != reflect.Ptr { 129 | return errors.New("result must be a pointer") 130 | } 131 | 132 | val = val.Elem() 133 | if !val.CanAddr() { 134 | return errors.New("result must be addressable (a pointer)") 135 | } 136 | 137 | return nil 138 | } 139 | -------------------------------------------------------------------------------- /tests/cli_tests/0_tenderly_zcnbridge_list_authorizers_test.go: -------------------------------------------------------------------------------- 1 | package cli_tests 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | "testing" 7 | "time" 8 | 9 | "github.com/0chain/system_test/internal/api/util/test" 10 | 11 | cliutils "github.com/0chain/system_test/internal/cli/util" 12 | "github.com/stretchr/testify/require" 13 | ) 14 | 15 | func Test0TenderlyListAuthorizers(testSetup *testing.T) { 16 | t := test.NewSystemTest(testSetup) 17 | t.SetSmokeTests("List authorizers should work") 18 | 19 | t.Parallel() 20 | 21 | t.Run("List authorizers should work", func(t *test.SystemTest) { 22 | output, err := getAuthorizersList(t, true) 23 | 24 | require.Nil(t, err, "error trying to get the list of authorizers", strings.Join(output, "\n")) 25 | }) 26 | } 27 | 28 | // nolint 29 | func getAuthorizersList(t *test.SystemTest, retry bool) ([]string, error) { 30 | t.Logf("Getting list of authorizers...") 31 | cmd := fmt.Sprintf( 32 | "./zwallet bridge-list-auth --silent "+ 33 | "--configDir ./config --config %s", 34 | configPath, 35 | ) 36 | if retry { 37 | return cliutils.RunCommand(t, cmd, 3, time.Second*2) 38 | } else { 39 | return cliutils.RunCommandWithoutRetry(cmd) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tests/cli_tests/0_tenderly_zcnbridge_mint_test.go: -------------------------------------------------------------------------------- 1 | package cli_tests 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | "testing" 7 | "time" 8 | 9 | "github.com/0chain/system_test/internal/api/util/test" 10 | 11 | cliutils "github.com/0chain/system_test/internal/cli/util" 12 | "github.com/stretchr/testify/require" 13 | ) 14 | 15 | func Test0TenderlyBridgeMint(testSetup *testing.T) { 16 | t := test.NewSystemTest(testSetup) 17 | 18 | if !tenderlyInitialized { 19 | t.Skip("Tenderly has not been initialized properly!") 20 | } 21 | 22 | t.RunSequentiallyWithTimeout("Mint WZCN tokens", time.Minute*10, func(t *test.SystemTest) { 23 | createWallet(t) 24 | 25 | output, err := resetUserNonce(t, true) 26 | require.Nil(t, err) 27 | require.Greater(t, len(output), 0) 28 | 29 | output, err = burnZcn(t, "1", false) 30 | require.Nil(t, err) 31 | require.Greater(t, len(output), 0) 32 | require.Contains(t, output[len(output)-1], "Transaction completed successfully:") 33 | 34 | output, err = mintWrappedZcnTokens(t, true) 35 | require.Nil(t, err, "error: %s", strings.Join(output, "\n")) 36 | require.Greater(t, len(output), 0) 37 | require.Contains(t, output[len(output)-1], "Done.") 38 | }) 39 | 40 | t.RunSequentiallyWithTimeout("Mint ZCN tokens", time.Minute*10, func(t *test.SystemTest) { 41 | t.Skip("Skip due to Tenderly rate throttling") 42 | 43 | createWallet(t) 44 | 45 | output, err := burnEth(t, "1000000000000", true) 46 | require.Nil(t, err) 47 | require.Greater(t, len(output), 0) 48 | require.Contains(t, output[len(output)-1], "Verification:") 49 | 50 | output, err = mintZcnTokens(t, true) 51 | require.Nil(t, err, "error: %s", strings.Join(output, "\n")) 52 | require.Greater(t, len(output), 0) 53 | require.Contains(t, output[len(output)-1], "Done.") 54 | }) 55 | } 56 | 57 | // nolint 58 | func mintZcnTokens(t *test.SystemTest, retry bool) ([]string, error) { 59 | t.Logf("Mint ZCN tokens using WZCN burn ticket...") 60 | cmd := fmt.Sprintf( 61 | "./zwallet bridge-mint-zcn --silent "+ 62 | "--configDir ./config --config %s --path %s --wallet %s", 63 | configPath, 64 | configDir, 65 | escapedTestName(t)+"_wallet.json", 66 | ) 67 | if retry { 68 | return cliutils.RunCommand(t, cmd, 3, time.Second*2) 69 | } else { 70 | return cliutils.RunCommandWithoutRetry(cmd) 71 | } 72 | } 73 | 74 | // nolint 75 | func mintWrappedZcnTokens(t *test.SystemTest, retry bool) ([]string, error) { 76 | t.Logf("Mint WZCN tokens using ZCN burn ticket...") 77 | cmd := fmt.Sprintf( 78 | "./zwallet bridge-mint-wzcn --silent "+ 79 | "--configDir ./config --config %s --path %s --wallet %s", 80 | configPath, 81 | configDir, 82 | escapedTestName(t)+"_wallet.json", 83 | ) 84 | if retry { 85 | return cliutils.RunCommand(t, cmd, 2, time.Second*2) 86 | } else { 87 | return cliutils.RunCommandWithoutRetry(cmd) 88 | } 89 | } 90 | 91 | // nolint 92 | func resetUserNonce(t *test.SystemTest, retry bool) ([]string, error) { 93 | t.Logf("Reset user nonce...") 94 | cmd := fmt.Sprintf( 95 | "./zwallet reset-user-nonce --silent "+ 96 | "--configDir ./config --config %s --wallet %s --path %s", 97 | configPath, 98 | escapedTestName(t)+"_wallet.json", 99 | configDir, 100 | ) 101 | 102 | if retry { 103 | return cliutils.RunCommand(t, cmd, 2, time.Second*10) 104 | } else { 105 | return cliutils.RunCommandWithoutRetry(cmd) 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /tests/cli_tests/0_tenderly_zcnbridge_verify_ethereum_test.go: -------------------------------------------------------------------------------- 1 | package cli_tests 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | "testing" 7 | "time" 8 | 9 | "github.com/0chain/system_test/internal/api/util/test" 10 | 11 | cliutils "github.com/0chain/system_test/internal/cli/util" 12 | "github.com/stretchr/testify/require" 13 | ) 14 | 15 | func Test0TenderlyBridgeVerify(testSetup *testing.T) { 16 | t := test.NewSystemTest(testSetup) 17 | 18 | if !tenderlyInitialized { 19 | t.Skip("Tenderly has not been initialized properly!") 20 | } 21 | 22 | t.SetSmokeTests("Verify ethereum transaction") 23 | 24 | t.RunSequentiallyWithTimeout("Verify ethereum transaction", time.Minute*10, func(t *test.SystemTest) { 25 | output, err := burnEth(t, "1000000000000", true) 26 | require.Nil(t, err, output) 27 | require.Greater(t, len(output), 0) 28 | require.Contains(t, output[len(output)-1], "Verification:") 29 | 30 | ethTxHash := getTransactionHash(output, true) 31 | 32 | output, err = verifyBridgeTransaction(t, ethTxHash, false) 33 | require.Nil(t, err, "error trying to verify transaction", strings.Join(output, "\n")) 34 | require.Greater(t, len(output), 0) 35 | require.Equal(t, "Transaction verification success: "+ethTxHash, output[len(output)-1]) 36 | }) 37 | } 38 | 39 | func verifyBridgeTransaction(t *test.SystemTest, address string, retry bool) ([]string, error) { // nolint 40 | t.Logf("verifying ethereum transaction...") 41 | cmd := fmt.Sprintf( 42 | "./zwallet bridge-verify --hash %s --silent --configDir ./config --config %s --path %s", 43 | address, 44 | configPath, 45 | configDir, 46 | ) 47 | if retry { 48 | return cliutils.RunCommand(t, cmd, 2, time.Second*2) 49 | } else { 50 | return cliutils.RunCommandWithoutRetry(cmd) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /tests/cli_tests/config/cli_tests_config.yaml: -------------------------------------------------------------------------------- 1 | default_test_case_timeout: 3m 2 | s3_access_key: 3 | s3_secret_key: 4 | s3_bucket_name: 5 | s3_bucket_name_alternate: alternate-test-bucket 6 | dropboxAccessToken: 7 | gdriveAccessToken: 8 | -------------------------------------------------------------------------------- /tests/cli_tests/config/config.yaml: -------------------------------------------------------------------------------- 1 | block_worker: https://dev-st.devnet-0chain.net/dns 2 | confirmation_chain_length: 3 3 | ethereum_node_url: "https://rpc.tenderly.co/fork/5b7ffac9-50cc-4169-b0ca-6fd203d26ef6" 4 | min_confirmation: 50 5 | min_submit: 50 6 | signature_scheme: bls0chain 7 | store_unlock_duration_sec: 2 8 | 9 | bridge: 10 | bridge_address: 0x7700D773022b19622095118Fadf46f7B9448Be9b 11 | token_address: 0xb9EF770B6A5e12E45983C5D80545258aA38F3B78 12 | authorizers_address: 0x481daB4407b9880DE0A68dc62E6aF611c4949E42 13 | uniswap_address: 0x4c12C2FeEDD86267d17dB64BaB2cFD12cD8611f5 14 | ethereum_address: 0x8E25cfd9bd6c0ca67a5522cd920b3c66D39d6E97 15 | password: "12345678" -------------------------------------------------------------------------------- /tests/cli_tests/config/nodes.yaml: -------------------------------------------------------------------------------- 1 | version: 1.0 2 | 3 | nodes: 4 | miner01ID: "73ad5727612116c025bb4405bf3adb4a4a04867ae508c51cf885395bffc8a949" 5 | miner02ID: "3ec9a42db3355f33c35750ce589ed717c08787997b7f34a7f1f9fb0a03f2b17c" 6 | miner03ID: "c6f4b8ce5da386b278ba8c4e6cf98b24b32d15bc675b4d12c95e082079c91937" 7 | sharder01ID: "ea26431f8adb7061766f1d6bbcc3b292d70dd59960d857f04b8a75e6a5bbe04f" 8 | sharder02ID: "30001a01a888584772b7fee13934021ab8557e0ed471c0a3a454e9164180aef1" -------------------------------------------------------------------------------- /tests/cli_tests/config/wallets/UTC--2022-11-13T22-51-36.015115000Z--d8c9156e782c68ee671c09b6b92de76c97948432: -------------------------------------------------------------------------------- 1 | {"address":"d8c9156e782c68ee671c09b6b92de76c97948432","crypto":{"cipher":"aes-128-ctr","ciphertext":"e4a7f436e5aaf5e70c4d599710d73e87555ca52f8e980609f318cb1b139a5731","cipherparams":{"iv":"e9ab45b3c316f0f1af6279747682787f"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"6a06e705fd938963f61971296034a725051ccc80009053b8840229797a3583d7"},"mac":"12b8e284bc94e18955b534c8ce0883f0bce2d86358322aee3e60fcb288541159"},"id":"3aa1668c-8285-4770-86db-71dd8bcb8c20","version":3} -------------------------------------------------------------------------------- /tests/cli_tests/config/wallets/UTC--2022-11-16T09-39-06.387907000Z--c49926c4124cee1cba0ea94ea31a6c12318df947: -------------------------------------------------------------------------------- 1 | {"address":"557850520d8acd3177b445caaed6410899ef976a","crypto":{"cipher":"aes-128-ctr","ciphertext":"ef825a7251925e843dd95b64c76be91ada95f2163fcda96b7d3e4d1ff7cf5bde","cipherparams":{"iv":"0368717b09cdb7f7922e5d995926cd9d"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"fb53a903919480c85938400eb5a1d419311fe33f800e0f2f5178dc74222a5353"},"mac":"af6847ae024b4bace78cbded20033ea7976c45bc99b332d33f147e8b0934ef00"},"id":"b0af2ac2-3ebf-449b-810b-5f6f8be4374f","version":3} -------------------------------------------------------------------------------- /tests/cli_tests/config/wallets/UTC--2022-11-24T20-45-27.508229000Z--c49926c4124cee1cba0ea94ea31a6c12318df947: -------------------------------------------------------------------------------- 1 | {"address":"c49926c4124cee1cba0ea94ea31a6c12318df947","crypto":{"cipher":"aes-128-ctr","ciphertext":"d4836bccc34c9ae4a968ec39b380644a9889e8327888f1604e66c320fec48bef","cipherparams":{"iv":"c4fdfd5238be9481e773aec3d97b030c"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"278e0fbc2f8f8a07273954494c77b196331b6bbe88f2d7ba7f1c15b6b7b52d6d"},"mac":"4e50efbbe89f009dc2b400e00ad07e6e13a1e882848094d95f6a43326904456e"},"id":"ae56a19b-f04d-46b6-b3a8-25827bd67f25","version":3} -------------------------------------------------------------------------------- /tests/cli_tests/config/wallets/UTC--2023-10-26T00-34-42.327566000Z--8e25cfd9bd6c0ca67a5522cd920b3c66d39d6e97: -------------------------------------------------------------------------------- 1 | {"address":"8e25cfd9bd6c0ca67a5522cd920b3c66d39d6e97","crypto":{"cipher":"aes-128-ctr","ciphertext":"3e6a7c7fc1875e9437fb1b19d8195b707d2143f5aa40615b02efce3ef0422619","cipherparams":{"iv":"ab9d87b14b8593112338abc7da502866"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"94cdd599dd1c4a9eb24f837ca0dbd02d30a33b890bd43eca936c0ca25fd2e983"},"mac":"f07cf9a0c324e8449a1f7c17f5d7f6d3a942ec47b1ee73e157dfc3f325cbb9d3"},"id":"db1bba38-3573-4d53-905f-f075458da3d4","version":3} -------------------------------------------------------------------------------- /tests/cli_tests/config/wallets/blobber_owner_wallet.json: -------------------------------------------------------------------------------- 1 | {"client_id": "591d6d0d5642bdbc924756ca2647b4b59adce0acd02a487ecc4d1bd4669293a8","client_key": "ac8798bcadd5ce5ea14f4745850eec61aa080e6fedc1d769af95c42e0079ba03ee9710e9dc966f7c5eb9cd6ef9184af51869d5a345b9520e507aa55ba22bf902","keys": [{"public_key": "ac8798bcadd5ce5ea14f4745850eec61aa080e6fedc1d769af95c42e0079ba03ee9710e9dc966f7c5eb9cd6ef9184af51869d5a345b9520e507aa55ba22bf902","private_key": "fbdc0bcc12168588e2def826b7ee9d8b4c6f1fbacf22ee5064b7db49482b8f0d"}],"mnemonics": "economy day fan flower between rebuild valid bid catch bargain vivid hybrid room permit check manage mean twelve damage summer close churn boat either","version": "1.0","date_created": "2021-12-04T17:03:37Z"} -------------------------------------------------------------------------------- /tests/cli_tests/config/wallets/miner01_node_delegate_wallet.json: -------------------------------------------------------------------------------- 1 | { 2 | "client_id": "9636ab821fd93a37740ab4c6a27d9e2cf3a4072b4bc8fd1c6048f9c3ef9cf2a8", 3 | "client_key": "02237d7edafc8c648b1e2ff64ad5d4e6a7cea949a40448e15a55f0a90c71bc1928d8f1409d8985757cc1f59f13d82d83fe6757e4a510d9b47c6385d91ea5d59b", 4 | "keys": [ 5 | { 6 | "public_key": "02237d7edafc8c648b1e2ff64ad5d4e6a7cea949a40448e15a55f0a90c71bc1928d8f1409d8985757cc1f59f13d82d83fe6757e4a510d9b47c6385d91ea5d59b", 7 | "private_key": "17627154df3d2a77a273c6b5caf71ca552d26addce0198c1126331eb71ef5c0a" 8 | } 9 | ], 10 | "mnemonics": "family admit sound girl recall another rule hawk equip soccer action dance tumble style prepare face cluster endorse wonder raven unit vital hybrid mass", 11 | "version": "1.0", 12 | "date_created": "1661370959", 13 | "nonce": 0 14 | } -------------------------------------------------------------------------------- /tests/cli_tests/config/wallets/miner02_node_delegate_wallet.json: -------------------------------------------------------------------------------- 1 | { 2 | "client_id": "b8b25d509afbe8f68f1342a2fa719acf312915a6f5a5bb0918cad6598e01325f", 3 | "client_key": "e88949ab4fdfa724459fe41bb2c2e9ce5467ddb6911469614a4201b741933e157a1423853cb9426c3360b970ad8d9d6e07b93a60ba8531b268d1377f5804d103", 4 | "keys": [ 5 | { 6 | "public_key": "e88949ab4fdfa724459fe41bb2c2e9ce5467ddb6911469614a4201b741933e157a1423853cb9426c3360b970ad8d9d6e07b93a60ba8531b268d1377f5804d103", 7 | "private_key": "b7c415c17659b198de177e95d15345a9c576cd2522ea14a0c20399fdb7731c0b" 8 | } 9 | ], 10 | "mnemonics": "lock olive another scare idea awesome hat chaos general gauge immense near torch magic tomato ancient mule release know siege few twin donor race", 11 | "version": "1.0", 12 | "date_created": "1661370970", 13 | "nonce": 0 14 | } -------------------------------------------------------------------------------- /tests/cli_tests/config/wallets/miner03_node_delegate_wallet.json: -------------------------------------------------------------------------------- 1 | { 2 | "client_id": "bbe8b6abdb54b0642324a103c49f8b04e2623db74cd7f1427cd2d5f0308e674d", 3 | "client_key": "0f1d9339776c39a43bcb722dc0fdc0fe0df8ae397b06432b2184c279e41aa81963c45abb3791ca6a939f8c1b6d437f4e30d4c1044c7697eaa1ba55af3198bd22", 4 | "keys": [ 5 | { 6 | "public_key": "0f1d9339776c39a43bcb722dc0fdc0fe0df8ae397b06432b2184c279e41aa81963c45abb3791ca6a939f8c1b6d437f4e30d4c1044c7697eaa1ba55af3198bd22", 7 | "private_key": "16bb6962b0fa54c83d97f5b139a73148a9015b7f9ae7a2dbc5d34753a94ee01b" 8 | } 9 | ], 10 | "mnemonics": "friend display mask album rebel liar pilot trim dad pupil brand trigger enter pink sad mistake miracle insect glad notable cause diesel pool hard", 11 | "version": "1.0", 12 | "date_created": "1661370979", 13 | "nonce": 0 14 | } -------------------------------------------------------------------------------- /tests/cli_tests/config/wallets/sc_owner_wallet.json: -------------------------------------------------------------------------------- 1 | {"client_id":"1746b06bb09f55ee01b33b5e2e055d6cc7a900cb57c0a3a5eaabb8a0e7745802","client_key":"7b630ba670dac2f22d43c2399b70eff378689a53ee03ea20957bb7e73df016200fea410ba5102558b0c39617e5afd2c1843b161a1dedec15e1ab40543a78a518","keys":[{"public_key":"7b630ba670dac2f22d43c2399b70eff378689a53ee03ea20957bb7e73df016200fea410ba5102558b0c39617e5afd2c1843b161a1dedec15e1ab40543a78a518","private_key":"c06b6f6945ba02d5a3be86b8779deca63bb636ce7e46804a479c50e53c864915"}],"mnemonics":"cactus panther essence ability copper fox wise actual need cousin boat uncover ride diamond group jacket anchor current float rely tragic omit child payment","version":"1.0","date_created":"2021-08-04 18:53:56.949069945 +0100 BST m=+0.018986002"} -------------------------------------------------------------------------------- /tests/cli_tests/config/wallets/sharder01_node_delegate_wallet.json: -------------------------------------------------------------------------------- 1 | { 2 | "client_id": "b888ae3400b67a47362aad7d6263fcfeb6585fe696e8d182d3bb4f4a9d737bae", 3 | "client_key": "e2075a6d93dd3544e14a185b03e7bf5fbf402fe498452b3e786ddb6b500be2095eaa42ef748ccd0e139e6cc041c19da4dffa06ecb9b37bed783e4bffd89b8295", 4 | "keys": [ 5 | { 6 | "public_key": "e2075a6d93dd3544e14a185b03e7bf5fbf402fe498452b3e786ddb6b500be2095eaa42ef748ccd0e139e6cc041c19da4dffa06ecb9b37bed783e4bffd89b8295", 7 | "private_key": "0d3c9bf1844fb66cc98fd82c6a93d6ed0199aef8af3387cfdd7bc53f3e2aa602" 8 | } 9 | ], 10 | "mnemonics": "manage envelope elephant bamboo inmate blast legend quality vocal cushion black party mad mixture coyote prepare visit surge pair elite treat place match blouse", 11 | "version": "1.0", 12 | "date_created": "1661370992", 13 | "nonce": 0 14 | } -------------------------------------------------------------------------------- /tests/cli_tests/config/wallets/sharder02_node_delegate_wallet.json: -------------------------------------------------------------------------------- 1 | { 2 | "client_id": "b3e3f587dd65aaf4118adf87878a138dbb3163a3b169a0d1872aa9a7a0fa5c50", 3 | "client_key": "1f7d5b5d96b5f97d4dd6d421b9fa69dc9b9fd11768d71b387ec4c0607092f608f3f13481062a0dc3536f980e2962a52ca6a3bac6ad90cabd1d29b83d3a32a19f", 4 | "keys": [ 5 | { 6 | "public_key": "1f7d5b5d96b5f97d4dd6d421b9fa69dc9b9fd11768d71b387ec4c0607092f608f3f13481062a0dc3536f980e2962a52ca6a3bac6ad90cabd1d29b83d3a32a19f", 7 | "private_key": "2ba53541de3cb2ed6d1fc1489ef94479794f2180c052c7f7002d5db45f39f624" 8 | } 9 | ], 10 | "mnemonics": "secret mansion motor tissue grid host scorpion pill doll burger noble replace menu caution uniform clock long secret install pencil lock yellow coach dream", 11 | "version": "1.0", 12 | "date_created": "1661371000", 13 | "nonce": 0 14 | } -------------------------------------------------------------------------------- /tests/cli_tests/config/wallets/staking_wallet.json: -------------------------------------------------------------------------------- 1 | {"client_id":"f6f9fdbb244721cd4839135898a9b6bb3e929632865b0e3f9aa27f9f27659896","client_key":"9623de0125ec1e93ca474e5ae2d333d4d1b75604db7eea2f29498be50650231a5eba174762f6b9ec9dc5b7c822526056403a548d2a613fff0db72b19a81ff29a","keys":[{"public_key":"9623de0125ec1e93ca474e5ae2d333d4d1b75604db7eea2f29498be50650231a5eba174762f6b9ec9dc5b7c822526056403a548d2a613fff0db72b19a81ff29a","private_key":"c225c78f32702d157d8b7c00f6480a24490e133a71aaed77042b5285581bef0e"}],"mnemonics":"effort pelican sudden thought fence punch hedgehog emerge coast certain seat middle sting purchase diet alter spread motion story donkey have tank power smart","version":"1.0","date_created":"2024-02-09T11:20:55+01:00","nonce":0} -------------------------------------------------------------------------------- /tests/cli_tests/config/wallets/zbox_team_wallet.json: -------------------------------------------------------------------------------- 1 | {"client_id":"d4c5ad2959282b05a1c267c542c859271670da1b0b44f0714babfb87e57c3c83","client_key":"d7dba8a72b5752b37001d07247e3c7c475c6cb5374962ce608965aeefaa999142b3adfd34e9c1c9949210c05c45b5b51ddb83a3234b56983b3936b25717d6c8d","peer_public_key":"","keys":[{"public_key":"d7dba8a72b5752b37001d07247e3c7c475c6cb5374962ce608965aeefaa999142b3adfd34e9c1c9949210c05c45b5b51ddb83a3234b56983b3936b25717d6c8d","private_key":"26e4adfa189350df06bf1983569e03a50fb69d6112386e76610e8b08cc90a009"}],"mnemonics":"now segment air treat fame sport trouble open shed jewel bird shock cave shove quick embody hundred hole replace cheap mammal panel recycle decorate","version":"1.0","date_created":"2025-03-13T16:19:26Z","nonce":0,"is_split":false} -------------------------------------------------------------------------------- /tests/cli_tests/config/wallets/zcnsc_owner_wallet.json: -------------------------------------------------------------------------------- 1 | {"client_id":"1746b06bb09f55ee01b33b5e2e055d6cc7a900cb57c0a3a5eaabb8a0e7745802","client_key":"7b630ba670dac2f22d43c2399b70eff378689a53ee03ea20957bb7e73df016200fea410ba5102558b0c39617e5afd2c1843b161a1dedec15e1ab40543a78a518","keys":[{"public_key":"7b630ba670dac2f22d43c2399b70eff378689a53ee03ea20957bb7e73df016200fea410ba5102558b0c39617e5afd2c1843b161a1dedec15e1ab40543a78a518","private_key":"c06b6f6945ba02d5a3be86b8779deca63bb636ce7e46804a479c50e53c864915"}],"mnemonics":"cactus panther essence ability copper fox wise actual need cousin boat uncover ride diamond group jacket anchor current float rely tragic omit child payment","version":"1.0","date_created":"2021-08-04 18:53:56.949069945 +0100 BST m=+0.018986002"} -------------------------------------------------------------------------------- /tests/cli_tests/config/zbox_config.yaml: -------------------------------------------------------------------------------- 1 | block_worker: https://dev-st.devnet-0chain.net/dns 2 | confirmation_chain_length: 3 3 | ethereum_node_url: "https://rpc.tenderly.co/fork/5b7ffac9-50cc-4169-b0ca-6fd203d26ef6" 4 | min_confirmation: 50 5 | min_submit: 50 6 | signature_scheme: bls0chain 7 | store_unlock_duration_sec: 2 8 | 9 | bridge: 10 | bridge_address: 0x7700D773022b19622095118Fadf46f7B9448Be9b 11 | token_address: 0xb9EF770B6A5e12E45983C5D80545258aA38F3B78 12 | authorizers_address: 0x481daB4407b9880DE0A68dc62E6aF611c4949E42 13 | uniswap_address: 0x4c12C2FeEDD86267d17dB64BaB2cFD12cD8611f5 14 | ethereum_address: 0x8E25cfd9bd6c0ca67a5522cd920b3c66D39d6E97 15 | password: "12345678" -------------------------------------------------------------------------------- /tests/cli_tests/config2/config.yaml: -------------------------------------------------------------------------------- 1 | block_worker: https://dev.zus.network/dns 2 | confirmation_chain_length: 3 3 | ethereum_node_url: https://rpc.tenderly.co/fork/05077a9d-3973-4409-a3bf-eee719ca2806 4 | min_confirmation: 50 5 | min_submit: 50 6 | signature_scheme: bls0chain 7 | store_unlock_duration_sec: 2 8 | ethereum_address: 0xD8c9156e782C68EE671C09b6b92de76C97948432 9 | -------------------------------------------------------------------------------- /tests/cli_tests/config2/wallet.json: -------------------------------------------------------------------------------- 1 | { 2 | "client_id": "1746b06bb09f55ee01b33b5e2e055d6cc7a900cb57c0a3a5eaabb8a0e7745802", 3 | "client_key": "7b630ba670dac2f22d43c2399b70eff378689a53ee03ea20957bb7e73df016200fea410ba5102558b0c39617e5afd2c1843b161a1dedec15e1ab40543a78a518", 4 | "keys": [ 5 | { 6 | "public_key": "7b630ba670dac2f22d43c2399b70eff378689a53ee03ea20957bb7e73df016200fea410ba5102558b0c39617e5afd2c1843b161a1dedec15e1ab40543a78a518", 7 | "private_key": "c06b6f6945ba02d5a3be86b8779deca63bb636ce7e46804a479c50e53c864915" 8 | } 9 | ], 10 | "mnemonics": "cactus panther essence ability copper fox wise actual need cousin boat uncover ride diamond group jacket anchor current float rely tragic omit child payment", 11 | "version": "1.0", 12 | "date_created": "2021-08-04 18:53:56.949069945 +0100 BST m=+0.018986002" 13 | } 14 | -------------------------------------------------------------------------------- /tests/cli_tests/mc_tests/1_basic_operations_test.go: -------------------------------------------------------------------------------- 1 | package cli_tests 2 | 3 | import ( 4 | "os" 5 | "testing" 6 | "time" 7 | 8 | test "github.com/0chain/system_test/internal/api/util/test" 9 | cli_utils "github.com/0chain/system_test/internal/cli/util" 10 | "github.com/stretchr/testify/assert" 11 | ) 12 | 13 | func TestZs3Server(testSetup *testing.T) { 14 | t := test.NewSystemTest(testSetup) 15 | 16 | if _, err := os.Stat("../mc"); os.IsNotExist(err) { 17 | t.Fatalf("../mc is not installed") 18 | } else { 19 | t.Logf("../mc is installed") 20 | } 21 | 22 | defer func() { 23 | _, err := cli_utils.RunCommand(t, "rm -rf a.txt", 1, time.Hour*2) 24 | if err != nil { 25 | t.Logf("Error while deferring command: %v", err) 26 | } 27 | }() 28 | 29 | // listing the buckets in the command 30 | t.RunSequentially("Should list the buckets", func(t *test.SystemTest) { 31 | output, _ := cli_utils.RunCommand(t, "../mc ls play", 1, time.Hour*2) 32 | assert.NotContains(t, output, "error") 33 | }) 34 | 35 | t.RunSequentially("Test Bucket Creation", func(t *test.SystemTest) { 36 | output, _ := cli_utils.RunCommand(t, "../mc mb custombucket", 1, time.Hour*2) 37 | assert.Contains(t, output, "Bucket created successfully `custombucket`.") 38 | }) 39 | 40 | t.RunSequentially("Test Copying File Upload", func(t *test.SystemTest) { 41 | // create a file with content 42 | _, _ = cli_utils.RunCommand(t, "../mc mb custombucket", 1, time.Hour*2) 43 | 44 | file, err := os.Create("a.txt") 45 | if err != nil { 46 | t.Fatalf("Error creating file: %v", err) 47 | } 48 | defer file.Close() 49 | 50 | _, err = file.WriteString("test") 51 | if err != nil { 52 | t.Fatalf("Error writing to file: %v", err) 53 | } 54 | 55 | output, _ := cli_utils.RunCommand(t, "../mc cp a.txt custombucket", 1, time.Hour*2) 56 | 57 | assert.NotContains(t, output, "../mc: ") 58 | 59 | os.Remove("a.txt") 60 | }) 61 | 62 | t.RunSequentially("Test for moving file", func(t *test.SystemTest) { 63 | _, _ = cli_utils.RunCommand(t, "../mc mb custombucket", 1, time.Hour*2) 64 | 65 | file, err := os.Create("a.txt") 66 | if err != nil { 67 | t.Fatalf("Error creating file: %v", err) 68 | } 69 | defer file.Close() 70 | 71 | _, err = file.WriteString("test") 72 | if err != nil { 73 | t.Fatalf("Error writing to file: %v", err) 74 | } 75 | 76 | _, _ = cli_utils.RunCommand(t, "../mc cp a.txt custombucket", 1, time.Hour*2) 77 | 78 | output, _ := cli_utils.RunCommand(t, "../mc mv custombucket/a.txt custombucket/b", 1, time.Hour*2) 79 | assert.NotContains(t, output, "../mc: ") 80 | }) 81 | 82 | t.RunSequentially("Test for copying file ", func(t *test.SystemTest) { 83 | output, _ := cli_utils.RunCommand(t, "../mc cp a.txt custombucket", 1, time.Hour*2) 84 | 85 | assert.NotContains(t, output, "../mc: ") 86 | }) 87 | 88 | t.RunSequentially("Test for removing file", func(t *test.SystemTest) { 89 | output, _ := cli_utils.RunCommand(t, "../mc rm custombucket/a.txt", 1, time.Hour*2) 90 | assert.Contains(t, output, "Removed `custombucket/a.txt`.") 91 | }) 92 | } 93 | -------------------------------------------------------------------------------- /tests/cli_tests/mc_tests/2_bucket_to_bucket_test.go: -------------------------------------------------------------------------------- 1 | package cli_tests 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "testing" 7 | "time" 8 | 9 | test "github.com/0chain/system_test/internal/api/util/test" 10 | cli_utils "github.com/0chain/system_test/internal/cli/util" 11 | 12 | "github.com/stretchr/testify/assert" 13 | ) 14 | 15 | func TestZs3ServerBucket(testSetup *testing.T) { 16 | t := test.NewSystemTest(testSetup) 17 | 18 | // test for moving the file from testbucket to testbucket2 19 | t.RunSequentially("Test for moving file from testbucket to testbucket2", func(t *test.SystemTest) { 20 | _, err := cli_utils.RunCommand(t, "../mc mb testbucket", 1, time.Hour*2) 21 | 22 | if err != nil { 23 | t.Fatalf("Error creating bucket: %v", err) 24 | } 25 | 26 | _, err = cli_utils.RunCommand(t, "../mc mb testbucket2", 1, time.Hour*2) 27 | if err != nil { 28 | t.Fatalf("Error creating bucket: %v", err) 29 | } 30 | 31 | file, err := os.Create("a.txt") 32 | if err != nil { 33 | t.Fatalf("Error creating file: %v", err) 34 | } 35 | defer file.Close() 36 | 37 | _, err = file.WriteString("test") 38 | if err != nil { 39 | t.Fatalf("Error writing to file: %v", err) 40 | } 41 | 42 | output_ls, _ := cli_utils.RunCommand(t, "../mc mv a.txt testbucket", 1, time.Hour*2) 43 | 44 | assert.NotContains(t, output_ls, "../mc: ") 45 | output, _ := cli_utils.RunCommand(t, "../mc mv testbucket/a.txt testbucket2 ", 1, time.Hour*2) 46 | // output is in format ...sts/./mc_tests/testbucket/a.txt: 4 B / 4 B ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ 707 B/s 0s 47 | 48 | assert.NotContains(t, output, "../mc: ") 49 | if _, err := os.Stat("testbucket2/a.txt"); err != nil { 50 | t.Errorf("Local file %s not found: %v", "testbucket2/a.txt", err) 51 | } 52 | 53 | // Assert that the local file exists 54 | assert.NoError(t, err, fmt.Sprintf("Local file %s should exist", "testbucket2/a.txt")) 55 | }) 56 | } 57 | -------------------------------------------------------------------------------- /tests/cli_tests/mc_tests/3_replication_disaster_recovery_test.go: -------------------------------------------------------------------------------- 1 | package cli_tests 2 | 3 | import ( 4 | "os" 5 | "strings" 6 | "testing" 7 | "time" 8 | 9 | test "github.com/0chain/system_test/internal/api/util/test" 10 | cli_utils "github.com/0chain/system_test/internal/cli/util" 11 | "github.com/stretchr/testify/assert" 12 | ) 13 | 14 | func TestZs3ServerReplication(testSetup *testing.T) { 15 | t := test.NewSystemTest(testSetup) 16 | config := cli_utils.ReadFileMC(testSetup) 17 | 18 | t.RunWithTimeout("Test for replication", 4000*time.Second, func(t *test.SystemTest) { 19 | t.Log(config.Server, "server") 20 | command_primary := "../mc alias set primary http://" + config.Server + ":" + config.HostPort + " " + config.AccessKey + " " + config.SecretKey + " --api S3v2" 21 | t.Log(command_primary, "command Generated") 22 | 23 | command_secondary := "../mc alias set secondary http://" + config.SecondaryServer + ":" + config.SecondaryPort + " " + config.AccessKey + " " + config.SecretKey + " --api S3v2" 24 | t.Log(command_secondary, "command Generated") 25 | 26 | _, _ = cli_utils.RunCommand(t, command_primary, 1, time.Hour*2) 27 | _, _ = cli_utils.RunCommand(t, command_secondary, 1, time.Hour*2) 28 | 29 | _, _ = cli_utils.RunCommand(t, "../mc mb primary/mybucket", 1, time.Hour*2) 30 | 31 | file, err := os.Create("a.txt") 32 | if err != nil { 33 | t.Fatalf("Error creating file: %v", err) 34 | } 35 | defer file.Close() 36 | 37 | _, err = file.WriteString("test") 38 | if err != nil { 39 | t.Fatalf("Error writing to file: %v", err) 40 | } 41 | 42 | _, _ = cli_utils.RunCommand(t, "../mc mb secondary/mirrorbucket", 1, time.Hour*2) 43 | 44 | t.Log("copying... the a.txt") 45 | _, _ = cli_utils.RunCommand(t, "../mc cp a.txt primary/mybucket", 1, time.Second*2) 46 | 47 | _, _ = cli_utils.RunCommand(t, "../mc mirror --overwrite primary/mybucket secondary/mirrorbucket ", 1, time.Minute*2) 48 | 49 | t.Log("removing... the a.txt from primary bucket") 50 | _, _ = cli_utils.RunCommand(t, "../mc rm primary/mybucket/a.txt", 1, time.Second*2) 51 | t.Log("listing... secondary bucket") 52 | 53 | output, err := cli_utils.RunCommand(t, "../mc ls secondary/mirrorbucket", 1, time.Second*2) 54 | if err != nil { 55 | t.Log(err, "err of command") 56 | } 57 | 58 | t.Log("All operations are completed") 59 | t.Log("Cleaning up ..... ") 60 | _, _ = cli_utils.RunCommand(t, "../mc rm primary/mybucket", 1, time.Hour*2) 61 | _, _ = cli_utils.RunCommand(t, "../mc rm secondary/mirrorbucket", 1, time.Hour*2) 62 | 63 | _, _ = cli_utils.RunCommand(t, "../mc alias rm primary", 1, 2*time.Hour) 64 | _, _ = cli_utils.RunCommand(t, "../mc alias rm secondary", 1, 2*time.Hour) 65 | _ = os.Remove("a.txt") 66 | 67 | assert.Contains(t, strings.Join(output, "\n"), "a.txt") 68 | _, err = cli_utils.KillProcess() 69 | 70 | if err != nil { 71 | t.Logf("Error killing the command process") 72 | } 73 | }) 74 | } 75 | -------------------------------------------------------------------------------- /tests/cli_tests/mc_tests/mc_hosts.yaml: -------------------------------------------------------------------------------- 1 | server: localhost 2 | port: 9000 3 | # access_key: someminiouser 4 | # secret_key: someminiopassword 5 | concurrent: 900 6 | secondary_server: localhost 7 | secondary_port: 9000 8 | use_command: True 9 | # server: 65.109.152.43 10 | # port: 9001 11 | access_key: rootroot 12 | secret_key: rootroot 13 | # concurrent: 900 14 | # secondary_server: 65.109.152.43 15 | # secondary_port: 9002 16 | -------------------------------------------------------------------------------- /tests/cli_tests/zboxcli_blobber_availability_test.go: -------------------------------------------------------------------------------- 1 | package cli_tests 2 | 3 | import ( 4 | "strconv" 5 | "strings" 6 | "testing" 7 | "time" 8 | 9 | cliutil "github.com/0chain/system_test/internal/cli/util" 10 | 11 | "github.com/0chain/system_test/internal/cli/model" 12 | "github.com/stretchr/testify/require" 13 | 14 | "github.com/0chain/system_test/internal/api/util/test" 15 | ) 16 | 17 | func TestBlobberAvailability(testSetup *testing.T) { 18 | t := test.NewSystemTest(testSetup) 19 | t.SetSmokeTests("blobber is available switch controls blobber use for allocations") 20 | 21 | t.RunSequentially("blobber is available switch controls blobber use for allocations", func(t *test.SystemTest) { 22 | createWallet(t) 23 | 24 | startBlobbers := getBlobbers(t) 25 | var blobberToDeactivate *model.BlobberDetails 26 | var activeBlobbers int 27 | for i := range startBlobbers { 28 | if !startBlobbers[i].NotAvailable && !startBlobbers[i].IsKilled && !startBlobbers[i].IsShutdown { 29 | activeBlobbers++ 30 | if blobberToDeactivate == nil { 31 | blobberToDeactivate = &startBlobbers[i] 32 | } 33 | } 34 | } 35 | require.NotEqual(t, blobberToDeactivate, "", "no active blobbers") 36 | require.True(t, activeBlobbers > 2, "need at least three active blobbers") 37 | dataShards := 1 38 | parityShards := activeBlobbers - dataShards 39 | 40 | output, err := createNewAllocation(t, configPath, createParams(map[string]interface{}{ 41 | "data": strconv.Itoa(dataShards), 42 | "parity": strconv.Itoa(parityShards), 43 | "lock": "3.0", 44 | "size": "10000", 45 | })) 46 | require.NoError(t, err, strings.Join(output, "\n")) 47 | beforeAllocationId, err := getAllocationID(output[0]) 48 | require.NoError(t, err, "error getting allocation id") 49 | beforeAllocation := getAllocation(t, beforeAllocationId) 50 | 51 | setNotAvailability(t, blobberToDeactivate.ID, true) 52 | t.Cleanup(func() { setNotAvailability(t, blobberToDeactivate.ID, false) }) 53 | cliutil.Wait(t, 1*time.Second) 54 | betweenBlobbers := getBlobbers(t) 55 | for i := range betweenBlobbers { 56 | if betweenBlobbers[i].ID == blobberToDeactivate.ID { 57 | require.Falsef(t, !betweenBlobbers[i].NotAvailable, "blobber %s should be deactivated", blobberToDeactivate.ID) 58 | } 59 | } 60 | 61 | output, err = createNewAllocation(t, configPath, createParams(map[string]interface{}{ 62 | "data": strconv.Itoa(dataShards), 63 | "parity": strconv.Itoa(parityShards), 64 | "lock": "3.0", 65 | "size": "10000", 66 | })) 67 | require.Error(t, err, "create allocation should fail") 68 | require.Len(t, output, 1) 69 | require.True(t, strings.Contains(output[0], "not enough blobbers to honor the allocation")) 70 | 71 | output, err = updateAllocation(t, configPath, createParams(map[string]interface{}{ 72 | "allocation": beforeAllocationId, 73 | "extend": true, 74 | }), true) 75 | require.Nil(t, err, "error updating allocation", strings.Join(output, "\n")) 76 | 77 | afterAlloc := getAllocation(t, beforeAllocationId) 78 | require.Greater(t, afterAlloc.ExpirationDate, beforeAllocation.ExpirationDate) 79 | createAllocationTestTeardown(t, beforeAllocationId) 80 | 81 | setNotAvailability(t, blobberToDeactivate.ID, false) 82 | cliutil.Wait(t, 1*time.Second) 83 | afterBlobbers := getBlobbers(t) 84 | for i := range betweenBlobbers { 85 | if afterBlobbers[i].ID == blobberToDeactivate.ID { 86 | require.Truef(t, !afterBlobbers[i].NotAvailable, "blobber %s should be activated", blobberToDeactivate.ID) 87 | } 88 | } 89 | 90 | output, err = createNewAllocation(t, configPath, createParams(map[string]interface{}{ 91 | "data": strconv.Itoa(dataShards), 92 | "parity": strconv.Itoa(parityShards), 93 | "lock": "3.0", 94 | "size": "10000", 95 | })) 96 | require.NoError(t, err, strings.Join(output, "\n")) 97 | afterAllocationId, err := getAllocationID(output[0]) 98 | require.NoError(t, err, "error getting allocation id") 99 | createAllocationTestTeardown(t, afterAllocationId) 100 | }) 101 | } 102 | 103 | func setNotAvailability(t *test.SystemTest, blobberId string, availability bool) { 104 | output, err := updateBlobberInfo(t, configPath, createParams(map[string]interface{}{ 105 | "blobber_id": blobberId, 106 | "not_available": availability, 107 | })) 108 | require.NoError(t, err, strings.Join(output, "\n")) 109 | require.Len(t, output, 1) 110 | } 111 | -------------------------------------------------------------------------------- /tests/cli_tests/zboxcli_cancel_allocation_test.go: -------------------------------------------------------------------------------- 1 | package cli_tests 2 | 3 | import ( 4 | "fmt" 5 | "regexp" 6 | "strings" 7 | "testing" 8 | "time" 9 | 10 | "github.com/0chain/system_test/internal/api/util/test" 11 | 12 | "github.com/stretchr/testify/require" 13 | 14 | cliutils "github.com/0chain/system_test/internal/cli/util" 15 | ) 16 | 17 | var ( 18 | cancelAllocationRegex = regexp.MustCompile(`^Allocation canceled with txId : [a-f0-9]{64}$`) 19 | ) 20 | 21 | func TestCancelAllocation(testSetup *testing.T) { 22 | t := test.NewSystemTest(testSetup) 23 | t.SetSmokeTests("Cancel allocation immediately should work") 24 | 25 | t.Parallel() 26 | 27 | t.Run("Cancel allocation immediately should work", func(t *test.SystemTest) { 28 | allocationID := setupAllocation(t, configPath) 29 | 30 | output, err := cancelAllocation(t, configPath, allocationID, true) 31 | require.NoError(t, err, "cancel allocation failed but should succeed", strings.Join(output, "\n")) 32 | require.Len(t, output, 1) 33 | assertOutputMatchesAllocationRegex(t, cancelAllocationRegex, output[0]) 34 | }) 35 | 36 | t.RunWithTimeout("Cancel allocation after upload should work", 5*time.Minute, func(t *test.SystemTest) { 37 | allocationID := setupAllocation(t, configPath) 38 | 39 | filename := generateRandomTestFileName(t) 40 | err := createFileWithSize(filename, 1*MB) 41 | require.Nil(t, err) 42 | 43 | output, err := uploadFile(t, configPath, map[string]interface{}{ 44 | "allocation": allocationID, 45 | "remotepath": "/", 46 | "localpath": filename, 47 | }, true) 48 | require.Nil(t, err, strings.Join(output, "\n")) 49 | require.Len(t, output, 2) 50 | 51 | time.Sleep(1 * time.Minute) 52 | 53 | output, err = cancelAllocation(t, configPath, allocationID, true) 54 | require.NoError(t, err, "cancel allocation failed but should succeed", strings.Join(output, "\n")) 55 | require.Len(t, output, 1) 56 | assertOutputMatchesAllocationRegex(t, cancelAllocationRegex, output[0]) 57 | }) 58 | 59 | t.Run("No allocation param should fail", func(t *test.SystemTest) { 60 | // create wallet 61 | createWallet(t) 62 | 63 | cmd := fmt.Sprintf( 64 | "./zbox alloc-cancel --silent "+ 65 | "--wallet %s --configDir ./config --config %s", 66 | escapedTestName(t)+"_wallet.json", 67 | configPath, 68 | ) 69 | 70 | output, err := cliutils.RunCommandWithoutRetry(cmd) 71 | require.Error(t, err, "expected error canceling allocation", strings.Join(output, "\n")) 72 | require.Len(t, output, 1) 73 | require.Equal(t, "Error: allocation flag is missing", output[0]) 74 | }) 75 | 76 | t.Run("Cancel Other's Allocation Should Fail", func(t *test.SystemTest) { 77 | otherAllocationID := setupAllocationWithWallet(t, escapedTestName(t)+"_other_wallet.json", configPath) 78 | 79 | createWallet(t) 80 | // otherAllocationID should not be cancelable from this level 81 | output, err := cancelAllocation(t, configPath, otherAllocationID, false) 82 | 83 | require.Error(t, err, "expected error canceling allocation", strings.Join(output, "\n")) 84 | require.True(t, len(output) > 0, "expected output length be at least 1", strings.Join(output, "\n")) 85 | require.Equal(t, "Error canceling allocation:alloc_cancel_failed: only owner can cancel an allocation", output[len(output)-1]) 86 | }) 87 | 88 | t.Run("Cancel Non-existent Allocation Should Fail", func(t *test.SystemTest) { 89 | createWallet(t) 90 | 91 | allocationID := "123abc" 92 | 93 | output, err := cancelAllocation(t, configPath, allocationID, false) 94 | 95 | require.Error(t, err, "expected error updating allocation", strings.Join(output, "\n")) 96 | require.Equal(t, "Error canceling allocation:alloc_cancel_failed: value not present", output[0]) 97 | }) 98 | } 99 | 100 | func cancelAllocation(t *test.SystemTest, cliConfigFilename, allocationID string, retry bool) ([]string, error) { 101 | t.Logf("Canceling allocation...") 102 | cmd := fmt.Sprintf( 103 | "./zbox alloc-cancel --allocation %s --silent "+ 104 | "--wallet %s --configDir ./config --config %s", 105 | allocationID, 106 | escapedTestName(t)+"_wallet.json", 107 | cliConfigFilename, 108 | ) 109 | 110 | if retry { 111 | return cliutils.RunCommand(t, cmd, 3, time.Second*2) 112 | } else { 113 | return cliutils.RunCommandWithoutRetry(cmd) 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /tests/cli_tests/zboxcli_finalize_allocation_test.go: -------------------------------------------------------------------------------- 1 | package cli_tests 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | "testing" 7 | "time" 8 | 9 | "github.com/0chain/system_test/internal/api/util/test" 10 | 11 | cliutils "github.com/0chain/system_test/internal/cli/util" 12 | "github.com/stretchr/testify/require" 13 | ) 14 | 15 | func TestFinalizeAllocation(testSetup *testing.T) { 16 | t := test.NewSystemTest(testSetup) 17 | 18 | t.Parallel() 19 | 20 | t.Run("Finalize Non-Expired Allocation Should Fail", func(t *test.SystemTest) { 21 | allocationID := setupAllocation(t, configPath) 22 | 23 | output, err := finalizeAllocation(t, configPath, allocationID, false) 24 | require.NotNil(t, err, "expected error updating allocation", strings.Join(output, "\n")) 25 | require.True(t, len(output) > 0, "expected output length be at least 1", strings.Join(output, "\n")) 26 | require.Equal(t, "Error finalizing allocation:fini_alloc_failed: allocation is not expired yet", output[0]) 27 | }) 28 | 29 | t.Run("Finalize Other's Allocation Should Fail", func(t *test.SystemTest) { 30 | var otherAllocationID = setupAllocationWithWallet(t, escapedTestName(t)+"_other_wallet.json", configPath) 31 | 32 | // create wallet 33 | createWallet(t) 34 | // Then try updating with otherAllocationID: should not work 35 | output, err := finalizeAllocation(t, configPath, otherAllocationID, false) 36 | 37 | // Error should not be nil since finalize is not working 38 | require.NotNil(t, err, "expected error finalizing allocation", strings.Join(output, "\n")) 39 | require.True(t, len(output) > 0, "expected output length be at least 1", strings.Join(output, "\n")) 40 | require.Equal(t, "Error finalizing allocation:fini_alloc_failed: not allowed, unknown finalization initiator", output[len(output)-1]) 41 | }) 42 | 43 | t.Run("No allocation param should fail", func(t *test.SystemTest) { 44 | createWallet(t) 45 | 46 | cmd := fmt.Sprintf( 47 | "./zbox alloc-fini --silent "+ 48 | "--wallet %s --configDir ./config --config %s", 49 | escapedTestName(t)+"_wallet.json", 50 | configPath, 51 | ) 52 | 53 | output, err := cliutils.RunCommandWithoutRetry(cmd) 54 | require.Error(t, err, "expected error finalizing allocation", strings.Join(output, "\n")) 55 | require.Len(t, output, 1) 56 | require.Equal(t, "Error: allocation flag is missing", output[len(output)-1]) 57 | }) 58 | } 59 | 60 | func finalizeAllocation(t *test.SystemTest, cliConfigFilename, allocationID string, retry bool) ([]string, error) { 61 | t.Logf("Finalizing allocation...") 62 | cmd := fmt.Sprintf( 63 | "./zbox alloc-fini --allocation %s "+ 64 | "--silent --wallet %s --configDir ./config --config %s", 65 | allocationID, 66 | escapedTestName(t)+"_wallet.json", 67 | cliConfigFilename, 68 | ) 69 | if retry { 70 | return cliutils.RunCommand(t, cmd, 3, time.Second*2) 71 | } else { 72 | return cliutils.RunCommandWithoutRetry(cmd) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /tests/cli_tests/zboxcli_max_file_test.go: -------------------------------------------------------------------------------- 1 | package cli_tests 2 | 3 | import ( 4 | "path/filepath" 5 | "strings" 6 | "testing" 7 | "time" 8 | 9 | "github.com/0chain/system_test/internal/api/util/test" 10 | "github.com/0chain/system_test/tests/tokenomics_tests/utils" 11 | "github.com/stretchr/testify/require" 12 | ) 13 | 14 | func TestMaxFileSize(testSetup *testing.T) { 15 | t := test.NewSystemTest(testSetup) 16 | 17 | t.TestSetup("Create new owner wallet", func() { 18 | output, err := updateStorageSCConfig(t, scOwnerWallet, map[string]string{ 19 | "max_file_size": "1024", 20 | }, true) 21 | require.Nil(t, err, strings.Join(output, "\n")) 22 | 23 | time.Sleep(2 * time.Minute) // Wait for config to take effect on blobber 24 | }) 25 | 26 | t.Cleanup(func() { 27 | output, err := updateStorageSCConfig(t, scOwnerWallet, map[string]string{ 28 | "max_file_size": "1000000000000", 29 | }, true) 30 | require.Nil(t, err, strings.Join(output, "\n")) 31 | }) 32 | 33 | t.Run("should be able to upload files equal or smaller than max_file_size per blobber", func(t *test.SystemTest) { 34 | output, err := utils.CreateWallet(t, configPath) 35 | require.Nil(t, err, "Error registering wallet", strings.Join(output, "\n")) 36 | 37 | _, err = utils.ExecuteFaucetWithTokens(t, configPath, 9) 38 | require.Nil(t, err, "Error executing faucet", strings.Join(output, "\n")) 39 | 40 | output, err = utils.CreateNewAllocation(t, configPath, utils.CreateParams(map[string]interface{}{ 41 | "size": 10 * MB, 42 | "data": 1, 43 | "lock": 2, 44 | "parity": 1, 45 | })) 46 | require.Nil(t, err, "Error creating allocation", strings.Join(output, "\n")) 47 | 48 | allocationId, err := utils.GetAllocationID(output[0]) 49 | require.Nil(t, err, "Error getting allocation ID", strings.Join(output, "\n")) 50 | 51 | remotepath := "/dir/" 52 | filesize := 1024 53 | filename := utils.GenerateRandomTestFileName(t) 54 | 55 | err = utils.CreateFileWithSize(filename, int64(filesize)) 56 | require.Nil(t, err) 57 | 58 | output, err = utils.UploadFile(t, configPath, map[string]interface{}{ 59 | "allocation": allocationId, 60 | "remotepath": remotepath + filepath.Base(filename), 61 | "localpath": filename, 62 | }, true) 63 | require.Nil(t, err, "error uploading file", strings.Join(output, "\n")) 64 | }) 65 | 66 | t.Run("upload should fail on sizes higher than max_file_size per blobber", func(t *test.SystemTest) { 67 | output, err := utils.CreateWallet(t, configPath) 68 | require.Nil(t, err, "Error registering wallet", strings.Join(output, "\n")) 69 | 70 | _, err = utils.ExecuteFaucetWithTokens(t, configPath, 9) 71 | require.Nil(t, err, "Error executing faucet", strings.Join(output, "\n")) 72 | 73 | output, err = utils.CreateNewAllocation(t, configPath, utils.CreateParams(map[string]interface{}{ 74 | "size": 10 * MB, 75 | "data": 1, 76 | "lock": 2, 77 | "parity": 1, 78 | })) 79 | require.Nil(t, err, "Error creating allocation", strings.Join(output, "\n")) 80 | 81 | allocationId, err := utils.GetAllocationID(output[0]) 82 | require.Nil(t, err, "Error getting allocation ID", strings.Join(output, "\n")) 83 | 84 | remotepath := "/dir/" 85 | filesize := 2048 86 | filename := utils.GenerateRandomTestFileName(t) 87 | 88 | err = utils.CreateFileWithSize(filename, int64(filesize)) 89 | require.Nil(t, err) 90 | 91 | _, err = utils.UploadFile(t, configPath, map[string]interface{}{ 92 | "allocation": allocationId, 93 | "remotepath": remotepath + filepath.Base(filename), 94 | "localpath": filename, 95 | }, false) 96 | require.Error(t, err, "Upload should fail") 97 | }) 98 | } 99 | -------------------------------------------------------------------------------- /tests/cli_tests/zboxcli_repair_test.go: -------------------------------------------------------------------------------- 1 | package cli_tests 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "path/filepath" 7 | "strings" 8 | "testing" 9 | "time" 10 | 11 | "github.com/0chain/system_test/internal/api/util/test" 12 | "github.com/0chain/system_test/internal/cli/model" 13 | cliutils "github.com/0chain/system_test/internal/cli/util" 14 | "github.com/stretchr/testify/require" 15 | ) 16 | 17 | func TestRepairSize(testSetup *testing.T) { 18 | t := test.NewSystemTest(testSetup) 19 | 20 | t.RunSequentiallyWithTimeout("repair size should work", 5*time.Minute, func(t *test.SystemTest) { 21 | allocSize := int64(1 * MB) 22 | fileSize := int64(512 * KB) 23 | 24 | allocationID := setupAllocation(t, configPath, map[string]interface{}{ 25 | "size": allocSize, 26 | "parity": 1, 27 | "data": 1, 28 | }) 29 | 30 | filename := generateRandomTestFileName(t) 31 | err := createFileWithSize(filename, fileSize) 32 | require.Nil(t, err) 33 | 34 | output, err := uploadFile(t, configPath, map[string]interface{}{ 35 | "allocation": allocationID, 36 | "remotepath": "/", 37 | "localpath": filename, 38 | }, true) 39 | require.Nil(t, err, strings.Join(output, "\n")) 40 | require.Len(t, output, 2) 41 | 42 | expected := fmt.Sprintf( 43 | "Status completed callback. Type = text/plain. Name = %s", 44 | filepath.Base(filename), 45 | ) 46 | require.Equal(t, expected, output[1]) 47 | 48 | output, err = getRepairSize(t, configPath, map[string]interface{}{ 49 | "allocation": allocationID, 50 | "repairpath": "/", 51 | }, true) 52 | require.Nilf(t, err, "error getting repair size: %v", err) 53 | var rs model.RepairSize 54 | err = json.Unmarshal([]byte(output[0]), &rs) 55 | require.Nilf(t, err, "error unmarshal repair size: %v", err) 56 | require.Equal(t, uint64(0), rs.UploadSize, "upload size should be zero") 57 | require.Equal(t, uint64(0), rs.DownloadSize, "download size should be zero") 58 | // optional repairpath 59 | output, err = getRepairSize(t, configPath, map[string]interface{}{ 60 | "allocation": allocationID, 61 | }, true) 62 | require.Nilf(t, err, "error getting repair size: %v", err) 63 | var rs2 model.RepairSize 64 | err = json.Unmarshal([]byte(output[0]), &rs2) 65 | require.Nilf(t, err, "error unmarshal repair size: %v", err) 66 | require.Equal(t, uint64(0), rs2.UploadSize, "upload size should be zero") 67 | require.Equal(t, uint64(0), rs2.DownloadSize, "download size should be zero") 68 | }) 69 | } 70 | 71 | func getRepairSize(t *test.SystemTest, cliConfigFilename string, param map[string]interface{}, retry bool) ([]string, error) { 72 | return getRepairSizeForWallet(t, escapedTestName(t), cliConfigFilename, param, retry) 73 | } 74 | 75 | func getRepairSizeForWallet(t *test.SystemTest, wallet, cliConfigFilename string, param map[string]interface{}, retry bool) ([]string, error) { 76 | t.Logf("getting Repair size...") 77 | 78 | p := createParams(param) 79 | cmd := fmt.Sprintf( 80 | "./zbox repair-size %s --silent --wallet %s_wallet.json --configDir ./config --config %s", 81 | p, 82 | wallet, 83 | cliConfigFilename, 84 | ) 85 | 86 | if retry { 87 | return cliutils.RunCommand(t, cmd, 3, time.Second*40) 88 | } else { 89 | return cliutils.RunCommandWithoutRetry(cmd) 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /tests/cli_tests/zboxcli_upload_token_test.go: -------------------------------------------------------------------------------- 1 | package cli_tests 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "regexp" 7 | "strings" 8 | "testing" 9 | "time" 10 | 11 | "github.com/0chain/system_test/internal/api/util/test" 12 | 13 | climodel "github.com/0chain/system_test/internal/cli/model" 14 | cliutils "github.com/0chain/system_test/internal/cli/util" 15 | "github.com/stretchr/testify/require" 16 | ) 17 | 18 | const tokenUnit float64 = 1e+10 19 | 20 | func TestFileUploadTokenMovement(testSetup *testing.T) { 21 | t := test.NewSystemTest(testSetup) 22 | t.SetSmokeTests("Challenge pool should be 0 before any write") 23 | 24 | t.Parallel() 25 | 26 | balance := 0.8 // 800.000 mZCN 27 | t.Run("Challenge pool should be 0 before any write", func(t *test.SystemTest) { 28 | createWallet(t) 29 | 30 | allocParam := createParams(map[string]interface{}{ 31 | "lock": balance, 32 | "size": 10000, 33 | }) 34 | output, err := createNewAllocation(t, configPath, allocParam) 35 | require.Nil(t, err, "Failed to create new allocation", strings.Join(output, "\n")) 36 | require.Len(t, output, 1) 37 | 38 | allocationID := strings.Fields(output[0])[2] 39 | 40 | output, err = challengePoolInfo(t, configPath, allocationID) 41 | require.Nil(t, err, "Could not fetch challenge pool", strings.Join(output, "\n")) 42 | require.Len(t, output, 1) 43 | 44 | challengePool := climodel.ChallengePoolInfo{} 45 | err = json.Unmarshal([]byte(output[0]), &challengePool) 46 | require.Nil(t, err, "Error unmarshalling challenge pool info", strings.Join(output, "\n")) 47 | require.NotEmpty(t, challengePool) 48 | 49 | require.Regexp(t, regexp.MustCompile(fmt.Sprintf("([a-f0-9]{64}):challengepool:%s", allocationID)), challengePool.Id) 50 | require.IsType(t, int64(0), challengePool.StartTime) 51 | require.IsType(t, int64(0), challengePool.Expiration) 52 | require.False(t, challengePool.Finalized) 53 | require.Equal(t, float64(0), float64(challengePool.Balance)) 54 | }) 55 | 56 | t.Run("Total balance in blobber pool equals locked tokens", func(t *test.SystemTest) { 57 | createWallet(t) 58 | 59 | allocParam := createParams(map[string]interface{}{ 60 | "lock": balance, 61 | "size": 10000, 62 | }) 63 | output, err := createNewAllocation(t, configPath, allocParam) 64 | require.Nil(t, err, "Failed to create new allocation", strings.Join(output, "\n")) 65 | 66 | require.Len(t, output, 1) 67 | require.Regexp(t, regexp.MustCompile("Allocation created: ([a-f0-9]{64})"), output[0], "Allocation creation output did not match expected") 68 | 69 | allocationID := strings.Fields(output[0])[2] 70 | 71 | allocation := getAllocation(t, allocationID) 72 | require.Equal(t, 0.8, intToZCN(allocation.WritePool)) 73 | }) 74 | } 75 | 76 | func getUploadCostInUnit(t *test.SystemTest, cliConfigFilename, allocationID, localpath string) ([]string, error) { 77 | t.Logf("Getting upload cost...") 78 | output, err := cliutils.RunCommand(t, "./zbox get-upload-cost --allocation "+allocationID+" --end --localpath "+localpath+" --silent --wallet "+escapedTestName(t)+"_wallet.json"+" --configDir ./config --config "+cliConfigFilename, 3, time.Second*2) 79 | require.Nil(t, err, "error getting upload cost in unit", strings.Join(output, "\n")) 80 | require.Len(t, output, 1) 81 | return output, err 82 | } 83 | 84 | func challengePoolInfo(t *test.SystemTest, cliConfigFilename, allocationID string) ([]string, error) { 85 | t.Logf("Getting challenge pool info...") 86 | return cliutils.RunCommand(t, "./zbox cp-info --allocation "+allocationID+" --json --silent --wallet "+escapedTestName(t)+"_wallet.json"+" --configDir ./config --config "+cliConfigFilename, 3, time.Second*2) 87 | } 88 | 89 | func intToZCN(balance int64) float64 { 90 | return float64(balance) / tokenUnit 91 | } 92 | -------------------------------------------------------------------------------- /tests/cli_tests/zs3server_tests/1_mixed_test.go: -------------------------------------------------------------------------------- 1 | package zs3servertests 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | "time" 7 | 8 | test "github.com/0chain/system_test/internal/api/util/test" 9 | cliutils "github.com/0chain/system_test/internal/cli/util" 10 | ) 11 | 12 | func TestZs3serverMixedWarpTests(testSetup *testing.T) { 13 | config := cliutils.ReadFile(testSetup) 14 | t := test.NewSystemTest(testSetup) 15 | 16 | t.RunSequentiallyWithTimeout("Warp Mixed Benchmark", 40*time.Minute, func(t *test.SystemTest) { 17 | commandGenerated := "../warp mixed --host=" + config.Server + ":" + config.HostPort + " --access-key=" + config.AccessKey + " --secret-key=" + config.SecretKey + " --objects=" + "22" + " --duration=" + "30s" + " --obj.size=" + "256B" 18 | output, err := cliutils.RunCommand(t, commandGenerated, 1, time.Hour*2) 19 | if err != nil { 20 | testSetup.Fatalf("Error running warp mixed: %v\nOutput: %s", err, output) 21 | } 22 | output_string := strings.Join(output, "\n") 23 | err = cliutils.AppendToFile("warp-mixed_output.txt", output_string) 24 | 25 | if err != nil { 26 | testSetup.Fatalf("Error appending to file: %v\n", err) 27 | } 28 | }) 29 | } 30 | -------------------------------------------------------------------------------- /tests/cli_tests/zs3server_tests/2_put_test.go: -------------------------------------------------------------------------------- 1 | package zs3servertests 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | "time" 7 | 8 | test "github.com/0chain/system_test/internal/api/util/test" 9 | cliutils "github.com/0chain/system_test/internal/cli/util" 10 | ) 11 | 12 | func TestZs3serverPutWarpTests(testSetup *testing.T) { 13 | config := cliutils.ReadFile(testSetup) 14 | t := test.NewSystemTest(testSetup) 15 | 16 | commandGenerated := "../warp put --host=" + config.Server + ":" + config.HostPort + " --access-key=" + config.AccessKey + " --secret-key=" + config.SecretKey + " --concurrent " + config.Concurrent + " --duration 30s" + " --obj.size " + config.ObjectSize 17 | output, err := cliutils.RunCommand(t, commandGenerated, 1, time.Hour*2) 18 | 19 | if err != nil { 20 | testSetup.Fatalf("Error running warp put: %v\nOutput: %s", err, output) 21 | } 22 | output_string := strings.Join(output, "\n") 23 | output_string = strings.Split(output_string, "----------------------------------------")[1] 24 | 25 | output_string = "Condition 2 : Put \n--------\n" + output_string 26 | err = cliutils.AppendToFile("warp-put_output.txt", output_string) 27 | 28 | if err != nil { 29 | testSetup.Fatalf("Error appending to file: %v\n", err) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/cli_tests/zs3server_tests/3_fanout_test.go: -------------------------------------------------------------------------------- 1 | package zs3servertests 2 | 3 | import ( 4 | "log" 5 | "os" 6 | "strings" 7 | "testing" 8 | "time" 9 | 10 | test "github.com/0chain/system_test/internal/api/util/test" 11 | cliutils "github.com/0chain/system_test/internal/cli/util" 12 | ) 13 | 14 | func TestZs3serverFanoutTests(testSetup *testing.T) { 15 | timeout := time.Duration(200 * time.Minute) 16 | err := os.Setenv("GO_TEST_TIMEOUT", timeout.String()) 17 | if err != nil { 18 | log.Printf("Error setting environment variable: %v", err) 19 | } 20 | 21 | config := cliutils.ReadFile(testSetup) 22 | t := test.NewSystemTest(testSetup) 23 | 24 | commandGenerated := "../warp fanout --copies=50 --obj.size=512KiB --host=" + config.Server + ":" + config.HostPort + " --access-key=" + config.AccessKey + " --secret-key=" + config.SecretKey + " --concurrent " + config.Concurrent + " --duration 30s" + " --obj.size " + config.ObjectSize 25 | 26 | output, err := cliutils.RunCommand(t, commandGenerated, 1, time.Hour*3) 27 | 28 | if err != nil { 29 | testSetup.Fatalf("Error running warp multipart: %v\nOutput: %s", err, output) 30 | } 31 | output_string := strings.Join(output, "\n") 32 | output_string = strings.Split(output_string, "----------------------------------------")[1] 33 | output_string = strings.Split(output_string, "warp: Starting cleanup")[0] 34 | 35 | output_string = "Condition 1: Retention : objects: 1 \n--------\n" + output_string 36 | err = cliutils.AppendToFile("warp-put_output.txt", output_string) 37 | 38 | if err != nil { 39 | testSetup.Fatalf("Error appending to file: %v\n", err) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tests/cli_tests/zs3server_tests/4_listing_purge_test.go: -------------------------------------------------------------------------------- 1 | package zs3servertests 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | "time" 7 | 8 | test "github.com/0chain/system_test/internal/api/util/test" 9 | cliutils "github.com/0chain/system_test/internal/cli/util" 10 | ) 11 | 12 | func TestZs3serverListTests(testSetup *testing.T) { 13 | config := cliutils.ReadFile(testSetup) 14 | t := test.NewSystemTest(testSetup) 15 | 16 | t.RunSequentiallyWithTimeout("Warp List Benchmark", 40*time.Minute, func(t *test.SystemTest) { 17 | commandGenerated := "../warp get --host=" + config.Server + ":" + config.HostPort + " --access-key=" + config.AccessKey + " --secret-key=" + config.SecretKey + " --duration 30s" + " --obj.size " + config.ObjectSize + " --objects " + config.ObjectCount 18 | output, err := cliutils.RunCommand(t, commandGenerated, 1, time.Hour*2) 19 | if err != nil { 20 | testSetup.Fatalf("Error running warp list: %v\nOutput: %s", err, output) 21 | } 22 | output_string := strings.Join(output, "\n") 23 | output_string = strings.Split(output_string, "----------------------------------------")[1] 24 | 25 | output_string = strings.Split(output_string, "warp: Starting cleanup")[0] 26 | 27 | output_string = "Condition 1: Get objects: 1 \n--------\n" + output_string 28 | err = cliutils.AppendToFile("warp-list_output.txt", output_string) 29 | 30 | if err != nil { 31 | testSetup.Fatalf("Error appending to file: %v\n", err) 32 | } 33 | }) 34 | 35 | t.RunSequentiallyWithTimeout("Warp List Benchmark", 40*time.Minute, func(t *test.SystemTest) { 36 | commandGenerated := "../warp get --host=" + config.Server + ":" + config.HostPort + " --access-key=" + config.AccessKey + " --secret-key=" + config.SecretKey + " --objects " + config.ObjectCount + " --concurrent " + config.Concurrent + " --duration 30s" + " --obj.size " + config.ObjectSize 37 | output, err := cliutils.RunCommand(t, commandGenerated, 1, time.Hour*2) 38 | 39 | if err != nil { 40 | testSetup.Fatalf("Error running warp list: %v\nOutput: %s", err, output) 41 | } 42 | output_string := strings.Join(output, "\n") 43 | output_string = strings.Split(output_string, "----------------------------------------")[1] 44 | 45 | output_string = "Condition 1: Get objects: 100 concurrent 50:: \n--------\n" + output_string 46 | 47 | err = cliutils.AppendToFile("warp-list_output.txt", output_string) 48 | 49 | if err != nil { 50 | testSetup.Fatalf("Error appending to file: %v\n", err) 51 | } 52 | }) 53 | } 54 | -------------------------------------------------------------------------------- /tests/cli_tests/zs3server_tests/allocation.yaml: -------------------------------------------------------------------------------- 1 | data: 2 2 | parity: 2 3 | lock: 10 4 | access_key: rootroot 5 | secret_key: rootroot 6 | -------------------------------------------------------------------------------- /tests/cli_tests/zs3server_tests/analyzing zst files.md: -------------------------------------------------------------------------------- 1 | ## example to analyze mixed file 2 | 3 | warp analyze --analyze.op=GET --analyze.v warp-mixed-2024-07-03\[213722\]-g9hN.csv.zst 4 | -------------------------------------------------------------------------------- /tests/cli_tests/zs3server_tests/hosts.yaml: -------------------------------------------------------------------------------- 1 | server: localhost 2 | port: 9000 3 | # access_key: someminiouser 4 | # secret_key: someminiopassword 5 | concurrent: 1 6 | object_size: 256B 7 | object_count: 22 8 | # server: 65.109.152.43 9 | # port: 9000 10 | access_key: rootroot 11 | secret_key: rootroot 12 | # concurrent: 900 13 | -------------------------------------------------------------------------------- /tests/cli_tests/zs3server_tests/readme.md: -------------------------------------------------------------------------------- 1 | Prerequisites: 2 | 3 | ## Recommended network: 4 | 5 | -> test3a, test 6 | 7 | ## required allocation 8 | 9 | minimum size : 7000000000 10 | 11 | ## minio server should be running at 9000 port. 12 | -------------------------------------------------------------------------------- /tests/cli_tests/zs3server_tests/warp_analysis_test.go: -------------------------------------------------------------------------------- 1 | package zs3servertests 2 | 3 | import ( 4 | "fmt" 5 | "os/exec" 6 | "path/filepath" 7 | "strings" 8 | "testing" 9 | ) 10 | 11 | func TestWarpAnalysis(t *testing.T) { 12 | files, err := filepath.Glob("warp*.csv.zst") 13 | if err != nil { 14 | t.Fatalf("Error finding files: %v", err) 15 | } 16 | 17 | for _, file := range files { 18 | fmt.Printf("<%s->\n\n", strings.Repeat("-", 50)) 19 | fmt.Printf("Analyzing %s\n\n", file) 20 | cmd := exec.Command("../warp", "analyze", "--analyze.op=GET", "--analyze.v", file) 21 | 22 | stdoutStderr, err := cmd.CombinedOutput() 23 | if err != nil { 24 | t.Fatalf("Error executing command for %s: %v\nOutput:\n%s", file, err, stdoutStderr) 25 | } 26 | 27 | fmt.Printf("Command output for %s:\n%s\n", file, stdoutStderr) 28 | 29 | fmt.Printf("<%s->\n\n", strings.Repeat("-", 50)) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/cli_tests/zwalletcli_get_id_test.go: -------------------------------------------------------------------------------- 1 | package cli_tests 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | "strings" 7 | "testing" 8 | "time" 9 | 10 | "github.com/0chain/system_test/internal/api/util/test" 11 | 12 | cliutils "github.com/0chain/system_test/internal/cli/util" 13 | "github.com/stretchr/testify/require" 14 | ) 15 | 16 | func TestGetId(testSetup *testing.T) { 17 | t := test.NewSystemTest(testSetup) 18 | t.SetSmokeTests("get miner id should work") 19 | 20 | t.Parallel() 21 | 22 | t.Run("get miner id should work", func(t *test.SystemTest) { 23 | miners := getMinersList(t) 24 | minerUrl := fmt.Sprint("http://", miners.Nodes[0].Host, ":", miners.Nodes[0].Port) 25 | 26 | output, err := getId(t, configPath, minerUrl, true) 27 | require.Nil(t, err, "get id failed", strings.Join(output, "\n")) 28 | require.Greater(t, len(output), 1, "Expected output length to be at least 2", strings.Join(output, "\n")) 29 | require.Equal(t, "URL: "+minerUrl, output[len(output)-2], strings.Join(output, "\n")) 30 | require.Equal(t, "ID: "+miners.Nodes[0].ID, output[len(output)-1], strings.Join(output, "\n")) 31 | }) 32 | 33 | t.Run("get sharder id should work", func(t *test.SystemTest) { 34 | createWallet(t) 35 | 36 | sharders := getShardersList(t) 37 | sharderKey := reflect.ValueOf(sharders).MapKeys()[0].String() 38 | sharder := sharders[sharderKey] 39 | sharderUrl := fmt.Sprint("http://", sharder.Host, ":", sharder.Port) 40 | require.NotNil(t, sharder) 41 | 42 | output, err := getId(t, configPath, sharderUrl, true) 43 | require.Nil(t, err, "get is failed", strings.Join(output, "\n")) 44 | require.Greater(t, len(output), 1, "Expected output length to be at least 2", strings.Join(output, "\n")) 45 | require.Equal(t, "URL: "+sharderUrl, output[len(output)-2], strings.Join(output, "\n")) 46 | require.Equal(t, "ID: "+sharder.ID, output[len(output)-1], strings.Join(output, "\n")) 47 | }) 48 | 49 | t.Run("get blobber id should not work", func(t *test.SystemTest) { 50 | createWallet(t) 51 | 52 | blobbers := getBlobbersList(t) 53 | blobberUrl := blobbers[0].Url 54 | 55 | output, err := getId(t, configPath, blobberUrl, false) 56 | require.NotNil(t, err, "expected get id to fail", strings.Join(output, "\n")) 57 | require.Len(t, output, 1, strings.Join(output, "\n")) 58 | require.Equal(t, "Error: ID not found", output[0], strings.Join(output, "\n")) 59 | }) 60 | } 61 | 62 | func getId(t *test.SystemTest, cliConfigFilename, url string, retry bool) ([]string, error) { 63 | t.Logf("getting id for [%s]...", url) 64 | if retry { 65 | return cliutils.RunCommand(t, fmt.Sprintf("./zwallet getid --silent --configDir ./config --url %s --config %s", url, cliConfigFilename), 3, time.Second) 66 | } else { 67 | return cliutils.RunCommandWithoutRetry(fmt.Sprintf("./zwallet getid --silent --configDir ./config --url %s --config %s", url, cliConfigFilename)) 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /tests/cli_tests/zwalletcli_mn_pool_info_test.go: -------------------------------------------------------------------------------- 1 | package cli_tests 2 | 3 | import ( 4 | "encoding/json" 5 | "os" 6 | "regexp" 7 | "testing" 8 | 9 | "github.com/0chain/system_test/internal/api/util/test" 10 | 11 | climodel "github.com/0chain/system_test/internal/cli/model" 12 | "github.com/stretchr/testify/require" 13 | ) 14 | 15 | func TestMinerSharderPoolInfo(testSetup *testing.T) { 16 | t := test.NewSystemTest(testSetup) 17 | t.SetSmokeTests("Miner pool info after locking against miner should work") 18 | 19 | t.Parallel() 20 | 21 | var sharder climodel.Sharder 22 | var miner climodel.Node 23 | t.TestSetup("get miners and sharders", func() { 24 | if _, err := os.Stat("./config/" + sharder01NodeDelegateWalletName + "_wallet.json"); err != nil { 25 | t.Skipf("miner node owner wallet located at %s is missing", "./config/"+sharder01NodeDelegateWalletName+"_wallet.json") 26 | } 27 | 28 | sharders := getShardersListForWallet(t, sharder01NodeDelegateWalletName) 29 | 30 | sharderNodeDelegateWallet, err := getWalletForName(t, configPath, sharder01NodeDelegateWalletName) 31 | require.Nil(t, err, "error fetching sharderNodeDelegate wallet") 32 | 33 | for _, sharder = range sharders { 34 | if sharder.ID != sharderNodeDelegateWallet.ClientID { 35 | break 36 | } 37 | } 38 | 39 | if _, err := os.Stat("./config/" + miner02NodeDelegateWalletName + "_wallet.json"); err != nil { 40 | t.Skipf("miner node owner wallet located at %s is missing", "./config/"+miner02NodeDelegateWalletName+"_wallet.json") 41 | } 42 | 43 | miners := getMinersListForWallet(t, miner02NodeDelegateWalletName) 44 | 45 | for _, miner = range miners.Nodes { 46 | if miner.ID == miner03ID { 47 | break 48 | } 49 | } 50 | }) 51 | 52 | var ( 53 | lockOutputRegex = regexp.MustCompile("locked with: [a-f0-9]{64}") 54 | ) 55 | 56 | t.Run("Miner pool info after locking against miner should work", func(t *test.SystemTest) { 57 | createWallet(t) 58 | 59 | output, err := minerOrSharderLock(t, configPath, createParams(map[string]interface{}{ 60 | "miner_id": miner.ID, 61 | "tokens": 1, 62 | }), true) 63 | require.Nil(t, err, "error staking tokens against a node") 64 | require.Len(t, output, 1) 65 | require.Regexp(t, lockOutputRegex, output[0]) 66 | 67 | var poolsInfo climodel.DelegatePool 68 | output, err = minerSharderPoolInfo(t, configPath, createParams(map[string]interface{}{ 69 | "id": miner.ID, 70 | }), true) 71 | require.Nil(t, err, "error fetching Miner Sharder pools") 72 | require.Len(t, output, 1) 73 | 74 | err = json.Unmarshal([]byte(output[0]), &poolsInfo) 75 | require.Nil(t, err, "error unmarshalling Miner Sharder pools") 76 | }) 77 | 78 | t.Run("Miner pool info after locking against sharder should work", func(t *test.SystemTest) { 79 | createWallet(t) 80 | 81 | output, err := minerOrSharderLock(t, configPath, createParams(map[string]interface{}{ 82 | "sharder_id": sharder.ID, 83 | "tokens": 5, 84 | }), true) 85 | require.Nil(t, err, "error staking tokens against a node") 86 | require.Len(t, output, 1) 87 | require.Regexp(t, lockOutputRegex, output[0]) 88 | 89 | var poolsInfo climodel.DelegatePool 90 | 91 | output, err = minerSharderPoolInfo(t, configPath, createParams(map[string]interface{}{ 92 | "id": sharder.ID, 93 | }), true) 94 | require.Nil(t, err, "error fetching Miner Sharder pools") 95 | require.Len(t, output, 1) 96 | 97 | err = json.Unmarshal([]byte(output[0]), &poolsInfo) 98 | require.Nil(t, err, "error unmarshalling Miner Sharder pools") 99 | }) 100 | 101 | t.Run("Miner/Sharder pool info for invalid node id should fail", func(t *test.SystemTest) { 102 | createWallet(t) 103 | 104 | output, err := minerSharderPoolInfo(t, configPath, createParams(map[string]interface{}{ 105 | "id": "abcdefgh", 106 | }), false) 107 | require.NotNil(t, err, "expected error when trying to fetch pool info from invalid id") 108 | require.Len(t, output, 1) 109 | require.Equal(t, `resource_not_found: can't find pool stats`, output[0]) 110 | }) 111 | } 112 | -------------------------------------------------------------------------------- /tests/cli_tests/zwalletcli_recover_wallet_test.go: -------------------------------------------------------------------------------- 1 | package cli_tests 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | "time" 7 | 8 | "github.com/0chain/system_test/internal/api/util/test" 9 | 10 | "github.com/stretchr/testify/require" 11 | 12 | cliutils "github.com/0chain/system_test/internal/cli/util" 13 | ) 14 | 15 | func TestRecoverWallet(testSetup *testing.T) { 16 | t := test.NewSystemTest(testSetup) 17 | t.SetSmokeTests("Recover wallet valid mnemonic") 18 | 19 | t.Parallel() 20 | 21 | t.Run("Recover wallet valid mnemonic", func(t *test.SystemTest) { 22 | validMnemonic := "pull floor crop best weasel suit solid gown" + 23 | " filter kitten loan absent noodle nation potato planet demise" + 24 | " online ten affair rich panel rent sell" 25 | 26 | output, err := recoverWalletFromMnemonic(t, configPath, validMnemonic, true) 27 | 28 | require.Nil(t, err, "error occurred recovering a wallet", strings.Join(output, "\n")) 29 | require.Len(t, output, 1) 30 | require.Equal(t, "Wallet recovered!!", output[len(output)-1]) 31 | }) 32 | 33 | //FIXME: POSSIBLE BUG: Blank wallet created if mnemonic is invalid (same issue in missing mnemonic test) 34 | t.Run("Recover wallet invalid mnemonic", func(t *test.SystemTest) { 35 | inValidMnemonic := "floor crop best weasel suit solid gown" + 36 | " filter kitten loan absent noodle nation potato planet demise" + 37 | " online ten affair rich panel rent sell" 38 | 39 | output, err := recoverWalletFromMnemonic(t, configPath, inValidMnemonic, false) 40 | 41 | require.NotNil(t, err, "expected error to occur recovering a wallet", strings.Join(output, "\n")) 42 | require.Len(t, output, 1) 43 | 44 | require.Equal(t, "Error: Invalid mnemonic", output[0]) 45 | }) 46 | 47 | t.Run("Recover wallet no mnemonic", func(t *test.SystemTest) { 48 | output, err := cliutils.RunCommandWithoutRetry("./zwallet recoverwallet --silent " + 49 | "--wallet " + escapedTestName(t) + "_wallet.json" + " " + 50 | "--configDir ./config --config " + configPath) 51 | 52 | require.NotNil(t, err, "expected error to occur recovering a wallet", strings.Join(output, "\n")) 53 | require.Len(t, output, 1) 54 | require.Equal(t, "Error: Mnemonic not provided", output[0]) 55 | }) 56 | } 57 | 58 | func recoverWalletFromMnemonic(t *test.SystemTest, configPath, mnemonic string, retry bool) ([]string, error) { 59 | t.Logf("Recovering wallet from mnemonic...") 60 | cmd := "./zwallet recoverwallet " + 61 | "--silent --wallet " + escapedTestName(t) + "_wallet.json" + " " + 62 | "--configDir ./config --config " + configPath + " --mnemonic \"" + mnemonic + "\"" 63 | 64 | if retry { 65 | return cliutils.RunCommand(t, cmd, 3, time.Second*2) 66 | } else { 67 | return cliutils.RunCommandWithoutRetry(cmd) 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /tests/cli_tests/zzwalletcli_kill_sharder_test.go: -------------------------------------------------------------------------------- 1 | package cli_tests 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | "testing" 7 | "time" 8 | 9 | "github.com/stretchr/testify/require" 10 | 11 | "github.com/0chain/system_test/internal/api/util/test" 12 | cliutil "github.com/0chain/system_test/internal/cli/util" 13 | cliutils "github.com/0chain/system_test/internal/cli/util" 14 | ) 15 | 16 | const ( 17 | minShardersForKillSharderTest = 2 18 | ) 19 | 20 | func TestKillSharder(testSetup *testing.T) { // nolint:gocyclo // team preference is to have codes all within test. 21 | t := test.NewSystemTest(testSetup) 22 | 23 | createWallet(t) 24 | 25 | sharderUrl := getSharderUrl(t) 26 | startSharders := getNodeSlice(t, "getSharderList", sharderUrl) 27 | if len(startSharders) < minShardersForKillSharderTest { 28 | t.Skipf("not enough sharders in blockchain, found %d need %d", len(startSharders), minShardersForKillSharderTest) 29 | } 30 | 31 | var sharderToKill string 32 | for i := range startSharders { 33 | if !startSharders[i].IsKilled { 34 | sharderToKill = startSharders[i].ID 35 | break 36 | } 37 | } 38 | if sharderToKill == "" { 39 | t.Skip("all sharders in the blockchain have been killed") 40 | } 41 | 42 | t.RunSequentially("kill sharder by non-smartcontract owner should fail", func(t *test.SystemTest) { 43 | createWallet(t) 44 | output, err := killSharder(t, escapedTestName(t), configPath, createParams(map[string]interface{}{ 45 | "id": sharderToKill, 46 | }), true) 47 | require.Error(t, err, "kill sharder by non-smartcontract owner should fail") 48 | require.Len(t, output, 1) 49 | require.True(t, strings.Contains(output[0], "unauthorized access - only the owner can access"), "") 50 | }) 51 | 52 | t.RunSequentially("Killed sharder does not receive rewards", func(t *test.SystemTest) { 53 | createWallet(t) 54 | output, err := killSharder(t, scOwnerWallet, configPath, createParams(map[string]interface{}{ 55 | "id": sharderToKill, 56 | }), true) 57 | require.NoError(t, err, strings.Join(output, "\n")) 58 | require.Len(t, output, 1) 59 | 60 | cliutil.Wait(t, time.Second) 61 | 62 | sharderAfterKill := getMinersDetail(t, sharderToKill) 63 | require.True(t, sharderAfterKill.IsKilled, "sharder should be killed") 64 | 65 | // ------------------------------------ 66 | cliutil.Wait(t, 10*time.Second) 67 | // ------------------------------------ 68 | 69 | sharderAfterRewardTest := getMinersDetail(t, sharderToKill) 70 | require.Equalf(t, sharderAfterKill.TotalReward, sharderAfterRewardTest.TotalReward, 71 | "killed sharder %s should not receive any more rewards", sharderToKill) 72 | }) 73 | } 74 | 75 | func killSharder(t *test.SystemTest, wallet, cliConfigFilename, params string, retry bool) ([]string, error) { 76 | t.Log("kill sharder...") 77 | cmd := fmt.Sprintf("./zwallet sh-kill %s --silent --wallet %s_wallet.json --configDir ./config --config %s", 78 | params, wallet, cliConfigFilename) 79 | if retry { 80 | return cliutils.RunCommand(t, cmd, 3, time.Second*2) 81 | } else { 82 | return cliutils.RunCommandWithoutRetry(cmd) 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /tests/cli_tests/zzzwalletcli_kill_miner_test.go: -------------------------------------------------------------------------------- 1 | package cli_tests 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | "testing" 7 | "time" 8 | 9 | "github.com/stretchr/testify/require" 10 | 11 | "github.com/0chain/system_test/internal/api/util/test" 12 | cliutil "github.com/0chain/system_test/internal/cli/util" 13 | cliutils "github.com/0chain/system_test/internal/cli/util" 14 | ) 15 | 16 | const ( 17 | minMinersForKillMinerTest = 2 18 | ) 19 | 20 | func TestKillMiner(testSetup *testing.T) { // nolint:gocyclo // team preference is to have codes all within test. 21 | t := test.NewSystemTest(testSetup) 22 | 23 | createWallet(t) 24 | 25 | sharderUrl := getSharderUrl(t) 26 | startMiners := getNodeSlice(t, "getMinerList", sharderUrl) 27 | if len(startMiners) < minMinersForKillMinerTest { 28 | t.Skipf("not enough miners in blockchain, found %d need %d", len(startMiners), minMinersForKillMinerTest) 29 | } 30 | 31 | var minerToKill string 32 | for i := range startMiners { 33 | if !startMiners[i].IsKilled { 34 | minerToKill = startMiners[i].ID 35 | break 36 | } 37 | } 38 | if minerToKill == "" { 39 | t.Skip("all miners in the blockchain have been killed") 40 | } 41 | 42 | t.RunSequentially("kill miner by non-smartcontract owner should fail", func(t *test.SystemTest) { 43 | createWallet(t) 44 | output, err := killMiner(t, escapedTestName(t), configPath, createParams(map[string]interface{}{ 45 | "id": minerToKill, 46 | }), true) 47 | require.Error(t, err, "kill miner by non-smartcontract owner should fail") 48 | require.Len(t, output, 1) 49 | require.True(t, strings.Contains(output[0], "unauthorized access - only the owner can access"), "") 50 | }) 51 | 52 | t.RunSequentially("Killed miner does not receive rewards", func(t *test.SystemTest) { 53 | createWallet(t) 54 | 55 | output, err := killMiner(t, scOwnerWallet, configPath, createParams(map[string]interface{}{ 56 | "id": minerToKill, 57 | }), true) 58 | require.NoError(t, err, strings.Join(output, "\n")) 59 | require.Len(t, output, 1) 60 | 61 | cliutil.Wait(t, time.Second) 62 | 63 | minerAfterKill := getMinersDetail(t, minerToKill) 64 | require.True(t, minerAfterKill.IsKilled, "miner should be killed") 65 | 66 | // ------------------------------------ 67 | cliutil.Wait(t, 10*time.Second) 68 | // ------------------------------------ 69 | 70 | minerAfterRewardTest := getMinersDetail(t, minerToKill) 71 | require.Equalf(t, minerAfterKill.TotalReward, minerAfterRewardTest.TotalReward, 72 | "killed miner %s should not receive any more rewards", minerToKill) 73 | }) 74 | } 75 | 76 | func killMiner(t *test.SystemTest, wallet, cliConfigFilename, params string, retry bool) ([]string, error) { 77 | t.Log("kill miner...") 78 | cmd := fmt.Sprintf("./zwallet mn-kill %s --silent --wallet %s_wallet.json --configDir ./config --config %s", 79 | params, wallet, cliConfigFilename) 80 | if retry { 81 | return cliutils.RunCommand(t, cmd, 3, time.Second*2) 82 | } else { 83 | return cliutils.RunCommandWithoutRetry(cmd) 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /tests/tokenomics_tests/config/bridge.yaml: -------------------------------------------------------------------------------- 1 | bridge: 2 | Password: "\"02289b9\"" 3 | EthereumAddress: 0xD8c9156e782C68EE671C09b6b92de76C97948432 4 | AuthorizersAddress: 0xB132C20A02AD7C38d88805F0e3fFDdfb54224C58 5 | BridgeAddress: 0x2405e40161ea6da91AE0e95061e7A8462b4D5eEa 6 | WzcnAddress: 0x10140fbca3a468A1c35F132D75659eF0EB5d95DB 7 | EthereumNodeURL: "https://rpc.tenderly.co/fork/e753f650-9968-4f58-af77-5f02ace53cdc" 8 | GasLimit: 300000 9 | Value: 0 10 | ConsensusThreshold: 75 11 | -------------------------------------------------------------------------------- /tests/tokenomics_tests/config/cli_tests_config.yaml: -------------------------------------------------------------------------------- 1 | default_test_case_timeout: 75s 2 | -------------------------------------------------------------------------------- /tests/tokenomics_tests/config/config.yaml: -------------------------------------------------------------------------------- 1 | block_worker: https://dev.zus.network/dns 2 | confirmation_chain_length: 3 3 | ethereum_node_url: "https://rpc.tenderly.co/fork/05077a9d-3973-4409-a3bf-eee719ca2806" 4 | min_confirmation: 50 5 | min_submit: 50 6 | signature_scheme: bls0chain 7 | store_unlock_duration_sec: 2 8 | ethereum_address: 0xD8c9156e782C68EE671C09b6b92de76C97948432 9 | -------------------------------------------------------------------------------- /tests/tokenomics_tests/config/nodes.yaml: -------------------------------------------------------------------------------- 1 | version: 1.0 2 | 3 | nodes: 4 | miner01ID: "73ad5727612116c025bb4405bf3adb4a4a04867ae508c51cf885395bffc8a949" 5 | miner02ID: "3ec9a42db3355f33c35750ce589ed717c08787997b7f34a7f1f9fb0a03f2b17c" 6 | miner03ID: "c6f4b8ce5da386b278ba8c4e6cf98b24b32d15bc675b4d12c95e082079c91937" 7 | sharder01ID: "ea26431f8adb7061766f1d6bbcc3b292d70dd59960d857f04b8a75e6a5bbe04f" 8 | sharder02ID: "30001a01a888584772b7fee13934021ab8557e0ed471c0a3a454e9164180aef1" -------------------------------------------------------------------------------- /tests/tokenomics_tests/config/owner.yaml: -------------------------------------------------------------------------------- 1 | bridge: 2 | Password: "\"02289b9\"" 3 | EthereumAddress: 0xD8c9156e782C68EE671C09b6b92de76C97948432 4 | BridgeAddress: 0xF6533C445f3A8173539b1D5e90661737ed90E294 5 | WzcnAddress: 0x31E77dA0bC7bB60d27C224c12eb9ce8001b973e8 6 | AuthorizersAddress: 0x8f528548189759761B40FF3b3d91A9544d52FaC5 7 | EthereumNodeURL: https://rpc.tenderly.co/fork/e753f650-9968-4f58-af77-5f02ace53cdc 8 | GasLimit: 300000 9 | Value: 0 10 | ConsensusThreshold: 75 11 | -------------------------------------------------------------------------------- /tests/tokenomics_tests/config/tokenomics_tests_config.yaml: -------------------------------------------------------------------------------- 1 | block_worker: https://dev.0chain.net 2 | 0box_url: https://0box.dev.0chain.net 3 | zs3_server_url: https://dev.0chain.net/zs3server/ 4 | zvault_url: http://zvault.dev.0chain.net 5 | zauth_url: http://zauth.dev.0chain.net 6 | ethereum_node_url: "https://rpc.tenderly.co/fork/e753f650-9968-4f58-af77-5f02ace53cdc" 7 | confirmation_chain_length: 3 8 | min_confirmation: 50 9 | min_submit: 50 10 | signature_scheme: bls0chain 11 | store_unlock_duration_sec: 2 12 | ethereum_address: 0xD8c9156e782C68EE671C09b6b92de76C97948432 13 | 0box_phone_number: +917696229925 14 | default_test_case_timeout: 300s 15 | -------------------------------------------------------------------------------- /tests/tokenomics_tests/config/wallets/blobber1_delegate1_wallet.json: -------------------------------------------------------------------------------- 1 | {"client_id":"ded1a98d8f4139f06c580e885d31848dbf3df250a18c40e4d58f909fb51f3e00","client_key":"c29a28072fd66ee856a7417d88f0e647ea0788076df0fa4e1a5a3ab60de09810067dd99a843c68397fd873c73f7a037c63a6ac7a4d8abbe2c18be29fdfc009a5","keys":[{"public_key":"c29a28072fd66ee856a7417d88f0e647ea0788076df0fa4e1a5a3ab60de09810067dd99a843c68397fd873c73f7a037c63a6ac7a4d8abbe2c18be29fdfc009a5","private_key":"d637bde8ef376c688e3194f30ab192bce7091b4046e33dc3efdc81e26e398d08"}],"mnemonics":"recall such basket hood topple intact around naive capital fluid lecture tell rough tooth reform field machine click clay ice exchange sort obtain universe","version":"1.0","date_created":"1680360757","nonce":0} -------------------------------------------------------------------------------- /tests/tokenomics_tests/config/wallets/blobber1_delegate2_wallet.json: -------------------------------------------------------------------------------- 1 | {"client_id":"c088cf5cd5092d6b61a05cfa5b816c9e9c833708b68f77c84f76e30fd2dd465e","client_key":"a081f1b6edee50e367cd6acc25fc91290b1aa7744b4e39ad731432275af463153de4ce251dfa0eaf6def02836260de4236c8c0665e1413740acd2e6305b28c01","keys":[{"public_key":"a081f1b6edee50e367cd6acc25fc91290b1aa7744b4e39ad731432275af463153de4ce251dfa0eaf6def02836260de4236c8c0665e1413740acd2e6305b28c01","private_key":"1e198bd13bafd92b75c3bc58294e01bada6f3191657a190c332677f9e0e7ff08"}],"mnemonics":"whale viable forward atom picture impose brain gun also remember crash toss happy defy satisfy engage teach exclude cousin robot lucky battle coin lab","version":"1.0","date_created":"1680360814","nonce":0} -------------------------------------------------------------------------------- /tests/tokenomics_tests/config/wallets/blobber1_wallet.json: -------------------------------------------------------------------------------- 1 | {"client_id":"fd5eaad5d972234de74f3d89343df013b82ed0abba6d17405e43e67f3fbaf7b1","client_key":"7fa653f2479ba97145c3f8c308e1b9693f938181076ed7cc5af25cce369f90001029ffb18078918c62a2ed83938e9e95d0c54170fa6f30ed46fa7778dc7c8c17","keys":[{"public_key":"7fa653f2479ba97145c3f8c308e1b9693f938181076ed7cc5af25cce369f90001029ffb18078918c62a2ed83938e9e95d0c54170fa6f30ed46fa7778dc7c8c17","private_key":"89805e2629a1ef94b0c4cc0378d29640fe94f9000b77884dbec4178303a80102"}],"mnemonics":"combine begin other release turn position half camera mail cactus mail smile kind tattoo resource rocket cabbage rural total upon jump attend wear solution","version":"1.0","date_created":"1676633284","nonce":0} -------------------------------------------------------------------------------- /tests/tokenomics_tests/config/wallets/blobber2_delegate1_wallet.json: -------------------------------------------------------------------------------- 1 | {"client_id":"a8acf4fb806b72117c6cc431a35ceb3f8be86c6006fbb4a09bfb58ce2194e385","client_key":"559f3926f40e059818f0baab03db387ca639dc1f44e0f05a3d1330990e6803181efcf9e5cd9c1a8941c40784e9f7486e5811774d7a4a504296c4c9a5b94d6c0f","keys":[{"public_key":"559f3926f40e059818f0baab03db387ca639dc1f44e0f05a3d1330990e6803181efcf9e5cd9c1a8941c40784e9f7486e5811774d7a4a504296c4c9a5b94d6c0f","private_key":"7bf9e2b3421e84ad2d5728374c3e58dd3e72d7509bd8ded058673084f8c96e0e"}],"mnemonics":"toddler birth tortoise foam sample wisdom eager dinosaur play beauty inch relief stadium manage couch birth table rebel electric hurdle canvas draw prevent glad","version":"1.0","date_created":"1680360835","nonce":0} -------------------------------------------------------------------------------- /tests/tokenomics_tests/config/wallets/blobber2_delegate2_wallet.json: -------------------------------------------------------------------------------- 1 | {"client_id":"16b470018a2c388fa62a923a794cdeb8c4aab516da261969d5d230cebd838c05","client_key":"725961492f390005575daabe593d87f4186c898dc0c7e3d5a76ed1339d9c980dd3dd0afa8fcf2687fd4772be146e76960bcd9f3a487575912c8dc3332f00a897","keys":[{"public_key":"725961492f390005575daabe593d87f4186c898dc0c7e3d5a76ed1339d9c980dd3dd0afa8fcf2687fd4772be146e76960bcd9f3a487575912c8dc3332f00a897","private_key":"9f3d4ca894bca01df8a7671a4020624625989ac545526006da096cc38a53860c"}],"mnemonics":"common initial any force food music gesture swing expire fantasy trim unusual inner under general rebel shiver adult advice myself ranch powder boat woman","version":"1.0","date_created":"1680360975","nonce":0} -------------------------------------------------------------------------------- /tests/tokenomics_tests/config/wallets/blobber2_wallet.json: -------------------------------------------------------------------------------- 1 | {"client_id":"65ab971dbd8c5d1c1268471ed41d70a6e4bfd43ec2f78c288e1333db8a28f597","client_key":"3306319c3775b3962e8f44f79fd69b2040f0c65baf2b2acdbf177bdbf3275309bb5c2bb29090b72ba137f4fd4f537028a5496c62d55293c87fd79670d0338901","keys":[{"public_key":"3306319c3775b3962e8f44f79fd69b2040f0c65baf2b2acdbf177bdbf3275309bb5c2bb29090b72ba137f4fd4f537028a5496c62d55293c87fd79670d0338901","private_key":"c2743cb47d84b67b44c2016c9e162863f017dee4d1b076fcbb9c993aadaa5d10"}],"mnemonics":"recycle walk orient negative away word wasp thumb angle street matter drastic initial track believe permit huge cabin boat combine identify tennis diesel buddy","version":"1.0","date_created":"1676634211","nonce":0} -------------------------------------------------------------------------------- /tests/tokenomics_tests/config/wallets/blobber_owner_wallet.json: -------------------------------------------------------------------------------- 1 | {"client_id": "591d6d0d5642bdbc924756ca2647b4b59adce0acd02a487ecc4d1bd4669293a8","client_key": "ac8798bcadd5ce5ea14f4745850eec61aa080e6fedc1d769af95c42e0079ba03ee9710e9dc966f7c5eb9cd6ef9184af51869d5a345b9520e507aa55ba22bf902","keys": [{"public_key": "ac8798bcadd5ce5ea14f4745850eec61aa080e6fedc1d769af95c42e0079ba03ee9710e9dc966f7c5eb9cd6ef9184af51869d5a345b9520e507aa55ba22bf902","private_key": "fbdc0bcc12168588e2def826b7ee9d8b4c6f1fbacf22ee5064b7db49482b8f0d"}],"mnemonics": "economy day fan flower between rebuild valid bid catch bargain vivid hybrid room permit check manage mean twelve damage summer close churn boat either","version": "1.0","date_created": "2021-12-04T17:03:37Z"} -------------------------------------------------------------------------------- /tests/tokenomics_tests/config/wallets/miner01_node_delegate_wallet.json: -------------------------------------------------------------------------------- 1 | { 2 | "client_id": "9636ab821fd93a37740ab4c6a27d9e2cf3a4072b4bc8fd1c6048f9c3ef9cf2a8", 3 | "client_key": "02237d7edafc8c648b1e2ff64ad5d4e6a7cea949a40448e15a55f0a90c71bc1928d8f1409d8985757cc1f59f13d82d83fe6757e4a510d9b47c6385d91ea5d59b", 4 | "keys": [ 5 | { 6 | "public_key": "02237d7edafc8c648b1e2ff64ad5d4e6a7cea949a40448e15a55f0a90c71bc1928d8f1409d8985757cc1f59f13d82d83fe6757e4a510d9b47c6385d91ea5d59b", 7 | "private_key": "17627154df3d2a77a273c6b5caf71ca552d26addce0198c1126331eb71ef5c0a" 8 | } 9 | ], 10 | "mnemonics": "family admit sound girl recall another rule hawk equip soccer action dance tumble style prepare face cluster endorse wonder raven unit vital hybrid mass", 11 | "version": "1.0", 12 | "date_created": "1661370959", 13 | "nonce": 0 14 | } -------------------------------------------------------------------------------- /tests/tokenomics_tests/config/wallets/miner02_node_delegate_wallet.json: -------------------------------------------------------------------------------- 1 | { 2 | "client_id": "b8b25d509afbe8f68f1342a2fa719acf312915a6f5a5bb0918cad6598e01325f", 3 | "client_key": "e88949ab4fdfa724459fe41bb2c2e9ce5467ddb6911469614a4201b741933e157a1423853cb9426c3360b970ad8d9d6e07b93a60ba8531b268d1377f5804d103", 4 | "keys": [ 5 | { 6 | "public_key": "e88949ab4fdfa724459fe41bb2c2e9ce5467ddb6911469614a4201b741933e157a1423853cb9426c3360b970ad8d9d6e07b93a60ba8531b268d1377f5804d103", 7 | "private_key": "b7c415c17659b198de177e95d15345a9c576cd2522ea14a0c20399fdb7731c0b" 8 | } 9 | ], 10 | "mnemonics": "lock olive another scare idea awesome hat chaos general gauge immense near torch magic tomato ancient mule release know siege few twin donor race", 11 | "version": "1.0", 12 | "date_created": "1661370970", 13 | "nonce": 0 14 | } -------------------------------------------------------------------------------- /tests/tokenomics_tests/config/wallets/miner03_node_delegate_wallet.json: -------------------------------------------------------------------------------- 1 | { 2 | "client_id": "bbe8b6abdb54b0642324a103c49f8b04e2623db74cd7f1427cd2d5f0308e674d", 3 | "client_key": "0f1d9339776c39a43bcb722dc0fdc0fe0df8ae397b06432b2184c279e41aa81963c45abb3791ca6a939f8c1b6d437f4e30d4c1044c7697eaa1ba55af3198bd22", 4 | "keys": [ 5 | { 6 | "public_key": "0f1d9339776c39a43bcb722dc0fdc0fe0df8ae397b06432b2184c279e41aa81963c45abb3791ca6a939f8c1b6d437f4e30d4c1044c7697eaa1ba55af3198bd22", 7 | "private_key": "16bb6962b0fa54c83d97f5b139a73148a9015b7f9ae7a2dbc5d34753a94ee01b" 8 | } 9 | ], 10 | "mnemonics": "friend display mask album rebel liar pilot trim dad pupil brand trigger enter pink sad mistake miracle insect glad notable cause diesel pool hard", 11 | "version": "1.0", 12 | "date_created": "1661370979", 13 | "nonce": 0 14 | } -------------------------------------------------------------------------------- /tests/tokenomics_tests/config/wallets/sc_owner_wallet.json: -------------------------------------------------------------------------------- 1 | {"client_id":"1746b06bb09f55ee01b33b5e2e055d6cc7a900cb57c0a3a5eaabb8a0e7745802","client_key":"7b630ba670dac2f22d43c2399b70eff378689a53ee03ea20957bb7e73df016200fea410ba5102558b0c39617e5afd2c1843b161a1dedec15e1ab40543a78a518","keys":[{"public_key":"7b630ba670dac2f22d43c2399b70eff378689a53ee03ea20957bb7e73df016200fea410ba5102558b0c39617e5afd2c1843b161a1dedec15e1ab40543a78a518","private_key":"c06b6f6945ba02d5a3be86b8779deca63bb636ce7e46804a479c50e53c864915"}],"mnemonics":"cactus panther essence ability copper fox wise actual need cousin boat uncover ride diamond group jacket anchor current float rely tragic omit child payment","version":"1.0","date_created":"2021-08-04 18:53:56.949069945 +0100 BST m=+0.018986002"} -------------------------------------------------------------------------------- /tests/tokenomics_tests/config/wallets/sharder01_node_delegate_wallet.json: -------------------------------------------------------------------------------- 1 | { 2 | "client_id": "b888ae3400b67a47362aad7d6263fcfeb6585fe696e8d182d3bb4f4a9d737bae", 3 | "client_key": "e2075a6d93dd3544e14a185b03e7bf5fbf402fe498452b3e786ddb6b500be2095eaa42ef748ccd0e139e6cc041c19da4dffa06ecb9b37bed783e4bffd89b8295", 4 | "keys": [ 5 | { 6 | "public_key": "e2075a6d93dd3544e14a185b03e7bf5fbf402fe498452b3e786ddb6b500be2095eaa42ef748ccd0e139e6cc041c19da4dffa06ecb9b37bed783e4bffd89b8295", 7 | "private_key": "0d3c9bf1844fb66cc98fd82c6a93d6ed0199aef8af3387cfdd7bc53f3e2aa602" 8 | } 9 | ], 10 | "mnemonics": "manage envelope elephant bamboo inmate blast legend quality vocal cushion black party mad mixture coyote prepare visit surge pair elite treat place match blouse", 11 | "version": "1.0", 12 | "date_created": "1661370992", 13 | "nonce": 0 14 | } -------------------------------------------------------------------------------- /tests/tokenomics_tests/config/wallets/sharder02_node_delegate_wallet.json: -------------------------------------------------------------------------------- 1 | { 2 | "client_id": "b3e3f587dd65aaf4118adf87878a138dbb3163a3b169a0d1872aa9a7a0fa5c50", 3 | "client_key": "1f7d5b5d96b5f97d4dd6d421b9fa69dc9b9fd11768d71b387ec4c0607092f608f3f13481062a0dc3536f980e2962a52ca6a3bac6ad90cabd1d29b83d3a32a19f", 4 | "keys": [ 5 | { 6 | "public_key": "1f7d5b5d96b5f97d4dd6d421b9fa69dc9b9fd11768d71b387ec4c0607092f608f3f13481062a0dc3536f980e2962a52ca6a3bac6ad90cabd1d29b83d3a32a19f", 7 | "private_key": "2ba53541de3cb2ed6d1fc1489ef94479794f2180c052c7f7002d5db45f39f624" 8 | } 9 | ], 10 | "mnemonics": "secret mansion motor tissue grid host scorpion pill doll burger noble replace menu caution uniform clock long secret install pencil lock yellow coach dream", 11 | "version": "1.0", 12 | "date_created": "1661371000", 13 | "nonce": 0 14 | } -------------------------------------------------------------------------------- /tests/tokenomics_tests/config/wallets/validator1_delegate1_wallet.json: -------------------------------------------------------------------------------- 1 | {"client_id":"fe440fb9a870202b16aa8536bf03ef1e125edcd197e951efc46909b92b8ed88d","client_key":"dbd96098871b00bbe51d2a3deeb2fa11e556b878a91dd020b63a8f959e8a731886c195774d34354675c15150c9386fdf5446e7aa41b2150844294403f3c98898","keys":[{"public_key":"dbd96098871b00bbe51d2a3deeb2fa11e556b878a91dd020b63a8f959e8a731886c195774d34354675c15150c9386fdf5446e7aa41b2150844294403f3c98898","private_key":"eafe5e2db1fc40185e4aa7fb6b029ac60cc9d86b9780935dc12a3ae5aa36371f"}],"mnemonics":"exit possible endorse poverty token minor enrich early sausage common funny meadow grab super squeeze salute inmate soap champion version invest hotel affair box","version":"1.0","date_created":"1680361042","nonce":0} -------------------------------------------------------------------------------- /tests/tokenomics_tests/config/wallets/validator1_delegate2_wallet.json: -------------------------------------------------------------------------------- 1 | {"client_id":"15ddaf7f9e5044b1c5fa2ef43ab4da342aa23ecc32f5d0ce5437d61a5d9df3df","client_key":"a9d527c2e6bd9b4829a2ab6dc604b59e98b31088e829fdcc0deeb0bdb65b9113409fdfd56d3c79a4579abe8e12760f998262fcefc68aaa5a07522b58f897551a","keys":[{"public_key":"a9d527c2e6bd9b4829a2ab6dc604b59e98b31088e829fdcc0deeb0bdb65b9113409fdfd56d3c79a4579abe8e12760f998262fcefc68aaa5a07522b58f897551a","private_key":"180f5897f0b0696be90fb1800ef8c2faf88ebfc97418fbe7a7b79813251d261e"}],"mnemonics":"lunch seed hunt cook denial resource parent grocery anchor napkin regret slim weekend proof pattern swallow employ desert village cloth royal cry crunch abuse","version":"1.0","date_created":"1680361059","nonce":0} -------------------------------------------------------------------------------- /tests/tokenomics_tests/config/wallets/validator1_wallet.json: -------------------------------------------------------------------------------- 1 | {"client_id":"334238e2c3753fec18d654099f21c911fa370188b4fc6d951efcf8fedfed1b6d","client_key":"3156f136f79e2bec57680947b3985f16b9aedceaaac10eb4af6f0c85df8bb41cd6d8a1655cce2582f20802f94d70326930baafd8300ebe1ee7b778591d86ed9b","keys":[{"public_key":"3156f136f79e2bec57680947b3985f16b9aedceaaac10eb4af6f0c85df8bb41cd6d8a1655cce2582f20802f94d70326930baafd8300ebe1ee7b778591d86ed9b","private_key":"560dd01af41906c7df2722fc00943ef008a8bc50df9dec4a53aa647ae15db41b"}],"mnemonics":"garage uncover diesel machine ginger lab horror wise win creek flee fringe viable valid pen such good cover industry stuff intact employ hope permit","version":"1.0","date_created":"1676634658","nonce":0} -------------------------------------------------------------------------------- /tests/tokenomics_tests/config/wallets/validator2_delegate1_wallet.json: -------------------------------------------------------------------------------- 1 | {"client_id":"9df0bfb1114c31a8a31fa5ab432e3514e34edb655a788f660228645d642551e1","client_key":"fd785e64d21f72295e9784f5bc23407cc99b97863a273c696953306a49e75317be1887ab1695d35cda1c8a49ca1bd791a743c10ad54a41fe96d216da4c575e23","keys":[{"public_key":"fd785e64d21f72295e9784f5bc23407cc99b97863a273c696953306a49e75317be1887ab1695d35cda1c8a49ca1bd791a743c10ad54a41fe96d216da4c575e23","private_key":"3cab52442bf2218121a2e3411d11db1203ceb07412c554b1ed944c3ab156f415"}],"mnemonics":"team drop quality leave vintage secret phone mask banana inherit hybrid tooth diagram media achieve street elder hour kangaroo vacant gather valley drop obey","version":"1.0","date_created":"1680361072","nonce":0} -------------------------------------------------------------------------------- /tests/tokenomics_tests/config/wallets/validator2_delegate2_wallet.json: -------------------------------------------------------------------------------- 1 | {"client_id":"0143967236c224855e1ad6791cdfdfa6409d7789950f5b95a55b0147636d8fea","client_key":"8b753604a1de7974b24459b06472807caa9f454ec3f3fde71d80633c7765c912e5dfb187a6bd0ba7867f375dab7c22002f0d8bfed809c1170fe752192b30da15","keys":[{"public_key":"8b753604a1de7974b24459b06472807caa9f454ec3f3fde71d80633c7765c912e5dfb187a6bd0ba7867f375dab7c22002f0d8bfed809c1170fe752192b30da15","private_key":"0420dd449acf8bfde614198c0fff8cd35a4af8dd0152eecc5b6374afe4461b13"}],"mnemonics":"rookie twelve render credit dolphin pool fatal catalog drive scatter captain canvas idle knife elbow spin select token angle gospel eight giggle hen cradle","version":"1.0","date_created":"1680361084","nonce":0} -------------------------------------------------------------------------------- /tests/tokenomics_tests/config/wallets/validator2_wallet.json: -------------------------------------------------------------------------------- 1 | {"client_id":"e77872ee40afd02fe4873a057c212e768c5efd26280a6b8a8afc9375ba7b09c8","client_key":"293511382e9c87342795e0bf31f0d38821488d889a011c09adc8179f6a4bdb0e95adb975ee65a86a429258a8fb885a0b079c4659cd641cdff2f49362e3acac90","keys":[{"public_key":"293511382e9c87342795e0bf31f0d38821488d889a011c09adc8179f6a4bdb0e95adb975ee65a86a429258a8fb885a0b079c4659cd641cdff2f49362e3acac90","private_key":"a3ae273a1edc23c93a807c19b25958f049bdb3af9ef19aff8074e4c8ab38a205"}],"mnemonics":"public believe example melt inherit path inquiry lizard joy clown lumber toddler verb shove rhythm spider rubber ski tree plug shaft face panel large","version":"1.0","date_created":"1676638952","nonce":0} -------------------------------------------------------------------------------- /tests/tokenomics_tests/config/wallets/validator_owner_wallet.json: -------------------------------------------------------------------------------- 1 | {"client_id": "ff867f12bdcc4999f3c42c5d61a81854f6510f71e3c9d9531a6d8bcd206e2d65","client_key": "340102d1a28bc4a9afb1347ff4a27dd1c25e0c215c66c015772bd76a3d6e4a03c2405b7dd560e07938c3220127ee58aabd92554297c3f8327e340d60b717a8a1","keys": [{"public_key": "340102d1a28bc4a9afb1347ff4a27dd1c25e0c215c66c015772bd76a3d6e4a03c2405b7dd560e07938c3220127ee58aabd92554297c3f8327e340d60b717a8a1","private_key": "48e1bad31a920bfb5fad0fd9670f312e0c5304689a9d2f255f2ec2104bf3ef0a"}],"mnemonics": "glory cloud that cabbage real couple flat suffer forget exhibit inmate glove measure year onion oval polar aim civil violin cake custom flag trade","version": "1.0","date_created": "2021-12-04T17:03:37Z"} -------------------------------------------------------------------------------- /tests/tokenomics_tests/config/wallets/zbox_team_wallet.json: -------------------------------------------------------------------------------- 1 | {"client_id":"d4c5ad2959282b05a1c267c542c859271670da1b0b44f0714babfb87e57c3c83","client_key":"d7dba8a72b5752b37001d07247e3c7c475c6cb5374962ce608965aeefaa999142b3adfd34e9c1c9949210c05c45b5b51ddb83a3234b56983b3936b25717d6c8d","peer_public_key":"","keys":[{"public_key":"d7dba8a72b5752b37001d07247e3c7c475c6cb5374962ce608965aeefaa999142b3adfd34e9c1c9949210c05c45b5b51ddb83a3234b56983b3936b25717d6c8d","private_key":"26e4adfa189350df06bf1983569e03a50fb69d6112386e76610e8b08cc90a009"}],"mnemonics":"now segment air treat fame sport trouble open shed jewel bird shock cave shove quick embody hundred hole replace cheap mammal panel recycle decorate","version":"1.0","date_created":"2025-03-13T16:19:26Z","nonce":0,"is_split":false} -------------------------------------------------------------------------------- /tests/tokenomics_tests/config/zbox_config.yaml: -------------------------------------------------------------------------------- 1 | block_worker: https://dev.zus.network/dns 2 | confirmation_chain_length: 3 3 | ethereum_node_url: https://goerli.infura.io/v3/773bfe30452f40f998e5d0f2f8a29888 4 | min_confirmation: 50 5 | min_submit: 50 6 | signature_scheme: bls0chain 7 | store_unlock_duration_sec: 2 8 | ethereum_address: 0xD8c9156e782C68EE671C09b6b92de76C97948432 9 | -------------------------------------------------------------------------------- /tests/tokenomics_tests/utils/general.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | "regexp" 7 | "strings" 8 | 9 | "github.com/stretchr/testify/require" 10 | 11 | "github.com/0chain/system_test/internal/api/util/test" 12 | ) 13 | 14 | const ( 15 | configPath = "./zbox_config.yaml" 16 | 17 | KB = 1024 // kilobyte 18 | MB = 1024 * KB // megabyte 19 | GB = 1024 * MB // gigabyte 20 | 21 | tokenUnit float64 = 1e+10 22 | ) 23 | 24 | func EscapedTestName(t *test.SystemTest) string { 25 | replacer := strings.NewReplacer("/", "-", "\"", "-", ":", "-", "(", "-", 26 | ")", "-", "<", "LESS_THAN", ">", "GREATER_THAN", "|", "-", "*", "-", 27 | "?", "-") 28 | return replacer.Replace(t.Name()) 29 | } 30 | 31 | func CreateParams(params map[string]interface{}) string { 32 | var builder strings.Builder 33 | 34 | for k, v := range params { 35 | if v == nil { 36 | _, _ = builder.WriteString(fmt.Sprintf("--%s ", k)) 37 | } else if reflect.TypeOf(v).String() == "bool" { 38 | _, _ = builder.WriteString(fmt.Sprintf("--%s=%v ", k, v)) 39 | } else { 40 | _, _ = builder.WriteString(fmt.Sprintf("--%s %v ", k, v)) 41 | } 42 | } 43 | return strings.TrimSpace(builder.String()) 44 | } 45 | 46 | func IntToZCN(balance int64) float64 { 47 | return float64(balance) / tokenUnit 48 | } 49 | 50 | func UnitToZCN(unitCost float64, unit string) float64 { 51 | switch unit { 52 | case "SAS", "sas": 53 | unitCost /= 1e10 54 | return unitCost 55 | case "uZCN", "uzcn": 56 | unitCost /= 1e6 57 | return unitCost 58 | case "mZCN", "mzcn": 59 | unitCost /= 1e3 60 | return unitCost 61 | } 62 | return unitCost 63 | } 64 | 65 | func AssertOutputMatchesAllocationRegex(t *test.SystemTest, re *regexp.Regexp, str string) { 66 | match := re.FindStringSubmatch(str) 67 | require.True(t, len(match) > 0, "expected allocation to match regex", re, str) 68 | } 69 | -------------------------------------------------------------------------------- /tests/tokenomics_tests/utils/miners.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "io" 7 | "net/http" 8 | "reflect" 9 | "sort" 10 | "strings" 11 | "time" 12 | 13 | cliutil "github.com/0chain/system_test/internal/cli/util" 14 | 15 | "github.com/0chain/system_test/internal/api/util/test" 16 | climodel "github.com/0chain/system_test/internal/cli/model" 17 | "github.com/stretchr/testify/require" 18 | ) 19 | 20 | const ( 21 | MinerSmartContractAddress = "6dba10422e368813802877a85039d3985d96760ed844092319743fb3a76712d9" 22 | FaucetSmartContractAddress = "6dba10422e368813802877a85039d3985d96760ed844092319743fb3a76712d3" 23 | StorageSmartContractAddress = "6dba10422e368813802877a85039d3985d96760ed844092319743fb3a76712d7" 24 | ZCNSmartContractAddess = "6dba10422e368813802877a85039d3985d96760ed844092319743fb3a76712e0" 25 | ) 26 | 27 | func apiGetLatestFinalized(sharderBaseURL string) (*http.Response, error) { 28 | return http.Get(sharderBaseURL + "/v1/block/get/latest_finalized") 29 | } 30 | 31 | func getNodeBaseURL(host string, port int) string { 32 | return fmt.Sprintf(`http://%s:%d`, host, port) 33 | } 34 | 35 | func GetLatestFinalizedBlock(t *test.SystemTest) *climodel.LatestFinalizedBlock { 36 | output, err := CreateWallet(t, configPath) 37 | require.Nil(t, err, "Failed to register wallet", strings.Join(output, "\n")) 38 | 39 | sharders := getShardersList(t) 40 | sharder := sharders[reflect.ValueOf(sharders).MapKeys()[0].String()] 41 | sharderBaseUrl := getNodeBaseURL(sharder.Host, sharder.Port) 42 | 43 | res, err := apiGetLatestFinalized(sharderBaseUrl) 44 | require.Nil(t, err, "Error retrieving latest block") 45 | require.True(t, res.StatusCode >= 200 && res.StatusCode < 300, "Failed API request to get latest block: %d", res.StatusCode) 46 | require.NotNil(t, res.Body, "Latest block API response must not be nil") 47 | 48 | resBody, err := io.ReadAll(res.Body) 49 | require.Nil(t, err, "Error reading response body") 50 | 51 | var block climodel.LatestFinalizedBlock 52 | err = json.Unmarshal(resBody, &block) 53 | require.Nil(t, err, "Error deserializing JSON string `%s`: %v", string(resBody), err) 54 | 55 | return &block 56 | } 57 | 58 | func GetSortedMinerIds(t *test.SystemTest, sharderBaseURL string) []string { 59 | return getSortedNodeIds(t, "getMinerList", sharderBaseURL) 60 | } 61 | 62 | func getSortedNodeIds(t *test.SystemTest, endpoint, sharderBaseURL string) []string { 63 | nodeList := getNodeSlice(t, endpoint, sharderBaseURL) 64 | var nodeIds []string 65 | for i := range nodeList { 66 | nodeIds = append(nodeIds, nodeList[i].ID) 67 | } 68 | sort.Slice(nodeIds, func(i, j int) bool { 69 | return nodeIds[i] < nodeIds[j] 70 | }) 71 | return nodeIds 72 | } 73 | 74 | func getNodeSlice(t *test.SystemTest, endpoint, sharderBaseURL string) []climodel.Node { 75 | t.Logf("getting miner or sharder nodes...") 76 | url := sharderBaseURL + "/v1/screst/" + MinerSmartContractAddress + "/" + endpoint 77 | nodeList := cliutil.ApiGetRetries[climodel.NodeList](t, url, nil, 3) 78 | return nodeList.Nodes 79 | } 80 | 81 | func MinerOrSharderLock(t *test.SystemTest, cliConfigFilename, params string, retry bool) ([]string, error) { 82 | return minerOrSharderLockForWallet(t, cliConfigFilename, params, EscapedTestName(t), retry) 83 | } 84 | 85 | func minerOrSharderLockForWallet(t *test.SystemTest, cliConfigFilename, params, wallet string, retry bool) ([]string, error) { 86 | t.Log("locking tokens against miner/sharder...") 87 | if retry { 88 | return cliutil.RunCommand(t, fmt.Sprintf("./zwallet mn-lock %s --silent --wallet %s_wallet.json --configDir ./config --config %s", params, wallet, cliConfigFilename), 3, time.Second) 89 | } else { 90 | return cliutil.RunCommandWithoutRetry(fmt.Sprintf("./zwallet mn-lock %s --silent --wallet %s_wallet.json --configDir ./config --config %s", params, wallet, cliConfigFilename)) 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /tests/tokenomics_tests/utils/sharders.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "encoding/json" 5 | "reflect" 6 | "strings" 7 | 8 | "github.com/0chain/system_test/internal/api/util/test" 9 | climodel "github.com/0chain/system_test/internal/cli/model" 10 | cliutil "github.com/0chain/system_test/internal/cli/util" 11 | "github.com/stretchr/testify/require" 12 | ) 13 | 14 | func getShardersList(t *test.SystemTest) map[string]climodel.Sharder { 15 | return getShardersListForWallet(t, EscapedTestName(t)) 16 | } 17 | 18 | func getShardersListForWallet(t *test.SystemTest, wallet string) map[string]climodel.Sharder { // Get sharder list. 19 | output, err := getShardersForWallet(t, configPath, wallet) 20 | found := false 21 | for index, line := range output { 22 | if line == "MagicBlock Sharders" { 23 | found = true 24 | output = output[index:] 25 | break 26 | } 27 | } 28 | require.True(t, found, "MagicBlock Sharders not found in getShardersForWallet output") 29 | require.Nil(t, err, "get sharders failed", strings.Join(output, "\n")) 30 | require.Greater(t, len(output), 0) 31 | require.Equal(t, "MagicBlock Sharders", output[0]) 32 | 33 | var sharders map[string]climodel.Sharder 34 | err = json.Unmarshal([]byte(strings.Join(output[1:], "")), &sharders) 35 | require.Nil(t, err, "Error deserializing JSON string `%s`: %v", strings.Join(output[1:], "\n"), err) 36 | require.NotEmpty(t, sharders, "No sharders found: %v", strings.Join(output[1:], "\n")) 37 | 38 | return sharders 39 | } 40 | 41 | func GetSharderUrl(t *test.SystemTest) string { 42 | t.Logf("getting sharder url...") 43 | // Get sharder list. 44 | output, err := getSharders(t, configPath) 45 | require.Nil(t, err, "get sharders failed", strings.Join(output, "\n")) 46 | require.Greater(t, len(output), 1) 47 | require.Equal(t, "MagicBlock Sharders", output[0]) 48 | 49 | var sharders map[string]climodel.Sharder 50 | err = json.Unmarshal([]byte(strings.Join(output[1:], "")), &sharders) 51 | require.Nil(t, err, "Error deserializing JSON string `%s`: %v", strings.Join(output[1:], "\n"), err) 52 | require.NotEmpty(t, sharders, "No sharders found: %v", strings.Join(output[1:], "\n")) 53 | 54 | sharder := sharders[reflect.ValueOf(sharders).MapKeys()[0].String()] 55 | 56 | return getNodeBaseURL(sharder.Host, sharder.Port) 57 | } 58 | 59 | func getSharders(t *test.SystemTest, cliConfigFilename string) ([]string, error) { 60 | return getShardersForWallet(t, cliConfigFilename, EscapedTestName(t)) 61 | } 62 | 63 | func getShardersForWallet(t *test.SystemTest, cliConfigFilename, wallet string) ([]string, error) { 64 | t.Logf("list sharder nodes...") 65 | return cliutil.RunCommandWithRawOutput("./zwallet ls-sharders --active --json --silent --wallet " + wallet + "_wallet.json --configDir ./config --config " + cliConfigFilename) 66 | } 67 | 68 | func GetSortedSharderIds(t *test.SystemTest, sharderBaseURL string) []string { 69 | return getSortedNodeIds(t, "getSharderList", sharderBaseURL) 70 | } 71 | --------------------------------------------------------------------------------