Skip to content

Commit d30b281

Browse files
committed
Changed convert to consider the average prices of the source and destination assets. Added an activation height for this. Did some minor refactoring
1 parent 08a0449 commit d30b281

17 files changed

Lines changed: 1053 additions & 182 deletions

cmd/api.go

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,13 @@ import (
1313
"text/tabwriter"
1414
"time"
1515

16-
"github.com/pegnet/pegnet/modules/conversions"
16+
"github.com/pegnet/pegnetd/node"
1717

1818
"github.com/Factom-Asset-Tokens/factom"
1919
"github.com/pegnet/pegnetd/config"
2020
"github.com/pegnet/pegnetd/fat/fat2"
21-
"github.com/pegnet/pegnetd/node"
21+
22+
"github.com/pegnet/pegnetd/node/conversions"
2223
"github.com/pegnet/pegnetd/node/pegnet"
2324
"github.com/pegnet/pegnetd/srv"
2425
"github.com/spf13/cobra"
@@ -350,8 +351,8 @@ var conv = &cobra.Command{
350351

351352
// Let's check the pXXX -> pFCT first
352353
status := getStatus()
353-
if (destAsset == "pFCT" || destAsset == "FCT") && uint32(status.Current) >= node.OneWaypFCTConversions {
354-
cmd.PrintErrln(fmt.Sprintf("pXXX -> pFCT conversions are not allowed since block height %d. If you need to acquire pFCT, you have to burn FCT -> pFCT", node.OneWaypFCTConversions))
354+
if (destAsset == "pFCT" || destAsset == "FCT") && uint32(status.Current) >= config.OneWaypFCTConversions {
355+
cmd.PrintErrln(fmt.Sprintf("pXXX -> pFCT conversions are not allowed since block height %d. If you need to acquire pFCT, you have to burn FCT -> pFCT", config.OneWaypFCTConversions))
355356
os.Exit(1)
356357
}
357358

@@ -360,8 +361,8 @@ var conv = &cobra.Command{
360361
if (destAsset == "PEG" || destAsset == "pDCR" || destAsset == "pDGB" || destAsset == "pDOGE" || destAsset == "pHBAR" ||
361362
destAsset == "pONT" || destAsset == "pRVN" || destAsset == "pBAT" || destAsset == "pALGO" || destAsset == "pBIF" ||
362363
destAsset == "pETB" || destAsset == "pKES" || destAsset == "pNGN" || destAsset == "pRWF" || destAsset == "pTZS" ||
363-
destAsset == "pUGX") && uint32(status.Current) >= node.OneWaySmallAssetsConversions {
364-
cmd.PrintErrln(fmt.Sprintf("pXXX -> pSmallAssets conversions are not allowed since block height %d.", node.OneWaySmallAssetsConversions))
364+
destAsset == "pUGX") && uint32(status.Current) >= config.OneWaySmallAssetsConversions {
365+
cmd.PrintErrln(fmt.Sprintf("pXXX -> pSmallAssets conversions are not allowed since block height %d.", config.OneWaySmallAssetsConversions))
365366
os.Exit(1)
366367
}
367368

@@ -793,7 +794,7 @@ var getBank = &cobra.Command{
793794
cl := srv.NewClient()
794795
cl.PegnetdServer = viper.GetString(config.Pegnetd)
795796
var res pegnet.BankEntry
796-
err = cl.Request("get-bank", srv.ParamsGetBank{Height: int32(height)}, &res)
797+
err = cl.Request("get-bank", srv.ParamsGetBank{Height: int32(height)}, &res) //TODO: height should be uint32
797798
if err != nil {
798799
fmt.Printf("Failed to make RPC request\nDetails:\n%v\n", err)
799800
os.Exit(1)
@@ -822,9 +823,9 @@ var getBank = &cobra.Command{
822823
if err == nil {
823824
fmt.Println("")
824825
fmt.Println("Value in USD")
825-
dAmt, _ := conversions.Convert(res.BankAmount, rates[fat2.PTickerPEG], rates[fat2.PTickerUSD])
826-
dUsed, _ := conversions.Convert(res.BankUsed, rates[fat2.PTickerPEG], rates[fat2.PTickerUSD])
827-
dReq, _ := conversions.Convert(res.PEGRequested, rates[fat2.PTickerPEG], rates[fat2.PTickerUSD])
826+
dAmt, _ := conversions.Convert(uint32(height), res.BankAmount, rates[fat2.PTickerPEG], rates[fat2.PTickerPEG], rates[fat2.PTickerUSD], rates[fat2.PTickerUSD])
827+
dUsed, _ := conversions.Convert(uint32(height), res.BankUsed, rates[fat2.PTickerPEG], rates[fat2.PTickerPEG], rates[fat2.PTickerUSD], rates[fat2.PTickerUSD])
828+
dReq, _ := conversions.Convert(uint32(height), res.PEGRequested, rates[fat2.PTickerPEG], rates[fat2.PTickerPEG], rates[fat2.PTickerUSD], rates[fat2.PTickerUSD])
828829
fmt.Printf("PEG in Bank : $%s\n", FactoshiToFactoid(dAmt))
829830
fmt.Printf("PEG Consumed : $%s\n", FactoshiToFactoid(dUsed))
830831
fmt.Printf("PEG Requested : $%s\n", FactoshiToFactoid(dReq))

cmd/root.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,12 +149,12 @@ func always(cmd *cobra.Command, args []string) {
149149
}
150150

151151
// Set all activations for testing
152-
node.SetAllActivations(uint32(act))
152+
config.SetAllActivations(uint32(act))
153153
}
154154

155155
if testingact, _ := cmd.Flags().GetInt32("testingact"); testingact >= 0 {
156156
fat2.Fat2RCDEActivation = uint32(testingact)
157-
node.V20HeightActivation = uint32(testingact)
157+
config.V20HeightActivation = uint32(testingact)
158158
// Also updaet hardfork
159159
pegnet.Hardforks[1].ActivationHeight = uint32(testingact)
160160
}

cmd/tx.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ import (
44
"fmt"
55
"strings"
66

7+
"github.com/pegnet/pegnetd/config"
8+
79
"github.com/spf13/cobra"
810

911
"github.com/Factom-Asset-Tokens/factom"
1012
"github.com/pegnet/pegnetd/fat/fat2"
11-
"github.com/pegnet/pegnetd/node"
1213
)
1314

1415
func addressRules(input string, output string) error {
@@ -67,7 +68,7 @@ func signAndSend(source string, tx *fat2.Transaction, cl *factom.Client, payment
6768
var txBatch fat2.TransactionBatch
6869
txBatch.Version = 1
6970
txBatch.Transactions = []fat2.Transaction{*tx}
70-
txBatch.Entry.ChainID = &node.TransactionChain
71+
txBatch.Entry.ChainID = &config.TransactionChain //TODO consider not passing a pointer to config.TransactionChain
7172

7273
// Sign the tx and make an entry
7374
entry, err := txBatch.Sign(priv)

config/activations.go

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package config
2+
3+
import (
4+
"github.com/Factom-Asset-Tokens/factom"
5+
"github.com/pegnet/pegnetd/fat/fat2"
6+
)
7+
8+
var (
9+
OPRChain = factom.NewBytes32("a642a8674f46696cc47fdb6b65f9c87b2a19c5ea8123b3d2f0c13b6f33a9d5ef")
10+
SPRChain = factom.NewBytes32("d5e395125335a21cef0ceca528168e87fe929fdac1f156870c1b1be6502448b4")
11+
TransactionChain = factom.NewBytes32("cffce0f409ebba4ed236d49d89c70e4bd1f1367d86402a3363366683265a242d")
12+
13+
// Acivation Heights
14+
15+
PegnetActivation uint32 = 206421
16+
GradingV2Activation uint32 = 210330
17+
18+
// TransactionConversionActivation indicates when tx/conversions go live on mainnet.
19+
// Target Activation Height is Oct 7, 2019 15 UTC
20+
TransactionConversionActivation uint32 = 213237
21+
22+
// This is when PEG is priced by the market cap equation
23+
// Estimated to be Oct 14 2019, 15:00:00 UTC
24+
PEGPricingActivation uint32 = 214287
25+
26+
// OneWaypFCTConversions makes pFCT a 1 way conversion. This means pFCT->pXXX,
27+
// but no asset can go into pFCT. AKA pXXX -/> pFCT.
28+
// The only way to aquire pFCT is to burn FCT. The burn command will remain.
29+
// Estimated to be Nov 25, 2019 17:47:00 UTC
30+
OneWaypFCTConversions uint32 = 220346
31+
32+
// Once this is activated, a maximum amount of PEG of 5,000 can be
33+
// converted per block. At a future height, a dynamic bank should be used.
34+
// Estimated to be Dec 9, 2019, 17:00 UTC
35+
PegnetConversionLimitActivation uint32 = 222270
36+
37+
// This is when PEG price is determined by the exchange price
38+
// Estimated to be Dec 9, 2019, 17:00 UTC
39+
PEGFreeFloatingPriceActivation uint32 = 222270
40+
41+
// V4OPRUpdate indicates the activation of additional currencies and ecdsa keys.
42+
// Estimated to be Feb 12, 2020, 18:00 UTC
43+
V4OPRUpdate uint32 = 231620
44+
45+
// V20HeightActivation indicates the activation of PegNet 2.0.
46+
// Estimated to be Aug 19th 2020 14:00 UTC
47+
V20HeightActivation uint32 = 258796
48+
49+
// Activation height for developer rewards
50+
V20DevRewardsHeightActivation uint32 = 260118
51+
52+
// SprSignatureActivation indicates the activation of SPR Signature.
53+
// Estimated to be Aug 28th 2020
54+
SprSignatureActivation uint32 = 260118
55+
56+
// OneWaypAssetsConversions makes some pAssets a 1 way conversion.
57+
// pDCR, pDGB, pDOGE, pHBAR, pONT, pRVN, pBAT, pALGO, pBIF, pETB, pKES, pNGN, pRWF, pTZS, pUGX
58+
// These pAssets have got small marketcap, and these will be disabled for conversion.
59+
// Estimated to be Dec 3th 2020
60+
OneWaySmallAssetsConversions uint32 = 274036
61+
62+
// V202EnhanceActivation indicates the activation of PegNet 2.0.2.
63+
// Estimated to be Dec 3th 2020
64+
V202EnhanceActivation uint32 = 274036
65+
66+
// V204EnhanceActivation indicates the activation of PegNet 2.0.4.
67+
// Estimated to be Mar 16th 2021
68+
V204EnhanceActivation uint32 = 288878
69+
70+
// V204EnhanceActivation indicates the activation that burns remaining airdrop amount.
71+
// Estimated to be April 16th 2021
72+
V204BurnMintedTokenActivation uint32 = 294206
73+
74+
// PIP10AveragingActivation changes conversions to use the lesser of a rolling average and market price
75+
// for the source of a conversion, and the higher of the rolling average and the market price for the
76+
// target of a conversion
77+
PIP10AverageActivation uint32 = 300000
78+
)
79+
80+
func SetAllActivations(act uint32) {
81+
PegnetActivation = act
82+
GradingV2Activation = act
83+
TransactionConversionActivation = act
84+
PEGPricingActivation = act
85+
OneWaypFCTConversions = act
86+
PegnetConversionLimitActivation = act
87+
PEGFreeFloatingPriceActivation = act
88+
fat2.Fat2RCDEActivation = act
89+
V4OPRUpdate = act
90+
V20HeightActivation = act
91+
V20DevRewardsHeightActivation = act
92+
OneWaySmallAssetsConversions = act
93+
SprSignatureActivation = act
94+
V202EnhanceActivation = act
95+
V204EnhanceActivation = act
96+
V204BurnMintedTokenActivation = act
97+
PIP10AverageActivation = act
98+
}

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,5 @@ replace github.com/Factom-Asset-Tokens/factom => github.com/Emyrk/factom v0.0.0-
1919
replace crawshaw.io/sqlite => github.com/AdamSLevy/sqlite v0.1.3-0.20191014215059-b98bb18889de
2020

2121
replace github.com/spf13/pflag v1.0.3 => github.com/AdamSLevy/pflag v1.0.4
22+
23+
replace github.com/pegnet/pegnet => ../pegnet

node/average.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package node
2+
3+
import (
4+
"context"
5+
6+
"github.com/pegnet/pegnetd/fat/fat2"
7+
)
8+
9+
const AveragePeriod = uint64(288) // Our Average Period is 2 days (144 10 minute blocks per day)
10+
11+
// getPegNetRateAverages
12+
// Gets all the rates for the AveragePeriod (the number of blocks contributing to the average), and computes
13+
// the average rate for all assets. If values are missing for an asset for any of the blocks in the AveragePeriod,
14+
// then don't allow conversions by setting the averate to zero for that asset
15+
//
16+
// Return a map of averages of the form map[fat2.PTicker]uint64
17+
//
18+
// Also note that if asked twice about the same height, we cache the response.
19+
func (d *Pegnetd) GetPegNetRateAverages(ctx context.Context, height uint32) (Avg interface{}) {
20+
21+
if d.LastAveragesHeight == height { // If a cache hit is detected, return the cache value
22+
return d.LastAverages
23+
}
24+
25+
ratesOverPeriod := map[fat2.PTicker][]uint64{} // First collect all the values over the blocks
26+
averages := map[fat2.PTicker]uint64{} // in the average period, then compute the averages
27+
28+
defer func() { // Always set up the cache when exiting the routine
29+
d.LastAveragesHeight = height
30+
d.LastAverages = averages
31+
}()
32+
33+
startHeight := height - (uint32(AveragePeriod)) + 1 // The startHeight is AveragePeriod before height+1
34+
// (add 1 so the block at height is included)
35+
if startHeight < 1 { // If AveragePeriod blocks don't exist, then ignore
36+
return averages
37+
}
38+
39+
for h := startHeight; height <= height; h++ { // Collect rates over the blocks (including height)
40+
var rates map[fat2.PTicker]uint64 // Collect all the rates
41+
var err error
42+
43+
if rates, err = d.Pegnet.SelectRates(ctx, h); err != nil { // Pull the rates out of the database at each
44+
return averages // height. Return averages if an error
45+
}
46+
47+
for k, v := range rates { // For all the rates
48+
if ratesOverPeriod[k] == nil { // if no rates yet, at a slice for them
49+
ratesOverPeriod[k] = []uint64{} // Allocate the slice
50+
}
51+
if v != 0 { // Only collect non-zero rates
52+
ratesOverPeriod[k] = append(ratesOverPeriod[k], v) // Add the rates we find
53+
}
54+
}
55+
}
56+
57+
for k, v := range ratesOverPeriod { // When we average the rates, we return a zero for
58+
averages[k] = 0 // any asset that doesn't have a rate in all blocks
59+
if uint64(len(v)) != AveragePeriod { // We can see missing rates because the list isn't
60+
continue // long enough. Just skip it, it will be zero
61+
}
62+
for _, v2 := range v { // Sum up all the rates found for an asset
63+
averages[k] += v2
64+
}
65+
averages[k] = averages[k] / AveragePeriod // We made sure all valid assets have AveragePeriod rates
66+
}
67+
68+
return averages // Return the rates we found.
69+
}

0 commit comments

Comments
 (0)