Skip to content
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: Version downgrade check ported to master #4093

Merged
merged 6 commits into from
Jun 8, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion config/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -910,6 +910,9 @@ func initConsensusProtocols() {
// Enable application support
v24.Application = true

// Although Inners were not allowed yet, this gates downgrade checks, which must be allowed
v24.MinInnerApplVersion = 6

// Enable rekeying
v24.SupportRekeying = true

Expand Down Expand Up @@ -1090,7 +1093,6 @@ func initConsensusProtocols() {
v31.LogicSigVersion = 6
v31.EnableInnerTransactionPooling = true
v31.IsolateClearState = true
v31.MinInnerApplVersion = 6

// stat proof key registration
v31.EnableStateProofKeyregCheck = true
Expand Down
6 changes: 3 additions & 3 deletions data/transactions/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -726,9 +726,9 @@ func ProgramVersion(bytecode []byte) (version uint64, length int, err error) {
// matching versions between approval and clearstate.
const syncProgramsVersion = 6

// CheckContractVersions ensures that for v6 and higher two programs are version
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jannotti see if this wording works or feel free to adjust inline on the branch.

// matched, and that they are not a downgrade. If proto.AllowV4InnerAppls, then
// no downgrades are allowed, regardless of version.
// CheckContractVersions ensures that for syncProgramsVersion and higher, two programs are version
// matched, and that they are not a downgrade. If either the approval or clear state program version is
// >= proto.MinInnerApplVersion, no downgrades are allowed.
func CheckContractVersions(approval []byte, clear []byte, previous basics.AppParams, proto *config.ConsensusParams) error {
av, _, err := ProgramVersion(approval)
if err != nil {
Expand Down
44 changes: 41 additions & 3 deletions ledger/internal/apptxn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1890,7 +1890,7 @@ func TestInnerAppVersionCalling(t *testing.T) {

genBalances, addrs, _ := ledgertesting.NewTestGenesis()

// 31 allowed inner appls. vFuture enables proto.AllowV4InnerAppls (presumed v33, below)
// 31 allowed inner appls. vFuture enables proto.MinInnerApplVersion (presumed v33, below)
testConsensusRange(t, 31, 0, func(t *testing.T, ver int) {
dl := NewDoubleLedger(t, genBalances, consensusByNumber[ver])
defer dl.Close()
Expand Down Expand Up @@ -1994,7 +1994,7 @@ itxn_submit`,
createAndOptin.ApplicationArgs = [][]byte{six.Program, six.Program}
dl.txn(&createAndOptin, "overspend") // passed the checks, but is an overspend
} else {
// after 32 proto.AllowV4InnerAppls should be in effect, so calls and optins to v5 are ok
// after 32 proto.MinInnerApplVersion should be in effect, so calls and optins to v5 are ok
dl.txn(&call, "overspend") // it tried to execute, but test doesn't bother funding
dl.txn(&optin, "overspend") // it tried to execute, but test doesn't bother funding
optin.ForeignApps[0] = v5withv3csp // but we can't optin to a v5 if it has an old csp
Expand Down Expand Up @@ -2070,6 +2070,10 @@ func TestAppDowngrade(t *testing.T) {
partitiontest.PartitionTest(t)
t.Parallel()

two, err := logic.AssembleStringWithVersion("int 1", 2)
require.NoError(t, err)
three, err := logic.AssembleStringWithVersion("int 1", 3)
require.NoError(t, err)
four, err := logic.AssembleStringWithVersion("int 1", 4)
require.NoError(t, err)
five, err := logic.AssembleStringWithVersion("int 1", 5)
Expand All @@ -2078,6 +2082,40 @@ func TestAppDowngrade(t *testing.T) {
require.NoError(t, err)

genBalances, addrs, _ := ledgertesting.NewTestGenesis()

// Confirm that in old protocol version, downgrade is legal
// Start at 28 because we want to v4 app to downgrade to v3
testConsensusRange(t, 28, 30, func(t *testing.T, ver int) {
dl := NewDoubleLedger(t, genBalances, consensusByNumber[ver])
defer dl.Close()

create := txntest.Txn{
Type: "appl",
Sender: addrs[0],
ApprovalProgram: four.Program,
ClearStateProgram: four.Program,
}

vb := dl.fullBlock(&create)
app := vb.Block().Payset[0].ApplicationID

update := txntest.Txn{
Type: "appl",
ApplicationID: app,
OnCompletion: transactions.UpdateApplicationOC,
Sender: addrs[0],
ApprovalProgram: three.Program,
ClearStateProgram: three.Program,
}

// No change - legal
dl.fullBlock(&update)

update.ApprovalProgram = two.Program
// Also legal, and let's check mismatched version while we're at it.
dl.fullBlock(&update)
})

testConsensusRange(t, 31, 0, func(t *testing.T, ver int) {
dl := NewDoubleLedger(t, genBalances, consensusByNumber[ver])
defer dl.Close()
Expand Down Expand Up @@ -2112,7 +2150,7 @@ func TestAppDowngrade(t *testing.T) {
update.ClearStateProgram = five.Program
dl.fullBlock(&update)

// Downgrade (allowed for pre 6 programs until AllowV4InnerAppls)
// Downgrade (allowed for pre 6 programs until MinInnerApplVersion)
update.ClearStateProgram = four.Program
if ver <= 32 {
dl.fullBlock(update.Noted("actually a repeat of first upgrade"))
Expand Down