-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #185 from pegnet/develop
PIP 10 implementation
- Loading branch information
Showing
17 changed files
with
1,274 additions
and
182 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
package config | ||
|
||
import ( | ||
"github.com/Factom-Asset-Tokens/factom" | ||
"github.com/pegnet/pegnetd/fat/fat2" | ||
) | ||
|
||
var ( | ||
OPRChain = factom.NewBytes32("a642a8674f46696cc47fdb6b65f9c87b2a19c5ea8123b3d2f0c13b6f33a9d5ef") | ||
SPRChain = factom.NewBytes32("d5e395125335a21cef0ceca528168e87fe929fdac1f156870c1b1be6502448b4") | ||
TransactionChain = factom.NewBytes32("cffce0f409ebba4ed236d49d89c70e4bd1f1367d86402a3363366683265a242d") | ||
|
||
// Acivation Heights | ||
|
||
PegnetActivation uint32 = 206421 | ||
GradingV2Activation uint32 = 210330 | ||
|
||
// TransactionConversionActivation indicates when tx/conversions go live on mainnet. | ||
// Target Activation Height is Oct 7, 2019 15 UTC | ||
TransactionConversionActivation uint32 = 213237 | ||
|
||
// This is when PEG is priced by the market cap equation | ||
// Estimated to be Oct 14 2019, 15:00:00 UTC | ||
PEGPricingActivation uint32 = 214287 | ||
|
||
// OneWaypFCTConversions makes pFCT a 1 way conversion. This means pFCT->pXXX, | ||
// but no asset can go into pFCT. AKA pXXX -/> pFCT. | ||
// The only way to aquire pFCT is to burn FCT. The burn command will remain. | ||
// Estimated to be Nov 25, 2019 17:47:00 UTC | ||
OneWaypFCTConversions uint32 = 220346 | ||
|
||
// Once this is activated, a maximum amount of PEG of 5,000 can be | ||
// converted per block. At a future height, a dynamic bank should be used. | ||
// Estimated to be Dec 9, 2019, 17:00 UTC | ||
PegnetConversionLimitActivation uint32 = 222270 | ||
|
||
// This is when PEG price is determined by the exchange price | ||
// Estimated to be Dec 9, 2019, 17:00 UTC | ||
PEGFreeFloatingPriceActivation uint32 = 222270 | ||
|
||
// V4OPRUpdate indicates the activation of additional currencies and ecdsa keys. | ||
// Estimated to be Feb 12, 2020, 18:00 UTC | ||
V4OPRUpdate uint32 = 231620 | ||
|
||
// V20HeightActivation indicates the activation of PegNet 2.0. | ||
// Estimated to be Aug 19th 2020 14:00 UTC | ||
V20HeightActivation uint32 = 258796 | ||
|
||
// Activation height for developer rewards | ||
V20DevRewardsHeightActivation uint32 = 260118 | ||
|
||
// SprSignatureActivation indicates the activation of SPR Signature. | ||
// Estimated to be Aug 28th 2020 | ||
SprSignatureActivation uint32 = 260118 | ||
|
||
// OneWaypAssetsConversions makes some pAssets a 1 way conversion. | ||
// pDCR, pDGB, pDOGE, pHBAR, pONT, pRVN, pBAT, pALGO, pBIF, pETB, pKES, pNGN, pRWF, pTZS, pUGX | ||
// These pAssets have got small marketcap, and these will be disabled for conversion. | ||
// Estimated to be Dec 3th 2020 | ||
OneWaySmallAssetsConversions uint32 = 274036 | ||
|
||
// V202EnhanceActivation indicates the activation of PegNet 2.0.2. | ||
// Estimated to be Dec 3th 2020 | ||
V202EnhanceActivation uint32 = 274036 | ||
|
||
// V204EnhanceActivation indicates the activation of PegNet 2.0.4. | ||
// Estimated to be Mar 16th 2021 | ||
V204EnhanceActivation uint32 = 288878 | ||
|
||
// V204EnhanceActivation indicates the activation that burns remaining airdrop amount. | ||
// Estimated to be April 16th 2021 | ||
V204BurnMintedTokenActivation uint32 = 294206 | ||
|
||
// PIP10AveragingActivation changes conversions to use the lesser of a rolling average and market price | ||
// for the source of a conversion, and the higher of the rolling average and the market price for the | ||
// target of a conversion | ||
// | ||
// Activation of 2.0.5 | ||
PIP10AverageActivation uint32 = 295190 | ||
) | ||
|
||
func SetAllActivations(act uint32) { | ||
PegnetActivation = act | ||
GradingV2Activation = act | ||
TransactionConversionActivation = act | ||
PEGPricingActivation = act | ||
OneWaypFCTConversions = act | ||
PegnetConversionLimitActivation = act | ||
PEGFreeFloatingPriceActivation = act | ||
fat2.Fat2RCDEActivation = act | ||
V4OPRUpdate = act | ||
V20HeightActivation = act | ||
V20DevRewardsHeightActivation = act | ||
OneWaySmallAssetsConversions = act | ||
SprSignatureActivation = act | ||
V202EnhanceActivation = act | ||
V204EnhanceActivation = act | ||
V204BurnMintedTokenActivation = act | ||
PIP10AverageActivation = act | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
package node | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/pegnet/pegnetd/fat/fat2" | ||
) | ||
|
||
var AveragePeriod = uint64(288) // Our Average Period is 2 days (144 10 minute blocks per day) | ||
var AverageRequired = AveragePeriod / 2 // If we have at least half the rates, we can do conversions | ||
|
||
// getPegNetRateAverages | ||
// Gets all the rates for the AveragePeriod (the number of blocks contributing to the average), and computes | ||
// the average rate for all assets. If values are missing for an asset for any of the blocks in the AveragePeriod, | ||
// then don't allow conversions by setting the averate to zero for that asset | ||
// | ||
// Return a map of averages of the form map[fat2.PTicker]uint64 | ||
// | ||
// Also note that if asked twice about the same height, we cache the response. | ||
func (d *Pegnetd) GetPegNetRateAverages(ctx context.Context, height uint32) (Avg interface{}) { | ||
|
||
if d.LastAveragesHeight == height { // If a cache hit is detected, return the cache value | ||
return d.LastAverages | ||
} | ||
|
||
ratesOverPeriod := d.LastAveragesData // First collect all the values over the blocks | ||
averages := map[fat2.PTicker]uint64{} // in the average period, then compute the averages | ||
if ratesOverPeriod == nil { // If no map exists yet | ||
ratesOverPeriod = map[fat2.PTicker][]uint64{} // create one. | ||
} | ||
|
||
defer func() { // Always set up the cache when exiting the routine | ||
d.LastAveragesData = ratesOverPeriod // Save the data we used to create averages | ||
d.LastAveragesHeight = height // Save the height of this data | ||
d.LastAverages = averages // Save the averages we computed | ||
}() | ||
|
||
// collectRatesAtHeight | ||
// This routine collects all the data used to compute an average. If any data is missing, then | ||
// that data is represented by a zero. | ||
collectRatesAtHeight := func(h uint32) { | ||
for k := range ratesOverPeriod { // Make sure there is room for a new height | ||
for len(ratesOverPeriod[k]) >= int(AveragePeriod) { // If at the limit or above, | ||
copy(ratesOverPeriod[k], ratesOverPeriod[k][1:]) // Shift data down 1 element | ||
ratesOverPeriod[k] = ratesOverPeriod[k][:len(ratesOverPeriod[k])-1] // And drop off the last value | ||
} | ||
} | ||
|
||
if rates, err := d.Pegnet.SelectRates(ctx, h); err != nil { // Pull the rates out of the database at each | ||
panic("no recovery from a database error getting rates") | ||
} else { | ||
for k, v := range rates { // For all the rates | ||
if ratesOverPeriod[k] == nil { // if no rates yet, at a slice for them | ||
ratesOverPeriod[k] = []uint64{} // Allocate the slice | ||
} | ||
ratesOverPeriod[k] = append(ratesOverPeriod[k], v) // Add the rates we find | ||
} | ||
} | ||
} | ||
|
||
switch { | ||
// If the LastAveragesHeight is out of range given our current height, we just need to load | ||
// all the values | ||
case d.LastAveragesHeight+1 < height || d.LastAveragesHeight > height: | ||
for k, v := range ratesOverPeriod { | ||
if v != nil { | ||
ratesOverPeriod[k] = ratesOverPeriod[k][:0] | ||
} | ||
} | ||
startHeightS := int64(height) - (int64(AveragePeriod)) + 1 // startHeight is AveragePeriod before height+1 | ||
// (add 1 so the block at height is included) | ||
if startHeightS < 1 { // If AveragePeriod blocks don't exist, | ||
startHeightS = 1 // then flour the start to 1 | ||
} | ||
|
||
startHeight := uint32(startHeightS) | ||
|
||
for h := startHeight; h <= height; h++ { // Collect rates over the blocks (including height) | ||
collectRatesAtHeight(h) // and add them to ratesOverPeriod | ||
} | ||
|
||
// If all we need is the next height, then only collect that height. | ||
case d.LastAveragesHeight+1 == height: | ||
collectRatesAtHeight(height) // Add the current height to the dataset so far | ||
} | ||
|
||
for k, v := range ratesOverPeriod { // The average rate is zero for any asset without | ||
averages[k] = 0 // the number of required rates | ||
if AveragePeriod-numberMissing(v) < AverageRequired { // Count the missing values, and if not enough | ||
continue // skip it | ||
} | ||
for _, v2 := range v { // Sum up all the rates found for an asset | ||
averages[k] += v2 // The assumption is that rates are no where near | ||
} // 64 bits, so they won't overflow | ||
averages[k] = averages[k] / uint64(len(v)) // Divide the sum of the rates by the number of rates | ||
} | ||
|
||
return averages // Return the rates we found. | ||
} | ||
|
||
func numberMissing(dataset []uint64) (numZeros uint64) { | ||
for _, v := range dataset { | ||
if v == 0 { | ||
numZeros++ | ||
} | ||
} | ||
if len(dataset) < int(AveragePeriod) { | ||
numZeros += AveragePeriod - uint64(len(dataset)) | ||
} | ||
return numZeros | ||
} |
Oops, something went wrong.