Changes to address Rob's comments. Added generic/event_triggered transformer, tests, and repo migrations for Burn and Mint events
This commit is contained in:
parent
4aa403d90d
commit
d66e50dad6
@ -0,0 +1 @@
|
|||||||
|
DROP TABLE token_burns;
|
13
db/migrations/20180911134701_create_token_burn_table.up.sql
Normal file
13
db/migrations/20180911134701_create_token_burn_table.up.sql
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
CREATE TABLE token_burns (
|
||||||
|
id SERIAL,
|
||||||
|
vulcanize_log_id INTEGER NOT NULL UNIQUE,
|
||||||
|
token_name CHARACTER VARYING(66) NOT NULL,
|
||||||
|
token_address CHARACTER VARYING(66) NOT NULL,
|
||||||
|
burner CHARACTER VARYING(66) NOT NULL,
|
||||||
|
tokens DECIMAL NOT NULL,
|
||||||
|
block INTEGER NOT NULL,
|
||||||
|
tx CHARACTER VARYING(66) NOT NULL,
|
||||||
|
CONSTRAINT log_index_fk FOREIGN KEY (vulcanize_log_id)
|
||||||
|
REFERENCES logs (id)
|
||||||
|
ON DELETE CASCADE
|
||||||
|
)
|
@ -0,0 +1 @@
|
|||||||
|
DROP TABLE token_mints;
|
14
db/migrations/20180911134708_create_token_mint_table.up.sql
Normal file
14
db/migrations/20180911134708_create_token_mint_table.up.sql
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
CREATE TABLE token_mints (
|
||||||
|
id SERIAL,
|
||||||
|
vulcanize_log_id INTEGER NOT NULL UNIQUE,
|
||||||
|
token_name CHARACTER VARYING(66) NOT NULL,
|
||||||
|
token_address CHARACTER VARYING(66) NOT NULL,
|
||||||
|
minter CHARACTER VARYING(66) NOT NULL,
|
||||||
|
mintee CHARACTER VARYING(66) NOT NULL,
|
||||||
|
tokens DECIMAL NOT NULL,
|
||||||
|
block INTEGER NOT NULL,
|
||||||
|
tx CHARACTER VARYING(66) NOT NULL,
|
||||||
|
CONSTRAINT log_index_fk FOREIGN KEY (vulcanize_log_id)
|
||||||
|
REFERENCES logs (id)
|
||||||
|
ON DELETE CASCADE
|
||||||
|
)
|
File diff suppressed because one or more lines are too long
@ -17,9 +17,12 @@ package event_triggered
|
|||||||
import (
|
import (
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
|
||||||
|
"github.com/vulcanize/vulcanizedb/examples/constants"
|
||||||
"github.com/vulcanize/vulcanizedb/examples/generic"
|
"github.com/vulcanize/vulcanizedb/examples/generic"
|
||||||
"github.com/vulcanize/vulcanizedb/examples/generic/helpers"
|
"github.com/vulcanize/vulcanizedb/examples/generic/helpers"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/geth"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Converter converts a raw event log into its corresponding entity
|
// Converter converts a raw event log into its corresponding entity
|
||||||
@ -27,26 +30,35 @@ import (
|
|||||||
|
|
||||||
type ERC20ConverterInterface interface {
|
type ERC20ConverterInterface interface {
|
||||||
ToTransferEntity(watchedEvent core.WatchedEvent) (*TransferEntity, error)
|
ToTransferEntity(watchedEvent core.WatchedEvent) (*TransferEntity, error)
|
||||||
ToTransferModel(entity TransferEntity) TransferModel
|
ToTransferModel(entity *TransferEntity) *TransferModel
|
||||||
ToApprovalEntity(watchedEvent core.WatchedEvent) (*ApprovalEntity, error)
|
ToApprovalEntity(watchedEvent core.WatchedEvent) (*ApprovalEntity, error)
|
||||||
ToApprovalModel(entity ApprovalEntity) ApprovalModel
|
ToApprovalModel(entity *ApprovalEntity) *ApprovalModel
|
||||||
}
|
}
|
||||||
|
|
||||||
type ERC20Converter struct {
|
type ERC20Converter struct {
|
||||||
config generic.ContractConfig
|
config generic.ContractConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewERC20Converter(config generic.ContractConfig) ERC20Converter {
|
func NewERC20Converter(config generic.ContractConfig) (*ERC20Converter, error) {
|
||||||
return ERC20Converter{
|
var err error
|
||||||
|
|
||||||
|
config.ParsedAbi, err = geth.ParseAbi(config.Abi)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
converter := &ERC20Converter{
|
||||||
config: config,
|
config: config,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return converter, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c ERC20Converter) ToTransferEntity(watchedEvent core.WatchedEvent) (*TransferEntity, error) {
|
func (c ERC20Converter) ToTransferEntity(watchedEvent core.WatchedEvent) (*TransferEntity, error) {
|
||||||
result := &TransferEntity{}
|
result := &TransferEntity{}
|
||||||
contract := bind.NewBoundContract(common.HexToAddress(c.config.Address), c.config.ParsedAbi, nil, nil, nil)
|
contract := bind.NewBoundContract(common.HexToAddress(c.config.Address), c.config.ParsedAbi, nil, nil, nil)
|
||||||
event := helpers.ConvertToLog(watchedEvent)
|
event := helpers.ConvertToLog(watchedEvent)
|
||||||
err := contract.UnpackLog(result, "Transfer", event)
|
err := contract.UnpackLog(result, constants.TransferEvent.String(), event)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
@ -58,20 +70,19 @@ func (c ERC20Converter) ToTransferEntity(watchedEvent core.WatchedEvent) (*Trans
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c ERC20Converter) ToTransferModel(transferEntity TransferEntity) TransferModel {
|
func (c ERC20Converter) ToTransferModel(entity *TransferEntity) *TransferModel {
|
||||||
to := transferEntity.Dst.String()
|
to := entity.Dst.String()
|
||||||
from := transferEntity.Src.String()
|
from := entity.Src.String()
|
||||||
tokens := transferEntity.Wad.String()
|
tokens := entity.Wad.String()
|
||||||
block := transferEntity.Block
|
|
||||||
tx := transferEntity.TxHash
|
return &TransferModel{
|
||||||
return TransferModel{
|
|
||||||
TokenName: c.config.Name,
|
TokenName: c.config.Name,
|
||||||
TokenAddress: c.config.Address,
|
TokenAddress: c.config.Address,
|
||||||
To: to,
|
To: to,
|
||||||
From: from,
|
From: from,
|
||||||
Tokens: tokens,
|
Tokens: tokens,
|
||||||
Block: block,
|
Block: entity.Block,
|
||||||
TxHash: tx,
|
TxHash: entity.TxHash,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,7 +90,7 @@ func (c ERC20Converter) ToApprovalEntity(watchedEvent core.WatchedEvent) (*Appro
|
|||||||
result := &ApprovalEntity{}
|
result := &ApprovalEntity{}
|
||||||
contract := bind.NewBoundContract(common.HexToAddress(c.config.Address), c.config.ParsedAbi, nil, nil, nil)
|
contract := bind.NewBoundContract(common.HexToAddress(c.config.Address), c.config.ParsedAbi, nil, nil, nil)
|
||||||
event := helpers.ConvertToLog(watchedEvent)
|
event := helpers.ConvertToLog(watchedEvent)
|
||||||
err := contract.UnpackLog(result, "Approval", event)
|
err := contract.UnpackLog(result, constants.ApprovalEvent.String(), event)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
@ -91,19 +102,18 @@ func (c ERC20Converter) ToApprovalEntity(watchedEvent core.WatchedEvent) (*Appro
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c ERC20Converter) ToApprovalModel(TransferEntity ApprovalEntity) ApprovalModel {
|
func (c ERC20Converter) ToApprovalModel(entity *ApprovalEntity) *ApprovalModel {
|
||||||
tokenOwner := TransferEntity.Src.String()
|
tokenOwner := entity.Src.String()
|
||||||
spender := TransferEntity.Guy.String()
|
spender := entity.Guy.String()
|
||||||
tokens := TransferEntity.Wad.String()
|
tokens := entity.Wad.String()
|
||||||
block := TransferEntity.Block
|
|
||||||
tx := TransferEntity.TxHash
|
return &ApprovalModel{
|
||||||
return ApprovalModel{
|
|
||||||
TokenName: c.config.Name,
|
TokenName: c.config.Name,
|
||||||
TokenAddress: c.config.Address,
|
TokenAddress: c.config.Address,
|
||||||
Owner: tokenOwner,
|
Owner: tokenOwner,
|
||||||
Spender: spender,
|
Spender: spender,
|
||||||
Tokens: tokens,
|
Tokens: tokens,
|
||||||
Block: block,
|
Block: entity.Block,
|
||||||
TxHash: tx,
|
TxHash: entity.TxHash,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
"github.com/vulcanize/vulcanizedb/examples/constants"
|
"github.com/vulcanize/vulcanizedb/examples/constants"
|
||||||
"github.com/vulcanize/vulcanizedb/examples/erc20_watcher/event_triggered"
|
"github.com/vulcanize/vulcanizedb/examples/erc20_watcher/event_triggered"
|
||||||
"github.com/vulcanize/vulcanizedb/examples/generic"
|
"github.com/vulcanize/vulcanizedb/examples/generic"
|
||||||
@ -27,7 +28,7 @@ import (
|
|||||||
|
|
||||||
var expectedTransferModel = event_triggered.TransferModel{
|
var expectedTransferModel = event_triggered.TransferModel{
|
||||||
TokenName: "Dai",
|
TokenName: "Dai",
|
||||||
TokenAddress: "0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359",
|
TokenAddress: constants.DaiContractAddress,
|
||||||
To: "0x09BbBBE21a5975cAc061D82f7b843bCE061BA391",
|
To: "0x09BbBBE21a5975cAc061D82f7b843bCE061BA391",
|
||||||
From: "0x000000000000000000000000000000000000Af21",
|
From: "0x000000000000000000000000000000000000Af21",
|
||||||
Tokens: "1097077688018008265106216665536940668749033598146",
|
Tokens: "1097077688018008265106216665536940668749033598146",
|
||||||
@ -37,7 +38,7 @@ var expectedTransferModel = event_triggered.TransferModel{
|
|||||||
|
|
||||||
var expectedTransferEntity = event_triggered.TransferEntity{
|
var expectedTransferEntity = event_triggered.TransferEntity{
|
||||||
TokenName: "Dai",
|
TokenName: "Dai",
|
||||||
TokenAddress: common.HexToAddress("0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359"),
|
TokenAddress: common.HexToAddress(constants.DaiContractAddress),
|
||||||
Src: common.HexToAddress("0x000000000000000000000000000000000000Af21"),
|
Src: common.HexToAddress("0x000000000000000000000000000000000000Af21"),
|
||||||
Dst: common.HexToAddress("0x09BbBBE21a5975cAc061D82f7b843bCE061BA391"),
|
Dst: common.HexToAddress("0x09BbBBE21a5975cAc061D82f7b843bCE061BA391"),
|
||||||
Wad: helpers.BigFromString("1097077688018008265106216665536940668749033598146"),
|
Wad: helpers.BigFromString("1097077688018008265106216665536940668749033598146"),
|
||||||
@ -47,7 +48,7 @@ var expectedTransferEntity = event_triggered.TransferEntity{
|
|||||||
|
|
||||||
var expectedApprovalModel = event_triggered.ApprovalModel{
|
var expectedApprovalModel = event_triggered.ApprovalModel{
|
||||||
TokenName: "Dai",
|
TokenName: "Dai",
|
||||||
TokenAddress: "0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359",
|
TokenAddress: constants.DaiContractAddress,
|
||||||
Owner: "0x000000000000000000000000000000000000Af21",
|
Owner: "0x000000000000000000000000000000000000Af21",
|
||||||
Spender: "0x09BbBBE21a5975cAc061D82f7b843bCE061BA391",
|
Spender: "0x09BbBBE21a5975cAc061D82f7b843bCE061BA391",
|
||||||
Tokens: "1097077688018008265106216665536940668749033598146",
|
Tokens: "1097077688018008265106216665536940668749033598146",
|
||||||
@ -57,7 +58,7 @@ var expectedApprovalModel = event_triggered.ApprovalModel{
|
|||||||
|
|
||||||
var expectedApprovalEntity = event_triggered.ApprovalEntity{
|
var expectedApprovalEntity = event_triggered.ApprovalEntity{
|
||||||
TokenName: "Dai",
|
TokenName: "Dai",
|
||||||
TokenAddress: common.HexToAddress("0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359"),
|
TokenAddress: common.HexToAddress(constants.DaiContractAddress),
|
||||||
Src: common.HexToAddress("0x000000000000000000000000000000000000Af21"),
|
Src: common.HexToAddress("0x000000000000000000000000000000000000Af21"),
|
||||||
Guy: common.HexToAddress("0x09BbBBE21a5975cAc061D82f7b843bCE061BA391"),
|
Guy: common.HexToAddress("0x09BbBBE21a5975cAc061D82f7b843bCE061BA391"),
|
||||||
Wad: helpers.BigFromString("1097077688018008265106216665536940668749033598146"),
|
Wad: helpers.BigFromString("1097077688018008265106216665536940668749033598146"),
|
||||||
@ -67,12 +68,12 @@ var expectedApprovalEntity = event_triggered.ApprovalEntity{
|
|||||||
|
|
||||||
var transferEvent = core.WatchedEvent{
|
var transferEvent = core.WatchedEvent{
|
||||||
LogID: 1,
|
LogID: 1,
|
||||||
Name: "Transfer",
|
Name: constants.TransferEvent.String(),
|
||||||
BlockNumber: 5488076,
|
BlockNumber: 5488076,
|
||||||
Address: constants.DaiContractAddress,
|
Address: constants.DaiContractAddress,
|
||||||
TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
|
TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
|
||||||
Index: 110,
|
Index: 110,
|
||||||
Topic0: constants.TransferEventSignature,
|
Topic0: constants.TransferEvent.Signature(),
|
||||||
Topic1: "0x000000000000000000000000000000000000000000000000000000000000af21",
|
Topic1: "0x000000000000000000000000000000000000000000000000000000000000af21",
|
||||||
Topic2: "0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391",
|
Topic2: "0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391",
|
||||||
Topic3: "",
|
Topic3: "",
|
||||||
@ -81,12 +82,12 @@ var transferEvent = core.WatchedEvent{
|
|||||||
|
|
||||||
var approvalEvent = core.WatchedEvent{
|
var approvalEvent = core.WatchedEvent{
|
||||||
LogID: 1,
|
LogID: 1,
|
||||||
Name: "Approval",
|
Name: constants.ApprovalEvent.String(),
|
||||||
BlockNumber: 5488076,
|
BlockNumber: 5488076,
|
||||||
Address: constants.DaiContractAddress,
|
Address: constants.DaiContractAddress,
|
||||||
TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
|
TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
|
||||||
Index: 110,
|
Index: 110,
|
||||||
Topic0: constants.ApprovalEventSignature,
|
Topic0: constants.ApprovalEvent.Signature(),
|
||||||
Topic1: "0x000000000000000000000000000000000000000000000000000000000000af21",
|
Topic1: "0x000000000000000000000000000000000000000000000000000000000000af21",
|
||||||
Topic2: "0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391",
|
Topic2: "0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391",
|
||||||
Topic3: "",
|
Topic3: "",
|
||||||
@ -95,20 +96,19 @@ var approvalEvent = core.WatchedEvent{
|
|||||||
|
|
||||||
var _ = Describe("Transfer Converter", func() {
|
var _ = Describe("Transfer Converter", func() {
|
||||||
|
|
||||||
daiConverter := event_triggered.NewERC20Converter(generic.DaiConfig)
|
var daiConverter *event_triggered.ERC20Converter
|
||||||
|
var err error
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
daiConverter, err = event_triggered.NewERC20Converter(generic.DaiConfig)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
It("converts a watched transfer event into a TransferEntity", func() {
|
It("converts a watched transfer event into a TransferEntity", func() {
|
||||||
|
|
||||||
result, err := daiConverter.ToTransferEntity(transferEvent)
|
result, err := daiConverter.ToTransferEntity(transferEvent)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(result).To(Equal(&expectedTransferEntity))
|
||||||
Expect(result.TokenName).To(Equal(expectedTransferEntity.TokenName))
|
|
||||||
Expect(result.TokenAddress).To(Equal(expectedTransferEntity.TokenAddress))
|
|
||||||
Expect(result.Dst).To(Equal(expectedTransferEntity.Dst))
|
|
||||||
Expect(result.Src).To(Equal(expectedTransferEntity.Src))
|
|
||||||
Expect(result.Wad).To(Equal(expectedTransferEntity.Wad))
|
|
||||||
Expect(result.Block).To(Equal(expectedTransferEntity.Block))
|
|
||||||
Expect(result.TxHash).To(Equal(expectedTransferEntity.TxHash))
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("converts a TransferEntity to an TransferModel", func() {
|
It("converts a TransferEntity to an TransferModel", func() {
|
||||||
@ -116,35 +116,27 @@ var _ = Describe("Transfer Converter", func() {
|
|||||||
result, err := daiConverter.ToTransferEntity(transferEvent)
|
result, err := daiConverter.ToTransferEntity(transferEvent)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
model := daiConverter.ToTransferModel(*result)
|
model := daiConverter.ToTransferModel(result)
|
||||||
|
Expect(model).To(Equal(&expectedTransferModel))
|
||||||
Expect(model.TokenName).To(Equal(expectedTransferModel.TokenName))
|
|
||||||
Expect(model.TokenAddress).To(Equal(expectedTransferModel.TokenAddress))
|
|
||||||
Expect(model.To).To(Equal(expectedTransferModel.To))
|
|
||||||
Expect(model.From).To(Equal(expectedTransferModel.From))
|
|
||||||
Expect(model.Tokens).To(Equal(expectedTransferModel.Tokens))
|
|
||||||
Expect(model.Block).To(Equal(expectedTransferModel.Block))
|
|
||||||
Expect(model.TxHash).To(Equal(expectedTransferModel.TxHash))
|
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
var _ = Describe("Approval Converter", func() {
|
var _ = Describe("Approval Converter", func() {
|
||||||
|
|
||||||
daiConverter := event_triggered.NewERC20Converter(generic.DaiConfig)
|
var daiConverter *event_triggered.ERC20Converter
|
||||||
|
var err error
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
daiConverter, err = event_triggered.NewERC20Converter(generic.DaiConfig)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
It("converts a watched approval event into a ApprovalEntity", func() {
|
It("converts a watched approval event into a ApprovalEntity", func() {
|
||||||
|
|
||||||
result, err := daiConverter.ToApprovalEntity(approvalEvent)
|
result, err := daiConverter.ToApprovalEntity(approvalEvent)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(result).To(Equal(&expectedApprovalEntity))
|
||||||
Expect(result.TokenName).To(Equal(expectedApprovalEntity.TokenName))
|
|
||||||
Expect(result.TokenAddress).To(Equal(expectedApprovalEntity.TokenAddress))
|
|
||||||
Expect(result.Src).To(Equal(expectedApprovalEntity.Src))
|
|
||||||
Expect(result.Guy).To(Equal(expectedApprovalEntity.Guy))
|
|
||||||
Expect(result.Wad).To(Equal(expectedApprovalEntity.Wad))
|
|
||||||
Expect(result.Block).To(Equal(expectedApprovalEntity.Block))
|
|
||||||
Expect(result.TxHash).To(Equal(expectedApprovalEntity.TxHash))
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("converts a ApprovalEntity to an ApprovalModel", func() {
|
It("converts a ApprovalEntity to an ApprovalModel", func() {
|
||||||
@ -152,15 +144,8 @@ var _ = Describe("Approval Converter", func() {
|
|||||||
result, err := daiConverter.ToApprovalEntity(approvalEvent)
|
result, err := daiConverter.ToApprovalEntity(approvalEvent)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
model := daiConverter.ToApprovalModel(*result)
|
model := daiConverter.ToApprovalModel(result)
|
||||||
|
Expect(model).To(Equal(&expectedApprovalModel))
|
||||||
Expect(model.TokenName).To(Equal(expectedApprovalModel.TokenName))
|
|
||||||
Expect(model.TokenAddress).To(Equal(expectedApprovalModel.TokenAddress))
|
|
||||||
Expect(model.Owner).To(Equal(expectedApprovalModel.Owner))
|
|
||||||
Expect(model.Spender).To(Equal(expectedApprovalModel.Spender))
|
|
||||||
Expect(model.Tokens).To(Equal(expectedApprovalModel.Tokens))
|
|
||||||
Expect(model.Block).To(Equal(expectedApprovalModel.Block))
|
|
||||||
Expect(model.TxHash).To(Equal(expectedApprovalModel.TxHash))
|
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
@ -15,8 +15,9 @@
|
|||||||
package event_triggered
|
package event_triggered
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TransferEntity struct {
|
type TransferEntity struct {
|
||||||
|
@ -22,12 +22,8 @@ import (
|
|||||||
"github.com/vulcanize/vulcanizedb/examples/erc20_watcher/event_triggered"
|
"github.com/vulcanize/vulcanizedb/examples/erc20_watcher/event_triggered"
|
||||||
"github.com/vulcanize/vulcanizedb/examples/generic"
|
"github.com/vulcanize/vulcanizedb/examples/generic"
|
||||||
"github.com/vulcanize/vulcanizedb/examples/test_helpers"
|
"github.com/vulcanize/vulcanizedb/examples/test_helpers"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/config"
|
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
|
|
||||||
"math/rand"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var transferLog = core.Log{
|
var transferLog = core.Log{
|
||||||
@ -36,7 +32,7 @@ var transferLog = core.Log{
|
|||||||
TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
|
TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
|
||||||
Index: 110,
|
Index: 110,
|
||||||
Topics: [4]string{
|
Topics: [4]string{
|
||||||
constants.TransferEventSignature,
|
constants.TransferEvent.Signature(),
|
||||||
"0x000000000000000000000000000000000000000000000000000000000000af21",
|
"0x000000000000000000000000000000000000000000000000000000000000af21",
|
||||||
"0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391",
|
"0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391",
|
||||||
"",
|
"",
|
||||||
@ -50,7 +46,7 @@ var approvalLog = core.Log{
|
|||||||
TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
|
TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
|
||||||
Index: 110,
|
Index: 110,
|
||||||
Topics: [4]string{
|
Topics: [4]string{
|
||||||
constants.ApprovalEventSignature,
|
constants.ApprovalEvent.Signature(),
|
||||||
"0x000000000000000000000000000000000000000000000000000000000000af21",
|
"0x000000000000000000000000000000000000000000000000000000000000af21",
|
||||||
"0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391",
|
"0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391",
|
||||||
"",
|
"",
|
||||||
@ -74,100 +70,65 @@ var logs = []core.Log{
|
|||||||
|
|
||||||
var _ = Describe("Integration test with vulcanizedb", func() {
|
var _ = Describe("Integration test with vulcanizedb", func() {
|
||||||
var db *postgres.DB
|
var db *postgres.DB
|
||||||
rand.Seed(time.Now().UnixNano())
|
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
var err error
|
db = test_helpers.SetupIntegrationDB(db, logs)
|
||||||
db, err = postgres.NewDB(config.Database{
|
|
||||||
Hostname: "localhost",
|
|
||||||
Name: "vulcanize_private",
|
|
||||||
Port: 5432,
|
|
||||||
}, core.Node{})
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
receiptRepository := repositories.ReceiptRepository{DB: db}
|
|
||||||
blockRepository := *repositories.NewBlockRepository(db)
|
|
||||||
|
|
||||||
blockNumber := rand.Int63()
|
|
||||||
blockId := test_helpers.CreateBlock(blockNumber, blockRepository)
|
|
||||||
|
|
||||||
receipt := core.Receipt{
|
|
||||||
Logs: logs,
|
|
||||||
}
|
|
||||||
receipts := []core.Receipt{receipt}
|
|
||||||
|
|
||||||
err = receiptRepository.CreateReceiptsAndLogs(blockId, receipts)
|
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
|
|
||||||
var vulcanizeLogIds []int64
|
|
||||||
err = db.Select(&vulcanizeLogIds, `SELECT id FROM logs`)
|
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
_, err := db.Exec(`DELETE FROM token_transfers`)
|
db = test_helpers.TearDownIntegrationDB(db)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
_, err = db.Exec(`DELETE FROM token_approvals`)
|
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
_, err = db.Exec(`DELETE FROM log_filters`)
|
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
_, err = db.Exec(`DELETE FROM logs`)
|
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("creates transfer entry for each Transfer event received", func() {
|
It("creates token_transfers entry for each Transfer event received", func() {
|
||||||
transformer := event_triggered.NewTransformer(db, generic.DaiConfig)
|
transformer, err := event_triggered.NewTransformer(db, generic.DaiConfig)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
transformer.Execute()
|
transformer.Execute()
|
||||||
|
|
||||||
var count int
|
var count int
|
||||||
err := db.QueryRow(`SELECT COUNT(*) FROM token_transfers`).Scan(&count)
|
err = db.QueryRow(`SELECT COUNT(*) FROM token_transfers`).Scan(&count)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(count).To(Equal(1))
|
Expect(count).To(Equal(1))
|
||||||
|
|
||||||
type dbRow struct {
|
transfer := event_triggered.TransferModel{}
|
||||||
DBID uint64 `db:"id"`
|
|
||||||
VulcanizeLogID int64 `db:"vulcanize_log_id"`
|
err = db.Get(&transfer, `SELECT
|
||||||
event_triggered.TransferModel
|
token_name,
|
||||||
}
|
token_address,
|
||||||
var transfer dbRow
|
to_address,
|
||||||
err = db.Get(&transfer, `SELECT * FROM token_transfers WHERE block=$1`, logs[0].BlockNumber)
|
from_address,
|
||||||
|
tokens,
|
||||||
|
block,
|
||||||
|
tx
|
||||||
|
FROM token_transfers WHERE block=$1`, logs[0].BlockNumber)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(transfer.TokenName).To(Equal(expectedTransferModel.TokenName))
|
Expect(transfer).To(Equal(expectedTransferModel))
|
||||||
Expect(transfer.TokenAddress).To(Equal(expectedTransferModel.TokenAddress))
|
|
||||||
Expect(transfer.To).To(Equal(expectedTransferModel.To))
|
|
||||||
Expect(transfer.From).To(Equal(expectedTransferModel.From))
|
|
||||||
Expect(transfer.Tokens).To(Equal(expectedTransferModel.Tokens))
|
|
||||||
Expect(transfer.Block).To(Equal(expectedTransferModel.Block))
|
|
||||||
Expect(transfer.TxHash).To(Equal(expectedTransferModel.TxHash))
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("creates approval entry for each Approval event received", func() {
|
It("creates token_approvals entry for each Approval event received", func() {
|
||||||
transformer := event_triggered.NewTransformer(db, generic.DaiConfig)
|
transformer, err := event_triggered.NewTransformer(db, generic.DaiConfig)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
transformer.Execute()
|
transformer.Execute()
|
||||||
|
|
||||||
var count int
|
var count int
|
||||||
err := db.QueryRow(`SELECT COUNT(*) FROM token_approvals`).Scan(&count)
|
err = db.QueryRow(`SELECT COUNT(*) FROM token_approvals`).Scan(&count)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(count).To(Equal(1))
|
Expect(count).To(Equal(1))
|
||||||
|
|
||||||
type dbRow struct {
|
approval := event_triggered.ApprovalModel{}
|
||||||
DBID uint64 `db:"id"`
|
|
||||||
VulcanizeLogID int64 `db:"vulcanize_log_id"`
|
err = db.Get(&approval, `SELECT
|
||||||
event_triggered.ApprovalModel
|
token_name,
|
||||||
}
|
token_address,
|
||||||
var transfer dbRow
|
owner,
|
||||||
err = db.Get(&transfer, `SELECT * FROM token_approvals WHERE block=$1`, logs[0].BlockNumber)
|
spender,
|
||||||
|
tokens,
|
||||||
|
block,
|
||||||
|
tx
|
||||||
|
FROM token_approvals WHERE block=$1`, logs[0].BlockNumber)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(transfer.TokenName).To(Equal(expectedApprovalModel.TokenName))
|
Expect(approval).To(Equal(expectedApprovalModel))
|
||||||
Expect(transfer.TokenAddress).To(Equal(expectedApprovalModel.TokenAddress))
|
|
||||||
Expect(transfer.Owner).To(Equal(expectedApprovalModel.Owner))
|
|
||||||
Expect(transfer.Spender).To(Equal(expectedApprovalModel.Spender))
|
|
||||||
Expect(transfer.Tokens).To(Equal(expectedApprovalModel.Tokens))
|
|
||||||
Expect(transfer.Block).To(Equal(expectedApprovalModel.Block))
|
|
||||||
Expect(transfer.TxHash).To(Equal(expectedApprovalModel.TxHash))
|
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
@ -18,16 +18,16 @@ import (
|
|||||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Datastore interface {
|
type ERC20EventDatastore interface {
|
||||||
CreateTransfer(model TransferModel, vulcanizeLogId int64) error
|
CreateTransfer(model *TransferModel, vulcanizeLogId int64) error
|
||||||
CreateApproval(model ApprovalModel, vulcanizeLogId int64) error
|
CreateApproval(model *ApprovalModel, vulcanizeLogId int64) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type Repository struct {
|
type ERC20EventRepository struct {
|
||||||
*postgres.DB
|
*postgres.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repository Repository) CreateTransfer(transferModel TransferModel, vulcanizeLogId int64) error {
|
func (repository ERC20EventRepository) CreateTransfer(transferModel *TransferModel, vulcanizeLogId int64) error {
|
||||||
_, err := repository.DB.Exec(
|
_, err := repository.DB.Exec(
|
||||||
|
|
||||||
`INSERT INTO token_transfers (vulcanize_log_id, token_name, token_address, to_address, from_address, tokens, block, tx)
|
`INSERT INTO token_transfers (vulcanize_log_id, token_name, token_address, to_address, from_address, tokens, block, tx)
|
||||||
@ -35,14 +35,10 @@ func (repository Repository) CreateTransfer(transferModel TransferModel, vulcani
|
|||||||
ON CONFLICT (vulcanize_log_id) DO NOTHING`,
|
ON CONFLICT (vulcanize_log_id) DO NOTHING`,
|
||||||
vulcanizeLogId, transferModel.TokenName, transferModel.TokenAddress, transferModel.To, transferModel.From, transferModel.Tokens, transferModel.Block, transferModel.TxHash)
|
vulcanizeLogId, transferModel.TokenName, transferModel.TokenAddress, transferModel.To, transferModel.From, transferModel.Tokens, transferModel.Block, transferModel.TxHash)
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repository Repository) CreateApproval(approvalModel ApprovalModel, vulcanizeLogId int64) error {
|
func (repository ERC20EventRepository) CreateApproval(approvalModel *ApprovalModel, vulcanizeLogId int64) error {
|
||||||
_, err := repository.DB.Exec(
|
_, err := repository.DB.Exec(
|
||||||
|
|
||||||
`INSERT INTO token_approvals (vulcanize_log_id, token_name, token_address, owner, spender, tokens, block, tx)
|
`INSERT INTO token_approvals (vulcanize_log_id, token_name, token_address, owner, spender, tokens, block, tx)
|
||||||
@ -50,9 +46,5 @@ func (repository Repository) CreateApproval(approvalModel ApprovalModel, vulcani
|
|||||||
ON CONFLICT (vulcanize_log_id) DO NOTHING`,
|
ON CONFLICT (vulcanize_log_id) DO NOTHING`,
|
||||||
vulcanizeLogId, approvalModel.TokenName, approvalModel.TokenAddress, approvalModel.Owner, approvalModel.Spender, approvalModel.Tokens, approvalModel.Block, approvalModel.TxHash)
|
vulcanizeLogId, approvalModel.TokenName, approvalModel.TokenAddress, approvalModel.Owner, approvalModel.Spender, approvalModel.Tokens, approvalModel.Block, approvalModel.TxHash)
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
@ -15,9 +15,13 @@
|
|||||||
package event_triggered_test
|
package event_triggered_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math/rand"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
"github.com/vulcanize/vulcanizedb/examples/erc20_watcher/event_triggered"
|
"github.com/vulcanize/vulcanizedb/examples/erc20_watcher/event_triggered"
|
||||||
"github.com/vulcanize/vulcanizedb/examples/generic/helpers"
|
"github.com/vulcanize/vulcanizedb/examples/generic/helpers"
|
||||||
"github.com/vulcanize/vulcanizedb/examples/test_helpers"
|
"github.com/vulcanize/vulcanizedb/examples/test_helpers"
|
||||||
@ -25,11 +29,9 @@ import (
|
|||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
|
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
|
||||||
"math/rand"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var transferEntity = event_triggered.TransferEntity{
|
var transferEntity = &event_triggered.TransferEntity{
|
||||||
TokenName: "Dai",
|
TokenName: "Dai",
|
||||||
TokenAddress: common.HexToAddress("0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359"),
|
TokenAddress: common.HexToAddress("0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359"),
|
||||||
Src: common.HexToAddress("0x000000000000000000000000000000000000Af21"),
|
Src: common.HexToAddress("0x000000000000000000000000000000000000Af21"),
|
||||||
@ -39,7 +41,7 @@ var transferEntity = event_triggered.TransferEntity{
|
|||||||
TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
|
TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
|
||||||
}
|
}
|
||||||
|
|
||||||
var approvalEntity = event_triggered.ApprovalEntity{
|
var approvalEntity = &event_triggered.ApprovalEntity{
|
||||||
TokenName: "Dai",
|
TokenName: "Dai",
|
||||||
TokenAddress: common.HexToAddress("0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359"),
|
TokenAddress: common.HexToAddress("0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359"),
|
||||||
Src: common.HexToAddress("0x000000000000000000000000000000000000Af21"),
|
Src: common.HexToAddress("0x000000000000000000000000000000000000Af21"),
|
||||||
@ -51,7 +53,8 @@ var approvalEntity = event_triggered.ApprovalEntity{
|
|||||||
|
|
||||||
var _ = Describe("Approval and Transfer Repository Tests", func() {
|
var _ = Describe("Approval and Transfer Repository Tests", func() {
|
||||||
var db *postgres.DB
|
var db *postgres.DB
|
||||||
var repository event_triggered.Repository
|
var converter event_triggered.ERC20Converter
|
||||||
|
var repository event_triggered.ERC20EventRepository
|
||||||
var logRepository repositories.LogRepository
|
var logRepository repositories.LogRepository
|
||||||
var blockRepository repositories.BlockRepository
|
var blockRepository repositories.BlockRepository
|
||||||
var receiptRepository repositories.ReceiptRepository
|
var receiptRepository repositories.ReceiptRepository
|
||||||
@ -89,7 +92,8 @@ var _ = Describe("Approval and Transfer Repository Tests", func() {
|
|||||||
err = logRepository.Get(&vulcanizeLogId, `SELECT id FROM logs`)
|
err = logRepository.Get(&vulcanizeLogId, `SELECT id FROM logs`)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
repository = event_triggered.Repository{DB: db}
|
repository = event_triggered.ERC20EventRepository{DB: db}
|
||||||
|
converter = event_triggered.ERC20Converter{}
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -97,12 +101,11 @@ var _ = Describe("Approval and Transfer Repository Tests", func() {
|
|||||||
db.Query(`DELETE FROM logs`)
|
db.Query(`DELETE FROM logs`)
|
||||||
db.Query(`DELETE FROM log_filters`)
|
db.Query(`DELETE FROM log_filters`)
|
||||||
db.Query(`DELETE FROM token_transfers`)
|
db.Query(`DELETE FROM token_transfers`)
|
||||||
|
db.Query(`DELETE FROM token_approvals`)
|
||||||
|
|
||||||
repository.DB.Exec(`DELETE FROM token_transfers`)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("Creates a new Transfer record", func() {
|
It("Creates a new Transfer record", func() {
|
||||||
converter := event_triggered.ERC20Converter{}
|
|
||||||
model := converter.ToTransferModel(transferEntity)
|
model := converter.ToTransferModel(transferEntity)
|
||||||
err := repository.CreateTransfer(model, vulcanizeLogId)
|
err := repository.CreateTransfer(model, vulcanizeLogId)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
@ -127,7 +130,6 @@ var _ = Describe("Approval and Transfer Repository Tests", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("does not duplicate token_transfers that have already been seen", func() {
|
It("does not duplicate token_transfers that have already been seen", func() {
|
||||||
converter := event_triggered.ERC20Converter{}
|
|
||||||
model := converter.ToTransferModel(transferEntity)
|
model := converter.ToTransferModel(transferEntity)
|
||||||
|
|
||||||
err := repository.CreateTransfer(model, vulcanizeLogId)
|
err := repository.CreateTransfer(model, vulcanizeLogId)
|
||||||
@ -144,7 +146,6 @@ var _ = Describe("Approval and Transfer Repository Tests", func() {
|
|||||||
It("Removes a Transfer record when the corresponding log is removed", func() {
|
It("Removes a Transfer record when the corresponding log is removed", func() {
|
||||||
var exists bool
|
var exists bool
|
||||||
|
|
||||||
converter := event_triggered.ERC20Converter{}
|
|
||||||
model := converter.ToTransferModel(transferEntity)
|
model := converter.ToTransferModel(transferEntity)
|
||||||
err := repository.CreateTransfer(model, vulcanizeLogId)
|
err := repository.CreateTransfer(model, vulcanizeLogId)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
@ -168,7 +169,6 @@ var _ = Describe("Approval and Transfer Repository Tests", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("Creates a new Approval record", func() {
|
It("Creates a new Approval record", func() {
|
||||||
converter := event_triggered.ERC20Converter{}
|
|
||||||
model := converter.ToApprovalModel(approvalEntity)
|
model := converter.ToApprovalModel(approvalEntity)
|
||||||
err := repository.CreateApproval(model, vulcanizeLogId)
|
err := repository.CreateApproval(model, vulcanizeLogId)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
@ -193,7 +193,6 @@ var _ = Describe("Approval and Transfer Repository Tests", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("does not duplicate token_approvals that have already been seen", func() {
|
It("does not duplicate token_approvals that have already been seen", func() {
|
||||||
converter := event_triggered.ERC20Converter{}
|
|
||||||
model := converter.ToApprovalModel(approvalEntity)
|
model := converter.ToApprovalModel(approvalEntity)
|
||||||
|
|
||||||
err := repository.CreateApproval(model, vulcanizeLogId)
|
err := repository.CreateApproval(model, vulcanizeLogId)
|
||||||
@ -210,7 +209,6 @@ var _ = Describe("Approval and Transfer Repository Tests", func() {
|
|||||||
It("Removes a Approval record when the corresponding log is removed", func() {
|
It("Removes a Approval record when the corresponding log is removed", func() {
|
||||||
var exists bool
|
var exists bool
|
||||||
|
|
||||||
converter := event_triggered.ERC20Converter{}
|
|
||||||
model := converter.ToApprovalModel(approvalEntity)
|
model := converter.ToApprovalModel(approvalEntity)
|
||||||
err := repository.CreateApproval(model, vulcanizeLogId)
|
err := repository.CreateApproval(model, vulcanizeLogId)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
@ -15,9 +15,9 @@
|
|||||||
package event_triggered
|
package event_triggered
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"fmt"
|
|
||||||
"github.com/vulcanize/vulcanizedb/examples/constants"
|
"github.com/vulcanize/vulcanizedb/examples/constants"
|
||||||
"github.com/vulcanize/vulcanizedb/examples/generic"
|
"github.com/vulcanize/vulcanizedb/examples/generic"
|
||||||
"github.com/vulcanize/vulcanizedb/libraries/shared"
|
"github.com/vulcanize/vulcanizedb/libraries/shared"
|
||||||
@ -26,50 +26,56 @@ import (
|
|||||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
|
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DaiTransformer struct {
|
type ERC20EventTransformer struct {
|
||||||
Converter ERC20ConverterInterface
|
Converter ERC20ConverterInterface
|
||||||
WatchedEventRepository datastore.WatchedEventRepository
|
WatchedEventRepository datastore.WatchedEventRepository
|
||||||
FilterRepository datastore.FilterRepository
|
FilterRepository datastore.FilterRepository
|
||||||
Repository Datastore
|
Repository ERC20EventDatastore
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTransformer(db *postgres.DB, config generic.ContractConfig) shared.Transformer {
|
func NewTransformer(db *postgres.DB, config generic.ContractConfig) (shared.Transformer, error) {
|
||||||
var transformer shared.Transformer
|
var transformer shared.Transformer
|
||||||
cnvtr := NewERC20Converter(config)
|
|
||||||
|
cnvtr, err := NewERC20Converter(config)
|
||||||
|
if err != nil {
|
||||||
|
return transformer, err
|
||||||
|
}
|
||||||
|
|
||||||
wer := repositories.WatchedEventRepository{DB: db}
|
wer := repositories.WatchedEventRepository{DB: db}
|
||||||
fr := repositories.FilterRepository{DB: db}
|
fr := repositories.FilterRepository{DB: db}
|
||||||
lkr := Repository{DB: db}
|
lkr := ERC20EventRepository{DB: db}
|
||||||
transformer = &DaiTransformer{
|
transformer = ERC20EventTransformer{
|
||||||
Converter: cnvtr,
|
Converter: cnvtr,
|
||||||
WatchedEventRepository: wer,
|
WatchedEventRepository: wer,
|
||||||
FilterRepository: fr,
|
FilterRepository: fr,
|
||||||
Repository: lkr,
|
Repository: lkr,
|
||||||
}
|
}
|
||||||
for _, filter := range constants.DaiFilters {
|
|
||||||
|
for _, filter := range constants.DaiERC20Filters {
|
||||||
fr.CreateFilter(filter)
|
fr.CreateFilter(filter)
|
||||||
}
|
}
|
||||||
return transformer
|
return transformer, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tr DaiTransformer) Execute() error {
|
func (tr ERC20EventTransformer) Execute() error {
|
||||||
for _, filter := range constants.DaiFilters {
|
for _, filter := range constants.DaiERC20Filters {
|
||||||
watchedEvents, err := tr.WatchedEventRepository.GetWatchedEvents(filter.Name)
|
watchedEvents, err := tr.WatchedEventRepository.GetWatchedEvents(filter.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(fmt.Sprintf("Error fetching events for %s:", filter.Name), err)
|
log.Println(fmt.Sprintf("Error fetching events for %s:", filter.Name), err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, we := range watchedEvents {
|
for _, we := range watchedEvents {
|
||||||
if filter.Name == "Transfer" {
|
if filter.Name == constants.TransferEvent.String() {
|
||||||
entity, err := tr.Converter.ToTransferEntity(*we)
|
entity, err := tr.Converter.ToTransferEntity(*we)
|
||||||
model := tr.Converter.ToTransferModel(*entity)
|
model := tr.Converter.ToTransferModel(entity)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error persisting data for Dai Transfers (watchedEvent.LogID %d):\n %s", we.LogID, err)
|
log.Printf("Error persisting data for Dai Transfers (watchedEvent.LogID %d):\n %s", we.LogID, err)
|
||||||
}
|
}
|
||||||
tr.Repository.CreateTransfer(model, we.LogID)
|
tr.Repository.CreateTransfer(model, we.LogID)
|
||||||
}
|
}
|
||||||
if filter.Name == "Approval" {
|
if filter.Name == constants.ApprovalEvent.String() {
|
||||||
entity, err := tr.Converter.ToApprovalEntity(*we)
|
entity, err := tr.Converter.ToApprovalEntity(*we)
|
||||||
model := tr.Converter.ToApprovalModel(*entity)
|
model := tr.Converter.ToApprovalModel(entity)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error persisting data for Dai Approvals (watchedEvent.LogID %d):\n %s", we.LogID, err)
|
log.Printf("Error persisting data for Dai Approvals (watchedEvent.LogID %d):\n %s", we.LogID, err)
|
||||||
}
|
}
|
||||||
|
@ -17,43 +17,13 @@ package event_triggered_test
|
|||||||
import (
|
import (
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
"github.com/vulcanize/vulcanizedb/examples/constants"
|
"github.com/vulcanize/vulcanizedb/examples/constants"
|
||||||
"github.com/vulcanize/vulcanizedb/examples/erc20_watcher/event_triggered"
|
"github.com/vulcanize/vulcanizedb/examples/erc20_watcher/event_triggered"
|
||||||
"github.com/vulcanize/vulcanizedb/examples/mocks"
|
"github.com/vulcanize/vulcanizedb/examples/mocks"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MockERC20Converter struct {
|
|
||||||
watchedEvents []*core.WatchedEvent
|
|
||||||
transfersToConvert []event_triggered.TransferEntity
|
|
||||||
approvalsToConvert []event_triggered.ApprovalEntity
|
|
||||||
block int64
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mlkc *MockERC20Converter) ToTransferModel(entity event_triggered.TransferEntity) event_triggered.TransferModel {
|
|
||||||
mlkc.transfersToConvert = append(mlkc.transfersToConvert, entity)
|
|
||||||
return event_triggered.TransferModel{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mlkc *MockERC20Converter) ToTransferEntity(watchedEvent core.WatchedEvent) (*event_triggered.TransferEntity, error) {
|
|
||||||
mlkc.watchedEvents = append(mlkc.watchedEvents, &watchedEvent)
|
|
||||||
e := &event_triggered.TransferEntity{Block: watchedEvent.BlockNumber}
|
|
||||||
mlkc.block++
|
|
||||||
return e, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mlkc *MockERC20Converter) ToApprovalModel(entity event_triggered.ApprovalEntity) event_triggered.ApprovalModel {
|
|
||||||
mlkc.approvalsToConvert = append(mlkc.approvalsToConvert, entity)
|
|
||||||
return event_triggered.ApprovalModel{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mlkc *MockERC20Converter) ToApprovalEntity(watchedEvent core.WatchedEvent) (*event_triggered.ApprovalEntity, error) {
|
|
||||||
mlkc.watchedEvents = append(mlkc.watchedEvents, &watchedEvent)
|
|
||||||
e := &event_triggered.ApprovalEntity{Block: watchedEvent.BlockNumber}
|
|
||||||
mlkc.block++
|
|
||||||
return e, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var blockID1 = int64(5428074)
|
var blockID1 = int64(5428074)
|
||||||
var logID1 = int64(113)
|
var logID1 = int64(113)
|
||||||
var blockID2 = int64(5428405)
|
var blockID2 = int64(5428405)
|
||||||
@ -62,12 +32,12 @@ var logID2 = int64(100)
|
|||||||
var fakeWatchedEvents = []*core.WatchedEvent{
|
var fakeWatchedEvents = []*core.WatchedEvent{
|
||||||
{
|
{
|
||||||
LogID: logID1,
|
LogID: logID1,
|
||||||
Name: "Transfer",
|
Name: constants.TransferEvent.String(),
|
||||||
BlockNumber: blockID1,
|
BlockNumber: blockID1,
|
||||||
Address: constants.DaiContractAddress,
|
Address: constants.DaiContractAddress,
|
||||||
TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
|
TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
|
||||||
Index: 110,
|
Index: 110,
|
||||||
Topic0: constants.TransferEventSignature,
|
Topic0: constants.TransferEvent.Signature(),
|
||||||
Topic1: "0x000000000000000000000000000000000000000000000000000000000000af21",
|
Topic1: "0x000000000000000000000000000000000000000000000000000000000000af21",
|
||||||
Topic2: "0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391",
|
Topic2: "0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391",
|
||||||
Topic3: "",
|
Topic3: "",
|
||||||
@ -75,12 +45,12 @@ var fakeWatchedEvents = []*core.WatchedEvent{
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
LogID: logID2,
|
LogID: logID2,
|
||||||
Name: "Approval",
|
Name: constants.ApprovalEvent.String(),
|
||||||
BlockNumber: blockID2,
|
BlockNumber: blockID2,
|
||||||
Address: constants.DaiContractAddress,
|
Address: constants.DaiContractAddress,
|
||||||
TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
|
TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
|
||||||
Index: 110,
|
Index: 110,
|
||||||
Topic0: constants.ApprovalEventSignature,
|
Topic0: constants.ApprovalEvent.Signature(),
|
||||||
Topic1: "0x000000000000000000000000000000000000000000000000000000000000af21",
|
Topic1: "0x000000000000000000000000000000000000000000000000000000000000af21",
|
||||||
Topic2: "0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391",
|
Topic2: "0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391",
|
||||||
Topic3: "",
|
Topic3: "",
|
||||||
@ -89,19 +59,20 @@ var fakeWatchedEvents = []*core.WatchedEvent{
|
|||||||
}
|
}
|
||||||
|
|
||||||
var _ = Describe("Mock ERC20 transformer", func() {
|
var _ = Describe("Mock ERC20 transformer", func() {
|
||||||
var mockERC20Converter MockERC20Converter
|
var mockERC20Converter mocks.MockERC20Converter
|
||||||
var watchedEventsRepo mocks.MockWatchedEventsRepository
|
var watchedEventsRepo mocks.MockWatchedEventsRepository
|
||||||
var mockEventRepo mocks.MockEventRepo
|
var mockEventRepo mocks.MockEventRepo
|
||||||
var filterRepo mocks.MockFilterRepository
|
var filterRepo mocks.MockFilterRepository
|
||||||
var transformer event_triggered.DaiTransformer
|
var transformer event_triggered.ERC20EventTransformer
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
mockERC20Converter = MockERC20Converter{}
|
mockERC20Converter = mocks.MockERC20Converter{}
|
||||||
watchedEventsRepo = mocks.MockWatchedEventsRepository{}
|
watchedEventsRepo = mocks.MockWatchedEventsRepository{}
|
||||||
watchedEventsRepo.SetWatchedEvents(fakeWatchedEvents)
|
watchedEventsRepo.SetWatchedEvents(fakeWatchedEvents)
|
||||||
mockEventRepo = mocks.MockEventRepo{}
|
mockEventRepo = mocks.MockEventRepo{}
|
||||||
filterRepo = mocks.MockFilterRepository{}
|
filterRepo = mocks.MockFilterRepository{}
|
||||||
transformer = event_triggered.DaiTransformer{
|
|
||||||
|
transformer = event_triggered.ERC20EventTransformer{
|
||||||
Converter: &mockERC20Converter,
|
Converter: &mockERC20Converter,
|
||||||
WatchedEventRepository: &watchedEventsRepo,
|
WatchedEventRepository: &watchedEventsRepo,
|
||||||
FilterRepository: filterRepo,
|
FilterRepository: filterRepo,
|
||||||
@ -112,22 +83,22 @@ var _ = Describe("Mock ERC20 transformer", func() {
|
|||||||
It("calls the watched events repo with correct filter", func() {
|
It("calls the watched events repo with correct filter", func() {
|
||||||
transformer.Execute()
|
transformer.Execute()
|
||||||
Expect(len(watchedEventsRepo.Names)).To(Equal(2))
|
Expect(len(watchedEventsRepo.Names)).To(Equal(2))
|
||||||
Expect(watchedEventsRepo.Names).To(ConsistOf([]string{"Transfer", "Approval"}))
|
Expect(watchedEventsRepo.Names).To(ConsistOf([]string{constants.TransferEvent.String(), constants.ApprovalEvent.String()}))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("calls the mock ERC20 converter with the watched events", func() {
|
It("calls the mock ERC20 converter with the watched events", func() {
|
||||||
transformer.Execute()
|
transformer.Execute()
|
||||||
Expect(len(mockERC20Converter.watchedEvents)).To(Equal(2))
|
Expect(len(mockERC20Converter.WatchedEvents)).To(Equal(2))
|
||||||
Expect(mockERC20Converter.watchedEvents).To(ConsistOf(fakeWatchedEvents))
|
Expect(mockERC20Converter.WatchedEvents).To(ConsistOf(fakeWatchedEvents))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("converts a Transfer entity to a model", func() {
|
It("converts a Transfer and Approval entity to their models", func() {
|
||||||
transformer.Execute()
|
transformer.Execute()
|
||||||
Expect(len(mockERC20Converter.transfersToConvert)).To(Equal(1))
|
Expect(len(mockERC20Converter.TransfersToConvert)).To(Equal(1))
|
||||||
Expect(mockERC20Converter.transfersToConvert[0].Block).To(Equal(blockID1))
|
Expect(mockERC20Converter.TransfersToConvert[0].Block).To(Equal(blockID1))
|
||||||
|
|
||||||
Expect(len(mockERC20Converter.approvalsToConvert)).To(Equal(1))
|
Expect(len(mockERC20Converter.ApprovalsToConvert)).To(Equal(1))
|
||||||
Expect(mockERC20Converter.approvalsToConvert[0].Block).To(Equal(blockID2))
|
Expect(mockERC20Converter.ApprovalsToConvert[0].Block).To(Equal(blockID2))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("persists Transfer and Approval data for each watched Transfer or Approval event", func() {
|
It("persists Transfer and Approval data for each watched Transfer or Approval event", func() {
|
||||||
|
@ -15,12 +15,12 @@
|
|||||||
package every_block_test
|
package every_block_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestEveryBlock(t *testing.T) {
|
func TestEveryBlock(t *testing.T) {
|
||||||
|
@ -32,13 +32,13 @@ type ERC20GetterInterface interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Getter struct
|
// Getter struct
|
||||||
type Getter struct {
|
type ERC20Getter struct {
|
||||||
fetcher generic.Fetcher
|
fetcher generic.Fetcher
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initializes and returns a Getter with the given blockchain
|
// Initializes and returns a Getter with the given blockchain
|
||||||
func NewGetter(blockChain core.BlockChain) Getter {
|
func NewGetter(blockChain core.BlockChain) ERC20Getter {
|
||||||
return Getter{
|
return ERC20Getter{
|
||||||
fetcher: generic.Fetcher{
|
fetcher: generic.Fetcher{
|
||||||
BlockChain: blockChain,
|
BlockChain: blockChain,
|
||||||
},
|
},
|
||||||
@ -46,19 +46,19 @@ func NewGetter(blockChain core.BlockChain) Getter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Public getter methods for calling contract methods
|
// Public getter methods for calling contract methods
|
||||||
func (g Getter) GetTotalSupply(contractAbi, contractAddress string, blockNumber int64) (big.Int, error) {
|
func (g ERC20Getter) GetTotalSupply(contractAbi, contractAddress string, blockNumber int64) (big.Int, error) {
|
||||||
return g.fetcher.FetchBigInt("totalSupply", contractAbi, contractAddress, blockNumber, nil)
|
return g.fetcher.FetchBigInt("totalSupply", contractAbi, contractAddress, blockNumber, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g Getter) GetBalance(contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (big.Int, error) {
|
func (g ERC20Getter) GetBalance(contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (big.Int, error) {
|
||||||
return g.fetcher.FetchBigInt("balanceOf", contractAbi, contractAddress, blockNumber, methodArgs)
|
return g.fetcher.FetchBigInt("balanceOf", contractAbi, contractAddress, blockNumber, methodArgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g Getter) GetAllowance(contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (big.Int, error) {
|
func (g ERC20Getter) GetAllowance(contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (big.Int, error) {
|
||||||
return g.fetcher.FetchBigInt("allowance", contractAbi, contractAddress, blockNumber, methodArgs)
|
return g.fetcher.FetchBigInt("allowance", contractAbi, contractAddress, blockNumber, methodArgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method to retrieve the Getter's blockchain
|
// Method to retrieve the Getter's blockchain
|
||||||
func (g Getter) GetBlockChain() core.BlockChain {
|
func (g ERC20Getter) GetBlockChain() core.BlockChain {
|
||||||
return g.fetcher.BlockChain
|
return g.fetcher.BlockChain
|
||||||
}
|
}
|
||||||
|
@ -17,12 +17,12 @@ package every_block_test
|
|||||||
import (
|
import (
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/ethclient"
|
"github.com/ethereum/go-ethereum/ethclient"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
"github.com/vulcanize/vulcanizedb/examples/constants"
|
"github.com/vulcanize/vulcanizedb/examples/constants"
|
||||||
"github.com/vulcanize/vulcanizedb/examples/erc20_watcher/every_block"
|
"github.com/vulcanize/vulcanizedb/examples/erc20_watcher/every_block"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
||||||
|
@ -15,8 +15,12 @@
|
|||||||
package every_block_test
|
package every_block_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math/big"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
"github.com/vulcanize/vulcanizedb/examples/constants"
|
"github.com/vulcanize/vulcanizedb/examples/constants"
|
||||||
"github.com/vulcanize/vulcanizedb/examples/erc20_watcher/every_block"
|
"github.com/vulcanize/vulcanizedb/examples/erc20_watcher/every_block"
|
||||||
"github.com/vulcanize/vulcanizedb/examples/generic"
|
"github.com/vulcanize/vulcanizedb/examples/generic"
|
||||||
@ -25,8 +29,6 @@ import (
|
|||||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
|
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
||||||
"math/big"
|
|
||||||
"strconv"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func setLastBlockOnChain(blockChain *fakes.MockBlockChain, blockNumber int64) {
|
func setLastBlockOnChain(blockChain *fakes.MockBlockChain, blockNumber int64) {
|
||||||
|
@ -16,12 +16,13 @@ package every_block
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Interface definition for a generic ERC20 token repository
|
// Interface definition for a generic ERC20 token repository
|
||||||
type ERC20RepositoryInterface interface {
|
type ERC20TokenDatastore interface {
|
||||||
CreateSupply(supply TokenSupply) error
|
CreateSupply(supply TokenSupply) error
|
||||||
CreateBalance(balance TokenBalance) error
|
CreateBalance(balance TokenBalance) error
|
||||||
CreateAllowance(allowance TokenAllowance) error
|
CreateAllowance(allowance TokenAllowance) error
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
package every_block_test
|
package every_block_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math/rand"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
@ -24,7 +26,6 @@ import (
|
|||||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
|
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
|
||||||
"github.com/vulcanize/vulcanizedb/test_config"
|
"github.com/vulcanize/vulcanizedb/test_config"
|
||||||
"math/rand"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("ERC20 Token Supply Repository", func() {
|
var _ = Describe("ERC20 Token Supply Repository", func() {
|
||||||
|
@ -16,23 +16,25 @@ package every_block
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
|
||||||
"github.com/vulcanize/vulcanizedb/examples/generic"
|
"github.com/vulcanize/vulcanizedb/examples/generic"
|
||||||
"github.com/vulcanize/vulcanizedb/libraries/shared"
|
"github.com/vulcanize/vulcanizedb/libraries/shared"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||||
"log"
|
|
||||||
"math/big"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Transformer struct {
|
type ERC20Transformer struct {
|
||||||
Getter ERC20GetterInterface
|
Getter ERC20GetterInterface
|
||||||
Repository ERC20RepositoryInterface
|
Repository ERC20TokenDatastore
|
||||||
Retriever generic.Retriever
|
Retriever generic.TokenHolderRetriever
|
||||||
Config generic.ContractConfig
|
Config generic.ContractConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Transformer) SetConfiguration(config generic.ContractConfig) {
|
func (t *ERC20Transformer) SetConfiguration(config generic.ContractConfig) {
|
||||||
t.Config = config
|
t.Config = config
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,8 +45,8 @@ type ERC20TokenTransformerInitializer struct {
|
|||||||
func (i ERC20TokenTransformerInitializer) NewERC20TokenTransformer(db *postgres.DB, blockchain core.BlockChain) shared.Transformer {
|
func (i ERC20TokenTransformerInitializer) NewERC20TokenTransformer(db *postgres.DB, blockchain core.BlockChain) shared.Transformer {
|
||||||
getter := NewGetter(blockchain)
|
getter := NewGetter(blockchain)
|
||||||
repository := ERC20TokenRepository{DB: db}
|
repository := ERC20TokenRepository{DB: db}
|
||||||
retriever := generic.NewRetriever(db, i.Config.Address)
|
retriever := generic.NewTokenHolderRetriever(db, i.Config.Address)
|
||||||
transformer := Transformer{
|
transformer := ERC20Transformer{
|
||||||
Getter: &getter,
|
Getter: &getter,
|
||||||
Repository: &repository,
|
Repository: &repository,
|
||||||
Retriever: retriever,
|
Retriever: retriever,
|
||||||
@ -81,7 +83,7 @@ func newTransformerError(err error, blockNumber int64, msg string) error {
|
|||||||
return &e
|
return &e
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t Transformer) Execute() error {
|
func (t ERC20Transformer) Execute() error {
|
||||||
var upperBoundBlock int64
|
var upperBoundBlock int64
|
||||||
blockchain := t.Getter.GetBlockChain()
|
blockchain := t.Getter.GetBlockChain()
|
||||||
lastBlock := blockchain.LastBlock().Int64()
|
lastBlock := blockchain.LastBlock().Int64()
|
||||||
|
@ -15,17 +15,19 @@
|
|||||||
package every_block_test
|
package every_block_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math/big"
|
||||||
|
"math/rand"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
"github.com/vulcanize/vulcanizedb/examples/constants"
|
"github.com/vulcanize/vulcanizedb/examples/constants"
|
||||||
"github.com/vulcanize/vulcanizedb/examples/erc20_watcher/every_block"
|
"github.com/vulcanize/vulcanizedb/examples/erc20_watcher/every_block"
|
||||||
"github.com/vulcanize/vulcanizedb/examples/generic"
|
"github.com/vulcanize/vulcanizedb/examples/generic"
|
||||||
"github.com/vulcanize/vulcanizedb/examples/mocks"
|
"github.com/vulcanize/vulcanizedb/examples/mocks"
|
||||||
"github.com/vulcanize/vulcanizedb/examples/test_helpers"
|
"github.com/vulcanize/vulcanizedb/examples/test_helpers"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
||||||
"math/big"
|
|
||||||
"math/rand"
|
|
||||||
"strconv"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var testContractConfig = generic.ContractConfig{
|
var testContractConfig = generic.ContractConfig{
|
||||||
@ -41,7 +43,7 @@ var config = testContractConfig
|
|||||||
var _ = Describe("Everyblock transformer", func() {
|
var _ = Describe("Everyblock transformer", func() {
|
||||||
var getter mocks.Getter
|
var getter mocks.Getter
|
||||||
var repository mocks.ERC20TokenRepository
|
var repository mocks.ERC20TokenRepository
|
||||||
var transformer every_block.Transformer
|
var transformer every_block.ERC20Transformer
|
||||||
var blockChain *fakes.MockBlockChain
|
var blockChain *fakes.MockBlockChain
|
||||||
var initialSupply = "27647235749155415536952630"
|
var initialSupply = "27647235749155415536952630"
|
||||||
var initialSupplyPlusOne = "27647235749155415536952631"
|
var initialSupplyPlusOne = "27647235749155415536952631"
|
||||||
@ -57,10 +59,10 @@ var _ = Describe("Everyblock transformer", func() {
|
|||||||
repository = mocks.ERC20TokenRepository{}
|
repository = mocks.ERC20TokenRepository{}
|
||||||
repository.SetMissingSupplyBlocks([]int64{config.FirstBlock})
|
repository.SetMissingSupplyBlocks([]int64{config.FirstBlock})
|
||||||
db := test_helpers.CreateNewDatabase()
|
db := test_helpers.CreateNewDatabase()
|
||||||
rt := generic.NewRetriever(db, config.Address)
|
rt := generic.NewTokenHolderRetriever(db, config.Address)
|
||||||
//setting the mock repository to return the first block as the missing blocks
|
//setting the mock repository to return the first block as the missing blocks
|
||||||
|
|
||||||
transformer = every_block.Transformer{
|
transformer = every_block.ERC20Transformer{
|
||||||
Getter: &getter,
|
Getter: &getter,
|
||||||
Repository: &repository,
|
Repository: &repository,
|
||||||
Retriever: rt,
|
Retriever: rt,
|
||||||
@ -150,7 +152,7 @@ var _ = Describe("Everyblock transformer", func() {
|
|||||||
It("returns an error if the call to get missing blocks fails", func() {
|
It("returns an error if the call to get missing blocks fails", func() {
|
||||||
failureRepository := mocks.FailureRepository{}
|
failureRepository := mocks.FailureRepository{}
|
||||||
failureRepository.SetMissingSupplyBlocksFail(true)
|
failureRepository.SetMissingSupplyBlocksFail(true)
|
||||||
transformer = every_block.Transformer{
|
transformer = every_block.ERC20Transformer{
|
||||||
Getter: &getter,
|
Getter: &getter,
|
||||||
Repository: &failureRepository,
|
Repository: &failureRepository,
|
||||||
}
|
}
|
||||||
@ -165,7 +167,7 @@ var _ = Describe("Everyblock transformer", func() {
|
|||||||
failureBlockchain.SetLastBlock(&defaultLastBlock)
|
failureBlockchain.SetLastBlock(&defaultLastBlock)
|
||||||
failureBlockchain.SetFetchContractDataErr(fakes.FakeError)
|
failureBlockchain.SetFetchContractDataErr(fakes.FakeError)
|
||||||
getter := every_block.NewGetter(failureBlockchain)
|
getter := every_block.NewGetter(failureBlockchain)
|
||||||
transformer = every_block.Transformer{
|
transformer = every_block.ERC20Transformer{
|
||||||
Getter: &getter,
|
Getter: &getter,
|
||||||
Repository: &repository,
|
Repository: &repository,
|
||||||
}
|
}
|
||||||
@ -180,7 +182,7 @@ var _ = Describe("Everyblock transformer", func() {
|
|||||||
failureRepository.SetMissingSupplyBlocks([]int64{config.FirstBlock})
|
failureRepository.SetMissingSupplyBlocks([]int64{config.FirstBlock})
|
||||||
failureRepository.SetCreateSupplyFail(true)
|
failureRepository.SetCreateSupplyFail(true)
|
||||||
|
|
||||||
transformer = every_block.Transformer{
|
transformer = every_block.ERC20Transformer{
|
||||||
Getter: &getter,
|
Getter: &getter,
|
||||||
Repository: &failureRepository,
|
Repository: &failureRepository,
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
|
|
||||||
type ContractConfig struct {
|
type ContractConfig struct {
|
||||||
Address string
|
Address string
|
||||||
|
Owner string
|
||||||
Abi string
|
Abi string
|
||||||
ParsedAbi abi.ABI
|
ParsedAbi abi.ABI
|
||||||
FirstBlock int64
|
FirstBlock int64
|
||||||
@ -30,9 +31,18 @@ type ContractConfig struct {
|
|||||||
|
|
||||||
var DaiConfig = ContractConfig{
|
var DaiConfig = ContractConfig{
|
||||||
Address: constants.DaiContractAddress,
|
Address: constants.DaiContractAddress,
|
||||||
|
Owner: constants.DaiContractOwner,
|
||||||
Abi: constants.DaiAbiString,
|
Abi: constants.DaiAbiString,
|
||||||
ParsedAbi: constants.ParsedDaiAbi,
|
|
||||||
FirstBlock: int64(4752008),
|
FirstBlock: int64(4752008),
|
||||||
LastBlock: -1,
|
LastBlock: -1,
|
||||||
Name: "Dai",
|
Name: "Dai",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var TusdConfig = ContractConfig{
|
||||||
|
Address: constants.TusdContractAddress,
|
||||||
|
Owner: constants.TusdContractOwner,
|
||||||
|
Abi: constants.TusdAbiString,
|
||||||
|
FirstBlock: int64(5197514),
|
||||||
|
LastBlock: -1,
|
||||||
|
Name: "Tusd",
|
||||||
|
}
|
||||||
|
117
examples/generic/event_triggered/converter.go
Normal file
117
examples/generic/event_triggered/converter.go
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
// Copyright 2018 Vulcanize
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package event_triggered
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
|
||||||
|
"github.com/vulcanize/vulcanizedb/examples/constants"
|
||||||
|
"github.com/vulcanize/vulcanizedb/examples/generic"
|
||||||
|
"github.com/vulcanize/vulcanizedb/examples/generic/helpers"
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/geth"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Converter converts a raw event log into its corresponding entity
|
||||||
|
// and can subsequently convert the entity into a model
|
||||||
|
|
||||||
|
type GenericConverterInterface interface {
|
||||||
|
ToBurnEntity(watchedEvent core.WatchedEvent) (*BurnEntity, error)
|
||||||
|
ToBurnModel(entity *BurnEntity) *BurnModel
|
||||||
|
ToMintEntity(watchedEvent core.WatchedEvent) (*MintEntity, error)
|
||||||
|
ToMintModel(entity *MintEntity) *MintModel
|
||||||
|
}
|
||||||
|
|
||||||
|
type GenericConverter struct {
|
||||||
|
config generic.ContractConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGenericConverter(config generic.ContractConfig) (*GenericConverter, error) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
config.ParsedAbi, err = geth.ParseAbi(config.Abi)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
converter := &GenericConverter{
|
||||||
|
config: config,
|
||||||
|
}
|
||||||
|
|
||||||
|
return converter, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c GenericConverter) ToBurnEntity(watchedEvent core.WatchedEvent) (*BurnEntity, error) {
|
||||||
|
result := &BurnEntity{}
|
||||||
|
contract := bind.NewBoundContract(common.HexToAddress(c.config.Address), c.config.ParsedAbi, nil, nil, nil)
|
||||||
|
event := helpers.ConvertToLog(watchedEvent)
|
||||||
|
err := contract.UnpackLog(result, constants.BurnEvent.String(), event)
|
||||||
|
if err != nil {
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
result.TokenName = c.config.Name
|
||||||
|
result.TokenAddress = common.HexToAddress(c.config.Address)
|
||||||
|
result.Block = watchedEvent.BlockNumber
|
||||||
|
result.TxHash = watchedEvent.TxHash
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c GenericConverter) ToBurnModel(entity *BurnEntity) *BurnModel {
|
||||||
|
burner := entity.Burner.String()
|
||||||
|
tokens := entity.Value.String()
|
||||||
|
|
||||||
|
return &BurnModel{
|
||||||
|
TokenName: c.config.Name,
|
||||||
|
TokenAddress: c.config.Address,
|
||||||
|
Burner: burner,
|
||||||
|
Tokens: tokens,
|
||||||
|
Block: entity.Block,
|
||||||
|
TxHash: entity.TxHash,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c GenericConverter) ToMintEntity(watchedEvent core.WatchedEvent) (*MintEntity, error) {
|
||||||
|
result := &MintEntity{}
|
||||||
|
contract := bind.NewBoundContract(common.HexToAddress(c.config.Address), c.config.ParsedAbi, nil, nil, nil)
|
||||||
|
event := helpers.ConvertToLog(watchedEvent)
|
||||||
|
err := contract.UnpackLog(result, constants.MintEvent.String(), event)
|
||||||
|
if err != nil {
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
result.TokenName = c.config.Name
|
||||||
|
result.TokenAddress = common.HexToAddress(c.config.Address)
|
||||||
|
result.Block = watchedEvent.BlockNumber
|
||||||
|
result.TxHash = watchedEvent.TxHash
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c GenericConverter) ToMintModel(entity *MintEntity) *MintModel {
|
||||||
|
mintee := entity.To.String()
|
||||||
|
minter := c.config.Owner
|
||||||
|
tokens := entity.Amount.String()
|
||||||
|
|
||||||
|
return &MintModel{
|
||||||
|
TokenName: c.config.Name,
|
||||||
|
TokenAddress: c.config.Address,
|
||||||
|
Mintee: mintee,
|
||||||
|
Minter: minter,
|
||||||
|
Tokens: tokens,
|
||||||
|
Block: entity.Block,
|
||||||
|
TxHash: entity.TxHash,
|
||||||
|
}
|
||||||
|
}
|
148
examples/generic/event_triggered/converter_test.go
Normal file
148
examples/generic/event_triggered/converter_test.go
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
// Copyright 2018 Vulcanize
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package event_triggered_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
|
"github.com/vulcanize/vulcanizedb/examples/constants"
|
||||||
|
"github.com/vulcanize/vulcanizedb/examples/generic"
|
||||||
|
"github.com/vulcanize/vulcanizedb/examples/generic/event_triggered"
|
||||||
|
"github.com/vulcanize/vulcanizedb/examples/generic/helpers"
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
|
)
|
||||||
|
|
||||||
|
var expectedBurnModel = event_triggered.BurnModel{
|
||||||
|
TokenName: "Tusd",
|
||||||
|
TokenAddress: constants.TusdContractAddress,
|
||||||
|
Burner: "0x09BbBBE21a5975cAc061D82f7b843bCE061BA391",
|
||||||
|
Tokens: "1097077688018008265106216665536940668749033598146",
|
||||||
|
Block: 5488076,
|
||||||
|
TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
|
||||||
|
}
|
||||||
|
|
||||||
|
var expectedBurnEntity = event_triggered.BurnEntity{
|
||||||
|
TokenName: "Tusd",
|
||||||
|
TokenAddress: common.HexToAddress(constants.TusdContractAddress),
|
||||||
|
Burner: common.HexToAddress("0x09BbBBE21a5975cAc061D82f7b843bCE061BA391"),
|
||||||
|
Value: helpers.BigFromString("1097077688018008265106216665536940668749033598146"),
|
||||||
|
Block: 5488076,
|
||||||
|
TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
|
||||||
|
}
|
||||||
|
|
||||||
|
var expectedMintModel = event_triggered.MintModel{
|
||||||
|
TokenName: "Tusd",
|
||||||
|
TokenAddress: constants.TusdContractAddress,
|
||||||
|
Minter: constants.TusdContractOwner,
|
||||||
|
Mintee: "0x09BbBBE21a5975cAc061D82f7b843bCE061BA391",
|
||||||
|
Tokens: "1097077688018008265106216665536940668749033598146",
|
||||||
|
Block: 5488076,
|
||||||
|
TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
|
||||||
|
}
|
||||||
|
|
||||||
|
var expectedMintEntity = event_triggered.MintEntity{
|
||||||
|
TokenName: "Tusd",
|
||||||
|
TokenAddress: common.HexToAddress(constants.TusdContractAddress),
|
||||||
|
To: common.HexToAddress("0x09BbBBE21a5975cAc061D82f7b843bCE061BA391"),
|
||||||
|
Amount: helpers.BigFromString("1097077688018008265106216665536940668749033598146"),
|
||||||
|
Block: 5488076,
|
||||||
|
TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
|
||||||
|
}
|
||||||
|
|
||||||
|
var burnEvent = core.WatchedEvent{
|
||||||
|
LogID: 1,
|
||||||
|
Name: constants.BurnEvent.String(),
|
||||||
|
BlockNumber: 5488076,
|
||||||
|
Address: constants.TusdContractAddress,
|
||||||
|
TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
|
||||||
|
Index: 110,
|
||||||
|
Topic0: constants.BurnEvent.Signature(),
|
||||||
|
Topic1: "0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391",
|
||||||
|
Topic2: "",
|
||||||
|
Topic3: "",
|
||||||
|
Data: "0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000089d24a6b4ccb1b6faa2625fe562bdd9a23260359000000000000000000000000000000000000000000000000392d2e2bda9c00000000000000000000000000000000000000000000000000927f41fa0a4a418000000000000000000000000000000000000000000000000000000000005adcfebe",
|
||||||
|
}
|
||||||
|
|
||||||
|
var mintEvent = core.WatchedEvent{
|
||||||
|
LogID: 1,
|
||||||
|
Name: constants.MintEvent.String(),
|
||||||
|
BlockNumber: 5488076,
|
||||||
|
Address: constants.TusdContractAddress,
|
||||||
|
TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
|
||||||
|
Index: 110,
|
||||||
|
Topic0: constants.MintEvent.Signature(),
|
||||||
|
Topic1: "0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391",
|
||||||
|
Topic2: "",
|
||||||
|
Topic3: "",
|
||||||
|
Data: "0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000089d24a6b4ccb1b6faa2625fe562bdd9a23260359000000000000000000000000000000000000000000000000392d2e2bda9c00000000000000000000000000000000000000000000000000927f41fa0a4a418000000000000000000000000000000000000000000000000000000000005adcfebe",
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ = Describe("Transfer Converter", func() {
|
||||||
|
|
||||||
|
var converter *event_triggered.GenericConverter
|
||||||
|
var err error
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
converter, err = event_triggered.NewGenericConverter(generic.TusdConfig)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("converts a watched burn event into a BurnEntity", func() {
|
||||||
|
|
||||||
|
result, err := converter.ToBurnEntity(burnEvent)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(result).To(Equal(&expectedBurnEntity))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("converts a BurnEntity to a BurnModel", func() {
|
||||||
|
|
||||||
|
result, err := converter.ToBurnEntity(burnEvent)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
model := converter.ToBurnModel(result)
|
||||||
|
Expect(model).To(Equal(&expectedBurnModel))
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
var _ = Describe("Approval Converter", func() {
|
||||||
|
|
||||||
|
var converter *event_triggered.GenericConverter
|
||||||
|
var err error
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
converter, err = event_triggered.NewGenericConverter(generic.TusdConfig)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("converts a watched mint event into a MintEntity", func() {
|
||||||
|
|
||||||
|
result, err := converter.ToMintEntity(mintEvent)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(result).To(Equal(&expectedMintEntity))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("converts a MintEntity to a MintModel", func() {
|
||||||
|
|
||||||
|
result, err := converter.ToMintEntity(mintEvent)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
model := converter.ToMintModel(result)
|
||||||
|
Expect(model).To(Equal(&expectedMintModel))
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
39
examples/generic/event_triggered/entity.go
Normal file
39
examples/generic/event_triggered/entity.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// Copyright 2018 Vulcanize
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package event_triggered
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BurnEntity struct {
|
||||||
|
TokenName string
|
||||||
|
TokenAddress common.Address
|
||||||
|
Burner common.Address
|
||||||
|
Value *big.Int
|
||||||
|
Block int64
|
||||||
|
TxHash string
|
||||||
|
}
|
||||||
|
|
||||||
|
type MintEntity struct {
|
||||||
|
TokenName string
|
||||||
|
TokenAddress common.Address
|
||||||
|
To common.Address
|
||||||
|
Amount *big.Int
|
||||||
|
Block int64
|
||||||
|
TxHash string
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
// Copyright 2018 Vulcanize
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package event_triggered_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestLogKill(t *testing.T) {
|
||||||
|
RegisterFailHandler(Fail)
|
||||||
|
RunSpecs(t, "ERC20 Event Triggered test Suite")
|
||||||
|
}
|
133
examples/generic/event_triggered/integration_test.go
Normal file
133
examples/generic/event_triggered/integration_test.go
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
// Copyright 2018 Vulcanize
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package event_triggered_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
|
"github.com/vulcanize/vulcanizedb/examples/constants"
|
||||||
|
"github.com/vulcanize/vulcanizedb/examples/generic"
|
||||||
|
"github.com/vulcanize/vulcanizedb/examples/generic/event_triggered"
|
||||||
|
"github.com/vulcanize/vulcanizedb/examples/test_helpers"
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||||
|
)
|
||||||
|
|
||||||
|
var burnLog = core.Log{
|
||||||
|
BlockNumber: 5488076,
|
||||||
|
Address: constants.TusdContractAddress,
|
||||||
|
TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
|
||||||
|
Index: 110,
|
||||||
|
Topics: [4]string{
|
||||||
|
constants.BurnEvent.Signature(),
|
||||||
|
"0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
},
|
||||||
|
Data: "0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000089d24a6b4ccb1b6faa2625fe562bdd9a23260359000000000000000000000000000000000000000000000000392d2e2bda9c00000000000000000000000000000000000000000000000000927f41fa0a4a418000000000000000000000000000000000000000000000000000000000005adcfebe",
|
||||||
|
}
|
||||||
|
|
||||||
|
var mintLog = core.Log{
|
||||||
|
BlockNumber: 5488076,
|
||||||
|
Address: constants.TusdContractAddress,
|
||||||
|
TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
|
||||||
|
Index: 110,
|
||||||
|
Topics: [4]string{
|
||||||
|
constants.MintEvent.Signature(),
|
||||||
|
"0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
},
|
||||||
|
Data: "0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000089d24a6b4ccb1b6faa2625fe562bdd9a23260359000000000000000000000000000000000000000000000000392d2e2bda9c00000000000000000000000000000000000000000000000000927f41fa0a4a418000000000000000000000000000000000000000000000000000000000005adcfebe",
|
||||||
|
}
|
||||||
|
|
||||||
|
//converted transfer to assert against
|
||||||
|
var logs = []core.Log{
|
||||||
|
burnLog,
|
||||||
|
mintLog,
|
||||||
|
{
|
||||||
|
BlockNumber: 0,
|
||||||
|
TxHash: "",
|
||||||
|
Address: "",
|
||||||
|
Topics: core.Topics{},
|
||||||
|
Index: 0,
|
||||||
|
Data: "",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ = Describe("Integration test with vulcanizedb", func() {
|
||||||
|
var db *postgres.DB
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
db = test_helpers.SetupIntegrationDB(db, logs)
|
||||||
|
})
|
||||||
|
|
||||||
|
AfterEach(func() {
|
||||||
|
db = test_helpers.TearDownIntegrationDB(db)
|
||||||
|
})
|
||||||
|
|
||||||
|
It("creates token_burns entry for each Burn event received", func() {
|
||||||
|
transformer, err := event_triggered.NewTransformer(db, generic.TusdConfig)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
transformer.Execute()
|
||||||
|
|
||||||
|
var count int
|
||||||
|
err = db.QueryRow(`SELECT COUNT(*) FROM token_burns`).Scan(&count)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(count).To(Equal(1))
|
||||||
|
|
||||||
|
burn := event_triggered.BurnModel{}
|
||||||
|
|
||||||
|
err = db.Get(&burn, `SELECT
|
||||||
|
token_name,
|
||||||
|
token_address,
|
||||||
|
burner,
|
||||||
|
tokens,
|
||||||
|
block,
|
||||||
|
tx
|
||||||
|
FROM token_burns WHERE block=$1`, logs[0].BlockNumber)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(burn).To(Equal(expectedBurnModel))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("creates token_mints entry for each Mint event received", func() {
|
||||||
|
transformer, err := event_triggered.NewTransformer(db, generic.TusdConfig)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
transformer.Execute()
|
||||||
|
|
||||||
|
var count int
|
||||||
|
err = db.QueryRow(`SELECT COUNT(*) FROM token_mints`).Scan(&count)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(count).To(Equal(1))
|
||||||
|
|
||||||
|
mint := event_triggered.MintModel{}
|
||||||
|
|
||||||
|
err = db.Get(&mint, `SELECT
|
||||||
|
token_name,
|
||||||
|
token_address,
|
||||||
|
minter,
|
||||||
|
mintee,
|
||||||
|
tokens,
|
||||||
|
block,
|
||||||
|
tx
|
||||||
|
FROM token_mints WHERE block=$1`, logs[0].BlockNumber)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(mint).To(Equal(expectedMintModel))
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
34
examples/generic/event_triggered/model.go
Normal file
34
examples/generic/event_triggered/model.go
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// Copyright 2018 Vulcanize
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package event_triggered
|
||||||
|
|
||||||
|
type BurnModel struct {
|
||||||
|
TokenName string `db:"token_name"`
|
||||||
|
TokenAddress string `db:"token_address"`
|
||||||
|
Burner string `db:"burner"`
|
||||||
|
Tokens string `db:"tokens"`
|
||||||
|
Block int64 `db:"block"`
|
||||||
|
TxHash string `db:"tx"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MintModel struct {
|
||||||
|
TokenName string `db:"token_name"`
|
||||||
|
TokenAddress string `db:"token_address"`
|
||||||
|
Mintee string `db:"mintee"`
|
||||||
|
Minter string `db:"minter"`
|
||||||
|
Tokens string `db:"tokens"`
|
||||||
|
Block int64 `db:"block"`
|
||||||
|
TxHash string `db:"tx"`
|
||||||
|
}
|
50
examples/generic/event_triggered/repository.go
Normal file
50
examples/generic/event_triggered/repository.go
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// Copyright 2018 Vulcanize
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package event_triggered
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GenericEventDatastore interface {
|
||||||
|
CreateBurn(model *BurnModel, vulcanizeLogId int64) error
|
||||||
|
CreateMint(model *MintModel, vulcanizeLogId int64) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type GenericEventRepository struct {
|
||||||
|
*postgres.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func (repository GenericEventRepository) CreateBurn(burnModel *BurnModel, vulcanizeLogId int64) error {
|
||||||
|
_, err := repository.DB.Exec(
|
||||||
|
|
||||||
|
`INSERT INTO token_burns (vulcanize_log_id, token_name, token_address, burner, tokens, block, tx)
|
||||||
|
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
||||||
|
ON CONFLICT (vulcanize_log_id) DO NOTHING`,
|
||||||
|
vulcanizeLogId, burnModel.TokenName, burnModel.TokenAddress, burnModel.Burner, burnModel.Tokens, burnModel.Block, burnModel.TxHash)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (repository GenericEventRepository) CreateMint(mintModel *MintModel, vulcanizeLogId int64) error {
|
||||||
|
_, err := repository.DB.Exec(
|
||||||
|
|
||||||
|
`INSERT INTO token_mints (vulcanize_log_id, token_name, token_address, minter, mintee, tokens, block, tx)
|
||||||
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
||||||
|
ON CONFLICT (vulcanize_log_id) DO NOTHING`,
|
||||||
|
vulcanizeLogId, mintModel.TokenName, mintModel.TokenAddress, mintModel.Minter, mintModel.Mintee, mintModel.Tokens, mintModel.Block, mintModel.TxHash)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
229
examples/generic/event_triggered/repository_test.go
Normal file
229
examples/generic/event_triggered/repository_test.go
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
// Copyright 2018 Vulcanize
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package event_triggered_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/rand"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
|
"github.com/vulcanize/vulcanizedb/examples/generic/event_triggered"
|
||||||
|
"github.com/vulcanize/vulcanizedb/examples/generic/helpers"
|
||||||
|
"github.com/vulcanize/vulcanizedb/examples/test_helpers"
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/config"
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
|
||||||
|
)
|
||||||
|
|
||||||
|
var burnEntity = &event_triggered.BurnEntity{
|
||||||
|
TokenName: "Tusd",
|
||||||
|
TokenAddress: common.HexToAddress("0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359"),
|
||||||
|
Burner: common.HexToAddress("0x09BbBBE21a5975cAc061D82f7b843bCE061BA391"),
|
||||||
|
Value: helpers.BigFromString("1097077688018008265106216665536940668749033598146"),
|
||||||
|
Block: 5488076,
|
||||||
|
TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
|
||||||
|
}
|
||||||
|
|
||||||
|
var mintEntity = &event_triggered.MintEntity{
|
||||||
|
TokenName: "Tusd",
|
||||||
|
TokenAddress: common.HexToAddress("0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359"),
|
||||||
|
To: common.HexToAddress("0x09BbBBE21a5975cAc061D82f7b843bCE061BA391"),
|
||||||
|
Amount: helpers.BigFromString("1097077688018008265106216665536940668749033598146"),
|
||||||
|
Block: 5488076,
|
||||||
|
TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ = Describe("Approval and Transfer Repository Tests", func() {
|
||||||
|
var db *postgres.DB
|
||||||
|
var converter event_triggered.GenericConverter
|
||||||
|
var repository event_triggered.GenericEventRepository
|
||||||
|
var logRepository repositories.LogRepository
|
||||||
|
var blockRepository repositories.BlockRepository
|
||||||
|
var receiptRepository repositories.ReceiptRepository
|
||||||
|
var blockNumber int64
|
||||||
|
var blockId int64
|
||||||
|
var vulcanizeLogId int64
|
||||||
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
var err error
|
||||||
|
db, err = postgres.NewDB(config.Database{
|
||||||
|
Hostname: "localhost",
|
||||||
|
Name: "vulcanize_private",
|
||||||
|
Port: 5432,
|
||||||
|
}, core.Node{})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
receiptRepository = repositories.ReceiptRepository{DB: db}
|
||||||
|
logRepository = repositories.LogRepository{DB: db}
|
||||||
|
blockRepository = *repositories.NewBlockRepository(db)
|
||||||
|
|
||||||
|
blockNumber = rand.Int63()
|
||||||
|
blockId = test_helpers.CreateBlock(blockNumber, blockRepository)
|
||||||
|
|
||||||
|
log := core.Log{}
|
||||||
|
logs := []core.Log{log}
|
||||||
|
receipt := core.Receipt{
|
||||||
|
Logs: logs,
|
||||||
|
}
|
||||||
|
receipts := []core.Receipt{receipt}
|
||||||
|
|
||||||
|
err = receiptRepository.CreateReceiptsAndLogs(blockId, receipts)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
err = logRepository.Get(&vulcanizeLogId, `SELECT id FROM logs`)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
repository = event_triggered.GenericEventRepository{DB: db}
|
||||||
|
converter = event_triggered.GenericConverter{}
|
||||||
|
})
|
||||||
|
|
||||||
|
AfterEach(func() {
|
||||||
|
db.Query(`DELETE FROM logs`)
|
||||||
|
db.Query(`DELETE FROM log_filters`)
|
||||||
|
db.Query(`DELETE FROM token_burns`)
|
||||||
|
db.Query(`DELETE FROM token_mints`)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
It("Creates a new Burn record", func() {
|
||||||
|
model := converter.ToBurnModel(burnEntity)
|
||||||
|
err := repository.CreateBurn(model, vulcanizeLogId)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
type DBRow struct {
|
||||||
|
DBID uint64 `db:"id"`
|
||||||
|
VulcanizeLogID int64 `db:"vulcanize_log_id"`
|
||||||
|
event_triggered.BurnModel
|
||||||
|
}
|
||||||
|
dbResult := DBRow{}
|
||||||
|
|
||||||
|
err = repository.QueryRowx(`SELECT * FROM token_burns`).StructScan(&dbResult)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
Expect(dbResult.VulcanizeLogID).To(Equal(vulcanizeLogId))
|
||||||
|
Expect(dbResult.TokenName).To(Equal(model.TokenName))
|
||||||
|
Expect(dbResult.TokenAddress).To(Equal(model.TokenAddress))
|
||||||
|
Expect(dbResult.Burner).To(Equal(model.Burner))
|
||||||
|
Expect(dbResult.Tokens).To(Equal(model.Tokens))
|
||||||
|
Expect(dbResult.Block).To(Equal(model.Block))
|
||||||
|
Expect(dbResult.TxHash).To(Equal(model.TxHash))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("does not duplicate token_transfers that have already been seen", func() {
|
||||||
|
model := converter.ToBurnModel(burnEntity)
|
||||||
|
|
||||||
|
err := repository.CreateBurn(model, vulcanizeLogId)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
err = repository.CreateBurn(model, vulcanizeLogId)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
var count int
|
||||||
|
err = repository.DB.QueryRowx(`SELECT count(*) FROM token_burns`).Scan(&count)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(count).To(Equal(1))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("Removes a Burn record when the corresponding log is removed", func() {
|
||||||
|
var exists bool
|
||||||
|
|
||||||
|
model := converter.ToBurnModel(burnEntity)
|
||||||
|
err := repository.CreateBurn(model, vulcanizeLogId)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
err = repository.DB.QueryRow(`SELECT exists (SELECT * FROM token_burns WHERE vulcanize_log_id = $1)`, vulcanizeLogId).Scan(&exists)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(exists).To(BeTrue())
|
||||||
|
|
||||||
|
var logCount int
|
||||||
|
_, err = logRepository.DB.Exec(`DELETE FROM logs WHERE id = $1`, vulcanizeLogId)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
err = logRepository.Get(&logCount, `SELECT count(*) FROM logs WHERE id = $1`, vulcanizeLogId)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(logCount).To(BeZero())
|
||||||
|
|
||||||
|
var LogKillCount int
|
||||||
|
err = repository.DB.QueryRowx(
|
||||||
|
`SELECT count(*) FROM token_burns WHERE vulcanize_log_id = $1`, vulcanizeLogId).Scan(&LogKillCount)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(LogKillCount).To(BeZero())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("Creates a new Mint record", func() {
|
||||||
|
model := converter.ToMintModel(mintEntity)
|
||||||
|
err := repository.CreateMint(model, vulcanizeLogId)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
type DBRow struct {
|
||||||
|
DBID uint64 `db:"id"`
|
||||||
|
VulcanizeLogID int64 `db:"vulcanize_log_id"`
|
||||||
|
event_triggered.MintModel
|
||||||
|
}
|
||||||
|
dbResult := DBRow{}
|
||||||
|
|
||||||
|
err = repository.QueryRowx(`SELECT * FROM token_mints`).StructScan(&dbResult)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
Expect(dbResult.VulcanizeLogID).To(Equal(vulcanizeLogId))
|
||||||
|
Expect(dbResult.TokenName).To(Equal(model.TokenName))
|
||||||
|
Expect(dbResult.TokenAddress).To(Equal(model.TokenAddress))
|
||||||
|
Expect(dbResult.Mintee).To(Equal(model.Mintee))
|
||||||
|
Expect(dbResult.Minter).To(Equal(model.Minter))
|
||||||
|
Expect(dbResult.Tokens).To(Equal(model.Tokens))
|
||||||
|
Expect(dbResult.Block).To(Equal(model.Block))
|
||||||
|
Expect(dbResult.TxHash).To(Equal(model.TxHash))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("does not duplicate token_mints that have already been seen", func() {
|
||||||
|
model := converter.ToMintModel(mintEntity)
|
||||||
|
|
||||||
|
err := repository.CreateMint(model, vulcanizeLogId)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
err = repository.CreateMint(model, vulcanizeLogId)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
var count int
|
||||||
|
err = repository.DB.QueryRowx(`SELECT count(*) FROM token_mints`).Scan(&count)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(count).To(Equal(1))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("Removes a Mint record when the corresponding log is removed", func() {
|
||||||
|
var exists bool
|
||||||
|
|
||||||
|
model := converter.ToMintModel(mintEntity)
|
||||||
|
err := repository.CreateMint(model, vulcanizeLogId)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
err = repository.DB.QueryRow(`SELECT exists (SELECT * FROM token_mints WHERE vulcanize_log_id = $1)`, vulcanizeLogId).Scan(&exists)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(exists).To(BeTrue())
|
||||||
|
|
||||||
|
var logCount int
|
||||||
|
_, err = logRepository.DB.Exec(`DELETE FROM logs WHERE id = $1`, vulcanizeLogId)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
err = logRepository.Get(&logCount, `SELECT count(*) FROM logs WHERE id = $1`, vulcanizeLogId)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(logCount).To(BeZero())
|
||||||
|
|
||||||
|
var LogKillCount int
|
||||||
|
err = repository.DB.QueryRowx(
|
||||||
|
`SELECT count(*) FROM token_mints WHERE vulcanize_log_id = $1`, vulcanizeLogId).Scan(&LogKillCount)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(LogKillCount).To(BeZero())
|
||||||
|
})
|
||||||
|
})
|
87
examples/generic/event_triggered/transformer.go
Normal file
87
examples/generic/event_triggered/transformer.go
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
// Copyright 2018 Vulcanize
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package event_triggered
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/vulcanize/vulcanizedb/examples/constants"
|
||||||
|
"github.com/vulcanize/vulcanizedb/examples/generic"
|
||||||
|
"github.com/vulcanize/vulcanizedb/libraries/shared"
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/datastore"
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GenericTransformer struct {
|
||||||
|
Converter GenericConverterInterface
|
||||||
|
WatchedEventRepository datastore.WatchedEventRepository
|
||||||
|
FilterRepository datastore.FilterRepository
|
||||||
|
Repository GenericEventDatastore
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTransformer(db *postgres.DB, config generic.ContractConfig) (shared.Transformer, error) {
|
||||||
|
var transformer shared.Transformer
|
||||||
|
|
||||||
|
cnvtr, err := NewGenericConverter(config)
|
||||||
|
if err != nil {
|
||||||
|
return transformer, err
|
||||||
|
}
|
||||||
|
|
||||||
|
wer := repositories.WatchedEventRepository{DB: db}
|
||||||
|
fr := repositories.FilterRepository{DB: db}
|
||||||
|
lkr := GenericEventRepository{DB: db}
|
||||||
|
transformer = GenericTransformer{
|
||||||
|
Converter: cnvtr,
|
||||||
|
WatchedEventRepository: wer,
|
||||||
|
FilterRepository: fr,
|
||||||
|
Repository: lkr,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, filter := range constants.TusdGenericFilters {
|
||||||
|
fr.CreateFilter(filter)
|
||||||
|
}
|
||||||
|
return transformer, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tr GenericTransformer) Execute() error {
|
||||||
|
for _, filter := range constants.TusdGenericFilters {
|
||||||
|
watchedEvents, err := tr.WatchedEventRepository.GetWatchedEvents(filter.Name)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(fmt.Sprintf("Error fetching events for %s:", filter.Name), err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, we := range watchedEvents {
|
||||||
|
if filter.Name == constants.BurnEvent.String() {
|
||||||
|
entity, err := tr.Converter.ToBurnEntity(*we)
|
||||||
|
model := tr.Converter.ToBurnModel(entity)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error persisting data for Dai Burns (watchedEvent.LogID %d):\n %s", we.LogID, err)
|
||||||
|
}
|
||||||
|
tr.Repository.CreateBurn(model, we.LogID)
|
||||||
|
}
|
||||||
|
if filter.Name == constants.MintEvent.String() {
|
||||||
|
entity, err := tr.Converter.ToMintEntity(*we)
|
||||||
|
model := tr.Converter.ToMintModel(entity)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error persisting data for Dai Mints (watchedEvent.LogID %d):\n %s", we.LogID, err)
|
||||||
|
}
|
||||||
|
tr.Repository.CreateMint(model, we.LogID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
111
examples/generic/event_triggered/transformer_test.go
Normal file
111
examples/generic/event_triggered/transformer_test.go
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
// Copyright 2018 Vulcanize
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package event_triggered_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
|
"github.com/vulcanize/vulcanizedb/examples/constants"
|
||||||
|
"github.com/vulcanize/vulcanizedb/examples/generic/event_triggered"
|
||||||
|
"github.com/vulcanize/vulcanizedb/examples/mocks"
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
|
)
|
||||||
|
|
||||||
|
var blockID1 = int64(5428074)
|
||||||
|
var logID1 = int64(113)
|
||||||
|
var blockID2 = int64(5428405)
|
||||||
|
var logID2 = int64(100)
|
||||||
|
|
||||||
|
var fakeWatchedEvents = []*core.WatchedEvent{
|
||||||
|
{
|
||||||
|
LogID: logID1,
|
||||||
|
Name: constants.BurnEvent.String(),
|
||||||
|
BlockNumber: blockID1,
|
||||||
|
Address: constants.TusdContractAddress,
|
||||||
|
TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
|
||||||
|
Index: 110,
|
||||||
|
Topic0: constants.BurnEvent.Signature(),
|
||||||
|
Topic1: "0x000000000000000000000000000000000000000000000000000000000000af21",
|
||||||
|
Topic2: "0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391",
|
||||||
|
Topic3: "",
|
||||||
|
Data: "0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000089d24a6b4ccb1b6faa2625fe562bdd9a23260359000000000000000000000000000000000000000000000000392d2e2bda9c00000000000000000000000000000000000000000000000000927f41fa0a4a418000000000000000000000000000000000000000000000000000000000005adcfebe",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
LogID: logID2,
|
||||||
|
Name: constants.MintEvent.String(),
|
||||||
|
BlockNumber: blockID2,
|
||||||
|
Address: constants.TusdContractAddress,
|
||||||
|
TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
|
||||||
|
Index: 110,
|
||||||
|
Topic0: constants.MintEvent.Signature(),
|
||||||
|
Topic1: "0x000000000000000000000000000000000000000000000000000000000000af21",
|
||||||
|
Topic2: "0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391",
|
||||||
|
Topic3: "",
|
||||||
|
Data: "0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000089d24a6b4ccb1b6faa2625fe562bdd9a23260359000000000000000000000000000000000000000000000000392d2e2bda9c00000000000000000000000000000000000000000000000000927f41fa0a4a418000000000000000000000000000000000000000000000000000000000005adcfebe",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ = Describe("Mock ERC20 transformer", func() {
|
||||||
|
var mockERC20Converter mocks.MockERC20Converter
|
||||||
|
var watchedEventsRepo mocks.MockWatchedEventsRepository
|
||||||
|
var mockEventRepo mocks.MockEventRepo
|
||||||
|
var filterRepo mocks.MockFilterRepository
|
||||||
|
var transformer event_triggered.GenericTransformer
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
mockERC20Converter = mocks.MockERC20Converter{}
|
||||||
|
watchedEventsRepo = mocks.MockWatchedEventsRepository{}
|
||||||
|
watchedEventsRepo.SetWatchedEvents(fakeWatchedEvents)
|
||||||
|
mockEventRepo = mocks.MockEventRepo{}
|
||||||
|
filterRepo = mocks.MockFilterRepository{}
|
||||||
|
|
||||||
|
transformer = event_triggered.GenericTransformer{
|
||||||
|
Converter: &mockERC20Converter,
|
||||||
|
WatchedEventRepository: &watchedEventsRepo,
|
||||||
|
FilterRepository: filterRepo,
|
||||||
|
Repository: &mockEventRepo,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
It("calls the watched events repo with correct filter", func() {
|
||||||
|
transformer.Execute()
|
||||||
|
Expect(len(watchedEventsRepo.Names)).To(Equal(2))
|
||||||
|
Expect(watchedEventsRepo.Names).To(ConsistOf([]string{constants.BurnEvent.String(), constants.MintEvent.String()}))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("calls the mock ERC20 converter with the watched events", func() {
|
||||||
|
transformer.Execute()
|
||||||
|
Expect(len(mockERC20Converter.WatchedEvents)).To(Equal(2))
|
||||||
|
Expect(mockERC20Converter.WatchedEvents).To(ConsistOf(fakeWatchedEvents))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("converts a Burn and Mint entity to their models", func() {
|
||||||
|
transformer.Execute()
|
||||||
|
Expect(len(mockERC20Converter.BurnsToConvert)).To(Equal(1))
|
||||||
|
Expect(mockERC20Converter.BurnsToConvert[0].Block).To(Equal(blockID1))
|
||||||
|
|
||||||
|
Expect(len(mockERC20Converter.MintsToConvert)).To(Equal(1))
|
||||||
|
Expect(mockERC20Converter.MintsToConvert[0].Block).To(Equal(blockID2))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("persists Burn and Mint data for each watched Burn or Mint event", func() {
|
||||||
|
transformer.Execute()
|
||||||
|
Expect(len(mockEventRepo.BurnLogs)).To(Equal(1))
|
||||||
|
Expect(len(mockEventRepo.MintLogs)).To(Equal(1))
|
||||||
|
Expect(mockEventRepo.VulcanizeLogIDs).To(ConsistOf(logID1, logID2))
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
@ -15,12 +15,12 @@
|
|||||||
package every_block_test
|
package every_block_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestEveryBlock(t *testing.T) {
|
func TestEveryBlock(t *testing.T) {
|
||||||
|
@ -15,10 +15,12 @@
|
|||||||
package every_block
|
package every_block
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
|
||||||
"github.com/vulcanize/vulcanizedb/examples/generic"
|
"github.com/vulcanize/vulcanizedb/examples/generic"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
"math/big"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Getter serves as a higher level data fetcher that invokes its underlying Fetcher methods for a given contract method
|
// Getter serves as a higher level data fetcher that invokes its underlying Fetcher methods for a given contract method
|
||||||
@ -36,13 +38,13 @@ type GenericGetterInterface interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Getter struct
|
// Getter struct
|
||||||
type Getter struct {
|
type GenericGetter struct {
|
||||||
fetcher generic.Fetcher // Underlying Fetcher
|
fetcher generic.Fetcher // Underlying Fetcher
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initializes and returns a Getter with the given blockchain
|
// Initializes and returns a Getter with the given blockchain
|
||||||
func NewGetter(blockChain core.BlockChain) Getter {
|
func NewGetter(blockChain core.BlockChain) GenericGetter {
|
||||||
return Getter{
|
return GenericGetter{
|
||||||
fetcher: generic.Fetcher{
|
fetcher: generic.Fetcher{
|
||||||
BlockChain: blockChain,
|
BlockChain: blockChain,
|
||||||
},
|
},
|
||||||
@ -50,35 +52,35 @@ func NewGetter(blockChain core.BlockChain) Getter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Public getter methods for calling contract methods
|
// Public getter methods for calling contract methods
|
||||||
func (g Getter) GetOwner(contractAbi, contractAddress string, blockNumber int64) (common.Address, error) {
|
func (g GenericGetter) GetOwner(contractAbi, contractAddress string, blockNumber int64) (common.Address, error) {
|
||||||
return g.fetcher.FetchAddress("owner", contractAbi, contractAddress, blockNumber, nil)
|
return g.fetcher.FetchAddress("owner", contractAbi, contractAddress, blockNumber, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g Getter) GetStoppedStatus(contractAbi, contractAddress string, blockNumber int64) (bool, error) {
|
func (g GenericGetter) GetStoppedStatus(contractAbi, contractAddress string, blockNumber int64) (bool, error) {
|
||||||
return g.fetcher.FetchBool("stopped", contractAbi, contractAddress, blockNumber, nil)
|
return g.fetcher.FetchBool("stopped", contractAbi, contractAddress, blockNumber, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g Getter) GetStringName(contractAbi, contractAddress string, blockNumber int64) (string, error) {
|
func (g GenericGetter) GetStringName(contractAbi, contractAddress string, blockNumber int64) (string, error) {
|
||||||
return g.fetcher.FetchString("name", contractAbi, contractAddress, blockNumber, nil)
|
return g.fetcher.FetchString("name", contractAbi, contractAddress, blockNumber, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g Getter) GetHashName(contractAbi, contractAddress string, blockNumber int64) (common.Hash, error) {
|
func (g GenericGetter) GetHashName(contractAbi, contractAddress string, blockNumber int64) (common.Hash, error) {
|
||||||
return g.fetcher.FetchHash("name", contractAbi, contractAddress, blockNumber, nil)
|
return g.fetcher.FetchHash("name", contractAbi, contractAddress, blockNumber, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g Getter) GetStringSymbol(contractAbi, contractAddress string, blockNumber int64) (string, error) {
|
func (g GenericGetter) GetStringSymbol(contractAbi, contractAddress string, blockNumber int64) (string, error) {
|
||||||
return g.fetcher.FetchString("symbol", contractAbi, contractAddress, blockNumber, nil)
|
return g.fetcher.FetchString("symbol", contractAbi, contractAddress, blockNumber, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g Getter) GetHashSymbol(contractAbi, contractAddress string, blockNumber int64) (common.Hash, error) {
|
func (g GenericGetter) GetHashSymbol(contractAbi, contractAddress string, blockNumber int64) (common.Hash, error) {
|
||||||
return g.fetcher.FetchHash("symbol", contractAbi, contractAddress, blockNumber, nil)
|
return g.fetcher.FetchHash("symbol", contractAbi, contractAddress, blockNumber, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g Getter) GetDecimals(contractAbi, contractAddress string, blockNumber int64) (big.Int, error) {
|
func (g GenericGetter) GetDecimals(contractAbi, contractAddress string, blockNumber int64) (big.Int, error) {
|
||||||
return g.fetcher.FetchBigInt("decimals", contractAbi, contractAddress, blockNumber, nil)
|
return g.fetcher.FetchBigInt("decimals", contractAbi, contractAddress, blockNumber, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method to retrieve the Getter's blockchain
|
// Method to retrieve the Getter's blockchain
|
||||||
func (g Getter) GetBlockChain() core.BlockChain {
|
func (g GenericGetter) GetBlockChain() core.BlockChain {
|
||||||
return g.fetcher.BlockChain
|
return g.fetcher.BlockChain
|
||||||
}
|
}
|
||||||
|
@ -15,12 +15,14 @@
|
|||||||
package every_block_test
|
package every_block_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/ethclient"
|
"github.com/ethereum/go-ethereum/ethclient"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
"github.com/vulcanize/vulcanizedb/examples/constants"
|
"github.com/vulcanize/vulcanizedb/examples/constants"
|
||||||
"github.com/vulcanize/vulcanizedb/examples/generic/every_block"
|
"github.com/vulcanize/vulcanizedb/examples/generic/every_block"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
||||||
@ -28,7 +30,6 @@ import (
|
|||||||
"github.com/vulcanize/vulcanizedb/pkg/geth/client"
|
"github.com/vulcanize/vulcanizedb/pkg/geth/client"
|
||||||
rpc2 "github.com/vulcanize/vulcanizedb/pkg/geth/converters/rpc"
|
rpc2 "github.com/vulcanize/vulcanizedb/pkg/geth/converters/rpc"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/geth/node"
|
"github.com/vulcanize/vulcanizedb/pkg/geth/node"
|
||||||
"math/big"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("every_block Getter", func() {
|
var _ = Describe("every_block Getter", func() {
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -16,21 +16,25 @@ package generic
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Retriever is used to iterate over addresses going into or out of a contract
|
// Retriever is used to iterate over addresses going into or out of a contract
|
||||||
// address in an attempt to generate a list of token holder addresses
|
// address in an attempt to generate a list of token holder addresses
|
||||||
|
|
||||||
type RetrieverInterface interface {
|
type TokenHolderRetrieverInterface interface {
|
||||||
retrieveTransferEventAddresses() ([][2]string, error)
|
RetrieveTokenHolderAddresses() (map[common.Address]bool, error)
|
||||||
retrieveApprovalEventAddresses() ([][2]string, error)
|
retrieveTokenSenders() ([]string, error)
|
||||||
RetrieveContractAssociatedAddresses() (map[common.Address]bool, error)
|
retrieveTokenReceivers() ([]string, error)
|
||||||
|
retrieveTokenOwners() ([]string, error)
|
||||||
|
retrieveTokenSpenders() ([]string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Retriever struct {
|
type TokenHolderRetriever struct {
|
||||||
Database *postgres.DB
|
Database *postgres.DB
|
||||||
ContractAddress string
|
ContractAddress string
|
||||||
}
|
}
|
||||||
@ -59,16 +63,18 @@ const (
|
|||||||
GetReceiversError = "Error fetching token receivers from contract %s: %s"
|
GetReceiversError = "Error fetching token receivers from contract %s: %s"
|
||||||
GetOwnersError = "Error fetching token owners from contract %s: %s"
|
GetOwnersError = "Error fetching token owners from contract %s: %s"
|
||||||
GetSpendersError = "Error fetching token spenders from contract %s: %s"
|
GetSpendersError = "Error fetching token spenders from contract %s: %s"
|
||||||
|
GetMinteesError = "Error fetching token mintees from contract %s: %s"
|
||||||
|
GetBurnersError = "Error fetching token burners from contract %s: %s"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewRetriever(db *postgres.DB, address string) Retriever {
|
func NewTokenHolderRetriever(db *postgres.DB, address string) TokenHolderRetriever {
|
||||||
return Retriever{
|
return TokenHolderRetriever{
|
||||||
Database: db,
|
Database: db,
|
||||||
ContractAddress: address,
|
ContractAddress: address,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rt Retriever) retrieveTokenSenders() ([]string, error) {
|
func (rt TokenHolderRetriever) retrieveTokenSenders() ([]string, error) {
|
||||||
|
|
||||||
senders := make([]string, 0)
|
senders := make([]string, 0)
|
||||||
|
|
||||||
@ -81,10 +87,11 @@ func (rt Retriever) retrieveTokenSenders() ([]string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return []string{}, newRetrieverError(err, GetSendersError, rt.ContractAddress)
|
return []string{}, newRetrieverError(err, GetSendersError, rt.ContractAddress)
|
||||||
}
|
}
|
||||||
return senders, err
|
|
||||||
|
return senders, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rt Retriever) retrieveTokenReceivers() ([]string, error) {
|
func (rt TokenHolderRetriever) retrieveTokenReceivers() ([]string, error) {
|
||||||
|
|
||||||
receivers := make([]string, 0)
|
receivers := make([]string, 0)
|
||||||
|
|
||||||
@ -100,7 +107,41 @@ func (rt Retriever) retrieveTokenReceivers() ([]string, error) {
|
|||||||
return receivers, err
|
return receivers, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rt Retriever) retrieveTokenOwners() ([]string, error) {
|
func (rt TokenHolderRetriever) retrieveTokenMintees() ([]string, error) {
|
||||||
|
|
||||||
|
mintees := make([]string, 0)
|
||||||
|
|
||||||
|
err := rt.Database.DB.Select(
|
||||||
|
&mintees,
|
||||||
|
`SELECT mintee FROM token_mints
|
||||||
|
WHERE token_address = $1`,
|
||||||
|
rt.ContractAddress,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return []string{}, newRetrieverError(err, GetMinteesError, rt.ContractAddress)
|
||||||
|
}
|
||||||
|
|
||||||
|
return mintees, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rt TokenHolderRetriever) retrieveTokenBurners() ([]string, error) {
|
||||||
|
|
||||||
|
burners := make([]string, 0)
|
||||||
|
|
||||||
|
err := rt.Database.DB.Select(
|
||||||
|
&burners,
|
||||||
|
`SELECT burner FROM token_burns
|
||||||
|
WHERE token_address = $1`,
|
||||||
|
rt.ContractAddress,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return []string{}, newRetrieverError(err, GetBurnersError, rt.ContractAddress)
|
||||||
|
}
|
||||||
|
|
||||||
|
return burners, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rt TokenHolderRetriever) retrieveTokenOwners() ([]string, error) {
|
||||||
|
|
||||||
owners := make([]string, 0)
|
owners := make([]string, 0)
|
||||||
|
|
||||||
@ -113,10 +154,11 @@ func (rt Retriever) retrieveTokenOwners() ([]string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return []string{}, newRetrieverError(err, GetOwnersError, rt.ContractAddress)
|
return []string{}, newRetrieverError(err, GetOwnersError, rt.ContractAddress)
|
||||||
}
|
}
|
||||||
return owners, err
|
|
||||||
|
return owners, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rt Retriever) retrieveTokenSpenders() ([]string, error) {
|
func (rt TokenHolderRetriever) retrieveTokenSpenders() ([]string, error) {
|
||||||
|
|
||||||
spenders := make([]string, 0)
|
spenders := make([]string, 0)
|
||||||
|
|
||||||
@ -129,10 +171,11 @@ func (rt Retriever) retrieveTokenSpenders() ([]string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return []string{}, newRetrieverError(err, GetSpendersError, rt.ContractAddress)
|
return []string{}, newRetrieverError(err, GetSpendersError, rt.ContractAddress)
|
||||||
}
|
}
|
||||||
return spenders, err
|
|
||||||
|
return spenders, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rt Retriever) RetrieveTokenHolderAddresses() (map[common.Address]bool, error) {
|
func (rt TokenHolderRetriever) RetrieveTokenHolderAddresses() (map[common.Address]bool, error) {
|
||||||
|
|
||||||
senders, err := rt.retrieveTokenSenders()
|
senders, err := rt.retrieveTokenSenders()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -144,6 +187,16 @@ func (rt Retriever) RetrieveTokenHolderAddresses() (map[common.Address]bool, err
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mintees, err := rt.retrieveTokenMintees()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
burners, err := rt.retrieveTokenBurners()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
owners, err := rt.retrieveTokenOwners()
|
owners, err := rt.retrieveTokenOwners()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -164,6 +217,14 @@ func (rt Retriever) RetrieveTokenHolderAddresses() (map[common.Address]bool, err
|
|||||||
contractAddresses[common.HexToAddress(addr)] = true
|
contractAddresses[common.HexToAddress(addr)] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, addr := range mintees {
|
||||||
|
contractAddresses[common.HexToAddress(addr)] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, addr := range burners {
|
||||||
|
contractAddresses[common.HexToAddress(addr)] = true
|
||||||
|
}
|
||||||
|
|
||||||
for _, addr := range owners {
|
for _, addr := range owners {
|
||||||
contractAddresses[common.HexToAddress(addr)] = true
|
contractAddresses[common.HexToAddress(addr)] = true
|
||||||
}
|
}
|
||||||
|
78
examples/mocks/converter.go
Normal file
78
examples/mocks/converter.go
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
// Copyright 2018 Vulcanize
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package mocks
|
||||||
|
|
||||||
|
import (
|
||||||
|
et1 "github.com/vulcanize/vulcanizedb/examples/erc20_watcher/event_triggered"
|
||||||
|
et2 "github.com/vulcanize/vulcanizedb/examples/generic/event_triggered"
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MockERC20Converter struct {
|
||||||
|
WatchedEvents []*core.WatchedEvent
|
||||||
|
TransfersToConvert []et1.TransferEntity
|
||||||
|
ApprovalsToConvert []et1.ApprovalEntity
|
||||||
|
BurnsToConvert []et2.BurnEntity
|
||||||
|
MintsToConvert []et2.MintEntity
|
||||||
|
block int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mlkc *MockERC20Converter) ToTransferModel(entity *et1.TransferEntity) *et1.TransferModel {
|
||||||
|
mlkc.TransfersToConvert = append(mlkc.TransfersToConvert, *entity)
|
||||||
|
return &et1.TransferModel{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mlkc *MockERC20Converter) ToTransferEntity(watchedEvent core.WatchedEvent) (*et1.TransferEntity, error) {
|
||||||
|
mlkc.WatchedEvents = append(mlkc.WatchedEvents, &watchedEvent)
|
||||||
|
e := &et1.TransferEntity{Block: watchedEvent.BlockNumber}
|
||||||
|
mlkc.block++
|
||||||
|
return e, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mlkc *MockERC20Converter) ToApprovalModel(entity *et1.ApprovalEntity) *et1.ApprovalModel {
|
||||||
|
mlkc.ApprovalsToConvert = append(mlkc.ApprovalsToConvert, *entity)
|
||||||
|
return &et1.ApprovalModel{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mlkc *MockERC20Converter) ToApprovalEntity(watchedEvent core.WatchedEvent) (*et1.ApprovalEntity, error) {
|
||||||
|
mlkc.WatchedEvents = append(mlkc.WatchedEvents, &watchedEvent)
|
||||||
|
e := &et1.ApprovalEntity{Block: watchedEvent.BlockNumber}
|
||||||
|
mlkc.block++
|
||||||
|
return e, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mlkc *MockERC20Converter) ToBurnEntity(watchedEvent core.WatchedEvent) (*et2.BurnEntity, error) {
|
||||||
|
mlkc.WatchedEvents = append(mlkc.WatchedEvents, &watchedEvent)
|
||||||
|
e := &et2.BurnEntity{Block: watchedEvent.BlockNumber}
|
||||||
|
mlkc.block++
|
||||||
|
return e, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mlkc *MockERC20Converter) ToBurnModel(entity *et2.BurnEntity) *et2.BurnModel {
|
||||||
|
mlkc.BurnsToConvert = append(mlkc.BurnsToConvert, *entity)
|
||||||
|
return &et2.BurnModel{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mlkc *MockERC20Converter) ToMintEntity(watchedEvent core.WatchedEvent) (*et2.MintEntity, error) {
|
||||||
|
mlkc.WatchedEvents = append(mlkc.WatchedEvents, &watchedEvent)
|
||||||
|
e := &et2.MintEntity{Block: watchedEvent.BlockNumber}
|
||||||
|
mlkc.block++
|
||||||
|
return e, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mlkc *MockERC20Converter) ToMintModel(entity *et2.MintEntity) *et2.MintModel {
|
||||||
|
mlkc.MintsToConvert = append(mlkc.MintsToConvert, *entity)
|
||||||
|
return &et2.MintModel{}
|
||||||
|
}
|
@ -15,7 +15,8 @@
|
|||||||
package mocks
|
package mocks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/vulcanize/vulcanizedb/examples/erc20_watcher/event_triggered"
|
et1 "github.com/vulcanize/vulcanizedb/examples/erc20_watcher/event_triggered"
|
||||||
|
et2 "github.com/vulcanize/vulcanizedb/examples/generic/event_triggered"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/filters"
|
"github.com/vulcanize/vulcanizedb/pkg/filters"
|
||||||
)
|
)
|
||||||
@ -23,6 +24,8 @@ import (
|
|||||||
type MockWatchedEventsRepository struct {
|
type MockWatchedEventsRepository struct {
|
||||||
watchedTransferEvents []*core.WatchedEvent
|
watchedTransferEvents []*core.WatchedEvent
|
||||||
watchedApprovalEvents []*core.WatchedEvent
|
watchedApprovalEvents []*core.WatchedEvent
|
||||||
|
watchedBurnEvents []*core.WatchedEvent
|
||||||
|
watchedMintEvents []*core.WatchedEvent
|
||||||
Names []string
|
Names []string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,6 +37,12 @@ func (mwer *MockWatchedEventsRepository) SetWatchedEvents(watchedEvents []*core.
|
|||||||
if event.Name == "Approval" {
|
if event.Name == "Approval" {
|
||||||
mwer.watchedApprovalEvents = append(mwer.watchedApprovalEvents, event)
|
mwer.watchedApprovalEvents = append(mwer.watchedApprovalEvents, event)
|
||||||
}
|
}
|
||||||
|
if event.Name == "Burn" {
|
||||||
|
mwer.watchedBurnEvents = append(mwer.watchedBurnEvents, event)
|
||||||
|
}
|
||||||
|
if event.Name == "Mint" {
|
||||||
|
mwer.watchedMintEvents = append(mwer.watchedMintEvents, event)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,23 +59,47 @@ func (mwer *MockWatchedEventsRepository) GetWatchedEvents(name string) ([]*core.
|
|||||||
// clear watched events once returned so same events are returned for every filter while testing
|
// clear watched events once returned so same events are returned for every filter while testing
|
||||||
mwer.watchedApprovalEvents = []*core.WatchedEvent{}
|
mwer.watchedApprovalEvents = []*core.WatchedEvent{}
|
||||||
}
|
}
|
||||||
|
if name == "Burn" {
|
||||||
|
result = mwer.watchedBurnEvents
|
||||||
|
// clear watched events once returned so same events are returned for every filter while testing
|
||||||
|
mwer.watchedBurnEvents = []*core.WatchedEvent{}
|
||||||
|
}
|
||||||
|
if name == "Mint" {
|
||||||
|
result = mwer.watchedMintEvents
|
||||||
|
// clear watched events once returned so same events are returned for every filter while testing
|
||||||
|
mwer.watchedMintEvents = []*core.WatchedEvent{}
|
||||||
|
}
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type MockEventRepo struct {
|
type MockEventRepo struct {
|
||||||
TransferLogs []event_triggered.TransferModel
|
TransferLogs []et1.TransferModel
|
||||||
ApprovalLogs []event_triggered.ApprovalModel
|
ApprovalLogs []et1.ApprovalModel
|
||||||
|
BurnLogs []et2.BurnModel
|
||||||
|
MintLogs []et2.MintModel
|
||||||
VulcanizeLogIDs []int64
|
VulcanizeLogIDs []int64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (molr *MockEventRepo) CreateTransfer(transferModel event_triggered.TransferModel, vulcanizeLogId int64) error {
|
func (molr *MockEventRepo) CreateTransfer(transferModel *et1.TransferModel, vulcanizeLogId int64) error {
|
||||||
molr.TransferLogs = append(molr.TransferLogs, transferModel)
|
molr.TransferLogs = append(molr.TransferLogs, *transferModel)
|
||||||
molr.VulcanizeLogIDs = append(molr.VulcanizeLogIDs, vulcanizeLogId)
|
molr.VulcanizeLogIDs = append(molr.VulcanizeLogIDs, vulcanizeLogId)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (molk *MockEventRepo) CreateApproval(approvalModel event_triggered.ApprovalModel, vulcanizeLogID int64) error {
|
func (molk *MockEventRepo) CreateApproval(approvalModel *et1.ApprovalModel, vulcanizeLogID int64) error {
|
||||||
molk.ApprovalLogs = append(molk.ApprovalLogs, approvalModel)
|
molk.ApprovalLogs = append(molk.ApprovalLogs, *approvalModel)
|
||||||
|
molk.VulcanizeLogIDs = append(molk.VulcanizeLogIDs, vulcanizeLogID)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (molr *MockEventRepo) CreateBurn(burnModel *et2.BurnModel, vulcanizeLogId int64) error {
|
||||||
|
molr.BurnLogs = append(molr.BurnLogs, *burnModel)
|
||||||
|
molr.VulcanizeLogIDs = append(molr.VulcanizeLogIDs, vulcanizeLogId)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (molk *MockEventRepo) CreateMint(mintModel *et2.MintModel, vulcanizeLogID int64) error {
|
||||||
|
molk.MintLogs = append(molk.MintLogs, *mintModel)
|
||||||
molk.VulcanizeLogIDs = append(molk.VulcanizeLogIDs, vulcanizeLogID)
|
molk.VulcanizeLogIDs = append(molk.VulcanizeLogIDs, vulcanizeLogID)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -17,10 +17,11 @@ package mocks
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
"reflect"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Fetcher struct {
|
type Fetcher struct {
|
||||||
|
@ -18,6 +18,7 @@ import (
|
|||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -15,8 +15,12 @@
|
|||||||
package test_helpers
|
package test_helpers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math/rand"
|
||||||
|
"time"
|
||||||
|
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/config"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
|
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
|
||||||
@ -74,3 +78,52 @@ func CreateBlock(blockNumber int64, repository repositories.BlockRepository) (bl
|
|||||||
|
|
||||||
return blockId
|
return blockId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SetupIntegrationDB(db *postgres.DB, logs []core.Log) *postgres.DB {
|
||||||
|
|
||||||
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
|
||||||
|
db, err := postgres.NewDB(config.Database{
|
||||||
|
Hostname: "localhost",
|
||||||
|
Name: "vulcanize_private",
|
||||||
|
Port: 5432,
|
||||||
|
}, core.Node{})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
receiptRepository := repositories.ReceiptRepository{DB: db}
|
||||||
|
blockRepository := *repositories.NewBlockRepository(db)
|
||||||
|
|
||||||
|
blockNumber := rand.Int63()
|
||||||
|
blockId := CreateBlock(blockNumber, blockRepository)
|
||||||
|
|
||||||
|
receipt := core.Receipt{
|
||||||
|
Logs: logs,
|
||||||
|
}
|
||||||
|
receipts := []core.Receipt{receipt}
|
||||||
|
|
||||||
|
err = receiptRepository.CreateReceiptsAndLogs(blockId, receipts)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
var vulcanizeLogIds []int64
|
||||||
|
err = db.Select(&vulcanizeLogIds, `SELECT id FROM logs`)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
return db
|
||||||
|
}
|
||||||
|
|
||||||
|
func TearDownIntegrationDB(db *postgres.DB) *postgres.DB {
|
||||||
|
|
||||||
|
_, err := db.Exec(`DELETE FROM token_transfers`)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
_, err = db.Exec(`DELETE FROM token_approvals`)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
_, err = db.Exec(`DELETE FROM log_filters`)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
_, err = db.Exec(`DELETE FROM logs`)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
return db
|
||||||
|
}
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/geth"
|
"github.com/vulcanize/vulcanizedb/pkg/geth"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/geth/client"
|
"github.com/vulcanize/vulcanizedb/pkg/geth/client"
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/geth"
|
"github.com/vulcanize/vulcanizedb/pkg/geth"
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package integration_test
|
package integration_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
"testing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestIntegrationTest(t *testing.T) {
|
func TestIntegrationTest(t *testing.T) {
|
||||||
|
@ -2,10 +2,10 @@ package test_config
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/config"
|
"github.com/vulcanize/vulcanizedb/pkg/config"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||||
|
@ -2,12 +2,9 @@ package utils
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/config"
|
"github.com/vulcanize/vulcanizedb/pkg/config"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
|
4
vendor/github.com/btcsuite/btcd/btcec/btcec_test.go
generated
vendored
4
vendor/github.com/btcsuite/btcd/btcec/btcec_test.go
generated
vendored
@ -898,7 +898,7 @@ var testVectors = []struct {
|
|||||||
r, s string
|
r, s string
|
||||||
ok bool
|
ok bool
|
||||||
}{
|
}{
|
||||||
/*
|
/*
|
||||||
* All of these tests are disabled since they are for P224, not sec256k1.
|
* All of these tests are disabled since they are for P224, not sec256k1.
|
||||||
* they are left here as an example of test vectors for when some *real*
|
* they are left here as an example of test vectors for when some *real*
|
||||||
* vectors may be found.
|
* vectors may be found.
|
||||||
@ -1023,7 +1023,7 @@ var testVectors = []struct {
|
|||||||
"ed1a719cc0c507edc5239d76fe50e2306c145ad252bd481da04180c0",
|
"ed1a719cc0c507edc5239d76fe50e2306c145ad252bd481da04180c0",
|
||||||
false,
|
false,
|
||||||
},
|
},
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVectors(t *testing.T) {
|
func TestVectors(t *testing.T) {
|
||||||
|
Loading…
Reference in New Issue
Block a user