mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-09 14:48:08 -05:00
[research/ouroboros] finished basic simulation
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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]")
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user