Skip to content

Commit 5d29ce0

Browse files
authored
Merge pull request #9 from AppLayerLabs/development
Sync infos for bdk-cpp
2 parents 82ce995 + 3e604f2 commit 5d29ce0

33 files changed

+465
-466
lines changed
2.06 KB
Loading

.gitbook/assets/core-folder.png

-4.11 KB
Loading

.gitbook/assets/utils-folder.png

6.31 KB
Loading

bdk-implementation/README.md

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,33 +6,42 @@ description: How the functional elements of AppLayer interact with each other.
66

77
This chapter aims to explain in technical detail how the BDK is implemented, as well as its submodules and how everything comes together to deliver a blazing fast blockchain.
88

9-
The first few subchapters paint a more holistic view of the BDK, as most components are pretty straight-forward to understand, and developers are expected to use the [Doxygen](https://doxygen.nl) documentation as a reference to further understand how the project works. The later subchapters show some components that are particularly denser and/or complex enough that they warrant their own separated explanations.
9+
The first few subchapters paint a more holistic view of the BDK, as most components are pretty straight-forward to understand. Developers are expected to use the [Doxygen](https://doxygen.nl) documentation as a reference to further understand how the project works. The later subchapters show some components that are particularly denser and/or complex enough that they warrant their own separated explanations.
1010

1111
Looking at a higher level of abstraction, the original C++ implementation of the BDK is structured like this:
1212

13-
* The `src/bins` folder contains the source files for the project's main executables - the blockchain executable itself, contract ABI generator and other testing-related executables are all coded here in their respective subfolders
13+
* The `src/bins` folder contains the source files for the project's main executables - the blockchain executable itself, contract ABI generator, network simulator, faucet API and other testing-related executables are all coded here in their respective subfolders
14+
* The `src/bytes` folder contains code related to the `bytes` class, a container that deals with raw bytes - specifically the `bytes::join()` function and the `bytes::View` class, both used extensively across the project
1415
* The `src/contract` folder contains everything related to the logic of smart contracts - from ABI parsing to custom variable types and template contracts
1516
* The `src/core` folder contains the heart of the BDK - the main components of the blockchain and what makes it tick
1617
* The `src/libs` folder contains third-party libraries not inherently tied to the project but used throughout development
1718
* The `src/net` folder contains everything related to networking, communication between nodes and support for protocols such as gRPC, HTTP, P2P, JSON-RPC, etc.
1819
* The `src/utils` folder contains several commonly-used functions, structures, classes and overall logic to support the functioning of the BDK as a whole
1920

21+
There is also a `tests` folder that contains several unit tests for each of the components described above.
22+
2023
## Source tree
2124

2225
For the more visually inclined, here is a source tree (headers only) containing all of the files inside the `src` folder (except `src/bins` as it only contains source files), their respective subfolders and which components are declared in them. Each component is further explained through the following subchapters of this documentation. For more technical details (e.g. API references for developers), please refer to the [Doxygen](https://www.doxygen.nl) documentation on the project's own repository.
2326

2427
```
2528
src
29+
├── bytes
30+
│   ├── initializer.h (bytes::Initializer, bytes::SizedInitializer)
31+
│   ├── join.h (bytes::join())
32+
│   ├── range.h (bytes::Range, bytes::DataRange, bytes::BorrowedDataRange)
33+
│   └── view.h (bytes::View, bytes::Span)
2634
├── contract (Contracts)
2735
│   ├── abi.h (ABI - encoders, decoders, helper structs, etc.)
36+
│   ├── calltracer.h (trace namespace, Call struct, CallTracer class)
2837
│   ├── contractfactory.h (ContractFactory)
2938
│   ├── contract.h (ContractGlobals, ContractLocals, BaseContract)
3039
│   ├── contracthost.h (ContractHost)
3140
│   ├── contractmanager.h (ContractManager)
3241
│   ├── contractstack.h (ContractStack)
3342
│   ├── customcontracts.h (for declaring custom contracts)
3443
│   ├── dynamiccontract.h (DynamicContract)
35-
│   ├── event.h (Event, EventManager)
44+
│   ├── event.h (Event)
3645
│   ├── templates (folder for contract templates)
3746
│   │ ├── dexv2 (subfolder for the DEXV2 contract components)
3847
│   │ │ ├── dexv2factory.h (DEXV2Factory)
@@ -44,71 +53,83 @@ src
4453
│   │ ├── erc20wrapper.h (ERC20Wrapper)
4554
│   │ ├── erc721.h (ERC721)
4655
│   │ ├── erc721test.h (ERC721Test, used solely for testing purposes)
56+
│   │   ├── erc721uristorage.h (ERC721URIStorage, converted from OpenZeppelin)
4757
│   │ ├── nativewrapper.h (NativeWrapper)
58+
│   │   ├── ownable.h (Ownable, converted from OpenZeppelin)
59+
│   │   ├── pebble.h (Pebble)
4860
│   │ ├── randomnesstest.h (RandomnessTest)
4961
│   │ ├── simplecontract.h (SimpleContract)
62+
│   │   ├── snailtracer.h, snailtraceroptimized.h (SnailTracer and SnailTracerOptimized, converted from the original EVM impl)
5063
│   │ ├── testThrowVars.h (TestThrowVars, used solely for testing purposes)
51-
│   │ └── throwtestA.h, throwtestB.h, throwtestC.h (for testing CM nested calls)
64+
│   │ └── throwtestA.h, throwtestB.h, throwtestC.h (for testing nested contract calls)
5265
│   └── variables (Safe Variables for use within Dynamic Contracts)
5366
│   ├── reentrancyguard.h (ReentrancyGuard)
5467
│   ├── safeaddress.h (SafeAddress)
5568
│   ├── safearray.h (SafeArray)
5669
│   ├── safebase.h (SafeBase - used as base for all other types)
5770
│   ├── safebool.h (SafeBool)
58-
│   ├── safeint.h (SafeInt)
71+
│   ├── safebytes.h (SafeBytes)
72+
│   ├── safeint.h (SafeInt and respective aliases)
5973
│   ├── safestring.h (SafeString)
6074
│   ├── safetuple.h (SafeTuple)
61-
│   ├── safeuint.h (SafeUint)
75+
│   ├── safeuint.h (SafeUint and respective aliases)
6276
│   ├── safeunorderedmap.h (SafeUnorderedMap)
6377
│   └── safevector.h (SafeVector)
6478
├── core (Core components)
6579
│   ├── blockchain.h (Blockchain, Syncer)
6680
│   ├── consensus.h (Consensus)
6781
│   ├── dump.h (Dumpable, DumpManager, DumpWorker)
68-
│   ├── rdpos.h (Validator, rdPoS, rdPoSWorker)
69-
│   ├── state.h (State)
82+
│   ├── rdpos.h (Validator, rdPoS)
83+
│   ├── state.h (BlockValidationStatus, State)
7084
│   └── storage.h (Storage)
71-
├── libs (Third-party libs)
85+
├── libs (Third-party libraries)
7286
│ ├── BS_thread_pool_light.hpp (https://github.com/bshoshany/thread-pool)
7387
│ ├── catch2/catch_amalgamated.hpp (https://github.com/catchorg/Catch2)
74-
│ └── json.hpp (https://github.com/nlohmann/json)
88+
│ ├── json.hpp (https://github.com/nlohmann/json)
89+
│ ├── wyhash.h (https://github.com/wangyi-fudan/wyhash)
90+
│ └── zpp_bits.h (https://github.com/eyalz800/zpp_bits)
7591
├── net (Networking)
76-
│   ├── grpcclient.h (gRPCClient)
77-
│   ├── grpcserver.h (gRPCServer)
7892
│   ├── http (HTTP part of networking)
7993
│   │   ├── httpclient.h (HTTPClient)
8094
│   │   ├── httplistener.h (HTTPListener)
8195
│   │   ├── httpparser.h (parser functions for HTTP requests)
8296
│   │   ├── httpserver.h (HTTPServer)
8397
│   │   ├── httpsession.h (HTTPQueue, HTTPSession)
8498
│   │   └── jsonrpc (Namespace for handling JSONRPC data)
85-
│   │   ├── decoding.h (functions for decoding JSONRPC data)
86-
│   │   ├── encoding.h (functions for encoding JSONRPC data)
87-
│   │   └── methods.h (declarations for JSONRPC methods)
99+
│   │   ├── blocktag.h (BlockTag, BlockTagOrNumber)
100+
│   │   ├── call.h (call() - a function that processes a JSON RPC call)
101+
│   │   ├── error.h (Error - for abstracting JSON RPC errors)
102+
│   │   ├── methods.h (contains all implemented JSON RPC methods)
103+
│   │   ├── parser.h (Parser and helper tempate functions)
104+
│   │   └── variadicparser.h (VariadicParser and helper template functions)
88105
│   └── p2p (P2P part of networking)
89-
│   ├── client.h (ClientFactory)
106+
│   ├── broadcaster.h (Broadcaster)
90107
│   ├── discovery.h (DiscoveryWorker - worker thread for ManagerDiscovery)
91108
│   ├── encoding.h (collection of enums, structs, classes, encoders and decoders used in P2P communications)
92109
│   ├── managerbase.h (ManagerBase - used as base for ManagerDiscovery and ManagerNormal)
93110
│   ├── managerdiscovery.h (ManagerDiscovery)
94111
│   ├── managernormal.h (ManagerNormal)
95112
│   ├── nodeconns.h (NodeConns)
96-
│   ├── server.h (ServerListener, Server)
97113
│   └── session.h (Session)
98-
└── utils (Base components)
99-
├── contractreflectioninterface.h (ContractReflectionInterface - interface for registering contracts)
114+
└── utils (Utility components)
115+
├── clargs.h (definitions for helper functions, enums and structs that deal with command-line argument parsing)
116+
├── contractreflectioninterface.h (ContractReflectionInterface - interface for registering Dynamic Contracts)
100117
├── db.h (DBPrefix, DBServer, DBEntry, DBBatch, DB)
101118
├── dynamicexception.h (DynamicException - custom exception class)
102119
├── ecdsa.h (PrivKey, Pubkey, UPubkey, Secp256k1)
120+
├── evmcconv.h (EVMCConv - namespace for EVMC-related data conversion functions)
103121
├── finalizedblock.h (FinalizedBlock)
104122
├── hex.h (Hex)
123+
├── intconv.h (IntConv - namespace for signed integer aliases and data conversion functions)
105124
├── jsonabi.h (JsonAbi - namespace for writing contract ABIs to JSON format)
106-
├── logger.h (LogType, Log, LogInfo, Logger)
125+
├── logger.h (LogType, Log, LogInfo, Logger, LogicalLocationProvider)
107126
├── merkle.h (Merkle)
108127
├── options.h (Options singleton - generated by CMake through a .in file)
109128
├── randomgen.h (RandomGen)
110129
├── safehash.h (SafeHash, FNVHash)
111-
├── strings.h (FixedBytes, Hash, Functor, Signature, Address)
130+
├── strconv.h (StrConv - namespace for string-related data conversion and manipulation functions)
131+
├── strings.h (FixedBytes and its derivatives - Hash, Functor, Signature, Address, StorageKey)
112132
├── tx.h (TxBlock, TxValidator)
113-
└── utils.h (definitions for Bytes/Account structs, uint/ethCallInfo types, Networks, and the Utils namespace)
133+
├── uintconv.h (UintConv - namespace for unsigned integer aliases and data conversion functions)
134+
└── utils.h (Utils namespace and other misc struct and enum definitions)
114135
```

bdk-implementation/contract-call-handling.md

Lines changed: 26 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -12,69 +12,42 @@ For example, a call with a variable that starts with the value "10", then five c
1212

1313
## ContractStack class overview
1414

15-
Here's an overview of the `ContractStack` class definition and functionalities:
15+
Here's an overview of the `ContractStack` class definition and functionalities (comments removed for easier reading, check the `contract/contractstack.h` file for more details):
1616

1717
```c++
1818
class ContractStack {
1919
private:
20-
std::unordered_map<Address, Bytes, SafeHash> code_;
21-
std::unordered_map<Address, uint256_t, SafeHash> balance_;
22-
std::unordered_map<Address, uint64_t, SafeHash> nonce_;
23-
std::unordered_map<StorageKey, Hash, SafeHash> storage_;
20+
boost::unordered_flat_map<Address, Bytes, SafeHash> code_;
21+
boost::unordered_flat_map<Address, uint256_t, SafeHash> balance_;
22+
boost::unordered_flat_map<Address, uint64_t, SafeHash> nonce_;
23+
boost::unordered_flat_map<StorageKey, Hash, SafeHash> storage_;
2424
std::vector<Event> events_;
25-
std::vector<Address> contracts_; // Contracts that have been created during the execution of the call, we need to revert them if the call reverts.
25+
std::vector<std::pair<Address,BaseContract*>> contracts_;
2626
std::vector<std::reference_wrapper<SafeBase>> usedVars_;
2727

2828
public:
29-
ContractStack() = default;
30-
~ContractStack() = default;
31-
32-
inline void registerCode(const Address& addr, const Bytes& code) {
33-
if (!this->code_.contains(addr)) {
34-
this->code_[addr] = code;
35-
}
36-
}
37-
38-
inline void registerBalance(const Address& addr, const uint256_t& balance) {
39-
if (!this->balance_.contains(addr)) {
40-
this->balance_[addr] = balance;
41-
}
42-
}
43-
44-
inline void registerNonce(const Address& addr, const uint64_t& nonce) {
45-
if (!this->nonce_.contains(addr)) {
46-
this->nonce_[addr] = nonce;
47-
}
48-
}
49-
50-
inline void registerStorageChange(const StorageKey& key, const Hash& value) {
51-
if (!this->storage_.contains(key)) {
52-
this->storage_[key] = value;
53-
}
54-
}
55-
56-
inline void registerEvent(Event&& event) {
57-
this->events_.emplace_back(std::move(event));
58-
}
59-
60-
inline void registerContract(const Address& addr) {
61-
this->contracts_.push_back(addr);
62-
}
63-
64-
inline void registerVariableUse(SafeBase& var) {
65-
this->usedVars_.emplace_back(var);
66-
}
67-
68-
/// Getters
69-
inline const std::unordered_map<Address, Bytes, SafeHash>& getCode() const { return this->code_; }
70-
inline const std::unordered_map<Address, uint256_t, SafeHash>& getBalance() const { return this->balance_; }
71-
inline const std::unordered_map<Address, uint64_t, SafeHash>& getNonce() const { return this->nonce_; }
72-
inline const std::unordered_map<StorageKey, Hash, SafeHash>& getStorage() const { return this->storage_; }
29+
inline void registerCode(const Address& addr, const Bytes& code) { this->code_.try_emplace(addr, code); }
30+
31+
inline void registerBalance(const Address& addr, const uint256_t& balance) { this->balance_.try_emplace(addr, balance); }
32+
33+
inline void registerNonce(const Address& addr, const uint64_t& nonce) { this->nonce_.try_emplace(addr, nonce); }
34+
35+
inline void registerStorageChange(const StorageKey& key, const Hash& value) { this->storage_.try_emplace(key, value); }
36+
37+
inline void registerEvent(Event event) { this->events_.emplace_back(std::move(event)); }
38+
39+
inline void registerContract(const Address& addr, BaseContract* contract) { this->contracts_.emplace_back(addr, contract); }
40+
41+
inline void registerVariableUse(SafeBase& var) { this->usedVars_.emplace_back(var); }
42+
43+
inline const boost::unordered_flat_map<Address, Bytes, SafeHash>& getCode() const { return this->code_; }
44+
inline const boost::unordered_flat_map<Address, uint256_t, SafeHash>& getBalance() const { return this->balance_; }
45+
inline const boost::unordered_flat_map<Address, uint64_t, SafeHash>& getNonce() const { return this->nonce_; }
46+
inline const boost::unordered_flat_map<StorageKey, Hash, SafeHash>& getStorage() const { return this->storage_; }
7347
inline std::vector<Event>& getEvents() { return this->events_; }
74-
inline const std::vector<Address>& getContracts() const { return this->contracts_; }
48+
inline const std::vector<std::pair<Address,BaseContract*>>& getContracts() const { return this->contracts_; }
7549
inline const std::vector<std::reference_wrapper<SafeBase>>& getUsedVars() const { return this->usedVars_; }
7650
};
7751
```
7852
79-
The existence of only *one* instance of `ContractStack` per `ContractHost`, and its integration within the RAII framework of `ContractHost`, guarantees that state values are meticulously committed or reverted upon the completion or rollback of transactions. This robust design prevents state spill-over between different contract executions, fortifying transaction isolation and integrity across the blockchain network - even in the dynamic and mutable landscape of blockchain transactions, the integrity and consistency of state changes are meticulously maintained, safeguarding against unintended consequences and errors during contract execution.
80-
53+
The existence of only *one* instance of `ContractStack` per `ContractHost`, as well as its integration within the RAII framework of `ContractHost`, guarantees that state values are meticulously committed or reverted upon the completion or rollback of transactions. This robust design prevents state spill-over between different contract executions, fortifying transaction isolation and integrity across the blockchain network - even in the dynamic and mutable landscape of blockchain transactions, the integrity and consistency of state changes are meticulously maintained, safeguarding against unintended consequences and errors during contract execution.

0 commit comments

Comments
 (0)