Skip to content

Commit

Permalink
Remove the 25 Merit scaling from the ConsensusTest.
Browse files Browse the repository at this point in the history
It was too problematic to work properly. Removing it required scaling 
everything by 25, which makes this test run much slower, but the 
pointless mining was removed (we never check against a difficulty) which 
helps.

This pointed out a couple of bugs in unverification which have been 
fixed (deleted unverified statuses from the cache/trued to unverify 
finalized transactions).

Also took the oppurtunity to apply a few optimizations.
  • Loading branch information
kayabaNerve committed Jan 19, 2020
1 parent 77d8377 commit 763881c
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 35 deletions.
2 changes: 1 addition & 1 deletion Meros.nimble
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ task unit, "Run unit tests.":
nimbleExec "install --depsOnly"

#Create a single test file will all test imports.
var contents: string = "{.warning[UnusedImport]:off.}\n\n"
var contents: string = "{.warning[UnusedImport]: off.}\n\n"
for f in gatherTestFiles(testsDir):
contents &= "import ../../tests" & f.replace(testsDir).changeFileExt("") & "\n"
mkDir testWorkingDir
Expand Down
6 changes: 5 additions & 1 deletion src/Database/Consensus/Consensus.nim
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,11 @@ proc flag*(
try:
status = consensus.getStatus(packet.hash)
except IndexError as e:
doAssert(false, "Couldn't get the status of a Transaction in Epochs: " & e.msg)
doAssert(false, "Couldn't get the status of a Transaction in Epochs at one point: " & e.msg)

#Don't recalculate Transactions which have already finalized.
if status.merit != -1:
continue

if status.verified and status.holders.contains(removal.holder):
var merit: int = 0
Expand Down
16 changes: 7 additions & 9 deletions src/Database/Consensus/objects/ConsensusObj.nim
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,18 @@ proc newConsensusObj*(
#Just like Epochs, this first requires loading the old last 5 Blocks and then the current last 5 Blocks.
var
height: int = functions.merit.getHeight()
old: seq[Hash[256]] = @[]
old: HashSet[Hash[256]] = initHashSet[Hash[256]]()
try:
for i in max(height - 10, 0) ..< height - 5:
for packet in functions.merit.getBlockByNonce(i).body.packets:
old.add(packet.hash)
old.incl(packet.hash)

for i in max(height - 5, 0) ..< height:
#Skip old Transactions.
for packet in functions.merit.getBlockByNonce(i).body.packets:
if old.contains(packet.hash):
continue

try:
result.statuses[packet.hash] = result.db.load(packet.hash)
except DBReadError:
Expand All @@ -144,11 +148,6 @@ proc newConsensusObj*(
except IndexError as e:
doAssert(false, "Couldn't get a Block on the Blockchain: " & e.msg)

#Delete old Transaction statuses.
for oldStatus in old:
result.statuses.del(oldStatus)
result.close.excl(oldStatus)

#Load unmentioned Transactions.
var unmentioned: seq[Hash[256]] = result.db.loadUnmentioned()
for hash in unmentioned:
Expand Down Expand Up @@ -312,12 +311,11 @@ proc unverify*(
doAssert(false, "Couldn't get the Transaction/Status for a Transaction we're calculating the Merit of.")

#If this child was verified, unverify it and grab children.
#Children of Transactions which aren't verified cann't be verified and therefore can be skipped.
#Children of Transactions which aren't verified can't be verified and therefore can be skipped.
if childStatus.verified:
echo "Verified Transaction was unverified: ", child
childStatus.verified = false
consensus.db.save(child, childStatus)
consensus.statuses.del(child)

try:
for o in 0 ..< tx.outputs.len:
Expand Down
2 changes: 1 addition & 1 deletion src/MainMerit.nim
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ proc mainMerit() {.forceCheck: [].} =
merit.processBlock(newBlock)

#Copy the State.
var rewardsState = merit.state
var rewardsState: State = merit.state

#Add the Block to the Epochs and State.
var
Expand Down
73 changes: 50 additions & 23 deletions tests/Database/Consensus/ConsensusTest.nim
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ suite "Consensus":
"CONSENSUS_DB_TEST",
1,
$Hash[256](),
25
625
)
#Transactions.
transactions: Transactions = newTransactions(
Expand Down Expand Up @@ -172,7 +172,7 @@ suite "Consensus":
var
miner: MinerWallet
mining: Block
if (rand(2) == 0) or (holders.len == 0):
if (rand(74) == 0) or (holders.len == 0):
miner = newMinerWallet()
miner.nick = uint16(holders.len)
holders.add(miner)
Expand All @@ -199,30 +199,32 @@ suite "Consensus":
aggregate = aggregate
)

#Mine it.
while merit.blockchain.difficulty.difficulty > mining.header.hash:
miner.hash(mining.header, mining.header.proof + 1)
#Check who has their Merit removed.
var removed: set[uint16] = {}
for elem in mining.body.elements:
if elem of MeritRemoval:
consensus.flag(merit.blockchain, merit.state, cast[MeritRemoval](elem))
removed.incl(elem.holder)

#Add a Block to the Blockchain to generate a holder.
merit.processBlock(mining)

#Copy the State.
var rewardsState: State = merit.state

#Add the Block to the Epochs and State.
var
epoch: Epoch
incd: uint16
decd: int
(epoch, incd, decd) = merit.postProcessBlock()

#Add an extra 24 Merit from each to speed up the process of getting difficulty votes.
merit.state[incd] = merit.state[incd] + 24

#Archive the Epochs.
consensus.archive(merit.state, mining.body.packets, mining.body.elements, epoch, incd, decd)

#Remove 24 Merit, if neccessary.
#This is done here so we can still trigger the merit + 1 mod 50 == 0 check.
if decd != -1:
merit.state[uint16(decd)] = merit.state[uint16(decd)] - 24
#Have the Consensus handle every person who suffered a MeritRemoval.
for removee in removed:
consensus.remove(removee, rewardsState[removee])

#Add the elements.
for elem in elements:
Expand Down Expand Up @@ -256,8 +258,8 @@ suite "Consensus":
#Compare the Consensus DAGs.
compare(consensus, reloaded)

#Iterate over 50 'rounds'.
for r in 1 .. 50:
#Iterate over 1250 'rounds'.
for r in 1 .. 1250:
#Clear the packets, unsigned table, and aggregate.
packets = @[]
unsigned = @[]
Expand Down Expand Up @@ -353,26 +355,51 @@ suite "Consensus":
consensus.add(merit.state, packet)
break

#Add a Send Difficulty.
#Add Difficulties.
var
holder: int = rand(holders.len - 1)
difficulty: Hash[256]
diff1: Hash[256]
diff2: Hash[256]
sendDiff: SignedSendDifficulty
dataDiff: SignedDataDifficulty
for b in 0 ..< 32:
difficulty.data[b] = uint8(rand(255))
sendDiff = newSignedSendDifficultyObj(consensus.getArchivedNonce(uint16(holder)) + 1, difficulty)
diff1.data[b] = uint8(rand(255))
diff2.data[b] = uint8(rand(255))

sendDiff = newSignedSendDifficultyObj(consensus.getArchivedNonce(uint16(holder)) + 1, diff1)
sendDiff.holder = uint16(holder)
elements.add(sendDiff)

#Add a Data Difficulty.
var dataDiff: SignedDataDifficulty
holder = rand(holders.len - 1)
for b in 0 ..< 32:
difficulty.data[b] = uint8(rand(255))
dataDiff = newSignedDataDifficultyObj(consensus.getArchivedNonce(uint16(holder)) + 1, difficulty)
dataDiff = newSignedDataDifficultyObj(consensus.getArchivedNonce(uint16(holder)) + 1, diff2)
dataDiff.holder = uint16(holder)
elements.add(dataDiff)

if rand(125) == 0:
#Add a Merit Removal.
holder = rand(holders.len - 1)
while merit.state[uint16(holder)] == 0:
holder = rand(holders.len - 1)
for b in 0 ..< 32:
diff1.data[b] = uint8(rand(255))
diff2.data[b] = uint8(rand(255))

var
e1: SendDifficulty
e2: DataDifficulty
e1 = newSendDifficultyObj(0, diff1)
e1.holder = uint16(holder)
e2 = newDataDifficultyObj(0, diff2)
e2.holder = uint16(holder)

elements.add(newMeritRemoval(
uint16(holder),
false,
e1,
e2,
merit.state.holders
))

#Mine the packets.
mineBlock()

Expand Down

0 comments on commit 763881c

Please sign in to comment.