github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/acm/acmstate/state.go (about)

     1  package acmstate
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/hyperledger/burrow/acm"
     7  	"github.com/hyperledger/burrow/binary"
     8  	"github.com/hyperledger/burrow/crypto"
     9  	"golang.org/x/crypto/sha3"
    10  
    11  	"github.com/hyperledger/burrow/permission"
    12  	"github.com/tmthrgd/go-hex"
    13  )
    14  
    15  // MetadataHash is the keccak hash for the metadata. This is to make the metadata content-addressed
    16  type MetadataHash [32]byte
    17  
    18  func (h *MetadataHash) Bytes() []byte {
    19  	b := make([]byte, 32)
    20  	copy(b, h[:])
    21  	return b
    22  }
    23  
    24  func (ch *MetadataHash) UnmarshalText(hexBytes []byte) error {
    25  	bs, err := hex.DecodeString(string(hexBytes))
    26  	if err != nil {
    27  		return err
    28  	}
    29  	copy(ch[:], bs)
    30  	return nil
    31  }
    32  
    33  func (ch MetadataHash) MarshalText() ([]byte, error) {
    34  	return []byte(ch.String()), nil
    35  }
    36  
    37  func (ch MetadataHash) String() string {
    38  	return hex.EncodeUpperToString(ch[:])
    39  }
    40  
    41  func GetMetadataHash(metadata string) (metahash MetadataHash) {
    42  	hash := sha3.NewLegacyKeccak256()
    43  	hash.Write([]byte(metadata))
    44  	copy(metahash[:], hash.Sum(nil))
    45  	return
    46  }
    47  
    48  // CodeHash is the keccak hash for the code for an account. This is used for the EVM CODEHASH opcode, and to find the
    49  // correct Metadata for a contract
    50  type CodeHash [32]byte
    51  
    52  func (h *CodeHash) Bytes() []byte {
    53  	b := make([]byte, 32)
    54  	copy(b, h[:])
    55  	return b
    56  }
    57  
    58  func (ch *CodeHash) UnmarshalText(hexBytes []byte) error {
    59  	bs, err := hex.DecodeString(string(hexBytes))
    60  	if err != nil {
    61  		return err
    62  	}
    63  	copy(ch[:], bs)
    64  	return nil
    65  }
    66  
    67  func (ch CodeHash) MarshalText() ([]byte, error) {
    68  	return []byte(ch.String()), nil
    69  }
    70  
    71  func (ch CodeHash) String() string {
    72  	return hex.EncodeUpperToString(ch[:])
    73  }
    74  
    75  type AccountGetter interface {
    76  	// Get an account by its address return nil if it does not exist (which should not be an error)
    77  	GetAccount(address crypto.Address) (*acm.Account, error)
    78  }
    79  
    80  type AccountIterable interface {
    81  	// Iterates through accounts calling passed function once per account, if the consumer
    82  	// returns true the iteration breaks and returns true to indicate it iteration
    83  	// was escaped
    84  	IterateAccounts(consumer func(*acm.Account) error) (err error)
    85  }
    86  
    87  type AccountUpdater interface {
    88  	// Updates the fields of updatedAccount by address, creating the account
    89  	// if it does not exist
    90  	UpdateAccount(updatedAccount *acm.Account) error
    91  	// Remove the account at address
    92  	RemoveAccount(address crypto.Address) error
    93  }
    94  
    95  type StorageGetter interface {
    96  	// Retrieve a 32-byte value stored at key for the account at address, return Zero256 if key does not exist but
    97  	// error if address does not
    98  	GetStorage(address crypto.Address, key binary.Word256) (value []byte, err error)
    99  }
   100  
   101  type StorageSetter interface {
   102  	// Store a 32-byte value at key for the account at address, setting to Zero256 removes the key
   103  	SetStorage(address crypto.Address, key binary.Word256, value []byte) error
   104  }
   105  
   106  type StorageIterable interface {
   107  	// Iterates through the storage of account ad address calling the passed function once per account,
   108  	// if the iterator function returns true the iteration breaks and returns true to indicate it iteration
   109  	// was escaped
   110  	IterateStorage(address crypto.Address, consumer func(key binary.Word256, value []byte) error) (err error)
   111  }
   112  
   113  type MetadataReader interface {
   114  	// Get an Metadata by its hash. This is content-addressed
   115  	GetMetadata(metahash MetadataHash) (string, error)
   116  }
   117  
   118  type MetadataWriter interface {
   119  	// Set an Metadata according to it keccak-256 hash.
   120  	SetMetadata(metahash MetadataHash, metadata string) error
   121  }
   122  
   123  type AccountStats struct {
   124  	AccountsWithCode    uint64
   125  	AccountsWithoutCode uint64
   126  }
   127  
   128  type AccountStatsGetter interface {
   129  	GetAccountStats() AccountStats
   130  }
   131  
   132  // Compositions
   133  
   134  // Read-only account and storage state
   135  type Reader interface {
   136  	AccountGetter
   137  	StorageGetter
   138  }
   139  
   140  type Iterable interface {
   141  	AccountIterable
   142  	StorageIterable
   143  }
   144  
   145  // Read and list account and storage state
   146  type IterableReader interface {
   147  	Iterable
   148  	Reader
   149  }
   150  
   151  type IterableStatsReader interface {
   152  	Iterable
   153  	Reader
   154  	AccountStatsGetter
   155  }
   156  
   157  type Writer interface {
   158  	AccountUpdater
   159  	StorageSetter
   160  }
   161  
   162  // Read and write account and storage state
   163  type ReaderWriter interface {
   164  	Reader
   165  	Writer
   166  }
   167  
   168  type MetadataReaderWriter interface {
   169  	MetadataReader
   170  	MetadataWriter
   171  }
   172  
   173  type IterableReaderWriter interface {
   174  	Iterable
   175  	Reader
   176  	Writer
   177  }
   178  
   179  // Get global permissions from the account at GlobalPermissionsAddress
   180  func GlobalAccountPermissions(getter AccountGetter) (permission.AccountPermissions, error) {
   181  	acc, err := getter.GetAccount(acm.GlobalPermissionsAddress)
   182  	if err != nil {
   183  		return permission.AccountPermissions{}, err
   184  	}
   185  	if acc == nil {
   186  		return permission.AccountPermissions{}, fmt.Errorf("global permissions account is not defined but must be")
   187  	}
   188  	return acc.Permissions, nil
   189  }