Third-party code auditing and testing of Algorand test network: mature system and good anti-attack

Algorand's code review and testing – InCodeWeTrust team.

Posted on May 2019 by MaksKyryliuk

Algorand recently opened its TestNet to the public, along with their release of Java/JavaScript and GolangSDKs.

TestNet resources are collected on a perfect structural development network (https://developer.algorand.org) and contain everything for development purposes to run standalone nodes and set up private test networks. Although the source code has not been publicly released on the web (except for several installation script files), InCodeWeTrust has licensed access to Algorand's private code base, which is the purpose of this article.

ALGORAND Network Principles

Algorand's new agreement aims to increase speed. In theory, it is most effective to determine blocks by only one round of voting. Therefore, the amount of transactions per second should be greatly increased, and each block is guaranteed to be completed immediately.

Since the speed of no security does not provide any real value, Algorand has focused on designing network protocols to "prevent long-term network partitions and recover quickly from these partitions to solve many attacks in the real world." Network partitioning is a network-level attack (as opposed to protocol-level attacks), where an attacker targets a communication link between users, making it difficult or impossible for users to interact.

Network attacks can be performed on any decentralized system. No matter how the blockchain is designed, if the attacker is powerful enough to stop a network partition forever, then no block will be produced. The best way we can do is to increase the cost of stopping the attacker's blockchain.

In PoW, the worst case is quite bad. Two chains will be generated, one for each partition. When the segmentation heals, the smaller chains disappear. All transactions that appear in that chain will be restored. Cyber ​​attacks can be said to be very embarrassing. A skilled and powerful opponent may allow all traffic except for specific protocol information to pass undisturbed, making partition detection almost impossible.

Algorand uses the Byzantine protocol but is optimized for global scale and high performance. (Traditional BA has a maximum of 12 users, requiring participants to be pre-determined and publicized.) This is valid under more than two-thirds of the majority of honest conditions and does not depend on the participant having a synchronized clock. When honest information is passed, if the elected leader is malicious, then the worst-case delay agreement will be reached after a fixed number of steps. If the elected leader is honest, then the delay agreement will be in two After the steps are reached.

The protocol has strong resilience to network partitions of unknown length and recovers faster after partition resolution and message delay repair. The Algorand protocol makes the stalled blockchain economically expensive because of the ability to recover from the partition almost instantaneously (because the attacker needs to pay for the network frequently).

When an honest leader proposes a transaction block, the first voting step proceeds in parallel with the block propagation (ie, the network participants vote immediately after receiving the block). In fact, after the block has been propagated through all participating nodes, it is only necessary to vote for this step to generate a certificate.

To extend the consensus to more network participants, Algorand used a new mechanism based on verifiable random functions that allowed participants to privately check if they were selected to participate in the next block of the protocol, and chose for them. The certificate will also be included in the network message.

In Algorand's protocol, the user does not retain any private state other than the private key, which allows Algorand to replace the participant as soon as they send the message. This reduces the attacks against the selected participants after their identity is exposed.

Even if the attacker implements full control over the network and specifies which users receive which messages, the Algorand protocol will not fork and the user's balance will remain secure.

Algorand is designed to work efficiently and securely in a completely unlicensed environment where any number of participants can join or leave the network at any time without any review or any type of license.

Source code review

The code review below is based entirely on the Algorand private repository and is not yet open to the public. We would like to thank Algorand for providing us with access to this review as the first external party. Due to the private state of the repository, we cannot discuss the code logic in detail.

Code structure and architecture:

• Good code structure • Clear functionality • Short code • No workarounds or hackers

Code format and comments: • Fits 13-inch screens without horizontal scrolling • Comments are descriptive • No code comments, no code shards

Maintainability: • The code is self-explanatory and names the variable/function with the appropriate name • Reusability and testability are well supported

The code follows object-oriented analysis and design principles. The file is short (usually less than 300 lines) and has a focus. Development is straightforward and the code quality is high. The code follows the configurability method and saves the configurable values ​​separately, so you don't need to change the code even if the values ​​change frequently.

Extensions can be easily added with minimal changes to existing code, and the code is modular, so components can be easily replaced. From a performance perspective, all the data types used are well suited for their purpose – such as the StringBuilder generic collection class.

Public blockchain projects always require a high level of security, and we are happy to see that Algorand uses best practices to protect against security threats in authentication, authorization and data entry verification. In particular, kmd (KeyManagement Daemon Key Management Daemon), which can be run on a secure external machine, takes this project to a higher level.

The source code is organized in an organized folder with good naming and interpretation. Further view the selected file:

As shown in the example above, this type of comment often appears in the source file. It explains the logical relationship very accurately, and there is no room for misunderstanding, which makes our further pre-arrangement of logic useless. The code follows the typical opening and closing principles and the SRS (SingleResponsibility Principle). Functions and classes are well built, and dependencies are linked as packages. Another point worth mentioning is that private repositories for projects in development are often not well documented and lack readme files. But Algorand is not the case, even the private repository has excellent documentation.

It seems that the team is fully prepared for the public release of the repository. In addition, we also noticed that the repository uses docker to unify the installation process.

The project has 2,171 submissions and 142 branches and has developed very well.

In service.go, Algorand defines the service as an instance of the protocol. This code is at the heart of Algorand's work.

Again, the code has been well developed and annotated. The team also uses the TODO tag, which creates an automated ToDo-list for developers, which makes it easy for teams to manage source code development.

Installation and functional testing.

The second part of the repository check is to install the system. To this end, we used two different target platforms (OS-X and Linux) to evaluate different installation methods. We installed Algorand on MacBookPro 15 (2017), i72.8 GHz, 16GBRAM, OSX High Sierra, and Algorand on i73.2 GHz, 16GB RAM, Ubuntu 17.04 LTS. Both systems are equipped with 512GB SSD. For installation instructions, please see https://developer.algorand.org/

Node installation; System: Apple OS-X After downloading and extracting tar.gz files, install and run, and automatically alleviate problems such as missing directories; very smooth process:

:./update.sh-i -c stable -p ~/node -d ~/node/data –n ./update.sh: line102: /Users/xxx/node/algod: No such file or directory CurrentVersion = 0 Latest Version = 131084 New versionfound Update Downloaded to /var/folders/sf/t15_85yx06g29jf2ts1hpw7h0000gn/T/tmp.vhku2NPV/131084.tar.gz Expandingupdate… Validating update… Starting the new updatescript to complete the installation… ./update.sh: line 301: pushd: /Users/xxx/node/data: No such file or directory Failed toarchive logs (or none to archive) ./update.sh: line 313: popd:directory stack empty … Resuming installation from the latestupdatescript /var/ Folder/sf/t15_85yx06g29jf2ts1hpw7h0000gn/T/tmp.vhku2NPV/a/bin/update.sh:line 123: /Users/xxx/node/algod: No such file or directory CurrentVersion = 0 Stopping node… … node not running Backingup current binary Files… Backing up current data files from/Users/xxx/node/data… Installing new binary files… Installingnew data files into /Users/xxx/node/data… Checking for newledge r in /Users/xxx/node/data head:/Users/xxx/node/data/wallet-genesis.id: No such file or directory Newgenesis ID, resetting wallets New Ledger – restoring genesiswallets in /Users/xxx/node/ Data New Ledger – importingrootkeys for genesis wallets Imported 0 keys Applyingmigration fixups… Deleting existing log files in/Users/xxx/node/data Install complete – restart node manually

After configuring the telemetry, we start the node:

:./goalnode start -d data Algorand node successfully started! Wethen check if the node daemon process is really running: :pgrepalgod 61072

:./goalnode status -d data Last committed block: 299 Time sincelast block: 0.0s Sync Time: 0.0s Last consensus protocol:v2 Next consensus protocol: v2 Round for next consensusprotocol: 300 Next consensus protocol supported: true

:./carpenter-d data Watching file: data/node.log… could not decodeline from JSON: ++++++++++++++++++++++++++ ++++++++++++ could not decode line from JSON: Logging Starting could not decodeline from JSON: Telemetry Enabled:486c33a2-cb1c-44ca-ac8e-746dd8de603f:Dirks-MacBook-Pro-2 could not decode line from JSON: Session: 914dbb7b-1ff0-40fb-80c0-3da891f027f5 could not decode line fromJSON: +++++++++++++++++++++++++++++++ +++++++++ :ProposalAssembled -300.0.0| 300.0.1: StepTimeout – | :ProposalFrozen AAAAA-300.0.0| 300.0.2: StepTimeout –| 300.0.3: VoteAttest AAAAA- | 300.0.3: StepTimeout –| 300.0.4: VoteAttest AAAAA- | 300.0.4: StepTimeout –| 300.0.5: VoteAttest AAAAA- | 300.0.5: StepTimeout –| 300.0.6: VoteAttest AAAAA- | 300.0.6: StepTimeout –| 300.0. 0: RoundInterrupted – | : ProposalAssembled-301.0.0| 301.0.0: RoundInterrupted – | :ProposalAssembled -302.0.0| 302.0.0: RoundInterrupted –| …(truncated)

Node installation; System: Ubuntu 17.04

Run a private LAN testmode

Although the node attempts to run on a network that does not require a license, Algorand provides an option to create a licensed (private) network for development and testing purposes before deploying to the primary network. We first define a private network consisting of two nodes and three wallets: TestNetwork.json { "Genesis": { "NetworkName": "TestNetwork", "Wallets": [ { "Name": "Wallet1", "Stake" :50, "Online": true }, { "Name": "Wallet2", "Stake": 40, "Online": true }, { "Name": "Wallet3", "Stake": 10, "Online" : false } ] }, “Nodes”: [ { “Name”: “Primary”, “IsRelay”: true, “Wallets”: [ { “Name”: “Wallet1”, “ParticationOnly”: false } ] }, { "Name": "Node", "Wallets": [ { "Name": "Wallet2", "ParticationOnly": false }, { "Name": "Wallet3", "ParticationOnly": false } ] } ] } The above configuration file creates a network:

:./goalnetwork create -r ~/net1 -n private -t ​​./TestNetwork.json Creatednew rootkey: /Users/xxx/net1/Wallet1.rootkey Created newpartkey: /Users/xxx/net1/Wallet1.300.1000300.partkey Created newrootkey : /Users/xxx/net1/Wallet2.rootkey Created new partkey:/Users/xxx/net1/Wallet2.300.1000300.partkey Created new rootkey:/Users/xxx/net1/Wallet3.rootkey Created new partkey:/Users/xxx/ Net1/Wallet3.300.1000300.partkey Network privatecreated under /Users/xxx/net1

Then we start our network with two nodes:

:./goalnetwork start -r ~/net1 Network Started under/Users/drdirkbauer/net1

Now we need to check our network status with our nodes "Prinmary" and "Node":

:./goalnetwork status -r ~/net1 [Primary] Last committed block:308 Time since last block: 2.4s Sync Time: 0.0s Lastconsensus protocol: v4 Next consensus protocol: v4 Roundfor next consensus protocol: 309 Next consensus protocolsupported: true

[Code translation content][Node] Last submitted block: 308 Time from the previous block: 2.4s Synchronization time: 0.0s Previous consensus agreement: v4 Next consensus agreement: v4 Next round of consensus agreement: 309 Next supported consensus agreement: true

A node can be configured as a standard node or a relay node. Standard nodes have two modes: archive mode and non-archive mode. The archived version will store the complete blockchain on the system, and the non-archive version only needs the information needed to run the node. The relay node will connect to TestNet and always store the complete blockchain on the system. Let's check which wallet is already associated with our "Primary" node:

:./goalwallet list -d ~/net1/Primary

#

Wallet:unencrypted-default-wallet ID: 04df26305aa1337dcf6e787622b78cce

#

As expected, there is only one wallet based on the configuration originally provided for the network. We try to create another wallet for this node:

:./goalwallet new MyWallet -d ~/net1/Primary Please choose a passwordfor wallet 'MyWallet': Please confirm thepassword: Creating wallet… Created wallet'MyWallet' Your new wallet has a backup phrase that can beused for recovery. Keeping this backup Phrase safe is extremelyimportant. Would you like to see it now? (Y/n): Y Yourbackup phrase is printed below. Keep this information safe —never share it with anyone! patient stand liar plunge hidden….(truncated seed phrase)

Code pure translation [:./goalwallet new MyWallet -d~/net1/Primary

Please select a "MyWallet" password: Please confirm the password: Create a wallet… Create a wallet 'MyWallet' Your new wallet has a backup available for recovery. It is very important to ensure the security of this backup. Do you want to see it now? (Y/n): Y Your backup is as follows. Keep this information safe – don't share it with anyone! Patientstand liar plunge hidden ….(truncated seed phrase)

We set the new wallet for this node to the default value:

:./goalwallet -f MyWallet -d ~/net1/Primary And create two addressesfor the new default wallet :./goal account new -d~/net1/Primary Created new account with addressESIVU7EFBABFHE4ZGAYHYENRORD7DCN34JAHHVF5NJP3HDA6O6WTN35SXY :./goal account new -d ~/ Net1/Primary Created new account withaddress RZTAVIJEF7XNNDWUAMORBTLKVHGOA4WCJV7VRYR2XJ4RO23LZ5IWQQREO4

We continue to create a transaction between the two addresses of this wallet:

:./goalclerk send -s -o ./raw.tx -a 100 -fESIVU7EFBABFHE4ZGAYHYENRORD7DCN34JAHHVF5NJP3HDA6O6WTN35SXY -tRZTAVIJEF7XNNDWUAMORBTLKVHGOA4WCJV7VRYR2XJ4RO23LZ5IWQQREO4 -d~/net1/Primary Please enter the password for wallet 'MyWallet':…

We check if the transaction is successful:

:curl-s -X POST –> As expected, the deal was unsuccessful because we have never funded this wallet. Finally, we terminated the execution of the private network in these two node types for more than 48 hours without any stability issues:

:./goalnetwork stop -r ~/net1 The network stopped at /Users/drdirkbauer/net1 before stopping. We also tried the rest of GoalCLI's command set without any problems. Everything is done according to specifications. It is also worth mentioning that we are impressed with the consistency of the various target commands in terms of options/parameters. Even in Linux, people are often forced to use a specific order of inconsistent options in Linux. Algorand's impression is a very solid and mature system that gives us a very lean experience.

RestAPI RestAPI can be used on algod (Algorand protocol daemon) or kmd (key management daemon). The algod process starts automatically when the node starts. The kmd process needs to be mobilized by Goal. It is primarily used for key management and transaction signing and can be run on a separate machine (improving security). It is a good concept to support key business processes. We tried RestAPI by signing a deal and it worked exactly as expected.

SDK Algorand provides SDKs for three major development languages ​​Go, JS (node.js) and Java. GoSDK (which we used in the past) is available on AlgorandGitHub. The SDK can fight against kmd and algod (see RestAPI). We installed GOSDK from GitHub and tested it (provided that the GO language library was installed).

:go get -u github.com/algorand/go-algorand-sdk/… Then we startour node and key management daemon again: :./goal node start -d~/algorand/TestNet/data/relay Algorand node successfullystarted!

:./goalkmd start -d ./data/relay Successfully started kmd

in conclusion

Algorand has previously introduced several key components for the blockchain ecosystem and is now widely adopted. It has further improved the blockchain technology by introducing a recovery mechanism for network partitioning attacks, allowing the opponent to interrupt the network at any time. It became very high.

Algorand was impressed with the test experience, showing even fewer glitch than software from global vendors such as Apple and Microsoft (we have experience in everyday customer projects).

(InCodeWeTrust team)