Upstream change
rainlanguage/rain.deploy#242 removes DeployCandidate.sourceCreationCode and
makes checkCandidatesAnchoredToSource resolve the candidate's own
snapshot.artifactPath through vm.getCode instead. The source operand now
comes from the compiler rather than from the declaration.
The removed field was one a consumer filled in. Pointing it at the same
generated constant as the record made the one check that catches a snapshot of
the wrong contract compare a value with itself — green for any candidate at all,
in CI and on the irreversible RainDeployBroadcast.run() path alike. That is
rainlanguage/rain.factory.deploy#34, which #242 closes.
This is a BREAKING change. This repo has two candidates: one migrates
mechanically, and one cannot be expressed under #242 as written.
BLOCKER: the log-tables candidate has no compiler artifact to anchor to
src/abstract/DecimalFloatDeploySuites.sol, logTablesCandidate() (lines
64-77):
artifactPath: "",
...
sourceCreationCode: LibDataContract.contractCreationCode(LibDecimalFloatDeploy.combinedTables())
There is no Solidity contract behind this suite. Its creation code is
LibDataContract's data-contract wrapper around the bytes
LibDecimalFloatDeploy.combinedTables() (src/lib/deploy/LibDecimalFloatDeploy.sol:59,
internal pure) concatenates out of src/generated/LogTables.pointers.sol. The
declaration's own doc comment says so, and says the artifact path is empty
"because there is no source file for an explorer to verify against".
After #242 the anchor runs vm.getCode(candidates[i].snapshot.artifactPath) over
every candidate, with NoDeployCandidates refusing a declaration that names
none and no way to spell an exemption. vm.getCode("") resolves to no artifact.
So this candidate does not merely lose a field — it fails the anchor, and it
fails it inside RainDeployBroadcast.run() before the broadcast, not only in CI.
This is an upstream gap rather than a local slip: #242's migration text assumes
every candidate's source is a compiler artifact, and this one legitimately is
not. Resolving it is a precondition for this repo's migration, not a detail of
it. It needs an answer in rainlanguage/rain.deploy#242 (or a follow-up there)
before the edits below are worth making. Directions, none of them chosen here:
- a documented way for a candidate to declare that its source is derived rather
than compiled, which the anchor honours without becoming an exemption a
consumer can spell for an ordinary contract;
- emitting a real Solidity artifact for the log tables so
artifactPath has
something to resolve to;
- keeping the log tables out of the candidate set entirely and anchoring them by
some other check.
raindex has the same problem from a different direction — see its issue, whose
route-processor candidate is a vendored bytecode constant with
artifactPath: "RouteProcessor4".
What migrates cleanly, once the blocker is answered
Current pin: "rain-deploy" = "0.1.10" (foundry.toml:80).
1. src/abstract/DecimalFloatDeploySuites.sol — the decimal-float candidate
- Line 100 — delete
sourceCreationCode: type(DecimalFloat).creationCode,
and the trailing comma on the snapshot: DeploySuite({...}) entry above it.
- Line 7 — delete
import {DecimalFloat} from "../concrete/DecimalFloat.sol";.
It becomes unused: line 100 is its only use in this file.
- Line 6 —
import {LibDataContract} from "rain-datacontract-0.1.9/src/lib/LibDataContract.sol";
becomes unused too, but only once the log-tables blocker above is resolved:
line 74 is its only use.
artifactPath at line 98 is "src/concrete/DecimalFloat.sol:DecimalFloat".
Checked against the tree: that file exists and declares contract DecimalFloat,
so it resolves and needs no correction.
The doc comment at lines 52-58 explains why sourceCreationCode is "that same
pure expression rather than a type(X).creationCode" and needs rewriting
whichever way the blocker is answered.
2. script/Build.sol
- Line 146 —
contracts[i].candidate.sourceCreationCode, becomes
vm.getCode(contracts[i].candidate.snapshot.artifactPath),. Note this is the
same call the blocker breaks: regenerateSnapshots writing the log-tables
snapshot cannot read it from an artifact that does not exist, so
script/Build.sol is blocked on the same answer.
- Line 34 — the
GeneratedContract doc comment names sourceCreationCode.
3. Version pin, when there is one to move to
Eight files spell the versioned remapping prefix rain-deploy-0.1.10/ and each
has to be rewritten together with foundry.toml and soldeer.lock:
src/abstract/RainDeploySuitesBase.sol (the re-export shim holding the one
local spelling of the package path, which the generated libs reach through a
relative import and so cannot be skipped)
script/Build.sol, script/Deploy.sol
test/src/abstract/DecimalFloatDeployChain.t.sol,
test/src/abstract/DecimalFloatDeploySnapshot.t.sol,
test/src/lib/deploy/LibDecimalFloatDeployCandidate.t.sol,
test/src/lib/deploy/LibDecimalFloatDeployProd.t.sol,
test/src/lib/deploy/LibDecimalFloatDeploy.t.sol
The version to bump to does not exist yet
rainlanguage/rain.deploy#242 is open, unmerged and unreleased. There is no
published rain-deploy version carrying this change, so this issue deliberately
names none. The bump target has to be filled in once #242 merges and a Soldeer
release is cut; until then this issue is the record of what the edit will be,
not a request to make it.
Not affected in this repo
Migration item 3 of #242 — "any consumer wrapper marked pure must become
view" — needs no edit here. This repo inherits RainDeployVerifySnapshot
without redeclaring testSnapshotMatchesSource or wrapping
checkCandidatesAnchoredToSource, so the mutability change lands entirely
inside the package.
Migration item 4 — no foundry.toml change is required, because vm.getCode
does not go through fs_permissions.
Upstream change
rainlanguage/rain.deploy#242 removes
DeployCandidate.sourceCreationCodeandmakes
checkCandidatesAnchoredToSourceresolve the candidate's ownsnapshot.artifactPaththroughvm.getCodeinstead. The source operand nowcomes from the compiler rather than from the declaration.
The removed field was one a consumer filled in. Pointing it at the same
generated constant as the record made the one check that catches a snapshot of
the wrong contract compare a value with itself — green for any candidate at all,
in CI and on the irreversible
RainDeployBroadcast.run()path alike. That israinlanguage/rain.factory.deploy#34, which #242 closes.
This is a BREAKING change. This repo has two candidates: one migrates
mechanically, and one cannot be expressed under #242 as written.
BLOCKER: the
log-tablescandidate has no compiler artifact to anchor tosrc/abstract/DecimalFloatDeploySuites.sol,logTablesCandidate()(lines64-77):
There is no Solidity contract behind this suite. Its creation code is
LibDataContract's data-contract wrapper around the bytesLibDecimalFloatDeploy.combinedTables()(src/lib/deploy/LibDecimalFloatDeploy.sol:59,internal pure) concatenates out ofsrc/generated/LogTables.pointers.sol. Thedeclaration's own doc comment says so, and says the artifact path is empty
"because there is no source file for an explorer to verify against".
After #242 the anchor runs
vm.getCode(candidates[i].snapshot.artifactPath)overevery candidate, with
NoDeployCandidatesrefusing a declaration that namesnone and no way to spell an exemption.
vm.getCode("")resolves to no artifact.So this candidate does not merely lose a field — it fails the anchor, and it
fails it inside
RainDeployBroadcast.run()before the broadcast, not only in CI.This is an upstream gap rather than a local slip: #242's migration text assumes
every candidate's source is a compiler artifact, and this one legitimately is
not. Resolving it is a precondition for this repo's migration, not a detail of
it. It needs an answer in rainlanguage/rain.deploy#242 (or a follow-up there)
before the edits below are worth making. Directions, none of them chosen here:
than compiled, which the anchor honours without becoming an exemption a
consumer can spell for an ordinary contract;
artifactPathhassomething to resolve to;
some other check.
raindexhas the same problem from a different direction — see its issue, whoseroute-processorcandidate is a vendored bytecode constant withartifactPath: "RouteProcessor4".What migrates cleanly, once the blocker is answered
Current pin:
"rain-deploy" = "0.1.10"(foundry.toml:80).1.
src/abstract/DecimalFloatDeploySuites.sol— thedecimal-floatcandidatesourceCreationCode: type(DecimalFloat).creationCode,and the trailing comma on the
snapshot: DeploySuite({...})entry above it.import {DecimalFloat} from "../concrete/DecimalFloat.sol";.It becomes unused: line 100 is its only use in this file.
import {LibDataContract} from "rain-datacontract-0.1.9/src/lib/LibDataContract.sol";becomes unused too, but only once the
log-tablesblocker above is resolved:line 74 is its only use.
artifactPathat line 98 is"src/concrete/DecimalFloat.sol:DecimalFloat".Checked against the tree: that file exists and declares
contract DecimalFloat,so it resolves and needs no correction.
The doc comment at lines 52-58 explains why
sourceCreationCodeis "that samepure expression rather than a
type(X).creationCode" and needs rewritingwhichever way the blocker is answered.
2.
script/Build.solcontracts[i].candidate.sourceCreationCode,becomesvm.getCode(contracts[i].candidate.snapshot.artifactPath),. Note this is thesame call the blocker breaks:
regenerateSnapshotswriting thelog-tablessnapshot cannot read it from an artifact that does not exist, so
script/Build.solis blocked on the same answer.GeneratedContractdoc comment namessourceCreationCode.3. Version pin, when there is one to move to
Eight files spell the versioned remapping prefix
rain-deploy-0.1.10/and eachhas to be rewritten together with
foundry.tomlandsoldeer.lock:src/abstract/RainDeploySuitesBase.sol(the re-export shim holding the onelocal spelling of the package path, which the generated libs reach through a
relative import and so cannot be skipped)
script/Build.sol,script/Deploy.soltest/src/abstract/DecimalFloatDeployChain.t.sol,test/src/abstract/DecimalFloatDeploySnapshot.t.sol,test/src/lib/deploy/LibDecimalFloatDeployCandidate.t.sol,test/src/lib/deploy/LibDecimalFloatDeployProd.t.sol,test/src/lib/deploy/LibDecimalFloatDeploy.t.solThe version to bump to does not exist yet
rainlanguage/rain.deploy#242 is open, unmerged and unreleased. There is no
published
rain-deployversion carrying this change, so this issue deliberatelynames none. The bump target has to be filled in once #242 merges and a Soldeer
release is cut; until then this issue is the record of what the edit will be,
not a request to make it.
Not affected in this repo
Migration item 3 of #242 — "any consumer wrapper marked
puremust becomeview" — needs no edit here. This repo inheritsRainDeployVerifySnapshotwithout redeclaring
testSnapshotMatchesSourceor wrappingcheckCandidatesAnchoredToSource, so the mutability change lands entirelyinside the package.
Migration item 4 — no
foundry.tomlchange is required, becausevm.getCodedoes not go through
fs_permissions.