github.com/datachainlab/burrow@v0.25.0/execution/state/accounts.go (about)

     1  package state
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/hyperledger/burrow/acm"
     7  	"github.com/hyperledger/burrow/acm/acmstate"
     8  	"github.com/hyperledger/burrow/binary"
     9  	"github.com/hyperledger/burrow/crypto"
    10  )
    11  
    12  // Returns nil if account does not exist with given address.
    13  func (s *ReadState) GetAccount(address crypto.Address) (*acm.Account, error) {
    14  	tree, err := s.Forest.Reader(keys.Account.Prefix())
    15  	if err != nil {
    16  		return nil, err
    17  	}
    18  	accBytes := tree.Get(keys.Account.KeyNoPrefix(address))
    19  	if accBytes == nil {
    20  		return nil, nil
    21  	}
    22  	return acm.Decode(accBytes)
    23  }
    24  
    25  func (ws *writeState) statsAddAccount(acc *acm.Account) {
    26  	if acc != nil {
    27  		if len(acc.Code) > 0 {
    28  			ws.accountStats.AccountsWithCode++
    29  		} else {
    30  			ws.accountStats.AccountsWithoutCode++
    31  		}
    32  	}
    33  }
    34  
    35  func (ws *writeState) statsRemoveAccount(acc *acm.Account) {
    36  	if acc != nil {
    37  		if len(acc.Code) > 0 {
    38  			ws.accountStats.AccountsWithCode--
    39  		} else {
    40  			ws.accountStats.AccountsWithoutCode--
    41  		}
    42  	}
    43  }
    44  
    45  func (ws *writeState) UpdateAccount(account *acm.Account) error {
    46  	if account == nil {
    47  		return fmt.Errorf("UpdateAccount passed nil account in State")
    48  	}
    49  	encodedAccount, err := account.Encode()
    50  	if err != nil {
    51  		return fmt.Errorf("UpdateAccount could not encode account: %v", err)
    52  	}
    53  	tree, err := ws.forest.Writer(keys.Account.Prefix())
    54  	if err != nil {
    55  		return err
    56  	}
    57  	updated := tree.Set(keys.Account.KeyNoPrefix(account.Address), encodedAccount)
    58  	if updated {
    59  		ws.statsAddAccount(account)
    60  	}
    61  	return nil
    62  }
    63  
    64  func (ws *writeState) RemoveAccount(address crypto.Address) error {
    65  	tree, err := ws.forest.Writer(keys.Account.Prefix())
    66  	if err != nil {
    67  		return err
    68  	}
    69  	accBytes, deleted := tree.Delete(keys.Account.KeyNoPrefix(address))
    70  	if deleted {
    71  		acc, err := acm.Decode(accBytes)
    72  		if err != nil {
    73  			return err
    74  		}
    75  		ws.statsRemoveAccount(acc)
    76  		// Delete storage associated with account too
    77  		_, err = ws.forest.Delete(keys.Storage.Key(address))
    78  		if err != nil {
    79  			return err
    80  		}
    81  	}
    82  	return nil
    83  }
    84  
    85  func (s *ReadState) IterateAccounts(consumer func(*acm.Account) error) error {
    86  	tree, err := s.Forest.Reader(keys.Account.Prefix())
    87  	if err != nil {
    88  		return err
    89  	}
    90  	return tree.Iterate(nil, nil, true, func(key []byte, value []byte) error {
    91  		account, err := acm.Decode(value)
    92  		if err != nil {
    93  			return fmt.Errorf("IterateAccounts could not decode account: %v", err)
    94  		}
    95  		return consumer(account)
    96  	})
    97  }
    98  
    99  func (s *State) GetAccountStats() acmstate.AccountStats {
   100  	return s.writeState.accountStats
   101  }
   102  
   103  // Storage
   104  
   105  func (s *ReadState) GetStorage(address crypto.Address, key binary.Word256) (binary.Word256, error) {
   106  	keyFormat := keys.Storage.Fix(address)
   107  	tree, err := s.Forest.Reader(keyFormat.Prefix())
   108  	if err != nil {
   109  		return binary.Zero256, err
   110  	}
   111  	return binary.LeftPadWord256(tree.Get(keyFormat.KeyNoPrefix(key))), nil
   112  }
   113  
   114  func (ws *writeState) SetStorage(address crypto.Address, key, value binary.Word256) error {
   115  	keyFormat := keys.Storage.Fix(address)
   116  	tree, err := ws.forest.Writer(keyFormat.Prefix())
   117  	if err != nil {
   118  		return err
   119  	}
   120  	if value == binary.Zero256 {
   121  		tree.Delete(keyFormat.KeyNoPrefix(key))
   122  	} else {
   123  		tree.Set(keyFormat.KeyNoPrefix(key), value.Bytes())
   124  	}
   125  	return nil
   126  }
   127  
   128  func (s *ReadState) IterateStorage(address crypto.Address, consumer func(key, value binary.Word256) error) error {
   129  	keyFormat := keys.Storage.Fix(address)
   130  	tree, err := s.Forest.Reader(keyFormat.Prefix())
   131  	if err != nil {
   132  		return err
   133  	}
   134  	return tree.Iterate(nil, nil, true,
   135  		func(key []byte, value []byte) error {
   136  
   137  			if len(key) != binary.Word256Length {
   138  				return fmt.Errorf("key '%X' stored for account %s is not a %v-byte word",
   139  					key, address, binary.Word256Length)
   140  			}
   141  			if len(value) != binary.Word256Length {
   142  				return fmt.Errorf("value '%X' stored for account %s is not a %v-byte word",
   143  					key, address, binary.Word256Length)
   144  			}
   145  			return consumer(binary.LeftPadWord256(key), binary.LeftPadWord256(value))
   146  		})
   147  }