Skip to content

Commit 4b21755

Browse files
committed
Merge branch 'master' into bastian/computation-profiling
2 parents 620875f + ab5961a commit 4b21755

File tree

9 files changed

+629
-89
lines changed

9 files changed

+629
-89
lines changed

README.md

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ values.
7373
| `--host` | `FLOW_HOST` | ` ` | Host to listen on for emulator GRPC/REST/Admin servers (default: All Interfaces) |
7474
| `--chain-id` | `FLOW_CHAINID` | `emulator` | Chain to simulate, if 'mainnet' or 'testnet' values are used, you will be able to run transactions against that network and a local fork will be created. Valid values are: 'emulator', 'testnet', 'mainnet' |
7575
| `--redis-url` | `FLOW_REDIS_URL` | '' | Redis-server URL for persisting redis storage backend ( `redis://[[username:]password@]host[:port][/database]` ) |
76-
| `--start-block-height` | `FLOW_STARTBLOCKHEIGHT` | `0` | Start block height to use when starting the network using 'testnet' or 'mainnet' as the chain-id |
77-
| `--rpc-host` | `FLOW_RPCHOST` | '' | RPC host (access node) to query for previous state when starting the network using 'testnet' or 'mainnet' as the chain-id |
76+
| `--fork-host` | `FLOW_FORK_HOST` | '' | gRPC access node address (`host:port`) to fork from |
77+
| `--fork-height` | `FLOW_FORK_HEIGHT` | `0` | Block height to pin the fork (defaults to latest sealed) |
7878
| `--legacy-upgrade` | `FLOW_LEGACYUPGRADE` | `false` | Enable upgrading of legacy contracts |
7979
| `--computation-reporting` | `FLOW_COMPUTATIONREPORTING` | `false` | Enable computation reporting for Cadence scripts & transactions |
8080
| `--checkpoint-dir` | `FLOW_CHECKPOINTDIR` | '' | Checkpoint directory to load the emulator state from, if starting the emulator from a checkpoint |
@@ -155,8 +155,7 @@ Post Data: height={block height}
155155
```
156156
157157
Note: it is only possible to roll back state to a height that was previously executed by the emulator.
158-
To roll back to a past block height when using a forked Mainnet or Testnet network, use the
159-
`--start-block-height` flag.
158+
To pin the starting block height when using a fork, use the `--fork-height` flag.
160159
161160
## Managing emulator state
162161
It's possible to manage emulator state by using the admin API. You can at any point
@@ -269,15 +268,14 @@ you must specify the network name for the chain ID flag and the RPC host
269268
to connect to.
270269

271270
```
272-
flow emulator --chain-id mainnet --rpc-host access.mainnet.nodes.onflow.org:9000
273-
flow emulator --chain-id mainnet --rpc-host access.devnet.nodes.onflow.org:9000
271+
flow emulator --fork-host access.mainnet.nodes.onflow.org:9000
272+
flow emulator --fork-host access.mainnet.nodes.onflow.org:9000 --fork-height 12345
274273
```
275274

276275
Please note, that the actual execution on the real network may differ depending on the exact state when the transaction is
277276
executed.
278277

279-
By default, the forked network will start from the latest sealed block when the emulator
280-
is started. You can specify a different starting block height by using the `--start-block-height` flag.
278+
By default, the forked network will start from the latest sealed block when the emulator is started. You can specify a different starting block height by using the `--fork-height` flag.
281279

282280
You can also store all of your changes and cached registers to a persistent db by using the `--persist` flag,
283281
along with the other SQLite settings.

cmd/emulator/start/start.go

Lines changed: 57 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,18 @@ type Config struct {
7676
CoverageReportingEnabled bool `default:"false" flag:"coverage-reporting" info:"enable Cadence code coverage reporting"`
7777
ComputationProfilingEnabled bool `default:"false" flag:"computation-profiling" info:"enable Cadence computation profiling"`
7878
LegacyContractUpgradeEnabled bool `default:"false" flag:"legacy-upgrade" info:"enable Cadence legacy contract upgrade"`
79-
StartBlockHeight uint64 `default:"0" flag:"start-block-height" info:"block height to start the emulator at. only valid when forking Mainnet or Testnet"`
80-
RPCHost string `default:"" flag:"rpc-host" info:"rpc host to query when forking Mainnet or Testnet"`
79+
ForkHost string `default:"" flag:"fork-host" info:"gRPC access node address (host:port) to fork from"`
80+
ForkHeight uint64 `default:"0" flag:"fork-height" info:"height to pin fork; defaults to latest sealed"`
8181
CheckpointPath string `default:"" flag:"checkpoint-dir" info:"checkpoint directory to load the emulator state from"`
8282
StateHash string `default:"" flag:"state-hash" info:"state hash of the checkpoint to load the emulator state from"`
8383
ComputationReportingEnabled bool `default:"false" flag:"computation-reporting" info:"enable Cadence computation reporting"`
8484
ScheduledTransactionsEnabled bool `default:"true" flag:"scheduled-transactions" info:"enable Cadence scheduled transactions"`
8585
SetupEVMEnabled bool `default:"true" flag:"setup-evm" info:"enable EVM setup for the emulator, this will deploy the EVM contracts"`
8686
SetupVMBridgeEnabled bool `default:"true" flag:"setup-vm-bridge" info:"enable VM Bridge setup for the emulator, this will deploy the VM Bridge contracts"`
87+
88+
// Deprecated hidden aliases
89+
StartBlockHeight uint64 `default:"0" flag:"start-block-height" info:"(deprecated) use --fork-height"`
90+
RPCHost string `default:"" flag:"rpc-host" info:"(deprecated) use --fork-host"`
8791
}
8892

8993
const EnvPrefix = "FLOW"
@@ -148,31 +152,23 @@ func Cmd(config StartConfig) *cobra.Command {
148152
Exit(1, err.Error())
149153
}
150154

151-
if conf.StartBlockHeight > 0 && flowChainID != flowgo.Mainnet && flowChainID != flowgo.Testnet {
152-
Exit(1, "❗ --start-block-height is only valid when forking Mainnet or Testnet")
155+
// Deprecation shims: map old flags to new and warn
156+
if conf.RPCHost != "" && conf.ForkHost == "" {
157+
logger.Warn().Msg("❗ --rpc-host is deprecated; use --fork-host")
158+
conf.ForkHost = conf.RPCHost
153159
}
154-
155-
if (flowChainID == flowgo.Mainnet || flowChainID == flowgo.Testnet) && conf.RPCHost == "" {
156-
Exit(1, "❗ --rpc-host must be provided when forking Mainnet or Testnet")
160+
if conf.StartBlockHeight > 0 && conf.ForkHeight == 0 {
161+
logger.Warn().Msg("❗ --start-block-height is deprecated; use --fork-height")
162+
conf.ForkHeight = conf.StartBlockHeight
157163
}
158164

159-
serviceAddress := flowsdk.ServiceAddress(flowsdk.ChainID(flowChainID))
160-
if conf.SimpleAddresses {
161-
serviceAddress = flowsdk.HexToAddress("0x1")
165+
// In non-fork mode, fork-only flags are invalid
166+
if conf.ForkHost == "" && (conf.StartBlockHeight > 0 || conf.ForkHeight > 0) {
167+
Exit(1, "❗ --fork-height requires --fork-host")
162168
}
163169

164-
serviceFields := map[string]any{
165-
"serviceAddress": serviceAddress.Hex(),
166-
"servicePubKey": hex.EncodeToString(servicePublicKey.Encode()),
167-
"serviceSigAlgo": serviceKeySigAlgo.String(),
168-
"serviceHashAlgo": serviceKeyHashAlgo.String(),
169-
}
170-
171-
if servicePrivateKey != nil {
172-
serviceFields["servicePrivKey"] = hex.EncodeToString(servicePrivateKey.Encode())
173-
}
174-
175-
logger.Info().Fields(serviceFields).Msgf("⚙️ Using service account 0x%s", serviceAddress.Hex())
170+
// Service account logging is deferred until after server configuration to allow
171+
// higher-level wrappers to customize fork settings via ConfigureServer.
176172

177173
minimumStorageReservation := fvm.DefaultMinimumStorageReservation
178174
if conf.MinimumAccountBalance != "" {
@@ -184,6 +180,18 @@ func Cmd(config StartConfig) *cobra.Command {
184180
storageMBPerFLOW = parseCadenceUFix64(conf.StorageMBPerFLOW, "storage-per-flow")
185181
}
186182

183+
// Recompute chain ID and service address accurately for fork mode by querying the node.
184+
forkHost := conf.ForkHost
185+
resolvedChainID := flowChainID
186+
forkMode := forkHost != ""
187+
if forkMode {
188+
parsed, err := server.DetectRemoteChainID(forkHost)
189+
if err != nil {
190+
Exit(1, fmt.Sprintf("failed to detect remote chain id from %s: %v", forkHost, err))
191+
}
192+
resolvedChainID = parsed
193+
}
194+
187195
serverConf := &server.Config{
188196
GRPCPort: conf.Port,
189197
GRPCDebug: conf.GRPCDebug,
@@ -213,14 +221,14 @@ func Cmd(config StartConfig) *cobra.Command {
213221
SkipTransactionValidation: conf.SkipTxValidation,
214222
SimpleAddressesEnabled: conf.SimpleAddresses,
215223
Host: conf.Host,
216-
ChainID: flowChainID,
224+
ChainID: resolvedChainID,
217225
RedisURL: conf.RedisURL,
218226
ContractRemovalEnabled: conf.ContractRemovalEnabled,
219227
SqliteURL: conf.SqliteURL,
220228
CoverageReportingEnabled: conf.CoverageReportingEnabled,
221229
ComputationProfilingEnabled: conf.ComputationProfilingEnabled,
222-
StartBlockHeight: conf.StartBlockHeight,
223-
RPCHost: conf.RPCHost,
230+
ForkHost: conf.ForkHost,
231+
ForkHeight: conf.ForkHeight,
224232
CheckpointPath: conf.CheckpointPath,
225233
StateHash: conf.StateHash,
226234
ComputationReportingEnabled: conf.ComputationReportingEnabled,
@@ -229,6 +237,24 @@ func Cmd(config StartConfig) *cobra.Command {
229237
SetupVMBridgeEnabled: conf.SetupVMBridgeEnabled,
230238
}
231239

240+
serviceAddress := flowsdk.ServiceAddress(flowsdk.ChainID(resolvedChainID))
241+
if conf.SimpleAddresses {
242+
serviceAddress = flowsdk.HexToAddress("0x1")
243+
}
244+
245+
serviceFields := map[string]any{
246+
"serviceAddress": serviceAddress.Hex(),
247+
"servicePubKey": hex.EncodeToString(servicePublicKey.Encode()),
248+
"serviceSigAlgo": serviceKeySigAlgo.String(),
249+
"serviceHashAlgo": serviceKeyHashAlgo.String(),
250+
}
251+
252+
if servicePrivateKey != nil {
253+
serviceFields["servicePrivKey"] = hex.EncodeToString(servicePrivateKey.Encode())
254+
}
255+
256+
logger.Info().Fields(serviceFields).Msgf("⚙️ Using service account 0x%s", serviceAddress.Hex())
257+
232258
emu := server.NewEmulatorServer(logger, serverConf)
233259
if emu != nil {
234260
for _, middleware := range config.RestMiddlewares {
@@ -243,6 +269,12 @@ func Cmd(config StartConfig) *cobra.Command {
243269

244270
initConfig(cmd)
245271

272+
// Hide and deprecate legacy flags while keeping them functional
273+
_ = cmd.PersistentFlags().MarkHidden("rpc-host")
274+
_ = cmd.PersistentFlags().MarkDeprecated("rpc-host", "use --fork-host")
275+
_ = cmd.PersistentFlags().MarkHidden("start-block-height")
276+
_ = cmd.PersistentFlags().MarkDeprecated("start-block-height", "use --fork-height")
277+
246278
return cmd
247279
}
248280

docs/overview.md

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ values.
7373
| `--host` | `FLOW_HOST` | ` ` | Host to listen on for emulator GRPC/REST/Admin servers (default: all interfaces) |
7474
| `--chain-id` | `FLOW_CHAINID` | `emulator` | Chain to emulate for address generation. Valid values are: 'emulator', 'testnet', 'mainnet' |
7575
| `--redis-url` | `FLOW_REDIS_URL` | '' | Redis-server URL for persisting redis storage backend ( `redis://[[username:]password@]host[:port][/database]` ) |
76-
| `--start-block-height` | `FLOW_STARTBLOCKHEIGHT` | `0` | Start block height to use when starting the network using 'testnet' or 'mainnet' as the chain-id |
77-
| `--rpc-host` | `FLOW_RPCHOST` | '' | RPC host (access node) to query for previous state when starting the network using 'testnet' or 'mainnet' as the chain-id |
76+
| `--fork-host` | `FLOW_FORK_HOST` | '' | gRPC access node address (`host:port`) to fork from |
77+
| `--fork-height` | `FLOW_FORK_HEIGHT` | `0` | Block height to pin the fork (defaults to latest sealed) |
7878

7979
## Running the emulator with the Flow CLI
8080

@@ -149,8 +149,7 @@ Post Data: height={block height}
149149
```
150150

151151
Note: it is only possible to roll back state to a height that was previously executed by the emulator.
152-
To roll back to a past block height when using a forked Mainnet or Testnet network, use the
153-
`--start-block-height` flag.
152+
To pin the starting block height when using a fork, use the `--fork-height` flag.
154153

155154
## Managing emulator state
156155

@@ -246,14 +245,13 @@ you must specify the network name for the chain ID flag as well as the RPC host
246245
to connect to.
247246

248247
```
249-
flow emulator --chain-id mainnet --rpc-host access-008.mainnet24.nodes.onflow.org:9000
250-
flow emulator --chain-id mainnet --rpc-host access-002.devnet49.nodes.onflow.org:9000
248+
flow emulator --fork-host access.mainnet.nodes.onflow.org:9000
249+
flow emulator --fork-host access.mainnet.nodes.onflow.org:9000 --fork-height 12345
251250
```
252251

253252
Please note, the actual execution on the real network may differ depending on the exact state when the transaction is executed.
254253

255-
By default, the forked network will start from the latest sealed block when the emulator
256-
is started. You can specify a different starting block height by using the `--start-block-height` flag.
254+
By default, the forked network will start from the latest sealed block when the emulator is started. You can specify a different starting block height by using the `--fork-height` flag.
257255

258256
You can also store all of your changes and cached registers to a persistent db by using the `--persist` flag,
259257
along with the other sqlite settings.

go.mod

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@ go 1.25.0
55
require (
66
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2
77
github.com/fxamacker/cbor/v2 v2.8.1-0.20250402194037-6f932b086829
8-
github.com/glebarez/go-sqlite v1.22.0
98
github.com/go-redis/redis/v8 v8.11.5
109
github.com/google/go-dap v0.11.0
1110
github.com/gorilla/mux v1.8.1
1211
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
12+
github.com/hashicorp/golang-lru/v2 v2.0.7
1313
github.com/improbable-eng/grpc-web v0.15.0
1414
github.com/logrusorgru/aurora v2.0.3+incompatible
1515
github.com/onflow/cadence v1.8.1
1616
github.com/onflow/crypto v0.25.3
17-
github.com/onflow/flow-core-contracts/lib/go/templates v1.9.0
18-
github.com/onflow/flow-go v0.43.3-0.20251020174348-b36af5491350
17+
github.com/onflow/flow-core-contracts/lib/go/templates v1.9.1
18+
github.com/onflow/flow-go v0.43.3-0.20251021182938-b0fef2c5ca47
1919
github.com/onflow/flow-go-sdk v1.9.0
2020
github.com/onflow/flow-nft/lib/go/contracts v1.3.0
2121
github.com/onflow/flow/protobuf/go/flow v0.4.16
@@ -27,7 +27,8 @@ require (
2727
github.com/stretchr/testify v1.11.1
2828
go.uber.org/atomic v1.11.0
2929
go.uber.org/mock v0.6.0
30-
google.golang.org/grpc v1.75.1
30+
google.golang.org/grpc v1.76.0
31+
modernc.org/sqlite v1.28.0
3132
)
3233

3334
require github.com/SaveTheRbtz/mph v0.1.1-0.20240117162131-4166ec7869bc // indirect
@@ -94,7 +95,6 @@ require (
9495
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect
9596
github.com/hashicorp/errwrap v1.1.0 // indirect
9697
github.com/hashicorp/go-multierror v1.1.1 // indirect
97-
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
9898
github.com/hashicorp/hcl v1.0.0 // indirect
9999
github.com/holiman/bloomfilter/v2 v2.0.3 // indirect
100100
github.com/holiman/uint256 v1.3.2 // indirect
@@ -115,6 +115,7 @@ require (
115115
github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect
116116
github.com/jordanschalm/lockctx v0.0.0-20250412215529-226f85c10956 // indirect
117117
github.com/k0kubun/pp/v3 v3.5.0 // indirect
118+
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
118119
github.com/kevinburke/go-bindata v3.24.0+incompatible // indirect
119120
github.com/klauspost/compress v1.18.0 // indirect
120121
github.com/klauspost/cpuid/v2 v2.2.9 // indirect
@@ -146,7 +147,7 @@ require (
146147
github.com/olekukonko/tablewriter v0.0.5 // indirect
147148
github.com/onflow/atree v0.11.0 // indirect
148149
github.com/onflow/fixed-point v0.1.1 // indirect
149-
github.com/onflow/flow-core-contracts/lib/go/contracts v1.9.0 // indirect
150+
github.com/onflow/flow-core-contracts/lib/go/contracts v1.9.1 // indirect
150151
github.com/onflow/flow-evm-bridge v0.1.0 // indirect
151152
github.com/onflow/flow-ft/lib/go/contracts v1.0.1 // indirect
152153
github.com/onflow/flow-ft/lib/go/templates v1.0.1 // indirect
@@ -209,25 +210,32 @@ require (
209210
go.yaml.in/yaml/v2 v2.4.2 // indirect
210211
golang.org/x/crypto v0.41.0 // indirect
211212
golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 // indirect
213+
golang.org/x/mod v0.27.0 // indirect
212214
golang.org/x/net v0.43.0 // indirect
213215
golang.org/x/sync v0.16.0 // indirect
214216
golang.org/x/sys v0.36.0 // indirect
215217
golang.org/x/term v0.34.0 // indirect
216218
golang.org/x/text v0.28.0 // indirect
217219
golang.org/x/time v0.12.0 // indirect
220+
golang.org/x/tools v0.36.0 // indirect
218221
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect
219222
gonum.org/v1/gonum v0.16.0 // indirect
220223
google.golang.org/appengine v1.6.8 // indirect
221-
google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7 // indirect
224+
google.golang.org/genproto/googleapis/api v0.0.0-20250804133106-a7a43d27e69b // indirect
222225
google.golang.org/genproto/googleapis/rpc v0.0.0-20250804133106-a7a43d27e69b // indirect
223226
google.golang.org/protobuf v1.36.9 // indirect
224227
gopkg.in/ini.v1 v1.67.0 // indirect
225228
gopkg.in/yaml.v2 v2.4.0 // indirect
226229
gopkg.in/yaml.v3 v3.0.1 // indirect
227230
lukechampine.com/blake3 v1.4.1 // indirect
231+
lukechampine.com/uint128 v1.2.0 // indirect
232+
modernc.org/cc/v3 v3.41.0 // indirect
233+
modernc.org/ccgo/v3 v3.16.15 // indirect
228234
modernc.org/libc v1.37.6 // indirect
229235
modernc.org/mathutil v1.6.0 // indirect
230236
modernc.org/memory v1.7.2 // indirect
231-
modernc.org/sqlite v1.28.0 // indirect
237+
modernc.org/opt v0.1.3 // indirect
238+
modernc.org/strutil v1.1.3 // indirect
239+
modernc.org/token v1.1.0 // indirect
232240
nhooyr.io/websocket v1.8.7 // indirect
233241
)

0 commit comments

Comments
 (0)