# ZHCASH Experimental Upgrade README, 2026-07-20

This document describes the experimental Linux x86_64 maintenance build:

- Download: `http://95.133.236.37:8080/experimental/linux-x86_64/zhcash-linux-x86_64-experimental-20260720.tar.gz`
- SHA256: `58f305d0be50a59ffc9a2b67c780e2816ed160d2b02d09fd7e04fc617258d018`
- Includes: `zerohourd`, `zerohour-cli`, `zerohour-qt`, `zerohour-tx`, `zerohour-wallet`

The build is experimental. It is intended for compatibility testing before a public maintenance release.

## What Changed

The upgrade keeps the existing network/protocol/consensus behavior unchanged. The only intentional changes are wallet, RPC, Qt, local simulation, diagnostics, and regtest/test infrastructure fixes.

Implemented changes:

- `sendtoaddress` now detects when the destination is an existing contract address and creates a standard `OP_CALL` with empty calldata and the sent ZHC amount. This should trigger Solidity `receive() external payable` or payable fallback.
- `sendtocontract` in Qt no longer silently resets amount to zero for ABI functions marked non-payable. If a non-zero amount is used for a non-payable function, Qt warns the user.
- `callcontract` gas handling was fixed for local simulation. It now supports gas above `DEFAULT_BLOCK_GAS_LIMIT_DGP` up to the configured maximum.
- New RPC option: `-rpcmaxcallcontractgas=<n>`. Default is `1000000000`, capped by `MAX_BLOCK_GAS_LIMIT_DGP`. This affects local `callcontract` simulation only.
- Explicit negative or zero gas values are rejected in RPC paths where gas is provided by the user.
- `createrawtransaction` rejects creating more than one contract output in one transaction in maintenance mode. Historical block execution is not changed.
- Slow validation diagnostics were added:
  - `-zhcslowblockms=<n>`
  - `-zhcslowevmms=<n>`
  - `-zhcslowcommitms=<n>`
- Fresh `regtest` startup was fixed by accepting the configured genesis hash during header proof checks.
- Functional test compatibility shims were added for ZHCASH test imports.

## What Did Not Change

These areas must remain compatible with old nodes and historical data:

- P2P protocol
- block format
- transaction format accepted by consensus
- historical EVM execution rules
- `ZHCASHTxConverter` behavior for old blocks
- state root calculation for historical blocks
- wallet encryption format
- `wallet.dat` Berkeley DB format
- OpenSSL wallet cryptography path: SHA512 plus AES-256-CBC remains unchanged

Consensus changes are forbidden in this maintenance line except for the separately reviewed halving/tail-reward patch.

## Upgrade Checklist

Before replacing a production node:

1. Stop the old node cleanly:

   ```bash
   zerohour-cli stop
   ```

2. Backup the full data directory, especially `wallet.dat`:

   ```bash
   cp -a ~/.zerohour ~/.zerohour.backup-before-20260720
   ```

3. Verify the downloaded archive:

   ```bash
   sha256sum zhcash-linux-x86_64-experimental-20260720.tar.gz
   ```

   Expected:

   ```text
   58f305d0be50a59ffc9a2b67c780e2816ed160d2b02d09fd7e04fc617258d018
   ```

4. Unpack and check versions:

   ```bash
   tar -xzf zhcash-linux-x86_64-experimental-20260720.tar.gz
   ./zhcash-linux-x86_64-experimental-20260720/bin/zerohourd --version
   ./zhcash-linux-x86_64-experimental-20260720/bin/zerohour-qt --version
   ```

5. Start the node with logging for slow validation:

   ```bash
   ./zhcash-linux-x86_64-experimental-20260720/bin/zerohourd \
     -daemon \
     -zhcslowblockms=2000 \
     -zhcslowevmms=1000 \
     -zhcslowcommitms=1000
   ```

## Required Compatibility Checks

Run these checks before declaring the upgrade safe.

### Wallet Checks

- Old `wallet.dat` opens without errors.
- Encrypted wallet unlocks with the old passphrase.
- Existing addresses are visible.
- Existing balance matches the old node.
- `listunspent` returns expected UTXOs.
- A small ordinary `sendtoaddress` to a normal address works.
- Wallet can be stopped and reopened again without corruption.

Useful commands:

```bash
zerohour-cli getwalletinfo
zerohour-cli getbalance
zerohour-cli listunspent
zerohour-cli walletpassphrase "passphrase" 60
```

### Chain And Sync Checks

- Node starts on the existing datadir without reindex unless explicitly requested.
- Best block hash matches a trusted old node at the same height.
- Node can sync past 10,000 blocks.
- Node can stop cleanly after syncing.
- Restart after stop does not trigger block database errors.

Useful commands:

```bash
zerohour-cli getblockchaininfo
zerohour-cli getbestblockhash
zerohour-cli getblockcount
zerohour-cli stop
```

### Peer Compatibility Checks

- The node connects to old public nodes.
- Old nodes do not disconnect this node because of protocol mismatch.
- `getpeerinfo` shows normal inbound/outbound traffic.
- Blocks accepted by the old node are accepted by the new node.

Useful commands:

```bash
zerohour-cli getnetworkinfo
zerohour-cli getpeerinfo
zerohour-cli addnode "193.24.208.96:38100" "onetry"
```

### Smart Contract Checks

- Existing contracts can be queried with `callcontract`.
- A complex `callcontract` that previously hit `Default` gas can run with a larger gas value.
- `callcontract` does not spend coins and does not create on-chain state changes.
- `sendtocontract` with amount works for payable functions.
- Ordinary `sendtoaddress` to an existing contract address creates an `OP_CALL` and triggers payable `receive()` or fallback.
- Ordinary `sendtoaddress` to a normal address remains a normal payment.
- Creating a raw transaction with multiple contract outputs is rejected in maintenance mode.

Example:

```bash
zerohour-cli callcontract <contract> <datahex> "" 100000000
zerohour-cli sendtoaddress <normal_address> 1
zerohour-cli sendtoaddress <contract_address> 1
```

### Qt Checks

- `zerohour-qt` starts on Ubuntu 24.04 with the required X11 runtime libraries installed.
- Wallet opens and shows the expected balance.
- Send form works for normal payments.
- SendToContract amount field stays active.
- Non-payable ABI plus non-zero amount shows a warning instead of silently zeroing the amount.

### Performance Checks

- During initial sync, the UI or daemon logs should show progress rather than appearing permanently stuck.
- Check `debug.log` for slow validation lines:

  ```text
  Slow block validation
  Slow EVM execution
  ```

- If freezes still happen, record:
  - block height
  - block hash
  - last 200 lines of `debug.log`
  - operating system
  - whether Qt or daemon was used

## Rollback

Rollback must preserve the old datadir backup.

1. Stop the experimental node:

   ```bash
   zerohour-cli stop
   ```

2. Restore the backup:

   ```bash
   mv ~/.zerohour ~/.zerohour.experimental-failed
   mv ~/.zerohour.backup-before-20260720 ~/.zerohour
   ```

3. Start the previous known-good binary.

Do not reuse a modified production datadir with an old binary unless a backup exists and the rollback was tested.

## Verification Already Performed

On the build machine:

- Linux CLI and Qt binaries compiled successfully.
- `zerohourd --version` works.
- `zerohour-qt --version` works under `xvfb`.
- `ldd zerohour-qt` reports no missing shared libraries.
- Fresh `regtest` startup works and returns `getblockchaininfo`.
- `test/functional/qtum_callcontract.py` passes.
- `make check` exits successfully, but the current configure generated zero unit tests.

Remaining required validation:

- real mainnet/testnet sync against old nodes;
- old encrypted `wallet.dat` unlock test on user wallets;
- contract receive/fallback test on a known deployed contract;
- Windows and macOS packaging checks are outside this Linux-only experimental build.
