فهرست منبع

[research/lotterysim] move from tipless fee mechanism to tip auction

ertosns 3 سال پیش
والد
کامیت
45746dbdd2

+ 1 - 1
script/research/lotterysim/core/constants.py

@@ -39,7 +39,7 @@ PRIMARY_REWARD_TARGET = 0.35 # staked ratio
 # secondary controller assumes certain frequency of leaders per slot
 # secondary controller assumes certain frequency of leaders per slot
 SECONDARY_LEAD_TARGET = 1 #number of lead per slot
 SECONDARY_LEAD_TARGET = 1 #number of lead per slot
 # maximum transaction size
 # maximum transaction size
-MAX_BLOCK_SIZE = 1000
+MAX_BLOCK_SIZE = 100
 # maximum transaction computational cost
 # maximum transaction computational cost
 MAX_BLOCK_CC = 10
 MAX_BLOCK_CC = 10
 # fee controller computational capacity target
 # fee controller computational capacity target

+ 16 - 5
script/research/lotterysim/core/darkie.py

@@ -14,6 +14,7 @@ class Darkie():
         self.slot = 0
         self.slot = 0
         self.won_hist = [] # winning history boolean
         self.won_hist = [] # winning history boolean
         self.fees = []
         self.fees = []
+        self.tips = [0]
 
 
     def clone(self):
     def clone(self):
         return Darkie(self.stake)
         return Darkie(self.stake)
@@ -170,8 +171,17 @@ class Darkie():
 
 
     @returns: transaction emulated as series of random floats between 0,1
     @returns: transaction emulated as series of random floats between 0,1
     """
     """
-    def tx(self):
-        return Tx(random.randint(0, MAX_BLOCK_SIZE))
+    def tx(self, last_reward):
+        tx_size = random.randint(0, MAX_BLOCK_SIZE)
+        tip = self.tx_tip(tx_size, last_reward)
+        if self.stake < tip:
+            return Tx(tx_size, 0)
+        return Tx(tx_size, tip)
+
+    def tx_tip(self, tx_size, last_reward):
+        tip = random_tip_strategy()
+        apr = self.apr_scaled_to_runningtime()
+        return tip.get_tip(float(last_reward), float(apr), tx_size, self.tips[-1])
 
 
     """
     """
     deduct tip paid to miner plus burned base fee or computational cost.
     deduct tip paid to miner plus burned base fee or computational cost.
@@ -185,20 +195,21 @@ class Darkie():
         return self.fees[-1] if len(self.fees)>0 else 0
         return self.fees[-1] if len(self.fees)>0 else 0
 
 
 class Tx(object):
 class Tx(object):
-    def __init__(self, size):
+    def __init__(self, size, tip):
         self.tx = [random.random() for _ in range(size)]
         self.tx = [random.random() for _ in range(size)]
         self.len = size
         self.len = size
+        self.tip = tip
 
 
     """
     """
     anonymous contract assumed to be of random streams from uniform distribution,
     anonymous contract assumed to be of random streams from uniform distribution,
     it's circuit execution cost it thus random.
     it's circuit execution cost it thus random.
-    naive emulation of transaction smart contract computational cost (aka tip) as a avg of txs sum,
+    naive emulation of transaction smart contract computational cost as a avg of txs sum,
     which is random function
     which is random function
 
 
     @returns: transaction computational cost
     @returns: transaction computational cost
     """
     """
     def cc(self):
     def cc(self):
-        return sum(self.tx) if len(self.tx)>0 else 0
+        return int(sum(self.tx) if len(self.tx)>0 else 0)
 
 
     def __len__(self):
     def __len__(self):
         return len(self.tx)
         return len(self.tx)

+ 5 - 4
script/research/lotterysim/core/lottery.py

@@ -143,7 +143,8 @@ class DarkfiTable:
     def tx_fees(self, darkie_lead_idx, debug=False):
     def tx_fees(self, darkie_lead_idx, debug=False):
         txs = []
         txs = []
         for darkie in self.darkies:
         for darkie in self.darkies:
-            txs += [darkie.tx()]
+            # make sure tip is covered by darkie stake
+            txs += [darkie.tx(self.rewards[-1])]
         ret, actual_cc = DarkfiTable.auction(txs)
         ret, actual_cc = DarkfiTable.auction(txs)
         self.computational_cost += [actual_cc]
         self.computational_cost += [actual_cc]
         self.cc_diff += [MAX_BLOCK_CC - actual_cc]
         self.cc_diff += [MAX_BLOCK_CC - actual_cc]
@@ -209,9 +210,9 @@ class DarkfiTable:
             for w in range(W + 1):
             for w in range(W + 1):
                 if i == 0 or w == 0:
                 if i == 0 or w == 0:
                     K[i][w] = [0,[]]
                     K[i][w] = [0,[]]
-                elif len(txs[i-1]) <= w:
-                    if txs[i-1].cc() + K[i-1][w-len(txs[i-1])][0] > K[i-1][w][0]:
-                        K[i][w] = [txs[i-1].cc() + K[i-1][w-len(txs[i-1])][0], K[i-1][w-len(txs[i-1])][1] + [i-1]]
+                elif txs[i-1].cc() <= w:
+                    if txs[i-1].tip + K[i-1][w-txs[i-1].cc()][0] > K[i-1][w][0]:
+                        K[i][w] = [txs[i-1].tip + K[i-1][w-txs[i-1].cc()][0], K[i-1][w-txs[i-1].cc()][1] + [i-1]]
                     else:
                     else:
                         K[i][w] = K[i-1][w]
                         K[i][w] = K[i-1][w]
                 else:
                 else:

+ 105 - 0
script/research/lotterysim/core/strategy.py

@@ -72,6 +72,7 @@ class SigmoidStrategy(Strategy):
     def set_ratio(self, slot, apr):
     def set_ratio(self, slot, apr):
         if slot%self.epoch_len==0:
         if slot%self.epoch_len==0:
                 apr_ratio = apr/self.target_apy
                 apr_ratio = apr/self.target_apy
+                apr_ratio = max(apr_ratio, 0)
                 sr = Num(2/(1+math.pow(math.e, -4*apr_ratio))-1)
                 sr = Num(2/(1+math.pow(math.e, -4*apr_ratio))-1)
                 if sr>1:
                 if sr>1:
                     sr = 1
                     sr = 1
@@ -90,3 +91,107 @@ def random_strategy(epoch_length=EPOCH_LENGTH):
         return LogarithmicStrategy(epoch_length)
         return LogarithmicStrategy(epoch_length)
     else:
     else:
         return SigmoidStrategy(epoch_length)
         return SigmoidStrategy(epoch_length)
+
+
+class Tip(object):
+    def __init__(self):
+        self.type = 'tip'
+
+    def get_tip(self, last_reward, apr, size, last_tip):
+        return 0
+
+class ZeroTip(Tip):
+
+    def __init__(self):
+        super().__init__()
+        self.type = 'zero'
+
+    def get_tip(self, last_reward, apr, size, last_tip):
+        return 0
+
+class TenthOfReward(Tip):
+    def __init__(self):
+        super().__init__()
+        self.type = '10th'
+
+    def get_tip(self, last_reward, apr, size, last_tip):
+        return last_reward/10
+
+class HundredthOfReward(Tip):
+    def __init__(self):
+        super().__init__()
+        self.type = '100th'
+
+    def get_tip(self, last_reward, apr, size, last_tip):
+        return last_reward/100
+
+class MilthOfReward(Tip):
+    def __init__(self):
+        super().__init__()
+        self.type = '1000th'
+
+    def get_tip(self, last_reward, apr, size, last_tip):
+        return last_reward/1000
+
+class RewardApr(Tip):
+    def __init__(self):
+        super().__init__()
+        self.type = 'reward_apr'
+
+    def get_tip(self, last_reward, apr, size, last_tip):
+        apr_relu = max(apr, 0)
+        return last_reward*apr_relu
+
+class TenthRewardApr(Tip):
+    def __init__(self):
+        super().__init__()
+        self.type = 'reward_apr'
+
+    def get_tip(self, last_reward, apr, size, last_tip):
+        apr_relu = max(apr, 0)
+        return last_reward*apr_relu/10
+
+
+class TenthCCApr(Tip):
+    def __init__(self):
+        super().__init__()
+        self.type = "cc_apr_10"
+
+    def get_tip(self, last_reward, apr, size, last_tip):
+        return size/MAX_BLOCK_SIZE/10
+
+class HundredthCCApr(Tip):
+    def __init__(self):
+        super().__init__()
+        self.type = "cc_apr_100"
+
+    def get_tip(self, last_reward, apr, size, last_tip):
+        return size/MAX_BLOCK_SIZE/100
+
+class MilthCCApr(Tip):
+    def __init__(self):
+        super().__init__()
+        self.type = "cc_apr_1000"
+
+    def get_tip(self, last_reward, apr, size, last_tip):
+        return size/MAX_BLOCK_SIZE/1000
+
+class Conservative(Tip):
+    def __init__(self):
+        super().__init__()
+        self.type = "cc_apr_1000"
+
+    def get_tip(self, last_reward, apr, size, last_tip):
+        return last_tip
+
+class Generous(Tip):
+    def __init__(self):
+        super().__init__()
+        self.type = "cc_apr_1000"
+
+    def get_tip(self, last_reward, apr, size, last_tip):
+        return last_tip*2
+
+
+def random_tip_strategy():
+    return random.choice([ZeroTip(), TenthOfReward(), HundredthOfReward(), MilthOfReward(), RewardApr(), TenthRewardApr(), TenthCCApr(), HundredthCCApr(), MilthCCApr(), Conservative(), Generous()])

+ 3 - 3
script/research/lotterysim/discrete_instance_pi_headstart.py

@@ -16,12 +16,12 @@ if __name__ == "__main__":
     mu = PREMINT/NODES
     mu = PREMINT/NODES
     darkies = [Darkie(random.gauss(mu, mu/10), strategy=random_strategy(EPOCH_LENGTH)) for _ in range(NODES)]
     darkies = [Darkie(random.gauss(mu, mu/10), strategy=random_strategy(EPOCH_LENGTH)) for _ in range(NODES)]
     #dt = DarkfiTable(0, RUNNING_TIME, CONTROLLER_TYPE_DISCRETE, kp=-0.010399999999938556, ki=-0.0365999996461878, kd=0.03840000000000491,  r_kp=-2.53, r_ki=29.5, r_kd=53.77)
     #dt = DarkfiTable(0, RUNNING_TIME, CONTROLLER_TYPE_DISCRETE, kp=-0.010399999999938556, ki=-0.0365999996461878, kd=0.03840000000000491,  r_kp=-2.53, r_ki=29.5, r_kd=53.77)
-    dt = DarkfiTable(PREMINT, RUNNING_TIME, CONTROLLER_TYPE_DISCRETE, kp=-0.010399999999938556, ki=-0.0365999996461878, kd=0.03840000000000491,  r_kp=-0.719, r_ki=1.6, r_kd=0.1)
+    dt = DarkfiTable(PREMINT, RUNNING_TIME, CONTROLLER_TYPE_DISCRETE, kp=-0.010399999999938556, ki=-0.0365999996461878, kd=0.03840000000000491,  r_kp=-0.719, r_ki=1.6, r_kd=0.1, fee_kp=-0.068188, fee_ki=-0.000205)
     for darkie in darkies:
     for darkie in darkies:
         dt.add_darkie(darkie)
         dt.add_darkie(darkie)
-    acc, avg_apy, avg_reward, stake_ratio, avg_apr = dt.background(rand_running_time=False)
+    acc, cc_acc, avg_apy, avg_reward, stake_ratio, avg_apr = dt.background(rand_running_time=False)
     #sum_zero_stake = sum([darkie.stake for darkie in darkies[NODES:]])
     #sum_zero_stake = sum([darkie.stake for darkie in darkies[NODES:]])
-    print('acc: {}, avg(apr): {}%, avg(reward): {}, stake_ratio: {}'.format(acc, round(avg_apr*100,2), avg_reward, stake_ratio))
+    print('acc: {}, cc_acc: {}, avg(apr): {}%, avg(reward): {}, stake_ratio: {}'.format(round(acc,2), round(cc_acc, 2), round(avg_apr*100,2), avg_reward, stake_ratio))
     #print('total stake of 0mint: {}, ratio: {}'.format(sum_zero_stake, sum_zero_stake/ERC20DRK))
     #print('total stake of 0mint: {}, ratio: {}'.format(sum_zero_stake, sum_zero_stake/ERC20DRK))
     dt.write()
     dt.write()
     aprs = []
     aprs = []