@@ -286,6 +286,11 @@ export type SnapRuntimeData = {
286286 * A mutex to prevent concurrent state updates.
287287 */
288288 stateMutex : Mutex ;
289+
290+ /**
291+ * A mutex to prevent concurrent state decryption.
292+ */
293+ getStateMutex : Mutex ;
289294} ;
290295
291296export type SnapError = {
@@ -2046,33 +2051,35 @@ export class SnapController extends BaseController<
20462051 */
20472052 async getSnapState ( snapId : SnapId , encrypted : boolean ) : Promise < Json > {
20482053 const runtime = this . #getRuntimeExpect( snapId ) ;
2049- const cachedState = encrypted ? runtime . state : runtime . unencryptedState ;
2054+ return await runtime . getStateMutex . runExclusive ( ( ) => {
2055+ const cachedState = encrypted ? runtime . state : runtime . unencryptedState ;
20502056
2051- if ( cachedState !== undefined ) {
2052- return cachedState ;
2053- }
2057+ if ( cachedState !== undefined ) {
2058+ return cachedState ;
2059+ }
20542060
2055- const state = encrypted
2056- ? this . state . snapStates [ snapId ]
2057- : this . state . unencryptedSnapStates [ snapId ] ;
2061+ const state = encrypted
2062+ ? this . state . snapStates [ snapId ]
2063+ : this . state . unencryptedSnapStates [ snapId ] ;
20582064
2059- if ( state === null || state === undefined ) {
2060- return null ;
2061- }
2065+ if ( state === null || state === undefined ) {
2066+ return null ;
2067+ }
20622068
2063- if ( ! encrypted ) {
2064- // For performance reasons, we do not validate that the state is JSON,
2065- // since we control serialization.
2066- const json = JSON . parse ( state ) ;
2067- runtime . unencryptedState = json ;
2069+ if ( ! encrypted ) {
2070+ // For performance reasons, we do not validate that the state is JSON,
2071+ // since we control serialization.
2072+ const json = JSON . parse ( state ) ;
2073+ runtime . unencryptedState = json ;
20682074
2069- return json ;
2070- }
2075+ return json ;
2076+ }
20712077
2072- const decrypted = await this . #decryptSnapState( snapId , state ) ;
2073- runtime . state = decrypted ;
2078+ const decrypted = await this . #decryptSnapState( snapId , state ) ;
2079+ runtime . state = decrypted ;
20742080
2075- return decrypted ;
2081+ return decrypted ;
2082+ } ) ;
20762083 }
20772084
20782085 /**
@@ -3968,6 +3975,7 @@ export class SnapController extends BaseController<
39683975 interpreter,
39693976 stopping : false ,
39703977 stateMutex : new Mutex ( ) ,
3978+ getStateMutex : new Mutex ( ) ,
39713979 } ) ;
39723980 }
39733981
0 commit comments