Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support query account tx APIs by txType #227

Merged
merged 5 commits into from
Oct 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 38 additions & 6 deletions dao/tx/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,26 @@ const (
StatusVerified
)

type getTxOption struct {
Types []int64
}

type GetTxOptionFunc func(*getTxOption)

func GetTxWithTypes(txTypes []int64) GetTxOptionFunc {
return func(o *getTxOption) {
o.Types = txTypes
}
}

type (
TxModel interface {
CreateTxTable() error
DropTxTable() error
GetTxsTotalCount() (count int64, err error)
GetTxs(limit int64, offset int64) (txList []*Tx, err error)
GetTxsByAccountIndex(accountIndex int64, limit int64, offset int64) (txList []*Tx, err error)
GetTxsCountByAccountIndex(accountIndex int64) (count int64, err error)
GetTxsByAccountIndex(accountIndex int64, limit int64, offset int64, options ...GetTxOptionFunc) (txList []*Tx, err error)
GetTxsCountByAccountIndex(accountIndex int64, options ...GetTxOptionFunc) (count int64, err error)
GetTxByHash(txHash string) (tx *Tx, err error)
GetTxsTotalCountBetween(from, to time.Time) (count int64, err error)
GetDistinctAccountsCountBetween(from, to time.Time) (count int64, err error)
Expand Down Expand Up @@ -127,8 +139,18 @@ func (m *defaultTxModel) GetTxs(limit int64, offset int64) (txList []*Tx, err er
return txList, nil
}

func (m *defaultTxModel) GetTxsByAccountIndex(accountIndex int64, limit int64, offset int64) (txList []*Tx, err error) {
dbTx := m.DB.Table(m.table).Where("account_index = ?", accountIndex).Limit(int(limit)).Offset(int(offset)).Order("created_at desc").Find(&txList)
func (m *defaultTxModel) GetTxsByAccountIndex(accountIndex int64, limit int64, offset int64, options ...GetTxOptionFunc) (txList []*Tx, err error) {
opt := &getTxOption{}
for _, f := range options {
f(opt)
}

dbTx := m.DB.Table(m.table).Where("account_index = ?", accountIndex)
if len(opt.Types) > 0 {
dbTx = dbTx.Where("tx_type IN ?", opt.Types)
}

dbTx = dbTx.Limit(int(limit)).Offset(int(offset)).Order("created_at desc").Find(&txList)
if dbTx.Error != nil {
return nil, types.DbErrSqlOperation
} else if dbTx.RowsAffected == 0 {
Expand All @@ -137,8 +159,18 @@ func (m *defaultTxModel) GetTxsByAccountIndex(accountIndex int64, limit int64, o
return txList, nil
}

func (m *defaultTxModel) GetTxsCountByAccountIndex(accountIndex int64) (count int64, err error) {
dbTx := m.DB.Table(m.table).Where("account_index = ?", accountIndex).Count(&count)
func (m *defaultTxModel) GetTxsCountByAccountIndex(accountIndex int64, options ...GetTxOptionFunc) (count int64, err error) {
opt := &getTxOption{}
for _, f := range options {
f(opt)
}

dbTx := m.DB.Table(m.table).Where("account_index = ?", accountIndex)
if len(opt.Types) > 0 {
dbTx = dbTx.Where("tx_type IN ?", opt.Types)
}

dbTx = dbTx.Count(&count)
if dbTx.Error != nil {
return 0, types.DbErrSqlOperation
} else if dbTx.RowsAffected == 0 {
Expand Down
17 changes: 13 additions & 4 deletions dao/tx/tx_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ type (
GetTxByTxHash(hash string) (txs *Tx, err error)
GetTxsByStatus(status int) (txs []*Tx, err error)
CreateTxs(txs []*Tx) error
GetPendingTxsByAccountIndex(accountIndex int64) (txs []*Tx, err error)
GetPendingTxsByAccountIndex(accountIndex int64, options ...GetTxOptionFunc) (txs []*Tx, err error)
GetMaxNonceByAccountIndex(accountIndex int64) (nonce int64, err error)
CreateTxsInTransact(tx *gorm.DB, txs []*Tx) error
UpdateTxsInTransact(tx *gorm.DB, txs []*Tx) error
Expand Down Expand Up @@ -122,9 +122,18 @@ func (m *defaultTxPoolModel) CreateTxs(txs []*Tx) error {
})
}

func (m *defaultTxPoolModel) GetPendingTxsByAccountIndex(accountIndex int64) (txs []*Tx, err error) {
dbTx := m.DB.Table(m.table).Where("tx_status = ? AND account_index = ?", StatusPending, accountIndex).
Order("created_at, id").Find(&txs)
func (m *defaultTxPoolModel) GetPendingTxsByAccountIndex(accountIndex int64, options ...GetTxOptionFunc) (txs []*Tx, err error) {
opt := &getTxOption{}
for _, f := range options {
f(opt)
}

dbTx := m.DB.Table(m.table).Where("tx_status = ? AND account_index = ?", StatusPending, accountIndex)
if len(opt.Types) > 0 {
dbTx = dbTx.Where("tx_type IN ?", opt.Types)
}

dbTx = dbTx.Order("created_at, id").Find(&txs)
if dbTx.Error != nil {
return nil, types.DbErrSqlOperation
} else if dbTx.RowsAffected == 0 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

"github.com/zeromicro/go-zero/core/logx"

"github.com/bnb-chain/zkbnb/dao/tx"
"github.com/bnb-chain/zkbnb/service/apiserver/internal/logic/utils"
"github.com/bnb-chain/zkbnb/service/apiserver/internal/svc"
"github.com/bnb-chain/zkbnb/service/apiserver/internal/types"
Expand Down Expand Up @@ -53,7 +54,12 @@ func (l *GetAccountPendingTxsLogic) GetAccountPendingTxs(req *types.ReqGetAccoun
return nil, types2.AppErrInternal
}

poolTxs, err := l.svcCtx.TxPoolModel.GetPendingTxsByAccountIndex(accountIndex)
options := []tx.GetTxOptionFunc{}
if len(req.Types) > 0 {
options = append(options, tx.GetTxWithTypes(req.Types))
}

poolTxs, err := l.svcCtx.TxPoolModel.GetPendingTxsByAccountIndex(accountIndex, options...)
if err != nil {
if err != types2.DbErrNotFound {
return nil, types2.AppErrInternal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

"github.com/zeromicro/go-zero/core/logx"

"github.com/bnb-chain/zkbnb/dao/tx"
"github.com/bnb-chain/zkbnb/service/apiserver/internal/logic/utils"
"github.com/bnb-chain/zkbnb/service/apiserver/internal/svc"
"github.com/bnb-chain/zkbnb/service/apiserver/internal/types"
Expand Down Expand Up @@ -59,7 +60,12 @@ func (l *GetAccountTxsLogic) GetAccountTxs(req *types.ReqGetAccountTxs) (resp *t
return nil, types2.AppErrInternal
}

total, err := l.svcCtx.TxModel.GetTxsCountByAccountIndex(accountIndex)
options := []tx.GetTxOptionFunc{}
if len(req.Types) > 0 {
options = append(options, tx.GetTxWithTypes(req.Types))
}

total, err := l.svcCtx.TxModel.GetTxsCountByAccountIndex(accountIndex, options...)
if err != nil {
return nil, types2.AppErrInternal
}
Expand All @@ -69,7 +75,7 @@ func (l *GetAccountTxsLogic) GetAccountTxs(req *types.ReqGetAccountTxs) (resp *t
return resp, nil
}

txs, err := l.svcCtx.TxModel.GetTxsByAccountIndex(accountIndex, int64(req.Limit), int64(req.Offset))
txs, err := l.svcCtx.TxModel.GetTxsByAccountIndex(accountIndex, int64(req.Limit), int64(req.Offset), options...)
if err != nil {
return nil, types2.AppErrInternal
}
Expand Down
14 changes: 8 additions & 6 deletions service/apiserver/server.api
Original file line number Diff line number Diff line change
Expand Up @@ -308,10 +308,11 @@ type (
}

ReqGetAccountTxs {
By string `form:"by,options=account_index|account_name|account_pk"`
Value string `form:"value"`
Offset uint16 `form:"offset,range=[0:100000]"`
Limit uint16 `form:"limit,range=[1:100]"`
By string `form:"by,options=account_index|account_name|account_pk"`
Value string `form:"value"`
Types []int64 `form:"types,optional"`
Offset uint16 `form:"offset,range=[0:100000]"`
Limit uint16 `form:"limit,range=[1:100]"`
}

ReqGetTx {
Expand All @@ -324,8 +325,9 @@ type (
}

ReqGetAccountPendingTxs {
By string `form:"by,options=account_index|account_name|account_pk"`
Value string `form:"value"`
By string `form:"by,options=account_index|account_name|account_pk"`
Value string `form:"value"`
Types []int64 `form:"types,optional"`
}

ReqGetNextNonce {
Expand Down
35 changes: 22 additions & 13 deletions service/apiserver/test/getaccountpendingtxs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ import (

func (s *ApiServerSuite) TestGetAccountPoolTxs() {
type args struct {
by string
value string
by string
value string
txTypes []int64
}

type testcase struct {
Expand All @@ -26,25 +27,28 @@ func (s *ApiServerSuite) TestGetAccountPoolTxs() {
}

tests := []testcase{
{"not found by index", args{"account_index", "9999999"}, 200},
{"not found by name", args{"account_name", "notexists.legend"}, 200},
{"not found by pk", args{"account_pk", "notexists"}, 200},
{"invalidby", args{"invalidby", ""}, 400},
{"not found by index", args{"account_index", "9999999", nil}, 200},
{"not found by name", args{"account_name", "notexists.legend", nil}, 200},
{"not found by pk", args{"account_pk", "notexists", nil}, 200},
{"invalidby", args{"invalidby", "", nil}, 400},
}

statusCode, txs := GetPendingTxs(s, 0, 100)
if statusCode == http.StatusOK && len(txs.Txs) > 0 {
_, account := GetAccount(s, "name", txs.Txs[len(txs.Txs)-1].AccountName)
tx := txs.Txs[len(txs.Txs)-1]
_, account := GetAccount(s, "name", tx.AccountName)
tests = append(tests, []testcase{
{"found by index", args{"account_index", strconv.Itoa(int(account.Index))}, 200},
{"found by name", args{"account_name", account.Name}, 200},
{"found by pk", args{"account_pk", account.Pk}, 200},
{"found by index", args{"account_index", strconv.Itoa(int(account.Index)), nil}, 200},
{"found by name", args{"account_name", account.Name, nil}, 200},
{"found by pk", args{"account_pk", account.Pk, nil}, 200},
{"found by index and type", args{"account_index", strconv.Itoa(int(account.Index)), []int64{tx.Type}}, 200},
{"not found by index and type", args{"account_index", strconv.Itoa(int(account.Index)), []int64{10000}}, 200},
}...)
}

for _, tt := range tests {
s.T().Run(tt.name, func(t *testing.T) {
httpCode, result := GetAccountPendingTxs(s, tt.args.by, tt.args.value)
httpCode, result := GetAccountPendingTxs(s, tt.args.by, tt.args.value, tt.args.txTypes)
assert.Equal(t, tt.httpCode, httpCode)
if httpCode == http.StatusOK {
if result.Total > 0 {
Expand All @@ -63,8 +67,13 @@ func (s *ApiServerSuite) TestGetAccountPoolTxs() {

}

func GetAccountPendingTxs(s *ApiServerSuite, by, value string) (int, *types.Txs) {
resp, err := http.Get(fmt.Sprintf("%s/api/v1/accountPendingTxs?by=%s&value=%s", s.url, by, value))
func GetAccountPendingTxs(s *ApiServerSuite, by, value string, txTypes []int64) (int, *types.Txs) {
url := fmt.Sprintf("%s/api/v1/accountPendingTxs?by=%s&value=%s", s.url, by, value)
if len(txTypes) > 0 {
data, _ := json.Marshal(txTypes)
url += fmt.Sprintf("&types=%s", string(data))
}
resp, err := http.Get(url)
assert.NoError(s.T(), err)
defer resp.Body.Close()

Expand Down
39 changes: 24 additions & 15 deletions service/apiserver/test/getaccounttxs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ import (

func (s *ApiServerSuite) TestGetAccountTxs() {
type args struct {
by string
value string
offset int
limit int
by string
value string
offset int
limit int
txTypes []int64
}

type testcase struct {
Expand All @@ -28,25 +29,28 @@ func (s *ApiServerSuite) TestGetAccountTxs() {
}

tests := []testcase{
{"not found by index", args{"account_index", "99999999", 0, 10}, 200},
{"not found by name", args{"account_name", "fakeaccount.legend", 0, 10}, 200},
{"not found by pk", args{"account_pk", "fake8470d33c59a5cbf5e10df426eb97c2773ab890c3364f4162ba782a56ca998", 0, 10}, 200},
{"invalid by", args{"invalidby", "fake8470d33c59a5cbf5e10df426eb97c2773ab890c3364f4162ba782a56ca998", 0, 10}, 400},
{"not found by index", args{"account_index", "99999999", 0, 10, nil}, 200},
{"not found by name", args{"account_name", "fakeaccount.legend", 0, 10, nil}, 200},
{"not found by pk", args{"account_pk", "fake8470d33c59a5cbf5e10df426eb97c2773ab890c3364f4162ba782a56ca998", 0, 10, nil}, 200},
{"invalid by", args{"invalidby", "fake8470d33c59a5cbf5e10df426eb97c2773ab890c3364f4162ba782a56ca998", 0, 10, nil}, 400},
}

statusCode, txs := GetTxs(s, 0, 100)
if statusCode == http.StatusOK && len(txs.Txs) > 0 {
_, account := GetAccount(s, "name", txs.Txs[len(txs.Txs)-1].AccountName)
tx := txs.Txs[len(txs.Txs)-1]
_, account := GetAccount(s, "name", tx.AccountName)
tests = append(tests, []testcase{
{"found by index", args{"account_index", strconv.Itoa(int(account.Index)), 0, 10}, 200},
{"found by name", args{"account_name", account.Name, 0, 10}, 200},
{"found by pk", args{"account_pk", account.Pk, 0, 10}, 200},
{"found by index", args{"account_index", strconv.Itoa(int(account.Index)), 0, 10, nil}, 200},
{"found by name", args{"account_name", account.Name, 0, 10, nil}, 200},
{"found by pk", args{"account_pk", account.Pk, 0, 10, nil}, 200},
{"found by index and type", args{"account_index", strconv.Itoa(int(account.Index)), 0, 10, []int64{tx.Type}}, 200},
{"not found by index and type", args{"account_index", strconv.Itoa(int(account.Index)), 0, 10, []int64{10000}}, 200},
}...)
}

for _, tt := range tests {
s.T().Run(tt.name, func(t *testing.T) {
httpCode, result := GetAccountTxs(s, tt.args.by, tt.args.value, tt.args.offset, tt.args.limit)
httpCode, result := GetAccountTxs(s, tt.args.by, tt.args.value, tt.args.offset, tt.args.limit, tt.args.txTypes)
assert.Equal(t, tt.httpCode, httpCode)
if httpCode == http.StatusOK {
if tt.args.offset < int(result.Total) {
Expand All @@ -65,8 +69,13 @@ func (s *ApiServerSuite) TestGetAccountTxs() {

}

func GetAccountTxs(s *ApiServerSuite, by, value string, offset, limit int) (int, *types.Txs) {
resp, err := http.Get(fmt.Sprintf("%s/api/v1/accountTxs?by=%s&value=%s&offset=%d&limit=%d", s.url, by, value, offset, limit))
func GetAccountTxs(s *ApiServerSuite, by, value string, offset, limit int, txTypes []int64) (int, *types.Txs) {
url := fmt.Sprintf("%s/api/v1/accountTxs?by=%s&value=%s&offset=%d&limit=%d", s.url, by, value, offset, limit)
if len(txTypes) > 0 {
data, _ := json.Marshal(txTypes)
url += fmt.Sprintf("&types=%s", string(data))
}
resp, err := http.Get(url)
assert.NoError(s.T(), err)
defer resp.Body.Close()

Expand Down