[research/ouroboros] finished basic simulation

This commit is contained in:
mohab
2022-02-11 13:42:31 +02:00
parent 8895116a1e
commit 4545cf2a1c
7 changed files with 46 additions and 29 deletions

View File

@@ -14,7 +14,7 @@ proof, and base to the genesis block.
#TODO implement trustedbeacon as a node
'''
class TrustedBeacon(SynchedNTPClock, threading.Thread):
def __init__(self, node, vrf_sk, epoch_length):
def __init__(self, node, vrf_sk, epoch_length, genesis_time):
self.epoch_length=epoch_length # how many slots in a a block
SynchedNTPClock.__init__(self)
threading.Thread.__init__(self)
@@ -22,11 +22,11 @@ class TrustedBeacon(SynchedNTPClock, threading.Thread):
self.node = node #stakeholder
self.vrf = VRF(self.node.vrf_pk, vrf_sk, self.node.vrf_base)
self.current_slot = self.slot
self.log = Logger(self)
self.log.info("[TrustedBeacon]")
self.log = Logger(self, genesis_time)
self.log.info(f"[TrustedBeacon] constructed for node {str(node)}")
def __repr__(self):
return f"trustedbeadon\n"
return f"trustedbeacon"
def run(self):
self.log.info("[TrustedBeacon] thread [start]")
@@ -44,9 +44,10 @@ class TrustedBeacon(SynchedNTPClock, threading.Thread):
self.current_slot = self.slot
sigmas = []
proofs = []
self.log.info(f"[TrustedBeacon] new slot of idx: {self.current_slot}")
for i in range(self.epoch_length):
self.log.info(f"[TrustedBeacon] callback: new slot of idx: {self.current_slot}, epoch slot {i}")
y, pi = self.vrf.sign(self.current_slot)
self.log.info(f"[TrustedBeacon] callback: signature calculated for {str(self.node)}")
sigmas.append(y)
proofs.append(pi)
if self.current_slot%self.epoch_length==0:
@@ -58,4 +59,3 @@ class TrustedBeacon(SynchedNTPClock, threading.Thread):
def verify(self, y, pi, pk_raw, g):
return VRF.verify(self.current_slot, y, pi, pk_raw, g)

View File

@@ -1,12 +1,13 @@
from ouroboros.logger import Logger
import time
'''
Non-forkable Blockchain for simplicity
#TODO consider forkable property
'''
class Blockchain(object):
def __init__(self, R):
def __init__(self, R, genesis_time):
self.blocks = []
self.log = Logger(self)
self.log = Logger(self, genesis_time)
self.R = R # how many slots in single epoch
@property

View File

@@ -2,12 +2,14 @@ import numpy as np
import math
import random
from ouroboros.logger import Logger
import time
'''
\class Z is the environment
'''
class Z(object):
def __init__(self, stakeholdes, epoch_length):
self.log = Logger(self)
def __init__(self, stakeholdes, epoch_length, genesis_time=time.time()):
self.genesis_time=genesis_time
self.log = Logger(self, genesis_time)
self.epoch_length=epoch_length
self.stakeholders = np.array(stakeholdes)
self.adversary_mask=np.array([True]*len(stakeholdes))
@@ -72,12 +74,12 @@ class Z(object):
return len(self.stakeholders[self.adversary_mask])
def select_epoch_leaders(self, sigmas, proofs):
assert(len(sigmas)==self.epoch_length and len(proofs)==self.epoch_length, \
f"size mismatch between sigmas: {len(sigmas)}, proofs: {len(proofs)}, and epoch_length: {self.epoch_length}")
if len(sigmas)==self.epoch_length or len(proofs)==self.epoch_length:
self.log.error(f"size mismatch between sigmas: {len(sigmas)}, proofs: {len(proofs)}, and epoch_length: {self.epoch_length}")
for i in range(self.epoch_length):
self.log.info(f"current sigma of index {i} of total {len(sigmas)}, epoch_length: {self.epoch_length}")
sigma = sigmas[i]
assert (sigma!=None, 'proof cant be None')
assert sigma!=None, 'proof cant be None'
def leader_selection_hash(sigma):
Y = np.array(sigma)
y_hypotenuse2 = math.ceil(np.sum(Y[1]**2+Y[2]**2))
@@ -97,7 +99,7 @@ class Z(object):
self.current_slot=slot
self.log.info(f"stakeholders: {self.stakeholders}")
current_leader = self.stakeholders[self.current_leader_id]
assert(current_leader!=None, "current leader cant be None")
assert current_leader!=None, "current leader cant be None"
if current_leader.is_leader:
#pass leadership to the current slot leader from the epoch leader
self.stakeholders[self.current_epoch_leaders[slot%self.epoch_length]].set_leader()
@@ -106,7 +108,7 @@ class Z(object):
self.current_slot=slot
#self.log.info(f"stakeholders: {self.stakeholders}")
#current_leader = self.stakeholders[self.current_leader_id]
#assert(current_leader!=None, 'current leader cant be none')
#assert current_leader!=None, 'current leader cant be none'
#assert(current_leader.is_leader)
self.select_epoch_leaders(sigmas, proofs)

View File

@@ -1,13 +1,24 @@
import time
import os
os.system("color")
class Logger(object):
def __init__(self, obj):
def __init__(self, obj, genesis_time=time.time()):
self.obj = obj
self.genesis=genesis_time
@property
def diff(self):
cur = time.time()
d = cur - self.genesis
return round(d,1)
def info(self, payload):
print(f"\t[{self.obj}]:\n{payload}\n")
print("\033[32m", f"[{self.diff}] - [{self.obj}]:\n\t{payload}\n", "\033[0m")
def warn(self, payload):
print(f"\t[{self.obj}]:\n{payload}\n")
print("\033[33m", f"[{self.diff}] - [{self.obj}]:\n\t{payload}\n", "\033[0m")
def error(self, payload):
print(f"\t[{self.obj}]:\n{payload}\n")
print("\033[31m", f"[{self.diff}] - [{self.obj}]:\n\t{payload}\n", "\033[0m")
exit()

View File

@@ -6,7 +6,7 @@ from ouroboros.beacon import TrustedBeacon
from ouroboros.vrf import generate_vrf_keys, VRF
from ouroboros.utils import *
from ouroboros.logger import Logger
import time
'''
\class Stakeholder
'''
@@ -17,24 +17,23 @@ class Stakeholder(object):
self.stake=0
self.epoch_length=epoch_length
pk, sk, g = generate_vrf_keys(self.passwd)
#verification keys
self.__vrf_pk = pk
self.__vrf_sk = sk
self.__vrf_base = g
self.blockchain = Blockchain(self.epoch_length)
self.beacon = TrustedBeacon(self, self.epoch_length, self.__vrf_sk)
#signature keys
sig_sk, sig_pk = generate_sig_keys(self.passwd)
self.sig_sk = sig_sk
self.sig_pk = sig_pk
#
self.current_block = None
self.uncommited_tx=''
self.tx=''
self.current_slot_uid = self.beacon.slot
self.current_epoch = None
self.am_current_leader=False
self.am_current_endorder=False
self.am_corrupt=False
self.log = Logger(self)
#
@property
def is_leader(self):
@@ -55,6 +54,11 @@ class Stakeholder(object):
def __call__(self, env):
self.env=env
self.log = Logger(self, self.env.genesis_time)
self.blockchain = Blockchain(self.epoch_length, self.env.genesis_time)
self.beacon = TrustedBeacon(self, self.__vrf_sk, self.epoch_length, self.env.genesis_time)
self.current_slot_uid = self.beacon.slot
def start(self):
self.log.info("Stakeholder.start [started]")

View File

@@ -14,8 +14,7 @@ def generate_vrf_keys(sk_seed):
generate pk/sk
return: list of pk (public key), sk(secret key), base(field base)
'''
#sk = vrf_hash(sk_seed)
sk=2
sk = vrf_hash(sk_seed)
base = ecc.gen()
pk = ecc.scalar_mult(sk, base)
return (pk, sk, base)

View File

@@ -1,13 +1,13 @@
from ouroboros import Stakeholder
from ouroboros import Z
import random
import time
EPOCH_LENGTH = 3
stakeholders = []
for i in range(3):
stakeholders.append(Stakeholder(EPOCH_LENGTH))
environment = Z(stakeholders, EPOCH_LENGTH)
environment = Z(stakeholders, EPOCH_LENGTH, genesis_time=time.time())
environment.start()