Git Product home page Git Product logo

spacemeshos / go-spacemesh Goto Github PK

View Code? Open in Web Editor NEW
747.0 44.0 211.0 137.81 MB

Go Implementation of the Spacemesh protocol full node. 💾⏰💪

Home Page: https://spacemesh.io

License: MIT License

Go 99.49% Makefile 0.25% Dockerfile 0.09% Pascal 0.15% Shell 0.02%
golang p2p blockchain consensus cryptocurrencies proof-of-work proof-of-space proof-of-space-time decentralization go blockmesh dag spacemesh

go-spacemesh's Introduction

license release platform go version open help wanted issues discord made by Go Report Card Bors enabled godoc CI: passing

go-spacemesh

💾⏰💪

Thanks for your interest in this open source project. This repo is the go implementation of the Spacemesh p2p full node software.

Spacemesh is a decentralized blockchain computer using a new race-free consensus protocol that doesn't involve energy-wasteful proof of work.

We aim to create a secure and scalable decentralized computer formed by a large number of desktop PCs at home.

We are designing and coding a modern blockchain platform from the ground up for scale, security and speed based on the learnings of the achievements and mistakes of previous projects in this space.

To learn more about Spacemesh head over to https://spacemesh.io.

To learn more about the Spacemesh protocol watch this video.

Motivation

Spacemesh is designed to create a decentralized blockchain smart contracts computer and a cryptocurrency that is formed by connecting the home PCs of people from around the world into one virtual computer without incurring massive energy waste and mining pools issues that are inherent in other blockchain computers, and provide a provably-secure and incentive-compatible smart contracts execution environment.

Spacemesh is designed to be ASIC-resistant and in a way that doesn’t give an unfair advantage to rich parties who can afford setting up dedicated computers on the network. We achieve this by using a novel consensus protocol and optimize the software to be most effectively be used on home PCs that are also used for interactive apps.

What is this good for?

Provide dapp and app developers with a robust way to add value exchange and other value related features to their apps at scale. Our goal is to create a truly decentralized cryptocurrency that fulfills the original vision behind bitcoin to become a secure trustless store of value as well as a transactional currency with extremely low transaction fees.

Target Users

go-spacemesh is designed to be installed and operated on users' home PCs to form one decentralized computer. It is going to be distributed in the Spacemesh App but people can also build and run it from source code.

Project Status

We are working hard towards our first major milestone - a public permissionless testnet running the Spacemesh consensus protocol.

Contributing

Thank you for considering to contribute to the go-spacemesh open source project!

We welcome contributions large and small and we actively accept contributions.

Diggin' Deeper

Please read the Spacemesh full FAQ.

go-spacemesh Architecture

Architecture

Getting

git clone [email protected]:spacemeshos/go-spacemesh.git

or fork the project from https://github.com/spacemeshos/go-spacemesh

Since the project uses Go Modules it is best to place the code outside your $GOPATH. Read this for alternatives.

Setting Up Local Dev Environment

Building is supported on:

  • Linux, GLIBC 2.34+ is required
  • MacOS 13 (Intel) and MacOS 14 (Arm) and newer
  • Windows 10 and newer

FreeBSD is not officially supported.

Install Go 1.22 or later for your platform, if you haven't already.

On Windows you need to install make via msys2, MingGW-w64 or mingw.

Ensure that $GOPATH is set correctly and that the $GOPATH/bin directory appears in $PATH.

Before building we need to set up the golang environment. Do this by running:

make install

Make sure the environment is set up correctly:

make go-env-test

CGO_CFLAGS must be set to "-I<absolute_path_to_repo>/go-spacemesh/build/ -DSQLITE_ENABLE_DBSTAT_VTAB=1" CGO_LDFLAGS must be set to "-L<absolute_path_to_repo>/go-spacemesh/build/ -Wl,-rpath,$ORIGIN -Wl,-rpath,<absolute_path_to_repo>/go-spacemesh/build/"

Make sure you have OpenCL library installed

To check if setup was configured successfully, try to run:

make test

There shouldn't be any build errors, but please note that running the tests will take some time.

How to run standalone node?

After you got a binary standalone fully functional network can be launched with a simple command:

./build/go-spacemesh --preset=standalone --genesis-time=2023-06-08T5:30:00.000Z

Network will use short epochs (1 minute), and 10 layers within the epoch (each 6s). Poet is launched in the same process in this mode. So expect that it will periodically hog 1 core. Minimal smeshing is enabled in order for consensus to work.

Public GRPC API are launched on 0.0.0.0:9092. Private - 0.0.0.0:9093.

Building

To build go-spacemesh for your current system architecture, from the project root directory, use:

make build

(On FreeBSD, you should instead use gmake build. You can install gmake with pkg install gmake if it isn't already installed.)

This will build the go-spacemesh binary, saving it in the build/ directory.

On linux or mac you can build a binary for windows using:

make windows

Be aware that this will require a cross-platform gcc like x86_64-w64-mingw32-gcc. Platform-specific binaries are saved to the build/*target* directory.

Using go build and go test without make

To build or test code without using make some golang environment variables must be set appropriately.

The environment variables can be printed by running either make print-env or make print-test-env.

They can be set in 3 ways:

Note: we need to use eval to interpret the commands since there are spaces in the values of the variables so the shell can't correctly split them as arguments.

  1. Setting the variables on the same line as the go command (e.g., eval $(make print-env) go build ./...). This affects the environment for that command invocation only.
  2. Exporting the variables in the shell's environment (e.g., eval export $(make print-env)). The variables will persist for the duration of that shell (and will be passed to subshells).
  3. Setting the variables in the go environment (e.g., eval go env -w $(make print-env)). Persistently adds these values to Go's environment for any future runs.

Running

Note: go-spacemesh relies on a gpu setup dynamic library in order to run. make install puts this file in the build folder, so if you are running spacemesh from the build folder you don't need to take any extra action. However if you have built the binary using go build or moved the binary from the build folder you need to ensure that you have the gpu setup dynamic library (the exact name will vary based on your OS) accessible by the go-spacemesh binary. The simplest way to do this is just copy the library file to be in the same directory as the go-spacemesh binary. Alternatively you can modify your system's library search paths (e.g. LD_LIBRARY_PATH) to ensure that the library is found.

go-spacemesh is p2p software which is designed to form a decentralized network by connecting to other instances of go-spacemesh running on remote computers.

To run go-spacemesh you need to specify the parameters shared between all instances on a specific network.

You specify these parameters by providing go-spacemesh with a json config file. Other CLI flags control local node behavior and override default values.

Joining a Testnet (without mining)

  1. Build go-spacemesh from source code.

  2. Download the testnet's json config file. Make sure your local config file suffix is .json.

  3. Start go-spacemesh with the following arguments:

    ./go-spacemesh --listen [a_multiaddr] --config [configFileLocation] -d [nodeDataFilesPath]

    Example:

    Assuming tn1.json is a testnet config file saved in the same directory as go-spacemesh, use the following command to join the testnet. The data folder will be created in the same directory as go-spacemesh. The node will use TCP port 7513 and UDP port 7513 for p2p connections:

    ./go-spacemesh --listen /ip4/0.0.0.0/tcp/7513 --config ./tn1.json -d ./sm_data
  4. Build the CLI Wallet from source code and run it:

  5. Use the CLI Wallet commands to setup accounts, start smeshing and execute transactions.

./cli_wallet

Joining a Testnet (with mining)

  1. Run go-spacemesh to join a testnet without mining (see above).

  2. Run the CLI Wallet to create a coinbase account. Save your coinbase account public address - you'll need it later.

  3. Stop go-spacemesh and start it with the following params:

    ./go-spacemesh --listen [a_multiaddr] --config [configFileLocation] -d [nodeDataFilesPath] \
        --smeshing-coinbase [coinbase_account] \
        --smeshing-start --smeshing-opts-datadir [dir_for_post_data]

    Example:

    ./go-spacemesh --listen /ip4/0.0.0.0/tcp/7513 --config ./tn1.json -d ./sm_data \
        --smeshing-coinbase stest1qqqqqqp3qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqql50dsa \
        --smeshing-start --smeshing-opts-datadir ./post_data
  4. Use the CLI wallet to check your coinbase account balance and to transact


Smeshing

To be able to initialize your PoST using your Graphics card you will need to install the tools necessary to enable OpenCL support on your system. The exact steps to do this will vary based on your OS and GPU. In general you will need to install the OpenCL runtime for your GPU and ICD loader.

A good starting point to get more info is https://wiki.archlinux.org/title/GPGPU.

If your system doesn't have a GPU or you can use a generic runtime instead. Be aware that we do not recommend this for initialization of PoST. On Ubuntu you need to install the following packages:

apt-get update
apt-get install libpocl2

on Windows you can use Intel OpenAPI:

choco install opencl-intel-cpu-runtime

Using a remote machine as provider for PoST proofs

To disable the internal PoST service and disable smeshing on your node you can use the following config:

"smeshing": {
    "smeshing-start": false,
}

or use the --smeshing-start=false flag. Additionally rename the local.key in your data/identities folder to a unique name for your node (e.g. nodeA.key). This will disable smeshing on your node causing, i.e. it will not generate any PoST proofs until a remote post service connects. Be aware that you still need to set your coinbase via

"smeshing": {
    "smeshing-coinbase": "your coinbase address",
}

or use the --smeshing-coinbase CLI parameter, otherwise your node will not be able to receive rewards.

Additionally you will have to set grpc-post-listener to e.g. 0.0.0.0:9094 in your api config to allow the remote post service to connect to your node.

Merging multiple existing nodes into a single one with multiple remote PoST services

To help in the process of merging multiple nodes into a single one, you can use merge-nodes tool. This tool will copy over identities and merge their local states into a single node. Ensure that all nodes are running the latest version of go-spacemesh and were started at least once after upgrading. We recommend to back up the data directory of the nodes you want to merge before running this tool to avoid data loss. Specifically the local.sql files and the identities directories.

Stop the two nodes you want to merge and ensure that they have been set up for remote smeshing (i.e. smeshing-start is false and local.key has been renamed). src is the node that will be merged into dst:

merge-nodes --src /path/to/src/data --dst /path/to/dst/data

This will copy over the identities from src to dst and merge the local states of both nodes. The command will tell you if it encounters any issues merging the identities or the local states.

You can repeat this process with as many nodes as you want to merge into dst. After you have completed the merging process, you can start dst. For every identity setup a post service to use the existing PoST data for that identity and connect to the node. For details refer to the post-service README.

Using a remote PoST service over insecure connections

If you want to allow connections from post services over the internet to your node, we strongly recommend not to connect via grpc-post-listener but rather use the grpc-tls-listener configuration parameter and setup TLS for the connection.

This is useful for example if you want to run a node on a cloud provider with fewer resources and run PoST on a local machine with more resources. The post service only needs to be online for the initial proof (i.e. when joining the network for the first time) and during the cyclegap in every epoch.

To setup TLS-secured public connections the API config has been extended with the following options:

"api": {
  "grpc-tls-listener": "0.0.0.0:9094",           // listen address for TLS connections
  "grpc-tls-ca-cert": "/path/to/ca.pem",         // CA certificate that signed the node's and the PoST service's certificates
  "grpc-tls-cert": "/path/to/cert.pem",          // certificate for the node
  "grpc-tls-key": "/path/to/key.pem",            // private key for the node
}

Ensure that remote PoST services are setup to connect to your node via TLS, that they trust your node's certificate and use a certificate that is signed by the same CA as your node's certificate.

Configuring a remote PoST service

The post service is at the moment configured exclusively via command line parameters:

  • --dir specifies the directory containing postdata_metadata.json and the postdata_xxx.bin files; other files in the post directory need to stay with the node!
  • --address specifies the address the post service should connect to
  • --ca-cert, --cert and --key specify the location of the CA certificate, the post services certificate and the post services key respectively. For more information see below.
  • --threads, --nonces and --randomx-mode can be adapted to optimize proof generation. They are analogous to smeshing-opts-proving-threads, smeshing-opts-proving-nonces and smeshing-opts-proving-randomx-mode respectively.
  • -h or --help prints a help message with all available options and more details on their usage.

Keys and certificates

The PoST service and the node talk to each other via mTLS and have to authenticate themselves at the opposite end. For this both need keys and certificates.

Here is a script that generates a key & certificate for a CA, a key for the client (PoST service) and a key for the server (node). Then it uses the CAs key to generate certificates from the keys for both the client & server.

Make sure to adjust the certificate extensions & subjects for your setup accordingly.

ca.crt needs to be provided to both the PoST service and the node, server.crt & server.key are only needed by the node and client.crt & client.key are only needed by the PoST service.

# create certificate extensions to allow using them for localhost
cat > server-domains.ext <<EOF
[v3_req]
subjectAltName = @alt_names

[alt_names]
DNS.1 = node
IP.1 = 127.0.0.1
EOF

cat > client-domains.ext <<EOF
[v3_req]
subjectAltName = @alt_names

[alt_names]
DNS.1 = post
EOF

# create CA private key and certificate
openssl req -x509 -newkey rsa:4096 -days 365 -nodes -keyout ca.key -out ca.crt \
    -subj "/C=EN/ST=Spacemesh/L=Tel Aviv/O=Spacemesh/CN=spacemesh.io/[email protected]"

# create server private key and CSR
openssl req -newkey rsa:4096 -nodes -keyout server.key -out server-req.pem \
    -subj "/C=EN/ST=Spacemesh/L=Tel Aviv/O=Server/CN=server.spacemesh.io/[email protected]"

# use CA private key to sign ser CRS and get back the signed certificate
openssl x509 -req -in server-req.pem -days 60 -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt \
    -extfile server-domains.ext -extensions v3_req
rm server-req.pem

# create client private key and CSR
openssl req -newkey rsa:4096 -nodes -keyout client.key -out client-req.pem \
    -subj "/C=EN/ST=Spacemesh/L=Tel Aviv/O=Client/CN=client.spacemesh.io/[email protected]" \

# use CA private key to sign client CSR and get back the signed certificate
openssl x509 -req -in client-req.pem -days 60 -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt \
    -extfile client-domains.ext -extensions v3_req
rm client-req.pem

Testing

NOTE: if tests are hanging try running ulimit -n 400. some tests require that to work.

TEST_LOG_LEVEL="" make test

The optional TEST_LOG_LEVEL environment variable can be set to change the log level during test execution. If not set, tests won't print any logs. Valid values are the error levels of zapcore

For code coverage you can run:

make cover

This will start a local web service and open your browser to render a coverage report. If you just want to generate a cover profile you can run:

make cover-profile

The generated file will be saved to ./cover.out. It can be loaded into your editor or IDE to view which code paths are covered by tests and which not.

Continuous Integration

We've enabled continuous integration on this repository in GitHub. You can see more details about our CI workflows on the Actions tab.

Docker

A Dockerfile is included in the project allowing anyone to build and run a docker image:

docker build -t spacemesh .
docker run -d --name=spacemesh spacemesh

Windows

On Windows you will need the following prerequisites:

  • Powershell - included by in Windows by default since Windows 7 and Windows Server 2008 R2
  • Git for Windows - after installation remove C:\Program Files\Git\bin from System PATH (if present) and add C:\Program Files\Git\cmd to System PATH (if not already present)
  • Make - after installation add C:\Program Files (x86)\GnuWin32\bin to System PATH
  • Golang
  • GCC. There are several ways to install gcc on Windows, including Cygwin. Instead, we recommend tdm-gcc which we've tested.

Close and reopen powershell to load the new PATH. You can then run the command make install followed by make build as on UNIX-based systems.

Running a Local Testnet

  • You can run a local Spacemesh Testnet with 6 full nodes, 6 user accounts, and 1 POET support service on your computer using docker.
  • The local testnet full nodes are built from this repo.
  • This is a great way to get a feel for the protocol and the platform and to start hacking on Spacemesh.
  • Follow the steps in our Local Testnet Guide

Improved decentralization and P2P diagnostic features

WARNING! THIS IS EXPERIMENTAL FUNCTIONALITY, USE WITH CARE!

In order to make the p2p network more decentralized, the following options are provided:

  • "enable-routing-discovery": true: enables routing discovery for finding new peers, including those behind NAT, ans also for discovering relay nodes which are used for NAT hole punching. Note that hole punching can be done when both ends of the connection are behind an endpoint-independent ("cone") NAT.
  • "routing-discovery-advertise": true advertises this node for discovery by other peers, even if it is behind NAT.
  • "enable-quic-transport": true: enables QUIC transport which, together with TCP transport, heightens the changes of successful NAT hole punching.
  • "enable-tcp-transport": false disables TCP transport. This option is intended to be used for debugging purposes only!
  • "static-relays": ["/dns4/relay.example.com/udp/5000/quic-v1/p2p/...", ...] provides a static list of relay nodes for use for NAT hole punching in case of routing discovery based relay search is not to be used.
  • "ping-peers": ["p2p_id_1", "p2p_id_2", ...] runs P2P ping against the specified peers, logging the results.

For the purpose of debugging P2P connectivity issues, the following command can also be used:

$ grpcurl -plaintext 127.0.0.1:9093 spacemesh.v1.DebugService.NetworkInfo
{
  "id": "12D3Koo...",
  "listenAddresses": [
    "/ip4/0.0.0.0/tcp/50212",
    "/ip4/0.0.0.0/udp/59458/quic-v1",
    "/p2p-circuit"
  ],
  "knownAddresses": [
    "/ip4/127.0.0.1/tcp/50212",
    "/ip4/127.0.0.1/udp/59458/quic-v1",
    "/ip4/192.168.33.5/tcp/50212",
    "/ip4/192.168.33.5/udp/59458/quic-v1",
    "/ip4/.../tcp/37670/p2p/12D3Koo.../p2p-circuit",
    "/ip4/.../udp/37659/quic-v1/p2p/12D3Koo.../p2p-circuit",
    "/ip4/.../tcp/31960/p2p/12D3Koo.../p2p-circuit",
    "/ip4/.../udp/33377/quic-v1/p2p/12D3Koo.../p2p-circuit"
  ],
  "natTypeUdp": "Cone",
  "natTypeTcp": "Cone",
  "reachability": "Private"
}

Next Steps

Got Questions?

go-spacemesh's People

Contributors

abergasov avatar acud avatar almogdepaz avatar amitshaul avatar andres-spacemesh avatar antonlerner avatar avive avatar beckmani avatar countvonzero avatar dependabot[bot] avatar dshulyak avatar evt avatar fasmat avatar gavraz avatar ivan4th avatar jankei avatar kacpersaw avatar kare avatar lrettig avatar moshababo avatar narayanprusty avatar nkryuchkov avatar noamnelke avatar piersy avatar pigmej avatar poszu avatar sidsankhe avatar valar999 avatar y0sher avatar zalmen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-spacemesh's Issues

Replace inhouse 'assert' with 'testify'

testify is a widely used testing set of packages that exposes an API similar to what we have at assert and more.

I think we shouldn't maintain our own assertion lib as long we don't have any special testing needs.

to complete this issue -

  • Remove assert package from go-spacemesh
  • import add testify to our vendor list.
  • replace usages by assert across our testing files if needed.

chore: swarm config params

Feature description

Make all swarm config values command-line and config-file modifiable. Look at SwarmConfigValues - right now the values are hard-coded.

Reasons for adding this feature

This feature will allow us to more easily test swarm features.

Accounts

Support keystore and accounts infra

Add macOS deployment and testing to travis

Feature description

Add osx support to our travis ci

Main Reason for adding this feature

We must be sure that go-spacemesh works on all operating systems at ci level.

NOTE : please contact me on gitter if any travis credentials are needed.

Config bugs filesystem, solution: Pass config structs instead of using hardcoded values

Expected behavior

Every constructor that requires config information will receive a config struct by parameter.

Edit: Labeled as a bug because it messes up filesystem location in tests.
We've setup filesystem helpers that should help create a dedicated folders for tests and be removed afterwards, though the use of a global config messes this up. we resulted in limiting parallel testing to make this have less impact on us while developing. Making filesystem work for a specific configuration will probably solve it.

Actual behavior

In some places like p2pand api we use hardcoded values from ConfigValues initialized structs.

We moved to using cobra in #135 , this is what's left to make CLI and config loading more tied to good practices.

Make tests work in parallel

go test ./... runs packages tests in parallel, we had several conflicts in config and filesystem when using this approach.
We have lately (#133) changed tests (locally and in ci) to run sequentially even package-wide.

though to keep testing as fast as possible and to follow golang good practices we want to be able to to isolate tests and run them in parallel.

build fails due to go fmt issues

Expected behavior

validate-gofmt.sh to not return any error.

Actual behavior

go fmt fails due to what looks like a vendor issue. However, the script is supposed to skip all vendored packages.

Steps to reproduce the actual behavior

$ ./ci/validate-gofmt.sh

Result:
vendor/golang.org/x/net/context/go19.go:15:14: expected type, found '='
vendor/golang.org/x/net/context/go19.go:20:17: expected type, found '='
validate-gofmt.sh: error vendor/gopkg.in/natefinch/lumberjack.v2/lumberjack.go

Also see: https://travis-ci.org/spacemeshos/go-spacemesh/jobs/333154598

Add network id to account and node store

Feature description

Add network id to the account and node persisted data.
localnodestore.go should be expanded to save to node's NetworkId for future loads.
check NodeData struct and persistData func

in accounts/store.go should have pretty much the same. (though its not the same networkID param)
check AccountData struct and Persist func

Main Reason for adding this feature

For nodes it is necessary to load the node's network id when starting from a persisted node for users to be able to easily stop and restart nodes.

For accounts, this will help mitigate attempts to use an account on the wrong network id which can be quite confusing to the user and introduce some nasty bugs. The account data in local store is supposed to be used with an account that was created on-chain. There's not much use to an account that is not associated with a specific network id.

NTP support

Implement NTP client with time-drift detection (SNTP protocol).
Kill node that is on a system with a wall clock too far apart from the ref time on startup.

Peer connectivity latency metrics

Add peers connection latency metrics per peer and use them in routing table ops. e.g. drop from table peers with very high latency.

Coinbase account support

Fully support a notion of a coinbase account:

  • A coinbase account is the account that gets block validation awards
  • When a new account is created - if it is only account - set it as coinbase on the running node
  • Restore node's coinbase account when loading node from storage

Distinct node log colors

Feature description

We added node console coloring in log/log.go .
this happens by generating RGB colors and adding the needed console literals to the names of newly created node loggers.
We want to make sure colors will be distinguishable and distinct from the previous selected colors.

Main Reason for adding this feature

This is needed for debugging and logging purposes, when reading logs of multiple nodes executions we want to be able to tell easily which node outputed the log line.
We're getting some similar colors right now. (different shades of the same color).

Check the code in log/log.go createRandomColor. and ask any questions here if needed.

NOTE : If converting to using another color scheme (e.g : HSL.. ) is needed please discuss here or in PR.

Add network id and client version to handshake

Feature description

The handshake message should include Network ID and client version.
Add params to the handshake protocol :

  • networkID
  • clientVersion
  • timestamp

you can find the message now in : p2p/pb/message.proto

message HandshakeData { .. .... add params here

you should add a const for NetworkID 's
MainNet = 1 TestNet = 2
for now we'll default to 2. (TestNet)

we already store clientVersion.

timestamp should be the time where the message was sent.

On the handshake stage if the local node recognizes that the incoming handshake of remote node networkID and/or clientVersion are different it should drop it that node from our routing table (if its there) and drop the message.

Local node network id should be set as a node config param at startup and save for future use of that node.

Main Reason for adding this feature

We want to distinguish between nodes in different networks (main net, testnets) or versions easily and as fast as we can so they won't communicate with each other beyond handshake.
This will ease on developers playing with the spacemesh client and make sure development will stay in its on network.
Testnet will be the default network for now.

Graceful shutdown of json-http api server

Expected behavior

Properly shut-down json-http api server

Actual behavior

Calling server.Shutdown() panics

Steps to reproduce the actual behavior

  • Uncomment s.server.Shutdown(s.ctx) in JsonHttpServer.Stop()
  • Run api_test.go

Refactor P2P package

Feature description

  • a robust directory and package structure for the p2p package.
  • decide about concurrency patterns and guidelines to our project.
  • enforce golang and software practices we want to adopt.

Main Reason for adding this feature

Currently stuff are pretty much all over. the main p2p package has all the protocols and protocols tests, the swarm, local node and some other stuff.
Sooner (hopefully) or later we're gonna populate our code with the consensus protocols, metrics and more.
So everything should be organized in the best golang-way we can.
also remember tests.

Research REPL library

Feature description

Recommend GO REPL library for use in this project.

Main Reason for adding this feature

We need to decide which GO REPL library to use for implement the Spacemesh REPL.

To clarify, we do not need a REPL that allows interactive GO programming but rather a REPL that allows the user to interactively interact with the node using commands we define ourselves (see REPL wiki for more info). REPL may be a misleading name - perhaps an interactive shell app is more appropriate as most GO REPLs are designed to parse GOlang source code.

Evaluation criteria
  1. Must be open source with MIT license
  2. Flexibility and robustness (color, command completion, etc...)
  3. Number of serious open issues that are not being fixed quickly. e.g. more than few weeks old.
  4. Major other GO apps that use the library
  5. Number of library dependencies
  6. Library binary size - the smaller the better
  7. Users sentiment about the library - github comments, blog posts, etc...
  8. Experience using it in another project.
  9. Experiment and build a simple GO app with a REPL using the library - the best way to evaluate a library is to try to build something simple with it.
  10. Documentation - are the maintainer helpful to use questions in issues? Is the library well documented?

Add peers protocol matching mechanism

Feature description

When a session is established between two nodes they should be able to know which protocols each node is supporting right after handshake.
If there's no matching protocols drop that node for now.

Main Reason for adding this feature

The other scenario is trying to communicate with a node, then getting unsupported protocol msg, then trying other protocol or query protocols.
this can be saved and be easier with that feature.

DHT tests fail randomly

Expected behavior

All table callbacks finishing.

Actual behavior

Some times the last callback won't get to the channel and we'll have timeout with 99 callbacks (instead of 100).

--- FAIL: TestTableCallbacks (10.02s)
	table_test.go:46: Failed to get expected update callbacks on time
<APP> INFO 001 17:51:04.974 table.onFindReq ▶ Found <RN Id: hJ5yyQ8z. Ip:0.0.0.0:46888 DhtId: ed11f87a> in the routing table
<APP> INFO 002 17:51:04.974 table.onFindReq ▶ Found <RN Id: 2AYz8hcm. Ip:0.0.0.0:37923 DhtId: ca7a2960> in the routing table
<APP> INFO 003 17:51:04.974 table.onFindReq ▶ Found <RN Id: fJQMsQxE. Ip:0.0.0.0:10223 DhtId: 2619f675> in the routing table
<APP> INFO 004 17:51:04.974 table.onFindReq ▶ Found <RN Id: 22tsefyG. Ip:0.0.0.0:6092 DhtId: 6f7c31d3> in the routing table
<APP> INFO 005 17:51:04.974 table.onFindReq ▶ Found <RN Id: o9H8ZRK8. Ip:0.0.0.0:38269 DhtId: 22253ce1> in the routing table
FAIL
FAIL	github.com/spacemeshos/go-spacemesh/p2p/dht/table/tests	10.614s

Steps to reproduce the actual behavior

just run the test a lot of times until you get it.

Implement reliable and robust (event) monitoring/logging system

I realized developing Spacemesh requires constant debugging of asynchronous and concurrent operations involving multiple peers communications.

To keep track of all of that, we must establish a reliable and robust monitoring/logging flow that'll be able to distinguish between different operations, operation types and their stages.

The current logging system has multiple logging outputs (file, console) which is useful and we should keep that, but the log output isn't consistent enough to track all actions correctly.

This kind of reliable logging system will be a corner stone for out development and in the future for showcasing the project in action. (ex: using logging to update simulations)

This is open to discussion. I'll post more libs or methods as I do more research.

WIP - Finish Gossip protocol features

  • Support protools gossip flag. When set, forward incoming message to all randomly selected connected peers. We might need to change this to only up to 2 or 5 randomly connected peers based on further testing.
  • Write comprehensive tests for gossip scenarios.

Make all comments show up good on godoc.

Feature description

Make all comments show up good on godoc.
Some comments are missing some just don't show up well on godoc

Main Reason for adding this feature

GoDoc is an awesome tool and we can leverage it to have our code fully documented online.

Switch from urfave/cli to cobra

Feature description

switch using urfave/cli to cobra.
It seems that by repo statics they're quite the same though cobra has some really nice projects using it.

Verify that Cobra supports these cli features that we need

  • flags
  • bind flags to variables ( default values )
  • commands
  • help
  • autocomplete
  • config file parsing (toml/yaml or other)

Main Reason for adding this feature

Some bugs with urfave/cli (loading config files), flexibility offered by cobra seems to attract great noticeable projects.

Implement Ping/Pong Protocol

Feature description

When using Update on a node in our routing table, it should check the right bucket for it and add it if that bucket has enough space for it.
If this bucket is full then the least recent node in this bucket and if it fails to answer replace it with the new one.
check p2p/dht/table/table.go - func update(node Node) there's a todo there.

We would like to implement a new and lighter ping protocol just for dht nodes

Main Reason for adding this feature

Kademlia- KBuckets way of keeping a healthy node is always keeping the live most recent nodes at the top of the bucket.

Spacemesh White Paper 1

Feature description

Finish and publish WP 1

Main Reason for adding this feature

Fully articulate out project goals and our proposed solutions.

Merkle Patricia tree features

Implement optimized Merkle Patricia tree data structure with backing storage in leveldb (kv store). Implement Merkle proofs. Write comprehensive tests.

Set appropriate log levels for production/tests.

Expected behavior

We want console's stdout to show only really important informative messages, warnings and errors.
The rest of the message should be considered as Debug messages. written to log file but not shown in console unless running a test or declared as a flag beforehand.

limit the logging lib with log.SetLevel(logging.INFO) on either a test or a flag, change console log messages that are not critical for the user to see to .Debug instead Info/Warning.

Actual behavior

All messages are output to the console all the time.

Steps to reproduce the actual behavior

run any instance or test of the spacemesh.

Add sha3-256 tests with published test vectors

Unless there is some subtly here that I am missing, the sha256 function is returning incorrect data

I haven't looked for known bugs in golang.org/x/crypto/sha3 yet

Expected behavior

sha256 value input ABCDEFGHIJKL
output expected (as hexdigest) 922429ccdb7045d11143e2e3982a11afc11b537bf259d88d2425fa8806e86e78

Actual behavior

digest is d99428764cc43a2ff5c1ac4db1e5da826a97dae5530e268650318adb2e2e246f

Steps to reproduce the actual behavior

I am using the following sha3_test.go running in the crypto directory

package crypto

import (
"encoding/hex"
"fmt"
"github.com/spacemeshos/go-spacemesh/assert"
"testing"
)

func TestSha256(t *testing.T) {
// biggest vs smallest
data := []byte("ABCDEFGHIJKL")
sha256hex := "922429ccdb7045d11143e2e3982a11afc11b537bf259d88d2425fa8806e86e78"
shaOfData, err := hex.DecodeString(sha256hex)
assert.Nil(t, err, fmt.Sprintf("hex.DecodeString: this should not happen"))
try := Sha256(data)
t.Errorf("%v", try)
t.Errorf("%v", shaOfData)
assert.Equal(t, fmt.Sprintf("%v", try), fmt.Sprintf("%v", shaOfData), fmt.Sprintf("sha256 should be %s but is %s", sha256hex, hex.EncodeToString(try)))
}

P2P Simulation and visualization framework

Feature description

P2P isn't easy nor simple, we want to be able to run our p2p suite tests and simulate a network from a single running binary.
Another component of the simulation framework is visualizing all the p2p operations using an animated visualization library.
The options I see are using logged text and the file system as event triggers, or adding some kind of event tracking to the code.
spawning a webserver with client-side animated canvas looks like a goto solution since go doesn't really have any mature animation or network simulation libs.
Further discussion and research will be added to this issue, please feel free to contribute.

links :

Main Reason for adding this feature

Debugging and testing P2P networks is hard, visualization can help get a hold of what's happening in the network, also it'll help explain our stack to new developers.

fix make cover

Expected behavior

make cover to properly generate test coverage html page

Actual behavior

$ make cover

Check for cover :

go test ./ -coverprofile=cover.out -covermode=count; go tool cover -html=cover.out
? github.com/spacemeshos/go-spacemesh [no test files]
cover: open cover.out: no such file or directory
make: *** [cover] Error 1

Steps to reproduce the actual behavior

Run make cover from the project root directory

Readme file for filesystem package

Feature description

Readme file for filesystem package with a description of the purpose and uses of the package

Main Reason for adding this feature

For an introduction and quick code entry for new developers

Standardize bootstrapping, DHT and node discovery

Validate DHT and node discovery code architecture, including:

  • Create a design document which describes the HL modules and the different code flows.
  • Modify the code according to the updated design.
  • List all open issues.
  • Handle all major TODOs and open issues.

Definition of success:

  • Design document published on the project's wiki
  • All committed code is complied with the design
  • No open issues nor major TODOs

Add app config file support

Implement support for app configuration via a config file, and write tests for app configs using a file.
Choose TOML or YAML as file format and integrate with cli1.v1

Finish node discovery features

  • Comprehensive tests for the dht/kad protocol and swarm nodes discovery.
  • Test connection to 5 random node on startup using bootstrap node

A more robust logging system

Robust logging is critical for performing complex p2p networking and consensus test.
We are currently using https://github.com/op/go-logging and the goal was to have per-module logger so we can easily identify a log entry source module. This is useful when performing tests that involve several local nodes. There's a flaw our current logging - we actually only support 1 module because logger.SetBackend() replaces previously set backends. What we want is to be able to have multiple loggers, one per module and make sure that log entries from module a are never recorded on module b's loggers (e.g file + os.stdOut).

Current behavior:
After a local node is started, all app log entries go the node's logger.
In tests where we have multiple nodes in the same test - a node log entries will appear as if it is coming from the most recently created nodes.

Expected behavior:
App log entries to only appear int he app loggers (file+console) and not in a local node's loggers.

Use goreleaser to build and release new versions

Use goreleaser or similar so that we can release new versions on one command building the binaries for several platforms and architectures.

The main reason for adding this is automate the process of new releases as much as possible.

Use go 1.9 bit manipulation libs for bit ops

Feature description

We should use golang 1.9 new bit ops lib instead of our homegrown bit manipulation code.

Main Reason for adding this feature

It safe to say that these libs are going to be more extensively tested and more optimized by the GO larger open source community. Unless there's a very good reason for custom supporting libs, we should always strive to use as many standard golang libs as possible instead of our own libs. See http://herman.asia/bit-manipulation-in-go-1-9

Simplify installation by providing a Dockerfile

Add a Dockerfile that includes all preinstallations (Go, Protobufs...) and git clone, build and run

Expected behavior

sudo docker build -t spacemesh/go-spacemesh .
sudo docker run -d spacemesh/go-spacemesh
Will start the Spacemesh blockchain p2p node

Actual behavior

Steps to reproduce the actual behavior

Feature request template

Feature description

Reasons for adding this feature

Simplify deployment and testing

Too much todo!

Go over the todo comments scattered throughout the source code, create an issue for each todo task and remove the comment from the code.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.