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
Fix- extraProgramPages #2580
Fix- extraProgramPages #2580
Conversation
Codecov Report
@@ Coverage Diff @@
## master #2580 +/- ##
==========================================
+ Coverage 46.94% 46.97% +0.03%
==========================================
Files 346 348 +2
Lines 55697 55725 +28
==========================================
+ Hits 26147 26177 +30
Misses 26603 26603
+ Partials 2947 2945 -2
Continue to review full report at Codecov.
|
ledger/apply/application_test.go
Outdated
err = ApplicationCall(ac, h, &b, ad, &ep, txnCounter) | ||
a.NoError(err) |
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.
Why does this work? You are updating with a 6k program, under the old proto. That should fail. Am I misreading?
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.
this works because b is a mocked Balances obj and it actually invokes this mocked StatefulEval
go-algorand/ledger/apply/application_test.go
Line 189 in af3858c
func (b *testBalances) StatefulEval(params logic.EvalParams, aidx basics.AppIndex, program []byte) (passed bool, evalDelta basics.EvalDelta, err error) { |
since I wanted to test updateApplication() only, b.pass is set to true at line 1006.
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.
ApplicationCall should still have failed, I think, even before it got to StatefulEval(). Your extra program pages is 1 in params. But you are calling this with UpdateApplicationOC and a 6k approval program. Why does updateApplication allow such a big approval program?
I don't think we can trust these kinds of tests for actual transaction execution very much. We need to put them in e2e subs tests against a running network or we'll never have the level of confidence we need. There, we can try to update an app and then actually check to see that it's been changed.
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 see the bug. In the new code, you don't check the length at all in old versions. But you must check the length - you must maintain the same behavior in old versions. So the behaviour should be:
Old version: check against a single program page of space
New version: check against the extra pages specified in params
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'll add an e2e test.
do I need to add a check for the old version in updateApplication() though?
doesn't these checks,
go-algorand/data/transactions/transaction.go
Lines 405 to 414 in e3e4197
pages := int(1 + effectiveEPP) | |
if lap > pages*proto.MaxAppProgramLen { | |
return fmt.Errorf("approval program too long. max len %d bytes", pages*proto.MaxAppProgramLen) | |
} | |
if lcs > pages*proto.MaxAppProgramLen { | |
return fmt.Errorf("clear state program too long. max len %d bytes", pages*proto.MaxAppProgramLen) | |
} | |
if lap+lcs > pages*proto.MaxAppTotalProgramLen { | |
return fmt.Errorf("app programs too long. max total len %d bytes", pages*proto.MaxAppTotalProgramLen) | |
} |
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 you are right. I find it a bit confusing because in old code, a too big program is rejected in WellFormed, while in the new code, it's rejected in updateApplication. When just reading updateApplication, it appears we have no check at all unless proto.EnableExtraPagesOnAppUpdate
is true.
Could you add a comment in updateApplication explaining that WellFormed rejects all multipage program updates when proto.EnableExtraPagesOnAppUpdate
is false? Or else simply reject them here too, even though it's redundant.
ledger/apply/application_test.go
Outdated
|
||
b.pass = true | ||
err = ApplicationCall(ac, h, &b, ad, &ep, txnCounter) | ||
a.Contains(err.Error(), "updateApplication app programs too long") |
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.
We want to confirm that it IS possible to have a 3k approval program here. Currently, you can not update to 3k, even though your extra pages = 1 when you created it (which is what I think this is testing).
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.
this test is for validating this added check is actually invoked,
go-algorand/ledger/apply/application.go
Lines 203 to 209 in af3858c
if proto.EnableExPagesOnAppUpdate { | |
allowed := int(1+params.ExtraProgramPages) * proto.MaxAppProgramLen | |
actual := len(ac.ApprovalProgram) + len(ac.ClearStateProgram) | |
if actual > allowed { | |
return fmt.Errorf("updateApplication app programs too long, %d. max total len %d bytes", actual, allowed) | |
} | |
} |
But, yes, I need to add another test to validate that it is possible to have a 3K approval program.
ledger/apply/application_test.go
Outdated
appr := make([]byte, 6050, 6050) | ||
|
||
for i := range appr { | ||
appr[i] = 2 | ||
} |
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.
nit:
appr := make([]byte, 6050, 6050) | |
for i := range appr { | |
appr[i] = 2 | |
} | |
appr := bytes.Repeat([]byte{2}, 6050) |
But! it not even needed since b.pass = true
assumes logic.EvalStateful
not even called.
so this works and setting zero byte to version 4 not needed as well:
appr := make([]byte, 6050, 6050) | |
for i := range appr { | |
appr[i] = 2 | |
} | |
appr := make([]byte, 6050) |
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.
It's needed to validate this new check in updateApplication, https://github.com/shiqizng/go-algorand/blob/fix/exPages/ledger/apply/application.go#L208.
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.
the line you pointed is a size check and not eval call (it is mocked in this unit test)
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 get static check error from checkProgram if I set appr := make([]byte, 6050). check failed on ApprovalProgram: pc=702 static cost budget of 700 exceeded
. https://github.com/shiqizng/go-algorand/blob/fix/exPages/ledger/apply/application.go#L364
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.
then appr[0] = 4
is needed indeed
@@ -344,6 +344,7 @@ func (tx Transaction) WellFormed(spec SpecialAddresses, proto config.ConsensusPa | |||
} | |||
} | |||
|
|||
effectiveEPP := tx.ExtraProgramPages |
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.
call it maxExtraProgramPages
?
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 effectiveEPP is better because it doesn't always equal to maxExtraProgramPages. when ApplicationID=0, effectiveEPP = tx.ExtraProgramPages
}, | ||
}, | ||
spec: specialAddr, | ||
proto: curProto, |
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.
this test will fail after the protocol upgrade, use v28 instead?
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.
LGTM
Fix for updating an application with extra program pages
This PR contains patch proposed by @jeapostrophe that fixes issue 2431.