diff --git a/cmd/stateSnapshot.go b/cmd/stateSnapshot.go index 0df439b..222ee24 100644 --- a/cmd/stateSnapshot.go +++ b/cmd/stateSnapshot.go @@ -43,9 +43,16 @@ func stateSnapshot() { if err != nil { logWithCommand.Fatal(err) } - height := uint64(viper.GetInt64("snapshot.blockHeight")) - if err := snapshotService.CreateSnapshot(height); err != nil { - logWithCommand.Fatal(err) + height := viper.GetInt64("snapshot.blockHeight") + if height < 0 { + if err := snapshotService.CreateLatestSnapshot(); err != nil { + logWithCommand.Fatal(err) + } + } else { + uHeight := uint64(height) + if err := snapshotService.CreateSnapshot(uHeight); err != nil { + logWithCommand.Fatal(err) + } } logWithCommand.Infof("state snapshot at height %d is complete", height) } diff --git a/pkg/snapshot/publisher.go b/pkg/snapshot/publisher.go index 0a6f76f..8bb1c1d 100644 --- a/pkg/snapshot/publisher.go +++ b/pkg/snapshot/publisher.go @@ -126,7 +126,7 @@ func (p *Publisher) PublishStorageNode(node Node, stateID int64) error { } mhKey, _ := shared.MultihashKeyFromCIDString(storageCIDStr) _, err = tx.Exec(`INSERT INTO eth.storage_cids (state_id, storage_leaf_key, cid, storage_path, node_type, diff, mh_key) VALUES ($1, $2, $3, $4, $5, $6, $7) - ON CONFLICT (state_id, storage_path) DO UPDATE SET (storage_leaf_key, cid, node_type, diff, mh_key) = ($2, $3, $5, $6, $7)`, + ON CONFLICT (state_id, storage_path, diff) DO UPDATE SET (storage_leaf_key, cid, node_type, mh_key) = ($2, $3, $5, $7)`, stateID, storageKey, storageCIDStr, node.Path, node.NodeType, false, mhKey) return err } diff --git a/pkg/snapshot/service.go b/pkg/snapshot/service.go index 48ca582..a6d7f12 100644 --- a/pkg/snapshot/service.go +++ b/pkg/snapshot/service.go @@ -20,8 +20,6 @@ import ( "errors" "fmt" - "github.com/sirupsen/logrus" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" @@ -29,6 +27,7 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie" + "github.com/sirupsen/logrus" "github.com/vulcanize/ipfs-blockchain-watcher/pkg/postgres" ) @@ -61,6 +60,32 @@ func NewSnapshotService(con Config) (*Service, error) { }, nil } +func (s *Service) CreateLatestSnapshot() error { + // extract header from lvldb and publish to PG-IPFS + // hold onto the headerID so that we can link the state nodes to this header + logrus.Info("Creating snapshot at head") + hash := rawdb.ReadHeadHeaderHash(s.ethDB) + height := rawdb.ReadHeaderNumber(s.ethDB, hash) + if height == nil { + return fmt.Errorf("unable to read header height for header hash %s", hash.String()) + } + header := rawdb.ReadHeader(s.ethDB, hash, *height) + if header == nil { + return fmt.Errorf("unable to read canonical header at height %d", height) + } + logrus.Infof("head hash: %s head height: %d", hash.Hex(), *height) + headerID, err := s.ipfsPublisher.PublishHeader(header) + if err != nil { + return err + } + t, err := s.stateDB.OpenTrie(header.Root) + if err != nil { + return err + } + trieDB := s.stateDB.TrieDB() + return s.createSnapshot(t.NodeIterator([]byte{}), trieDB, headerID) +} + func (s *Service) CreateSnapshot(height uint64) error { // extract header from lvldb and publish to PG-IPFS // hold onto the headerID so that we can link the state nodes to this header