@@ -44,17 +44,27 @@ import (
4444// [Header] or [Block] / [Body] is a non-nil `HPtr` or `BPtr` respectively. The
4545// latter guarantee ensures that hooks won't be called on nil-pointer receivers.
4646func RegisterExtras [
47- H any , HPtr interface {
48- HeaderHooks
49- * H
50- },
51- B any , BPtr interface {
52- BlockBodyPayload [BPtr ]
53- * B
54- },
47+ H any , HPtr HeaderHooksPointer [H ],
48+ B any , BPtr BlockBodyHooksPointer [B , BPtr ],
5549 SA any ,
5650]() ExtraPayloads [HPtr , BPtr , SA ] {
57- extra := ExtraPayloads [HPtr , BPtr , SA ]{
51+ payloads , ctors := payloadsAndConstructors [H , HPtr , B , BPtr , SA ]()
52+ registeredExtras .MustRegister (ctors )
53+ log .Info (
54+ "Registered core/types extras" ,
55+ "Header" , log .TypeOf (pseudo .Zero [HPtr ]().Value .Get ()),
56+ "Block/Body" , log .TypeOf (pseudo .Zero [BPtr ]().Value .Get ()),
57+ "StateAccount" , log .TypeOf (pseudo .Zero [SA ]().Value .Get ()),
58+ )
59+ return payloads
60+ }
61+
62+ func payloadsAndConstructors [
63+ H any , HPtr HeaderHooksPointer [H ],
64+ B any , BPtr BlockBodyHooksPointer [B , BPtr ],
65+ SA any ,
66+ ]() (ExtraPayloads [HPtr , BPtr , SA ], * extraConstructors ) {
67+ payloads := ExtraPayloads [HPtr , BPtr , SA ]{
5868 Header : pseudo .NewAccessor [* Header , HPtr ](
5969 (* Header ).extraPayload ,
6070 func (h * Header , t * pseudo.Type ) { h .extra = t },
@@ -72,7 +82,7 @@ func RegisterExtras[
7282 func (a StateOrSlimAccount , t * pseudo.Type ) { a .extra ().t = t },
7383 ),
7484 }
75- registeredExtras . MustRegister ( & extraConstructors {
85+ ctors := & extraConstructors {
7686 stateAccountType : func () string {
7787 var x SA
7888 return fmt .Sprintf ("%T" , x )
@@ -84,15 +94,40 @@ func RegisterExtras[
8494 newHeader : pseudo .NewConstructor [H ]().NewPointer , // i.e. non-nil HPtr
8595 newBlockOrBody : pseudo .NewConstructor [B ]().NewPointer , // i.e. non-nil BPtr
8696 newStateAccount : pseudo .NewConstructor [SA ]().Zero ,
87- hooks : extra ,
88- })
89- log .Info (
90- "Registered core/types extras" ,
91- "Header" , log .TypeOf (pseudo .Zero [HPtr ]().Value .Get ()),
92- "Block/Body" , log .TypeOf (pseudo .Zero [BPtr ]().Value .Get ()),
93- "StateAccount" , log .TypeOf (pseudo .Zero [SA ]().Value .Get ()),
94- )
95- return extra
97+ hooks : payloads ,
98+ }
99+ return payloads , ctors
100+ }
101+
102+ // WithTempRegisteredExtras temporarily registers `HPtr`, `BPtr`, and `SA` as if
103+ // calling [RegisterExtras] the same type parameters. The [ExtraPayloads] are
104+ // passed to `fn` instead of being returned. After `fn` returns, the
105+ // registration is returned to its former state, be that none or the types
106+ // originally passed to [RegisterExtras].
107+ //
108+ // This MUST NOT be used in a live chain. It is solely intended for off-chain
109+ // consumers that require access to extras.
110+ func WithTempRegisteredExtras [
111+ H any , B any , SA any ,
112+ HPtr HeaderHooksPointer [H ],
113+ BPtr BlockBodyHooksPointer [B , BPtr ],
114+ ](fn func (ExtraPayloads [HPtr , BPtr , SA ])) {
115+ payloads , ctors := payloadsAndConstructors [H , HPtr , B , BPtr , SA ]()
116+ registeredExtras .TempOverride (ctors , func () { fn (payloads ) })
117+ }
118+
119+ // A HeaderHooksPointer is a type constraint for an implementation of
120+ // [HeaderHooks] with a pointer receiver.
121+ type HeaderHooksPointer [H any ] interface {
122+ HeaderHooks
123+ * H
124+ }
125+
126+ // A BlockBodyHooksPointer is a type constraint for an implementation of
127+ // [BlockBodyPayload] with a pointer receiver.
128+ type BlockBodyHooksPointer [B any , Self any ] interface {
129+ BlockBodyPayload [Self ]
130+ * B
96131}
97132
98133// A BlockBodyPayload is an implementation of [BlockBodyHooks] that is also able
0 commit comments