Skip to content

Commit

Permalink
Merge pull request #5070 from onflow/janez/setup-evm-account-on-boots…
Browse files Browse the repository at this point in the history
…trap

Setup EVM account Flow vault during bootstrap
  • Loading branch information
janezpodhostnik authored Dec 13, 2023
2 parents cb152a0 + 0cce03f commit 00b49e3
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 10 deletions.
19 changes: 19 additions & 0 deletions fvm/blueprints/fees.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ var setupParametersTransactionTemplate string
//go:embed scripts/setupStorageForServiceAccountsTemplate.cdc
var setupStorageForServiceAccountsTemplate string

//go:embed scripts/setupStorageForAccount.cdc
var setupStorageForAccountTemplate string

//go:embed scripts/setupFeesTransactionTemplate.cdc
var setupFeesTransactionTemplate string

Expand Down Expand Up @@ -116,6 +119,22 @@ func SetupStorageForServiceAccountsTransaction(
AddAuthorizer(feeContract)
}

func SetupStorageForAccountTransaction(
account, service, fungibleToken, flowToken flow.Address,
) *flow.TransactionBody {
return flow.NewTransactionBody().
SetScript([]byte(templates.ReplaceAddresses(setupStorageForAccountTemplate,
templates.Environment{
ServiceAccountAddress: service.Hex(),
StorageFeesAddress: service.Hex(),
FungibleTokenAddress: fungibleToken.Hex(),
FlowTokenAddress: flowToken.Hex(),
})),
).
AddAuthorizer(account).
AddAuthorizer(service)
}

func SetupFeesTransaction(
service flow.Address,
flowFees flow.Address,
Expand Down
25 changes: 25 additions & 0 deletions fvm/blueprints/scripts/setupStorageForAccount.cdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import FlowServiceAccount from 0xFLOWSERVICEADDRESS
import FlowStorageFees from 0xFLOWSTORAGEFEESADDRESS
import FungibleToken from 0xFUNGIBLETOKENADDRESS
import FlowToken from 0xFLOWTOKENADDRESS

// This transaction sets up storage on a auth account.
// This is used during bootstrapping a local environment
transaction() {
prepare(account: AuthAccount, service: AuthAccount) {

// take all the funds from the service account
let tokenVault = service.borrow<&FlowToken.Vault>(from: /storage/flowTokenVault)
?? panic("Unable to borrow reference to the default token vault")

let storageReservation <- tokenVault.withdraw(amount: FlowStorageFees.minimumStorageReservation) as! @FlowToken.Vault
let hasReceiver = account.getCapability(/public/flowTokenReceiver)!.check<&{FungibleToken.Receiver}>()
if !hasReceiver {
FlowServiceAccount.initDefaultToken(account)
}
let receiver = account.getCapability(/public/flowTokenReceiver)!.borrow<&{FungibleToken.Receiver}>()
?? panic("Could not borrow receiver reference to the recipient's Vault")

receiver.deposit(from: <-storageReservation)
}
}
24 changes: 21 additions & 3 deletions fvm/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ func (b *bootstrapExecutor) Execute() error {
b.setStakingAllowlist(service, b.identities.NodeIDs())

// sets up the EVM environment
b.setupEVM(service, flowToken)
b.setupEVM(service, fungibleToken, flowToken)

return nil
}
Expand Down Expand Up @@ -771,6 +771,22 @@ func (b *bootstrapExecutor) setupStorageForServiceAccounts(
panicOnMetaInvokeErrf("failed to setup storage for service accounts: %s", txError, err)
}

func (b *bootstrapExecutor) setupStorageForAccount(
account, service, fungibleToken, flowToken flow.Address,
) {
txError, err := b.invokeMetaTransaction(
b.ctx,
Transaction(
blueprints.SetupStorageForAccountTransaction(
account,
service,
fungibleToken,
flowToken),
0),
)
panicOnMetaInvokeErrf("failed to setup storage for service accounts: %s", txError, err)
}

func (b *bootstrapExecutor) setStakingAllowlist(
service flow.Address,
allowedIDs []flow.Identifier,
Expand All @@ -788,9 +804,9 @@ func (b *bootstrapExecutor) setStakingAllowlist(
panicOnMetaInvokeErrf("failed to set staking allow-list: %s", txError, err)
}

func (b *bootstrapExecutor) setupEVM(serviceAddress, flowTokenAddress flow.Address) {
func (b *bootstrapExecutor) setupEVM(serviceAddress, fungibleTokenAddress, flowTokenAddress flow.Address) {
if b.setupEVMEnabled {
b.createAccount(nil) // account for storage
evmAcc := b.createAccount(nil) // account for storage
tx := blueprints.DeployContractTransaction(
serviceAddress,
stdlib.ContractCode(flowTokenAddress),
Expand All @@ -802,6 +818,8 @@ func (b *bootstrapExecutor) setupEVM(serviceAddress, flowTokenAddress flow.Addre
Transaction(tx, 0),
)
panicOnMetaInvokeErrf("failed to deploy EVM contract: %s", txError, err)

b.setupStorageForAccount(evmAcc, serviceAddress, fungibleTokenAddress, flowTokenAddress)
}
}

Expand Down
11 changes: 4 additions & 7 deletions fvm/fvm_bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,7 @@ func NewBasicBlockExecutor(tb testing.TB, chain flow.Chain, logger zerolog.Logge

opts := []fvm.Option{
fvm.WithTransactionFeesEnabled(true),
// TODO (JanezP): enable storage feee once we figure out how storage limits work
// with the EVM account
fvm.WithAccountStorageLimit(false),
fvm.WithAccountStorageLimit(true),
fvm.WithChain(chain),
fvm.WithLogger(logger),
fvm.WithMaxStateInteractionSize(interactionLimit),
Expand Down Expand Up @@ -450,10 +448,9 @@ func BenchmarkRuntimeTransaction(b *testing.B) {
for _, account := range accounts {
addrs = append(addrs, account.Address)
}
// TODO (JanezP): fix when the evm account has a receiver
//evmAddress, err := chain.AddressAtIndex(environment.EVMAccountIndex)
//require.NoError(b, err)
//addrs = append(addrs, evmAddress)
evmAddress, err := chain.AddressAtIndex(systemcontracts.EVMAccountIndex)
require.NoError(b, err)
addrs = append(addrs, evmAddress)

// fund all accounts so not to run into storage problems
fundAccounts(b, blockExecutor, cadence.UFix64(1_000_000_000_000), addrs...)
Expand Down

0 comments on commit 00b49e3

Please sign in to comment.