Set up a proper test of a simple Copper network.

The reliability layer isn't in use here, as it will be tested separately.
I need to adjust the base Copper protocol first.
This commit is contained in:
gamemanj 2017-03-18 11:32:14 +00:00
parent 2b458b5df8
commit 97fd892922
2 changed files with 121 additions and 22 deletions

View File

@ -30,11 +30,11 @@ return function (hostname, transmit, onReceive, time)
-- Expect a response by this many seconds,
-- or else clear the known receivers cache and resend.
local tuningExpectResponse = 20
local tuningExpectResponse = 10
-- Flush the loop detector every so often.
-- This is not a complete clear.
local tuningFlushLoopDetector = 120
local tuningFlushLoopDetector = 10
-- Do not change this value. I mean it. Don't. Just. Don't.
local tuningAutorejectLen = 4000
@ -49,17 +49,12 @@ return function (hostname, transmit, onReceive, time)
local seenBefore = {}
local seenBeforeCount = 0
-- Unacknowledged packets.
-- Can cause an earlier cache flush.
-- [address] = giveupTime
-- (These are just forgotten after a while)
--local sentBNR = {}--NYI
-- [address] = {
-- node,
-- expiry
-- expiry,
-- broadcastOnExpire
-- }
--local lastKnownReceiver = {}--NYI
local lastKnownReceiver = {}
local function refresh()
local t = time()
@ -75,6 +70,14 @@ return function (hostname, transmit, onReceive, time)
end
loopDetectorNext = time() + tuningFlushLoopDetector
end
for k, v in pairs(lastKnownReceiver) do
if t >= v[2] then
lastKnownReceiver[k] = nil
for _, m in ipairs(v[3]) do
transmit(nil, m)
end
end
end
end
local culib = {}
@ -82,6 +85,7 @@ return function (hostname, transmit, onReceive, time)
-- Can be changed.
culib.hostname = hostname
culib.input = function (node, message)
local t = time()
if message:len() > tuningAutorejectLen then
return
end
@ -97,24 +101,44 @@ return function (hostname, transmit, onReceive, time)
seenBefore = {}
end
end
-- Begin parsing
local rawmessage = message
if message:len() < 2 then return end
local nlen = message:byte(1) + 1
local fnam = message:sub(1, nlen)
message = message:sub(nlen + 1)
local fnam = message:sub(2, nlen + 1)
message = message:sub(nlen + 2)
if message:len() < 2 then return end
local nlen = message:byte(1) + 1
local tnam = message:sub(1, nlen)
message = message:sub(nlen + 1)
if message:len() < 1 then return end
local tnam = message:sub(2, nlen + 1)
message = message:sub(nlen + 2)
lastKnownReceiver[fnam] = {node, t + tuningExpectResponse, {}}
onReceive(fnam, tnam, message)
if culib.hostname == tnam then return end
-- Redistribution of messages not aimed here
transmit(nil, message)
local lkr = lastKnownReceiver[tnam]
if lkr then
transmit(lkr[1], rawmessage)
table.insert(lkr[3], rawmessage)
else
transmit(nil, rawmessage)
end
end
local function encodeName(name)
if name:len() > 256 then error("Bad name (l>256)") end
if name == "" then error("No name") end
return string.char(name:len() - 1) .. name
end
culib.refresh = refresh
culib.output = function (fnam, tnam, message)
onReceive(fnam, tnam, message)
if tnam == culib.hostname then return end
transmit(nil, encodeName(fnam) .. encodeName(tnam) .. message)
local m = encodeName(fnam) .. encodeName(tnam) .. message
transmit(nil, m)
end
return culib
end

View File

@ -1,13 +1,88 @@
-- Load testnet
local culib = require("culib")
local nodes = {}
local nodeconnect = {}
local nodenames = {}
loadfile("testnet.lua")(function (n)
table.insert(nodes, {})
local systime = 0
local function getsystime()
return systime / 20
end
local queuedCalls = {}
local function queueSend(n, v, data)
--print("transmit", n, v, data)
table.insert(queuedCalls, function ()
nodes[v].input(n, data)
end)
end
local statSD = 0
local statPT = 0
loadfile("testnet.lua")()(function (n)
local conn = {}
local nodeidx = (#nodes) + 1
table.insert(nodes, culib(n, function (node, data)
if node then
for _, v in ipairs(conn) do
if v == node then
queueSend(nodeidx, v, data)
return
end
end
error(nodeidx .. " -> " .. node .. " not directly possible")
else
for _, v in ipairs(conn) do
queueSend(nodeidx, v, data)
end
end
end, function (nfrom, nto, data)
if nto == n then
if data:sub(1, 1) == "T" then
nodes[nodeidx].output(n, nfrom, "R" .. data)
else
statSD = statSD + 1
end
else
statPT = statPT + 1
end
end, getsystime))
table.insert(nodeconnect, conn)
table.insert(nodenames, n)
end, function (a, b)
table.insert(nodes[a], b)
table.insert(nodes[b], a)
table.insert(nodeconnect[a], b)
table.insert(nodeconnect[b], a)
end)
-- Start testing
require("culib")
local function generateMessage()
local na = math.random(#nodes)
local nb = math.random(#nodes)
nodes[na].output(nodenames[na], nodenames[nb], "T" .. tostring(math.random()))
end
local generateEvery = 1
local generateCount = 10000
while (generateCount > 0) or (#queuedCalls > 0) do
if (systime % generateEvery) == 0 then
if generateCount > 0 then
generateMessage()
generateCount = generateCount - 1
end
end
local qc = queuedCalls
queuedCalls = {}
for _, v in ipairs(nodes) do
v.refresh()
end
for _, v in ipairs(qc) do
v()
end
print("run iteration, " .. #qc .. " calls")
systime = systime + 1
end
print(statSD, statPT)