From 18f47b7b6a074d4054d48bd64e60774b2b851db8 Mon Sep 17 00:00:00 2001 From: Elizabeth Engelman Date: Tue, 30 Jul 2019 07:52:36 -0500 Subject: [PATCH] Memoizing keccak hhash of address => transformer --- libraries/shared/watcher/storage_watcher.go | 40 ++++++++++------- .../shared/watcher/storage_watcher_test.go | 45 ++++++++++++++++++- 2 files changed, 67 insertions(+), 18 deletions(-) diff --git a/libraries/shared/watcher/storage_watcher.go b/libraries/shared/watcher/storage_watcher.go index 3fbe42e3..4ac2a3cf 100644 --- a/libraries/shared/watcher/storage_watcher.go +++ b/libraries/shared/watcher/storage_watcher.go @@ -33,22 +33,25 @@ import ( ) type StorageWatcher struct { - db *postgres.DB - diffSource string - StorageFetcher fetcher.IStorageFetcher - Queue storage.IStorageQueue - Transformers map[common.Address]transformer.StorageTransformer + db *postgres.DB + diffSource string + StorageFetcher fetcher.IStorageFetcher + Queue storage.IStorageQueue + Transformers map[common.Address]transformer.StorageTransformer + KeccakAddressTransformers map[common.Address]transformer.StorageTransformer // keccak hash of an address => transformer } func NewStorageWatcher(fetcher fetcher.IStorageFetcher, db *postgres.DB) StorageWatcher { - transformers := make(map[common.Address]transformer.StorageTransformer) queue := storage.NewStorageQueue(db) + transformers := make(map[common.Address]transformer.StorageTransformer) + keccakAddressTransformers := make(map[common.Address]transformer.StorageTransformer) return StorageWatcher{ - db: db, - diffSource: "csv", - StorageFetcher: fetcher, - Queue: queue, - Transformers: transformers, + db: db, + diffSource: "csv", + StorageFetcher: fetcher, + Queue: queue, + Transformers: transformers, + KeccakAddressTransformers: keccakAddressTransformers, } } @@ -83,11 +86,16 @@ func (storageWatcher StorageWatcher) getTransformer(contractAddress common.Addre storageTransformer, ok := storageWatcher.Transformers[contractAddress] return storageTransformer, ok } else if storageWatcher.diffSource == "geth" { - logrus.Debug("number of transformers", len(storageWatcher.Transformers)) - for address, t := range storageWatcher.Transformers { - keccakOfTransformerAddress := common.BytesToAddress(crypto.Keccak256(address[:])) - if keccakOfTransformerAddress == contractAddress { - return t, true + storageTransformer, ok := storageWatcher.KeccakAddressTransformers[contractAddress] + if ok { + return storageTransformer, ok + } else { + for address, transformer := range storageWatcher.Transformers { + keccakOfTransformerAddress := common.BytesToAddress(crypto.Keccak256(address[:])) + if keccakOfTransformerAddress == contractAddress { + storageWatcher.KeccakAddressTransformers[contractAddress] = transformer + return transformer, true + } } } diff --git a/libraries/shared/watcher/storage_watcher_test.go b/libraries/shared/watcher/storage_watcher_test.go index 3eaaf8ba..6e54fabb 100644 --- a/libraries/shared/watcher/storage_watcher_test.go +++ b/libraries/shared/watcher/storage_watcher_test.go @@ -56,12 +56,15 @@ var _ = Describe("Storage Watcher", func() { gethDiff utils.StorageDiff diffs chan utils.StorageDiff storageWatcher watcher.StorageWatcher + address common.Address + keccakOfAddress common.Address ) BeforeEach(func() { errs = make(chan error) diffs = make(chan utils.StorageDiff) - address := common.HexToAddress("0x0123456789abcdef") + address = common.HexToAddress("0x0123456789abcdef") + keccakOfAddress = common.BytesToAddress(crypto.Keccak256(address[:])) mockFetcher = mocks.NewMockStorageFetcher() mockQueue = &mocks.MockStorageQueue{} mockTransformer = &mocks.MockStorageTransformer{Address: address} @@ -75,7 +78,7 @@ var _ = Describe("Storage Watcher", func() { } gethDiff = utils.StorageDiff{ Id: 1338, - Contract: common.BytesToAddress(crypto.Keccak256(address[:])), + Contract: keccakOfAddress, BlockHash: common.HexToHash("0xfedcba9876543210"), BlockHeight: 0, StorageKey: common.HexToHash("0xabcdef1234567890"), @@ -208,6 +211,44 @@ var _ = Describe("Storage Watcher", func() { }).Should(ContainSubstring(fakes.FakeError.Error())) close(done) }) + + It("keeps track transformers by the keccak256 hash of their contract address ", func(done Done) { + go storageWatcher.Execute(diffs, errs, time.Hour) + + m := make(map[common.Address]transformer.StorageTransformer) + m[keccakOfAddress] = mockTransformer + + Eventually(func() map[common.Address]transformer.StorageTransformer { + return storageWatcher.KeccakAddressTransformers + }).Should(Equal(m)) + + close(done) + }) + + It("gets the transformer from the known keccak address map first", func(done Done) { + anotherAddress := common.HexToAddress("0xafakeaddress") + anotherTransformer := &mocks.MockStorageTransformer{Address: anotherAddress} + keccakOfAnotherAddress := common.BytesToAddress(crypto.Keccak256(anotherAddress[:])) + + anotherGethDiff := utils.StorageDiff{ + Id: 1338, + Contract: keccakOfAnotherAddress, + BlockHash: common.HexToHash("0xfedcba9876543210"), + BlockHeight: 0, + StorageKey: common.HexToHash("0xabcdef1234567890"), + StorageValue: common.HexToHash("0x9876543210abcdef"), + } + mockFetcher.DiffsToReturn = []utils.StorageDiff{anotherGethDiff} + storageWatcher.KeccakAddressTransformers[keccakOfAnotherAddress] = anotherTransformer + + go storageWatcher.Execute(diffs, errs, time.Hour) + + Eventually(func() utils.StorageDiff { + return anotherTransformer.PassedDiff + }).Should(Equal(anotherGethDiff)) + + close(done) + }) }) })