Blockchain parameters

The node is configured via the nodix.node file.

The first object in the node script file is the blockchain configuration. It is used to define blockchain parameters such as

  • Blockchain name.
  • Network magic number.
  • Prefix used for wallet address generation.
  • Signature module.
  • Seed node address and port.
  • Mining target block time and reward.
  • Total number of blocks to be mined.
  • Staking target block time and reward.
  • Informations for the genesis block.

It is defined once for all for the whole life-time of the blockchain. Any change in this object will trigger an hard fork.

let NODE_GFX_OBJECT configuration = `

{

"name":"nodix",

"magic" :0xD9BEFECA,

"pubKeyVersion":0x19,

"sign_mod" : { "file":"modz/ecdsa.tpo"},

"seed_node" :

{

"host":"nodix.eu",

"port" : 16819

},

"staking":

{

"targetspacing":64,

"maxtargetspacing" : 640,

"targettimespan":960,

"limit":0x1B00FFFF,

"minStakeDepth":2,

"reward" : 150000000,

"pos_kernel" : { "file":"modz/stake_pos3.tpo"}

},

"mining":

{

"targetspacing":64,

"maxtargetspacing" : 640,

"targettimespan":960,

"limit":0x1E0FFFFF,

"reward":10000000000000,

"last_pow_block":200000,

},

"genesis":

{

"version" :1,

"time" :1466419085,

"bits" :0x1e0fffff,

"nonce" :579883,

"InitialStakeModifier":0,

"InitialStakeModifier2":0

}

}`

Node configuration

The second object in the node definition script is the node object. It is used to define web service configuration, as well as various parameters to determine node behavior.

  • Amount of fee this node will include in transactions.
  • Blockchain protocol version.
  • Enable or Disable uPnP port forwarding.
  • Number of valid block ahead to trigger chain change.
  • Max size of P2P messages.
  • Enable checking of transaction signature in received blocks.
  • Address used for mining on this node. If this field is omitted, the node will automatically create new address.
  • List of trusted applicatons. The node will load and execute module and script only for applications present in this array.
  • Address used for the p2p network.

let NODE_BITCORE_NODE SelfNode = `

{

"user_agent" : "nodix",

(NODE_GFX_BINT)"paytxfee" : 0,

"privKeyVersion" : 0x55,

"block_height" : 0,

(NODE_GFX_INT)"version" : 60018,

(NODE_GFX_BOOL)"uPnP":false,

(NODE_GFX_INT)"bestChainDepth":3,

(NODE_GFX_INT)"maxMsgSize":1024,

(NODE_GFX_INT)"checktxsign" : 0,

(NODE_GFX_INT)"next_check" : 0,

(NODE_BITCORE_WALLET_ADDR)"coinbaseAddr" : "B8mPBEg2XbYSUwEh5a7yrfehvMNijpAm1P",

(NODE_GFX_INT)"scriptBlock" : 0,

(NODE_GFX_INT)"current_pos_diff" : 0,

(NODE_GFX_INT)"current_pow_diff" : 0,

(NODE_GFX_BINT)"pos_reward" : 0,

(NODE_GFX_BINT)"pow_reward" : 0,

(NODE_GFX_SIGNED_BINT)"ping_delay" : 0,

(NODE_GFX_INT)"last_block_time" : 0,

(NODE_BITCORE_BLK_HDR) "last_block" : {},

(NODE_BITCORE_BLK_HDR) "lastPOSBlk" : {},

(NODE_BITCORE_BLK_HDR) "lastPOWBlk" : {},

(NODE_GFX_OBJECT) "trustedApps" : { "blog" : true , "raytrace" : true },

(NODE_BITCORE_ADDR)"p2p_addr" :

{

"services" : 0,

(NODE_NET_IP)"addr" : "127.0.0.1",

(NODE_GFX_SHORT)"port" : 16819

},

(NODE_BITCORE_NODE_LIST) "peer_nodes" : [],

(NODE_BITCORE_WALLET_ADDR_LIST) "addr scan list" : null,

(NODE_BITCORE_MSG_LIST) "send queue" : [],

(NODE_BITCORE_MSG_LIST) "emitted_queue" : [],

(NODE_BITCORE_TX_LIST) "mempool" : [],

(NODE_BITCORE_TX_LIST) "submitted txs" : [],

(NODE_BITCORE_HASH_LIST) "pending files" : [],

(NODE_BITCORE_BLOCK_LIST) "submitted blocks" : []

}`

Node initialization

Core blockchain modules import and loading


let NODE_MODULE_DEF vec = `{ "order" :0, "file" : "modz/vec3.tpo"}`

let NODE_MODULE_DEF protocol_adx = `{"order":1, "file" : "modz/protocol_adx.tpo"}`

let NODE_MODULE_DEF block_adx = `{"order":2, "file" : "modz/block_adx.tpo"}`

let NODE_MODULE_DEF wallet = `{"order":3, "file" : "modz/wallet.tpo"}`

let NODE_MODULE_DEF node_adx = `{"order":4, "file" : "modz/node_adx.tpo"}`

let NODE_MODULE_DEF nodix = `{"order":5, "file" : "modz/nodix.tpo"}`


Network message handlers


handler on_verack(node , payload ) = `

node_adx.queue_ping_message(node )

success

`

handler on_ping(node,payload) = `

node_adx .queue_pong_message(node,payload .nonce)

success

`

handler on_pong(node, payload) = `

gettime node.ping_delay;

gettime node.last_pong;

sub node.ping_delay, node.last_ping;

set node.next_pong = 0;

set node.synching = 1;

success

`

handler on_inv(node, payload) = `

node_adx.queue_getdata_message(node , payload .hashes)

success

`

handler on_addr(node, payload) = `

foreach payload .addrs > node_adx.node_log_addr_infos ; node_adx.node_add_remote_peers ( node , payload .addrs)

success

`

handler on_tx(node, payload) = `

node_adx .node_add_tx_to_mempool( payload .tx) ? node_adx.check_tx_files(node , payload .tx) endor

success

`

handler on_mempool(node, payload) = `

node_adx .node_get_mempool_hashes (hash_list)

node_adx .queue_inv_message(node ,hash_list) success

`

handler on_version(node,payload) = `

if( node .entrant = 1)

set node.p2p_addr.port = payload.my_addr.port;

endif


set node.p2p_addr.services = payload.services;

set node.my_addr = payload.their_addr;

set node.user_agent = payload.user_agent;

set node.version = payload.proto_ver;

set node.block_height = payload.last_blk;


node_adx.node_log_version_infos (node)

node_adx.node_set_bookmark (node.p2p_addr, one);

node_adx.queue_verack_message (node)

node_adx.node_broadcast_addr (node.p2p_addr)

success


`



Initialization


proc init_node = `


protocol_adx.init_protocol (configuration)

block_adx.init_blocks (configuration, SelfNode.trustedApps)

node_adx.node_init_self (SelfNode)


loadmod(configuration.staking.pos_kernel)

configuration.staking.pos_kernel.init_pos(configuration.staking)

nodix.init_staking()


node_adx.node_check_block_index (checkNum,LastGood) ?

nodix.truncate_chain_to (LastGood)

endor


node_adx.node_load_block_indexes ()


block_adx.make_genesis_block(configuration.genesis, genesis_blk)


if (SelfNode.block_height = 0)

node_adx.node_set_last_block (genesis_blk)

node_adx.node_compute_pow_diff_after (genesis_blk)

configuration.staking.pos_kernel.store_blk_staking (genesis_blk)

endif


if (SelfNode.block_height > 1)

node_adx.node_load_last_blks()


block_adx.get_pow_reward(SelfNode.lastPOWBlk.height, block_reward)

set SelfNode.pow_reward = block_reward;

configuration.staking.pos_kernel.load_last_pos_blk(SelfNode.lastPOSBlk) : set SelfNode.lastPOSBlk = SelfNode.last_block;

configuration.staking.pos_kernel.find_last_pos_block(SelfNode.lastPOSBlk)

node_adx.node_store_last_pos_hash (SelfNode.lastPOSBlk)

endor


configuration.staking.pos_kernel.compute_last_pos_diff (SelfNode.lastPOSBlk, SelfNode.current_pos_diff) :

set SelfNode.current_pos_diff = configuration.staking.limit;

endor


configuration.staking.pos_kernel.stake_get_reward (SelfNode.lastPOSBlk.height, block_reward)

set SelfNode.pos_reward = block_reward;


endif


sethandler SelfNode.emitted_queue{ "cmd=verack" } = on_verack;

sethandler SelfNode.emitted_queue{ "cmd=version" } = on_version;

sethandler SelfNode.emitted_queue{ "cmd=ping" } = on_ping;

sethandler SelfNode.emitted_queue{ "cmd=pong" } = on_pong;

sethandler SelfNode.emitted_queue{ "cmd=inv" } = on_inv;

sethandler SelfNode.emitted_queue{ "cmd=addr" } = on_addr;

sethandler SelfNode.emitted_queue{ "cmd=mempool" } = on_mempool;

sethandler SelfNode.emitted_queue{ "cmd=tx" } = on_tx;

node_adx.node_load_bookmark() :

node_adx.connect_peer_node(configuration.seed_node)

endor


node_adx.set_next_check(0)


success


`

Service configuration

  • port used for the http service
  • ip used for the http service
  • run service in a separate thread
  • base path for http request, relative to exe path
  • base path used to access applications
  • service name
  • index page for the service
  • mime type association with file extension
  • mime type used for other files
  • set the cache time for files
  • number of threads used to serve http requests
  • maximum size of post data in kilobytes

(NODE_SERVICE)"http_service":

{

"port" : 16820,

(NODE_NET_IP)"addr" : "127.0.0.1",

"useThread" : true,

"docroot" : "web",

"apppath" : "/app/",

"name" : "Nodix webservice" ,

"indexpage" : "/app/NodixSite/page/index.site",

"mimes" : { "js":"text/javascript" , "css" : "text/css" , "woff" : "text/css" , "woff2" : "text/css" , "png" : "image/png" , "pdf" : "application/pdf" , "gif" : "image/gif" , "svg" : "image/svg+xml" , "html" : "text/html" },

"defaultmime" : "text/plain",

"cacheTime" : 0,

"nthreads" : 4,

"maxpost" : 1024,

"modules" :

[

{"base" : "/jsonrpc" , "type" : "rpc" , (NODE_MODULE_DEF) "rpc_wallet" : { "file":"modz/rpc_wallet.tpo"}},

{"base" : "/pubwal" , "allowed_ip":["127.0.0.1" ] , "type" : "rpc" , (NODE_MODULE_DEF) "anon_wallet" : { "file":"modz/anon_rpc.tpo"}},

{"base" : "/api/" , "type" : "cgi" , (NODE_MODULE_DEF) "block_explorer" : { "file":"modz/block_explorer.tpo"}},

{"base" : "/siteapi/" , "type" : "cgi" , (NODE_MODULE_DEF) "site_cgi" : { "file":"modz/site_cgi.tpo"}}

]

}


For informations about service modules, see modules section of framework documentation.

For informations on this node's service, see wallet service page

Informations about this node service