EOSIO / eosio.contracts

Smart contracts that provide some of the basic functions of the EOSIO blockchain
https://eosio.github.io/eosio.contracts/latest
MIT License
325 stars 574 forks source link

NRM modelling: decay_secs has no effect? #551

Closed YaroShkvorets closed 3 years ago

YaroShkvorets commented 3 years ago

Attached are model config parameters and model input data for this NRM modelling test case.

In it, starting with 0 utilization on a fully transitioned model,

  1. On 2021-03-26T01:00:00.000 I reserve 10% of total CPU amount
  2. On 2021-03-27T01:00:01.000 (1 second after previous loan expires) I reserve 0.1% of total CPU amount and end up paying 10.3900 TST

Then 1 month later, once utilization drops back to 0,

  1. On 2021-04-26T01:00:00.000 I reserve again 10% of total CPU amount
  2. On 2021-04-29T01:00:01.000 (48 hours after previous loan expires) I reserve 0.1% of total CPU amount and end up paying the same 10.3900 TST

Correct me if I'm wrong but it was my understanding that because of price decay I should be paying a bit more in the first case, no? If not, then what's the point of decay_secs parameter in the first place?

I tried setting different values for decay_secs - from 60 to 86400, always getting the same fee in both cases.

model_config.zip

deckb commented 3 years ago

Because both the rentals happen after the 1 day decay_secs there will be no price difference. If you changed 2. to be 2021-03-26T13:00:00.000 you would see that since it falls within the decay_sec timeframe the fee is 10.3959 TST.

YaroShkvorets commented 3 years ago

Yes, that's what I would expect since by 13:00 my previous loan still didn't expire. I'm talking about price decay AFTER loan expires. According to utilization decay formula immediately after my 10% loan expires my adjusted utilization would still be at 10%. 24 Hours later my adjusted utilization would be at 3.7%, 48 hours later - at 1.369%, etc.

image

Here are the calculations based on calc_powerup_fee()

CPU state immediately after 10% loan expires:

start_u = 0
end_u = 0.001
adj_u = 0.1
fee = p(0.1) * min(0.001, 0.1)
p(0.1) = 100000000 + (4000000000 - 100000000) * 0.1^3 = 103900000
fee = 10.3900 TST

CPU state 48 Hours(=2*decay_secs) after 10% loan expires:

start_u = 0
end_u = 0.001
adj_u = 0.1*0.37*0.37 = 0.01369  (decayed 2x by 63%)
fee = p(0.01369) * min(0.001, 0.01369)
p(0.01369) = 100000000 + (4000000000 - 100000000) * 0.01369^3 = 100010006
fee = 10.0010 TST

So the fee should be 10.0010 TST but it's the same 10.3900 TST as immediately after loan expiry.

It appears adjusted_utilization doesn't get updated for some reason. I'm now thinking maybe that's related to that model testing bug we had discussed on telegram?

Attached is a stripped-down rentbw_input.csv with only 4 rentbw() calls:

2021-02-26T01:00:00.000,rentbw,aaaaaaaaaaaa,aaaaaaaaaaaa,1,0,100000000000000,5000009.0001,0
2021-02-27T01:00:00.000,rentbw,aaaaaaaaaaaa,aaaaaaaaaaaa,1,0,1000000000000,5000009.0001,0
2021-04-26T01:00:00.000,rentbw,aaaaaaaaaaaa,aaaaaaaaaaaa,1,0,100000000000000,5000009.0001,0
2021-04-29T01:00:00.000,rentbw,aaaaaaaaaaaa,aaaaaaaaaaaa,1,0,1000000000000,5000009.0001,0

I would expect fee for last rentbw call to be 10.0010 TST instead 10.0039 TST I'm getting. rentbw_input.zip

deckb commented 3 years ago

Ok so the reality of the system is that without prompting by either a rentbw/powerup or rentbwexec/powerupexec the decay timer will not start. The timer is started from the expiration of the order so in this case the fee will be the roughly same as if you waited a day + a second.

If you "manually" expire the order with rentbwexec like:

datetime,function,payer,receiver,days,net_frac,cpu_frac,max_payment,queue_max
2021-01-01T01:00:00.000,configrentbw,aaaaaaaaaaaa,aaaaaaaaaaaa,1,1000000000000,1000000000000,5000009.0001,0
2021-02-26T01:00:00.000,rentbw,aaaaaaaaaaaa,aaaaaaaaaaaa,1,0,100000000000000,5000009.0001,0
2021-02-27T01:00:00.000,rentbw,aaaaaaaaaaaa,aaaaaaaaaaaa,1,0,1000000000000,5000009.0001,0
2021-04-26T01:00:00.000,rentbw,aaaaaaaaaaaa,aaaaaaaaaaaa,1,0,100000000000000,5000009.0001,0
2021-04-27T01:00:00.001,rentbwexec,aaaaaaaaaaaa,aaaaaaaaaaaa,1,0,0,0.0000,2
2021-04-29T01:00:00.000,rentbw,aaaaaaaaaaaa,aaaaaaaaaaaa,1,0,1000000000000,5000009.0001,0

You can see the the fee is closer to your expected value:

last_block_time.       function  cpu.utilization  cpu.adjusted_utilization                                                               
2021-02-25 20:00:00      rentbw   39600000000000                         0   
2021-02-26 20:00:00      rentbw     396000000000            39600000000000   
2021-04-25 21:00:00      rentbw   39600000000000              396000000000   
2021-04-26 21:00:00  rentbwexec                0            39600000000000   
2021-04-28 21:00:00      rentbw     396000000000             5359277216169   

                          fee       cpu.weight  cpu.utilization_timestamp  
last_block_time                                                            
2021-02-25 20:00:00  1009.750  396000000000000                 1614301200  
2021-02-26 20:00:00    10.390  396000000000000                 1614387600  
2021-04-25 21:00:00  1009.750  396000000000000                 1619398800  
2021-04-26 21:00:00     0.000  396000000000000                 1619485200  
2021-04-28 21:00:00    10.001  396000000000000                 1619658000  
YaroShkvorets commented 3 years ago

I see, that explains it.