2019-10-24 16:35:39 +00:00
// VulcanizeDB
// Copyright © 2019 Vulcanize
2019-07-08 20:34:06 +00:00
2019-10-24 16:35:39 +00:00
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
2019-07-08 20:34:06 +00:00
package fetcher
import (
2019-07-29 19:15:33 +00:00
"fmt"
2019-09-30 17:34:43 +00:00
2019-11-04 20:50:10 +00:00
"github.com/ethereum/go-ethereum/common"
2019-07-08 20:34:06 +00:00
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/statediff"
2019-07-29 19:15:33 +00:00
"github.com/sirupsen/logrus"
2019-09-30 17:34:43 +00:00
2019-07-08 20:34:06 +00:00
"github.com/vulcanize/vulcanizedb/libraries/shared/storage/utils"
"github.com/vulcanize/vulcanizedb/libraries/shared/streamer"
)
2019-11-01 05:29:57 +00:00
const (
PayloadChanBufferSize = 20000 // the max eth sub buffer size
)
2019-10-18 16:16:19 +00:00
type GethRPCStorageFetcher struct {
2019-11-01 05:29:57 +00:00
StatediffPayloadChan chan statediff . Payload
2019-07-08 22:52:06 +00:00
streamer streamer . Streamer
2019-07-08 20:34:06 +00:00
}
2019-11-01 05:29:57 +00:00
func NewGethRPCStorageFetcher ( streamer streamer . Streamer ) GethRPCStorageFetcher {
2019-10-18 16:16:19 +00:00
return GethRPCStorageFetcher {
2019-11-01 05:29:57 +00:00
StatediffPayloadChan : make ( chan statediff . Payload , PayloadChanBufferSize ) ,
2019-07-08 22:52:06 +00:00
streamer : streamer ,
2019-07-08 20:34:06 +00:00
}
}
2019-10-31 16:04:53 +00:00
func ( fetcher GethRPCStorageFetcher ) FetchStorageDiffs ( out chan <- utils . StorageDiffInput , errs chan <- error ) {
2019-11-01 05:29:57 +00:00
ethStatediffPayloadChan := fetcher . StatediffPayloadChan
2019-07-29 19:15:33 +00:00
clientSubscription , clientSubErr := fetcher . streamer . Stream ( ethStatediffPayloadChan )
if clientSubErr != nil {
errs <- clientSubErr
2019-07-30 20:27:38 +00:00
panic ( fmt . Sprintf ( "Error creating a geth client subscription: %v" , clientSubErr ) )
2019-07-08 20:34:06 +00:00
}
2019-07-29 19:15:33 +00:00
logrus . Info ( "Successfully created a geth client subscription: " , clientSubscription )
2019-07-08 20:34:06 +00:00
2019-07-22 21:48:18 +00:00
for {
diff := <- ethStatediffPayloadChan
2019-07-29 19:15:33 +00:00
logrus . Trace ( "received a statediff" )
2019-07-08 20:34:06 +00:00
stateDiff := new ( statediff . StateDiff )
2019-07-29 19:15:33 +00:00
decodeErr := rlp . DecodeBytes ( diff . StateDiffRlp , stateDiff )
if decodeErr != nil {
logrus . Warn ( "Error decoding state diff into RLP: " , decodeErr )
errs <- decodeErr
2019-07-08 20:34:06 +00:00
}
2019-09-30 17:34:43 +00:00
accounts := utils . GetAccountsFromDiff ( * stateDiff )
2019-07-29 19:15:33 +00:00
logrus . Trace ( fmt . Sprintf ( "iterating through %d accounts on stateDiff for block %d" , len ( accounts ) , stateDiff . BlockNumber ) )
2019-07-08 20:34:06 +00:00
for _ , account := range accounts {
2019-11-04 20:50:10 +00:00
logrus . Trace ( fmt . Sprintf ( "iterating through %d Storage values on account with key %s" , len ( account . Storage ) , common . BytesToHash ( account . Key ) . Hex ( ) ) )
2019-07-08 20:34:06 +00:00
for _ , storage := range account . Storage {
2019-08-30 19:17:26 +00:00
diff , formatErr := utils . FromGethStateDiff ( account , stateDiff , storage )
2019-10-24 16:35:39 +00:00
if formatErr != nil {
2019-11-04 20:50:10 +00:00
logrus . Error ( "failed to format utils.StorageDiff from storage with key: " , common . BytesToHash ( storage . Key ) , "from account with key: " , common . BytesToHash ( account . Key ) )
2019-10-24 16:35:39 +00:00
errs <- formatErr
continue
}
2019-09-04 14:00:33 +00:00
logrus . Trace ( "adding storage diff to out channel" ,
2019-09-10 21:26:54 +00:00
"keccak of address: " , diff . HashedAddress . Hex ( ) ,
2019-09-04 14:00:33 +00:00
"block height: " , diff . BlockHeight ,
"storage key: " , diff . StorageKey . Hex ( ) ,
"storage value: " , diff . StorageValue . Hex ( ) )
2019-08-30 19:17:26 +00:00
out <- diff
2019-07-08 20:34:06 +00:00
}
}
}
}