-
Notifications
You must be signed in to change notification settings - Fork 491
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AVM: Allow app downgrades in old protocol versions #4086
Conversation
@@ -1090,7 +1093,6 @@ func initConsensusProtocols() { | |||
v31.LogicSigVersion = 6 | |||
v31.EnableInnerTransactionPooling = true | |||
v31.IsolateClearState = true | |||
v31.MinInnerApplVersion = 6 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
moving MinInnerApplVersion
back in protocols smells - my understanding is set of parameters in a protocol is fixed. It might be OK from a technical perspective, but looks really strange from the "protocol guarantees" and "specs" point of view.
so I suggest another fix for this specific problem: emulate the old behavior for pre v31 when MinInnerApplVersion
was introduced.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you suggesting that I detect the version (number?) and skip the downgrade check before v31? Or are you suggesting that I treat MinInnerApplyVersion=0 to mean that the downgrade check should not be done? Both seem like more complexity in the code. I don't think (a) is possible, and (b) seems like we're just admitting that the value exists before v31, but we are putting in the knowledge that it will start at 0 because that's how Go works.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or are you suggesting that I treat MinInnerApplyVersion=0 to mean that the downgrade check should not be done?
I suggest to do not change consensus params due to the concern above.
if proto.MinInnerApplVersion == 0 {
// preserve pre v32 behavior
if pv >= syncProgramsVersion && av < pv {
return fmt.Errorf("program version downgrade: %d < %d", av, pv)
}
} else if pav >= proto.MinInnerApplVersion && av < pav {
return fmt.Errorf("program version downgrade: %d < %d", av, pv)
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In your suggestion, MinInnerApplVersion does still exist on old protocol versions, but we've also introduced the convention that setting it to 0 means something very different that setting it to non-zero. I think that makes it harder to reason about the code.
I prefer configuration over code. By setting the value in the right place, more than 50% of this code is eliminated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you think of the protocol version as guaranteeing certain behavior as described in a spec, versus a set of specific parameter values in the code, I think it is OK to retroactively encode the behavior of a previous version with a new parameter variable that didn't exist back then. I assume we have done this kind of thing before?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, for example:
v24.MaxAppTotalProgramLen = 2048 // No effect until v28, when MaxAppProgramLen increased
v24.MaxAppSumKeyValueLens = 128 // Set here to have no effect until MaxAppBytesValueLen increases
// Intended to have no effect in v24 (it's set to accounts +
// asas + apps). In later vers, it allows increasing the
// individual limits while maintaining same max references.
v24.MaxAppTotalTxnReferences = 8
In a sense, it's what we do whenever we add an "Enable" value like:
// Enable AssetCloseAmount field
v25.EnableAssetCloseAmount = true
The default value, false, gets set on all old versions. It's just that in those cases we are happy with the Go default, so we don't go out of our way to say that we're adding that to all old versions. It would be strange to be ok with it when the value of 0 or false works for us, but to avoid it otherwise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found one example of retroactively initializing a new consensus parameter in #172 when introducing MaxTxGroupSize and setting it default to 1 (instead of 0)
https://github.com/algorand/go-algorand/pull/172/files#diff-fe44f09c4d5977b5f5eaea29170b6a0748819c9d02271746a20d81a5f3efca17
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that when the retroactive change is done to codify something that wasn't even a parameter (the txgroup size is a good example) it is very hard to argue against. That what I felt I was doing here. Previously, there was a hardcoded value "syncVersion" set to 6, and there was a test against it to decide if we should prevent downgrades. When we decided we wanted that to change, it seemed proper to move that into a consensus parameter, so it could change properly.
My mistake was missing that the fact that, after the change, the simpler test is now run on all updates, so the new parameter had to be set from the earliest point updates could occur, not just since the old "syncVersion".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So are you saying the syncVersion
/ ExtraProgramChecksVersion
appeared in the code with version v31 (with TEAL v6) and you just moved it into the params?
278b702
to
ff17369
Compare
Codecov Report
@@ Coverage Diff @@
## rel/beta #4086 +/- ##
============================================
- Coverage 54.53% 54.49% -0.05%
============================================
Files 391 391
Lines 48665 48665
============================================
- Hits 26541 26519 -22
- Misses 19896 19920 +24
+ Partials 2228 2226 -2
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I digged the history and indeed ExtraProgramChecksVersion = 6
appeared with TEALv6 and MinInnerApplVersion
value in the protocol. It is safe to proceed.
Added test for protocol version before inners were introduced to ensure downgrading is allowed then.