Skip to content

Commit

Permalink
Merge pull request #134 from sigrlami/sb/features/pip-0016-developer-…
Browse files Browse the repository at this point in the history
…rewards

PIP 16 - Developer Rewards Mechanism
  • Loading branch information
StarNeit authored Aug 11, 2020
2 parents 9d453a0 + b30100a commit 21e9f7e
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 0 deletions.
35 changes: 35 additions & 0 deletions node/devs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package node

// Special structure for the Developer rewards
type DevReward struct {
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 (
DeveloperRewardAddreses = []DevReward{
{"Listing Tech Support", "FA2i9WZqJnaKbJxDY2AZdVgewE28uCcSwoFt8LJCMtGCC7tpCa2n", 10.00},
{"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},
{"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},
}
)
59 changes: 59 additions & 0 deletions node/pegnet/txhistory.go
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,65 @@ func (p *Pegnet) InsertStakingCoinbase(tx *sql.Tx, txid string, height uint32, h
return nil
}

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
}

// 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.

// 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
}

// Special construction to nullify burn address
func (p *Pegnet) InsertZeroingCoinbase(tx *sql.Tx, txid string, addTxid string, height uint32, heightTimestamp time.Time, payout uint64, asset string, faAdd factom.FAAddress) error {
txidBytes, err := hex.DecodeString(txid)
Expand Down
70 changes: 70 additions & 0 deletions node/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,15 @@ 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, DeveloperRewardAddreses)
if err != nil {
// something wrong happend during payout execution
return err
}
}

return nil
}

Expand Down Expand Up @@ -484,6 +493,67 @@ func (d *Pegnetd) SnapshotPayouts(tx *sql.Tx, fLog *log.Entry, rates map[fat2.PT
return nil
}

// 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()

// We need to mock a TXID to record dev rewards
txid := fmt.Sprintf("%064d", height)

// we use hardcoded list of dev payouts
i := 0
for _, dev := range developers {

// we calculate developers reward from % pre-defined
rewardPayout := uint64((conversions.PerBlockDevelopers / 100) * dev.DevRewardPct)
addr, err := factom.NewFAAddress(dev.DevAddress)

_, err = d.Pegnet.AddToBalance(tx, &addr, fat2.PTickerPEG, rewardPayout)
if err != nil {
return err
}

// Mock entry hash value
addTxid := fmt.Sprintf("%d-%s", i, txid)
i++

// 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")
return err
}

// ---- 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),
"PEG": float64(rewardPayout) / 1e8, // Float is good enough here
}).Info("developer reward | paid out to")

}

fLog.WithFields(log.Fields{
"total": float64(totalPayout) / 1e8,
"elapsed": time.Since(payoutStart),
"txid": txid,
}).Info("developer rewards | paid out")

return nil
}

func multiFetch(eblock *factom.EBlock, c *factom.Client) error {
err := eblock.Get(nil, c)
if err != nil {
Expand Down

0 comments on commit 21e9f7e

Please sign in to comment.