Skip to content

Commit

Permalink
Merge pull request #43 from getamis/develop
Browse files Browse the repository at this point in the history
Release v0.2.2
  • Loading branch information
bailantaotao authored Jul 10, 2018
2 parents b4e9def + 197e853 commit 4c3e5b5
Show file tree
Hide file tree
Showing 17 changed files with 282 additions and 1,131 deletions.
12 changes: 8 additions & 4 deletions common/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,20 @@ const (
)

var (
// ErrWrongSigner returns if it's a wrong signer
// ErrWrongSigner is returned if it's a wrong signer
ErrWrongSigner = errors.New("wrong signer")
// ErrInconsistentRoot returns if the block and dump states have different root
// ErrInconsistentRoot is returned if the block and dump states have different root
ErrInconsistentRoot = errors.New("inconsistent root")
// ErrInconsistentStates returns if the number of blocks, dumps or recipents are different
// ErrInconsistentStates is returned if the number of blocks, dumps or receipts are different
ErrInconsistentStates = errors.New("inconsistent states")
// ErrInvalidTD is returned when a block has invalid TD
ErrInvalidTD = errors.New("invalid TD")
// ErrInvalidReceiptLog returns if it's a invalid receipt log
// ErrInvalidReceiptLog is returned if it's a invalid receipt log
ErrInvalidReceiptLog = errors.New("invalid receipt log")
// ErrHasPrevBalance is returned if an account has a previous balance when it's a new subscription
ErrHasPrevBalance = errors.New("missing previous balance")
// ErrMissingPrevBalance is returned if an account is missing previous balance when it's an old subscription
ErrMissingPrevBalance = errors.New("missing previous balance")
)

// DuplicateError checks whether it's a duplicate key error
Expand Down
16 changes: 11 additions & 5 deletions example/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@
package main

import (
"context"
"fmt"

"github.com/ethereum/go-ethereum/common"
"github.com/getamis/eth-indexer/store"
"github.com/getamis/eth-indexer/model"
"github.com/getamis/eth-indexer/store/account"
"github.com/getamis/sirius/database"
gormFactory "github.com/getamis/sirius/database/gorm"
"github.com/getamis/sirius/database/mysql"
Expand All @@ -35,7 +36,12 @@ func main() {
),
)
addr := common.HexToAddress("0x756f45e3fa69347a9a973a725e3c98bc4db0b5a0")
manager := store.NewServiceManager(db)
balance, blockNumber, _ := manager.GetBalance(context.Background(), addr, -1)
fmt.Println(balance, blockNumber)
store := account.NewWithDB(db)

account, err := store.FindAccount(model.ETHAddress, addr)
if err != nil {
fmt.Printf("Failed to find account: %v\n", err)
} else {
fmt.Printf("Find account, block_number: %v, balance: %v, \n", account.Balance, account.BlockNumber)
}
}
26 changes: 26 additions & 0 deletions store/account/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
package account

import (
"fmt"

"github.com/ethereum/go-ethereum/common"
"github.com/getamis/eth-indexer/model"
"github.com/jinzhu/gorm"
Expand All @@ -39,6 +41,7 @@ type Store interface {
// Accounts
InsertAccount(account *model.Account) error
FindAccount(contractAddress common.Address, address common.Address, blockNr ...int64) (result *model.Account, err error)
FindLatestAccounts(contractAddress common.Address, addrs [][]byte) (result []*model.Account, err error)
DeleteAccounts(contractAddress common.Address, from, to int64) error

// Transfer events
Expand Down Expand Up @@ -144,6 +147,29 @@ func (t *store) FindAccount(contractAddress common.Address, address common.Addre
return
}

func (t *store) FindLatestAccounts(contractAddress common.Address, addrs [][]byte) (result []*model.Account, err error) {
if len(addrs) == 0 {
return []*model.Account{}, nil
}

acct := model.Account{
ContractAddress: contractAddress.Bytes(),
}
// The following query does not work because the select fields needs to also be in group by fields (ONLY_FULL_GROUP_BY mode)
// "select address, balance, MAX(block_number) as block_number from %s where address in (?) group by address"
// and the following query
// "select address, balance, MAX(block_number) as block_number from %s where address in (?) group by (address, balance)"
// is not what we want, because (address, balance) isn't unique
query := fmt.Sprintf(
"select * from %s as t1, (select address, MAX(block_number) as block_number from %s where address in (?) group by address) as t2 where t1.address = t2.address and t1.block_number = t2.block_number",
acct.TableName(), acct.TableName())
err = t.db.Raw(query, addrs).Scan(&result).Error
if err != nil {
return
}
return
}

func (t *store) DeleteAccounts(contractAddress common.Address, from, to int64) error {
return t.db.Delete(model.Account{
ContractAddress: contractAddress.Bytes(),
Expand Down
80 changes: 79 additions & 1 deletion store/account/account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package account
import (
"os"
"reflect"
"strconv"
"testing"

gethCommon "github.com/ethereum/go-ethereum/common"
Expand All @@ -38,11 +39,15 @@ func makeERC20(hexAddr string) *model.ERC20 {
}

func makeAccount(contractAddress []byte, blockNum int64, hexAddr string) *model.Account {
return makeAccountWithBalance(contractAddress, blockNum, hexAddr, "987654321098765432109876543210")
}

func makeAccountWithBalance(contractAddress []byte, blockNum int64, hexAddr, balance string) *model.Account {
return &model.Account{
ContractAddress: contractAddress,
BlockNumber: blockNum,
Address: common.HexToBytes(hexAddr),
Balance: "987654321098765432109876543210",
Balance: balance,
}
}

Expand Down Expand Up @@ -210,6 +215,79 @@ var _ = Describe("Account Database Test", func() {
})
})

Context("FindLatestAccounts()", func() {
It("finds the eth records with highest block numbers", func() {
store := NewWithDB(db)
hexAddr0 := "0xF287a379e6caCa6732E50b88D23c290aA990A892" // does not exist in DB
hexAddr1 := "0xA287a379e6caCa6732E50b88D23c290aA990A892"
hexAddr2 := "0xC487a379e6caCa6732E50b88D23c290aA990A892"
hexAddr3 := "0xD487a379e6caCa6732E50b88D23c290aA990A892"

blockNumber := int64(1000300)
var expected []*model.Account
for _, hexAddr := range []string{hexAddr1, hexAddr2, hexAddr3} {
var acct *model.Account
for i := 0; i < 3; i++ {
acct = makeAccountWithBalance(model.ETHBytes, blockNumber+int64(i), hexAddr, strconv.FormatInt(blockNumber, 10))
err := store.InsertAccount(acct)
Expect(err).Should(Succeed())
}
// the last one is with the highest block number
expected = append(expected, acct)
blockNumber++
}

addrs := [][]byte{common.HexToBytes(hexAddr0), common.HexToBytes(hexAddr1), common.HexToBytes(hexAddr2), common.HexToBytes(hexAddr3), common.HexToBytes(hexAddr3)}
// should return accounts at latest block number
accounts, err := store.FindLatestAccounts(model.ETHAddress, addrs)
Expect(err).Should(Succeed())
Expect(len(accounts)).Should(Equal(3))
for i, acct := range accounts {
acct.ContractAddress = model.ETHBytes
Expect(acct).Should(Equal(expected[i]))
}
})

It("finds the erc20 records with highest block numbers", func() {
store := NewWithDB(db)

// Insert code to create table
hexAddr := "0xB287a379e6caCa6732E50b88D23c290aA990A892"
tokenAddr := gethCommon.HexToAddress(hexAddr)
erc20 := makeERC20(hexAddr)
err := store.InsertERC20(erc20)
Expect(err).Should(Succeed())

hexAddr0 := "0xF287a379e6caCa6732E50b88D23c290aA990A892" // does not exist in DB
hexAddr1 := "0xA287a379e6caCa6732E50b88D23c290aA990A892"
hexAddr2 := "0xC487a379e6caCa6732E50b88D23c290aA990A892"
hexAddr3 := "0xD487a379e6caCa6732E50b88D23c290aA990A892"

blockNumber := int64(1000300)
var expected []*model.Account
for _, hexAddr := range []string{hexAddr1, hexAddr2, hexAddr3} {
var acct *model.Account
for i := 0; i < 3; i++ {
acct = makeAccountWithBalance(erc20.Address, blockNumber+int64(i), hexAddr, strconv.FormatInt(blockNumber, 10))
err := store.InsertAccount(acct)
Expect(err).Should(Succeed())
}
// the last one is with the highest block number
expected = append(expected, acct)
blockNumber++
}
addrs := [][]byte{common.HexToBytes(hexAddr0), common.HexToBytes(hexAddr1), common.HexToBytes(hexAddr2), common.HexToBytes(hexAddr3), common.HexToBytes(hexAddr3)}
// should return accounts at latest block number
accounts, err := store.FindLatestAccounts(tokenAddr, addrs)
Expect(err).Should(Succeed())
Expect(len(accounts)).Should(Equal(3))
for i, acct := range accounts {
acct.ContractAddress = erc20.Address
Expect(acct).Should(Equal(expected[i]))
}
})
})

Context("DeleteAccounts()", func() {
It("deletes eth account states from a block number", func() {
store := NewWithDB(db)
Expand Down
23 changes: 23 additions & 0 deletions store/account/mocks/Store.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

61 changes: 0 additions & 61 deletions store/balance.go

This file was deleted.

Loading

0 comments on commit 4c3e5b5

Please sign in to comment.