From a31c7e9cedc42cd049b10f8eaea7602732c53bc2 Mon Sep 17 00:00:00 2001 From: Ian Norden Date: Mon, 15 Apr 2019 11:28:55 -0500 Subject: [PATCH] payload converter - interface for converting state diff payload into payload for ipld publishing --- pkg/ipfs/payload_converter.go | 110 ++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 pkg/ipfs/payload_converter.go diff --git a/pkg/ipfs/payload_converter.go b/pkg/ipfs/payload_converter.go new file mode 100644 index 00000000..24327c42 --- /dev/null +++ b/pkg/ipfs/payload_converter.go @@ -0,0 +1,110 @@ +// VulcanizeDB +// Copyright © 2019 Vulcanize + +// 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 . + +package ipfs + +import ( + "context" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/statediff" + + "github.com/vulcanize/vulcanizedb/pkg/core" +) + +type Converter interface { + Convert(payload statediff.Payload) (*IPLDPayload, error) +} + +type PayloadConverter struct { + client core.EthClient +} + +type IPLDPayload struct { + HeaderRLP []byte + BlockNumber *big.Int + BlockHash common.Hash + BlockBody *types.Body + Receipts types.Receipts + StateLeafs map[common.Hash][]byte + StorageLeafs map[common.Hash]map[common.Hash][]byte +} + +func NewPayloadConverter(client core.EthClient) *PayloadConverter { + return &PayloadConverter{ + client: client, + } +} + +func (pc *PayloadConverter) Convert(payload statediff.Payload) (*IPLDPayload, error) { + // Unpack block rlp to access fields + block := new(types.Block) + err := rlp.DecodeBytes(payload.BlockRlp, block) + header := block.Header() + headerRlp, err := rlp.EncodeToBytes(header) + if err != nil { + return nil, err + } + convertedPayload := &IPLDPayload{ + BlockHash: block.Hash(), + BlockNumber: block.Number(), + HeaderRLP: headerRlp, + BlockBody: block.Body(), + Receipts: make(types.Receipts, 0), + StateLeafs: make(map[common.Hash][]byte), + StorageLeafs: make(map[common.Hash]map[common.Hash][]byte), + } + for _, trx := range block.Transactions() { + gethReceipt, err := pc.client.TransactionReceipt(context.Background(), trx.Hash()) + if err != nil { + return nil, err + } + convertedPayload.Receipts = append(convertedPayload.Receipts, gethReceipt) + } + + // Unpack state diff rlp to access fields + stateDiff := new(statediff.StateDiff) + err = rlp.DecodeBytes(payload.StateDiffRlp, stateDiff) + if err != nil { + return nil, err + } + for addr, createdAccount := range stateDiff.CreatedAccounts { + convertedPayload.StateLeafs[addr] = createdAccount.Value + convertedPayload.StorageLeafs[addr] = make(map[common.Hash][]byte) + for _, storageDiff := range createdAccount.Storage { + convertedPayload.StorageLeafs[addr][common.BytesToHash(storageDiff.Key)] = storageDiff.Value + } + } + for addr, deletedAccount := range stateDiff.DeletedAccounts { + convertedPayload.StateLeafs[addr] = deletedAccount.Value + convertedPayload.StorageLeafs[addr] = make(map[common.Hash][]byte) + for _, storageDiff := range deletedAccount.Storage { + convertedPayload.StorageLeafs[addr][common.BytesToHash(storageDiff.Key)] = storageDiff.Value + } + } + for addr, updatedAccount := range stateDiff.UpdatedAccounts { + convertedPayload.StateLeafs[addr] = updatedAccount.Value + convertedPayload.StorageLeafs[addr] = make(map[common.Hash][]byte) + for _, storageDiff := range updatedAccount.Storage { + convertedPayload.StorageLeafs[addr][common.BytesToHash(storageDiff.Key)] = storageDiff.Value + } + } + return convertedPayload, nil +} +