From a55aac8d11eabd0ed5df8cf937d8b44828833942 Mon Sep 17 00:00:00 2001 From: Cedric Fung Date: Wed, 1 Nov 2023 09:00:12 +0000 Subject: [PATCH] mint multiple batches should consider year leaps --- kernel/mint.go | 77 ++++++++++++++++++++++++++------------------- kernel/mint_test.go | 23 +++++++++++++- 2 files changed, 67 insertions(+), 33 deletions(-) diff --git a/kernel/mint.go b/kernel/mint.go index 251f40639..130497709 100644 --- a/kernel/mint.go +++ b/kernel/mint.go @@ -15,22 +15,16 @@ import ( ) var ( - MintPool common.Integer - MintLiquidity common.Integer - MintYearShares int - MintYearBatches int - KernelNodePledgeAmount common.Integer - KernelNetworkLegacyEnding uint64 + KernelNodePledgeAmount = common.NewInteger(13439) + MintPool = common.NewInteger(500000) + MintLiquidity = common.NewInteger(500000) + MintYearPercent = common.NewInteger(10).Ration(common.NewInteger(100)) ) -func init() { - MintPool = common.NewInteger(500000) - MintLiquidity = common.NewInteger(500000) - MintYearShares = 10 - MintYearBatches = 365 - KernelNodePledgeAmount = common.NewInteger(13439) +const ( + MintYearDays = 365 KernelNetworkLegacyEnding = 1706 -} +) func (chain *Chain) AggregateMintWork() { logger.Printf("AggregateMintWork(%s)\n", chain.ChainId) @@ -155,7 +149,6 @@ func (node *Node) buildUniversalMintTransaction(custodianRequest *common.Custodi return nil } - // TODO mint works should calculate according to finalized previous round, new fork required kernel := amount.Div(10).Mul(5) accepted := node.NodesListWithoutState(timestamp, true) mints, err := node.distributeKernelMintByWorks(accepted, kernel, timestamp) @@ -229,13 +222,14 @@ func (node *Node) lastMintDistribution() *common.MintData { func poolSizeUniversal(batch int) common.Integer { mint, pool := common.Zero, MintPool - for i := 0; i < batch/MintYearBatches; i++ { - year := pool.Div(MintYearShares) + for i := 0; i < batch/MintYearDays; i++ { + year := MintYearPercent.Product(pool) mint = mint.Add(year) pool = pool.Sub(year) } - day := pool.Div(MintYearShares).Div(MintYearBatches) - if count := batch % MintYearBatches; count > 0 { + year := MintYearPercent.Product(pool) + day := year.Div(MintYearDays) + if count := batch % MintYearDays; count > 0 { mint = mint.Add(day.Mul(count)) } if mint.Sign() > 0 { @@ -244,6 +238,30 @@ func poolSizeUniversal(batch int) common.Integer { return MintPool } +func mintBatchSize(batch uint64) common.Integer { + pool, years := MintPool, batch/MintYearDays + if years > 10000 { + panic(years) + } + for i := 0; i < int(years); i++ { + year := MintYearPercent.Product(pool) + pool = pool.Sub(year) + } + year := MintYearPercent.Product(pool) + return year.Div(MintYearDays) +} + +func mintMultiBatchesSize(old, batch uint64) common.Integer { + if old >= batch { + panic(batch) + } + var amount common.Integer + for i := old + 1; i <= batch; i++ { + amount = amount.Add(mintBatchSize(i)) + } + return amount +} + func (node *Node) validateMintSnapshot(snap *common.Snapshot, tx *common.VersionedTransaction) error { timestamp := snap.Timestamp if snap.Timestamp == 0 && snap.NodeId == node.IdForNetwork { @@ -284,16 +302,9 @@ func (node *Node) checkUniversalMintPossibility(timestamp uint64, validateOnly b return 0, common.Zero } - pool := MintPool - for i := 0; i < int(batch)/MintYearBatches; i++ { - pool = pool.Sub(pool.Div(MintYearShares)) - } - pool = pool.Div(MintYearShares) - total := pool.Div(MintYearBatches) - dist := node.lastMintDistribution() - logger.Verbosef("checkUniversalMintPossibility OLD %s %s %d %s %d\n", - pool, total, batch, dist.Amount, dist.Batch) + logger.Verbosef("checkUniversalMintPossibility OLD %d %s %d\n", + batch, dist.Amount, dist.Batch) if batch < dist.Batch { return 0, common.Zero @@ -305,9 +316,9 @@ func (node *Node) checkUniversalMintPossibility(timestamp uint64, validateOnly b return 0, common.Zero } - amount := total.Mul(int(batch - dist.Batch)) - logger.Verbosef("checkUniversalMintPossibility NEW %s %s %s %d %s %d\n", - pool, total, amount, batch, dist.Amount, dist.Batch) + amount := mintMultiBatchesSize(dist.Batch, batch) + logger.Verbosef("checkUniversalMintPossibility NEW %s %d %s %d\n", + amount, batch, dist.Amount, dist.Batch) return batch, amount } @@ -386,8 +397,10 @@ func (node *Node) distributeKernelMintByWorks(accepted []*CNode, base common.Int for _, m := range mints { ns := spaces[m.IdForNetwork] if len(ns) > 0 { - // TODO enable this for universal mint distributions - logger.Printf("node spaces %s %d %d\n", m.IdForNetwork, ns[0].Batch, len(ns)) + // TODO enable this for universal mint distributions, need to ensure all nodes + // have their own transaction monitor, send some regular transactions + // otherwise this will not work in low transaction conditions + logger.Verbosef("node spaces %s %d %d\n", m.IdForNetwork, ns[0].Batch, len(ns)) } w := works[m.IdForNetwork] diff --git a/kernel/mint_test.go b/kernel/mint_test.go index 968016d9e..91ceb76f1 100644 --- a/kernel/mint_test.go +++ b/kernel/mint_test.go @@ -20,6 +20,27 @@ func TestPledgeAmount(t *testing.T) { require.Equal(common.NewIntegerFromString("13439"), KernelNodePledgeAmount) } +func TestMintBatchSize(t *testing.T) { + require := require.New(t) + + for i := uint64(1707); i < 1825; i++ { + amount := common.NewIntegerFromString("89.87671232") + require.Equal(amount, mintBatchSize(i)) + } + require.Equal(common.NewIntegerFromString("89.87671232"), mintMultiBatchesSize(1706, 1707)) + require.Equal(common.NewIntegerFromString("179.75342464"), mintMultiBatchesSize(1706, 1708)) + + require.Equal(common.NewIntegerFromString("80.88904109"), mintBatchSize(1825)) + require.Equal(common.NewIntegerFromString("80.88904109"), mintMultiBatchesSize(1824, 1825)) + require.Equal(common.NewIntegerFromString("80.88904109"), mintMultiBatchesSize(1825, 1826)) + require.Equal(common.NewIntegerFromString("161.77808218"), mintMultiBatchesSize(1825, 1827)) + + require.Equal(common.NewIntegerFromString("89.87671232"), mintMultiBatchesSize(1823, 1824)) + require.Equal(common.NewIntegerFromString("170.76575341"), mintMultiBatchesSize(1823, 1825)) + require.Equal(common.NewIntegerFromString("251.65479450"), mintMultiBatchesSize(1823, 1826)) + require.Equal(common.NewIntegerFromString("341.53150682"), mintMultiBatchesSize(1822, 1826)) +} + func TestPoolSize(t *testing.T) { require := require.New(t) @@ -135,7 +156,7 @@ func TestUniversalMintTransaction(t *testing.T) { amount = common.NewIntegerFromString("89.87671232") mint := versioned.Inputs[0].Mint - require.Equal(KernelNetworkLegacyEnding+1, mint.Batch) + require.Equal(uint64(KernelNetworkLegacyEnding+1), mint.Batch) require.Equal("UNIVERSAL", mint.Group) require.Equal(amount.String(), mint.Amount.String()) require.Len(versioned.Outputs, len(signers)+2)