Coder Social home page Coder Social logo

lisk-engine's Introduction

Logo

Lisk Engine

License: Apache 2.0 Build status GitHub tag (latest by date) GitHub repo size GitHub issues GitHub closed issues

Lisk Engine is a consensus engine written in Golang implementing the Lisk v4 protocol.

Requirements

  • Go v1.21 or above

Development

Linting

golangci-lint is used for linting. To setup the local environment, refer to Editor Integration in the usage guide.

Documentation

Execute the folllowing command to view the generated documentation locally:

make godocs

Usage

Execute the folllowing command to run Lisk Engine against a known ABI server:

make run.lengine PATH_TO_ABI_SERVER PATH_TO_CONFIG

# Example
# make run.lengine path=~/.lisk/dpos-mainchain/tmp/sockets/abi.ipc config=./cmd/debug/app/config.json

Codecs

To generate a new codec:

  1. Define a new struct with a tag on each property fieldNumber: "n"
  2. Add //go:generate go run github.com/LiskHQ/lisk-engine/pkg/codec/gen at the top of the file
  3. Call make generate.codec

Tests

To run the tests:

  • make test - To run all the tests and show a summary
  • make test.coverage - To run all the tests and show a detailed coverage report
  • make test.coverage.html - To run all the tests and produce a HTML coverage report

Contributors

https://github.com/LiskHQ/lisk-engine/graphs/contributors

Disclaimer

Warning

By using the source code of Lisk Engine, you acknowledge and agree that you have an adequate understanding of the risks associated with the use of the source code of Lisk Engine and that it is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. To the fullest extent permitted by law, in no event shall the Lisk Foundation or other parties involved in the development of Lisk Engine have any liability whatsoever to any person for any direct or indirect loss, liability, cost, claim, expense or damage of any kind, whether in contract or in tort, including negligence, or otherwise, arising out of or related to the use of all or part of the source code of Lisk Engine.

License

Copyright 2016-2024 Lisk Foundation

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

lisk-engine's People

Contributors

matjazv avatar dependabot[bot] avatar shuse2 avatar hrmhatef avatar nazgolze avatar

Watchers

 avatar  avatar  avatar  avatar Clemente avatar Franco NG avatar Abhishek Jalan avatar Alessandro Ricottone avatar  avatar

lisk-engine's Issues

Implement validator for messages

Description

Before a received message is broadcasted to other connected peers it needs to be validated. Invalid messages are rejected and not sent further to the other peers. A peer is punished and it's score is decreased.

  • Define validation for envelope of a message.
  • Implement/update unittest.

Acceptance Criteria

  • Invalid messages are rejected and not sent to the other connected peers.
  • All new code is unit tested.

Additional Information

  • AddPenality should be implemented
  • structure of the message format (not the content)
  • we should check rate limiting exists for gossipsub and req/res, if not we need rate limiting
  • Check how to tamper the propagation in case of validation fails
  • Check if we can delay the configure re-publishing strategy because block processing is asynchronous.

Implement peer identity

Description

Each peer needs to have a unique and fixed peer ID.
On boot if a peer doesn't have a peer ID, generate and save it for a later use.

Consider a possibility to import private key via config file. Than something like this can be used:
privKey, err := crypto.UnmarshalPrivateKey([]byte)

Acceptance Criteria

  • Peer has a fixed peer ID and is not changed during a system reset.
  • All new code is unit tested.

Additional Information

Remove duplicate functions from p2p and define one `host` for all usage

Description

  • Already there is two implementation of P2pAddrs one is free function in pubsub and the other one is a method of Peer struct. So it should be solve.
  • The Peer struct in Peer.go has a host as it member and it is private, host should be accessible for other package of p2p also it should be independent to making an instance for passing it as a function argument, for example in function NewGossipSub we need to have it.

Acceptance Criteria

  • All existing test should pass

Implement support for browsers and mobile devices

Description

Implement support for browsers and mobile devices.

  • Support as many web browser as possible (Chrome, Safari, Firefox, Edge)
  • Support Android and iOS devices.
  • Implement/update unittest.

Acceptance Criteria

  • It is possible to run a node from a web browser.
  • It is possible to run a node within Android or iOS operating systems.
  • All new code is unit tested.

Additional Information

Implement peerbook or some similar list of peers

Description

New P2P package needs handling of all (known) peers. List of known peers needs to be saved in non-volatile memory so it can be reused in case of node reset.
It should be possible to provide different lists of peers to internal functions and external packages.

In gossip sub, we need

getConnectedPeers(): []peerID
getBlacklistedPeers(): []peerID

and in the initialization, we want gossipsub to start with

NewGossipSub(&Option{
  seedPeers: []peerID,
  knownPeers: []peerID,
  staticPeers: []peerID,
  blacklistedPeers: []peerID,
})

Acceptance Criteria

  • Internal functions and external packages have possibility to get a different lists of peers.
  • All new code is unit tested.

Additional Information

  • we need to check what we can passed to the gossipsub for the initial state, and discuss the input when creating the option

Invalid sending and receiving format for post block on P2P

Expected behavior

Consensus should send and receive data for postBlock event in the same format

Actual behavior

Here it's broadcasting block with EventPostBlock schema. however, it's expecting the message to be a block on receive

Which version(s) does this affect? (Environment, OS, etc...)

main

Follow standard crypto interface in the crypto package

Description

Currently, crypto package GetKeys do not follow standard crypto library interface. For example, PrivateKey is []byte but it implements Public and Equal. we should keep the standard interface as much as possible

  • crypto should have PublicKey PrivateKey type instead of []byte
  • Refactor GetKeys to accept []byte instead of string
  • Add Verify and Sign
  • Refactor util functions (Hash, hexToString, hexToBytes, GetAddress etc) to be in different file (utils.go)

Acceptance Criteria

  • Update comments and examples
  • All function should be covered by unit test

Implement functionality for configuring P2P package

Description

A user should have a possibility to change behavior of a node. For that reason there should be a file with all configurable P2P package parameters like default transport protocol, port number, min. and max. number of outbound connections, etc.

  • P2P package parameters must be read from config.json file.
  • Implement/update unittests.

Acceptance Criteria

  • Parameters are read from a config.json file.
  • All new code is unit tested.

Implement simple ping/pong app and package

Description

Implement a ping/pong application for a starting point of a new P2P module.

  • Implement multi-address support.
  • Implement (basic) peer handling.
  • Implement communication between peers using stream.
  • Implement/update unittests.

Acceptance Criteria

  • Two peers are able to communicate with each other in a local environment.
  • All new code is unit tested.

Additional Information

Implement missing validators for events

Description

Validators for events are registered but they are not yet implemented.

Acceptance Criteria

  • Validator for events are properly implemented.
  • All new code is unit tested.

Refactor block and transaction to remove duplicate signing block/transaction

Description

  • Remove duplication of SigningTransaction and signingBlockHeader and use embedded struct.
  • Remove frozen transaction because defining interface for transaction in the package adds complexity without much benefit. interface should be defined in the user side.

Acceptance Criteria

  • All test should be passing

Additional Information

  • this requires #54 otherwise it will increase the non generated boilerplate code for codec

Implement RegisterRPCHandler in P2P module

Description

Implement function RegisterRPCHandler to be able to register all necessary RPC handlers from the modules of the engine.

Acceptance Criteria

  • Modules can call RegisterRPCHandler function to be able to register their RPC handlers.
  • All new code is unit tested.

Additional Information

  • Example usage is like this

Implement retry policy for a message delivery

Description

In request/response message transferring it could occur that a request is not delivered or a response is lost because of various reasons.
Currently when a request is sent and if a response is not received a timeout occurs and an error is returned.
Implement additional feature that in case of a timeout, a request is sent again and only after configured number of retries an error is returned.

Acceptance Criteria

  • If a response is not received, a request is sent again.
  • Only after configured number of retries an error is returned.
  • All new code is unit tested.

Verify peer searching mechanism and seed node handling

Description

Peer searching mechanism should be implemented in the gossipsub.
We need to check

  • How seed node disconnect from incoming connection.
  • How node connected to seed node disconnects and choose another nodes
  • How seed node ensures the open slots for the new connections

Acceptance Criteria

  • Above checks should have result on this issue
  • If new code is added, the code is unit tested

Additional Information

  • Peer struct has field peerbook which provides among others, a list of known peers. If gossipsub needs such a list it can use it because peer is accessible from gossipsub.
  • For discovering new peers using seed peer we could use https://github.com/ipfs/kubo/blob/master/core/bootstrap/bootstrap.go
  • Check if knownPeers are needed at all in Peerbook struct because gossipsub should handle by its own its internal list of know peers.

Implement handshake protocol

Description

When establishing a new connection with a peer, a connection must be accepted only if some conditions are true:

  • chainID
  • networkVersion

A peer should also send info if it's addresses can be advertised to other peers in the network or not.

  • advertiseAddress

Acceptance Criteria

  • Only valid connections from other peers are accepted.
  • If peer sets advertiseAddress to false it's address is not passed to the other peers.
  • All new code is unit tested.

Implement functionality for targeting a peer

Description

P2P module needs to support targeting a peer. That means it is possible to send a request/message to a specific peer and not only to all peers or a randomly selected peer.

  • Being able to send a request to a target peer.
  • Peer will open a stream to the other peer to be able to communicate with each other.
  • Req/Res needs to be implemented
  • Define Req/Res format
  • Implement/update unittests.

Acceptance Criteria

  • A peer can send a request to a specific peer to which it is connected to.
  • All new code is unit tested.

Implement NAT traversal feature

Description

A peer/node could be behind NAT and an owner of this node is not in a position to configure router to be able to re-route an incoming request to a node's private IP address. libp2p offers some features to overcome this issue. Below is a list of features which needs to be implemented that a peer behind NAT will be able to be called by another peer from a public network.

  1. Implement AutoNAT feature:
    -- A peer is being able to detect if it is behind NAT with a libp2p AutoNAT feature.

  2. Implement circuit relay transport protocol:
    -- https://docs.libp2p.io/concepts/nat/circuit-relay
    -- By default it is enabled, but it can be disabled or change the limit from the config.

  3. Add NAT and holepunching features:
    -- https://docs.libp2p.io/concepts/nat
    -- https://blog.ipfs.tech/2022-01-20-libp2p-hole-punching
    -- Implement/update unittests.

Acceptance Criteria

  • A peer which is behind NAT is able to be called by another peer outside of it's local/private network.
  • After two peers connect with each other through a relayer peer, a direct connection between them is established with a holepunching mechanism.
  • All new code is unit tested.

Additional Information

Update a config of `gossipsub` based on Lisk network needs

Description

A libp2p and gossipsub have an extensive list of parameters to set. They need to be set in a way that they will best fit for the Lisk network.

  • Perform a different measurements to be able to tweak gossipsub parameters for best possible network performance and usage.
  • Implement/update unittest.

Acceptance Criteria

  • All new code is unit tested.

Additional Information

  • Change parameters together with a Research team to guarantee safety, reliability and usability.

Panic when DB failed with unexpected reason

Description

Update db to panic when unexpected error happens. With that, we could update general DB interface to be

Get(key []byte): ([]byte, bool)
Set(key, value []byte)
Del(key []byte)

Motivation

If underlying DB fails with unexpected reason (ex: other than not found error), there is no way to recover or continue from that state automatically. Further more, if it proceed with the state, it could result in unexpected state.
Therefore, unrecoverable error should be panic and stop the process.

Store reference to included block in transaction

Description

Add BlockID property when storing the block, and it should return in the response from the RPC.
There should be distinction between general Transaction concept which used inside of block or in transaction pool. Therefore, Transaction struct should remain as it is.

Motivation

Currently, there is no information about in which block the transaction is included when transaction is fetched from storage.
This will make other system hard to link the block when fetching single transaction

Allow codec to use embedded struct

Description

For example, below script should be able to produce equivalent outcome of encode/decode when generated.

type Transaction struct {
	SigningTransaction
	ID         codec.Hex   `json:"id"`
	size       int         `json:"-"`
	Signatures []codec.Hex `json:"signatures" fieldNumber:"8"`
}
  • In case of the embedded struct is from another package, it can be ignored

Motivation

Sometimes, there are multiple version of types needs to be defined. For example, Transaction/Block header has signing block/transaction type and ones with signatures.
Currently, they are independent struct, but since properties are the same, it would be nice to be able to declare as an embedded struct

Additional Information

  • codec generation is parsing per file/package. Therefore, it cannot tell if struct from other package is encodable or not

Add Jenkins

This is the Jenkins version of #2

To be used until we're ready to use Github Actions

Check that P2P package is able to mitigate all common attacks

Description

P2P package needs to be able to mitigate all common (P2P) network attacks like:

  • DDoS
  • Peer Poisoning
  • Sybil
  • Eclipse

Tasks to do:

  • Discover potential weaknesses and improve them.
  • Implement missing (safety) features.
  • Implement/update unittests.

Acceptance Criteria

  • Research team approve safety of the P2P package.
  • All new code is unit tested.

Additional Information

  • Check implementation together with a Research team to guarantee safety of the P2P package.

Implement functionality to disallow incoming connections

Description

Is some cases (ex. if a node is owned by an exchange) we would like to prevent that a node will accept any incoming connection.
Such node will only connect to a known (trusted) nodes by itself by creating an outgoing connections.

  • A peer should be able to set a setting which disable accepting any incoming connection.
  • Implement/update unittests.

Acceptance Criteria

  • If functionality is enabled, all incoming connections are rejected.
  • All new code is unit tested.

Additional Information

In current P2P (v1), when incomingConnections is 0, it doesn't start the websocket server

Implement ability to hide a peer's role

Description

In some cases it is beneficial for a peer to not expose it's role to the other peers.
Implement a feature that will allow a node operator to hide a node's role.

  • Prevent that other peers will realize who is a message creator.
  • Prevent that other peers will realize who is a block generator.
  • Implement/update unittests.

Acceptance Criteria

  • It is possible to send a message to another peer without revealing that a peer is creator of that message.
  • All new code is unit tested.

Integrate P2P package into the engine

Description

Replace v1 P2P package with v2 P2P package in the other packages in lisk-engine.

Acceptance Criteria

  • v1 P2P package is not used anymore.
  • All packages inside lisk-engine are using v2 P2P package.
  • All new code is unit tested.

Additional Information

  • How block/transaction/signature are re-published need to be changed
  • How node info is propagated to neighbour peers for synching need to be changed
  • All conn.RegisterEventHandler and conn.RegisterRPCHandler need to be checked

Add limitation for `Peer IDs` for each IP

Description

Currently we try to ban Peer ID and remove it after 24 hours, it would be nice if we have a counter for peer ID based on the IPs.

Motivation

  • We can make a limitation for IDs per IPs.
  • For example if each IP requested by 10 different peer ID we well be able to block that IP.

Add `gossipsub` with a default config

Description

Introduce gossipsub module into libp2p module by implementing following requirements:

  • Peer is able to broadcast information/message to all connected peers
  • Implement/update unittests.

Implement and use features which are useful for new P2P package. Features to be considered (list is not complete):

  • Outbound mesh quotas
  • Explicit peering agreements
  • List of bootstrapper nodes
  • Opportunistic grafting
  • Prune peer eXchange
  • Extended message validators
  • Peer scoring
  • Peer banning

Acceptance Criteria

  • P2P module supports above features from gossipsub module.
  • Peers are able to communicate using gossipsub features (explicit peering agreements, peer scoring/banning, outbound mesh quotas, etc.).
  • Peer can broadcast message to all connected peers in the same mesh.
  • All new code is unit tested.

Additional Information

Improve managing connections to peers

Description

If the number of connections exceeds the maximum allowed number of connections, some of those connections need to be closed. To manage such connections a Connection manager from libp2p may be used.

If the number of connections drops below the minimum number of connections, try to connect to some of the known peers manually without libp2p or gossipsub assistance.

To prevent an indefinite amount of time to be connected with any of non-fixed peers, randomly close connection at predefined time intervals.

Acceptance Criteria

  • Number of open connections doesn't exceed the maximum allowed number of connections.
  • Connections are randomly closed at predefined time intervals.
  • All new code is unit tested.

Additional Information

Implement new testplan for the latest p2p/v2 module

Description

To ensure that new p2p/v2 module is working as expected and we'll be able to adjust parameters for gossipsub accordingly to our needs, implement a new testplan for a testground.

Testplan needs to check:

  • Connecting/disconnecting from a peers.
  • Connecting to a seed peer(s) and then to a newly discovered peers.
  • Always connected peers (FixedPeers).
  • Disallow incoming connections.
  • Blacklisting peers.
  • Sending direct messages to a specific peer.
  • Responding to a direct messages from a specific peer.
  • Broadcasting messages using gossipsub.

Bonus or if out of scope for this testplan a new issue could be created:

  • Check NAT connections.
  • Check Relay service/connections.
  • Check hole punching.

Acceptance Criteria

  • New testground plan is implemented.
  • All new code is unit tested.

Check missing API functionality for new P2P package

Description

Try to integrate new P2P package into an engine and check which API functions are missing.
Implement those functions (body can be empty) to make an engine compilable with new P2P package.

Acceptance Criteria

  • Engine is compilable with new P2P package.
  • All missing API functions are present in P2P package.

Create test application for new P2P module

Description

lisk-engine is currently not compatible with the latest version of lisk-sdk.
To properly test lisk-engine without lisk-sdk create a new test application.

Acceptance Criteria

  • New test application is created.
  • lisk-engine can be tested with test application.

Sometimes unit test fails in self-hosted machine

Expected behavior

When PR is created, all unit tests pass.

Actual behavior

Sometimes some unit tests fail.

Steps to reproduce

Create a new PR and check GH Actions.

Which version(s) does this affect? (Environment, OS, etc...)

Latest main branch

Check functions visibility in p2p/v2

Description

Some functions in p2p/v2 may not need to be exposed to other modules.
Check all exposed functions and consider their visibility. If needed, mark any of those as private.

Acceptance Criteria

  • All functions in p2p/v2 have appropriate visibility (public or private).
  • All new code is unit tested.

Add additional flags for `go test`

Description

If -race flag is added to go test command there are some warnings regarding race conditions in engine source code.
Check and fix those errors/warnings.
Update GH actions with this flag to prevent race conditions will occur in the future.
Add also -shuffle=on flag to tell test runner to shuffle tests before running them to prevent any dependency between tests.

Acceptance Criteria

  • -race -shuffle=on flags are added in go test in GH actions.
  • There is no warnings for race condition when unit tests are executed.

Additional Information

  • In p2p/v2 there is no race condition detected.

Add transaction size validation

Description

Add transaction size validation according to LIP

Acceptance Criteria

  • Add unit test to check size validation in transaction class
  • Default value of the MAX_TRANSACTIONS_SIZE_BYTES should be the same as block size

Refactor to follow the convention of the code in unit tests

Description

In the unit tests the following edits needed:

  1. Convert all context.Background() function to the following style when the test needs to reuse the context in the unit test:
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()
  1. When we need more than one assertion check in code please try to define assert by the following definition at the top of each unit test to reduce call assert(t, ...):
    assert := assert.New(t)

Acceptance Criteria

  • All unit tests should follow the above rules.

Additional Information

  • Scope is p2p/v2

Implement ability to reject incoming connection

Description

If an invalid peer wants to establish connection with our peer, we need to be able to disallow it and prevent a peer to be connected with our peer.

  • While a handshake is performing, a peer checks if a network ID from a peer which wants to connect is the same as its network ID and its network version. In case it is not, a connection is rejected.
  • Check if gossipsub rejects the banned peer automatically, and if not handle the rejection
  • Implement/update unittests.

Acceptance Criteria

  • It is possible to reject an incoming connection.
  • All new code is unit tested.

Improve P2P protocol efficiency and consistency

Description

Define generic efficient message protocol to be consistent on all of the messages passed through the network using binary format.
Additionally, add missing P2P features to improve the infrastructure.

Motivation

  • Update the architecture to prevent incoming messages from affecting the on-chain processing
  • Implement missing critical P2P features
  • Remove unnecessary dependencies
  • Define the communication protocol format

Tasks

Add blacklist setting to the RPC config

Description

Add

disabledMethods: ['namespace', 'namespace_method']

to the RPC config, and RPC server should reject if the requested method is in the blacklist or not.
if disabledMethods specifies namespace, it should reject all request to the namespace, and if config specifies namespace_method, it should only reject only that method.
Partial match should not be allowed.

Motivation

Some RPC endpoints are specifically used for validator nodes, and some endpoint should not exposed on the RPC node

Define and implement a communication protocol format

Description

  • Define generic and efficient message protocol.
  • It must be in a binary format.
  • Check what kind of messages are required.
  • Defining envelope for the message.
  • Implement/update unittests.

Acceptance Criteria

  • Messages according to a defined protocol are sent over a network.
  • All new code is unit tested.

Additional Information

  • Publish(topic: string, data: []byte) and RegisterEventHandler need to be implemented
  • Above those 2 functions need to be connected to the pubsub
  • We need a method to create new topic in gossipsub

Move NetworkConfig to P2P package

Description

At the moment, NetworkConfig is inside engine module. Dependency wise it would be better if this config will be inside P2P package.
For engine needs define a new config or reuse one from P2P package.

Acceptance Criteria

  • NetworkConfig is part of P2P package
  • All new code is unit tested.

Batch RPC call

Description

Allow caller of RPC to send the request in batch.
It should accept

[
  {
    "jsonrpc": "2.0",
    "method": "message@create",
    "params": "...",
    "id": 1
  },
  {
    "jsonrpc": "2.0",
    "method": "message@create",
    "params": "...",
    "id": 2
  }
]

and it should response as

[
  {
    "id": "1",
    "result": "pong",
    "jsonrpc": "2.0"
  },
  {
    "id": "2",
    "result": "pong",
    "jsonrpc": "2.0"
  }
]

Motivation

If we have multiple small rpc endpoints, calling one by one will be inefficient for network traffic.

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.