-
-
Notifications
You must be signed in to change notification settings - Fork 7
Rewrite math using bigDecimal and Antelope Integers #16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
8c5c070
7670438
0302c44
e2d0ba4
628c865
66eee78
fb3ec73
adaa025
c183978
eb7d7a3
8113844
baef0d9
3983499
329f10c
facd652
303c5c6
f15a278
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -10,9 +10,8 @@ import { | |||||
| UInt8, | ||||||
| } from '@wharfkit/antelope' | ||||||
|
|
||||||
| import BN from 'bn.js' | ||||||
| import {intToBigDecimal} from '..' | ||||||
| import {PowerUpStateOptions} from './options' | ||||||
| import bigDecimal from 'js-big-decimal' | ||||||
|
|
||||||
| export abstract class PowerUpStateResource extends Struct { | ||||||
| @Struct.field('uint8') version!: UInt8 | ||||||
|
|
@@ -37,92 +36,83 @@ export abstract class PowerUpStateResource extends Struct { | |||||
| abstract per_day(options?: PowerUpStateOptions): number | ||||||
|
|
||||||
| // Get the current number of allocated units (shift from REX -> PowerUp) | ||||||
| public get allocated() { | ||||||
| return 1 - Number(this.weight_ratio) / Number(this.target_weight_ratio) / 100 | ||||||
| public get allocated(): number { | ||||||
| return 1 - Number(this.weight_ratio.dividing(this.target_weight_ratio)) / 100 | ||||||
| } | ||||||
|
|
||||||
| // Get the current percentage of reserved units | ||||||
| public get reserved() { | ||||||
| return new BN(String(this.utilization)) / new BN(String(this.weight)) | ||||||
| public get reserved(): Int64 { | ||||||
| return this.utilization.dividing(this.weight) | ||||||
| } | ||||||
|
|
||||||
| // Get the symbol definition for the token | ||||||
| public get symbol() { | ||||||
| return this.min_price.symbol | ||||||
| } | ||||||
|
|
||||||
| // Common casting for typed values to numbers | ||||||
| cast() { | ||||||
| return { | ||||||
| adjusted_utilization: Number(this.adjusted_utilization), | ||||||
| decay_secs: Number(this.decay_secs.value), | ||||||
| exponent: Number(this.exponent), | ||||||
| utilization: Number(this.utilization), | ||||||
| utilization_timestamp: Number(this.utilization_timestamp.value), | ||||||
| weight: new BN(String(this.weight)), | ||||||
| weight_ratio: Number(this.weight_ratio), | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| // Mimic: https://github.com/EOSIO/eosio.contracts/blob/d7bc0a5cc8c0c2edd4dc61b0126517d0cb46fd94/contracts/eosio.system/src/powerup.cpp#L358 | ||||||
| utilization_increase(sample: UInt128, frac) { | ||||||
| const {weight} = this | ||||||
| const frac128 = UInt128.from(frac) | ||||||
| const utilization_increase = | ||||||
| new BN(weight.value.mul(new BN(frac128.value))) / Math.pow(10, 15) | ||||||
| return Math.ceil(utilization_increase) | ||||||
| utilization_increase(frac: UInt128) { | ||||||
| const base = intToBigDecimal(frac) | ||||||
| const weight = intToBigDecimal(this.weight) | ||||||
| const multiplier = intToBigDecimal(Math.pow(10, 15)) | ||||||
| return UInt128.from(base.multiply(weight).divide(multiplier, 15).ceil().getValue()) | ||||||
| } | ||||||
|
|
||||||
| // Mimic: https://github.com/EOSIO/eosio.contracts/blob/d7bc0a5cc8c0c2edd4dc61b0126517d0cb46fd94/contracts/eosio.system/src/powerup.cpp#L284-L298 | ||||||
| price_function(utilization: number): number { | ||||||
| const {exponent, weight} = this.cast() | ||||||
| const max_price: number = this.max_price.value | ||||||
| const min_price: number = this.min_price.value | ||||||
| let price = min_price | ||||||
| const new_exponent = exponent - 1.0 | ||||||
| price_function(utilization: Int64): number { | ||||||
| const {weight} = this | ||||||
| let price = this.min_price.value | ||||||
| const new_exponent = Number(this.exponent) - 1.0 | ||||||
| if (new_exponent <= 0.0) { | ||||||
| return max_price | ||||||
| return this.max_price.value | ||||||
| } else { | ||||||
| const util_weight = new BN(utilization) / weight | ||||||
| price += (max_price - min_price) * Math.pow(util_weight, new_exponent) | ||||||
| // const util_weight = utilization.dividing(weight) | ||||||
| const util_weight = intToBigDecimal(utilization).divide(intToBigDecimal(weight), 18) | ||||||
|
||||||
| const util_weight = intToBigDecimal(utilization).divide(intToBigDecimal(weight), 18) | |
| const util_weight = intToBigDecimal(utilization).divide(intToBigDecimal(weight), DECIMAL_PRECISION) |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,9 +1,8 @@ | ||||||||||||||||||||
| import {Struct, UInt128} from '@wharfkit/antelope' | ||||||||||||||||||||
| import {Asset, Int64, Int64Type, Struct, UInt128, UInt128Type} from '@wharfkit/antelope' | ||||||||||||||||||||
|
|
||||||||||||||||||||
| import {BNPrecision, SampleUsage} from '..' | ||||||||||||||||||||
| import {BNPrecision, intToBigDecimal, SampleUsage} from '..' | ||||||||||||||||||||
| import {PowerUpStateResource} from './abstract' | ||||||||||||||||||||
| import {PowerUpStateOptions} from './options' | ||||||||||||||||||||
| import BN from 'bn.js' | ||||||||||||||||||||
|
|
||||||||||||||||||||
| @Struct.type('powerupstateresourcecpu') | ||||||||||||||||||||
| export class PowerUpStateResourceCPU extends PowerUpStateResource { | ||||||||||||||||||||
|
|
@@ -25,13 +24,15 @@ export class PowerUpStateResourceCPU extends PowerUpStateResource { | |||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // Convert weight to μs (microseconds) | ||||||||||||||||||||
| weight_to_us(sample: UInt128, weight: number): number { | ||||||||||||||||||||
| return Math.ceil((weight * Number(sample)) / BNPrecision) | ||||||||||||||||||||
| weight_to_us(sample: UInt128Type, weight: Int64Type): UInt128 { | ||||||||||||||||||||
| return UInt128.from( | ||||||||||||||||||||
| UInt128.from(weight).multiplying(Int64.from(sample)).dividing(BNPrecision, 'ceil') | ||||||||||||||||||||
| ) | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // Convert μs (microseconds) to weight | ||||||||||||||||||||
| us_to_weight(sample: UInt128, us: number): number { | ||||||||||||||||||||
| return Math.floor((us / Number(sample)) * BNPrecision) | ||||||||||||||||||||
| us_to_weight(sample: UInt128, us: Int64Type): Int64 { | ||||||||||||||||||||
| return Int64.from(us).multiplying(BNPrecision).dividing(sample, 'floor') | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // Default frac generation by smallest unit type | ||||||||||||||||||||
|
|
@@ -41,10 +42,13 @@ export class PowerUpStateResourceCPU extends PowerUpStateResource { | |||||||||||||||||||
| frac_by_ms = (usage: SampleUsage, ms: number) => this.frac_by_us(usage, ms * 1000) | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // Frac generation by μs (microseconds) | ||||||||||||||||||||
| frac_by_us(usage: SampleUsage, us: number) { | ||||||||||||||||||||
| const {weight} = this.cast() | ||||||||||||||||||||
| const frac = new BN(this.us_to_weight(usage.cpu, us)) / weight | ||||||||||||||||||||
| return Math.floor(frac * Math.pow(10, 15)) | ||||||||||||||||||||
| frac_by_us(usage: SampleUsage, us: Int64Type): Int64 { | ||||||||||||||||||||
| const precision = 15 | ||||||||||||||||||||
| const converted = intToBigDecimal(this.us_to_weight(usage.cpu, us)) | ||||||||||||||||||||
| const current = intToBigDecimal(this.weight) | ||||||||||||||||||||
| const multiplier = intToBigDecimal(Math.pow(10, precision)) | ||||||||||||||||||||
| const frac = converted.divide(current, precision).multiply(multiplier) | ||||||||||||||||||||
|
Comment on lines
+46
to
+50
|
||||||||||||||||||||
| const precision = 15 | |
| const converted = intToBigDecimal(this.us_to_weight(usage.cpu, us)) | |
| const current = intToBigDecimal(this.weight) | |
| const multiplier = intToBigDecimal(Math.pow(10, precision)) | |
| const frac = converted.divide(current, precision).multiply(multiplier) | |
| const converted = intToBigDecimal(this.us_to_weight(usage.cpu, us)) | |
| const current = intToBigDecimal(this.weight) | |
| const multiplier = intToBigDecimal(Math.pow(10, PRECISION)) | |
| const frac = converted.divide(current, PRECISION).multiply(multiplier) |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,9 +1,8 @@ | ||||||
| import {Struct, UInt128} from '@wharfkit/antelope' | ||||||
| import {Int64, Int64Type, Struct, UInt128} from '@wharfkit/antelope' | ||||||
|
|
||||||
| import {BNPrecision, SampleUsage} from '..' | ||||||
| import {BNPrecision, intToBigDecimal, SampleUsage} from '..' | ||||||
| import {PowerUpStateResource} from './abstract' | ||||||
| import {PowerUpStateOptions} from './options' | ||||||
| import BN from 'bn.js' | ||||||
|
|
||||||
| @Struct.type('powerupstateresourcenet') | ||||||
| export class PowerUpStateResourceNET extends PowerUpStateResource { | ||||||
|
|
@@ -25,13 +24,15 @@ export class PowerUpStateResourceNET extends PowerUpStateResource { | |||||
| } | ||||||
|
|
||||||
| // Convert weight to bytes | ||||||
| weight_to_bytes(sample: UInt128, weight: number): number { | ||||||
| return Math.ceil((weight * Number(sample)) / BNPrecision) | ||||||
| weight_to_bytes(sample: UInt128, weight: number): UInt128 { | ||||||
| return UInt128.from( | ||||||
| UInt128.from(weight).multiplying(Int64.from(sample)).dividing(BNPrecision, 'ceil') | ||||||
| ) | ||||||
| } | ||||||
|
|
||||||
| // Convert bytes to weight | ||||||
| bytes_to_weight(sample: UInt128, bytes: number): number { | ||||||
| return Math.floor((bytes / Number(sample)) * BNPrecision) | ||||||
| bytes_to_weight(sample: UInt128, bytes: Int64Type): Int64 { | ||||||
| return Int64.from(bytes).multiplying(BNPrecision).dividing(Int64.from(sample), 'floor') | ||||||
| } | ||||||
|
|
||||||
| // Default frac generation by smallest unit type | ||||||
|
|
@@ -42,10 +43,13 @@ export class PowerUpStateResourceNET extends PowerUpStateResource { | |||||
| this.frac_by_bytes(usage, kilobytes * 1000) | ||||||
|
|
||||||
| // Frac generation by bytes | ||||||
| frac_by_bytes(usage: SampleUsage, bytes: number) { | ||||||
| const {weight} = this.cast() | ||||||
| const frac = new BN(this.bytes_to_weight(usage.net, bytes)) / weight | ||||||
| return Math.floor(frac * Math.pow(10, 15)) | ||||||
| frac_by_bytes(usage: SampleUsage, bytes: Int64Type): Int64 { | ||||||
| const precision = 15 | ||||||
|
||||||
| const precision = 15 | |
| const precision = PRECISION; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,11 @@ | ||
| import {TimePointType, UInt64} from '@wharfkit/antelope' | ||
| import {Asset, TimePointType, UInt64} from '@wharfkit/antelope' | ||
|
|
||
| export interface PowerUpStateOptions { | ||
| // timestamp to base adjusted_utilization off | ||
| timestamp?: TimePointType | ||
| // blockchain resource limits for calculating usage | ||
| virtual_block_cpu_limit?: UInt64 | ||
| virtual_block_net_limit?: UInt64 | ||
| // minimum payment amount | ||
| min_payment?: Asset | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The magic number '15' should be extracted to a named constant to improve code readability and maintainability.