From f7452d82498434ec288eb71e39d93dff97633343 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Tue, 30 Sep 2025 15:59:20 +0300 Subject: [PATCH 01/62] add root hash for state accesses event --- data/outport.go | 2 ++ process/eventsHandler.go | 2 ++ 2 files changed, 4 insertions(+) diff --git a/data/outport.go b/data/outport.go index 18ec51a..7ca5a73 100644 --- a/data/outport.go +++ b/data/outport.go @@ -80,6 +80,8 @@ type BlockStateAccesses struct { ShardID uint32 `json:"shardID"` TimeStampMs uint64 `json:"timestampMs"` Nonce uint64 `json:"nonce"` + RootHash []byte `json:"rootHash"` + ScheduledRootHash []byte `json:"scheduledRootHash"` StateAccessesPerAccounts map[string]*stateChange.StateAccesses `json:"stateAccessesPerAccounts"` } diff --git a/process/eventsHandler.go b/process/eventsHandler.go index 0c8856b..9fd35ea 100644 --- a/process/eventsHandler.go +++ b/process/eventsHandler.go @@ -135,6 +135,8 @@ func (eh *eventsHandler) HandleSaveBlockEvents(allEvents data.ArgsSaveBlockData) ShardID: eventsData.Header.GetShardID(), TimeStampMs: headerTimeStampMs, Nonce: eventsData.Header.GetNonce(), + RootHash: eventsData.Header.GetRootHash(), + ScheduledRootHash: eventsData.Header.GetAdditionalData().GetScheduledRootHash(), StateAccessesPerAccounts: eventsData.StateAccessesPerAccounts, } eh.handleStateAccesses(stateAccesses) From d182636a9093dd3fd62a83c6e7cac60b618f6d26 Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Tue, 30 Sep 2025 20:05:25 +0300 Subject: [PATCH 02/62] fix scheduled root hash --- process/eventsHandler.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/process/eventsHandler.go b/process/eventsHandler.go index 9fd35ea..adf2510 100644 --- a/process/eventsHandler.go +++ b/process/eventsHandler.go @@ -130,13 +130,18 @@ func (eh *eventsHandler) HandleSaveBlockEvents(allEvents data.ArgsSaveBlockData) } eh.handleBlockEventsWithOrder(txsWithOrder) + var scheduledRootHash []byte + if eventsData.Header.GetAdditionalData() != nil { + scheduledRootHash = eventsData.Header.GetAdditionalData().GetScheduledRootHash() + } + stateAccesses := data.BlockStateAccesses{ Hash: eventsData.Hash, ShardID: eventsData.Header.GetShardID(), TimeStampMs: headerTimeStampMs, Nonce: eventsData.Header.GetNonce(), RootHash: eventsData.Header.GetRootHash(), - ScheduledRootHash: eventsData.Header.GetAdditionalData().GetScheduledRootHash(), + ScheduledRootHash: scheduledRootHash, StateAccessesPerAccounts: eventsData.StateAccessesPerAccounts, } eh.handleStateAccesses(stateAccesses) From 625139a58e2bfe13e518f29f2037df2ba6f1a8c2 Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Tue, 7 Oct 2025 12:02:56 +0300 Subject: [PATCH 03/62] update logging --- process/eventsInterceptor.go | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/process/eventsInterceptor.go b/process/eventsInterceptor.go index 9043fc9..b299067 100644 --- a/process/eventsInterceptor.go +++ b/process/eventsInterceptor.go @@ -2,7 +2,9 @@ package process import ( "encoding/hex" + "fmt" "sort" + "strings" "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/core/check" @@ -174,6 +176,8 @@ func (ei *eventsInterceptor) getStateAccessesPerAccounts(eventsData *data.ArgsSa } stateAccessesPerAccounts[accKey].StateAccess = append(stateAccessesPerAccounts[accKey].StateAccess, stateAccess) + // TODO: remove this log after testing + log.Trace("added state access to account", "account", stateAccess.MainTrieKey, "stateAccess", stateAccessToString(stateAccess), "txHash", txInfo.hash) } } @@ -199,14 +203,27 @@ func logStateAccessesPerTxs(stateAccesses map[string]*stateChange.StateAccesses) ) for _, st := range sts.StateAccess { - log.Trace("st", - "actionType", st.GetType(), - "operation", st.GetOperation(), - ) + log.Trace("state access", "stateChange", stateAccessToString(st)) } } } +func stateAccessToString(stateAccess *stateChange.StateAccess) string { + dataTrieChanges := make([]string, len(stateAccess.GetDataTrieChanges())) + for i, dataTrieChange := range stateAccess.GetDataTrieChanges() { + dataTrieChanges[i] = fmt.Sprintf("key: %v, val: %v, type: %v, operation %v, version %v", hex.EncodeToString(dataTrieChange.Key), hex.EncodeToString(dataTrieChange.Val), dataTrieChange.Type, dataTrieChange.Operation, dataTrieChange.Version) + } + return fmt.Sprintf("type: %v, operation: %v, mainTrieKey: %v, mainTrieVal: %v, index: %v, dataTrieChanges: %v, accountChanges %v", + stateAccess.GetType(), + stateAccess.GetOperation(), + hex.EncodeToString(stateAccess.GetMainTrieKey()), + hex.EncodeToString(stateAccess.GetMainTrieVal()), + stateAccess.GetIndex(), + strings.Join(dataTrieChanges, ", "), + stateAccess.GetAccountChanges(), + ) +} + func (ei *eventsInterceptor) getLogEventsFromTransactionsPool(logs []*outport.LogData) []data.Event { var logEvents []*logEvent for _, logData := range logs { From 456819deb789365de05d5701a5f72c646501a204 Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Tue, 7 Oct 2025 15:05:51 +0300 Subject: [PATCH 04/62] update logging --- process/eventsInterceptor.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/process/eventsInterceptor.go b/process/eventsInterceptor.go index b299067..60d2a0b 100644 --- a/process/eventsInterceptor.go +++ b/process/eventsInterceptor.go @@ -100,30 +100,38 @@ func getTxsWithOrder(transactionsPool *outport.TransactionPool) []txWithOrder { hash: txHash, index: txInfo.ExecutionOrder, }) + log.Trace("tx with order before sort - normal", "txHash", txHash, "index", txInfo.ExecutionOrder) } for txHash, txInfo := range transactionsPool.SmartContractResults { txsWithOrder = append(txsWithOrder, txWithOrder{ hash: txHash, index: txInfo.ExecutionOrder, }) + log.Trace("tx with order before sort - scr", "txHash", txHash, "index", txInfo.ExecutionOrder) } for txHash, txInfo := range transactionsPool.Rewards { txsWithOrder = append(txsWithOrder, txWithOrder{ hash: txHash, index: txInfo.ExecutionOrder, }) + log.Trace("tx with order before sort - rewards", "txHash", txHash, "index", txInfo.ExecutionOrder) } for txHash, txInfo := range transactionsPool.InvalidTxs { txsWithOrder = append(txsWithOrder, txWithOrder{ hash: txHash, index: txInfo.ExecutionOrder, }) + log.Trace("tx with order before sort - invalid tx", "txHash", txHash, "index", txInfo.ExecutionOrder) } sort.Slice(txsWithOrder, func(i, j int) bool { return txsWithOrder[i].index < txsWithOrder[j].index }) + for i, txInfo := range txsWithOrder { + log.Trace("tx with order after sort", "txHash", txInfo.hash, "index", txInfo.index, "position in slice", i) + } + return txsWithOrder } @@ -146,6 +154,7 @@ func (ei *eventsInterceptor) getStateAccessesPerAccounts(eventsData *data.ArgsSa stateAccessesPerAccounts := make(map[string]*stateChange.StateAccesses) for _, txInfo := range txsWithOrder { + log.Trace("tx with order", "txHash", txInfo.hash, "index", txInfo.index) txHash, err := hex.DecodeString(txInfo.hash) if err != nil { log.Error("failed to decode tx hash", "txHash", txInfo.hash) @@ -184,6 +193,15 @@ func (ei *eventsInterceptor) getStateAccessesPerAccounts(eventsData *data.ArgsSa log.Trace("getStateAccessesPerAccounts", "num stateAccessesPerAccounts", len(stateAccessesPerAccounts), ) + for accKey, sts := range stateAccessesPerAccounts { + log.Trace("stateAccessesPerAccount", + "account", accKey, + "num stateAccesses", len(sts.StateAccess), + ) + for _, st := range sts.StateAccess { + log.Trace("state access", "stateChange", stateAccessToString(st)) + } + } return stateAccessesPerAccounts } From 885db0390db7f0ab870e327303ee5f1670de5687 Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Tue, 7 Oct 2025 16:19:30 +0300 Subject: [PATCH 05/62] remove duplicates from txsWithOrder --- process/eventsInterceptor.go | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/process/eventsInterceptor.go b/process/eventsInterceptor.go index 60d2a0b..46eca0e 100644 --- a/process/eventsInterceptor.go +++ b/process/eventsInterceptor.go @@ -93,35 +93,31 @@ func (ei *eventsInterceptor) ProcessBlockEvents(eventsData *data.ArgsSaveBlockDa } func getTxsWithOrder(transactionsPool *outport.TransactionPool) []txWithOrder { - txsWithOrder := make([]txWithOrder, 0) + txsWithOrderMap := make(map[string]uint32) for txHash, txInfo := range transactionsPool.Transactions { - txsWithOrder = append(txsWithOrder, txWithOrder{ - hash: txHash, - index: txInfo.ExecutionOrder, - }) + txsWithOrderMap[txHash] = txInfo.ExecutionOrder log.Trace("tx with order before sort - normal", "txHash", txHash, "index", txInfo.ExecutionOrder) } for txHash, txInfo := range transactionsPool.SmartContractResults { - txsWithOrder = append(txsWithOrder, txWithOrder{ - hash: txHash, - index: txInfo.ExecutionOrder, - }) + txsWithOrderMap[txHash] = txInfo.ExecutionOrder log.Trace("tx with order before sort - scr", "txHash", txHash, "index", txInfo.ExecutionOrder) } for txHash, txInfo := range transactionsPool.Rewards { - txsWithOrder = append(txsWithOrder, txWithOrder{ - hash: txHash, - index: txInfo.ExecutionOrder, - }) + txsWithOrderMap[txHash] = txInfo.ExecutionOrder log.Trace("tx with order before sort - rewards", "txHash", txHash, "index", txInfo.ExecutionOrder) } for txHash, txInfo := range transactionsPool.InvalidTxs { + txsWithOrderMap[txHash] = txInfo.ExecutionOrder + log.Trace("tx with order before sort - invalid tx", "txHash", txHash, "index", txInfo.ExecutionOrder) + } + + txsWithOrder := make([]txWithOrder, 0, len(txsWithOrderMap)) + for txHash, index := range txsWithOrderMap { txsWithOrder = append(txsWithOrder, txWithOrder{ hash: txHash, - index: txInfo.ExecutionOrder, + index: index, }) - log.Trace("tx with order before sort - invalid tx", "txHash", txHash, "index", txInfo.ExecutionOrder) } sort.Slice(txsWithOrder, func(i, j int) bool { From d2d0ae146141590251cb6195b0b3facaef844b2f Mon Sep 17 00:00:00 2001 From: ssd04 Date: Fri, 10 Oct 2025 11:39:21 +0300 Subject: [PATCH 06/62] fixes after merge --- process/eventsInterceptor.go | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/process/eventsInterceptor.go b/process/eventsInterceptor.go index 56501ba..f9a356b 100644 --- a/process/eventsInterceptor.go +++ b/process/eventsInterceptor.go @@ -97,7 +97,6 @@ func getTxsWithOrder(transactionsPool *outport.TransactionPool) []txWithOrder { for txHash, txInfo := range transactionsPool.Transactions { txsWithOrderMap[txHash] = txInfo.ExecutionOrder -<<<<<<< HEAD log.Trace("tx with order before sort - normal", "txHash", txHash, "index", txInfo.ExecutionOrder) } for txHash, txInfo := range transactionsPool.SmartContractResults { @@ -111,17 +110,6 @@ func getTxsWithOrder(transactionsPool *outport.TransactionPool) []txWithOrder { for txHash, txInfo := range transactionsPool.InvalidTxs { txsWithOrderMap[txHash] = txInfo.ExecutionOrder log.Trace("tx with order before sort - invalid tx", "txHash", txHash, "index", txInfo.ExecutionOrder) -======= - } - for txHash, txInfo := range transactionsPool.SmartContractResults { - txsWithOrderMap[txHash] = txInfo.ExecutionOrder - } - for txHash, txInfo := range transactionsPool.Rewards { - txsWithOrderMap[txHash] = txInfo.ExecutionOrder - } - for txHash, txInfo := range transactionsPool.InvalidTxs { - txsWithOrderMap[txHash] = txInfo.ExecutionOrder ->>>>>>> rc/supernova } txsWithOrder := make([]txWithOrder, 0, len(txsWithOrderMap)) @@ -193,8 +181,6 @@ func (ei *eventsInterceptor) getStateAccessesPerAccounts(eventsData *data.ArgsSa } stateAccessesPerAccounts[accKey].StateAccess = append(stateAccessesPerAccounts[accKey].StateAccess, stateAccess) - // TODO: remove this log after testing - log.Trace("added state access to account", "account", stateAccess.MainTrieKey, "stateAccess", stateAccessToString(stateAccess), "txHash", txInfo.hash) } } From e269c114cf60af2131f18b2c4d5d5adce9580667 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Thu, 30 Oct 2025 15:11:12 +0200 Subject: [PATCH 07/62] cleanup logs --- process/eventsInterceptor.go | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/process/eventsInterceptor.go b/process/eventsInterceptor.go index f9a356b..6523d83 100644 --- a/process/eventsInterceptor.go +++ b/process/eventsInterceptor.go @@ -97,19 +97,15 @@ func getTxsWithOrder(transactionsPool *outport.TransactionPool) []txWithOrder { for txHash, txInfo := range transactionsPool.Transactions { txsWithOrderMap[txHash] = txInfo.ExecutionOrder - log.Trace("tx with order before sort - normal", "txHash", txHash, "index", txInfo.ExecutionOrder) } for txHash, txInfo := range transactionsPool.SmartContractResults { txsWithOrderMap[txHash] = txInfo.ExecutionOrder - log.Trace("tx with order before sort - scr", "txHash", txHash, "index", txInfo.ExecutionOrder) } for txHash, txInfo := range transactionsPool.Rewards { txsWithOrderMap[txHash] = txInfo.ExecutionOrder - log.Trace("tx with order before sort - rewards", "txHash", txHash, "index", txInfo.ExecutionOrder) } for txHash, txInfo := range transactionsPool.InvalidTxs { txsWithOrderMap[txHash] = txInfo.ExecutionOrder - log.Trace("tx with order before sort - invalid tx", "txHash", txHash, "index", txInfo.ExecutionOrder) } txsWithOrder := make([]txWithOrder, 0, len(txsWithOrderMap)) @@ -124,10 +120,6 @@ func getTxsWithOrder(transactionsPool *outport.TransactionPool) []txWithOrder { return txsWithOrder[i].index < txsWithOrder[j].index }) - for i, txInfo := range txsWithOrder { - log.Trace("tx with order after sort", "txHash", txInfo.hash, "index", txInfo.index, "position in slice", i) - } - return txsWithOrder } @@ -150,7 +142,6 @@ func (ei *eventsInterceptor) getStateAccessesPerAccounts(eventsData *data.ArgsSa stateAccessesPerAccounts := make(map[string]*stateChange.StateAccesses) for _, txInfo := range txsWithOrder { - log.Trace("tx with order", "txHash", txInfo.hash, "index", txInfo.index) txHash, err := hex.DecodeString(txInfo.hash) if err != nil { log.Error("failed to decode tx hash", "txHash", txInfo.hash) @@ -184,10 +175,21 @@ func (ei *eventsInterceptor) getStateAccessesPerAccounts(eventsData *data.ArgsSa } } - log.Trace("getStateAccessesPerAccounts", - "num stateAccessesPerAccounts", len(stateAccessesPerAccounts), + logStateAccessesPerAccounts(stateAccessesPerAccounts) + + return stateAccessesPerAccounts +} + +func logStateAccessesPerAccounts(stateAccesses map[string]*stateChange.StateAccesses) { + if log.GetLevel() > logger.LogTrace { + return + } + + log.Trace("state accesses per accounts", + "num stateAccessesPerAccounts", len(stateAccesses), ) - for accKey, sts := range stateAccessesPerAccounts { + + for accKey, sts := range stateAccesses { log.Trace("stateAccessesPerAccount", "account", accKey, "num stateAccesses", len(sts.StateAccess), @@ -196,8 +198,6 @@ func (ei *eventsInterceptor) getStateAccessesPerAccounts(eventsData *data.ArgsSa log.Trace("state access", "stateChange", stateAccessToString(st)) } } - - return stateAccessesPerAccounts } func logStateAccessesPerTxs(stateAccesses map[string]*stateChange.StateAccesses) { @@ -205,7 +205,7 @@ func logStateAccessesPerTxs(stateAccesses map[string]*stateChange.StateAccesses) return } - log.Trace("getStateAccessesPerAccounts", + log.Trace("state accesses per transaction", "num stateAccessesPerTxs", len(stateAccesses), ) From f3b5eab11f6746c7ed975be3b9a79740be22e85f Mon Sep 17 00:00:00 2001 From: ssd04 Date: Thu, 30 Oct 2025 15:35:54 +0200 Subject: [PATCH 08/62] add state accesses in unit tests --- process/eventsHandler_test.go | 98 +++++++++++++++++++++++++++++------ 1 file changed, 81 insertions(+), 17 deletions(-) diff --git a/process/eventsHandler_test.go b/process/eventsHandler_test.go index 6e46d95..0bab1dc 100644 --- a/process/eventsHandler_test.go +++ b/process/eventsHandler_test.go @@ -2,6 +2,7 @@ package process_test import ( "context" + "encoding/hex" "errors" "testing" @@ -9,6 +10,7 @@ import ( "github.com/multiversx/mx-chain-core-go/data/block" "github.com/multiversx/mx-chain-core-go/data/outport" "github.com/multiversx/mx-chain-core-go/data/smartContractResult" + "github.com/multiversx/mx-chain-core-go/data/stateChange" "github.com/multiversx/mx-chain-core-go/data/transaction" "github.com/multiversx/mx-chain-notifier-go/common" "github.com/multiversx/mx-chain-notifier-go/data" @@ -181,9 +183,31 @@ func TestHandleSaveBlockEvents(t *testing.T) { }, } + stateAccesses := make(map[string]*stateChange.StateAccesses) + stateAccesses["txHash1"] = &stateChange.StateAccesses{ + StateAccess: []*stateChange.StateAccess{ + &stateChange.StateAccess{ + Type: stateChange.Write, + MainTrieKey: []byte("mainTrieKey1"), + MainTrieVal: []byte("mainTrieVal1"), + }, + &stateChange.StateAccess{ + Type: stateChange.Write, + MainTrieKey: []byte("mainTrieKey2"), + MainTrieVal: []byte("mainTrieVal2"), + }, + }, + } + stateAccesses["txHash2"] = &stateChange.StateAccesses{} + + rootHash := []byte("rootHash1") + timeStamp := uint64(123) + timeStampMs := uint64(1234) header := &block.HeaderV2{ Header: &block.Header{ - ShardID: 2, + ShardID: 2, + TimeStamp: timeStamp, + RootHash: rootHash, }, } blockData := data.ArgsSaveBlockData{ @@ -193,7 +217,9 @@ func TestHandleSaveBlockEvents(t *testing.T) { SmartContractResults: scrs, Logs: logData, }, - Header: &block.HeaderV2{}, + Header: &block.HeaderV2{}, + StateAccesses: stateAccesses, + HeaderTimeStampMs: timeStampMs, } expTxs := map[string]*transaction.Transaction{ @@ -216,9 +242,11 @@ func TestHandleSaveBlockEvents(t *testing.T) { Scrs: expScrs, } expLogEvents := data.BlockEvents{ - Hash: blockHash, - Events: logEvents, - ShardID: 2, + Hash: blockHash, + TimeStamp: timeStamp, + TimeStampMs: timeStampMs, + Events: logEvents, + ShardID: 2, } expTxsWithOrder := map[string]*outport.TxInfo{ @@ -237,30 +265,61 @@ func TestHandleSaveBlockEvents(t *testing.T) { }, } expTxsWithOrderData := data.BlockEventsWithOrder{ - Hash: blockHash, - ShardID: 2, - Txs: expTxsWithOrder, - Scrs: expScrsWithOrder, - Events: logEvents, + Hash: blockHash, + TimeStamp: timeStamp, + TimeStampMs: timeStampMs, + ShardID: 2, + Txs: expTxsWithOrder, + Scrs: expScrsWithOrder, + Events: logEvents, + } + + expStateAccessesPerAccounts := make(map[string]*stateChange.StateAccesses) + expStateAccessesPerAccounts[hex.EncodeToString([]byte("mainTrieKey1"))] = &stateChange.StateAccesses{ + StateAccess: []*stateChange.StateAccess{ + &stateChange.StateAccess{ + Type: stateChange.Write, + MainTrieKey: []byte("mainTrieKey1"), + MainTrieVal: []byte("mainTrieVal1"), + }, + }, + } + expStateAccessesPerAccounts[hex.EncodeToString([]byte("mainTrieKey2"))] = &stateChange.StateAccesses{ + StateAccess: []*stateChange.StateAccess{ + &stateChange.StateAccess{ + Type: stateChange.Write, + MainTrieKey: []byte("mainTrieKey2"), + MainTrieVal: []byte("mainTrieVal2"), + }, + }, + } + expStateAccesses := data.BlockStateAccesses{ + Hash: blockHash, + ShardID: 2, + TimeStampMs: 1234, + RootHash: rootHash, + StateAccessesPerAccounts: expStateAccessesPerAccounts, } pushWasCalled := false txsWasCalled := false scrsWasCalled := false blockEventsWithOrderWasCalled := false + stateAccessesWasCalled := false args := createMockEventsHandlerArgs() args.EventsInterceptor = &mocks.EventsInterceptorStub{ ProcessBlockEventsCalled: func(eventsData *data.ArgsSaveBlockData) (*data.InterceptorBlockData, error) { return &data.InterceptorBlockData{ - Hash: blockHash, - Header: header, - Txs: expTxs, - Scrs: expScrs, - LogEvents: logEvents, - TxsWithOrder: expTxsWithOrder, - ScrsWithOrder: expScrsWithOrder, + Hash: blockHash, + Header: header, + Txs: expTxs, + Scrs: expScrs, + LogEvents: logEvents, + TxsWithOrder: expTxsWithOrder, + ScrsWithOrder: expScrsWithOrder, + StateAccessesPerAccounts: expStateAccessesPerAccounts, }, nil }, } @@ -282,6 +341,10 @@ func TestHandleSaveBlockEvents(t *testing.T) { blockEventsWithOrderWasCalled = true assert.Equal(t, expTxsWithOrderData, event) }, + BroadcastStateAccessesCalled: func(event data.BlockStateAccesses) { + stateAccessesWasCalled = true + assert.Equal(t, expStateAccesses, event) + }, } eventsHandler, err := process.NewEventsHandler(args) @@ -294,6 +357,7 @@ func TestHandleSaveBlockEvents(t *testing.T) { assert.True(t, txsWasCalled) assert.True(t, scrsWasCalled) assert.True(t, blockEventsWithOrderWasCalled) + assert.True(t, stateAccessesWasCalled) }) } From e282c873b1ba0b135f36a99ae7feee86216e34c6 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Tue, 11 Nov 2025 17:04:47 +0200 Subject: [PATCH 09/62] adapt to use header and metablock v3 --- go.mod | 2 +- go.sum | 4 ++-- process/preprocess/basePreProcessor.go | 10 +++++++++ process/preprocess/basePreProcessor_test.go | 25 +++++++++++++++++++++ process/preprocess/export_test.go | 5 +++++ 5 files changed, 43 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index eedde3f..7f8ca78 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.3 github.com/multiversx/mx-chain-communication-go v1.2.0 - github.com/multiversx/mx-chain-core-go v1.4.1-0.20250924085417-30f7c94f7d5d + github.com/multiversx/mx-chain-core-go v1.4.2-0.20251110143213-7437907451be github.com/multiversx/mx-chain-logger-go v1.1.0 github.com/pelletier/go-toml v1.9.3 github.com/prometheus/client_model v0.6.1 diff --git a/go.sum b/go.sum index 1dde752..65f6b0d 100644 --- a/go.sum +++ b/go.sum @@ -130,8 +130,8 @@ github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/multiversx/mx-chain-communication-go v1.2.0 h1:0wOoLldiRbvaOPxwICbnRCqCpLqPewg8M/FMbC/0OXY= github.com/multiversx/mx-chain-communication-go v1.2.0/go.mod h1:wS3aAwkmHbC9mlzQdvL6p7l8Rqw3vmzhj7WZW1dTveA= -github.com/multiversx/mx-chain-core-go v1.4.1-0.20250924085417-30f7c94f7d5d h1:DLZo0iqbsu7iMPWu2948XvkWE9jCly5A6IFFgeGf7MQ= -github.com/multiversx/mx-chain-core-go v1.4.1-0.20250924085417-30f7c94f7d5d/go.mod h1:IO+vspNan+gT0WOHnJ95uvWygiziHZvfXpff6KnxV7g= +github.com/multiversx/mx-chain-core-go v1.4.2-0.20251110143213-7437907451be h1:xCDAuqyRR/4+Cs3XJQhPnxHuXoFfim5l4V0f/7CYtJc= +github.com/multiversx/mx-chain-core-go v1.4.2-0.20251110143213-7437907451be/go.mod h1:IO+vspNan+gT0WOHnJ95uvWygiziHZvfXpff6KnxV7g= github.com/multiversx/mx-chain-crypto-go v1.2.13-0.20250218161752-9482d9a22234 h1:NNI7kYxzsq+4mTPSUJo0cK1+iPxjUX+gRJDaBRwEQ7M= github.com/multiversx/mx-chain-crypto-go v1.2.13-0.20250218161752-9482d9a22234/go.mod h1:QZAw2bZcOxGQRgYACTrmP8pfTa3NyxENIL+00G6nM5E= github.com/multiversx/mx-chain-logger-go v1.1.0 h1:97x84A6L4RfCa6YOx1HpAFxZp1cf/WI0Qh112whgZNM= diff --git a/process/preprocess/basePreProcessor.go b/process/preprocess/basePreProcessor.go index 63a9bad..fbed27b 100644 --- a/process/preprocess/basePreProcessor.go +++ b/process/preprocess/basePreProcessor.go @@ -80,10 +80,20 @@ func createEmptyBlockCreatorContainer() (EmptyBlockCreatorContainer, error) { return nil, err } + err = container.Add(core.ShardHeaderV3, block.NewEmptyHeaderV3Creator()) + if err != nil { + return nil, err + } + err = container.Add(core.MetaHeader, block.NewEmptyMetaBlockCreator()) if err != nil { return nil, err } + err = container.Add(core.MetaHeaderV3, block.NewEmptyMetaBlockV3Creator()) + if err != nil { + return nil, err + } + return container, nil } diff --git a/process/preprocess/basePreProcessor_test.go b/process/preprocess/basePreProcessor_test.go index b944f8e..19a1bc4 100644 --- a/process/preprocess/basePreProcessor_test.go +++ b/process/preprocess/basePreProcessor_test.go @@ -3,6 +3,7 @@ package preprocess_test import ( "testing" + "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/core/mock" "github.com/multiversx/mx-chain-notifier-go/common" "github.com/multiversx/mx-chain-notifier-go/mocks" @@ -51,3 +52,27 @@ func TestNewBaseEventsPreProcessor(t *testing.T) { require.NotNil(t, dp) }) } + +func TestCreateEmptyBlockCreatorContainer(t *testing.T) { + t.Parallel() + + cont, err := preprocess.CreateEmptyBlockCreatorContainer() + require.Nil(t, err) + + // shard + _, err = cont.Get(core.ShardHeaderV1) + require.Nil(t, err) + + _, err = cont.Get(core.ShardHeaderV2) + require.Nil(t, err) + + _, err = cont.Get(core.ShardHeaderV3) + require.Nil(t, err) + + // meta + _, err = cont.Get(core.MetaHeader) + require.Nil(t, err) + + _, err = cont.Get(core.MetaHeaderV3) + require.Nil(t, err) +} diff --git a/process/preprocess/export_test.go b/process/preprocess/export_test.go index 2422783..2b790af 100644 --- a/process/preprocess/export_test.go +++ b/process/preprocess/export_test.go @@ -4,3 +4,8 @@ package preprocess func NewBaseEventsPreProcessor(args ArgsEventsPreProcessor) (*baseEventsPreProcessor, error) { return newBaseEventsPreProcessor(args) } + +// CreateEmptyBlockCreatorContainer - +func CreateEmptyBlockCreatorContainer() (EmptyBlockCreatorContainer, error) { + return createEmptyBlockCreatorContainer() +} From c0f9f20c0a5ed4ea6f6a0f794968271f86b14490 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Tue, 11 Nov 2025 18:09:41 +0200 Subject: [PATCH 10/62] handle logs events from execution results --- data/block.go | 7 ++ data/outport.go | 18 +++-- process/errors.go | 3 + process/eventsHandler.go | 80 ++++++++++++++++++++++ process/eventsInterceptor.go | 67 +++++++++++++++++- process/interface.go | 1 + process/preprocess/eventsPreProcessorV1.go | 20 +++++- 7 files changed, 188 insertions(+), 8 deletions(-) diff --git a/data/block.go b/data/block.go index cf26ebe..8753aa9 100644 --- a/data/block.go +++ b/data/block.go @@ -21,6 +21,12 @@ type SaveBlockData struct { LogEvents []Event `json:"events"` } +type ExecInterceptorBlockData struct { + Hash string + Header nodeData.HeaderHandler + ExecResultsData []*InterceptorBlockData +} + // InterceptorBlockData holds the block data needed for processing type InterceptorBlockData struct { Hash string @@ -47,6 +53,7 @@ type ArgsSaveBlockData struct { NumberOfShards uint32 HeaderTimeStampMs uint64 StateAccesses map[string]*stateChange.StateAccesses + Results map[string]*outport.ExecutionResultsData } // OutportBlockDataOld holds the block data that will be received on push events diff --git a/data/outport.go b/data/outport.go index 18ec51a..2566b9c 100644 --- a/data/outport.go +++ b/data/outport.go @@ -28,11 +28,19 @@ type Event struct { // BlockEvents holds events data for a block type BlockEvents struct { - Hash string `json:"hash"` - ShardID uint32 `json:"shardId"` - TimeStamp uint64 `json:"timestamp"` - TimeStampMs uint64 `json:"timestampMs"` - Events []Event `json:"events"` + Hash string `json:"hash"` + ShardID uint32 `json:"shardId"` + TimeStamp uint64 `json:"timestamp"` + TimeStampMs uint64 `json:"timestampMs"` + Events []Event `json:"events,omitempty"` + ExecutedEvents []ExecutedEvents `json:"executedEvents"` +} + +// ExecutedEvents holds events data for the executed block events +// With async execution, there can be multiple executed block results notarized on a block +type ExecutedEvents struct { + ExecutedHash string `json:"executedHash"` + Events []Event `json:"events"` } // RevertBlock holds revert event data diff --git a/process/errors.go b/process/errors.go index 1c1739d..d3e8243 100644 --- a/process/errors.go +++ b/process/errors.go @@ -34,3 +34,6 @@ var ErrNilEventsInterceptor = errors.New("nil events interceptor") // ErrNilStateAccesses signals that a nil state accesses has been provided var ErrNilStateAccesses = errors.New("nil state accesses provided") + +// ErrNilExecutionResults signals that a nil execution results map has been provided +var ErrNilExecutionResults = errors.New("nil execution results provided") diff --git a/process/eventsHandler.go b/process/eventsHandler.go index 0c8856b..6e2fca6 100644 --- a/process/eventsHandler.go +++ b/process/eventsHandler.go @@ -83,6 +83,13 @@ func (eh *eventsHandler) HandleSaveBlockEvents(allEvents data.ArgsSaveBlockData) return nil } + if check.IfNil(allEvents.Header) { + return ErrNilBlockHeader + } + if allEvents.Header.IsHeaderV3() { + return eh.handleSaveBlockEventsV3(allEvents) + } + eventsData, err := eh.eventsInterceptor.ProcessBlockEvents(&allEvents) if err != nil { return err @@ -142,6 +149,79 @@ func (eh *eventsHandler) HandleSaveBlockEvents(allEvents data.ArgsSaveBlockData) return nil } +func (eh *eventsHandler) handleSaveBlockEventsV3(allEvents data.ArgsSaveBlockData) error { + execEventsData, err := eh.eventsInterceptor.ProcessBlockEventsV3(&allEvents) + if err != nil { + return err + } + + execEvents := eh.getExecutedEventsData(execEventsData.ExecResultsData) + + headerTimeStamp := execEventsData.Header.GetTimeStamp() + headerTimeStampMs := allEvents.HeaderTimeStampMs + + pushEvents := data.BlockEvents{ + Hash: execEventsData.Hash, + ShardID: execEventsData.Header.GetShardID(), + TimeStamp: headerTimeStamp, + TimeStampMs: headerTimeStampMs, + ExecutedEvents: execEvents, + } + err = eh.handlePushEvents(pushEvents) + if err != nil { + return err + } + + // txs := data.BlockTxs{ + // Hash: eventsData.Hash, + // Txs: eventsData.Txs, + // } + // eh.handleBlockTxs(txs) + + // scrs := data.BlockScrs{ + // Hash: eventsData.Hash, + // Scrs: eventsData.Scrs, + // } + // eh.handleBlockScrs(scrs) + + // txsWithOrder := data.BlockEventsWithOrder{ + // Hash: eventsData.Hash, + // ShardID: eventsData.Header.GetShardID(), + // TimeStamp: headerTimeStamp, + // TimeStampMs: headerTimeStampMs, + // Txs: eventsData.TxsWithOrder, + // Scrs: eventsData.ScrsWithOrder, + // Events: eventsData.LogEvents, + // } + // eh.handleBlockEventsWithOrder(txsWithOrder) + + // stateAccesses := data.BlockStateAccesses{ + // Hash: eventsData.Hash, + // ShardID: eventsData.Header.GetShardID(), + // TimeStampMs: headerTimeStampMs, + // Nonce: eventsData.Header.GetNonce(), + // StateAccessesPerAccounts: eventsData.StateAccessesPerAccounts, + // } + // eh.handleStateAccesses(stateAccesses) + + return nil +} + +func (eh *eventsHandler) getExecutedEventsData(interceptedBlocksData []*data.InterceptorBlockData) []data.ExecutedEvents { + executedEvents := make([]data.ExecutedEvents, 0) + + for _, interceptedBlockData := range interceptedBlocksData { + execEvents := data.ExecutedEvents{ + ExecutedHash: interceptedBlockData.Hash, + Events: interceptedBlockData.LogEvents, + } + + executedEvents = append(executedEvents, execEvents) + } + + return executedEvents +} + // HandlePushEvents will handle push events received from observer func (eh *eventsHandler) handlePushEvents(events data.BlockEvents) error { if events.Hash == "" { diff --git a/process/eventsInterceptor.go b/process/eventsInterceptor.go index bd04659..c209681 100644 --- a/process/eventsInterceptor.go +++ b/process/eventsInterceptor.go @@ -6,7 +6,7 @@ import ( "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/core/check" - nodeData "github.com/multiversx/mx-chain-core-go/data" + coreData "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/outport" "github.com/multiversx/mx-chain-core-go/data/smartContractResult" "github.com/multiversx/mx-chain-core-go/data/stateChange" @@ -22,7 +22,7 @@ type txWithOrder struct { // logEvent defines a log event associated with corresponding tx hash type logEvent struct { - EventHandler nodeData.EventHandler + EventHandler coreData.EventHandler TxHash string } @@ -90,6 +90,69 @@ func (ei *eventsInterceptor) ProcessBlockEvents(eventsData *data.ArgsSaveBlockDa }, nil } +// ProcessBlockEventsV3 will process block events data for async execution model +// TODO: update to have a wrapper struct with header info +func (ei *eventsInterceptor) ProcessBlockEventsV3(eventsData *data.ArgsSaveBlockData) ([]*data.InterceptorBlockData, error) { + if eventsData == nil { + return nil, ErrNilBlockEvents + } + if eventsData.Header == nil { + return nil, ErrNilBlockHeader + } + + if !eventsData.Header.IsHeaderV3() { + // return early, no need to handle execution results events + return make([]*data.InterceptorBlockData, 0), nil + } + + if eventsData.Results == nil { + return nil, ErrNilExecutionResults + } + + execBlocksData := make([]*data.InterceptorBlockData, 0) + if len(eventsData.Results) == 0 { + return execBlocksData, nil + } + + for headerHash, execBlockData := range eventsData.Results { + transactionsPool := execBlockData.GetTransactionPool() + body := execBlockData.Body + + events := ei.getLogEventsFromTransactionsPool(transactionsPool.GetLogs()) + + txs := make(map[string]*transaction.Transaction) + for hash, tx := range transactionsPool.GetTransactions() { + txs[hash] = tx.Transaction + } + txsWithOrder := transactionsPool.GetTransactions() + + scrs := make(map[string]*smartContractResult.SmartContractResult) + for hash, scr := range transactionsPool.GetSmartContractResults() { + scrs[hash] = scr.SmartContractResult + } + scrsWithOrder := transactionsPool.GetSmartContractResults() + + // TODO: handle state accesses for header v3 + stateAccessesPerAccounts := ei.getStateAccessesPerAccounts(eventsData) + + blockData := &data.InterceptorBlockData{ + Hash: headerHash, + Body: body, + Header: eventsData.Header, // this holds current proposed header, not executed header + Txs: txs, + TxsWithOrder: txsWithOrder, + Scrs: scrs, + ScrsWithOrder: scrsWithOrder, + LogEvents: events, + StateAccessesPerAccounts: stateAccessesPerAccounts, + } + + execBlocksData = append(execBlocksData, blockData) + } + + return execBlocksData, nil +} + func getTxsWithOrder(transactionsPool *outport.TransactionPool) []txWithOrder { txsWithOrderMap := make(map[string]uint32) diff --git a/process/interface.go b/process/interface.go index 5e9c863..f315ede 100644 --- a/process/interface.go +++ b/process/interface.go @@ -40,6 +40,7 @@ type EventsHandler interface { // EventsInterceptor defines the behaviour of an events interceptor component type EventsInterceptor interface { ProcessBlockEvents(eventsData *data.ArgsSaveBlockData) (*data.InterceptorBlockData, error) + ProcessBlockEventsV3(eventsData *data.ArgsSaveBlockData) (*data.ExecInterceptorBlockData, error) IsInterfaceNil() bool } diff --git a/process/preprocess/eventsPreProcessorV1.go b/process/preprocess/eventsPreProcessorV1.go index 9a4add0..8600aa1 100644 --- a/process/preprocess/eventsPreProcessorV1.go +++ b/process/preprocess/eventsPreProcessorV1.go @@ -49,11 +49,19 @@ func (d *eventsPreProcessorV1) SaveBlock(marshalledData []byte) error { return err } - header, err := d.getHeaderFromBytes(core.HeaderType(outportBlock.BlockData.HeaderType), outportBlock.BlockData.HeaderBytes) + headerType := core.HeaderType(outportBlock.BlockData.HeaderType) + + header, err := d.getHeaderFromBytes(headerType, outportBlock.BlockData.HeaderBytes) if err != nil { return err } + // executionResults := make(map[string]*outport.ExecutionResultsData) + var executionResults map[string]*outport.ExecutionResultsData + if isHeaderV3(headerType) { + executionResults = outportBlock.BlockData.Results + } + saveBlockData := &data.ArgsSaveBlockData{ HeaderHash: outportBlock.BlockData.HeaderHash, Body: outportBlock.BlockData.Body, @@ -66,6 +74,7 @@ func (d *eventsPreProcessorV1) SaveBlock(marshalledData []byte) error { Header: header, HeaderTimeStampMs: outportBlock.BlockData.GetTimestampMs(), StateAccesses: outportBlock.GetStateAccesses(), + Results: executionResults, } err = d.facade.HandlePushEvents(*saveBlockData) @@ -76,6 +85,15 @@ func (d *eventsPreProcessorV1) SaveBlock(marshalledData []byte) error { return nil } +func isHeaderV3(headerType core.HeaderType) bool { + if headerType == core.ShardHeaderV3 || + headerType == core.MetaHeaderV3 { + return true + } + + return false +} + func checkBlockDataValid(block *outport.OutportBlock) error { if block.BlockData == nil { return ErrNilBlockData From e1c209c75007024afd324e508627c2f02c51457b Mon Sep 17 00:00:00 2001 From: ssd04 Date: Wed, 12 Nov 2025 16:16:52 +0200 Subject: [PATCH 11/62] refactor to handle block data for v3 --- data/block.go | 6 -- data/outport.go | 18 ++--- mocks/eventsInterceptorStub.go | 12 +++- process/eventsHandler.go | 118 ++++++++++++++------------------- process/eventsHandler_test.go | 36 +++++++++- process/eventsInterceptor.go | 4 +- process/interface.go | 2 +- 7 files changed, 102 insertions(+), 94 deletions(-) diff --git a/data/block.go b/data/block.go index 8753aa9..04f7717 100644 --- a/data/block.go +++ b/data/block.go @@ -21,12 +21,6 @@ type SaveBlockData struct { LogEvents []Event `json:"events"` } -type ExecInterceptorBlockData struct { - Hash string - Header nodeData.HeaderHandler - ExecResultsData []*InterceptorBlockData -} - // InterceptorBlockData holds the block data needed for processing type InterceptorBlockData struct { Hash string diff --git a/data/outport.go b/data/outport.go index 2566b9c..8c7c95f 100644 --- a/data/outport.go +++ b/data/outport.go @@ -28,19 +28,11 @@ type Event struct { // BlockEvents holds events data for a block type BlockEvents struct { - Hash string `json:"hash"` - ShardID uint32 `json:"shardId"` - TimeStamp uint64 `json:"timestamp"` - TimeStampMs uint64 `json:"timestampMs"` - Events []Event `json:"events,omitempty"` - ExecutedEvents []ExecutedEvents `json:"executedEvents"` -} - -// ExecutedEvents holds events data for the executed block events -// With async execution, there can be multiple executed block results notarized on a block -type ExecutedEvents struct { - ExecutedHash string `json:"executedHash"` - Events []Event `json:"events"` + Hash string `json:"hash"` + ShardID uint32 `json:"shardId"` + TimeStamp uint64 `json:"timestamp"` + TimeStampMs uint64 `json:"timestampMs"` + Events []Event `json:"events,omitempty"` } // RevertBlock holds revert event data diff --git a/mocks/eventsInterceptorStub.go b/mocks/eventsInterceptorStub.go index 6c7fb8d..897c75b 100644 --- a/mocks/eventsInterceptorStub.go +++ b/mocks/eventsInterceptorStub.go @@ -4,7 +4,8 @@ import "github.com/multiversx/mx-chain-notifier-go/data" // EventsInterceptorStub - type EventsInterceptorStub struct { - ProcessBlockEventsCalled func(eventsData *data.ArgsSaveBlockData) (*data.InterceptorBlockData, error) + ProcessBlockEventsCalled func(eventsData *data.ArgsSaveBlockData) (*data.InterceptorBlockData, error) + ProcessBlockEventsV3Called func(eventsData *data.ArgsSaveBlockData) ([]*data.InterceptorBlockData, error) } // ProcessBlockEvents - @@ -16,6 +17,15 @@ func (stub *EventsInterceptorStub) ProcessBlockEvents(eventsData *data.ArgsSaveB return nil, nil } +// ProcessBlockEventsV3 - +func (stub *EventsInterceptorStub) ProcessBlockEventsV3(eventsData *data.ArgsSaveBlockData) ([]*data.InterceptorBlockData, error) { + if stub.ProcessBlockEventsV3Called != nil { + return stub.ProcessBlockEventsV3Called(eventsData) + } + + return nil, nil +} + // IsInterfaceNil returns true if there is not value under the interface func (stub *EventsInterceptorStub) IsInterfaceNil() bool { return stub == nil diff --git a/process/eventsHandler.go b/process/eventsHandler.go index 6e2fca6..820005b 100644 --- a/process/eventsHandler.go +++ b/process/eventsHandler.go @@ -90,26 +90,51 @@ func (eh *eventsHandler) HandleSaveBlockEvents(allEvents data.ArgsSaveBlockData) return eh.handleSaveBlockEventsV3(allEvents) } + return eh.handleSaveBlockEventsLegacy(allEvents) +} + +func (eh *eventsHandler) handleSaveBlockEventsLegacy(allEvents data.ArgsSaveBlockData) error { eventsData, err := eh.eventsInterceptor.ProcessBlockEvents(&allEvents) if err != nil { return err } + headerTimeStamp := eventsData.Header.GetTimeStamp() + headerTimeStampMs := allEvents.HeaderTimeStampMs + shardID := eventsData.Header.GetShardID() + nonce := eventsData.Header.GetNonce() + + return eh.handleSaveBlockEvents( + eventsData, + headerTimeStamp, + headerTimeStampMs, + shardID, + nonce, + ) +} + +func (eh *eventsHandler) handleSaveBlockEvents( + eventsData *data.InterceptorBlockData, + headerTimeStamp uint64, + headerTimeStampMs uint64, + shardID uint32, + nonce uint64, +) error { + if eventsData == nil { + return ErrNilEventsInterceptor + } if check.IfNil(eventsData.Header) { return ErrNilBlockHeader } - headerTimeStamp := eventsData.Header.GetTimeStamp() - headerTimeStampMs := allEvents.HeaderTimeStampMs - pushEvents := data.BlockEvents{ Hash: eventsData.Hash, - ShardID: eventsData.Header.GetShardID(), + ShardID: shardID, TimeStamp: headerTimeStamp, TimeStampMs: headerTimeStampMs, Events: eventsData.LogEvents, } - err = eh.handlePushEvents(pushEvents) + err := eh.handlePushEvents(pushEvents) if err != nil { return err } @@ -128,7 +153,7 @@ func (eh *eventsHandler) HandleSaveBlockEvents(allEvents data.ArgsSaveBlockData) txsWithOrder := data.BlockEventsWithOrder{ Hash: eventsData.Hash, - ShardID: eventsData.Header.GetShardID(), + ShardID: shardID, TimeStamp: headerTimeStamp, TimeStampMs: headerTimeStampMs, Txs: eventsData.TxsWithOrder, @@ -139,9 +164,9 @@ func (eh *eventsHandler) HandleSaveBlockEvents(allEvents data.ArgsSaveBlockData) stateAccesses := data.BlockStateAccesses{ Hash: eventsData.Hash, - ShardID: eventsData.Header.GetShardID(), + ShardID: shardID, TimeStampMs: headerTimeStampMs, - Nonce: eventsData.Header.GetNonce(), + Nonce: nonce, StateAccessesPerAccounts: eventsData.StateAccessesPerAccounts, } eh.handleStateAccesses(stateAccesses) @@ -155,71 +180,26 @@ func (eh *eventsHandler) handleSaveBlockEventsV3(allEvents data.ArgsSaveBlockDat return err } - execEvents := eh.getExecutedEventsData(execEventsData.ExecResultsData) - - headerTimeStamp := execEventsData.Header.GetTimeStamp() + // TODO: get timestamp from executed header, not from current proposed header + headerTimeStamp := allEvents.Header.GetTimeStamp() headerTimeStampMs := allEvents.HeaderTimeStampMs - - pushEvents := data.BlockEvents{ - Hash: execEventsData.Hash, - ShardID: execEventsData.Header.GetShardID(), - TimeStamp: headerTimeStamp, - TimeStampMs: headerTimeStampMs, - ExecutedEvents: execEvents, - } - err = eh.handlePushEvents(pushEvents) - if err != nil { - return err - } - - // txs := data.BlockTxs{ - // Hash: eventsData.Hash, - // Txs: eventsData.Txs, - // } - // eh.handleBlockTxs(txs) - - // scrs := data.BlockScrs{ - // Hash: eventsData.Hash, - // Scrs: eventsData.Scrs, - // } - // eh.handleBlockScrs(scrs) - - // txsWithOrder := data.BlockEventsWithOrder{ - // Hash: eventsData.Hash, - // ShardID: eventsData.Header.GetShardID(), - // TimeStamp: headerTimeStamp, - // TimeStampMs: headerTimeStampMs, - // Txs: eventsData.TxsWithOrder, - // Scrs: eventsData.ScrsWithOrder, - // Events: eventsData.LogEvents, - // } - // eh.handleBlockEventsWithOrder(txsWithOrder) - - // stateAccesses := data.BlockStateAccesses{ - // Hash: eventsData.Hash, - // ShardID: eventsData.Header.GetShardID(), - // TimeStampMs: headerTimeStampMs, - // Nonce: eventsData.Header.GetNonce(), - // StateAccessesPerAccounts: eventsData.StateAccessesPerAccounts, - // } - // eh.handleStateAccesses(stateAccesses) - - return nil -} - -func (eh *eventsHandler) getExecutedEventsData(interceptedBlocksData []*data.InterceptorBlockData) []data.ExecutedEvents { - executedEvents := make([]data.ExecutedEvents, 0) - - for _, interceptedBlockData := range interceptedBlocksData { - execEvents := data.ExecutedEvents{ - ExecutedHash: interceptedBlockData.Hash, - Events: interceptedBlockData.LogEvents, + shardID := allEvents.Header.GetShardID() + nonce := allEvents.Header.GetNonce() + + for _, execEv := range execEventsData { + err = eh.handleSaveBlockEvents( + execEv, + headerTimeStamp, + headerTimeStampMs, + shardID, + nonce, + ) + if err != nil { + return err } - - executedEvents = append(executedEvents, execEvents) } - return executedEvents + return nil } // HandlePushEvents will handle push events received from observer diff --git a/process/eventsHandler_test.go b/process/eventsHandler_test.go index 6e46d95..f43cf31 100644 --- a/process/eventsHandler_test.go +++ b/process/eventsHandler_test.go @@ -120,6 +120,36 @@ func TestHandleSaveBlockEvents(t *testing.T) { require.Nil(t, err) }) + t.Run("nil events header, should fail", func(t *testing.T) { + t.Parallel() + + args := createMockEventsHandlerArgs() + args.CheckDuplicates = true + + args.Locker = &mocks.LockerStub{ + IsEventProcessedCalled: func(ctx context.Context, blockHash string) (bool, error) { + return true, nil + }, + } + + expectedErr := errors.New("expected err") + args.EventsInterceptor = &mocks.EventsInterceptorStub{ + ProcessBlockEventsCalled: func(eventsData *data.ArgsSaveBlockData) (*data.InterceptorBlockData, error) { + return nil, expectedErr + }, + } + + eventsHandler, err := process.NewEventsHandler(args) + require.Nil(t, err) + + blockData := data.ArgsSaveBlockData{ + Header: nil, + } + + err = eventsHandler.HandleSaveBlockEvents(blockData) + require.Equal(t, process.ErrNilBlockHeader, err) + }) + t.Run("failed to pre-process events, should fail", func(t *testing.T) { t.Parallel() @@ -142,7 +172,11 @@ func TestHandleSaveBlockEvents(t *testing.T) { eventsHandler, err := process.NewEventsHandler(args) require.Nil(t, err) - err = eventsHandler.HandleSaveBlockEvents(data.ArgsSaveBlockData{}) + blockData := data.ArgsSaveBlockData{ + Header: &block.HeaderV2{}, + } + + err = eventsHandler.HandleSaveBlockEvents(blockData) require.Equal(t, expectedErr, err) }) diff --git a/process/eventsInterceptor.go b/process/eventsInterceptor.go index c209681..7636ddf 100644 --- a/process/eventsInterceptor.go +++ b/process/eventsInterceptor.go @@ -91,7 +91,6 @@ func (ei *eventsInterceptor) ProcessBlockEvents(eventsData *data.ArgsSaveBlockDa } // ProcessBlockEventsV3 will process block events data for async execution model -// TODO: update to have a wrapper struct with header info func (ei *eventsInterceptor) ProcessBlockEventsV3(eventsData *data.ArgsSaveBlockData) ([]*data.InterceptorBlockData, error) { if eventsData == nil { return nil, ErrNilBlockEvents @@ -101,8 +100,7 @@ func (ei *eventsInterceptor) ProcessBlockEventsV3(eventsData *data.ArgsSaveBlock } if !eventsData.Header.IsHeaderV3() { - // return early, no need to handle execution results events - return make([]*data.InterceptorBlockData, 0), nil + return nil, coreData.ErrInvalidHeaderType } if eventsData.Results == nil { diff --git a/process/interface.go b/process/interface.go index f315ede..9537847 100644 --- a/process/interface.go +++ b/process/interface.go @@ -40,7 +40,7 @@ type EventsHandler interface { // EventsInterceptor defines the behaviour of an events interceptor component type EventsInterceptor interface { ProcessBlockEvents(eventsData *data.ArgsSaveBlockData) (*data.InterceptorBlockData, error) - ProcessBlockEventsV3(eventsData *data.ArgsSaveBlockData) (*data.ExecInterceptorBlockData, error) + ProcessBlockEventsV3(eventsData *data.ArgsSaveBlockData) ([]*data.InterceptorBlockData, error) IsInterfaceNil() bool } From 640c3948e2c6db96ca8ec6c9eff2043281767bee Mon Sep 17 00:00:00 2001 From: ssd04 Date: Wed, 12 Nov 2025 17:42:58 +0200 Subject: [PATCH 12/62] add unit tests --- process/eventsHandler.go | 1 + process/eventsHandler_test.go | 242 +++++++++++++++++--------- process/eventsInterceptor.go | 29 ++-- process/eventsInterceptor_test.go | 274 ++++++++++++++++++++++++++---- process/export_test.go | 5 + 5 files changed, 425 insertions(+), 126 deletions(-) diff --git a/process/eventsHandler.go b/process/eventsHandler.go index 820005b..46af20e 100644 --- a/process/eventsHandler.go +++ b/process/eventsHandler.go @@ -86,6 +86,7 @@ func (eh *eventsHandler) HandleSaveBlockEvents(allEvents data.ArgsSaveBlockData) if check.IfNil(allEvents.Header) { return ErrNilBlockHeader } + if allEvents.Header.IsHeaderV3() { return eh.handleSaveBlockEventsV3(allEvents) } diff --git a/process/eventsHandler_test.go b/process/eventsHandler_test.go index f43cf31..610d57a 100644 --- a/process/eventsHandler_test.go +++ b/process/eventsHandler_test.go @@ -91,7 +91,7 @@ func TestNewEventsHandler(t *testing.T) { }) } -func TestHandleSaveBlockEvents(t *testing.T) { +func TestHandleSaveBlockEvents_ShouldFail(t *testing.T) { t.Parallel() t.Run("duplicated events, should return early", func(t *testing.T) { @@ -179,47 +179,143 @@ func TestHandleSaveBlockEvents(t *testing.T) { err = eventsHandler.HandleSaveBlockEvents(blockData) require.Equal(t, expectedErr, err) }) +} - t.Run("should work", func(t *testing.T) { - t.Parallel() +func TestHandleSaveBlockEvents_ShouldWork(t *testing.T) { + t.Parallel() - blockHash := "blockHash1" - txs := map[string]*outport.TxInfo{ - "hash1": { - Transaction: &transaction.Transaction{ - Nonce: 1, - }, - ExecutionOrder: 1, + blockHash := "blockHash1" + txs := map[string]*outport.TxInfo{ + "hash1": { + Transaction: &transaction.Transaction{ + Nonce: 1, }, - } - scrs := map[string]*outport.SCRInfo{ - "hash2": { - SmartContractResult: &smartContractResult.SmartContractResult{ - Nonce: 2, - }, + ExecutionOrder: 1, + }, + } + scrs := map[string]*outport.SCRInfo{ + "hash2": { + SmartContractResult: &smartContractResult.SmartContractResult{ + Nonce: 2, }, - } - logData := []*outport.LogData{ - { - Log: &transaction.Log{ - Address: []byte("logaddr1"), - Events: []*transaction.Event{}, - }, - TxHash: "logHash1", + }, + } + logData := []*outport.LogData{ + { + Log: &transaction.Log{ + Address: []byte("logaddr1"), + Events: []*transaction.Event{}, }, - } + TxHash: "logHash1", + }, + } + + logEvents := []data.Event{ + { + Address: "addr1", + }, + } + + expTxs := map[string]*transaction.Transaction{ + "hash1": { + Nonce: 1, + }, + } + expScrs := map[string]*smartContractResult.SmartContractResult{ + "hash2": { + Nonce: 2, + }, + } + + expTxsData := data.BlockTxs{ + Hash: blockHash, + Txs: expTxs, + } + expScrsData := data.BlockScrs{ + Hash: blockHash, + Scrs: expScrs, + } + expLogEvents := data.BlockEvents{ + Hash: blockHash, + Events: logEvents, + ShardID: 2, + } - logEvents := []data.Event{ - { - Address: "addr1", + expTxsWithOrder := map[string]*outport.TxInfo{ + "hash1": { + Transaction: &transaction.Transaction{ + Nonce: 1, }, - } + ExecutionOrder: 1, + }, + } + expScrsWithOrder := map[string]*outport.SCRInfo{ + "hash2": { + SmartContractResult: &smartContractResult.SmartContractResult{ + Nonce: 2, + }, + }, + } + expTxsWithOrderData := data.BlockEventsWithOrder{ + Hash: blockHash, + ShardID: 2, + Txs: expTxsWithOrder, + Scrs: expScrsWithOrder, + Events: logEvents, + } + + t.Run("should work before header v3", func(t *testing.T) { + t.Parallel() header := &block.HeaderV2{ Header: &block.Header{ ShardID: 2, }, } + + pushWasCalled := false + txsWasCalled := false + scrsWasCalled := false + blockEventsWithOrderWasCalled := false + + args := createMockEventsHandlerArgs() + + args.EventsInterceptor = &mocks.EventsInterceptorStub{ + ProcessBlockEventsCalled: func(eventsData *data.ArgsSaveBlockData) (*data.InterceptorBlockData, error) { + return &data.InterceptorBlockData{ + Hash: blockHash, + Header: header, + Txs: expTxs, + Scrs: expScrs, + LogEvents: logEvents, + TxsWithOrder: expTxsWithOrder, + ScrsWithOrder: expScrsWithOrder, + }, nil + }, + } + + args.Publisher = &mocks.PublisherStub{ + BroadcastCalled: func(events data.BlockEvents) { + pushWasCalled = true + assert.Equal(t, expLogEvents, events) + }, + BroadcastTxsCalled: func(event data.BlockTxs) { + txsWasCalled = true + assert.Equal(t, expTxsData, event) + }, + BroadcastScrsCalled: func(event data.BlockScrs) { + scrsWasCalled = true + assert.Equal(t, expScrsData, event) + }, + BroadcastBlockEventsWithOrderCalled: func(event data.BlockEventsWithOrder) { + blockEventsWithOrderWasCalled = true + assert.Equal(t, expTxsWithOrderData, event) + }, + } + + eventsHandler, err := process.NewEventsHandler(args) + require.Nil(t, err) + blockData := data.ArgsSaveBlockData{ HeaderHash: []byte(blockHash), TransactionsPool: &outport.TransactionPool{ @@ -227,55 +323,23 @@ func TestHandleSaveBlockEvents(t *testing.T) { SmartContractResults: scrs, Logs: logData, }, - Header: &block.HeaderV2{}, + Header: header, } - expTxs := map[string]*transaction.Transaction{ - "hash1": { - Nonce: 1, - }, - } - expScrs := map[string]*smartContractResult.SmartContractResult{ - "hash2": { - Nonce: 2, - }, - } + err = eventsHandler.HandleSaveBlockEvents(blockData) + require.Nil(t, err) - expTxsData := data.BlockTxs{ - Hash: blockHash, - Txs: expTxs, - } - expScrsData := data.BlockScrs{ - Hash: blockHash, - Scrs: expScrs, - } - expLogEvents := data.BlockEvents{ - Hash: blockHash, - Events: logEvents, - ShardID: 2, - } + assert.True(t, pushWasCalled) + assert.True(t, txsWasCalled) + assert.True(t, scrsWasCalled) + assert.True(t, blockEventsWithOrderWasCalled) + }) - expTxsWithOrder := map[string]*outport.TxInfo{ - "hash1": { - Transaction: &transaction.Transaction{ - Nonce: 1, - }, - ExecutionOrder: 1, - }, - } - expScrsWithOrder := map[string]*outport.SCRInfo{ - "hash2": { - SmartContractResult: &smartContractResult.SmartContractResult{ - Nonce: 2, - }, - }, - } - expTxsWithOrderData := data.BlockEventsWithOrder{ - Hash: blockHash, + t.Run("should work with header v3", func(t *testing.T) { + t.Parallel() + + header := &block.HeaderV3{ ShardID: 2, - Txs: expTxsWithOrder, - Scrs: expScrsWithOrder, - Events: logEvents, } pushWasCalled := false @@ -287,14 +351,20 @@ func TestHandleSaveBlockEvents(t *testing.T) { args.EventsInterceptor = &mocks.EventsInterceptorStub{ ProcessBlockEventsCalled: func(eventsData *data.ArgsSaveBlockData) (*data.InterceptorBlockData, error) { - return &data.InterceptorBlockData{ - Hash: blockHash, - Header: header, - Txs: expTxs, - Scrs: expScrs, - LogEvents: logEvents, - TxsWithOrder: expTxsWithOrder, - ScrsWithOrder: expScrsWithOrder, + assert.Fail(t, "should have not been called") + return &data.InterceptorBlockData{}, nil + }, + ProcessBlockEventsV3Called: func(eventsData *data.ArgsSaveBlockData) ([]*data.InterceptorBlockData, error) { + return []*data.InterceptorBlockData{ + { + Hash: blockHash, + Header: header, + Txs: expTxs, + Scrs: expScrs, + LogEvents: logEvents, + TxsWithOrder: expTxsWithOrder, + ScrsWithOrder: expScrsWithOrder, + }, }, nil }, } @@ -321,6 +391,16 @@ func TestHandleSaveBlockEvents(t *testing.T) { eventsHandler, err := process.NewEventsHandler(args) require.Nil(t, err) + blockData := data.ArgsSaveBlockData{ + HeaderHash: []byte(blockHash), + TransactionsPool: &outport.TransactionPool{ + Transactions: txs, + SmartContractResults: scrs, + Logs: logData, + }, + Header: header, + } + err = eventsHandler.HandleSaveBlockEvents(blockData) require.Nil(t, err) diff --git a/process/eventsInterceptor.go b/process/eventsInterceptor.go index 7636ddf..ff172fa 100644 --- a/process/eventsInterceptor.go +++ b/process/eventsInterceptor.go @@ -46,19 +46,28 @@ func NewEventsInterceptor(args ArgsEventsInterceptor) (*eventsInterceptor, error }, nil } -// ProcessBlockEvents will process block events data -func (ei *eventsInterceptor) ProcessBlockEvents(eventsData *data.ArgsSaveBlockData) (*data.InterceptorBlockData, error) { +func baseNilEventsDataChecks(eventsData *data.ArgsSaveBlockData) error { if eventsData == nil { - return nil, ErrNilBlockEvents + return ErrNilBlockEvents } if eventsData.TransactionsPool == nil { - return nil, ErrNilTransactionsPool + return ErrNilTransactionsPool } if eventsData.Body == nil { - return nil, ErrNilBlockBody + return ErrNilBlockBody } if eventsData.Header == nil { - return nil, ErrNilBlockHeader + return ErrNilBlockHeader + } + + return nil +} + +// ProcessBlockEvents will process block events data +func (ei *eventsInterceptor) ProcessBlockEvents(eventsData *data.ArgsSaveBlockData) (*data.InterceptorBlockData, error) { + err := baseNilEventsDataChecks(eventsData) + if err != nil { + return nil, err } events := ei.getLogEventsFromTransactionsPool(eventsData.TransactionsPool.Logs) @@ -92,11 +101,9 @@ func (ei *eventsInterceptor) ProcessBlockEvents(eventsData *data.ArgsSaveBlockDa // ProcessBlockEventsV3 will process block events data for async execution model func (ei *eventsInterceptor) ProcessBlockEventsV3(eventsData *data.ArgsSaveBlockData) ([]*data.InterceptorBlockData, error) { - if eventsData == nil { - return nil, ErrNilBlockEvents - } - if eventsData.Header == nil { - return nil, ErrNilBlockHeader + err := baseNilEventsDataChecks(eventsData) + if err != nil { + return nil, err } if !eventsData.Header.IsHeaderV3() { diff --git a/process/eventsInterceptor_test.go b/process/eventsInterceptor_test.go index 325809a..07ad467 100644 --- a/process/eventsInterceptor_test.go +++ b/process/eventsInterceptor_test.go @@ -45,62 +45,55 @@ func TestNewEventsInterceptor(t *testing.T) { }) } -func TestProcessBlockEvents(t *testing.T) { +func TestEventsInterceptor_baseNilChecks(t *testing.T) { t.Parallel() t.Run("nil block events data", func(t *testing.T) { t.Parallel() - eventsInterceptor, _ := process.NewEventsInterceptor(createMockEventsInterceptorArgs()) - events, err := eventsInterceptor.ProcessBlockEvents(nil) - require.Nil(t, events) + err := process.BaseNilEventsDataCheks(nil) require.Equal(t, process.ErrNilBlockEvents, err) }) t.Run("nil transactions pool", func(t *testing.T) { t.Parallel() - eventsInterceptor, _ := process.NewEventsInterceptor(createMockEventsInterceptorArgs()) - eventsData := &data.ArgsSaveBlockData{ HeaderHash: []byte("headerHash"), TransactionsPool: nil, } - events, err := eventsInterceptor.ProcessBlockEvents(eventsData) - require.Nil(t, events) + err := process.BaseNilEventsDataCheks(eventsData) require.Equal(t, process.ErrNilTransactionsPool, err) }) t.Run("nil block body", func(t *testing.T) { t.Parallel() - eventsInterceptor, _ := process.NewEventsInterceptor(createMockEventsInterceptorArgs()) - eventsData := &data.ArgsSaveBlockData{ HeaderHash: []byte("headerHash"), TransactionsPool: &outport.TransactionPool{}, Body: nil, } - events, err := eventsInterceptor.ProcessBlockEvents(eventsData) - require.Nil(t, events) + err := process.BaseNilEventsDataCheks(eventsData) require.Equal(t, process.ErrNilBlockBody, err) }) t.Run("nil block header", func(t *testing.T) { t.Parallel() - eventsInterceptor, _ := process.NewEventsInterceptor(createMockEventsInterceptorArgs()) - eventsData := &data.ArgsSaveBlockData{ HeaderHash: []byte("headerHash"), TransactionsPool: &outport.TransactionPool{}, Body: &block.Body{}, Header: nil, } - events, err := eventsInterceptor.ProcessBlockEvents(eventsData) - require.Nil(t, events) + err := process.BaseNilEventsDataCheks(eventsData) require.Equal(t, process.ErrNilBlockHeader, err) }) +} + +func TestProcessBlockEvents_WithoutExecutionResults(t *testing.T) { + t.Parallel() t.Run("nil state accesses, should return empty map", func(t *testing.T) { t.Parallel() @@ -307,7 +300,220 @@ func TestProcessBlockEvents(t *testing.T) { require.Nil(t, err) require.Equal(t, expEvents, events) }) +} + +func TestProcessBlockEvents_WithExecutionResults(t *testing.T) { + t.Parallel() + + // TODO: add test for state accesses when implemented on the node + + t.Run("should work", func(t *testing.T) { + t.Parallel() + + eventsInterceptor, _ := process.NewEventsInterceptor(createMockEventsInterceptorArgs()) + + txs := map[string]*outport.TxInfo{ + "hash2": { + Transaction: &transaction.Transaction{ + Nonce: 2, + }, + ExecutionOrder: 1, + }, + } + scrs := map[string]*outport.SCRInfo{ + "hash3": { + SmartContractResult: &smartContractResult.SmartContractResult{ + Nonce: 3, + }, + ExecutionOrder: 1, + }, + } + addr := []byte("addr1") + + blockBody := &block.Body{ + MiniBlocks: make([]*block.MiniBlock, 1), + } + blockHeader := &block.HeaderV3{ + ShardID: 1, + TimestampMs: 1234, + } + + logs := []*outport.LogData{ + { + Log: &transaction.Log{ + Address: addr, + Events: []*transaction.Event{ + { + Address: addr, + }, + }, + }, + }, + } + + proposedTxPool := &outport.TransactionPool{ + Transactions: nil, + SmartContractResults: nil, + Logs: nil, + } + + execTxPool := &outport.TransactionPool{ + Transactions: txs, + SmartContractResults: scrs, + Logs: logs, + } + + blockHash := []byte("blockHash") + + execResults := map[string]*outport.ExecutionResultsData{ + hex.EncodeToString(blockHash): { + Body: blockBody, + TransactionPool: execTxPool, + }, + } + + blockEvents := data.ArgsSaveBlockData{ + HeaderHash: blockHash, + Body: blockBody, + Header: blockHeader, + TransactionsPool: proposedTxPool, + StateAccesses: make(map[string]*stateChange.StateAccesses), + Results: execResults, + } + + expTxs := map[string]*transaction.Transaction{ + "hash2": { + Nonce: 2, + }, + } + expTxsWithOrder := map[string]*outport.TxInfo{ + "hash2": { + Transaction: &transaction.Transaction{ + Nonce: 2, + }, + ExecutionOrder: 1, + }, + } + expScrs := map[string]*smartContractResult.SmartContractResult{ + "hash3": { + Nonce: 3, + }, + } + expScrsWithOrder := map[string]*outport.SCRInfo{ + "hash3": { + SmartContractResult: &smartContractResult.SmartContractResult{ + Nonce: 3, + }, + ExecutionOrder: 1, + }, + } + + expEvents := []*data.InterceptorBlockData{ + { + Hash: hex.EncodeToString(blockHash), + Body: blockBody, + Header: blockHeader, + Txs: expTxs, + TxsWithOrder: expTxsWithOrder, + Scrs: expScrs, + ScrsWithOrder: expScrsWithOrder, + LogEvents: []data.Event{ + { + Address: hex.EncodeToString(addr), + Identifier: "", + Data: make([]byte, 0), + Topics: make([][]byte, 0), + }, + }, + StateAccessesPerAccounts: make(map[string]*stateChange.StateAccesses), + }, + } + + events, err := eventsInterceptor.ProcessBlockEventsV3(&blockEvents) + require.Nil(t, err) + require.Equal(t, expEvents, events) + }) + + t.Run("nil event fields should be returned as empty", func(t *testing.T) { + t.Parallel() + + eventsInterceptor, _ := process.NewEventsInterceptor(createMockEventsInterceptorArgs()) + addr := []byte("addr1") + + blockBody := &block.Body{ + MiniBlocks: make([]*block.MiniBlock, 1), + } + blockHeader := &block.HeaderV3{ + ShardID: 1, + TimestampMs: 1234, + } + + logs := []*outport.LogData{ + { + Log: &transaction.Log{ + Address: addr, + Events: []*transaction.Event{ + { + Address: addr, + Topics: nil, + Data: nil, + Identifier: nil, + }, + }, + }, + }, + } + + proposedTxPool := &outport.TransactionPool{ + Logs: nil, + } + + execTxPool := &outport.TransactionPool{ + Logs: logs, + } + + blockHash := []byte("blockHash") + + execResults := map[string]*outport.ExecutionResultsData{ + hex.EncodeToString(blockHash): { + Body: blockBody, + TransactionPool: execTxPool, + }, + } + + blockEvents := data.ArgsSaveBlockData{ + HeaderHash: blockHash, + Body: blockBody, + Header: blockHeader, + TransactionsPool: proposedTxPool, + StateAccesses: make(map[string]*stateChange.StateAccesses), + Results: execResults, + } + + expEvents := []*data.InterceptorBlockData{ + { + Hash: hex.EncodeToString(blockHash), + Body: blockBody, + Header: blockHeader, + Txs: make(map[string]*transaction.Transaction), + Scrs: make(map[string]*smartContractResult.SmartContractResult), + LogEvents: []data.Event{ + { + Address: hex.EncodeToString(addr), + Identifier: "", + Data: make([]byte, 0), + Topics: make([][]byte, 0), + }, + }, + StateAccessesPerAccounts: make(map[string]*stateChange.StateAccesses), + }, + } + + events, err := eventsInterceptor.ProcessBlockEventsV3(&blockEvents) + require.Nil(t, err) + require.Equal(t, expEvents, events) + }) } func TestGetLogEventsFromTransactionsPool(t *testing.T) { @@ -406,12 +612,12 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { stateAccesses := make(map[string]*stateChange.StateAccesses) stateAccesses["txHash1"] = &stateChange.StateAccesses{ StateAccess: []*stateChange.StateAccess{ - &stateChange.StateAccess{ + { Type: stateChange.Write, MainTrieKey: []byte("mainTrieKey1"), MainTrieVal: []byte("mainTrieVal1"), }, - &stateChange.StateAccess{ + { Type: stateChange.Write, MainTrieKey: []byte("mainTrieKey2"), MainTrieVal: []byte("mainTrieVal2"), @@ -421,12 +627,12 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { stateAccesses["txHash2"] = &stateChange.StateAccesses{} stateAccesses["txHash0"] = &stateChange.StateAccesses{ StateAccess: []*stateChange.StateAccess{ - &stateChange.StateAccess{ + { Type: stateChange.Write, MainTrieKey: []byte("mainTrieKey3"), MainTrieVal: []byte("mainTrieVal3"), }, - &stateChange.StateAccess{ + { Type: stateChange.Write, MainTrieKey: []byte("mainTrieKey2"), MainTrieVal: []byte("mainTrieVal4"), @@ -447,7 +653,7 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { expStateAccessesPerAccounts := make(map[string]*stateChange.StateAccesses) expStateAccessesPerAccounts[hex.EncodeToString([]byte("mainTrieKey1"))] = &stateChange.StateAccesses{ StateAccess: []*stateChange.StateAccess{ - &stateChange.StateAccess{ + { Type: stateChange.Write, MainTrieKey: []byte("mainTrieKey1"), MainTrieVal: []byte("mainTrieVal1"), @@ -456,12 +662,12 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { } expStateAccessesPerAccounts[hex.EncodeToString([]byte("mainTrieKey2"))] = &stateChange.StateAccesses{ StateAccess: []*stateChange.StateAccess{ - &stateChange.StateAccess{ + { Type: stateChange.Write, MainTrieKey: []byte("mainTrieKey2"), MainTrieVal: []byte("mainTrieVal4"), }, - &stateChange.StateAccess{ + { Type: stateChange.Write, MainTrieKey: []byte("mainTrieKey2"), MainTrieVal: []byte("mainTrieVal2"), @@ -470,7 +676,7 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { } expStateAccessesPerAccounts[hex.EncodeToString([]byte("mainTrieKey3"))] = &stateChange.StateAccesses{ StateAccess: []*stateChange.StateAccess{ - &stateChange.StateAccess{ + { Type: stateChange.Write, MainTrieKey: []byte("mainTrieKey3"), MainTrieVal: []byte("mainTrieVal3"), @@ -489,12 +695,12 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { stateAccesses := make(map[string]*stateChange.StateAccesses) stateAccesses["txHash1"] = &stateChange.StateAccesses{ StateAccess: []*stateChange.StateAccess{ - &stateChange.StateAccess{ + { Type: stateChange.Read, MainTrieKey: []byte("mainTrieKey1"), MainTrieVal: []byte("mainTrieVal1"), }, - &stateChange.StateAccess{ + { Type: stateChange.Read, MainTrieKey: []byte("mainTrieKey2"), MainTrieVal: []byte("mainTrieVal2"), @@ -504,12 +710,12 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { stateAccesses["txHash2"] = &stateChange.StateAccesses{} stateAccesses["txHash0"] = &stateChange.StateAccesses{ StateAccess: []*stateChange.StateAccess{ - &stateChange.StateAccess{ + { Type: stateChange.Read, MainTrieKey: []byte("mainTrieKey3"), MainTrieVal: []byte("mainTrieVal3"), }, - &stateChange.StateAccess{ + { Type: stateChange.Read, MainTrieKey: []byte("mainTrieKey2"), MainTrieVal: []byte("mainTrieVal4"), @@ -540,12 +746,12 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { stateAccesses := make(map[string]*stateChange.StateAccesses) stateAccesses["txHash1"] = &stateChange.StateAccesses{ StateAccess: []*stateChange.StateAccess{ - &stateChange.StateAccess{ + { Type: stateChange.Read, MainTrieKey: []byte("mainTrieKey1"), MainTrieVal: []byte("mainTrieVal1"), }, - &stateChange.StateAccess{ + { Type: stateChange.Write, MainTrieKey: []byte("mainTrieKey2"), MainTrieVal: []byte("mainTrieVal2"), @@ -555,12 +761,12 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { stateAccesses["txHash2"] = &stateChange.StateAccesses{} stateAccesses["txHash0"] = &stateChange.StateAccesses{ StateAccess: []*stateChange.StateAccess{ - &stateChange.StateAccess{ + { Type: stateChange.Write, MainTrieKey: []byte("mainTrieKey3"), MainTrieVal: []byte("mainTrieVal3"), }, - &stateChange.StateAccess{ + { Type: stateChange.Read, MainTrieKey: []byte("mainTrieKey2"), MainTrieVal: []byte("mainTrieVal4"), @@ -581,7 +787,7 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { expStateAccessesPerAccounts := make(map[string]*stateChange.StateAccesses) expStateAccessesPerAccounts[hex.EncodeToString([]byte("mainTrieKey2"))] = &stateChange.StateAccesses{ StateAccess: []*stateChange.StateAccess{ - &stateChange.StateAccess{ + { Type: stateChange.Write, MainTrieKey: []byte("mainTrieKey2"), MainTrieVal: []byte("mainTrieVal2"), @@ -590,7 +796,7 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { } expStateAccessesPerAccounts[hex.EncodeToString([]byte("mainTrieKey3"))] = &stateChange.StateAccesses{ StateAccess: []*stateChange.StateAccess{ - &stateChange.StateAccess{ + { Type: stateChange.Write, MainTrieKey: []byte("mainTrieKey3"), MainTrieVal: []byte("mainTrieVal3"), diff --git a/process/export_test.go b/process/export_test.go index fa032b3..e57075a 100644 --- a/process/export_test.go +++ b/process/export_test.go @@ -45,3 +45,8 @@ func (ei *eventsInterceptor) GetLogEventsFromTransactionsPool(logs []*outport.Lo func (ei *eventsInterceptor) GetStateAccessesPerAccounts(eventsData *data.ArgsSaveBlockData) map[string]*stateChange.StateAccesses { return ei.getStateAccessesPerAccounts(eventsData) } + +// BaseNilEventsDataCheks - +func BaseNilEventsDataCheks(eventsData *data.ArgsSaveBlockData) error { + return baseNilEventsDataChecks(eventsData) +} From 5a79367f9d016145f69ee7413e1919c9decb1664 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Wed, 12 Nov 2025 17:46:38 +0200 Subject: [PATCH 13/62] small renamings --- data/outport.go | 2 +- process/eventsHandler.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/data/outport.go b/data/outport.go index 8c7c95f..18ec51a 100644 --- a/data/outport.go +++ b/data/outport.go @@ -32,7 +32,7 @@ type BlockEvents struct { ShardID uint32 `json:"shardId"` TimeStamp uint64 `json:"timestamp"` TimeStampMs uint64 `json:"timestampMs"` - Events []Event `json:"events,omitempty"` + Events []Event `json:"events"` } // RevertBlock holds revert event data diff --git a/process/eventsHandler.go b/process/eventsHandler.go index 46af20e..d444ca2 100644 --- a/process/eventsHandler.go +++ b/process/eventsHandler.go @@ -176,7 +176,7 @@ func (eh *eventsHandler) handleSaveBlockEvents( } func (eh *eventsHandler) handleSaveBlockEventsV3(allEvents data.ArgsSaveBlockData) error { - execEventsData, err := eh.eventsInterceptor.ProcessBlockEventsV3(&allEvents) + executionResultsData, err := eh.eventsInterceptor.ProcessBlockEventsV3(&allEvents) if err != nil { return err } @@ -187,9 +187,9 @@ func (eh *eventsHandler) handleSaveBlockEventsV3(allEvents data.ArgsSaveBlockDat shardID := allEvents.Header.GetShardID() nonce := allEvents.Header.GetNonce() - for _, execEv := range execEventsData { + for _, executionResultData := range executionResultsData { err = eh.handleSaveBlockEvents( - execEv, + executionResultData, headerTimeStamp, headerTimeStampMs, shardID, From 1f62faf1f9c6f963fc20bc1a285f8aab6fd41a5a Mon Sep 17 00:00:00 2001 From: ssd04 Date: Mon, 17 Nov 2025 16:07:46 +0200 Subject: [PATCH 14/62] fixes after review --- process/eventsInterceptor.go | 62 +++++++++++----------- process/preprocess/eventsPreProcessorV1.go | 12 +---- 2 files changed, 31 insertions(+), 43 deletions(-) diff --git a/process/eventsInterceptor.go b/process/eventsInterceptor.go index ff172fa..b5a52fa 100644 --- a/process/eventsInterceptor.go +++ b/process/eventsInterceptor.go @@ -70,19 +70,9 @@ func (ei *eventsInterceptor) ProcessBlockEvents(eventsData *data.ArgsSaveBlockDa return nil, err } - events := ei.getLogEventsFromTransactionsPool(eventsData.TransactionsPool.Logs) + transactionsPool := eventsData.TransactionsPool - txs := make(map[string]*transaction.Transaction) - for hash, tx := range eventsData.TransactionsPool.Transactions { - txs[hash] = tx.Transaction - } - txsWithOrder := eventsData.TransactionsPool.Transactions - - scrs := make(map[string]*smartContractResult.SmartContractResult) - for hash, scr := range eventsData.TransactionsPool.SmartContractResults { - scrs[hash] = scr.SmartContractResult - } - scrsWithOrder := eventsData.TransactionsPool.SmartContractResults + events := ei.getLogEventsFromTransactionsPool(transactionsPool.Logs) stateAccessesPerAccounts := ei.getStateAccessesPerAccounts(eventsData) @@ -90,10 +80,10 @@ func (ei *eventsInterceptor) ProcessBlockEvents(eventsData *data.ArgsSaveBlockDa Hash: hex.EncodeToString(eventsData.HeaderHash), Body: eventsData.Body, Header: eventsData.Header, - Txs: txs, - TxsWithOrder: txsWithOrder, - Scrs: scrs, - ScrsWithOrder: scrsWithOrder, + Txs: getTxsFromPool(transactionsPool), + TxsWithOrder: transactionsPool.GetTransactions(), + Scrs: getScrsFromPool(transactionsPool), + ScrsWithOrder: transactionsPool.GetSmartContractResults(), LogEvents: events, StateAccessesPerAccounts: stateAccessesPerAccounts, }, nil @@ -125,18 +115,6 @@ func (ei *eventsInterceptor) ProcessBlockEventsV3(eventsData *data.ArgsSaveBlock events := ei.getLogEventsFromTransactionsPool(transactionsPool.GetLogs()) - txs := make(map[string]*transaction.Transaction) - for hash, tx := range transactionsPool.GetTransactions() { - txs[hash] = tx.Transaction - } - txsWithOrder := transactionsPool.GetTransactions() - - scrs := make(map[string]*smartContractResult.SmartContractResult) - for hash, scr := range transactionsPool.GetSmartContractResults() { - scrs[hash] = scr.SmartContractResult - } - scrsWithOrder := transactionsPool.GetSmartContractResults() - // TODO: handle state accesses for header v3 stateAccessesPerAccounts := ei.getStateAccessesPerAccounts(eventsData) @@ -144,10 +122,10 @@ func (ei *eventsInterceptor) ProcessBlockEventsV3(eventsData *data.ArgsSaveBlock Hash: headerHash, Body: body, Header: eventsData.Header, // this holds current proposed header, not executed header - Txs: txs, - TxsWithOrder: txsWithOrder, - Scrs: scrs, - ScrsWithOrder: scrsWithOrder, + Txs: getTxsFromPool(transactionsPool), + TxsWithOrder: transactionsPool.GetTransactions(), + Scrs: getScrsFromPool(transactionsPool), + ScrsWithOrder: transactionsPool.GetSmartContractResults(), LogEvents: events, StateAccessesPerAccounts: stateAccessesPerAccounts, } @@ -158,6 +136,26 @@ func (ei *eventsInterceptor) ProcessBlockEventsV3(eventsData *data.ArgsSaveBlock return execBlocksData, nil } +func getScrsFromPool(transactionsPool *outport.TransactionPool) map[string]*smartContractResult.SmartContractResult { + scrs := make(map[string]*smartContractResult.SmartContractResult) + + for hash, scr := range transactionsPool.GetSmartContractResults() { + scrs[hash] = scr.SmartContractResult + } + + return scrs +} + +func getTxsFromPool(transactionsPool *outport.TransactionPool) map[string]*transaction.Transaction { + txs := make(map[string]*transaction.Transaction) + + for hash, tx := range transactionsPool.GetTransactions() { + txs[hash] = tx.Transaction + } + + return txs +} + func getTxsWithOrder(transactionsPool *outport.TransactionPool) []txWithOrder { txsWithOrderMap := make(map[string]uint32) diff --git a/process/preprocess/eventsPreProcessorV1.go b/process/preprocess/eventsPreProcessorV1.go index 8600aa1..60de8df 100644 --- a/process/preprocess/eventsPreProcessorV1.go +++ b/process/preprocess/eventsPreProcessorV1.go @@ -56,9 +56,8 @@ func (d *eventsPreProcessorV1) SaveBlock(marshalledData []byte) error { return err } - // executionResults := make(map[string]*outport.ExecutionResultsData) var executionResults map[string]*outport.ExecutionResultsData - if isHeaderV3(headerType) { + if header.IsHeaderV3() { executionResults = outportBlock.BlockData.Results } @@ -85,15 +84,6 @@ func (d *eventsPreProcessorV1) SaveBlock(marshalledData []byte) error { return nil } -func isHeaderV3(headerType core.HeaderType) bool { - if headerType == core.ShardHeaderV3 || - headerType == core.MetaHeaderV3 { - return true - } - - return false -} - func checkBlockDataValid(block *outport.OutportBlock) error { if block.BlockData == nil { return ErrNilBlockData From 7471e4a36486b7ebf9ce83734726a498146cf9c7 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Mon, 17 Nov 2025 17:53:34 +0200 Subject: [PATCH 15/62] fix tx pool nil checks --- process/eventsInterceptor.go | 11 ++++++++--- process/eventsInterceptor_test.go | 11 ----------- process/preprocess/eventsPreProcessorV1.go | 3 --- process/preprocess/eventsPreProcessorV1_test.go | 14 -------------- 4 files changed, 8 insertions(+), 31 deletions(-) diff --git a/process/eventsInterceptor.go b/process/eventsInterceptor.go index b5a52fa..037378a 100644 --- a/process/eventsInterceptor.go +++ b/process/eventsInterceptor.go @@ -2,6 +2,7 @@ package process import ( "encoding/hex" + "fmt" "sort" "github.com/multiversx/mx-chain-core-go/core" @@ -50,9 +51,6 @@ func baseNilEventsDataChecks(eventsData *data.ArgsSaveBlockData) error { if eventsData == nil { return ErrNilBlockEvents } - if eventsData.TransactionsPool == nil { - return ErrNilTransactionsPool - } if eventsData.Body == nil { return ErrNilBlockBody } @@ -69,6 +67,9 @@ func (ei *eventsInterceptor) ProcessBlockEvents(eventsData *data.ArgsSaveBlockDa if err != nil { return nil, err } + if eventsData.TransactionsPool == nil { + return nil, ErrNilTransactionsPool + } transactionsPool := eventsData.TransactionsPool @@ -111,6 +112,10 @@ func (ei *eventsInterceptor) ProcessBlockEventsV3(eventsData *data.ArgsSaveBlock for headerHash, execBlockData := range eventsData.Results { transactionsPool := execBlockData.GetTransactionPool() + if transactionsPool == nil { + return nil, fmt.Errorf("%w: for execution results block data", ErrNilTransactionsPool) + } + body := execBlockData.Body events := ei.getLogEventsFromTransactionsPool(transactionsPool.GetLogs()) diff --git a/process/eventsInterceptor_test.go b/process/eventsInterceptor_test.go index 07ad467..94cbdd0 100644 --- a/process/eventsInterceptor_test.go +++ b/process/eventsInterceptor_test.go @@ -55,17 +55,6 @@ func TestEventsInterceptor_baseNilChecks(t *testing.T) { require.Equal(t, process.ErrNilBlockEvents, err) }) - t.Run("nil transactions pool", func(t *testing.T) { - t.Parallel() - - eventsData := &data.ArgsSaveBlockData{ - HeaderHash: []byte("headerHash"), - TransactionsPool: nil, - } - err := process.BaseNilEventsDataCheks(eventsData) - require.Equal(t, process.ErrNilTransactionsPool, err) - }) - t.Run("nil block body", func(t *testing.T) { t.Parallel() diff --git a/process/preprocess/eventsPreProcessorV1.go b/process/preprocess/eventsPreProcessorV1.go index 60de8df..a48cfa4 100644 --- a/process/preprocess/eventsPreProcessorV1.go +++ b/process/preprocess/eventsPreProcessorV1.go @@ -88,9 +88,6 @@ func checkBlockDataValid(block *outport.OutportBlock) error { if block.BlockData == nil { return ErrNilBlockData } - if block.TransactionPool == nil { - return ErrNilTransactionPool - } if block.HeaderGasConsumption == nil { return ErrNilHeaderGasConsumption } diff --git a/process/preprocess/eventsPreProcessorV1_test.go b/process/preprocess/eventsPreProcessorV1_test.go index 0042ca7..cbaf5d8 100644 --- a/process/preprocess/eventsPreProcessorV1_test.go +++ b/process/preprocess/eventsPreProcessorV1_test.go @@ -34,20 +34,6 @@ func TestPreProcessorV1_SaveBlock(t *testing.T) { require.Equal(t, preprocess.ErrNilBlockData, err) }) - t.Run("nil transaction pool", func(t *testing.T) { - t.Parallel() - - outportBlock := createDefaultOutportBlock() - outportBlock.TransactionPool = nil - - dp, err := preprocess.NewEventsPreProcessorV1(createMockEventsDataPreProcessorArgs()) - require.Nil(t, err) - - marshalledBlock, _ := json.Marshal(outportBlock) - err = dp.SaveBlock(marshalledBlock) - require.Equal(t, preprocess.ErrNilTransactionPool, err) - }) - t.Run("nil header gas consumption", func(t *testing.T) { t.Parallel() From c0f5d4ff22083f42035e8af5399d269f23b59fb4 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Mon, 17 Nov 2025 17:53:48 +0200 Subject: [PATCH 16/62] add test data for v3 --- testdata/testData.go | 109 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/testdata/testData.go b/testdata/testData.go index 9962d4d..758de24 100644 --- a/testdata/testData.go +++ b/testdata/testData.go @@ -198,6 +198,115 @@ func (bd *blockData) OutportBlockV1() *outport.OutportBlock { } } +// OutportBlockV2 - +func (bd *blockData) OutportBlockV2() *outport.OutportBlock { + header := &block.HeaderV3{ + ShardID: 1, + TimestampMs: 1234, + } + headerBytes, _ := bd.marshaller.Marshal(header) + + execBlockHash := []byte("execBlockHash1") + + stateAccesses := make(map[string]*stateChange.StateAccesses) + stateAccesses["txHash1"] = &stateChange.StateAccesses{ + StateAccess: []*stateChange.StateAccess{ + &stateChange.StateAccess{ + Type: stateChange.Write, + MainTrieKey: []byte("mainTrieKey1"), + MainTrieVal: []byte("mainTrieVal1"), + TxHash: []byte("txHash1"), + AccountChanges: 8, + }, + &stateChange.StateAccess{ + Type: stateChange.Write, + MainTrieKey: []byte("mainTrieKey2"), + MainTrieVal: []byte("mainTrieVal2"), + TxHash: []byte("txHash1"), + AccountChanges: 4, + }, + }, + } + stateAccesses["txHash2"] = &stateChange.StateAccesses{} + + blockBody := &block.Body{ + MiniBlocks: []*block.MiniBlock{ + { + TxHashes: [][]byte{}, + ReceiverShardID: 1, + SenderShardID: 1, + }, + }, + } + + execResTxPool := &outport.TransactionPool{ + Transactions: map[string]*outport.TxInfo{ + hex.EncodeToString([]byte("txHash1")): { + Transaction: &transaction.Transaction{ + Nonce: 1, + GasPrice: 1, + GasLimit: 1, + }, + FeeInfo: &outport.FeeInfo{ + GasUsed: 1, + }, + ExecutionOrder: 2, + }, + }, + SmartContractResults: map[string]*outport.SCRInfo{ + hex.EncodeToString([]byte("scrHash1")): { + SmartContractResult: &smartContractResult.SmartContractResult{ + Nonce: 2, + GasLimit: 2, + GasPrice: 2, + CallType: 2, + }, + FeeInfo: &outport.FeeInfo{ + GasUsed: 2, + }, + ExecutionOrder: 0, + }, + }, + Logs: []*outport.LogData{ + { + Log: &transaction.Log{ + Address: []byte("logaddr1"), + Events: []*transaction.Event{}, + }, + TxHash: "logHash1", + }, + }, + } + + execResults := map[string]*outport.ExecutionResultsData{ + hex.EncodeToString(execBlockHash): { + Body: blockBody, + TransactionPool: execResTxPool, + }, + } + + return &outport.OutportBlock{ + BlockData: &outport.BlockData{ + HeaderBytes: headerBytes, + HeaderType: "Header", + HeaderHash: []byte("headerHash1"), + Body: &block.Body{ + MiniBlocks: []*block.MiniBlock{ + { + TxHashes: [][]byte{}, + ReceiverShardID: 1, + SenderShardID: 1, + }, + }, + }, + Results: execResults, + }, + HeaderGasConsumption: &outport.HeaderGasConsumption{}, + NumberOfShards: 2, + StateAccesses: stateAccesses, + } +} + // RevertBlockV0 - func (bd *blockData) RevertBlockV0() *notifierData.RevertBlock { return ¬ifierData.RevertBlock{ From 9784855bb7d14704d1f52bb9d25d238de45c5e33 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Mon, 17 Nov 2025 17:54:29 +0200 Subject: [PATCH 17/62] add TODO for integration tests updates for v3 --- integrationTests/websocket/testNotifierWithWebsockets_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/integrationTests/websocket/testNotifierWithWebsockets_test.go b/integrationTests/websocket/testNotifierWithWebsockets_test.go index 3c55879..a28f14d 100644 --- a/integrationTests/websocket/testNotifierWithWebsockets_test.go +++ b/integrationTests/websocket/testNotifierWithWebsockets_test.go @@ -20,6 +20,8 @@ import ( "github.com/stretchr/testify/require" ) +// TODO: adapt integration tests for v3 + func TestNotifierWithWebsockets_PushEvents(t *testing.T) { cfg := integrationTests.GetDefaultConfigs() notifier, err := integrationTests.NewTestNotifierWithWS(cfg.MainConfig) From a2baa425853ffbecffcff92a3267b32ca7394535 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Tue, 18 Nov 2025 13:42:36 +0200 Subject: [PATCH 18/62] add error logging --- api/groups/eventsGroup.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/api/groups/eventsGroup.go b/api/groups/eventsGroup.go index a394c7e..0fd83f9 100644 --- a/api/groups/eventsGroup.go +++ b/api/groups/eventsGroup.go @@ -98,6 +98,7 @@ func getPayloadVersion(c *gin.Context) uint32 { func (h *eventsGroup) pushEvents(c *gin.Context) { pushEventsRawData, err := c.GetRawData() if err != nil { + log.Error("pushEvents: failed to get raw data", "error", err) shared.JSONResponse(c, http.StatusBadRequest, nil, err.Error()) return } @@ -106,6 +107,7 @@ func (h *eventsGroup) pushEvents(c *gin.Context) { err = h.payloadHandler.ProcessPayload(pushEventsRawData, outport.TopicSaveBlock, payloadVersion) if err != nil { + log.Error("pushEvents: failed to process payload", "error", err) shared.JSONResponse(c, http.StatusBadRequest, nil, err.Error()) return } @@ -116,6 +118,7 @@ func (h *eventsGroup) pushEvents(c *gin.Context) { func (h *eventsGroup) revertEvents(c *gin.Context) { revertEventsRawData, err := c.GetRawData() if err != nil { + log.Error("revertEvents: failed to get raw data", "error", err) shared.JSONResponse(c, http.StatusBadRequest, nil, err.Error()) return } @@ -124,6 +127,7 @@ func (h *eventsGroup) revertEvents(c *gin.Context) { err = h.payloadHandler.ProcessPayload(revertEventsRawData, outport.TopicRevertIndexedBlock, payloadVersion) if err != nil { + log.Error("revertEvents: failed to process payload", "error", err) shared.JSONResponse(c, http.StatusBadRequest, nil, err.Error()) return } @@ -134,6 +138,7 @@ func (h *eventsGroup) revertEvents(c *gin.Context) { func (h *eventsGroup) finalizedEvents(c *gin.Context) { finalizedRawData, err := c.GetRawData() if err != nil { + log.Error("finalizedEvents: failed to get raw data", "error", err) shared.JSONResponse(c, http.StatusBadRequest, nil, err.Error()) return } @@ -142,6 +147,7 @@ func (h *eventsGroup) finalizedEvents(c *gin.Context) { err = h.payloadHandler.ProcessPayload(finalizedRawData, outport.TopicFinalizedBlock, payloadVersion) if err != nil { + log.Error("finalizedEvents: failed to process payload", "error", err) shared.JSONResponse(c, http.StatusBadRequest, nil, err.Error()) return } From b98eddfdf3366ab194fc392b53f5256e0f03026f Mon Sep 17 00:00:00 2001 From: ssd04 Date: Tue, 18 Nov 2025 13:44:36 +0200 Subject: [PATCH 19/62] adapt integrationt test for v3 --- .../rabbitmq/testNotifierWithRabbitMQ_test.go | 66 ++++++++++++++++++- .../testNotifierWithWebsockets_test.go | 66 ++++++++++++++++++- process/eventsInterceptor.go | 3 +- testdata/testData.go | 10 ++- 4 files changed, 137 insertions(+), 8 deletions(-) diff --git a/integrationTests/rabbitmq/testNotifierWithRabbitMQ_test.go b/integrationTests/rabbitmq/testNotifierWithRabbitMQ_test.go index 4afcb41..55b3116 100644 --- a/integrationTests/rabbitmq/testNotifierWithRabbitMQ_test.go +++ b/integrationTests/rabbitmq/testNotifierWithRabbitMQ_test.go @@ -13,9 +13,11 @@ import ( "github.com/multiversx/mx-chain-core-go/data/smartContractResult" "github.com/multiversx/mx-chain-core-go/data/stateChange" "github.com/multiversx/mx-chain-core-go/data/transaction" + "github.com/multiversx/mx-chain-core-go/marshal" logger "github.com/multiversx/mx-chain-logger-go" "github.com/multiversx/mx-chain-notifier-go/common" "github.com/multiversx/mx-chain-notifier-go/integrationTests" + "github.com/multiversx/mx-chain-notifier-go/testdata" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -32,6 +34,16 @@ func TestNotifierWithRabbitMQ(t *testing.T) { }) } +func TestNotifierWithRabbitMQV3(t *testing.T) { + t.Run("with http observer connnector", func(t *testing.T) { + testNotifierWithRabbitMQV3(t, common.HTTPConnectorType, common.PayloadV1) + }) + + t.Run("with ws observer connnector", func(t *testing.T) { + testNotifierWithRabbitMQV3(t, common.WSObsConnectorType, common.PayloadV1) + }) +} + func testNotifierWithRabbitMQ(t *testing.T, observerType string, payloadVersion uint32) { cfg := integrationTests.GetDefaultConfigs() cfg.MainConfig.General.CheckDuplicates = true @@ -64,6 +76,38 @@ func testNotifierWithRabbitMQ(t *testing.T, observerType string, payloadVersion assert.Equal(t, 7, len(notifier.RabbitMQClient.GetEntries())) } +func testNotifierWithRabbitMQV3(t *testing.T, observerType string, payloadVersion uint32) { + cfg := integrationTests.GetDefaultConfigs() + cfg.MainConfig.General.CheckDuplicates = true + notifier, err := integrationTests.NewTestNotifierWithRabbitMq(cfg.MainConfig) + require.Nil(t, err) + + client, err := integrationTests.CreateObserverConnector(notifier.Facade, observerType, common.MessageQueuePublisherType, payloadVersion) + require.Nil(t, err) + + // wait for components to start + time.Sleep(time.Second * 5) + + _ = notifier.Publisher.Run() + defer notifier.Publisher.Close() + + wg := &sync.WaitGroup{} + wg.Add(5) + + go pushEventsRequestV3(wg, client) + go pushRevertRequest(wg, client) + go pushFinalizedRequest(wg, client) + + // send requests again + go pushEventsRequest(wg, client) + go pushRevertRequest(wg, client) + + integrationTests.WaitTimeout(t, wg, time.Second*2) + + assert.Equal(t, 3, len(notifier.RedisClient.GetEntries())) + assert.Equal(t, 7, len(notifier.RabbitMQClient.GetEntries())) +} + func pushEventsRequest(wg *sync.WaitGroup, webServer integrationTests.ObserverConnector) { header := &block.HeaderV2{ Header: &block.Header{ @@ -109,11 +153,11 @@ func pushEventsRequest(wg *sync.WaitGroup, webServer integrationTests.ObserverCo stateAccesses := make(map[string]*stateChange.StateAccesses) stateAccesses["txHash1"] = &stateChange.StateAccesses{ StateAccess: []*stateChange.StateAccess{ - &stateChange.StateAccess{ + { MainTrieKey: []byte("mainTrieKey1"), MainTrieVal: []byte("mainTrieVal1"), }, - &stateChange.StateAccess{ + { MainTrieKey: []byte("mainTrieKey2"), MainTrieVal: []byte("mainTrieVal2"), }, @@ -145,6 +189,24 @@ func pushEventsRequest(wg *sync.WaitGroup, webServer integrationTests.ObserverCo } } +func pushEventsRequestV3( + wg *sync.WaitGroup, + webServer integrationTests.ObserverConnector, +) { + marshaller := &marshal.JsonMarshalizer{} + blockData, err := testdata.NewBlockData(marshaller) + log.LogIfError(err) + + saveBlockData := blockData.OutportBlockV2() + + err = webServer.PushEventsRequest(saveBlockData) + log.LogIfError(err) + + if err == nil { + wg.Done() + } +} + func pushRevertRequest(wg *sync.WaitGroup, webServer integrationTests.ObserverConnector) { header := &block.HeaderV2{ Header: &block.Header{ diff --git a/integrationTests/websocket/testNotifierWithWebsockets_test.go b/integrationTests/websocket/testNotifierWithWebsockets_test.go index a28f14d..bc13b61 100644 --- a/integrationTests/websocket/testNotifierWithWebsockets_test.go +++ b/integrationTests/websocket/testNotifierWithWebsockets_test.go @@ -13,9 +13,11 @@ import ( "github.com/multiversx/mx-chain-core-go/data/smartContractResult" "github.com/multiversx/mx-chain-core-go/data/stateChange" "github.com/multiversx/mx-chain-core-go/data/transaction" + "github.com/multiversx/mx-chain-core-go/marshal" "github.com/multiversx/mx-chain-notifier-go/common" "github.com/multiversx/mx-chain-notifier-go/data" "github.com/multiversx/mx-chain-notifier-go/integrationTests" + "github.com/multiversx/mx-chain-notifier-go/testdata" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -68,11 +70,11 @@ func TestNotifierWithWebsockets_PushEvents(t *testing.T) { stateAccesses := make(map[string]*stateChange.StateAccesses) stateAccesses["txHash1"] = &stateChange.StateAccesses{ StateAccess: []*stateChange.StateAccess{ - &stateChange.StateAccess{ + { MainTrieKey: []byte("mainTrieKey1"), MainTrieVal: []byte("mainTrieVal1"), }, - &stateChange.StateAccess{ + { MainTrieKey: []byte("mainTrieKey2"), MainTrieVal: []byte("mainTrieVal2"), }, @@ -126,6 +128,66 @@ func TestNotifierWithWebsockets_PushEvents(t *testing.T) { integrationTests.WaitTimeout(t, wg, time.Second*2) } +func TestNotifierWithWebsockets_PushEventsV3(t *testing.T) { + cfg := integrationTests.GetDefaultConfigs() + notifier, err := integrationTests.NewTestNotifierWithWS(cfg.MainConfig) + require.Nil(t, err) + + webServer, err := integrationTests.CreateObserverConnector(notifier.Facade, common.HTTPConnectorType, common.WSPublisherType, common.PayloadV1) + require.Nil(t, err) + + _ = notifier.Publisher.Run() + defer notifier.Publisher.Close() + + ws, err := integrationTests.NewWSClient(notifier.WSHandler) + require.Nil(t, err) + defer ws.Close() + + subscribeEvent := &data.SubscribeEvent{ + SubscriptionEntries: []data.SubscriptionEntry{ + { + EventType: common.PushLogsAndEvents, + }, + }, + } + + ws.SendSubscribeMessage(subscribeEvent) + + addr := []byte("logaddr1") + events := []data.Event{ + { + Address: hex.EncodeToString(addr), + TxHash: "txHash1", + Data: make([]byte, 0), + Topics: make([][]byte, 0), + }, + } + + marshaller := &marshal.JsonMarshalizer{} + blockData, err := testdata.NewBlockData(marshaller) + require.Nil(t, err) + + saveBlockData := blockData.OutportBlockV2() + + wg := &sync.WaitGroup{} + wg.Add(1) + + go func() { + reply, err := ws.ReceiveEvents() + require.Nil(t, err) + + require.Equal(t, events, reply) + wg.Done() + }() + + time.Sleep(time.Second) + + err = webServer.PushEventsRequest(saveBlockData) + require.Nil(t, err) + + integrationTests.WaitTimeout(t, wg, time.Second*2) +} + func TestNotifierWithWebsockets_BlockEvents(t *testing.T) { cfg := integrationTests.GetDefaultConfigs() notifier, err := integrationTests.NewTestNotifierWithWS(cfg.MainConfig) diff --git a/process/eventsInterceptor.go b/process/eventsInterceptor.go index 037378a..e9fddcb 100644 --- a/process/eventsInterceptor.go +++ b/process/eventsInterceptor.go @@ -121,7 +121,8 @@ func (ei *eventsInterceptor) ProcessBlockEventsV3(eventsData *data.ArgsSaveBlock events := ei.getLogEventsFromTransactionsPool(transactionsPool.GetLogs()) // TODO: handle state accesses for header v3 - stateAccessesPerAccounts := ei.getStateAccessesPerAccounts(eventsData) + // stateAccessesPerAccounts := ei.getStateAccessesPerAccounts(eventsData) + stateAccessesPerAccounts := make(map[string]*stateChange.StateAccesses) blockData := &data.InterceptorBlockData{ Hash: headerHash, diff --git a/testdata/testData.go b/testdata/testData.go index 758de24..d3c5ac7 100644 --- a/testdata/testData.go +++ b/testdata/testData.go @@ -271,9 +271,13 @@ func (bd *blockData) OutportBlockV2() *outport.OutportBlock { { Log: &transaction.Log{ Address: []byte("logaddr1"), - Events: []*transaction.Event{}, + Events: []*transaction.Event{ + { + Address: []byte("logaddr1"), + }, + }, }, - TxHash: "logHash1", + TxHash: "txHash1", }, }, } @@ -288,7 +292,7 @@ func (bd *blockData) OutportBlockV2() *outport.OutportBlock { return &outport.OutportBlock{ BlockData: &outport.BlockData{ HeaderBytes: headerBytes, - HeaderType: "Header", + HeaderType: "HeaderV3", HeaderHash: []byte("headerHash1"), Body: &block.Body{ MiniBlocks: []*block.MiniBlock{ From ce9be576bb2d2e8b69c5e74719a72347bd045d87 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Wed, 19 Nov 2025 11:21:09 +0200 Subject: [PATCH 20/62] added more integration tests for v3 --- .../rabbitmq/testNotifierWithRabbitMQ_test.go | 43 ++++++++++--- .../testNotifierWithWebsockets_test.go | 61 ++++++++++++++++++- 2 files changed, 95 insertions(+), 9 deletions(-) diff --git a/integrationTests/rabbitmq/testNotifierWithRabbitMQ_test.go b/integrationTests/rabbitmq/testNotifierWithRabbitMQ_test.go index 55b3116..ad7fc4d 100644 --- a/integrationTests/rabbitmq/testNotifierWithRabbitMQ_test.go +++ b/integrationTests/rabbitmq/testNotifierWithRabbitMQ_test.go @@ -22,6 +22,17 @@ import ( "github.com/stretchr/testify/require" ) +const ( + // number of expected redis events + // one event for each outport driver method: Save, Revert, Finalized + numExpRedisEvents = 3 + + // number of exected rabbitmq events + // 5 events (logs & events, txs, scrs, full blocks events, state accesses) for Save method + // + one event for each other outport driver method: Revert, Finalized + numExpRabbitMQEvents = 7 +) + var log = logger.GetOrCreate("integrationTests/rabbitmq") func TestNotifierWithRabbitMQ(t *testing.T) { @@ -72,8 +83,8 @@ func testNotifierWithRabbitMQ(t *testing.T, observerType string, payloadVersion integrationTests.WaitTimeout(t, wg, time.Second*2) - assert.Equal(t, 3, len(notifier.RedisClient.GetEntries())) - assert.Equal(t, 7, len(notifier.RabbitMQClient.GetEntries())) + assert.Equal(t, numExpRedisEvents, len(notifier.RedisClient.GetEntries())) + assert.Equal(t, numExpRabbitMQEvents, len(notifier.RabbitMQClient.GetEntries())) } func testNotifierWithRabbitMQV3(t *testing.T, observerType string, payloadVersion uint32) { @@ -95,17 +106,17 @@ func testNotifierWithRabbitMQV3(t *testing.T, observerType string, payloadVersio wg.Add(5) go pushEventsRequestV3(wg, client) - go pushRevertRequest(wg, client) + go pushRevertRequestV3(wg, client) go pushFinalizedRequest(wg, client) // send requests again - go pushEventsRequest(wg, client) - go pushRevertRequest(wg, client) + go pushEventsRequestV3(wg, client) + go pushRevertRequestV3(wg, client) integrationTests.WaitTimeout(t, wg, time.Second*2) - assert.Equal(t, 3, len(notifier.RedisClient.GetEntries())) - assert.Equal(t, 7, len(notifier.RabbitMQClient.GetEntries())) + assert.Equal(t, numExpRedisEvents, len(notifier.RedisClient.GetEntries())) + assert.Equal(t, numExpRabbitMQEvents, len(notifier.RabbitMQClient.GetEntries())) } func pushEventsRequest(wg *sync.WaitGroup, webServer integrationTests.ObserverConnector) { @@ -227,6 +238,24 @@ func pushRevertRequest(wg *sync.WaitGroup, webServer integrationTests.ObserverCo } } +func pushRevertRequestV3(wg *sync.WaitGroup, webServer integrationTests.ObserverConnector) { + header := &block.HeaderV3{ + Nonce: 1, + } + headerBytes, _ := json.Marshal(header) + blockData := &outport.BlockData{ + HeaderBytes: headerBytes, + HeaderType: string(core.ShardHeaderV3), + HeaderHash: []byte("headerHash3"), + } + err := webServer.RevertEventsRequest(blockData) + log.LogIfError(err) + + if err == nil { + wg.Done() + } +} + func pushFinalizedRequest(wg *sync.WaitGroup, webServer integrationTests.ObserverConnector) { blockEvents := &outport.FinalizedBlock{ HeaderHash: []byte("headerHash3"), diff --git a/integrationTests/websocket/testNotifierWithWebsockets_test.go b/integrationTests/websocket/testNotifierWithWebsockets_test.go index bc13b61..7e1046d 100644 --- a/integrationTests/websocket/testNotifierWithWebsockets_test.go +++ b/integrationTests/websocket/testNotifierWithWebsockets_test.go @@ -22,8 +22,6 @@ import ( "github.com/stretchr/testify/require" ) -// TODO: adapt integration tests for v3 - func TestNotifierWithWebsockets_PushEvents(t *testing.T) { cfg := integrationTests.GetDefaultConfigs() notifier, err := integrationTests.NewTestNotifierWithWS(cfg.MainConfig) @@ -350,6 +348,65 @@ func TestNotifierWithWebsockets_RevertEvents(t *testing.T) { integrationTests.WaitTimeout(t, wg, time.Second*2) } +func TestNotifierWithWebsockets_RevertEventsV3(t *testing.T) { + cfg := integrationTests.GetDefaultConfigs() + notifier, err := integrationTests.NewTestNotifierWithWS(cfg.MainConfig) + require.Nil(t, err) + + webServer, err := integrationTests.CreateObserverConnector(notifier.Facade, common.HTTPConnectorType, common.WSPublisherType, common.PayloadV1) + require.Nil(t, err) + + _ = notifier.Publisher.Run() + defer notifier.Publisher.Close() + + ws, err := integrationTests.NewWSClient(notifier.WSHandler) + require.Nil(t, err) + defer ws.Close() + + subscribeEvent := &data.SubscribeEvent{ + SubscriptionEntries: []data.SubscriptionEntry{ + { + EventType: common.RevertBlockEvents, + }, + }, + } + + ws.SendSubscribeMessage(subscribeEvent) + + header := &block.HeaderV3{ + Nonce: 1, + } + headerBytes, _ := json.Marshal(header) + blockEvents := &outport.BlockData{ + HeaderBytes: headerBytes, + HeaderType: string(core.ShardHeaderV3), + HeaderHash: []byte("hash1"), + } + + expReply := &data.RevertBlock{ + Hash: hex.EncodeToString([]byte("hash1")), + Nonce: 1, + } + + wg := &sync.WaitGroup{} + wg.Add(1) + + go func() { + reply, err := ws.ReceiveRevertBlock() + require.Nil(t, err) + + require.Equal(t, expReply, reply) + wg.Done() + }() + + time.Sleep(time.Second) + + err = webServer.RevertEventsRequest(blockEvents) + require.Nil(t, err) + + integrationTests.WaitTimeout(t, wg, time.Second*2) +} + func TestNotifierWithWebsockets_FinalizedEvents(t *testing.T) { cfg := integrationTests.GetDefaultConfigs() notifier, err := integrationTests.NewTestNotifierWithWS(cfg.MainConfig) From c3b7e1c2b6cb13bcbed63c16cdd0e3d4949788ee Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Thu, 27 Nov 2025 13:42:47 +0200 Subject: [PATCH 21/62] adapt stateAccesses for supernova --- data/block.go | 4 +- go.mod | 2 +- go.sum | 4 +- .../rabbitmq/testNotifierWithRabbitMQ_test.go | 8 ++- .../testNotifierWithWebsockets_test.go | 30 +++++++-- process/eventsInterceptor.go | 24 ++++--- process/eventsInterceptor_test.go | 24 ++++--- process/export_test.go | 4 +- process/preprocess/eventsPreProcessorV1.go | 4 +- testdata/testData.go | 63 ++++++++----------- 10 files changed, 96 insertions(+), 71 deletions(-) diff --git a/data/block.go b/data/block.go index 04f7717..52f14d5 100644 --- a/data/block.go +++ b/data/block.go @@ -46,8 +46,8 @@ type ArgsSaveBlockData struct { AlteredAccounts map[string]*alteredAccount.AlteredAccount NumberOfShards uint32 HeaderTimeStampMs uint64 - StateAccesses map[string]*stateChange.StateAccesses - Results map[string]*outport.ExecutionResultsData + StateAccesses map[string]*outport.StateAccessesForBlock + Results map[string]*outport.ExecutionResultData } // OutportBlockDataOld holds the block data that will be received on push events diff --git a/go.mod b/go.mod index 7f8ca78..e4dc4de 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.3 github.com/multiversx/mx-chain-communication-go v1.2.0 - github.com/multiversx/mx-chain-core-go v1.4.2-0.20251110143213-7437907451be + github.com/multiversx/mx-chain-core-go v1.4.2-0.20251127090701-d5c8e7bcab06 github.com/multiversx/mx-chain-logger-go v1.1.0 github.com/pelletier/go-toml v1.9.3 github.com/prometheus/client_model v0.6.1 diff --git a/go.sum b/go.sum index 65f6b0d..5fb1b75 100644 --- a/go.sum +++ b/go.sum @@ -130,8 +130,8 @@ github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/multiversx/mx-chain-communication-go v1.2.0 h1:0wOoLldiRbvaOPxwICbnRCqCpLqPewg8M/FMbC/0OXY= github.com/multiversx/mx-chain-communication-go v1.2.0/go.mod h1:wS3aAwkmHbC9mlzQdvL6p7l8Rqw3vmzhj7WZW1dTveA= -github.com/multiversx/mx-chain-core-go v1.4.2-0.20251110143213-7437907451be h1:xCDAuqyRR/4+Cs3XJQhPnxHuXoFfim5l4V0f/7CYtJc= -github.com/multiversx/mx-chain-core-go v1.4.2-0.20251110143213-7437907451be/go.mod h1:IO+vspNan+gT0WOHnJ95uvWygiziHZvfXpff6KnxV7g= +github.com/multiversx/mx-chain-core-go v1.4.2-0.20251127090701-d5c8e7bcab06 h1:8Ph6N2kLSun+hurIGios94ZgNwXFYgOcYuB+q4of6jA= +github.com/multiversx/mx-chain-core-go v1.4.2-0.20251127090701-d5c8e7bcab06/go.mod h1:IO+vspNan+gT0WOHnJ95uvWygiziHZvfXpff6KnxV7g= github.com/multiversx/mx-chain-crypto-go v1.2.13-0.20250218161752-9482d9a22234 h1:NNI7kYxzsq+4mTPSUJo0cK1+iPxjUX+gRJDaBRwEQ7M= github.com/multiversx/mx-chain-crypto-go v1.2.13-0.20250218161752-9482d9a22234/go.mod h1:QZAw2bZcOxGQRgYACTrmP8pfTa3NyxENIL+00G6nM5E= github.com/multiversx/mx-chain-logger-go v1.1.0 h1:97x84A6L4RfCa6YOx1HpAFxZp1cf/WI0Qh112whgZNM= diff --git a/integrationTests/rabbitmq/testNotifierWithRabbitMQ_test.go b/integrationTests/rabbitmq/testNotifierWithRabbitMQ_test.go index 4afcb41..5c707b8 100644 --- a/integrationTests/rabbitmq/testNotifierWithRabbitMQ_test.go +++ b/integrationTests/rabbitmq/testNotifierWithRabbitMQ_test.go @@ -58,7 +58,7 @@ func testNotifierWithRabbitMQ(t *testing.T, observerType string, payloadVersion go pushEventsRequest(wg, client) go pushRevertRequest(wg, client) - integrationTests.WaitTimeout(t, wg, time.Second*2) + integrationTests.WaitTimeout(t, wg, time.Second*5) assert.Equal(t, 3, len(notifier.RedisClient.GetEntries())) assert.Equal(t, 7, len(notifier.RabbitMQClient.GetEntries())) @@ -134,7 +134,11 @@ func pushEventsRequest(wg *sync.WaitGroup, webServer integrationTests.ObserverCo }, TransactionPool: txPool, HeaderGasConsumption: &outport.HeaderGasConsumption{}, - StateAccesses: stateAccesses, + StateAccessesForBlock: map[string]*outport.StateAccessesForBlock{ + hex.EncodeToString([]byte("headerHash1")): { + StateAccesses: stateAccesses, + }, + }, } err := webServer.PushEventsRequest(saveBlockData) diff --git a/integrationTests/websocket/testNotifierWithWebsockets_test.go b/integrationTests/websocket/testNotifierWithWebsockets_test.go index a28f14d..21d9787 100644 --- a/integrationTests/websocket/testNotifierWithWebsockets_test.go +++ b/integrationTests/websocket/testNotifierWithWebsockets_test.go @@ -104,7 +104,11 @@ func TestNotifierWithWebsockets_PushEvents(t *testing.T) { }, }, HeaderGasConsumption: &outport.HeaderGasConsumption{}, - StateAccesses: stateAccesses, + StateAccessesForBlock: map[string]*outport.StateAccessesForBlock{ + hex.EncodeToString([]byte("headerHash")): { + StateAccesses: stateAccesses, + }, + }, } wg := &sync.WaitGroup{} @@ -205,7 +209,11 @@ func TestNotifierWithWebsockets_BlockEvents(t *testing.T) { TimestampMs: 1234000, }, HeaderGasConsumption: &outport.HeaderGasConsumption{}, - StateAccesses: stateAccesses, + StateAccessesForBlock: map[string]*outport.StateAccessesForBlock{ + hex.EncodeToString(headerHash): { + StateAccesses: stateAccesses, + }, + }, } wg := &sync.WaitGroup{} @@ -397,7 +405,11 @@ func TestNotifierWithWebsockets_TxsEvents(t *testing.T) { }, }, HeaderGasConsumption: &outport.HeaderGasConsumption{}, - StateAccesses: stateAccesses, + StateAccessesForBlock: map[string]*outport.StateAccessesForBlock{ + hex.EncodeToString(blockHash): { + StateAccesses: stateAccesses, + }, + }, } expTxs := map[string]*transaction.Transaction{ @@ -485,7 +497,11 @@ func TestNotifierWithWebsockets_ScrsEvents(t *testing.T) { }, }, HeaderGasConsumption: &outport.HeaderGasConsumption{}, - StateAccesses: stateAccesses, + StateAccessesForBlock: map[string]*outport.StateAccessesForBlock{ + hex.EncodeToString(blockHash): { + StateAccesses: stateAccesses, + }, + }, } expScrs := map[string]*smartContractResult.SmartContractResult{ @@ -704,7 +720,11 @@ func testNotifierWithWebsockets_AllEvents(t *testing.T, observerType string) { TimestampMs: 1234000, }, HeaderGasConsumption: &outport.HeaderGasConsumption{}, - StateAccesses: stateAccesses, + StateAccessesForBlock: map[string]*outport.StateAccessesForBlock{ + hex.EncodeToString(blockHash): { + StateAccesses: stateAccesses, + }, + }, } numEvents := 6 diff --git a/process/eventsInterceptor.go b/process/eventsInterceptor.go index 037378a..a9f4e9b 100644 --- a/process/eventsInterceptor.go +++ b/process/eventsInterceptor.go @@ -75,7 +75,7 @@ func (ei *eventsInterceptor) ProcessBlockEvents(eventsData *data.ArgsSaveBlockDa events := ei.getLogEventsFromTransactionsPool(transactionsPool.Logs) - stateAccessesPerAccounts := ei.getStateAccessesPerAccounts(eventsData) + stateAccessesPerAccounts := ei.getStateAccessesPerAccounts(eventsData, hex.EncodeToString(eventsData.HeaderHash)) return &data.InterceptorBlockData{ Hash: hex.EncodeToString(eventsData.HeaderHash), @@ -120,8 +120,7 @@ func (ei *eventsInterceptor) ProcessBlockEventsV3(eventsData *data.ArgsSaveBlock events := ei.getLogEventsFromTransactionsPool(transactionsPool.GetLogs()) - // TODO: handle state accesses for header v3 - stateAccessesPerAccounts := ei.getStateAccessesPerAccounts(eventsData) + stateAccessesPerAccounts := ei.getStateAccessesPerAccounts(eventsData, headerHash) blockData := &data.InterceptorBlockData{ Hash: headerHash, @@ -192,24 +191,31 @@ func getTxsWithOrder(transactionsPool *outport.TransactionPool) []txWithOrder { return txsWithOrder } -func (ei *eventsInterceptor) getStateAccessesPerAccounts(eventsData *data.ArgsSaveBlockData) map[string]*stateChange.StateAccesses { +func (ei *eventsInterceptor) getStateAccessesPerAccounts(eventsData *data.ArgsSaveBlockData, headerHash string) map[string]*stateChange.StateAccesses { if eventsData.StateAccesses == nil { log.Warn("getStateAccessesPerAccounts failed: will return empty state accesses per accounts", - "block hash", eventsData.HeaderHash, + "block hash", headerHash, "error", ErrNilStateAccesses, ) return make(map[string]*stateChange.StateAccesses) } - stateAccessesPerTxs := eventsData.StateAccesses + stateAccessesPerAccounts := make(map[string]*stateChange.StateAccesses) + stateAccessesPerTxs, ok := eventsData.StateAccesses[headerHash] + if !ok { + log.Warn("getStateAccessesPerAccounts failed: will return empty state accesses per accounts", + "block hash", headerHash, + ) + return stateAccessesPerAccounts + } - logStateAccessesPerTxs(stateAccessesPerTxs) + stateAccesses := stateAccessesPerTxs.StateAccesses + logStateAccessesPerTxs(stateAccesses) // txs hashes with order txsWithOrder := getTxsWithOrder(eventsData.TransactionsPool) - stateAccessesPerAccounts := make(map[string]*stateChange.StateAccesses) for _, txInfo := range txsWithOrder { txHash, err := hex.DecodeString(txInfo.hash) if err != nil { @@ -217,7 +223,7 @@ func (ei *eventsInterceptor) getStateAccessesPerAccounts(eventsData *data.ArgsSa continue } - stateAccessesPerTx, ok := stateAccessesPerTxs[string(txHash)] + stateAccessesPerTx, ok := stateAccesses[string(txHash)] if !ok { log.Warn("did not find state accesses for tx", "txHash", txInfo.hash) continue diff --git a/process/eventsInterceptor_test.go b/process/eventsInterceptor_test.go index 94cbdd0..54f9f7e 100644 --- a/process/eventsInterceptor_test.go +++ b/process/eventsInterceptor_test.go @@ -170,7 +170,7 @@ func TestProcessBlockEvents_WithoutExecutionResults(t *testing.T) { SmartContractResults: scrs, Logs: logs, }, - StateAccesses: make(map[string]*stateChange.StateAccesses), + StateAccesses: make(map[string]*outport.StateAccessesForBlock), } expTxs := map[string]*transaction.Transaction{ @@ -265,7 +265,7 @@ func TestProcessBlockEvents_WithoutExecutionResults(t *testing.T) { TransactionsPool: &outport.TransactionPool{ Logs: logs, }, - StateAccesses: make(map[string]*stateChange.StateAccesses), + StateAccesses: make(map[string]*outport.StateAccessesForBlock), } expEvents := &data.InterceptorBlockData{ @@ -354,7 +354,7 @@ func TestProcessBlockEvents_WithExecutionResults(t *testing.T) { blockHash := []byte("blockHash") - execResults := map[string]*outport.ExecutionResultsData{ + execResults := map[string]*outport.ExecutionResultData{ hex.EncodeToString(blockHash): { Body: blockBody, TransactionPool: execTxPool, @@ -366,7 +366,7 @@ func TestProcessBlockEvents_WithExecutionResults(t *testing.T) { Body: blockBody, Header: blockHeader, TransactionsPool: proposedTxPool, - StateAccesses: make(map[string]*stateChange.StateAccesses), + StateAccesses: make(map[string]*outport.StateAccessesForBlock), Results: execResults, } @@ -464,7 +464,7 @@ func TestProcessBlockEvents_WithExecutionResults(t *testing.T) { blockHash := []byte("blockHash") - execResults := map[string]*outport.ExecutionResultsData{ + execResults := map[string]*outport.ExecutionResultData{ hex.EncodeToString(blockHash): { Body: blockBody, TransactionPool: execTxPool, @@ -476,7 +476,7 @@ func TestProcessBlockEvents_WithExecutionResults(t *testing.T) { Body: blockBody, Header: blockHeader, TransactionsPool: proposedTxPool, - StateAccesses: make(map[string]*stateChange.StateAccesses), + StateAccesses: make(map[string]*outport.StateAccessesForBlock), Results: execResults, } @@ -636,7 +636,9 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { SmartContractResults: scrs, InvalidTxs: invalidTxs, }, - StateAccesses: stateAccesses, + StateAccesses: map[string]*outport.StateAccessesForBlock{ + hex.EncodeToString(blockHash): {stateAccesses}, + }, } expStateAccessesPerAccounts := make(map[string]*stateChange.StateAccesses) @@ -719,7 +721,9 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { SmartContractResults: scrs, InvalidTxs: invalidTxs, }, - StateAccesses: stateAccesses, + StateAccesses: map[string]*outport.StateAccessesForBlock{ + hex.EncodeToString(blockHash): {stateAccesses}, + }, } expStateAccessesPerAccounts := make(map[string]*stateChange.StateAccesses) @@ -770,7 +774,9 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { SmartContractResults: scrs, InvalidTxs: invalidTxs, }, - StateAccesses: stateAccesses, + StateAccesses: map[string]*outport.StateAccessesForBlock{ + hex.EncodeToString(blockHash): {stateAccesses}, + }, } expStateAccessesPerAccounts := make(map[string]*stateChange.StateAccesses) diff --git a/process/export_test.go b/process/export_test.go index e57075a..c0c424d 100644 --- a/process/export_test.go +++ b/process/export_test.go @@ -1,6 +1,8 @@ package process import ( + "encoding/hex" + "github.com/multiversx/mx-chain-core-go/data/outport" "github.com/multiversx/mx-chain-core-go/data/stateChange" "github.com/multiversx/mx-chain-notifier-go/data" @@ -43,7 +45,7 @@ func (ei *eventsInterceptor) GetLogEventsFromTransactionsPool(logs []*outport.Lo // GetStateAccessesPerAccounts - func (ei *eventsInterceptor) GetStateAccessesPerAccounts(eventsData *data.ArgsSaveBlockData) map[string]*stateChange.StateAccesses { - return ei.getStateAccessesPerAccounts(eventsData) + return ei.getStateAccessesPerAccounts(eventsData, hex.EncodeToString(eventsData.HeaderHash)) } // BaseNilEventsDataCheks - diff --git a/process/preprocess/eventsPreProcessorV1.go b/process/preprocess/eventsPreProcessorV1.go index a48cfa4..f92d862 100644 --- a/process/preprocess/eventsPreProcessorV1.go +++ b/process/preprocess/eventsPreProcessorV1.go @@ -56,7 +56,7 @@ func (d *eventsPreProcessorV1) SaveBlock(marshalledData []byte) error { return err } - var executionResults map[string]*outport.ExecutionResultsData + var executionResults map[string]*outport.ExecutionResultData if header.IsHeaderV3() { executionResults = outportBlock.BlockData.Results } @@ -72,7 +72,7 @@ func (d *eventsPreProcessorV1) SaveBlock(marshalledData []byte) error { TransactionsPool: outportBlock.TransactionPool, Header: header, HeaderTimeStampMs: outportBlock.BlockData.GetTimestampMs(), - StateAccesses: outportBlock.GetStateAccesses(), + StateAccesses: outportBlock.GetStateAccessesForBlock(), Results: executionResults, } diff --git a/testdata/testData.go b/testdata/testData.go index 758de24..653385f 100644 --- a/testdata/testData.go +++ b/testdata/testData.go @@ -117,33 +117,14 @@ func (bd *blockData) OutportBlockV1() *outport.OutportBlock { TimeStamp: 1234, } headerBytes, _ := bd.marshaller.Marshal(header) - - stateAccesses := make(map[string]*stateChange.StateAccesses) - stateAccesses["txHash1"] = &stateChange.StateAccesses{ - StateAccess: []*stateChange.StateAccess{ - &stateChange.StateAccess{ - Type: stateChange.Write, - MainTrieKey: []byte("mainTrieKey1"), - MainTrieVal: []byte("mainTrieVal1"), - TxHash: []byte("txHash1"), - AccountChanges: 8, - }, - &stateChange.StateAccess{ - Type: stateChange.Write, - MainTrieKey: []byte("mainTrieKey2"), - MainTrieVal: []byte("mainTrieVal2"), - TxHash: []byte("txHash1"), - AccountChanges: 4, - }, - }, - } - stateAccesses["txHash2"] = &stateChange.StateAccesses{} + headerHash := []byte("headerHash1") + stateAccessesForBlock := getStateAccessesForBlock(headerHash) return &outport.OutportBlock{ BlockData: &outport.BlockData{ HeaderBytes: headerBytes, HeaderType: "Header", - HeaderHash: []byte("headerHash1"), + HeaderHash: headerHash, Body: &block.Body{ MiniBlocks: []*block.MiniBlock{ { @@ -193,21 +174,12 @@ func (bd *blockData) OutportBlockV1() *outport.OutportBlock { }, }, }, - StateAccesses: stateAccesses, - NumberOfShards: 2, + StateAccessesForBlock: stateAccessesForBlock, + NumberOfShards: 2, } } -// OutportBlockV2 - -func (bd *blockData) OutportBlockV2() *outport.OutportBlock { - header := &block.HeaderV3{ - ShardID: 1, - TimestampMs: 1234, - } - headerBytes, _ := bd.marshaller.Marshal(header) - - execBlockHash := []byte("execBlockHash1") - +func getStateAccessesForBlock(headerHash []byte) map[string]*outport.StateAccessesForBlock { stateAccesses := make(map[string]*stateChange.StateAccesses) stateAccesses["txHash1"] = &stateChange.StateAccesses{ StateAccess: []*stateChange.StateAccess{ @@ -228,6 +200,21 @@ func (bd *blockData) OutportBlockV2() *outport.OutportBlock { }, } stateAccesses["txHash2"] = &stateChange.StateAccesses{} + stateAccessesForBlock := map[string]*outport.StateAccessesForBlock{} + stateAccessesForBlock[hex.EncodeToString(headerHash)] = &outport.StateAccessesForBlock{StateAccesses: stateAccesses} + return stateAccessesForBlock +} + +// OutportBlockV2 - +func (bd *blockData) OutportBlockV2() *outport.OutportBlock { + header := &block.HeaderV3{ + ShardID: 1, + TimestampMs: 1234, + } + headerBytes, _ := bd.marshaller.Marshal(header) + + execBlockHash := []byte("execBlockHash1") + stateAccessesForBlock := getStateAccessesForBlock(execBlockHash) blockBody := &block.Body{ MiniBlocks: []*block.MiniBlock{ @@ -278,7 +265,7 @@ func (bd *blockData) OutportBlockV2() *outport.OutportBlock { }, } - execResults := map[string]*outport.ExecutionResultsData{ + execResults := map[string]*outport.ExecutionResultData{ hex.EncodeToString(execBlockHash): { Body: blockBody, TransactionPool: execResTxPool, @@ -301,9 +288,9 @@ func (bd *blockData) OutportBlockV2() *outport.OutportBlock { }, Results: execResults, }, - HeaderGasConsumption: &outport.HeaderGasConsumption{}, - NumberOfShards: 2, - StateAccesses: stateAccesses, + HeaderGasConsumption: &outport.HeaderGasConsumption{}, + NumberOfShards: 2, + StateAccessesForBlock: stateAccessesForBlock, } } From 7df98147a0d3de16b503328c00b5a9e584007dab Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Thu, 27 Nov 2025 15:03:24 +0200 Subject: [PATCH 22/62] fix after merge --- .../rabbitmq/testNotifierWithRabbitMQ_test.go | 2 +- process/eventsInterceptor.go | 12 ++++++++---- process/export_test.go | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/integrationTests/rabbitmq/testNotifierWithRabbitMQ_test.go b/integrationTests/rabbitmq/testNotifierWithRabbitMQ_test.go index 0305119..6fd179a 100644 --- a/integrationTests/rabbitmq/testNotifierWithRabbitMQ_test.go +++ b/integrationTests/rabbitmq/testNotifierWithRabbitMQ_test.go @@ -113,7 +113,7 @@ func testNotifierWithRabbitMQV3(t *testing.T, observerType string, payloadVersio go pushEventsRequestV3(wg, client) go pushRevertRequestV3(wg, client) - integrationTests.WaitTimeout(t, wg, time.Second*2) + integrationTests.WaitTimeout(t, wg, time.Second*5) assert.Equal(t, numExpRedisEvents, len(notifier.RedisClient.GetEntries())) assert.Equal(t, numExpRabbitMQEvents, len(notifier.RabbitMQClient.GetEntries())) diff --git a/process/eventsInterceptor.go b/process/eventsInterceptor.go index a9f4e9b..8c1fb49 100644 --- a/process/eventsInterceptor.go +++ b/process/eventsInterceptor.go @@ -75,7 +75,7 @@ func (ei *eventsInterceptor) ProcessBlockEvents(eventsData *data.ArgsSaveBlockDa events := ei.getLogEventsFromTransactionsPool(transactionsPool.Logs) - stateAccessesPerAccounts := ei.getStateAccessesPerAccounts(eventsData, hex.EncodeToString(eventsData.HeaderHash)) + stateAccessesPerAccounts := ei.getStateAccessesPerAccounts(eventsData, hex.EncodeToString(eventsData.HeaderHash), transactionsPool) return &data.InterceptorBlockData{ Hash: hex.EncodeToString(eventsData.HeaderHash), @@ -120,7 +120,7 @@ func (ei *eventsInterceptor) ProcessBlockEventsV3(eventsData *data.ArgsSaveBlock events := ei.getLogEventsFromTransactionsPool(transactionsPool.GetLogs()) - stateAccessesPerAccounts := ei.getStateAccessesPerAccounts(eventsData, headerHash) + stateAccessesPerAccounts := ei.getStateAccessesPerAccounts(eventsData, headerHash, transactionsPool) blockData := &data.InterceptorBlockData{ Hash: headerHash, @@ -191,7 +191,11 @@ func getTxsWithOrder(transactionsPool *outport.TransactionPool) []txWithOrder { return txsWithOrder } -func (ei *eventsInterceptor) getStateAccessesPerAccounts(eventsData *data.ArgsSaveBlockData, headerHash string) map[string]*stateChange.StateAccesses { +func (ei *eventsInterceptor) getStateAccessesPerAccounts( + eventsData *data.ArgsSaveBlockData, + headerHash string, + transactionPool *outport.TransactionPool, +) map[string]*stateChange.StateAccesses { if eventsData.StateAccesses == nil { log.Warn("getStateAccessesPerAccounts failed: will return empty state accesses per accounts", "block hash", headerHash, @@ -214,7 +218,7 @@ func (ei *eventsInterceptor) getStateAccessesPerAccounts(eventsData *data.ArgsSa logStateAccessesPerTxs(stateAccesses) // txs hashes with order - txsWithOrder := getTxsWithOrder(eventsData.TransactionsPool) + txsWithOrder := getTxsWithOrder(transactionPool) for _, txInfo := range txsWithOrder { txHash, err := hex.DecodeString(txInfo.hash) diff --git a/process/export_test.go b/process/export_test.go index c0c424d..d83a089 100644 --- a/process/export_test.go +++ b/process/export_test.go @@ -45,7 +45,7 @@ func (ei *eventsInterceptor) GetLogEventsFromTransactionsPool(logs []*outport.Lo // GetStateAccessesPerAccounts - func (ei *eventsInterceptor) GetStateAccessesPerAccounts(eventsData *data.ArgsSaveBlockData) map[string]*stateChange.StateAccesses { - return ei.getStateAccessesPerAccounts(eventsData, hex.EncodeToString(eventsData.HeaderHash)) + return ei.getStateAccessesPerAccounts(eventsData, hex.EncodeToString(eventsData.HeaderHash), eventsData.TransactionsPool) } // BaseNilEventsDataCheks - From fb6626aa395de462a3882400c10bc9c67ffbab83 Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Thu, 4 Dec 2025 13:47:01 +0200 Subject: [PATCH 23/62] fix after merge --- process/eventsHandler_test.go | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/process/eventsHandler_test.go b/process/eventsHandler_test.go index 5430376..4d589e6 100644 --- a/process/eventsHandler_test.go +++ b/process/eventsHandler_test.go @@ -221,12 +221,12 @@ func TestHandleSaveBlockEvents_ShouldWork(t *testing.T) { stateAccesses := make(map[string]*stateChange.StateAccesses) stateAccesses["txHash1"] = &stateChange.StateAccesses{ StateAccess: []*stateChange.StateAccess{ - &stateChange.StateAccess{ + { Type: stateChange.Write, MainTrieKey: []byte("mainTrieKey1"), MainTrieVal: []byte("mainTrieVal1"), }, - &stateChange.StateAccess{ + { Type: stateChange.Write, MainTrieKey: []byte("mainTrieKey2"), MainTrieVal: []byte("mainTrieVal2"), @@ -288,7 +288,7 @@ func TestHandleSaveBlockEvents_ShouldWork(t *testing.T) { expStateAccessesPerAccounts := make(map[string]*stateChange.StateAccesses) expStateAccessesPerAccounts[hex.EncodeToString([]byte("mainTrieKey1"))] = &stateChange.StateAccesses{ StateAccess: []*stateChange.StateAccess{ - &stateChange.StateAccess{ + { Type: stateChange.Write, MainTrieKey: []byte("mainTrieKey1"), MainTrieVal: []byte("mainTrieVal1"), @@ -297,7 +297,7 @@ func TestHandleSaveBlockEvents_ShouldWork(t *testing.T) { } expStateAccessesPerAccounts[hex.EncodeToString([]byte("mainTrieKey2"))] = &stateChange.StateAccesses{ StateAccess: []*stateChange.StateAccess{ - &stateChange.StateAccess{ + { Type: stateChange.Write, MainTrieKey: []byte("mainTrieKey2"), MainTrieVal: []byte("mainTrieVal2"), @@ -387,6 +387,7 @@ func TestHandleSaveBlockEvents_ShouldWork(t *testing.T) { assert.True(t, txsWasCalled) assert.True(t, scrsWasCalled) assert.True(t, blockEventsWithOrderWasCalled) + assert.True(t, stateAccessesWasCalled) }) t.Run("should work with header v3", func(t *testing.T) { @@ -400,6 +401,7 @@ func TestHandleSaveBlockEvents_ShouldWork(t *testing.T) { txsWasCalled := false scrsWasCalled := false blockEventsWithOrderWasCalled := false + stateAccessesWasCalled := false args := createMockEventsHandlerArgs() @@ -411,13 +413,14 @@ func TestHandleSaveBlockEvents_ShouldWork(t *testing.T) { ProcessBlockEventsV3Called: func(eventsData *data.ArgsSaveBlockData) ([]*data.InterceptorBlockData, error) { return []*data.InterceptorBlockData{ { - Hash: blockHash, - Header: header, - Txs: expTxs, - Scrs: expScrs, - LogEvents: logEvents, - TxsWithOrder: expTxsWithOrder, - ScrsWithOrder: expScrsWithOrder, + Hash: blockHash, + Header: header, + Txs: expTxs, + Scrs: expScrs, + LogEvents: logEvents, + TxsWithOrder: expTxsWithOrder, + ScrsWithOrder: expScrsWithOrder, + StateAccessesPerAccounts: expStateAccessesPerAccounts, }, }, nil }, @@ -440,6 +443,10 @@ func TestHandleSaveBlockEvents_ShouldWork(t *testing.T) { blockEventsWithOrderWasCalled = true assert.Equal(t, expTxsWithOrderData, event) }, + BroadcastStateAccessesCalled: func(event data.BlockStateAccesses) { + stateAccessesWasCalled = true + assert.Equal(t, expStateAccesses, event) + }, } eventsHandler, err := process.NewEventsHandler(args) From fca6452f34b68b4c0cd6b9232523f953f9be78c2 Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Thu, 4 Dec 2025 15:28:48 +0200 Subject: [PATCH 24/62] update for headerV3 --- data/block.go | 1 + go.mod | 2 +- go.sum | 4 ++-- process/eventsHandler.go | 18 ++++++++++++------ process/eventsHandler_test.go | 5 +++-- process/eventsInterceptor.go | 1 + 6 files changed, 20 insertions(+), 11 deletions(-) diff --git a/data/block.go b/data/block.go index 52f14d5..9e3561f 100644 --- a/data/block.go +++ b/data/block.go @@ -32,6 +32,7 @@ type InterceptorBlockData struct { ScrsWithOrder map[string]*outport.SCRInfo LogEvents []Event StateAccessesPerAccounts map[string]*stateChange.StateAccesses + RootHash []byte } // ArgsSaveBlockData holds the block data that will be received on push events diff --git a/go.mod b/go.mod index e4dc4de..b73c686 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.3 github.com/multiversx/mx-chain-communication-go v1.2.0 - github.com/multiversx/mx-chain-core-go v1.4.2-0.20251127090701-d5c8e7bcab06 + github.com/multiversx/mx-chain-core-go v1.4.2-0.20251204131317-59c120f3519a github.com/multiversx/mx-chain-logger-go v1.1.0 github.com/pelletier/go-toml v1.9.3 github.com/prometheus/client_model v0.6.1 diff --git a/go.sum b/go.sum index 5fb1b75..f036303 100644 --- a/go.sum +++ b/go.sum @@ -130,8 +130,8 @@ github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/multiversx/mx-chain-communication-go v1.2.0 h1:0wOoLldiRbvaOPxwICbnRCqCpLqPewg8M/FMbC/0OXY= github.com/multiversx/mx-chain-communication-go v1.2.0/go.mod h1:wS3aAwkmHbC9mlzQdvL6p7l8Rqw3vmzhj7WZW1dTveA= -github.com/multiversx/mx-chain-core-go v1.4.2-0.20251127090701-d5c8e7bcab06 h1:8Ph6N2kLSun+hurIGios94ZgNwXFYgOcYuB+q4of6jA= -github.com/multiversx/mx-chain-core-go v1.4.2-0.20251127090701-d5c8e7bcab06/go.mod h1:IO+vspNan+gT0WOHnJ95uvWygiziHZvfXpff6KnxV7g= +github.com/multiversx/mx-chain-core-go v1.4.2-0.20251204131317-59c120f3519a h1:/6mA7LPJCloOkRic9f/BJIUTI3yRsaQKwiFsLU1VWV8= +github.com/multiversx/mx-chain-core-go v1.4.2-0.20251204131317-59c120f3519a/go.mod h1:IO+vspNan+gT0WOHnJ95uvWygiziHZvfXpff6KnxV7g= github.com/multiversx/mx-chain-crypto-go v1.2.13-0.20250218161752-9482d9a22234 h1:NNI7kYxzsq+4mTPSUJo0cK1+iPxjUX+gRJDaBRwEQ7M= github.com/multiversx/mx-chain-crypto-go v1.2.13-0.20250218161752-9482d9a22234/go.mod h1:QZAw2bZcOxGQRgYACTrmP8pfTa3NyxENIL+00G6nM5E= github.com/multiversx/mx-chain-logger-go v1.1.0 h1:97x84A6L4RfCa6YOx1HpAFxZp1cf/WI0Qh112whgZNM= diff --git a/process/eventsHandler.go b/process/eventsHandler.go index 4f97c7c..61bb825 100644 --- a/process/eventsHandler.go +++ b/process/eventsHandler.go @@ -105,12 +105,19 @@ func (eh *eventsHandler) handleSaveBlockEventsLegacy(allEvents data.ArgsSaveBloc shardID := eventsData.Header.GetShardID() nonce := eventsData.Header.GetNonce() + var scheduledRootHash []byte + if eventsData.Header.GetAdditionalData() != nil { + scheduledRootHash = allEvents.Header.GetAdditionalData().GetScheduledRootHash() + } + return eh.handleSaveBlockEvents( eventsData, headerTimeStamp, headerTimeStampMs, shardID, nonce, + allEvents.Header.GetRootHash(), + scheduledRootHash, ) } @@ -120,6 +127,8 @@ func (eh *eventsHandler) handleSaveBlockEvents( headerTimeStampMs uint64, shardID uint32, nonce uint64, + rootHash []byte, + scheduledRootHash []byte, ) error { if eventsData == nil { return ErrNilEventsInterceptor @@ -163,17 +172,12 @@ func (eh *eventsHandler) handleSaveBlockEvents( } eh.handleBlockEventsWithOrder(txsWithOrder) - var scheduledRootHash []byte - if eventsData.Header.GetAdditionalData() != nil { - scheduledRootHash = eventsData.Header.GetAdditionalData().GetScheduledRootHash() - } - stateAccesses := data.BlockStateAccesses{ Hash: eventsData.Hash, ShardID: shardID, TimeStampMs: headerTimeStampMs, Nonce: nonce, - RootHash: eventsData.Header.GetRootHash(), + RootHash: rootHash, ScheduledRootHash: scheduledRootHash, StateAccessesPerAccounts: eventsData.StateAccessesPerAccounts, } @@ -201,6 +205,8 @@ func (eh *eventsHandler) handleSaveBlockEventsV3(allEvents data.ArgsSaveBlockDat headerTimeStampMs, shardID, nonce, + executionResultData.RootHash, + nil, ) if err != nil { return err diff --git a/process/eventsHandler_test.go b/process/eventsHandler_test.go index 4d589e6..8b67d1d 100644 --- a/process/eventsHandler_test.go +++ b/process/eventsHandler_test.go @@ -307,7 +307,6 @@ func TestHandleSaveBlockEvents_ShouldWork(t *testing.T) { expStateAccesses := data.BlockStateAccesses{ Hash: blockHash, ShardID: 2, - TimeStampMs: 1234, RootHash: rootHash, StateAccessesPerAccounts: expStateAccessesPerAccounts, } @@ -317,7 +316,8 @@ func TestHandleSaveBlockEvents_ShouldWork(t *testing.T) { header := &block.HeaderV2{ Header: &block.Header{ - ShardID: 2, + ShardID: 2, + RootHash: rootHash, }, } @@ -421,6 +421,7 @@ func TestHandleSaveBlockEvents_ShouldWork(t *testing.T) { TxsWithOrder: expTxsWithOrder, ScrsWithOrder: expScrsWithOrder, StateAccessesPerAccounts: expStateAccessesPerAccounts, + RootHash: rootHash, }, }, nil }, diff --git a/process/eventsInterceptor.go b/process/eventsInterceptor.go index af391d6..92a62f6 100644 --- a/process/eventsInterceptor.go +++ b/process/eventsInterceptor.go @@ -133,6 +133,7 @@ func (ei *eventsInterceptor) ProcessBlockEventsV3(eventsData *data.ArgsSaveBlock ScrsWithOrder: transactionsPool.GetSmartContractResults(), LogEvents: events, StateAccessesPerAccounts: stateAccessesPerAccounts, + RootHash: execBlockData.GetRootHash(), } execBlocksData = append(execBlocksData, blockData) From dff0aca51495bca21b0e0240d565c24e30c8b8f0 Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Thu, 11 Dec 2025 11:28:04 +0200 Subject: [PATCH 25/62] add nonce from execResult --- data/block.go | 1 + process/eventsHandler.go | 6 ++++-- process/eventsInterceptor.go | 9 +++++++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/data/block.go b/data/block.go index 9e3561f..3dc30fa 100644 --- a/data/block.go +++ b/data/block.go @@ -33,6 +33,7 @@ type InterceptorBlockData struct { LogEvents []Event StateAccessesPerAccounts map[string]*stateChange.StateAccesses RootHash []byte + Nonce uint64 } // ArgsSaveBlockData holds the block data that will be received on push events diff --git a/process/eventsHandler.go b/process/eventsHandler.go index 61bb825..2293e4e 100644 --- a/process/eventsHandler.go +++ b/process/eventsHandler.go @@ -196,7 +196,6 @@ func (eh *eventsHandler) handleSaveBlockEventsV3(allEvents data.ArgsSaveBlockDat headerTimeStamp := allEvents.Header.GetTimeStamp() headerTimeStampMs := allEvents.HeaderTimeStampMs shardID := allEvents.Header.GetShardID() - nonce := allEvents.Header.GetNonce() for _, executionResultData := range executionResultsData { err = eh.handleSaveBlockEvents( @@ -204,7 +203,7 @@ func (eh *eventsHandler) handleSaveBlockEventsV3(allEvents data.ArgsSaveBlockDat headerTimeStamp, headerTimeStampMs, shardID, - nonce, + executionResultData.Nonce, executionResultData.RootHash, nil, ) @@ -399,6 +398,9 @@ func (eh *eventsHandler) handleStateAccesses(stateAccesses data.BlockStateAccess log.Info("received state accesses", "block hash", stateAccesses.Hash, + "nonce", stateAccesses.Nonce, + "rootHash", stateAccesses.RootHash, + "stateAccesesPerAccounts num", len(stateAccesses.StateAccessesPerAccounts), ) t := time.Now() diff --git a/process/eventsInterceptor.go b/process/eventsInterceptor.go index 92a62f6..8875314 100644 --- a/process/eventsInterceptor.go +++ b/process/eventsInterceptor.go @@ -134,6 +134,7 @@ func (ei *eventsInterceptor) ProcessBlockEventsV3(eventsData *data.ArgsSaveBlock LogEvents: events, StateAccessesPerAccounts: stateAccessesPerAccounts, RootHash: execBlockData.GetRootHash(), + Nonce: execBlockData.GetHeaderNonce(), } execBlocksData = append(execBlocksData, blockData) @@ -216,6 +217,14 @@ func (ei *eventsInterceptor) getStateAccessesPerAccounts( return stateAccessesPerAccounts } + if stateAccessesPerTxs == nil { + log.Warn("stateAccessesPerTxs failed: will return empty state accesses per accounts", + "block hash", headerHash, + "num state accesses", len(eventsData.StateAccesses), + ) + return stateAccessesPerAccounts + } + stateAccesses := stateAccessesPerTxs.StateAccesses logStateAccessesPerTxs(stateAccesses) From 22c363de73b732f7e6bc141f315adfc4943b2134 Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Thu, 11 Dec 2025 11:35:38 +0200 Subject: [PATCH 26/62] fix nonce for stateAccesses --- data/block.go | 1 + process/eventsHandler.go | 5 +++-- process/eventsInterceptor.go | 9 +++++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/data/block.go b/data/block.go index 52f14d5..f9762d0 100644 --- a/data/block.go +++ b/data/block.go @@ -32,6 +32,7 @@ type InterceptorBlockData struct { ScrsWithOrder map[string]*outport.SCRInfo LogEvents []Event StateAccessesPerAccounts map[string]*stateChange.StateAccesses + Nonce uint64 } // ArgsSaveBlockData holds the block data that will be received on push events diff --git a/process/eventsHandler.go b/process/eventsHandler.go index d444ca2..bfad2aa 100644 --- a/process/eventsHandler.go +++ b/process/eventsHandler.go @@ -185,7 +185,6 @@ func (eh *eventsHandler) handleSaveBlockEventsV3(allEvents data.ArgsSaveBlockDat headerTimeStamp := allEvents.Header.GetTimeStamp() headerTimeStampMs := allEvents.HeaderTimeStampMs shardID := allEvents.Header.GetShardID() - nonce := allEvents.Header.GetNonce() for _, executionResultData := range executionResultsData { err = eh.handleSaveBlockEvents( @@ -193,7 +192,7 @@ func (eh *eventsHandler) handleSaveBlockEventsV3(allEvents data.ArgsSaveBlockDat headerTimeStamp, headerTimeStampMs, shardID, - nonce, + executionResultData.Nonce, ) if err != nil { return err @@ -386,6 +385,8 @@ func (eh *eventsHandler) handleStateAccesses(stateAccesses data.BlockStateAccess log.Info("received state accesses", "block hash", stateAccesses.Hash, + "nonce", stateAccesses.Nonce, + "stateAccesesPerAccounts num", len(stateAccesses.StateAccessesPerAccounts), ) t := time.Now() diff --git a/process/eventsInterceptor.go b/process/eventsInterceptor.go index 8c1fb49..43eafc8 100644 --- a/process/eventsInterceptor.go +++ b/process/eventsInterceptor.go @@ -132,6 +132,7 @@ func (ei *eventsInterceptor) ProcessBlockEventsV3(eventsData *data.ArgsSaveBlock ScrsWithOrder: transactionsPool.GetSmartContractResults(), LogEvents: events, StateAccessesPerAccounts: stateAccessesPerAccounts, + Nonce: execBlockData.GetHeaderNonce(), } execBlocksData = append(execBlocksData, blockData) @@ -214,6 +215,14 @@ func (ei *eventsInterceptor) getStateAccessesPerAccounts( return stateAccessesPerAccounts } + if stateAccessesPerTxs == nil { + log.Warn("stateAccessesPerTxs failed: will return empty state accesses per accounts", + "block hash", headerHash, + "num state accesses", len(eventsData.StateAccesses), + ) + return stateAccessesPerAccounts + } + stateAccesses := stateAccessesPerTxs.StateAccesses logStateAccessesPerTxs(stateAccesses) From f4919cdbeae6a9c0bc33eb349965c7942ddb89c8 Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Tue, 16 Dec 2025 14:44:24 +0200 Subject: [PATCH 27/62] update go mod --- api/groups/eventsGroup_test.go | 2 +- go.mod | 2 +- go.sum | 4 ++-- .../rabbitmq/testNotifierWithRabbitMQ_test.go | 2 +- .../websocket/testNotifierWithWebsockets_test.go | 6 +++--- process/eventsHandler_test.go | 2 +- process/eventsInterceptor.go | 2 +- process/eventsInterceptor_test.go | 10 +++++----- process/export_test.go | 4 ++-- process/preprocess/eventsPreProcessorV0.go | 7 ++++--- process/preprocess/eventsPreProcessorV1_test.go | 2 +- testdata/testData.go | 4 ++-- 12 files changed, 24 insertions(+), 23 deletions(-) diff --git a/api/groups/eventsGroup_test.go b/api/groups/eventsGroup_test.go index 32c17a4..5cfc5c4 100644 --- a/api/groups/eventsGroup_test.go +++ b/api/groups/eventsGroup_test.go @@ -190,7 +190,7 @@ func TestEventsGroup_PushEvents(t *testing.T) { ExecutionOrder: 1, }, }, - Logs: []*outport.LogData{ + Logs: []*transaction.LogData{ { Log: &transaction.Log{ Address: []byte("logaddr1"), diff --git a/go.mod b/go.mod index e4dc4de..d721ad6 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.3 github.com/multiversx/mx-chain-communication-go v1.2.0 - github.com/multiversx/mx-chain-core-go v1.4.2-0.20251127090701-d5c8e7bcab06 + github.com/multiversx/mx-chain-core-go v1.4.2-0.20251216121256-1d518f1eb139 github.com/multiversx/mx-chain-logger-go v1.1.0 github.com/pelletier/go-toml v1.9.3 github.com/prometheus/client_model v0.6.1 diff --git a/go.sum b/go.sum index 5fb1b75..e943d43 100644 --- a/go.sum +++ b/go.sum @@ -130,8 +130,8 @@ github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/multiversx/mx-chain-communication-go v1.2.0 h1:0wOoLldiRbvaOPxwICbnRCqCpLqPewg8M/FMbC/0OXY= github.com/multiversx/mx-chain-communication-go v1.2.0/go.mod h1:wS3aAwkmHbC9mlzQdvL6p7l8Rqw3vmzhj7WZW1dTveA= -github.com/multiversx/mx-chain-core-go v1.4.2-0.20251127090701-d5c8e7bcab06 h1:8Ph6N2kLSun+hurIGios94ZgNwXFYgOcYuB+q4of6jA= -github.com/multiversx/mx-chain-core-go v1.4.2-0.20251127090701-d5c8e7bcab06/go.mod h1:IO+vspNan+gT0WOHnJ95uvWygiziHZvfXpff6KnxV7g= +github.com/multiversx/mx-chain-core-go v1.4.2-0.20251216121256-1d518f1eb139 h1:YACeQwdcDDmgIxD9x6nBSpv4yRyk7s9ZnmDGDSLJA+8= +github.com/multiversx/mx-chain-core-go v1.4.2-0.20251216121256-1d518f1eb139/go.mod h1:IO+vspNan+gT0WOHnJ95uvWygiziHZvfXpff6KnxV7g= github.com/multiversx/mx-chain-crypto-go v1.2.13-0.20250218161752-9482d9a22234 h1:NNI7kYxzsq+4mTPSUJo0cK1+iPxjUX+gRJDaBRwEQ7M= github.com/multiversx/mx-chain-crypto-go v1.2.13-0.20250218161752-9482d9a22234/go.mod h1:QZAw2bZcOxGQRgYACTrmP8pfTa3NyxENIL+00G6nM5E= github.com/multiversx/mx-chain-logger-go v1.1.0 h1:97x84A6L4RfCa6YOx1HpAFxZp1cf/WI0Qh112whgZNM= diff --git a/integrationTests/rabbitmq/testNotifierWithRabbitMQ_test.go b/integrationTests/rabbitmq/testNotifierWithRabbitMQ_test.go index 6fd179a..2855efa 100644 --- a/integrationTests/rabbitmq/testNotifierWithRabbitMQ_test.go +++ b/integrationTests/rabbitmq/testNotifierWithRabbitMQ_test.go @@ -150,7 +150,7 @@ func pushEventsRequest(wg *sync.WaitGroup, webServer integrationTests.ObserverCo ExecutionOrder: 3, }, }, - Logs: []*outport.LogData{ + Logs: []*transaction.LogData{ { Log: &transaction.Log{ Address: []byte("logaddr1"), diff --git a/integrationTests/websocket/testNotifierWithWebsockets_test.go b/integrationTests/websocket/testNotifierWithWebsockets_test.go index c999016..b51ead0 100644 --- a/integrationTests/websocket/testNotifierWithWebsockets_test.go +++ b/integrationTests/websocket/testNotifierWithWebsockets_test.go @@ -82,7 +82,7 @@ func TestNotifierWithWebsockets_PushEvents(t *testing.T) { saveBlockData := &outport.OutportBlock{ TransactionPool: &outport.TransactionPool{ - Logs: []*outport.LogData{ + Logs: []*transaction.LogData{ { Log: &transaction.Log{ Events: []*transaction.Event{ @@ -246,7 +246,7 @@ func TestNotifierWithWebsockets_BlockEvents(t *testing.T) { saveBlockData := &outport.OutportBlock{ TransactionPool: &outport.TransactionPool{ - Logs: []*outport.LogData{ + Logs: []*transaction.LogData{ { Log: &transaction.Log{ Events: []*transaction.Event{ @@ -815,7 +815,7 @@ func testNotifierWithWebsockets_AllEvents(t *testing.T, observerType string) { TransactionPool: &outport.TransactionPool{ Transactions: txs, SmartContractResults: scrs, - Logs: []*outport.LogData{ + Logs: []*transaction.LogData{ { Log: &transaction.Log{ Events: []*transaction.Event{ diff --git a/process/eventsHandler_test.go b/process/eventsHandler_test.go index 610d57a..73f0ffc 100644 --- a/process/eventsHandler_test.go +++ b/process/eventsHandler_test.go @@ -200,7 +200,7 @@ func TestHandleSaveBlockEvents_ShouldWork(t *testing.T) { }, }, } - logData := []*outport.LogData{ + logData := []*transaction.LogData{ { Log: &transaction.Log{ Address: []byte("logaddr1"), diff --git a/process/eventsInterceptor.go b/process/eventsInterceptor.go index 43eafc8..a73787d 100644 --- a/process/eventsInterceptor.go +++ b/process/eventsInterceptor.go @@ -293,7 +293,7 @@ func logStateAccessesPerTxs(stateAccesses map[string]*stateChange.StateAccesses) } } -func (ei *eventsInterceptor) getLogEventsFromTransactionsPool(logs []*outport.LogData) []data.Event { +func (ei *eventsInterceptor) getLogEventsFromTransactionsPool(logs []*transaction.LogData) []data.Event { var logEvents []*logEvent for _, logData := range logs { if logData == nil { diff --git a/process/eventsInterceptor_test.go b/process/eventsInterceptor_test.go index 54f9f7e..4d31f46 100644 --- a/process/eventsInterceptor_test.go +++ b/process/eventsInterceptor_test.go @@ -147,7 +147,7 @@ func TestProcessBlockEvents_WithoutExecutionResults(t *testing.T) { }, } - logs := []*outport.LogData{ + logs := []*transaction.LogData{ { Log: &transaction.Log{ Address: addr, @@ -241,7 +241,7 @@ func TestProcessBlockEvents_WithoutExecutionResults(t *testing.T) { }, } - logs := []*outport.LogData{ + logs := []*transaction.LogData{ { Log: &transaction.Log{ Address: addr, @@ -327,7 +327,7 @@ func TestProcessBlockEvents_WithExecutionResults(t *testing.T) { TimestampMs: 1234, } - logs := []*outport.LogData{ + logs := []*transaction.LogData{ { Log: &transaction.Log{ Address: addr, @@ -438,7 +438,7 @@ func TestProcessBlockEvents_WithExecutionResults(t *testing.T) { TimestampMs: 1234, } - logs := []*outport.LogData{ + logs := []*transaction.LogData{ { Log: &transaction.Log{ Address: addr, @@ -526,7 +526,7 @@ func TestGetLogEventsFromTransactionsPool(t *testing.T) { }, } - logs := []*outport.LogData{ + logs := []*transaction.LogData{ { Log: &transaction.Log{ Events: []*transaction.Event{ diff --git a/process/export_test.go b/process/export_test.go index d83a089..8fd69ab 100644 --- a/process/export_test.go +++ b/process/export_test.go @@ -3,8 +3,8 @@ package process import ( "encoding/hex" - "github.com/multiversx/mx-chain-core-go/data/outport" "github.com/multiversx/mx-chain-core-go/data/stateChange" + "github.com/multiversx/mx-chain-core-go/data/transaction" "github.com/multiversx/mx-chain-notifier-go/data" ) @@ -39,7 +39,7 @@ func (eh *eventsHandler) ShouldProcessSaveBlockEvents(blockHash string) bool { } // GetLogEventsFromTransactionsPool exports internal method for testing -func (ei *eventsInterceptor) GetLogEventsFromTransactionsPool(logs []*outport.LogData) []data.Event { +func (ei *eventsInterceptor) GetLogEventsFromTransactionsPool(logs []*transaction.LogData) []data.Event { return ei.getLogEventsFromTransactionsPool(logs) } diff --git a/process/preprocess/eventsPreProcessorV0.go b/process/preprocess/eventsPreProcessorV0.go index 8d2398b..9e78d8e 100644 --- a/process/preprocess/eventsPreProcessorV0.go +++ b/process/preprocess/eventsPreProcessorV0.go @@ -8,6 +8,7 @@ import ( nodeData "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/block" "github.com/multiversx/mx-chain-core-go/data/outport" + "github.com/multiversx/mx-chain-core-go/data/transaction" "github.com/multiversx/mx-chain-notifier-go/data" "github.com/multiversx/mx-chain-notifier-go/process" ) @@ -113,14 +114,14 @@ func (d *eventsPreProcessorV0) parseScrs(scrs map[string]*data.NodeSmartContract return newScrs } -func (d *eventsPreProcessorV0) parseLogs(logs []*data.LogData) []*outport.LogData { - newLogs := make([]*outport.LogData, len(logs)) +func (d *eventsPreProcessorV0) parseLogs(logs []*data.LogData) []*transaction.LogData { + newLogs := make([]*transaction.LogData, len(logs)) for _, logHandler := range logs { if logHandler == nil { continue } - newLogs = append(newLogs, &outport.LogData{ + newLogs = append(newLogs, &transaction.LogData{ TxHash: logHandler.TxHash, Log: logHandler.LogHandler, }) diff --git a/process/preprocess/eventsPreProcessorV1_test.go b/process/preprocess/eventsPreProcessorV1_test.go index cbaf5d8..84b6bea 100644 --- a/process/preprocess/eventsPreProcessorV1_test.go +++ b/process/preprocess/eventsPreProcessorV1_test.go @@ -228,7 +228,7 @@ func createDefaultOutportBlock() *outport.OutportBlock { ExecutionOrder: 2, }, }, - Logs: []*outport.LogData{}, + Logs: []*transaction.LogData{}, }, HeaderGasConsumption: &outport.HeaderGasConsumption{ GasProvided: 3, diff --git a/testdata/testData.go b/testdata/testData.go index 8bcb462..49a0135 100644 --- a/testdata/testData.go +++ b/testdata/testData.go @@ -164,7 +164,7 @@ func (bd *blockData) OutportBlockV1() *outport.OutportBlock { ExecutionOrder: 0, }, }, - Logs: []*outport.LogData{ + Logs: []*transaction.LogData{ { Log: &transaction.Log{ Address: []byte("logaddr1"), @@ -254,7 +254,7 @@ func (bd *blockData) OutportBlockV2() *outport.OutportBlock { ExecutionOrder: 0, }, }, - Logs: []*outport.LogData{ + Logs: []*transaction.LogData{ { Log: &transaction.Log{ Address: []byte("logaddr1"), From e7a11ba3fb8122a66472a0abfd1a8ad2d5c58b02 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Fri, 23 Jan 2026 18:28:02 +0200 Subject: [PATCH 28/62] bump core-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index d721ad6..ab42328 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.3 github.com/multiversx/mx-chain-communication-go v1.2.0 - github.com/multiversx/mx-chain-core-go v1.4.2-0.20251216121256-1d518f1eb139 + github.com/multiversx/mx-chain-core-go v1.4.2-0.20260119152911-59518132fb78 github.com/multiversx/mx-chain-logger-go v1.1.0 github.com/pelletier/go-toml v1.9.3 github.com/prometheus/client_model v0.6.1 diff --git a/go.sum b/go.sum index e943d43..f3f6902 100644 --- a/go.sum +++ b/go.sum @@ -130,8 +130,8 @@ github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/multiversx/mx-chain-communication-go v1.2.0 h1:0wOoLldiRbvaOPxwICbnRCqCpLqPewg8M/FMbC/0OXY= github.com/multiversx/mx-chain-communication-go v1.2.0/go.mod h1:wS3aAwkmHbC9mlzQdvL6p7l8Rqw3vmzhj7WZW1dTveA= -github.com/multiversx/mx-chain-core-go v1.4.2-0.20251216121256-1d518f1eb139 h1:YACeQwdcDDmgIxD9x6nBSpv4yRyk7s9ZnmDGDSLJA+8= -github.com/multiversx/mx-chain-core-go v1.4.2-0.20251216121256-1d518f1eb139/go.mod h1:IO+vspNan+gT0WOHnJ95uvWygiziHZvfXpff6KnxV7g= +github.com/multiversx/mx-chain-core-go v1.4.2-0.20260119152911-59518132fb78 h1:OUkeiv36YWdbbLyLAB9g6VXKuj2N1V6iyDOrdR0rI+I= +github.com/multiversx/mx-chain-core-go v1.4.2-0.20260119152911-59518132fb78/go.mod h1:IO+vspNan+gT0WOHnJ95uvWygiziHZvfXpff6KnxV7g= github.com/multiversx/mx-chain-crypto-go v1.2.13-0.20250218161752-9482d9a22234 h1:NNI7kYxzsq+4mTPSUJo0cK1+iPxjUX+gRJDaBRwEQ7M= github.com/multiversx/mx-chain-crypto-go v1.2.13-0.20250218161752-9482d9a22234/go.mod h1:QZAw2bZcOxGQRgYACTrmP8pfTa3NyxENIL+00G6nM5E= github.com/multiversx/mx-chain-logger-go v1.1.0 h1:97x84A6L4RfCa6YOx1HpAFxZp1cf/WI0Qh112whgZNM= From 28e4b027484f7095266d4d6500624989577ea1b8 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Fri, 23 Jan 2026 18:28:36 +0200 Subject: [PATCH 29/62] fix execution result timestamp --- data/block.go | 1 + process/eventsHandler.go | 8 +++----- process/eventsInterceptor.go | 1 + 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/data/block.go b/data/block.go index f9762d0..93f0a70 100644 --- a/data/block.go +++ b/data/block.go @@ -33,6 +33,7 @@ type InterceptorBlockData struct { LogEvents []Event StateAccessesPerAccounts map[string]*stateChange.StateAccesses Nonce uint64 + TimeStampMs uint64 } // ArgsSaveBlockData holds the block data that will be received on push events diff --git a/process/eventsHandler.go b/process/eventsHandler.go index bfad2aa..686d380 100644 --- a/process/eventsHandler.go +++ b/process/eventsHandler.go @@ -181,16 +181,14 @@ func (eh *eventsHandler) handleSaveBlockEventsV3(allEvents data.ArgsSaveBlockDat return err } - // TODO: get timestamp from executed header, not from current proposed header - headerTimeStamp := allEvents.Header.GetTimeStamp() - headerTimeStampMs := allEvents.HeaderTimeStampMs shardID := allEvents.Header.GetShardID() for _, executionResultData := range executionResultsData { + timeStampSec := common.ConvertTimeStampMsToSec(executionResultData.TimeStampMs) // this is used for backwards compatibility err = eh.handleSaveBlockEvents( executionResultData, - headerTimeStamp, - headerTimeStampMs, + timeStampSec, + executionResultData.TimeStampMs, shardID, executionResultData.Nonce, ) diff --git a/process/eventsInterceptor.go b/process/eventsInterceptor.go index a73787d..ad6f3c4 100644 --- a/process/eventsInterceptor.go +++ b/process/eventsInterceptor.go @@ -133,6 +133,7 @@ func (ei *eventsInterceptor) ProcessBlockEventsV3(eventsData *data.ArgsSaveBlock LogEvents: events, StateAccessesPerAccounts: stateAccessesPerAccounts, Nonce: execBlockData.GetHeaderNonce(), + TimeStampMs: execBlockData.GetTimestampMs(), } execBlocksData = append(execBlocksData, blockData) From a03c8cf7115b450ac4133b4cf5c3bd48e63a862a Mon Sep 17 00:00:00 2001 From: ssd04 Date: Fri, 23 Jan 2026 18:28:53 +0200 Subject: [PATCH 30/62] update test data --- testdata/testData.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/testdata/testData.go b/testdata/testData.go index 49a0135..edc061d 100644 --- a/testdata/testData.go +++ b/testdata/testData.go @@ -1,6 +1,7 @@ package testdata import ( + "bytes" "encoding/hex" "github.com/multiversx/mx-chain-core-go/core/check" @@ -260,7 +261,7 @@ func (bd *blockData) OutportBlockV2() *outport.OutportBlock { Address: []byte("logaddr1"), Events: []*transaction.Event{ { - Address: []byte("logaddr1"), + Address: bytes.Repeat([]byte("0"), 32), }, }, }, @@ -269,11 +270,17 @@ func (bd *blockData) OutportBlockV2() *outport.OutportBlock { }, } + execBlockHash2 := []byte("execBlockHash2") + execResults := map[string]*outport.ExecutionResultData{ hex.EncodeToString(execBlockHash): { Body: blockBody, TransactionPool: execResTxPool, }, + hex.EncodeToString(execBlockHash2): { + Body: blockBody, + TransactionPool: execResTxPool, + }, } return &outport.OutportBlock{ From a790a68f6bdd899ae0d5db23448679a7d26efac7 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Fri, 23 Jan 2026 18:32:45 +0200 Subject: [PATCH 31/62] add common func --- common/common.go | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 common/common.go diff --git a/common/common.go b/common/common.go new file mode 100644 index 0000000..889986f --- /dev/null +++ b/common/common.go @@ -0,0 +1,6 @@ +package common + +// ConvertTimeStampMsToSec will convert unix timestamp from milliseconds to seconds +func ConvertTimeStampMsToSec(timeStamp uint64) uint64 { + return timeStamp / 1000 +} From bcb59a68b1eadec62cddf7000d0ad223d534672e Mon Sep 17 00:00:00 2001 From: ssd04 Date: Fri, 23 Jan 2026 18:36:49 +0200 Subject: [PATCH 32/62] Revert "update test data" This reverts commit a03c8cf7115b450ac4133b4cf5c3bd48e63a862a. --- testdata/testData.go | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/testdata/testData.go b/testdata/testData.go index edc061d..49a0135 100644 --- a/testdata/testData.go +++ b/testdata/testData.go @@ -1,7 +1,6 @@ package testdata import ( - "bytes" "encoding/hex" "github.com/multiversx/mx-chain-core-go/core/check" @@ -261,7 +260,7 @@ func (bd *blockData) OutportBlockV2() *outport.OutportBlock { Address: []byte("logaddr1"), Events: []*transaction.Event{ { - Address: bytes.Repeat([]byte("0"), 32), + Address: []byte("logaddr1"), }, }, }, @@ -270,17 +269,11 @@ func (bd *blockData) OutportBlockV2() *outport.OutportBlock { }, } - execBlockHash2 := []byte("execBlockHash2") - execResults := map[string]*outport.ExecutionResultData{ hex.EncodeToString(execBlockHash): { Body: blockBody, TransactionPool: execResTxPool, }, - hex.EncodeToString(execBlockHash2): { - Body: blockBody, - TransactionPool: execResTxPool, - }, } return &outport.OutportBlock{ From 27472c09b5a05d7f70be2a5747de13801829362e Mon Sep 17 00:00:00 2001 From: ssd04 Date: Fri, 23 Jan 2026 18:37:04 +0200 Subject: [PATCH 33/62] Reapply "update test data" This reverts commit bcb59a68b1eadec62cddf7000d0ad223d534672e. --- testdata/testData.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/testdata/testData.go b/testdata/testData.go index 49a0135..edc061d 100644 --- a/testdata/testData.go +++ b/testdata/testData.go @@ -1,6 +1,7 @@ package testdata import ( + "bytes" "encoding/hex" "github.com/multiversx/mx-chain-core-go/core/check" @@ -260,7 +261,7 @@ func (bd *blockData) OutportBlockV2() *outport.OutportBlock { Address: []byte("logaddr1"), Events: []*transaction.Event{ { - Address: []byte("logaddr1"), + Address: bytes.Repeat([]byte("0"), 32), }, }, }, @@ -269,11 +270,17 @@ func (bd *blockData) OutportBlockV2() *outport.OutportBlock { }, } + execBlockHash2 := []byte("execBlockHash2") + execResults := map[string]*outport.ExecutionResultData{ hex.EncodeToString(execBlockHash): { Body: blockBody, TransactionPool: execResTxPool, }, + hex.EncodeToString(execBlockHash2): { + Body: blockBody, + TransactionPool: execResTxPool, + }, } return &outport.OutportBlock{ From 08337d39b63ef2cc04af7a67b78eebe8f3c6f352 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Fri, 23 Jan 2026 18:38:48 +0200 Subject: [PATCH 34/62] revert test data addr --- testdata/testData.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/testdata/testData.go b/testdata/testData.go index edc061d..711c196 100644 --- a/testdata/testData.go +++ b/testdata/testData.go @@ -1,7 +1,6 @@ package testdata import ( - "bytes" "encoding/hex" "github.com/multiversx/mx-chain-core-go/core/check" @@ -261,7 +260,7 @@ func (bd *blockData) OutportBlockV2() *outport.OutportBlock { Address: []byte("logaddr1"), Events: []*transaction.Event{ { - Address: bytes.Repeat([]byte("0"), 32), + Address: []byte("logaddr1"), }, }, }, From 9de8c98cd453ffb8b7f1a216636244b87cbe1d78 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Fri, 30 Jan 2026 15:54:23 +0200 Subject: [PATCH 35/62] update unnecessary warn logs --- process/eventsHandler.go | 6 +++--- process/eventsInterceptor.go | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/process/eventsHandler.go b/process/eventsHandler.go index 686d380..0652983 100644 --- a/process/eventsHandler.go +++ b/process/eventsHandler.go @@ -210,7 +210,7 @@ func (eh *eventsHandler) handlePushEvents(events data.BlockEvents) error { } if len(events.Events) == 0 { - log.Warn("received empty events", "event", common.PushLogsAndEvents, + log.Debug("received empty events", "event", common.PushLogsAndEvents, "block hash", events.Hash, ) events.Events = make([]data.Event, 0) @@ -317,7 +317,7 @@ func (eh *eventsHandler) handleBlockTxs(blockTxs data.BlockTxs) { } if len(blockTxs.Txs) == 0 { - log.Warn("received empty events", "event", common.BlockTxs, + log.Debug("received empty events", "event", common.BlockTxs, "block hash", blockTxs.Hash, ) } else { @@ -341,7 +341,7 @@ func (eh *eventsHandler) handleBlockScrs(blockScrs data.BlockScrs) { } if len(blockScrs.Scrs) == 0 { - log.Warn("received empty events", "event", common.BlockScrs, + log.Debug("received empty events", "event", common.BlockScrs, "block hash", blockScrs.Hash, ) } else { diff --git a/process/eventsInterceptor.go b/process/eventsInterceptor.go index ad6f3c4..882a62b 100644 --- a/process/eventsInterceptor.go +++ b/process/eventsInterceptor.go @@ -199,7 +199,7 @@ func (ei *eventsInterceptor) getStateAccessesPerAccounts( transactionPool *outport.TransactionPool, ) map[string]*stateChange.StateAccesses { if eventsData.StateAccesses == nil { - log.Warn("getStateAccessesPerAccounts failed: will return empty state accesses per accounts", + log.Debug("getStateAccessesPerAccounts failed: will return empty state accesses per accounts", "block hash", headerHash, "error", ErrNilStateAccesses, ) @@ -210,14 +210,14 @@ func (ei *eventsInterceptor) getStateAccessesPerAccounts( stateAccessesPerAccounts := make(map[string]*stateChange.StateAccesses) stateAccessesPerTxs, ok := eventsData.StateAccesses[headerHash] if !ok { - log.Warn("getStateAccessesPerAccounts failed: will return empty state accesses per accounts", + log.Debug("getStateAccessesPerAccounts failed: will return empty state accesses per accounts", "block hash", headerHash, ) return stateAccessesPerAccounts } if stateAccessesPerTxs == nil { - log.Warn("stateAccessesPerTxs failed: will return empty state accesses per accounts", + log.Debug("stateAccessesPerTxs failed: will return empty state accesses per accounts", "block hash", headerHash, "num state accesses", len(eventsData.StateAccesses), ) From 41402d9dd210f9032d538f812c9bebf7d4c2bb4c Mon Sep 17 00:00:00 2001 From: ssd04 Date: Fri, 30 Jan 2026 15:58:08 +0200 Subject: [PATCH 36/62] add duration logs for entire flow --- process/payloadHandler.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/process/payloadHandler.go b/process/payloadHandler.go index 310c472..49c813b 100644 --- a/process/payloadHandler.go +++ b/process/payloadHandler.go @@ -2,6 +2,7 @@ package process import ( "errors" + "time" "github.com/multiversx/mx-chain-core-go/data/outport" ) @@ -65,6 +66,11 @@ func (ph *payloadHandler) saveBlock(marshalledData []byte, version uint32) error return ErrInvalidPayloadType } + t := time.Now() + defer func() { + log.Debug("saveBlock done", "duration", time.Since(t)) + }() + return dataProcessor.SaveBlock(marshalledData) } @@ -75,6 +81,11 @@ func (ph *payloadHandler) revertIndexedBlock(marshalledData []byte, version uint return ErrInvalidPayloadType } + t := time.Now() + defer func() { + log.Debug("revertIndexedBlock done", "duration", time.Since(t)) + }() + return dataProcessor.RevertIndexedBlock(marshalledData) } @@ -85,6 +96,11 @@ func (ph *payloadHandler) finalizedBlock(marshalledData []byte, version uint32) return ErrInvalidPayloadType } + t := time.Now() + defer func() { + log.Debug("finalizedBlock done", "duration", time.Since(t)) + }() + return dataProcessor.FinalizedBlock(marshalledData) } From e311ca3c293b494c713049bd87f61e2b100036f0 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Thu, 5 Feb 2026 13:17:27 +0200 Subject: [PATCH 37/62] update communication-go --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index ab42328..ee02334 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/go-redis/redis/v8 v8.11.3 github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.3 - github.com/multiversx/mx-chain-communication-go v1.2.0 + github.com/multiversx/mx-chain-communication-go v1.3.0 github.com/multiversx/mx-chain-core-go v1.4.2-0.20260119152911-59518132fb78 github.com/multiversx/mx-chain-logger-go v1.1.0 github.com/pelletier/go-toml v1.9.3 @@ -48,7 +48,7 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mr-tron/base58 v1.2.0 // indirect - github.com/multiversx/mx-chain-crypto-go v1.2.13-0.20250218161752-9482d9a22234 // indirect + github.com/multiversx/mx-chain-crypto-go v1.3.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/pelletier/go-toml/v2 v2.1.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect diff --git a/go.sum b/go.sum index f3f6902..692c07b 100644 --- a/go.sum +++ b/go.sum @@ -128,12 +128,12 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/multiversx/mx-chain-communication-go v1.2.0 h1:0wOoLldiRbvaOPxwICbnRCqCpLqPewg8M/FMbC/0OXY= -github.com/multiversx/mx-chain-communication-go v1.2.0/go.mod h1:wS3aAwkmHbC9mlzQdvL6p7l8Rqw3vmzhj7WZW1dTveA= +github.com/multiversx/mx-chain-communication-go v1.3.0 h1:ziNM1dRuiR/7al2L/jGEA/a/hjurtJ/HEqgazHNt9P8= +github.com/multiversx/mx-chain-communication-go v1.3.0/go.mod h1:gDVWn6zUW6aCN1YOm/FbbT5MUmhgn/L1Rmpl8EoH3Yg= github.com/multiversx/mx-chain-core-go v1.4.2-0.20260119152911-59518132fb78 h1:OUkeiv36YWdbbLyLAB9g6VXKuj2N1V6iyDOrdR0rI+I= github.com/multiversx/mx-chain-core-go v1.4.2-0.20260119152911-59518132fb78/go.mod h1:IO+vspNan+gT0WOHnJ95uvWygiziHZvfXpff6KnxV7g= -github.com/multiversx/mx-chain-crypto-go v1.2.13-0.20250218161752-9482d9a22234 h1:NNI7kYxzsq+4mTPSUJo0cK1+iPxjUX+gRJDaBRwEQ7M= -github.com/multiversx/mx-chain-crypto-go v1.2.13-0.20250218161752-9482d9a22234/go.mod h1:QZAw2bZcOxGQRgYACTrmP8pfTa3NyxENIL+00G6nM5E= +github.com/multiversx/mx-chain-crypto-go v1.3.0 h1:0eK2bkDOMi8VbSPrB1/vGJSYT81IBtfL4zw+C4sWe/k= +github.com/multiversx/mx-chain-crypto-go v1.3.0/go.mod h1:nPIkxxzyTP8IquWKds+22Q2OJ9W7LtusC7cAosz7ojM= github.com/multiversx/mx-chain-logger-go v1.1.0 h1:97x84A6L4RfCa6YOx1HpAFxZp1cf/WI0Qh112whgZNM= github.com/multiversx/mx-chain-logger-go v1.1.0/go.mod h1:K9XgiohLwOsNACETMNL0LItJMREuEvTH6NsoXWXWg7g= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= From 587a7ee79e1958c2aa94b8b15ff98d7ebab937f3 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Wed, 11 Feb 2026 10:03:44 +0200 Subject: [PATCH 38/62] use latest core-go tag reference --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index ee02334..f0af130 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.3 github.com/multiversx/mx-chain-communication-go v1.3.0 - github.com/multiversx/mx-chain-core-go v1.4.2-0.20260119152911-59518132fb78 + github.com/multiversx/mx-chain-core-go v1.4.2-0.20260210121034-184d4fbfa371 github.com/multiversx/mx-chain-logger-go v1.1.0 github.com/pelletier/go-toml v1.9.3 github.com/prometheus/client_model v0.6.1 diff --git a/go.sum b/go.sum index 692c07b..c170968 100644 --- a/go.sum +++ b/go.sum @@ -132,6 +132,8 @@ github.com/multiversx/mx-chain-communication-go v1.3.0 h1:ziNM1dRuiR/7al2L/jGEA/ github.com/multiversx/mx-chain-communication-go v1.3.0/go.mod h1:gDVWn6zUW6aCN1YOm/FbbT5MUmhgn/L1Rmpl8EoH3Yg= github.com/multiversx/mx-chain-core-go v1.4.2-0.20260119152911-59518132fb78 h1:OUkeiv36YWdbbLyLAB9g6VXKuj2N1V6iyDOrdR0rI+I= github.com/multiversx/mx-chain-core-go v1.4.2-0.20260119152911-59518132fb78/go.mod h1:IO+vspNan+gT0WOHnJ95uvWygiziHZvfXpff6KnxV7g= +github.com/multiversx/mx-chain-core-go v1.4.2-0.20260210121034-184d4fbfa371 h1:5a94TjX7IG7K4zKO87SF3D4gzfNiy56RCAM+Qw9M4TY= +github.com/multiversx/mx-chain-core-go v1.4.2-0.20260210121034-184d4fbfa371/go.mod h1:IO+vspNan+gT0WOHnJ95uvWygiziHZvfXpff6KnxV7g= github.com/multiversx/mx-chain-crypto-go v1.3.0 h1:0eK2bkDOMi8VbSPrB1/vGJSYT81IBtfL4zw+C4sWe/k= github.com/multiversx/mx-chain-crypto-go v1.3.0/go.mod h1:nPIkxxzyTP8IquWKds+22Q2OJ9W7LtusC7cAosz7ojM= github.com/multiversx/mx-chain-logger-go v1.1.0 h1:97x84A6L4RfCa6YOx1HpAFxZp1cf/WI0Qh112whgZNM= From 03e2acb42b7296af326a84f14dd01379f831c9af Mon Sep 17 00:00:00 2001 From: ssd04 Date: Wed, 11 Feb 2026 10:42:01 +0200 Subject: [PATCH 39/62] fix merge conflicts --- go.mod | 5 ----- go.sum | 9 --------- process/eventsInterceptor_test.go | 25 +++---------------------- 3 files changed, 3 insertions(+), 36 deletions(-) diff --git a/go.mod b/go.mod index 241713a..ee02334 100644 --- a/go.mod +++ b/go.mod @@ -8,13 +8,8 @@ require ( github.com/go-redis/redis/v8 v8.11.3 github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.3 -<<<<<<< HEAD github.com/multiversx/mx-chain-communication-go v1.3.0 github.com/multiversx/mx-chain-core-go v1.4.2-0.20260119152911-59518132fb78 -======= - github.com/multiversx/mx-chain-communication-go v1.2.0 - github.com/multiversx/mx-chain-core-go v1.4.1 ->>>>>>> main github.com/multiversx/mx-chain-logger-go v1.1.0 github.com/pelletier/go-toml v1.9.3 github.com/prometheus/client_model v0.6.1 diff --git a/go.sum b/go.sum index eb75b30..692c07b 100644 --- a/go.sum +++ b/go.sum @@ -128,21 +128,12 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -<<<<<<< HEAD github.com/multiversx/mx-chain-communication-go v1.3.0 h1:ziNM1dRuiR/7al2L/jGEA/a/hjurtJ/HEqgazHNt9P8= github.com/multiversx/mx-chain-communication-go v1.3.0/go.mod h1:gDVWn6zUW6aCN1YOm/FbbT5MUmhgn/L1Rmpl8EoH3Yg= github.com/multiversx/mx-chain-core-go v1.4.2-0.20260119152911-59518132fb78 h1:OUkeiv36YWdbbLyLAB9g6VXKuj2N1V6iyDOrdR0rI+I= github.com/multiversx/mx-chain-core-go v1.4.2-0.20260119152911-59518132fb78/go.mod h1:IO+vspNan+gT0WOHnJ95uvWygiziHZvfXpff6KnxV7g= github.com/multiversx/mx-chain-crypto-go v1.3.0 h1:0eK2bkDOMi8VbSPrB1/vGJSYT81IBtfL4zw+C4sWe/k= github.com/multiversx/mx-chain-crypto-go v1.3.0/go.mod h1:nPIkxxzyTP8IquWKds+22Q2OJ9W7LtusC7cAosz7ojM= -======= -github.com/multiversx/mx-chain-communication-go v1.2.0 h1:0wOoLldiRbvaOPxwICbnRCqCpLqPewg8M/FMbC/0OXY= -github.com/multiversx/mx-chain-communication-go v1.2.0/go.mod h1:wS3aAwkmHbC9mlzQdvL6p7l8Rqw3vmzhj7WZW1dTveA= -github.com/multiversx/mx-chain-core-go v1.4.1 h1:ljs53jpdjtCohpaqm2n/dvTGrFlSgIpoZYH8RVt5cWo= -github.com/multiversx/mx-chain-core-go v1.4.1/go.mod h1:IO+vspNan+gT0WOHnJ95uvWygiziHZvfXpff6KnxV7g= -github.com/multiversx/mx-chain-crypto-go v1.2.13-0.20250218161752-9482d9a22234 h1:NNI7kYxzsq+4mTPSUJo0cK1+iPxjUX+gRJDaBRwEQ7M= -github.com/multiversx/mx-chain-crypto-go v1.2.13-0.20250218161752-9482d9a22234/go.mod h1:QZAw2bZcOxGQRgYACTrmP8pfTa3NyxENIL+00G6nM5E= ->>>>>>> main github.com/multiversx/mx-chain-logger-go v1.1.0 h1:97x84A6L4RfCa6YOx1HpAFxZp1cf/WI0Qh112whgZNM= github.com/multiversx/mx-chain-logger-go v1.1.0/go.mod h1:K9XgiohLwOsNACETMNL0LItJMREuEvTH6NsoXWXWg7g= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= diff --git a/process/eventsInterceptor_test.go b/process/eventsInterceptor_test.go index 5814a5d..2684ada 100644 --- a/process/eventsInterceptor_test.go +++ b/process/eventsInterceptor_test.go @@ -689,7 +689,6 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { t.Run("with write operations", func(t *testing.T) { t.Parallel() -<<<<<<< HEAD stateAccesses := make(map[string]*stateChange.StateAccesses) stateAccesses["txHash1"] = &stateChange.StateAccesses{ StateAccess: []*stateChange.StateAccess{ @@ -721,8 +720,6 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { }, } -======= ->>>>>>> main blockEvents := &data.ArgsSaveBlockData{ HeaderHash: blockHash, TransactionsPool: &outport.TransactionPool{ @@ -730,13 +727,9 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { SmartContractResults: scrs, InvalidTxs: invalidTxs, }, -<<<<<<< HEAD StateAccesses: map[string]*outport.StateAccessesForBlock{ hex.EncodeToString(blockHash): {stateAccesses}, }, -======= - StateAccesses: stateAccessesWrite, ->>>>>>> main } expStateAccessesPerAccounts := make(map[string]*stateChange.StateAccesses) @@ -784,7 +777,6 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { t.Run("with read operations, but not enabled from config", func(t *testing.T) { t.Parallel() -<<<<<<< HEAD stateAccesses := make(map[string]*stateChange.StateAccesses) stateAccesses["txHash1"] = &stateChange.StateAccesses{ StateAccess: []*stateChange.StateAccess{ @@ -816,8 +808,6 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { }, } -======= ->>>>>>> main blockEvents := &data.ArgsSaveBlockData{ HeaderHash: blockHash, TransactionsPool: &outport.TransactionPool{ @@ -825,13 +815,9 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { SmartContractResults: scrs, InvalidTxs: invalidTxs, }, -<<<<<<< HEAD StateAccesses: map[string]*outport.StateAccessesForBlock{ hex.EncodeToString(blockHash): {stateAccesses}, }, -======= - StateAccesses: stateAccessesRead, ->>>>>>> main } args := createMockEventsInterceptorArgs() @@ -847,7 +833,6 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { t.Run("with read (not enabled from config) and write operations", func(t *testing.T) { t.Parallel() -<<<<<<< HEAD stateAccesses := make(map[string]*stateChange.StateAccesses) stateAccesses["txHash1"] = &stateChange.StateAccesses{ StateAccess: []*stateChange.StateAccess{ @@ -879,8 +864,6 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { }, } -======= ->>>>>>> main blockEvents := &data.ArgsSaveBlockData{ HeaderHash: blockHash, TransactionsPool: &outport.TransactionPool{ @@ -888,13 +871,9 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { SmartContractResults: scrs, InvalidTxs: invalidTxs, }, -<<<<<<< HEAD StateAccesses: map[string]*outport.StateAccessesForBlock{ hex.EncodeToString(blockHash): {stateAccesses}, }, -======= - StateAccesses: stateAccessesReadWrite, ->>>>>>> main } expStateAccessesPerAccounts := make(map[string]*stateChange.StateAccesses) @@ -935,7 +914,9 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { SmartContractResults: scrs, InvalidTxs: invalidTxs, }, - StateAccesses: stateAccessesReadWrite, + StateAccesses: map[string]*outport.StateAccessesForBlock{ + hex.EncodeToString(blockHash): {stateAccessesReadWrite}, + }, } expStateAccessesPerAccounts := make(map[string]*stateChange.StateAccesses) From 63e85b9cfd801889a47c62cf91dcaf9bffa32afb Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Wed, 11 Feb 2026 12:13:05 +0200 Subject: [PATCH 40/62] update go mod --- go.mod | 2 +- go.sum | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index f0af130..66cea9d 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.3 github.com/multiversx/mx-chain-communication-go v1.3.0 - github.com/multiversx/mx-chain-core-go v1.4.2-0.20260210121034-184d4fbfa371 + github.com/multiversx/mx-chain-core-go v1.4.2-0.20260211100920-a4e12f6428cc github.com/multiversx/mx-chain-logger-go v1.1.0 github.com/pelletier/go-toml v1.9.3 github.com/prometheus/client_model v0.6.1 diff --git a/go.sum b/go.sum index c170968..09eb497 100644 --- a/go.sum +++ b/go.sum @@ -130,10 +130,8 @@ github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/multiversx/mx-chain-communication-go v1.3.0 h1:ziNM1dRuiR/7al2L/jGEA/a/hjurtJ/HEqgazHNt9P8= github.com/multiversx/mx-chain-communication-go v1.3.0/go.mod h1:gDVWn6zUW6aCN1YOm/FbbT5MUmhgn/L1Rmpl8EoH3Yg= -github.com/multiversx/mx-chain-core-go v1.4.2-0.20260119152911-59518132fb78 h1:OUkeiv36YWdbbLyLAB9g6VXKuj2N1V6iyDOrdR0rI+I= -github.com/multiversx/mx-chain-core-go v1.4.2-0.20260119152911-59518132fb78/go.mod h1:IO+vspNan+gT0WOHnJ95uvWygiziHZvfXpff6KnxV7g= -github.com/multiversx/mx-chain-core-go v1.4.2-0.20260210121034-184d4fbfa371 h1:5a94TjX7IG7K4zKO87SF3D4gzfNiy56RCAM+Qw9M4TY= -github.com/multiversx/mx-chain-core-go v1.4.2-0.20260210121034-184d4fbfa371/go.mod h1:IO+vspNan+gT0WOHnJ95uvWygiziHZvfXpff6KnxV7g= +github.com/multiversx/mx-chain-core-go v1.4.2-0.20260211100920-a4e12f6428cc h1:lYAuFTp8hpoFhDaYfMyvV95JPtbdPI7Ykq128sgeaQ8= +github.com/multiversx/mx-chain-core-go v1.4.2-0.20260211100920-a4e12f6428cc/go.mod h1:IO+vspNan+gT0WOHnJ95uvWygiziHZvfXpff6KnxV7g= github.com/multiversx/mx-chain-crypto-go v1.3.0 h1:0eK2bkDOMi8VbSPrB1/vGJSYT81IBtfL4zw+C4sWe/k= github.com/multiversx/mx-chain-crypto-go v1.3.0/go.mod h1:nPIkxxzyTP8IquWKds+22Q2OJ9W7LtusC7cAosz7ojM= github.com/multiversx/mx-chain-logger-go v1.1.0 h1:97x84A6L4RfCa6YOx1HpAFxZp1cf/WI0Qh112whgZNM= From 98d6dbb346ef12e771414597dadcf00c98e545b4 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Wed, 4 Mar 2026 12:04:43 +0200 Subject: [PATCH 41/62] use backwards compatible state accesses per txs --- data/block.go | 3 +- process/eventsInterceptor.go | 43 ++- process/eventsInterceptor_test.go | 328 +++++++++++++++++++-- process/export_test.go | 5 + process/preprocess/eventsPreProcessorV1.go | 3 +- 5 files changed, 348 insertions(+), 34 deletions(-) diff --git a/data/block.go b/data/block.go index 93f0a70..6a30ae7 100644 --- a/data/block.go +++ b/data/block.go @@ -48,7 +48,8 @@ type ArgsSaveBlockData struct { AlteredAccounts map[string]*alteredAccount.AlteredAccount NumberOfShards uint32 HeaderTimeStampMs uint64 - StateAccesses map[string]*outport.StateAccessesForBlock + StateAccesses map[string]*stateChange.StateAccesses + StateAccessesForBlock map[string]*outport.StateAccessesForBlock Results map[string]*outport.ExecutionResultData } diff --git a/process/eventsInterceptor.go b/process/eventsInterceptor.go index ba46b3f..9b9bdd2 100644 --- a/process/eventsInterceptor.go +++ b/process/eventsInterceptor.go @@ -123,7 +123,7 @@ func (ei *eventsInterceptor) ProcessBlockEventsV3(eventsData *data.ArgsSaveBlock events := ei.getLogEventsFromTransactionsPool(transactionsPool.GetLogs()) - stateAccessesPerAccounts := ei.getStateAccessesPerAccounts(eventsData, headerHash, transactionsPool) + stateAccessesPerAccounts := ei.getStateAccessesPerAccountsV3(eventsData, headerHash, transactionsPool) blockData := &data.InterceptorBlockData{ Hash: headerHash, @@ -210,24 +210,49 @@ func (ei *eventsInterceptor) getStateAccessesPerAccounts( return make(map[string]*stateChange.StateAccesses) } - stateAccessesPerAccounts := make(map[string]*stateChange.StateAccesses) - stateAccessesPerTxs, ok := eventsData.StateAccesses[headerHash] + stateAccesses := eventsData.StateAccesses + + return ei.fetchStateAccessesPerAccounts(stateAccesses, transactionPool) +} + +func (ei *eventsInterceptor) getStateAccessesPerAccountsV3( + eventsData *data.ArgsSaveBlockData, + headerHash string, + transactionPool *outport.TransactionPool, +) map[string]*stateChange.StateAccesses { + stateAccessesPerBlock, ok := eventsData.StateAccessesForBlock[headerHash] if !ok { - log.Debug("getStateAccessesPerAccounts failed: will return empty state accesses per accounts", + log.Debug("stateAccessesPerBlock failed: will return empty state accesses per accounts", "block hash", headerHash, ) - return stateAccessesPerAccounts + + return make(map[string]*stateChange.StateAccesses) } - if stateAccessesPerTxs == nil { - log.Debug("stateAccessesPerTxs failed: will return empty state accesses per accounts", + if stateAccessesPerBlock == nil { + log.Debug("stateAccessesPerBlock failed: will return empty state accesses per accounts", "block hash", headerHash, "num state accesses", len(eventsData.StateAccesses), ) - return stateAccessesPerAccounts + + return make(map[string]*stateChange.StateAccesses) } - stateAccesses := stateAccessesPerTxs.StateAccesses + stateAccesses := stateAccessesPerBlock.StateAccesses + + return ei.fetchStateAccessesPerAccounts(stateAccesses, transactionPool) +} + +func (ei *eventsInterceptor) fetchStateAccessesPerAccounts( + stateAccesses map[string]*stateChange.StateAccesses, + transactionPool *outport.TransactionPool, +) map[string]*stateChange.StateAccesses { + if stateAccesses == nil { + return make(map[string]*stateChange.StateAccesses) + } + + stateAccessesPerAccounts := make(map[string]*stateChange.StateAccesses) + logStateAccessesPerTxs(stateAccesses) // txs hashes with order diff --git a/process/eventsInterceptor_test.go b/process/eventsInterceptor_test.go index 2684ada..871db03 100644 --- a/process/eventsInterceptor_test.go +++ b/process/eventsInterceptor_test.go @@ -171,7 +171,8 @@ func TestProcessBlockEvents_WithoutExecutionResults(t *testing.T) { SmartContractResults: scrs, Logs: logs, }, - StateAccesses: make(map[string]*outport.StateAccessesForBlock), + StateAccesses: make(map[string]*stateChange.StateAccesses), + StateAccessesForBlock: make(map[string]*outport.StateAccessesForBlock), } expTxs := map[string]*transaction.Transaction{ @@ -266,7 +267,8 @@ func TestProcessBlockEvents_WithoutExecutionResults(t *testing.T) { TransactionsPool: &outport.TransactionPool{ Logs: logs, }, - StateAccesses: make(map[string]*outport.StateAccessesForBlock), + StateAccesses: make(map[string]*stateChange.StateAccesses), + StateAccessesForBlock: make(map[string]*outport.StateAccessesForBlock), } expEvents := &data.InterceptorBlockData{ @@ -363,12 +365,13 @@ func TestProcessBlockEvents_WithExecutionResults(t *testing.T) { } blockEvents := data.ArgsSaveBlockData{ - HeaderHash: blockHash, - Body: blockBody, - Header: blockHeader, - TransactionsPool: proposedTxPool, - StateAccesses: make(map[string]*outport.StateAccessesForBlock), - Results: execResults, + HeaderHash: blockHash, + Body: blockBody, + Header: blockHeader, + TransactionsPool: proposedTxPool, + StateAccesses: make(map[string]*stateChange.StateAccesses), + StateAccessesForBlock: make(map[string]*outport.StateAccessesForBlock), + Results: execResults, } expTxs := map[string]*transaction.Transaction{ @@ -473,12 +476,13 @@ func TestProcessBlockEvents_WithExecutionResults(t *testing.T) { } blockEvents := data.ArgsSaveBlockData{ - HeaderHash: blockHash, - Body: blockBody, - Header: blockHeader, - TransactionsPool: proposedTxPool, - StateAccesses: make(map[string]*outport.StateAccessesForBlock), - Results: execResults, + HeaderHash: blockHash, + Body: blockBody, + Header: blockHeader, + TransactionsPool: proposedTxPool, + StateAccesses: make(map[string]*stateChange.StateAccesses), + StateAccessesForBlock: make(map[string]*outport.StateAccessesForBlock), + Results: execResults, } expEvents := []*data.InterceptorBlockData{ @@ -563,7 +567,7 @@ func TestGetLogEventsFromTransactionsPool(t *testing.T) { require.Equal(t, txHash2, receivedEvents[2].TxHash) } -func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { +func TestEventsInterceptor_GetStateAccessesPerAccountsV3(t *testing.T) { t.Parallel() txs := map[string]*outport.TxInfo{ @@ -686,6 +690,279 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { blockHash := []byte("blockHash") + // before header V3 + + t.Run("with write operations", func(t *testing.T) { + t.Parallel() + + stateAccesses := make(map[string]*stateChange.StateAccesses) + stateAccesses["txHash1"] = &stateChange.StateAccesses{ + StateAccess: []*stateChange.StateAccess{ + { + Type: stateChange.Write, + MainTrieKey: []byte("mainTrieKey1"), + MainTrieVal: []byte("mainTrieVal1"), + }, + { + Type: stateChange.Write, + MainTrieKey: []byte("mainTrieKey2"), + MainTrieVal: []byte("mainTrieVal2"), + }, + }, + } + stateAccesses["txHash2"] = &stateChange.StateAccesses{} + stateAccesses["txHash0"] = &stateChange.StateAccesses{ + StateAccess: []*stateChange.StateAccess{ + { + Type: stateChange.Write, + MainTrieKey: []byte("mainTrieKey3"), + MainTrieVal: []byte("mainTrieVal3"), + }, + { + Type: stateChange.Write, + MainTrieKey: []byte("mainTrieKey2"), + MainTrieVal: []byte("mainTrieVal4"), + }, + }, + } + + blockEvents := &data.ArgsSaveBlockData{ + HeaderHash: blockHash, + TransactionsPool: &outport.TransactionPool{ + Transactions: txs, + SmartContractResults: scrs, + InvalidTxs: invalidTxs, + }, + StateAccesses: stateAccesses, + } + + expStateAccessesPerAccounts := make(map[string]*stateChange.StateAccesses) + expStateAccessesPerAccounts[hex.EncodeToString([]byte("mainTrieKey1"))] = &stateChange.StateAccesses{ + StateAccess: []*stateChange.StateAccess{ + { + Type: stateChange.Write, + MainTrieKey: []byte("mainTrieKey1"), + MainTrieVal: []byte("mainTrieVal1"), + }, + }, + } + expStateAccessesPerAccounts[hex.EncodeToString([]byte("mainTrieKey2"))] = &stateChange.StateAccesses{ + StateAccess: []*stateChange.StateAccess{ + { + Type: stateChange.Write, + MainTrieKey: []byte("mainTrieKey2"), + MainTrieVal: []byte("mainTrieVal4"), + }, + { + Type: stateChange.Write, + MainTrieKey: []byte("mainTrieKey2"), + MainTrieVal: []byte("mainTrieVal2"), + }, + }, + } + expStateAccessesPerAccounts[hex.EncodeToString([]byte("mainTrieKey3"))] = &stateChange.StateAccesses{ + StateAccess: []*stateChange.StateAccess{ + { + Type: stateChange.Write, + MainTrieKey: []byte("mainTrieKey3"), + MainTrieVal: []byte("mainTrieVal3"), + }, + }, + } + + args := createMockEventsInterceptorArgs() + en, _ := process.NewEventsInterceptor(args) + + stateAccessesPerAccounts := en.GetStateAccessesPerAccounts(blockEvents) + + require.Equal(t, expStateAccessesPerAccounts, stateAccessesPerAccounts) + }) + + t.Run("with read operations, but not enabled from config", func(t *testing.T) { + t.Parallel() + + stateAccesses := make(map[string]*stateChange.StateAccesses) + stateAccesses["txHash1"] = &stateChange.StateAccesses{ + StateAccess: []*stateChange.StateAccess{ + { + Type: stateChange.Read, + MainTrieKey: []byte("mainTrieKey1"), + MainTrieVal: []byte("mainTrieVal1"), + }, + { + Type: stateChange.Read, + MainTrieKey: []byte("mainTrieKey2"), + MainTrieVal: []byte("mainTrieVal2"), + }, + }, + } + stateAccesses["txHash2"] = &stateChange.StateAccesses{} + stateAccesses["txHash0"] = &stateChange.StateAccesses{ + StateAccess: []*stateChange.StateAccess{ + { + Type: stateChange.Read, + MainTrieKey: []byte("mainTrieKey3"), + MainTrieVal: []byte("mainTrieVal3"), + }, + { + Type: stateChange.Read, + MainTrieKey: []byte("mainTrieKey2"), + MainTrieVal: []byte("mainTrieVal4"), + }, + }, + } + + blockEvents := &data.ArgsSaveBlockData{ + HeaderHash: blockHash, + TransactionsPool: &outport.TransactionPool{ + Transactions: txs, + SmartContractResults: scrs, + InvalidTxs: invalidTxs, + }, + StateAccesses: stateAccesses, + } + + args := createMockEventsInterceptorArgs() + en, _ := process.NewEventsInterceptor(args) + + expStateAccessesPerAccounts := make(map[string]*stateChange.StateAccesses) + + stateAccessesPerAccounts := en.GetStateAccessesPerAccounts(blockEvents) + + require.Equal(t, expStateAccessesPerAccounts, stateAccessesPerAccounts) + }) + + t.Run("with read (not enabled from config) and write operations", func(t *testing.T) { + t.Parallel() + + stateAccesses := make(map[string]*stateChange.StateAccesses) + stateAccesses["txHash1"] = &stateChange.StateAccesses{ + StateAccess: []*stateChange.StateAccess{ + { + Type: stateChange.Read, + MainTrieKey: []byte("mainTrieKey1"), + MainTrieVal: []byte("mainTrieVal1"), + }, + { + Type: stateChange.Write, + MainTrieKey: []byte("mainTrieKey2"), + MainTrieVal: []byte("mainTrieVal2"), + }, + }, + } + stateAccesses["txHash2"] = &stateChange.StateAccesses{} + stateAccesses["txHash0"] = &stateChange.StateAccesses{ + StateAccess: []*stateChange.StateAccess{ + { + Type: stateChange.Write, + MainTrieKey: []byte("mainTrieKey3"), + MainTrieVal: []byte("mainTrieVal3"), + }, + { + Type: stateChange.Read, + MainTrieKey: []byte("mainTrieKey2"), + MainTrieVal: []byte("mainTrieVal4"), + }, + }, + } + + blockEvents := &data.ArgsSaveBlockData{ + HeaderHash: blockHash, + Header: &block.HeaderV3{}, + TransactionsPool: &outport.TransactionPool{ + Transactions: txs, + SmartContractResults: scrs, + InvalidTxs: invalidTxs, + }, + StateAccesses: stateAccesses, + } + + expStateAccessesPerAccounts := make(map[string]*stateChange.StateAccesses) + expStateAccessesPerAccounts[hex.EncodeToString([]byte("mainTrieKey2"))] = &stateChange.StateAccesses{ + StateAccess: []*stateChange.StateAccess{ + { + Type: stateChange.Write, + MainTrieKey: []byte("mainTrieKey2"), + MainTrieVal: []byte("mainTrieVal2"), + }, + }, + } + expStateAccessesPerAccounts[hex.EncodeToString([]byte("mainTrieKey3"))] = &stateChange.StateAccesses{ + StateAccess: []*stateChange.StateAccess{ + { + Type: stateChange.Write, + MainTrieKey: []byte("mainTrieKey3"), + MainTrieVal: []byte("mainTrieVal3"), + }, + }, + } + + args := createMockEventsInterceptorArgs() + en, _ := process.NewEventsInterceptor(args) + + stateAccessesPerAccounts := en.GetStateAccessesPerAccounts(blockEvents) + + require.Equal(t, expStateAccessesPerAccounts, stateAccessesPerAccounts) + }) + + t.Run("with read and write operations", func(t *testing.T) { + t.Parallel() + + blockEvents := &data.ArgsSaveBlockData{ + HeaderHash: blockHash, + TransactionsPool: &outport.TransactionPool{ + Transactions: txs, + SmartContractResults: scrs, + InvalidTxs: invalidTxs, + }, + StateAccesses: stateAccessesReadWrite, + } + + expStateAccessesPerAccounts := make(map[string]*stateChange.StateAccesses) + expStateAccessesPerAccounts[hex.EncodeToString([]byte("mainTrieKey1"))] = &stateChange.StateAccesses{ + StateAccess: []*stateChange.StateAccess{ + &stateChange.StateAccess{ + Type: stateChange.Read, + MainTrieKey: []byte("mainTrieKey1"), + MainTrieVal: []byte("mainTrieVal1"), + }, + }, + } + expStateAccessesPerAccounts[hex.EncodeToString([]byte("mainTrieKey2"))] = &stateChange.StateAccesses{ + StateAccess: []*stateChange.StateAccess{ + &stateChange.StateAccess{ + Type: stateChange.Read, + MainTrieKey: []byte("mainTrieKey2"), + MainTrieVal: []byte("mainTrieVal4"), + }, + &stateChange.StateAccess{ + Type: stateChange.Write, + MainTrieKey: []byte("mainTrieKey2"), + MainTrieVal: []byte("mainTrieVal2"), + }, + }, + } + expStateAccessesPerAccounts[hex.EncodeToString([]byte("mainTrieKey3"))] = &stateChange.StateAccesses{ + StateAccess: []*stateChange.StateAccess{ + &stateChange.StateAccess{ + Type: stateChange.Write, + MainTrieKey: []byte("mainTrieKey3"), + MainTrieVal: []byte("mainTrieVal3"), + }, + }, + } + + args := createMockEventsInterceptorArgs() + args.WithReadStateChanges = true + en, _ := process.NewEventsInterceptor(args) + + stateAccessesPerAccounts := en.GetStateAccessesPerAccounts(blockEvents) + + require.Equal(t, expStateAccessesPerAccounts, stateAccessesPerAccounts) + }) + + // with header V3 + t.Run("with write operations", func(t *testing.T) { t.Parallel() @@ -727,7 +1004,8 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { SmartContractResults: scrs, InvalidTxs: invalidTxs, }, - StateAccesses: map[string]*outport.StateAccessesForBlock{ + StateAccesses: make(map[string]*stateChange.StateAccesses), + StateAccessesForBlock: map[string]*outport.StateAccessesForBlock{ hex.EncodeToString(blockHash): {stateAccesses}, }, } @@ -769,7 +1047,7 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { args := createMockEventsInterceptorArgs() en, _ := process.NewEventsInterceptor(args) - stateAccessesPerAccounts := en.GetStateAccessesPerAccounts(blockEvents) + stateAccessesPerAccounts := en.GetStateAccessesPerAccountsV3(blockEvents) require.Equal(t, expStateAccessesPerAccounts, stateAccessesPerAccounts) }) @@ -815,7 +1093,8 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { SmartContractResults: scrs, InvalidTxs: invalidTxs, }, - StateAccesses: map[string]*outport.StateAccessesForBlock{ + StateAccesses: make(map[string]*stateChange.StateAccesses), + StateAccessesForBlock: map[string]*outport.StateAccessesForBlock{ hex.EncodeToString(blockHash): {stateAccesses}, }, } @@ -825,7 +1104,7 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { expStateAccessesPerAccounts := make(map[string]*stateChange.StateAccesses) - stateAccessesPerAccounts := en.GetStateAccessesPerAccounts(blockEvents) + stateAccessesPerAccounts := en.GetStateAccessesPerAccountsV3(blockEvents) require.Equal(t, expStateAccessesPerAccounts, stateAccessesPerAccounts) }) @@ -866,12 +1145,14 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { blockEvents := &data.ArgsSaveBlockData{ HeaderHash: blockHash, + Header: &block.HeaderV3{}, TransactionsPool: &outport.TransactionPool{ Transactions: txs, SmartContractResults: scrs, InvalidTxs: invalidTxs, }, - StateAccesses: map[string]*outport.StateAccessesForBlock{ + StateAccesses: make(map[string]*stateChange.StateAccesses), + StateAccessesForBlock: map[string]*outport.StateAccessesForBlock{ hex.EncodeToString(blockHash): {stateAccesses}, }, } @@ -899,7 +1180,7 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { args := createMockEventsInterceptorArgs() en, _ := process.NewEventsInterceptor(args) - stateAccessesPerAccounts := en.GetStateAccessesPerAccounts(blockEvents) + stateAccessesPerAccounts := en.GetStateAccessesPerAccountsV3(blockEvents) require.Equal(t, expStateAccessesPerAccounts, stateAccessesPerAccounts) }) @@ -914,7 +1195,8 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { SmartContractResults: scrs, InvalidTxs: invalidTxs, }, - StateAccesses: map[string]*outport.StateAccessesForBlock{ + StateAccesses: make(map[string]*stateChange.StateAccesses), + StateAccessesForBlock: map[string]*outport.StateAccessesForBlock{ hex.EncodeToString(blockHash): {stateAccessesReadWrite}, }, } @@ -957,7 +1239,7 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { args.WithReadStateChanges = true en, _ := process.NewEventsInterceptor(args) - stateAccessesPerAccounts := en.GetStateAccessesPerAccounts(blockEvents) + stateAccessesPerAccounts := en.GetStateAccessesPerAccountsV3(blockEvents) require.Equal(t, expStateAccessesPerAccounts, stateAccessesPerAccounts) }) diff --git a/process/export_test.go b/process/export_test.go index 8fd69ab..48f3c2f 100644 --- a/process/export_test.go +++ b/process/export_test.go @@ -48,6 +48,11 @@ func (ei *eventsInterceptor) GetStateAccessesPerAccounts(eventsData *data.ArgsSa return ei.getStateAccessesPerAccounts(eventsData, hex.EncodeToString(eventsData.HeaderHash), eventsData.TransactionsPool) } +// GetStateAccessesPerAccountsV3 - +func (ei *eventsInterceptor) GetStateAccessesPerAccountsV3(eventsData *data.ArgsSaveBlockData) map[string]*stateChange.StateAccesses { + return ei.getStateAccessesPerAccountsV3(eventsData, hex.EncodeToString(eventsData.HeaderHash), eventsData.TransactionsPool) +} + // BaseNilEventsDataCheks - func BaseNilEventsDataCheks(eventsData *data.ArgsSaveBlockData) error { return baseNilEventsDataChecks(eventsData) diff --git a/process/preprocess/eventsPreProcessorV1.go b/process/preprocess/eventsPreProcessorV1.go index f92d862..924be8e 100644 --- a/process/preprocess/eventsPreProcessorV1.go +++ b/process/preprocess/eventsPreProcessorV1.go @@ -72,7 +72,8 @@ func (d *eventsPreProcessorV1) SaveBlock(marshalledData []byte) error { TransactionsPool: outportBlock.TransactionPool, Header: header, HeaderTimeStampMs: outportBlock.BlockData.GetTimestampMs(), - StateAccesses: outportBlock.GetStateAccessesForBlock(), + StateAccesses: outportBlock.GetStateAccesses(), + StateAccessesForBlock: outportBlock.GetStateAccessesForBlock(), Results: executionResults, } From 57b40dda541b873a218ed3b2d1403ca3357b3062 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Wed, 4 Mar 2026 12:06:45 +0200 Subject: [PATCH 42/62] add state accesses also for outport integration v0 --- data/block.go | 1 + process/preprocess/eventsPreProcessorV0.go | 1 + testdata/testData.go | 22 ++++++++++++++++++++++ 3 files changed, 24 insertions(+) diff --git a/data/block.go b/data/block.go index 6a30ae7..6d645a8 100644 --- a/data/block.go +++ b/data/block.go @@ -66,6 +66,7 @@ type OutportBlockDataOld struct { AlteredAccounts map[string]*alteredAccount.AlteredAccount NumberOfShards uint32 IsImportDB bool + StateAccesses map[string]*stateChange.StateAccesses } // ArgsSaveBlock holds block data with header type diff --git a/process/preprocess/eventsPreProcessorV0.go b/process/preprocess/eventsPreProcessorV0.go index 9e78d8e..74571a0 100644 --- a/process/preprocess/eventsPreProcessorV0.go +++ b/process/preprocess/eventsPreProcessorV0.go @@ -58,6 +58,7 @@ func (d *eventsPreProcessorV0) SaveBlock(marshalledData []byte) error { NumberOfShards: blockData.NumberOfShards, TransactionsPool: txsPool, Header: header, + StateAccesses: blockData.StateAccesses, } err = d.facade.HandlePushEvents(*saveBlockData) diff --git a/testdata/testData.go b/testdata/testData.go index 711c196..f95751f 100644 --- a/testdata/testData.go +++ b/testdata/testData.go @@ -52,6 +52,27 @@ func (bd *blockData) OldSaveBlockData() *notifierData.SaveBlockData { // OutportBlockV0 - func (bd *blockData) OutportBlockV0() *notifierData.ArgsSaveBlock { + stateAccesses := make(map[string]*stateChange.StateAccesses) + stateAccesses["txHash1"] = &stateChange.StateAccesses{ + StateAccess: []*stateChange.StateAccess{ + &stateChange.StateAccess{ + Type: stateChange.Write, + MainTrieKey: []byte("mainTrieKey1"), + MainTrieVal: []byte("mainTrieVal1"), + TxHash: []byte("txHash1"), + AccountChanges: 8, + }, + &stateChange.StateAccess{ + Type: stateChange.Write, + MainTrieKey: []byte("mainTrieKey2"), + MainTrieVal: []byte("mainTrieVal2"), + TxHash: []byte("txHash1"), + AccountChanges: 4, + }, + }, + } + stateAccesses["txHash2"] = &stateChange.StateAccesses{} + saveBlockData := data.OutportBlockDataOld{ HeaderHash: []byte("headerHash3"), Body: &block.Body{ @@ -102,6 +123,7 @@ func (bd *blockData) OutportBlockV0() *notifierData.ArgsSaveBlock { }, }, NumberOfShards: 2, + StateAccesses: stateAccesses, } return &data.ArgsSaveBlock{ From 05f3db4f1447421ab0e37cf86958993a639ff4b7 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Wed, 4 Mar 2026 12:39:42 +0200 Subject: [PATCH 43/62] small fixes --- process/eventsInterceptor.go | 2 +- process/eventsInterceptor_test.go | 2 +- testdata/testData.go | 5 ++--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/process/eventsInterceptor.go b/process/eventsInterceptor.go index 9b9bdd2..6062363 100644 --- a/process/eventsInterceptor.go +++ b/process/eventsInterceptor.go @@ -232,7 +232,7 @@ func (ei *eventsInterceptor) getStateAccessesPerAccountsV3( if stateAccessesPerBlock == nil { log.Debug("stateAccessesPerBlock failed: will return empty state accesses per accounts", "block hash", headerHash, - "num state accesses", len(eventsData.StateAccesses), + "num state accesses for block", len(eventsData.StateAccessesForBlock), ) return make(map[string]*stateChange.StateAccesses) diff --git a/process/eventsInterceptor_test.go b/process/eventsInterceptor_test.go index 871db03..f19aa0d 100644 --- a/process/eventsInterceptor_test.go +++ b/process/eventsInterceptor_test.go @@ -567,7 +567,7 @@ func TestGetLogEventsFromTransactionsPool(t *testing.T) { require.Equal(t, txHash2, receivedEvents[2].TxHash) } -func TestEventsInterceptor_GetStateAccessesPerAccountsV3(t *testing.T) { +func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { t.Parallel() txs := map[string]*outport.TxInfo{ diff --git a/testdata/testData.go b/testdata/testData.go index f95751f..4f6b896 100644 --- a/testdata/testData.go +++ b/testdata/testData.go @@ -11,7 +11,6 @@ import ( "github.com/multiversx/mx-chain-core-go/data/transaction" "github.com/multiversx/mx-chain-core-go/marshal" "github.com/multiversx/mx-chain-notifier-go/common" - "github.com/multiversx/mx-chain-notifier-go/data" notifierData "github.com/multiversx/mx-chain-notifier-go/data" ) @@ -73,7 +72,7 @@ func (bd *blockData) OutportBlockV0() *notifierData.ArgsSaveBlock { } stateAccesses["txHash2"] = &stateChange.StateAccesses{} - saveBlockData := data.OutportBlockDataOld{ + saveBlockData := notifierData.OutportBlockDataOld{ HeaderHash: []byte("headerHash3"), Body: &block.Body{ MiniBlocks: []*block.MiniBlock{ @@ -126,7 +125,7 @@ func (bd *blockData) OutportBlockV0() *notifierData.ArgsSaveBlock { StateAccesses: stateAccesses, } - return &data.ArgsSaveBlock{ + return ¬ifierData.ArgsSaveBlock{ HeaderType: "Header", OutportBlockDataOld: saveBlockData, } From ab0dac9a5ddf4df110f5779a5a33f50f522d4bf3 Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Wed, 4 Mar 2026 13:58:09 +0200 Subject: [PATCH 44/62] change config --- cmd/notifier/config/config.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/notifier/config/config.toml b/cmd/notifier/config/config.toml index fba4695..93695b3 100644 --- a/cmd/notifier/config/config.toml +++ b/cmd/notifier/config/config.toml @@ -1,7 +1,7 @@ [General] # CheckDuplicates signals if the events received from observers have been already pushed to clients # Requires a redis instance/cluster and should be used when multiple observers push from the same shard - CheckDuplicates = true + CheckDuplicates = false # WithReadStateChanges signals if read state changes operation will be handled # It depends also if read state changes are enabled from observer nodes @@ -23,7 +23,7 @@ [WebSocketConnector] # Enabled will determine if websocket connector will be enabled or not - Enabled = false + Enabled = true # URL for the WebSocket client/server connection # This value represents the IP address and port number that the WebSocket client or server will use to establish a connection. From 17e1fc0d009fce30415a3f9c46cb8bcb07b431e3 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Thu, 5 Mar 2026 11:12:49 +0200 Subject: [PATCH 45/62] remove scheduled root hash field --- data/outport.go | 1 - process/eventsHandler.go | 12 ++---------- process/eventsHandler_test.go | 1 + process/eventsInterceptor.go | 6 ++++++ 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/data/outport.go b/data/outport.go index 7ca5a73..f29b44b 100644 --- a/data/outport.go +++ b/data/outport.go @@ -81,7 +81,6 @@ type BlockStateAccesses struct { TimeStampMs uint64 `json:"timestampMs"` Nonce uint64 `json:"nonce"` RootHash []byte `json:"rootHash"` - ScheduledRootHash []byte `json:"scheduledRootHash"` StateAccessesPerAccounts map[string]*stateChange.StateAccesses `json:"stateAccessesPerAccounts"` } diff --git a/process/eventsHandler.go b/process/eventsHandler.go index 5f5e434..cc96629 100644 --- a/process/eventsHandler.go +++ b/process/eventsHandler.go @@ -104,11 +104,7 @@ func (eh *eventsHandler) handleSaveBlockEventsLegacy(allEvents data.ArgsSaveBloc headerTimeStampMs := allEvents.HeaderTimeStampMs shardID := eventsData.Header.GetShardID() nonce := eventsData.Header.GetNonce() - - var scheduledRootHash []byte - if eventsData.Header.GetAdditionalData() != nil { - scheduledRootHash = allEvents.Header.GetAdditionalData().GetScheduledRootHash() - } + rootHash := eventsData.RootHash return eh.handleSaveBlockEvents( eventsData, @@ -116,8 +112,7 @@ func (eh *eventsHandler) handleSaveBlockEventsLegacy(allEvents data.ArgsSaveBloc headerTimeStampMs, shardID, nonce, - allEvents.Header.GetRootHash(), - scheduledRootHash, + rootHash, ) } @@ -128,7 +123,6 @@ func (eh *eventsHandler) handleSaveBlockEvents( shardID uint32, nonce uint64, rootHash []byte, - scheduledRootHash []byte, ) error { if eventsData == nil { return ErrNilEventsInterceptor @@ -178,7 +172,6 @@ func (eh *eventsHandler) handleSaveBlockEvents( TimeStampMs: headerTimeStampMs, Nonce: nonce, RootHash: rootHash, - ScheduledRootHash: scheduledRootHash, StateAccessesPerAccounts: eventsData.StateAccessesPerAccounts, } eh.handleStateAccesses(stateAccesses) @@ -203,7 +196,6 @@ func (eh *eventsHandler) handleSaveBlockEventsV3(allEvents data.ArgsSaveBlockDat shardID, executionResultData.Nonce, executionResultData.RootHash, - nil, ) if err != nil { return err diff --git a/process/eventsHandler_test.go b/process/eventsHandler_test.go index 5eaab98..1c55035 100644 --- a/process/eventsHandler_test.go +++ b/process/eventsHandler_test.go @@ -340,6 +340,7 @@ func TestHandleSaveBlockEvents_ShouldWork(t *testing.T) { TxsWithOrder: expTxsWithOrder, ScrsWithOrder: expScrsWithOrder, StateAccessesPerAccounts: expStateAccessesPerAccounts, + RootHash: rootHash, }, nil }, } diff --git a/process/eventsInterceptor.go b/process/eventsInterceptor.go index a709521..f47504a 100644 --- a/process/eventsInterceptor.go +++ b/process/eventsInterceptor.go @@ -81,6 +81,11 @@ func (ei *eventsInterceptor) ProcessBlockEvents(eventsData *data.ArgsSaveBlockDa stateAccessesPerAccounts := ei.getStateAccessesPerAccounts(eventsData, hex.EncodeToString(eventsData.HeaderHash), transactionsPool) + rootHash := eventsData.Header.GetRootHash() + if eventsData.Header.GetAdditionalData() != nil { + rootHash = eventsData.Header.GetAdditionalData().GetScheduledRootHash() + } + return &data.InterceptorBlockData{ Hash: hex.EncodeToString(eventsData.HeaderHash), Body: eventsData.Body, @@ -91,6 +96,7 @@ func (ei *eventsInterceptor) ProcessBlockEvents(eventsData *data.ArgsSaveBlockDa ScrsWithOrder: transactionsPool.GetSmartContractResults(), LogEvents: events, StateAccessesPerAccounts: stateAccessesPerAccounts, + RootHash: rootHash, }, nil } From 6a10d12a920f769ed6f794739376ea109ac719ff Mon Sep 17 00:00:00 2001 From: ssd04 Date: Thu, 5 Mar 2026 11:14:21 +0200 Subject: [PATCH 46/62] revert config changes --- cmd/notifier/config/config.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/notifier/config/config.toml b/cmd/notifier/config/config.toml index 93695b3..fba4695 100644 --- a/cmd/notifier/config/config.toml +++ b/cmd/notifier/config/config.toml @@ -1,7 +1,7 @@ [General] # CheckDuplicates signals if the events received from observers have been already pushed to clients # Requires a redis instance/cluster and should be used when multiple observers push from the same shard - CheckDuplicates = false + CheckDuplicates = true # WithReadStateChanges signals if read state changes operation will be handled # It depends also if read state changes are enabled from observer nodes @@ -23,7 +23,7 @@ [WebSocketConnector] # Enabled will determine if websocket connector will be enabled or not - Enabled = true + Enabled = false # URL for the WebSocket client/server connection # This value represents the IP address and port number that the WebSocket client or server will use to establish a connection. From 119ce1a89fba70091c7ecbf0235ae8206bd84f74 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Thu, 5 Mar 2026 11:19:40 +0200 Subject: [PATCH 47/62] update core-go version --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 66cea9d..8398025 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.3 github.com/multiversx/mx-chain-communication-go v1.3.0 - github.com/multiversx/mx-chain-core-go v1.4.2-0.20260211100920-a4e12f6428cc + github.com/multiversx/mx-chain-core-go v1.4.2-0.20260219122727-014ae9f9311f github.com/multiversx/mx-chain-logger-go v1.1.0 github.com/pelletier/go-toml v1.9.3 github.com/prometheus/client_model v0.6.1 diff --git a/go.sum b/go.sum index 09eb497..1e6e71d 100644 --- a/go.sum +++ b/go.sum @@ -130,8 +130,8 @@ github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/multiversx/mx-chain-communication-go v1.3.0 h1:ziNM1dRuiR/7al2L/jGEA/a/hjurtJ/HEqgazHNt9P8= github.com/multiversx/mx-chain-communication-go v1.3.0/go.mod h1:gDVWn6zUW6aCN1YOm/FbbT5MUmhgn/L1Rmpl8EoH3Yg= -github.com/multiversx/mx-chain-core-go v1.4.2-0.20260211100920-a4e12f6428cc h1:lYAuFTp8hpoFhDaYfMyvV95JPtbdPI7Ykq128sgeaQ8= -github.com/multiversx/mx-chain-core-go v1.4.2-0.20260211100920-a4e12f6428cc/go.mod h1:IO+vspNan+gT0WOHnJ95uvWygiziHZvfXpff6KnxV7g= +github.com/multiversx/mx-chain-core-go v1.4.2-0.20260219122727-014ae9f9311f h1:kngckbX3TbZpU0LQpetUM8xNvUu/FtmZQtM66yoGcz0= +github.com/multiversx/mx-chain-core-go v1.4.2-0.20260219122727-014ae9f9311f/go.mod h1:IO+vspNan+gT0WOHnJ95uvWygiziHZvfXpff6KnxV7g= github.com/multiversx/mx-chain-crypto-go v1.3.0 h1:0eK2bkDOMi8VbSPrB1/vGJSYT81IBtfL4zw+C4sWe/k= github.com/multiversx/mx-chain-crypto-go v1.3.0/go.mod h1:nPIkxxzyTP8IquWKds+22Q2OJ9W7LtusC7cAosz7ojM= github.com/multiversx/mx-chain-logger-go v1.1.0 h1:97x84A6L4RfCa6YOx1HpAFxZp1cf/WI0Qh112whgZNM= From 6bae7ca511faeac2f8f686560b4da5ae91588146 Mon Sep 17 00:00:00 2001 From: Darius Date: Thu, 5 Mar 2026 17:04:56 +0200 Subject: [PATCH 48/62] Revert "add root hash for state accesses event" --- data/block.go | 1 - data/outport.go | 1 - go.mod | 2 +- go.sum | 6 ++- process/eventsHandler.go | 6 --- process/eventsHandler_test.go | 94 ++++++----------------------------- process/eventsInterceptor.go | 55 +++----------------- 7 files changed, 28 insertions(+), 137 deletions(-) diff --git a/data/block.go b/data/block.go index 1daafc1..6d645a8 100644 --- a/data/block.go +++ b/data/block.go @@ -32,7 +32,6 @@ type InterceptorBlockData struct { ScrsWithOrder map[string]*outport.SCRInfo LogEvents []Event StateAccessesPerAccounts map[string]*stateChange.StateAccesses - RootHash []byte Nonce uint64 TimeStampMs uint64 } diff --git a/data/outport.go b/data/outport.go index f29b44b..18ec51a 100644 --- a/data/outport.go +++ b/data/outport.go @@ -80,7 +80,6 @@ type BlockStateAccesses struct { ShardID uint32 `json:"shardID"` TimeStampMs uint64 `json:"timestampMs"` Nonce uint64 `json:"nonce"` - RootHash []byte `json:"rootHash"` StateAccessesPerAccounts map[string]*stateChange.StateAccesses `json:"stateAccessesPerAccounts"` } diff --git a/go.mod b/go.mod index 8398025..f0af130 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.3 github.com/multiversx/mx-chain-communication-go v1.3.0 - github.com/multiversx/mx-chain-core-go v1.4.2-0.20260219122727-014ae9f9311f + github.com/multiversx/mx-chain-core-go v1.4.2-0.20260210121034-184d4fbfa371 github.com/multiversx/mx-chain-logger-go v1.1.0 github.com/pelletier/go-toml v1.9.3 github.com/prometheus/client_model v0.6.1 diff --git a/go.sum b/go.sum index 1e6e71d..c170968 100644 --- a/go.sum +++ b/go.sum @@ -130,8 +130,10 @@ github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/multiversx/mx-chain-communication-go v1.3.0 h1:ziNM1dRuiR/7al2L/jGEA/a/hjurtJ/HEqgazHNt9P8= github.com/multiversx/mx-chain-communication-go v1.3.0/go.mod h1:gDVWn6zUW6aCN1YOm/FbbT5MUmhgn/L1Rmpl8EoH3Yg= -github.com/multiversx/mx-chain-core-go v1.4.2-0.20260219122727-014ae9f9311f h1:kngckbX3TbZpU0LQpetUM8xNvUu/FtmZQtM66yoGcz0= -github.com/multiversx/mx-chain-core-go v1.4.2-0.20260219122727-014ae9f9311f/go.mod h1:IO+vspNan+gT0WOHnJ95uvWygiziHZvfXpff6KnxV7g= +github.com/multiversx/mx-chain-core-go v1.4.2-0.20260119152911-59518132fb78 h1:OUkeiv36YWdbbLyLAB9g6VXKuj2N1V6iyDOrdR0rI+I= +github.com/multiversx/mx-chain-core-go v1.4.2-0.20260119152911-59518132fb78/go.mod h1:IO+vspNan+gT0WOHnJ95uvWygiziHZvfXpff6KnxV7g= +github.com/multiversx/mx-chain-core-go v1.4.2-0.20260210121034-184d4fbfa371 h1:5a94TjX7IG7K4zKO87SF3D4gzfNiy56RCAM+Qw9M4TY= +github.com/multiversx/mx-chain-core-go v1.4.2-0.20260210121034-184d4fbfa371/go.mod h1:IO+vspNan+gT0WOHnJ95uvWygiziHZvfXpff6KnxV7g= github.com/multiversx/mx-chain-crypto-go v1.3.0 h1:0eK2bkDOMi8VbSPrB1/vGJSYT81IBtfL4zw+C4sWe/k= github.com/multiversx/mx-chain-crypto-go v1.3.0/go.mod h1:nPIkxxzyTP8IquWKds+22Q2OJ9W7LtusC7cAosz7ojM= github.com/multiversx/mx-chain-logger-go v1.1.0 h1:97x84A6L4RfCa6YOx1HpAFxZp1cf/WI0Qh112whgZNM= diff --git a/process/eventsHandler.go b/process/eventsHandler.go index cc96629..0652983 100644 --- a/process/eventsHandler.go +++ b/process/eventsHandler.go @@ -104,7 +104,6 @@ func (eh *eventsHandler) handleSaveBlockEventsLegacy(allEvents data.ArgsSaveBloc headerTimeStampMs := allEvents.HeaderTimeStampMs shardID := eventsData.Header.GetShardID() nonce := eventsData.Header.GetNonce() - rootHash := eventsData.RootHash return eh.handleSaveBlockEvents( eventsData, @@ -112,7 +111,6 @@ func (eh *eventsHandler) handleSaveBlockEventsLegacy(allEvents data.ArgsSaveBloc headerTimeStampMs, shardID, nonce, - rootHash, ) } @@ -122,7 +120,6 @@ func (eh *eventsHandler) handleSaveBlockEvents( headerTimeStampMs uint64, shardID uint32, nonce uint64, - rootHash []byte, ) error { if eventsData == nil { return ErrNilEventsInterceptor @@ -171,7 +168,6 @@ func (eh *eventsHandler) handleSaveBlockEvents( ShardID: shardID, TimeStampMs: headerTimeStampMs, Nonce: nonce, - RootHash: rootHash, StateAccessesPerAccounts: eventsData.StateAccessesPerAccounts, } eh.handleStateAccesses(stateAccesses) @@ -195,7 +191,6 @@ func (eh *eventsHandler) handleSaveBlockEventsV3(allEvents data.ArgsSaveBlockDat executionResultData.TimeStampMs, shardID, executionResultData.Nonce, - executionResultData.RootHash, ) if err != nil { return err @@ -389,7 +384,6 @@ func (eh *eventsHandler) handleStateAccesses(stateAccesses data.BlockStateAccess log.Info("received state accesses", "block hash", stateAccesses.Hash, "nonce", stateAccesses.Nonce, - "rootHash", stateAccesses.RootHash, "stateAccesesPerAccounts num", len(stateAccesses.StateAccessesPerAccounts), ) diff --git a/process/eventsHandler_test.go b/process/eventsHandler_test.go index 1c55035..73f0ffc 100644 --- a/process/eventsHandler_test.go +++ b/process/eventsHandler_test.go @@ -2,7 +2,6 @@ package process_test import ( "context" - "encoding/hex" "errors" "testing" @@ -10,7 +9,6 @@ import ( "github.com/multiversx/mx-chain-core-go/data/block" "github.com/multiversx/mx-chain-core-go/data/outport" "github.com/multiversx/mx-chain-core-go/data/smartContractResult" - "github.com/multiversx/mx-chain-core-go/data/stateChange" "github.com/multiversx/mx-chain-core-go/data/transaction" "github.com/multiversx/mx-chain-notifier-go/common" "github.com/multiversx/mx-chain-notifier-go/data" @@ -218,25 +216,6 @@ func TestHandleSaveBlockEvents_ShouldWork(t *testing.T) { }, } - stateAccesses := make(map[string]*stateChange.StateAccesses) - stateAccesses["txHash1"] = &stateChange.StateAccesses{ - StateAccess: []*stateChange.StateAccess{ - { - Type: stateChange.Write, - MainTrieKey: []byte("mainTrieKey1"), - MainTrieVal: []byte("mainTrieVal1"), - }, - { - Type: stateChange.Write, - MainTrieKey: []byte("mainTrieKey2"), - MainTrieVal: []byte("mainTrieVal2"), - }, - }, - } - stateAccesses["txHash2"] = &stateChange.StateAccesses{} - - rootHash := []byte("rootHash1") - expTxs := map[string]*transaction.Transaction{ "hash1": { Nonce: 1, @@ -285,39 +264,12 @@ func TestHandleSaveBlockEvents_ShouldWork(t *testing.T) { Events: logEvents, } - expStateAccessesPerAccounts := make(map[string]*stateChange.StateAccesses) - expStateAccessesPerAccounts[hex.EncodeToString([]byte("mainTrieKey1"))] = &stateChange.StateAccesses{ - StateAccess: []*stateChange.StateAccess{ - { - Type: stateChange.Write, - MainTrieKey: []byte("mainTrieKey1"), - MainTrieVal: []byte("mainTrieVal1"), - }, - }, - } - expStateAccessesPerAccounts[hex.EncodeToString([]byte("mainTrieKey2"))] = &stateChange.StateAccesses{ - StateAccess: []*stateChange.StateAccess{ - { - Type: stateChange.Write, - MainTrieKey: []byte("mainTrieKey2"), - MainTrieVal: []byte("mainTrieVal2"), - }, - }, - } - expStateAccesses := data.BlockStateAccesses{ - Hash: blockHash, - ShardID: 2, - RootHash: rootHash, - StateAccessesPerAccounts: expStateAccessesPerAccounts, - } - t.Run("should work before header v3", func(t *testing.T) { t.Parallel() header := &block.HeaderV2{ Header: &block.Header{ - ShardID: 2, - RootHash: rootHash, + ShardID: 2, }, } @@ -325,22 +277,19 @@ func TestHandleSaveBlockEvents_ShouldWork(t *testing.T) { txsWasCalled := false scrsWasCalled := false blockEventsWithOrderWasCalled := false - stateAccessesWasCalled := false args := createMockEventsHandlerArgs() args.EventsInterceptor = &mocks.EventsInterceptorStub{ ProcessBlockEventsCalled: func(eventsData *data.ArgsSaveBlockData) (*data.InterceptorBlockData, error) { return &data.InterceptorBlockData{ - Hash: blockHash, - Header: header, - Txs: expTxs, - Scrs: expScrs, - LogEvents: logEvents, - TxsWithOrder: expTxsWithOrder, - ScrsWithOrder: expScrsWithOrder, - StateAccessesPerAccounts: expStateAccessesPerAccounts, - RootHash: rootHash, + Hash: blockHash, + Header: header, + Txs: expTxs, + Scrs: expScrs, + LogEvents: logEvents, + TxsWithOrder: expTxsWithOrder, + ScrsWithOrder: expScrsWithOrder, }, nil }, } @@ -362,10 +311,6 @@ func TestHandleSaveBlockEvents_ShouldWork(t *testing.T) { blockEventsWithOrderWasCalled = true assert.Equal(t, expTxsWithOrderData, event) }, - BroadcastStateAccessesCalled: func(event data.BlockStateAccesses) { - stateAccessesWasCalled = true - assert.Equal(t, expStateAccesses, event) - }, } eventsHandler, err := process.NewEventsHandler(args) @@ -388,7 +333,6 @@ func TestHandleSaveBlockEvents_ShouldWork(t *testing.T) { assert.True(t, txsWasCalled) assert.True(t, scrsWasCalled) assert.True(t, blockEventsWithOrderWasCalled) - assert.True(t, stateAccessesWasCalled) }) t.Run("should work with header v3", func(t *testing.T) { @@ -402,7 +346,6 @@ func TestHandleSaveBlockEvents_ShouldWork(t *testing.T) { txsWasCalled := false scrsWasCalled := false blockEventsWithOrderWasCalled := false - stateAccessesWasCalled := false args := createMockEventsHandlerArgs() @@ -414,15 +357,13 @@ func TestHandleSaveBlockEvents_ShouldWork(t *testing.T) { ProcessBlockEventsV3Called: func(eventsData *data.ArgsSaveBlockData) ([]*data.InterceptorBlockData, error) { return []*data.InterceptorBlockData{ { - Hash: blockHash, - Header: header, - Txs: expTxs, - Scrs: expScrs, - LogEvents: logEvents, - TxsWithOrder: expTxsWithOrder, - ScrsWithOrder: expScrsWithOrder, - StateAccessesPerAccounts: expStateAccessesPerAccounts, - RootHash: rootHash, + Hash: blockHash, + Header: header, + Txs: expTxs, + Scrs: expScrs, + LogEvents: logEvents, + TxsWithOrder: expTxsWithOrder, + ScrsWithOrder: expScrsWithOrder, }, }, nil }, @@ -445,10 +386,6 @@ func TestHandleSaveBlockEvents_ShouldWork(t *testing.T) { blockEventsWithOrderWasCalled = true assert.Equal(t, expTxsWithOrderData, event) }, - BroadcastStateAccessesCalled: func(event data.BlockStateAccesses) { - stateAccessesWasCalled = true - assert.Equal(t, expStateAccesses, event) - }, } eventsHandler, err := process.NewEventsHandler(args) @@ -471,7 +408,6 @@ func TestHandleSaveBlockEvents_ShouldWork(t *testing.T) { assert.True(t, txsWasCalled) assert.True(t, scrsWasCalled) assert.True(t, blockEventsWithOrderWasCalled) - assert.True(t, stateAccessesWasCalled) }) } diff --git a/process/eventsInterceptor.go b/process/eventsInterceptor.go index f47504a..6062363 100644 --- a/process/eventsInterceptor.go +++ b/process/eventsInterceptor.go @@ -4,7 +4,6 @@ import ( "encoding/hex" "fmt" "sort" - "strings" "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/core/check" @@ -81,11 +80,6 @@ func (ei *eventsInterceptor) ProcessBlockEvents(eventsData *data.ArgsSaveBlockDa stateAccessesPerAccounts := ei.getStateAccessesPerAccounts(eventsData, hex.EncodeToString(eventsData.HeaderHash), transactionsPool) - rootHash := eventsData.Header.GetRootHash() - if eventsData.Header.GetAdditionalData() != nil { - rootHash = eventsData.Header.GetAdditionalData().GetScheduledRootHash() - } - return &data.InterceptorBlockData{ Hash: hex.EncodeToString(eventsData.HeaderHash), Body: eventsData.Body, @@ -96,7 +90,6 @@ func (ei *eventsInterceptor) ProcessBlockEvents(eventsData *data.ArgsSaveBlockDa ScrsWithOrder: transactionsPool.GetSmartContractResults(), LogEvents: events, StateAccessesPerAccounts: stateAccessesPerAccounts, - RootHash: rootHash, }, nil } @@ -142,7 +135,6 @@ func (ei *eventsInterceptor) ProcessBlockEventsV3(eventsData *data.ArgsSaveBlock ScrsWithOrder: transactionsPool.GetSmartContractResults(), LogEvents: events, StateAccessesPerAccounts: stateAccessesPerAccounts, - RootHash: execBlockData.GetRootHash(), Nonce: execBlockData.GetHeaderNonce(), TimeStampMs: execBlockData.GetTimestampMs(), } @@ -296,29 +288,11 @@ func (ei *eventsInterceptor) fetchStateAccessesPerAccounts( } } - logStateAccessesPerAccounts(stateAccessesPerAccounts) - - return stateAccessesPerAccounts -} - -func logStateAccessesPerAccounts(stateAccesses map[string]*stateChange.StateAccesses) { - if log.GetLevel() > logger.LogTrace { - return - } - - log.Trace("state accesses per accounts", - "num stateAccessesPerAccounts", len(stateAccesses), + log.Trace("getStateAccessesPerAccounts", + "num stateAccessesPerAccounts", len(stateAccessesPerAccounts), ) - for accKey, sts := range stateAccesses { - log.Trace("stateAccessesPerAccount", - "account", accKey, - "num stateAccesses", len(sts.StateAccess), - ) - for _, st := range sts.StateAccess { - log.Trace("state access", "stateChange", stateAccessToString(st)) - } - } + return stateAccessesPerAccounts } func logStateAccessesPerTxs(stateAccesses map[string]*stateChange.StateAccesses) { @@ -326,7 +300,7 @@ func logStateAccessesPerTxs(stateAccesses map[string]*stateChange.StateAccesses) return } - log.Trace("state accesses per transaction", + log.Trace("getStateAccessesPerAccounts", "num stateAccessesPerTxs", len(stateAccesses), ) @@ -336,27 +310,14 @@ func logStateAccessesPerTxs(stateAccesses map[string]*stateChange.StateAccesses) ) for _, st := range sts.StateAccess { - log.Trace("state access", "stateChange", stateAccessToString(st)) + log.Trace("st", + "actionType", st.GetType(), + "operation", st.GetOperation(), + ) } } } -func stateAccessToString(stateAccess *stateChange.StateAccess) string { - dataTrieChanges := make([]string, len(stateAccess.GetDataTrieChanges())) - for i, dataTrieChange := range stateAccess.GetDataTrieChanges() { - dataTrieChanges[i] = fmt.Sprintf("key: %v, val: %v, type: %v, operation %v, version %v", hex.EncodeToString(dataTrieChange.Key), hex.EncodeToString(dataTrieChange.Val), dataTrieChange.Type, dataTrieChange.Operation, dataTrieChange.Version) - } - return fmt.Sprintf("type: %v, operation: %v, mainTrieKey: %v, mainTrieVal: %v, index: %v, dataTrieChanges: %v, accountChanges %v", - stateAccess.GetType(), - stateAccess.GetOperation(), - hex.EncodeToString(stateAccess.GetMainTrieKey()), - hex.EncodeToString(stateAccess.GetMainTrieVal()), - stateAccess.GetIndex(), - strings.Join(dataTrieChanges, ", "), - stateAccess.GetAccountChanges(), - ) -} - func (ei *eventsInterceptor) getLogEventsFromTransactionsPool(logs []*transaction.LogData) []data.Event { var logEvents []*logEvent for _, logData := range logs { From 4c619f12a1fd9ea990e1a560a312ae910cf43020 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Thu, 5 Mar 2026 17:19:06 +0200 Subject: [PATCH 49/62] update core-go version --- go.mod | 2 +- go.sum | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index f0af130..8398025 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.3 github.com/multiversx/mx-chain-communication-go v1.3.0 - github.com/multiversx/mx-chain-core-go v1.4.2-0.20260210121034-184d4fbfa371 + github.com/multiversx/mx-chain-core-go v1.4.2-0.20260219122727-014ae9f9311f github.com/multiversx/mx-chain-logger-go v1.1.0 github.com/pelletier/go-toml v1.9.3 github.com/prometheus/client_model v0.6.1 diff --git a/go.sum b/go.sum index c170968..1e6e71d 100644 --- a/go.sum +++ b/go.sum @@ -130,10 +130,8 @@ github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/multiversx/mx-chain-communication-go v1.3.0 h1:ziNM1dRuiR/7al2L/jGEA/a/hjurtJ/HEqgazHNt9P8= github.com/multiversx/mx-chain-communication-go v1.3.0/go.mod h1:gDVWn6zUW6aCN1YOm/FbbT5MUmhgn/L1Rmpl8EoH3Yg= -github.com/multiversx/mx-chain-core-go v1.4.2-0.20260119152911-59518132fb78 h1:OUkeiv36YWdbbLyLAB9g6VXKuj2N1V6iyDOrdR0rI+I= -github.com/multiversx/mx-chain-core-go v1.4.2-0.20260119152911-59518132fb78/go.mod h1:IO+vspNan+gT0WOHnJ95uvWygiziHZvfXpff6KnxV7g= -github.com/multiversx/mx-chain-core-go v1.4.2-0.20260210121034-184d4fbfa371 h1:5a94TjX7IG7K4zKO87SF3D4gzfNiy56RCAM+Qw9M4TY= -github.com/multiversx/mx-chain-core-go v1.4.2-0.20260210121034-184d4fbfa371/go.mod h1:IO+vspNan+gT0WOHnJ95uvWygiziHZvfXpff6KnxV7g= +github.com/multiversx/mx-chain-core-go v1.4.2-0.20260219122727-014ae9f9311f h1:kngckbX3TbZpU0LQpetUM8xNvUu/FtmZQtM66yoGcz0= +github.com/multiversx/mx-chain-core-go v1.4.2-0.20260219122727-014ae9f9311f/go.mod h1:IO+vspNan+gT0WOHnJ95uvWygiziHZvfXpff6KnxV7g= github.com/multiversx/mx-chain-crypto-go v1.3.0 h1:0eK2bkDOMi8VbSPrB1/vGJSYT81IBtfL4zw+C4sWe/k= github.com/multiversx/mx-chain-crypto-go v1.3.0/go.mod h1:nPIkxxzyTP8IquWKds+22Q2OJ9W7LtusC7cAosz7ojM= github.com/multiversx/mx-chain-logger-go v1.1.0 h1:97x84A6L4RfCa6YOx1HpAFxZp1cf/WI0Qh112whgZNM= From 3cbc0340e3e3188a913a704043d8896996e55aa1 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Fri, 6 Mar 2026 12:50:04 +0200 Subject: [PATCH 50/62] ws vs http integration distinction --- README.md | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 2cfce9d..9798420 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ The notifier service is a component that receives block events synchronously from multiversx observer nodes, and it forwards them to a subscribing component -(via message queuing service or websockets) +(via message queuing service or websockets). ## Prerequisites @@ -11,15 +11,12 @@ has to setup one or multiple observers. For running an observing squad, these [docs](https://docs.multiversx.com/integrators/observing-squad/) cover the whole process. -The observer node can be connected using WebSocket integration. Please check observer -node config for setting up the connector. Enable `HostDriversConfig` in order to use -WebSocket integration. +There are two ways the observer nodes can push data to the notifier service: -The required configs for launching an observer/s with a driver attached, -can be found [here](https://github.com/multiversx/mx-chain-go/blob/master/cmd/node/config/external.toml). +1. **WebSocket Integration (Recommended)**: The observer node pushes events to the notifier over a persistent WebSocket connection. This is the newer, more efficient method. To use this, check the observer node config and enable `HostDriversConfig`. + The required configs for launching an observer/s with a WS driver attached can be found [here](https://github.com/multiversx/mx-chain-go/blob/master/cmd/node/config/external.toml). -The HTTP integration is still available for backwards compatibility, but it will be -deprecated in the future. +2. **HTTP POST Integration (Deprecated)**: The observer node makes separate HTTP POST requests to the notifier's API endpoints (`/events/push`, etc.) for every event. This integration is still available for backwards compatibility, but it will be deprecated in the future. ## How to run @@ -131,15 +128,21 @@ make docker-new publisher_type=rabbitmq ### API Endpoints -Notifier service will expose several events routes, the observer nodes will -push events to these routes: +Depending on the observer integration method chosen, the notifier service will expose the following routes. + +**For WebSocket Integration (Observer -> Notifier):** +When using the WebSocket integration, the observer pushes all events through a single persistent WebSocket connection rather than relying on the HTTP routes above. + +**For HTTP POST Integration (Observer -> Notifier):** +The observer nodes will push events to these routes via consecutive HTTP requests: - `/events/push` (POST) -> it will handle all events for each round - `/events/revert` (POST) -> if there is a reverted block, the event will be pushed on this route - `/events/finalized` (POST) -> when the block has been finalized, the events will be pushed on this route -If the service will be in "notifier" mode, it will expose a additional route: +**For Client Subscriptions (Notifier -> Consumer):** +If the service will be in "notifier" mode (using the `ws` publisher), it will expose an additional route for end consumers to receive data: - `/hub/ws` (GET) - this route can be used to manage the websocket connection (check [websocket subscribing](#websockets) section for more details on this) ## Redis From 3477a5e7035d3dcd57f1660e6a5eb0815850b45c Mon Sep 17 00:00:00 2001 From: ssd04 Date: Fri, 6 Mar 2026 13:16:23 +0200 Subject: [PATCH 51/62] update event types section --- README.md | 167 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 106 insertions(+), 61 deletions(-) diff --git a/README.md b/README.md index 9798420..a210242 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,8 @@ The supported config variables are: as the one specified in the `ProxyUrl` described above. - `Username`: the username used to authorize an observer. Can be left empty for `UseAuthorization = false` on observer connector. - `Password`: the password used to authorize an observer. Can be left empty for `UseAuthorization = false` on observer connector. +- `CheckDuplicates`: signals if the events received from observers have already been pushed to clients. Requires a Redis instance/cluster. +- `WithReadStateChanges`: signals if read state changes operations will be handled by the notifier. Note: this requires read state changes to also be enabled on the observer nodes. If observer connector is set to use BasicAuth with `UseAuthorization = true`, `Username` and `Password` has to be set here on events notifier, and `Auth` flag has to be enabled in @@ -169,10 +171,113 @@ in code in `data/outport.go` file. Once the proxy is launched together with the observer/s, the driver's methods will be called. +### Event types + +There are multiple event types available, they can be found as constants in common package, +[constants](https://github.com/multiversx/mx-chain-notifier-go/blob/main/common/constants.go). +Below is the list of available event types together with their associated JSON payload structures. + +- `all_events`: Pushes all logs and events for a block. +```json +{ + "hash": "blockHash1", + "events": [ + { + "address": "addr1", + "identifier": "identifier", + "topics": ["topic1", "topic2"], + "data": "data", + ... + } + ] +} +``` + +- `block_events`: Pushes block info alongside its logs and events. +```json +{ + "hash": "blockHash1", + "shardId": 1, + "timestamp": 12345678, + "timestampMs": 12345678000, + "events": [ + { + "address": "addr1", + "identifier": "identifier", + ... + } + ] +} +``` + +- `revert_events`: Pushes information relating to a reverted block. +```json +{ + "hash": "blockHash1", + "nonce": 11, + "round": 2, + "epoch": 1, + "shardId": 1, + "timestamp": 12345678, + "timestampMs": 12345678000 +} +``` + +- `finalized_events`: Pushes the hash of a finalized block. +```json +{ + "hash": "blockHash" +} +``` + +- `block_txs`: Pushes all transactions contained within a block. +```json +{ + "hash": "blockHash1", + "txs": { + "txHash1": { + "Nonce": 123, + "Round": 1, + "Epoch": 1, + ... + } + } +} +``` + +- `block_scrs`: Pushes all smart contract results contained within a block. +```json +{ + "hash": "blockHash1", + "scrs": { + "scrHash1": { + "Nonce": 123, + ... + } + } +} +``` + +- `block_state_accesses`: Pushes information regarding the state accesses (reads/writes) occurring within a block. *(Requires `WithReadStateChanges` config enabled)* +```json +{ + "hash": "blockHash1", + "shardID": 1, + "timestampMs": 12345678000, + "nonce": 123, + "stateAccessesPerAccounts": { + "erd1...": { + "reads": [...], + "writes": [...] + } + } +} +``` + ### RabbitMQ When using a setup with `RabbitMQ` you have to subscribe to each exchange -separately. +separately. This can be handled via RabbitMQ Management UI platform. ### WebSockets @@ -298,63 +403,3 @@ inner marshalled data like: } ``` -There are multiple event types available, they can be found as constants in common package, -[constants](https://github.com/multiversx/mx-chain-notifier-go/blob/main/common/constants.go). Below there is the event type together with the associated marshalled data type. -- `all_events` -```json -{ - "hash": "blockHash1", - "events": [ - { - "address": "addr1", - "identifier": "identifier", - ... - } - ] -} -``` - -- `revert_events` -```json -{ - "hash": "blockHash1", - "nonce": 11, - "round": 2, - "epoch": 1, -} -``` - -- `finalized_events` -```json -{ - "hash": "blockHash" -} -``` - -- `block_txs`: -```json -{ - "hash": "blockHash1", - "txs": { - "txHash1": { - "Nonce": 123, - "Round": 1, - "Epoch": 1, - ... - } - } -} -``` - -- `block_scrs` -```json -{ - "hash": "blockHash1", - "scrs": { - "scrHash1": { - "Nonce": 123, - ... - } - } -} -``` From ba48f436177c339f6223655ba8027163b234be00 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Fri, 6 Mar 2026 15:28:24 +0200 Subject: [PATCH 52/62] fixes after review --- README.md | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index a210242..b567918 100644 --- a/README.md +++ b/README.md @@ -133,7 +133,7 @@ make docker-new publisher_type=rabbitmq Depending on the observer integration method chosen, the notifier service will expose the following routes. **For WebSocket Integration (Observer -> Notifier):** -When using the WebSocket integration, the observer pushes all events through a single persistent WebSocket connection rather than relying on the HTTP routes above. +When using the WebSocket integration, the observer pushes all events through a single persistent WebSocket connection rather than relying on the HTTP routes below. **For HTTP POST Integration (Observer -> Notifier):** The observer nodes will push events to these routes via consecutive HTTP requests: @@ -145,7 +145,7 @@ The observer nodes will push events to these routes via consecutive HTTP request **For Client Subscriptions (Notifier -> Consumer):** If the service will be in "notifier" mode (using the `ws` publisher), it will expose an additional route for end consumers to receive data: -- `/hub/ws` (GET) - this route can be used to manage the websocket connection (check [websocket subscribing](#websockets) section for more details on this) +- `/hub/ws` (GET) - this route can be used to manage the WebSocket connection (check [websocket subscribing](#websockets) section for more details on this) ## Redis @@ -185,8 +185,8 @@ Below is the list of available event types together with their associated JSON p { "address": "addr1", "identifier": "identifier", - "topics": ["topic1", "topic2"], - "data": "data", + "topics": ["<< base64 encoded topic1 >>", "<< base64 encoded topic2 >>"], + "data": "<< base64 encoded data >> ", ... } ] @@ -266,10 +266,7 @@ Below is the list of available event types together with their associated JSON p "timestampMs": 12345678000, "nonce": 123, "stateAccessesPerAccounts": { - "erd1...": { - "reads": [...], - "writes": [...] - } + ... } } ``` From f9c2dfb9c990765bd81c431018dd9e7f6b0c2f18 Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Mon, 16 Mar 2026 13:17:31 +0200 Subject: [PATCH 53/62] fix header gas consumption check --- process/preprocess/eventsPreProcessorV1.go | 28 +++++++++++++++------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/process/preprocess/eventsPreProcessorV1.go b/process/preprocess/eventsPreProcessorV1.go index 924be8e..b5def19 100644 --- a/process/preprocess/eventsPreProcessorV1.go +++ b/process/preprocess/eventsPreProcessorV1.go @@ -5,6 +5,7 @@ import ( "errors" "github.com/multiversx/mx-chain-core-go/core" + coreData "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/outport" "github.com/multiversx/mx-chain-notifier-go/data" ) @@ -44,9 +45,8 @@ func (d *eventsPreProcessorV1) SaveBlock(marshalledData []byte) error { return err } - err = checkBlockDataValid(outportBlock) - if err != nil { - return err + if outportBlock.BlockData == nil { + return ErrNilBlockData } headerType := core.HeaderType(outportBlock.BlockData.HeaderType) @@ -56,6 +56,11 @@ func (d *eventsPreProcessorV1) SaveBlock(marshalledData []byte) error { return err } + err = checkHeaderGasConsumption(header, outportBlock) + if err != nil { + return err + } + var executionResults map[string]*outport.ExecutionResultData if header.IsHeaderV3() { executionResults = outportBlock.BlockData.Results @@ -85,12 +90,19 @@ func (d *eventsPreProcessorV1) SaveBlock(marshalledData []byte) error { return nil } -func checkBlockDataValid(block *outport.OutportBlock) error { - if block.BlockData == nil { - return ErrNilBlockData +func checkHeaderGasConsumption(header coreData.HeaderHandler, block *outport.OutportBlock) error { + if !header.IsHeaderV3() { + if block.HeaderGasConsumption == nil { + return ErrNilHeaderGasConsumption + } + + return nil } - if block.HeaderGasConsumption == nil { - return ErrNilHeaderGasConsumption + + for _, execRes := range block.BlockData.Results { + if execRes.HeaderGasConsumption == nil { + return ErrNilHeaderGasConsumption + } } return nil From e17536d55dae0ca314e43ec7a9b3ede5ff77606f Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Mon, 16 Mar 2026 13:24:13 +0200 Subject: [PATCH 54/62] fix test --- testdata/testData.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/testdata/testData.go b/testdata/testData.go index 4f6b896..a090cf9 100644 --- a/testdata/testData.go +++ b/testdata/testData.go @@ -294,12 +294,14 @@ func (bd *blockData) OutportBlockV2() *outport.OutportBlock { execResults := map[string]*outport.ExecutionResultData{ hex.EncodeToString(execBlockHash): { - Body: blockBody, - TransactionPool: execResTxPool, + Body: blockBody, + TransactionPool: execResTxPool, + HeaderGasConsumption: &outport.HeaderGasConsumption{}, }, hex.EncodeToString(execBlockHash2): { - Body: blockBody, - TransactionPool: execResTxPool, + Body: blockBody, + TransactionPool: execResTxPool, + HeaderGasConsumption: &outport.HeaderGasConsumption{}, }, } From 804b69b47e21b4125a561668333758bd575039a9 Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Mon, 16 Mar 2026 13:32:04 +0200 Subject: [PATCH 55/62] add nil check for execRes --- process/preprocess/eventsPreProcessorV1.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/process/preprocess/eventsPreProcessorV1.go b/process/preprocess/eventsPreProcessorV1.go index b5def19..060ff32 100644 --- a/process/preprocess/eventsPreProcessorV1.go +++ b/process/preprocess/eventsPreProcessorV1.go @@ -100,6 +100,9 @@ func checkHeaderGasConsumption(header coreData.HeaderHandler, block *outport.Out } for _, execRes := range block.BlockData.Results { + if execRes == nil { + continue + } if execRes.HeaderGasConsumption == nil { return ErrNilHeaderGasConsumption } From bdc53da8603b030159903d8f69f86afe49dabed4 Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Tue, 17 Mar 2026 15:10:02 +0200 Subject: [PATCH 56/62] do not WARN if no state change found for SCR tx --- process/eventsInterceptor.go | 53 ++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 14 deletions(-) diff --git a/process/eventsInterceptor.go b/process/eventsInterceptor.go index 6062363..1a0f3e6 100644 --- a/process/eventsInterceptor.go +++ b/process/eventsInterceptor.go @@ -16,9 +16,19 @@ import ( "github.com/multiversx/mx-chain-notifier-go/data" ) +type TxType int + +const ( + Transaction TxType = iota + SCR + Reward + InvalidTx +) + type txWithOrder struct { - hash string - index uint32 + hash string + index uint32 + txType TxType } // logEvent defines a log event associated with corresponding tx hash @@ -166,26 +176,35 @@ func getTxsFromPool(transactionsPool *outport.TransactionPool) map[string]*trans } func getTxsWithOrder(transactionsPool *outport.TransactionPool) []txWithOrder { - txsWithOrderMap := make(map[string]uint32) + numTxs := len(transactionsPool.Transactions) + len(transactionsPool.SmartContractResults) + len(transactionsPool.Rewards) + len(transactionsPool.InvalidTxs) + txsWithOrder := make([]txWithOrder, 0, numTxs) for txHash, txInfo := range transactionsPool.Transactions { - txsWithOrderMap[txHash] = txInfo.ExecutionOrder + txsWithOrder = append(txsWithOrder, txWithOrder{ + hash: txHash, + index: txInfo.ExecutionOrder, + txType: Transaction, + }) } for txHash, txInfo := range transactionsPool.SmartContractResults { - txsWithOrderMap[txHash] = txInfo.ExecutionOrder + txsWithOrder = append(txsWithOrder, txWithOrder{ + hash: txHash, + index: txInfo.ExecutionOrder, + txType: SCR, + }) } for txHash, txInfo := range transactionsPool.Rewards { - txsWithOrderMap[txHash] = txInfo.ExecutionOrder + txsWithOrder = append(txsWithOrder, txWithOrder{ + hash: txHash, + index: txInfo.ExecutionOrder, + txType: Reward, + }) } for txHash, txInfo := range transactionsPool.InvalidTxs { - txsWithOrderMap[txHash] = txInfo.ExecutionOrder - } - - txsWithOrder := make([]txWithOrder, 0, len(txsWithOrderMap)) - for txHash, index := range txsWithOrderMap { txsWithOrder = append(txsWithOrder, txWithOrder{ - hash: txHash, - index: index, + hash: txHash, + index: txInfo.ExecutionOrder, + txType: InvalidTx, }) } @@ -267,7 +286,13 @@ func (ei *eventsInterceptor) fetchStateAccessesPerAccounts( stateAccessesPerTx, ok := stateAccesses[string(txHash)] if !ok { - log.Warn("did not find state accesses for tx", "txHash", txInfo.hash) + if txInfo.txType == SCR { + // there are cases when SCRs are generated but no state accesses are produced, so we will not log a warning in those cases + log.Trace("SCR with no state accesses", "txHash", txInfo.hash) + continue + } + + log.Warn("did not find state accesses for tx", "txHash", txInfo.hash, "txType", txInfo.txType) continue } From fa4a91624e6e1fb7350b180e8c7741ff37dbaa87 Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Tue, 17 Mar 2026 15:12:43 +0200 Subject: [PATCH 57/62] add missing comment --- process/eventsInterceptor.go | 1 + 1 file changed, 1 insertion(+) diff --git a/process/eventsInterceptor.go b/process/eventsInterceptor.go index 1a0f3e6..6501ce0 100644 --- a/process/eventsInterceptor.go +++ b/process/eventsInterceptor.go @@ -16,6 +16,7 @@ import ( "github.com/multiversx/mx-chain-notifier-go/data" ) +// TxType defines the type of transaction used for ordering state accesses type TxType int const ( From 2665bb7a8e4844c9938082e63207aa1bfa7635d4 Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Tue, 17 Mar 2026 15:15:31 +0200 Subject: [PATCH 58/62] unexport constants --- process/eventsInterceptor.go | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/process/eventsInterceptor.go b/process/eventsInterceptor.go index 6501ce0..4b34246 100644 --- a/process/eventsInterceptor.go +++ b/process/eventsInterceptor.go @@ -16,20 +16,19 @@ import ( "github.com/multiversx/mx-chain-notifier-go/data" ) -// TxType defines the type of transaction used for ordering state accesses -type TxType int +type txType int const ( - Transaction TxType = iota - SCR - Reward - InvalidTx + normalTx txType = iota + scr + rewardTx + invalidTx ) type txWithOrder struct { hash string index uint32 - txType TxType + txType txType } // logEvent defines a log event associated with corresponding tx hash @@ -184,28 +183,28 @@ func getTxsWithOrder(transactionsPool *outport.TransactionPool) []txWithOrder { txsWithOrder = append(txsWithOrder, txWithOrder{ hash: txHash, index: txInfo.ExecutionOrder, - txType: Transaction, + txType: normalTx, }) } for txHash, txInfo := range transactionsPool.SmartContractResults { txsWithOrder = append(txsWithOrder, txWithOrder{ hash: txHash, index: txInfo.ExecutionOrder, - txType: SCR, + txType: scr, }) } for txHash, txInfo := range transactionsPool.Rewards { txsWithOrder = append(txsWithOrder, txWithOrder{ hash: txHash, index: txInfo.ExecutionOrder, - txType: Reward, + txType: rewardTx, }) } for txHash, txInfo := range transactionsPool.InvalidTxs { txsWithOrder = append(txsWithOrder, txWithOrder{ hash: txHash, index: txInfo.ExecutionOrder, - txType: InvalidTx, + txType: invalidTx, }) } @@ -287,7 +286,7 @@ func (ei *eventsInterceptor) fetchStateAccessesPerAccounts( stateAccessesPerTx, ok := stateAccesses[string(txHash)] if !ok { - if txInfo.txType == SCR { + if txInfo.txType == scr { // there are cases when SCRs are generated but no state accesses are produced, so we will not log a warning in those cases log.Trace("SCR with no state accesses", "txHash", txInfo.hash) continue From aee1394a6cb7f8475e6444ca89f07f99d765b70b Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Thu, 19 Mar 2026 14:43:51 +0200 Subject: [PATCH 59/62] remove duplicated txs --- process/eventsInterceptor.go | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/process/eventsInterceptor.go b/process/eventsInterceptor.go index 4b34246..5777c60 100644 --- a/process/eventsInterceptor.go +++ b/process/eventsInterceptor.go @@ -176,36 +176,44 @@ func getTxsFromPool(transactionsPool *outport.TransactionPool) map[string]*trans } func getTxsWithOrder(transactionsPool *outport.TransactionPool) []txWithOrder { - numTxs := len(transactionsPool.Transactions) + len(transactionsPool.SmartContractResults) + len(transactionsPool.Rewards) + len(transactionsPool.InvalidTxs) - txsWithOrder := make([]txWithOrder, 0, numTxs) + // This map is needed because of duplicated transactions. + // There can be a case when a transaction is included in the block, but also marked as invalid, so it will be present + // in both transactions and invalidTxs maps from transactions pool, with the same execution order. In that case, + // we want to make sure that we process that transaction only as invalid. + txsWithOrderMap := make(map[string]txWithOrder) for txHash, txInfo := range transactionsPool.Transactions { - txsWithOrder = append(txsWithOrder, txWithOrder{ + txsWithOrderMap[txHash] = txWithOrder{ hash: txHash, index: txInfo.ExecutionOrder, txType: normalTx, - }) + } } for txHash, txInfo := range transactionsPool.SmartContractResults { - txsWithOrder = append(txsWithOrder, txWithOrder{ + txsWithOrderMap[txHash] = txWithOrder{ hash: txHash, index: txInfo.ExecutionOrder, txType: scr, - }) + } } for txHash, txInfo := range transactionsPool.Rewards { - txsWithOrder = append(txsWithOrder, txWithOrder{ + txsWithOrderMap[txHash] = txWithOrder{ hash: txHash, index: txInfo.ExecutionOrder, txType: rewardTx, - }) + } } for txHash, txInfo := range transactionsPool.InvalidTxs { - txsWithOrder = append(txsWithOrder, txWithOrder{ + txsWithOrderMap[txHash] = txWithOrder{ hash: txHash, index: txInfo.ExecutionOrder, txType: invalidTx, - }) + } + } + + txsWithOrder := make([]txWithOrder, 0, len(txsWithOrderMap)) + for _, txWithData := range txsWithOrderMap { + txsWithOrder = append(txsWithOrder, txWithData) } sort.Slice(txsWithOrder, func(i, j int) bool { From bd16a9f7d9f69fc5aac848502f646c45c42a77b7 Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Thu, 19 Mar 2026 15:00:43 +0200 Subject: [PATCH 60/62] add unit test --- process/eventsInterceptor_test.go | 34 +++++++++++++++++++++++++++++++ process/export_test.go | 6 ++++++ 2 files changed, 40 insertions(+) diff --git a/process/eventsInterceptor_test.go b/process/eventsInterceptor_test.go index f19aa0d..dd7a102 100644 --- a/process/eventsInterceptor_test.go +++ b/process/eventsInterceptor_test.go @@ -13,6 +13,7 @@ import ( "github.com/multiversx/mx-chain-notifier-go/data" "github.com/multiversx/mx-chain-notifier-go/mocks" "github.com/multiversx/mx-chain-notifier-go/process" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -1244,3 +1245,36 @@ func TestEventsInterceptor_GetStateAccessesPerAccounts(t *testing.T) { require.Equal(t, expStateAccessesPerAccounts, stateAccessesPerAccounts) }) } + +func TestEventsInterceptor_GetTxsWithOrder(t *testing.T) { + t.Parallel() + + transactionPool := &outport.TransactionPool{ + Transactions: map[string]*outport.TxInfo{ + "hash1": { + ExecutionOrder: 0, + }, + "hash2": { + ExecutionOrder: 1, + }, + }, + SmartContractResults: map[string]*outport.SCRInfo{ + "hash3": { + ExecutionOrder: 2, + }, + }, + Rewards: map[string]*outport.RewardInfo{ + "hash4": { + ExecutionOrder: 3, + }, + }, + InvalidTxs: map[string]*outport.TxInfo{ + "hash1": { + ExecutionOrder: 0, + }, + }, + } + + txsWithOrder := process.GetTxsWithOrder(transactionPool) + assert.Len(t, txsWithOrder, 4) +} diff --git a/process/export_test.go b/process/export_test.go index 48f3c2f..bef35e6 100644 --- a/process/export_test.go +++ b/process/export_test.go @@ -3,6 +3,7 @@ package process import ( "encoding/hex" + "github.com/multiversx/mx-chain-core-go/data/outport" "github.com/multiversx/mx-chain-core-go/data/stateChange" "github.com/multiversx/mx-chain-core-go/data/transaction" "github.com/multiversx/mx-chain-notifier-go/data" @@ -57,3 +58,8 @@ func (ei *eventsInterceptor) GetStateAccessesPerAccountsV3(eventsData *data.Args func BaseNilEventsDataCheks(eventsData *data.ArgsSaveBlockData) error { return baseNilEventsDataChecks(eventsData) } + +// GetTxsWithOrder exports internal method for testing +func GetTxsWithOrder(transactionsPool *outport.TransactionPool) []txWithOrder { + return getTxsWithOrder(transactionsPool) +} From 1eff8a1653a29268fe9d4e24ded3c1f91b0d6ec9 Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Mon, 23 Mar 2026 11:14:55 +0200 Subject: [PATCH 61/62] fixes after review --- process/eventsInterceptor.go | 6 +++++- process/eventsInterceptor_test.go | 25 +++++++++++++++++++++++-- process/export_test.go | 19 +++++++++++++++++-- 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/process/eventsInterceptor.go b/process/eventsInterceptor.go index 5777c60..482a56f 100644 --- a/process/eventsInterceptor.go +++ b/process/eventsInterceptor.go @@ -180,7 +180,11 @@ func getTxsWithOrder(transactionsPool *outport.TransactionPool) []txWithOrder { // There can be a case when a transaction is included in the block, but also marked as invalid, so it will be present // in both transactions and invalidTxs maps from transactions pool, with the same execution order. In that case, // we want to make sure that we process that transaction only as invalid. - txsWithOrderMap := make(map[string]txWithOrder) + numTxs := len(transactionsPool.Transactions) + + len(transactionsPool.SmartContractResults) + + len(transactionsPool.Rewards) + + len(transactionsPool.InvalidTxs) + txsWithOrderMap := make(map[string]txWithOrder, numTxs) for txHash, txInfo := range transactionsPool.Transactions { txsWithOrderMap[txHash] = txWithOrder{ diff --git a/process/eventsInterceptor_test.go b/process/eventsInterceptor_test.go index dd7a102..5e9f937 100644 --- a/process/eventsInterceptor_test.go +++ b/process/eventsInterceptor_test.go @@ -13,7 +13,6 @@ import ( "github.com/multiversx/mx-chain-notifier-go/data" "github.com/multiversx/mx-chain-notifier-go/mocks" "github.com/multiversx/mx-chain-notifier-go/process" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -1276,5 +1275,27 @@ func TestEventsInterceptor_GetTxsWithOrder(t *testing.T) { } txsWithOrder := process.GetTxsWithOrder(transactionPool) - assert.Len(t, txsWithOrder, 4) + + // we expect one entry for each execution order 0..3, + // with the duplicate "hash1" treated as invalid + require.Len(t, txsWithOrder, 4) + var hashes []string + invalidCount := 0 + for _, tx := range txsWithOrder { + hashes = append(hashes, tx.Hash) + if tx.TxType == 3 { //invalid tx + invalidCount++ + } + } + // execution order should be preserved: 0,1,2,3 -> hash1,hash2,hash3,hash4 + require.Equal(t, []string{"hash1", "hash2", "hash3", "hash4"}, hashes) + // "hash1" should appear exactly once and be marked invalid + hash1Count := 0 + for _, h := range hashes { + if h == "hash1" { + hash1Count++ + } + } + require.Equal(t, 1, hash1Count) + require.Equal(t, invalidCount, 1) } diff --git a/process/export_test.go b/process/export_test.go index bef35e6..15f8edb 100644 --- a/process/export_test.go +++ b/process/export_test.go @@ -59,7 +59,22 @@ func BaseNilEventsDataCheks(eventsData *data.ArgsSaveBlockData) error { return baseNilEventsDataChecks(eventsData) } +type txsWithOrderExportedFields struct { + Hash string + Index uint32 + TxType txType +} + // GetTxsWithOrder exports internal method for testing -func GetTxsWithOrder(transactionsPool *outport.TransactionPool) []txWithOrder { - return getTxsWithOrder(transactionsPool) +func GetTxsWithOrder(transactionsPool *outport.TransactionPool) []txsWithOrderExportedFields { + txsWithOrder := getTxsWithOrder(transactionsPool) + txsWithExportedFields := make([]txsWithOrderExportedFields, len(txsWithOrder)) + for i, tx := range txsWithOrder { + txsWithExportedFields[i] = txsWithOrderExportedFields{ + Hash: tx.hash, + Index: tx.index, + TxType: tx.txType, + } + } + return txsWithExportedFields } From b5a6e3b49cc2d38adea68b2db0f3646bacd59b59 Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Mon, 23 Mar 2026 13:15:06 +0200 Subject: [PATCH 62/62] small refactor --- process/eventsInterceptor.go | 42 ++++++++++++++++++------------------ process/export_test.go | 19 ++-------------- 2 files changed, 23 insertions(+), 38 deletions(-) diff --git a/process/eventsInterceptor.go b/process/eventsInterceptor.go index 482a56f..5d62ca7 100644 --- a/process/eventsInterceptor.go +++ b/process/eventsInterceptor.go @@ -26,9 +26,9 @@ const ( ) type txWithOrder struct { - hash string - index uint32 - txType txType + Hash string + Index uint32 + TxType txType } // logEvent defines a log event associated with corresponding tx hash @@ -188,30 +188,30 @@ func getTxsWithOrder(transactionsPool *outport.TransactionPool) []txWithOrder { for txHash, txInfo := range transactionsPool.Transactions { txsWithOrderMap[txHash] = txWithOrder{ - hash: txHash, - index: txInfo.ExecutionOrder, - txType: normalTx, + Hash: txHash, + Index: txInfo.ExecutionOrder, + TxType: normalTx, } } for txHash, txInfo := range transactionsPool.SmartContractResults { txsWithOrderMap[txHash] = txWithOrder{ - hash: txHash, - index: txInfo.ExecutionOrder, - txType: scr, + Hash: txHash, + Index: txInfo.ExecutionOrder, + TxType: scr, } } for txHash, txInfo := range transactionsPool.Rewards { txsWithOrderMap[txHash] = txWithOrder{ - hash: txHash, - index: txInfo.ExecutionOrder, - txType: rewardTx, + Hash: txHash, + Index: txInfo.ExecutionOrder, + TxType: rewardTx, } } for txHash, txInfo := range transactionsPool.InvalidTxs { txsWithOrderMap[txHash] = txWithOrder{ - hash: txHash, - index: txInfo.ExecutionOrder, - txType: invalidTx, + Hash: txHash, + Index: txInfo.ExecutionOrder, + TxType: invalidTx, } } @@ -221,7 +221,7 @@ func getTxsWithOrder(transactionsPool *outport.TransactionPool) []txWithOrder { } sort.Slice(txsWithOrder, func(i, j int) bool { - return txsWithOrder[i].index < txsWithOrder[j].index + return txsWithOrder[i].Index < txsWithOrder[j].Index }) return txsWithOrder @@ -290,21 +290,21 @@ func (ei *eventsInterceptor) fetchStateAccessesPerAccounts( txsWithOrder := getTxsWithOrder(transactionPool) for _, txInfo := range txsWithOrder { - txHash, err := hex.DecodeString(txInfo.hash) + txHash, err := hex.DecodeString(txInfo.Hash) if err != nil { - log.Error("failed to decode tx hash", "txHash", txInfo.hash) + log.Error("failed to decode tx hash", "txHash", txInfo.Hash) continue } stateAccessesPerTx, ok := stateAccesses[string(txHash)] if !ok { - if txInfo.txType == scr { + if txInfo.TxType == scr { // there are cases when SCRs are generated but no state accesses are produced, so we will not log a warning in those cases - log.Trace("SCR with no state accesses", "txHash", txInfo.hash) + log.Trace("SCR with no state accesses", "txHash", txInfo.Hash) continue } - log.Warn("did not find state accesses for tx", "txHash", txInfo.hash, "txType", txInfo.txType) + log.Warn("did not find state accesses for tx", "txHash", txInfo.Hash, "txType", txInfo.TxType) continue } diff --git a/process/export_test.go b/process/export_test.go index 15f8edb..bef35e6 100644 --- a/process/export_test.go +++ b/process/export_test.go @@ -59,22 +59,7 @@ func BaseNilEventsDataCheks(eventsData *data.ArgsSaveBlockData) error { return baseNilEventsDataChecks(eventsData) } -type txsWithOrderExportedFields struct { - Hash string - Index uint32 - TxType txType -} - // GetTxsWithOrder exports internal method for testing -func GetTxsWithOrder(transactionsPool *outport.TransactionPool) []txsWithOrderExportedFields { - txsWithOrder := getTxsWithOrder(transactionsPool) - txsWithExportedFields := make([]txsWithOrderExportedFields, len(txsWithOrder)) - for i, tx := range txsWithOrder { - txsWithExportedFields[i] = txsWithOrderExportedFields{ - Hash: tx.hash, - Index: tx.index, - TxType: tx.txType, - } - } - return txsWithExportedFields +func GetTxsWithOrder(transactionsPool *outport.TransactionPool) []txWithOrder { + return getTxsWithOrder(transactionsPool) }