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  }