github.com/koko1123/flow-go-1@v0.29.6/fvm/environment/accounts_status.go (about) 1 package environment 2 3 import ( 4 "encoding/binary" 5 "encoding/hex" 6 7 "github.com/onflow/atree" 8 9 "github.com/koko1123/flow-go-1/fvm/errors" 10 ) 11 12 const ( 13 flagSize = 1 14 storageUsedSize = 8 15 storageIndexSize = 8 16 publicKeyCountsSize = 8 17 18 accountStatusSize = flagSize + 19 storageUsedSize + 20 storageIndexSize + 21 publicKeyCountsSize 22 23 flagIndex = 0 24 storageUsedStartIndex = flagIndex + flagSize 25 storageIndexStartIndex = storageUsedStartIndex + storageUsedSize 26 publicKeyCountsStartIndex = storageIndexStartIndex + storageIndexSize 27 ) 28 29 // AccountStatus holds meta information about an account 30 // 31 // currently modelled as a byte array with on-demand encoding/decoding of sub arrays 32 // the first byte captures flags (e.g. frozen) 33 // the next 8 bytes (big-endian) captures storage used by an account 34 // the next 8 bytes (big-endian) captures the storage index of an account 35 // and the last 8 bytes (big-endian) captures the number of public keys stored on this account 36 type AccountStatus [accountStatusSize]byte 37 38 const ( 39 maskFrozen byte = 0b1000_0000 40 ) 41 42 // NewAccountStatus returns a new AccountStatus 43 // sets the storage index to the init value 44 func NewAccountStatus() *AccountStatus { 45 return &AccountStatus{ 46 0, // initial empty flags 47 0, 0, 0, 0, 0, 0, 0, 0, // init value for storage used 48 0, 0, 0, 0, 0, 0, 0, 1, // init value for storage index 49 0, 0, 0, 0, 0, 0, 0, 0, // init value for public key counts 50 } 51 } 52 53 // ToBytes converts AccountStatus to a byte slice 54 // 55 // this has been kept this way in case one day 56 // we decided to move on to use an struct to represent 57 // account status. 58 func (a *AccountStatus) ToBytes() []byte { 59 return a[:] 60 } 61 62 // AccountStatusFromBytes constructs an AccountStatus from the given byte slice 63 func AccountStatusFromBytes(inp []byte) (*AccountStatus, error) { 64 var as AccountStatus 65 if len(inp) != accountStatusSize { 66 return &as, errors.NewValueErrorf(hex.EncodeToString(inp), "invalid account status size") 67 } 68 copy(as[:], inp) 69 return &as, nil 70 } 71 72 // IsAccountFrozen returns true if account's frozen flag is set 73 func (a *AccountStatus) IsAccountFrozen() bool { 74 return a[flagIndex]&maskFrozen > 0 75 } 76 77 // SetFrozenFlag sets the frozen flag 78 func (a *AccountStatus) SetFrozenFlag(frozen bool) { 79 if frozen { 80 a[flagIndex] = a[flagIndex] | maskFrozen 81 return 82 } 83 a[flagIndex] = a[flagIndex] & (0xFF - maskFrozen) 84 } 85 86 // SetStorageUsed updates the storage used by the account 87 func (a *AccountStatus) SetStorageUsed(used uint64) { 88 binary.BigEndian.PutUint64(a[storageUsedStartIndex:storageUsedStartIndex+storageUsedSize], used) 89 } 90 91 // StorageUsed returns the storage used by the account 92 func (a *AccountStatus) StorageUsed() uint64 { 93 return binary.BigEndian.Uint64(a[storageUsedStartIndex : storageUsedStartIndex+storageUsedSize]) 94 } 95 96 // SetStorageIndex updates the storage index of the account 97 func (a *AccountStatus) SetStorageIndex(index atree.StorageIndex) { 98 copy(a[storageIndexStartIndex:storageIndexStartIndex+storageIndexSize], index[:storageIndexSize]) 99 } 100 101 // StorageIndex returns the storage index of the account 102 func (a *AccountStatus) StorageIndex() atree.StorageIndex { 103 var index atree.StorageIndex 104 copy(index[:], a[storageIndexStartIndex:storageIndexStartIndex+storageIndexSize]) 105 return index 106 } 107 108 // SetPublicKeyCount updates the public key count of the account 109 func (a *AccountStatus) SetPublicKeyCount(count uint64) { 110 binary.BigEndian.PutUint64(a[publicKeyCountsStartIndex:publicKeyCountsStartIndex+publicKeyCountsSize], count) 111 } 112 113 // PublicKeyCount returns the public key count of the account 114 func (a *AccountStatus) PublicKeyCount() uint64 { 115 return binary.BigEndian.Uint64(a[publicKeyCountsStartIndex : publicKeyCountsStartIndex+publicKeyCountsSize]) 116 }