Commit 7c10620b authored by rohrer's avatar rohrer
Browse files

Updated bns codebase and geo topology model.

parent 2539ba83
This diff is collapsed.
......@@ -4,7 +4,7 @@ NS_LOG_COMPONENT_DEFINE ("BNSBitcoinNode");
namespace bns {
BitcoinNode::BitcoinNode (ns3::Ipv4Address address, bool isMiner, double hashRate) : m_socket(0), m_address (address), m_isRunning(false), m_isMiner(isMiner), m_isSelfish(false), m_isByzantine(false), m_miner(nullptr), m_hashRate(hashRate), m_ttfb(0), m_ttlb(0), m_miningTime(0), m_nMinedBlocks(0), m_totalMinedBlocksSize(0), m_receivedFirstPartBlock(false), m_receivedFirstFullBlock(false)
BitcoinNode::BitcoinNode (ns3::Ipv4Address address, bool isMiner, double hashRate) : m_socket(0), m_address (address), m_isRunning(false), m_isMiner(isMiner), m_isSelfish(false), m_isByzantine(false), m_miner(nullptr), m_hashRate(hashRate), m_receivedFirstPartBlock(false), m_receivedFirstFullBlock(false), m_nMinedBlocks(0), m_totalMinedBlocksSize(0), m_region(Region::NA)
{
NS_LOG_FUNCTION(this);
m_blockchain = new Blockchain(this);
......@@ -100,11 +100,8 @@ BitcoinNode::GetHashRate()
ns3::Time
BitcoinNode::GetValidationDelay(Block& b)
{
// Adopted from Gervais et al. simulator:
const int averageBlockSizeBytes = 458263;
const double averageValidationTimeSeconds = 0.174;
double validationTime = averageValidationTimeSeconds * b.blockSize / averageBlockSizeBytes;
return ns3::Seconds(validationTime);
double validationTimeMilliSeconds = BTC_VALIDATION_INTERCEPT + (BTC_VALIDATION_SLOPE * b.blockSize);
return ns3::MilliSeconds(validationTimeMilliSeconds);
}
ns3::Time
......@@ -116,7 +113,7 @@ BitcoinNode::GetTTFB()
void
BitcoinNode::SetTTFB(ns3::Time ttfb)
{
if (m_ttfb == 0) {
if (m_ttfb.IsZero()) {
m_ttfb = ttfb;
}
......@@ -131,7 +128,7 @@ BitcoinNode::GetTTLB()
void
BitcoinNode::SetTTLB(ns3::Time ttlb)
{
if (m_ttlb == 0) {
if (m_ttlb.IsZero()) {
m_ttlb = ttlb;
}
}
......@@ -145,12 +142,23 @@ BitcoinNode::GetMiningTime()
void
BitcoinNode::SetMiningTime(ns3::Time miningTime)
{
if (m_miningTime == 0) {
if (m_miningTime.IsZero()) {
m_miningTime = miningTime;
}
}
Region
BitcoinNode::GetRegion()
{
return m_region;
}
void
BitcoinNode::SetRegion(Region reg) {
m_region = reg;
}
uint32_t
BitcoinNode::GetNMinedBlocks()
{
......
......@@ -10,6 +10,7 @@
#include "bitcoin-miner.h"
#include "blockchain.h"
#include "bitcoin-topology-helper.h"
namespace bns {
......@@ -52,6 +53,9 @@ class BitcoinNode : public ns3::Application
void SetMiningTime(ns3::Time miningTime);
ns3::Time GetMiningTime();
void SetRegion(Region reg);
Region GetRegion();
uint32_t GetNMinedBlocks();
uint32_t GetTotalMinedBlocksSize();
......@@ -86,6 +90,7 @@ class BitcoinNode : public ns3::Application
ns3::Time m_miningTime;
uint32_t m_nMinedBlocks;
uint32_t m_totalMinedBlocksSize;
Region m_region;
};
}
#endif
This diff is collapsed.
......@@ -103,11 +103,13 @@ namespace bns {
class BitcoinTopologyHelper{
public:
//Constructor
BitcoinTopologyHelper(unsigned int nLeafs, uint32_t seed);
BitcoinTopologyHelper(unsigned int nLeafs, unsigned int nMiners, uint32_t seed, std::string singleMinerRegion);
// methods do get individual nodes in the bitcoin topology
ns3::Ptr<ns3::Node> GetRouter(Region reg);
ns3::Ptr<ns3::Node> GetLeaf (Region reg, unsigned int index);
ns3::Ptr<ns3::Node> GetTopologyLeaf(unsigned int index);
ns3::NodeContainer GetRegionMiners(Region reg);
ns3::NodeContainer GetMiners();
ns3::Ipv4Address GetRouterAddress(Region reg, unsigned int index);
ns3::Ipv4Address GetLeafAddress(Region reg, unsigned int index);
ns3::Ipv4Address GetTopologyAddress(unsigned int index);
......@@ -116,7 +118,8 @@ class BitcoinTopologyHelper{
ns3::NetDeviceContainer GetIntracontinentalDevices (Region reg);
unsigned int GetNumberOfLeafs (Region reg);
std::string RegionToString(Region reg);
static std::string RegionToString(Region reg);
static Region RegionFromString(std::string regStr);
private:
/*
Each continent consists of two nodecontainers, one for the router and one for the leaf nodes.
......@@ -125,31 +128,40 @@ class BitcoinTopologyHelper{
Each continent has two ns3::Ipv4InterfaceContainers to assign IP addresses to the router and the leafs
*/
unsigned int m_nLeafs;
unsigned int m_nMiners;
std::mt19937 m_generator;
std::string m_singleMinerRegion;
// TOPOLOGY Containers
ns3::NodeContainer topologyLeafs;
ns3::NodeContainer miners;
ns3::Ipv4InterfaceContainer topologyInterfaces;
std::unordered_map<Region, unsigned int> numLeafsMap;
std::unordered_map<Region, unsigned int> numMinerMap;
std::unordered_map<Region, ns3::NodeContainer> routerMap;
std::unordered_map<Region, ns3::NodeContainer> leafMap;
std::unordered_map<Region, ns3::NodeContainer> minerMap;
std::unordered_map<Region, ns3::NetDeviceContainer> routerDevMap;
std::unordered_map<Region, ns3::NetDeviceContainer> hubDevMap;
std::unordered_map<Region, ns3::NetDeviceContainer> leafDevMap;
std::unordered_map<Region, ns3::Ipv4InterfaceContainer> routerInterfaceMap;
std::unordered_map<Region, ns3::Ipv4InterfaceContainer> leafInterfaceMap;
std::unordered_map<bns::Region, std::vector<float>> downloadRateMap;
std::unordered_map<bns::Region, std::vector<float>> uploadRateMap;
std::unordered_map<bns::Region, std::normal_distribution<double>> downloadRateDistMap;
std::unordered_map<bns::Region, std::normal_distribution<double>> uploadRateDistMap;
std::unordered_map<bns::Region, std::vector<float>> dataRateMap;
std::unordered_map<bns::Region, std::piecewise_linear_distribution<double>> dataRateDistMap;
std::unordered_map<std::pair<Region,Region>, std::piecewise_linear_distribution<double>> latencyDistMap;
std::unordered_map<bns::Region, float> avgPacketLossRateMap;
std::unordered_map<bns::Region, std::vector<float>> packetLossRatesMap;
std::unordered_map<bns::Region, std::vector<double>> linkDelayMap;
void ReadDataRates();
void ReadPacketLossRates();
void ReadLatencies();
void ReadRegionShares();
void ReadMiningShares();
void PopulateTopology ();
void PopulateRegion (Region);
......
......@@ -10,8 +10,6 @@
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"
#include "ns3/point-to-point-layout-module.h"
#include "ns3/mpi-interface.h"
#include "bitcoin-node.h"
#include "kadcast-node.h"
......@@ -24,6 +22,7 @@ NS_LOG_COMPONENT_DEFINE ("BNS");
static double totalTraffic = 0;
static void ReceivedPacket(ns3::Ptr<const ns3::Packet> packet);
void SetReceivedCallback (bns::BitcoinTopologyHelper& topology);
ns3::ApplicationContainer buildStarTopology (struct bnsParams& params);
......@@ -38,8 +37,8 @@ double median(std::vector<double> scores);
struct bnsParams {
uint32_t seed = 23;
uint16_t nHours = 12;
uint32_t nPeers = 100;
uint16_t nHours = 1;
uint32_t nPeers = 500;
uint32_t nMiners = bns::btcNumPools;
uint32_t nBootstrap = nPeers;
double blockSizeFactor = 1.0;
......@@ -49,7 +48,9 @@ struct bnsParams {
std::string topo = "geo";
// vanilla specific
bool unsolicited = false;
uint16_t nVanMaxConnIn = 117;
uint16_t nVanMaxConnOut = 8;
std::string vanPropMode = "SENDHEADERS";
// kadcast specific
uint16_t kadK = 20;
......@@ -60,9 +61,13 @@ struct bnsParams {
// star topo specific
std::string starLeafDataRate = "50Mbps";
std::string starHubDataRate = "100Gbps";
// geo topo specific
std::string singleMinerRegion = "none";
};
struct bnsResults {
bns::Region firstMinerRegion;
std::vector<double> ttfbValues;
std::vector<double> ttlbValues;
double avgTTFB = 0.0;
......@@ -104,7 +109,9 @@ main (int argc, char *argv[])
cmd.AddValue("net", "Set the network stack (vanilla or kadcast)", params.netStack);
cmd.AddValue("topo", "Set the network topology (star or geo)", params.topo);
cmd.AddValue("unsolicited", "Vanilla: Enable unsolicited block transmission.", params.unsolicited);
cmd.AddValue("vanPropMode", "Vanilla: Set block propagation mode (UNSOLICITED, SENDHEADERS, INV, CMPCTBLOCKS).", params.vanPropMode);
cmd.AddValue("vanMaxConnIn", "Vanilla: Set number of allowed inbound connections.", params.nVanMaxConnIn);
cmd.AddValue("vanMaxConnOut", "Vanilla: Set number outbound connections.", params.nVanMaxConnOut);
cmd.AddValue("kadK", "Kadcast: Set the bucket size k.", params.kadK);
cmd.AddValue("kadAlpha", "Kadcast: Set the alpha factor determining the number of parallel lookup requests.", params.kadAlpha);
......@@ -114,21 +121,41 @@ main (int argc, char *argv[])
cmd.AddValue("starLeafDataRate", "Set the data rate for each link", params.starLeafDataRate);
cmd.AddValue("starHubRate", "Set the data rate for the star network hub", params.starHubDataRate);
cmd.AddValue("singleMinerRegion", "Spawn a single miner in the region of your choice (NA, SA, EU, AF, AS, CN, OC).", params.singleMinerRegion);
cmd.Parse (argc, argv);
if (params.singleMinerRegion != "none") {
params.nMiners = 1;
params.topo = "geo";
}
if (params.nMiners != 1 && params.nMiners % bns::btcNumPools != 0) {
NS_LOG_INFO ("Please pick either a single miner, or a multiple of 16 (as there are 16 major bitcoin pools).");
NS_LOG_INFO ("Please pick either a single miner, or a multiple of 10 (as there are 10 major bitcoin pools).");
return -1;
}
if (params.nPeers < 200 && params.topo == "geo") {
NS_LOG_INFO ("Please pick at least 200 nodes for geo topology.");
return -1;
}
bns::BitcoinMiner::blockSizeFactor = params.blockSizeFactor;
bns::BitcoinMiner::blockIntervalFactor = params.blockIntervalFactor;
if (params.unsolicited) {
NS_LOG_INFO ("Enabled unsolicited block relay.");
bns::VanillaNode::vanBroadcastType = bns::BroadcastType::UNSOLICITED;
NS_LOG_INFO ("Setting propagation mode:" << params.vanPropMode);
if(params.vanPropMode == "UNSOLICITED") {
bns::VanillaNode::vanPropagationMode = bns::PropagationMode::UNSOLICITED;
} else if(params.vanPropMode == "INV") {
bns::VanillaNode::vanPropagationMode = bns::PropagationMode::INV;
} else if(params.vanPropMode == "CMPCTBLOCKS") {
bns::VanillaNode::vanPropagationMode = bns::PropagationMode::CMPCTBLOCKS;
} else {
// default SENDHEADERS
bns::VanillaNode::vanPropagationMode = bns::PropagationMode::SENDHEADERS;
}
bns::KadcastNode::kadK = params.kadK;
bns::KadcastNode::kadAlpha = params.kadAlpha;
bns::KadcastNode::kadBeta = params.kadBeta;
......@@ -166,7 +193,6 @@ main (int argc, char *argv[])
NS_LOG_INFO("Marked " << byzApps.size() << " nodes as byzantine.");
//pointToPoint.EnablePcapAll ("KadcastTest");
//ns3::Ipv4GlobalRoutingHelper g;
//ns3::Ptr<ns3::OutputStreamWrapper> routingStream = ns3::Create<ns3::OutputStreamWrapper>
// ("routes.txt", std::ios::out);
......@@ -195,82 +221,75 @@ void evaluate(struct bnsParams& params, ns3::ApplicationContainer apps)
ns3::ApplicationContainer
buildGeoTopology (struct bnsParams& params) {
ns3::ApplicationContainer apps;
bns::BitcoinTopologyHelper topology(params.nPeers, params.seed);
bns::BitcoinTopologyHelper topology(params.nPeers, params.nMiners, params.seed, params.singleMinerRegion);
SetReceivedCallback(topology);
ns3::Ptr<ns3::UniformRandomVariable> leafIndexVar = ns3::CreateObject<ns3::UniformRandomVariable> ();
leafIndexVar->SetAttribute ("Min", ns3::DoubleValue (0));
leafIndexVar->SetAttribute ("Max", ns3::DoubleValue (params.nPeers-1));
std::vector<uint32_t> miners;
uint32_t toAdd = params.nMiners;
while (toAdd > 0) {
uint32_t randIndex = leafIndexVar->GetInteger();
auto it = std::find(std::begin(miners), std::end(miners), randIndex);
if (it == std::end(miners)) {
miners.push_back(randIndex);
toAdd--;
}
}
for (uint32_t i = 0; i < params.nPeers; i++){
ns3::Ipv4Address nodeAddr = topology.GetTopologyAddress(i);
//NS_LOG_INFO("Setting up node " << topology.GetTopologyLeaf(i)->GetId() << ": " << nodeAddr);
ns3::Ptr<bns::BitcoinNode> app;
if (params.netStack == "kadcast") {
auto it = std::find(std::begin(miners), std::end(miners), i);
if (it != std::end(miners)) {// if the current index is a miner
auto index = std::distance(std::begin(miners), it); // get its index in miner list
std::vector<bns::Region> regs = {{bns::Region::NA, bns::Region::EU, bns::Region::AS, bns::Region::OC, bns::Region::AF, bns::Region::SA, bns::Region::CN}};
for (auto reg : regs) {
for (unsigned int i = 0; i < topology.GetNumberOfLeafs(reg); i++) {
ns3::NodeContainer regMinerList = topology.GetRegionMiners(reg);
ns3::NodeContainer minerList = topology.GetMiners();
ns3::Ptr<ns3::Node> node = topology.GetLeaf(reg, i);
ns3::Ipv4Address nodeAddr = topology.GetLeafAddress(reg,i);
ns3::Ptr<bns::BitcoinNode> app;
bool miner = false;
double hashRate = 0.0;
if (regMinerList.Contains(node->GetId())) {
miner = true;
auto pIsNode = [&node](ns3::Ptr<ns3::Node> n) {return node->GetId() == n->GetId();};
auto it = std::find_if(minerList.Begin(), minerList.End(), pIsNode);
if (it == minerList.End()) {
NS_LOG_INFO("Miner node not found. SHOULD NOT HAPPEN.");
continue;
}
// now it points to the node in the global list
auto index = std::distance(minerList.Begin(), it); // get its index in miner list
double poolShare;
if (params.nMiners == 1) {
poolShare = 1.0;
} else {
poolShare = bns::btcHashRateDistribution[index % bns::btcNumPools]/(params.nMiners / bns::btcNumPools);
poolShare = bns::btcHashRateDistribution[index % bns::btcNumPools]/((double) minerList.GetN() / bns::btcNumPools);
}
double hashRate = poolShare * bns::btcTotalHashRate;
app = ns3::CreateObject<bns::KadcastNode> (nodeAddr, true, hashRate);
hashRate = poolShare * bns::btcTotalHashRate;
}
if (params.netStack == "kadcast") {
app = ns3::CreateObject<bns::KadcastNode> (nodeAddr, miner, hashRate);
apps.Add(app);
} else {
app = ns3::CreateObject<bns::KadcastNode> (nodeAddr, false, 0);
app = ns3::CreateObject<bns::VanillaNode> (nodeAddr, miner, hashRate, params.nVanMaxConnIn, params.nVanMaxConnOut);
apps.Add(app);
}
} else {
auto it = std::find(std::begin(miners), std::end(miners), i);
if (it != std::end(miners)) {// if the current index is a miner
auto index = std::distance(std::begin(miners), it); // get its index in miner list
double poolShare;
if (params.nMiners == 1) {
poolShare = 1.0;
} else {
poolShare = bns::btcHashRateDistribution[index % bns::btcNumPools]/(params.nMiners / bns::btcNumPools);
topology.GetLeaf(reg,i)->AddApplication (app);
app->SetRegion(reg);
// Bootstrap
ns3::Ptr<ns3::UniformRandomVariable> leafIndexVar = ns3::CreateObject<ns3::UniformRandomVariable> ();
leafIndexVar->SetAttribute ("Min", ns3::DoubleValue (0));
leafIndexVar->SetAttribute ("Max", ns3::DoubleValue (params.nPeers-1));
std::vector<ns3::Ipv4Address> peerAddresses;
uint32_t toBootstrap = std::min(params.nBootstrap, params.nPeers);
while (toBootstrap > 0) {
uint32_t randIndex = leafIndexVar->GetInteger ();
ns3::Ipv4Address addr = topology.GetTopologyAddress(randIndex);
auto it = std::find(std::begin(peerAddresses), std::end(peerAddresses), addr);
if (it == std::end(peerAddresses)) {
peerAddresses.push_back(addr);
toBootstrap--;
}
double hashRate = poolShare * bns::btcTotalHashRate;
app = ns3::CreateObject<bns::VanillaNode> (nodeAddr, true, hashRate);
apps.Add(app);
} else {
app = ns3::CreateObject<bns::VanillaNode> (nodeAddr, false, 0);
apps.Add(app);
}
app->SetKnownAddresses(peerAddresses);
}
topology.GetTopologyLeaf(i)->AddApplication (app);
app->SetStartTime(ns3::Seconds (2.0));
//app->SetStopTime(ns3::Minutes (10.0));
}
// Bootstrap
std::vector<ns3::Ipv4Address> peerAddresses;
uint32_t toBootstrap = std::min(params.nBootstrap, params.nPeers);
while (toBootstrap > 0) {
uint32_t randIndex = leafIndexVar->GetInteger ();
ns3::Ipv4Address addr = topology.GetTopologyAddress(randIndex);
auto it = std::find(std::begin(peerAddresses), std::end(peerAddresses), addr);
if (it == std::end(peerAddresses)) {
peerAddresses.push_back(addr);
toBootstrap--;
}
}
app->SetKnownAddresses(peerAddresses);
}
return apps;
}
......@@ -338,14 +357,14 @@ ns3::ApplicationContainer buildStarTopology (struct bnsParams& params) {
if (params.nMiners % bns::btcNumPools == 0) {
double poolShare = bns::btcHashRateDistribution[i % bns::btcNumPools]/(params.nMiners / bns::btcNumPools);
double hashRate = poolShare * bns::btcTotalHashRate;
app = ns3::CreateObject<bns::VanillaNode> (nodeAddr, true, hashRate);
app = ns3::CreateObject<bns::VanillaNode> (nodeAddr, true, hashRate, params.nVanMaxConnIn, params.nVanMaxConnOut);
apps.Add(app);
} else if (params.nMiners == 1) {
app = ns3::CreateObject<bns::VanillaNode> (nodeAddr, true, bns::btcTotalHashRate);
app = ns3::CreateObject<bns::VanillaNode> (nodeAddr, true, bns::btcTotalHashRate, params.nVanMaxConnIn, params.nVanMaxConnOut);
apps.Add(app);
}
} else {
app = ns3::CreateObject<bns::VanillaNode> (nodeAddr, false, 0);
app = ns3::CreateObject<bns::VanillaNode> (nodeAddr, false, 0, params.nVanMaxConnIn, params.nVanMaxConnOut);
apps.Add(app);
}
}
......@@ -379,6 +398,7 @@ collectPropagationData(struct bnsParams& params, struct bnsResults& res, ns3::Ap
std::vector<double> ttlbs;
ns3::Ptr<bns::BitcoinNode> a;
ns3::Ptr<bns::BitcoinNode> firstMiner;
double firstMiningTime = 0;
for (uint32_t i = 0; i < apps.GetN(); ++i) {
......@@ -386,18 +406,26 @@ collectPropagationData(struct bnsParams& params, struct bnsResults& res, ns3::Ap
double maybe = a->GetMiningTime().GetMilliSeconds();
if (a->IsMiner() && maybe != 0) {
firstMiningTime = maybe;
firstMiner = a;
break;
}
}
assert(firstMiningTime != 0);
for (uint32_t i = 0; i < apps.GetN(); ++i) {
a = apps.Get(i)->GetObject<bns::BitcoinNode>();
double curMiningTime = a->GetMiningTime().GetMilliSeconds();
if (a->IsMiner() && curMiningTime != 0) {
firstMiningTime = std::min(firstMiningTime, curMiningTime);
if (curMiningTime < firstMiningTime) {
firstMiningTime = curMiningTime;
firstMiner = a;
}
}
}
bns::Region firstMinerRegion = firstMiner->GetRegion();
assert(firstMiningTime != 0);
for (uint32_t i = 0; i < apps.GetN(); ++i) {
......@@ -432,6 +460,7 @@ collectPropagationData(struct bnsParams& params, struct bnsResults& res, ns3::Ap
float coverage = (float) ttlbs.size() / (float) params.nPeers;
NS_LOG_INFO("First Miner Region: " << bns::BitcoinTopologyHelper::RegionToString(firstMinerRegion) << ".");
NS_LOG_DEBUG ("TTFBs size: " << ttfbs.size());
NS_LOG_DEBUG ("TTLBs size: " << ttlbs.size());
NS_LOG_DEBUG ("Avg. TTFB: " << avg_ttfb);
......@@ -440,6 +469,7 @@ collectPropagationData(struct bnsParams& params, struct bnsResults& res, ns3::Ap
NS_LOG_DEBUG ("Median TTLB: " << median_ttlb);
NS_LOG_DEBUG ("Coverage: " << coverage);
res.firstMinerRegion = firstMinerRegion;
res.ttfbValues = ttfbs;
res.ttlbValues = ttlbs;
res.avgTTFB = avg_ttfb;
......@@ -504,6 +534,9 @@ writeResults(struct bnsParams& params, struct bnsResults& res)
csv << params.byzantineFactor << del;
csv << params.netStack << del;
csv << params.topo << del;
csv << params.vanPropMode << del;
csv << params.nVanMaxConnIn << del;
csv << params.nVanMaxConnOut << del;
csv << params.kadK << del;
csv << params.kadAlpha << del;
csv << params.kadBeta << del;
......@@ -540,10 +573,14 @@ writeResults(struct bnsParams& params, struct bnsResults& res)
csv << params.byzantineFactor << del;
csv << params.netStack << del;
csv << params.topo << del;
csv << params.vanPropMode << del;
csv << params.nVanMaxConnIn << del;
csv << params.nVanMaxConnOut << del;
csv << params.kadK << del;
csv << params.kadAlpha << del;
csv << params.kadBeta << del;
csv << params.kadFecOverhead << del;
csv << bns::BitcoinTopologyHelper::RegionToString(res.firstMinerRegion) << del;
csv << e;
csv << std::endl;
}
......@@ -569,10 +606,14 @@ writeResults(struct bnsParams& params, struct bnsResults& res)
csv << params.byzantineFactor << del;
csv << params.netStack << del;
csv << params.topo << del;
csv << params.vanPropMode << del;
csv << params.nVanMaxConnIn << del;
csv << params.nVanMaxConnOut << del;
csv << params.kadK << del;
csv << params.kadAlpha << del;
csv << params.kadBeta << del;
csv << params.kadFecOverhead << del;
csv << bns::BitcoinTopologyHelper::RegionToString(res.firstMinerRegion) << del;
csv << e;
csv << std::endl;
}
......
......@@ -38,6 +38,7 @@ enum class VanMsgType
HEADERS, //3
GETBLOCKS, //4
BLOCK, //5
CMPCTBLOCK, //6
};
class VanLengthHeader : public ns3::Header
......
......@@ -27,9 +27,9 @@ NS_LOG_COMPONENT_DEFINE ("BNSVanillaNode");
namespace bns {
BroadcastType VanillaNode::vanBroadcastType = BroadcastType::SENDHEADERS;
PropagationMode VanillaNode::vanPropagationMode = PropagationMode::CMPCTBLOCKS;
VanillaNode::VanillaNode (ns3::Ipv4Address address, bool isMiner, double hashRate) : BitcoinNode(address, isMiner, hashRate), m_nInPeers(0), m_nOutPeers(0)
VanillaNode::VanillaNode (ns3::Ipv4Address address, bool isMiner, double hashRate, uint32_t nMaxConnIn, uint32_t nMaxConnOut) : BitcoinNode(address, isMiner, hashRate), m_nInPeers(0), m_nOutPeers(0), m_nMaxConnIn(nMaxConnIn), m_nMaxConnOut(nMaxConnOut)
{
NS_LOG_FUNCTION (this);
}
......@@ -110,7 +110,7 @@ VanillaNode::InitOutgoingConnection(void)
if (size == 0) return;
if (m_nOutPeers < VAN_MAXCONN_OUT) {
if (m_nOutPeers < m_nMaxConnOut) {
ns3::Ipv4Address const randAddr = RandomKnownAddress();
if ((m_address != randAddr) && m_peers.count(randAddr) == 0) {
NS_LOG_INFO("Connecting to address " << randAddr);
......@@ -136,6 +136,25 @@ VanillaNode::InitBroadcast (Block& b)
NS_LOG_FUNCTION(this);
//NS_LOG_INFO ("Broadcasting BLOCK " << b.blockID << ", prevID: " << b.prevID << ", size: " << b.blockSize << ").");
//
// std::vector<ns3::Ipv4Address> randomizedPeerAddrs;
//
// ns3::Ptr<ns3::UniformRandomVariable> indexVar = ns3::CreateObject<ns3::UniformRandomVariable> ();
// indexVar->SetAttribute ("Min", ns3::DoubleValue (0));
// indexVar->SetAttribute ("Max", ns3::DoubleValue (m_peers.size()-1));
// while (randomizedPeerAddrs.size() < m_peers.size()) {
// auto randIter = std::begin(m_peers);
// auto const steps = indexVar->GetInteger ();
// std::advance(randIter, steps);
//
// ns3::Ipv4Address randAddr = (*randIter).first;
//
// auto it = std::find(std::begin(randomizedPeerAddrs), std::end(randomizedPeerAddrs), randAddr);
// if (it == std::end(randomizedPeerAddrs)) {
// randomizedPeerAddrs.push_back(randAddr);
// }
// }
//
for (auto p : m_peers) {
ns3::Ipv4Address peerAddr = p.first;
Peer& peer = p.second;
......@@ -143,17 +162,20 @@ VanillaNode::InitBroadcast (Block& b)
if (!PeerKnowsBlock(peerAddr, b.blockID)) {
std::vector<uint64_t> inventory;
inventory.push_back(b.blockID);
switch (VanillaNode::vanBroadcastType)
switch (VanillaNode::vanPropagationMode)
{
case BroadcastType::UNSOLICITED:
case PropagationMode::UNSOLICITED:
SendBlockMessage(peer.socket, b);
break;
case BroadcastType::SENDHEADERS:
case PropagationMode::SENDHEADERS:
SendHeadersMessage(peer.socket, inventory);
break;
case BroadcastType::INV:
case PropagationMode::INV:
SendInvMessage(peer.socket, inventory);
break;
case PropagationMode::CMPCTBLOCKS:
SendCmpctBlockMessage(peer.socket, b);
break;
}
SetBlockKnown(peerAddr, b.blockID);
}
......@@ -197,7 +219,7 @@ VanillaNode::HandleAccept (ns3::Ptr<ns3::Socket> socketPtr, const ns3::Address&
return;
}
if (m_nInPeers >= VAN_MAXCONN_IN) {
if (m_nInPeers >= m_nMaxConnIn) {
NS_LOG_INFO("Incoming connection REFUSED (max connections): " << peerAddr);
socketPtr->Close ();
return;
......