From 71cecd858357fb5649a0880c2e3174e2dc2559ce Mon Sep 17 00:00:00 2001 From: jacklevin74 Date: Mon, 22 Jan 2024 10:31:00 -1000 Subject: [PATCH 01/21] Update config.go faster startup, we are testing so its ok --- gossip/emitter/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gossip/emitter/config.go b/gossip/emitter/config.go index 58446020d..e52996f55 100644 --- a/gossip/emitter/config.go +++ b/gossip/emitter/config.go @@ -65,7 +65,7 @@ func DefaultConfig() Config { Min: 150 * time.Millisecond, Max: 10 * time.Minute, Confirming: 170 * time.Millisecond, - DoublesignProtection: 27 * time.Minute, // should be greater than MaxEmitInterval + DoublesignProtection: 30 * time.Second, // should be greater than MaxEmitInterval ParallelInstanceProtection: 1 * time.Minute, }, From 630e96b2b6bb3ac5224e3143f6b88f630d657e33 Mon Sep 17 00:00:00 2001 From: jacklevin74 Date: Mon, 22 Jan 2024 10:33:21 -1000 Subject: [PATCH 02/21] Update txs.go no speed bumps --- gossip/emitter/txs.go | 34 +++++++++------------------------- 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/gossip/emitter/txs.go b/gossip/emitter/txs.go index 364ca6d4c..2db228aef 100644 --- a/gossip/emitter/txs.go +++ b/gossip/emitter/txs.go @@ -3,7 +3,7 @@ package emitter import ( "time" "fmt" - "math/rand" + "math/rand" "github.com/Fantom-foundation/lachesis-base/common/bigendian" "github.com/Fantom-foundation/lachesis-base/hash" "github.com/Fantom-foundation/lachesis-base/inter/idx" @@ -47,7 +47,7 @@ func (em *Emitter) maxGasPowerToUse(e *inter.MutableEventPayload) uint64 { estimatedAlloc := gaspowercheck.CalcValidatorGasPower(e, e.CreationTime(), e.MedianTime(), 0, em.validators, gaspowercheck.Config{ Idx: inter.LongTermGas, - AllocPerSec: rules.Economy.LongGasPower.AllocPerSec * 2, + AllocPerSec: rules.Economy.LongGasPower.AllocPerSec * 5, MaxAllocPeriod: inter.Timestamp(time.Minute) * 2, MinEnsuredAlloc: 0, StartupAllocPeriod: 0, @@ -87,27 +87,8 @@ func (em *Emitter) maxGasPowerToUse(e *inter.MutableEventPayload) uint64 { //override //maxGasToUse = estimatedAlloc } - // pendingGas should be below MaxBlockGas - //{ - // maxPendingGas := max64(max64(rules.Blocks.MaxBlockGas/3, rules.Economy.Gas.MaxEventGas), 15000000) - // if maxPendingGas <= em.pendingGas { - // return 0 - // } - // this is likely a bug, there is no pendingGas - //if maxPendingGas < em.pendingGas+maxGasToUse { - // maxGasToUse = maxPendingGas - em.pendingGas - //} - //} - // No txs if power is low - //{ - // threshold := em.config.NoTxsThreshold - // if e.GasPowerLeft().Min() <= threshold { - // return 0 - // } else if e.GasPowerLeft().Min() < threshold+maxGasToUse { - // maxGasToUse = e.GasPowerLeft().Min() - threshold - // fmt.Println("Show me maxGasToUse = e.GasPowerLeft().Min() - threshold ", maxGasToUse , e.GasPowerLeft().Min(), threshold) - // } - //} + // ignore all calculations and speedbumps + maxGasToUse = rules.Economy.Gas.MaxEventGas return maxGasToUse } @@ -176,8 +157,11 @@ func (em *Emitter) addTxs(e *inter.MutableEventPayload, sorted *types.Transactio continue } // check there's enough gas power to originate the transaction - if tx.Gas() >= e.GasPowerLeft().Min() || e.GasPowerUsed()+tx.Gas() >= maxGasUsed { - if params.TxGas >= e.GasPowerLeft().Min() || e.GasPowerUsed()+params.TxGas >= maxGasUsed { + //if tx.Gas() >= e.GasPowerLeft().Min() || e.GasPowerUsed()+tx.Gas() >= maxGasUsed { + // if params.TxGas >= e.GasPowerLeft().Min() || e.GasPowerUsed()+params.TxGas >= maxGasUsed { + // Do not track GasPowerLeft + if e.GasPowerUsed()+tx.Gas() >= maxGasUsed { + if e.GasPowerUsed()+params.TxGas >= maxGasUsed { // stop if cannot originate even an empty transaction break From 7587eb8ed7e59df1f4d305cae3bb6bfc25b10019 Mon Sep 17 00:00:00 2001 From: jacklevin74 Date: Mon, 22 Jan 2024 10:59:27 -1000 Subject: [PATCH 03/21] Update txs.go --- gossip/emitter/txs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gossip/emitter/txs.go b/gossip/emitter/txs.go index 2db228aef..961f214b7 100644 --- a/gossip/emitter/txs.go +++ b/gossip/emitter/txs.go @@ -173,7 +173,7 @@ func (em *Emitter) addTxs(e *inter.MutableEventPayload, sorted *types.Transactio // check not conflicted with already originated txs (in any connected event) if em.originatedTxs.TotalOf(sender) != 0 { sorted.Pop() - fmt.Println("Already Originated TX from sender: ", sender, tx.Hash(), tx.Nonce(), time.Now(),e.Creator()) + fmt.Println("Throttle TX as already Originated: ", sender, tx.Hash(), tx.Nonce(), time.Now(),e.Creator()) continue } // my turn, i.e. try to not include the same tx simultaneously by different validators From 68c54f2adb070cb62123729f59c33fecb9ec85bc Mon Sep 17 00:00:00 2001 From: jacklevin74 Date: Mon, 22 Jan 2024 11:15:18 -1000 Subject: [PATCH 04/21] Update txs.go do not check for repeated transactions from a sender --- gossip/emitter/txs.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/gossip/emitter/txs.go b/gossip/emitter/txs.go index 961f214b7..7177e176f 100644 --- a/gossip/emitter/txs.go +++ b/gossip/emitter/txs.go @@ -170,12 +170,6 @@ func (em *Emitter) addTxs(e *inter.MutableEventPayload, sorted *types.Transactio sorted.Pop() continue } - // check not conflicted with already originated txs (in any connected event) - if em.originatedTxs.TotalOf(sender) != 0 { - sorted.Pop() - fmt.Println("Throttle TX as already Originated: ", sender, tx.Hash(), tx.Nonce(), time.Now(),e.Creator()) - continue - } // my turn, i.e. try to not include the same tx simultaneously by different validators if !em.isMyTxTurn(tx.Hash(), sender, tx.Nonce(), time.Now(), em.validators, e.Creator(), em.epoch) { fmt.Println("Not my turn TX from sender: ", sender, tx.Hash(), tx.Nonce(), time.Now(), e.Creator()) From 98585f6c61fe9d5ad32fd3b246e421ceaa1d5e11 Mon Sep 17 00:00:00 2001 From: jacklevin74 Date: Mon, 22 Jan 2024 12:11:28 -1000 Subject: [PATCH 05/21] Update txs.go do not check other validators for turn (we have too many) --- gossip/emitter/txs.go | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/gossip/emitter/txs.go b/gossip/emitter/txs.go index 7177e176f..78221f625 100644 --- a/gossip/emitter/txs.go +++ b/gossip/emitter/txs.go @@ -170,12 +170,7 @@ func (em *Emitter) addTxs(e *inter.MutableEventPayload, sorted *types.Transactio sorted.Pop() continue } - // my turn, i.e. try to not include the same tx simultaneously by different validators - if !em.isMyTxTurn(tx.Hash(), sender, tx.Nonce(), time.Now(), em.validators, e.Creator(), em.epoch) { - fmt.Println("Not my turn TX from sender: ", sender, tx.Hash(), tx.Nonce(), time.Now(), e.Creator()) - sorted.Pop() - continue - } + // check transaction is not outdated if !em.world.TxPool.Has(tx.Hash()) { fmt.Println("Outdated TX from sender: ", sender, tx.Hash(), tx.Nonce(), time.Now(), e.Creator()) From c4edba1d6e670a3501637d5559e1ea0fda773ca0 Mon Sep 17 00:00:00 2001 From: jacklevin74 Date: Mon, 22 Jan 2024 18:28:06 -1000 Subject: [PATCH 06/21] Update validators.go don't check stake so often --- gossip/emitter/validators.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gossip/emitter/validators.go b/gossip/emitter/validators.go index 0292c6e80..eea5f12b7 100644 --- a/gossip/emitter/validators.go +++ b/gossip/emitter/validators.go @@ -9,7 +9,7 @@ import ( ) const ( - validatorChallenge = 4 * time.Second + validatorChallenge = 200 * time.Second ) func (em *Emitter) recountConfirmingIntervals(validators *pos.Validators) { From 75d10245a6c9d19613f099c1a6e2f3702444e7d6 Mon Sep 17 00:00:00 2001 From: jacklevin74 Date: Mon, 22 Jan 2024 18:29:04 -1000 Subject: [PATCH 07/21] Update control.go smaller set of Vals for now, rotate it later --- gossip/emitter/control.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gossip/emitter/control.go b/gossip/emitter/control.go index 5feebeacf..a7f437fbc 100644 --- a/gossip/emitter/control.go +++ b/gossip/emitter/control.go @@ -42,6 +42,8 @@ func eventMetric(orig ancestor.Metric, seq idx.Event) ancestor.Metric { } func (em *Emitter) isAllowedToEmit(e inter.EventI, eTxs bool, metric ancestor.Metric, selfParent *inter.Event) bool { + // for now allow only vals up to ID 30 to emit: + if (e.Creator() < 31) { passedTime := e.CreationTime().Time().Sub(em.prevEmittedAtTime) if passedTime < 0 { passedTime = 0 @@ -129,6 +131,8 @@ func (em *Emitter) isAllowedToEmit(e inter.EventI, eTxs bool, metric ancestor.Me } return true + } + return false } func (em *Emitter) recheckIdleTime() { From 562d868965ec619184b5e94c3857943fb34027c7 Mon Sep 17 00:00:00 2001 From: jacklevin74 Date: Mon, 22 Jan 2024 21:14:33 -1000 Subject: [PATCH 08/21] Update control.go enforce emitting for idle validators --- gossip/emitter/control.go | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/gossip/emitter/control.go b/gossip/emitter/control.go index a7f437fbc..b05c362d6 100644 --- a/gossip/emitter/control.go +++ b/gossip/emitter/control.go @@ -43,7 +43,6 @@ func eventMetric(orig ancestor.Metric, seq idx.Event) ancestor.Metric { func (em *Emitter) isAllowedToEmit(e inter.EventI, eTxs bool, metric ancestor.Metric, selfParent *inter.Event) bool { // for now allow only vals up to ID 30 to emit: - if (e.Creator() < 31) { passedTime := e.CreationTime().Time().Sub(em.prevEmittedAtTime) if passedTime < 0 { passedTime = 0 @@ -52,6 +51,12 @@ func (em *Emitter) isAllowedToEmit(e inter.EventI, eTxs bool, metric ancestor.Me if passedTimeIdle < 0 { passedTimeIdle = 0 } + // metric is a decimal (0.0, 1.0], being an estimation of how much the event will advance the consensus + adjustedPassedTime := time.Duration(ancestor.Metric(passedTime/piecefunc.DecimalUnit) * metric) + adjustedPassedIdleTime := time.Duration(ancestor.Metric(passedTimeIdle/piecefunc.DecimalUnit) * metric) + passedBlocks := em.world.GetLatestBlockIndex() - em.prevEmittedAtBlock + + if (e.Creator() < 31) { if em.stakeRatio[e.Creator()] < 0.35*piecefunc.DecimalUnit { // top validators emit event right after transaction is originated passedTimeIdle = passedTime @@ -62,10 +67,6 @@ func (em *Emitter) isAllowedToEmit(e inter.EventI, eTxs bool, metric ancestor.Me if passedTimeIdle > passedTime { passedTimeIdle = passedTime } - // metric is a decimal (0.0, 1.0], being an estimation of how much the event will advance the consensus - adjustedPassedTime := time.Duration(ancestor.Metric(passedTime/piecefunc.DecimalUnit) * metric) - adjustedPassedIdleTime := time.Duration(ancestor.Metric(passedTimeIdle/piecefunc.DecimalUnit) * metric) - passedBlocks := em.world.GetLatestBlockIndex() - em.prevEmittedAtBlock // Forbid emitting if not enough power and power is decreasing { threshold := em.config.EmergencyThreshold @@ -129,9 +130,21 @@ func (em *Emitter) isAllowedToEmit(e inter.EventI, eTxs bool, metric ancestor.Me return false } } - + // only allow top validators return true - } + } else { + // Enforce emitting if passed too many time/blocks since previous event + rules := em.world.GetRules() + maxBlocks := rules.Economy.BlockMissedSlack/2 + 1 + if rules.Economy.BlockMissedSlack > maxBlocks && maxBlocks < rules.Economy.BlockMissedSlack-5 { + maxBlocks = rules.Economy.BlockMissedSlack - 5 + } + if passedTime >= em.intervals.Max || + passedBlocks >= maxBlocks*4/5 && metric >= piecefunc.DecimalUnit/2 || + passedBlocks >= maxBlocks { + return true + } + } return false } From 7c4ff654eac661fb951378786f214a7c08b8adcd Mon Sep 17 00:00:00 2001 From: jacklevin74 Date: Thu, 25 Jan 2024 17:26:39 -1000 Subject: [PATCH 09/21] Update go.mod replace base to jack --- go.mod | 2 ++ 1 file changed, 2 insertions(+) diff --git a/go.mod b/go.mod index 4ca1dd877..10e463aef 100644 --- a/go.mod +++ b/go.mod @@ -114,3 +114,5 @@ replace github.com/ethereum/go-ethereum => github.com/faircrypto/go-ethereum v1. replace github.com/dvyukov/go-fuzz => github.com/guzenok/go-fuzz v0.0.0-20210201043429-a8e90a2a4f88 replace github.com/recws-org/recws => github.com/nibty/recws v0.0.0-20231129011923-06823df0d0db + +replace github.com/Fantom-foundation/lachesis-base => github.com/jacklevin74/lachesis-base v0.0.0-20230817040848-1326ba9aa59b From a4546910d92479cff20055f2a824e0bf2bf139d4 Mon Sep 17 00:00:00 2001 From: jacklevin74 Date: Fri, 26 Jan 2024 09:26:08 -1000 Subject: [PATCH 10/21] Update hooks.go apply supermajority for consensus messages --- gossip/emitter/hooks.go | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/gossip/emitter/hooks.go b/gossip/emitter/hooks.go index 974cc3ddd..c2e88fae4 100644 --- a/gossip/emitter/hooks.go +++ b/gossip/emitter/hooks.go @@ -2,7 +2,7 @@ package emitter import ( "time" - + "fmt" "github.com/Fantom-foundation/lachesis-base/emitter/ancestor" "github.com/Fantom-foundation/lachesis-base/inter/idx" "github.com/Fantom-foundation/lachesis-base/inter/pos" @@ -85,14 +85,47 @@ func (em *Emitter) OnNewEpoch(newValidators *pos.Validators, newEpoch idx.Epoch) em.payloadIndexer = ancestor.NewPayloadIndexer(PayloadIndexerSize) } + +// Function to get the top 100 elements from a slice +func top100(slice []idx.ValidatorID) []idx.ValidatorID { + if len(slice) > 100 { + return slice[:100] // Return the first 100 elements + } + return slice // Return the slice as is if it has less than or equal to 100 elements +} + +// Function to check if a number is in the top 100 elements of a slice +func isInTop100(number idx.ValidatorID, slice []idx.ValidatorID) bool { + var v idx.ValidatorID + top100Slice := top100(slice) + for _, v = range top100Slice { + if v == number { + return true + } + } + return false +} + + // OnEventConnected tracks new events func (em *Emitter) OnEventConnected(e inter.EventPayloadI) { + var supermajority bool + supermajority = true if !em.isValidator() { return } - if em.fcIndexer != nil { + // Filter this node's events if not in top100 supermajority of stakers + if e.Creator() == em.config.Validator.ID && !isInTop100(e.Creator(), em.validators.SortedIDs()) { + fmt.Println("This node is not in supermajority") + supermajority = false + } + + if em.fcIndexer != nil && supermajority { em.fcIndexer.ProcessEvent(e) + fmt.Printf("OnEventConnected fcIndexer.ProcessEvent %v\n", e) } else if em.quorumIndexer != nil { + fmt.Printf("OnEventConnected quorumIndexer.ProcessEvent %v \n", e) + //fmt.Printf("OnEventConnected quorumIndexer.ProcessEvent %v %v\n", e, em.validators.SortedIDs()) em.quorumIndexer.ProcessEvent(e, e.Creator() == em.config.Validator.ID) } em.payloadIndexer.ProcessEvent(e, ancestor.Metric(e.Txs().Len())) From c00c52e7133d000774d0cdedbe1a560685cec49d Mon Sep 17 00:00:00 2001 From: jacklevin74 Date: Fri, 26 Jan 2024 13:10:31 -1000 Subject: [PATCH 11/21] Update hooks.go better readability --- gossip/emitter/hooks.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gossip/emitter/hooks.go b/gossip/emitter/hooks.go index c2e88fae4..c72150960 100644 --- a/gossip/emitter/hooks.go +++ b/gossip/emitter/hooks.go @@ -119,8 +119,8 @@ func (em *Emitter) OnEventConnected(e inter.EventPayloadI) { fmt.Println("This node is not in supermajority") supermajority = false } - - if em.fcIndexer != nil && supermajority { + if supermajority { + if em.fcIndexer != nil { em.fcIndexer.ProcessEvent(e) fmt.Printf("OnEventConnected fcIndexer.ProcessEvent %v\n", e) } else if em.quorumIndexer != nil { @@ -128,6 +128,7 @@ func (em *Emitter) OnEventConnected(e inter.EventPayloadI) { //fmt.Printf("OnEventConnected quorumIndexer.ProcessEvent %v %v\n", e, em.validators.SortedIDs()) em.quorumIndexer.ProcessEvent(e, e.Creator() == em.config.Validator.ID) } + } em.payloadIndexer.ProcessEvent(e, ancestor.Metric(e.Txs().Len())) for _, tx := range e.Txs() { addr, _ := types.Sender(em.world.TxSigner, tx) From 3094fd6101e35c2089395ebf4b680cc30a76ab62 Mon Sep 17 00:00:00 2001 From: jacklevin74 Date: Fri, 26 Jan 2024 13:25:15 -1000 Subject: [PATCH 12/21] Update hooks.go reverting, doesn't work --- gossip/emitter/hooks.go | 36 +----------------------------------- 1 file changed, 1 insertion(+), 35 deletions(-) diff --git a/gossip/emitter/hooks.go b/gossip/emitter/hooks.go index c72150960..974cc3ddd 100644 --- a/gossip/emitter/hooks.go +++ b/gossip/emitter/hooks.go @@ -2,7 +2,7 @@ package emitter import ( "time" - "fmt" + "github.com/Fantom-foundation/lachesis-base/emitter/ancestor" "github.com/Fantom-foundation/lachesis-base/inter/idx" "github.com/Fantom-foundation/lachesis-base/inter/pos" @@ -85,50 +85,16 @@ func (em *Emitter) OnNewEpoch(newValidators *pos.Validators, newEpoch idx.Epoch) em.payloadIndexer = ancestor.NewPayloadIndexer(PayloadIndexerSize) } - -// Function to get the top 100 elements from a slice -func top100(slice []idx.ValidatorID) []idx.ValidatorID { - if len(slice) > 100 { - return slice[:100] // Return the first 100 elements - } - return slice // Return the slice as is if it has less than or equal to 100 elements -} - -// Function to check if a number is in the top 100 elements of a slice -func isInTop100(number idx.ValidatorID, slice []idx.ValidatorID) bool { - var v idx.ValidatorID - top100Slice := top100(slice) - for _, v = range top100Slice { - if v == number { - return true - } - } - return false -} - - // OnEventConnected tracks new events func (em *Emitter) OnEventConnected(e inter.EventPayloadI) { - var supermajority bool - supermajority = true if !em.isValidator() { return } - // Filter this node's events if not in top100 supermajority of stakers - if e.Creator() == em.config.Validator.ID && !isInTop100(e.Creator(), em.validators.SortedIDs()) { - fmt.Println("This node is not in supermajority") - supermajority = false - } - if supermajority { if em.fcIndexer != nil { em.fcIndexer.ProcessEvent(e) - fmt.Printf("OnEventConnected fcIndexer.ProcessEvent %v\n", e) } else if em.quorumIndexer != nil { - fmt.Printf("OnEventConnected quorumIndexer.ProcessEvent %v \n", e) - //fmt.Printf("OnEventConnected quorumIndexer.ProcessEvent %v %v\n", e, em.validators.SortedIDs()) em.quorumIndexer.ProcessEvent(e, e.Creator() == em.config.Validator.ID) } - } em.payloadIndexer.ProcessEvent(e, ancestor.Metric(e.Txs().Len())) for _, tx := range e.Txs() { addr, _ := types.Sender(em.world.TxSigner, tx) From d9a6337cccd513f66cdfa6b0c19b55a89cbb9f31 Mon Sep 17 00:00:00 2001 From: jacklevin74 Date: Fri, 26 Jan 2024 15:45:40 -1000 Subject: [PATCH 13/21] Update control.go emission control --- gossip/emitter/control.go | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/gossip/emitter/control.go b/gossip/emitter/control.go index b05c362d6..d33ee31a5 100644 --- a/gossip/emitter/control.go +++ b/gossip/emitter/control.go @@ -2,7 +2,7 @@ package emitter import ( "time" - + "fmt" "github.com/Fantom-foundation/lachesis-base/emitter/ancestor" "github.com/Fantom-foundation/lachesis-base/inter/idx" "github.com/Fantom-foundation/lachesis-base/inter/pos" @@ -41,6 +41,26 @@ func eventMetric(orig ancestor.Metric, seq idx.Event) ancestor.Metric { return kickStartMetric(ancestor.Metric(eventMetricF(uint64(orig))), seq) } +// Function to get the top 50 elements from a slice + func top50(slice []idx.ValidatorID) []idx.ValidatorID { + if len(slice) > 50 { + return slice[:50] // Return the first 100 elements + } + return slice // Return the slice as is if it has less than or equal to 100 elements + } + + // Function to check if a number is in the top 50 elements of a slice + func isInTop50(number idx.ValidatorID, slice []idx.ValidatorID) bool { + var v idx.ValidatorID + top50Slice := top50(slice) + for _, v = range top50Slice { + if v == number { + return true + } + } + return false + } + func (em *Emitter) isAllowedToEmit(e inter.EventI, eTxs bool, metric ancestor.Metric, selfParent *inter.Event) bool { // for now allow only vals up to ID 30 to emit: passedTime := e.CreationTime().Time().Sub(em.prevEmittedAtTime) @@ -56,7 +76,14 @@ func (em *Emitter) isAllowedToEmit(e inter.EventI, eTxs bool, metric ancestor.Me adjustedPassedIdleTime := time.Duration(ancestor.Metric(passedTimeIdle/piecefunc.DecimalUnit) * metric) passedBlocks := em.world.GetLatestBlockIndex() - em.prevEmittedAtBlock - if (e.Creator() < 31) { + supermajority := true + // Filter this node's events if not in top50 supermajority of stakers + if e.Creator() == em.config.Validator.ID && !isInTop50(e.Creator(), em.validators.SortedIDs()) { + fmt.Println("This node is not in supermajority") + supermajority = false + } + + if (supermajority) { if em.stakeRatio[e.Creator()] < 0.35*piecefunc.DecimalUnit { // top validators emit event right after transaction is originated passedTimeIdle = passedTime From d6bf2d7f5156f4d823f8d95a14ac0b0b424f95bd Mon Sep 17 00:00:00 2001 From: jacklevin74 Date: Fri, 26 Jan 2024 16:10:51 -1000 Subject: [PATCH 14/21] Update control.go verbosity off --- gossip/emitter/control.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gossip/emitter/control.go b/gossip/emitter/control.go index d33ee31a5..c98bea6ed 100644 --- a/gossip/emitter/control.go +++ b/gossip/emitter/control.go @@ -79,7 +79,7 @@ func (em *Emitter) isAllowedToEmit(e inter.EventI, eTxs bool, metric ancestor.Me supermajority := true // Filter this node's events if not in top50 supermajority of stakers if e.Creator() == em.config.Validator.ID && !isInTop50(e.Creator(), em.validators.SortedIDs()) { - fmt.Println("This node is not in supermajority") + //fmt.Println("This node is not in supermajority") supermajority = false } From cb8579b7852d40660fa214407bb24144174ae62d Mon Sep 17 00:00:00 2001 From: jacklevin74 Date: Fri, 26 Jan 2024 18:12:43 -1000 Subject: [PATCH 15/21] Update control.go remove fmt module --- gossip/emitter/control.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gossip/emitter/control.go b/gossip/emitter/control.go index c98bea6ed..8e172796d 100644 --- a/gossip/emitter/control.go +++ b/gossip/emitter/control.go @@ -2,7 +2,7 @@ package emitter import ( "time" - "fmt" + "github.com/Fantom-foundation/lachesis-base/emitter/ancestor" "github.com/Fantom-foundation/lachesis-base/inter/idx" "github.com/Fantom-foundation/lachesis-base/inter/pos" From 1ef679cd19739d1c400356e54f54d7dcb0d7c038 Mon Sep 17 00:00:00 2001 From: jacklevin74 Date: Fri, 26 Jan 2024 20:15:54 -1000 Subject: [PATCH 16/21] Update control.go basic enforcement to emit at max interface if not in super majority --- gossip/emitter/control.go | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/gossip/emitter/control.go b/gossip/emitter/control.go index 8e172796d..f38cbffea 100644 --- a/gossip/emitter/control.go +++ b/gossip/emitter/control.go @@ -160,15 +160,8 @@ func (em *Emitter) isAllowedToEmit(e inter.EventI, eTxs bool, metric ancestor.Me // only allow top validators return true } else { - // Enforce emitting if passed too many time/blocks since previous event - rules := em.world.GetRules() - maxBlocks := rules.Economy.BlockMissedSlack/2 + 1 - if rules.Economy.BlockMissedSlack > maxBlocks && maxBlocks < rules.Economy.BlockMissedSlack-5 { - maxBlocks = rules.Economy.BlockMissedSlack - 5 - } - if passedTime >= em.intervals.Max || - passedBlocks >= maxBlocks*4/5 && metric >= piecefunc.DecimalUnit/2 || - passedBlocks >= maxBlocks { + // Enforce emitting if passed Max time (10 mins) + if passedTime >= em.intervals.Max { return true } } From 099597ac63140f81d9c020cb3efd0d5c43379602 Mon Sep 17 00:00:00 2001 From: jacklevin74 Date: Sat, 27 Jan 2024 20:02:04 -1000 Subject: [PATCH 17/21] Update gas_power_check.go Do not validate peer gas power use. --- eventcheck/gaspowercheck/gas_power_check.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/eventcheck/gaspowercheck/gas_power_check.go b/eventcheck/gaspowercheck/gas_power_check.go index 954ed5edf..60a26813f 100644 --- a/eventcheck/gaspowercheck/gas_power_check.go +++ b/eventcheck/gaspowercheck/gas_power_check.go @@ -167,6 +167,8 @@ func CalcValidatorGasPowerPerSec( // Validate event func (v *Checker) Validate(e inter.EventI, selfParent inter.EventI) error { + // do no validate gas power (with weak consensus) everything allowed + return nil gasPowers, err := v.CalcGasPower(e, selfParent) if err != nil { return err From 5206a0dbf3bdf7203a875d62ab72729fb7f4722c Mon Sep 17 00:00:00 2001 From: jacklevin74 Date: Sat, 27 Jan 2024 20:37:23 -1000 Subject: [PATCH 18/21] Update control.go --- gossip/emitter/control.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gossip/emitter/control.go b/gossip/emitter/control.go index f38cbffea..c19518bff 100644 --- a/gossip/emitter/control.go +++ b/gossip/emitter/control.go @@ -80,7 +80,9 @@ func (em *Emitter) isAllowedToEmit(e inter.EventI, eTxs bool, metric ancestor.Me // Filter this node's events if not in top50 supermajority of stakers if e.Creator() == em.config.Validator.ID && !isInTop50(e.Creator(), em.validators.SortedIDs()) { //fmt.Println("This node is not in supermajority") - supermajority = false + //supermajority = false + // disable check + supermajority = true } if (supermajority) { From 2ca3bfa52c8a66ff833b48b4cb27163d889a0dd1 Mon Sep 17 00:00:00 2001 From: jacklevin74 Date: Sun, 28 Jan 2024 07:54:18 -1000 Subject: [PATCH 19/21] Update txs.go reverting back to gas control --- gossip/emitter/txs.go | 106 +++++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 58 deletions(-) diff --git a/gossip/emitter/txs.go b/gossip/emitter/txs.go index 78221f625..5f96889e3 100644 --- a/gossip/emitter/txs.go +++ b/gossip/emitter/txs.go @@ -3,7 +3,6 @@ package emitter import ( "time" "fmt" - "math/rand" "github.com/Fantom-foundation/lachesis-base/common/bigendian" "github.com/Fantom-foundation/lachesis-base/hash" "github.com/Fantom-foundation/lachesis-base/inter/idx" @@ -34,12 +33,10 @@ func max64(a, b uint64) uint64 { func (em *Emitter) maxGasPowerToUse(e *inter.MutableEventPayload) uint64 { rules := em.world.GetRules() - maxGasToUse := rules.Economy.Gas.MaxEventGas - //fmt.Println("maxGasToUse in maxGasPowertoUse, GasPowerLeft ", maxGasToUse, e.GasPowerLeft().Min()) + maxGasToUse := rules.Economy.Gas.MaxEventGas if maxGasToUse > e.GasPowerLeft().Min() { maxGasToUse = e.GasPowerLeft().Min() } - //fmt.Println("maxGasToUse in maxGasPowertoUsem after control: ", maxGasToUse) // Smooth TPS if power isn't big if em.config.LimitedTpsThreshold > em.config.NoTxsThreshold { upperThreshold := em.config.LimitedTpsThreshold @@ -47,18 +44,17 @@ func (em *Emitter) maxGasPowerToUse(e *inter.MutableEventPayload) uint64 { estimatedAlloc := gaspowercheck.CalcValidatorGasPower(e, e.CreationTime(), e.MedianTime(), 0, em.validators, gaspowercheck.Config{ Idx: inter.LongTermGas, - AllocPerSec: rules.Economy.LongGasPower.AllocPerSec * 5, - MaxAllocPeriod: inter.Timestamp(time.Minute) * 2, + AllocPerSec: rules.Economy.LongGasPower.AllocPerSec * 4 / 5, + MaxAllocPeriod: inter.Timestamp(time.Minute), MinEnsuredAlloc: 0, StartupAllocPeriod: 0, MinStartupGas: 0, }) - //fmt.Println("EstimatedAlloc: ", estimatedAlloc) gasPowerLeft := e.GasPowerLeft().Min() + estimatedAlloc - //if gasPowerLeft < downThreshold { - // return 0 - //} + if gasPowerLeft < downThreshold { + return 0 + } newGasPowerLeft := uint64(0) if gasPowerLeft > maxGasToUse { newGasPowerLeft = gasPowerLeft - maxGasToUse @@ -84,64 +80,55 @@ func (em *Emitter) maxGasPowerToUse(e *inter.MutableEventPayload) uint64 { if maxGasToUse > smoothGasToUse { maxGasToUse = smoothGasToUse } - //override - //maxGasToUse = estimatedAlloc } - // ignore all calculations and speedbumps - maxGasToUse = rules.Economy.Gas.MaxEventGas + // pendingGas should be below MaxBlockGas + { + maxPendingGas := max64(max64(rules.Blocks.MaxBlockGas/3, rules.Economy.Gas.MaxEventGas), 15000000) + if maxPendingGas <= em.pendingGas { + return 0 + } + if maxPendingGas < em.pendingGas+maxGasToUse { + maxGasToUse = maxPendingGas - em.pendingGas + } + } + // No txs if power is low + { + threshold := em.config.NoTxsThreshold + if e.GasPowerLeft().Min() <= threshold { + return 0 + } else if e.GasPowerLeft().Min() < threshold+maxGasToUse { + maxGasToUse = e.GasPowerLeft().Min() - threshold + } + } return maxGasToUse } -// randomWithWeight returns a random number between 1 and 50, -// with the first 21 numbers having a 70% chance of being chosen. -func randomWithWeight() int { - rand.Seed(time.Now().UnixNano()) // Initialize the random number generator. - - if rand.Float64() < 0.7 { - // 70% chance to choose a number between 1 and 21. - return rand.Intn(21) + 1 - } else { - // 30% chance to choose a number between 22 and 50. - return rand.Intn(29) + 22 - } -} - - func getTxRoundIndex(now, txTime time.Time, validatorsNum idx.Validator) int { - passed := now.Sub(txTime) - if passed < 0 { - passed = 0 - } - return int((passed / TxTurnPeriod) % time.Duration(validatorsNum)) - } + passed := now.Sub(txTime) + if passed < 0 { + passed = 0 + } + return int((passed / TxTurnPeriod) % time.Duration(validatorsNum)) +} // safe for concurrent use func (em *Emitter) isMyTxTurn(txHash common.Hash, sender common.Address, accountNonce uint64, now time.Time, validators *pos.Validators, me idx.ValidatorID, epoch idx.Epoch) bool { txTime := txtime.Of(txHash) - //roundIndex := getTxRoundIndex(now, txTime, validators.Len()) - roundIndex := getTxRoundIndex(now, txTime, 50) + roundIndex := getTxRoundIndex(now, txTime, validators.Len()) if roundIndex != getTxRoundIndex(now.Add(TxTurnPeriodLatency), txTime, validators.Len()) { // round is about to change, avoid originating the transaction to avoid racing with another validator return false - //return true } roundsHash := hash.Of(sender.Bytes(), bigendian.Uint64ToBytes(accountNonce/TxTurnNonces), epoch.Bytes()) rounds := utils.WeightedPermutation(roundIndex+1, validators.SortedWeights(), roundsHash) - fmt.Println ("Validator turn id: ", rounds, validators.GetID(idx.Validator(rounds[roundIndex]))) - chosenVal := randomWithWeight() - fmt.Println ("Validator new turn id: ", chosenVal, chosenVal == int(me)) - return true - //return validators.GetID(idx.Validator(rounds[roundIndex])) == me + return validators.GetID(idx.Validator(rounds[roundIndex])) == me } func (em *Emitter) addTxs(e *inter.MutableEventPayload, sorted *types.TransactionsByPriceAndNonce) { maxGasUsed := em.maxGasPowerToUse(e) - //fmt.Println ("Old maxGasused: ", maxGasUsed) - oldMaxGasUsed := maxGasUsed if maxGasUsed <= e.GasPowerUsed() { - fmt.Println ("Too much gas already trying to process: ", maxGasUsed, e.GasPowerUsed()) return } @@ -149,39 +136,42 @@ func (em *Emitter) addTxs(e *inter.MutableEventPayload, sorted *types.Transactio rules := em.world.GetRules() for tx := sorted.Peek(); tx != nil; tx = sorted.Peek() { sender, _ := types.Sender(em.world.TxSigner, tx) - //fmt.Println("Considering TX from sender: ", sender, tx.Hash(), tx.Nonce(), time.Now(), e.Creator()) // check transaction epoch rules if epochcheck.CheckTxs(types.Transactions{tx}, rules) != nil { - fmt.Println("Failing rules TX from sender: ", sender, tx.Hash(), tx.Nonce(), time.Now(), e.Creator()) sorted.Pop() continue } // check there's enough gas power to originate the transaction - //if tx.Gas() >= e.GasPowerLeft().Min() || e.GasPowerUsed()+tx.Gas() >= maxGasUsed { - // if params.TxGas >= e.GasPowerLeft().Min() || e.GasPowerUsed()+params.TxGas >= maxGasUsed { - // Do not track GasPowerLeft - if e.GasPowerUsed()+tx.Gas() >= maxGasUsed { - if e.GasPowerUsed()+params.TxGas >= maxGasUsed { - + if tx.Gas() >= e.GasPowerLeft().Min() || e.GasPowerUsed()+tx.Gas() >= maxGasUsed { + if params.TxGas >= e.GasPowerLeft().Min() || e.GasPowerUsed()+params.TxGas >= maxGasUsed { // stop if cannot originate even an empty transaction break } - fmt.Println("Gas Issues TX from sender: ", sender, tx.Hash(), tx.Nonce(), time.Now(), e.Creator() , tx.Gas() , e.GasPowerLeft().Min(), e.GasPowerUsed()+tx.Gas(), maxGasUsed) sorted.Pop() continue } - + // check not conflicted with already originated txs (in any connected event) + if em.originatedTxs.TotalOf(sender) != 0 { + sorted.Pop() + continue + } + // my turn, i.e. try to not include the same tx simultaneously by different validators + if !em.isMyTxTurn(tx.Hash(), sender, tx.Nonce(), time.Now(), em.validators, e.Creator(), em.epoch) { + sorted.Pop() + continue + } // check transaction is not outdated if !em.world.TxPool.Has(tx.Hash()) { - fmt.Println("Outdated TX from sender: ", sender, tx.Hash(), tx.Nonce(), time.Now(), e.Creator()) sorted.Pop() continue } // add - fmt.Println("My Turn to Execute e.GasPowerUsed()+tx.Gas() >= maxGasUsed: ", e.GasPowerUsed()+tx.Gas(), maxGasUsed, oldMaxGasUsed) + fmt.Println("My Turn to Execute e.GasPowerUsed()+tx.Gas() >= maxGasUsed: ", e.GasPowerUsed()+tx.Gas(), maxGasUsed) e.SetGasPowerUsed(e.GasPowerUsed() + tx.Gas()) e.SetGasPowerLeft(e.GasPowerLeft().Sub(tx.Gas())) e.SetTxs(append(e.Txs(), tx)) sorted.Shift() } } + + From 8d43b7f486f48fdef4212b2bffe822b875012533 Mon Sep 17 00:00:00 2001 From: jacklevin74 Date: Sun, 28 Jan 2024 08:15:38 -1000 Subject: [PATCH 20/21] Update gas_power_check.go experiment, may crash --- eventcheck/gaspowercheck/gas_power_check.go | 70 ++++++++++++--------- 1 file changed, 40 insertions(+), 30 deletions(-) diff --git a/eventcheck/gaspowercheck/gas_power_check.go b/eventcheck/gaspowercheck/gas_power_check.go index 60a26813f..b872988cf 100644 --- a/eventcheck/gaspowercheck/gas_power_check.go +++ b/eventcheck/gaspowercheck/gas_power_check.go @@ -4,6 +4,7 @@ import ( "errors" "math/big" "time" + //"fmt" "github.com/Fantom-foundation/lachesis-base/eventcheck/epochcheck" "github.com/Fantom-foundation/lachesis-base/hash" @@ -127,47 +128,56 @@ func CalcValidatorGasPower(e inter.EventI, eTime, prevTime inter.Timestamp, prev if gasPower > maxGasPower { gasPower = maxGasPower } + //fmt.Printf("e.Creator: %v, gasPower %v gasPowerAllocatedBn: %v\n", e.Creator(), gasPower, gasPowerAllocatedBn) return gasPower } func CalcValidatorGasPowerPerSec( - validator idx.ValidatorID, - validators *pos.Validators, - config Config, + validator idx.ValidatorID, + validators *pos.Validators, + config Config, ) ( - perSec uint64, - maxGasPower uint64, - startup uint64, + perSec uint64, + maxGasPower uint64, + startup uint64, ) { - stake := validators.Get(validator) - if stake == 0 { - return 0, 0, 0 - } - - gas := config - - validatorGasPowerPerSecBn := new(big.Int).SetUint64(gas.AllocPerSec) - mul(validatorGasPowerPerSecBn, uint64(stake)) - div(validatorGasPowerPerSecBn, uint64(validators.TotalWeight())) - perSec = validatorGasPowerPerSecBn.Uint64() - - maxGasPower = perSec * (uint64(gas.MaxAllocPeriod) / uint64(time.Second)) - if maxGasPower < gas.MinEnsuredAlloc { - maxGasPower = gas.MinEnsuredAlloc - } - - startup = perSec * (uint64(gas.StartupAllocPeriod) / uint64(time.Second)) - if startup < gas.MinStartupGas { - startup = gas.MinStartupGas - } - - return + stake := validators.Get(validator) + if stake == 0 { + return 0, 0, 0 + } + + // don't calculate, keep the same for all + //maxGasPower = 1000 * 28000 * 60 + //startup = 100 * 28000 + //return + + gas := config + + validatorGasPowerPerSecBn := new(big.Int).SetUint64(gas.AllocPerSec) + mul(validatorGasPowerPerSecBn, uint64(stake)) + div(validatorGasPowerPerSecBn, uint64(validators.TotalWeight())) + perSec = validatorGasPowerPerSecBn.Uint64() + //if validator == 7 { + perSec = 1000 * 28000 + //} + + maxGasPower = perSec * (uint64(gas.MaxAllocPeriod) / uint64(time.Second)) + if maxGasPower < gas.MinEnsuredAlloc { + maxGasPower = gas.MinEnsuredAlloc + } + + startup = perSec * (uint64(gas.StartupAllocPeriod) / uint64(time.Second)) + if startup < gas.MinStartupGas { + startup = gas.MinStartupGas + } + //fmt.Printf("validator:%v , GasPowerPerSec: Persec: %v, maxGasPower: %v, startup: %v gas.AllocPerSec %v stake %v validators.TotalWeight() %v\n",validator, perSec, maxGasPower, startup, gas.AllocPerSec, stake, validators.TotalWeight()) + + return } // Validate event func (v *Checker) Validate(e inter.EventI, selfParent inter.EventI) error { - // do no validate gas power (with weak consensus) everything allowed return nil gasPowers, err := v.CalcGasPower(e, selfParent) if err != nil { From 4f2461367437d073a3e9e58ef62a957aafd0d78c Mon Sep 17 00:00:00 2001 From: Nicholas Pettas Date: Sun, 28 Jan 2024 11:39:22 -0800 Subject: [PATCH 21/21] update the go.mod --- go.mod | 2 -- 1 file changed, 2 deletions(-) diff --git a/go.mod b/go.mod index 2453c38d2..a53d0d013 100644 --- a/go.mod +++ b/go.mod @@ -116,5 +116,3 @@ replace github.com/Fantom-foundation/lachesis-base => github.com/faircrypto/lach replace github.com/dvyukov/go-fuzz => github.com/guzenok/go-fuzz v0.0.0-20210201043429-a8e90a2a4f88 replace github.com/recws-org/recws => github.com/nibty/recws v0.0.0-20231129011923-06823df0d0db - -replace github.com/Fantom-foundation/lachesis-base => github.com/jacklevin74/lachesis-base v0.0.0-20230817040848-1326ba9aa59b