You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A value whose type is declared inside a function can be written into realm state
successfully, but any later transaction that reads it aborts with unexpected type with id …. The write commits and the failure only surfaces on a subsequent
read, leaving the realm holding state it can no longer load.
Expected: both calls succeed, Read returns func-ok.
Actual:SetFunc succeeds; Read aborts:
VM panic: unexpected type with id gno.land/r/g1…/lt[gno.land/r/g1…/lt/lt.gno:5:1-8:2].ft
5:1-8:2 is the span of SetFunc — the ParentLoc baked into the local type's
TypeID.
Cause
saveNewPackageValuesAndTypes registers declared types by walking the package
block only (gnovm/pkg/gnolang/machine.go:905-918 @ 33763e8269):
ifbv, ok:=pv.Block.(*Block); ok {
for_, tv:=rangebv.Values {
iftvv, ok:=tv.V.(TypeValue); ok {
ifdt, ok:=tvv.Type.(*DeclaredType); ok&&dt.PkgPath==pv.PkgPath {
m.Store.SetType(dt)
}
}
}
}
A function-local *DeclaredType never appears in the package block, so it is
never SetType'd. Persisting a value of that type writes the TypeID into the
object image anyway; the next GetType(tid) finds nothing in cache or backend
and panics (store.go:793-796).
Nothing rejects the write at preprocess or commit time, so the corruption is
silent until read.
Scope
Not a regression; reproduces at 33763e8269 and at 7547806.
Verified via an interface-typed package var. Any escape route that lands the
value in persisted realm state should behave the same, though I only tested
this one.
Values that never leave the transaction are unaffected.
Summary
A value whose type is declared inside a function can be written into realm state
successfully, but any later transaction that reads it aborts with
unexpected type with id …. The write commits and the failure only surfaces on a subsequentread, leaving the realm holding state it can no longer load.
Verified at master
33763e8269.Reproducer
Drop into
gno.land/pkg/integration/testdata/:Expected: both calls succeed,
Readreturnsfunc-ok.Actual:
SetFuncsucceeds;Readaborts:5:1-8:2is the span ofSetFunc— theParentLocbaked into the local type'sTypeID.
Cause
saveNewPackageValuesAndTypesregisters declared types by walking the packageblock only (
gnovm/pkg/gnolang/machine.go:905-918@33763e8269):A function-local
*DeclaredTypenever appears in the package block, so it isnever
SetType'd. Persisting a value of that type writes the TypeID into theobject image anyway; the next
GetType(tid)finds nothing in cache or backendand panics (
store.go:793-796).Nothing rejects the write at preprocess or commit time, so the corruption is
silent until read.
Scope
33763e8269and at7547806.value in persisted realm state should behave the same, though I only tested
this one.
typedeclarations in nested blocks, which widens the set ofcode shapes that can reach this, but is not the cause — the reproducer uses a
plain function-body declaration that already compiles on master.