From 2dd62f9adfb098b51ba30a49755d16259f362bb8 Mon Sep 17 00:00:00 2001 From: Sergey Bushnyak Date: Thu, 4 Jun 2020 13:32:11 +0300 Subject: [PATCH 01/18] init work on dev rewards --- node/sync.go | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/node/sync.go b/node/sync.go index c46ed39..d30438a 100644 --- a/node/sync.go +++ b/node/sync.go @@ -269,6 +269,36 @@ func (d *Pegnetd) SyncBlock(ctx context.Context, tx *sql.Tx, height uint32) erro return nil } +// DevelopersPayouts works along with SnapshotPayouts. We assume that the current shapshot moved to the "past", and updated the current snapshot. +// So we can proceed to do the snapshot developer payouts. +func (d *Pegnetd) DevelopersPayouts( tx *sql.Tx, fLog *log.Entry, height uint32, heightTimestamp time.Time) error { + + // TODO: 1. read developer addresses from config file + // 2. calculate payouts and prepare structure + // 3. Insert tx into the db + + // We need to mock a TXID for the reward payouts + // to remove unnecessary network load + txid := fmt.Sprintf("%064d", height) + + type RewardAmount struct { + Address factom.FAAddress + PUSD uint64 + } + + var list []RewardAmount + var totalPayout = 2000 * 5 // Should length of the list + + fLog.WithFields(log.Fields{ + "eligible": len(list), + "PEG": float64(totalPayout) / 1e8, // Float is good enough here, + "txid": txid, + }).Info("balances snapshotted & developer rewards paid") + + return nil + +} + func multiFetch(eblock *factom.EBlock, c *factom.Client) error { err := eblock.Get(nil, c) if err != nil { From 9797e38afaa9089e44317d400b2f94196e739daf Mon Sep 17 00:00:00 2001 From: Sergey Bushnyak Date: Thu, 4 Jun 2020 14:33:26 +0300 Subject: [PATCH 02/18] update formatting --- node/sync.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/node/sync.go b/node/sync.go index d30438a..fd97344 100644 --- a/node/sync.go +++ b/node/sync.go @@ -269,9 +269,9 @@ func (d *Pegnetd) SyncBlock(ctx context.Context, tx *sql.Tx, height uint32) erro return nil } -// DevelopersPayouts works along with SnapshotPayouts. We assume that the current shapshot moved to the "past", and updated the current snapshot. +// DevelopersPayouts works along with SnapshotPayouts. We assume that the current shapshot moved to the "past", and updated the current snapshot. // So we can proceed to do the snapshot developer payouts. -func (d *Pegnetd) DevelopersPayouts( tx *sql.Tx, fLog *log.Entry, height uint32, heightTimestamp time.Time) error { +func (d *Pegnetd) DevelopersPayouts(tx *sql.Tx, fLog *log.Entry, height uint32, heightTimestamp time.Time) error { // TODO: 1. read developer addresses from config file // 2. calculate payouts and prepare structure @@ -285,7 +285,7 @@ func (d *Pegnetd) DevelopersPayouts( tx *sql.Tx, fLog *log.Entry, height uint32, Address factom.FAAddress PUSD uint64 } - + var list []RewardAmount var totalPayout = 2000 * 5 // Should length of the list @@ -296,7 +296,6 @@ func (d *Pegnetd) DevelopersPayouts( tx *sql.Tx, fLog *log.Entry, height uint32, }).Info("balances snapshotted & developer rewards paid") return nil - } func multiFetch(eblock *factom.EBlock, c *factom.Client) error { From 2cbaf7511e0ff4bb783d6bc7c2010fd7d19d2b03 Mon Sep 17 00:00:00 2001 From: Sergey Bushnyak Date: Tue, 28 Jul 2020 19:44:06 +0300 Subject: [PATCH 03/18] revert and move addresses from config to hardcoded version --- node/devs.go | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 node/devs.go diff --git a/node/devs.go b/node/devs.go new file mode 100644 index 0000000..feec47d --- /dev/null +++ b/node/devs.go @@ -0,0 +1,32 @@ +package node + +// Special structure +type DevReward struct { + dev_group string // group or comment about reward + dev_address string // address where to send developer reward + dev_reward_pct float64 // % from total development rewards +} + +var ( + // Hardcode developers who work active on PegNet + // to avoid manipulations from config files + // TODO v2.5 move into special DevRewards chain + DeveloperRewardAddress = []DevReward{ + {"Listing Tech Support", "FA2i9WZqJnaKbJxDY2AZdVgewE28uCcSwoFt8LJCMtGCC7tpCa2n", 10.00}, + {"Archecture Dev for PegNet 2.5", "FA37cGXKWMtf2MmHy3n1rMCYeLVuR5MpDaP4VXVeFavjJCJLYYez", 9.0}, + {"Trading Bots Work", "FA2wDRieaBrWeZHVuXXWUHY6t9nKCVCCKAMS5xknLUExuVAq3ziS", 9.0}, + {"Mining Pool Support / Dev/ Infra Hosting/ Gateway Operation", "FA3LDEA5fcskV6ZoFpKE84qPcjd7GYjEnswGHMZXL1V9d14wmgh3", 9.0}, + {"Media Tech Support", "FA381EygeEXjZzB6hNvxbE4oSUzHZMfvGByMZoW5UrG1gHEKJcNK", 8.0}, + {"Social Coverage User Support", "FA2DxkaTx1k2oGfbTqvwVMScSHHac7JFRiBjRngjRnqQpeBxsLhA", 8.0}, + {"pTrader + PIPs", "FA2Ersb227gn7eWJ2HPsHZ5QqxfMBZhSjwixQ44dAS17CtRXSDRU", 8.0}, + {"Desktop Wallet + PIPs", " FA2eFEVUzTQZxNp3LYYgjPaaHUfGmuvShhtBdGB2BBWMeByPCmJy", 8.0}, + {"DeFi Integrations + PIPs Work", "FA2z6Nnaj8a5nXmwZD8tYhDENAx8ciVE3xeNeixKiFj22vZEZEdT", 8.0}, + {"Explorer + Mobile", " FA2T72oxBxXvnujNdsVUshqFM2qV1W4nJy33nkrpxbYQV8rFbUPP", 5.0}, + {"Prosper / Staking GUI Upgrades", "FA2cEaq1GdGfFjhymiTEzW24DocZFZHNBqe9qkT18YPaL5ZzsgRi", 5.0}, + {"Payment Intergrations Work", "FA2YhZBZbc4V858ao7dJuAqRC4iwA3MrbZs7BHUPK7Mq19yYdMwZ", 3.0}, + {"General Development Tasks", "FA3PYuvrsDvkhnekokVNrgLn7JiL5pChSBTtR9gZB1mVGFVB7JRD", 3.0}, + {"Gateway Ethereum Upgrade", "FA2Wy7AzeoBuaXYnGu67xa5zdNkmqTbPryUgpy7qVPvj46GRZkep", 2.0}, + {"Statistics & Visualizations of PegNet", "FA3dsCiKGzwrTALfX4T2CKv8wCmNMxwJx3jS4jz1ST9fwge9Wrnm", 2.0}, + {"Trading Tech Support", "FA2a2nXgkBg7pL5wrgm99rLZDGFs2T8jfTgMuia6ep8ZMkVtPe8E", 3.00}, + } +) From 15fbcb76e7d369688c3bc53c59bba940ba949c00 Mon Sep 17 00:00:00 2001 From: Sergey Bushnyak Date: Tue, 28 Jul 2020 20:12:29 +0300 Subject: [PATCH 04/18] correct naming convention --- node/devs.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/node/devs.go b/node/devs.go index feec47d..9253e8e 100644 --- a/node/devs.go +++ b/node/devs.go @@ -2,15 +2,15 @@ package node // Special structure type DevReward struct { - dev_group string // group or comment about reward - dev_address string // address where to send developer reward - dev_reward_pct float64 // % from total development rewards + DevGroup string // group or comment about reward + DevAddress string // address where to send developer reward + DevRewardPct float64 // % from total development rewards } var ( // Hardcode developers who work active on PegNet // to avoid manipulations from config files - // TODO v2.5 move into special DevRewards chain + // TODO: v2.5 move into special Developer Rewards Chain (DRC) DeveloperRewardAddress = []DevReward{ {"Listing Tech Support", "FA2i9WZqJnaKbJxDY2AZdVgewE28uCcSwoFt8LJCMtGCC7tpCa2n", 10.00}, {"Archecture Dev for PegNet 2.5", "FA37cGXKWMtf2MmHy3n1rMCYeLVuR5MpDaP4VXVeFavjJCJLYYez", 9.0}, From 6a0abc9e63399cfa0e33d438dc0dba605848b0aa Mon Sep 17 00:00:00 2001 From: Sergey Bushnyak Date: Sun, 2 Aug 2020 20:39:04 +0300 Subject: [PATCH 05/18] move logic to separate block outside snapshotting; rebase on top of staging as standalone logic --- node/devs.go | 2 +- node/sync.go | 43 ++++++++++++++++++++++++------------------- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/node/devs.go b/node/devs.go index 9253e8e..5c14deb 100644 --- a/node/devs.go +++ b/node/devs.go @@ -11,7 +11,7 @@ var ( // Hardcode developers who work active on PegNet // to avoid manipulations from config files // TODO: v2.5 move into special Developer Rewards Chain (DRC) - DeveloperRewardAddress = []DevReward{ + DeveloperRewardAddreses = []DevReward{ {"Listing Tech Support", "FA2i9WZqJnaKbJxDY2AZdVgewE28uCcSwoFt8LJCMtGCC7tpCa2n", 10.00}, {"Archecture Dev for PegNet 2.5", "FA37cGXKWMtf2MmHy3n1rMCYeLVuR5MpDaP4VXVeFavjJCJLYYez", 9.0}, {"Trading Bots Work", "FA2wDRieaBrWeZHVuXXWUHY6t9nKCVCCKAMS5xknLUExuVAq3ziS", 9.0}, diff --git a/node/sync.go b/node/sync.go index fd97344..cd3421f 100644 --- a/node/sync.go +++ b/node/sync.go @@ -266,34 +266,39 @@ func (d *Pegnetd) SyncBlock(ctx context.Context, tx *sql.Tx, height uint32) erro return err } } + + + // 5) Apply Developers Rewards + if height >= V20HeightActivation { + err := d.DevelopersPayouts(tx, fLog, rates, height, dblock.Timestamp) + if err != nil { + // something wrong happend during payout execution + return err + } + } + + return nil } -// DevelopersPayouts works along with SnapshotPayouts. We assume that the current shapshot moved to the "past", and updated the current snapshot. -// So we can proceed to do the snapshot developer payouts. +// DevelopersPayouts for PIP16 sending rewards for developers func (d *Pegnetd) DevelopersPayouts(tx *sql.Tx, fLog *log.Entry, height uint32, heightTimestamp time.Time) error { - // TODO: 1. read developer addresses from config file - // 2. calculate payouts and prepare structure - // 3. Insert tx into the db + var totalPayout = 2000 // PEG - // We need to mock a TXID for the reward payouts - // to remove unnecessary network load - txid := fmt.Sprintf("%064d", height) + // we use hardcoded list of dev payouts + for _, dev := DeveloperRewardAddreses { - type RewardAmount struct { - Address factom.FAAddress - PUSD uint64 - } + // TODO: move real txid + txid := fmt.Sprintf("%064d", height) - var list []RewardAmount - var totalPayout = 2000 * 5 // Should length of the list + fLog.WithFields(log.Fields{ + "eligible": len(list), + "PEG": float64(totalPayout) / 1e8, // Float is good enough here, + "txid": txid, + }).Info("developer rewards | paid out ") - fLog.WithFields(log.Fields{ - "eligible": len(list), - "PEG": float64(totalPayout) / 1e8, // Float is good enough here, - "txid": txid, - }).Info("balances snapshotted & developer rewards paid") + } return nil } From 8e6fa7a930fc956ac5c4025cb11fc1176b8cd9ec Mon Sep 17 00:00:00 2001 From: Sergey Bushnyak Date: Sun, 2 Aug 2020 22:14:51 +0300 Subject: [PATCH 06/18] update logic --- node/sync.go | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/node/sync.go b/node/sync.go index cd3421f..df65866 100644 --- a/node/sync.go +++ b/node/sync.go @@ -267,36 +267,35 @@ func (d *Pegnetd) SyncBlock(ctx context.Context, tx *sql.Tx, height uint32) erro } } - // 5) Apply Developers Rewards if height >= V20HeightActivation { - err := d.DevelopersPayouts(tx, fLog, rates, height, dblock.Timestamp) - if err != nil { - // something wrong happend during payout execution - return err - } + err := d.DevelopersPayouts(tx, fLog, height, dblock.Timestamp) + if err != nil { + // something wrong happend during payout execution + return err + } } - return nil } // DevelopersPayouts for PIP16 sending rewards for developers func (d *Pegnetd) DevelopersPayouts(tx *sql.Tx, fLog *log.Entry, height uint32, heightTimestamp time.Time) error { - var totalPayout = 2000 // PEG - // we use hardcoded list of dev payouts - for _, dev := DeveloperRewardAddreses { + for _, dev := range DeveloperRewardAddreses { + + // here PerBlockDevelopers is total payout value + reward := (PerBlockDevelopers / 100) * dev.DevRewardPct - // TODO: move real txid - txid := fmt.Sprintf("%064d", height) + // TODO: move real txid + txid := fmt.Sprintf("%064d", height) - fLog.WithFields(log.Fields{ - "eligible": len(list), - "PEG": float64(totalPayout) / 1e8, // Float is good enough here, - "txid": txid, - }).Info("developer rewards | paid out ") + fLog.WithFields(log.Fields{ + "developer": len(dev.DevAddress), + "PEG": float64(reward) / 1e8, // Float is good enough here, + "txid": txid, + }).Info("developer reward | paid out to") } From 528c2259b45f78168601bdfec8857a5ae3ffea81 Mon Sep 17 00:00:00 2001 From: Sergey Bushnyak Date: Sun, 2 Aug 2020 22:22:04 +0300 Subject: [PATCH 07/18] update totals --- node/sync.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/node/sync.go b/node/sync.go index 48b951c..049d270 100644 --- a/node/sync.go +++ b/node/sync.go @@ -285,16 +285,19 @@ func (d *Pegnetd) SyncBlock(ctx context.Context, tx *sql.Tx, height uint32) erro // DevelopersPayouts for PIP16 sending rewards for developers func (d *Pegnetd) DevelopersPayouts(tx *sql.Tx, fLog *log.Entry, height uint32, heightTimestamp time.Time) error { + totalPayout := uint64(conversions.PerBlockDevelopers) * 144 // once a day, should be changed to SnapshotRate when it's integrated + // we use hardcoded list of dev payouts for _, dev := range DeveloperRewardAddreses { // here PerBlockDevelopers is total payout value - reward := (PerBlockDevelopers / 100) * dev.DevRewardPct + reward := (conversions.PerBlockDevelopers / 100) * dev.DevRewardPct // TODO: move real txid txid := fmt.Sprintf("%064d", height) fLog.WithFields(log.Fields{ + "total": float64(totalPayout) / 1e8, "developer": len(dev.DevAddress), "PEG": float64(reward) / 1e8, // Float is good enough here, "txid": txid, From 223e28c09a567467b5c561eddcd9737a70e006e8 Mon Sep 17 00:00:00 2001 From: Sergey Bushnyak Date: Mon, 3 Aug 2020 17:08:03 +0300 Subject: [PATCH 08/18] change code to use SnapshotRate period also for dev rewards --- node/devs.go | 26 ++++++++++++++++++++++++++ node/sync.go | 52 +++++++++++++++++++++++++++------------------------- 2 files changed, 53 insertions(+), 25 deletions(-) diff --git a/node/devs.go b/node/devs.go index 5c14deb..0d00684 100644 --- a/node/devs.go +++ b/node/devs.go @@ -30,3 +30,29 @@ var ( {"Trading Tech Support", "FA2a2nXgkBg7pL5wrgm99rLZDGFs2T8jfTgMuia6ep8ZMkVtPe8E", 3.00}, } ) + +// DevelopersPayouts for PIP16 sending rewards for developers +func (d *Pegnetd) DevelopersPayouts(tx *sql.Tx, fLog *log.Entry, height uint32, heightTimestamp time.Time) error { + + totalPayout := uint64(conversions.PerBlockDevelopers) * 144 // once a day, should be changed to SnapshotRate when it's integrated + + // we use hardcoded list of dev payouts + for _, dev := range DeveloperRewardAddreses { + + // here PerBlockDevelopers is total payout value + reward := (conversions.PerBlockDevelopers / 100) * dev.DevRewardPct + + // TODO: move real txid + txid := fmt.Sprintf("%064d", height) + + fLog.WithFields(log.Fields{ + "total": float64(totalPayout) / 1e8, + "developer": len(dev.DevAddress), + "PEG": float64(reward) / 1e8, // Float is good enough here, + "txid": txid, + }).Info("developer reward | paid out to") + + } + + return nil +} diff --git a/node/sync.go b/node/sync.go index 95d9235..e74f941 100644 --- a/node/sync.go +++ b/node/sync.go @@ -312,31 +312,6 @@ func (d *Pegnetd) SyncBlock(ctx context.Context, tx *sql.Tx, height uint32) erro return nil } -// DevelopersPayouts for PIP16 sending rewards for developers -func (d *Pegnetd) DevelopersPayouts(tx *sql.Tx, fLog *log.Entry, height uint32, heightTimestamp time.Time) error { - - totalPayout := uint64(conversions.PerBlockDevelopers) * 144 // once a day, should be changed to SnapshotRate when it's integrated - - // we use hardcoded list of dev payouts - for _, dev := range DeveloperRewardAddreses { - - // here PerBlockDevelopers is total payout value - reward := (conversions.PerBlockDevelopers / 100) * dev.DevRewardPct - - // TODO: move real txid - txid := fmt.Sprintf("%064d", height) - - fLog.WithFields(log.Fields{ - "total": float64(totalPayout) / 1e8, - "developer": len(dev.DevAddress), - "PEG": float64(reward) / 1e8, // Float is good enough here, - "txid": txid, - }).Info("developer reward | paid out to") - - } - - return nil -} // SnapshotPayouts moves the current shapshot to the "past", and updates the current snapshot. Then // it proceeds to do the snapshot staking payouts. @@ -457,6 +432,33 @@ func (d *Pegnetd) SnapshotPayouts(tx *sql.Tx, fLog *log.Entry, rates map[fat2.PT return nil } + +// DevelopersPayouts for PIP16 sending rewards for developers +func (d *Pegnetd) DevelopersPayouts(tx *sql.Tx, fLog *log.Entry, height uint32, heightTimestamp time.Time) error { + + totalPayout := uint64(conversions.PerBlockDevelopers) * pegnet.SnapshotRate // once a day + + // we use hardcoded list of dev payouts + for _, dev := range DeveloperRewardAddreses { + + // here PerBlockDevelopers is total payout value + reward := (conversions.PerBlockDevelopers / 100) * dev.DevRewardPct + + // TODO: move real txid + txid := fmt.Sprintf("%064d", height) + + fLog.WithFields(log.Fields{ + "total": float64(totalPayout) / 1e8, + "developer": len(dev.DevAddress), + "PEG": float64(reward) / 1e8, // Float is good enough here, + "txid": txid, + }).Info("developer reward | paid out to") + + } + + return nil +} + func multiFetch(eblock *factom.EBlock, c *factom.Client) error { err := eblock.Get(nil, c) if err != nil { From cdd75cc7cad18234f15e248b954dc2ce9d683316 Mon Sep 17 00:00:00 2001 From: Sergey Bushnyak Date: Mon, 3 Aug 2020 17:10:47 +0300 Subject: [PATCH 09/18] cleanup code --- node/devs.go | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/node/devs.go b/node/devs.go index 0d00684..5c14deb 100644 --- a/node/devs.go +++ b/node/devs.go @@ -30,29 +30,3 @@ var ( {"Trading Tech Support", "FA2a2nXgkBg7pL5wrgm99rLZDGFs2T8jfTgMuia6ep8ZMkVtPe8E", 3.00}, } ) - -// DevelopersPayouts for PIP16 sending rewards for developers -func (d *Pegnetd) DevelopersPayouts(tx *sql.Tx, fLog *log.Entry, height uint32, heightTimestamp time.Time) error { - - totalPayout := uint64(conversions.PerBlockDevelopers) * 144 // once a day, should be changed to SnapshotRate when it's integrated - - // we use hardcoded list of dev payouts - for _, dev := range DeveloperRewardAddreses { - - // here PerBlockDevelopers is total payout value - reward := (conversions.PerBlockDevelopers / 100) * dev.DevRewardPct - - // TODO: move real txid - txid := fmt.Sprintf("%064d", height) - - fLog.WithFields(log.Fields{ - "total": float64(totalPayout) / 1e8, - "developer": len(dev.DevAddress), - "PEG": float64(reward) / 1e8, // Float is good enough here, - "txid": txid, - }).Info("developer reward | paid out to") - - } - - return nil -} From c6326be20e1e16716c334ecea092fae2c964cb57 Mon Sep 17 00:00:00 2001 From: Sergey Bushnyak Date: Mon, 3 Aug 2020 17:41:12 +0300 Subject: [PATCH 10/18] move transactions into separate loop --- node/pegnet/txhistory.go | 4 ++++ node/sync.go | 30 ++++++++++++++++++++++-------- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/node/pegnet/txhistory.go b/node/pegnet/txhistory.go index b31ef83..5f55e16 100644 --- a/node/pegnet/txhistory.go +++ b/node/pegnet/txhistory.go @@ -450,3 +450,7 @@ func (p *Pegnet) InsertStakingCoinbase(tx *sql.Tx, txid string, height uint32, h return nil } + +func (p *Pegnet) InsertDeveloperRewardsCoinbase(tx *sql.Tx, txid string, height uint32, heightTimestamp time.Time, payouts map[string]uint64, addressMap map[string]factom.FAAddress) error { + return nil +} diff --git a/node/sync.go b/node/sync.go index e74f941..7c10376 100644 --- a/node/sync.go +++ b/node/sync.go @@ -312,7 +312,6 @@ func (d *Pegnetd) SyncBlock(ctx context.Context, tx *sql.Tx, height uint32) erro return nil } - // SnapshotPayouts moves the current shapshot to the "past", and updates the current snapshot. Then // it proceeds to do the snapshot staking payouts. func (d *Pegnetd) SnapshotPayouts(tx *sql.Tx, fLog *log.Entry, rates map[fat2.PTicker]uint64, height uint32, heightTimestamp time.Time) error { @@ -432,30 +431,45 @@ func (d *Pegnetd) SnapshotPayouts(tx *sql.Tx, fLog *log.Entry, rates map[fat2.PT return nil } - // DevelopersPayouts for PIP16 sending rewards for developers func (d *Pegnetd) DevelopersPayouts(tx *sql.Tx, fLog *log.Entry, height uint32, heightTimestamp time.Time) error { totalPayout := uint64(conversions.PerBlockDevelopers) * pegnet.SnapshotRate // once a day + payoutStart := time.Now() // we use hardcoded list of dev payouts for _, dev := range DeveloperRewardAddreses { - // here PerBlockDevelopers is total payout value - reward := (conversions.PerBlockDevelopers / 100) * dev.DevRewardPct + // we calculate developers reward from % pre-defined + rewardPayout := uint64((conversions.PerBlockDevelopers / 100) * dev.DevRewardPct) + addr, err := factom.NewFAAddress(dev.DevAddress) - // TODO: move real txid - txid := fmt.Sprintf("%064d", height) + _, err = d.Pegnet.AddToBalance(tx, &addr, fat2.PTickerPEG, rewardPayout) + if err != nil { + return err + } fLog.WithFields(log.Fields{ "total": float64(totalPayout) / 1e8, "developer": len(dev.DevAddress), - "PEG": float64(reward) / 1e8, // Float is good enough here, - "txid": txid, + "PEG": float64(rewardPayout) / 1e8, // Float is good enough here, + //"txid": txid, }).Info("developer reward | paid out to") } + //We need to mock a TXID for the payouts + txid := fmt.Sprintf("%064d", height) + + ///////////////////////////////////////////////// + fLog.WithFields(log.Fields{ + "total": float64(totalPayout) / 1e8, + //"developer": len(dev.DevAddress), + //"PEG": float64(reward) / 1e8, // Float is good enough here, + "elapsed": time.Since(payoutStart), + "txid": txid, + }).Info("developer reward | paid out to") + return nil } From 28f7190f65c2f749bb70240e667cef1d83767694 Mon Sep 17 00:00:00 2001 From: Sergey Bushnyak Date: Tue, 4 Aug 2020 22:01:16 +0300 Subject: [PATCH 11/18] cleanup comments --- node/devs.go | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/node/devs.go b/node/devs.go index 5c14deb..0fc674e 100644 --- a/node/devs.go +++ b/node/devs.go @@ -1,19 +1,22 @@ package node -// Special structure +// Special structure for the Developer rewards type DevReward struct { - DevGroup string // group or comment about reward - DevAddress string // address where to send developer reward + DevGroup string // group or information about reward + DevAddress string // FCT address where to send developer reward DevRewardPct float64 // % from total development rewards } +// Hardcode developers who work active on PegNet to avoid manipulations from config files +// +// contains the percentage distribution of the total 2000 +// defined in `pegnet` repo `modules/conversions/conversionlimit.go` as PerBlockDevelopers +// +// TODO: in v2.5 move into special Developer Rewards Chain (DRC) var ( - // Hardcode developers who work active on PegNet - // to avoid manipulations from config files - // TODO: v2.5 move into special Developer Rewards Chain (DRC) DeveloperRewardAddreses = []DevReward{ {"Listing Tech Support", "FA2i9WZqJnaKbJxDY2AZdVgewE28uCcSwoFt8LJCMtGCC7tpCa2n", 10.00}, - {"Archecture Dev for PegNet 2.5", "FA37cGXKWMtf2MmHy3n1rMCYeLVuR5MpDaP4VXVeFavjJCJLYYez", 9.0}, + {"Architecture Dev for PegNet 2.5", "FA37cGXKWMtf2MmHy3n1rMCYeLVuR5MpDaP4VXVeFavjJCJLYYez", 9.0}, {"Trading Bots Work", "FA2wDRieaBrWeZHVuXXWUHY6t9nKCVCCKAMS5xknLUExuVAq3ziS", 9.0}, {"Mining Pool Support / Dev/ Infra Hosting/ Gateway Operation", "FA3LDEA5fcskV6ZoFpKE84qPcjd7GYjEnswGHMZXL1V9d14wmgh3", 9.0}, {"Media Tech Support", "FA381EygeEXjZzB6hNvxbE4oSUzHZMfvGByMZoW5UrG1gHEKJcNK", 8.0}, From b0fcbb674195002dd17406e77e1caf725ea018d0 Mon Sep 17 00:00:00 2001 From: Sergey Bushnyak Date: Tue, 4 Aug 2020 22:08:11 +0300 Subject: [PATCH 12/18] restore rewards coinbase function --- node/pegnet/txhistory.go | 59 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/node/pegnet/txhistory.go b/node/pegnet/txhistory.go index 5f55e16..bc59ce8 100644 --- a/node/pegnet/txhistory.go +++ b/node/pegnet/txhistory.go @@ -452,5 +452,64 @@ func (p *Pegnet) InsertStakingCoinbase(tx *sql.Tx, txid string, height uint32, h } func (p *Pegnet) InsertDeveloperRewardsCoinbase(tx *sql.Tx, txid string, height uint32, heightTimestamp time.Time, payouts map[string]uint64, addressMap map[string]factom.FAAddress) error { + txidBytes, err := hex.DecodeString(txid) + if err != nil { + return err + } + + // First we need to record the batch. The batch is the entire set of transactions, where + // each tx is a deverloper reward. + stmt, err := tx.Prepare(`INSERT INTO "pn_history_txbatch" + (entry_hash, height, blockorder, timestamp, executed) VALUES + (?, ?, ?, ?, ?)`) + if err != nil { + return err + } + + // The Entryhash is the custom txid, it is not an actual entry on chain + // The executed height is the same height as the recorded. + _, err = stmt.Exec(txidBytes, height, 0, heightTimestamp.Unix(), height) + if err != nil { + return err + } + + // Now we record each developer reward. + for addTxid, payout := range payouts { + // The address to pay + faAdd := addressMap[addTxid] + // All addresses are stored as bytes in the sqlitedb + add := faAdd[:] + // index for the address + index, _, err := SplitTxID(addTxid) + if err != nil { + return err + } + + // Insert each payout as a coinbase. + // Insert the TX + coinbaseStatement, err := tx.Prepare(`INSERT INTO "pn_history_transaction" + (entry_hash, tx_index, action_type, from_address, from_asset, from_amount, to_asset, to_amount, outputs) VALUES + (?, ?, ?, ?, ?, ?, ?, ?, ?)`) + if err != nil { + return err + } + + _, err = coinbaseStatement.Exec(txidBytes, index, Coinbase, add, "", 0, "PEG", payout, "") + if err != nil { + return err + } + + // Insert into lookup table + lookup, err := tx.Prepare(insertLookupQuery) + if err != nil { + return err + } + + if _, err = lookup.Exec(txidBytes, index, add); err != nil { + return err + } + + } + return nil } From 01898eacb664fdcb6993890c3768e902d3a608f4 Mon Sep 17 00:00:00 2001 From: Sergey Bushnyak Date: Wed, 5 Aug 2020 17:05:04 +0300 Subject: [PATCH 13/18] use single loop for stakingl; fix mockup issue --- node/pegnet/txhistory.go | 56 +++++++++++++++++++--------------------- node/sync.go | 25 +++++++++++++++--- 2 files changed, 48 insertions(+), 33 deletions(-) diff --git a/node/pegnet/txhistory.go b/node/pegnet/txhistory.go index bc59ce8..4e44992 100644 --- a/node/pegnet/txhistory.go +++ b/node/pegnet/txhistory.go @@ -451,7 +451,7 @@ func (p *Pegnet) InsertStakingCoinbase(tx *sql.Tx, txid string, height uint32, h return nil } -func (p *Pegnet) InsertDeveloperRewardsCoinbase(tx *sql.Tx, txid string, height uint32, heightTimestamp time.Time, payouts map[string]uint64, addressMap map[string]factom.FAAddress) error { +func (p *Pegnet) InsertDeveloperRewardCoinbase(tx *sql.Tx, txid string, addTxid string, height uint32, heightTimestamp time.Time, payout uint64, faAdd factom.FAAddress) error { txidBytes, err := hex.DecodeString(txid) if err != nil { return err @@ -474,41 +474,37 @@ func (p *Pegnet) InsertDeveloperRewardsCoinbase(tx *sql.Tx, txid string, height } // Now we record each developer reward. - for addTxid, payout := range payouts { - // The address to pay - faAdd := addressMap[addTxid] - // All addresses are stored as bytes in the sqlitedb - add := faAdd[:] - // index for the address - index, _, err := SplitTxID(addTxid) - if err != nil { - return err - } - // Insert each payout as a coinbase. - // Insert the TX - coinbaseStatement, err := tx.Prepare(`INSERT INTO "pn_history_transaction" + // All addresses are stored as bytes in the sqlitedb + add := faAdd[:] + // index for the address + index, _, err := SplitTxID(addTxid) + if err != nil { + return err + } + + // Insert each payout as a coinbase. + // Insert the TX + coinbaseStatement, err := tx.Prepare(`INSERT INTO "pn_history_transaction" (entry_hash, tx_index, action_type, from_address, from_asset, from_amount, to_asset, to_amount, outputs) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`) - if err != nil { - return err - } - - _, err = coinbaseStatement.Exec(txidBytes, index, Coinbase, add, "", 0, "PEG", payout, "") - if err != nil { - return err - } + if err != nil { + return err + } - // Insert into lookup table - lookup, err := tx.Prepare(insertLookupQuery) - if err != nil { - return err - } + _, err = coinbaseStatement.Exec(txidBytes, index, Coinbase, add, "", 0, "PEG", payout, "") + if err != nil { + return err + } - if _, err = lookup.Exec(txidBytes, index, add); err != nil { - return err - } + // Insert into lookup table + lookup, err := tx.Prepare(insertLookupQuery) + if err != nil { + return err + } + if _, err = lookup.Exec(txidBytes, index, add); err != nil { + return err } return nil diff --git a/node/sync.go b/node/sync.go index 7c10376..b060d04 100644 --- a/node/sync.go +++ b/node/sync.go @@ -437,6 +437,9 @@ func (d *Pegnetd) DevelopersPayouts(tx *sql.Tx, fLog *log.Entry, height uint32, totalPayout := uint64(conversions.PerBlockDevelopers) * pegnet.SnapshotRate // once a day payoutStart := time.Now() + // We need to mock a TXID to record zeroing + txid := fmt.Sprintf("%064d", height) + // we use hardcoded list of dev payouts for _, dev := range DeveloperRewardAddreses { @@ -449,6 +452,25 @@ func (d *Pegnetd) DevelopersPayouts(tx *sql.Tx, fLog *log.Entry, height uint32, return err } + // Mock entry hash value + addTxid := fmt.Sprintf("%d-%s", dev.DevAddress, txid) + + // Get dev address as FAAdress + FADevAddress, err := factom.NewFAAddress(dev.DevAddress) + if err != nil { + log.WithFields(log.Fields{ + "error": err, + "addr": dev.DevAddress, + }).Info("error getting developer address") + } + + // ---- Database Payouts ---- + // Inserts tx into the db + err = d.Pegnet.InsertDeveloperRewardCoinbase(tx, txid, addTxid, height, heightTimestamp, rewardPayout, FADevAddress) + if err != nil { + return err + } + fLog.WithFields(log.Fields{ "total": float64(totalPayout) / 1e8, "developer": len(dev.DevAddress), @@ -458,9 +480,6 @@ func (d *Pegnetd) DevelopersPayouts(tx *sql.Tx, fLog *log.Entry, height uint32, } - //We need to mock a TXID for the payouts - txid := fmt.Sprintf("%064d", height) - ///////////////////////////////////////////////// fLog.WithFields(log.Fields{ "total": float64(totalPayout) / 1e8, From eec44386f16aaa8a3eeb51e4da309de8ae62b928 Mon Sep 17 00:00:00 2001 From: Sergey Bushnyak Date: Wed, 5 Aug 2020 17:24:01 +0300 Subject: [PATCH 14/18] make developer payouts only once a day --- node/sync.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/node/sync.go b/node/sync.go index b060d04..d80cd0a 100644 --- a/node/sync.go +++ b/node/sync.go @@ -301,7 +301,7 @@ func (d *Pegnetd) SyncBlock(ctx context.Context, tx *sql.Tx, height uint32) erro } // 5) Apply Developers Rewards - if height >= V20HeightActivation { + if height >= V20HeightActivation && height%pegnet.SnapshotRate == 0 { err := d.DevelopersPayouts(tx, fLog, height, dblock.Timestamp) if err != nil { // something wrong happend during payout execution @@ -437,7 +437,7 @@ func (d *Pegnetd) DevelopersPayouts(tx *sql.Tx, fLog *log.Entry, height uint32, totalPayout := uint64(conversions.PerBlockDevelopers) * pegnet.SnapshotRate // once a day payoutStart := time.Now() - // We need to mock a TXID to record zeroing + // We need to mock a TXID to record dev rewards txid := fmt.Sprintf("%064d", height) // we use hardcoded list of dev payouts @@ -462,6 +462,7 @@ func (d *Pegnetd) DevelopersPayouts(tx *sql.Tx, fLog *log.Entry, height uint32, "error": err, "addr": dev.DevAddress, }).Info("error getting developer address") + return err } // ---- Database Payouts ---- From fd01afe6eb859045c6dc58ae153d063abb48fd9f Mon Sep 17 00:00:00 2001 From: Sergey Bushnyak Date: Wed, 5 Aug 2020 18:00:01 +0300 Subject: [PATCH 15/18] small cleanup --- node/sync.go | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/node/sync.go b/node/sync.go index 8883398..8587074 100644 --- a/node/sync.go +++ b/node/sync.go @@ -522,7 +522,7 @@ func (d *Pegnetd) DevelopersPayouts(tx *sql.Tx, fLog *log.Entry, height uint32, if err != nil { log.WithFields(log.Fields{ "error": err, - "addr": dev.DevAddress, + "addr": dev.DevAddress, }).Info("error getting developer address") return err } @@ -537,20 +537,16 @@ func (d *Pegnetd) DevelopersPayouts(tx *sql.Tx, fLog *log.Entry, height uint32, fLog.WithFields(log.Fields{ "total": float64(totalPayout) / 1e8, "developer": len(dev.DevAddress), - "PEG": float64(rewardPayout) / 1e8, // Float is good enough here, - //"txid": txid, + "PEG": float64(rewardPayout) / 1e8, // Float is good enough here }).Info("developer reward | paid out to") } - ///////////////////////////////////////////////// fLog.WithFields(log.Fields{ - "total": float64(totalPayout) / 1e8, - //"developer": len(dev.DevAddress), - //"PEG": float64(reward) / 1e8, // Float is good enough here, + "total": float64(totalPayout) / 1e8, "elapsed": time.Since(payoutStart), "txid": txid, - }).Info("developer reward | paid out to") + }).Info("developer rewards | paid out") return nil } From 30a82acb8c60af609da71f2d77999b4c10ac6551 Mon Sep 17 00:00:00 2001 From: Sergey Bushnyak Date: Wed, 5 Aug 2020 18:10:52 +0300 Subject: [PATCH 16/18] fix build error --- node/sync.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/sync.go b/node/sync.go index 8587074..b530a0f 100644 --- a/node/sync.go +++ b/node/sync.go @@ -515,7 +515,7 @@ func (d *Pegnetd) DevelopersPayouts(tx *sql.Tx, fLog *log.Entry, height uint32, } // Mock entry hash value - addTxid := fmt.Sprintf("%d-%s", dev.DevAddress, txid) + addTxid := fmt.Sprintf("%d-%s", 0, txid) // Get dev address as FAAdress FADevAddress, err := factom.NewFAAddress(dev.DevAddress) From 1bc4ffff06f0e0ebce17a46d6fc7c6d653dd113b Mon Sep 17 00:00:00 2001 From: Sergey Bushnyak Date: Wed, 5 Aug 2020 18:13:50 +0300 Subject: [PATCH 17/18] try to fix build error again --- node/sync.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/node/sync.go b/node/sync.go index b530a0f..a687627 100644 --- a/node/sync.go +++ b/node/sync.go @@ -503,6 +503,7 @@ func (d *Pegnetd) DevelopersPayouts(tx *sql.Tx, fLog *log.Entry, height uint32, txid := fmt.Sprintf("%064d", height) // we use hardcoded list of dev payouts + i := 0 for _, dev := range DeveloperRewardAddreses { // we calculate developers reward from % pre-defined @@ -515,7 +516,8 @@ func (d *Pegnetd) DevelopersPayouts(tx *sql.Tx, fLog *log.Entry, height uint32, } // Mock entry hash value - addTxid := fmt.Sprintf("%d-%s", 0, txid) + addTxid := fmt.Sprintf("%d-%s", i, txid) + i++ // Get dev address as FAAdress FADevAddress, err := factom.NewFAAddress(dev.DevAddress) From b30100ac206b5b3904394ba21b49b6fca013f5f3 Mon Sep 17 00:00:00 2001 From: Sergey Bushnyak Date: Wed, 5 Aug 2020 18:24:17 +0300 Subject: [PATCH 18/18] add comments --- node/sync.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/node/sync.go b/node/sync.go index a687627..a6aef03 100644 --- a/node/sync.go +++ b/node/sync.go @@ -364,7 +364,7 @@ func (d *Pegnetd) SyncBlock(ctx context.Context, tx *sql.Tx, height uint32) erro // 5) Apply Developers Rewards if height >= V20HeightActivation && height%pegnet.SnapshotRate == 0 { - err := d.DevelopersPayouts(tx, fLog, height, dblock.Timestamp) + err := d.DevelopersPayouts(tx, fLog, height, dblock.Timestamp, DeveloperRewardAddreses) if err != nil { // something wrong happend during payout execution return err @@ -493,8 +493,9 @@ func (d *Pegnetd) SnapshotPayouts(tx *sql.Tx, fLog *log.Entry, rates map[fat2.PT return nil } -// DevelopersPayouts for PIP16 sending rewards for developers -func (d *Pegnetd) DevelopersPayouts(tx *sql.Tx, fLog *log.Entry, height uint32, heightTimestamp time.Time) error { +// Developers Reward Payouts +// implementation of PIP16 - distributed rewards collected for developers every 24h +func (d *Pegnetd) DevelopersPayouts(tx *sql.Tx, fLog *log.Entry, height uint32, heightTimestamp time.Time, developers []DevReward) error { totalPayout := uint64(conversions.PerBlockDevelopers) * pegnet.SnapshotRate // once a day payoutStart := time.Now() @@ -504,7 +505,7 @@ func (d *Pegnetd) DevelopersPayouts(tx *sql.Tx, fLog *log.Entry, height uint32, // we use hardcoded list of dev payouts i := 0 - for _, dev := range DeveloperRewardAddreses { + for _, dev := range developers { // we calculate developers reward from % pre-defined rewardPayout := uint64((conversions.PerBlockDevelopers / 100) * dev.DevRewardPct)