Skip to content

Commit fda935e

Browse files
authored
Merge pull request #7050 from multiversx/merge-barnard-into-feat-timestamp-ms
Merge barnard into feat timestamp ms
2 parents f2f7382 + cfb10da commit fda935e

File tree

10 files changed

+153
-33
lines changed

10 files changed

+153
-33
lines changed

.github/workflows/build_and_run_chain_simulator_and_execute_system_test.yml

Lines changed: 106 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,23 @@ jobs:
2222
(github.event_name == 'issue_comment' && contains(github.event.comment.body, 'Run Tests:')) ||
2323
github.event_name == 'workflow_dispatch'
2424
25-
strategy:
26-
matrix:
27-
#TODO Include Macos support later on
28-
runs-on: [ubuntu-latest]
29-
runs-on: ${{ matrix.runs-on }}
25+
runs-on: [self-hosted, Linux, X64]
3026
env:
3127
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
3228
TARGET_BRANCH: ""
3329
MX_CHAIN_GO_TARGET_BRANCH: ""
3430
MX_CHAIN_SIMULATOR_TARGET_BRANCH: ""
3531
MX_CHAIN_TESTING_SUITE_TARGET_BRANCH: ""
3632

33+
CF_R2_ACCESS_KEY: ${{ secrets.CF_R2_ACCESS_KEY }}
34+
CF_R2_SECRET_KEY: ${{ secrets.CF_R2_SECRET_KEY }}
35+
CF_R2_ENDPOINT: ${{ secrets.CF_R2_ENDPOINT }}
36+
37+
REPORT_BUCKET: mx-chain-go-testing-reports
38+
REPORT_BASE_URL: https://mx-chain-go-testing-reports.multiversx.com
39+
40+
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
41+
3742
steps:
3843
- name: Determine Target Branches
3944
id: target_branch
@@ -132,6 +137,22 @@ jobs:
132137
echo "LATEST_COMMIT_HASH=${latest_commit_hash}" >> $GITHUB_ENV
133138
echo "Latest commit hash: ${latest_commit_hash}"
134139
140+
- name: Install rclone
141+
run: |
142+
TS=$(date +'%Y_%^B_%d__%H_%M_%S');
143+
echo "TS=$TS" >> "$GITHUB_ENV"
144+
echo "TIMESTAMP=$TS" >> "$GITHUB_ENV"
145+
sudo apt-get update -y && sudo apt-get install -y rclone
146+
mkdir -p ~/.config/rclone
147+
cat > ~/.config/rclone/rclone.conf <<EOF
148+
[r2]
149+
type = s3
150+
provider = Cloudflare
151+
access_key_id = ${CF_R2_ACCESS_KEY}
152+
secret_access_key = ${CF_R2_SECRET_KEY}
153+
endpoint = ${CF_R2_ENDPOINT}
154+
EOF
155+
135156
- name: Checkout mx-chain-simulator-go
136157
uses: actions/checkout@v4
137158
with:
@@ -147,6 +168,8 @@ jobs:
147168
- name: Install Python Dependencies and Update go.mod
148169
run: |
149170
cd mx-chain-simulator-go
171+
echo "SIMULATOR_REF=$(git symbolic-ref --short HEAD || git describe --tags)" >> $GITHUB_ENV
172+
echo "SIMULATOR_COMMIT_HASH=$(git rev-parse HEAD)" >> $GITHUB_ENV
150173
pip install -r scripts/update-go-mod/requirements.txt
151174
python scripts/update-go-mod/update-go-mod.py $LATEST_COMMIT_HASH
152175
@@ -241,10 +264,12 @@ jobs:
241264
ref: ${{ env.MX_CHAIN_TESTING_SUITE_TARGET_BRANCH || github.event.pull_request.base.ref }}
242265
token: ${{ secrets.MVX_TESTER_GH_TOKEN }}
243266

244-
- name: Install Dependencies
267+
- name: Install MX-Chain-Testing-Suite Dependencies
245268
run: |
246269
pip install -r mx-chain-testing-suite/requirements.txt
247270
echo "PYTHONPATH=mx-chain-testing-suite" >> $GITHUB_ENV
271+
cd mx-chain-testing-suite
272+
echo "CURRENT_COMMIT_HASH=$(git rev-parse HEAD)" >> $GITHUB_ENV
248273
249274
250275
- name: Run tests and generate HTML report
@@ -262,6 +287,19 @@ jobs:
262287
else
263288
echo "Report not found."
264289
fi
290+
291+
- name: Stage report for R2
292+
run: |
293+
mkdir -p r2_upload
294+
cp reports/report.html r2_upload/index.html # correct source
295+
296+
- name: Upload report to Cloudflare R2
297+
if: always()
298+
run: |
299+
branch="${{ env.BRANCH_NAME }}"
300+
target="reports/chain-simulator/${branch}/${TS}"
301+
rclone copy r2_upload/ "r2:${REPORT_BUCKET}/${target}"
302+
echo "R2_REPORT_URL=${REPORT_BASE_URL}/${target}/index.html" >> $GITHUB_ENV
265303
266304
- name: Upload test report
267305
if: always()
@@ -346,42 +384,54 @@ jobs:
346384
MX_CHAIN_TESTING_SUITE_TARGET_BRANCH: ${{ env.MX_CHAIN_TESTING_SUITE_TARGET_BRANCH }}
347385
LATEST_COMMIT_HASH: ${{ env.LATEST_COMMIT_HASH }}
348386
PYTEST_EXIT_CODE: ${{ env.PYTEST_EXIT_CODE }}
349-
387+
CURRENT_COMMIT_HASH: ${{ env.CURRENT_COMMIT_HASH }}
388+
SIMULATOR_COMMIT_HASH: ${{ env.SIMULATOR_COMMIT_HASH }}
389+
SIMULATOR_REF: ${{ env.SIMULATOR_REF }}
390+
R2_REPORT_URL: ${{ env.R2_REPORT_URL }}
350391
with:
351392
github-token: ${{ secrets.GITHUB_TOKEN }}
352393
script: |
353-
const timestamp = process.env.TIMESTAMP;
354-
const branchName = process.env.BRANCH_NAME;
355-
const currentBranch = process.env.CURRENT_BRANCH;
356-
const goTargetBranch = process.env.MX_CHAIN_GO_TARGET_BRANCH;
357-
const simulatorTargetBranch = process.env.MX_CHAIN_SIMULATOR_TARGET_BRANCH;
358-
const testingSuiteTargetBranch = process.env.MX_CHAIN_TESTING_SUITE_TARGET_BRANCH;
359-
const commitHash = process.env.LATEST_COMMIT_HASH;
360-
const exitCode = process.env.PYTEST_EXIT_CODE;
394+
const timestamp = process.env.TIMESTAMP;
395+
const branchName = process.env.BRANCH_NAME;
396+
const currentBranch = process.env.CURRENT_BRANCH;
397+
const goTargetBranch = process.env.MX_CHAIN_GO_TARGET_BRANCH;
398+
const simulatorTargetBranch = process.env.MX_CHAIN_SIMULATOR_TARGET_BRANCH;
399+
const testingSuiteTargetBranch = process.env.MX_CHAIN_TESTING_SUITE_TARGET_BRANCH;
400+
const commitHash = process.env.LATEST_COMMIT_HASH;
401+
const exitCode = process.env.PYTEST_EXIT_CODE;
402+
403+
const simulatorCommitHash = process.env.SIMULATOR_COMMIT_HASH || 'N/A';
404+
const r2Url = process.env.R2_REPORT_URL || 'N/A';
405+
361406
const issue_number = context.issue.number;
362-
const owner = context.repo.owner;
363-
const repo = context.repo.repo;
407+
const owner = context.repo.owner;
408+
const repo = context.repo.repo;
409+
const ts = process.env.TS || process.env.TIMESTAMP;
410+
const verdict = exitCode === "0"
411+
? "✅ **Integration Tests passed successfully!**"
412+
: "❌ **Integration Tests completed with failures or errors.**";
364413
let message;
365-
366-
if (timestamp && branchName && timestamp !== "" && branchName !== "") {
367-
const reportUrl = `https://multiversx.github.io/mx-chain-testing-suite/reports/${branchName}/${timestamp}/index.html`;
414+
if (timestamp && branchName) {
415+
const backupUrl = `https://multiversx.github.io/mx-chain-testing-suite/reports/${branchName}/${timestamp}/index.html`;
368416
message = `
369-
📊 **MultiversX Automated Test Report:** [View Report](${reportUrl})
417+
${verdict}
370418
419+
📊 **MultiversX Automated Test Report:** [View Report](${r2Url})
420+
371421
🔄 **Build Details:**
372422
- **mx-chain-go Commit Hash:** \`${commitHash}\`
373423
- **Current Branch:** \`${currentBranch}\`
374424
- **mx-chain-go Target Branch:** \`${goTargetBranch}\`
375425
- **mx-chain-simulator-go Target Branch:** \`${simulatorTargetBranch}\`
376426
- **mx-chain-testing-suite Target Branch:** \`${testingSuiteTargetBranch}\`
377-
427+
- **mx-chain-simulator-go Commit Hash:** \`${simulatorCommitHash}\`
428+
378429
🚀 **Environment Variables:**
379-
- **TIMESTAMP:** \`${timestamp}\`
380-
- **PYTEST_EXIT_CODE:** \`${exitCode}\`
381-
🎉 **MultiversX CI/CD Workflow Complete!**
430+
- **TIMESTAMP:** \`${ts}\`
431+
- **PYTEST_EXIT_CODE:** \`${exitCode}\`
382432
`;
383433
} else {
384-
message = "⚠️ No report was generated due to an error or cancellation of the process.\nPlease checkout gh action logs for details";
434+
message = "⚠️ No report was generated due to an error or cancellation of the process.\nPlease checkout GH-Action logs for details.";
385435
}
386436
387437
github.rest.issues.createComment({
@@ -391,6 +441,36 @@ jobs:
391441
body: message
392442
});
393443
444+
- name: Notify Slack
445+
if: always()
446+
env:
447+
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
448+
R2_REPORT_URL: ${{ env.R2_REPORT_URL }}
449+
BRANCH_NAME: ${{ env.BRANCH_NAME }}
450+
CURRENT_COMMIT_HASH: ${{ env.CURRENT_COMMIT_HASH }}
451+
SIMULATOR_REF: ${{ env.SIMULATOR_REF }}
452+
SIMULATOR_COMMIT_HASH: ${{ env.SIMULATOR_COMMIT_HASH }}
453+
TS: ${{ env.TS }}
454+
PYTEST_EXIT_CODE: ${{ env.PYTEST_EXIT_CODE }}
455+
run: |
456+
status="❌ FAILED"
457+
[ "${PYTEST_EXIT_CODE}" = "0" ] && status="✅ PASSED"
458+
repo="${GITHUB_REPOSITORY##*/}"
459+
base="${{ github.base_ref }}"
460+
461+
msg="*MX-CHAIN-GO ChainSimulator CI – ${status}*\
462+
\n• *Report:* <${R2_REPORT_URL:-N/A}|HTML>\
463+
\n• *Repository:* \`${repo}\`\
464+
\n• *Branch:* \`${BRANCH_NAME}\` → \`${base:-main}\`\
465+
\n• *Testing-suite Commit:* \`${CURRENT_COMMIT_HASH}\`\
466+
\n• *Chain Simulator Branch:* \`${SIMULATOR_REF}\`\
467+
\n• *Chain Simulator Commit:* \`${SIMULATOR_COMMIT_HASH}\`\
468+
\n• *Run at:* ${TS}"
469+
470+
curl -s -X POST -H 'Content-Type: application/json' \
471+
-d "{\"text\":\"${msg}\"}" \
472+
"$SLACK_WEBHOOK_URL"
473+
394474
- name: Fail job if tests failed
395475
if: always()
396476
run: |

.github/workflows/check-cli-md.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ on:
77
push:
88
workflow_dispatch:
99

10+
permissions:
11+
contents: read
12+
1013
jobs:
1114
build:
1215
strategy:

.github/workflows/code-coverage.yml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,14 @@ on:
66
- master
77
pull_request:
88
branches: [ master, feat/*, rc/* ]
9-
109
workflow_dispatch:
1110

11+
permissions:
12+
contents: read
13+
1214
jobs:
1315
build:
14-
strategy:
15-
matrix:
16-
runs-on: [ubuntu-latest]
17-
runs-on: ${{ matrix.runs-on }}
16+
runs-on: [self-hosted, Linux, X64]
1817
name: Build
1918
steps:
2019
- name: Set up Go 1.23.6

.github/workflows/docker-keygenerator.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ name: Build & push keygenerator docker image
33
on:
44
workflow_dispatch:
55

6+
permissions:
7+
contents: read
8+
69
jobs:
710
build-docker-image:
811
strategy:

api/groups/addressGroup.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ const (
4242
urlParamWithKeys = "withKeys"
4343
)
4444

45+
// maxUint64 is represented on 20 characters as a string
46+
const maxNumCharsForNonceAsString = 20
47+
4548
// addressFacadeHandler defines the methods to be implemented by a facade for handling address requests
4649
type addressFacadeHandler interface {
4750
GetBalance(address string, options api.AccountQueryOptions) (*big.Int, api.BlockInfo, error)
@@ -634,6 +637,9 @@ func extractGetESDTNFTDataParams(c *gin.Context) (string, string, *big.Int, api.
634637
if nonceAsStr == "" {
635638
return "", "", nil, api.AccountQueryOptions{}, errors.ErrNonceInvalid
636639
}
640+
if len(nonceAsStr) > maxNumCharsForNonceAsString {
641+
return "", "", nil, api.AccountQueryOptions{}, fmt.Errorf("%w: nonce too long, num chars %v, max num chars %v", errors.ErrNonceInvalid, len(nonceAsStr), maxNumCharsForNonceAsString)
642+
}
637643

638644
nonceAsBigInt, okConvert := big.NewInt(0).SetString(nonceAsStr, 10)
639645
if !okConvert {

api/groups/addressGroup_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -992,6 +992,9 @@ func TestAddressGroup_getESDTNFTData(t *testing.T) {
992992
t.Run("invalid nonce should error",
993993
testErrorScenario("/address/erd1alice/nft/newToken/nonce/not-int", "GET", nil,
994994
formatExpectedErr(apiErrors.ErrGetESDTNFTData, apiErrors.ErrNonceInvalid)))
995+
t.Run("nonce too long should error",
996+
testErrorScenario("/address/erd1alice/nft/newToken/nonce/1234567489123456789123", "GET", nil,
997+
formatExpectedErr(apiErrors.ErrGetESDTNFTData, apiErrors.ErrNonceInvalid)))
995998
t.Run("with node fail should err", func(t *testing.T) {
996999
t.Parallel()
9971000

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -401,8 +401,6 @@ github.com/multiversx/concurrent-map v0.1.4 h1:hdnbM8VE4b0KYJaGY5yJS2aNIW9TFFsUY
401401
github.com/multiversx/concurrent-map v0.1.4/go.mod h1:8cWFRJDOrWHOTNSqgYCUvwT7c7eFQ4U2vKMOp4A/9+o=
402402
github.com/multiversx/mx-chain-communication-go v1.2.1-0.20250520083403-3f2bad6d5476 h1:Dn73bH1AdG+7+3/FFRfOiivOEvwPyzZUBWWxpk8QVxc=
403403
github.com/multiversx/mx-chain-communication-go v1.2.1-0.20250520083403-3f2bad6d5476/go.mod h1:99+FW6f7X0Ri5tph+2l2GaDVrdej1do89exkfh7gilE=
404-
github.com/multiversx/mx-chain-core-go v1.3.2-0.20250606113953-9e4dc87c16cb h1:orPuViEu3dnElbfp6w2q1iokLQlTueb9akRpxfqe6IU=
405-
github.com/multiversx/mx-chain-core-go v1.3.2-0.20250606113953-9e4dc87c16cb/go.mod h1:IO+vspNan+gT0WOHnJ95uvWygiziHZvfXpff6KnxV7g=
406404
github.com/multiversx/mx-chain-core-go v1.3.2-0.20250611135730-8202519ce227 h1:0Xu8i4k/aMO5Vb36SIS4ejJHI3gbEtpHjIZUsaVCSSE=
407405
github.com/multiversx/mx-chain-core-go v1.3.2-0.20250611135730-8202519ce227/go.mod h1:IO+vspNan+gT0WOHnJ95uvWygiziHZvfXpff6KnxV7g=
408406
github.com/multiversx/mx-chain-crypto-go v1.2.13-0.20250520075055-8ab2a164945d h1:NI5uKpkwP5XZu9gtDiWxmbbb07T9hXegPist17WAzY4=
@@ -419,6 +417,8 @@ github.com/multiversx/mx-chain-vm-common-go v1.5.17-0.20250604100541-1efc3d1b131
419417
github.com/multiversx/mx-chain-vm-common-go v1.5.17-0.20250604100541-1efc3d1b1314/go.mod h1:HlpJgCTYVvHE1nrEJLIsR/AJx0gqzg3m+qdJwf7jOjU=
420418
github.com/multiversx/mx-chain-vm-go v1.5.41-0.20250612091736-50ea397e96f7 h1:oNbDBD1VZauOg9iltCd9q8QXkNpS+cglgnjklG8cEtI=
421419
github.com/multiversx/mx-chain-vm-go v1.5.41-0.20250612091736-50ea397e96f7/go.mod h1:K9NYP80fWFD7pSRG+5RQ42P9AGTsbdSF6Y9vLC1M4Z0=
420+
github.com/multiversx/mx-chain-vm-go v1.5.41-0.20250613100924-fa527150f62e h1:487uQFdkWIJ/cI6c7sPPOXHxspMxRg7zumsNnyfapx4=
421+
github.com/multiversx/mx-chain-vm-go v1.5.41-0.20250613100924-fa527150f62e/go.mod h1:vfFEw1qAmR1mUU8/p2EKu2woKS+o9W8wSqi3muEqRds=
422422
github.com/multiversx/mx-chain-vm-v1_2-go v1.2.69-0.20250520080927-410c413d962f h1:Sg1SZWm90IeliVPce3w0CtLjr+a+mcWAFVHW2VGR0nA=
423423
github.com/multiversx/mx-chain-vm-v1_2-go v1.2.69-0.20250520080927-410c413d962f/go.mod h1:aeGXPTVkUDsPcHwuSer2VXEnMow7iofEvuDGPd47Cj8=
424424
github.com/multiversx/mx-chain-vm-v1_3-go v1.3.70-0.20250520081414-edf8b75e054d h1:DFYWypkQs7BYepsLPz/IIN8cGsEf4+fWM9L0a6mnfKU=

node/node.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,10 @@ func (n *Node) GetAllESDTTokens(address string, options api.AccountQueryOptions,
679679
continue
680680
}
681681

682+
if esdtToken.Value.Sign() <= 0 {
683+
continue
684+
}
685+
682686
if esdtToken.TokenMetaData != nil {
683687
esdtTokenCreatorAddr, errEncode := n.coreComponents.AddressPubKeyConverter().Encode(esdtToken.TokenMetaData.Creator)
684688
if errEncode != nil {

node/node_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1080,13 +1080,30 @@ func TestNode_GetAllESDTTokensShouldReturnEsdtAndFormattedNft(t *testing.T) {
10801080
nftData := &esdt.ESDigitalToken{Type: uint32(core.NonFungible), Value: big.NewInt(10), TokenMetaData: nftMetaData}
10811081
marshalledNftData, _ := getMarshalizer().Marshal(nftData)
10821082

1083+
dynamicNft := "TCKR-abcdef"
1084+
dynamicNftNonce := big.NewInt(100)
1085+
dynamicNftKey := []byte(core.ProtectedKeyPrefix + core.ESDTKeyIdentifier + dynamicNft)
1086+
dynamicNftKeyWithBytes := append(dynamicNftKey, dynamicNftNonce.Bytes()...)
1087+
dynamicNftSuffix := append(dynamicNftKeyWithBytes, acc.AddressBytes()...)
1088+
dynamicNftData := &esdt.ESDigitalToken{
1089+
Type: uint32(core.DynamicNFT),
1090+
Value: big.NewInt(0),
1091+
TokenMetaData: &esdt.MetaData{
1092+
Nonce: dynamicNftNonce.Uint64(),
1093+
URIs: [][]byte{[]byte("https://example.com/dynamic-nft")},
1094+
},
1095+
}
1096+
marshalledDynamicNftData, _ := getMarshalizer().Marshal(dynamicNftData)
1097+
10831098
esdtStorageStub := &testscommon.EsdtStorageHandlerStub{
10841099
GetESDTNFTTokenOnDestinationWithCustomSystemAccountCalled: func(acnt vmcommon.UserAccountHandler, esdtTokenKey []byte, nonce uint64, _ vmcommon.UserAccountHandler) (*esdt.ESDigitalToken, bool, error) {
10851100
switch string(esdtTokenKey) {
10861101
case string(esdtKey):
10871102
return esdtData, false, nil
10881103
case string(nftKey):
10891104
return nftData, false, nil
1105+
case string(dynamicNftKey):
1106+
return dynamicNftData, false, nil
10901107
default:
10911108
return nil, false, nil
10921109
}
@@ -1103,6 +1120,10 @@ func TestNode_GetAllESDTTokensShouldReturnEsdtAndFormattedNft(t *testing.T) {
11031120

11041121
trieLeaf = keyValStorage.NewKeyValStorage(nftKey, append(marshalledNftData, nftSuffix...))
11051122
leavesChannels.LeavesChan <- trieLeaf
1123+
1124+
trieLeaf = keyValStorage.NewKeyValStorage(dynamicNftKey, append(marshalledDynamicNftData, dynamicNftSuffix...))
1125+
leavesChannels.LeavesChan <- trieLeaf
1126+
11061127
wg.Done()
11071128
close(leavesChannels.LeavesChan)
11081129
leavesChannels.ErrChan.Close()

sonar-project.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
sonar.exclusions=**/*_test.go, integrationTests/**, testcommon/**, **/mock/**, **/disabled/**, **/disabled*.go, examples/**, scripts/**, **/*.pb.go

0 commit comments

Comments
 (0)