calculate the message delivery ratio - c++

I am trying to calculate the message delivery ratio using TraCIDemo.
In sendBeacon I am incrementing messageDeliverySend every time I send a message and in processBeacon I increment the messageDeliveryReceive parameter based on the sending node.
In processBeacon I do a string compare with node[0], but I want to check this parameter dynamically. How do I do the dynamic check part for this code?
My scenario will be if there are multiple nodes transmitting to node[1] for example I want to record values only from node[0].
void ROAMER::sendBeacon(ROAMERBeacon * beacon, double delay) {
ROAMER_EV << "Sending beacon: address = " << beacon->getAddress()
<< ", position = " << beacon->getPosition() << endl;
IPv4ControlInfo * networkProtocolControlInfo = new IPv4ControlInfo();
networkProtocolControlInfo->setProtocol(IP_PROT_MANET);
networkProtocolControlInfo->setTimeToLive(255);
networkProtocolControlInfo->setDestAddr(IPv4Address::LL_MANET_ROUTERS);
networkProtocolControlInfo->setSrcAddr(getSelfAddress().get4());
messageDeliverySend++;
delayTime = simTime();
UDPPacket * udpPacket = new UDPPacket(beacon->getName());
udpPacket->encapsulate(beacon);
udpPacket->setSourcePort(ROAMER_UDP_PORT);
udpPacket->setDestinationPort(ROAMER_UDP_PORT);
udpPacket->setControlInfo(networkProtocolControlInfo);
sendUDPPacket(udpPacket, delay);
}
void ROAMER::processBeacon(ROAMERBeacon * beacon) {
if(strcmp(beacon->getSenderAddress(),"node[0]") == 0){
messageDeliveryReceive++;
}
}
void ROAMER::finish(){
messageDeliveryRatio = messageDeliveryReceive/messageDeliverySend;
recordScalar("Message Delivery Ratio",messageDeliveryVecRatio);
}

Related

Building an OSC message with a for loop in C++/oscpack for lidar

Ok, so I'm decent with many programming languages, C++ isn't one of them. This task would take me 5 minutes in pretty much anything else, but after many tries, I'm hoping for some guidance.
My application is reading data from an RPLidar A3, and packaging up the data into OSC to be forwarded to other applications that work with the data and convert it into trackable blobs as a generic tracking system for people in a space. ( It currently looks like this )
I'm doing this via a TINY modification to their example viewer app using the oscpack library.
The sensor returns 2 values: an angle (Float) and a distance in mm (integer)
The sdk gets all the values from a spin and then you iterate through them with a loop. I have it working fine where it sends the value pairs out as it gets them "ie lidar1/ angle distance" out a UDP socket. It looks like this:
UdpTransmitSocket transmitSocket(IpEndpointName(ADDRESS, PORT));
char lidbuffer[OUTPUT_BUFFER_SIZE];
for (int pos = 0; pos < (int)count; ++pos) {
scanDot dot;
if (!buffer[pos].dist_mm_q2) continue;
dot.quality = buffer[pos].quality;
dot.angle = buffer[pos].angle_z_q14 * 90.f / 16384.f;
dot.dist = buffer[pos].dist_mm_q2 /4.0f;
_scan_data.push_back(dot);
osc::OutboundPacketStream p(lidbuffer, OUTPUT_BUFFER_SIZE);
p << osc::BeginMessage(SENDPREFIX)
<< dot.angle << (int)dot.dist << osc::EndMessage;
transmitSocket.Send(p.Data(), p.Size());
}
It works, but as I've move to a higher resolution sensor, I'm having issues with dropped data, so I would like to build the data into a single message or a bundle. As a reference, each revolution of the sensor is about 800 angle/distance pairs.
This is what I thought would work, based on the oscpack example It compiles, but crashes on opening:
As a big message:
UdpTransmitSocket transmitSocket(IpEndpointName(ADDRESS, PORT));
char lidbuffer[OUTPUT_BUFFER_SIZE];
//make a new message
osc::OutboundPacketStream p(lidbuffer, OUTPUT_BUFFER_SIZE);
p << osc::BeginMessage(SENDPREFIX);
for (int pos = 0; pos < (int)count; ++pos) {
scanDot dot;
if (!buffer[pos].dist_mm_q2) continue;
dot.quality = buffer[pos].quality;
dot.angle = buffer[pos].angle_z_q14 * 90.f / 16384.f;
dot.dist = buffer[pos].dist_mm_q2 /4.0f;
_scan_data.push_back(dot);
//add more data into the message
p << dot.angle << (int)dot.dist;
}
//send the message
p << osc::EndMessage;
transmitSocket.Send(p.Data(), p.Size());
As a bundle
UdpTransmitSocket transmitSocket(IpEndpointName(ADDRESS, PORT));
char lidbuffer[OUTPUT_BUFFER_SIZE];
osc::OutboundPacketStream p(lidbuffer, OUTPUT_BUFFER_SIZE);
//make a bundle
p << osc::BeginBundleImmediate;
for (int pos = 0; pos < (int)count; ++pos) {
scanDot dot;
if (!buffer[pos].dist_mm_q2) continue;
dot.quality = buffer[pos].quality;
dot.angle = buffer[pos].angle_z_q14 * 90.f / 16384.f;
dot.dist = buffer[pos].dist_mm_q2 /4.0f;
_scan_data.push_back(dot);
//add a message to the bundle
p << osc::BeginMessage(SENDPREFIX) << dot.angle << (int)dot.dist << osc::EndMessage;;
}
//send the bundle
p << osc::EndBundle;
transmitSocket.Send(p.Data(), p.Size());
Both compile but crash.
I've read several things, but << assignment methods aren't getting through and I'm guessing it is something really simple.
Caveats:
I know people have written wrappers for this driver code in many other languages, but I would like to stick with this one if possible
I would like to keep it as OSC/UDP
Any guidance is appreciated

Keep Lua state in a C++ environment to limit context switches

I'm having fun coding simple OpenGL demos and I recently decided to use Lua with my C++ engine in order to change the rendering dynamically without having to recompile on and on my project. Thus I can tweak more easily the rendering algorithm. But I know that my current rendering update functions are probably far from being efficient.
For the moment, I'm transfering a matrix from C++ to Lua, modifying it in a Lua script and sending it back to my C++ rendering engine. But I'm reloading the Lua script each time I get an update call from the C++ engine, and I'm losing all of the variable context. That means I'm always starting from scratch and my rendering is far from being smooth. I include some code sample below to explain what I'm doing. I am currently learning Lua with C++ embedding, so I know I still don't have the best practices.
update.lua
function transform(m)
amplitude = 1.5
frequency = 500
phase = 0.0
r = {}
for i = 1, #m do
r[i] = {}
for j = 1, #m[i] do
if (i % 2) then
r[i][j] = amplitude * math.sin(m[i][j] + phase)
else
r[i][j] = -amplitude * math.sin(m[i][j] + phase)
end
phase = phase + 0.001
end
end
return r
end
-- called by c++
function update()
m = pull()
r = transform(m)
push(r)
end
matrix.cpp
// pull matrix from lua point of view
static int pull(lua_State * _L)
{
_push(_L, &_m);
return 1;
}
// push matrix from lua point of view
static int push(lua_State * _L)
{
// get number of arguments
int n = lua_gettop(_L);
if(1 == n) {
_pull(_L, 1, &_m);
}
return 1;
}
void matrix::load_file(char * file, char * function)
{
int status;
// load the file containing the script we are going to run
status = luaL_loadfile(_L, file);
switch (status) {
case LUA_OK:
break;
case LUA_ERRFILE:
std::cout << "LUA_ERRFILE: " << lua_error(_L) << std::endl;
break;
case LUA_ERRSYNTAX:
std::cout << "LUA_ERRSYNTAX: " << lua_error(_L) << std::endl;
break;
default:
std::cout << lua_error(_L) << std::endl;
}
lua_getglobal(_L, function);
status = lua_pcall(_L, 1, 1, 0);
if (status != LUA_OK) {
std::cout << "error running file" << lua_error(_L) << std::endl;
}
}
void matrix::update()
{
load_file("lua/update.lua", "update");
}
I'm thinking of passing some arguments when calling the update() function, but I'm wondering if the C++ to Lua then back to C++ approach is correct and efficient. Especially considering the fact that I might transfer and modify huge matrix in Lua. I probably lack some embedded Lua knowledge to keep context while loading a script. Do you have some general advice on how I would improve my code ? I know that my current approach is overly complicated.
A quick fix would be to only load the file if it has been modified since the last frame:
static time_t last_modified = 0;
struct stat sbuf;
stat(file, &sbuf);
if (sbuf.st_mtime > last_modified) {
last_modified = sbuf.st_mtime;
status = luaL_loadfile(_L, file);
// etc
}
// Now call the function
lua_getglobal(_L, function);
status = lua_pcall(_L, 1, 1, 0);
OK, loading the chunk of the update() function into a global variable and having a global parameter table in the Lua script is the way to go. I achieved this using the following guidelines, and I will post the detailed steps below. Basically, loading the script entirely first ensures that all global variables are stored in the C++ context. Then storing the wanted function as an index allows us to run it again, while keeping the global variables in the script evolving on their own.
Step 1
First call luaL_loadfile once at init
Step 2
Run the script once using lua_pcall(_L, 0, 0, 0);
This ensures that the global variables, which are used as parameters in the Lua script are in memory.
Step 3
Store the Lua function. I managed to do it with the following C++ code:
void matrix::store(char * function)
{
lua_newtable(_L); // create table for functions
_idx = luaL_ref(_L, LUA_REGISTRYINDEX); // store said table in pseudo-registry
lua_rawgeti(_L, LUA_REGISTRYINDEX, _idx); // retrieve table for functions
lua_getglobal(_L, function); // retrieve function to store
if (lua_isfunction(_L, -1)) {
_f = luaL_ref(_L, -2); // store a function in the function table
}
else {
lua_pop(_L, 1);
std::cout << "can't find " << function << std::endl;
}
// table is two places up the current stack counter
lua_pop(_L, 1); // we are done with the function table, so pop it
std::cout << "idx: " << _idx << ", function: " << _f << std::endl;
}
Step 4
Call the stored function again when rendering using the following C++ function:
void matrix::run()
{
int status;
if (_f == -1) {
std::cout << "invalid function index " << _f << std::endl;
}
else {
lua_rawgeti(_L, LUA_REGISTRYINDEX, _idx); // retrieve function table
lua_rawgeti(_L, -1, _f); // retrieve function
//use function
status = lua_pcall(_L, 0, 0, 0); // 0 arguments, 0 results
if (status != LUA_OK) {
std::cout << "error running function" << lua_error(_L) << std::endl;
}
//don't forget to pop the function table from the stack
lua_pop(_L, 1);
}
}
Step 5 (optional)
If we set all the Lua parameters in a global table, we can retrieve them dynamically in C++ using the following piece of code:
void matrix::get_params(char * p)
{
lua_getglobal(_L, p);
lua_pushnil(_L);
int i = 0;
while(lua_next(_L,-2))
{
const char * key = lua_tostring(_L,-2);
double value = lua_tonumber(_L,-1);
lua_pop(_L,1);
std::cout << key << " = " << value << std::endl;
_h[i].key.assign(key);
_h[i].value = value;
i++;
}
lua_pop(_L, 1);
}
Where _his a simple dynamic structure defined as such:
typedef struct {
std::string key;
float value;
} hash;
I only use float, so this simple structure is convenient enough for my needs, and allows me to add lots of variables in my Lua script without bothering with a structure definition in C++. This way I can add as many parameters in my Lua table and do the maths when updating.
Step 6
Tweak the Lua script forever ! Et voila:
p = {
amplitude = 1.5,
frequency = 500,
phase = 0.0
}
function transform(m)
r = {}
for i = 1, #m do
r[i] = {}
for j = 1, #m[i] do
if (i % 2) then
r[i][j] = p.amplitude * math.sin(m[i][j] + p.phase)
else
r[i][j] = -p.amplitude * math.sin(m[i][j] + p.phase)
end
p.phase = p.phase + 0.001
end
end
return r
end
-- called by c++
function update()
m = pull()
r = transform(m)
push(r)
end
This solution fits my needs, but seems very complicated and inefficient. But it was a fine hacking session anyway.

Sending messages and roadside to roadside (R2R) communication in Veins

I'm new in Omnet Veins. I try to create my own application. So first of all, I have done this in the existing TraciDemo11p files (I have just kept the files name and modify the code).
In the first step, I want to make all nodes sending a HelloMsg (a new packet that I have created .msg .h and .cc).
To well understand how messages are exchanged between nodes, I launched the simulation and all is well, but I cannot realize if the messages are received by nodes or not.
This is a screenshot of what I have:
enter image description here
I followed the transmission of the message between the application, mac and phy layers. I can see that the message is successfully transmitted by node1 for example. But does the message on node[0] "packet was not detected by the card. power was under sensitivity threshold" mean that the packet was not received by node[0]?. If it is the case, how can I fix that? Also, I cannot find the source file of this message (apparently, in PhyLayer80211p.cc or BasehyLayer.cc but I cannot find it).
In the second step, I want to use two RSUs. Nodes broadcast a helloMessage and then each RSU will repeat the received signal. To clarify more, this exactly what I have:
First of all. I add another RSU to the veins example as follows:
##########################################################
# RSU SETTINGS #
# #
# #
##########################################################
*.rsu[0].mobility.x = 6490
*.rsu[0].mobility.y = 1000
*.rsu[0].mobility.z = 3
*.rsu[1].mobility.x = 7491
*.rsu[1].mobility.y = 1000
*.rsu[1].mobility.z = 3
*.rsu[*].applType = "TraCIDemoRSU11p"
*.rsu[*].appl.headerLength = 80 bit
*.rsu[*].appl.sendBeacons = false
*.rsu[*].appl.dataOnSch = false
*.rsu[*].appl.beaconInterval = 1s
*.rsu[*].appl.beaconUserPriority = 7
*.rsu[*].appl.dataUserPriority = 5
Also, I made two maxInterferenceDistance, one of the nodes and the other for the RSUs:
##########################################################
# 11p specific parameters #
# #
# NIC-Settings #
##########################################################
*.connectionManager.sendDirect = true
*.connectionManager.maxInterfDist = 1000m #2600m
*.connectionManager.drawMaxIntfDist = false #false
*.connectionManager.maxInterfDistNodes = 300m
*.connectionManager.drawMaxIntfDistNodes = false
*.**.nic.mac1609_4.useServiceChannel = false
*.**.nic.mac1609_4.txPower = 20mW
*.**.nic.mac1609_4.bitrate = 6Mbps
*.**.nic.phy80211p.sensitivity = -89dBm
*.**.nic.phy80211p.useThermalNoise = true
*.**.nic.phy80211p.thermalNoise = -110dBm
*.**.nic.phy80211p.decider = xmldoc("config.xml")
*.**.nic.phy80211p.analogueModels = xmldoc("config.xml")
*.**.nic.phy80211p.usePropagationDelay = true
*.**.nic.phy80211p.antenna = xmldoc("antenna.xml", "/root/Antenna[#id='monopole']")
To make the transmission range of RSU different on that of nodes, I made this change in the isInRange function of the baseConnectionMannager:
bool BaseConnectionManager::isInRange(BaseConnectionManager::NicEntries::mapped_type pFromNic, BaseConnectionManager::NicEntries::mapped_type pToNic)
{
double dDistance = 0.0;
if ((pFromNic->hostId == 7) || (pFromNic->hostId == 8)) {
EV<<"RSU In range from: "<<pFromNic->getName()<<" "<<pFromNic->hostId<<" to: "<<pToNic->getName()<<" "<<pToNic->hostId<<"\n";
if(useTorus) {
dDistance = sqrTorusDist(pFromNic->pos, pToNic->pos, *playgroundSize);
} else {
dDistance = pFromNic->pos.sqrdist(pToNic->pos);
}
return (dDistance <= maxDistSquared);
} else {
if(useTorus) {
dDistance = sqrTorusDist(pFromNic->pos, pToNic->pos, *playgroundSize);
} else {
dDistance = pFromNic->pos.sqrdist(pToNic->pos);
}
return (dDistance <= maxDistSquaredNodes);
}
}
Where node IDs 7 and 8 are the RSUs in the scenario I run.
In addition, I have the TraciDemo11p (for nodes) and TraciDemoRSU11p (for RSUs) modified as follow:
- In the TraciDemo11p, nodes when enter the network broadcast a Hello message to all their neighbors. The code is:
void TraCIDemo11p::initialize(int stage) {
BaseWaveApplLayer::initialize(stage);
if (stage == 0) {
HelloMsg *msg = createMsg();
SendHello(msg);
}
}
HelloMsg* TraCIDemo11p::createMsg() {
int source_id = myId;
double t0 = 0;
int port = 0;
char msgName[20];
sprintf(msgName, "send Hello from %d at %f from gate %d",source_id, t0, port);
HelloMsg* msg = new HelloMsg(msgName);
populateWSM(msg);
return msg;
}
void TraCIDemo11p::SendHello(HelloMsg* msg) {
findHost()->getDisplayString().updateWith("r=16,green");
msg->setSource_id(myId);
cMessage* mm = dynamic_cast<cMessage*>(msg);
scheduleAt(simTime() + 10 + uniform(0.01, 0.02), mm);
}
void TraCIDemo11p::handleSelfMsg(cMessage* msg) {
if (dynamic_cast<HelloMsg*>(msg)) {
HelloMsg* recv = dynamic_cast<HelloMsg*>(msg);
ASSERT(recv);
int sender = recv->getSource_id();
if (sender == myId) {
EV <<myId <<" broadcasting Hello Message \n";
recv->setT0(SIMTIME_DBL(simTime()));
sendDown(recv->dup());
}
}
else {
BaseWaveApplLayer::handleSelfMsg(msg);
}
}
void TraCIDemo11p::onHelloMsg(HelloMsg* hmsg) {
if ((hmsg->getSource_id() == 7) || (hmsg->getSource_id() == 8)) {
EV <<"Node: "<<myId<<" receiving HelloMsg from rsu: "<<hmsg->getSource_id()<<"\n";
} else {
EV <<"Node: "<<myId<<" receiving HelloMsg "<<hmsg->getKind()<<" from node: "<<hmsg->getSource_id()<<"\n";
NBneighbors++;
neighbors.push_back(hmsg->getSource_id());
EV <<"Node: "<<myId<<" neighbors list: ";
list<int>::iterator it = neighbors.begin();
while (it != neighbors.end()) {
EV <<*it<<" ";
it++;
}
}
}
void TraCIDemo11p::handlePositionUpdate(cObject* obj) {
BaseWaveApplLayer::handlePositionUpdate(obj);
}
On the other hand, RSUs just repeat the message they received from nodes. So, I have on the TraciDemoRSU11p:
void TraCIDemoRSU11p::onHelloMsg(HelloMsg* hmsg) {
if ((hmsg->getSource_id() != 7) && (hmsg->getSource_id() != 8))
{
EV <<"RSU: "<<myId<<" receiving HelloMsg "<<hmsg->getKind()<<" from node: "<<hmsg->getSource_id()<<" at: "<<SIMTIME_DBL(simTime())<<" \n";
//HelloMsg *msg = createMsg();
//SendHello(msg);
hmsg->setSenderAddress(myId);
hmsg->setSource_id(myId);
sendDelayedDown(hmsg->dup(), 2 + uniform(0.01,0.2));
}
else {
EV<<"Successful connection between RSUs \n";
EV <<"RSU: "<<myId<<" receiving HelloMsg "<<hmsg->getKind()<<" from node: "<<hmsg->getSource_id()<<"\n";
}
}
After the execution of this code, I can see:
a few numbers of vehicles receiving the hello message from their neighbors.
also, just a few messages were received by the two RSUs.
Each RSUs repeats the signal it receives, but there is no communication between the two RSU, which are supposed in the transmission of one another.
And always I have a lot of this message "packet was not detected by the card. power was under sensitivity threshold" printed on my screen.
Is there any problem in the transmission range or it is a question of interference? Also, I would like to mention that in the analysis there is no packet loss.
Thanks in advance.
Please help.

Encountering "ReadBlockFromDisk: Errors in block header at CBlockDiskPos(nFile=0, nPos=8)" error when I ran modified litecoin chainparams.cpp

First: I am a newbite to altcoin development, next to generate an altcoin from litecoin,
1- I have made a clone of litecoin using git clone https://githubcom/litecoin-project/lotecoin.git
2- I changed some of chain and coin parameters in chainparams.cpp as below:
// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2009-2015 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "chainparams.h"
#include "consensus/merkle.h"
#include "tinyformat.h"
#include "util.h"
#include "utilstrencodings.h"
#include <assert.h>
#include "chainparamsseeds.h"
#include "arith_uint256.h"
static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
{
CMutableTransaction txNew;
txNew.nVersion = 1;
txNew.vin.resize(1);
txNew.vout.resize(1);
txNew.vin[0].scriptSig = CScript() << 486604799 << CScriptNum(4) << std::vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
txNew.vout[0].nValue = genesisReward;
txNew.vout[0].scriptPubKey = genesisOutputScript;
CBlock genesis;
genesis.nTime = nTime;
genesis.nBits = nBits;
genesis.nNonce = nNonce;
genesis.nVersion = nVersion;
genesis.vtx.push_back(MakeTransactionRef(std::move(txNew)));
genesis.hashPrevBlock.SetNull();
genesis.hashMerkleRoot = BlockMerkleRoot(genesis);
return genesis;
}
/**
* Build the genesis block. Note that the output of its generation
* transaction cannot be spent since it did not originally exist in the
* database.
*
* CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, *nNonce=2083236893, vtx=1)
* CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0)
* CTxIn(COutPoint(000000, -1), coinbase *04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420**666f722062616e6b73)
* CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B)
* vMerkleTree: 4a5e1e
*/
static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
{
const char* pszTimestamp = "Tehran Times, Stonica wins finally";
const CScript genesisOutputScript = CScript() << ParseHex("040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9") << OP_CHECKSIG;
return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward);
}
void CChainParams::UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout)
{
consensus.vDeployments[d].nStartTime = nStartTime;
consensus.vDeployments[d].nTimeout = nTimeout;
}
/**
* Main network
*/
/**
* What makes a good checkpoint block?
* + Is surrounded by blocks with reasonable timestamps
* (no blocks before with a timestamp after, none after with
* timestamp before)
* + Contains no strange transactions
*/
class CMainParams : public CChainParams {
public:
CMainParams() {
strNetworkID = "main";
consensus.nSubsidyHalvingInterval = 840000;
consensus.BIP34Height = 710000;
consensus.BIP34Hash = uint256S("00000000b2c50d03d4d0bdd38681775ce522f137518145d6b3c913b7dd4423e5");
consensus.BIP65Height = 918684; // bab3041e8977e0dc3eeff63fe707b92bde1dd449d8efafb248c27c8264cc311a
consensus.BIP66Height = 811879; // 7aceee012833fa8952f8835d8b1b3ae233cd6ab08fdb27a771d2bd7bdc491894
consensus.powLimit = uint256S("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.nPowTargetTimespan = 3.5 * 24 * 60 * 60; // 3.5 days
consensus.nPowTargetSpacing = 2.5 * 60;
consensus.fPowAllowMinDifficultyBlocks = false;
consensus.fPowNoRetargeting = false;
consensus.nRuleChangeActivationThreshold = 6048; // 75% of 8064
consensus.nMinerConfirmationWindow = 8064; // nPowTargetTimespan / nPowTargetSpacing * 4
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008
// Deployment of BIP68, BIP112, and BIP113.
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0;
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1485561600; // January 28, 2017
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 1517356801; // January 31st, 2018
// Deployment of SegWit (BIP141, BIP143, and BIP147)
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1;
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 1485561600; // January 28, 2017
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1517356801; // January 31st, 2018
// The best chain should have at least this much work.
consensus.nMinimumChainWork = uint256S("0x00000000000000000000000000000000000000000000000ba50a60f8b56c7fe0");
// By default assume that the signatures in ancestors of this block are valid.
consensus.defaultAssumeValid = uint256S("0x29c8c00e1a5f446a6364a29633d3f1ee16428d87c8d3851a1c570be8170b04c2"); //1259849
/**
* The message start string is designed to be unlikely to occur in normal data.
* The characters are rarely used upper ASCII, not valid as UTF-8, and produce
* a large 32-bit integer with any alignment.
*/
pchMessageStart[0] = 0x0b;
pchMessageStart[1] = 0xd0;
pchMessageStart[2] = 0xb6;
pchMessageStart[3] = 0xdb;
nDefaultPort = 9335;
nPruneAfterHeight = 100000;
//static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
genesis = CreateGenesisBlock(1511279793, 1251189192, 0x1d00ffff , 1, 50 * COIN);
consensus.hashGenesisBlock = genesis.GetHash();
/*
// calculate Genesis Block
// Reset genesis
consensus.hashGenesisBlock = uint256S("0x");
std::cout << std::string("Begin calculating Mainnet Genesis Block:\n");
if (true && (genesis.GetHash() != consensus.hashGenesisBlock)) {
LogPrintf("Calculating Mainnet Genesis Block:\n");
arith_uint256 hashTarget = arith_uint256().SetCompact(genesis.nBits);
uint256 hash;
genesis.nNonce = 0;
// This will figure out a valid hash and Nonce if you're
// creating a different genesis block:
// uint256 hashTarget = CBigNum().SetCompact(genesis.nBits).getuint256();
// hashTarget.SetCompact(genesis.nBits, &fNegative, &fOverflow).getuint256();
// while (genesis.GetHash() > hashTarget)
while (UintToArith256(genesis.GetHash()) > hashTarget)
{
++genesis.nNonce;
if (genesis.nNonce == 0)
{
LogPrintf("NONCE WRAPPED, incrementing time");
std::cout << std::string("NONCE WRAPPED, incrementing time:\n");
++genesis.nTime;
}
if (genesis.nNonce % 10000 == 0)
{
LogPrintf("Mainnet: nonce %08u: hash = %s \n", genesis.nNonce, genesis.GetHash().ToString().c_str());
// std::cout << strNetworkID << " nonce: " << genesis.nNonce << " time: " << genesis.nTime << " hash: " << genesis.GetHash().ToString().c_str() << "\n";
}
}
std::cout << "Mainnet ---\n";
std::cout << " nonce: " << genesis.nNonce << "\n";
std::cout << " time: " << genesis.nTime << "\n";
std::cout << " hash: " << genesis.GetHash().ToString().c_str() << "\n";
std::cout << " merklehash: " << genesis.hashMerkleRoot.ToString().c_str() << "\n";
// Mainnet --- nonce: 296277 time: 1390095618 hash: 000000bdd771b14e5a031806292305e563956ce2584278de414d9965f6ab54b0
}
std::cout << std::string("Finished calculating Mainnet Genesis Block:\n");
*/
//printf("%s\n",consensus.hashGenesisBlock.Tostring().c_str());
std::cout << std::string("ENTER:\n");
assert(consensus.hashGenesisBlock == uint256S("0x00000000b2c50d03d4d0bdd38681775ce522f137518145d6b3c913b7dd4423e5"));
assert(genesis.hashMerkleRoot == uint256S("0xf8621e34b0dcd43361fe589702e06aa79992229bfbca57d058d8561635c30fbe"));
std::cout << std::string("PASSED:\n");
printf("min nBit: %08x\n", consensus.powLimit);
// Note that of those with the service bits flag, most only support a subset of possible options
//vSeeds.emplace_back("seed-a.stonicacoin.loshan.co.uk", true);
//vSeeds.emplace_back("dnsseed.thrasher.io", true);
//vSeeds.emplace_back("dnsseed.stonicacointools.com", true);
//vSeeds.emplace_back("dnsseed.stonicacoinpool.org", true);
//vSeeds.emplace_back("dnsseed.koin-project.com", false);
base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,127);
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,65);
base58Prefixes[SCRIPT_ADDRESS2] = std::vector<unsigned char>(1,56);
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,176);
base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x88, 0xB2, 0x1E};
base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x88, 0xAD, 0xE4};
vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_main, pnSeed6_main + ARRAYLEN(pnSeed6_main));
fDefaultConsistencyChecks = false;
fRequireStandard = true;
fMineBlocksOnDemand = false;
checkpointData = (CCheckpointData) {
{
{ 0, uint256S("0x00000000b2c50d03d4d0bdd38681775ce522f137518145d6b3c913b7dd4423e5")},
}
};
chainTxData = ChainTxData{
// Data as of block db42d00d824950a125f9b08b6b6c282c484781562fa8b3bd29d6ce4a2627c348 (height 1259851).
1502955334, // * UNIX timestamp of last known number of transactions
1, // * total number of transactions between genesis and that timestamp
// (the tx=... number in the SetBestChain debug.log lines)
0.00 // * estimated number of transactions per second after that timestamp
};
}
};
/**
* Testnet (v3)
*/
class CTestNetParams : public CChainParams {
public:
CTestNetParams() {
strNetworkID = "test";
consensus.nSubsidyHalvingInterval = 840000;
consensus.BIP34Height = 76;
consensus.BIP34Hash = uint256S("8075c771ed8b495ffd943980a95f702ab34fce3c8c54e379548bda33cc8c0573");
consensus.BIP65Height = 76; // 8075c771ed8b495ffd943980a95f702ab34fce3c8c54e379548bda33cc8c0573
consensus.BIP66Height = 76; // 8075c771ed8b495ffd943980a95f702ab34fce3c8c54e379548bda33cc8c0573
consensus.powLimit = uint256S("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.nPowTargetTimespan = 3.5 * 24 * 60 * 60; // 3.5 days
consensus.nPowTargetSpacing = 2.5 * 60;
consensus.fPowAllowMinDifficultyBlocks = true;
consensus.fPowNoRetargeting = false;
consensus.nRuleChangeActivationThreshold = 1512; // 75% for testchains
consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008
// Deployment of BIP68, BIP112, and BIP113.
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0;
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1483228800; // January 1, 2017
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 1517356801; // January 31st, 2018
// Deployment of SegWit (BIP141, BIP143, and BIP147)
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1;
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 1483228800; // January 1, 2017
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1517356801; // January 31st, 2018
// The best chain should have at least this much work.
consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000000000000000364b0cbc3568");
// By default assume that the signatures in ancestors of this block are valid.
consensus.defaultAssumeValid = uint256S("0xad8ff6c2f5580d2b50bd881e11312425ea84fa99f322bf132beb722f97971bba"); //153490
pchMessageStart[0] = 0xfd;
pchMessageStart[1] = 0xd2;
pchMessageStart[2] = 0xc8;
pchMessageStart[3] = 0xf1;
nDefaultPort = 19335;
nPruneAfterHeight = 1000;
genesis = CreateGenesisBlock(1511279793, 0, 0x1d00ffff , 1, 50 * COIN);
consensus.hashGenesisBlock = genesis.GetHash();
//assert(consensus.hashGenesisBlock == uint256S("0x"));
//assert(genesis.hashMerkleRoot == uint256S("0x"));
vFixedSeeds.clear();
vSeeds.clear();
// nodes with support for servicebits filtering should be at the top
//vSeeds.emplace_back("testnet-seed.stonicacointools.com", true);
//vSeeds.emplace_back("seed-b.stonicacoin.loshan.co.uk", true);
//vSeeds.emplace_back("dnsseed-testnet.thrasher.io", true);
base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,111);
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,196);
base58Prefixes[SCRIPT_ADDRESS2] = std::vector<unsigned char>(1,58);
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,239);
base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF};
base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94};
vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_test, pnSeed6_test + ARRAYLEN(pnSeed6_test));
fDefaultConsistencyChecks = false;
fRequireStandard = false;
fMineBlocksOnDemand = false;
checkpointData = (CCheckpointData) {
{
{0, uint256S("")},
}
};
chainTxData = ChainTxData{
// Data as of block 3351b6229da00b47ad7a8d7e1323b0e2874744b5296e3d6448293463ab758624 (height 153489)
//1502953751,
//382986,
//0.01
};
}
};
/**
* Regression test
*/
class CRegTestParams : public CChainParams {
public:
CRegTestParams() {
strNetworkID = "regtest";
consensus.nSubsidyHalvingInterval = 150;
consensus.BIP34Height = 100000000; // BIP34 has not activated on regtest (far in the future so block v1 are not rejected in tests)
consensus.BIP34Hash = uint256();
consensus.BIP65Height = 1351; // BIP65 activated on regtest (Used in rpc activation tests)
consensus.BIP66Height = 1251; // BIP66 activated on regtest (Used in rpc activation tests)
consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.nPowTargetTimespan = 3.5 * 24 * 60 * 60; // two weeks
consensus.nPowTargetSpacing = 2.5 * 60;
consensus.fPowAllowMinDifficultyBlocks = true;
consensus.fPowNoRetargeting = true;
consensus.nRuleChangeActivationThreshold = 108; // 75% for testchains
consensus.nMinerConfirmationWindow = 144; // Faster than normal for regtest (144 instead of 2016)
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 0;
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 999999999999ULL;
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0;
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 0;
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 999999999999ULL;
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1;
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 0;
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 999999999999ULL;
// The best chain should have at least this much work.
consensus.nMinimumChainWork = uint256S("0x00");
// By default assume that the signatures in ancestors of this block are valid.
consensus.defaultAssumeValid = uint256S("0x00");
pchMessageStart[0] = 0xfa;
pchMessageStart[1] = 0xbf;
pchMessageStart[2] = 0xb5;
pchMessageStart[3] = 0xda;
nDefaultPort = 19444;
nPruneAfterHeight = 1000;
genesis = CreateGenesisBlock(1511279793, 0, 0x1d00ffff , 1, 50 * COIN);
consensus.hashGenesisBlock = genesis.GetHash();
assert(consensus.hashGenesisBlock == uint256S("0x9"));
assert(genesis.hashMerkleRoot == uint256S("0x"));
vFixedSeeds.clear(); //!< Regtest mode doesn't have any fixed seeds.
vSeeds.clear(); //!< Regtest mode doesn't have any DNS seeds.
fDefaultConsistencyChecks = true;
fRequireStandard = false;
fMineBlocksOnDemand = true;
checkpointData = (CCheckpointData) {
{
{0, uint256S("530827f38f93b43ed12af0b3ad25a288dc02ed74d6d7857862df51fc56c416f9")},
}
};
chainTxData = ChainTxData{
0,
0,
0
};
base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,111);
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,196);
base58Prefixes[SCRIPT_ADDRESS2] = std::vector<unsigned char>(1,58);
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,239);
base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF};
base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94};
}
};
static std::unique_ptr<CChainParams> globalChainParams;
const CChainParams &Params() {
assert(globalChainParams);
return *globalChainParams;
}
std::unique_ptr<CChainParams> CreateChainParams(const std::string& chain)
{
if (chain == CBaseChainParams::MAIN)
return std::unique_ptr<CChainParams>(new CMainParams());
else if (chain == CBaseChainParams::TESTNET)
return std::unique_ptr<CChainParams>(new CTestNetParams());
else if (chain == CBaseChainParams::REGTEST)
return std::unique_ptr<CChainParams>(new CRegTestParams());
throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain));
}
void SelectParams(const std::string& network)
{
SelectBaseParams(network);
globalChainParams = CreateChainParams(network);
}
void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout)
{
globalChainParams->UpdateVersionBitsParameters(d, nStartTime, nTimeout);
}
As you may know the bitcoin developers has omitted the genesis block mining code from source code published in github, but I fortunately found some piece of code in related blogs and it worked, then I have calculated the new Genesis hash, Merkelroot hash and Nonce and put into code as you can see above.
The code was compiled correctly and I have not received Assertion failed message for Genesis block but I received another error which you can see in debug.log as below:
2017-12-15 07:31:33
2017-12-15 07:31:33 Stonicacoin version v0.15.0.1-gba8ed3a93be
2017-12-15 07:31:33 InitParameterInteraction: parameter interaction: -whitelistforcerelay=1 -> setting -whitelistrelay=1
2017-12-15 07:31:33 Assuming ancestors of block 29c8c00e1a5f446a6364a29633d3f1ee16428d87c8d3851a1c570be8170b04c2 have valid signatures.
2017-12-15 07:31:33 Using the 'standard' SHA256 implementation
2017-12-15 07:31:33 Using RdRand as an additional entropy source
2017-12-15 07:31:33 Default data directory /home/kevin/.stonicacoin
2017-12-15 07:31:33 Using data directory /home/kevin/.stonicacoin
2017-12-15 07:31:33 Using config file /home/kevin/.stonicacoin/stonicacoin.conf
2017-12-15 07:31:33 Using at most 125 automatic connections (1024 file descriptors available)
2017-12-15 07:31:33 Using 16 MiB out of 32/2 requested for signature cache, able to store 524288 elements
2017-12-15 07:31:33 Using 16 MiB out of 32/2 requested for script execution cache, able to store 524288 elements
2017-12-15 07:31:33 Using 8 threads for script verification
2017-12-15 07:31:33 scheduler thread start
2017-12-15 07:31:33 HTTP: creating work queue of depth 16
2017-12-15 07:31:33 No rpcpassword set - using random cookie authentication
2017-12-15 07:31:33 Generated RPC authentication cookie /home/kevin/.stonicacoin/.cookie
2017-12-15 07:31:33 HTTP: starting 4 worker threads
2017-12-15 07:31:33 Cache configuration:
2017-12-15 07:31:33 * Using 2.0MiB for block index database
2017-12-15 07:31:33 * Using 8.0MiB for chain state database
2017-12-15 07:31:33 * Using 440.0MiB for in-memory UTXO set (plus up to 4.8MiB of unused mempool space)
2017-12-15 07:31:33 init message: Loading block index...
2017-12-15 07:31:33 Opening LevelDB in /home/kevin/.stonicacoin/blocks/index
2017-12-15 07:31:33 Opened LevelDB successfully
2017-12-15 07:31:33 Using obfuscation key for /home/kevin/.stonicacoin/blocks/index: 0000000000000000
2017-12-15 07:31:33 LoadBlockIndexDB: last block file = 0
2017-12-15 07:31:33 LoadBlockIndexDB: last block file info: CBlockFileInfo(blocks=0, size=0, heights=0...0, time=1970-01-01...1970-01-01)
2017-12-15 07:31:33 Checking all blk files are present...
2017-12-15 07:31:33 LoadBlockIndexDB: transaction index disabled
2017-12-15 07:31:33 Initializing databases...
2017-12-15 07:31:33 Pre-allocating up to position 0x1000000 in blk00000.dat
2017-12-15 07:31:33 Opening LevelDB in /home/kevin/.stonicacoin/chainstate
2017-12-15 07:31:33 Opened LevelDB successfully
2017-12-15 07:31:33 Wrote new obfuscate key for /home/kevin/.stonicacoin/chainstate: 77f259e28117a4e1
2017-12-15 07:31:33 Using obfuscation key for /home/kevin/.stonicacoin/chainstate: 77f259e28117a4e1
2017-12-15 07:31:33 init message: Rewinding blocks...
2017-12-15 07:31:33 block index 11ms
2017-12-15 07:31:33 No wallet support compiled in!
2017-12-15 07:31:33 ERROR: ReadBlockFromDisk: Errors in block header at CBlockDiskPos(nFile=0, nPos=8)
2017-12-15 07:31:33 *** Failed to read block
2017-12-15 07:31:33 Error: Error: A fatal internal error occurred, see debug.log for details
I found that this error(eg. ERROR: ReadBlockFromDisk: Errors in block header at CBlockDiskPos(nFile=0, nPos=8) ) occur in CheckProofOfWork function which is in pow.cpp, Any recommendation is appreciated.
After struggling too much I finally solve the issue:
1)
consensus.powLimit = uint256S("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
should be set to a lower limit like
consensus.powLimit = uint256S("00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
and set genesis.nBits to 0x1f00ffff when in CreateGenesisBlock function like
genesis = CreateGenesisBlock(1519394018, 6446, 0x1f0fffff, 1, 1 * COIN);
For Testnet I used 0x1f0fffff.
2) For Bitcoin v0.15+ the following genesis block generating code should be used:
// calculate Genesis Block
// Reset genesis
consensus.hashGenesisBlock = uint256S("0x");
std::cout << std::string("Begin calculating Mainnet Genesis Block:\n");
if (true && (genesis.GetHash(consensus) != consensus.hashGenesisBlock)) {
// LogPrintf("Calculating Mainnet Genesis Block:\n");
arith_uint256 hashTarget = arith_uint256().SetCompact(genesis.nBits);
uint256 hash;
genesis.nNonce = ArithToUint256(0);
while (UintToArith256(genesis.GetHash(consensus)) > hashTarget)
{
genesis.nNonce = ArithToUint256(UintToArith256(genesis.nNonce) + 1);
if (genesis.nNonce == ArithToUint256(arith_uint256(0)))
{
LogPrintf("NONCE WRAPPED, incrementing time");
std::cout << std::string("NONCE WRAPPED, incrementing time:\n");
++genesis.nTime;
}
if ((int)genesis.nNonce.GetUint64(0) % 10000 == 0)
{
std::cout << strNetworkID << " hashTarget: " << hashTarget.ToString() << " nonce: " << genesis.nNonce.ToString() << " time: " << genesis.nTime << " hash: " << genesis.GetHash(consensus).ToString().c_str() << "\r";
}
}
std::cout << "Mainnet ---\n";
std::cout << " nonce: " << genesis.nNonce.ToString() << "\n";
std::cout << " time: " << genesis.nTime << "\n";
std::cout << " hash: " << genesis.GetHash(consensus).ToString().c_str() << "\n";
std::cout << " merklehash: " << genesis.hashMerkleRoot.ToString().c_str() << "\n";
}
std::cout << std::string("Finished calculating Mainnet Genesis Block:\n");
For the older codebases the genesis block generating code that #Hossein Mirheydari given is working. Actually you should check
genesis.nNonce = ArithToUint256(arith_uint256(nNonce));
definition in
static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward);
function to see if it's given as above or as
genesis.nNonce = nNonce;
If it's given as the latter one then use #Hossein Mirheydari's genesis block generation code. If it's given with ArithToUint256() function use the genesis block generation code I pasted above.
3) This genesis block generation should be done for Mainnet and Testnet seperately. Regtest does not need a genesis block generation since it's pow limit is so small (but you may want to do it anyway just to be sure of everything works fine) and so
printf("TEST GENESIS HASH: %s\n",consensus.hashGenesisBlock.ToString().c_str());
printf("TEST MERKLE ROOT: %s\n",genesis.hashMerkleRoot.ToString().c_str());
assert(consensus.hashGenesisBlock == uint256S("0x0009b0d830d5e13f7a39dd6c30cae59ff95e1a4aa4fc22435dc1fcb92561cd8e"));
assert(genesis.hashMerkleRoot == uint256S("0xf1552bf3d58facdc6d7ec8461aff6b0560d20eb16e41749b9f8f5a7eaa1220fc"));
inserting the printed consensus.hashGenesisBlock and genesis.hashMerkleRoot into
assert(consensus.hashGenesisBlock == uint256S("0x0009b0d830d5e13f7a39dd6c30cae59ff95e1a4aa4fc22435dc1fcb92561cd8e"));
assert(genesis.hashMerkleRoot == uint256S("0xf1552bf3d58facdc6d7ec8461aff6b0560d20eb16e41749b9f8f5a7eaa1220fc"));
statements works.
4) If you have
consensus.powLimitStart = uint256S("0000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.powLimitLegacy = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
like the ones in Bitcoin Gold (which I now am using) use the same pow limit as consensus.powLimit.
Thus, with genesis generation code, genesis block is generated. With low pow limit, genesis block be in pow range and so no PoW validation error will occur anymore.
I hope this will help.
On the main branch at this time the solution for me was to change the GetHash() to GetPoWHash(). I also followed the answer of #Bedri Ozgur Guler for the PoWLimit and nBits:
consensus.hashGenesisBlock = uint256S("0x");
std::cout << std::string("Begin calculating Mainnet Genesis Block:\n");
if (true && (genesis.GetHash() != consensus.hashGenesisBlock)) {
LogPrintf("Calculating Mainnet Genesis Block:\n");
arith_uint256 hashTarget = arith_uint256().SetCompact(genesis.nBits);
uint256 hash;
genesis.nNonce = 0;
while (UintToArith256(genesis.GetPoWHash()) > hashTarget) // ---> Here GetPoWHash() !!
{
++genesis.nNonce;
if (genesis.nNonce == 0)
{
LogPrintf("NONCE WRAPPED, incrementing time");
std::cout << std::string("NONCE WRAPPED, incrementing time:\n");
++genesis.nTime;
}
if (genesis.nNonce % 10000 == 0)
{
LogPrintf("Mainnet: nonce %08u: hash = %s \n", genesis.nNonce, genesis.GetHash().ToString().c_str());
// std::cout << strNetworkID << " nonce: " << genesis.nNonce << " time: " << genesis.nTime << " hash: " << genesis.GetHash().ToString().c_str() << "\n";
}
}
std::cout << "Mainnet ---\n";
std::cout << " nonce: " << genesis.nNonce << "\n";
std::cout << " time: " << genesis.nTime << "\n";
std::cout << " hash: " << genesis.GetHash().ToString().c_str() << "\n"; // The hash for the assert is GetHash()
std::cout << " merklehash: " << genesis.hashMerkleRoot.ToString().c_str() << "\n";
// Mainnet --- nonce: 296277 time: 1390095618 hash: 000000bdd771b14e5a031806292305e563956ce2584278de414d9965f6ab54b0
}
std::cout << std::string("Finished calculating Mainnet Genesis Block:\n");
Looking in the file validation.cpp on the method ReadBlockFromDisk I found that the hash that must pass the CheckProofOfWork is the PoWHash
bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos, const Consensus::Params& consensusParams)
{
// ...
// Check the header
if (!CheckProofOfWork(block.GetPoWHash(), block.nBits, consensusParams))
return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString());
}
EDIT: Tested with the litecoin PoWLimit and nBits values and It worked.
consensus.powLimit = uint256S("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
genesis = CreateGenesisBlock(1619494752, 721332, 0x1e0ffff0, 1, 50 * COIN);
FreddyJS, genesis.GetPoWHash() worked nicely for litecoin, the hashes match what I would get with GenesisH0. But unfortunately it doesn't work on another coin I'm testing, gives an error on compilation. Any ideas?
error: no matching function for call to ‘CBlock::GetPoWHash()’
After some digging, the code is different than litecoin. In validation.cpp:
// Check the header
if (!CheckProofOfWork(block.GetPoWHash(nHeight), block.nBits, consensusParams))
return error("ReadBlockFromDisk: Errors in block header at %s, %d", pos.ToString(), nHeight);
GetPoWHash(nHeight) vs GetPoWHash() in litecoin.
This is code of Raptoreum
https://github.com/Raptor3um/raptoreum/blob/master/src/chainparams.cpp
Them try debug Dash to find genesis block hash
Them change only Time
static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
{
const char* pszTimestamp = "The Times 22/Jan/2018 Raptoreum is name of the game for new generation of firms";
const CScript genesisOutputScript = CScript() << ParseHex("040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9") << OP_CHECKSIG;
return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward);
}
The Dask use X11
###
static void FindMainNetGenesisBlock(uint32_t nTime, uint32_t nBits, const char* network)
{
CBlock block = CreateGenesisBlock(nTime, 0, nBits, 4, 5000 * COIN);
arith_uint256 bnTarget;
bnTarget.SetCompact(block.nBits);
for (uint32_t nNonce = 0; nNonce < UINT32_MAX; nNonce++) {
block.nNonce = nNonce;
uint256 hash = block.GetPOWHash();
if (nNonce % 48 == 0) {
printf("\nrnonce=%d, pow is %s\n", nNonce, hash.GetHex().c_str());
}
if (UintToArith256(hash) <= bnTarget) {
printf("\n%s net\n", network);
printf("\ngenesis is %s\n", block.ToString().c_str());
printf("\npow is %s\n", hash.GetHex().c_str());
printf("\ngenesisNonce is %d\n", nNonce);
std::cout << "Genesis Merkle " << block.hashMerkleRoot.GetHex() << std::endl;
return;
}
}
// This is very unlikely to happen as we start the devnet with a very low difficulty. In many cases even the first
// iteration of the above loop will give a result already
error("%sNetGenesisBlock: could not find %s genesis block",network, network);
assert(false);
}
###
It seems the -reindex parameter solves avoids the issue and gives the main reason of error which is Genesis Block does not have valid PoW. It is suggested in BITCOIN CORE CRASHED #8081 (https://github.com/bitcoin/bitcoin/issues/8081) for a solution for the issue of a corrupted blockchain data:
sipa commented on 21 May 2016
Start bitcoind or bitcoin-qt with
the -reindex command line option. This will throw away the indexes and
rebuild them from scratch, but reuse the blocks on disk in so far as
they are usable.

C++: when a message is sent using boost::asio::async_write to client, I receive repeats of the same message as the client

This is the code I am using to send a string message to the client. The problem, I think, has to do with the buffer.
void Client::send_message(std::string message) {
message = message + "\n";
std::ostream sending(&_out_buffer);
sending << message;
boost::asio::async_write(this->_socket, this->_out_buffer,
boost::bind(&Client::send_callback, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
debugger( "--> Message send to " + this->_client_name + " : " + message );
}
The problem, is that when I send a sequence of messages fairly quickly like so:
//Send the data to client
client->send_message("connected " + boost::lexical_cast<std::string>(number_of_cells));
//Send the cells
std::set<std::string> cells = it->second->get_names_of_all_non_empty_cells();
std::set<std::string>::iterator cell = cells.begin();
std::set<std::string>::iterator end = cells.end();
for(; cell != end; cell++) {
client->send_message("cell " + *cell + " " + it->second->get_cell_contents(*cell));
}
I will get this on the client side:
connected 2
connected 2
cell A1 testcontent
connected 2
cell A1 testcontent
cell B4 anothertest
When I drop the for loop in the sending code, it only sends the "connected 2" message one time. So I am thinking that this has to do with the buffer not being cleared properly or loaded up too quickly. I am unsure though. Is there a way to handle this situation? It only occurs when I send a lot of messages quickly in a block of code.
Thanks!
edit:
I found a workaround, though this doesn't fix the problem. Instead of calling the method "send_message" repeatedly, I just pulled together one large string and sent it. The new code:
//Send the data to client
std::string message = "connected " + boost::lexical_cast<std::string>(number_of_cells) + "\n";
//Send the cells
std::set<std::string> cells = it->second->get_names_of_all_non_empty_cells();
std::set<std::string>::iterator cell = cells.begin();
std::set<std::string>::iterator end = cells.end();
for(; cell != end; cell++) {
message += "cell " + *cell + " " + it->second->get_cell_contents(*cell) +"\n";
}
client->send_message(message);