parent
a0ba6ca6bd
commit
31516ea87e
3
db/migrations/1536942529_create_flop_kick.down.sql
Normal file
3
db/migrations/1536942529_create_flop_kick.down.sql
Normal file
@ -0,0 +1,3 @@
|
||||
DROP TABLE maker.flop_kick;
|
||||
ALTER TABLE public.checked_headers
|
||||
DROP COLUMN flop_kick_checked;
|
15
db/migrations/1536942529_create_flop_kick.up.sql
Normal file
15
db/migrations/1536942529_create_flop_kick.up.sql
Normal file
@ -0,0 +1,15 @@
|
||||
CREATE TABLE maker.flop_kick (
|
||||
id SERIAL PRIMARY KEY,
|
||||
header_id INTEGER NOT NULL REFERENCES headers (id) ON DELETE CASCADE,
|
||||
bid_id NUMERIC NOT NULL,
|
||||
lot NUMERIC NOT NULL,
|
||||
bid NUMERIC NOT NULL,
|
||||
gal VARCHAR,
|
||||
"end" TIMESTAMP WITH TIME ZONE,
|
||||
tx_idx INTEGER NOT NULL,
|
||||
raw_log JSONB,
|
||||
UNIQUE (header_id, tx_idx)
|
||||
);
|
||||
|
||||
ALTER TABLE public.checked_headers
|
||||
ADD COLUMN flop_kick_checked BOOLEAN NOT NULL DEFAULT FALSE;
|
@ -340,6 +340,43 @@ CREATE SEQUENCE maker.flip_kick_id_seq
|
||||
ALTER SEQUENCE maker.flip_kick_id_seq OWNED BY maker.flip_kick.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: flop_kick; Type: TABLE; Schema: maker; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE maker.flop_kick (
|
||||
id integer NOT NULL,
|
||||
header_id integer NOT NULL,
|
||||
bid_id numeric NOT NULL,
|
||||
lot numeric NOT NULL,
|
||||
bid numeric NOT NULL,
|
||||
gal character varying,
|
||||
"end" timestamp with time zone,
|
||||
tx_idx integer NOT NULL,
|
||||
raw_log jsonb
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: flop_kick_id_seq; Type: SEQUENCE; Schema: maker; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE maker.flop_kick_id_seq
|
||||
AS integer
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: flop_kick_id_seq; Type: SEQUENCE OWNED BY; Schema: maker; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE maker.flop_kick_id_seq OWNED BY maker.flop_kick.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: frob; Type: TABLE; Schema: maker; Owner: -
|
||||
--
|
||||
@ -670,6 +707,7 @@ CREATE TABLE public.checked_headers (
|
||||
id integer NOT NULL,
|
||||
header_id integer NOT NULL,
|
||||
price_feeds_checked boolean DEFAULT false NOT NULL,
|
||||
flop_kick_checked boolean DEFAULT false NOT NULL,
|
||||
deal_checked boolean DEFAULT false NOT NULL,
|
||||
dent_checked boolean DEFAULT false NOT NULL,
|
||||
flip_kick_checked boolean DEFAULT false NOT NULL,
|
||||
@ -1050,6 +1088,13 @@ ALTER TABLE ONLY maker.drip_file_vow ALTER COLUMN id SET DEFAULT nextval('maker.
|
||||
ALTER TABLE ONLY maker.flip_kick ALTER COLUMN id SET DEFAULT nextval('maker.flip_kick_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: flop_kick id; Type: DEFAULT; Schema: maker; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY maker.flop_kick ALTER COLUMN id SET DEFAULT nextval('maker.flop_kick_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: frob id; Type: DEFAULT; Schema: maker; Owner: -
|
||||
--
|
||||
@ -1305,6 +1350,22 @@ ALTER TABLE ONLY maker.flip_kick
|
||||
ADD CONSTRAINT flip_kick_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: flop_kick flop_kick_header_id_tx_idx_key; Type: CONSTRAINT; Schema: maker; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY maker.flop_kick
|
||||
ADD CONSTRAINT flop_kick_header_id_tx_idx_key UNIQUE (header_id, tx_idx);
|
||||
|
||||
|
||||
--
|
||||
-- Name: flop_kick flop_kick_pkey; Type: CONSTRAINT; Schema: maker; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY maker.flop_kick
|
||||
ADD CONSTRAINT flop_kick_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: frob frob_header_id_tx_idx_key; Type: CONSTRAINT; Schema: maker; Owner: -
|
||||
--
|
||||
@ -1643,6 +1704,14 @@ ALTER TABLE ONLY maker.flip_kick
|
||||
ADD CONSTRAINT flip_kick_header_id_fkey FOREIGN KEY (header_id) REFERENCES public.headers(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: flop_kick flop_kick_header_id_fkey; Type: FK CONSTRAINT; Schema: maker; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY maker.flop_kick
|
||||
ADD CONSTRAINT flop_kick_header_id_fkey FOREIGN KEY (header_id) REFERENCES public.headers(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: frob frob_header_id_fkey; Type: FK CONSTRAINT; Schema: maker; Owner: -
|
||||
--
|
||||
|
@ -9,9 +9,9 @@ import (
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
vulcCommon "github.com/vulcanize/vulcanizedb/pkg/geth/converters/common"
|
||||
"errors"
|
||||
)
|
||||
|
||||
var ErrEmptyHeader = errors.New("empty header returned over RPC")
|
||||
|
@ -54,14 +54,14 @@ func (BiteConverter) ToEntity(contractAddress string, contractAbi string, ethLog
|
||||
}
|
||||
func (converter BiteConverter) ToModel(entity BiteEntity) (BiteModel, error) {
|
||||
|
||||
id := entity.Id.String()
|
||||
id := entity.Id
|
||||
ilk := entity.Ilk[:]
|
||||
lad := entity.Lad[:]
|
||||
ink := entity.Ink.String()
|
||||
art := entity.Art.String()
|
||||
iArt := entity.IArt.String()
|
||||
tab := entity.Tab.String()
|
||||
flip := entity.Flip.String()
|
||||
ink := entity.Ink
|
||||
art := entity.Art
|
||||
iArt := entity.IArt
|
||||
tab := entity.Tab
|
||||
flip := entity.Flip
|
||||
txIdx := entity.TransactionIndex
|
||||
rawLogJson, err := json.Marshal(entity.Raw)
|
||||
rawLogString := string(rawLogJson)
|
||||
@ -70,14 +70,14 @@ func (converter BiteConverter) ToModel(entity BiteEntity) (BiteModel, error) {
|
||||
}
|
||||
|
||||
return BiteModel{
|
||||
Id: shared.ConvertNilToEmptyString(id),
|
||||
Id: shared.BigIntToString(id),
|
||||
Ilk: ilk,
|
||||
Lad: lad,
|
||||
Ink: shared.ConvertNilToEmptyString(ink),
|
||||
Art: shared.ConvertNilToEmptyString(art),
|
||||
IArt: shared.ConvertNilToEmptyString(iArt),
|
||||
Tab: shared.ConvertNilToEmptyString(tab),
|
||||
Flip: shared.ConvertNilToEmptyString(flip),
|
||||
Ink: shared.BigIntToString(ink),
|
||||
Art: shared.BigIntToString(art),
|
||||
IArt: shared.BigIntToString(iArt),
|
||||
Tab: shared.BigIntToString(tab),
|
||||
Flip: shared.BigIntToString(flip),
|
||||
TransactionIndex: txIdx,
|
||||
Raw: rawLogString,
|
||||
}, nil
|
||||
|
@ -64,13 +64,13 @@ func (FlipKickConverter) ToModels(flipKicks []FlipKickEntity) (results []FlipKic
|
||||
}
|
||||
|
||||
id := flipKick.Id.String()
|
||||
lot := shared.ConvertNilToEmptyString(flipKick.Lot.String())
|
||||
bid := shared.ConvertNilToEmptyString(flipKick.Bid.String())
|
||||
lot := shared.BigIntToString(flipKick.Lot)
|
||||
bid := shared.BigIntToString(flipKick.Bid)
|
||||
gal := flipKick.Gal.String()
|
||||
endValue := shared.ConvertNilToZeroTimeValue(flipKick.End)
|
||||
endValue := shared.BigIntToInt64(flipKick.End)
|
||||
end := time.Unix(endValue, 0)
|
||||
urn := common.BytesToAddress(flipKick.Urn[:common.AddressLength]).String()
|
||||
tab := shared.ConvertNilToEmptyString(flipKick.Tab.String())
|
||||
tab := shared.BigIntToString(flipKick.Tab)
|
||||
rawLogJson, err := json.Marshal(flipKick.Raw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
25
pkg/transformers/flop_kick/config.go
Normal file
25
pkg/transformers/flop_kick/config.go
Normal file
@ -0,0 +1,25 @@
|
||||
// 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 flop_kick
|
||||
|
||||
import "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
|
||||
var Config = shared.TransformerConfig{
|
||||
ContractAddress: shared.FlopperContractAddress,
|
||||
ContractAbi: shared.FlopperABI,
|
||||
Topics: []string{shared.FlopKickSignature},
|
||||
StartingBlockNumber: 0,
|
||||
EndingBlockNumber: 10000000,
|
||||
}
|
81
pkg/transformers/flop_kick/converter.go
Normal file
81
pkg/transformers/flop_kick/converter.go
Normal file
@ -0,0 +1,81 @@
|
||||
// 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 flop_kick
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/geth"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
)
|
||||
|
||||
type Converter interface {
|
||||
ToEntities(contractAddress, contractAbi string, ethLogs []types.Log) ([]Entity, error)
|
||||
ToModels(entities []Entity) ([]Model, error)
|
||||
}
|
||||
|
||||
type FlopKickConverter struct{}
|
||||
|
||||
func (FlopKickConverter) ToEntities(contractAddress, contractAbi string, ethLogs []types.Log) ([]Entity, error) {
|
||||
var results []Entity
|
||||
for _, ethLog := range ethLogs {
|
||||
entity := Entity{}
|
||||
address := common.HexToAddress(contractAddress)
|
||||
abi, err := geth.ParseAbi(contractAbi)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
contract := bind.NewBoundContract(address, abi, nil, nil, nil)
|
||||
|
||||
err = contract.UnpackLog(&entity, "Kick", ethLog)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
entity.Raw = ethLog
|
||||
entity.TransactionIndex = ethLog.TxIndex
|
||||
results = append(results, entity)
|
||||
}
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func (FlopKickConverter) ToModels(entities []Entity) ([]Model, error) {
|
||||
var results []Model
|
||||
for _, entity := range entities {
|
||||
endValue := shared.BigIntToInt64(entity.End)
|
||||
rawLogJson, err := json.Marshal(entity.Raw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
model := Model{
|
||||
BidId: shared.BigIntToString(entity.Id),
|
||||
Lot: shared.BigIntToString(entity.Lot),
|
||||
Bid: shared.BigIntToString(entity.Bid),
|
||||
Gal: entity.Gal.String(),
|
||||
End: time.Unix(endValue, 0),
|
||||
TransactionIndex: entity.TransactionIndex,
|
||||
Raw: rawLogJson,
|
||||
}
|
||||
results = append(results, model)
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
82
pkg/transformers/flop_kick/converter_test.go
Normal file
82
pkg/transformers/flop_kick/converter_test.go
Normal file
@ -0,0 +1,82 @@
|
||||
// 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 flop_kick_test
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/flop_kick"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
)
|
||||
|
||||
var _ = Describe("FlopKick Converter", func() {
|
||||
Describe("ToEntities", func() {
|
||||
It("converts a log to a FlopKick entity", func() {
|
||||
converter := flop_kick.FlopKickConverter{}
|
||||
entities, err := converter.ToEntities(shared.FlopperContractAddress, shared.FlopperABI, []types.Log{test_data.FlopKickLog})
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
entity := entities[0]
|
||||
Expect(entity.Id).To(Equal(test_data.FlopKickEntity.Id))
|
||||
Expect(entity.Lot).To(Equal(test_data.FlopKickEntity.Lot))
|
||||
Expect(entity.Bid).To(Equal(test_data.FlopKickEntity.Bid))
|
||||
Expect(entity.Gal).To(Equal(test_data.FlopKickEntity.Gal))
|
||||
Expect(entity.End).To(Equal(test_data.FlopKickEntity.End))
|
||||
Expect(entity.TransactionIndex).To(Equal(test_data.FlopKickEntity.TransactionIndex))
|
||||
Expect(entity.Raw).To(Equal(test_data.FlopKickEntity.Raw))
|
||||
})
|
||||
|
||||
It("returns an error if converting the log to an entity fails", func() {
|
||||
converter := flop_kick.FlopKickConverter{}
|
||||
entities, err := converter.ToEntities(shared.FlopperContractAddress, "error abi", []types.Log{test_data.FlopKickLog})
|
||||
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(entities).To(BeNil())
|
||||
})
|
||||
})
|
||||
|
||||
Describe("ToModels", func() {
|
||||
var emptyAddressHex = "0x0000000000000000000000000000000000000000"
|
||||
var emptyString = ""
|
||||
var emptyTime = time.Unix(0, 0)
|
||||
var emptyEntities = []flop_kick.Entity{flop_kick.Entity{}}
|
||||
|
||||
It("converts an Entity to a Model", func() {
|
||||
converter := flop_kick.FlopKickConverter{}
|
||||
models, err := converter.ToModels([]flop_kick.Entity{test_data.FlopKickEntity})
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(models[0]).To(Equal(test_data.FlopKickModel))
|
||||
})
|
||||
|
||||
It("handles nil values", func() {
|
||||
converter := flop_kick.FlopKickConverter{}
|
||||
|
||||
models, err := converter.ToModels(emptyEntities)
|
||||
model := models[0]
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(model.BidId).To(Equal(emptyString))
|
||||
Expect(model.Lot).To(Equal(emptyString))
|
||||
Expect(model.Bid).To(Equal(emptyString))
|
||||
Expect(model.Gal).To(Equal(emptyAddressHex))
|
||||
Expect(model.End).To(Equal(emptyTime))
|
||||
})
|
||||
})
|
||||
})
|
32
pkg/transformers/flop_kick/entity.go
Normal file
32
pkg/transformers/flop_kick/entity.go
Normal file
@ -0,0 +1,32 @@
|
||||
// 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 flop_kick
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
)
|
||||
|
||||
type Entity struct {
|
||||
Id *big.Int
|
||||
Lot *big.Int
|
||||
Bid *big.Int
|
||||
Gal common.Address
|
||||
End *big.Int
|
||||
TransactionIndex uint
|
||||
Raw types.Log
|
||||
}
|
13
pkg/transformers/flop_kick/flop_kick_suite_test.go
Normal file
13
pkg/transformers/flop_kick/flop_kick_suite_test.go
Normal file
@ -0,0 +1,13 @@
|
||||
package flop_kick_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
func TestFlopKick(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "FlopKick Suite")
|
||||
}
|
50
pkg/transformers/flop_kick/integration_test.go
Normal file
50
pkg/transformers/flop_kick/integration_test.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 flop_kick_test
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/geth"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/flop_kick"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
|
||||
)
|
||||
|
||||
var _ = Describe("Integration tests", func() {
|
||||
It("unpacks an flop kick event log", func() {
|
||||
address := common.HexToAddress(shared.FlopperContractAddress)
|
||||
abi, err := geth.ParseAbi(shared.FlopperABI)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
contract := bind.NewBoundContract(address, abi, nil, nil, nil)
|
||||
entity := &flop_kick.Entity{}
|
||||
|
||||
var eventLog = test_data.FlopKickLog
|
||||
|
||||
err = contract.UnpackLog(entity, "Kick", eventLog)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
expectedEntity := test_data.FlopKickEntity
|
||||
Expect(entity.Id).To(Equal(expectedEntity.Id))
|
||||
Expect(entity.Lot).To(Equal(expectedEntity.Lot))
|
||||
Expect(entity.Bid).To(Equal(expectedEntity.Bid))
|
||||
Expect(entity.Gal).To(Equal(expectedEntity.Gal))
|
||||
Expect(entity.End).To(Equal(expectedEntity.End))
|
||||
})
|
||||
})
|
27
pkg/transformers/flop_kick/model.go
Normal file
27
pkg/transformers/flop_kick/model.go
Normal file
@ -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 flop_kick
|
||||
|
||||
import "time"
|
||||
|
||||
type Model struct {
|
||||
BidId string `db:"bid_id"`
|
||||
Lot string
|
||||
Bid string
|
||||
Gal string
|
||||
End time.Time
|
||||
TransactionIndex uint `db:"tx_idx"`
|
||||
Raw []byte `db:"raw_log"`
|
||||
}
|
89
pkg/transformers/flop_kick/repository.go
Normal file
89
pkg/transformers/flop_kick/repository.go
Normal file
@ -0,0 +1,89 @@
|
||||
// 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 flop_kick
|
||||
|
||||
import (
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
)
|
||||
|
||||
type Repository interface {
|
||||
Create(headerId int64, flopKick []Model) error
|
||||
MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error)
|
||||
MarkHeaderChecked(headerId int64) error
|
||||
}
|
||||
|
||||
type FlopKickRepository struct {
|
||||
DB *postgres.DB
|
||||
}
|
||||
|
||||
func NewFlopKickRepository(db *postgres.DB) FlopKickRepository {
|
||||
return FlopKickRepository{DB: db}
|
||||
}
|
||||
|
||||
func (r FlopKickRepository) Create(headerId int64, flopKicks []Model) error {
|
||||
tx, err := r.DB.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, flopKick := range flopKicks {
|
||||
_, err = tx.Exec(
|
||||
`INSERT into maker.flop_kick (header_id, bid_id, lot, bid, gal, "end", tx_idx, raw_log)
|
||||
VALUES($1, $2, $3, $4, $5, $6, $7, $8)`,
|
||||
headerId, flopKick.BidId, flopKick.Lot, flopKick.Bid, flopKick.Gal, flopKick.End, flopKick.TransactionIndex, flopKick.Raw,
|
||||
)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
_, err = tx.Exec(`INSERT INTO public.checked_headers (header_id, flop_kick_checked)
|
||||
VALUES ($1, $2)
|
||||
ON CONFLICT (header_id) DO
|
||||
UPDATE SET flop_kick_checked = $2`, headerId, true)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func (r FlopKickRepository) MarkHeaderChecked(headerId int64) error {
|
||||
_, err := r.DB.Exec(`INSERT INTO public.checked_headers (header_id, flop_kick_checked)
|
||||
VALUES ($1, $2)
|
||||
ON CONFLICT (header_id) DO
|
||||
UPDATE SET flop_kick_checked = $2`, headerId, true)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r FlopKickRepository) MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error) {
|
||||
var result []core.Header
|
||||
err := r.DB.Select(
|
||||
&result,
|
||||
`SELECT headers.id, headers.block_number FROM headers
|
||||
LEFT JOIN checked_headers on headers.id = header_id
|
||||
WHERE (header_id ISNULL OR flop_kick_checked IS FALSE)
|
||||
AND headers.block_number >= $1
|
||||
AND headers.block_number <= $2
|
||||
AND headers.eth_node_fingerprint = $3`,
|
||||
startingBlockNumber,
|
||||
endingBlockNumber,
|
||||
r.DB.Node.ID,
|
||||
)
|
||||
|
||||
return result, err
|
||||
}
|
200
pkg/transformers/flop_kick/repository_test.go
Normal file
200
pkg/transformers/flop_kick/repository_test.go
Normal file
@ -0,0 +1,200 @@
|
||||
// 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 flop_kick_test
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/flop_kick"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
|
||||
"github.com/vulcanize/vulcanizedb/test_config"
|
||||
)
|
||||
|
||||
var _ = Describe("FlopRepository", func() {
|
||||
var db *postgres.DB
|
||||
var repository flop_kick.FlopKickRepository
|
||||
var headerRepository repositories.HeaderRepository
|
||||
var headerId int64
|
||||
var err error
|
||||
var dbResult test_data.FlopKickDBResult
|
||||
|
||||
BeforeEach(func() {
|
||||
node := test_config.NewTestNode()
|
||||
db = test_config.NewTestDB(node)
|
||||
test_config.CleanTestDB(db)
|
||||
repository = flop_kick.NewFlopKickRepository(db)
|
||||
headerRepository = repositories.NewHeaderRepository(db)
|
||||
headerId, err = headerRepository.CreateOrUpdateHeader(core.Header{})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
dbResult = test_data.FlopKickDBResult{}
|
||||
})
|
||||
|
||||
Describe("Create", func() {
|
||||
It("creates FlopKick records", func() {
|
||||
err := repository.Create(headerId, []flop_kick.Model{test_data.FlopKickModel})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = db.QueryRowx(`SELECT * FROM maker.flop_kick WHERE header_id = $1`, headerId).StructScan(&dbResult)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(dbResult.HeaderId).To(Equal(headerId))
|
||||
Expect(dbResult.BidId).To(Equal(test_data.FlopKickModel.BidId))
|
||||
Expect(dbResult.Lot).To(Equal(test_data.FlopKickModel.Lot))
|
||||
Expect(dbResult.Bid).To(Equal(test_data.FlopKickModel.Bid))
|
||||
Expect(dbResult.Gal).To(Equal(test_data.FlopKickModel.Gal))
|
||||
Expect(dbResult.End.Equal(test_data.FlopKickModel.End)).To(BeTrue())
|
||||
Expect(dbResult.TransactionIndex).To(Equal(test_data.FlopKickModel.TransactionIndex))
|
||||
Expect(dbResult.Raw).To(MatchJSON(test_data.FlopKickModel.Raw))
|
||||
})
|
||||
|
||||
It("marks headerId as checked for flop kick logs", func() {
|
||||
err = repository.Create(headerId, []flop_kick.Model{test_data.FlopKickModel})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
var headerChecked bool
|
||||
err = db.Get(&headerChecked, `SELECT flop_kick_checked FROM public.checked_headers WHERE header_id = $1`, headerId)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(headerChecked).To(BeTrue())
|
||||
})
|
||||
|
||||
It("returns an error if inserting the flop_kick record fails", func() {
|
||||
err = repository.Create(headerId, []flop_kick.Model{test_data.FlopKickModel})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = repository.Create(headerId, []flop_kick.Model{test_data.FlopKickModel})
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("pq: duplicate key value violates unique constraint"))
|
||||
})
|
||||
|
||||
It("deletes the flop_kick records if its corresponding header record is deleted", func() {
|
||||
err = repository.Create(headerId, []flop_kick.Model{test_data.FlopKickModel})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
var flopKickCount int
|
||||
err = db.QueryRow(`SELECT count(*) FROM maker.flop_kick`).Scan(&flopKickCount)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(flopKickCount).To(Equal(1))
|
||||
|
||||
_, err = db.Exec(`DELETE FROM headers where id = $1`, headerId)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = db.QueryRow(`SELECT count(*) FROM maker.flop_kick`).Scan(&flopKickCount)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(flopKickCount).To(Equal(0))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("MarkedHeadersChecked", func() {
|
||||
It("creates a row for a new headerId", func() {
|
||||
err := repository.MarkHeaderChecked(headerId)
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
var headerChecked bool
|
||||
err = db.Get(&headerChecked, `SELECT flop_kick_checked FROM public.checked_headers WHERE header_id = $1`, headerId)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(headerChecked).To(BeTrue())
|
||||
})
|
||||
|
||||
It("updates row when headerId already exists", func() {
|
||||
_, err = db.Exec(`INSERT INTO public.checked_headers (header_id) VALUES ($1)`, headerId)
|
||||
err = repository.MarkHeaderChecked(headerId)
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
var headerChecked bool
|
||||
err = db.Get(&headerChecked, `SELECT flop_kick_checked FROM public.checked_headers WHERE header_id = $1`, headerId)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(headerChecked).To(BeTrue())
|
||||
})
|
||||
})
|
||||
|
||||
Describe("MissingHeaders", func() {
|
||||
var flopKickBlockNumber = rand.Int63()
|
||||
var startingBlockNumber = flopKickBlockNumber - 1
|
||||
var endingBlockNumber = flopKickBlockNumber + 1
|
||||
var outOfRangeBlockNumber = flopKickBlockNumber + 2
|
||||
|
||||
It("returns headers haven't been checked", func() {
|
||||
var headerIds []int64
|
||||
|
||||
for _, number := range []int64{startingBlockNumber, flopKickBlockNumber, endingBlockNumber, outOfRangeBlockNumber} {
|
||||
headerId, err := headerRepository.CreateOrUpdateHeader(core.Header{BlockNumber: number})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
headerIds = append(headerIds, headerId)
|
||||
}
|
||||
|
||||
err = repository.MarkHeaderChecked(headerIds[1])
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
headers, err := repository.MissingHeaders(startingBlockNumber, endingBlockNumber)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(len(headers)).To(Equal(2))
|
||||
Expect(headers[0].BlockNumber).To(Or(Equal(startingBlockNumber), Equal(endingBlockNumber)))
|
||||
Expect(headers[1].BlockNumber).To(Or(Equal(startingBlockNumber), Equal(endingBlockNumber)))
|
||||
})
|
||||
|
||||
It("only treats headers as checked if flop_kicks have been checked", func() {
|
||||
var headerIds []int64
|
||||
for _, number := range []int64{startingBlockNumber, flopKickBlockNumber, endingBlockNumber, outOfRangeBlockNumber} {
|
||||
headerId, err := headerRepository.CreateOrUpdateHeader(core.Header{BlockNumber: number})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
headerIds = append(headerIds, headerId)
|
||||
}
|
||||
|
||||
_, err := db.Exec(`INSERT INTO public.checked_headers (header_id) VALUES ($1)`, headerIds[1])
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
headers, err := repository.MissingHeaders(startingBlockNumber, endingBlockNumber)
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(len(headers)).To(Equal(3))
|
||||
Expect(headers[0].BlockNumber).To(Or(Equal(startingBlockNumber), Equal(endingBlockNumber), Equal(flopKickBlockNumber)))
|
||||
Expect(headers[1].BlockNumber).To(Or(Equal(startingBlockNumber), Equal(endingBlockNumber), Equal(flopKickBlockNumber)))
|
||||
Expect(headers[2].BlockNumber).To(Or(Equal(startingBlockNumber), Equal(endingBlockNumber), Equal(flopKickBlockNumber)))
|
||||
})
|
||||
|
||||
It("only returns missing headers for the current node", func() {
|
||||
var headerIds []int64
|
||||
node2 := core.Node{}
|
||||
db2 := test_config.NewTestDB(node2)
|
||||
headerRepository2 := repositories.NewHeaderRepository(db2)
|
||||
flopKickRepository2 := flop_kick.NewFlopKickRepository(db2)
|
||||
|
||||
for _, number := range []int64{startingBlockNumber, flopKickBlockNumber, endingBlockNumber} {
|
||||
headerId, err := headerRepository.CreateOrUpdateHeader(core.Header{BlockNumber: number})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
headerIds = append(headerIds, headerId)
|
||||
|
||||
headerRepository2.CreateOrUpdateHeader(core.Header{BlockNumber: number})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
}
|
||||
|
||||
err = repository.MarkHeaderChecked(headerIds[1])
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
node1MissingHeaders, err := repository.MissingHeaders(startingBlockNumber, endingBlockNumber)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(len(node1MissingHeaders)).To(Equal(2))
|
||||
|
||||
node2MissingHeaders, err := flopKickRepository2.MissingHeaders(startingBlockNumber, endingBlockNumber)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(len(node2MissingHeaders)).To(Equal(3))
|
||||
})
|
||||
})
|
||||
})
|
81
pkg/transformers/flop_kick/transformer.go
Normal file
81
pkg/transformers/flop_kick/transformer.go
Normal file
@ -0,0 +1,81 @@
|
||||
// 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 flop_kick
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
)
|
||||
|
||||
type Transformer struct {
|
||||
Config shared.TransformerConfig
|
||||
Converter Converter
|
||||
Fetcher shared.LogFetcher
|
||||
Repository Repository
|
||||
}
|
||||
|
||||
type FlopKickTransformerInitializer struct {
|
||||
Config shared.TransformerConfig
|
||||
}
|
||||
|
||||
func (i FlopKickTransformerInitializer) NewFlopKickTransformer(db *postgres.DB, blockChain core.BlockChain) shared.Transformer {
|
||||
return Transformer{
|
||||
Config: i.Config,
|
||||
Converter: FlopKickConverter{},
|
||||
Fetcher: shared.NewFetcher(blockChain),
|
||||
Repository: NewFlopKickRepository(db),
|
||||
}
|
||||
}
|
||||
|
||||
func (t Transformer) Execute() error {
|
||||
config := t.Config
|
||||
headers, err := t.Repository.MissingHeaders(config.StartingBlockNumber, config.EndingBlockNumber)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, header := range headers {
|
||||
topics := [][]common.Hash{{common.HexToHash(shared.FlopKickSignature)}}
|
||||
matchingLogs, err := t.Fetcher.FetchLogs(config.ContractAddress, topics, header.BlockNumber)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(matchingLogs) < 1 {
|
||||
err := t.Repository.MarkHeaderChecked(header.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
entities, err := t.Converter.ToEntities(config.ContractAddress, config.ContractAbi, matchingLogs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
models, err := t.Converter.ToModels(entities)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = t.Repository.Create(header.Id, models)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
246
pkg/transformers/flop_kick/transformer_test.go
Normal file
246
pkg/transformers/flop_kick/transformer_test.go
Normal file
@ -0,0 +1,246 @@
|
||||
// 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 flop_kick_test
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/flop_kick"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data/mocks"
|
||||
flop_kick_mocks "github.com/vulcanize/vulcanizedb/pkg/transformers/test_data/mocks/flop_kick"
|
||||
)
|
||||
|
||||
var _ = Describe("FlopKick Transformer", func() {
|
||||
var fetcher mocks.MockLogFetcher
|
||||
var converter flop_kick_mocks.MockConverter
|
||||
var repository flop_kick_mocks.MockRepository
|
||||
var config = flop_kick.Config
|
||||
var headerOne core.Header
|
||||
var headerTwo core.Header
|
||||
|
||||
BeforeEach(func() {
|
||||
fetcher = mocks.MockLogFetcher{}
|
||||
converter = flop_kick_mocks.MockConverter{}
|
||||
repository = flop_kick_mocks.MockRepository{}
|
||||
headerOne = core.Header{Id: GinkgoRandomSeed(), BlockNumber: GinkgoRandomSeed()}
|
||||
headerTwo = core.Header{Id: GinkgoRandomSeed(), BlockNumber: GinkgoRandomSeed()}
|
||||
})
|
||||
|
||||
It("gets missing headers for specified block numbers", func() {
|
||||
transformer := flop_kick.Transformer{
|
||||
Config: config,
|
||||
Converter: &converter,
|
||||
Fetcher: &fetcher,
|
||||
Repository: &repository,
|
||||
}
|
||||
|
||||
err := transformer.Execute()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(repository.PassedStartingBlockNumber).To(Equal(flop_kick.Config.StartingBlockNumber))
|
||||
Expect(repository.PassedEndingBlockNumber).To(Equal(flop_kick.Config.EndingBlockNumber))
|
||||
})
|
||||
|
||||
It("returns error if getting missing headers fails", func() {
|
||||
transformer := flop_kick.Transformer{
|
||||
Config: config,
|
||||
Converter: &converter,
|
||||
Fetcher: &fetcher,
|
||||
Repository: &repository,
|
||||
}
|
||||
repository.SetMissingHeadersError(fakes.FakeError)
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err).To(MatchError(fakes.FakeError))
|
||||
})
|
||||
|
||||
It("fetches logs for each missing header", func() {
|
||||
transformer := flop_kick.Transformer{
|
||||
Config: config,
|
||||
Converter: &converter,
|
||||
Fetcher: &fetcher,
|
||||
Repository: &repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne, headerTwo})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(fetcher.FetchedBlocks).To(Equal([]int64{headerOne.BlockNumber, headerTwo.BlockNumber}))
|
||||
Expect(fetcher.FetchedContractAddress).To(Equal(flop_kick.Config.ContractAddress))
|
||||
Expect(fetcher.FetchedTopics).To(Equal([][]common.Hash{{common.HexToHash(shared.FlopKickSignature)}}))
|
||||
})
|
||||
|
||||
It("returns error if fetcher returns error", func() {
|
||||
transformer := flop_kick.Transformer{
|
||||
Config: config,
|
||||
Converter: &converter,
|
||||
Fetcher: &fetcher,
|
||||
Repository: &repository,
|
||||
}
|
||||
fetcher.SetFetcherError(fakes.FakeError)
|
||||
repository.SetMissingHeaders([]core.Header{{}})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err).To(MatchError(fakes.FakeError))
|
||||
})
|
||||
|
||||
It("marks header as checked even if no logs were returned", func() {
|
||||
transformer := flop_kick.Transformer{
|
||||
Config: config,
|
||||
Converter: &converter,
|
||||
Fetcher: &fetcher,
|
||||
Repository: &repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne, headerTwo})
|
||||
fetcher.SetFetchedLogs([]types.Log{})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(repository.CheckedHeaderIds).To(ContainElement(headerOne.Id))
|
||||
Expect(repository.CheckedHeaderIds).To(ContainElement(headerTwo.Id))
|
||||
})
|
||||
|
||||
It("returns error if marking header checked returns err", func() {
|
||||
transformer := flop_kick.Transformer{
|
||||
Config: config,
|
||||
Converter: &converter,
|
||||
Fetcher: &fetcher,
|
||||
Repository: &repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne, headerTwo})
|
||||
repository.SetCheckedHeaderError(fakes.FakeError)
|
||||
fetcher.SetFetchedLogs([]types.Log{})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err).To(MatchError(fakes.FakeError))
|
||||
})
|
||||
|
||||
It("converts matching logs to entity", func() {
|
||||
transformer := flop_kick.Transformer{
|
||||
Config: config,
|
||||
Converter: &converter,
|
||||
Fetcher: &fetcher,
|
||||
Repository: &repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: GinkgoRandomSeed()}})
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.FlopKickLog})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(converter.PassedContractAddress).To(Equal(flop_kick.Config.ContractAddress))
|
||||
Expect(converter.PassedContractABI).To(Equal(flop_kick.Config.ContractAbi))
|
||||
Expect(converter.PassedLogs).To(Equal([]types.Log{test_data.FlopKickLog}))
|
||||
})
|
||||
|
||||
It("returns an error if converting logs to entity fails", func() {
|
||||
transformer := flop_kick.Transformer{
|
||||
Config: config,
|
||||
Converter: &converter,
|
||||
Fetcher: &fetcher,
|
||||
Repository: &repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: GinkgoRandomSeed()}})
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.FlopKickLog})
|
||||
converter.SetToEntityConverterError(fakes.FakeError)
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err).To(MatchError(fakes.FakeError))
|
||||
})
|
||||
|
||||
It("converts flop_kick entity to model", func() {
|
||||
transformer := flop_kick.Transformer{
|
||||
Config: config,
|
||||
Converter: &converter,
|
||||
Fetcher: &fetcher,
|
||||
Repository: &repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{{}})
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.FlopKickLog})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(converter.PassedEntities).To(Equal([]flop_kick.Entity{test_data.FlopKickEntity}))
|
||||
})
|
||||
|
||||
It("returns an error if there's a failure in converting to model", func() {
|
||||
transformer := flop_kick.Transformer{
|
||||
Config: config,
|
||||
Converter: &converter,
|
||||
Fetcher: &fetcher,
|
||||
Repository: &repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{{}})
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.FlopKickLog})
|
||||
converter.SetToModelConverterError(fakes.FakeError)
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err).To(MatchError(fakes.FakeError))
|
||||
})
|
||||
|
||||
It("persists the flop_kick model", func() {
|
||||
transformer := flop_kick.Transformer{
|
||||
Config: config,
|
||||
Converter: &converter,
|
||||
Fetcher: &fetcher,
|
||||
Repository: &repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne, headerTwo})
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.FlopKickLog})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(repository.CreatedHeaderIds).To(ContainElement(headerOne.Id))
|
||||
Expect(repository.CreatedHeaderIds).To(ContainElement(headerTwo.Id))
|
||||
Expect(repository.CreatedModels).To(ContainElement(test_data.FlopKickModel))
|
||||
})
|
||||
|
||||
It("returns error if repository returns error for create", func() {
|
||||
transformer := flop_kick.Transformer{
|
||||
Config: config,
|
||||
Converter: &converter,
|
||||
Fetcher: &fetcher,
|
||||
Repository: &repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{{}})
|
||||
repository.SetCreateError(fakes.FakeError)
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.FlopKickLog})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err).To(MatchError(fakes.FakeError))
|
||||
})
|
||||
})
|
@ -1,79 +0,0 @@
|
||||
The main goal of creating a transformer is to fetch specific log events from Ethereum, convert/decode them into usable data and then persist them to VulcanizeDB. For Maker there are two main types of log events that we're tracking: custom events that are defined in the contract solidity code, and LogNote events which utilize the [DSNote library](https://github.com/dapphub/ds-note). The transformer process for each of these different log types is the same, except for the converting process, as denoted below.
|
||||
|
||||
## Creating a Transformer for custom events (i.e. FlopKick)
|
||||
To illustrate how to create a custom log event transformer we'll use the Kick event defined in [flop.sol](https://github.com/makerdao/dss/blob/master/src/flop.sol) as an example.
|
||||
|
||||
1. Get an example FlopKick log event either from mainnet (if the
|
||||
contract has already been deployed), from the Kovan testnet, or by
|
||||
deploying the contract to a local chain and emitting the event manually.
|
||||
We will use the example log event to test drive converting the log to a
|
||||
FlopKick database model.
|
||||
|
||||
1. Fetch the appropriate logs from the chain.
|
||||
- Most transformers use `shared.LogFetcher`
|
||||
- Price Feeds
|
||||
|
||||
1. Convert the raw log into a database model.
|
||||
- For Custom Events, such as FlopKick
|
||||
1. Create a converter to convert the raw log into a Go structure.
|
||||
- We've been using [go-ethereum's abigen tool](https://github.com/ethereum/go-ethereum/tree/master/cmd/abigen) to get the contract's ABI, and a Go struct that represents the event log. We will unpack the raw logs into this struct.
|
||||
- To use abigen: `abigen --sol flip.sol --pkg flip --out {/path/to/output_file}`
|
||||
- sol: this is the path to the solidity contract
|
||||
- pkg: a package name for the generated Go code
|
||||
- out: the file path for the generated Go code (optional)
|
||||
- the output for `flop.sol` will include the FlopperAbi and the FlopperKick struct:
|
||||
```go
|
||||
type FlopperKick struct {
|
||||
Id *big.Int
|
||||
Lot *big.Int
|
||||
Bid *big.Int
|
||||
Gal common.Address
|
||||
End *big.Int
|
||||
Raw types.Log
|
||||
}
|
||||
```
|
||||
- Using go-ethereum's `contract.UnpackLog` method we can unpack the raw log into the FlopperKick struct (which we're referring to as the `entity`).
|
||||
- See the `ToEntity` method in `pkg/transformers/flop_kick/converter`.
|
||||
- The unpack method will not add the `Raw` or `TransactionIndex` values to the entity struct - both of these values are accessible from the entity.
|
||||
1. Then convert the entity into a database model. See the `ToModel` method in `pkg/transformers/flop_kick/converter`.
|
||||
|
||||
- For LogNote Events, such as tend.
|
||||
- Since LogNote events are a generic structure, they depend on the
|
||||
method signature of the method that is calling them. For example,
|
||||
when the `tend` method is called on the
|
||||
[flip.sol contract](https://github.com/makerdao/dss/blob/master/src/flip.sol#L117), the method signature looks like this: `tend(uint id, uint lot, uint bid)`
|
||||
- the LogNote event will take the first
|
||||
|
||||
|
||||
|
||||
|
||||
1. Persist the log record to VulcanizeDB.
|
||||
- Each event log has it's own table in the database, as well as it's
|
||||
own column in the `checked_headers` table.
|
||||
- The `checked_headers` table alllows us to keep track of which
|
||||
headers have been queried for a given log type.
|
||||
- To create a new migration file: `migrate create -ext sql -dir ./db/migrations/ create_flop_kick`
|
||||
- See `db/migrations/1536942529_create_flop_kick.up.sql`.
|
||||
- The specific log event tables are all created in the `maker`
|
||||
schema.
|
||||
- There is a one-many association between `headers` and the log
|
||||
event tables. This is so that if a header is removed due to a
|
||||
reorg, the associated log event records are also removed.
|
||||
- We have been following a repository pattern to interact with the
|
||||
database for each table, see the `Create` method in `pkg/transformers/flop_kick/repository.go`.
|
||||
1. Get all MissingHeaders. //TODO//
|
||||
- The repository is also responsible for querying for all header
|
||||
records that have not yet been.
|
||||
1. MarkHeaderChecked//TODO//
|
||||
|
||||
1. Wire each component up in the transformer.
|
||||
|
||||
- Each transformer's `Execute` method iterates through all of the
|
||||
MissingHeaders
|
||||
- Currently each transformer's `Execute` method is responsible for
|
||||
fetching the missing headers, meaning the headers that haven't yet
|
||||
been checked for a given log type
|
||||
|
||||
|
||||
|
||||
#### For LogNote events
|
@ -20,6 +20,7 @@ var (
|
||||
CatABI = "[{\"constant\":true,\"inputs\":[],\"name\":\"vat\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vow\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"flips\",\"outputs\":[{\"name\":\"ilk\",\"type\":\"bytes32\"},{\"name\":\"lad\",\"type\":\"bytes32\"},{\"name\":\"ink\",\"type\":\"uint256\"},{\"name\":\"tab\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"nflip\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"live\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"}],\"name\":\"wards\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"ilks\",\"outputs\":[{\"name\":\"flip\",\"type\":\"address\"},{\"name\":\"chop\",\"type\":\"uint256\"},{\"name\":\"lump\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pit\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"vat_\",\"type\":\"address\"},{\"name\":\"pit_\",\"type\":\"address\"},{\"name\":\"vow_\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"ilk\",\"type\":\"bytes32\"},{\"indexed\":true,\"name\":\"lad\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"ink\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"art\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"tab\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"flip\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"iArt\",\"type\":\"uint256\"}],\"name\":\"Bite\",\"type\":\"event\"},{\"anonymous\":true,\"inputs\":[{\"indexed\":true,\"name\":\"sig\",\"type\":\"bytes4\"},{\"indexed\":true,\"name\":\"guy\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"foo\",\"type\":\"bytes32\"},{\"indexed\":true,\"name\":\"bar\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"wad\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"fax\",\"type\":\"bytes\"}],\"name\":\"LogNote\",\"type\":\"event\"},{\"constant\":false,\"inputs\":[{\"name\":\"guy\",\"type\":\"address\"}],\"name\":\"rely\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"guy\",\"type\":\"address\"}],\"name\":\"deny\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"ilk\",\"type\":\"bytes32\"},{\"name\":\"what\",\"type\":\"bytes32\"},{\"name\":\"data\",\"type\":\"uint256\"}],\"name\":\"file\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"ilk\",\"type\":\"bytes32\"},{\"name\":\"what\",\"type\":\"bytes32\"},{\"name\":\"flip\",\"type\":\"address\"}],\"name\":\"file\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"ilk\",\"type\":\"bytes32\"},{\"name\":\"lad\",\"type\":\"bytes32\"}],\"name\":\"bite\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"n\",\"type\":\"uint256\"},{\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"flip\",\"outputs\":[{\"name\":\"id\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"
|
||||
DripABI = `[{"constant":true,"inputs":[],"name":"vat","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x36569e77"},{"constant":true,"inputs":[],"name":"repo","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x56ff3122"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"wards","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0xbf353dbb"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"ilks","outputs":[{"name":"vow","type":"bytes32"},{"name":"tax","type":"uint256"},{"name":"rho","type":"uint48"}],"payable":false,"stateMutability":"view","type":"function","signature":"0xd9638d36"},{"inputs":[{"name":"vat_","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor","signature":"constructor"},{"anonymous":true,"inputs":[{"indexed":true,"name":"sig","type":"bytes4"},{"indexed":true,"name":"guy","type":"address"},{"indexed":true,"name":"foo","type":"bytes32"},{"indexed":true,"name":"bar","type":"bytes32"},{"indexed":false,"name":"wad","type":"uint256"},{"indexed":false,"name":"fax","type":"bytes"}],"name":"LogNote","type":"event","signature":"0x644843f351d3fba4abcd60109eaff9f54bac8fb8ccf0bab941009c21df21cf31"},{"constant":false,"inputs":[{"name":"guy","type":"address"}],"name":"rely","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x65fae35e"},{"constant":false,"inputs":[{"name":"guy","type":"address"}],"name":"deny","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x9c52a7f1"},{"constant":true,"inputs":[],"name":"era","outputs":[{"name":"","type":"uint48"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x143e55e0"},{"constant":false,"inputs":[{"name":"ilk","type":"bytes32"},{"name":"vow","type":"bytes32"},{"name":"tax","type":"uint256"}],"name":"file","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x1a0b287e"},{"constant":false,"inputs":[{"name":"what","type":"bytes32"},{"name":"data","type":"uint256"}],"name":"file","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x29ae8114"},{"constant":false,"inputs":[{"name":"ilk","type":"bytes32"}],"name":"drip","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x44e2a5a8"}]`
|
||||
FlipperABI = `[{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"bids","outputs":[{"name":"bid","type":"uint256"},{"name":"lot","type":"uint256"},{"name":"guy","type":"address"},{"name":"tic","type":"uint48"},{"name":"end","type":"uint48"},{"name":"urn","type":"bytes32"},{"name":"gal","type":"address"},{"name":"tab","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x4423c5f1"},{"constant":true,"inputs":[],"name":"ttl","outputs":[{"name":"","type":"uint48"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x4e8b1dd5"},{"constant":true,"inputs":[],"name":"gem","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x7bd2bea7"},{"constant":true,"inputs":[],"name":"beg","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x7d780d82"},{"constant":true,"inputs":[],"name":"tau","outputs":[{"name":"","type":"uint48"}],"payable":false,"stateMutability":"view","type":"function","signature":"0xcfc4af55"},{"constant":true,"inputs":[],"name":"kicks","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0xcfdd3302"},{"constant":true,"inputs":[],"name":"dai","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function","signature":"0xf4b9fa75"},{"inputs":[{"name":"dai_","type":"address"},{"name":"gem_","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor","signature":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"id","type":"uint256"},{"indexed":false,"name":"lot","type":"uint256"},{"indexed":false,"name":"bid","type":"uint256"},{"indexed":false,"name":"gal","type":"address"},{"indexed":false,"name":"end","type":"uint48"},{"indexed":true,"name":"urn","type":"bytes32"},{"indexed":false,"name":"tab","type":"uint256"}],"name":"Kick","type":"event","signature":"0xbac86238bdba81d21995024470425ecb370078fa62b7271b90cf28cbd1e3e87e"},{"anonymous":true,"inputs":[{"indexed":true,"name":"sig","type":"bytes4"},{"indexed":true,"name":"guy","type":"address"},{"indexed":true,"name":"foo","type":"bytes32"},{"indexed":true,"name":"bar","type":"bytes32"},{"indexed":false,"name":"wad","type":"uint256"},{"indexed":false,"name":"fax","type":"bytes"}],"name":"LogNote","type":"event","signature":"0x644843f351d3fba4abcd60109eaff9f54bac8fb8ccf0bab941009c21df21cf31"},{"constant":true,"inputs":[],"name":"era","outputs":[{"name":"","type":"uint48"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x143e55e0"},{"constant":false,"inputs":[{"name":"urn","type":"bytes32"},{"name":"gal","type":"address"},{"name":"tab","type":"uint256"},{"name":"lot","type":"uint256"},{"name":"bid","type":"uint256"}],"name":"kick","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0xeae19d9e"},{"constant":false,"inputs":[{"name":"id","type":"uint256"}],"name":"tick","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0xfc7b6aee"},{"constant":false,"inputs":[{"name":"id","type":"uint256"},{"name":"lot","type":"uint256"},{"name":"bid","type":"uint256"}],"name":"tend","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x4b43ed12"},{"constant":false,"inputs":[{"name":"id","type":"uint256"},{"name":"lot","type":"uint256"},{"name":"bid","type":"uint256"}],"name":"dent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x5ff3a382"},{"constant":false,"inputs":[{"name":"id","type":"uint256"}],"name":"deal","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0xc959c42b"}]`
|
||||
FlopperABI = "[{\"constant\":true,\"inputs\":[],\"name\":\"era\",\"outputs\":[{\"name\":\"\",\"type\":\"uint48\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bids\",\"outputs\":[{\"name\":\"bid\",\"type\":\"uint256\"},{\"name\":\"lot\",\"type\":\"uint256\"},{\"name\":\"guy\",\"type\":\"address\"},{\"name\":\"tic\",\"type\":\"uint48\"},{\"name\":\"end\",\"type\":\"uint48\"},{\"name\":\"vow\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"ttl\",\"outputs\":[{\"name\":\"\",\"type\":\"uint48\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"id\",\"type\":\"uint256\"},{\"name\":\"lot\",\"type\":\"uint256\"},{\"name\":\"bid\",\"type\":\"uint256\"}],\"name\":\"dent\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"guy\",\"type\":\"address\"}],\"name\":\"rely\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"gem\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"beg\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"guy\",\"type\":\"address\"}],\"name\":\"deny\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"gal\",\"type\":\"address\"},{\"name\":\"lot\",\"type\":\"uint256\"},{\"name\":\"bid\",\"type\":\"uint256\"}],\"name\":\"kick\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"}],\"name\":\"wards\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"deal\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"tau\",\"outputs\":[{\"name\":\"\",\"type\":\"uint48\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"kicks\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"dai\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"dai_\",\"type\":\"address\"},{\"name\":\"gem_\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"lot\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"bid\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"gal\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"end\",\"type\":\"uint48\"}],\"name\":\"Kick\",\"type\":\"event\"},{\"anonymous\":true,\"inputs\":[{\"indexed\":true,\"name\":\"sig\",\"type\":\"bytes4\"},{\"indexed\":true,\"name\":\"guy\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"foo\",\"type\":\"bytes32\"},{\"indexed\":true,\"name\":\"bar\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"wad\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"fax\",\"type\":\"bytes\"}],\"name\":\"LogNote\",\"type\":\"event\"}]"
|
||||
MedianizerABI = `[{"constant":false,"inputs":[{"name":"owner_","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"","type":"bytes32"}],"name":"poke","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"poke","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"compute","outputs":[{"name":"","type":"bytes32"},{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"wat","type":"address"}],"name":"set","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"wat","type":"address"}],"name":"unset","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"indexes","outputs":[{"name":"","type":"bytes12"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"next","outputs":[{"name":"","type":"bytes12"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"read","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"peek","outputs":[{"name":"","type":"bytes32"},{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes12"}],"name":"values","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"min_","type":"uint96"}],"name":"setMin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"authority_","type":"address"}],"name":"setAuthority","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"void","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"pos","type":"bytes12"},{"name":"wat","type":"address"}],"name":"set","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"authority","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"pos","type":"bytes12"}],"name":"unset","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"next_","type":"bytes12"}],"name":"setNext","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"min","outputs":[{"name":"","type":"uint96"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"val","type":"bytes32"}],"name":"LogValue","type":"event"},{"anonymous":true,"inputs":[{"indexed":true,"name":"sig","type":"bytes4"},{"indexed":true,"name":"guy","type":"address"},{"indexed":true,"name":"foo","type":"bytes32"},{"indexed":true,"name":"bar","type":"bytes32"},{"indexed":false,"name":"wad","type":"uint256"},{"indexed":false,"name":"fax","type":"bytes"}],"name":"LogNote","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"authority","type":"address"}],"name":"LogSetAuthority","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"}],"name":"LogSetOwner","type":"event"}]]`
|
||||
PitABI = `[{"constant":true,"inputs":[],"name":"vat","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x36569e77"},{"constant":true,"inputs":[],"name":"live","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x957aa58c"},{"constant":true,"inputs":[],"name":"drip","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x9f678cca"},{"constant":true,"inputs":[],"name":"Line","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0xbabe8a3f"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"wards","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0xbf353dbb"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"ilks","outputs":[{"name":"spot","type":"uint256"},{"name":"line","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0xd9638d36"},{"inputs":[{"name":"vat_","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor","signature":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"ilk","type":"bytes32"},{"indexed":true,"name":"urn","type":"bytes32"},{"indexed":false,"name":"ink","type":"uint256"},{"indexed":false,"name":"art","type":"uint256"},{"indexed":false,"name":"dink","type":"int256"},{"indexed":false,"name":"dart","type":"int256"},{"indexed":false,"name":"iArt","type":"uint256"}],"name":"Frob","type":"event","signature":"0xb2afa28318bcc689926b52835d844de174ef8de97e982a85c0199d584920791b"},{"anonymous":true,"inputs":[{"indexed":true,"name":"sig","type":"bytes4"},{"indexed":true,"name":"guy","type":"address"},{"indexed":true,"name":"foo","type":"bytes32"},{"indexed":true,"name":"bar","type":"bytes32"},{"indexed":false,"name":"wad","type":"uint256"},{"indexed":false,"name":"fax","type":"bytes"}],"name":"LogNote","type":"event","signature":"0x644843f351d3fba4abcd60109eaff9f54bac8fb8ccf0bab941009c21df21cf31"},{"constant":false,"inputs":[{"name":"guy","type":"address"}],"name":"rely","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x65fae35e"},{"constant":false,"inputs":[{"name":"guy","type":"address"}],"name":"deny","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x9c52a7f1"},{"constant":false,"inputs":[{"name":"ilk","type":"bytes32"},{"name":"what","type":"bytes32"},{"name":"data","type":"uint256"}],"name":"file","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x1a0b287e"},{"constant":false,"inputs":[{"name":"what","type":"bytes32"},{"name":"data","type":"uint256"}],"name":"file","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x29ae8114"},{"constant":false,"inputs":[{"name":"what","type":"bytes32"},{"name":"data","type":"address"}],"name":"file","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0xd4e8be83"},{"constant":false,"inputs":[{"name":"ilk","type":"bytes32"},{"name":"dink","type":"int256"},{"name":"dart","type":"int256"}],"name":"frob","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x5a984ded"}]`
|
||||
VatABI = `[{"constant":true,"inputs":[],"name":"debt","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x0dca59c1"},{"constant":true,"inputs":[{"name":"","type":"bytes32"},{"name":"","type":"bytes32"}],"name":"urns","outputs":[{"name":"ink","type":"uint256"},{"name":"art","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x26e27482"},{"constant":true,"inputs":[],"name":"vice","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x2d61a355"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"sin","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0xa60f1d3e"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"wards","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0xbf353dbb"},{"constant":true,"inputs":[{"name":"","type":"bytes32"},{"name":"","type":"bytes32"}],"name":"gem","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0xc0912683"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"ilks","outputs":[{"name":"take","type":"uint256"},{"name":"rate","type":"uint256"},{"name":"Ink","type":"uint256"},{"name":"Art","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0xd9638d36"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"dai","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0xf53e4e69"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor","signature":"constructor"},{"anonymous":true,"inputs":[{"indexed":true,"name":"sig","type":"bytes4"},{"indexed":true,"name":"foo","type":"bytes32"},{"indexed":true,"name":"bar","type":"bytes32"},{"indexed":true,"name":"too","type":"bytes32"},{"indexed":false,"name":"fax","type":"bytes"}],"name":"Note","type":"event","signature":"0x8c2dbbc2b33ffaa77c104b777e574a8a4ff79829dfee8b66f4dc63e3f8067152"},{"constant":false,"inputs":[{"name":"guy","type":"address"}],"name":"rely","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x65fae35e"},{"constant":false,"inputs":[{"name":"guy","type":"address"}],"name":"deny","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x9c52a7f1"},{"constant":false,"inputs":[{"name":"ilk","type":"bytes32"}],"name":"init","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x3b663195"},{"constant":false,"inputs":[{"name":"ilk","type":"bytes32"},{"name":"guy","type":"bytes32"},{"name":"rad","type":"int256"}],"name":"slip","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x42066cbb"},{"constant":false,"inputs":[{"name":"ilk","type":"bytes32"},{"name":"src","type":"bytes32"},{"name":"dst","type":"bytes32"},{"name":"rad","type":"int256"}],"name":"flux","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0xa6e41821"},{"constant":false,"inputs":[{"name":"src","type":"bytes32"},{"name":"dst","type":"bytes32"},{"name":"rad","type":"int256"}],"name":"move","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x78f19470"},{"constant":false,"inputs":[{"name":"i","type":"bytes32"},{"name":"u","type":"bytes32"},{"name":"v","type":"bytes32"},{"name":"w","type":"bytes32"},{"name":"dink","type":"int256"},{"name":"dart","type":"int256"}],"name":"tune","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x5dd6471a"},{"constant":false,"inputs":[{"name":"i","type":"bytes32"},{"name":"u","type":"bytes32"},{"name":"v","type":"bytes32"},{"name":"w","type":"bytes32"},{"name":"dink","type":"int256"},{"name":"dart","type":"int256"}],"name":"grab","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x3690ae4c"},{"constant":false,"inputs":[{"name":"u","type":"bytes32"},{"name":"v","type":"bytes32"},{"name":"rad","type":"int256"}],"name":"heal","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x990a5f63"},{"constant":false,"inputs":[{"name":"i","type":"bytes32"},{"name":"u","type":"bytes32"},{"name":"rate","type":"int256"}],"name":"fold","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0xe6a6a64d"},{"constant":false,"inputs":[{"name":"i","type":"bytes32"},{"name":"u","type":"bytes32"},{"name":"take","type":"int256"}],"name":"toll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x09b7a0b5"}]`
|
||||
@ -28,6 +29,7 @@ var (
|
||||
CatContractAddress = "0x2f34f22a00ee4b7a8f8bbc4eaee1658774c624e0"
|
||||
DripContractAddress = "0x891c04639a5edcae088e546fa125b5d7fb6a2b9d"
|
||||
FlipperContractAddress = "0x32d496ad866d110060866b7125981c73642cc509" // ETH FLIP Contract
|
||||
FlopperContractAddress = "0x6191c9b0086c2ebf92300cc507009b53996fbffa" // MCD FLOP Contract
|
||||
PepContractAddress = "0xB1997239Cfc3d15578A3a09730f7f84A90BB4975"
|
||||
PipContractAddress = "0x9FfFE440258B79c5d6604001674A4722FfC0f7Bc"
|
||||
PitContractAddress = "0xe7cf3198787c9a4daac73371a38f29aaeeced87e"
|
||||
@ -43,6 +45,7 @@ var (
|
||||
dripFileRepoMethod = GetSolidityMethodSignature(DripABI, "file")
|
||||
dripFileVowMethod = "file(bytes32,bytes32)"
|
||||
flipKickMethod = GetSolidityMethodSignature(FlipperABI, "Kick")
|
||||
flopKickMethod = GetSolidityMethodSignature(FlopperABI, "Kick")
|
||||
frobMethod = GetSolidityMethodSignature(PitABI, "Frob")
|
||||
logValueMethod = GetSolidityMethodSignature(MedianizerABI, "LogValue")
|
||||
pitFileDebtCeilingMethod = "file(bytes32,uint256)"
|
||||
@ -59,6 +62,7 @@ var (
|
||||
DripFileRepoSignature = GetLogNoteSignature(dripFileRepoMethod)
|
||||
DripFileVowSignature = GetLogNoteSignature(dripFileVowMethod)
|
||||
FlipKickSignature = GetEventSignature(flipKickMethod)
|
||||
FlopKickSignature = GetEventSignature(flopKickMethod)
|
||||
FrobSignature = GetEventSignature(frobMethod)
|
||||
LogValueSignature = GetEventSignature(logValueMethod)
|
||||
PitFileDebtCeilingSignature = GetLogNoteSignature(pitFileDebtCeilingMethod)
|
||||
|
@ -135,6 +135,13 @@ var _ = Describe("Event signature generator", func() {
|
||||
Expect(expected).To(Equal(actual))
|
||||
})
|
||||
|
||||
It("gets the flop Kick event signature", func() {
|
||||
expected := "Kick(uint256,uint256,uint256,address,uint48)"
|
||||
actual := shared.GetSolidityMethodSignature(shared.FlopperABI, "Kick")
|
||||
|
||||
Expect(expected).To(Equal(actual))
|
||||
})
|
||||
|
||||
It("gets the pit frob event signature", func() {
|
||||
expected := "Frob(bytes32,bytes32,uint256,uint256,int256,int256,uint256)"
|
||||
actual := shared.GetSolidityMethodSignature(shared.PitABI, "Frob")
|
||||
|
@ -16,7 +16,7 @@ package shared
|
||||
|
||||
import "math/big"
|
||||
|
||||
func ConvertNilToZeroTimeValue(value *big.Int) int64 {
|
||||
func BigIntToInt64(value *big.Int) int64 {
|
||||
if value == nil {
|
||||
return int64(0)
|
||||
} else {
|
||||
@ -24,10 +24,11 @@ func ConvertNilToZeroTimeValue(value *big.Int) int64 {
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertNilToEmptyString(value string) string {
|
||||
if value == "<nil>" {
|
||||
func BigIntToString(value *big.Int) string {
|
||||
result := value.String()
|
||||
if result == "<nil>" {
|
||||
return ""
|
||||
} else {
|
||||
return value
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
78
pkg/transformers/test_data/flop_kick.go
Normal file
78
pkg/transformers/test_data/flop_kick.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 test_data
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/flop_kick"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
"math/big"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
FlopKickLog = types.Log{
|
||||
Address: common.HexToAddress(shared.FlopperContractAddress),
|
||||
Topics: []common.Hash{
|
||||
common.HexToHash("0xefa52d9342a199cb30efd2692463f2c2bef63cd7186b50382d4fb94ad207880e"),
|
||||
common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000005"),
|
||||
},
|
||||
Data: hexutil.MustDecode("0x000000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000020000000000000000000000007d7bee5fcfd8028cf7b00876c5b1421c800561a6000000000000000000000000000000000000000000000000000000000002a300"),
|
||||
BlockNumber: 19,
|
||||
TxHash: common.HexToHash("0xd8fd67b37a6aa64a3cef4937204765183b180d8dc92eecd0d233f445526d31b5"),
|
||||
TxIndex: flopTxIndex,
|
||||
BlockHash: common.HexToHash("0x7891fe725691abc5b94113dc2bfa8c3509e1e1d0e0bb74289e3b996c30d00c8c"),
|
||||
Index: 32,
|
||||
Removed: false,
|
||||
}
|
||||
|
||||
flopTxIndex = uint(33)
|
||||
flopBidId = int64(5)
|
||||
flopLot = int64(15)
|
||||
flopBid = int64(2)
|
||||
flopGal = "0x7d7bEe5fCfD8028cf7b00876C5b1421c800561A6"
|
||||
rawFlopLogJson, _ = json.Marshal(FlopKickLog)
|
||||
flopEnd = int64(172800)
|
||||
|
||||
FlopKickEntity = flop_kick.Entity{
|
||||
Id: big.NewInt(flopBidId),
|
||||
Lot: big.NewInt(flopLot),
|
||||
Bid: big.NewInt(flopBid),
|
||||
Gal: common.HexToAddress(flopGal),
|
||||
End: big.NewInt(flopEnd),
|
||||
TransactionIndex: flopTxIndex,
|
||||
Raw: FlopKickLog,
|
||||
}
|
||||
|
||||
FlopKickModel = flop_kick.Model{
|
||||
BidId: strconv.FormatInt(flopBidId, 10),
|
||||
Lot: strconv.FormatInt(flopLot, 10),
|
||||
Bid: strconv.FormatInt(flopBid, 10),
|
||||
Gal: flopGal,
|
||||
End: time.Unix(flopEnd, 0),
|
||||
TransactionIndex: flopTxIndex,
|
||||
Raw: rawFlopLogJson,
|
||||
}
|
||||
)
|
||||
|
||||
type FlopKickDBResult struct {
|
||||
Id int64
|
||||
HeaderId int64 `db:"header_id"`
|
||||
flop_kick.Model
|
||||
}
|
51
pkg/transformers/test_data/mocks/flop_kick/converter.go
Normal file
51
pkg/transformers/test_data/mocks/flop_kick/converter.go
Normal file
@ -0,0 +1,51 @@
|
||||
// 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 flop_kick
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/flop_kick"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
|
||||
)
|
||||
|
||||
type MockConverter struct {
|
||||
PassedContractAddress string
|
||||
PassedContractABI string
|
||||
PassedLogs []types.Log
|
||||
PassedEntities []flop_kick.Entity
|
||||
entityConverterError error
|
||||
modelConverterError error
|
||||
}
|
||||
|
||||
func (c *MockConverter) ToEntities(contractAddress, contractAbi string, ethLogs []types.Log) ([]flop_kick.Entity, error) {
|
||||
c.PassedContractAddress = contractAddress
|
||||
c.PassedContractABI = contractAbi
|
||||
c.PassedLogs = ethLogs
|
||||
|
||||
return []flop_kick.Entity{test_data.FlopKickEntity}, c.entityConverterError
|
||||
}
|
||||
|
||||
func (c *MockConverter) ToModels(entities []flop_kick.Entity) ([]flop_kick.Model, error) {
|
||||
c.PassedEntities = entities
|
||||
return []flop_kick.Model{test_data.FlopKickModel}, c.modelConverterError
|
||||
}
|
||||
|
||||
func (c *MockConverter) SetToEntityConverterError(err error) {
|
||||
c.entityConverterError = err
|
||||
}
|
||||
|
||||
func (c *MockConverter) SetToModelConverterError(err error) {
|
||||
c.modelConverterError = err
|
||||
}
|
68
pkg/transformers/test_data/mocks/flop_kick/repository.go
Normal file
68
pkg/transformers/test_data/mocks/flop_kick/repository.go
Normal file
@ -0,0 +1,68 @@
|
||||
// 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 flop_kick
|
||||
|
||||
import (
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/flop_kick"
|
||||
)
|
||||
|
||||
type MockRepository struct {
|
||||
PassedStartingBlockNumber int64
|
||||
PassedEndingBlockNumber int64
|
||||
CreatedHeaderIds []int64
|
||||
CreatedModels []flop_kick.Model
|
||||
CheckedHeaderIds []int64
|
||||
missingHeaders []core.Header
|
||||
missingHeadersError error
|
||||
createError error
|
||||
checkedHeaderError error
|
||||
}
|
||||
|
||||
func (r *MockRepository) Create(headerId int64, flopKicks []flop_kick.Model) error {
|
||||
r.CreatedHeaderIds = append(r.CreatedHeaderIds, headerId)
|
||||
r.CreatedModels = flopKicks
|
||||
|
||||
return r.createError
|
||||
}
|
||||
|
||||
func (r *MockRepository) MarkHeaderChecked(headerId int64) error {
|
||||
r.CheckedHeaderIds = append(r.CheckedHeaderIds, headerId)
|
||||
|
||||
return r.checkedHeaderError
|
||||
}
|
||||
|
||||
func (r *MockRepository) MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error) {
|
||||
r.PassedStartingBlockNumber = startingBlockNumber
|
||||
r.PassedEndingBlockNumber = endingBlockNumber
|
||||
|
||||
return r.missingHeaders, r.missingHeadersError
|
||||
}
|
||||
|
||||
func (r *MockRepository) SetMissingHeaders(headers []core.Header) {
|
||||
r.missingHeaders = headers
|
||||
}
|
||||
|
||||
func (r *MockRepository) SetMissingHeadersError(err error) {
|
||||
r.missingHeadersError = err
|
||||
}
|
||||
|
||||
func (r *MockRepository) SetCreateError(err error) {
|
||||
r.createError = err
|
||||
}
|
||||
|
||||
func (r *MockRepository) SetCheckedHeaderError(err error) {
|
||||
r.checkedHeaderError = err
|
||||
}
|
@ -24,6 +24,7 @@ import (
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/drip_file/repo"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/drip_file/vow"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/flip_kick"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/flop_kick"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/frob"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file/debt_ceiling"
|
||||
@ -45,6 +46,7 @@ var (
|
||||
DripFileRepoTransformerInitializer = repo.DripFileRepoTransformerInitializer{Config: dripFileConfig}.NewDripFileRepoTransformer
|
||||
DripFileVowTransfromerInitializer = vow.DripFileVowTransformerInitializer{Config: dripFileConfig}.NewDripFileVowTransformer
|
||||
FlipKickTransformerInitializer = flip_kick.FlipKickTransformerInitializer{Config: flip_kick.FlipKickConfig}.NewFlipKickTransformer
|
||||
FlopKickTransformerInitializer = flop_kick.FlopKickTransformerInitializer{Config: flop_kick.Config}.NewFlopKickTransformer
|
||||
FrobTransformerInitializer = frob.FrobTransformerInitializer{Config: frob.FrobConfig}.NewFrobTransformer
|
||||
pitFileConfig = pit_file.PitFileConfig
|
||||
PitFileDebtCeilingTransformerInitializer = debt_ceiling.PitFileDebtCeilingTransformerInitializer{Config: pitFileConfig}.NewPitFileDebtCeilingTransformer
|
||||
@ -62,8 +64,10 @@ func TransformerInitializers() []shared.TransformerInitializer {
|
||||
DentTransformerInitializer,
|
||||
DripDripTransformerInitializer,
|
||||
DripFileIlkTransformerInitializer,
|
||||
DripFileVowTransfromerInitializer,
|
||||
DripFileRepoTransformerInitializer,
|
||||
FlipKickTransformerInitializer,
|
||||
FlopKickTransformerInitializer,
|
||||
FrobTransformerInitializer,
|
||||
PitFileDebtCeilingTransformerInitializer,
|
||||
PitFileIlkTransformerInitializer,
|
||||
|
Loading…
Reference in New Issue
Block a user