Skip to content

Commit 984d444

Browse files
authored
Fix dependency manager handling of block heights outside of query range (#2281)
1 parent e5637bc commit 984d444

File tree

4 files changed

+231
-157
lines changed

4 files changed

+231
-157
lines changed

go.mod

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ require (
2525
github.com/onflow/flow-go v0.45.0-internal-rc.3.0.20260129222115-cc0505f2afd5
2626
github.com/onflow/flow-go-sdk v1.9.13
2727
github.com/onflow/flow/protobuf/go/flow v0.4.19
28-
github.com/onflow/flowkit/v2 v2.10.2
28+
github.com/onflow/flowkit/v2 v2.11.0
2929
github.com/onflowser/flowser/v3 v3.2.1-0.20240131200229-7d4d22715f48
3030
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c
3131
github.com/pkg/errors v0.9.1
@@ -39,7 +39,7 @@ require (
3939
github.com/stretchr/testify v1.11.1
4040
golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546
4141
golang.org/x/term v0.40.0
42-
google.golang.org/grpc v1.78.0
42+
google.golang.org/grpc v1.79.1
4343
)
4444

4545
require (
@@ -270,12 +270,12 @@ require (
270270
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
271271
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect
272272
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
273-
go.opentelemetry.io/otel v1.38.0 // indirect
273+
go.opentelemetry.io/otel v1.39.0 // indirect
274274
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 // indirect
275275
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0 // indirect
276-
go.opentelemetry.io/otel/metric v1.38.0 // indirect
277-
go.opentelemetry.io/otel/sdk v1.38.0 // indirect
278-
go.opentelemetry.io/otel/trace v1.38.0 // indirect
276+
go.opentelemetry.io/otel/metric v1.39.0 // indirect
277+
go.opentelemetry.io/otel/sdk v1.39.0 // indirect
278+
go.opentelemetry.io/otel/trace v1.39.0 // indirect
279279
go.opentelemetry.io/proto/otlp v1.7.0 // indirect
280280
go.uber.org/atomic v1.11.0 // indirect
281281
go.uber.org/multierr v1.11.0 // indirect

go.sum

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY=
2-
cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw=
1+
cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4=
2+
cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4=
33
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
44
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
55
cloud.google.com/go v0.121.6 h1:waZiuajrI28iAf40cWgycWNgaXPO06dupuS+sgibK6c=
@@ -159,8 +159,8 @@ github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQ
159159
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw=
160160
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA=
161161
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
162-
github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f h1:Y8xYupdHxryycyPlc9Y+bSQAYZnetRJ70VMVKm5CKI0=
163-
github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f/go.mod h1:HlzOvOjVBOfTGSRXRyY0OiCS/3J1akRGQQpRO/7zyF4=
162+
github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 h1:6xNmx7iTtyBRev0+D/Tv1FZd4SCg8axKApyNyRsAt/w=
163+
github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5/go.mod h1:KdCmV+x/BuvyMxRnYBlmVaq4OLiKW6iRQfvC62cvdkI=
164164
github.com/cockroachdb/crlib v0.0.0-20241015224233-894974b3ad94 h1:bvJv505UUfjzbaIPdNS4AEkHreDqQk6yuNpsdRHpwFA=
165165
github.com/cockroachdb/crlib v0.0.0-20241015224233-894974b3ad94/go.mod h1:Gq51ZeKaFCXk6QwuGM0w1dnaOqc/F5zKT2zA9D6Xeac=
166166
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
@@ -266,12 +266,12 @@ github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4s
266266
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
267267
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
268268
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
269-
github.com/envoyproxy/go-control-plane v0.13.5-0.20251024222203-75eaa193e329 h1:K+fnvUM0VZ7ZFJf0n4L/BRlnsb9pL/GuDG6FqaH+PwM=
270-
github.com/envoyproxy/go-control-plane/envoy v1.35.0 h1:ixjkELDE+ru6idPxcHLj8LBVc2bFP7iBytj353BoHUo=
271-
github.com/envoyproxy/go-control-plane/envoy v1.35.0/go.mod h1:09qwbGVuSWWAyN5t/b3iyVfz5+z8QWGrzkoqm/8SbEs=
269+
github.com/envoyproxy/go-control-plane v0.14.0 h1:hbG2kr4RuFj222B6+7T83thSPqLjwBIfQawTkC++2HA=
270+
github.com/envoyproxy/go-control-plane/envoy v1.36.0 h1:yg/JjO5E7ubRyKX3m07GF3reDNEnfOboJ0QySbH736g=
271+
github.com/envoyproxy/go-control-plane/envoy v1.36.0/go.mod h1:ty89S1YCCVruQAm9OtKeEkQLTb+Lkz0k8v9W0Oxsv98=
272272
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
273-
github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=
274-
github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU=
273+
github.com/envoyproxy/protoc-gen-validate v1.3.0 h1:TvGH1wof4H33rezVKWSpqKz5NXWg5VPuZ0uONDT6eb4=
274+
github.com/envoyproxy/protoc-gen-validate v1.3.0/go.mod h1:HvYl7zwPa5mffgyeTUHA9zHIH36nmrm7oCbo4YKoSWA=
275275
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
276276
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
277277
github.com/ethereum/c-kzg-4844/v2 v2.1.5 h1:aVtoLK5xwJ6c5RiqO8g8ptJ5KU+2Hdquf6G3aXiHh5s=
@@ -820,8 +820,8 @@ github.com/onflow/flow-nft/lib/go/templates v1.3.0 h1:uGIBy4GEY6Z9hKP7sm5nA5kwvb
820820
github.com/onflow/flow-nft/lib/go/templates v1.3.0/go.mod h1:gVbb5fElaOwKhV5UEUjM+JQTjlsguHg2jwRupfM/nng=
821821
github.com/onflow/flow/protobuf/go/flow v0.4.19 h1:oYQoHWT/Iu441tX908qhCy7pCWAtwDspVrWbFGoTH1o=
822822
github.com/onflow/flow/protobuf/go/flow v0.4.19/go.mod h1:NA2pX2nw8zuaxfKphhKsk00kWLwfd+tv8mS23YXO4Sk=
823-
github.com/onflow/flowkit/v2 v2.10.2 h1:Rd4CtA5osdiYjvRdIzpflDnpST17QbkVANkQFjHDeMA=
824-
github.com/onflow/flowkit/v2 v2.10.2/go.mod h1:TsJ6WMt3gns6mrM4q16X/z/+VBSjHNNJJwOQmWMe+eM=
823+
github.com/onflow/flowkit/v2 v2.11.0 h1:/PilCUiaBPYv5jWmJ2ij2H5PtAehEke+r5e8mbvBpUw=
824+
github.com/onflow/flowkit/v2 v2.11.0/go.mod h1:lN8K+mJ1as/5CusbVgnIXXSocL9QqP0UQkNLVap3KR4=
825825
github.com/onflow/go-ethereum v1.15.10 h1:blZBeOLJDOVWqKuhkkMh6S2PKQAJvdgbvOL9ZNggFcU=
826826
github.com/onflow/go-ethereum v1.15.10/go.mod h1:t2nZJtwruVjA5u5yEK8InFzjImFLHrF7ak2bw3E4LDM=
827827
github.com/onflow/nft-storefront/lib/go/contracts v1.0.0 h1:sxyWLqGm/p4EKT6DUlQESDG1ZNMN9GjPCm1gTq7NGfc=
@@ -1154,26 +1154,26 @@ go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
11541154
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
11551155
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
11561156
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
1157-
go.opentelemetry.io/contrib/detectors/gcp v1.38.0 h1:ZoYbqX7OaA/TAikspPl3ozPI6iY6LiIY9I8cUfm+pJs=
1158-
go.opentelemetry.io/contrib/detectors/gcp v1.38.0/go.mod h1:SU+iU7nu5ud4oCb3LQOhIZ3nRLj6FNVrKgtflbaf2ts=
1157+
go.opentelemetry.io/contrib/detectors/gcp v1.39.0 h1:kWRNZMsfBHZ+uHjiH4y7Etn2FK26LAGkNFw7RHv1DhE=
1158+
go.opentelemetry.io/contrib/detectors/gcp v1.39.0/go.mod h1:t/OGqzHBa5v6RHZwrDBJ2OirWc+4q/w2fTbLZwAKjTk=
11591159
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ=
11601160
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo=
11611161
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=
11621162
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=
1163-
go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
1164-
go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
1163+
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
1164+
go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
11651165
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 h1:K0XaT3DwHAcV4nKLzcQvwAgSyisUghWoY20I7huthMk=
11661166
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0/go.mod h1:B5Ki776z/MBnVha1Nzwp5arlzBbE3+1jk+pGmaP5HME=
11671167
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0 h1:FFeLy03iVTXP6ffeN2iXrxfGsZGCjVx0/4KlizjyBwU=
11681168
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0/go.mod h1:TMu73/k1CP8nBUpDLc71Wj/Kf7ZS9FK5b53VapRsP9o=
1169-
go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA=
1170-
go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI=
1171-
go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E=
1172-
go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg=
1173-
go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM=
1174-
go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA=
1175-
go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
1176-
go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
1169+
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
1170+
go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=
1171+
go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=
1172+
go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=
1173+
go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=
1174+
go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=
1175+
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
1176+
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
11771177
go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os=
11781178
go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo=
11791179
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
@@ -1458,8 +1458,8 @@ google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8
14581458
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
14591459
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
14601460
google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
1461-
google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc=
1462-
google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U=
1461+
google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY=
1462+
google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
14631463
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
14641464
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
14651465
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=

internal/dependencymanager/dependencyinstaller.go

Lines changed: 84 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import (
2424
"encoding/hex"
2525
"fmt"
2626
"path/filepath"
27-
"strings"
2827

2928
"github.com/psiemens/sconfig"
3029

@@ -130,24 +129,25 @@ func (f *DependencyFlags) AddToCommand(cmd *cobra.Command) {
130129
}
131130

132131
type DependencyInstaller struct {
133-
Gateways map[string]gateway.Gateway
134-
Logger output.Logger
135-
State *flowkit.State
136-
SaveState bool
137-
TargetDir string
138-
SkipDeployments bool
139-
SkipAlias bool
140-
SkipUpdatePrompts bool
141-
Update bool
142-
DeploymentAccount string
143-
Name string
144-
logs categorizedLogs
145-
dependencies map[string]config.Dependency
146-
accountAliases map[string]map[string]flowsdk.Address // network -> account -> alias
147-
installCount int // Track number of dependencies installed
148-
pendingPrompts []pendingPrompt // Dependencies that need prompts after tree display
149-
prompter Prompter // Optional: for testing. If nil, uses real prompts
150-
blockHeightCache map[string]uint64 // Cache of latest block heights per network for consistent pinning
132+
Gateways map[string]gateway.Gateway
133+
Logger output.Logger
134+
State *flowkit.State
135+
SaveState bool
136+
TargetDir string
137+
SkipDeployments bool
138+
SkipAlias bool
139+
SkipUpdatePrompts bool
140+
Update bool
141+
DeploymentAccount string
142+
Name string
143+
logs categorizedLogs
144+
dependencies map[string]config.Dependency
145+
accountAliases map[string]map[string]flowsdk.Address // network -> account -> alias
146+
installCount int // Track number of dependencies installed
147+
pendingPrompts []pendingPrompt // Dependencies that need prompts after tree display
148+
prompter Prompter // Optional: for testing. If nil, uses real prompts
149+
blockHeightCache map[string]uint64 // Cache of latest block heights per network for consistent pinning
150+
minQueryableHeightCache map[string]uint64 // Cache of minimum queryable block heights per network (from CompatibleRange)
151151
}
152152

153153
type Prompter interface {
@@ -189,23 +189,24 @@ func NewDependencyInstaller(logger output.Logger, state *flowkit.State, saveStat
189189
}
190190

191191
return &DependencyInstaller{
192-
Gateways: gateways,
193-
Logger: logger,
194-
State: state,
195-
SaveState: saveState,
196-
TargetDir: targetDir,
197-
SkipDeployments: flags.skipDeployments,
198-
SkipAlias: flags.skipAlias,
199-
SkipUpdatePrompts: flags.skipUpdatePrompts,
200-
Update: flags.update,
201-
DeploymentAccount: flags.deploymentAccount,
202-
Name: flags.name,
203-
dependencies: make(map[string]config.Dependency),
204-
logs: categorizedLogs{},
205-
accountAliases: make(map[string]map[string]flowsdk.Address),
206-
pendingPrompts: make([]pendingPrompt, 0),
207-
prompter: prompter{},
208-
blockHeightCache: make(map[string]uint64),
192+
Gateways: gateways,
193+
Logger: logger,
194+
State: state,
195+
SaveState: saveState,
196+
TargetDir: targetDir,
197+
SkipDeployments: flags.skipDeployments,
198+
SkipAlias: flags.skipAlias,
199+
SkipUpdatePrompts: flags.skipUpdatePrompts,
200+
Update: flags.update,
201+
DeploymentAccount: flags.deploymentAccount,
202+
Name: flags.name,
203+
dependencies: make(map[string]config.Dependency),
204+
logs: categorizedLogs{},
205+
accountAliases: make(map[string]map[string]flowsdk.Address),
206+
pendingPrompts: make([]pendingPrompt, 0),
207+
prompter: prompter{},
208+
blockHeightCache: make(map[string]uint64),
209+
minQueryableHeightCache: make(map[string]uint64),
209210
}, nil
210211
}
211212

@@ -461,6 +462,40 @@ func (di *DependencyInstaller) processDependency(dependency config.Dependency) e
461462
return di.processDependencies(dependency)
462463
}
463464

465+
func (di *DependencyInstaller) getMinQueryableBlockHeight(network string) (uint64, error) {
466+
// Check cache first
467+
if height, ok := di.minQueryableHeightCache[network]; ok {
468+
return height, nil
469+
}
470+
471+
gw, ok := di.Gateways[network]
472+
if !ok {
473+
return 0, fmt.Errorf("gateway for network %s not found", network)
474+
}
475+
476+
ctx := context.Background()
477+
nodeVersionInfo, err := gw.GetNodeVersionInfo(ctx)
478+
if err != nil {
479+
return 0, fmt.Errorf("failed to get node version info for %s: %w", network, err)
480+
}
481+
482+
if nodeVersionInfo == nil {
483+
return 0, fmt.Errorf("node version info is nil for %s", network)
484+
}
485+
486+
// Get the minimum queryable block height from the compatible range
487+
var minHeight uint64
488+
if nodeVersionInfo.CompatibleRange != nil {
489+
minHeight = nodeVersionInfo.CompatibleRange.StartHeight
490+
}
491+
492+
// Cache the result (only if cache map is initialized)
493+
if di.minQueryableHeightCache != nil {
494+
di.minQueryableHeightCache[network] = minHeight
495+
}
496+
return minHeight, nil
497+
}
498+
464499
// getLatestBlockHeight returns the current block height for a given network.
465500
// Results are cached per network to ensure all dependencies in a single install
466501
// operation get pinned to the same block height for consistency.
@@ -609,33 +644,29 @@ func (di *DependencyInstaller) fetchDependenciesWithDepth(dependency config.Depe
609644
} else {
610645
// Use pinned block height for frozen dependencies
611646
blockHeight = existingDependency.BlockHeight
612-
}
613647

614-
accountContracts, err := di.getContractsAtBlockHeight(networkName, address, blockHeight)
615-
if err != nil {
616-
// If we get a spork-related error (block height too old), fall back to latest
617-
// This happens when flow.json has old block heights from before the current spork
618-
// We'll check the hash later - if it matches, we just update metadata; if not, normal update flow applies
619-
if strings.Contains(err.Error(), "spork root block height") || strings.Contains(err.Error(), "key not found") {
620-
di.Logger.Info(fmt.Sprintf(" %s Block height %d is from before current spork, fetching latest version", util.PrintEmoji("⚠️"), blockHeight))
648+
// Proactively check if this block height is within the node's compatible range
649+
minQueryableHeight, err := di.getMinQueryableBlockHeight(networkName)
650+
if err != nil {
651+
return fmt.Errorf("failed to check compatible block height range: %w", err)
652+
}
653+
654+
if blockHeight < minQueryableHeight {
655+
// Block height is before the minimum queryable height, need to use latest
621656
hadSporkRecovery = true
622-
// Get the current block height (will be cached from above for new deps)
623657
latestHeight, err := di.getLatestBlockHeight(networkName)
624658
if err != nil {
625659
return fmt.Errorf("failed to get latest block height: %w", err)
626660
}
627-
// Fetch at that specific block height
628-
accountContracts, err = di.getContractsAtBlockHeight(networkName, address, latestHeight)
629-
if err != nil {
630-
return fmt.Errorf("error fetching contracts: %w", err)
631-
}
632-
// Update blockHeight so it's used consistently for this dependency
633661
blockHeight = latestHeight
634-
} else {
635-
return fmt.Errorf("error fetching contracts: %w", err)
636662
}
637663
}
638664

665+
accountContracts, err := di.getContractsAtBlockHeight(networkName, address, blockHeight)
666+
if err != nil {
667+
return fmt.Errorf("error fetching contracts: %w", err)
668+
}
669+
639670
contract, ok := accountContracts[contractName]
640671
if !ok {
641672
return fmt.Errorf("contract %s not found at address %s", contractName, address.String())

0 commit comments

Comments
 (0)