Skip to content

Commit b910212

Browse files
committed
update to go 0.26 and address PR minor comments
Signed-off-by: Pau Escrich <p4u@dabax.net>
1 parent 62b3cbd commit b910212

11 files changed

Lines changed: 194 additions & 77 deletions

File tree

.github/workflows/main.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828
- name: Set up Go environment
2929
uses: actions/setup-go@v5
3030
with:
31-
go-version: '1.24'
31+
go-version: '1.26'
3232
- name: Tidy go module
3333
run: |
3434
go mod tidy
@@ -40,7 +40,7 @@ jobs:
4040
fi
4141
- name: Run gofumpt
4242
# Run gofumpt first, as it's quick and issues are common.
43-
run: diff -u <(echo -n) <(go run mvdan.cc/gofumpt@v0.7.0 -d .)
43+
run: diff -u <(echo -n) <(go run mvdan.cc/gofumpt@v0.9.2 -d .)
4444
- name: Run go vet
4545
run: go vet ./...
4646
- name: Run go generate
@@ -81,7 +81,7 @@ jobs:
8181
- uses: benjlevesque/short-sha@v3.0 # sets env.SHA to the first 7 chars of github.sha
8282
- uses: actions/setup-go@v5
8383
with:
84-
go-version: '1.24'
84+
go-version: '1.26'
8585
- run: mkdir -p "$PWD/gocoverage-unit/"
8686
- name: Run Go test -race
8787
id: go-test-race
@@ -151,7 +151,7 @@ jobs:
151151
- uses: actions/download-artifact@v4
152152
- uses: actions/setup-go@v5
153153
with:
154-
go-version: '1.24'
154+
go-version: '1.26'
155155
cache: false
156156
- name: Convert gocoverage format
157157
run: |
@@ -190,7 +190,7 @@ jobs:
190190
name: gocoverage-all-textfmt@${{ env.SHA }}
191191
- uses: actions/setup-go@v5
192192
with:
193-
go-version: '1.24'
193+
go-version: '1.26'
194194
cache: false
195195
- name: Send coverage to coveralls.io (unit)
196196
if: ${{ always() }}

.github/workflows/swagger.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ jobs:
2424
path: developer-portal
2525
- uses: actions/setup-go@v5
2626
with:
27-
go-version: '1.24'
27+
go-version: '1.26'
2828
cache: false
2929
- name: Install swag
3030
run: |

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# syntax=docker/dockerfile:experimental
22

3-
FROM golang:1.24 AS builder
3+
FROM golang:1.26 AS builder
44

55
ARG BUILDARGS
66

api/api_types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ func CensusTypeToOrigin(ctype CensusTypeDescription) (models.CensusOrigin, []byt
438438
origin = models.CensusOrigin_FARCASTER_FRAME
439439
root = ctype.RootHash
440440
default:
441-
return 0, nil, ErrCensusTypeUnknown.Withf("%q", ctype)
441+
return 0, nil, ErrCensusTypeUnknown.Withf("%v", ctype)
442442
}
443443
if root == nil {
444444
return 0, nil, ErrCensusRootIsNil

cmd/voconed/voconed.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,9 @@ func main() {
228228
vc.SetBlockSize(config.blockSize)
229229

230230
ctx, cancel := context.WithCancel(context.Background())
231+
startDone := make(chan struct{})
231232
go func() {
233+
defer close(startDone)
232234
if err := vc.Start(ctx); err != nil {
233235
log.Fatal(err)
234236
}
@@ -271,6 +273,8 @@ func main() {
271273
<-c
272274
log.Warnf("received SIGTERM, exiting at %s", time.Now().Format(time.RFC850))
273275
cancel()
276+
// Wait for the block production loop to exit before closing resources.
277+
<-startDone
274278
if err := vc.Close(); err != nil {
275279
log.Warnw("error closing vocone", "err", err)
276280
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module go.vocdoni.io/dvote
22

3-
go 1.24.0
3+
go 1.26.1
44

55
// For testing purposes
66
// replace go.vocdoni.io/proto => ../dvote-protobuf

vochain/cometbft.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ func (app *BaseApplication) InitChain(_ context.Context,
166166
for k, v := range genesisAppState.TxCost.AsMap() {
167167
err = app.State.SetTxBaseCost(k, v)
168168
if err != nil {
169-
return nil, fmt.Errorf("could not set tx cost %q to value %q from genesis file to the State", k, v)
169+
return nil, fmt.Errorf("could not set tx cost %q to value %d from genesis file to the State", k, v)
170170
}
171171
}
172172

vocone/blockstore.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ package vocone
33
import (
44
"encoding/binary"
55
"encoding/json"
6+
"errors"
67
"time"
78

89
comettmhash "github.com/cometbft/cometbft/crypto/tmhash"
910
comettypes "github.com/cometbft/cometbft/types"
1011
"go.vocdoni.io/dvote/crypto/ethereum"
12+
"go.vocdoni.io/dvote/db"
1113
"go.vocdoni.io/dvote/log"
1214
"go.vocdoni.io/proto/build/go/models"
1315
"google.golang.org/protobuf/proto"
@@ -43,6 +45,18 @@ func (vc *Vocone) storeBlockMeta(height int64, timestamp time.Time, txCount int3
4345
}
4446
wTx := vc.blockStore.WriteTx()
4547
defer wTx.Discard()
48+
if prevData, err := vc.blockStore.Get(metaKey(height)); err == nil {
49+
var prev blockMeta
50+
if jsonErr := json.Unmarshal(prevData, &prev); jsonErr == nil && len(prev.Hash) > 0 {
51+
if len(blockHash) == 0 || string(prev.Hash) != string(blockHash) {
52+
if err := wTx.Delete(blockHashKey(prev.Hash)); err != nil {
53+
return err
54+
}
55+
}
56+
}
57+
} else if !errors.Is(err, db.ErrKeyNotFound) {
58+
return err
59+
}
4660
if err := wTx.Set(metaKey(height), data); err != nil {
4761
return err
4862
}
@@ -154,6 +168,9 @@ func (vc *Vocone) getBlock(height int64) *comettypes.Block {
154168

155169
// getBlockByHash looks up a block by its hash using the reverse index.
156170
func (vc *Vocone) getBlockByHash(hash []byte) *comettypes.Block {
171+
if vc.closed.Load() {
172+
return nil
173+
}
157174
heightBytes, err := vc.blockStore.Get(blockHashKey(hash))
158175
if err != nil {
159176
return nil

vocone/mempool.go

Lines changed: 60 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package vocone
22

33
import (
4+
"bytes"
45
"context"
56
"encoding/binary"
67
"errors"
@@ -24,20 +25,38 @@ func (vc *Vocone) loadMempool() error {
2425
if err != nil && !errors.Is(err, db.ErrKeyNotFound) {
2526
return fmt.Errorf("could not read mempool sequence: %w", err)
2627
}
28+
var persistedSeq uint64
2729
if len(seqBytes) == 8 {
28-
vc.mempoolSeq = binary.BigEndian.Uint64(seqBytes)
30+
persistedSeq = binary.BigEndian.Uint64(seqBytes)
2931
}
3032

3133
// Iterate over all pending transactions and rebuild the key list.
3234
vc.mempoolKeys = nil
35+
var maxObservedSeq uint64
3336
if err := vc.mempoolDB.Iterate([]byte(prefixMempool), func(key, _ []byte) bool {
37+
switch {
38+
case len(key) == 8:
39+
// Some db wrappers return prefix-stripped keys.
40+
if seq := binary.BigEndian.Uint64(key); seq > maxObservedSeq {
41+
maxObservedSeq = seq
42+
}
43+
case len(key) >= len(prefixMempool)+8 && bytes.HasPrefix(key, []byte(prefixMempool)):
44+
if seq := binary.BigEndian.Uint64(key[len(key)-8:]); seq > maxObservedSeq {
45+
maxObservedSeq = seq
46+
}
47+
}
3448
keyCopy := make([]byte, len(key))
3549
copy(keyCopy, key)
3650
vc.mempoolKeys = append(vc.mempoolKeys, keyCopy)
3751
return true
3852
}); err != nil {
3953
return fmt.Errorf("could not iterate mempool: %w", err)
4054
}
55+
if persistedSeq >= maxObservedSeq {
56+
vc.mempoolSeq = persistedSeq
57+
} else {
58+
vc.mempoolSeq = maxObservedSeq
59+
}
4160

4261
if len(vc.mempoolKeys) > 0 {
4362
log.Infow("recovered pending transactions from mempool", "count", len(vc.mempoolKeys))
@@ -139,10 +158,10 @@ func mempoolKey(seq uint64) []byte {
139158
}
140159

141160
// prepareBlock drains transactions from the mempool, re-validates them,
142-
// stores valid ones in the block store, and returns the raw tx list.
143-
func (vc *Vocone) prepareBlock() [][]byte {
144-
height := vc.height.Load()
145-
161+
// and returns the raw tx list along with the mempool keys that were consumed.
162+
// It does NOT modify the mempool or blockstore — the caller is responsible
163+
// for persisting writes and cleaning up the mempool after a successful commit.
164+
func (vc *Vocone) prepareBlock() (txs [][]byte, consumedKeys [][]byte) {
146165
vc.mempoolMtx.Lock()
147166
// Take up to txsPerBlock keys from the front of the queue.
148167
count := min(vc.txsPerBlock, len(vc.mempoolKeys))
@@ -151,20 +170,9 @@ func (vc *Vocone) prepareBlock() [][]byte {
151170
vc.mempoolMtx.Unlock()
152171

153172
if len(pendingKeys) == 0 {
154-
return nil
173+
return nil, nil
155174
}
156175

157-
blockStoreTx := vc.blockStore.WriteTx()
158-
defer blockStoreTx.Discard()
159-
mempoolWTx := vc.mempoolDB.WriteTx()
160-
defer mempoolWTx.Discard()
161-
162-
var (
163-
transactions [][]byte
164-
consumedKeys [][]byte
165-
txCount int32
166-
)
167-
168176
for _, key := range pendingKeys {
169177
txData, err := vc.mempoolDB.Get(key)
170178
if err != nil {
@@ -187,42 +195,53 @@ func (vc *Vocone) prepareBlock() [][]byte {
187195
continue
188196
}
189197

190-
// Store in the block store.
191-
if err := blockStoreTx.Set(txKey(height, txCount), txData); err != nil {
192-
log.Errorw(err, "error storing tx in blockstore")
193-
break
194-
}
195-
transactions = append(transactions, txData)
198+
txs = append(txs, txData)
196199
consumedKeys = append(consumedKeys, key)
197-
txCount++
198200
}
199201

200-
// Commit block store writes.
201-
if len(transactions) > 0 {
202-
if err := blockStoreTx.Commit(); err != nil {
203-
log.Errorw(err, "could not commit block store transaction")
204-
return nil
205-
}
202+
if len(txs) > 0 {
203+
log.Infow("prepared block transactions",
204+
"count", len(txs), "height", vc.height.Load())
206205
}
206+
return txs, consumedKeys
207+
}
207208

208-
// Remove consumed transactions from the mempool db.
209+
// commitMempoolCleanup removes consumed keys from the persistent mempool
210+
// and the in-memory index. Must be called after a successful block commit.
211+
func (vc *Vocone) commitMempoolCleanup(consumedKeys [][]byte) {
212+
if len(consumedKeys) == 0 {
213+
return
214+
}
215+
wTx := vc.mempoolDB.WriteTx()
216+
defer wTx.Discard()
209217
for _, key := range consumedKeys {
210-
if err := mempoolWTx.Delete(key); err != nil {
218+
if err := wTx.Delete(key); err != nil {
211219
log.Errorw(err, "could not delete mempool entry")
212220
}
213221
}
214-
if err := mempoolWTx.Commit(); err != nil {
222+
if err := wTx.Commit(); err != nil {
215223
log.Errorw(err, "could not commit mempool cleanup")
216224
}
217225

218-
// Update the in-memory index.
226+
// Update the in-memory index by removing exactly the consumed keys.
219227
vc.mempoolMtx.Lock()
220-
vc.mempoolKeys = vc.mempoolKeys[len(consumedKeys):]
221-
vc.mempoolMtx.Unlock()
222-
223-
if len(transactions) > 0 {
224-
log.Infow("prepared block transactions",
225-
"count", len(transactions), "height", height)
228+
defer vc.mempoolMtx.Unlock()
229+
consumed := make(map[string]struct{}, len(consumedKeys))
230+
for _, key := range consumedKeys {
231+
consumed[string(key)] = struct{}{}
232+
}
233+
filtered := make([][]byte, 0, len(vc.mempoolKeys))
234+
removed := 0
235+
for _, key := range vc.mempoolKeys {
236+
if _, ok := consumed[string(key)]; ok {
237+
removed++
238+
continue
239+
}
240+
filtered = append(filtered, key)
241+
}
242+
if removed < len(consumed) {
243+
log.Warnw("mempool cleanup removed fewer keys than expected",
244+
"expectedUnique", len(consumed), "removed", removed)
226245
}
227-
return transactions
246+
vc.mempoolKeys = filtered
228247
}

0 commit comments

Comments
 (0)