github.com/koko1123/flow-go-1@v0.29.6/fvm/environment/account_freezer.go (about) 1 package environment 2 3 import ( 4 "fmt" 5 6 "github.com/onflow/cadence/runtime/common" 7 8 "github.com/koko1123/flow-go-1/fvm/errors" 9 "github.com/koko1123/flow-go-1/fvm/state" 10 "github.com/koko1123/flow-go-1/model/flow" 11 "github.com/koko1123/flow-go-1/module/trace" 12 ) 13 14 // AccountFreezer disables accounts. 15 // 16 // Note that scripts cannot freeze accounts, but must expose the API in 17 // compliance with the environment interface. 18 type AccountFreezer interface { 19 // Note that the script variant will return OperationNotSupportedError. 20 SetAccountFrozen(address common.Address, frozen bool) error 21 22 FrozenAccounts() []common.Address 23 24 Reset() 25 } 26 27 type ParseRestrictedAccountFreezer struct { 28 txnState *state.TransactionState 29 impl AccountFreezer 30 } 31 32 func NewParseRestrictedAccountFreezer( 33 txnState *state.TransactionState, 34 impl AccountFreezer, 35 ) AccountFreezer { 36 return ParseRestrictedAccountFreezer{ 37 txnState: txnState, 38 impl: impl, 39 } 40 } 41 42 func (freezer ParseRestrictedAccountFreezer) SetAccountFrozen( 43 address common.Address, 44 frozen bool, 45 ) error { 46 return parseRestrict2Arg( 47 freezer.txnState, 48 trace.FVMEnvSetAccountFrozen, 49 freezer.impl.SetAccountFrozen, 50 address, 51 frozen) 52 } 53 54 func (freezer ParseRestrictedAccountFreezer) FrozenAccounts() []common.Address { 55 return freezer.impl.FrozenAccounts() 56 } 57 58 func (freezer ParseRestrictedAccountFreezer) Reset() { 59 freezer.impl.Reset() 60 } 61 62 type NoAccountFreezer struct{} 63 64 func (NoAccountFreezer) FrozenAccounts() []common.Address { 65 return nil 66 } 67 68 func (NoAccountFreezer) SetAccountFrozen(_ common.Address, _ bool) error { 69 return errors.NewOperationNotSupportedError("SetAccountFrozen") 70 } 71 72 func (NoAccountFreezer) Reset() { 73 } 74 75 type accountFreezer struct { 76 serviceAddress flow.Address 77 78 accounts Accounts 79 transactionInfo TransactionInfo 80 81 frozenAccounts []common.Address 82 } 83 84 func NewAccountFreezer( 85 serviceAddress flow.Address, 86 accounts Accounts, 87 transactionInfo TransactionInfo, 88 ) *accountFreezer { 89 freezer := &accountFreezer{ 90 serviceAddress: serviceAddress, 91 accounts: accounts, 92 transactionInfo: transactionInfo, 93 } 94 freezer.Reset() 95 return freezer 96 } 97 98 func (freezer *accountFreezer) Reset() { 99 freezer.frozenAccounts = nil 100 } 101 102 func (freezer *accountFreezer) FrozenAccounts() []common.Address { 103 return freezer.frozenAccounts 104 } 105 106 func (freezer *accountFreezer) SetAccountFrozen( 107 address common.Address, 108 frozen bool, 109 ) error { 110 flowAddress := flow.Address(address) 111 112 if flowAddress == freezer.serviceAddress { 113 return fmt.Errorf( 114 "setting account frozen failed: %w", 115 errors.NewValueErrorf( 116 flowAddress.String(), 117 "cannot freeze service account")) 118 } 119 120 if !freezer.transactionInfo.IsServiceAccountAuthorizer() { 121 return fmt.Errorf( 122 "setting account frozen failed: %w", 123 errors.NewOperationAuthorizationErrorf( 124 "SetAccountFrozen", 125 "accounts can be frozen only by transactions authorized by "+ 126 "the service account")) 127 } 128 129 err := freezer.accounts.SetAccountFrozen(flowAddress, frozen) 130 if err != nil { 131 return fmt.Errorf("setting account frozen failed: %w", err) 132 } 133 134 if frozen { 135 freezer.frozenAccounts = append(freezer.frozenAccounts, address) 136 } 137 138 return nil 139 }