|
|
@@ -3,24 +3,25 @@ from ouroboros.block import Block, GensisBlock, EmptyBlock
|
|
|
from ouroboros.blockchain import Blockchain
|
|
|
from ouroboros.epoch import Epoch
|
|
|
from ouroboros.beacon import TrustedBeacon
|
|
|
-from ouroboros.vrf import generate_vrf_keys, VRF
|
|
|
+from ouroboros.vrf import verify, VRF
|
|
|
from ouroboros.utils import *
|
|
|
from ouroboros.logger import Logger
|
|
|
+from ouroboros.consts import *
|
|
|
import time
|
|
|
'''
|
|
|
\class Stakeholder
|
|
|
'''
|
|
|
class Stakeholder(object):
|
|
|
- def __init__(self, epoch_length=100, passwd='password'):
|
|
|
+ def __init__(self, epoch_length=2, passwd='password'):
|
|
|
#TODO (fix) remove redundant variables reley on environment
|
|
|
self.passwd=passwd
|
|
|
self.stake=0
|
|
|
self.epoch_length=epoch_length
|
|
|
- pk, sk, g = generate_vrf_keys(self.passwd)
|
|
|
+ self.vrf = VRF(self.passwd)
|
|
|
#verification keys
|
|
|
- self.__vrf_pk = pk
|
|
|
- self.__vrf_sk = sk
|
|
|
- self.__vrf_base = g
|
|
|
+ self.__vrf_pk = self.vrf.pk
|
|
|
+ self.__vrf_sk = self.vrf.sk
|
|
|
+ self.__vrf_base = self.vrf.g
|
|
|
#signature keys
|
|
|
sig_sk, sig_pk = generate_sig_keys(self.passwd)
|
|
|
self.sig_sk = sig_sk
|
|
|
@@ -56,19 +57,27 @@ class Stakeholder(object):
|
|
|
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.beacon = TrustedBeacon(self, self.vrf, self.epoch_length, self.env.genesis_time)
|
|
|
self.current_slot_uid = self.beacon.slot
|
|
|
|
|
|
|
|
|
def start(self):
|
|
|
- self.log.info("Stakeholder.start [started]")
|
|
|
+ self.log.info("start [started]")
|
|
|
self.beacon.start()
|
|
|
- self.log.info("Stakeholder.start [ended]")
|
|
|
+ self.log.info("start [ended]")
|
|
|
|
|
|
@property
|
|
|
def epoch_index(self):
|
|
|
return round(self.current_slot_uid/self.epoch_length)
|
|
|
|
|
|
+ def __gen_genesis_epoch(self):
|
|
|
+ '''
|
|
|
+ '''
|
|
|
+ self.tx = self.env.get_genesis_data()
|
|
|
+ self.tx[TX]=self.uncommited_tx
|
|
|
+ self.uncommited_tx=''
|
|
|
+ self.current_block=GensisBlock(self.current_block, self.tx, self.current_slot_uid)
|
|
|
+ self.current_epoch=Epoch(self.current_block, self.epoch_length, self.epoch_index, self.env.genesis_time)
|
|
|
'''
|
|
|
it's a callback function, and called by the diffuser
|
|
|
'''
|
|
|
@@ -78,17 +87,15 @@ class Stakeholder(object):
|
|
|
for this implementation we assume synchrony,
|
|
|
and at this point, and no delay is considered (for simplicity)
|
|
|
'''
|
|
|
- self.log.info("[stakeholder.new_epoch] start")
|
|
|
+ self.log.highlight("<new_epoch> start")
|
|
|
self.env.new_epoch(slot, sigmas, proofs)
|
|
|
self.current_slot_uid = slot
|
|
|
- # add epoch to the ledger
|
|
|
- if self.current_slot_uid > 1:
|
|
|
- self.blockchain.add_epoch(self.current_epoch)
|
|
|
#kickoff gensis block
|
|
|
- self.tx = self.env.get_genesis_data()
|
|
|
- self.current_block=GensisBlock(self.current_block, self.tx, self.current_slot_uid)
|
|
|
- self.current_epoch=Epoch(self.current_block, self.epoch_length, self.epoch_index)
|
|
|
+ # add old epoch to the ledger
|
|
|
+ if self.current_slot_uid > 1 and self.current_epoch!=None and len(self.current_epoch)>0:
|
|
|
+ self.blockchain.add_epoch(self.current_epoch)
|
|
|
#if leader, you need to broadcast the block
|
|
|
+ self.__gen_genesis_epoch()
|
|
|
if self.am_current_leader:
|
|
|
self.broadcast_block()
|
|
|
|
|
|
@@ -101,26 +108,27 @@ class Stakeholder(object):
|
|
|
for this implementation we assume synchrony,
|
|
|
and at this point, and no delay is considered (for simplicity)
|
|
|
'''
|
|
|
- self.log.info("[stakeholder.new_slot] start")
|
|
|
+ self.log.highlight("<new_slot> start")
|
|
|
self.env.new_slot(slot, sigma, proof)
|
|
|
vrf_pk = self.env.current_leader_vrf_pk
|
|
|
vrf_g = self.env.current_leader_vrf_g
|
|
|
assert(vrf_pk!=None)
|
|
|
assert(vrf_g!=None)
|
|
|
- if not VRF.verify(slot, sigma, proof, vrf_pk,vrf_g) :
|
|
|
+ if not verify(slot, sigma, proof, vrf_pk,vrf_g) :
|
|
|
#TODO the leader is corrupted, action to be taken against the corrupt stakeholder
|
|
|
#in this case this slot is empty
|
|
|
self.current_block=EmptyBlock()
|
|
|
if self.current_epoch!=None:
|
|
|
self.current_epoch.add_block(self.current_block)
|
|
|
else:
|
|
|
- #TODO (fix) this shouldn't happen!
|
|
|
- self.log.info(f"[Stakeholder] new_slot, current_epoch is None!")
|
|
|
- return
|
|
|
+ self.log.warn(f"<new_slot> current_epoch is None!")
|
|
|
+ return
|
|
|
+ if self.current_epoch==None:
|
|
|
+ self.log.warn(f"<new_slot> current_epoch is None!")
|
|
|
+ self.__gen_genesis_epoch()
|
|
|
self.current_slot_uid = slot
|
|
|
self.current_block=Block(self.current_block, self.tx, self.current_slot_uid)
|
|
|
self.current_epoch.add_block(self.current_block)
|
|
|
- #TODO if leader you need to broadcast the block
|
|
|
if self.am_current_leader:
|
|
|
self.broadcast_block()
|
|
|
|
|
|
@@ -134,6 +142,7 @@ class Stakeholder(object):
|
|
|
self.am_corrupt=False
|
|
|
|
|
|
def broadcast_block(self):
|
|
|
+ self.log.highlight("broadcasting block")
|
|
|
assert(self.am_current_leader)
|
|
|
signed_block = sign_message(self.passwd, self.sig_sk, self.current_block)
|
|
|
self.env.broadcast_block(signed_block)
|
|
|
@@ -141,6 +150,7 @@ class Stakeholder(object):
|
|
|
|
|
|
|
|
|
def receive_block(self, received_block):
|
|
|
+ self.log.highlight("receiving block")
|
|
|
if verify_signature(self.env.current_leader_sig_pk, self.current_block, received_block):
|
|
|
pass
|
|
|
else:
|