DepChain is a Byzantine fault-tolerant (BFT) blockchain with high dependability guarantees supporting transaction execution and smart contract state management. It uses the HotStuff BFT consensus algorithm with an EVM-compatible execution layer powered by Hyperledger Besu.
blockchain/
├── src/main/java/ist/sec/
│ ├── server/ # Server node and HotStuff integration
│ │ ├── consensus/ # Byzantine HotStuff implementation
│ │ └── services/ # BlockchainService, BlockchainState
│ ├── client/ # CLI client and message handling
│ ├── smart_contract/ # Besu EVM integration and world state
│ ├── domain/blockchain/ # Block, Transaction, command model
│ ├── network/ # APL and fault-injection network stack
│ └── genesis/ # Static info + genesis generation
├── configs/ # Scenario configs for robustness demos
├── scripts/ # End-to-end scenario runners (test1..test14)
├── blocks/ # Persisted blocks + genesis
├── keys/ # Generated server/client keys and shares
└── logs/ # Scenario execution logs
The system leverages HotStuff BFT consensus mechanism to. The protocol pipelines block proposals through leader-driven PREPARE, PRE-COMMIT, COMMIT, and DECIDE phases, aggregating validator signatures into Quorum Certificates (QCs) at each step. A timeout-driven pacemaker robustly handles view changes and leader rotation, ensuring the system can recover and advance even if the current leader crashes, equivocates, or becomes isolated. Furthermore, the networking layer explicitly includes support for malicious behavior injection, such as dropping messages, selective communication, replaying stale packets, and leader impersonation, to rigorously test fault tolerance.
By integrating the Besu EVM, DepChain is able to execute standard Solidity smart contracts. Example implementations included in the tests demonstrate ERC-20 token execution and vulnerability mitigations, such as protecting against standard allowance front-running attacks. Transactions monotonically transition the blockchain state, while the system effectively maintains transaction nonces, applies gas semantics to prevent infinite loops and spam, and updates account storage deterministically. Additionally, the blockchain and its corresponding state are continuously written to disk. This allows nodes to crash securely and, upon restarting, replay persisted blocks to rebuild their EVM world state and safely rejoin the active consensus.
Config files (e.g. config.json, configs/test*.json) control the number of nodes, ports, and per-node fault
injection:
{
"numServers": 4,
"numClients": 1,
"serverBasePort": 8000,
"serverConsensusBasePort": 9000,
"clientBasePort": 10000,
"servers": [
{
"id": 0,
"behavior": "NORMAL",
"silentAfterMs": 0,
"dropChance": 0.0,
"corruptChance": 0.0,
"replayChance": 0.0
}
]
}Available behavior values:
| Value | Effect |
|---|---|
NORMAL |
Honest node |
DROP |
Drops outgoing messages with probability dropChance |
CORRUPT_PAYLOAD |
Corrupts outgoing payloads with probability corruptChance |
REPLAY |
Replays outgoing messages with probability replayChance |
SILENT |
Never sends any message |
IGNORE_LEADER |
Discards all messages received from the current leader |
IMPERSONATE_LEADER |
Sends forged leader messages (rejected by APL signature verification) |
INVALID_BLOCK_PROPOSAL |
Byzantine leader tampers with transactions inside proposed blocks so honest replicas reject them |
WITHHOLD_PREPARE |
Byzantine leader withholds PREPARE from a rotating minority of replicas while the rest of the protocol progresses |
WITHHOLD_PREPARE_AND_BLOCK |
Same as WITHHOLD_PREPARE, but also strips block payloads from later messages so missing replicas must recover the block |
Each scenario has a dedicated script under scripts/ and a matching config under configs/.
All scripts check for the JARs first - run mvn package once before using them.
This project is Nix-enabled (flake.nix) and can be built either inside the Nix dev shell or with a system Maven installation.
nix develop
mvn package -qmvn package -qArtifacts:
target/server.jartarget/client.jartarget/generate-static-info.jar
java -jar target/generate-static-info.jar <numServers> <numClients>Example:
java -jar target/generate-static-info.jar 4 1java -jar target/server.jar config.json 0
java -jar target/server.jar config.json 1
java -jar target/server.jar config.json 2
java -jar target/server.jar config.json 3java -jar target/client.jar config.json 0nix develop -c mvn testIf you do not use Nix:
mvn testThe automated JUnit suites cover both correctness and Byzantine-robustness properties:
-
ist.sec.server.services.BlockchainServiceTest- Command parsing and malformed payload rejection.
- Client response emission format.
- Spoofed sender rejection for native transfers.
- Nonce replay rejection and fee-priority ordering checks.
-
ist.sec.server.services.ByzantineClientValidationTest- Invalid signature rejection.
- Command ID / transaction ID mismatch rejection.
- Nonce replay rejection for repeated requests.
- Native transfer sender-address spoofing rejection.
-
ist.sec.server.services.BlockchainStateTest- Block persistence and height progression.
- Multi-block append behavior.
- Recovery from persisted blocks.
- Tolerance to malformed block filenames.
-
ist.sec.server.services.BlockchainPersistenceRecoveryTest- Persistence/recovery behavior in isolated recovery-focused cases.
- Ability to continue appending after recovery.
-
ist.sec.server.services.GasFeeSemanticsTest- Native transfer fee debit + creator fee credit.
- Gas-limit-too-low rejection path.
- Insufficient balance rejection with no state corruption.
- Zero gas parameter rejection.
-
ist.sec.domain.blockchain.TransactionSecurityTest- Signature round-trip validation.
- Signature tampering detection.
- Nonce-window enforcement.
- Sender-address verification against public key.
-
ist.sec.util.crypto.AddressDerivationTest- Deterministic Keccak-based address derivation and formatting checks.
- Equivalence between public-key and byte-array derivation paths.
- Address verification behavior (case-insensitive, with/without
0xprefix). - Byzantine sender-spoofing detection and invalid-input handling.
-
ist.sec.util.timer.AccumulatorTimerTest- Batch flush trigger at threshold boundary.
- Deterministic descending
gasPriceordering for accumulated transactions.
-
ist.sec.genesis.GenesisGenerationTest- Genesis JSON format and field structure.
- Key-state initialization correctness.
- Runtime bytecode presence in deployed contract account.
-
ist.sec.smart_contract.EVMUtilsTest- ABI call-data encoding and argument padding behavior.
-
ist.sec.smart_contract.WorldStateSerializationTest- Genesis state import into world model.
- Contract-account materialization from persisted state.
- Basic balance consistency checks.
-
smart_contract.ISTCoinTest- ERC-20 behavior: name/symbol/decimals/supply/balance/transfer/allowance flows.
-
smart_contract.ERC20AntiFrontRunningTestsafeApproveandtransferFromsequences relevant to approval race mitigation.- Reset-to-zero allowance handling and stale-spend protection checks.
chmod +x scripts/*.sh
./scripts/test1_all_normal.sh
./scripts/test2_one_silent.sh
./scripts/test3_ignore_leader.sh
./scripts/test4_impersonate_leader.sh
./scripts/test5_corrupt_and_drop.sh
./scripts/test6_leader_silent.sh
./scripts/test7_normal_batch_timeout.sh
./scripts/test8_replay_consensus_messages.sh
./scripts/test9_two_batches.sh
./scripts/test10_frontrunning_attack_fail_approve.sh
./scripts/test11_frontrunning_attack_reset_approve.sh
./scripts/test12_invalid_block_proposal.sh
./scripts/test13_withhold_prepare.sh
./scripts/test14_withhold_prepare_and_block.shtest1_all_normal.sh: happy path with batching threshold reached and successful commit/response.test2_one_silent.sh: tolerance to one silent replica plus replay/drop network noise.test3_ignore_leader.sh: behavior under leader-ignoring Byzantine nodes and view-change pressure.test4_impersonate_leader.sh: forged leader message attempts are neutralized by signature checks.test5_corrupt_and_drop.sh: resilience under simultaneous payload corruption and message drops.test6_leader_silent.sh: liveness recovery when the initial leader is silent.test7_normal_batch_timeout.sh: low-volume command accumulation flushes by timeout.test8_replay_consensus_messages.sh: replayed consensus messages do not break safety/progress.test9_two_batches.sh: two separate batches are accumulated and committed across views.test10_frontrunning_attack.sh: thesafeApprovemitigation blocks the allowance front-running attack.test11_frontrunning_attack_reset_approve.sh: reset-to-zero approval flow safely allows setting a new allowance after a race.test12_invalid_block_proposal.sh: Byzantine leader tampers with proposal transactions and honest replicas reject the block.test13_withhold_prepare.sh: leader withholdsPREPAREfrom a rotating minority, but honest replicas still recover and commit.test14_withhold_prepare_and_block.sh: same astest13, but missing replicas must also recover stripped block payloads before deciding.