OrbitsNetwork

2019.06 Monthly Report (OrbitsNetwork)

Index

  1. Node architecture in the Network Layer

  2. Bitcoin P2P

  3. Golang

Node architecture in the Network Layer

2019 Q3

  • Planet Wallet Launching

  • Network Layer Development

We have been developing the Network Layer to accomplish it by the third quarter of 2019 according to the GBT Protocol Roadmap. Currently, we are analyzing the pros and cons on based on the existing projects to detect potential problems and issues when Micro Nodes and Super Nodes are connected in the network.

The Orbits Network is a combined format of the Public Blockchain and the Private Blockchain. Micro Node’s network connection, which will be performed in the Public Blockchain, analyzes Bitcoin P2P and Ethereum P2P operation and utilizes them in the most efficient format. Super Node’s network connection, which will be performed in the Private Blockchain, analyzes Hyperledger Fabric P2P, Tendermint P2P, and EOS P2P operation and utilizes them in the most efficient format.

Blockchain nodes constantly share transactions and block data with each other. A node received data relays the data to another node. If some node sends 1MB data to known nodes, and the known nodes send the data to another known nodes in the network, the data is floating in the network as copied. Nodes can continuously receive the data again.

However, this type of network is inefficient; therefore, an order not to repeatedly receive the same data is necessary. And, we call it a protocol.

1. Micro Node

Grabity Dapp usage

  • Micronodes uses Dapps developed by Dapp developers. Transaction is created as Dapp is used, GBT is moved, and SC is operated.

Transaction verification

  1. Micronodes judge validity of the transaction by verifying GBT transactions.

  2. Based on the agreement among verifiers, renewed GBT validty state is stored.

2. Super Node

Block creation

  1. Supernodes confirms blocks delivered from micronodes and macronodes in order. If a wrong block is delivered, it is rejected.

  2. Supernodes record the result of vote by micronodes and macronodes on the block creation.

  3. Supernodes keep all transactions occurred in the network in a form of a block.

Micronode verification pool creation

  1. Supernodes regularly and randomly select nodes to verify micronodes’ transactions.

  2. Supernodes arrange and deliver transactions occurred from micronodes to the verification pool.

  3. Screening supernodes check the on/offline status of each micronode to create the verification pool.

Bitcoin P2P

1. Node management message

Nodes participating in the network have to consider other nodes’ environment. The participating nodes have to remember IP addresses and supportable functions of each node. And, they have to check whether nodes are active. To accomplish these tasks, they share version, verack, addr, ping, and pong messages.

Command "addr"
bool AddAddress(CAddrDB& addrdb, const CAddress& addr)
{
if(!addr.IsRoutable())
return false;
if(addr.ip == addrLocalHost.ip)
return false;
CRITICAL_BLOCK(cs_mapAddresses)
{
map<vector<unsigned char>, CAddress>::iterator it =
mapAddresses.find(addr.GetKey());
if(it == mapAddresses.end())
{
//New address
mapAddresses.insert(make_pair(addr.GetKey(), addr));
addrdb.WriteAddress(addr);
return true;
}
else
{
CAddress& addrFound = (*it).second;
if((addrFound.nServices | addr.nServies) != addrFound.nServices)
{
//Services have been added
addrFound.nServices |= addr.nServices;
addrdb.WriteAddress(addrFound);
return true;
}
}
}
return false;
}

2. Block Data Synchronization

If there is no blockchain data at all or a full node with only a part of the blockchain data enters, it has to synchronize the blockchain data with other full nodes. Nodes can keep the blockchain update to the latest by requesting insufficient blockchain data to other full nodes. Nodes should follow this to verify and deliver transactions and verify and connect newly created blocks to the chain. We call it the blockchain data synchronization.

Command "getdata"
class CNode
{
//.....
void PushInventory(const CInv& inv)
{
CRITICAL_BLOCK(cs_inventory)
if(!setInventoryKnown.count(inv))
vInventoryToSend.push_back(inv);
}
//......
}
inline void RelayInventory(const CInv& inv)
{
//Put on lists to offer to the other nodes
CRITICAL_BLOCK(cs_vNodes)
foreach(CNode* pnode, vNodes)
pnode->PushInventory(inv);
}
template<typename T>
void RelayMessage(const CInv& inv, const T& a)
{
CDataStream ss(SER_NETWORK);
ss.reserve(10000);
ss << a;
RelayMessage(inv, ss);
}
template<>
inline void RelayMessage<>(const CInv& inv, const CDataStream& ss)
{
CRITICAL_BLOCK(cs_mapRelay)
{
//Expire old relay messages
while(!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
{
mapRelay.erase(vRelayExpiration.front().second);
vRelayExpiration.pop_fron();
}
//Save original serialized message so newer versions are preserved
mapRelay[inv] = ss;
vRelayExpiration.push_back(make_pair(GetTime() + 15 * 60, inv));
}
RelayInventory(inv)
}

3. New block data relay

4. Transaction relay

When new transactions are occurred, each node verifies them and develier to the near nodes. Transaction data is delivered via inv, getdata, and tx messages. In this case, the data type is either MSG_TX or MSG_WITNESS

Command "tx"
void AddOrphanTx(const CDataStream& vMsg)
{
CTransaction tx;
CDataStream(vMsg) >> tx;
uint256 hash = tx.GetHash();
if(mapOrphanTransactions.count(hash))
return;
CDataStream* pvMsg = mapOrphanTransactions[hash] = new CDataStream(vMsg);
foreach(const CTxIn& txin, tx.vin)
mapOrphanTransactionsByPrev.insert(make_pair(txin.prevout.hash, pvMsg));
}
void EraseOrhpanTx(uint256 hash)
{
if(!mapOrphanTransactions.count(hash))
return;
const CDataStream* pvMsg = mapOrphanTransactions[hash];
CTransaction tx;
CDataStream(*pvMsg) >> tx;
foreach(const CTxIn& txin, tx.vin)
{
for(multimap<uint256, CDataStream*>::iterator mi =
mapOrphanTransactionsByPrev.lower_bound(txin.prevout.hash);
mi != mapOrphanTransactionsByPrev.upper_bound(txin.prevout.hash);)
{
if((*mi).second == pvMsg)
mapOrphanTransactionsByPrev.erase(mi++);
else
mi++;
}
}
delete pvMsg;
mapOrphanTransactions.erase(hash);
}

Golang

Golang is appropriate in developing large-scale complicated applications such as web browsers, servers, databases, or etc. In this field, it is more important to concentrate on building logics than spending time on the memory management. Therefore, with the Golang which doesn’t ask you to spend time on small details in the memory management, you can increase productivity.

The memory management can be flexible when you use Golang. And also, it is useful and convenient for the large and complicated tasks which requires much time in the maintenance. And, it is adequate for internet programming as it provides various network libraries.

Golang in the blockchain

Practice to create a webcrawler by using Goroutine

package main
import (
"bufio"
"fmt"
"net/http"
"os"
"strings"
"sync"
"github.com/yhat/scrape"
"golang.org/x/net/html"
"golang.org/x/net/html/atom"
)
const (
urlRoot = "http://"
)
func parseMainNodes(n *html.Node) bool {
if n.DataAtom == atom.A && n.Parent != nil {
return scrape.Attr(n.Parent, "class") == "row"
}
return false
}
func errCheck(err error) {
if err != nil {
panic(err)
}
}
var wg sync.WaitGroup
func scrapContents(url string, fn string) {
defer wg.Done()
resp, err := http.Get(url)
errCheck(err)
defer resp.Body.Close()
root, err := html.Parse(resp.Body)
errCheck(err)
matchNode := func(n *html.Node) bool {
return n.DataAtom == atom.A && scrape.Attr(n, "class") == "deco"
}
file, err := os.OpenFile("c:\\scrape\\"+fn+".txt", os.O_CREATE|os.O_RDWR, os.FileMode(0777))
errCheck(err)
defer file.Close()
w := bufio.NewWriter(file)
for _, g := range scrape.FindAll(root, matchNode) {
fmt.Println("result : ", scrape.Text(g))
w.WriteString(scrape.Text(g) + "\r\n")
}
w.Flush()
}
func main() {
resp, err := http.Get(urlRoot)
errCheck(err)
defer resp.Body.Close()
root, err := html.Parse(resp.Body)
errCheck(err)
urlList := scrape.FindAll(root, parseMainNodes)
for _, link := range urlList {
//fmt.Println("Check Main Link : ", link, idx)
//fmt.Println("TargetUrl : ", scrape.Attr(link, "href"))
fileName := strings.Replace(scrape.Attr(link, "href"), "http://", "", 1)
//fmt.Println(strings.Replace("oink oink oink oink", "k", "ky", 2))
//fmt.Println("fileName : ", fileName)
wg.Add(1)
go scrapContents(scrape.Attr(link, "href"), fileName)
}
wg.Wait()
}

Reference

  1. 파이썬으로 배우는 블록체인 구조와 이론 / 박미정,박은진 / 위키북스

  2. A Dissection of Bitcoin / Paul Huang

  3. 가장 빨리 만나는 Go언어 / 이재홍 / 길벗