github.com/koko1123/flow-go-1@v0.29.6/fvm/blueprints/epochs.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  
    11  	"github.com/onflow/flow-core-contracts/lib/go/templates"
    12  
    13  	flowsdk "github.com/onflow/flow-go-sdk"
    14  	sdktemplates "github.com/onflow/flow-go-sdk/templates"
    15  
    16  	"github.com/koko1123/flow-go-1/model/bootstrap"
    17  	"github.com/koko1123/flow-go-1/model/flow"
    18  	"github.com/koko1123/flow-go-1/module/epochs"
    19  )
    20  
    21  //go:embed scripts/deployIDTableStakingTransactionTemplate.cdc
    22  var deployIDTableStakingTransactionTemplate string
    23  
    24  //go:embed scripts/deployEpochTransactionTemplate.cdc
    25  var deployEpochTransactionTemplate string
    26  
    27  //go:embed scripts/setupAccountTemplate.cdc
    28  var setupAccountTemplate string
    29  
    30  //go:embed scripts/fundAccountTemplate.cdc
    31  var fundAccountTemplate string
    32  
    33  //go:embed scripts/deployLockedTokensTemplate.cdc
    34  var deployLockedTokensTemplate string
    35  
    36  // DeployEpochTransaction returns the transaction body for the deploy epoch transaction
    37  func DeployEpochTransaction(service flow.Address, contract []byte, epochConfig epochs.EpochConfig) *flow.TransactionBody {
    38  	return flow.NewTransactionBody().
    39  		SetScript([]byte(
    40  			templates.ReplaceAddresses(
    41  				deployEpochTransactionTemplate,
    42  				templates.Environment{
    43  					QuorumCertificateAddress: service.Hex(),
    44  				},
    45  			),
    46  		)).
    47  		AddArgument(jsoncdc.MustEncode(cadence.String(hex.EncodeToString(contract)))).
    48  		AddArgument(jsoncdc.MustEncode(epochConfig.CurrentEpochCounter)).
    49  		AddArgument(jsoncdc.MustEncode(epochConfig.NumViewsInEpoch)).
    50  		AddArgument(jsoncdc.MustEncode(epochConfig.NumViewsInStakingAuction)).
    51  		AddArgument(jsoncdc.MustEncode(epochConfig.NumViewsInDKGPhase)).
    52  		AddArgument(jsoncdc.MustEncode(epochConfig.NumCollectorClusters)).
    53  		AddArgument(jsoncdc.MustEncode(epochConfig.FLOWsupplyIncreasePercentage)).
    54  		AddArgument(jsoncdc.MustEncode(epochConfig.RandomSource)).
    55  		AddArgument(epochs.EncodeClusterAssignments(epochConfig.CollectorClusters)).
    56  		AddAuthorizer(service)
    57  }
    58  
    59  // SetupAccountTransaction returns the transaction body for the setup account transaction
    60  func SetupAccountTransaction(
    61  	fungibleToken flow.Address,
    62  	flowToken flow.Address,
    63  	accountAddress flow.Address,
    64  ) *flow.TransactionBody {
    65  	return flow.NewTransactionBody().
    66  		SetScript([]byte(
    67  			templates.ReplaceAddresses(
    68  				setupAccountTemplate,
    69  				templates.Environment{
    70  					FungibleTokenAddress: fungibleToken.Hex(),
    71  					FlowTokenAddress:     flowToken.Hex(),
    72  				},
    73  			),
    74  		)).
    75  		AddAuthorizer(accountAddress)
    76  }
    77  
    78  // DeployIDTableStakingTransaction returns the transaction body for the deploy id table staking transaction
    79  func DeployIDTableStakingTransaction(service flow.Address, contract []byte, epochTokenPayout cadence.UFix64, rewardCut cadence.UFix64) *flow.TransactionBody {
    80  	return flow.NewTransactionBody().
    81  		SetScript([]byte(deployIDTableStakingTransactionTemplate)).
    82  		AddArgument(jsoncdc.MustEncode(cadence.String(hex.EncodeToString(contract)))).
    83  		AddArgument(jsoncdc.MustEncode(epochTokenPayout)).
    84  		AddArgument(jsoncdc.MustEncode(rewardCut)).
    85  		AddAuthorizer(service)
    86  }
    87  
    88  // FundAccountTransaction returns the transaction body for the fund account transaction
    89  func FundAccountTransaction(
    90  	service flow.Address,
    91  	fungibleToken flow.Address,
    92  	flowToken flow.Address,
    93  	nodeAddress flow.Address,
    94  ) *flow.TransactionBody {
    95  
    96  	cdcAmount, err := cadence.NewUFix64(fmt.Sprintf("%d.0", 2_000_000))
    97  	if err != nil {
    98  		panic(err)
    99  	}
   100  
   101  	return flow.NewTransactionBody().
   102  		SetScript([]byte(templates.ReplaceAddresses(
   103  			fundAccountTemplate,
   104  			templates.Environment{
   105  				FungibleTokenAddress: fungibleToken.Hex(),
   106  				FlowTokenAddress:     flowToken.Hex(),
   107  			},
   108  		))).
   109  		AddArgument(jsoncdc.MustEncode(cdcAmount)).
   110  		AddArgument(jsoncdc.MustEncode(cadence.NewAddress(nodeAddress))).
   111  		AddAuthorizer(service)
   112  }
   113  
   114  // DeployLockedTokensTransaction returns the transaction body for the deploy locked tokens transaction
   115  func DeployLockedTokensTransaction(service flow.Address, contract []byte, publicKeys []cadence.Value) *flow.TransactionBody {
   116  	return flow.NewTransactionBody().
   117  		SetScript([]byte(
   118  			deployLockedTokensTemplate,
   119  		)).
   120  		AddArgument(jsoncdc.MustEncode(cadence.NewArray(publicKeys))).
   121  		AddArgument(jsoncdc.MustEncode(cadence.String(hex.EncodeToString(contract)))).
   122  		AddAuthorizer(service)
   123  }
   124  
   125  // RegisterNodeTransaction creates a new node struct object.
   126  // Then, if the node is a collector node, creates a new account and adds a QC object to it
   127  // If the node is a consensus node, it creates a new account and adds a DKG object to it
   128  func RegisterNodeTransaction(
   129  	service flow.Address,
   130  	flowTokenAddress flow.Address,
   131  	nodeAddress flow.Address,
   132  	id *flow.Identity,
   133  ) *flow.TransactionBody {
   134  
   135  	env := templates.Environment{
   136  		FlowTokenAddress:         flowTokenAddress.HexWithPrefix(),
   137  		IDTableAddress:           service.HexWithPrefix(),
   138  		QuorumCertificateAddress: service.HexWithPrefix(),
   139  		DkgAddress:               service.HexWithPrefix(),
   140  		EpochAddress:             service.HexWithPrefix(),
   141  	}
   142  
   143  	// Use NetworkingKey as the public key of the machine account.
   144  	// We do this for tests/localnet but normally it should be a separate key.
   145  	accountKey := &flowsdk.AccountKey{
   146  		PublicKey: id.NetworkPubKey,
   147  		SigAlgo:   id.NetworkPubKey.Algorithm(),
   148  		HashAlgo:  bootstrap.DefaultMachineAccountHashAlgo,
   149  		Weight:    1000,
   150  	}
   151  
   152  	cadenceCryptoKey, err := sdktemplates.AccountKeyToCadenceCryptoKey(accountKey)
   153  	if err != nil {
   154  		panic(err)
   155  	}
   156  
   157  	cadencePublicKeys := cadence.NewArray(
   158  		[]cadence.Value{
   159  			cadenceCryptoKey,
   160  		},
   161  	)
   162  
   163  	cdcAmount, err := cadence.NewUFix64("1250000.0")
   164  	if err != nil {
   165  		panic(err)
   166  	}
   167  
   168  	cdcNodeID, err := cadence.NewString(id.NodeID.String())
   169  	if err != nil {
   170  		panic(err)
   171  	}
   172  
   173  	cdcAddress, err := cadence.NewString(id.Address)
   174  	if err != nil {
   175  		panic(err)
   176  	}
   177  
   178  	cdcNetworkPubKey, err := cadence.NewString(id.NetworkPubKey.String()[2:])
   179  	if err != nil {
   180  		panic(err)
   181  	}
   182  
   183  	cdcStakingPubKey, err := cadence.NewString(id.StakingPubKey.String()[2:])
   184  	if err != nil {
   185  		panic(err)
   186  	}
   187  
   188  	// register node
   189  	return flow.NewTransactionBody().
   190  		SetScript(templates.GenerateEpochRegisterNodeScript(env)).
   191  		AddArgument(jsoncdc.MustEncode(cdcNodeID)).
   192  		AddArgument(jsoncdc.MustEncode(cadence.NewUInt8(uint8(id.Role)))).
   193  		AddArgument(jsoncdc.MustEncode(cdcAddress)).
   194  		AddArgument(jsoncdc.MustEncode(cdcNetworkPubKey)).
   195  		AddArgument(jsoncdc.MustEncode(cdcStakingPubKey)).
   196  		AddArgument(jsoncdc.MustEncode(cdcAmount)).
   197  		AddArgument(jsoncdc.MustEncode(cadencePublicKeys)).
   198  		AddAuthorizer(nodeAddress)
   199  }
   200  
   201  // SetStakingAllowlistTransaction returns transaction body for set staking allowlist transaction
   202  func SetStakingAllowlistTransaction(idTableStakingAddr flow.Address, allowedNodeIDs []flow.Identifier) *flow.TransactionBody {
   203  	env := templates.Environment{
   204  		IDTableAddress: idTableStakingAddr.HexWithPrefix(),
   205  	}
   206  
   207  	cdcNodeIDs := make([]cadence.Value, 0, len(allowedNodeIDs))
   208  	for _, id := range allowedNodeIDs {
   209  		cdcNodeID, err := cadence.NewString(id.String())
   210  		if err != nil {
   211  			panic(err)
   212  		}
   213  		cdcNodeIDs = append(cdcNodeIDs, cdcNodeID)
   214  	}
   215  
   216  	return flow.NewTransactionBody().
   217  		SetScript(templates.GenerateSetApprovedNodesScript(env)).
   218  		AddArgument(jsoncdc.MustEncode(cadence.NewArray(cdcNodeIDs))).
   219  		AddAuthorizer(idTableStakingAddr)
   220  }
   221  
   222  // BytesToCadenceArray converts byte slice to cadence array
   223  func BytesToCadenceArray(b []byte) cadence.Array {
   224  	values := make([]cadence.Value, len(b))
   225  	for i, v := range b {
   226  		values[i] = cadence.NewUInt8(v)
   227  	}
   228  	return cadence.NewArray(values)
   229  }