This repository has been archived by the owner on Aug 31, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
635 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
DROP TABLE maker.pit_file_ilk; | ||
DROP TABLE maker.pit_file_stability_fee; | ||
DROP TABLE maker.pit_file_stability_fee; | ||
DROP TABLE maker.pit_file_debt_ceiling; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package debt_ceiling | ||
|
||
import ( | ||
"encoding/json" | ||
"github.com/ethereum/go-ethereum/common" | ||
"github.com/ethereum/go-ethereum/core/types" | ||
"math/big" | ||
) | ||
|
||
type Converter interface { | ||
ToModel(contractAddress string, contractAbi string, ethLog types.Log) (PitFileDebtCeilingModel, error) | ||
} | ||
|
||
type PitFileDebtCeilingConverter struct{} | ||
|
||
func (PitFileDebtCeilingConverter) ToModel(contractAddress string, contractAbi string, ethLog types.Log) (PitFileDebtCeilingModel, error) { | ||
what := common.HexToAddress(ethLog.Topics[1].String()).String() | ||
itemByteLength := 32 | ||
riskBytes := ethLog.Data[len(ethLog.Data)-itemByteLength:] | ||
data := big.NewInt(0).SetBytes(riskBytes).String() | ||
|
||
raw, err := json.Marshal(ethLog) | ||
return PitFileDebtCeilingModel{ | ||
What: what, | ||
Data: data, | ||
TransactionIndex: ethLog.TxIndex, | ||
Raw: raw, | ||
}, err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package debt_ceiling_test | ||
|
||
import ( | ||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/gomega" | ||
|
||
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file/debt_ceiling" | ||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared" | ||
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data" | ||
) | ||
|
||
var _ = Describe("", func() { | ||
It("converts a log to an model", func() { | ||
converter := debt_ceiling.PitFileDebtCeilingConverter{} | ||
|
||
model, err := converter.ToModel(test_data.PitAddress, shared.PitABI, test_data.EthPitFileDebtCeilingLog) | ||
|
||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(model.What).To(Equal(test_data.PitFileDebtCeilingModel.What)) | ||
Expect(model.Data).To(Equal(test_data.PitFileDebtCeilingModel.Data)) | ||
Expect(model.TransactionIndex).To(Equal(test_data.PitFileDebtCeilingModel.TransactionIndex)) | ||
Expect(model.Raw).To(Equal(test_data.PitFileDebtCeilingModel.Raw)) | ||
Expect(model).To(Equal(test_data.PitFileDebtCeilingModel)) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package debt_ceiling | ||
|
||
type PitFileDebtCeilingModel struct { | ||
What string | ||
Data string | ||
TransactionIndex uint `db:"tx_idx"` | ||
Raw []byte `db:"raw_log"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package debt_ceiling | ||
|
||
import ( | ||
"github.com/vulcanize/vulcanizedb/pkg/core" | ||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres" | ||
) | ||
|
||
type Repository interface { | ||
Create(headerID int64, model PitFileDebtCeilingModel) error | ||
MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error) | ||
} | ||
|
||
type PitFileDebtCeilingRepository struct { | ||
db *postgres.DB | ||
} | ||
|
||
func NewPitFileDebtCeilingRepository(db *postgres.DB) PitFileDebtCeilingRepository { | ||
return PitFileDebtCeilingRepository{ | ||
db: db, | ||
} | ||
} | ||
|
||
func (repository PitFileDebtCeilingRepository) Create(headerID int64, model PitFileDebtCeilingModel) error { | ||
_, err := repository.db.Exec( | ||
`INSERT into maker.pit_file_debt_ceiling (header_id, what, data, tx_idx, raw_log) | ||
VALUES($1, $2, $3::NUMERIC, $4, $5)`, | ||
headerID, model.What, model.Data, model.TransactionIndex, model.Raw, | ||
) | ||
return err | ||
} | ||
|
||
func (repository PitFileDebtCeilingRepository) MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error) { | ||
var result []core.Header | ||
err := repository.db.Select( | ||
&result, | ||
`SELECT headers.id, headers.block_number FROM headers | ||
LEFT JOIN maker.pit_file_debt_ceiling on headers.id = header_id | ||
WHERE header_id ISNULL | ||
AND headers.block_number >= $1 | ||
AND headers.block_number <= $2 | ||
AND headers.eth_node_fingerprint = $3`, | ||
startingBlockNumber, | ||
endingBlockNumber, | ||
repository.db.Node.ID, | ||
) | ||
|
||
return result, err | ||
} |
130 changes: 130 additions & 0 deletions
130
pkg/transformers/pit_file/debt_ceiling/repository_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
package debt_ceiling_test | ||
|
||
import ( | ||
"database/sql" | ||
|
||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/gomega" | ||
|
||
"github.com/vulcanize/vulcanizedb/pkg/core" | ||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories" | ||
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file/debt_ceiling" | ||
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data" | ||
"github.com/vulcanize/vulcanizedb/test_config" | ||
) | ||
|
||
var _ = Describe("", func() { | ||
Describe("Create", func() { | ||
It("adds a pit file debt ceiling event", func() { | ||
db := test_config.NewTestDB(core.Node{}) | ||
test_config.CleanTestDB(db) | ||
headerRepository := repositories.NewHeaderRepository(db) | ||
headerID, err := headerRepository.CreateOrUpdateHeader(core.Header{}) | ||
Expect(err).NotTo(HaveOccurred()) | ||
pitFileRepository := debt_ceiling.NewPitFileDebtCeilingRepository(db) | ||
|
||
err = pitFileRepository.Create(headerID, test_data.PitFileDebtCeilingModel) | ||
|
||
Expect(err).NotTo(HaveOccurred()) | ||
var dbPitFile debt_ceiling.PitFileDebtCeilingModel | ||
err = db.Get(&dbPitFile, `SELECT what, data, tx_idx, raw_log FROM maker.pit_file_debt_ceiling WHERE header_id = $1`, headerID) | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(dbPitFile.What).To(Equal(test_data.PitFileDebtCeilingModel.What)) | ||
Expect(dbPitFile.Data).To(Equal(test_data.PitFileDebtCeilingModel.Data)) | ||
Expect(dbPitFile.TransactionIndex).To(Equal(test_data.PitFileDebtCeilingModel.TransactionIndex)) | ||
Expect(dbPitFile.Raw).To(MatchJSON(test_data.PitFileDebtCeilingModel.Raw)) | ||
}) | ||
|
||
It("does not duplicate pit file events", func() { | ||
db := test_config.NewTestDB(core.Node{}) | ||
test_config.CleanTestDB(db) | ||
headerRepository := repositories.NewHeaderRepository(db) | ||
headerID, err := headerRepository.CreateOrUpdateHeader(core.Header{}) | ||
Expect(err).NotTo(HaveOccurred()) | ||
pitFileRepository := debt_ceiling.NewPitFileDebtCeilingRepository(db) | ||
err = pitFileRepository.Create(headerID, test_data.PitFileDebtCeilingModel) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
err = pitFileRepository.Create(headerID, test_data.PitFileDebtCeilingModel) | ||
|
||
Expect(err).To(HaveOccurred()) | ||
Expect(err.Error()).To(ContainSubstring("pq: duplicate key value violates unique constraint")) | ||
}) | ||
|
||
It("removes pit file if corresponding header is deleted", func() { | ||
db := test_config.NewTestDB(core.Node{}) | ||
test_config.CleanTestDB(db) | ||
headerRepository := repositories.NewHeaderRepository(db) | ||
headerID, err := headerRepository.CreateOrUpdateHeader(core.Header{}) | ||
Expect(err).NotTo(HaveOccurred()) | ||
pitFileRepository := debt_ceiling.NewPitFileDebtCeilingRepository(db) | ||
err = pitFileRepository.Create(headerID, test_data.PitFileDebtCeilingModel) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
_, err = db.Exec(`DELETE FROM headers WHERE id = $1`, headerID) | ||
|
||
Expect(err).NotTo(HaveOccurred()) | ||
var dbPitFile debt_ceiling.PitFileDebtCeilingModel | ||
err = db.Get(&dbPitFile, `SELECT what, data, tx_idx, raw_log FROM maker.pit_file_debt_ceiling WHERE header_id = $1`, headerID) | ||
Expect(err).To(HaveOccurred()) | ||
Expect(err).To(MatchError(sql.ErrNoRows)) | ||
}) | ||
}) | ||
|
||
Describe("MissingHeaders", func() { | ||
It("returns headers with no associated pit file event", func() { | ||
db := test_config.NewTestDB(core.Node{}) | ||
test_config.CleanTestDB(db) | ||
headerRepository := repositories.NewHeaderRepository(db) | ||
startingBlockNumber := int64(1) | ||
pitFileBlockNumber := int64(2) | ||
endingBlockNumber := int64(3) | ||
blockNumbers := []int64{startingBlockNumber, pitFileBlockNumber, endingBlockNumber, endingBlockNumber + 1} | ||
var headerIDs []int64 | ||
for _, n := range blockNumbers { | ||
headerID, err := headerRepository.CreateOrUpdateHeader(core.Header{BlockNumber: n}) | ||
headerIDs = append(headerIDs, headerID) | ||
Expect(err).NotTo(HaveOccurred()) | ||
} | ||
pitFileRepository := debt_ceiling.NewPitFileDebtCeilingRepository(db) | ||
err := pitFileRepository.Create(headerIDs[1], test_data.PitFileDebtCeilingModel) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
headers, err := pitFileRepository.MissingHeaders(startingBlockNumber, endingBlockNumber) | ||
|
||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(len(headers)).To(Equal(2)) | ||
Expect(headers[0].BlockNumber).To(Or(Equal(startingBlockNumber), Equal(endingBlockNumber))) | ||
Expect(headers[1].BlockNumber).To(Or(Equal(startingBlockNumber), Equal(endingBlockNumber))) | ||
}) | ||
|
||
It("only returns headers associated with the current node", func() { | ||
db := test_config.NewTestDB(core.Node{}) | ||
test_config.CleanTestDB(db) | ||
blockNumbers := []int64{1, 2, 3} | ||
headerRepository := repositories.NewHeaderRepository(db) | ||
dbTwo := test_config.NewTestDB(core.Node{ID: "second"}) | ||
headerRepositoryTwo := repositories.NewHeaderRepository(dbTwo) | ||
var headerIDs []int64 | ||
for _, n := range blockNumbers { | ||
headerID, err := headerRepository.CreateOrUpdateHeader(core.Header{BlockNumber: n}) | ||
Expect(err).NotTo(HaveOccurred()) | ||
headerIDs = append(headerIDs, headerID) | ||
_, err = headerRepositoryTwo.CreateOrUpdateHeader(core.Header{BlockNumber: n}) | ||
Expect(err).NotTo(HaveOccurred()) | ||
} | ||
pitFileRepository := debt_ceiling.NewPitFileDebtCeilingRepository(db) | ||
pitFileRepositoryTwo := debt_ceiling.NewPitFileDebtCeilingRepository(dbTwo) | ||
err := pitFileRepository.Create(headerIDs[0], test_data.PitFileDebtCeilingModel) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
nodeOneMissingHeaders, err := pitFileRepository.MissingHeaders(blockNumbers[0], blockNumbers[len(blockNumbers)-1]) | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(len(nodeOneMissingHeaders)).To(Equal(len(blockNumbers) - 1)) | ||
|
||
nodeTwoMissingHeaders, err := pitFileRepositoryTwo.MissingHeaders(blockNumbers[0], blockNumbers[len(blockNumbers)-1]) | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(len(nodeTwoMissingHeaders)).To(Equal(len(blockNumbers))) | ||
}) | ||
}) | ||
}) |
Oops, something went wrong.