Skip to content

Commit 5e366fb

Browse files
committed
Make top level box reference resolution for app id=0 case consistent with txn.Access.Box.
1 parent 1a34a53 commit 5e366fb

File tree

3 files changed

+170
-2
lines changed

3 files changed

+170
-2
lines changed

api/converter_utils.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,13 @@ func signedTxnWithAdToTransaction(stxn *sdk.SignedTxnWithAD, extra rowData) (gen
488488
for _, v := range stxn.Txn.BoxReferences {
489489
var appID uint64
490490
if v.ForeignAppIdx == 0 {
491-
appID = 0
491+
// indicates this application, resolve app id
492+
if stxn.Txn.ApplicationID == 0 {
493+
// Use applyData.ApplicationID if Txn.ApplicationID is 0 (creation case)
494+
appID = uint64(stxn.ApplyData.ApplicationID)
495+
} else {
496+
appID = uint64(stxn.Txn.ApplicationID)
497+
}
492498
} else if int(v.ForeignAppIdx-1) < len(stxn.Txn.ForeignApps) {
493499
// Indexes are 1-based, so we subtract 1
494500
appID = uint64(stxn.Txn.ForeignApps[v.ForeignAppIdx-1])
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"application-transaction":{"access":[],"accounts":[],"application-args":["Y3JlYXRl","Ym94MQ==","Y3JlYXRl","YmFzZTY0"],"application-id":1002,"box-references":[{"app":0,"name":"Ym94MQ=="},{"app":1200,"name":"YmFzZTY0"}],"foreign-apps":[1200],"foreign-assets":[],"global-state-schema":{"num-byte-slice":0,"num-uint":0},"local-state-schema":{"num-byte-slice":0,"num-uint":0},"on-completion":"noop","reject-version":5},"close-rewards":0,"closing-amount":0,"confirmed-round":1,"fee":1000,"first-valid":9,"genesis-hash":"LYaCzCzg4CUP8HEyVJUp/vCIIMsAYM/JnxPLFInnEOA=","id":"5GCQ7BZSPENOWZBQ237FC6P25CJFE43X2WP3A5YTISDEK57ST3EQ","intra-round-offset":2,"last-valid":1009,"note":"oXE7HicX+GI=","receiver-rewards":0,"round-time":1751330221,"sender":"IKIIR47PIMJA6F3N2OWMV6KGFJOUM3VRH5VJUBQU45XUNIWILAZLXBUPGI","sender-rewards":0,"signature":{},"tx-type":"appl"}
1+
{"application-transaction":{"access":[],"accounts":[],"application-args":["Y3JlYXRl","Ym94MQ==","Y3JlYXRl","YmFzZTY0"],"application-id":1002,"box-references":[{"app":1002,"name":"Ym94MQ=="},{"app":1200,"name":"YmFzZTY0"}],"foreign-apps":[1200],"foreign-assets":[],"global-state-schema":{"num-byte-slice":0,"num-uint":0},"local-state-schema":{"num-byte-slice":0,"num-uint":0},"on-completion":"noop","reject-version":5},"close-rewards":0,"closing-amount":0,"confirmed-round":1,"fee":1000,"first-valid":9,"genesis-hash":"LYaCzCzg4CUP8HEyVJUp/vCIIMsAYM/JnxPLFInnEOA=","id":"5GCQ7BZSPENOWZBQ237FC6P25CJFE43X2WP3A5YTISDEK57ST3EQ","intra-round-offset":2,"last-valid":1009,"note":"oXE7HicX+GI=","receiver-rewards":0,"round-time":1751330221,"sender":"IKIIR47PIMJA6F3N2OWMV6KGFJOUM3VRH5VJUBQU45XUNIWILAZLXBUPGI","sender-rewards":0,"signature":{},"tx-type":"appl"}

api/util_test.go

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,4 +672,166 @@ func TestTxnAccessConversion(t *testing.T) {
672672
// Ensure holding is nil
673673
assert.Nil(t, boxItem.Holding)
674674
})
675+
676+
t.Run("BoxReferences Conversion - ForeignAppIdx 0", func(t *testing.T) {
677+
// Test conversion of stxn.Txn.BoxReferences with ForeignAppIdx: 0
678+
sender := makeAddress(12)
679+
boxName := []byte("test-box")
680+
txn := sdk.Transaction{
681+
Type: sdk.ApplicationCallTx,
682+
Header: sdk.Header{
683+
Sender: sender,
684+
Fee: sdk.MicroAlgos(1000),
685+
FirstValid: 1000,
686+
LastValid: 2000,
687+
},
688+
ApplicationFields: sdk.ApplicationFields{
689+
ApplicationCallTxnFields: sdk.ApplicationCallTxnFields{
690+
ApplicationID: 555,
691+
BoxReferences: []sdk.BoxReference{
692+
{ForeignAppIdx: 0, Name: boxName}, // this app
693+
},
694+
},
695+
},
696+
}
697+
698+
stxn := &sdk.SignedTxnWithAD{
699+
SignedTxn: sdk.SignedTxn{
700+
Txn: txn,
701+
},
702+
}
703+
704+
result, err := signedTxnWithAdToTransaction(stxn, extra)
705+
require.NoError(t, err)
706+
707+
require.NotNil(t, result.ApplicationTransaction)
708+
require.NotNil(t, result.ApplicationTransaction.BoxReferences)
709+
require.Equal(t, 1, len(*result.ApplicationTransaction.BoxReferences))
710+
711+
boxRef := (*result.ApplicationTransaction.BoxReferences)[0]
712+
assert.Equal(t, uint64(555), boxRef.App) // Should resolve to ApplicationID
713+
assert.Equal(t, boxName, boxRef.Name)
714+
})
715+
716+
t.Run("BoxReferences Conversion - App Creation", func(t *testing.T) {
717+
// Test conversion during app creation (ApplicationID = 0, ForeignAppIdx = 0)
718+
sender := makeAddress(13)
719+
boxName := []byte("creation-box")
720+
txn := sdk.Transaction{
721+
Type: sdk.ApplicationCallTx,
722+
Header: sdk.Header{
723+
Sender: sender,
724+
Fee: sdk.MicroAlgos(1000),
725+
FirstValid: 1000,
726+
LastValid: 2000,
727+
},
728+
ApplicationFields: sdk.ApplicationFields{
729+
ApplicationCallTxnFields: sdk.ApplicationCallTxnFields{
730+
ApplicationID: 0, // App creation
731+
BoxReferences: []sdk.BoxReference{
732+
{ForeignAppIdx: 0, Name: boxName}, // this app during creation
733+
},
734+
},
735+
},
736+
}
737+
738+
stxn := &sdk.SignedTxnWithAD{
739+
SignedTxn: sdk.SignedTxn{
740+
Txn: txn,
741+
},
742+
ApplyData: sdk.ApplyData{
743+
ApplicationID: 999, // Created app ID from ApplyData
744+
},
745+
}
746+
747+
result, err := signedTxnWithAdToTransaction(stxn, extra)
748+
require.NoError(t, err)
749+
750+
require.NotNil(t, result.ApplicationTransaction)
751+
require.NotNil(t, result.ApplicationTransaction.BoxReferences)
752+
require.Equal(t, 1, len(*result.ApplicationTransaction.BoxReferences))
753+
754+
boxRef := (*result.ApplicationTransaction.BoxReferences)[0]
755+
assert.Equal(t, uint64(999), boxRef.App) // Should resolve to ApplyData.ApplicationID
756+
assert.Equal(t, boxName, boxRef.Name)
757+
})
758+
759+
t.Run("BoxReferences Conversion - Valid ForeignAppIdx", func(t *testing.T) {
760+
// Test conversion with valid ForeignAppIdx reference
761+
sender := makeAddress(14)
762+
boxName := []byte("foreign-box")
763+
txn := sdk.Transaction{
764+
Type: sdk.ApplicationCallTx,
765+
Header: sdk.Header{
766+
Sender: sender,
767+
Fee: sdk.MicroAlgos(1000),
768+
FirstValid: 1000,
769+
LastValid: 2000,
770+
},
771+
ApplicationFields: sdk.ApplicationFields{
772+
ApplicationCallTxnFields: sdk.ApplicationCallTxnFields{
773+
ApplicationID: 123,
774+
ForeignApps: []sdk.AppIndex{777},
775+
BoxReferences: []sdk.BoxReference{
776+
{ForeignAppIdx: 1, Name: boxName}, // references ForeignApps[0]
777+
},
778+
},
779+
},
780+
}
781+
782+
stxn := &sdk.SignedTxnWithAD{
783+
SignedTxn: sdk.SignedTxn{
784+
Txn: txn,
785+
},
786+
}
787+
788+
result, err := signedTxnWithAdToTransaction(stxn, extra)
789+
require.NoError(t, err)
790+
791+
require.NotNil(t, result.ApplicationTransaction)
792+
require.NotNil(t, result.ApplicationTransaction.BoxReferences)
793+
require.Equal(t, 1, len(*result.ApplicationTransaction.BoxReferences))
794+
795+
boxRef := (*result.ApplicationTransaction.BoxReferences)[0]
796+
assert.Equal(t, uint64(777), boxRef.App) // Should resolve to ForeignApps[0]
797+
assert.Equal(t, boxName, boxRef.Name)
798+
})
799+
800+
t.Run("BoxReferences Conversion - Invalid ForeignAppIdx", func(t *testing.T) {
801+
// Test conversion with invalid ForeignAppIdx (should be skipped due to continue)
802+
sender := makeAddress(15)
803+
boxName := []byte("invalid-box")
804+
txn := sdk.Transaction{
805+
Type: sdk.ApplicationCallTx,
806+
Header: sdk.Header{
807+
Sender: sender,
808+
Fee: sdk.MicroAlgos(1000),
809+
FirstValid: 1000,
810+
LastValid: 2000,
811+
},
812+
ApplicationFields: sdk.ApplicationFields{
813+
ApplicationCallTxnFields: sdk.ApplicationCallTxnFields{
814+
ApplicationID: 123,
815+
ForeignApps: []sdk.AppIndex{777},
816+
BoxReferences: []sdk.BoxReference{
817+
{ForeignAppIdx: 10, Name: boxName}, // invalid index
818+
},
819+
},
820+
},
821+
}
822+
823+
stxn := &sdk.SignedTxnWithAD{
824+
SignedTxn: sdk.SignedTxn{
825+
Txn: txn,
826+
},
827+
}
828+
829+
result, err := signedTxnWithAdToTransaction(stxn, extra)
830+
require.NoError(t, err)
831+
832+
require.NotNil(t, result.ApplicationTransaction)
833+
require.NotNil(t, result.ApplicationTransaction.BoxReferences)
834+
// Should have 0 items because the invalid reference was skipped via continue
835+
assert.Equal(t, 0, len(*result.ApplicationTransaction.BoxReferences))
836+
})
675837
}

0 commit comments

Comments
 (0)