Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
38b9a0d
WIP: Base itest suite added with support of feature 25 added.
alexeykiselev Apr 13, 2026
5898f71
Fixed Docker connection API version.
alexeykiselev Apr 15, 2026
9982d9f
Rise level of log message.
alexeykiselev Apr 15, 2026
4d4bd2d
Scala node commitment for generation added to finality smoke itest.
alexeykiselev Apr 16, 2026
9c31ae1
Correct BLS keys generation for Go and Scala miners.
alexeykiselev Apr 16, 2026
87e51e6
Fixed BLS key generation for non-mining accounts.
alexeykiselev Apr 16, 2026
16778ec
Copilot review issues fixed.
alexeykiselev Apr 16, 2026
7245f18
Review fixes.
alexeykiselev Apr 17, 2026
90b617b
WIP. Function to burn deposit added.
alexeykiselev Apr 21, 2026
8a23896
WIP. TransactionID field added to commitments item.
alexeykiselev Apr 21, 2026
4af54c0
New way of storing and initializing of generator set implemented.
alexeykiselev Apr 23, 2026
109c7d3
Merge branch 'determenistic-finality-feature' into burn-deposit
alexeykiselev Apr 23, 2026
6f125ff
Default values for new setting added.
alexeykiselev Apr 23, 2026
c830be1
Fixed height issue then querying generating balance from generator set.
alexeykiselev Apr 24, 2026
19153b2
Merge branch 'determenistic-finality-feature' into burn-deposit
alexeykiselev Apr 27, 2026
f3b0bca
NG activation check added to mined block action of Sync state.
alexeykiselev Apr 28, 2026
446a034
Fixed copilot review issues.
alexeykiselev Apr 28, 2026
8a51c43
Fixed JSON names for finalized block API.
alexeykiselev Apr 28, 2026
aacf0f8
Duplicate sync peer field removed.
alexeykiselev Apr 29, 2026
443cd7e
Endorsements validation during block application depend on finalized …
alexeykiselev Apr 29, 2026
c512489
Peers suspending replaced with blacklisting.
alexeykiselev Apr 30, 2026
cae8e1f
Switching to Idle state directly after receiving empty signatures fro…
alexeykiselev Apr 30, 2026
eed3b3b
Select peer with the maximus score if no peer sync selected.
alexeykiselev May 4, 2026
f6eb621
Merge branch 'determenistic-finality-feature' into burn-deposit
alexeykiselev May 6, 2026
5b022be
Merge branch 'determenistic-finality-feature' into burn-deposit
alexeykiselev May 14, 2026
3169f46
Review fixes.
alexeykiselev May 14, 2026
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
2 changes: 2 additions & 0 deletions itests/config/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ func NewBlockchainConfig(options ...BlockchainOption) (*BlockchainConfig, error)
bs.BlockRewardTerm = defaultBlockRewardTerm
bs.MinXTNBuyBackPeriod = defaultMinXTNBuyBackPeriod
bs.LightNodeBlockFieldsAbsenceInterval = lightNodeBlockFieldsAbsenceInterval
bs.GenerationPeriod = defaultGenerationPeriod
bs.MaxEndorsements = defaultMaxEndorsements

cfg := &BlockchainConfig{
Settings: bs,
Expand Down
3 changes: 3 additions & 0 deletions itests/config/genesis_settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ const (
defaultQuorum = 1 // Default quorum is 1 to allow mining without waiting for testnet client.

lightNodeBlockFieldsAbsenceInterval = 2

defaultGenerationPeriod = 5
defaultMaxEndorsements = 3
)

var (
Expand Down
42 changes: 13 additions & 29 deletions pkg/api/node_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -623,14 +623,6 @@ func (a *NodeApi) PeersConnected(w http.ResponseWriter, _ *http.Request) error {
return nil
}

func (a *NodeApi) PeersSuspended(w http.ResponseWriter, _ *http.Request) error {
rs := a.app.PeersSuspended()
if err := trySendJSON(w, rs); err != nil {
return errors.Wrap(err, "PeersSuspended")
}
return nil
}

func (a *NodeApi) PeersBlackListed(w http.ResponseWriter, _ *http.Request) error {
rs := a.app.PeersBlackListed()
if err := trySendJSON(w, rs); err != nil {
Expand Down Expand Up @@ -906,13 +898,6 @@ func (a *NodeApi) snapshotStateHash(w http.ResponseWriter, r *http.Request) erro
return nil
}

// TODO: Move JSON tags to GeneratorInfo structure.
type generatorInfo struct {
Address string `json:"address"`
Balance uint64 `json:"balance"`
TransactionID string `json:"transactionID"`
}

func (a *NodeApi) GeneratorsAt(w http.ResponseWriter, r *http.Request) error {
heightStr := chi.URLParam(r, "height")
height, err := strconv.ParseUint(heightStr, 10, 64)
Expand All @@ -935,32 +920,31 @@ func (a *NodeApi) GeneratorsAt(w http.ResponseWriter, r *http.Request) error {
if err != nil {
return err
}

infos := make([]generatorInfo, len(gs))
for i, g := range gs {
infos[i] = generatorInfo{
Address: g.Address().String(),
Balance: g.GenerationBalance(),
TransactionID: "", // It was decided to leave it empty.
}
}
return trySendJSON(w, infos)
return trySendJSON(w, gs)
}

func (a *NodeApi) FinalizedHeight(w http.ResponseWriter, _ *http.Request) error {
h, err := a.state.LastFinalizedHeight()
if err != nil {
return err
return fmt.Errorf("failed to get finalized block height: %w", err)
}
return trySendJSON(w, map[string]uint64{"height": h})
}

func (a *NodeApi) FinalizedHeader(w http.ResponseWriter, _ *http.Request) error {
blockHeader, err := a.app.state.LastFinalizedBlock()
fh, err := a.state.LastFinalizedHeight()
if err != nil {
return err
return fmt.Errorf("failed to get finalized block height: %w", err)
}
header, err := a.app.state.LastFinalizedBlock()
if err != nil {
return fmt.Errorf("failed to get finalized block header: %w", err)
}
b, err := newAPIBlockFromHeader(*header, a.app.scheme(), fh)
if err != nil {
return fmt.Errorf("failed to get finalized block: %w", err)
}
return trySendJSON(w, blockHeader)
return trySendJSON(w, b)
}

type signTxEnvelope struct {
Expand Down
21 changes: 1 addition & 20 deletions pkg/api/peers.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,8 @@ type PeersKnown struct {
// PeersAll is a list of all known not banned, not suspended and not blacklisted peers with a publicly
// available declared address.
func (a *App) PeersAll() (PeersKnown, error) {
suspended := a.peers.Suspended()
blackList := a.peers.BlackList()
restrictedIPsMap := make(map[string]struct{}, len(suspended)+len(blackList))
for _, suspendedPeer := range suspended {
restrictedIPsMap[suspendedPeer.IP.String()] = struct{}{}
}
restrictedIPsMap := make(map[string]struct{}, len(blackList))
for _, blackListedPeer := range blackList {
restrictedIPsMap[blackListedPeer.IP.String()] = struct{}{}
}
Expand Down Expand Up @@ -144,21 +140,6 @@ type RestrictedPeerInfo struct {
Reason string `json:"reason,omitempty"`
}

func (a *App) PeersSuspended() []RestrictedPeerInfo {
suspended := a.peers.Suspended()

out := make([]RestrictedPeerInfo, 0, len(suspended))
for _, p := range suspended {
out = append(out, RestrictedPeerInfo{
Hostname: "/" + p.IP.String(),
Timestamp: p.RestrictTimestampMillis,
Reason: p.Reason,
})
}

return out
}

func (a *App) PeersBlackListed() []RestrictedPeerInfo {
blackList := a.peers.BlackList()

Expand Down
44 changes: 0 additions & 44 deletions pkg/api/peers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,50 +33,6 @@ func TestApp_PeersKnown(t *testing.T) {
require.Len(t, rs2.Peers, 1)
}

func TestApp_PeersSuspended(t *testing.T) {
peerManager := peers.NewMockPeerManager(t)

now := time.Now()
cfg := &settings.BlockchainSettings{
FunctionalitySettings: settings.FunctionalitySettings{
GenerationPeriod: 0,
},
}

ips := []string{"13.3.4.1", "5.3.6.7"}
testData := []storage.SuspendedPeer{
{
IP: storage.IPFromString(ips[0]),
RestrictTimestampMillis: now.Add(time.Minute).UnixMilli(),
RestrictDuration: time.Minute,
Reason: "some reason #1",
},
{
IP: storage.IPFromString(ips[1]),
RestrictTimestampMillis: now.Add(2 * time.Minute).UnixMilli(),
RestrictDuration: time.Minute,
Reason: "some reason #2",
},
}

peerManager.EXPECT().Suspended().Return(testData)

app, err := NewApp("key", nil, services.Services{Peers: peerManager}, cfg)
require.NoError(t, err)

suspended := app.PeersSuspended()

for i, actual := range suspended {
p := testData[i]
expected := RestrictedPeerInfo{
Hostname: "/" + ips[i],
Timestamp: p.RestrictTimestampMillis,
Reason: p.Reason,
}
assert.Equal(t, expected, actual)
}
}

func TestApp_PeersBlackList(t *testing.T) {
peerManager := peers.NewMockPeerManager(t)

Expand Down
1 change: 0 additions & 1 deletion pkg/api/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,6 @@ func (a *NodeApi) routes(opts *RunOptions) (chi.Router, error) {
r.Route("/peers", func(r chi.Router) {
r.Get("/all", wrapper(a.PeersAll))
r.Get("/connected", wrapper(a.PeersConnected))
r.Get("/suspended", wrapper(a.PeersSuspended))
r.Get("/blacklisted", wrapper(a.PeersBlackListed))

rAuth := r.With(checkAuthMiddleware)
Expand Down
5 changes: 1 addition & 4 deletions pkg/node/fsm/fsm_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,9 @@ func syncWithNewPeer(state State, baseInfo BaseInfo, p peer.Peer) (State, Async,
lastSignatures,
baseInfo.enableLightMode,
)
c := conf{
peerSyncWith: p,
timeout: defaultSyncTimeout,
}
baseInfo.logger.Debug("Starting synchronization with peer", "state", state.String(), "peer", p.ID())
baseInfo.syncPeer.SetPeer(p)
c := conf{timeout: defaultSyncTimeout}
return &SyncState{
baseInfo: baseInfo,
conf: c.Now(baseInfo.tm),
Expand Down
3 changes: 3 additions & 0 deletions pkg/node/fsm/idle_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package fsm

import (
"context"
"log/slog"

"github.com/pkg/errors"
"github.com/qmuntal/stateless"
Expand Down Expand Up @@ -49,6 +50,8 @@ func (a *IdleState) StartMining() (State, Async, error) {
func (a *IdleState) MinedBlock(
block *proto.Block, limits proto.MiningLimits, keyPair proto.KeyPair, vrf []byte,
) (State, Async, error) {
a.baseInfo.logger.Info("New block mined", slog.String("state", a.String()),
slog.String("blockID", block.ID.String()))
newA, ok := newNGState(a.baseInfo).(*NGState)
if !ok {
return a, nil, a.Errorf(errors.Errorf("unexpected type '%T' expected '*NGState'", a.baseInfo))
Expand Down
Loading
Loading