Skip to content

Commit 5e45732

Browse files
committed
Merge branches 'feat/api-refactor-pagination' (early part) and 'feat/index-blocks' (early part) into dev
2 parents f68c27c + f4715f1 commit 5e45732

24 files changed

+475
-148
lines changed

api/api_types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,4 +403,5 @@ func CensusTypeToOrigin(ctype CensusTypeDescription) (models.CensusOrigin, []byt
403403
type Block struct {
404404
comettypes.Block `json:",inline"`
405405
Hash types.HexBytes `json:"hash" `
406+
TxCount int64 `json:"txCount"`
406407
}

api/chain.go

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313
"go.vocdoni.io/dvote/crypto/zk/circuit"
1414
"go.vocdoni.io/dvote/httprouter"
1515
"go.vocdoni.io/dvote/httprouter/apirest"
16-
"go.vocdoni.io/dvote/types"
1716
"go.vocdoni.io/dvote/util"
1817
"go.vocdoni.io/dvote/vochain"
1918
"go.vocdoni.io/dvote/vochain/genesis"
@@ -634,7 +633,7 @@ func (a *API) chainTxbyHashHandler(_ *apirest.APIdata, ctx *httprouter.HTTPConte
634633
if err != nil {
635634
return err
636635
}
637-
ref, err := a.indexer.GetTxHashReference(hash)
636+
ref, err := a.indexer.GetTxReferenceByHash(hash)
638637
if err != nil {
639638
if errors.Is(err, indexer.ErrTransactionNotFound) {
640639
return ErrTransactionNotFound
@@ -713,7 +712,7 @@ func (a *API) chainTxByIndexHandler(_ *apirest.APIdata, ctx *httprouter.HTTPCont
713712
if err != nil {
714713
return err
715714
}
716-
ref, err := a.indexer.GetTransaction(index)
715+
ref, err := a.indexer.GetTxReferenceByID(index)
717716
if err != nil {
718717
if errors.Is(err, indexer.ErrTransactionNotFound) {
719718
return ErrTransactionNotFound
@@ -776,7 +775,7 @@ func (a *API) chainTxByHeightHandler(_ *apirest.APIdata, ctx *httprouter.HTTPCon
776775
tx.ProtoReflect().Descriptor().Oneofs().Get(0)).Name())
777776

778777
// TODO: can we avoid indexer Get calls in a loop?
779-
txRef, err := a.indexer.GetTxHashReference(block.Txs[i].Hash())
778+
txRef, err := a.indexer.GetTxReferenceByHash(block.Txs[i].Hash())
780779
if err != nil {
781780
return ErrTransactionNotFound
782781
}
@@ -845,18 +844,31 @@ func (a *API) chainBlockHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContext)
845844
if err != nil {
846845
return err
847846
}
848-
tmblock := a.vocapp.GetBlockByHeight(int64(height))
849-
if tmblock == nil {
850-
return ErrBlockNotFound
847+
idxblock, err := a.indexer.BlockByHeight(int64(height))
848+
if err != nil {
849+
if errors.Is(err, indexer.ErrBlockNotFound) {
850+
return ErrBlockNotFound
851+
}
852+
return ErrBlockNotFound.WithErr(err)
853+
}
854+
txcount, err := a.indexer.CountTransactionsByHeight(int64(height))
855+
if err != nil {
856+
return ErrIndexerQueryFailed.WithErr(err)
851857
}
852858
block := &Block{
853859
Block: comettypes.Block{
854-
Header: tmblock.Header,
855-
Data: tmblock.Data,
856-
Evidence: tmblock.Evidence,
857-
LastCommit: tmblock.LastCommit,
860+
Header: comettypes.Header{
861+
ChainID: idxblock.ChainID,
862+
Height: idxblock.Height,
863+
Time: idxblock.Time,
864+
ProposerAddress: []byte(idxblock.ProposerAddress),
865+
LastBlockID: comettypes.BlockID{
866+
Hash: []byte(idxblock.LastBlockHash),
867+
},
868+
},
858869
},
859-
Hash: types.HexBytes(tmblock.Hash()),
870+
Hash: idxblock.Hash,
871+
TxCount: txcount,
860872
}
861873
data, err := json.Marshal(block)
862874
if err != nil {
@@ -880,18 +892,31 @@ func (a *API) chainBlockByHashHandler(_ *apirest.APIdata, ctx *httprouter.HTTPCo
880892
if err != nil {
881893
return err
882894
}
883-
tmblock := a.vocapp.GetBlockByHash(hash)
884-
if tmblock == nil {
885-
return ErrBlockNotFound
895+
idxblock, err := a.indexer.BlockByHash(hash)
896+
if err != nil {
897+
if errors.Is(err, indexer.ErrBlockNotFound) {
898+
return ErrBlockNotFound
899+
}
900+
return ErrBlockNotFound.WithErr(err)
901+
}
902+
txcount, err := a.indexer.CountTransactionsByHeight(idxblock.Height)
903+
if err != nil {
904+
return ErrIndexerQueryFailed.WithErr(err)
886905
}
887906
block := &Block{
888907
Block: comettypes.Block{
889-
Header: tmblock.Header,
890-
Data: tmblock.Data,
891-
Evidence: tmblock.Evidence,
892-
LastCommit: tmblock.LastCommit,
908+
Header: comettypes.Header{
909+
ChainID: idxblock.ChainID,
910+
Height: idxblock.Height,
911+
Time: idxblock.Time,
912+
ProposerAddress: []byte(idxblock.ProposerAddress),
913+
LastBlockID: comettypes.BlockID{
914+
Hash: []byte(idxblock.LastBlockHash),
915+
},
916+
},
893917
},
894-
Hash: types.HexBytes(tmblock.Hash()),
918+
Hash: idxblock.Hash,
919+
TxCount: txcount,
895920
}
896921
data, err := json.Marshal(block)
897922
if err != nil {

test/api_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,41 @@ func TestAPIAccountTokentxs(t *testing.T) {
468468
qt.Assert(t, gotAcct1.Balance, qt.Equals, initBalance+amountAcc2toAcct1-amountAcc1toAcct2-uint64(txBasePrice))
469469
}
470470

471+
func TestAPIBlocks(t *testing.T) {
472+
server := testcommon.APIserver{}
473+
server.Start(t,
474+
api.ChainHandler,
475+
api.CensusHandler,
476+
api.VoteHandler,
477+
api.AccountHandler,
478+
api.ElectionHandler,
479+
api.WalletHandler,
480+
)
481+
token1 := uuid.New()
482+
c := testutil.NewTestHTTPclient(t, server.ListenAddr, &token1)
483+
484+
// Block 1
485+
server.VochainAPP.AdvanceTestBlock()
486+
waitUntilHeight(t, c, 1)
487+
488+
// create a new account
489+
initBalance := uint64(80)
490+
_ = createAccount(t, c, server, initBalance)
491+
492+
// Block 2
493+
server.VochainAPP.AdvanceTestBlock()
494+
waitUntilHeight(t, c, 2)
495+
496+
// check the txCount
497+
resp, code := c.Request("GET", nil, "chain", "blocks", "1")
498+
qt.Assert(t, code, qt.Equals, 200, qt.Commentf("response: %s", resp))
499+
500+
block := api.Block{}
501+
err := json.Unmarshal(resp, &block)
502+
qt.Assert(t, err, qt.IsNil)
503+
qt.Assert(t, block.TxCount, qt.Equals, int64(1))
504+
}
505+
471506
func runAPIElectionCostWithParams(t *testing.T,
472507
electionParams electionprice.ElectionParameters,
473508
startBlock uint32, initialBalance,

vochain/app.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -290,10 +290,6 @@ func (app *BaseApplication) beginBlock(t time.Time, height uint32) {
290290
app.State.SetHeight(height)
291291

292292
go app.State.CachePurge(height)
293-
app.State.OnBeginBlock(vstate.BeginBlock{
294-
Height: int64(height),
295-
Time: t,
296-
})
297293
}
298294

299295
// endBlock is called at the end of every block.

vochain/appsetup.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,6 @@ func (app *BaseApplication) SetNode(vochaincfg *config.VochainCfg) error {
2525
if app.Node, err = newTendermint(app, vochaincfg); err != nil {
2626
return fmt.Errorf("could not set tendermint node service: %s", err)
2727
}
28-
if vochaincfg.IsSeedNode {
29-
return nil
30-
}
3128
// Note that cometcli.New logs any error rather than returning it.
3229
app.NodeClient = cometcli.New(app.Node)
3330
return nil

vochain/indexer/bench_test.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ func BenchmarkIndexer(b *testing.B) {
8585
tx := &vochaintx.Tx{
8686
TxID: rnd.Random32(),
8787
TxModelType: "vote",
88+
Tx: &models.Tx{Payload: &models.Tx_Vote{}},
8889
}
8990
idx.OnNewTx(tx, height, txBlockIndex)
9091
curTxs = append(curTxs, tx)
@@ -112,7 +113,7 @@ func BenchmarkIndexer(b *testing.B) {
112113
qt.Check(b, bytes.Equal(voteRef.Meta.TxHash, tx.TxID[:]), qt.IsTrue)
113114
}
114115

115-
txRef, err := idx.GetTxHashReference(tx.TxID[:])
116+
txRef, err := idx.GetTxReferenceByHash(tx.TxID[:])
116117
qt.Check(b, err, qt.IsNil)
117118
if err == nil {
118119
qt.Check(b, txRef.BlockHeight, qt.Equals, vote.Height)
@@ -138,7 +139,11 @@ func BenchmarkFetchTx(b *testing.B) {
138139
b.ResetTimer()
139140
for i := 0; i < b.N; i++ {
140141
for j := 0; j < numTxs; j++ {
141-
idx.OnNewTx(&vochaintx.Tx{TxID: util.Random32()}, uint32(i), int32(j))
142+
idx.OnNewTx(&vochaintx.Tx{
143+
TxID: util.Random32(),
144+
TxModelType: "vote",
145+
Tx: &models.Tx{Payload: &models.Tx_Vote{}},
146+
}, uint32(i), int32(j))
142147
}
143148
err := idx.Commit(uint32(i))
144149
qt.Assert(b, err, qt.IsNil)
@@ -147,14 +152,14 @@ func BenchmarkFetchTx(b *testing.B) {
147152

148153
startTime := time.Now()
149154
for j := 0; j < numTxs; j++ {
150-
_, err = idx.GetTransaction(uint64((i * numTxs) + j + 1))
155+
_, err = idx.GetTxReferenceByID(uint64((i * numTxs) + j + 1))
151156
qt.Assert(b, err, qt.IsNil)
152157
}
153158
log.Infof("fetched %d transactions (out of %d total) by index, took %s",
154159
numTxs, (i+1)*numTxs, time.Since(startTime))
155160
startTime = time.Now()
156161
for j := 0; j < numTxs; j++ {
157-
_, err = idx.GetTxHashReference([]byte(fmt.Sprintf("hash%d%d", i, j)))
162+
_, err = idx.GetTxReferenceByHash([]byte(fmt.Sprintf("hash%d%d", i, j)))
158163
qt.Assert(b, err, qt.IsNil)
159164
}
160165
log.Infof("fetched %d transactions (out of %d total) by hash, took %s",

vochain/indexer/block.go

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,35 +7,41 @@ import (
77
"fmt"
88
"time"
99

10-
"go.vocdoni.io/dvote/log"
11-
indexerdb "go.vocdoni.io/dvote/vochain/indexer/db"
12-
"go.vocdoni.io/dvote/vochain/state"
10+
"go.vocdoni.io/dvote/vochain/indexer/indexertypes"
1311
)
1412

1513
// ErrBlockNotFound is returned if the block is not found in the indexer database.
1614
var ErrBlockNotFound = fmt.Errorf("block not found")
1715

18-
func (idx *Indexer) OnBeginBlock(bb state.BeginBlock) {
19-
idx.blockMu.Lock()
20-
defer idx.blockMu.Unlock()
21-
queries := idx.blockTxQueries()
22-
if _, err := queries.CreateBlock(context.TODO(), indexerdb.CreateBlockParams{
23-
Height: bb.Height,
24-
Time: bb.Time,
25-
DataHash: nonNullBytes(bb.DataHash),
26-
}); err != nil {
27-
log.Errorw(err, "cannot index new block")
16+
// BlockTimestamp returns the timestamp of the block at the given height
17+
func (idx *Indexer) BlockTimestamp(height int64) (time.Time, error) {
18+
block, err := idx.BlockByHeight(height)
19+
if err != nil {
20+
return time.Time{}, err
2821
}
22+
return block.Time, nil
2923
}
3024

31-
// BlockTimestamp returns the timestamp of the block at the given height
32-
func (idx *Indexer) BlockTimestamp(height int64) (time.Time, error) {
33-
block, err := idx.readOnlyQuery.GetBlock(context.TODO(), height)
25+
// BlockByHeight returns the available information of the block at the given height
26+
func (idx *Indexer) BlockByHeight(height int64) (*indexertypes.Block, error) {
27+
block, err := idx.readOnlyQuery.GetBlockByHeight(context.TODO(), height)
3428
if err != nil {
3529
if errors.Is(err, sql.ErrNoRows) {
36-
return time.Time{}, ErrBlockNotFound
30+
return nil, ErrBlockNotFound
3731
}
38-
return time.Time{}, err
32+
return nil, err
3933
}
40-
return block.Time, nil
34+
return indexertypes.BlockFromDB(&block), nil
35+
}
36+
37+
// BlockByHeight returns the available information of the block with the given hash
38+
func (idx *Indexer) BlockByHash(hash []byte) (*indexertypes.Block, error) {
39+
block, err := idx.readOnlyQuery.GetBlockByHash(context.TODO(), hash)
40+
if err != nil {
41+
if errors.Is(err, sql.ErrNoRows) {
42+
return nil, ErrBlockNotFound
43+
}
44+
return nil, err
45+
}
46+
return indexertypes.BlockFromDB(&block), nil
4147
}

vochain/indexer/db/blocks.sql.go

Lines changed: 48 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)