From 16dab9515151cf425190b3f9a9a11834ad249f87 Mon Sep 17 00:00:00 2001 From: Jean-Lessa <75625278+Jean-Lessa@users.noreply.github.com> Date: Sat, 22 Jun 2024 18:00:27 -0300 Subject: [PATCH 01/10] Update images and infos about code, p2p, safevars, etc. --- .gitbook/assets/core-folder.png | Bin 28496 -> 24289 bytes .gitbook/assets/utils-folder.png | Bin 52234 -> 49860 bytes bdk-implementation/README.md | 23 ++++---- bdk-implementation/database.md | 2 +- bdk-implementation/p2p-encoding.md | 30 ++++++++++- bdk-implementation/p2p-overview.md | 49 +++++++----------- bdk-implementation/the-core-folder.md | 31 +++++------ bdk-implementation/the-utils-folder.md | 41 ++++++++------- bdk-implementation/transactions-and-blocks.md | 30 ++++++----- .../safevariables-and-commit-revert-logic.md | 38 +++++--------- understanding-contracts/solidity-abi.md | 2 - 11 files changed, 126 insertions(+), 120 deletions(-) diff --git a/.gitbook/assets/core-folder.png b/.gitbook/assets/core-folder.png index fd5ea13dc4368eeba1963ae049501e8ebd4f8ef4..58a3aa150d261163222166d525fdd5cf333bad7f 100644 GIT binary patch literal 24289 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 CxVp3e diff --git a/.gitbook/assets/utils-folder.png b/.gitbook/assets/utils-folder.png index 87e422d286e7584efec0fb0cbd06aec134af87b7..f6262aea55b41324330b1a9fb4536e78c68fdd46 100644 GIT binary patch literal 49860 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 f+xP!vIyFo-mx|>aRH*Dfg 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

jndP*WEF< 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 diff --git a/bdk-implementation/README.md b/bdk-implementation/README.md index 0c45002..d6b69cf 100644 --- a/bdk-implementation/README.md +++ b/bdk-implementation/README.md @@ -65,16 +65,14 @@ src │   ├── blockchain.h (Blockchain, Syncer) │   ├── consensus.h (Consensus) │   ├── dump.h (Dumpable, DumpManager, DumpWorker) -│   ├── rdpos.h (Validator, rdPoS, rdPoSWorker) -│   ├── state.h (State) -│   └── storage.h (Storage) +│   ├── rdpos.h (Validator, rdPoS) +│   ├── state.h (BlockValidationStatus, State) +│   └── storage.h (StorageStatus, Storage) ├── libs (Third-party libs) │ ├── BS_thread_pool_light.hpp (https://github.com/bshoshany/thread-pool) │ ├── catch2/catch_amalgamated.hpp (https://github.com/catchorg/Catch2) │ └── json.hpp (https://github.com/nlohmann/json) ├── net (Networking) -│   ├── grpcclient.h (gRPCClient) -│   ├── grpcserver.h (gRPCServer) │   ├── http (HTTP part of networking) │   │   ├── httpclient.h (HTTPClient) │   │   ├── httplistener.h (HTTPListener) @@ -82,20 +80,23 @@ src │   │   ├── httpserver.h (HTTPServer) │   │   ├── httpsession.h (HTTPQueue, HTTPSession) │   │   └── jsonrpc (Namespace for handling JSONRPC data) -│   │   ├── decoding.h (functions for decoding JSONRPC data) -│   │   ├── encoding.h (functions for encoding JSONRPC data) -│   │   └── methods.h (declarations for JSONRPC methods) +│   │   ├── blocktag.h (BlockTag, BlockTagOrNumber) +│   │   ├── call.h (call() - a function that processes a JSON RPC call) +│   │   ├── error.h (Error - for abstracting JSON RPC errors) +│   │   ├── methods.h (contains all implemented JSON RPC methods) +│   │   ├── parser.h (Parser and helper tempate functions) +│   │   └── variadicparser.h (VariadicParser and helper template functions) │   └── p2p (P2P part of networking) -│   ├── client.h (ClientFactory) +│   ├── broadcaster.h (Broadcaster) │   ├── discovery.h (DiscoveryWorker - worker thread for ManagerDiscovery) │   ├── encoding.h (collection of enums, structs, classes, encoders and decoders used in P2P communications) │   ├── managerbase.h (ManagerBase - used as base for ManagerDiscovery and ManagerNormal) │   ├── managerdiscovery.h (ManagerDiscovery) │   ├── managernormal.h (ManagerNormal) │   ├── nodeconns.h (NodeConns) -│   ├── server.h (ServerListener, Server) │   └── session.h (Session) └── utils (Base components) + ├── clargs.h (definitions for helper functions, enums and structs that deal with command-line argument parsing) ├── contractreflectioninterface.h (ContractReflectionInterface - interface for registering contracts) ├── db.h (DBPrefix, DBServer, DBEntry, DBBatch, DB) ├── dynamicexception.h (DynamicException - custom exception class) @@ -103,7 +104,7 @@ src ├── finalizedblock.h (FinalizedBlock) ├── hex.h (Hex) ├── jsonabi.h (JsonAbi - namespace for writing contract ABIs to JSON format) - ├── logger.h (LogType, Log, LogInfo, Logger) + ├── logger.h (LogType, Log, LogInfo, Logger, LogicalLocationProvider) ├── merkle.h (Merkle) ├── options.h (Options singleton - generated by CMake through a .in file) ├── randomgen.h (RandomGen) diff --git a/bdk-implementation/database.md b/bdk-implementation/database.md index e112682..a97c9bf 100644 --- a/bdk-implementation/database.md +++ b/bdk-implementation/database.md @@ -12,7 +12,7 @@ The database requires a filesystem path to open it (if it already exists) or cre Content in the database is stored as raw bytes. This is due to space optimizations, as one raw byte equals two UTF-8 characters (e.g. an address like `0x1234567890123456789012345678901234567890`, ignoring the "0x" prefix, occupies 20 raw bytes - "12 34 56 ..." - , but 40 bytes if converted to a string, since each byte becomes two separate characters - "1 2 3 4 5 6 ..."). -For the main CRUD operations, refer to the `has()`, `get()`, `put()` and `del()` functions. Due to how the database works internally, updating an entry is the same as inserting a different value in a key that already exists, effectively replacing the value that existed before (e.g. `put(oldKey, newValue)`). There's also `getBatch()` and `putBatch()` for batched operations, as well as `getKeys()` for fetching only the keys. +For the main CRUD operations, refer to the `has()`, `get()`, `put()` and `del()` functions. Due to how the database works internally, updating an entry is the same as inserting a different value in a key that already exists, effectively replacing the value that existed before (e.g. `put(oldKey, newValue)`). There's also `getBatch()` and `putBatch()` for batched operations, as well as `getKeys()` for fetching only the keys, and `keyFromStr()` for encapsulating a key into a Bytes object. ## Structs and Prefixes diff --git a/bdk-implementation/p2p-encoding.md b/bdk-implementation/p2p-encoding.md index fc5d8c5..d376ef2 100644 --- a/bdk-implementation/p2p-encoding.md +++ b/bdk-implementation/p2p-encoding.md @@ -137,7 +137,7 @@ Broadcast a given TxValidator to all known connected nodes connected. They shoul Broadcast a given TxBlock to all known connected nodes. They should validate and rebroadcast. * Command ID: `0005` -* Request Type: Broadcast only +* Request Type: Broadcast * Request Payload: Tx RLP * Request Example: `0x02adf01827349cad810005f86b02851087ee060082520894f137c97b1345f0a7ec97d070c70cf96a3d71a1c9871a204f293018008025a0d738fcbf48d672da303e56192898a36400da52f26932dfe67b459238ac86b551a00a60deb51469ae5b0dc4a9dd702bad367d1111873734637d428626640bcef15c` @@ -146,7 +146,7 @@ Broadcast a given TxBlock to all known connected nodes. They should validate and Broadcast a given Block to all known connected nodes. They should validate and rebroadcast. * Command ID: `0006` -* Request Type: Broadcast only +* Request Type: Broadcast * Request Payload: Block RLP * Request Example: `0x02adf01827349cad81000618395ff0c8ee38a250b9e7aeb5733c437fed8d6ca2135fa634367bb288a3830a3c624e33401a1798ce09f049fb6507adc52b085d0a83dacc43adfa519c1228e70122143e16db549af9ccfd3b746ea4a74421847fa0fe7e0e278626a4e7307ac0f600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000186c872a48300000000057de95400000000000000d918395ff0c8ee38a250b9e7aeb5733c437fed8d6ca2135fa634367bb288a3830a3c624e33401a1798ce09f049fb6507adc52b085d0a83dacc43adfa519c1228e70122143e16db549af9ccfd3b746ea4a74421847fa0fe7e0e278626a4e7307ac0f600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000186c872a48300000000057de95400000000000000d9` @@ -163,3 +163,29 @@ Request the TxBlock memory pool of another node. * To encode this, the node has to encode the number of transactions (`0x00000002`), and then append the transactions' sizes and datas in an ordered manner * The resulting answer message would be `0x01adf01827349cad810003000000020000006df86ba4cfffe74621e0caa14dfcb67a6f263391f4a6ad957ace256f3e706b6da07517a63295165701823f44a08cfdf3826149ca0317eaf4f5832c867a4f5050e3e70d635323947d61a4f35618a07dbe86e6a8cef509c7c6174cb8c703ddd8cb695511d72043630d99888ff2ba200000006df86ba4cfffe74621e0caa14dfcb67a6f263391f4a6ad957ace256f3e706b6da07517a63295165701823f44a01545c0c89ad5fda9e4c6ef65f264ef575fa2edebef29d577f88d365ff9d28357a00d9ed64e1675315477aca44908148b9b572c7de45d420398193dcfc2d430d158` +### NotifyInfo + +Same as Info, but as a notification instead (doesn't request the other node's info). + +* Command ID: `0008` +* Request Type: Notification +* Request Payload: node version + epoch + latest nHeight + latest nHash + nConnectedNodes +* Request Example: `0x03adf01827349cad81000800000000000000010005f70436085980000000000000000156aef6ce3d9cefb653ea6a53fc8e810c95268c01428223a8ee267ed2ac9f05d8` + +| Variable | Size | Info | +| -------- | -------- | ------------------------------ | +| version | 8 Bytes | Node Version | +| Epoch | 8 Bytes | Timestamp in UNIX microseconds | +| nHeight | 8 Bytes | latest block nHeight | +| Hash | 32 Bytes | latest block hash | + +### RequestBlock + +Requests data from a given block or range of blocks to another node. + +* Command ID: `0009` +* Request Type: Answer or Request +* Request Payload: block height start range + block height end range + bytes limit (minimum 1 block) +* Request Example: TODO +* Answer Payload: serialized block size + content (1..N blocks) +* Answer Example: TODO diff --git a/bdk-implementation/p2p-overview.md b/bdk-implementation/p2p-overview.md index 84ddeee..6c921c4 100644 --- a/bdk-implementation/p2p-overview.md +++ b/bdk-implementation/p2p-overview.md @@ -6,9 +6,13 @@ description: A primer on how P2P messaging works in the Blockchain Development K This subchapter provides a comprehensive overview of the P2P classes and their organization within the BDK. It further elaborates on the life-cycle of a P2P connection and the dynamic flow of data between nodes. All classes described here are inside the `src/net/p2p` folder. Check their header files for full details on how each of them work. +## NodeConns + +The `NodeConns` class (`nodeconns.h`) takes the role of maintaining and periodically updating a list of all peer nodes in the network that are connected to the local node, as well as their respective info. It is through this list that the node keeps itself up-to-date with the most recent node info possible, while also dropping stale connections/timed out peers every now and then to avoid potential network sync problems. + ## Session -The `Session` class (`session.h`) encapsulates a TCP connection with a remote node, responsible for managing handshakes, sending and receiving messages by reading and writing socket data. It has a queue for outbound messages, allowing any thread that is responsible for sending a message to carry on with its task without having to wait for the message transmission to complete, and serves as a base for the `ClientSession` and `ServerSession` specialized classes. +The `Session` class (`session.h`) encapsulates a TCP connection with a remote node, responsible for managing handshakes, sending and receiving messages by reading and writing socket data. It servees for both client and server connections, having queues for both inbound and outbound messages, allowing any thread that is responsible for sending a message to carry on with its task without having to wait for the message transmission to complete. Sessions are designed to be used as `shared_ptr`s with `shared_from_this` to manage their lifecycles, as they primarily exist within the handlers of Boost's `io_context`. Once a session has successfully established a connection with a remote node, it is added to a list of sessions controlled by a manager. It is critical to properly manage those shared pointers, as the destructor of the `Session` class is intrinsically linked to the destructor of the socket, which, in turn, calls the `io_context`. If the pointer persists but its referenced `io_context` no longer exists, this will lead to a program crash. @@ -16,7 +20,7 @@ For instance, functions called by the thread pool to parse asynchronous operatio ## Life cycle of a session -Upon instantiation, a session's life-cycle is composed of three different routines: _handshake_, _read_ and _write_. +Upon instantiation, a session's life-cycle is composed of three different routines: *handshake*, *read* and *write*. ### Handshake routine @@ -49,31 +53,9 @@ The third routine is writing outbound messages going to the remote endpoint, lik * `do_write_message()` writes the full message, and calls `on_write_message()` when done * `on_write_message()` is a callback for when the message write process is done, locking the queue mutex, grabbing the next message from the queue, and calling `do_write_header()` again - this loop goes on until the queue is empty, where the outbound message pointer is set to null and any further callbacks from the write strand come to a halt -## ClientFactory - -The `ClientFactory` class (`client.h`) serves as an intermediary that allows the P2P manager to instantiate and launch a new outbound client session with a given IP address and port. It does not directly manage these instances, but rather facilitates their creation and execution within an `io_context`. At present, the class operates the `io_context` across _four_ threads. We use strands to effectively manage and execute asynchronous operations within the sessions. - -The code snippet below, demonstrates how a new `ClientSession` is instantiated and put into operation by `ClientFactory`: - -```cpp -void ClientFactory::createClientSession(const boost::asio::ip::address &address, const unsigned short &port) { - tcp::socket socket(this->io_context_); - auto session = std::make_shared(std::move(socket), ConnectionType::OUTBOUND, manager_, this->threadPool_, address, port); - session->run(); -} - -void ClientFactory::connectToServer(const boost::asio::ip::address &address, const unsigned short &port) { - boost::asio::post(this->connectorStrand_, std::bind(&ClientFactory::createClientSession, this, address, port)); -} -``` - -## Server - -The `Server` class (`server.h`) acts as a straightforward TCP server, listening for and creating new sessions for each incoming connection. It does not directly manage the sessions, it only focuses on accepting connections, creating corresponding sessions, and executing them within a designated `io_context`. - ## ManagerBase and derivatives -The P2P manager acts as the backbone of the P2P network. It bears the responsibility of managing `Session`s, the `Server`, and the `ClientFactory`, overseeing their operations and indirectly managing the `io_context`. Just like the `Session` class and its derivatives, the `ManagerBase` class (`managerbase.h`) serves as a base for the `ManagerNormal` (for Normal nodes) and `ManagerDiscovery` (for Discovery nodes) specialized classes. +The P2P manager acts as the backbone of the P2P network. It bears the responsibility of managing `Session`s, overseeing their operations and indirectly managing the `io_context`, and serves as a base for the `ManagerNormal` (for Normal nodes) and `ManagerDiscovery` (for Discovery nodes) specialized classes. Once a `Session` has successfully completed a handshake, it is registered within the manager, which then oversees the `Session`'s lifecycle. The manager's responsibilities include maintaining a registry of active `Session`s, handling incoming and outgoing requests and responses, and maintaining the communication between them. @@ -83,15 +65,22 @@ It's also important to be aware of the lifespan of the `io_context` and the obje ## Message types -Every incoming message is promptly parsed by the manager via the `handleMessage()` function. These messages can fall into one of three categories: `Request`, `Response`, or `Broadcast`, and each type is handled distinctly by the manager. +Every incoming message is promptly parsed by the manager via the `handleMessage()` function. These messages can fall into one of the following categories, with each one of them being treated distinctly: -A `Request` message represents a query for specific data from another node (e.g. a list of blocks, a list of transactions, info about the node itself, etc.), while a `Response` message represents an answer to said query. Both types work together in a bidirectional flow that goes like this: +* `Request` - a query for specific data from another node - e.g. a list of blocks, a list of transactions, info about the node itself, etc. +* `Answer` - an answer to a given request +* `Broadcast` - a dissemination of specific data to the network *with* possible re-broadcasting ("flooding"), such as a new block or transaction +* `Notification` - a dissemination of specific data to the network *without* re-broadcasting, such as node info + +Both `Request` and `Answer` messages work together in a bidirectional flow that goes like this: * The sender node initiates a `Request` by generating a random 8-byte ID, registering it internally and sending it alongside the message -* The receiver node receives the `Request`, its manager processes it by invoking the corresponding function to address it, formulates a `Response` with the requested data, assigns it the same ID and sends it back to the sender node -* The sender node receives the `Response` and checks if the received ID is the same one that was registered earlier. If it is, the manager fulfills the associated `Request` future with the received `Response` and deregisters the ID. If the ID is _not_ registered, the `Response` is discarded altogether +* The receiver node receives the `Request`, its manager processes it by invoking the corresponding function to address it, formulates an `Answer` with the requested data, assigns it the same ID and sends it back to the sender node +* The sender node receives the `Answer` and checks if the received ID is the same one that was registered earlier. If it is, the manager fulfills the associated `Request` future with the received `Answer` and deregisters the ID. If the ID is _not_ registered, the `Answer` is discarded altogether + +Both `Notification` and `Broadcast` messages, however, work with a simpler unidirectional flow, as the receiver node doesn't have to answer back to the sender. Instead, it verifies the received data and adds it to its own blockchain. The difference between both types is that `Notification` messages are never re-broadcast, while `Broadcast` messages may or may not be re-broadcast to other nodes, depending on whether said nodes had already received or not said broadcast in the past. -A `Broadcast` message signals a unilateral dissemination of certain data such as a new block or transaction. This type of communication contrasts the `Request`<->`Response` bidirectional flow, as the receiver node doesn't have to answer back to the sender. Instead, it verifies the received data and adds it to its own blockchain, rebroadcasting it to other nodes if necessary. +Due to this specific condition, `Broadcast` messages are specifically handled by the `Broadcaster` class (`Broadcaster.h`), while the other types are handled by `ManagerBase` and its derivative classes. ## Asynchronous Message Parsing diff --git a/bdk-implementation/the-core-folder.md b/bdk-implementation/the-core-folder.md index 102a3e5..19fd4df 100644 --- a/bdk-implementation/the-core-folder.md +++ b/bdk-implementation/the-core-folder.md @@ -15,11 +15,12 @@ The `blockchain.h` file contains the **Blockchain** and **Syncer** classes. The **Blockchain** class acts as the mother class that unites all the other components described throughout the docs, including the Syncer. Think of it as "the power button on AppLayer's PC case" - its objective is to be the entry point of the system and act as a mediator for the other components, passing around data to each other, such as (but not limited to): * The global options singleton +* The P2P connection manager * The database * The blockchain history/storage (for blocks and contract events) -* The blockchain state -* The rdPoS protocol -* The HTTP and P2P servers +* The blockchain state (which contains the rdPoS protocol in itself) +* The HTTP server +* The consensus protocol The **Syncer** class is responsible for syncing the blockchain with other nodes in the network, as well as handling proper transaction broadcasts and block creations (if the node happens to be a Validator). @@ -27,9 +28,19 @@ The **Syncer** class is responsible for syncing the blockchain with other nodes The `consensus.h` file contains the **Consensus** class - responsible for processing blocks and transactions in the blockchain and applying the network's consensus rules into them. +## Database dumping + +The `dump.h` file contains the **Dumpable**, **DumpManager** and **DumpWorker** classes - together they are responsible for dumping the blockchain's components from memory to disk when required (e.g. blocks, transactions, contracts, the state itself, etc.) + +*Dumpable* is an abstraction of a dumpable object - that is, any component that inherits it is able to dump itself to disk. All classes that inherit it must implement their own dumping routine accordingly. + +*DumpManager* is the class that manages a list of Dumpable components in the blockchain, iterating through each of them and dumping them one by one when told to. + +*DumpWorker* acts as a worker thread for DumpManager, doing the actual work of dumping each Dumpable component sent by DumpManager in a separate thread. This allows for parallel dumps, speeding up the process significantly, which is important when there are many objects or particularly heavy ones (e.g. State) that need to be dumped ASAP without hanging the entire blockchain. + ## rdPoS -The `rdpos.h` file contains the **rdPoS** class - the implementation of the _Random Deterministic Proof of Stake_ algorithm used by the AppLayer network - as well as the **rdPoSWorker** and **Validator** classes. rdPoS is also considered a smart contract, but remains part of the AppLayer core protocol. +The `rdpos.h` file contains the **rdPoS** class - the implementation of the *Random Deterministic Proof of Stake* algorithm used by the AppLayer network - as well as the **Validator** class. rdPoS is also considered a smart contract (it derives from **BaseContract**), but as it is an essential part of the AppLayer core protocol, it remains in the `core` folder. ## State @@ -46,20 +57,10 @@ Not all functions from the class update the state. Check the [Doxygen](https://d ## Storage -The `storage.h` file contains the **Storage** class - an abstraction of the blockchain's history, maintaining a collection of blocks approved and validated by the network, other nodes, or itself through time. Those blocks store transactions, contracts, accounts, and can't be altered once they're in the blockchain, only searched for or read from. +The `storage.h` file contains the **Storage** class - an abstraction of the blockchain's history, maintaining a collection of blocks approved and validated by the network, other nodes, or itself through time. Those blocks store transactions, contracts, accounts, and can't be altered once they're in the blockchain, only searched for or read from. The file also contains the **StorageStatus** enum, used to indicate the status of a given block or transaction inside the Storage itself. On node initialization, a history of up to 1000 of the most recent blocks is loaded into memory. Those blocks were stored in a previous initialization in the database. If there are no blocks (e.g. the blockchain was just deployed and initialized for the first time), a "genesis" block is automatically created and loaded in memory. Once a block and its transactions are received from the network, they're stored in memory. If more than 1000 blocks (or 1 million transactions) are stored in memory at a given time, older blocks are periodically saved to the database. This makes the blockchain lightweight memory-wise and extremely responsive. Searching for and reading from blocks in history is done in several places in the system, so when the Storage and DB classes are working together, they act as the end point of the blockchain's operations history. - -## Database dumping - -The `dump.h` file contains the **Dumpable**, **DumpManager** and **DumpWorker** classes - together they are responsible for dumping the blockchain's components from memory to disk when required (e.g. blocks, transactions, contracts, the state itself, etc.) - -_Dumpable_ is an abstraction of a dumpable object - that is, any component that inherits it is able to dump itself to disk. All classes that inherit it must implement their own dumping routine accordingly. - -_DumpManager_ is the class that manages a list of Dumpable components in the blockchain, iterating through each of them and dumping them one by one when told to. - -_DumpWorker_ acts as a worker thread for DumpManager, doing the actual work of dumping each Dumpable component sent by DumpManager in a separate thread. This allows for parallel dumps, speeding up the process significantly, which is important when there are many objects or particularly heavy ones (e.g. State) that need to be dumped ASAP without hanging the entire blockchain. diff --git a/bdk-implementation/the-utils-folder.md b/bdk-implementation/the-utils-folder.md index caf943c..a0b7716 100644 --- a/bdk-implementation/the-utils-folder.md +++ b/bdk-implementation/the-utils-folder.md @@ -8,11 +8,9 @@ This subchapter contains a brief overview of each one of the components inside t

-## FinalizedBlock +## Clargs -The `finalizedblock.h` file contains the **FinalizedBlock** class - an abstraction of the structure of a block sent through the network and stored in the blockchain. A finalized block is inherently *final* - it cannot be modified anymore after construction. - -The class only contains the bare structure and data of a block - it doesn't do any kind of operation, validation or verification on it. Having only finalized blocks across the entire project ensures block state integrity across all nodes. +The `clargs.h` file contains a few helper functions, structs and enums to parse command-line arguments passed to the project's executables. For an executable to be aware of the argument parser, it must be registered inside the **BDKTool** enum and the executable itself must call the `parseCommandLineArgs()` function, passing the arguments in a C-style manner (argc and argv) and the respective enum value. Check the executables' source files for more info. ## ContractReflectionInterface @@ -26,7 +24,7 @@ The `db.h` file contains the **DB** class - an abstraction of a [Speedb](https:/ The `dynamicexception.h` file contains the **DynamicException** class - a custom exception class inherited from `std::exception` used across the whole project. It is meant to be used when there's no applicable exception from the STD library for a given error that should be caught - usually the STD library is too generic, as the project grows some exceptions may become specific to the point we need to handle them in a customized manner. -## Secp256k1 +## ECDSA (Secp256k1) The `ecdsa.h` file contains the **Secp256k1** namespace - helper functions that abstract the functionalities of Bitcoin's [secp256k1](https://en.bitcoin.it/wiki/Secp256k1) elliptic curve cryptography library, used for handling, deriving and recovering private/public keys and addresses, as well as signing and verifying signed messages. @@ -36,6 +34,12 @@ The file also contains a few aliases for easier key handling, which are based on * **PubKey** (same as **FixedBytes<33>**) - alias for a _compressed_ public key * **UPubKey** (same as **FixedBytes<65>**) - alias for an _uncompressed_ public key +## FinalizedBlock + +The `finalizedblock.h` file contains the **FinalizedBlock** class - an abstraction of the structure of a block sent through the network and stored in the blockchain. A finalized block is inherently *final* - it cannot be modified anymore after construction. + +The class only contains the bare structure and data of a block - it doesn't do any kind of operation, validation or verification on it. Having only finalized blocks across the entire project ensures block state integrity across all nodes. + ## Hex The `hex.h` file contains the **Hex** class - an abstraction of a strictly hex-formatted string (meaning it only accepts the characters within the range of `0x[1-9][a-f][A-F]`), which can also be set to strict or not (whether the string REQUIRES the `0x` prefix or not to be considered valid). Also contains aliases for working with raw-byte strings, such as **Byte, Bytes, BytesArr and BytesArrView**. @@ -46,9 +50,9 @@ The `jsonabi.h` file contains the **JsonAbi** namespace - utility functions for ## Logger -The `logger.h` file contains the **Logger** class - a singleton responsible for logging any kind of info - and helper components such as the **Log** namespace (a namespace with predefined string names for referencing other modules), the **LogInfo** class (encapsulated log data), and the **LogType** enum (for flagging the severity of log messages). +The `logger.h` file contains the **Logger** class - a singleton responsible for logging any kind of info - and helper components such as the **Log** namespace (a namespace with predefined string names for referencing other modules), the **LogInfo** class (encapsulated log data), and the **LogType** enum (for flagging the severity of log messages). The `Logger::logToFile()` and `Logger::logToDebug()` functions print the given details to the respective `log.txt` and `debug.txt` files inside the node's directory. -The `Logger::logToFile()` and `Logger::logToDebug()` functions print the given details to the respective `log.txt` and `debug.txt` files inside the node's directory. +The file also contains a plethora of macros to leverage the logging functions and their flags in a more "hands-on" approach, usable anywhere in the project (with a few exceptions depending on the context of where the macro is used in code). Check the Doxygen comments in the file for more info on how to use them. ## Merkle @@ -75,7 +79,7 @@ For `RandomGen` to be useful, it needs to be seeded with a truly random number. The `safehash.h` contains the **SafeHash** struct - a custom hashing implementation for use with `std::unordered_map`, replacing the one used by default in C++'s STD library, like this for example: `std::unordered_map cachedBlocks;`. -Essentially, the STD implementation of `unordered_map` uses `uint64_t` hashes, which is vulnerable to a potentially dangerous edge case where collisions could happen by having an enormous number of accounts and distributing them in a way that they have the same hash across all nodes. +This is done because the STD implementation of `unordered_map` uses `uint64_t` hashes, which is vulnerable to a potentially dangerous edge case where collisions could happen by having an enormous number of accounts and distributing them in a way that they have the same hash across all nodes. [This article from CodeForces](https://codeforces.com/blog/entry/62393) provides a fix, which we implemented so we could continue using `std::unordered_map` normally, as it has blazing fast query times. It's not a perfect fix, since it still uses `uint64_t`, but it's better than nothing since nodes keep different hashes. @@ -83,37 +87,36 @@ The file also contains the **FNVHash** struct - a custom implementation of the [ ## FixedBytes and its child classes -The `strings.h` file contains the **FixedBytes** template class - an abstraction of a normal `std::array` with a fixed size. For example, a `FixedBytes<10>` would have _exactly_ 10 characters in it - no more, no less. If initialized as an empty string, it will remain as a 10-character string nonetheless, with all characters set to "empty" (or `\x00` to be more exact). +The `strings.h` file contains the **FixedBytes** template class - an abstraction of a normal `std::array` with a fixed size. For example, a `FixedBytes<10>` would have *exactly* 10 characters in it - no more, no less. If initialized as an empty string, it will remain as a 10-character string nonetheless, with all characters set to "empty" (or `\x00` to be more exact). -Even though FixedBytes can be used on its own (_it's meant to store only bytes_, after all), it also serves as a base for specific classes, also declared within the same file and created with the intent of dealing with the many different ways that data strings are managed and transferred through the project in a better, less confusing and less convoluted way. They all inherit from the base FixedBytes class, applying fixed sizes of their own: +Even though FixedBytes can be used on its own (*it's meant to store only bytes*, after all), it also serves as a base for specific classes, also declared within the same file and created with the intent of dealing with the many different ways that data strings are managed and transferred through the project in a better, less confusing and less convoluted way: * **Hash** inherits **FixedBytes<32>** and abstracts a given 32-byte hash -* **Functor** inherits **FixedBytes<4>** and abstracts the first 4 bytes of a Solidity function's keccak hash +* **Functor** abstracts the first 4 bytes of a Solidity function's keccak hash, but does not inherit **FixedBytes** directly - instead it opts for a more practical approach and just treats those bytes as a `uint32_t` * **Signature** inherits **FixedBytes<65>** and abstracts a given full ECDSA signature (r, s and v) * **Address** inherits **FixedBytes<20>** and abstracts a given 20-byte address -* **StorageKey** inherits **FixedBytes<52>** and abstracts an EVM storage key (address + slot key) +* **StorageKey** inherits **FixedBytes<52>** and abstracts an EVM storage key (20 bytes address + 32 bytes slot key) ## TxBlock and TxValidator -The `tx.h` file contains the **TxBlock** and **TxValidator** classes - abstractions for a block transaction and a Validator transaction, respectively. The implementation logic and details for transactions within AppLayer are derived from the "Account" model, used by Ethereum and implemented by the [Aleth](https://github.com/ethereum/aleth) library, which is different from the "UTXO" model used by Bitcoin. +The `tx.h` file contains the **TxBlock** and **TxValidator** classes - abstractions for a block transaction and a Validator transaction, respectively. The implementation logic and details for those transactions are derived from the "Account" model, used by Ethereum and implemented by the [Aleth](https://github.com/ethereum/aleth) library, which is different from the "UTXO" model used by Bitcoin. ## Utils -The `utils.h` file contains the **Utils** namespace - a place for more generalized miscellaneous utility functions, namespaces, enums and typedefs used throughout the BDK. +The `utils.h` file contains the **Utils** namespace - a place for generalized miscellaneous utility functions, namespaces, enums and typedefs used across the BDK. This list is only an example and does not reflect the entire contents of the file. We suggest you read the [Doxygen](https://doxygen.nl/) docs for more info about the class: -* Aliases for working with: - * Raw-byte strings (`Byte`,`Bytes`, `BytesArr`, `BytesArrView`), as well as helper functions for converting and/or manipulating them (e.g. `appendBytes()`) - * Unsigned integer types (`uintX_t`, `SafeUintX_t`) +* Helper functions that deal with printing (`safePrint()`, `safePrintTest()`, `printXYZ()`, etc.) +* Aliases for working with integer types (`intX_t`, `uintX_t`, `SafeIntX_t`, `SafeUintX_t`), raw-byte strings (`Byte`,`Bytes`, `BytesArr`, `BytesArrView`), and helper functions for converting and/or manipulating them (e.g. `appendBytes()`, `uintXToBytes()`, `bytesToUintX()`, `bytesToString()`, `stringToBytes()`, etc.) * A map with addresses for Protocol Contracts (e.g. `rdPoS` and `ContractManager`) * Enums for network types (`Networks`), contract function types (`FunctionTypes`) and contract types (`ContractType`) * The `Account` struct, used to maintain account balance and nonce statuses, as well as contract-specific data (if the account represents a contract) * A wrapper for a pointer that ensures the pointer is never null (`NonNullUniquePtr`), as well as a wrapper for a pointer that forcefully nullifies it on destruction (`PointerNullifier`) * The `EventParam` struct, used for abstracting a contract event parameter -* `safePrint()`, used to print details to the node's terminal (which can be checked by attaching a tmux session to it) +* Several templated helper functions that deal with tuples, as well as helper functions that deal with Functors * The `sha3()` function, used extensively as the primary hash function for the entire project -* Functions that convert byte strings to unsigned integers and vice-versa (e.g. `uint256ToBytes()` and `bytesToUint256()`), as well as raw byte strings to normal string and vice-versa (e.g. `bytesToString()` and `stringToBytes()`) +* The `randBytes()` function, used extensively as a random bytes string generator * `padLeft()` and `padRight()`, used for adding padding to strings at their left and right sides, respectively * `padLeftBytes()` and `padRightBytes()`, same as above, but specifically for use with raw byte strings * `toLower()` and `toUpper()`, used for converting strings to all-lower and all-upper case, respectively diff --git a/bdk-implementation/transactions-and-blocks.md b/bdk-implementation/transactions-and-blocks.md index 424c12e..2c21558 100644 --- a/bdk-implementation/transactions-and-blocks.md +++ b/bdk-implementation/transactions-and-blocks.md @@ -31,33 +31,35 @@ Depending on the type, a transaction will contain the following data fields once * **(TxBlock) value** - transaction value in its lowest unit * e.g. "satoshi" for BTC, "Wei" for ETH, etc. - "100000000" satoshis would be 1 BTC, "5000000000" Wei would be 0.000000005 ETH (or 5 gwei), so on and so forth * Since we're using an Ethereum-based format, we commonly refer to its terminology, so "value" is in "Wei" -* **(TxBlock) gasLimit** - maximum limit of gas units that the transaction will use, in Wei (e.g. "21000") - * If the transaction uses more than this limit, it will automatically fail - the original transaction value won't be spent, but what was already spent as gas is lost * **(TxBlock) maxPriorityFeePerGas** - value paid as an incentive for miners to include the transaction in the block, as per [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) * This is implemented but actively ignored since we don't have "miners", therefore only maxFeePerGas is counted * **(TxBlock) maxFeePerGas** - value paid by every unit of gas, in Gwei (e.g. "15" = 15000000000 Wei) * The total transaction fee is calculated as (gasLimit \* maxFeePerGas) - e.g. 21000 \* 15000000000 = 0.000315 ETH +* **(TxBlock) gasLimit** - maximum limit of gas units that the transaction will use, in Wei (e.g. "21000") + * If the transaction uses more than this limit, it will automatically fail - the original transaction value won't be spent, but what was already spent as gas is lost * **(Both)** ECDSA signature (Elliptic Curve Digital Signature Algorithm) for validating transaction integrity, split in three: * **r** - first half of the ECDSA signature (32 hex bytes) * **s** - second half of the ECDSA signature (32 hex bytes) * **v** - recovery ID (1 hex byte) +* **(Both) hash** - The transaction's own hash (including the signature), stored as a cache for performance reasons ## Block structure -Depending on the type, a block will contain the following conceptual structure: +A block will contain the following conceptual structure: -* **(FinalizedBlock only)** Validator signature (the one responsible for creating and signing the block) -* **(FinalizedBlock only)** Validator public key (for verifying the signature) +* Validator signature (the one responsible for creating and signing the block) +* Validator public key (for verifying the signature) * The block's header, which is made of: - * **(Both)** Previous block hash (a hash of the previous block's header, signed by the Validator) - * **(Both)** "Randomness" (a random seed generated by RandomGen during the previous block's creation) - * **(FinalizedBlock only)** Validator Tx Merkle Tree (to verify the integrity of Validator transactions) - * **(FinalizedBlock only)** Block Tx Merkle Tree (to verify the integrity of Block transactions) - * **(Both)** UNIX timestamp of the block, in microseconds - * **(Both)** Block height (commonly known as `nHeight`) -* **(Both)** List of block transactions -* **(Both)** List of Validator transactions -* **(Both)** A cached hash of the block's header + * Previous block hash (a hash of the previous block's header, signed by the Validator) + * "Randomness" (a random seed generated by RandomGen during the previous block's creation) + * Validator Tx Merkle Tree (to verify the integrity of Validator transactions) + * Block Tx Merkle Tree (to verify the integrity of Block transactions) + * UNIX timestamp of the block, in microseconds + * Block height (commonly known as `nHeight`) +* List of Validator transactions +* List of block transactions +* A cached hash of the block's header +* The total size of the block, in bytes In practice, a block is simply a serialized bytes string, transmitted through the network and stored in the blockchain, so it's up to the code logic to properly parse it. Another way to see the block in a more "raw" format would be ("bytes" are in hex format, e.g. `0xFF` = 1 byte): diff --git a/precompiled-contracts/safevariables-and-commit-revert-logic.md b/precompiled-contracts/safevariables-and-commit-revert-logic.md index 3ce6982..f33cddc 100644 --- a/precompiled-contracts/safevariables-and-commit-revert-logic.md +++ b/precompiled-contracts/safevariables-and-commit-revert-logic.md @@ -33,15 +33,14 @@ For Protocol Contracts, that's most of the required context. Dynamic Contracts, All SafeVariables inherit from the `SafeBase` class, which adhere to the following rules: -* Have two internal variables: one for the original value and another that is a pointer to a temporary value -* Must override the `check()`, `commit()`, and `revert()` functions - * `check()` should verify if the temporary value is `nullptr`; if it is, it should set the temporary value to the original value - * `commit()` should copy the temporary value to the original value - * `revert()` should set the temporary value to `nullptr` +* Have two internal variables: one for the current/original value and another for the previous/temporary value + * Optionally, if required, an undo stack for dealing with more complex variables such as containers +* Must override the `commit()`, and `revert()` functions + * `commit()` should keep the current value as-is and either discard the previous one or equal it to the current, depending on the implementation details + * `revert()` should do the opposite - discard the current value and set it back to the previous one (also applying the undo stack if it has one, again, depending on the implementation details) * Must be declared as *private* within contracts and initialized with `this` as the parameter - this enables the SafeVariable to mark itself as used in the `ContractManager`, allowing proper reversion of changes made to the contract -* Must call `check()` and return the temporary value (or reference to the temporary value) -* If non-`const`, must call `markAsUsed()` when accessed, allowing the contract to properly register the variable as used within the function call, and properly revert or commit changes made to the contract accordingly -* When initialized with values in a contract's constructor, must call `commit()` followed by `enableRegister()` so the commit/revert functionality can actually work +* Must call `markAsUsed()` on any and all non-`const` functions that it has (including ones that don't actually change the value), allowing the contract to properly register the variable as used within the function call, and properly revert or commit changes made to the contract accordingly +* When initialized with values in a contract's constructor, must call `commit()` followed by `enableRegister()` so the commit/revert functionality can actually work (see existing contracts for more info) ## Types of SafeVariables @@ -56,23 +55,10 @@ We provide the following SafeVariable types, fully functional and ready for use * `SafeUnorderedMap` - abstracts a mapping * `SafeVector` - abstracts a vector -## Caveats with safe containers +### Caveats -Containers have some exceptions to these rules. Copying the entire container would be prohibitively expensive, so only accessed values are copied to the temporary container. This means they do not behave like regular containers, requiring developers to exercise caution when using iterators or looping through them. - -Our `SafeUnorderedMap` variable allows limited looping through the container. This limitation is due to the inability to access both the original and temporary containers simultaneously; you can only access one at a time. It is recommended to loop through a container within a `const` function, as this will not modify the temporary container. - -`SafeUnorderedMap` includes the following functions for looping through both containers: - -| Function | Description | Return type | -| ---------- | -------------------------------------------------------------------- | --------------- | -| cbegin() | Returns a const iterator to the beginning of the original container | const\_iterator | -| cend() | Returns a const iterator to the end of the original container | const\_iterator | -| begin() | Returns a const iterator to the beginning of the temporary container | iterator | -| end() | Returns a const iterator to the end of the temporary container | iterator | -| empty() | Returns true both the original and temporary container is empty | bool | -| size() | Returns the size of the original container | size\_type | -| tempSize() | Returns the size of the temporary container | size\_type | - -Keep in mind that the temporary and original containers are not the same, so duplicates within `size()` and `tempSize()` are possible. +Some specific non-`const` functions from certain SafeVars are NOT considered "safe" at the moment - this means commit/revert logic does NOT work properly on them due to implementation issues. We advise caution for now if you want to use them, preferably in a read-only manner (as in, do not alter the value itself if using one of those): +* `SafeUnorderedMap::find()` +* `SafeUnorderedMap::begin()` +* `SafeUnorderedMap::end()` diff --git a/understanding-contracts/solidity-abi.md b/understanding-contracts/solidity-abi.md index 2a8542e..668bc6e 100644 --- a/understanding-contracts/solidity-abi.md +++ b/understanding-contracts/solidity-abi.md @@ -16,8 +16,6 @@ This is only an overview, check the [Doxygen](https://doxygen.nl) docs for more The **Types** enum contains the supported Solidity data types in the ABI. Each value has an intrinsic equivalency with both the Solidity data type and the native C++ data type that it represents. -TODO: gone? -> **BaseTypes** is a `std::variant` declared in `src/utils/utils.h` that abstracts all of the types in one typedef, for easier handling. - Replace the **X** in "uintX" and "intX" with the desired size number. The ABI supports every size from 8 to 256 (inclusive), in multiples of 8 (e.g. 8, 16, 24, 32, 40, 48, ..., until 256) - in other words, `x <= 256 && x % 8 == 0`. **Enums are encoded as uint8**. | Enum | Solidity | C++ | From e16081e110875579e833b120b7790da5d3635db4 Mon Sep 17 00:00:00 2001 From: Jean-Lessa <75625278+Jean-Lessa@users.noreply.github.com> Date: Sat, 13 Jul 2024 20:38:49 -0300 Subject: [PATCH 02/10] Add info for SafeBytes, SnailTracer, Wyhash and boost::unordered_flat_map --- bdk-implementation/README.md | 3 ++- bdk-implementation/contract-call-handling.md | 16 ++++++++-------- bdk-implementation/the-utils-folder.md | 6 +++--- .../state-management-and-vm-instance-creation.md | 8 ++++++-- .../creating-a-dynamic-contract-advanced.md | 2 +- .../creating-a-protocol-contract-advanced.md | 2 +- .../dynamic-and-protocol-contracts.md | 7 ++++--- .../safevariables-and-commit-revert-logic.md | 1 + 8 files changed, 26 insertions(+), 19 deletions(-) diff --git a/bdk-implementation/README.md b/bdk-implementation/README.md index d6b69cf..f34676c 100644 --- a/bdk-implementation/README.md +++ b/bdk-implementation/README.md @@ -71,7 +71,8 @@ src ├── libs (Third-party libs) │ ├── BS_thread_pool_light.hpp (https://github.com/bshoshany/thread-pool) │ ├── catch2/catch_amalgamated.hpp (https://github.com/catchorg/Catch2) -│ └── json.hpp (https://github.com/nlohmann/json) +│ ├── json.hpp (https://github.com/nlohmann/json) +│ └── wyhash.h (https://github.com/wangyi-fudan/wyhash) ├── net (Networking) │   ├── http (HTTP part of networking) │   │   ├── httpclient.h (HTTPClient) diff --git a/bdk-implementation/contract-call-handling.md b/bdk-implementation/contract-call-handling.md index 4854f9d..c0b585d 100644 --- a/bdk-implementation/contract-call-handling.md +++ b/bdk-implementation/contract-call-handling.md @@ -17,10 +17,10 @@ Here's an overview of the `ContractStack` class definition and functionalities: ```c++ class ContractStack { private: - std::unordered_map code_; - std::unordered_map balance_; - std::unordered_map nonce_; - std::unordered_map storage_; + boost::unordered_flat_map code_; + boost::unordered_flat_map balance_; + boost::unordered_flat_map nonce_; + boost::unordered_flat_map storage_; std::vector events_; std::vector
contracts_; // Contracts that have been created during the execution of the call, we need to revert them if the call reverts. std::vector> usedVars_; @@ -66,10 +66,10 @@ class ContractStack { } /// Getters - inline const std::unordered_map& getCode() const { return this->code_; } - inline const std::unordered_map& getBalance() const { return this->balance_; } - inline const std::unordered_map& getNonce() const { return this->nonce_; } - inline const std::unordered_map& getStorage() const { return this->storage_; } + inline const boost::unordered_flat_map& getCode() const { return this->code_; } + inline const boost::unordered_flat_map& getBalance() const { return this->balance_; } + inline const boost::unordered_flat_map& getNonce() const { return this->nonce_; } + inline const boost::unordered_flat_map& getStorage() const { return this->storage_; } inline std::vector& getEvents() { return this->events_; } inline const std::vector
& getContracts() const { return this->contracts_; } inline const std::vector>& getUsedVars() const { return this->usedVars_; } diff --git a/bdk-implementation/the-utils-folder.md b/bdk-implementation/the-utils-folder.md index a0b7716..e392085 100644 --- a/bdk-implementation/the-utils-folder.md +++ b/bdk-implementation/the-utils-folder.md @@ -77,11 +77,11 @@ For `RandomGen` to be useful, it needs to be seeded with a truly random number. ## SafeHash -The `safehash.h` contains the **SafeHash** struct - a custom hashing implementation for use with `std::unordered_map`, replacing the one used by default in C++'s STD library, like this for example: `std::unordered_map cachedBlocks;`. +The `safehash.h` contains the **SafeHash** struct - a custom hashing implementation for use with `unordered_map` and/or derivatives, replacing the one used by default, like this for example: `std::unordered_map`. -This is done because the STD implementation of `unordered_map` uses `uint64_t` hashes, which is vulnerable to a potentially dangerous edge case where collisions could happen by having an enormous number of accounts and distributing them in a way that they have the same hash across all nodes. +Previously, we used `std::unordered_map` in conjunction with [a custom fix from this CodeForces article](https://codeforces.com/blog/entry/62393) so we could continue using the C++ STD's implementation of `unordered_map` due to its blazing fast query times (basically the STD implementation uses `uint64_t` hashes, which is vulnerable to a potentially dangerous edge case where collisions could happen by having an enormous number of accounts and distributing them in a way that they have the same hash across all nodes - this fix is not perfect, since it still uses `uint64_t`, but it's better than nothing since nodes keep different hashes). -[This article from CodeForces](https://codeforces.com/blog/entry/62393) provides a fix, which we implemented so we could continue using `std::unordered_map` normally, as it has blazing fast query times. It's not a perfect fix, since it still uses `uint64_t`, but it's better than nothing since nodes keep different hashes. +Currently, we replaced the usage of `std::unordered_map` in the whole project with Boost's implementation (`boost::unordered_flat_map`) in conjunction with the [Wyhash](https://github.com/wangyi-fudan/wyhash) library, the highest and fastest quality hash function available for size_t (64-bit) hashes, to achieve a simpler, faster and more solid functionality. The file also contains the **FNVHash** struct - a custom implementation of the [Fowler-Noll-Vo](https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo\_hash\_function) hash struct, used within broadcast messages. This skips compiler optimizations and forces the whole string to be hashed, diminishing the chance of collisions (because, again, we're using 64-bit hashes). diff --git a/evm-contracts/state-management-and-vm-instance-creation.md b/evm-contracts/state-management-and-vm-instance-creation.md index 5e3f053..1c02611 100644 --- a/evm-contracts/state-management-and-vm-instance-creation.md +++ b/evm-contracts/state-management-and-vm-instance-creation.md @@ -9,11 +9,15 @@ The VM itself is owned and instantiated by the `State` class, which reflects a c ```cpp ContractHost( evmc_vm* vm, + DumpManager& manager, EventManager& eventManager, const Storage& storage, + const Hash& randomnessSeed, const evmc_tx_context& currentTxContext, - std::unordered_map, SafeHash>& accounts, - std::unordered_map& vmStorage, + boost::unordered_flat_map, SafeHash>& contracts, + boost::unordered_flat_map, SafeHash>& accounts, + boost::unordered_flat_map& vmStorage, + boost::unordered_flat_map& txToAddr, const Hash& txHash, const uint64_t txIndex, const Hash& blockHash, diff --git a/precompiled-contracts/creating-a-dynamic-contract-advanced.md b/precompiled-contracts/creating-a-dynamic-contract-advanced.md index 8812e5f..73907b5 100644 --- a/precompiled-contracts/creating-a-dynamic-contract-advanced.md +++ b/precompiled-contracts/creating-a-dynamic-contract-advanced.md @@ -89,7 +89,7 @@ Inside `erc20wrapper.h`, let's implement the header (comments were taken out so class ERC20Wrapper : public DynamicContract { private: - SafeUnorderedMap> tokensAndBalances_; + SafeUnorderedMap> tokensAndBalances_; void registerContractFunctions() override; public: diff --git a/precompiled-contracts/creating-a-protocol-contract-advanced.md b/precompiled-contracts/creating-a-protocol-contract-advanced.md index 27bc23c..3cc7d9e 100644 --- a/precompiled-contracts/creating-a-protocol-contract-advanced.md +++ b/precompiled-contracts/creating-a-protocol-contract-advanced.md @@ -40,7 +40,7 @@ Continuously monitor the performance and security of your Protocol Contract afte ## Add the Protocol Contract to the protocolContractAddresses map -Under `src/contract/contractmanager.h`, you will find a global `std::unordered_map` which contains the registered Protocol Contract addresses. You should stick to the same format as the other contracts, and add your contract address to the map. +Under `src/contract/contractmanager.h`, you will find a global map which contains the registered Protocol Contract addresses. You should stick to the same format as the other contracts, and add your contract address to the map. ## Pay attention to the contract's state diff --git a/precompiled-contracts/dynamic-and-protocol-contracts.md b/precompiled-contracts/dynamic-and-protocol-contracts.md index 297268c..27e20ba 100644 --- a/precompiled-contracts/dynamic-and-protocol-contracts.md +++ b/precompiled-contracts/dynamic-and-protocol-contracts.md @@ -27,11 +27,12 @@ AppLayer's BDK provides ready-to-use templates for the following Dynamic Contrac There are also specific contracts that only exist for internal testing purposes and are not meant to be used as templates: -* `SimpleContract` (template for a simple contract, used for both testing and teaching purposes) -* `RandomnessTest` (template for testing random number generation) +* `SimpleContract` (what it says on the tin - a simple contract, used for both testing and teaching purposes) +* `RandomnessTest` (contract for testing random number generation) * `ERC721Test` (derivative contract meant to test the capabilities of the ERC721 template) * `TestThrowVars` (contract meant to test SafeVariable commit/revert functionality using exception throwing) * `ThrowTestA/B/C` (contracts meant to test nested call revert functionality) +* `SnailTracer` / `SnailTracerOptimized` (C++ conversions of the [SnailTracer](https://github.com/karalabe/snailtracer) contract, used for benchmarking purposes) ## Protocol Contracts @@ -79,7 +80,7 @@ The transpiled code should look similar to this: #include <...> class ExampleContract : public DynamicContract { private: - std::unordered_map values; + std::unordered_map values; // or boost::unordered_flat_map for example // Const-reference as they are not changed by the function. void setValue(const Address &addr, const uint256 &value); public: diff --git a/precompiled-contracts/safevariables-and-commit-revert-logic.md b/precompiled-contracts/safevariables-and-commit-revert-logic.md index f33cddc..aba4cb2 100644 --- a/precompiled-contracts/safevariables-and-commit-revert-logic.md +++ b/precompiled-contracts/safevariables-and-commit-revert-logic.md @@ -49,6 +49,7 @@ We provide the following SafeVariable types, fully functional and ready for use * `SafeAddress` - abstracts a 20-byte address * `SafeArray` - abstracts an array * `SafeBool` - abstracts a boolean +* `SafeBytes` - abstracts a raw bytes string * `SafeInt` and `SafeUint` - abstract a range of signed/unsigned integers (see Solidity ABI) * `SafeString` - abstracts a string (either literal or raw bytes) * `SafeTuple` - abstracts a tuple/struct of any type From c47f55afbd3a68917eae69534332d9aa10cfbe68 Mon Sep 17 00:00:00 2001 From: Jean-Lessa <75625278+Jean-Lessa@users.noreply.github.com> Date: Wed, 31 Jul 2024 13:21:12 -0300 Subject: [PATCH 03/10] Add src/bytes, remove BytesArrView, update ERC20Wrapper example --- bdk-implementation/README.md | 15 ++++- bdk-implementation/the-utils-folder.md | 5 +- evm-contracts/seamless-cpp-evm-integration.md | 4 +- .../creating-a-dynamic-contract-advanced.md | 62 ++++++++----------- 4 files changed, 44 insertions(+), 42 deletions(-) diff --git a/bdk-implementation/README.md b/bdk-implementation/README.md index f34676c..d0162b8 100644 --- a/bdk-implementation/README.md +++ b/bdk-implementation/README.md @@ -11,6 +11,7 @@ The first few subchapters paint a more holistic view of the BDK, as most compone Looking at a higher level of abstraction, the original C++ implementation of the BDK is structured like this: * 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 +* The `src/bytes` folder contains code related to the `bytes` class, a container that deals with raw bytes - `bytes::View` is used extensively as a replacement for `BytesArrView`, the previous implementation * The `src/contract` folder contains everything related to the logic of smart contracts - from ABI parsing to custom variable types and template contracts * The `src/core` folder contains the heart of the BDK - the main components of the blockchain and what makes it tick * The `src/libs` folder contains third-party libraries not inherently tied to the project but used throughout development @@ -23,8 +24,14 @@ For the more visually inclined, here is a source tree (headers only) containing ``` src +├── bytes +│   ├── initializer.h +│   ├── join.h +│   ├── range.h +│   └── view.h ├── contract (Contracts) │   ├── abi.h (ABI - encoders, decoders, helper structs, etc.) +│   ├── calltracer.h (trace namespace, Call struct, CallTracer class) │   ├── contractfactory.h (ContractFactory) │   ├── contract.h (ContractGlobals, ContractLocals, BaseContract) │   ├── contracthost.h (ContractHost) @@ -44,9 +51,13 @@ src │   │ ├── erc20wrapper.h (ERC20Wrapper) │   │ ├── erc721.h (ERC721) │   │ ├── erc721test.h (ERC721Test, used solely for testing purposes) +│   │   ├── erc721uristorage.h (ERC721URIStorage, converted from OpenZeppelin) │   │ ├── nativewrapper.h (NativeWrapper) +│   │   ├── ownable.h (Ownable, converted from OpenZeppelin) +│   │   ├── pebble.h (Pebble) │   │ ├── randomnesstest.h (RandomnessTest) │   │ ├── simplecontract.h (SimpleContract) +│   │   ├── snailtracer.h, snailtraceroptimized.h (SnailTracer and SnailTracerOptimized, converted from the original EVM impl) │   │ ├── testThrowVars.h (TestThrowVars, used solely for testing purposes) │   │ └── throwtestA.h, throwtestB.h, throwtestC.h (for testing CM nested calls) │   └── variables (Safe Variables for use within Dynamic Contracts) @@ -55,6 +66,7 @@ src │   ├── safearray.h (SafeArray) │   ├── safebase.h (SafeBase - used as base for all other types) │   ├── safebool.h (SafeBool) +│   ├── safebytes.h (SafeBytes) │   ├── safeint.h (SafeInt) │   ├── safestring.h (SafeString) │   ├── safetuple.h (SafeTuple) @@ -72,7 +84,8 @@ src │ ├── BS_thread_pool_light.hpp (https://github.com/bshoshany/thread-pool) │ ├── catch2/catch_amalgamated.hpp (https://github.com/catchorg/Catch2) │ ├── json.hpp (https://github.com/nlohmann/json) -│ └── wyhash.h (https://github.com/wangyi-fudan/wyhash) +│ ├── wyhash.h (https://github.com/wangyi-fudan/wyhash) +│ └── zpp_bits.h (https://github.com/eyalz800/zpp_bits) ├── net (Networking) │   ├── http (HTTP part of networking) │   │   ├── httpclient.h (HTTPClient) diff --git a/bdk-implementation/the-utils-folder.md b/bdk-implementation/the-utils-folder.md index e392085..52ca409 100644 --- a/bdk-implementation/the-utils-folder.md +++ b/bdk-implementation/the-utils-folder.md @@ -42,7 +42,7 @@ The class only contains the bare structure and data of a block - it doesn't do a ## Hex -The `hex.h` file contains the **Hex** class - an abstraction of a strictly hex-formatted string (meaning it only accepts the characters within the range of `0x[1-9][a-f][A-F]`), which can also be set to strict or not (whether the string REQUIRES the `0x` prefix or not to be considered valid). Also contains aliases for working with raw-byte strings, such as **Byte, Bytes, BytesArr and BytesArrView**. +The `hex.h` file contains the **Hex** class - an abstraction of a strictly hex-formatted string (meaning it only accepts the characters within the range of `0x[1-9][a-f][A-F]`), which can also be set to strict or not (whether the string REQUIRES the `0x` prefix or not to be considered valid). Also contains aliases for working with raw-byte strings, such as **Byte, Bytes and BytesArr**. ## JsonAbi @@ -108,7 +108,8 @@ The `utils.h` file contains the **Utils** namespace - a place for generalized mi This list is only an example and does not reflect the entire contents of the file. We suggest you read the [Doxygen](https://doxygen.nl/) docs for more info about the class: * Helper functions that deal with printing (`safePrint()`, `safePrintTest()`, `printXYZ()`, etc.) -* Aliases for working with integer types (`intX_t`, `uintX_t`, `SafeIntX_t`, `SafeUintX_t`), raw-byte strings (`Byte`,`Bytes`, `BytesArr`, `BytesArrView`), and helper functions for converting and/or manipulating them (e.g. `appendBytes()`, `uintXToBytes()`, `bytesToUintX()`, `bytesToString()`, `stringToBytes()`, etc.) +* Aliases for working with integer types (`intX_t`, `uintX_t`, `SafeIntX_t`, `SafeUintX_t`), raw-byte strings (`Byte`,`Bytes`, `BytesArr`), and helper functions for converting and/or manipulating them (e.g. `appendBytes()`, `uintXToBytes()`, `bytesToUintX()`, `bytesToString()`, `stringToBytes()`, etc.) + * For `appendBytes()` specifically, it is recommended to use it if you need a buffer, otherwise you can use `bytes::join()` as a slightly faster replacement (e.g. if you have all the data required at once, use `bytes::join()`, if you have the data scattered across different places, use a `Bytes` object as a buffer and use it with `appendBytes()`) * A map with addresses for Protocol Contracts (e.g. `rdPoS` and `ContractManager`) * Enums for network types (`Networks`), contract function types (`FunctionTypes`) and contract types (`ContractType`) * The `Account` struct, used to maintain account balance and nonce statuses, as well as contract-specific data (if the account represents a contract) diff --git a/evm-contracts/seamless-cpp-evm-integration.md b/evm-contracts/seamless-cpp-evm-integration.md index e427bfb..f85dcf4 100644 --- a/evm-contracts/seamless-cpp-evm-integration.md +++ b/evm-contracts/seamless-cpp-evm-integration.md @@ -75,12 +75,12 @@ R callContractFunction( evmc_revision::EVMC_LATEST_STABLE_REVISION, &msg, recipientAcc.code.data(), recipientAcc.code.size())); this->leftoverGas_ = result.gas_left; if (result.status_code) { - auto hexResult = Hex::fromBytes(BytesArrView(result.output_data, result.output_data + result.output_size)); + auto hexResult = Hex::fromBytes(bytes::View(result.output_data, result.output_data + result.output_size)); throw DynamicException("ContractHost::callContractFunction: EVMC call failed - Type: " + Utils::getRealTypeName<C>() + " at address: " + targetAddr.hex().get() + " - Result: " + hexResult.get() ); } - return std::get<0>(ABI::Decoder::decodeData<R>(BytesArrView(result.output_data, result.output_data + result.output_size))); + return std::get<0>(ABI::Decoder::decodeData<R>(bytes::View(result.output_data, result.output_data + result.output_size))); } break; case ContractType::CPP : { this->deduceGas(1000); diff --git a/precompiled-contracts/creating-a-dynamic-contract-advanced.md b/precompiled-contracts/creating-a-dynamic-contract-advanced.md index 73907b5..5c5edd2 100644 --- a/precompiled-contracts/creating-a-dynamic-contract-advanced.md +++ b/precompiled-contracts/creating-a-dynamic-contract-advanced.md @@ -81,6 +81,7 @@ Inside `erc20wrapper.h`, let's implement the header (comments were taken out so #include #include "../../utils/db.h" +#include "../../utils/utils.h" #include "../abi.h" #include "../contractmanager.h" #include "../dynamiccontract.h" @@ -95,20 +96,13 @@ class ERC20Wrapper : public DynamicContract { public: using ConstructorArguments = std::tuple<>; - ERC20Wrapper( - const Address& contractAddress, const DB& db - ); - - ERC20Wrapper( - const Address& address, const Address& creator, - const uint64_t& chainId - ); + ERC20Wrapper(const Address& contractAddress, const DB& db); + ERC20Wrapper(const Address& address, const Address& creator, const uint64_t& chainId); + ~ERC20Wrapper() override; static void registerContract() { ContractReflectionInterface::registerContractMethods< - ERC20Wrapper, - const Address&, const Address&, const uint64_t&, - DB& + ERC20Wrapper, const Address&, const Address&, const uint64_t&, DB& >( std::vector{}, std::make_tuple("getContractBalance", &ERC20Wrapper::getContractBalance, FunctionTypes::View, std::vector{"token"}), @@ -128,7 +122,7 @@ class ERC20Wrapper : public DynamicContract { DBBatch dump() const override; }; -#endif // ERC20WRAPPER_H +#endif ``` Here, we recreated the contract's functions but also added a few extra functions (explained in the previous sections). In short, we create: @@ -146,15 +140,11 @@ Like in SimpleContract's case, you must include your contract's header in `custo Inside `erc20wrapper.cpp`, let's implement both constructors and the dumping function: ```cpp -#include "erc20wrapper.h" - -EERC20Wrapper::ERC20Wrapper( - ContractManagerInterface& interface, const Address& contractAddress, DB& db -) : DynamicContract(interface, contractAddress, db), tokensAndBalances_(this) +ERC20Wrapper::ERC20Wrapper(const Address& contractAddress, const DB& db +) : DynamicContract(contractAddress, db), tokensAndBalances_(this) { - auto tokensAndBalances = this->db_.getBatch(this->getNewPrefix("tokensAndBalances_")); - for (const auto& dbEntry : tokensAndBalances) { - BytesArrView valueView(dbEntry.value); + for (const auto& dbEntry : db.getBatch(this->getNewPrefix("tokensAndBalances_"))) { + bytes::View valueView(dbEntry.value); this->tokensAndBalances_[Address(dbEntry.key)][Address(valueView.subspan(0, 20))] = Utils::fromBigEndian(valueView.subspan(20)); } @@ -165,9 +155,8 @@ EERC20Wrapper::ERC20Wrapper( this->tokensAndBalances_.enableRegister(); } -ERC20Wrapper::ERC20Wrapper( - ContractManagerInterface& interface, const Address& address, const Address& creator, const uint64_t& chainId, DB& db -) : DynamicContract(interface, "ERC20Wrapper", address, creator, chainId, db), tokensAndBalances_(this) +ERC20Wrapper::ERC20Wrapper(const Address& address, const Address& creator, const uint64_t& chainId +) : DynamicContract("ERC20Wrapper", address, creator, chainId), tokensAndBalances_(this) { this->tokensAndBalances_.commit(); @@ -176,11 +165,14 @@ ERC20Wrapper::ERC20Wrapper( this->tokensAndBalances_.enableRegister(); } -DBBatch ERC20Wrapper::dump() const { +ERC20Wrapper::~ERC20Wrapper() {} + +DBBatch ERC20Wrapper::dump () const { DBBatch dbBatch = BaseContract::dump(); + for (auto i = tokensAndBalances_.cbegin(); i != tokensAndBalances_.cend(); ++i) { for (auto j = i->second.cbegin(); j != i->second.cend(); ++j) { - const auto& key = i->first.get(); + const auto& key = i->first; Bytes value = j->first.asBytes(); Utils::appendBytes(value, Utils::uintToBytes(j->second)); dbBatch.push_back(key, value, this->getNewPrefix("tokensAndBalances_")); @@ -205,32 +197,28 @@ uint256_t ERC20Wrapper::getContractBalance(const Address& token) const { uint256_t ERC20Wrapper::getUserBalance(const Address& token, const Address& user) const { auto it = this->tokensAndBalances_.find(token); - if (it == this->tokensAndBalances_.end()) { - return 0; - } + if (it == this->tokensAndBalances_.cend()) return 0; auto itUser = it->second.find(user); - if (itUser == it->second.end()) { - return 0; - } + if (itUser == it->second.cend()) return 0; return itUser->second; } void ERC20Wrapper::withdraw(const Address& token, const uint256_t& value) { auto it = this->tokensAndBalances_.find(token); - if (it == this->tokensAndBalances_.end()) throw std::runtime_error("Token not found"); + if (it == this->tokensAndBalances_.end()) throw DynamicException("Token not found"); auto itUser = it->second.find(this->getCaller()); - if (itUser == it->second.end()) throw std::runtime_error("User not found"); - if (itUser->second <= value) throw std::runtime_error("ERC20Wrapper: Not enough balance"); + if (itUser == it->second.end()) throw DynamicException("User not found"); + if (itUser->second <= value) throw DynamicException("ERC20Wrapper: Not enough balance"); itUser->second -= value; this->callContractFunction(token, &ERC20::transfer, this->getCaller(), value); } void ERC20Wrapper::transferTo(const Address& token, const Address& to, const uint256_t& value) { auto it = this->tokensAndBalances_.find(token); - if (it == this->tokensAndBalances_.end()) throw std::runtime_error("Token not found"); + if (it == this->tokensAndBalances_.end()) throw DynamicException("Token not found"); auto itUser = it->second.find(this->getCaller()); - if (itUser == it->second.end()) throw std::runtime_error("User not found"); - if (itUser->second <= value) throw std::runtime_error("ERC20Wrapper: Not enough balance"); + if (itUser == it->second.end()) throw DynamicException("User not found"); + if (itUser->second <= value) throw DynamicException("ERC20Wrapper: Not enough balance"); itUser->second -= value; this->callContractFunction(token, &ERC20::transfer, to, value); } From abd3995da715ae24732de2d4382234de135bcecc Mon Sep 17 00:00:00 2001 From: Jean-Lessa <75625278+Jean-Lessa@users.noreply.github.com> Date: Wed, 31 Jul 2024 13:49:02 -0300 Subject: [PATCH 04/10] Update DB prefixes, add info about Call, CallTracer & TxAdditionalData --- .gitbook/assets/contract-folder.png | Bin 35455 -> 37567 bytes bdk-implementation/database.md | 46 +++++++++++++--------- bdk-implementation/the-contract-folder.md | 4 ++ bdk-implementation/the-utils-folder.md | 2 + 4 files changed, 33 insertions(+), 19 deletions(-) diff --git a/.gitbook/assets/contract-folder.png b/.gitbook/assets/contract-folder.png index 223f52ba77b5d3d027478e07f3af43f003d7994e..7a14cf402bdf96ad6b21f84efffefd2b2153eada 100644 GIT binary patch literal 37567 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 HzW4rLu`#Vh literal 35455 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

~h3HKdb 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 B?l}Me diff --git a/bdk-implementation/database.md b/bdk-implementation/database.md index a97c9bf..31ca8f5 100644 --- a/bdk-implementation/database.md +++ b/bdk-implementation/database.md @@ -24,18 +24,19 @@ We have three helper structs to ease database manipulation: We also have a `DBPrefix` namespace to reference the database's prefixes in a simpler way: -| Descriptor | Prefix | -| --------------- | ------ | -| blocks | 0x0001 | -| blockHeightMaps | 0x0002 | -| nativeAccounts | 0x0003 | -| txToBlocks | 0x0004 | -| rdPoS | 0x0005 | -| contracts | 0x0006 | -| contractManager | 0x0007 | -| events | 0x0008 | -| vmStorage | 0x0009 | -| txToAddr | 0x000A | +| Descriptor | Prefix | +| ------------------ | ------ | +| blocks | 0x0001 | +| heightToBlock | 0x0002 | +| nativeAccounts | 0x0003 | +| txToBlock | 0x0004 | +| rdPoS | 0x0005 | +| contracts | 0x0006 | +| contractManager | 0x0007 | +| events | 0x0008 | +| vmStorage | 0x0009 | +| txToAdditionalData | 0x000A | +| txToCallTrace | 0x000B | Those prefixes are concatenated to the start of the _key_, so an entry that would have, for example, a key named "abc" and a value of "123", if inserted to the "0003" prefix, would be like this inside the database (in raw bytes format, strings here are just for the sake of the explanation): `{"0003abc": "123"}` @@ -49,7 +50,7 @@ Used to store serialized blocks based on their hashes. | ------------------ | ---------------- | | Prefix + BlockHash | Serialized Block | -### blockHeightMaps +### heightToBlock Used to store block hashes based on their heights. @@ -73,7 +74,7 @@ For example, an account with balance 1000000 and nonce 2 would be serialized as An account with balance 0 and nonce 0 would be serialized as `0000`. -### txToBlocks +### txToBlock Used to store block hashes, the tx indexes within that block and the block heights, based on their transaction hashes. @@ -132,11 +133,18 @@ Used to store EVM-related stuff like storage keys and values (essentially the EV | ------------------------------------------- | ------------------------ | | Address (20 bytes) + Storage Key (32 bytes) | Storage Value (32 bytes) | -### txToAddr +### txToAdditionalData -Used to store EVM transactions that created contracts, storing the transaction hash and the address where the contract was deployed. +Used to store EVM transactions that created contracts, storing the transaction hash and additional data about the contract that was deployed (see the `TxAdditionalData` struct in `utils/tx.h` for more details). -| Key | Value | -| ------------------------ | ------------------ | -| Prefix + TransactionHash | ContractAddress | +| Key | Value | +| ------------------------ | ---------------------------------- | +| Prefix + TransactionHash | Serialized TxAdditionalData struct | +### txToCallTrace + +Used to store debugging information about contract calls - see the `Call` struct in `contract/calltracer.h` for more details. + +| Key | Value | +| ------------------------ | ---------------------- | +| Prefix + TransactionHash | Serialized Call struct | diff --git a/bdk-implementation/the-contract-folder.md b/bdk-implementation/the-contract-folder.md index 755bcf1..df14377 100644 --- a/bdk-implementation/the-contract-folder.md +++ b/bdk-implementation/the-contract-folder.md @@ -12,6 +12,10 @@ This subchapter contains a brief overview of each one of the components inside t The `abi.h` file contains the **ABI** namespace - helper functions for handling Solidity ABI types and data natively, as well as the encoding and decoding of said data, also used for C++ <-> EVM inter-operability. +## CallTracer + +The `calltracer.h` file contains the **Call** struct and the **CallTracer** class respectively, both under the **trace** namespace - those are used specifically for debugging purposes, tracing the flux of a contract call and collecting specific details about it, such as the call type, the sender and receiver addresses, the value sent, the gas used, inputs and outputs, errors and any related subcalls. + ## BaseContract The `contract.h` file contains the **BaseContract** class - the base from which all smart contracts are derived - as well as the **ContractGlobals** and **ContractLocals** helper classes that provide access to global and local variables, respectively, for those contracts to work. diff --git a/bdk-implementation/the-utils-folder.md b/bdk-implementation/the-utils-folder.md index 52ca409..d17dfd6 100644 --- a/bdk-implementation/the-utils-folder.md +++ b/bdk-implementation/the-utils-folder.md @@ -101,6 +101,8 @@ Even though FixedBytes can be used on its own (*it's meant to store only bytes*, The `tx.h` file contains the **TxBlock** and **TxValidator** classes - abstractions for a block transaction and a Validator transaction, respectively. The implementation logic and details for those transactions are derived from the "Account" model, used by Ethereum and implemented by the [Aleth](https://github.com/ethereum/aleth) library, which is different from the "UTXO" model used by Bitcoin. +It also contains a helper struct called `TxAdditionalData`, which contains metadata about a contract that was deployed in the chain, such as the transaction hash, how much gas was used in the transaction, if the call succeeded or not, and the contract's address. + ## Utils The `utils.h` file contains the **Utils** namespace - a place for generalized miscellaneous utility functions, namespaces, enums and typedefs used across the BDK. From a86a91d2ea9521518904c4fd93282c9498aeae53 Mon Sep 17 00:00:00 2001 From: Jean-Lessa <75625278+Jean-Lessa@users.noreply.github.com> Date: Wed, 31 Jul 2024 14:24:40 -0300 Subject: [PATCH 05/10] Update info about Storage, FixedBytes types & dev env instructions --- bdk-implementation/README.md | 2 +- bdk-implementation/the-core-folder.md | 6 +-- bdk-implementation/the-utils-folder.md | 2 + .../setting-up-the-development-environment.md | 38 ++++++++----------- 4 files changed, 21 insertions(+), 27 deletions(-) diff --git a/bdk-implementation/README.md b/bdk-implementation/README.md index d0162b8..37093e6 100644 --- a/bdk-implementation/README.md +++ b/bdk-implementation/README.md @@ -79,7 +79,7 @@ src │   ├── dump.h (Dumpable, DumpManager, DumpWorker) │   ├── rdpos.h (Validator, rdPoS) │   ├── state.h (BlockValidationStatus, State) -│   └── storage.h (StorageStatus, Storage) +│   └── storage.h (Storage) ├── libs (Third-party libs) │ ├── BS_thread_pool_light.hpp (https://github.com/bshoshany/thread-pool) │ ├── catch2/catch_amalgamated.hpp (https://github.com/catchorg/Catch2) diff --git a/bdk-implementation/the-core-folder.md b/bdk-implementation/the-core-folder.md index 19fd4df..9cac1e3 100644 --- a/bdk-implementation/the-core-folder.md +++ b/bdk-implementation/the-core-folder.md @@ -57,10 +57,8 @@ Not all functions from the class update the state. Check the [Doxygen](https://d ## Storage -The `storage.h` file contains the **Storage** class - an abstraction of the blockchain's history, maintaining a collection of blocks approved and validated by the network, other nodes, or itself through time. Those blocks store transactions, contracts, accounts, and can't be altered once they're in the blockchain, only searched for or read from. The file also contains the **StorageStatus** enum, used to indicate the status of a given block or transaction inside the Storage itself. +The `storage.h` file contains the **Storage** class - an abstraction of the blockchain's history, maintaining a collection of blocks approved and validated by the network, other nodes, or itself through time. Those blocks store transactions, contracts, accounts, and can't be altered once they're in the blockchain, only searched for or read from. -On node initialization, a history of up to 1000 of the most recent blocks is loaded into memory. Those blocks were stored in a previous initialization in the database. If there are no blocks (e.g. the blockchain was just deployed and initialized for the first time), a "genesis" block is automatically created and loaded in memory. - -Once a block and its transactions are received from the network, they're stored in memory. If more than 1000 blocks (or 1 million transactions) are stored in memory at a given time, older blocks are periodically saved to the database. This makes the blockchain lightweight memory-wise and extremely responsive. +On node initialization, if there are no blocks (e.g. the blockchain was just deployed and initialized for the first time), a "genesis" block is automatically created and loaded in memory. The "latest" block is always kept in memory, with subsequent older blocks being dumped to and queried constantly from the database. This makes the blockchain lightweight memory-wise and extremely responsive. Searching for and reading from blocks in history is done in several places in the system, so when the Storage and DB classes are working together, they act as the end point of the blockchain's operations history. diff --git a/bdk-implementation/the-utils-folder.md b/bdk-implementation/the-utils-folder.md index d17dfd6..2266156 100644 --- a/bdk-implementation/the-utils-folder.md +++ b/bdk-implementation/the-utils-folder.md @@ -97,6 +97,8 @@ Even though FixedBytes can be used on its own (*it's meant to store only bytes*, * **Address** inherits **FixedBytes<20>** and abstracts a given 20-byte address * **StorageKey** inherits **FixedBytes<52>** and abstracts an EVM storage key (20 bytes address + 32 bytes slot key) +All of these custom types are standard compliant (trivially copyable and trivially destructible), which means they can be handled like a STD container such as `std::vector` for example. + ## TxBlock and TxValidator The `tx.h` file contains the **TxBlock** and **TxValidator** classes - abstractions for a block transaction and a Validator transaction, respectively. The implementation logic and details for those transactions are derived from the "Account" model, used by Ethereum and implemented by the [Aleth](https://github.com/ethereum/aleth) library, which is different from the "UTXO" model used by Bitcoin. diff --git a/understanding-contracts/setting-up-the-development-environment.md b/understanding-contracts/setting-up-the-development-environment.md index 33f5b38..4920777 100644 --- a/understanding-contracts/setting-up-the-development-environment.md +++ b/understanding-contracts/setting-up-the-development-environment.md @@ -57,15 +57,15 @@ After building the image, run it with the following command (again, if using Lin ```bash # For Linux/Mac -docker run -it -v $(pwd):/orbitersdk-volume -p 8080-8099:8080-8099 -p 8110-8111:8110-8111 bdk-cpp-dev:latest +docker run -it -v $(pwd):/bdk-volume -p 8080-8099:8080-8099 -p 8110-8111:8110-8111 bdk-cpp-dev:latest # For Windows -docker run -it -v %cd%:/orbitersdk-volume -p 8080-8099:8080-8099 -p 8110-8111:8110-8111 bdk-cpp-dev:latest +docker run -it -v %cd%:/bdk-volume -p 8080-8099:8080-8099 -p 8110-8111:8110-8111 bdk-cpp-dev:latest ``` where: * `$(pwd)` or `%cd%` is the absolute/full path to your repository's folder -* `:/orbitersdk-volume` is the path inside the container where the BDK will be mounted. This volume is synced with the `bdk-cpp` folder inside the container +* `:/bdk-volume` is the path inside the container where the BDK will be mounted. This volume is synced with the `bdk-cpp` folder inside the container * The `-p` flags expose the ports used by the nodes - the example exposes the default ports 8080-8099 and 8110-8111, if you happen to use different ports, change them accordingly When running the container, you will be logged in as the root user and will be able to develop, build and deploy the network within the container. Remember that we are using our local repo as a volume, so every change in the local folder will be reflected to the container in real time, and vice-versa (so you can develop outside and use the container only for build and deploy). You can also integrate the container with your favorite IDE or editor. @@ -97,7 +97,7 @@ You can follow these steps to build the BDK in your own system. Dependencies are * **libsnappy** for database compression * **tmux** (for deploying) * (optional) **clang-tidy** for linting -* (optional) **mold** for faster/better linking +* (optional) **mold** for faster/more efficient linking The versions of those dependencies should suffice out-of-the-box for at least the following distros (or greater, including their derivatives): @@ -107,14 +107,21 @@ The versions of those dependencies should suffice out-of-the-box for at least th * **Fedora 40** * Any rolling release distro from around **May 2024** onwards (check their repos to be sure) -For older distros, you may need to compile some dependencies from source (specifically CMake and Boost). Make sure to uninstall them from the system first to prevent any version conflicts. +For older distros, you may need to compile some dependencies from source (specifically CMake, Boost and/or GCC). Make sure to either uninstall them from the system first to prevent any version conflicts, or use a workaround like e.g. Debian's `update-alternatives` or similar. + +Specifically for GCC, make sure to also export the right paths for compilation in your environment in case you're using a self-compiled build. For example, in a Linux system, put something like this in your `~/.bashrc` file, changing the version accordingly to whichever one you have installed: + +```bash +PATH=/usr/local/gcc-14.1.0/bin:$PATH +LD_LIBRARY_PATH=/usr/local/gcc-14.1.0/lib64:$LD_LIBRARY_PATH +``` #### One-liners * For APT-based distros: ```bash -sudo apt install git build-essential cmake mold tmux clang-tidy autoconf libtool pkg-config libboost-all-dev libcrypto++-dev libscrypt-dev libsnappy-dev libssl-dev zlib1g-dev openssl +sudo apt install build-essential cmake tmux clang-tidy autoconf libtool pkg-config libabsl-dev libboost-all-dev libc-ares-dev libcrypto++-dev libgrpc-dev libgrpc++-dev librocksdb-dev libscrypt-dev libsnappy-dev libssl-dev zlib1g-dev openssl protobuf-compiler protobuf-compiler-grpc unison git ``` ## Compiling @@ -145,26 +152,13 @@ make -j$(nproc) cmake --build . -- -j$(nproc) ``` -After building, you can optionally run a test bench with the following command: `./src/bins/orbitersdkd-tests/orbitersdkd-tests -d yes` (the `-d yes` parameter will give a verbose output). You can also use filter tags to test specific parts of the project (e.g. `./src/bins/orbitersdkd-tests/orbitersdkd-tests [utils] -d yes` will test all the components inside the `src/utils` folder, `[utils][tx]` will test only the transaction-related components inside utils, etc.). - -Usable tags are: +After building, you can optionally run a test bench with the following command: `./src/bins/orbitersdkd-tests/orbitersdkd-tests -d yes` (the `-d yes` parameter will give a verbose output). -* `[utils]` - everything in `src/utils` - * `[utils][*]` - replace `*` with one of the class names: `block`, `db`, `hex`, `merkle`, `randomgen`, `secp256k1`, `strings`, `tx` (TxBlock), `txvalidator`, `utilsitself` (the last one refers to the actual Utils class), `[*][throw]` (for testing actual throwing conditions) -* `[contract]` - everything in `src/contract` - * `[contract][*]` - replace `*` with one of the contract names: `abi`, `contractabigenerator`, `contractmanager`, `dexv2`, `erc20`, `erc20wrapper`, `nativewrapper` - * `[contract][variables][*]` - all SafeVariable types - `[*]` is optional, if you want to test specific variables, replace `*` with one of the class names: `safeaddress`, `safearray`, `safebool`, `safestring`, `safeuintX_t` (replace X with a uint size from 8 to 256), `safeunorderedmap`, `safevector` -* `[core]` - everything in `src/core` - * `[core][*]` - replace `*` with one of the class names: `blockchain`, `options`, `rdpos`, `state`, `storage` - * `[core][rdpos][net]` - only networking-related functionality - append `[heavy]` for very taxing functionality -* `[net]` - everything in `src/net` - * `[net][http][jsonrpc]` - only JSONRPC-related functionality -* `[p2p]` - only P2P-related functionality -* `[sdktestsuite]` - test the SDKTestSuite itself (test suite used internally for testing contracts) +You can also use filter tags to test specific parts of the project (e.g. `./src/bins/orbitersdkd-tests/orbitersdkd-tests -d yes [utils]` will test all the components inside the `src/utils` folder, `[utils][tx]` will test only the transaction-related components inside utils, etc.). You can check all the available tags by doing a `grep -rw "\"\[.*\]\""` in the `tests` subfolder. ## Deploying -Currently there are two ways to deploy an AppLayer node: _manual_, and _dockerized_. Go back to the project's root folder and check the `scripts` subfolder - there are two main scripts there used for deploying the node. You can pick whichever one you prefer, depending on your needs. +Currently there are two ways to deploy an AppLayer node: *manual*, and *dockerized*. Go back to the project's root folder and check the `scripts` subfolder - there are two main scripts there used for deploying the node. You can pick whichever one you prefer, depending on your needs. ### Dockerized deploy From ce2a40eab31754582b7ab519f4e1b4cd9f09bfcd Mon Sep 17 00:00:00 2001 From: Jean-Lessa <75625278+Jean-Lessa@users.noreply.github.com> Date: Fri, 16 Aug 2024 12:35:40 -0300 Subject: [PATCH 06/10] Sync info about EventManager deprecation --- bdk-implementation/README.md | 2 +- bdk-implementation/contract-call-handling.md | 29 ++++++------------- bdk-implementation/the-contract-folder.md | 6 ++-- bdk-implementation/the-core-folder.md | 4 +-- ...ate-management-and-vm-instance-creation.md | 2 -- .../dynamic-and-protocol-contracts.md | 3 +- 6 files changed, 16 insertions(+), 30 deletions(-) diff --git a/bdk-implementation/README.md b/bdk-implementation/README.md index 37093e6..b1eaf80 100644 --- a/bdk-implementation/README.md +++ b/bdk-implementation/README.md @@ -39,7 +39,7 @@ src │   ├── contractstack.h (ContractStack) │   ├── customcontracts.h (for declaring custom contracts) │   ├── dynamiccontract.h (DynamicContract) -│   ├── event.h (Event, EventManager) +│   ├── event.h (Event) │   ├── templates (folder for contract templates) │   │ ├── dexv2 (subfolder for the DEXV2 contract components) │   │ │ ├── dexv2factory.h (DEXV2Factory) diff --git a/bdk-implementation/contract-call-handling.md b/bdk-implementation/contract-call-handling.md index c0b585d..1db537b 100644 --- a/bdk-implementation/contract-call-handling.md +++ b/bdk-implementation/contract-call-handling.md @@ -22,43 +22,32 @@ class ContractStack { boost::unordered_flat_map nonce_; boost::unordered_flat_map storage_; std::vector events_; - std::vector

contracts_; // Contracts that have been created during the execution of the call, we need to revert them if the call reverts. + std::vector> contracts_; // Contracts that have been created during the execution of the call, we need to revert them if the call reverts. std::vector> usedVars_; public: - ContractStack() = default; - ~ContractStack() = default; - inline void registerCode(const Address& addr, const Bytes& code) { - if (!this->code_.contains(addr)) { - this->code_[addr] = code; - } + this->code_.try_emplace(addr, code); } inline void registerBalance(const Address& addr, const uint256_t& balance) { - if (!this->balance_.contains(addr)) { - this->balance_[addr] = balance; - } + this->balance_.try_emplace(addr, balance); } inline void registerNonce(const Address& addr, const uint64_t& nonce) { - if (!this->nonce_.contains(addr)) { - this->nonce_[addr] = nonce; - } + this->nonce_.try_emplace(addr, nonce); } inline void registerStorageChange(const StorageKey& key, const Hash& value) { - if (!this->storage_.contains(key)) { - this->storage_[key] = value; - } + this->storage_.try_emplace(key, value); } - inline void registerEvent(Event&& event) { + inline void registerEvent(Event event) { this->events_.emplace_back(std::move(event)); } - inline void registerContract(const Address& addr) { - this->contracts_.push_back(addr); + inline void registerContract(const Address& addr, BaseContract* contract) { + this->contracts_.emplace_back(addr, contract); } inline void registerVariableUse(SafeBase& var) { @@ -71,7 +60,7 @@ class ContractStack { inline const boost::unordered_flat_map& getNonce() const { return this->nonce_; } inline const boost::unordered_flat_map& getStorage() const { return this->storage_; } inline std::vector& getEvents() { return this->events_; } - inline const std::vector
& getContracts() const { return this->contracts_; } + inline const std::vector>& getContracts() const { return this->contracts_; } inline const std::vector>& getUsedVars() const { return this->usedVars_; } }; ``` diff --git a/bdk-implementation/the-contract-folder.md b/bdk-implementation/the-contract-folder.md index df14377..4064d3f 100644 --- a/bdk-implementation/the-contract-folder.md +++ b/bdk-implementation/the-contract-folder.md @@ -44,11 +44,9 @@ The `customcontracts.h` file contains a tuple that holds all the registered cont The `dynamiccontract.h` file contains the **DynamicContract** class - the base from which all Dynamic Contracts are derived (while _BaseContract_ is mainly used for Protocol Contracts). -## Event and EventManager +## Event -The `event.h` file contains the **Event** and **EventManager** classes, as well as the **EventContainer** typedef for indexing - they represent the subset of contract functionality related to Solidity events. - -_Event_ is responsible for abstracting a Solidity event's structure and data, while _EventManager_ is responsible for maintaining all emitted events within the blockchain. Events are supported for both C++ and EVM contracts. +The `event.h` file contains the **Event** class - an abstraction of a Solidity event's structure and data, used extensively by contracts. Events are managed within the blockchain by the Storage class and are supported for both C++ and EVM contracts. ## The variables subfolder diff --git a/bdk-implementation/the-core-folder.md b/bdk-implementation/the-core-folder.md index 9cac1e3..e94b1a9 100644 --- a/bdk-implementation/the-core-folder.md +++ b/bdk-implementation/the-core-folder.md @@ -44,7 +44,7 @@ The `rdpos.h` file contains the **rdPoS** class - the implementation of the *Ran ## State -The `state.h` file contains the **State** class - an abstraction of the blockchain's current state of accounts, balances, nonces, transactions, token balances, deployed contracts and emitted events at the current block in the network, responsible for owning and maintaining all of those and a few other shared inner variables. +The `state.h` file contains the **State** class - an abstraction of the blockchain's current state of accounts, balances, nonces, transactions, token balances and deployed contracts at the current block in the network, responsible for owning and maintaining all of those and a few other shared inner variables. A node's state and its data can only be altered through the process of block creation, either by creating a block itself, or receiving one from the network. In AppLayer's case, the class is often used for querying account data (current balance and nonce) and also processing and validating blocks and their transactions, as well as contract calls, following requirements such as (not limited to, but those are some of the most common): @@ -57,7 +57,7 @@ Not all functions from the class update the state. Check the [Doxygen](https://d ## Storage -The `storage.h` file contains the **Storage** class - an abstraction of the blockchain's history, maintaining a collection of blocks approved and validated by the network, other nodes, or itself through time. Those blocks store transactions, contracts, accounts, and can't be altered once they're in the blockchain, only searched for or read from. +The `storage.h` file contains the **Storage** class - an abstraction of the blockchain's history, maintaining a collection of blocks approved and validated by the network, other nodes, or itself through time. Those blocks store transactions, contracts, accounts, and can't be altered once they're in the blockchain, only searched for or read from. The class is also responsible for storing and managing emitted events from contracts, if the node is initialized with the `RPC_TRACE` option set. On node initialization, if there are no blocks (e.g. the blockchain was just deployed and initialized for the first time), a "genesis" block is automatically created and loaded in memory. The "latest" block is always kept in memory, with subsequent older blocks being dumped to and queried constantly from the database. This makes the blockchain lightweight memory-wise and extremely responsive. diff --git a/evm-contracts/state-management-and-vm-instance-creation.md b/evm-contracts/state-management-and-vm-instance-creation.md index 1c02611..da89022 100644 --- a/evm-contracts/state-management-and-vm-instance-creation.md +++ b/evm-contracts/state-management-and-vm-instance-creation.md @@ -10,14 +10,12 @@ The VM itself is owned and instantiated by the `State` class, which reflects a c ContractHost( evmc_vm* vm, DumpManager& manager, - EventManager& eventManager, const Storage& storage, const Hash& randomnessSeed, const evmc_tx_context& currentTxContext, boost::unordered_flat_map, SafeHash>& contracts, boost::unordered_flat_map, SafeHash>& accounts, boost::unordered_flat_map& vmStorage, - boost::unordered_flat_map& txToAddr, const Hash& txHash, const uint64_t txIndex, const Hash& blockHash, diff --git a/precompiled-contracts/dynamic-and-protocol-contracts.md b/precompiled-contracts/dynamic-and-protocol-contracts.md index 27e20ba..1ba1888 100644 --- a/precompiled-contracts/dynamic-and-protocol-contracts.md +++ b/precompiled-contracts/dynamic-and-protocol-contracts.md @@ -44,7 +44,8 @@ There are also specific contracts that only exist for internal testing purposes Contracts in the AppLayer network are managed by a few classes working together (check the `src/core` and `src/contract` folders for more info on each class): -* `State` (`src/core/state.h`) is responsible for owning all the Dynamic Contracts registered in the blockchain (which you can get a list of by calling the class' `getCppContracts()` and/or `getEVMContracts()` functions, depending on which ones you need), as well as their global variables (name, address, owner, balances, events, etc.) +* `State` (`src/core/state.h`) is responsible for owning all the Dynamic Contracts registered in the blockchain (which you can get a list of by calling the class' `getCppContracts()` and/or `getEVMContracts()` functions, depending on which ones you need), as well as their global variables (name, address, owner, balances, etc.) +* `Storage` (`src/core/storage.h`) is responsible for properly storing contract data, such as emitted events and the transactions that triggered them * `ContractManager` (`src/contract/contractmanager.h`) is responsible for solely creating and registering the contracts, then passing them to State (with the `ContractFactory` namespace providing helper functions to do so) * `ContractHost` (`src/contract/contracthost.h`) is responsible for allowing contracts to interact with each other and to enable them to modify balances - this kind of inter-communication is done by intercepting calls of functions from registered contracts (if the functor/signature matches), which is done through either an `eth_call` request or a transaction processed from a block * `ContractStack` (`src/contract/contractstack.h`) is responsible for managing alterations of data, like contract variables and account balances during nested contract call chains, by keeping a stack of changes made during a contract call, and automatically committing or reverting them in the account state when required (for non-view functions) From 203e317930e9941f0ed0a5c142864d01a861624a Mon Sep 17 00:00:00 2001 From: Jean-Lessa <75625278+Jean-Lessa@users.noreply.github.com> Date: Fri, 15 Nov 2024 14:25:36 -0300 Subject: [PATCH 07/10] Sync infos from deps_rev/optimize & fix a bunch of stale info --- .gitbook/assets/utils-folder.png | Bin 49860 -> 58692 bytes bdk-implementation/README.md | 36 ++++---- bdk-implementation/contract-call-handling.md | 36 +++----- bdk-implementation/database.md | 8 +- bdk-implementation/p2p-overview.md | 4 +- bdk-implementation/the-core-folder.md | 2 +- bdk-implementation/the-utils-folder.md | 18 ++-- evm-contracts/README.md | 5 +- evm-contracts/cpp-to-other-contract-calls.md | 41 ++-------- evm-contracts/evm-to-other-contract-calls.md | 59 ++++++++------ evm-contracts/seamless-cpp-evm-integration.md | 52 ++++++------ introducing-applayer/what-is-applayer.md | 2 +- join-our-community.md | 6 +- precompiled-contracts/README.md | 4 +- .../creating-a-dynamic-contract-advanced.md | 5 +- .../README.md | 2 +- .../deploying-and-testing.md | 10 +-- .../simple-contract-header.md | 21 ++--- .../simple-contract-source.md | 12 +-- .../dynamic-and-protocol-contracts.md | 66 +++++++-------- .../safevariables-and-commit-revert-logic.md | 4 +- understanding-contracts/README.md | 2 +- .../setting-up-the-development-environment.md | 77 +++++++++++------- understanding-contracts/solidity-abi.md | 2 +- understanding-rdpos/README.md | 2 +- understanding-rdpos/slashing.md | 2 +- 26 files changed, 234 insertions(+), 244 deletions(-) diff --git a/.gitbook/assets/utils-folder.png b/.gitbook/assets/utils-folder.png index f6262aea55b41324330b1a9fb4536e78c68fdd46..784d50830a1cd4d8eff3301cd195514eedcb0dc9 100644 GIT binary patch literal 58692 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

l8HLCpiA$4u_}EgRt(VJYgjfxxX9Zob6D z?@c9NbCdrHhwFM_jI2_31BujGYzt!ayCHkC7B;%Oa$zn;)}ekrWY03E<g!cSvO+S7_JXrOi^-^jQ5`5cTFSIUx;kat8&2~ z=Ac{>mG(as4d$14W~1J|#UQ)y4}BY%Ia5#&Ev?P(%TY8p@2pQtUavgY9+UDkG51dB zH770K*NMuq{qQS>3beV8Qd{?*@0#5Ii2C>}7?Rc0Bzu^M0AC#T=l(_4k7?}%s4TNh z0lRB3@d}o@z5}DGAr^8~6?p=6=Jf4P8@xa&^mwpkKaIi_o2KI*x{fhzmD7zYj<9Zq%e~T<0 zv7&Iy8laNJ|+2-&#{?`L6=$hWhCt(8Lsk~vo5OOL@=sXF?%c_#~{|$!uDrpKmY&$ literal 49860 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 f+xP! nonce_; boost::unordered_flat_map storage_; std::vector events_; - std::vector> contracts_; // Contracts that have been created during the execution of the call, we need to revert them if the call reverts. + std::vector> contracts_; std::vector> usedVars_; public: - inline void registerCode(const Address& addr, const Bytes& code) { - this->code_.try_emplace(addr, code); - } + inline void registerCode(const Address& addr, const Bytes& code) { this->code_.try_emplace(addr, code); } - inline void registerBalance(const Address& addr, const uint256_t& balance) { - this->balance_.try_emplace(addr, balance); - } + inline void registerBalance(const Address& addr, const uint256_t& balance) { this->balance_.try_emplace(addr, balance); } - inline void registerNonce(const Address& addr, const uint64_t& nonce) { - this->nonce_.try_emplace(addr, nonce); - } + inline void registerNonce(const Address& addr, const uint64_t& nonce) { this->nonce_.try_emplace(addr, nonce); } - inline void registerStorageChange(const StorageKey& key, const Hash& value) { - this->storage_.try_emplace(key, value); - } + inline void registerStorageChange(const StorageKey& key, const Hash& value) { this->storage_.try_emplace(key, value); } - inline void registerEvent(Event event) { - this->events_.emplace_back(std::move(event)); - } + inline void registerEvent(Event event) { this->events_.emplace_back(std::move(event)); } - inline void registerContract(const Address& addr, BaseContract* contract) { - this->contracts_.emplace_back(addr, contract); - } + inline void registerContract(const Address& addr, BaseContract* contract) { this->contracts_.emplace_back(addr, contract); } - inline void registerVariableUse(SafeBase& var) { - this->usedVars_.emplace_back(var); - } + inline void registerVariableUse(SafeBase& var) { this->usedVars_.emplace_back(var); } - /// Getters inline const boost::unordered_flat_map& getCode() const { return this->code_; } inline const boost::unordered_flat_map& getBalance() const { return this->balance_; } inline const boost::unordered_flat_map& getNonce() const { return this->nonce_; } @@ -65,5 +50,4 @@ class ContractStack { }; ``` -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. - +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. diff --git a/bdk-implementation/database.md b/bdk-implementation/database.md index 31ca8f5..589ec85 100644 --- a/bdk-implementation/database.md +++ b/bdk-implementation/database.md @@ -12,7 +12,13 @@ The database requires a filesystem path to open it (if it already exists) or cre Content in the database is stored as raw bytes. This is due to space optimizations, as one raw byte equals two UTF-8 characters (e.g. an address like `0x1234567890123456789012345678901234567890`, ignoring the "0x" prefix, occupies 20 raw bytes - "12 34 56 ..." - , but 40 bytes if converted to a string, since each byte becomes two separate characters - "1 2 3 4 5 6 ..."). -For the main CRUD operations, refer to the `has()`, `get()`, `put()` and `del()` functions. Due to how the database works internally, updating an entry is the same as inserting a different value in a key that already exists, effectively replacing the value that existed before (e.g. `put(oldKey, newValue)`). There's also `getBatch()` and `putBatch()` for batched operations, as well as `getKeys()` for fetching only the keys, and `keyFromStr()` for encapsulating a key into a Bytes object. +For the main CRUD operations, refer to the `has()`, `get()`, `put()` and `del()` functions. Due to how the database works internally, updating an entry is the same as inserting a different value in a key that already exists, effectively replacing the value that existed before (e.g. `put(oldKey, newValue)`). There's also a few other helper functions such as: + +* `getBatch()` and `putBatch()` for batched operations +* `getKeys()` for fetching only the database's keys +* `keyFromStr()` for encapsulating a key into a Bytes object +* `getLastByPrefix()` for getting the last value stored in a given prefix +* `makeNewPrefix()` for concatenating prefixes when necessary ## Structs and Prefixes diff --git a/bdk-implementation/p2p-overview.md b/bdk-implementation/p2p-overview.md index 6c921c4..be3836f 100644 --- a/bdk-implementation/p2p-overview.md +++ b/bdk-implementation/p2p-overview.md @@ -65,7 +65,7 @@ It's also important to be aware of the lifespan of the `io_context` and the obje ## Message types -Every incoming message is promptly parsed by the manager via the `handleMessage()` function. These messages can fall into one of the following categories, with each one of them being treated distinctly: +Every incoming message is promptly parsed by the manager via the `handleMessage()` function. These messages can fall into one of the following categories, with each one of them being treated distinctly (the names here are conceptual, the actual variable names differ in implementation): * `Request` - a query for specific data from another node - e.g. a list of blocks, a list of transactions, info about the node itself, etc. * `Answer` - an answer to a given request @@ -80,7 +80,7 @@ Both `Request` and `Answer` messages work together in a bidirectional flow that Both `Notification` and `Broadcast` messages, however, work with a simpler unidirectional flow, as the receiver node doesn't have to answer back to the sender. Instead, it verifies the received data and adds it to its own blockchain. The difference between both types is that `Notification` messages are never re-broadcast, while `Broadcast` messages may or may not be re-broadcast to other nodes, depending on whether said nodes had already received or not said broadcast in the past. -Due to this specific condition, `Broadcast` messages are specifically handled by the `Broadcaster` class (`Broadcaster.h`), while the other types are handled by `ManagerBase` and its derivative classes. +Due to this specific condition, `Broadcast` messages are specifically handled by the `Broadcaster` class (`net/p2p/broadcaster.h`), while the other types are handled by `ManagerBase` and its derivative classes. ## Asynchronous Message Parsing diff --git a/bdk-implementation/the-core-folder.md b/bdk-implementation/the-core-folder.md index e94b1a9..b1ca2be 100644 --- a/bdk-implementation/the-core-folder.md +++ b/bdk-implementation/the-core-folder.md @@ -57,7 +57,7 @@ Not all functions from the class update the state. Check the [Doxygen](https://d ## Storage -The `storage.h` file contains the **Storage** class - an abstraction of the blockchain's history, maintaining a collection of blocks approved and validated by the network, other nodes, or itself through time. Those blocks store transactions, contracts, accounts, and can't be altered once they're in the blockchain, only searched for or read from. The class is also responsible for storing and managing emitted events from contracts, if the node is initialized with the `RPC_TRACE` option set. +The `storage.h` file contains the **Storage** class - an abstraction of the blockchain's history, storing and maintaining a collection of blocks approved and validated by the network, other nodes, or itself through time. Those blocks store transactions, contracts, accounts, emitted contract events (if the node is initialized with the `RPC_TRACE` indexing mode set) and other blockchain-related data. Said data can't be altered once it's in the blockchain, it can only be searched for or read from. On node initialization, if there are no blocks (e.g. the blockchain was just deployed and initialized for the first time), a "genesis" block is automatically created and loaded in memory. The "latest" block is always kept in memory, with subsequent older blocks being dumped to and queried constantly from the database. This makes the blockchain lightweight memory-wise and extremely responsive. diff --git a/bdk-implementation/the-utils-folder.md b/bdk-implementation/the-utils-folder.md index 2266156..6f6a8ae 100644 --- a/bdk-implementation/the-utils-folder.md +++ b/bdk-implementation/the-utils-folder.md @@ -61,7 +61,7 @@ The `merkle.h` class contains the **Merkle** class - a custom implementation of * [https://medium.com/coinmonks/implementing-merkle-tree-and-patricia-tree-b8badd6d9591](https://medium.com/coinmonks/implementing-merkle-tree-and-patricia-tree-b8badd6d9591) * [https://lab.miguelmota.com/merkletreejs/example/](https://lab.miguelmota.com/merkletreejs/example/) -A "Merkle Tree" is a data structure in binary tree format (e.g. "heap sort"), where data is stored in the "leaves", and the "branches" are paths to reach their data. This structure is commonly used in the crypto space as a tool for _verification_: it hashes the previous layers in pairs to make new layers, bottom-up, until it reaches a single result which would be the "root" of the tree - this makes the root a unique fingerprint for the entire tree, so you only need to check the root hash to verify that both the tree and its leaves were not tampered with. +A "Merkle Tree" is a data structure in binary tree format (e.g. "heap sort"), where data is stored in the "leaves", and the "branches" are paths to reach their data. This structure is commonly used in the crypto space as a tool for _verification_: it hashes the previous layers in pairs to make new layers, bottom-up, until it reaches a single result which would be the "root" of the tree - this makes the root a unique fingerprint for the entire tree, so you only need to check the root hash to verify both the tree and its leaves were not tampered with. ## Options @@ -105,6 +105,15 @@ The `tx.h` file contains the **TxBlock** and **TxValidator** classes - abstracti It also contains a helper struct called `TxAdditionalData`, which contains metadata about a contract that was deployed in the chain, such as the transaction hash, how much gas was used in the transaction, if the call succeeded or not, and the contract's address. +## UintConv, IntConv, StrConv and EVMCConv + +The respective files `uintconv.h`, `intconv.h`, `strconv.h` and `evmcconv.h` contain several namespaces related to aliases, conversion and manipulation of specific types of data (previously in the **Utils** namespace, now divided into their own namespaces): + +* **UintConv**: contains several `uintX_t` primitive type aliases used across the project, as well as their respective conversion functions (e.g. `uintXToBytes()`/`bytesToUintX()`) +* **IntConv**: contains several `intX_t` primitive type aliases used across the project, as well as their respective conversion functions (e.g. `intXToBytes()`/`bytesToIntX()`) +* **StrConv**: contains a few functions for converting and manipulating raw byte and UTF-8 strings (e.g. `padLeft()`/`padRight()` and their respective raw byte counterparts, `toLower()`/`toUpper()`, etc.) +* **EVMCConv**: contains a few functions for converting and manipulating EVMC-specific data types (e.g. functors and their specific implementation of uint256) + ## Utils The `utils.h` file contains the **Utils** namespace - a place for generalized miscellaneous utility functions, namespaces, enums and typedefs used across the BDK. @@ -112,9 +121,9 @@ The `utils.h` file contains the **Utils** namespace - a place for generalized mi This list is only an example and does not reflect the entire contents of the file. We suggest you read the [Doxygen](https://doxygen.nl/) docs for more info about the class: * Helper functions that deal with printing (`safePrint()`, `safePrintTest()`, `printXYZ()`, etc.) -* Aliases for working with integer types (`intX_t`, `uintX_t`, `SafeIntX_t`, `SafeUintX_t`), raw-byte strings (`Byte`,`Bytes`, `BytesArr`), and helper functions for converting and/or manipulating them (e.g. `appendBytes()`, `uintXToBytes()`, `bytesToUintX()`, `bytesToString()`, `stringToBytes()`, etc.) +* Aliases for working with raw-byte strings (`Byte`,`Bytes`, `BytesArr`) and helper functions for converting and/or manipulating them (e.g. `appendBytes()`, `bytesToString()`, `stringToBytes()`, etc.) * For `appendBytes()` specifically, it is recommended to use it if you need a buffer, otherwise you can use `bytes::join()` as a slightly faster replacement (e.g. if you have all the data required at once, use `bytes::join()`, if you have the data scattered across different places, use a `Bytes` object as a buffer and use it with `appendBytes()`) -* A map with addresses for Protocol Contracts (e.g. `rdPoS` and `ContractManager`) +* The `ProtocolContractAddress` map for storing addresses for deployed Protocol Contracts (e.g. `rdPoS` and `ContractManager`) * Enums for network types (`Networks`), contract function types (`FunctionTypes`) and contract types (`ContractType`) * The `Account` struct, used to maintain account balance and nonce statuses, as well as contract-specific data (if the account represents a contract) * A wrapper for a pointer that ensures the pointer is never null (`NonNullUniquePtr`), as well as a wrapper for a pointer that forcefully nullifies it on destruction (`PointerNullifier`) @@ -122,6 +131,3 @@ This list is only an example and does not reflect the entire contents of the fil * Several templated helper functions that deal with tuples, as well as helper functions that deal with Functors * The `sha3()` function, used extensively as the primary hash function for the entire project * The `randBytes()` function, used extensively as a random bytes string generator -* `padLeft()` and `padRight()`, used for adding padding to strings at their left and right sides, respectively -* `padLeftBytes()` and `padRightBytes()`, same as above, but specifically for use with raw byte strings -* `toLower()` and `toUpper()`, used for converting strings to all-lower and all-upper case, respectively diff --git a/evm-contracts/README.md b/evm-contracts/README.md index 1fb5a78..c85b812 100644 --- a/evm-contracts/README.md +++ b/evm-contracts/README.md @@ -4,7 +4,6 @@ description: A primer on EVM smart contracts in the AppLayer ecosystem. # EVM contracts -Aside from native contracts, AppLayer can also execute Solidity contracts as-is by the use of the AppLayer EVM, which is compatible with bytecode deployment. This means any language that compiles to EVM bytecode (e.g. Solidity, Viper, etc.) can be used to deploy contracts in the AppLayer EVM in a seamless, straight-forward way. - -This kind of compatibility is possible thanks to the integration of the [EVMOne](https://github.com/ethereum/evmone) virtual machine (originally made by the Ethereum devs) and EVMC libraries. +Aside from native contracts, AppLayer can also execute Solidity contracts as-is by the use of the AppLayer EVM, which is compatible with bytecode deployment. This means any language that compiles to EVM bytecode (e.g. [Solidity](https://soliditylang.org/), [Vyper](https://docs.vyperlang.org/en/stable/), etc.) can be used to deploy contracts in the AppLayer EVM in a seamless, straight-forward way. +This kind of compatibility is possible thanks to the integration of the [EVMOne](https://github.com/ethereum/evmone) virtual machine (originally made by the Ethereum devs) and [EVMC](https://github.com/ethereum/evmc) libraries. diff --git a/evm-contracts/cpp-to-other-contract-calls.md b/evm-contracts/cpp-to-other-contract-calls.md index 77a4812..3fd9dfd 100644 --- a/evm-contracts/cpp-to-other-contract-calls.md +++ b/evm-contracts/cpp-to-other-contract-calls.md @@ -7,49 +7,18 @@ description: How contract calls happen from the C++ side in AppLayer. The `ContractHost` class employs templated functions to support flexible and efficient interaction with contracts. These templates enable passing any combination of arguments and return types (including `void`) to and from other types of contracts. This use of templates helps to leverage the fast ABI encoding/decoding processes, ensuring optimal performance and flexibility during contract execution: ```cpp -template R -callContractViewFunction( - const BaseContract* caller, - const Address& targetAddr, - R(C::*func)(const Args&...) const, const - Args&... args) const; - -template R -callContractViewFunction( - const BaseContract* caller, - const Address& targetAddr, - R(C::*func)() const) const; - -template -requires (!std::is_same::value) -R callContractFunction( - BaseContract* caller, const Address& targetAddr, - const uint256_t& value, - R(C::*func)(const Args&...), const Args&... args -) - template -requires (std::is_same::value) -void callContractFunction( - BaseContract* caller, const Address& targetAddr, - const uint256_t& value, - R(C::*func)(const Args&...), const Args&... args -) +R callContractViewFunction( + const BaseContract* caller, const Address& targetAddr, + R(C::*func)(const Args&...) const, const Args&... args +) const; template -requires (!std::is_same::value) R callContractFunction( BaseContract* caller, const Address& targetAddr, const uint256_t& value, R(C::*func)(const Args&...), const Args&... args -) - -template -requires (!std::is_same::value) -R callContractFunction( - BaseContract* caller, const Address& targetAddr, - const uint256_t& value, R(C::*func)() -) +); ``` This approach allows for dynamic interaction with contracts without pre-defining all possible function signatures, accommodating various contract behaviors and states dynamically. diff --git a/evm-contracts/evm-to-other-contract-calls.md b/evm-contracts/evm-to-other-contract-calls.md index 363d093..a5d0253 100644 --- a/evm-contracts/evm-to-other-contract-calls.md +++ b/evm-contracts/evm-to-other-contract-calls.md @@ -14,33 +14,40 @@ This function is designed to handle both C++ and EVM contract calls, as shown be ```cpp evmc::Result ContractHost::call(const evmc_message& msg) noexcept { - Address recipient(msg.recipient); - auto &recipientAccount = *accounts_[recipient]; // We need to take a reference to the account, not a reference to the pointer. - this->leftoverGas_ = msg.gas; - /// evmc::Result constructor is: _status_code + _gas_left + _output_data + _output_size - if (recipientAccount.contractType == CPP) { - // We are a CPP contract, we need to call the contract evmEthCall function and put the result into a evmc::Result - try { - this->deduceGas(1000); // CPP contract call is 1000 gas - auto& contract = contracts_[recipient]; - if (contract == nullptr) { - throw DynamicException("ContractHost call: contract not found"); - } - this->setContractVars(contract.get(), Address(msg.sender), Utils::evmcUint256ToUint256(msg.value)); - Bytes ret = contract->evmEthCall(msg, this); - return evmc::Result(EVMC_SUCCESS, this->leftoverGas_, 0, ret.data(), ret.size()); - } catch (std::exception& e) { - this->evmcThrows_.emplace_back(e.what()); - this->evmcThrow_ = true; - return evmc::Result(EVMC_PRECOMPILE_FAILURE, this->leftoverGas_, 0, nullptr, 0); - } + evmc::Result result; + const bool isContractCall = isCall(msg); + + if (isContractCall) { + this->traceCallStarted(msg); + } + + switch (this->decodeContractCallType(msg)) + { + case ContractType::CREATE: { + result = this->callEVMCreate(msg); + break; + } + case ContractType::CREATE2: { + result = this->callEVMCreate2(msg); + break; + } + case ContractType::PRECOMPILED: { + result = this->processBDKPrecompile(msg); + break; } - evmc::Result result (evmc_execute(this->vm_, &this->get_interface(), this->to_context(), - evmc_revision::EVMC_LATEST_STABLE_REVISION, &msg, - recipientAccount.code.data(), recipientAccount.code.size())); - this->leftoverGas_ = result.gas_left; // gas_left is not linked with leftoverGas_, we need to link it. - this->deduceGas(5000); // EVM contract call is 5000 gas - result.gas_left = this->leftoverGas_; // We need to set the gas left to the leftoverGas_ + case ContractType::CPP: { + result = this->callCPPContract(msg); + break; + } + default: + result = this->callEVMContract(msg); + break; + } + + if (isContractCall) { + this->traceCallFinished(result.raw()); + } + return result; } ``` diff --git a/evm-contracts/seamless-cpp-evm-integration.md b/evm-contracts/seamless-cpp-evm-integration.md index f85dcf4..1fa6b9d 100644 --- a/evm-contracts/seamless-cpp-evm-integration.md +++ b/evm-contracts/seamless-cpp-evm-integration.md @@ -30,18 +30,18 @@ struct evmc_message { `ContractHost` plays a critical role in distinguishing whether a contract is implemented in C++ or EVM and executing it accordingly. Below is an example illustrating how C++ contracts can invoke functions in other contracts, whether they are C++ or EVM: -

template <typename R, typename C, typename... Args>
-requires (!std::is_same<R, void>::value)
-R callContractFunction(
-  BaseContract* caller, const Address& targetAddr,
-  const uint256_t& value,
-  R(C::*func)(const Args&...), const Args&... args
+```c++
+template 
+R callContractFunctionImpl(
+  BaseContract* caller, const Address& targetAddr,
+  const uint256_t& value,
+  R(C::*func)(const Args&...), const Args&... args
 ) {
   // 1000 Gas Limit for every C++ contract call!
-  auto& recipientAcc = *this->accounts_[targetAddr];
+  auto& recipientAcc = *this->accounts_[targetAddr];
   if (!recipientAcc.isContract()) {
     throw DynamicException(std::string(__func__) + ": Contract does not exist - Type: "
-      + Utils::getRealTypeName<C>() + " at address: " + targetAddr.hex().get()
+      + Utils::getRealTypeName() + " at address: " + targetAddr.hex().get()
     );
   }
   if (value) {
@@ -49,7 +49,7 @@ R callContractFunction(
   }
   NestedCallSafeGuard guard(caller, caller->caller_, caller->value_);
   switch (recipientAcc.contractType) {
-    case ContractType::EVM : {
+    case ContractType::EVM: {
       this->deduceGas(10000);
       evmc_message msg;
       msg.kind = EVMC_CALL;
@@ -62,35 +62,41 @@ R callContractFunction(
       if (functionName.empty()) {
         throw DynamicException("ContractHost::callContractFunction: EVM contract function name is empty (contract not registered?)");
       }
-      auto functor = ABI::FunctorEncoder::encode<Args...>(functionName);
-      Bytes fullData;
-      Utils::appendBytes(fullData, Utils::uint32ToBytes(functor.value));
-      Utils::appendBytes(fullData, ABI::Encoder::encodeData<Args...>(args...));
+      auto functor = ABI::FunctorEncoder::encode(functionName);
+      Bytes fullData;
+      Utils::appendBytes(fullData, UintConv::uint32ToBytes(functor.value));
+      if constexpr (sizeof...(Args) > 0) {
+        Utils::appendBytes(fullData, ABI::Encoder::encodeData(args...));
+      }
       msg.input_data = fullData.data();
       msg.input_size = fullData.size();
-      msg.value = Utils::uint256ToEvmcUint256(value);
+      msg.value = EVMCConv::uint256ToEvmcUint256(value);
       msg.create2_salt = {};
       msg.code_address = targetAddr.toEvmcAddress();
-      evmc::Result result (evmc_execute(this->vm_, &this->get_interface(), this->to_context(),
-      evmc_revision::EVMC_LATEST_STABLE_REVISION, &msg, recipientAcc.code.data(), recipientAcc.code.size()));
+      evmc::Result result (evmc_execute(this->vm_, &this->get_interface(), this->to_context(),
+      evmc_revision::EVMC_LATEST_STABLE_REVISION, &msg, recipientAcc.code.data(), recipientAcc.code.size()));
       this->leftoverGas_ = result.gas_left;
       if (result.status_code) {
         auto hexResult = Hex::fromBytes(bytes::View(result.output_data, result.output_data + result.output_size));
         throw DynamicException("ContractHost::callContractFunction: EVMC call failed - Type: "
-          + Utils::getRealTypeName<C>() + " at address: " + targetAddr.hex().get() + " - Result: " + hexResult.get()
+          + Utils::getRealTypeName() + " at address: " + targetAddr.hex().get() + " - Result: " + hexResult.get()
         );
       }
-      return std::get<0>(ABI::Decoder::decodeData<R>(bytes::View(result.output_data, result.output_data + result.output_size)));
+      if constexpr (std::same_as) {
+        return;
+      } else {
+        return std::get<0>(ABI::Decoder::decodeData(bytes::View(result.output_data, result.output_data + result.output_size)));
+      }
     } break;
-    case ContractType::CPP : {
+    case ContractType::CPP: {
       this->deduceGas(1000);
-      C* contract = this->getContract<C>(targetAddr);
+      C* contract = this->getContract(targetAddr);
       this->setContractVars(contract, caller->getContractAddress(), value);
       try {
         return contract->callContractFunction(this, func, args...);
-      } catch (const std::exception& e) {
+      } catch (const std::exception& e) {
         throw DynamicException(e.what() + std::string(" - Type: ")
-          + Utils::getRealTypeName<C>() + " at address: " + targetAddr.hex().get()
+          + Utils::getRealTypeName() + " at address: " + targetAddr.hex().get()
         );
       }
     }
@@ -99,4 +105,4 @@ R callContractFunction(
     }
   }
 }
-
+``` diff --git a/introducing-applayer/what-is-applayer.md b/introducing-applayer/what-is-applayer.md index 1d16748..d298be3 100644 --- a/introducing-applayer/what-is-applayer.md +++ b/introducing-applayer/what-is-applayer.md @@ -8,7 +8,7 @@ The AppLayer Network is made up of three parts: * A Blockchain Development Kit (hereby denominated [**BDK**](https://github.com/AppLayerLabs/bdk-cpp)), with extensive documentation for developers to easily build their own AppLayer's with unprecedented freedom * An EVM network built on top of the Blockchain Development Kit which enables builders to deploy EVM smart contracts and scale with C++ stateful pre-compiles -* A network that allows the bridging of data and assets between these app-specific chains and external chains we call the Chain Abstraction Network (**CAN**) +* A network that allows the bridging of data and assets between these app-specific chains and external chains - we call it the Chain Abstraction Network (**CAN**) Therefore, blockchains built using the BDK are able to communicate with each other through AppLayer. diff --git a/join-our-community.md b/join-our-community.md index 7e4b53d..bd32a10 100644 --- a/join-our-community.md +++ b/join-our-community.md @@ -12,12 +12,12 @@ AppLayer is empowering the next generation of **#Web3** builders! We share insig **Discord:** [https://discord.gg/mSheqXQrQm](https://discord.gg/mSheqXQrQm) -**Twitter:** [https://twitter.com/AppLayerLabs](https://twitter.com/SparqNet) +**Twitter:** [https://twitter.com/AppLayerLabs](https://twitter.com/AppLayerLabs) **Telegram:** [https://t.me/AppLayerLabs](https://t.me/AppLayerLabs) **Telegram Announcements:** [https://t.me/AppLayer\_News](https://t.me/AppLayer\_News) -**Medium:** [https://medium.com/@AppLayerLabs](https://medium.com/@SparqNet) +**Medium:** [https://medium.com/@AppLayerLabs](https://medium.com/@AppLayerLabs) -**LinkedIn:** [https://www.linkedin.com/company/sparq-network](https://www.linkedin.com/company/sparq-network) +**LinkedIn:** [https://www.linkedin.com/company/applayerlabs](https://www.linkedin.com/company/applayerlabs) diff --git a/precompiled-contracts/README.md b/precompiled-contracts/README.md index 5b5f8cd..8da55d9 100644 --- a/precompiled-contracts/README.md +++ b/precompiled-contracts/README.md @@ -4,8 +4,8 @@ description: A primer on natively-coded smart contracts in the AppLayer ecosyste # Precompiled contracts -Precompiled contracts (also known as "native contracts" or "stateful pre-compiles" - "stateful" since they can maintain a state, and "pre-compile" because they're compiled machine code not interpreted by a virtual machine) are contracts coded with the blockchain's native language, with things like transaction parsing methods and arguments, as well as management and storage of the contract's variables in a database, being manually coded in e.g. C++ to be tightly integrated with the blockchain itself. +Precompiled contracts (also known as "native contracts" or "stateful pre-compiles" - "stateful" since they can maintain a state, and "pre-compile" because they're compiled machine code not interpreted by a virtual machine) are contracts coded with the blockchain's native language, with things like transaction parsing methods and arguments, as well as management and storage of the contract's variables in a database, being manually coded in the blockchain's native language (e.g. bdk-cpp in C++) to be tightly integrated with the blockchain itself. Similar to Solidity contracts, they can be used to employ any type of logic within the network, but unlike Solidity, they aren’t subject to EVM constraints. This means we can take advantage of that fact and have full control of the contract's logic, unleashing blazing fast performance, flexibility and power. -The contract templates provided by AppLayer's BDK (in the `src/contract/templates` folder) are based on OpenZeppelin contracts, maintaining the same operational standards known in the Solidity ecosystem, but on native C++. +The contract templates provided by AppLayer's BDK (in the `src/contract/templates` folder) are based on OpenZeppelin contracts, maintaining the same operational standards known in the Solidity ecosystem, but on native C++ (in the case of bdk-cpp). diff --git a/precompiled-contracts/creating-a-dynamic-contract-advanced.md b/precompiled-contracts/creating-a-dynamic-contract-advanced.md index 5c5edd2..de0cdc5 100644 --- a/precompiled-contracts/creating-a-dynamic-contract-advanced.md +++ b/precompiled-contracts/creating-a-dynamic-contract-advanced.md @@ -140,6 +140,8 @@ Like in SimpleContract's case, you must include your contract's header in `custo Inside `erc20wrapper.cpp`, let's implement both constructors and the dumping function: ```cpp +#include "erc20wrapper.h" + ERC20Wrapper::ERC20Wrapper(const Address& contractAddress, const DB& db ) : DynamicContract(contractAddress, db), tokensAndBalances_(this) { @@ -167,9 +169,8 @@ ERC20Wrapper::ERC20Wrapper(const Address& address, const Address& creator, const ERC20Wrapper::~ERC20Wrapper() {} -DBBatch ERC20Wrapper::dump () const { +DBBatch ERC20Wrapper::dump() const { DBBatch dbBatch = BaseContract::dump(); - for (auto i = tokensAndBalances_.cbegin(); i != tokensAndBalances_.cend(); ++i) { for (auto j = i->second.cbegin(); j != i->second.cend(); ++j) { const auto& key = i->first; diff --git a/precompiled-contracts/creating-a-dynamic-contract-simple/README.md b/precompiled-contracts/creating-a-dynamic-contract-simple/README.md index 3072c6b..281a7de 100644 --- a/precompiled-contracts/creating-a-dynamic-contract-simple/README.md +++ b/precompiled-contracts/creating-a-dynamic-contract-simple/README.md @@ -4,7 +4,7 @@ description: A walkthrough on the basics of a Dynamic Contract's structure. # Creating a Dynamic Contract (Simple) -Let's create a test contract that allows three variables - `name`, `number` and `tuple` - to be changed by the owner of the contract, as well as perform basic operations with structs/tuples and event emissions. We will call this contract `SimpleContract` (which just so happens to be already implemented by the project due to internal testing purposes, but you can do it yourself by hand - check the `simplecontract.{h,cpp,sol}` files for reference). +Let's create a test contract that allows three variables - `name`, `number` and `tuple` - to be changed by the owner of the contract, as well as perform basic operations with structs/tuples and event emissions. We will call this contract `SimpleContract` (which just so happens to be already implemented by the project due to internal testing purposes, but you can do it yourself by hand - check the `src/contract/templates/simplecontract.{h,cpp,sol}` files for reference). ### Creating the Files diff --git a/precompiled-contracts/creating-a-dynamic-contract-simple/deploying-and-testing.md b/precompiled-contracts/creating-a-dynamic-contract-simple/deploying-and-testing.md index a791227..ed88a4d 100644 --- a/precompiled-contracts/creating-a-dynamic-contract-simple/deploying-and-testing.md +++ b/precompiled-contracts/creating-a-dynamic-contract-simple/deploying-and-testing.md @@ -56,17 +56,11 @@ Finally, write your tests. In this case, for `SimpleContract`, tests should look ```cpp #include "../../src/libs/catch2/catch_amalgamated.hpp" -#include "../../src/utils/db.h" -#include "../../src/utils/options.h" -#include "../../src/core/rdpos.h" -#include "../../src/contract/abi.h" -#include "../../src/contract/contractmanager.h" + #include "../../src/contract/templates/simplecontract.h" #include "../sdktestsuite.hpp" -#include - namespace TSimpleContract { TEST_CASE("SimpleContract class", "[contract][simplecontract]") { SECTION("SimpleContract creation") { @@ -129,6 +123,6 @@ namespace TSimpleContract { Keep in mind that we're not accessing the contract directly, we're interacting with it through `SDKTestSuite`, and that requires us to parse its inputs and outputs accordingly. -In order to run your tests, compile the project as you normally would, and then run `./src/bins/orbitersdkd-tests/orbitersdkd-tests -d yes [simplecontract]` from within your build directory. The `[simplecontract]` tag forces only these specific tests for SimpleContract to run (this is set in the `TEST_CASE()` lines in the example above). The `-d yes` flag makes it more verbose, showing exactly which test case is being run at the moment. +In order to run your tests, compile the project as you normally would, and then run `./src/bins/bdkd-tests/bdkd-tests -d yes [simplecontract]` from within your build directory. The `[simplecontract]` tag forces only these specific tests for SimpleContract to run (this is set in the `TEST_CASE()` lines in the example above). The `-d yes` flag makes it more verbose, showing exactly which test case is being run at the moment. As a bonus, even though this whole chapter is focused on precompiled contracts, the `SDKTestSuite` also has a function that can deploy a contract's bytecode directly, called `SDKTestSuite::deployBytecode()`, which takes a `Bytes` object as a parameter that represents the contract's bytecode. diff --git a/precompiled-contracts/creating-a-dynamic-contract-simple/simple-contract-header.md b/precompiled-contracts/creating-a-dynamic-contract-simple/simple-contract-header.md index dd39c3f..ce73b48 100644 --- a/precompiled-contracts/creating-a-dynamic-contract-simple/simple-contract-header.md +++ b/precompiled-contracts/creating-a-dynamic-contract-simple/simple-contract-header.md @@ -17,7 +17,7 @@ Open the header file (`simplecontract.h`) and add the following lines: #include "../dynamiccontract.h" #include "../variables/safestring.h" #include "../variables/safetuple.h" -#include "../../utils/utils.h" // SafeUintX_t aliases declared here +#include "../variables/safeuint.h" class SimpleContract : public DynamicContract { private: @@ -32,8 +32,7 @@ class SimpleContract : public DynamicContract { This is a simple skeleton so we can start building the proper contract. From top to bottom: * We create [include guards](https://en.wikipedia.org/wiki/Include\_guard) as a safety measure -* We include the `DynamicContract` class and three SafeVariable classes for the contract's inner variables - `SafeString`, `SafeUint256_t` and `SafeTuple`, which represent a Solidity `string`, `uint256` and `tuple/struct` types, respectively (check the `src/contract/variables` subfolder for all available variable abstractions) - * For SafeUint (and SafeInt as well), we include `src/utils/utils.h` as all of the SafeUintX/SafeIntX aliases are declared there, if you want to use `SafeUint_t`/`SafeInt_t` then include `src/contract/variables/safeuint.h` (or `safeint.h`) directly instead +* We include the `DynamicContract` class and three SafeVariable classes for the contract's inner variables - `SafeString`, `SafeUint256_t` and `SafeTuple`, which represent a Solidity `string`, `uint256` and `tuple/struct` types, respectively (check the `src/contract/variables` subfolder for all available variable abstractions) - for SafeUint (and SafeInt as well), you can either use `SafeUint_t`/`SafeInt_t` or the `SafeUintX_t`/`SafeIntX_t` aliases directly, as they are included in their respective header files * We create our `SimpleContract` class, inherit it from `DynamicContract`, and leave some space for the private and public members that will be coded next Now we can declare the members of our contract. We have to pay attention to some rules described earlier, which we'll go through slowly, one part at a time. @@ -107,7 +106,7 @@ class SimpleContract : public DynamicContract { // Constructor from load. Load contract from database. SimpleContract( const Address& address, - const std::unique_ptr &db + const DB& db ); // ... @@ -119,20 +118,19 @@ Aside from our `name`, `number` and `tuple` variables, both constructors also ta ```cpp // Constructor that creates the contract from scratch DynamicContract( - const std::string& contractName, const Address& address, const Address& creator, const uint64_t& chainId -) : BaseContract(contractName, address, creator, chainId) {}; +) : BaseContract("SimpleContract", address, creator, chainId) {}; // Constructor that loads the contract from the database DynamicContract( const Address& address, - const std::unique_ptr &db + const DB& db ) : BaseContract(address, db) {}; ``` -`address`, `creator`, `chainId` and `db` are internal variables used by the base class, and should _always_ be declared _last_. They are equivalent to: +`address`, `creator`, `chainId` and `db` are internal variables used by the base class, and should *always* be declared *last*. They are equivalent to: | DynamicContract constructor argument | Taken from | | ------------------------------------ | ------------------------------------------- | @@ -141,7 +139,7 @@ DynamicContract( | chainId | this->options->getChainID() | | DB | this->db | -Keep in mind that, when calling the base class constructor later on, the `contractName` argument MUST be EXACTLY the same as your contract's class name. This is because `contractName` is used to load the contract type from the database, so incorrectly naming it will result in a segfault at load time. +Keep in mind that, when calling the base class constructor later on, the contract's name argument (in this case, "SimpleContract") MUST be EXACTLY the same as your contract's class name. This is because the name is used to load the contract type from the database, so incorrectly naming it will result in a segfault at load time. ## Declaring the Contract Events @@ -181,7 +179,7 @@ class SimpleContract : public DynamicContract { * The first element is the argument type (e.g. `name` is a `std::string`, `number` is a `uint256_t`, `tuple` is a `std::tuple`) * The second element is a bool that indicates whether the argument should be indexed or not. * If your event has no arguments at all you can omit it or pass an empty tuple instead (e.g. `this->emitEvent(__func__, std::make_tuple())`) -* **(Optional)** A flag that indicates whether the event is anonymous or not. Events are non-anonymous by default, so if you wish you can omit this (which is the case for our example, it is equivalent to `this->emitEvent(__func__, std::make_tuple(name), false)` - if it was an anonymous event, the last flag would be `true` instead) +* **(Optional)** A flag that indicates whether the event is anonymous or not. Events are non-anonymous by default (the flag defaults to `false`), so if you wish you can omit this (which is the case for our example, it is equivalent to `this->emitEvent(__func__, std::make_tuple(name), false)` - if it was an anonymous event, the last flag would be `true` instead) ## Registering the Contract Class @@ -210,8 +208,7 @@ class SimpleContract : public DynamicContract { ContractReflectionInterface::registerContractMethods< SimpleContract, const std::string&, const uint256_t&, const std::tuple&, ContractManagerInterface&, - const Address&, const Address&, const uint64_t&, - const std::unique_ptr& + const Address&, const Address&, const uint64_t&, const DB& >( std::vector{"name_", "number_", "tuple_"}, std::make_tuple("getName", &SimpleContract::getName, FunctionTypes::View diff --git a/precompiled-contracts/creating-a-dynamic-contract-simple/simple-contract-source.md b/precompiled-contracts/creating-a-dynamic-contract-simple/simple-contract-source.md index 4c43f5a..662e070 100644 --- a/precompiled-contracts/creating-a-dynamic-contract-simple/simple-contract-source.md +++ b/precompiled-contracts/creating-a-dynamic-contract-simple/simple-contract-source.md @@ -24,6 +24,9 @@ Our source file will look something like this: ```cpp #include "simplecontract.h" +#include "../../utils/uintconv.h" +#include "../../utils/utils.h" + SimpleContract::SimpleContract( const std::string& name, const uint256_t& number, @@ -54,10 +57,10 @@ SimpleContract::SimpleContract( const DB& db ) : DynamicContract(address, db), name_(this), number_(this), tuple_(this) { this->name_ = Utils::bytesToString(db.get(std::string("name_"), this->getDBPrefix())); - this->number_ = Utils::bytesToUint256(db.get(std::string("number_"), this->getDBPrefix())); + this->number_ = UintConv::bytesToUint256(db.get(std::string("number_"), this->getDBPrefix())); this->tuple_ = std::make_tuple( Utils::bytesToString(db.get(std::string("tuple_name"), this->getDBPrefix())), - Utils::bytesToUint256(db.get(std::string("tuple_number"), this->getDBPrefix())) + UintConv::bytesToUint256(db.get(std::string("tuple_number"), this->getDBPrefix())) ); this->name_.commit(); @@ -71,13 +74,12 @@ SimpleContract::SimpleContract( this->tuple_.enableRegister(); } - DBBatch SimpleContract::dump() const { DBBatch dbBatch; dbBatch.push_back(Utils::stringToBytes("name_"), Utils::stringToBytes(this->name_.get()), this->getDBPrefix()); - dbBatch.push_back(Utils::stringToBytes("number_"), Utils::uint256ToBytes(this->number_.get()), this->getDBPrefix()); + dbBatch.push_back(Utils::stringToBytes("number_"), UintConv::uint256ToBytes(this->number_.get()), this->getDBPrefix()); dbBatch.push_back(Utils::stringToBytes("tuple_name"), Utils::stringToBytes(get<0>(this->tuple_)), this->getDBPrefix()); - dbBatch.push_back(Utils::stringToBytes("tuple_number"), Utils::uint256ToBytes(get<1>(this->tuple_)), this->getDBPrefix()); + dbBatch.push_back(Utils::stringToBytes("tuple_number"), UintConv::uint256ToBytes(get<1>(this->tuple_)), this->getDBPrefix()); return dbBatch; } ``` diff --git a/precompiled-contracts/dynamic-and-protocol-contracts.md b/precompiled-contracts/dynamic-and-protocol-contracts.md index 1ba1888..b81fcd0 100644 --- a/precompiled-contracts/dynamic-and-protocol-contracts.md +++ b/precompiled-contracts/dynamic-and-protocol-contracts.md @@ -25,6 +25,11 @@ AppLayer's BDK provides ready-to-use templates for the following Dynamic Contrac * `DEXV2Router02` (template for a DEX contract router) * `UQ112x112` (namespace for dealing with fixed point fractions in DEX contracts) +Some contracts were converted directly from their OpenZeppelin counterparts and are also available for use: + +* `ERC721URIStorage` +* `Ownable` + There are also specific contracts that only exist for internal testing purposes and are not meant to be used as templates: * `SimpleContract` (what it says on the tin - a simple contract, used for both testing and teaching purposes) @@ -33,6 +38,7 @@ There are also specific contracts that only exist for internal testing purposes * `TestThrowVars` (contract meant to test SafeVariable commit/revert functionality using exception throwing) * `ThrowTestA/B/C` (contracts meant to test nested call revert functionality) * `SnailTracer` / `SnailTracerOptimized` (C++ conversions of the [SnailTracer](https://github.com/karalabe/snailtracer) contract, used for benchmarking purposes) +* `Pebble` (contract meant to be used in the testnet as a little NFT mining game) ## Protocol Contracts @@ -65,7 +71,7 @@ Given the example Solidity contract: pragma solidity ^0.8.10; contract ExampleContract { - mapping(address => uint256) values;c + mapping(address => uint256) values; function setValue(address addr, uint256 value) external { values[addr] = value; return; @@ -73,7 +79,7 @@ contract ExampleContract { } ``` -The transpiled code should look similar to this: +The transpiled code should look similar to this (this is only an example, read further for more details): * Declaration (`ExampleContract.h`) @@ -83,12 +89,18 @@ class ExampleContract : public DynamicContract { private: std::unordered_map values; // or boost::unordered_flat_map for example // Const-reference as they are not changed by the function. - void setValue(const Address &addr, const uint256 &value); + void setValue(const Address& addr, const uint256_t& value); public: + // Constructor for creating the contract the first time. + // "address" is where the contract will be deployed. + // "creator" is the address that created the contract. + // "chainId" is the chain ID where the contract will operate. + ExampleContract( + const Address& address, const Address& creator, const uint64_t& chainId + ); + // Constructor for loading the already-created contract from the database. ExampleContract( - const Address& contractAddress, const uint64_t& chainId, - std::unique_ptr &contractManager, - std::unique_ptr db + const Address& address, const DB& db ); void callContractWithTransaction(const Tx& transaction); } @@ -100,13 +112,19 @@ class ExampleContract : public DynamicContract { #include "ExampleContract.h" ExampleContract( - const Address& contractAddress, const uint64_t& chainId, - std::unique_ptr &contractManager, - std::unique_ptr db -) : Dynamic Contract(contractAddress, chainId, contractManager, db) { + const Address& address, const Address& creator, const uint64_t& chainId +) : DynamicContract("ExampleContract", address, creator, chainId) { // Read the "values" variables from DB - // Code generated by the transpiller from all local variables - // of the solidity contract, on the ExampleContract, you have values as a address => uint256 mapping + // Code generated by the transpiler from all local variables + // of the solidity contract, on the ExampleContract, you have values as an address => uint256 mapping + ... +} + +ExampleContract::ExampleContract( + const Address& address, + const DB& db +) : DynamicContract(address, db) { + // Same thing but the contract already exists in the database so you just load it entirely from there ... } @@ -133,28 +151,6 @@ void ExampleContract::callContractWithTransaction(const Tx& transaction) { ## The BaseContract class -The `BaseContract` class, declared in `src/contract/contract.h`, is the base class which all contracts derive from. This class holds all the [Solidity global variables](https://docs.soliditylang.org/en/v0.8.17/units-and-global-variables.html), besides variables common among these contracts (such as contract address). Its header should look similar to the following: - -```cpp -class BaseContract { - private: - // CONTRACT VARIABLES - const Address _contractAddress; - const uint64_t _chainId; - const std::unique_ptr& _contractManager; - // GLOBAL VARIABLES - static Address _coinbase; // Current Miner Address - static uint256_t _blockNumber; // Current Block Number - static uint256_t _blockTimestamp; // Current Block Timestamp - public: - Contract(const Address& contractAddress, const uint64_t& chainId, std::unique_ptr &contractManager) : _contractAddress(contractAddress), _chainId(chainId), _contractManager(contractManager) {} - const Address& coinbase() { return _coinbase }; - const uint256_t& blockNumber() { return _blockNumber}; - const uint256_t blockTimestamp() { return _blockTimestamp}; - virtual void callContractWithTransaction(const Tx& transaction); - virtual std::string ethCallContract(const std::string& calldata) const; - friend State; // State can update the private global variables of the contracts -} -``` +The `BaseContract` class, declared in `src/contract/contract.h`, is the base class which all contracts derive from. This class holds all the [Solidity global variables](https://docs.soliditylang.org/en/v0.8.17/units-and-global-variables.html), besides variables common among these contracts (such as contract address). Have a look at the header file for further reference on its structure. Regarding the `callContractWithTransaction` and the `ethCallContract` functions, `callContractWithTransaction` is used by the State when calling from `processNewBlock()`, while `ethCallContract` is used by RPC to answer for `eth_call`. Strings returned by `ethCallContract` are hex strings encoded with the desired function result. diff --git a/precompiled-contracts/safevariables-and-commit-revert-logic.md b/precompiled-contracts/safevariables-and-commit-revert-logic.md index aba4cb2..892a632 100644 --- a/precompiled-contracts/safevariables-and-commit-revert-logic.md +++ b/precompiled-contracts/safevariables-and-commit-revert-logic.md @@ -11,7 +11,7 @@ MyClass::updateValueAndThrow(const uint64_t key, const uint64_t value) { // Suppose the original value of myMap[key] is 5 this->myMap[key] = value; // e.g. 10 throw std::runtime_error("Error"); - // myMap[key] is now 10, but it shouldn't be because it threw + // myMap[key] remains 10, but it shouldn't because it threw } ``` @@ -35,7 +35,7 @@ All SafeVariables inherit from the `SafeBase` class, which adhere to the followi * Have two internal variables: one for the current/original value and another for the previous/temporary value * Optionally, if required, an undo stack for dealing with more complex variables such as containers -* Must override the `commit()`, and `revert()` functions +* Must override the `commit()` and `revert()` functions * `commit()` should keep the current value as-is and either discard the previous one or equal it to the current, depending on the implementation details * `revert()` should do the opposite - discard the current value and set it back to the previous one (also applying the undo stack if it has one, again, depending on the implementation details) * Must be declared as *private* within contracts and initialized with `this` as the parameter - this enables the SafeVariable to mark itself as used in the `ContractManager`, allowing proper reversion of changes made to the contract diff --git a/understanding-contracts/README.md b/understanding-contracts/README.md index 224b9e7..4bd4d49 100644 --- a/understanding-contracts/README.md +++ b/understanding-contracts/README.md @@ -6,6 +6,6 @@ description: How smart contracts work in the AppLayer protocol. Contracts in the AppLayer network are custom, developer-made classes that directly interact with the current State of the Blockchain. This chapter will comprehensively cover creating native contracts for AppLayer using the BDK, as well as operating the AppLayer EVM to leverage existing Solidity contracts. -AppLayer ensures that contracts deployed in its network, no matter the type, remain compatible with existing frontend Web3 tools (e.g. MetaMask, ethers.js, web3.js, etc.). Those are originally designed to interact with Solidity contracts and thus require a similar interface. +AppLayer ensures that contracts deployed in its network, no matter the type, remain compatible with existing frontend Web3 tools (e.g. [MetaMask](https://metamask.io/), [ethers.js](https://github.com/ethers-io/ethers.js/), [web3.js](https://docs.web3js.org/), etc.). Those are originally designed to interact with Solidity contracts and thus require a similar interface. To call your contract's functions from a frontend, you'll also need to generate its ABI - you can either do it directly with our generator tool if coding a pre-compiled contract (explained further), or replicate their definitions in Solidity and use an external tool like Ethereum's [Remix](https://remix.ethereum.org/) or any other of your preference. This ABI can then be used by your preferred Web3 frontend. diff --git a/understanding-contracts/setting-up-the-development-environment.md b/understanding-contracts/setting-up-the-development-environment.md index 4920777..282f863 100644 --- a/understanding-contracts/setting-up-the-development-environment.md +++ b/understanding-contracts/setting-up-the-development-environment.md @@ -45,7 +45,7 @@ Then, install Docker on your system (if you don't have it installed already). In * [Docker for Mac](https://docs.docker.com/docker-for-mac/install/) * [Docker for Linux](https://docs.docker.com/desktop/install/linux-install/) -Once Docker is installed, go to the root directory of your cloned repository (where the `Dockerfile` is located), and run the following command (if you're on Linux or Mac, use `sudo`): +Once Docker is installed, go to the root directory of your cloned repository (where the `Dockerfile` is located), and run the following command: ```bash docker build -t bdk-cpp-dev:latest . @@ -53,17 +53,18 @@ docker build -t bdk-cpp-dev:latest . This will build the image and tag it as `bdk-cpp-dev:latest`. You can change the tag to whatever you want, but remember to change it at the next step. -After building the image, run it with the following command (again, if using Linux or Mac, run as `sudo`): +After building the image, run a container with the following command: ```bash # For Linux/Mac -docker run -it -v $(pwd):/bdk-volume -p 8080-8099:8080-8099 -p 8110-8111:8110-8111 bdk-cpp-dev:latest +docker run -it --name bdk-cpp -v $(pwd):/bdk-volume -p 8080-8099:8080-8099 -p 8110-8111:8110-8111 bdk-cpp-dev:latest # For Windows -docker run -it -v %cd%:/bdk-volume -p 8080-8099:8080-8099 -p 8110-8111:8110-8111 bdk-cpp-dev:latest +docker run -it --name bdk-cpp -v %cd%:/bdk-volume -p 8080-8099:8080-8099 -p 8110-8111:8110-8111 bdk-cpp-dev:latest ``` where: +* `--name bdk-cpp` is an optional label for easier handling of the container (instead of using its ID directly) * `$(pwd)` or `%cd%` is the absolute/full path to your repository's folder * `:/bdk-volume` is the path inside the container where the BDK will be mounted. This volume is synced with the `bdk-cpp` folder inside the container * The `-p` flags expose the ports used by the nodes - the example exposes the default ports 8080-8099 and 8110-8111, if you happen to use different ports, change them accordingly @@ -85,19 +86,31 @@ After editing the `docker-compose.yml` file, right-click on it and select `Compo ### Manual setup -You can follow these steps to build the BDK in your own system. Dependencies are: - -* **GCC** with support for **C++23** or higher -* **CMake 3.19.0** or higher -* **Boost 1.83** or higher (components: _chrono, filesystem, program-options, system, thread, nowide_) -* **OpenSSL 1.1.1** -* **CryptoPP 8.2.0** or higher -* **libscrypt** -* **zlib** -* **libsnappy** for database compression -* **tmux** (for deploying) -* (optional) **clang-tidy** for linting -* (optional) **mold** for faster/more efficient linking +You can follow these steps to build the BDK in your own system. Dependencies are divided logically into *toolchain binaries* and *libraries*: + +* *Toolchain binaries*: + * **git** + * **GCC** with support for **C++23** or higher + * **Make** + * **CMake 3.19.0** or higher + * **Protobuf** (protoc + grpc_cpp_plugin) + * **tmux** (for deploying) + * (optional) **ninja** if you prefer it over make + * (optional) **mold** if you prefer it over ld + * (optional) **doxygen** for generating docs + * (optional) **clang-tidy** for linting +* *Libraries*: + * **Boost 1.83** or higher (components: *chrono, filesystem, program-options, system, thread, nowide*) + * **OpenSSL 1.1.1** / **libssl 1.1.1** or higher + * **libzstd** + * **CryptoPP 8.2.0** or higher + * **libscrypt** + * **libc-ares** + * **gRPC** (libgrpc and libgrpc++) + * **secp256k1** + * **ethash** + **keccak** + * **EVMOne** + **EVMC** + * **Speedb** The versions of those dependencies should suffice out-of-the-box for at least the following distros (or greater, including their derivatives): @@ -107,21 +120,23 @@ The versions of those dependencies should suffice out-of-the-box for at least th * **Fedora 40** * Any rolling release distro from around **May 2024** onwards (check their repos to be sure) -For older distros, you may need to compile some dependencies from source (specifically CMake, Boost and/or GCC). Make sure to either uninstall them from the system first to prevent any version conflicts, or use a workaround like e.g. Debian's `update-alternatives` or similar. +#### Tips for dependencies -Specifically for GCC, make sure to also export the right paths for compilation in your environment in case you're using a self-compiled build. For example, in a Linux system, put something like this in your `~/.bashrc` file, changing the version accordingly to whichever one you have installed: +There is a script called `scripts/deps.sh` which you can use to check if you have those dependencies installed (`deps.sh --check`), and install them in case you don't (`deps.sh --install`). The script expects dependencies to be installed either on `/usr` or `/usr/local`, giving preference to the latter if it finds anything there (so you can use a higher version of a dependency while still keeping your distro's default one). -```bash -PATH=/usr/local/gcc-14.1.0/bin:$PATH -LD_LIBRARY_PATH=/usr/local/gcc-14.1.0/lib64:$LD_LIBRARY_PATH -``` +**Please note that installing most dependencies through the script only works on APT-based distros** (Debian, Ubuntu and derivatives) - you can still check the dependencies on any distro and install the few ones labeled as "external" (those are fetched through `git`), but if you're on a distro with another package manager and/or a distro older than one of the minimum ones listed above, you're on your own. -#### One-liners +For Debian specifically, you can (and should) use `update-alternatives` to register and set your GCC version to a more up-to-date build if required. -* For APT-based distros: +If you're using a self-compiled GCC build out of the system path (e.g. `--prefix=/usr/local/gcc-X.Y.Z` instead of `--prefix=/usr/local`), don't forget to export its installation paths in your `PATH` and `LD_LIBRARY_PATH` env vars (to prevent e.g. "version `GLIBCXX_...'/`CXXABI_...` not found" errors). Put something like this in your `~/.bashrc` file for example, changing the version accordingly to whichever one you have installed: ```bash -sudo apt install build-essential cmake tmux clang-tidy autoconf libtool pkg-config libabsl-dev libboost-all-dev libc-ares-dev libcrypto++-dev libgrpc-dev libgrpc++-dev librocksdb-dev libscrypt-dev libsnappy-dev libssl-dev zlib1g-dev openssl protobuf-compiler protobuf-compiler-grpc unison git +# For GCC in /usr/local +export LD_LIBRARY_PATH=/usr/local/lib64:$LD_LIBRARY_PATH + +# For self-contained GCC outside /usr/local +export PATH=/usr/local/gcc-14.2.0/bin:$PATH +export LD_LIBRARY_PATH=/usr/local/gcc-14.2.0/lib64:$LD_LIBRARY_PATH ``` ## Compiling @@ -152,13 +167,15 @@ make -j$(nproc) cmake --build . -- -j$(nproc) ``` -After building, you can optionally run a test bench with the following command: `./src/bins/orbitersdkd-tests/orbitersdkd-tests -d yes` (the `-d yes` parameter will give a verbose output). +Adjust `-j$(nproc)` accordingly to your system if necessary, as some parts of the project can get really heavy RAM-wise during compilation. + +After building, you can optionally run a test bench with the following command: `./src/bins/bdkd-tests/bdkd-tests -d yes` (the `-d yes` parameter will give a verbose output). -You can also use filter tags to test specific parts of the project (e.g. `./src/bins/orbitersdkd-tests/orbitersdkd-tests -d yes [utils]` will test all the components inside the `src/utils` folder, `[utils][tx]` will test only the transaction-related components inside utils, etc.). You can check all the available tags by doing a `grep -rw "\"\[.*\]\""` in the `tests` subfolder. +You can also use filter tags to test specific parts of the project (e.g. `./src/bins/bdkd-tests/bdkd-tests -d yes [utils]` will test all the components inside the `src/utils` folder, `[utils][tx]` will test only the transaction-related components inside utils, etc.). You can check all the available tags by doing a `grep -rw "\"\[.*\]\""` in the `tests` subfolder. ## Deploying -Currently there are two ways to deploy an AppLayer node: *manual*, and *dockerized*. Go back to the project's root folder and check the `scripts` subfolder - there are two main scripts there used for deploying the node. You can pick whichever one you prefer, depending on your needs. +Currently there are two ways to deploy an AppLayer node: *dockerized* and *manual*. Go back to the project's root folder and check the `scripts` subfolder - there are two main scripts there used for deploying the node. You can pick whichever one you prefer, depending on your needs. ### Dockerized deploy @@ -198,4 +215,4 @@ As an example, here's how to configure MetaMask to connect to your local testnet
-Once you're connected, import the following private key for the chain owner account: `0xe89ef6409c467285bcae9f80ab1cfeb3487cfe61ab28fb7d36443e1daa0c2867`. This account contains 1000 APPL Tokens from the get go and is able to call the `ContractManager` contract. +Once you're connected, import the following private key for the chain owner account: `0xe89ef6409c467285bcae9f80ab1cfeb3487cfe61ab28fb7d36443e1daa0c2867`. This account contains 1000 APPL Tokens from the get go and is able to call the `ContractManager` contract. Other details about the deployed testnet chain can be found in the project's README.md file. diff --git a/understanding-contracts/solidity-abi.md b/understanding-contracts/solidity-abi.md index 668bc6e..b4d8e10 100644 --- a/understanding-contracts/solidity-abi.md +++ b/understanding-contracts/solidity-abi.md @@ -8,7 +8,7 @@ description: >- AppLayer is primarily a _native, pre-compiled_ blockchain, which means its main focus is to run without the need for an EVM. However, the vast majority of the smart contract ecosystem operates and depends on [Solidity](https://docs.soliditylang.org/en/latest) - not only the contracts themselves but also the data they share across each other. -When developing pre-compiled contracts, AppLayer makes use of an abstraction of Solidity's ABI encoding and decoding processes to properly translate between native and non-native data types. The **ABI** namespace, declared in `src/contract/abi.h`, contains several functions for Solidity ABI-related operations, for managing and manipulating data in Solidity format. +When developing pre-compiled contracts, AppLayer makes use of an abstraction of Solidity's ABI encoding and decoding processes to properly translate between native and non-native data types. The **ABI** namespace (`src/contract/abi.h`) contains several functions for Solidity ABI-related operations, for managing and manipulating data in Solidity format. This is only an overview, check the [Doxygen](https://doxygen.nl) docs for more details on how those functions work. diff --git a/understanding-rdpos/README.md b/understanding-rdpos/README.md index 68cb5ea..5384fe1 100644 --- a/understanding-rdpos/README.md +++ b/understanding-rdpos/README.md @@ -4,6 +4,6 @@ description: How AppLayer uses Random Deterministic Proof of Stake. # Understanding rdPoS -To keep consensus on such a blazing fast network without tripping up and/or having to deal with rollbacks, AppLayer uses *random deterministic block creation* that allows only one given node to create a block for a given time, eliminating the risk of a block race condition in the network. +To keep consensus on such a blazing fast network without tripping up and/or having to deal with rollbacks, AppLayer uses a *random deterministic block creation* that allows only one given node to create a block for a given time, eliminating the risk of a block race condition in the network. This is implemented in AppLayer as its own consensus algorithm, called **rdPoS (Random Deterministic Proof of Stake)**, which empowers Validators and Sentinels to deal with block congestion and random number generation. This chapter aims to explain in-depth the rdPoS algorithm used by the AppLayer protocol, from concept to implementation. diff --git a/understanding-rdpos/slashing.md b/understanding-rdpos/slashing.md index b21f65b..da5f685 100644 --- a/understanding-rdpos/slashing.md +++ b/understanding-rdpos/slashing.md @@ -4,7 +4,7 @@ description: Cutting out malicious nodes, carefully. # Slashing -What happens when a validator answers with a "randomness" hash that does not match its own hash? Or when a validator creates an invalid block with invalid transactions? Or when a validator can't create a block before reaching the network's time limit? +What happens when a Validator answers with a "randomness" hash that does not match its own hash? Or when a Validator creates an invalid block with invalid transactions? Or when a Validator can't create a block before reaching the network's time limit? Misbehaving nodes suffer consequences. Since Validator signatures are required at protocol level, if a Validator tries to break the rules, it's possible to know who it is thanks to the signature, and "slash" it from the network. From d273bf10b3a293f7bf13c60f7db3f8bbc7935294 Mon Sep 17 00:00:00 2001 From: Jean-Lessa <75625278+Jean-Lessa@users.noreply.github.com> Date: Fri, 15 Nov 2024 15:44:10 -0300 Subject: [PATCH 08/10] Add example for RequestBlock --- bdk-implementation/p2p-encoding.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bdk-implementation/p2p-encoding.md b/bdk-implementation/p2p-encoding.md index d376ef2..69b36ce 100644 --- a/bdk-implementation/p2p-encoding.md +++ b/bdk-implementation/p2p-encoding.md @@ -186,6 +186,6 @@ Requests data from a given block or range of blocks to another node. * Command ID: `0009` * Request Type: Answer or Request * Request Payload: block height start range + block height end range + bytes limit (minimum 1 block) -* Request Example: TODO +* Request Example: `0x00d6906a45be95f8cb0009000000000000000000000000000000010000000000000400` * Answer Payload: serialized block size + content (1..N blocks) -* Answer Example: TODO +* Answer Example: `0x0164fca114cca6773b0009000000000000346bc95fe4d72f96048212a311e3ccfb3ceaef75e801fe1e84ada2b459e185ba097d0871716384a2b3c7076f380f7873d6251e38af74e916fa8eaa0e3ca65347b2c9010db6bd216c7910cccb1dea09f6e7a1c1488446ebacb82cb3ef46c2341b59b0eacfd30704b89f92a41ae8970dd2c001eb08273a5d3c5a7beede721dcd6bcf5ad89c329d6db3658c6da18743131bc95116819fdb8ea16b0abdb7eaf19c840ed09f3e3136569f2d6edab18568da6aef33ae18b8b02ad0a998af0364e184fa987236000626f79d95b771000000000000000a00000000000030e300000077...` From 68c53b02bf74483bc3b9d4de26102f78243448da Mon Sep 17 00:00:00 2001 From: Jean-Lessa <75625278+Jean-Lessa@users.noreply.github.com> Date: Sat, 16 Nov 2024 13:52:38 -0300 Subject: [PATCH 09/10] Move bytesToString/stringToBytes to StrConv --- bdk-implementation/the-utils-folder.md | 4 ++-- .../simple-contract-source.md | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bdk-implementation/the-utils-folder.md b/bdk-implementation/the-utils-folder.md index 6f6a8ae..b347b78 100644 --- a/bdk-implementation/the-utils-folder.md +++ b/bdk-implementation/the-utils-folder.md @@ -111,7 +111,7 @@ The respective files `uintconv.h`, `intconv.h`, `strconv.h` and `evmcconv.h` con * **UintConv**: contains several `uintX_t` primitive type aliases used across the project, as well as their respective conversion functions (e.g. `uintXToBytes()`/`bytesToUintX()`) * **IntConv**: contains several `intX_t` primitive type aliases used across the project, as well as their respective conversion functions (e.g. `intXToBytes()`/`bytesToIntX()`) -* **StrConv**: contains a few functions for converting and manipulating raw byte and UTF-8 strings (e.g. `padLeft()`/`padRight()` and their respective raw byte counterparts, `toLower()`/`toUpper()`, etc.) +* **StrConv**: contains a few functions for converting and manipulating raw byte and UTF-8 strings (e.g. `padLeft()`/`padRight()` and their respective raw byte counterparts, `toLower()`/`toUpper()`, `bytesToString()`, `stringToBytes()`, etc.) * **EVMCConv**: contains a few functions for converting and manipulating EVMC-specific data types (e.g. functors and their specific implementation of uint256) ## Utils @@ -121,7 +121,7 @@ The `utils.h` file contains the **Utils** namespace - a place for generalized mi This list is only an example and does not reflect the entire contents of the file. We suggest you read the [Doxygen](https://doxygen.nl/) docs for more info about the class: * Helper functions that deal with printing (`safePrint()`, `safePrintTest()`, `printXYZ()`, etc.) -* Aliases for working with raw-byte strings (`Byte`,`Bytes`, `BytesArr`) and helper functions for converting and/or manipulating them (e.g. `appendBytes()`, `bytesToString()`, `stringToBytes()`, etc.) +* Aliases for working with raw-byte strings (`Byte`,`Bytes`, `BytesArr`) and helper functions for converting and/or manipulating them (e.g. `appendBytes()`) * For `appendBytes()` specifically, it is recommended to use it if you need a buffer, otherwise you can use `bytes::join()` as a slightly faster replacement (e.g. if you have all the data required at once, use `bytes::join()`, if you have the data scattered across different places, use a `Bytes` object as a buffer and use it with `appendBytes()`) * The `ProtocolContractAddress` map for storing addresses for deployed Protocol Contracts (e.g. `rdPoS` and `ContractManager`) * Enums for network types (`Networks`), contract function types (`FunctionTypes`) and contract types (`ContractType`) diff --git a/precompiled-contracts/creating-a-dynamic-contract-simple/simple-contract-source.md b/precompiled-contracts/creating-a-dynamic-contract-simple/simple-contract-source.md index 662e070..4a479db 100644 --- a/precompiled-contracts/creating-a-dynamic-contract-simple/simple-contract-source.md +++ b/precompiled-contracts/creating-a-dynamic-contract-simple/simple-contract-source.md @@ -56,10 +56,10 @@ SimpleContract::SimpleContract( const Address& address, const DB& db ) : DynamicContract(address, db), name_(this), number_(this), tuple_(this) { - this->name_ = Utils::bytesToString(db.get(std::string("name_"), this->getDBPrefix())); + this->name_ = StrConv::bytesToString(db.get(std::string("name_"), this->getDBPrefix())); this->number_ = UintConv::bytesToUint256(db.get(std::string("number_"), this->getDBPrefix())); this->tuple_ = std::make_tuple( - Utils::bytesToString(db.get(std::string("tuple_name"), this->getDBPrefix())), + StrConv::bytesToString(db.get(std::string("tuple_name"), this->getDBPrefix())), UintConv::bytesToUint256(db.get(std::string("tuple_number"), this->getDBPrefix())) ); @@ -76,10 +76,10 @@ SimpleContract::SimpleContract( DBBatch SimpleContract::dump() const { DBBatch dbBatch; - dbBatch.push_back(Utils::stringToBytes("name_"), Utils::stringToBytes(this->name_.get()), this->getDBPrefix()); - dbBatch.push_back(Utils::stringToBytes("number_"), UintConv::uint256ToBytes(this->number_.get()), this->getDBPrefix()); - dbBatch.push_back(Utils::stringToBytes("tuple_name"), Utils::stringToBytes(get<0>(this->tuple_)), this->getDBPrefix()); - dbBatch.push_back(Utils::stringToBytes("tuple_number"), UintConv::uint256ToBytes(get<1>(this->tuple_)), this->getDBPrefix()); + dbBatch.push_back(StrConv::stringToBytes("name_"), StrConv::stringToBytes(this->name_.get()), this->getDBPrefix()); + dbBatch.push_back(StrConv::stringToBytes("number_"), UintConv::uint256ToBytes(this->number_.get()), this->getDBPrefix()); + dbBatch.push_back(StrConv::stringToBytes("tuple_name"), StrConv::stringToBytes(get<0>(this->tuple_)), this->getDBPrefix()); + dbBatch.push_back(StrConv::stringToBytes("tuple_number"), UintConv::uint256ToBytes(get<1>(this->tuple_)), this->getDBPrefix()); return dbBatch; } ``` From 3e604f2de9f5659ec762b73aa3a9391494b819a8 Mon Sep 17 00:00:00 2001 From: Jean-Lessa <75625278+Jean-Lessa@users.noreply.github.com> Date: Thu, 28 Nov 2024 09:03:44 -0300 Subject: [PATCH 10/10] Add deps cleanext and DB compression infos --- bdk-implementation/database.md | 2 +- .../setting-up-the-development-environment.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bdk-implementation/database.md b/bdk-implementation/database.md index 589ec85..5229a30 100644 --- a/bdk-implementation/database.md +++ b/bdk-implementation/database.md @@ -8,7 +8,7 @@ BDK validators use an in-disk database for storing data about themselves and oth The database itself is an abstraction of a [Speedb](https://github.com/speedb-io/speedb) database - a simple key/value database, but handled in a different way: keys use *prefixes*, which makes it possible to batch read and write, so we can get around the "simple key/value" limitation and divide data into sectors. -The database requires a filesystem path to open it (if it already exists) or create it on the spot (if it doesn't exist) during construction. It closes itself automatically on destruction. +The database requires a filesystem path to open it (if it already exists) or create it on the spot (if it doesn't exist) during construction. It closes itself automatically on destruction. Optionally, it also accepts a bool for enabling compression (disabled by default), if needed. Content in the database is stored as raw bytes. This is due to space optimizations, as one raw byte equals two UTF-8 characters (e.g. an address like `0x1234567890123456789012345678901234567890`, ignoring the "0x" prefix, occupies 20 raw bytes - "12 34 56 ..." - , but 40 bytes if converted to a string, since each byte becomes two separate characters - "1 2 3 4 5 6 ..."). diff --git a/understanding-contracts/setting-up-the-development-environment.md b/understanding-contracts/setting-up-the-development-environment.md index 282f863..01fbd21 100644 --- a/understanding-contracts/setting-up-the-development-environment.md +++ b/understanding-contracts/setting-up-the-development-environment.md @@ -122,7 +122,7 @@ The versions of those dependencies should suffice out-of-the-box for at least th #### Tips for dependencies -There is a script called `scripts/deps.sh` which you can use to check if you have those dependencies installed (`deps.sh --check`), and install them in case you don't (`deps.sh --install`). The script expects dependencies to be installed either on `/usr` or `/usr/local`, giving preference to the latter if it finds anything there (so you can use a higher version of a dependency while still keeping your distro's default one). +There is a script called `scripts/deps.sh` which you can use to check if you have those dependencies installed (`deps.sh --check`), install them in case you don't (`deps.sh --install`), and clean up the external ones for reinstalling (`deps.sh --cleanext`). The script expects dependencies to be installed either on `/usr` or `/usr/local`, giving preference to the latter if it finds anything there (so you can use a higher version of a dependency while still keeping your distro's default one). **Please note that installing most dependencies through the script only works on APT-based distros** (Debian, Ubuntu and derivatives) - you can still check the dependencies on any distro and install the few ones labeled as "external" (those are fetched through `git`), but if you're on a distro with another package manager and/or a distro older than one of the minimum ones listed above, you're on your own.