From 93b3c9d4b4615296c598100a6b1917432785899f Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Mon, 11 Mar 2024 17:01:02 +0200 Subject: [PATCH 1/7] added guardian as field on the transaction/pool by-sender request --- .../transactionAPI/apiTransactionProcessor.go | 11 +++++++++-- node/external/transactionAPI/fieldsHandler.go | 3 +++ node/external/transactionAPI/fieldsHandler_test.go | 3 ++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/node/external/transactionAPI/apiTransactionProcessor.go b/node/external/transactionAPI/apiTransactionProcessor.go index 404cc8eba8d..313a86f381c 100644 --- a/node/external/transactionAPI/apiTransactionProcessor.go +++ b/node/external/transactionAPI/apiTransactionProcessor.go @@ -8,6 +8,7 @@ import ( "time" "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/block" rewardTxData "github.com/multiversx/mx-chain-core-go/data/rewardTx" "github.com/multiversx/mx-chain-core-go/data/smartContractResult" @@ -319,11 +320,11 @@ func (atp *apiTransactionProcessor) extractRequestedTxInfo(wrappedTx *txcache.Wr } if requestedFieldsHandler.HasSender { - tx.TxFields[senderField], _ = atp.addressPubKeyConverter.Encode(wrappedTx.Tx.GetSndAddr()) + tx.TxFields[senderField] = atp.addressPubKeyConverter.SilentEncode(wrappedTx.Tx.GetSndAddr(), log) } if requestedFieldsHandler.HasReceiver { - tx.TxFields[receiverField], _ = atp.addressPubKeyConverter.Encode(wrappedTx.Tx.GetRcvAddr()) + tx.TxFields[receiverField] = atp.addressPubKeyConverter.SilentEncode(wrappedTx.Tx.GetRcvAddr(), log) } if requestedFieldsHandler.HasGasLimit { @@ -341,6 +342,12 @@ func (atp *apiTransactionProcessor) extractRequestedTxInfo(wrappedTx *txcache.Wr if requestedFieldsHandler.HasValue { tx.TxFields[valueField] = getTxValue(wrappedTx) } + if requestedFieldsHandler.HasGuardian { + guardedTx, isGuardedTx := wrappedTx.Tx.(data.GuardedTransactionHandler) + if isGuardedTx { + tx.TxFields[guardianField] = atp.addressPubKeyConverter.SilentEncode(guardedTx.GetGuardianAddr(), log) + } + } return tx } diff --git a/node/external/transactionAPI/fieldsHandler.go b/node/external/transactionAPI/fieldsHandler.go index 43ea27d473a..d79c5167d29 100644 --- a/node/external/transactionAPI/fieldsHandler.go +++ b/node/external/transactionAPI/fieldsHandler.go @@ -14,6 +14,7 @@ const ( rcvUsernameField = "receiverusername" dataField = "data" valueField = "value" + guardianField = "guardian" ) type fieldsHandler struct { @@ -25,6 +26,7 @@ type fieldsHandler struct { HasRcvUsername bool HasData bool HasValue bool + HasGuardian bool } func newFieldsHandler(parameters string) fieldsHandler { @@ -38,6 +40,7 @@ func newFieldsHandler(parameters string) fieldsHandler { HasRcvUsername: strings.Contains(parameters, rcvUsernameField), HasData: strings.Contains(parameters, dataField), HasValue: strings.Contains(parameters, valueField), + HasGuardian: strings.Contains(parameters, guardianField), } return ph } diff --git a/node/external/transactionAPI/fieldsHandler_test.go b/node/external/transactionAPI/fieldsHandler_test.go index 0948483fd11..398b868fc21 100644 --- a/node/external/transactionAPI/fieldsHandler_test.go +++ b/node/external/transactionAPI/fieldsHandler_test.go @@ -12,7 +12,7 @@ func Test_newFieldsHandler(t *testing.T) { fh := newFieldsHandler("") require.Equal(t, fieldsHandler{}, fh) - fh = newFieldsHandler("nOnCe,sender,receiver,gasLimit,GASprice,receiverusername,data,value") + fh = newFieldsHandler("nOnCe,sender,receiver,gasLimit,GASprice,receiverusername,data,value,guardian") expectedPH := fieldsHandler{ HasNonce: true, HasSender: true, @@ -22,6 +22,7 @@ func Test_newFieldsHandler(t *testing.T) { HasRcvUsername: true, HasData: true, HasValue: true, + HasGuardian: true, } require.Equal(t, expectedPH, fh) } From 8be1556f84a71e76fe5e64cb76102aeb73c69ca5 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Mon, 11 Mar 2024 20:49:07 +0200 Subject: [PATCH 2/7] added more fields + wild card --- api/groups/transactionGroup.go | 4 + .../transactionAPI/apiTransactionProcessor.go | 27 ++++++ .../apiTransactionProcessor_test.go | 2 +- node/external/transactionAPI/fieldsHandler.go | 88 +++++++++++++------ .../transactionAPI/fieldsHandler_test.go | 27 +++--- 5 files changed, 109 insertions(+), 39 deletions(-) diff --git a/api/groups/transactionGroup.go b/api/groups/transactionGroup.go index c2b47bf7a87..3c62221d121 100644 --- a/api/groups/transactionGroup.go +++ b/api/groups/transactionGroup.go @@ -745,6 +745,10 @@ func validateQuery(sender, fields string, lastNonce, nonceGaps bool) error { return errors.ErrEmptySenderToGetNonceGaps } + if fields == "*" { + return nil + } + if fields != "" { return validateFields(fields) } diff --git a/node/external/transactionAPI/apiTransactionProcessor.go b/node/external/transactionAPI/apiTransactionProcessor.go index 313a86f381c..eda6f5e422f 100644 --- a/node/external/transactionAPI/apiTransactionProcessor.go +++ b/node/external/transactionAPI/apiTransactionProcessor.go @@ -330,18 +330,38 @@ func (atp *apiTransactionProcessor) extractRequestedTxInfo(wrappedTx *txcache.Wr if requestedFieldsHandler.HasGasLimit { tx.TxFields[gasLimitField] = wrappedTx.Tx.GetGasLimit() } + if requestedFieldsHandler.HasGasPrice { tx.TxFields[gasPriceField] = wrappedTx.Tx.GetGasPrice() } + if requestedFieldsHandler.HasRcvUsername { tx.TxFields[rcvUsernameField] = wrappedTx.Tx.GetRcvUserName() } + if requestedFieldsHandler.HasData { tx.TxFields[dataField] = wrappedTx.Tx.GetData() } + if requestedFieldsHandler.HasValue { tx.TxFields[valueField] = getTxValue(wrappedTx) } + + if requestedFieldsHandler.HasSenderShardID { + tx.TxFields[senderShardID] = wrappedTx.SenderShardID + } + + if requestedFieldsHandler.HasReceiverShardID { + tx.TxFields[receiverShardID] = wrappedTx.ReceiverShardID + } + + if requestedFieldsHandler.HasSignature { + castedTx, hasSignature := wrappedTx.Tx.(data.GuardedTransactionHandler) + if hasSignature { + tx.TxFields[signatureField] = hex.EncodeToString(castedTx.GetSignature()) + } + } + if requestedFieldsHandler.HasGuardian { guardedTx, isGuardedTx := wrappedTx.Tx.(data.GuardedTransactionHandler) if isGuardedTx { @@ -349,6 +369,13 @@ func (atp *apiTransactionProcessor) extractRequestedTxInfo(wrappedTx *txcache.Wr } } + if requestedFieldsHandler.HasGuardianSignature { + guardedTx, isGuardedTx := wrappedTx.Tx.(data.GuardedTransactionHandler) + if isGuardedTx { + tx.TxFields[guardianSignatureField] = hex.EncodeToString(guardedTx.GetGuardianSignature()) + } + } + return tx } diff --git a/node/external/transactionAPI/apiTransactionProcessor_test.go b/node/external/transactionAPI/apiTransactionProcessor_test.go index f7d90c8f15b..7d86a1610c5 100644 --- a/node/external/transactionAPI/apiTransactionProcessor_test.go +++ b/node/external/transactionAPI/apiTransactionProcessor_test.go @@ -825,7 +825,7 @@ func TestApiTransactionProcessor_GetTransactionsPoolForSender(t *testing.T) { require.NoError(t, err) require.NotNil(t, atp) - res, err := atp.GetTransactionsPoolForSender(sender, "sender,value") + res, err := atp.GetTransactionsPoolForSender(sender, "*") require.NoError(t, err) expectedHashes := []string{hex.EncodeToString(txHash0), hex.EncodeToString(txHash1), hex.EncodeToString(txHash2), hex.EncodeToString(txHash3), hex.EncodeToString(txHash4)} expectedValues := []string{"100001", "100002", "100003", "100004", "100005"} diff --git a/node/external/transactionAPI/fieldsHandler.go b/node/external/transactionAPI/fieldsHandler.go index d79c5167d29..411141d271d 100644 --- a/node/external/transactionAPI/fieldsHandler.go +++ b/node/external/transactionAPI/fieldsHandler.go @@ -5,42 +5,74 @@ import ( ) const ( - hashField = "hash" - nonceField = "nonce" - senderField = "sender" - receiverField = "receiver" - gasLimitField = "gaslimit" - gasPriceField = "gasprice" - rcvUsernameField = "receiverusername" - dataField = "data" - valueField = "value" - guardianField = "guardian" + hashField = "hash" + nonceField = "nonce" + senderField = "sender" + receiverField = "receiver" + gasLimitField = "gaslimit" + gasPriceField = "gasprice" + rcvUsernameField = "receiverusername" + dataField = "data" + valueField = "value" + signatureField = "signature" + guardianField = "guardian" + guardianSignatureField = "guardiansignature" + senderShardID = "sendershard" + receiverShardID = "receivershard" + wildCard = "*" + + separator = "," ) type fieldsHandler struct { - HasNonce bool - HasSender bool - HasReceiver bool - HasGasLimit bool - HasGasPrice bool - HasRcvUsername bool - HasData bool - HasValue bool - HasGuardian bool + HasNonce bool + HasSender bool + HasReceiver bool + HasGasLimit bool + HasGasPrice bool + HasRcvUsername bool + HasData bool + HasValue bool + HasSignature bool + HasSenderShardID bool + HasReceiverShardID bool + HasGuardian bool + HasGuardianSignature bool } func newFieldsHandler(parameters string) fieldsHandler { parameters = strings.ToLower(parameters) + parametersMap := sliceToMap(strings.Split(parameters, separator)) ph := fieldsHandler{ - HasNonce: strings.Contains(parameters, nonceField), - HasSender: strings.Contains(parameters, senderField), - HasReceiver: strings.Contains(parameters, receiverField), - HasGasLimit: strings.Contains(parameters, gasLimitField), - HasGasPrice: strings.Contains(parameters, gasPriceField), - HasRcvUsername: strings.Contains(parameters, rcvUsernameField), - HasData: strings.Contains(parameters, dataField), - HasValue: strings.Contains(parameters, valueField), - HasGuardian: strings.Contains(parameters, guardianField), + HasNonce: shouldConsiderField(parametersMap, nonceField), + HasSender: shouldConsiderField(parametersMap, senderField), + HasReceiver: shouldConsiderField(parametersMap, receiverField), + HasGasLimit: shouldConsiderField(parametersMap, gasLimitField), + HasGasPrice: shouldConsiderField(parametersMap, gasPriceField), + HasRcvUsername: shouldConsiderField(parametersMap, rcvUsernameField), + HasData: shouldConsiderField(parametersMap, dataField), + HasValue: shouldConsiderField(parametersMap, valueField), + HasSignature: shouldConsiderField(parametersMap, signatureField), + HasSenderShardID: shouldConsiderField(parametersMap, senderShardID), + HasReceiverShardID: shouldConsiderField(parametersMap, receiverShardID), + HasGuardian: shouldConsiderField(parametersMap, guardianField), + HasGuardianSignature: shouldConsiderField(parametersMap, guardianSignatureField), } return ph } + +func shouldConsiderField(parametersMap map[string]struct{}, field string) bool { + _, has := parametersMap[field] + _, hasWildCard := parametersMap[wildCard] + + return has || hasWildCard +} + +func sliceToMap(providedSlice []string) map[string]struct{} { + result := make(map[string]struct{}, len(providedSlice)) + for _, entry := range providedSlice { + result[entry] = struct{}{} + } + + return result +} diff --git a/node/external/transactionAPI/fieldsHandler_test.go b/node/external/transactionAPI/fieldsHandler_test.go index 398b868fc21..1a2d68ce85a 100644 --- a/node/external/transactionAPI/fieldsHandler_test.go +++ b/node/external/transactionAPI/fieldsHandler_test.go @@ -12,17 +12,24 @@ func Test_newFieldsHandler(t *testing.T) { fh := newFieldsHandler("") require.Equal(t, fieldsHandler{}, fh) - fh = newFieldsHandler("nOnCe,sender,receiver,gasLimit,GASprice,receiverusername,data,value,guardian") + fh = newFieldsHandler("nOnCe,sender,receiver,gasLimit,GASprice,receiverusername,data,value,signature,guardian,guardiansignature,sendershard,receivershard") expectedPH := fieldsHandler{ - HasNonce: true, - HasSender: true, - HasReceiver: true, - HasGasLimit: true, - HasGasPrice: true, - HasRcvUsername: true, - HasData: true, - HasValue: true, - HasGuardian: true, + HasNonce: true, + HasSender: true, + HasReceiver: true, + HasGasLimit: true, + HasGasPrice: true, + HasRcvUsername: true, + HasData: true, + HasValue: true, + HasSignature: true, + HasSenderShardID: true, + HasReceiverShardID: true, + HasGuardian: true, + HasGuardianSignature: true, } require.Equal(t, expectedPH, fh) + + fh = newFieldsHandler("*") + require.Equal(t, expectedPH, fh) } From 4040b050b3bf65522ea18ebc848424665cb98ed7 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Mon, 11 Mar 2024 20:51:12 +0200 Subject: [PATCH 3/7] more tests --- api/groups/transactionGroup_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/groups/transactionGroup_test.go b/api/groups/transactionGroup_test.go index 1f8f6bffbd4..22085956fe9 100644 --- a/api/groups/transactionGroup_test.go +++ b/api/groups/transactionGroup_test.go @@ -704,6 +704,7 @@ func TestTransactionGroup_getTransactionsPool(t *testing.T) { t.Run("fields + nonce gaps", testTxPoolWithInvalidQuery("?fields=sender,receiver&nonce-gaps=true", apiErrors.ErrFetchingNonceGapsCannotIncludeFields)) t.Run("fields has spaces", testTxPoolWithInvalidQuery("?fields=sender ,receiver", apiErrors.ErrInvalidFields)) t.Run("fields has numbers", testTxPoolWithInvalidQuery("?fields=sender1", apiErrors.ErrInvalidFields)) + t.Run("fields + wild card", testTxPoolWithInvalidQuery("?fields=sender,receiver,*", apiErrors.ErrInvalidFields)) t.Run("GetTransactionsPool error should error", func(t *testing.T) { t.Parallel() @@ -816,8 +817,7 @@ func TestTransactionGroup_getTransactionsPool(t *testing.T) { t.Parallel() expectedSender := "sender" - providedFields := "sender,receiver" - query := "?by-sender=" + expectedSender + "&fields=" + providedFields + query := "?by-sender=" + expectedSender + "&fields=*" expectedResp := &common.TransactionsPoolForSenderApiResponse{ Transactions: []common.Transaction{ { From c07e4f280c462b9c823d9693766d142107a0d2b5 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Mon, 11 Mar 2024 21:00:25 +0200 Subject: [PATCH 4/7] improvement after review --- node/external/transactionAPI/fieldsHandler.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/node/external/transactionAPI/fieldsHandler.go b/node/external/transactionAPI/fieldsHandler.go index 411141d271d..d996d329751 100644 --- a/node/external/transactionAPI/fieldsHandler.go +++ b/node/external/transactionAPI/fieldsHandler.go @@ -62,10 +62,13 @@ func newFieldsHandler(parameters string) fieldsHandler { } func shouldConsiderField(parametersMap map[string]struct{}, field string) bool { - _, has := parametersMap[field] _, hasWildCard := parametersMap[wildCard] + if hasWildCard { + return true + } - return has || hasWildCard + _, has := parametersMap[field] + return has } func sliceToMap(providedSlice []string) map[string]struct{} { From 81f35e40edbcfe6e720208b82aed7091fe4c9201 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Tue, 12 Mar 2024 10:58:54 +0200 Subject: [PATCH 5/7] fixes after second review --- .../transactionAPI/apiTransactionProcessor.go | 83 ++++++------------- node/external/transactionAPI/fieldsHandler.go | 47 ++++------- .../transactionAPI/fieldsHandler_test.go | 29 +++---- 3 files changed, 52 insertions(+), 107 deletions(-) diff --git a/node/external/transactionAPI/apiTransactionProcessor.go b/node/external/transactionAPI/apiTransactionProcessor.go index eda6f5e422f..1b4867f0b39 100644 --- a/node/external/transactionAPI/apiTransactionProcessor.go +++ b/node/external/transactionAPI/apiTransactionProcessor.go @@ -309,74 +309,43 @@ func (atp *apiTransactionProcessor) getUnsignedTransactionsFromPool(requestedFie } func (atp *apiTransactionProcessor) extractRequestedTxInfo(wrappedTx *txcache.WrappedTransaction, requestedFieldsHandler fieldsHandler) common.Transaction { + fieldGetters := atp.getFieldGettersForTx(wrappedTx) tx := common.Transaction{ TxFields: make(map[string]interface{}), } - tx.TxFields[hashField] = hex.EncodeToString(wrappedTx.TxHash) - - if requestedFieldsHandler.HasNonce { - tx.TxFields[nonceField] = wrappedTx.Tx.GetNonce() - } - - if requestedFieldsHandler.HasSender { - tx.TxFields[senderField] = atp.addressPubKeyConverter.SilentEncode(wrappedTx.Tx.GetSndAddr(), log) - } - - if requestedFieldsHandler.HasReceiver { - tx.TxFields[receiverField] = atp.addressPubKeyConverter.SilentEncode(wrappedTx.Tx.GetRcvAddr(), log) - } - - if requestedFieldsHandler.HasGasLimit { - tx.TxFields[gasLimitField] = wrappedTx.Tx.GetGasLimit() - } - - if requestedFieldsHandler.HasGasPrice { - tx.TxFields[gasPriceField] = wrappedTx.Tx.GetGasPrice() - } - - if requestedFieldsHandler.HasRcvUsername { - tx.TxFields[rcvUsernameField] = wrappedTx.Tx.GetRcvUserName() - } - - if requestedFieldsHandler.HasData { - tx.TxFields[dataField] = wrappedTx.Tx.GetData() - } - - if requestedFieldsHandler.HasValue { - tx.TxFields[valueField] = getTxValue(wrappedTx) - } - - if requestedFieldsHandler.HasSenderShardID { - tx.TxFields[senderShardID] = wrappedTx.SenderShardID - } - - if requestedFieldsHandler.HasReceiverShardID { - tx.TxFields[receiverShardID] = wrappedTx.ReceiverShardID - } - - if requestedFieldsHandler.HasSignature { - castedTx, hasSignature := wrappedTx.Tx.(data.GuardedTransactionHandler) - if hasSignature { - tx.TxFields[signatureField] = hex.EncodeToString(castedTx.GetSignature()) + for field, getter := range fieldGetters { + if requestedFieldsHandler.IsFieldSet(field) { + tx.TxFields[field] = getter() } } - if requestedFieldsHandler.HasGuardian { - guardedTx, isGuardedTx := wrappedTx.Tx.(data.GuardedTransactionHandler) - if isGuardedTx { - tx.TxFields[guardianField] = atp.addressPubKeyConverter.SilentEncode(guardedTx.GetGuardianAddr(), log) - } + return tx +} + +func (atp *apiTransactionProcessor) getFieldGettersForTx(wrappedTx *txcache.WrappedTransaction) map[string]func() interface{} { + var fieldGetters = map[string]func() interface{}{ + hashField: func() interface{} { return hex.EncodeToString(wrappedTx.TxHash) }, + nonceField: func() interface{} { return wrappedTx.Tx.GetNonce() }, + senderField: func() interface{} { return atp.addressPubKeyConverter.SilentEncode(wrappedTx.Tx.GetSndAddr(), log) }, + receiverField: func() interface{} { return atp.addressPubKeyConverter.SilentEncode(wrappedTx.Tx.GetRcvAddr(), log) }, + gasLimitField: func() interface{} { return wrappedTx.Tx.GetGasLimit() }, + gasPriceField: func() interface{} { return wrappedTx.Tx.GetGasPrice() }, + rcvUsernameField: func() interface{} { return wrappedTx.Tx.GetRcvUserName() }, + dataField: func() interface{} { return wrappedTx.Tx.GetData() }, + valueField: func() interface{} { return getTxValue(wrappedTx) }, + senderShardID: func() interface{} { return wrappedTx.SenderShardID }, + receiverShardID: func() interface{} { return wrappedTx.ReceiverShardID }, } - if requestedFieldsHandler.HasGuardianSignature { - guardedTx, isGuardedTx := wrappedTx.Tx.(data.GuardedTransactionHandler) - if isGuardedTx { - tx.TxFields[guardianSignatureField] = hex.EncodeToString(guardedTx.GetGuardianSignature()) - } + guardedTx, isGuardedTx := wrappedTx.Tx.(data.GuardedTransactionHandler) + if isGuardedTx { + fieldGetters[signatureField] = func() interface{} { return hex.EncodeToString(guardedTx.GetSignature()) } + fieldGetters[guardianField] = func() interface{} { return atp.addressPubKeyConverter.SilentEncode(guardedTx.GetGuardianAddr(), log) } + fieldGetters[guardianSignatureField] = func() interface{} { return hex.EncodeToString(guardedTx.GetGuardianSignature()) } } - return tx + return fieldGetters } func (atp *apiTransactionProcessor) fetchTxsForSender(sender string, senderShard uint32) []*txcache.WrappedTransaction { diff --git a/node/external/transactionAPI/fieldsHandler.go b/node/external/transactionAPI/fieldsHandler.go index d996d329751..4f837968cb7 100644 --- a/node/external/transactionAPI/fieldsHandler.go +++ b/node/external/transactionAPI/fieldsHandler.go @@ -25,49 +25,32 @@ const ( ) type fieldsHandler struct { - HasNonce bool - HasSender bool - HasReceiver bool - HasGasLimit bool - HasGasPrice bool - HasRcvUsername bool - HasData bool - HasValue bool - HasSignature bool - HasSenderShardID bool - HasReceiverShardID bool - HasGuardian bool - HasGuardianSignature bool + fieldsMap map[string]struct{} } func newFieldsHandler(parameters string) fieldsHandler { + if len(parameters) == 0 { + return fieldsHandler{ + fieldsMap: map[string]struct{}{ + hashField: {}, // hash should always be returned + }, + } + } + parameters = strings.ToLower(parameters) - parametersMap := sliceToMap(strings.Split(parameters, separator)) - ph := fieldsHandler{ - HasNonce: shouldConsiderField(parametersMap, nonceField), - HasSender: shouldConsiderField(parametersMap, senderField), - HasReceiver: shouldConsiderField(parametersMap, receiverField), - HasGasLimit: shouldConsiderField(parametersMap, gasLimitField), - HasGasPrice: shouldConsiderField(parametersMap, gasPriceField), - HasRcvUsername: shouldConsiderField(parametersMap, rcvUsernameField), - HasData: shouldConsiderField(parametersMap, dataField), - HasValue: shouldConsiderField(parametersMap, valueField), - HasSignature: shouldConsiderField(parametersMap, signatureField), - HasSenderShardID: shouldConsiderField(parametersMap, senderShardID), - HasReceiverShardID: shouldConsiderField(parametersMap, receiverShardID), - HasGuardian: shouldConsiderField(parametersMap, guardianField), - HasGuardianSignature: shouldConsiderField(parametersMap, guardianSignatureField), + return fieldsHandler{ + fieldsMap: sliceToMap(strings.Split(parameters, separator)), } - return ph } -func shouldConsiderField(parametersMap map[string]struct{}, field string) bool { - _, hasWildCard := parametersMap[wildCard] +// IsFieldSet returns true if the provided field is set +func (handler *fieldsHandler) IsFieldSet(field string) bool { + _, hasWildCard := handler.fieldsMap[wildCard] if hasWildCard { return true } - _, has := parametersMap[field] + _, has := handler.fieldsMap[strings.ToLower(field)] return has } diff --git a/node/external/transactionAPI/fieldsHandler_test.go b/node/external/transactionAPI/fieldsHandler_test.go index 1a2d68ce85a..65c5e76bbaf 100644 --- a/node/external/transactionAPI/fieldsHandler_test.go +++ b/node/external/transactionAPI/fieldsHandler_test.go @@ -1,6 +1,8 @@ package transactionAPI import ( + "fmt" + "strings" "testing" "github.com/stretchr/testify/require" @@ -10,26 +12,17 @@ func Test_newFieldsHandler(t *testing.T) { t.Parallel() fh := newFieldsHandler("") - require.Equal(t, fieldsHandler{}, fh) + require.Equal(t, fieldsHandler{make(map[string]struct{})}, fh) - fh = newFieldsHandler("nOnCe,sender,receiver,gasLimit,GASprice,receiverusername,data,value,signature,guardian,guardiansignature,sendershard,receivershard") - expectedPH := fieldsHandler{ - HasNonce: true, - HasSender: true, - HasReceiver: true, - HasGasLimit: true, - HasGasPrice: true, - HasRcvUsername: true, - HasData: true, - HasValue: true, - HasSignature: true, - HasSenderShardID: true, - HasReceiverShardID: true, - HasGuardian: true, - HasGuardianSignature: true, + providedFields := "nOnCe,sender,receiver,gasLimit,GASprice,receiverusername,data,value,signature,guardian,guardiansignature,sendershard,receivershard" + splitFields := strings.Split(providedFields, separator) + fh = newFieldsHandler(providedFields) + for _, field := range splitFields { + require.True(t, fh.IsFieldSet(field), fmt.Sprintf("field %s is not set", field)) } - require.Equal(t, expectedPH, fh) fh = newFieldsHandler("*") - require.Equal(t, expectedPH, fh) + for _, field := range splitFields { + require.True(t, fh.IsFieldSet(field)) + } } From caa2b9079595a87257627a23f9526a4aadad739f Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Tue, 12 Mar 2024 12:27:51 +0200 Subject: [PATCH 6/7] fix tests --- node/external/transactionAPI/fieldsHandler_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/external/transactionAPI/fieldsHandler_test.go b/node/external/transactionAPI/fieldsHandler_test.go index 65c5e76bbaf..fab3b3a41d9 100644 --- a/node/external/transactionAPI/fieldsHandler_test.go +++ b/node/external/transactionAPI/fieldsHandler_test.go @@ -12,7 +12,7 @@ func Test_newFieldsHandler(t *testing.T) { t.Parallel() fh := newFieldsHandler("") - require.Equal(t, fieldsHandler{make(map[string]struct{})}, fh) + require.Equal(t, fieldsHandler{map[string]struct{}{hashField: {}}}, fh) providedFields := "nOnCe,sender,receiver,gasLimit,GASprice,receiverusername,data,value,signature,guardian,guardiansignature,sendershard,receivershard" splitFields := strings.Split(providedFields, separator) From 6d6332cb673eb7b7f435e0911e92bc87b4513b84 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Wed, 13 Mar 2024 11:08:09 +0200 Subject: [PATCH 7/7] fixes after review --- .../transactionAPI/apiTransactionProcessor.go | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/node/external/transactionAPI/apiTransactionProcessor.go b/node/external/transactionAPI/apiTransactionProcessor.go index 1b4867f0b39..b12aa9ac86f 100644 --- a/node/external/transactionAPI/apiTransactionProcessor.go +++ b/node/external/transactionAPI/apiTransactionProcessor.go @@ -314,35 +314,35 @@ func (atp *apiTransactionProcessor) extractRequestedTxInfo(wrappedTx *txcache.Wr TxFields: make(map[string]interface{}), } - for field, getter := range fieldGetters { + for field, value := range fieldGetters { if requestedFieldsHandler.IsFieldSet(field) { - tx.TxFields[field] = getter() + tx.TxFields[field] = value } } return tx } -func (atp *apiTransactionProcessor) getFieldGettersForTx(wrappedTx *txcache.WrappedTransaction) map[string]func() interface{} { - var fieldGetters = map[string]func() interface{}{ - hashField: func() interface{} { return hex.EncodeToString(wrappedTx.TxHash) }, - nonceField: func() interface{} { return wrappedTx.Tx.GetNonce() }, - senderField: func() interface{} { return atp.addressPubKeyConverter.SilentEncode(wrappedTx.Tx.GetSndAddr(), log) }, - receiverField: func() interface{} { return atp.addressPubKeyConverter.SilentEncode(wrappedTx.Tx.GetRcvAddr(), log) }, - gasLimitField: func() interface{} { return wrappedTx.Tx.GetGasLimit() }, - gasPriceField: func() interface{} { return wrappedTx.Tx.GetGasPrice() }, - rcvUsernameField: func() interface{} { return wrappedTx.Tx.GetRcvUserName() }, - dataField: func() interface{} { return wrappedTx.Tx.GetData() }, - valueField: func() interface{} { return getTxValue(wrappedTx) }, - senderShardID: func() interface{} { return wrappedTx.SenderShardID }, - receiverShardID: func() interface{} { return wrappedTx.ReceiverShardID }, +func (atp *apiTransactionProcessor) getFieldGettersForTx(wrappedTx *txcache.WrappedTransaction) map[string]interface{} { + var fieldGetters = map[string]interface{}{ + hashField: hex.EncodeToString(wrappedTx.TxHash), + nonceField: wrappedTx.Tx.GetNonce(), + senderField: atp.addressPubKeyConverter.SilentEncode(wrappedTx.Tx.GetSndAddr(), log), + receiverField: atp.addressPubKeyConverter.SilentEncode(wrappedTx.Tx.GetRcvAddr(), log), + gasLimitField: wrappedTx.Tx.GetGasLimit(), + gasPriceField: wrappedTx.Tx.GetGasPrice(), + rcvUsernameField: wrappedTx.Tx.GetRcvUserName(), + dataField: wrappedTx.Tx.GetData(), + valueField: getTxValue(wrappedTx), + senderShardID: wrappedTx.SenderShardID, + receiverShardID: wrappedTx.ReceiverShardID, } guardedTx, isGuardedTx := wrappedTx.Tx.(data.GuardedTransactionHandler) if isGuardedTx { - fieldGetters[signatureField] = func() interface{} { return hex.EncodeToString(guardedTx.GetSignature()) } - fieldGetters[guardianField] = func() interface{} { return atp.addressPubKeyConverter.SilentEncode(guardedTx.GetGuardianAddr(), log) } - fieldGetters[guardianSignatureField] = func() interface{} { return hex.EncodeToString(guardedTx.GetGuardianSignature()) } + fieldGetters[signatureField] = hex.EncodeToString(guardedTx.GetSignature()) + fieldGetters[guardianField] = atp.addressPubKeyConverter.SilentEncode(guardedTx.GetGuardianAddr(), log) + fieldGetters[guardianSignatureField] = hex.EncodeToString(guardedTx.GetGuardianSignature()) } return fieldGetters