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  }