github.com/0xPolygon/supernets2-node@v0.0.0-20230711153321-2fe574524eaa/sequencer/txtracker.go (about) 1 package sequencer 2 3 import ( 4 "math/big" 5 "time" 6 7 "github.com/0xPolygon/supernets2-node/log" 8 "github.com/0xPolygon/supernets2-node/state" 9 "github.com/ethereum/go-ethereum/common" 10 "github.com/ethereum/go-ethereum/core/types" 11 ) 12 13 // TxTracker is a struct that contains all the tx data needed to be managed by the worker 14 type TxTracker struct { 15 Hash common.Hash 16 HashStr string 17 From common.Address 18 FromStr string 19 Nonce uint64 20 Gas uint64 // To check if it fits into a batch 21 GasPrice *big.Int 22 Cost *big.Int // Cost = Amount + Benefit 23 Benefit *big.Int // GasLimit * GasPrice 24 BatchResources state.BatchResources // To check if it fits into a batch 25 Efficiency float64 26 RawTx []byte 27 ReceivedAt time.Time // To check if it has been in the efficiency list for too long 28 IP string // IP of the tx sender 29 FailedReason *string // FailedReason is the reason why the tx failed, if it failed 30 constraints batchConstraintsFloat64 31 weightMultipliers batchResourceWeightMultipliers 32 resourceCostMultiplier float64 33 totalWeight float64 34 } 35 36 // batchResourceWeightMultipliers is a struct that contains the weight multipliers for each resource 37 type batchResourceWeightMultipliers struct { 38 cumulativeGasUsed float64 39 arithmetics float64 40 binaries float64 41 keccakHashes float64 42 memAligns float64 43 poseidonHashes float64 44 poseidonPaddings float64 45 steps float64 46 batchBytesSize float64 47 } 48 49 // batchConstraints represents the constraints for a batch in float64 50 type batchConstraintsFloat64 struct { 51 maxTxsPerBatch float64 52 maxBatchBytesSize float64 53 maxCumulativeGasUsed float64 54 maxKeccakHashes float64 55 maxPoseidonHashes float64 56 maxPoseidonPaddings float64 57 maxMemAligns float64 58 maxArithmetics float64 59 maxBinaries float64 60 maxSteps float64 61 } 62 63 // newTxTracker creates and inti a TxTracker 64 func newTxTracker(tx types.Transaction, counters state.ZKCounters, constraints batchConstraintsFloat64, weights batchResourceWeights, resourceCostMultiplier float64, ip string) (*TxTracker, error) { 65 addr, err := state.GetSender(tx) 66 if err != nil { 67 return nil, err 68 } 69 70 totalWeight := float64(weights.WeightArithmetics + weights.WeightBatchBytesSize + weights.WeightBinaries + weights.WeightCumulativeGasUsed + 71 weights.WeightKeccakHashes + weights.WeightMemAligns + weights.WeightPoseidonHashes + weights.WeightPoseidonPaddings + weights.WeightSteps) 72 rawTx, err := state.EncodeTransactions([]types.Transaction{tx}) 73 if err != nil { 74 return nil, err 75 } 76 txTracker := &TxTracker{ 77 Hash: tx.Hash(), 78 HashStr: tx.Hash().String(), 79 From: addr, 80 FromStr: addr.String(), 81 Nonce: tx.Nonce(), 82 Gas: tx.Gas(), 83 GasPrice: tx.GasPrice(), 84 Cost: tx.Cost(), 85 Benefit: new(big.Int).Mul(new(big.Int).SetUint64(tx.Gas()), tx.GasPrice()), 86 BatchResources: state.BatchResources{ 87 Bytes: tx.Size(), 88 ZKCounters: counters, 89 }, 90 Efficiency: 0, 91 RawTx: rawTx, 92 ReceivedAt: time.Now(), 93 IP: ip, 94 constraints: constraints, 95 weightMultipliers: calculateWeightMultipliers(weights, totalWeight), 96 resourceCostMultiplier: resourceCostMultiplier, 97 totalWeight: totalWeight, 98 } 99 txTracker.calculateEfficiency(constraints, weights) 100 101 return txTracker, nil 102 } 103 104 // updateZKCounters updates the counters of the tx and recalculates the tx efficiency 105 106 func (tx *TxTracker) updateZKCounters(counters state.ZKCounters, constraints batchConstraintsFloat64, weights batchResourceWeights) { 107 tx.BatchResources.ZKCounters = counters 108 tx.calculateEfficiency(constraints, weights) 109 } 110 111 // calculateEfficiency calculates the tx efficiency 112 func (tx *TxTracker) calculateEfficiency(constraints batchConstraintsFloat64, weights batchResourceWeights) { 113 totalWeight := float64(weights.WeightArithmetics + weights.WeightBatchBytesSize + weights.WeightBinaries + weights.WeightCumulativeGasUsed + 114 weights.WeightKeccakHashes + weights.WeightMemAligns + weights.WeightPoseidonHashes + weights.WeightPoseidonPaddings + weights.WeightSteps) 115 116 // TODO: Optmize tx.Efficiency calculation (precalculate constansts values) 117 // TODO: Evaluate avoid type conversion (performance impact?) 118 resourceCost := (float64(tx.BatchResources.ZKCounters.CumulativeGasUsed)/constraints.maxCumulativeGasUsed)*float64(weights.WeightCumulativeGasUsed)/totalWeight + 119 (float64(tx.BatchResources.ZKCounters.UsedArithmetics)/constraints.maxArithmetics)*float64(weights.WeightArithmetics)/totalWeight + 120 (float64(tx.BatchResources.ZKCounters.UsedBinaries)/constraints.maxBinaries)*float64(weights.WeightBinaries)/totalWeight + 121 (float64(tx.BatchResources.ZKCounters.UsedKeccakHashes)/constraints.maxKeccakHashes)*float64(weights.WeightKeccakHashes)/totalWeight + 122 (float64(tx.BatchResources.ZKCounters.UsedMemAligns)/constraints.maxMemAligns)*float64(weights.WeightMemAligns)/totalWeight + 123 (float64(tx.BatchResources.ZKCounters.UsedPoseidonHashes)/constraints.maxPoseidonHashes)*float64(weights.WeightPoseidonHashes)/totalWeight + 124 (float64(tx.BatchResources.ZKCounters.UsedPoseidonPaddings)/constraints.maxPoseidonPaddings)*float64(weights.WeightPoseidonPaddings)/totalWeight + 125 (float64(tx.BatchResources.ZKCounters.UsedSteps)/constraints.maxSteps)*float64(weights.WeightSteps)/totalWeight + 126 (float64(tx.BatchResources.Bytes)/constraints.maxBatchBytesSize)*float64(weights.WeightBatchBytesSize)/totalWeight //Meto config 127 128 resourceCost = resourceCost * tx.resourceCostMultiplier 129 130 var eff *big.Float 131 132 ben := big.NewFloat(0).SetInt(tx.Benefit) 133 rc := big.NewFloat(0).SetFloat64(resourceCost) 134 eff = big.NewFloat(0).Quo(ben, rc) 135 136 var accuracy big.Accuracy 137 tx.Efficiency, accuracy = eff.Float64() 138 log.Infof("CalculateEfficiency(%f) for tx(%s)", tx.Efficiency, tx.Hash.String()) 139 if accuracy != big.Exact { 140 log.Errorf("CalculateEfficiency accuracy warning (%s). Calculated=%s Assigned=%f", accuracy.String(), eff.String(), tx.Efficiency) 141 } 142 } 143 144 // calculateWeightMultipliers calculates the weight multipliers for each resource 145 func calculateWeightMultipliers(weights batchResourceWeights, totalWeight float64) batchResourceWeightMultipliers { 146 return batchResourceWeightMultipliers{ 147 cumulativeGasUsed: float64(weights.WeightCumulativeGasUsed) / totalWeight, 148 arithmetics: float64(weights.WeightArithmetics) / totalWeight, 149 binaries: float64(weights.WeightBinaries) / totalWeight, 150 keccakHashes: float64(weights.WeightKeccakHashes) / totalWeight, 151 memAligns: float64(weights.WeightMemAligns) / totalWeight, 152 poseidonHashes: float64(weights.WeightPoseidonHashes) / totalWeight, 153 poseidonPaddings: float64(weights.WeightPoseidonPaddings) / totalWeight, 154 steps: float64(weights.WeightSteps) / totalWeight, 155 batchBytesSize: float64(weights.WeightBatchBytesSize) / totalWeight, 156 } 157 }