github.com/onflow/flow-go@v0.33.17/fvm/blueprints/fees.go (about) 1 package blueprints 2 3 import ( 4 _ "embed" 5 "encoding/hex" 6 "fmt" 7 8 "github.com/onflow/cadence" 9 jsoncdc "github.com/onflow/cadence/encoding/json" 10 "github.com/onflow/cadence/runtime/common" 11 "github.com/onflow/flow-core-contracts/lib/go/contracts" 12 "github.com/onflow/flow-core-contracts/lib/go/templates" 13 14 "github.com/onflow/flow-go/model/flow" 15 ) 16 17 var TransactionFeesExecutionEffortWeightsPath = cadence.Path{ 18 Domain: common.PathDomainStorage, 19 Identifier: "executionEffortWeights", 20 } 21 var TransactionFeesExecutionMemoryWeightsPath = cadence.Path{ 22 Domain: common.PathDomainStorage, 23 Identifier: "executionMemoryWeights", 24 } 25 var TransactionFeesExecutionMemoryLimitPath = cadence.Path{ 26 Domain: common.PathDomainStorage, 27 Identifier: "executionMemoryLimit", 28 } 29 30 //go:embed scripts/deployTxFeesTransactionTemplate.cdc 31 var deployTxFeesTransactionTemplate string 32 33 //go:embed scripts/setupParametersTransactionTemplate.cdc 34 var setupParametersTransactionTemplate string 35 36 //go:embed scripts/setupStorageForServiceAccountsTemplate.cdc 37 var setupStorageForServiceAccountsTemplate string 38 39 //go:embed scripts/setupStorageForAccount.cdc 40 var setupStorageForAccountTemplate string 41 42 //go:embed scripts/setupFeesTransactionTemplate.cdc 43 var setupFeesTransactionTemplate string 44 45 //go:embed scripts/setExecutionMemoryLimit.cdc 46 var setExecutionMemoryLimit string 47 48 func DeployTxFeesContractTransaction(service, fungibleToken, flowToken, storageFees, flowFees flow.Address) *flow.TransactionBody { 49 contract := contracts.FlowFees( 50 fungibleToken.HexWithPrefix(), 51 flowToken.HexWithPrefix(), 52 storageFees.HexWithPrefix(), 53 ) 54 55 return flow.NewTransactionBody(). 56 SetScript([]byte(deployTxFeesTransactionTemplate)). 57 AddArgument(jsoncdc.MustEncode(cadence.String(hex.EncodeToString(contract)))). 58 AddAuthorizer(flowFees). 59 AddAuthorizer(service) 60 } 61 62 func DeployStorageFeesContractTransaction(service flow.Address, contract []byte) *flow.TransactionBody { 63 return DeployContractTransaction(service, contract, "FlowStorageFees") 64 } 65 66 func SetupParametersTransaction( 67 service flow.Address, 68 addressCreationFee, 69 minimumStorageReservation, 70 storagePerFlow cadence.UFix64, 71 restrictedAccountCreationEnabled cadence.Bool, 72 ) *flow.TransactionBody { 73 addressCreationFeeArg, err := jsoncdc.Encode(addressCreationFee) 74 if err != nil { 75 panic(fmt.Sprintf("failed to encode address creation fee: %s", err.Error())) 76 } 77 minimumStorageReservationArg, err := jsoncdc.Encode(minimumStorageReservation) 78 if err != nil { 79 panic(fmt.Sprintf("failed to encode minimum storage reservation: %s", err.Error())) 80 } 81 storagePerFlowArg, err := jsoncdc.Encode(storagePerFlow) 82 if err != nil { 83 panic(fmt.Sprintf("failed to encode storage ratio: %s", err.Error())) 84 } 85 restrictedAccountCreationEnabledArg, err := jsoncdc.Encode(restrictedAccountCreationEnabled) 86 if err != nil { 87 panic(fmt.Sprintf("failed to encode restrictedAccountCreationEnabled: %s", err.Error())) 88 } 89 90 return flow.NewTransactionBody(). 91 SetScript([]byte(templates.ReplaceAddresses(setupParametersTransactionTemplate, 92 templates.Environment{ 93 StorageFeesAddress: service.Hex(), 94 ServiceAccountAddress: service.Hex(), 95 })), 96 ). 97 AddArgument(addressCreationFeeArg). 98 AddArgument(minimumStorageReservationArg). 99 AddArgument(storagePerFlowArg). 100 AddArgument(restrictedAccountCreationEnabledArg). 101 AddAuthorizer(service) 102 } 103 104 func SetupStorageForServiceAccountsTransaction( 105 service, fungibleToken, flowToken, feeContract flow.Address, 106 ) *flow.TransactionBody { 107 return flow.NewTransactionBody(). 108 SetScript([]byte(templates.ReplaceAddresses(setupStorageForServiceAccountsTemplate, 109 templates.Environment{ 110 ServiceAccountAddress: service.Hex(), 111 StorageFeesAddress: service.Hex(), 112 FungibleTokenAddress: fungibleToken.Hex(), 113 FlowTokenAddress: flowToken.Hex(), 114 })), 115 ). 116 AddAuthorizer(service). 117 AddAuthorizer(fungibleToken). 118 AddAuthorizer(flowToken). 119 AddAuthorizer(feeContract) 120 } 121 122 func SetupStorageForAccountTransaction( 123 account, service, fungibleToken, flowToken flow.Address, 124 ) *flow.TransactionBody { 125 return flow.NewTransactionBody(). 126 SetScript([]byte(templates.ReplaceAddresses(setupStorageForAccountTemplate, 127 templates.Environment{ 128 ServiceAccountAddress: service.Hex(), 129 StorageFeesAddress: service.Hex(), 130 FungibleTokenAddress: fungibleToken.Hex(), 131 FlowTokenAddress: flowToken.Hex(), 132 })), 133 ). 134 AddAuthorizer(account). 135 AddAuthorizer(service) 136 } 137 138 func SetupFeesTransaction( 139 service flow.Address, 140 flowFees flow.Address, 141 surgeFactor, 142 inclusionEffortCost, 143 executionEffortCost cadence.UFix64, 144 ) *flow.TransactionBody { 145 surgeFactorArg, err := jsoncdc.Encode(surgeFactor) 146 if err != nil { 147 panic(fmt.Sprintf("failed to encode surge factor: %s", err.Error())) 148 } 149 inclusionEffortCostArg, err := jsoncdc.Encode(inclusionEffortCost) 150 if err != nil { 151 panic(fmt.Sprintf("failed to encode inclusion effort cost: %s", err.Error())) 152 } 153 executionEffortCostArg, err := jsoncdc.Encode(executionEffortCost) 154 if err != nil { 155 panic(fmt.Sprintf("failed to encode execution effort cost: %s", err.Error())) 156 } 157 158 return flow.NewTransactionBody(). 159 SetScript([]byte(templates.ReplaceAddresses(setupFeesTransactionTemplate, 160 templates.Environment{ 161 FlowFeesAddress: flowFees.Hex(), 162 })), 163 ). 164 AddArgument(surgeFactorArg). 165 AddArgument(inclusionEffortCostArg). 166 AddArgument(executionEffortCostArg). 167 AddAuthorizer(service) 168 } 169 170 // SetExecutionEffortWeightsTransaction creates a transaction that sets up weights for the weighted Meter. 171 func SetExecutionEffortWeightsTransaction( 172 service flow.Address, 173 weights map[uint]uint64, 174 ) (*flow.TransactionBody, error) { 175 return setExecutionWeightsTransaction( 176 service, 177 weights, 178 TransactionFeesExecutionEffortWeightsPath, 179 ) 180 } 181 182 // SetExecutionMemoryWeightsTransaction creates a transaction that sets up weights for the weighted Meter. 183 func SetExecutionMemoryWeightsTransaction( 184 service flow.Address, 185 weights map[uint]uint64, 186 ) (*flow.TransactionBody, error) { 187 return setExecutionWeightsTransaction( 188 service, 189 weights, 190 TransactionFeesExecutionMemoryWeightsPath, 191 ) 192 } 193 194 func setExecutionWeightsTransaction( 195 service flow.Address, 196 weights map[uint]uint64, 197 path cadence.Path, 198 ) (*flow.TransactionBody, error) { 199 newWeightsKeyValuePairs := make([]cadence.KeyValuePair, len(weights)) 200 i := 0 201 for k, w := range weights { 202 newWeightsKeyValuePairs[i] = cadence.KeyValuePair{ 203 Key: cadence.UInt64(k), 204 Value: cadence.UInt64(w), 205 } 206 i += 1 207 } 208 newWeights, err := jsoncdc.Encode(cadence.NewDictionary(newWeightsKeyValuePairs)) 209 if err != nil { 210 return nil, err 211 } 212 213 storagePath, err := jsoncdc.Encode(path) 214 if err != nil { 215 return nil, err 216 } 217 218 tx := flow.NewTransactionBody(). 219 SetScript([]byte(setExecutionWeightsScript)). 220 AddArgument(newWeights). 221 AddArgument(storagePath). 222 AddAuthorizer(service) 223 224 return tx, nil 225 } 226 227 //go:embed scripts/setExecutionWeightsScript.cdc 228 var setExecutionWeightsScript string 229 230 func SetExecutionMemoryLimitTransaction( 231 service flow.Address, 232 limit uint64, 233 ) (*flow.TransactionBody, error) { 234 newLimit, err := jsoncdc.Encode(cadence.UInt64(limit)) 235 if err != nil { 236 return nil, err 237 } 238 239 storagePath, err := jsoncdc.Encode(TransactionFeesExecutionMemoryLimitPath) 240 if err != nil { 241 return nil, err 242 } 243 244 tx := flow.NewTransactionBody(). 245 SetScript([]byte(setExecutionMemoryLimit)). 246 AddArgument(newLimit). 247 AddArgument(storagePath). 248 AddAuthorizer(service) 249 250 return tx, nil 251 }