multiple_psr.go 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. package mps
  2. import (
  3. "sync"
  4. "github.com/ethereum/go-ethereum/common"
  5. "github.com/ethereum/go-ethereum/core/privatecache"
  6. "github.com/ethereum/go-ethereum/core/rawdb"
  7. "github.com/ethereum/go-ethereum/core/state"
  8. "github.com/ethereum/go-ethereum/core/types"
  9. "github.com/ethereum/go-ethereum/ethdb"
  10. )
  11. var (
  12. // emptyRoot is the known root hash of an empty trie.
  13. emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
  14. )
  15. type StateRootProviderFunc func(isEIP158 bool) (common.Hash, error)
  16. // MultiplePrivateStateRepository manages a number of state DB objects
  17. // identified by their types.PrivateStateIdentifier. It also maintains a trie
  18. // of private states whose root hash is mapped with a block hash.
  19. type MultiplePrivateStateRepository struct {
  20. db ethdb.Database
  21. // trie of private states cache
  22. repoCache state.Database
  23. privateCacheProvider privatecache.Provider
  24. // the trie of private states
  25. // key - the private state identifier
  26. // value - the root hash of the private state
  27. trie state.Trie
  28. // mux protects concurrent access to managedStates map
  29. mux sync.Mutex
  30. // managed states map
  31. managedStates map[types.PrivateStateIdentifier]*managedState
  32. }
  33. func NewMultiplePrivateStateRepository(db ethdb.Database, cache state.Database, privateStatesTrieRoot common.Hash, privateCacheProvider privatecache.Provider) (*MultiplePrivateStateRepository, error) {
  34. tr, err := cache.OpenTrie(privateStatesTrieRoot)
  35. if err != nil {
  36. return nil, err
  37. }
  38. repo := &MultiplePrivateStateRepository{
  39. db: db,
  40. repoCache: cache,
  41. privateCacheProvider: privateCacheProvider,
  42. trie: tr,
  43. managedStates: make(map[types.PrivateStateIdentifier]*managedState),
  44. }
  45. return repo, nil
  46. }
  47. // A managed state is a pair of stateDb and it's corresponding stateCache objects
  48. // Although right now we may not need a separate stateCache it may be useful if we'll do multiple managed state commits in parallel
  49. type managedState struct {
  50. stateDb *state.StateDB
  51. stateCache state.Database
  52. privateCacheProvider privatecache.Provider
  53. stateRootProviderFunc StateRootProviderFunc
  54. }
  55. func (ms *managedState) Copy() *managedState {
  56. copy := &managedState{
  57. stateDb: ms.stateDb.Copy(),
  58. stateCache: ms.stateCache,
  59. privateCacheProvider: ms.privateCacheProvider,
  60. }
  61. copy.stateRootProviderFunc = copy.calPrivateStateRoot
  62. return copy
  63. }
  64. // calPrivateStateRoot is to return state root hash from the commit of a managedState identified by psi
  65. func (ms *managedState) calPrivateStateRoot(isEIP158 bool) (common.Hash, error) {
  66. privateRoot, err := ms.stateDb.Commit(isEIP158)
  67. if err != nil {
  68. return common.Hash{}, err
  69. }
  70. err = ms.privateCacheProvider.Commit(ms.stateCache, privateRoot)
  71. if err != nil {
  72. return common.Hash{}, err
  73. }
  74. return privateRoot, nil
  75. }
  76. func (mpsr *MultiplePrivateStateRepository) DefaultState() (*state.StateDB, error) {
  77. return mpsr.StatePSI(EmptyPrivateStateMetadata.ID)
  78. }
  79. func (mpsr *MultiplePrivateStateRepository) DefaultStateMetadata() *PrivateStateMetadata {
  80. return EmptyPrivateStateMetadata
  81. }
  82. func (mpsr *MultiplePrivateStateRepository) IsMPS() bool {
  83. return true
  84. }
  85. func (mpsr *MultiplePrivateStateRepository) PrivateStateRoot(psi types.PrivateStateIdentifier) (common.Hash, error) {
  86. privateStateRoot, err := mpsr.trie.TryGet([]byte(psi))
  87. if err != nil {
  88. return common.Hash{}, err
  89. }
  90. return common.BytesToHash(privateStateRoot), nil
  91. }
  92. func (mpsr *MultiplePrivateStateRepository) StatePSI(psi types.PrivateStateIdentifier) (*state.StateDB, error) {
  93. mpsr.mux.Lock()
  94. ms, found := mpsr.managedStates[psi]
  95. mpsr.mux.Unlock()
  96. if found {
  97. return ms.stateDb, nil
  98. }
  99. privateStateRoot, err := mpsr.trie.TryGet([]byte(psi))
  100. if err != nil {
  101. return nil, err
  102. }
  103. var stateCache state.Database
  104. var stateDB *state.StateDB
  105. if privateStateRoot == nil && psi != EmptyPrivateStateMetadata.ID {
  106. // this is the first time we are trying to use this private state so branch from the empty state
  107. emptyState, err := mpsr.DefaultState()
  108. if err != nil {
  109. return nil, err
  110. }
  111. mpsr.mux.Lock()
  112. ms := mpsr.managedStates[EmptyPrivateStateMetadata.ID]
  113. mpsr.mux.Unlock()
  114. stateDB = emptyState.Copy()
  115. stateCache = ms.stateCache
  116. } else {
  117. stateCache = mpsr.privateCacheProvider.GetCache()
  118. stateDB, err = state.New(common.BytesToHash(privateStateRoot), stateCache, nil)
  119. if err != nil {
  120. return nil, err
  121. }
  122. }
  123. mpsr.mux.Lock()
  124. defer mpsr.mux.Unlock()
  125. managedState := &managedState{
  126. stateCache: stateCache,
  127. privateCacheProvider: mpsr.privateCacheProvider,
  128. stateDb: stateDB,
  129. }
  130. managedState.stateRootProviderFunc = managedState.calPrivateStateRoot
  131. mpsr.managedStates[psi] = managedState
  132. return stateDB, nil
  133. }
  134. func (mpsr *MultiplePrivateStateRepository) Reset() error {
  135. mpsr.mux.Lock()
  136. defer mpsr.mux.Unlock()
  137. for psi, managedState := range mpsr.managedStates {
  138. root, err := mpsr.trie.TryGet([]byte(psi))
  139. if err != nil {
  140. return err
  141. }
  142. // if this was a newly created private state (branched from the empty state) - remove it from the managedStates map
  143. if root == nil {
  144. delete(mpsr.managedStates, psi)
  145. continue
  146. }
  147. err = managedState.stateDb.Reset(common.BytesToHash(root))
  148. if err != nil {
  149. return err
  150. }
  151. }
  152. return nil
  153. }
  154. // CommitAndWrite commits all private states, updates the trie of private states, writes to disk
  155. func (mpsr *MultiplePrivateStateRepository) CommitAndWrite(isEIP158 bool, block *types.Block) error {
  156. mpsr.mux.Lock()
  157. defer mpsr.mux.Unlock()
  158. // commit each managed state
  159. for psi, managedState := range mpsr.managedStates {
  160. // calculate and commit state root if required
  161. privateRoot, err := managedState.stateRootProviderFunc(isEIP158)
  162. if err != nil {
  163. return err
  164. }
  165. // update the managed state root in the trie of state roots
  166. if err := mpsr.trie.TryUpdate([]byte(psi), privateRoot.Bytes()); err != nil {
  167. return err
  168. }
  169. }
  170. // commit the trie of states
  171. mtRoot, err := mpsr.trie.Commit(func(paths [][]byte, hexpath []byte, leaf []byte, parent common.Hash) error {
  172. privateRoot := common.BytesToHash(leaf)
  173. if privateRoot != emptyRoot {
  174. mpsr.privateCacheProvider.Reference(privateRoot, parent)
  175. }
  176. return nil
  177. })
  178. if err != nil {
  179. return err
  180. }
  181. err = rawdb.WritePrivateStatesTrieRoot(mpsr.db, block.Root(), mtRoot)
  182. if err != nil {
  183. return err
  184. }
  185. mpsr.privateCacheProvider.Commit(mpsr.repoCache, mtRoot)
  186. mpsr.privateCacheProvider.Reference(mtRoot, block.Root())
  187. return nil
  188. }
  189. // Commit commits all private states, updates the trie of private states only
  190. func (mpsr *MultiplePrivateStateRepository) Commit(isEIP158 bool, block *types.Block) error {
  191. mpsr.mux.Lock()
  192. defer mpsr.mux.Unlock()
  193. for psi, managedState := range mpsr.managedStates {
  194. // commit each managed state
  195. privateRoot, err := managedState.stateDb.Commit(isEIP158)
  196. if err != nil {
  197. return err
  198. }
  199. // update the managed state root in the trie of states
  200. err = mpsr.trie.TryUpdate([]byte(psi), privateRoot.Bytes())
  201. if err != nil {
  202. return err
  203. }
  204. }
  205. // commit the trie of states
  206. _, err := mpsr.trie.Commit(func(paths [][]byte, hexpath []byte, leaf []byte, parent common.Hash) error {
  207. privateRoot := common.BytesToHash(leaf)
  208. if privateRoot != emptyRoot {
  209. mpsr.privateCacheProvider.Reference(privateRoot, parent)
  210. }
  211. return nil
  212. })
  213. if err != nil {
  214. return err
  215. }
  216. return err
  217. }
  218. func (mpsr *MultiplePrivateStateRepository) Copy() PrivateStateRepository {
  219. mpsr.mux.Lock()
  220. defer mpsr.mux.Unlock()
  221. managedStatesCopy := make(map[types.PrivateStateIdentifier]*managedState)
  222. for key, value := range mpsr.managedStates {
  223. managedStatesCopy[key] = value.Copy()
  224. }
  225. return &MultiplePrivateStateRepository{
  226. db: mpsr.db,
  227. repoCache: mpsr.repoCache,
  228. privateCacheProvider: mpsr.privateCacheProvider,
  229. trie: mpsr.repoCache.CopyTrie(mpsr.trie),
  230. managedStates: managedStatesCopy,
  231. }
  232. }
  233. // Given a slice of public receipts and an overlapping (smaller) slice of
  234. // private receipts, return a new slice where the default for each location is
  235. // the public receipt but we take the private receipt in each place we have
  236. // one.
  237. // Each entry for a private receipt will actually consist of a copy of a dummy auxiliary receipt,
  238. // which holds the real private receipts for each PSI under PSReceipts[].
  239. // Note that we also add a private receipt for the "empty" PSI.
  240. func (mpsr *MultiplePrivateStateRepository) MergeReceipts(pub, priv types.Receipts) types.Receipts {
  241. m := make(map[common.Hash]*types.Receipt)
  242. for _, receipt := range pub {
  243. m[receipt.TxHash] = receipt
  244. }
  245. for _, receipt := range priv {
  246. publicReceipt, found := m[receipt.TxHash]
  247. if !found {
  248. // this is a PMT receipt - no merging required as it already has the relevant PSReceipts set
  249. continue
  250. }
  251. publicReceipt.PSReceipts = make(map[types.PrivateStateIdentifier]*types.Receipt)
  252. publicReceipt.PSReceipts[EmptyPrivateStateMetadata.ID] = receipt
  253. for psi, psReceipt := range receipt.PSReceipts {
  254. publicReceipt.PSReceipts[psi] = psReceipt
  255. }
  256. }
  257. ret := make(types.Receipts, len(pub))
  258. for idx, pubReceipt := range pub {
  259. ret[idx] = m[pubReceipt.TxHash]
  260. }
  261. return ret
  262. }